Merge pull request #13617 from strapi/ML-folder/bulk-move-select

[ML Folder] Bulk move fixes
This commit is contained in:
Julie Plantey 2022-06-24 12:05:20 +02:00 committed by GitHub
commit df17a62611
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 89 additions and 25 deletions

View File

@ -24,7 +24,7 @@ import SelectTree from '../SelectTree';
import { useFolderStructure } from '../../hooks/useFolderStructure'; import { useFolderStructure } from '../../hooks/useFolderStructure';
import { FolderDefinition, AssetDefinition } from '../../constants'; import { FolderDefinition, AssetDefinition } from '../../constants';
export const BulkMoveDialog = ({ onClose, selected }) => { export const BulkMoveDialog = ({ onClose, selected, currentFolder }) => {
const { formatMessage } = useIntl(); const { formatMessage } = useIntl();
const { data: folderStructure, isLoading } = useFolderStructure(); const { data: folderStructure, isLoading } = useFolderStructure();
const { move } = useBulkMove(); const { move } = useBulkMove();
@ -73,7 +73,10 @@ export const BulkMoveDialog = ({ onClose, selected }) => {
} }
const initialFormData = { const initialFormData = {
destination: folderStructure[0], destination: {
value: currentFolder?.id || '',
label: currentFolder?.name || folderStructure[0].label,
},
}; };
return ( return (
@ -148,9 +151,12 @@ export const BulkMoveDialog = ({ onClose, selected }) => {
); );
}; };
BulkMoveDialog.defaultProps = {}; BulkMoveDialog.defaultProps = {
currentFolder: undefined,
};
BulkMoveDialog.propTypes = { BulkMoveDialog.propTypes = {
selected: PropTypes.arrayOf(FolderDefinition, AssetDefinition).isRequired,
onClose: PropTypes.func.isRequired, onClose: PropTypes.func.isRequired,
currentFolder: FolderDefinition,
selected: PropTypes.arrayOf(FolderDefinition, AssetDefinition).isRequired,
}; };

View File

@ -8,6 +8,7 @@ import { QueryClientProvider, QueryClient } from 'react-query';
import { BulkMoveDialog } from '..'; import { BulkMoveDialog } from '..';
jest.mock('../../../hooks/useFolderStructure'); jest.mock('../../../hooks/useFolderStructure');
jest.mock('../../../hooks/useBulkMove');
const client = new QueryClient({ const client = new QueryClient({
defaultOptions: { defaultOptions: {
@ -31,7 +32,7 @@ function ComponentFixture(props) {
); );
} }
function setup(props = { onClose: jest.fn() }) { function setup(props = { onClose: jest.fn(), selected: [] }) {
return render(<ComponentFixture {...props} />, { container: document.getElementById('app') }); return render(<ComponentFixture {...props} />, { container: document.getElementById('app') });
} }
@ -41,10 +42,7 @@ describe('BulkMoveDialog', () => {
}); });
test('renders and matches the snapshot', () => { test('renders and matches the snapshot', () => {
setup({ setup();
selected: [],
onClose: jest.fn(),
});
expect(document.body).toMatchSnapshot(); expect(document.body).toMatchSnapshot();
}); });
}); });

View File

