mirror of
https://github.com/navidrome/navidrome.git
synced 2026-10-19 00:45:59 +00:00
fix(ui): don't crash the playlist list when rows lose their record (#6250)
Some checks failed
Pipeline: Test, Lint, Build / Validate DB migrations (push) Has been cancelled
Pipeline: Test, Lint, Build / Lint i18n files (push) Has been cancelled
Pipeline: Test, Lint, Build / Check Docker configuration (push) Has been cancelled
Pipeline: Test, Lint, Build / Get version info (push) Has been cancelled
Pipeline: Test, Lint, Build / Lint Go code (push) Has been cancelled
Pipeline: Test, Lint, Build / Test Go code (push) Has been cancelled
Pipeline: Test, Lint, Build / Test Go plugins (push) Has been cancelled
Pipeline: Test, Lint, Build / Test Go code (Windows) (push) Has been cancelled
Pipeline: Test, Lint, Build / Test JS code (push) Has been cancelled
Pipeline: Test, Lint, Build / Push to Docker Hub (push) Has been cancelled
Pipeline: Test, Lint, Build / Cleanup digest artifacts (push) Has been cancelled
Pipeline: Test, Lint, Build / Report coverage (push) Has been cancelled
Pipeline: Test, Lint, Build / Build (push) Has been cancelled
Pipeline: Test, Lint, Build / Build-1 (push) Has been cancelled
Pipeline: Test, Lint, Build / Build-2 (push) Has been cancelled
Pipeline: Test, Lint, Build / Build-3 (push) Has been cancelled
Pipeline: Test, Lint, Build / Build-4 (push) Has been cancelled
Pipeline: Test, Lint, Build / Build-5 (push) Has been cancelled
Pipeline: Test, Lint, Build / Build-6 (push) Has been cancelled
Pipeline: Test, Lint, Build / Build-7 (push) Has been cancelled
Pipeline: Test, Lint, Build / Build-8 (push) Has been cancelled
Pipeline: Test, Lint, Build / Build-9 (push) Has been cancelled
Pipeline: Test, Lint, Build / Build-10 (push) Has been cancelled
Pipeline: Test, Lint, Build / Push to GHCR (push) Has been cancelled
Pipeline: Test, Lint, Build / Build Windows installers (push) Has been cancelled
Pipeline: Test, Lint, Build / Package/Release (push) Has been cancelled
Pipeline: Test, Lint, Build / Upload Linux PKG (push) Has been cancelled
Some checks failed
Pipeline: Test, Lint, Build / Validate DB migrations (push) Has been cancelled
Pipeline: Test, Lint, Build / Lint i18n files (push) Has been cancelled
Pipeline: Test, Lint, Build / Check Docker configuration (push) Has been cancelled
Pipeline: Test, Lint, Build / Get version info (push) Has been cancelled
Pipeline: Test, Lint, Build / Lint Go code (push) Has been cancelled
Pipeline: Test, Lint, Build / Test Go code (push) Has been cancelled
Pipeline: Test, Lint, Build / Test Go plugins (push) Has been cancelled
Pipeline: Test, Lint, Build / Test Go code (Windows) (push) Has been cancelled
Pipeline: Test, Lint, Build / Test JS code (push) Has been cancelled
Pipeline: Test, Lint, Build / Push to Docker Hub (push) Has been cancelled
Pipeline: Test, Lint, Build / Cleanup digest artifacts (push) Has been cancelled
Pipeline: Test, Lint, Build / Report coverage (push) Has been cancelled
Pipeline: Test, Lint, Build / Build (push) Has been cancelled
Pipeline: Test, Lint, Build / Build-1 (push) Has been cancelled
Pipeline: Test, Lint, Build / Build-2 (push) Has been cancelled
Pipeline: Test, Lint, Build / Build-3 (push) Has been cancelled
Pipeline: Test, Lint, Build / Build-4 (push) Has been cancelled
Pipeline: Test, Lint, Build / Build-5 (push) Has been cancelled
Pipeline: Test, Lint, Build / Build-6 (push) Has been cancelled
Pipeline: Test, Lint, Build / Build-7 (push) Has been cancelled
Pipeline: Test, Lint, Build / Build-8 (push) Has been cancelled
Pipeline: Test, Lint, Build / Build-9 (push) Has been cancelled
Pipeline: Test, Lint, Build / Build-10 (push) Has been cancelled
Pipeline: Test, Lint, Build / Push to GHCR (push) Has been cancelled
Pipeline: Test, Lint, Build / Build Windows installers (push) Has been cancelled
Pipeline: Test, Lint, Build / Package/Release (push) Has been cancelled
Pipeline: Test, Lint, Build / Upload Linux PKG (push) Has been cancelled
* fix(ui): don't crash playlist list rows that lost their record react-admin 3 evicts records fetched more than 10 minutes ago whenever another getList for the same resource completes, but the list keeps its cached ids. The Datagrid then renders those rows with an undefined record, and the Public and Auto-import switches crashed reading record.id. This happened when the playlist list was left open and the sidebar or the add to playlist dialog reloaded a smaller set of playlists. Both switches now render nothing when the row has no record; the next list refresh fills the row in again. * refactor(ui): merge playlist list toggles into one ToggleField The Public and Auto-import switches were copies that differed only in the field they flip. ToggleField now flips its source field, and ToggleAutoImport just shows it for playlists that have a file path. The tests render inside TestContext, so they use react-admin's real hooks instead of mocks.
This commit is contained in:
parent
e03ce87177
commit
0e1893530b
2 changed files with 34 additions and 37 deletions
|
|
@ -67,15 +67,15 @@ const PlaylistFilter = (props) => {
|
|||
)
|
||||
}
|
||||
|
||||
const TogglePublicInput = ({ resource, source }) => {
|
||||
export const ToggleField = ({ resource, source }) => {
|
||||
const record = useRecordContext()
|
||||
const notify = useNotify()
|
||||
const [togglePublic] = useUpdate(
|
||||
const [toggle] = useUpdate(
|
||||
resource,
|
||||
record.id,
|
||||
record?.id,
|
||||
{
|
||||
...record,
|
||||
public: !record.public,
|
||||
[source]: !record?.[source],
|
||||
},
|
||||
{
|
||||
undoable: false,
|
||||
|
|
@ -86,10 +86,12 @@ const TogglePublicInput = ({ resource, source }) => {
|
|||
)
|
||||
|
||||
const handleClick = (e) => {
|
||||
togglePublic()
|
||||
toggle()
|
||||
e.stopPropagation()
|
||||
}
|
||||
|
||||
if (!record) return null
|
||||
|
||||
return (
|
||||
<Switch
|
||||
checked={record[source]}
|
||||
|
|
@ -99,35 +101,9 @@ const TogglePublicInput = ({ resource, source }) => {
|
|||
)
|
||||
}
|
||||
|
||||
const ToggleAutoImport = ({ resource, source }) => {
|
||||
export const ToggleAutoImport = (props) => {
|
||||
const record = useRecordContext()
|
||||
const notify = useNotify()
|
||||
const [ToggleAutoImport] = useUpdate(
|
||||
resource,
|
||||
record.id,
|
||||
{
|
||||
...record,
|
||||
sync: !record.sync,
|
||||
},
|
||||
{
|
||||
undoable: false,
|
||||
onFailure: (error) => {
|
||||
notify('ra.page.error', 'warning')
|
||||
},
|
||||
},
|
||||
)
|
||||
const handleClick = (e) => {
|
||||
ToggleAutoImport()
|
||||
e.stopPropagation()
|
||||
}
|
||||
|
||||
return record.path ? (
|
||||
<Switch
|
||||
checked={record[source]}
|
||||
onClick={handleClick}
|
||||
disabled={!isWritable(record.ownerId)}
|
||||
/>
|
||||
) : null
|
||||
return record?.path ? <ToggleField {...props} /> : null
|
||||
}
|
||||
|
||||
const PlaylistListBulkActions = (props) => {
|
||||
|
|
@ -169,9 +145,7 @@ const PlaylistList = (props) => {
|
|||
updatedAt: isDesktop && (
|
||||
<DateField source="updatedAt" sortByOrder={'DESC'} />
|
||||
),
|
||||
public: !isXsmall && (
|
||||
<TogglePublicInput source="public" sortByOrder={'DESC'} />
|
||||
),
|
||||
public: !isXsmall && <ToggleField source="public" sortByOrder={'DESC'} />,
|
||||
comment: <TextField source="comment" />,
|
||||
sync: !isXsmall && (
|
||||
<ToggleAutoImport source="sync" sortByOrder={'DESC'} />
|
||||
|
|
|
|||
|
|
@ -1,7 +1,8 @@
|
|||
import React from 'react'
|
||||
import { render, screen } from '@testing-library/react'
|
||||
import { describe, it, expect, vi } from 'vitest'
|
||||
import { PlaylistLove } from './PlaylistList'
|
||||
import { TestContext } from 'ra-test'
|
||||
import { PlaylistLove, ToggleField, ToggleAutoImport } from './PlaylistList'
|
||||
|
||||
vi.mock('../config', () => ({
|
||||
default: { enableFavourites: true },
|
||||
|
|
@ -32,3 +33,25 @@ describe('<PlaylistLove />', () => {
|
|||
})
|
||||
})
|
||||
})
|
||||
|
||||
// react-admin evicts records older than 10 minutes while the list still holds
|
||||
// their ids, so rows can render with no record.
|
||||
describe('playlist toggles without a record', () => {
|
||||
it('<ToggleField /> renders nothing', () => {
|
||||
const { container } = render(
|
||||
<TestContext>
|
||||
<ToggleField resource="playlist" source="public" />
|
||||
</TestContext>,
|
||||
)
|
||||
expect(container.innerHTML).toBe('')
|
||||
})
|
||||
|
||||
it('<ToggleAutoImport /> renders nothing', () => {
|
||||
const { container } = render(
|
||||
<TestContext>
|
||||
<ToggleAutoImport resource="playlist" source="sync" />
|
||||
</TestContext>,
|
||||
)
|
||||
expect(container.innerHTML).toBe('')
|
||||
})
|
||||
})
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue