fix(ui): keep the album grid working outside the Random list

Hoisting the shown-seed ref into AlbumList made the prop mandatory in practice:
ArtistShow renders the same grid through ReferenceManyField and passes no seed
tracking, so useRollChanged dereferenced undefined and the artist page died with
"Cannot read properties of undefined (reading 'current')".

Own a ref in the grid when none is passed. A caller with no roll to track then
behaves as it did before, while the Random list keeps the ref that has to outlive
the refresh remount.
This commit is contained in:
Deluan 2026-07-29 17:21:36 -04:00
parent 07a7d76e19
commit fbcda30473
2 changed files with 23 additions and 2 deletions

View File

@ -1,4 +1,4 @@
import React from 'react'
import React, { useRef } from 'react'
import {
GridList,
GridListTile,
@ -239,9 +239,12 @@ const AlbumGridView = ({
shownSeed,
...props
}) => {
// ArtistShow renders this grid too, with no roll to track, so own a ref when none is passed.
const ownSeed = useRef(null)
// A re-roll replaces every album, so the previous roll must not linger while it loads.
const rerolling =
useRollChanged(shownSeed, seed, loading) && albumListType === 'random'
useRollChanged(shownSeed ?? ownSeed, seed, loading) &&
albumListType === 'random'
const hide = rerolling || !props.data || !props.ids
return hide ? <Loading /> : <LoadedAlbumGrid {...props} />
}

View File

@ -0,0 +1,18 @@
import { render } from '@testing-library/react'
import { describe, it, expect, vi } from 'vitest'
import AlbumGridView from './AlbumGridView'
// react-admin's Link/useListContext need a router and a store; the grid body is not under test here.
vi.mock('react-admin', () => ({
linkToRecord: () => '/album/1',
useListContext: () => ({}),
Loading: () => <div data-testid="loading" />,
}))
describe('AlbumGridView', () => {
// ArtistShow renders the grid through ReferenceManyField, which passes no seed tracking.
it('renders without a shownSeed ref', () => {
expect(() =>
render(<AlbumGridView data={{}} ids={[]} basePath="/album" width="md" />),
).not.toThrow()
})
})