feat(ui): add remove all missing files functionality (#4108)
* Add remove all missing files feature * test: update mediafile_repository tests for missing files deletion Signed-off-by: Deluan <deluan@navidrome.org> --------- Signed-off-by: Deluan <deluan@navidrome.org>
This commit is contained in:
@@ -29,13 +29,14 @@ const useStyles = makeStyles(
|
||||
)
|
||||
|
||||
const DeleteMissingFilesButton = (props) => {
|
||||
const { selectedIds, className } = props
|
||||
const { selectedIds, className, deleteAll = false } = props
|
||||
const [open, setOpen] = useState(false)
|
||||
const unselectAll = useUnselectAll()
|
||||
const refresh = useRefresh()
|
||||
const notify = useNotify()
|
||||
|
||||
const [deleteMany, { loading }] = useDeleteMany('missing', selectedIds, {
|
||||
const ids = deleteAll ? [] : selectedIds
|
||||
const [deleteMany, { loading }] = useDeleteMany('missing', ids, {
|
||||
onSuccess: () => {
|
||||
notify('resources.missing.notifications.removed')
|
||||
refresh()
|
||||
@@ -57,7 +58,11 @@ const DeleteMissingFilesButton = (props) => {
|
||||
<>
|
||||
<Button
|
||||
onClick={handleClick}
|
||||
label="ra.action.remove"
|
||||
label={
|
||||
deleteAll
|
||||
? 'resources.missing.actions.remove_all'
|
||||
: 'ra.action.remove'
|
||||
}
|
||||
key="button"
|
||||
className={clsx('ra-delete-button', classes.deleteButton, className)}
|
||||
>
|
||||
@@ -66,8 +71,16 @@ const DeleteMissingFilesButton = (props) => {
|
||||
<Confirm
|
||||
isOpen={open}
|
||||
loading={loading}
|
||||
title="message.remove_missing_title"
|
||||
content="message.remove_missing_content"
|
||||
title={
|
||||
deleteAll
|
||||
? 'message.remove_all_missing_title'
|
||||
: 'message.remove_missing_title'
|
||||
}
|
||||
content={
|
||||
deleteAll
|
||||
? 'message.remove_all_missing_content'
|
||||
: 'message.remove_missing_content'
|
||||
}
|
||||
onConfirm={handleConfirm}
|
||||
onClose={handleDialogClose}
|
||||
/>
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
import React from 'react'
|
||||
import { render } from '@testing-library/react'
|
||||
import { describe, it, expect, beforeEach, vi } from 'vitest'
|
||||
import DeleteMissingFilesButton from './DeleteMissingFilesButton.jsx'
|
||||
import * as RA from 'react-admin'
|
||||
|
||||
vi.mock('react-admin', async () => {
|
||||
const actual = await vi.importActual('react-admin')
|
||||
return {
|
||||
...actual,
|
||||
Button: ({ children, onClick, label }) => (
|
||||
<button onClick={onClick}>{label || children}</button>
|
||||
),
|
||||
Confirm: ({ isOpen }) => (isOpen ? <div data-testid="confirm" /> : null),
|
||||
useNotify: vi.fn(),
|
||||
useDeleteMany: vi.fn(() => [vi.fn(), { loading: false }]),
|
||||
useRefresh: vi.fn(),
|
||||
useUnselectAll: vi.fn(),
|
||||
}
|
||||
})
|
||||
|
||||
describe('DeleteMissingFilesButton', () => {
|
||||
beforeEach(() => {
|
||||
vi.clearAllMocks()
|
||||
})
|
||||
|
||||
it('uses remove_all label when deleteAll is true', () => {
|
||||
const { getByRole } = render(<DeleteMissingFilesButton deleteAll />)
|
||||
expect(getByRole('button').textContent).toBe(
|
||||
'resources.missing.actions.remove_all',
|
||||
)
|
||||
})
|
||||
|
||||
it('calls useDeleteMany with empty ids when deleteAll is true', () => {
|
||||
render(<DeleteMissingFilesButton deleteAll />)
|
||||
expect(RA.useDeleteMany).toHaveBeenCalledWith(
|
||||
'missing',
|
||||
[],
|
||||
expect.any(Object),
|
||||
)
|
||||
})
|
||||
})
|
||||
@@ -8,6 +8,7 @@ import {
|
||||
} from 'react-admin'
|
||||
import jsonExport from 'jsonexport/dist'
|
||||
import DeleteMissingFilesButton from './DeleteMissingFilesButton.jsx'
|
||||
import MissingListActions from './MissingListActions.jsx'
|
||||
|
||||
const exporter = (files) => {
|
||||
const filesToExport = files.map((file) => {
|
||||
@@ -35,6 +36,7 @@ const MissingFilesList = (props) => {
|
||||
{...props}
|
||||
sort={{ field: 'updated_at', order: 'DESC' }}
|
||||
exporter={exporter}
|
||||
actions={<MissingListActions />}
|
||||
bulkActionButtons={<BulkActionButtons />}
|
||||
perPage={50}
|
||||
pagination={<MissingPagination />}
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
import React from 'react'
|
||||
import { TopToolbar, ExportButton } from 'react-admin'
|
||||
import DeleteMissingFilesButton from './DeleteMissingFilesButton.jsx'
|
||||
|
||||
const MissingListActions = (props) => (
|
||||
<TopToolbar {...props}>
|
||||
<ExportButton />
|
||||
<DeleteMissingFilesButton deleteAll />
|
||||
</TopToolbar>
|
||||
)
|
||||
|
||||
export default MissingListActions
|
||||
Reference in New Issue
Block a user