@ -199,7 +199,9 @@ export const MediaLibrary = () => {
/> />
<ContentLayout> <ContentLayout>
{selected.length > 0 && <BulkActions selected={selected} onSuccess={selectAll} />} {selected.length > 0 && (
<BulkActions currentFolder={currentFolder} selected={selected} onSuccess={selectAll} />
)}
{isLoading && <LoadingIndicatorPage />} {isLoading && <LoadingIndicatorPage />}

View File

@ -9,7 +9,7 @@ import getTrad from '../../../utils/getTrad';
import { BulkDeleteButton } from './BulkDeleteButton'; import { BulkDeleteButton } from './BulkDeleteButton';
import { BulkMoveButton } from './BulkMoveButton'; import { BulkMoveButton } from './BulkMoveButton';
export const BulkActions = ({ selected, onSuccess }) => { export const BulkActions = ({ selected, onSuccess, currentFolder }) => {
const { formatMessage } = useIntl(); const { formatMessage } = useIntl();
return ( return (
@ -29,12 +29,17 @@ export const BulkActions = ({ selected, onSuccess }) => {
</Typography> </Typography>
<BulkDeleteButton selected={selected} onSuccess={onSuccess} /> <BulkDeleteButton selected={selected} onSuccess={onSuccess} />
<BulkMoveButton selected={selected} onSuccess={onSuccess} /> <BulkMoveButton currentFolder={currentFolder} selected={selected} onSuccess={onSuccess} />
</Stack> </Stack>
); );
}; };
BulkActions.propTypes = { BulkActions.defaultProps = {
selected: PropTypes.arrayOf(AssetDefinition, FolderDefinition).isRequired, currentFolder: undefined,
onSuccess: PropTypes.func.isRequired, };
BulkActions.propTypes = {
onSuccess: PropTypes.func.isRequired,
currentFolder: FolderDefinition,
selected: PropTypes.arrayOf(AssetDefinition, FolderDefinition).isRequired,
}; };

View File

@ -7,7 +7,7 @@ import Folder from '@strapi/icons/Folder';
import { BulkMoveDialog } from '../../../components/BulkMoveDialog'; import { BulkMoveDialog } from '../../../components/BulkMoveDialog';
import { AssetDefinition, FolderDefinition } from '../../../constants'; import { AssetDefinition, FolderDefinition } from '../../../constants';
export const BulkMoveButton = ({ selected, onSuccess }) => { export const BulkMoveButton = ({ selected, onSuccess, currentFolder }) => {
const { formatMessage } = useIntl(); const { formatMessage } = useIntl();
const [showConfirmDialog, setShowConfirmDialog] = useState(false); const [showConfirmDialog, setShowConfirmDialog] = useState(false);
@ -27,12 +27,23 @@ export const BulkMoveButton = ({ selected, onSuccess }) => {
{formatMessage({ id: 'global.move', defaultMessage: 'Move' })} {formatMessage({ id: 'global.move', defaultMessage: 'Move' })}
</Button> </Button>
{showConfirmDialog && <BulkMoveDialog onClose={handleConfirmMove} selected={selected} />} {showConfirmDialog && (
<BulkMoveDialog
currentFolder={currentFolder}
onClose={handleConfirmMove}
selected={selected}
/>
)}
</> </>
); );
}; };
BulkMoveButton.propTypes = { BulkMoveButton.defaultProps = {
selected: PropTypes.arrayOf(AssetDefinition, FolderDefinition).isRequired, currentFolder: undefined,
onSuccess: PropTypes.func.isRequired, };
BulkMoveButton.propTypes = {
onSuccess: PropTypes.func.isRequired,
currentFolder: FolderDefinition,
selected: PropTypes.arrayOf(AssetDefinition, FolderDefinition).isRequired,
}; };

View File

@ -12,6 +12,20 @@ import { useBulkMove } from '../../../hooks/useBulkMove';
jest.mock('../../../hooks/useBulkMove'); jest.mock('../../../hooks/useBulkMove');
jest.mock('../../../hooks/useFolderStructure'); jest.mock('../../../hooks/useFolderStructure');
const FIXTURE_SELECTION = [
{
type: 'asset',
createdAt: '2022-06-21T07:04:49.813Z',
updatedAt: '2022-06-21T07:04:49.813Z',
pathId: 1,
path: '/1',
files: { count: 0 },
id: 1,
children: { count: 0 },
name: 'test',
},
];
const setup = ( const setup = (
props = { props = {
selected: [], selected: [],
@ -52,8 +66,6 @@ describe('BulkMoveButton', () => {
}); });
test('opens destination dialog before the API call', async () => { test('opens destination dialog before the API call', async () => {
const FIXTURE_SELECTION = [{ type: 'asset', id: 1 }];
const onSuccessSpy = jest.fn(); const onSuccessSpy = jest.fn();
const { getByText } = setup({ const { getByText } = setup({
onSuccess: onSuccessSpy, onSuccess: onSuccessSpy,
@ -81,12 +93,41 @@ describe('BulkMoveButton', () => {
fireEvent.click(submit); fireEvent.click(submit);
}); });
await waitFor(() => expect(moveSpy).toBeCalledWith(null, FIXTURE_SELECTION)); await waitFor(() => expect(moveSpy).toBeCalledWith('', FIXTURE_SELECTION));
await waitFor(() => expect(onSuccessSpy).toBeCalled()); await waitFor(() => expect(onSuccessSpy).toBeCalled());
}); });
test('set default form values', () => {
const { getByText } = setup({ onClose: jest.fn(), selected: [], onSuccess: jest.fn() });
fireEvent.click(getByText('Move'));
expect(screen.getByText('Media Library')).toBeInTheDocument();
});
test('set default form values with currentFolder', () => {
const FIXTURE_PARENT_FOLDER = {
id: 2,
name: 'default folder name',
updatedAt: '2022-06-21T15:35:36.932Z',
createdAt: '2022-06-21T07:04:49.813Z',
parent: null,
path: '/2',
pathId: 2,
};
const { getByText } = setup({
currentFolder: FIXTURE_PARENT_FOLDER,
onClose: jest.fn(),
selected: [],
onSuccess: jest.fn(),
});
fireEvent.click(getByText('Move'));
expect(screen.getByText(FIXTURE_PARENT_FOLDER.name)).toBeInTheDocument();
});
test('keeps destination dialog open if the API call errored', async () => { test('keeps destination dialog open if the API call errored', async () => {
const FIXTURE_SELECTION = [{ type: 'asset', id: 1 }];
const FIXTURE_ERROR_MESSAGE = 'Failed to move folder'; const FIXTURE_ERROR_MESSAGE = 'Failed to move folder';
const onSuccessSpy = jest.fn(); const onSuccessSpy = jest.fn();
@ -133,7 +174,7 @@ describe('BulkMoveButton', () => {
fireEvent.click(submit); fireEvent.click(submit);
}); });
await waitFor(() => expect(moveSpy).toBeCalledWith(null, FIXTURE_SELECTION)); await waitFor(() => expect(moveSpy).toBeCalledWith('', FIXTURE_SELECTION));
await waitFor(() => expect(onSuccessSpy).not.toBeCalled()); await waitFor(() => expect(onSuccessSpy).not.toBeCalled());
expect(getByText('Move elements to')).toBeInTheDocument(); expect(getByText('Move elements to')).toBeInTheDocument();

View File

@ -67,6 +67,7 @@
"modal.header.pending-assets": "Pending assets", "modal.header.pending-assets": "Pending assets",
"modal.header.select-files": "Selected files", "modal.header.select-files": "Selected files",
"modal.header.go-back": "Go back", "modal.header.go-back": "Go back",
"modal.folder.move.title": "Move elements to",
"modal.nav.browse": "browse", "modal.nav.browse": "browse",
"modal.nav.computer": "From computer", "modal.nav.computer": "From computer",
"modal.nav.selected": "selected", "modal.nav.selected": "selected",