Merge pull request #16802 from damuso/fix/media-library-multiple-selection

This commit is contained in:
Josh 2023-06-26 13:55:17 +01:00 committed by GitHub
commit c43d25328b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 106 additions and 17 deletions

View File

@ -34,5 +34,34 @@ export const useSelectionState = (keys, initialValue) => {
}
};
return [selections, { selectOne, selectAll, selectOnly, setSelections }];
const selectMultiple = (nextSelections) => {
setSelections((currSelections) => [
// already selected items
...currSelections,
// filter out already selected items from nextSelections
...nextSelections.filter(
(nextSelection) =>
currSelections.findIndex((currentSelection) =>
keys.every((key) => currentSelection[key] === nextSelection[key])
) === -1
),
]);
};
const deselectMultiple = (nextSelections) => {
setSelections((currSelections) => [
// filter out items in currSelections that are in nextSelections
...currSelections.filter(
(currentSelection) =>
nextSelections.findIndex((nextSelection) =>
keys.every((key) => currentSelection[key] === nextSelection[key])
) === -1
),
]);
};
return [
selections,
{ selectOne, selectAll, selectOnly, selectMultiple, deselectMultiple, setSelections },
];
};

View File

@ -127,4 +127,55 @@ describe('useSelectionState', () => {
expect(result.current[0]).toStrictEqual([FIXTURE[0]]);
});
test('selectMultiple - no previously selected + multiple keys', () => {
const { result } = setup(['id', 'name'], []);
act(() => {
result.current[1].selectMultiple(FIXTURE);
});
expect(result.current[0]).toStrictEqual(FIXTURE);
});
test('selectMultiple - already selected item + multiple keys', () => {
const alreadySelectedItem = { id: 0, name: 'already selected' };
const { result } = setup(['id', 'name'], [alreadySelectedItem]);
act(() => {
result.current[1].selectMultiple(FIXTURE);
});
expect(result.current[0]).toStrictEqual([alreadySelectedItem, ...FIXTURE]);
});
test('selectMultiple - no duplicates + multiple keys', () => {
const { result } = setup(['id', 'name'], FIXTURE);
act(() => {
result.current[1].selectMultiple(FIXTURE);
});
expect(result.current[0]).toStrictEqual(FIXTURE);
});
test('deselectMultiple - multiple keys', () => {
const { result } = setup(['id', 'name'], FIXTURE);
act(() => {
result.current[1].deselectMultiple(FIXTURE);
});
expect(result.current[0]).toStrictEqual([]);
});
test('deselectMultiple - some items to deselect + multiple keys', () => {
const { result } = setup(['id', 'name'], FIXTURE);
act(() => {
result.current[1].deselectMultiple([FIXTURE[0]]);
});
expect(result.current[0]).toStrictEqual([FIXTURE[1]]);
});
});

View File

@ -14,7 +14,7 @@ This hook is used in order to facilitate the select / partial selection of a glo
import { useSelectionState } from '@strapi/helper-plugin';
const Modal = ({ onToggle, isOpen }) => {
const [selectedAssets, { selectOne, selectAll, selectOnly, setSelections }] = useSelectionState(
const [selectedAssets, { selectOne, selectAll, selectOnly, selectMultiple, deselectMultiple, setSelections }] = useSelectionState(
['id'], // This are the comparaison attribute names
[]
);
@ -24,6 +24,8 @@ const Modal = ({ onToggle, isOpen }) => {
// selectOne({ id: 1 name: 'Hello' }) add the object to the selection list
// selectOnly({ id: 1 name: 'Hello' }) add the object to the selection list and remove every others in the list
// selectAll(assets) select all or remove all
// selectMultiple(assets) add the objects to the selection list - does not change already selected objects
// deselectMultiple(assets) remove the objects from the selection list - does not change already selected objects
// setSelections(): regular state used in react
return (

View File

@ -97,9 +97,11 @@ export const BrowseStep = ({
const allAllowedAsset = getAllowedFiles(allowedTypes, assets);
const areAllAssetSelected =
allAllowedAsset.length > 0 &&
selectedAssets.length > 0 &&
allAllowedAsset.every(
(asset) => selectedAssets.findIndex((currAsset) => currAsset.id === asset.id) !== -1
) && selectedAssets.length > 0;
);
const hasSomeAssetSelected = allAllowedAsset.some(
(asset) => selectedAssets.findIndex((currAsset) => currAsset.id === asset.id) !== -1
);
@ -290,7 +292,7 @@ export const BrowseStep = ({
<Flex as="h2" direction="column" alignItems="start" maxWidth="100%">
<TypographyMaxWidth fontWeight="semiBold" ellipsis>
{folder.name}
{/* VisuallyHidden dash here allows to separate folder title and count informations
{/* VisuallyHidden dash here allows to separate folder title and count informations
for voice reading structure purpose */}
<VisuallyHidden>-</VisuallyHidden>
</TypographyMaxWidth>

View File

@ -92,27 +92,32 @@ export const AssetDialog = ({
query: queryObject,
});
const [selectedAssets, { selectOne, selectAll, selectOnly, setSelections }] = useSelectionState(
['id'],
initiallySelectedAssets
);
const [
selectedAssets,
{ selectOne, selectOnly, setSelections, selectMultiple, deselectMultiple },
] = useSelectionState(['id'], initiallySelectedAssets);
const [initialSelectedTabIndex, setInitialSelectedTabIndex] = useState(
selectedAssets.length > 0 ? 1 : 0
);
const handleSelectAllAssets = () => {
const hasAllAssets = assets.every(
(asset) => selectedAssets.findIndex((curr) => curr.id === asset.id) !== -1
);
if (hasAllAssets) {
return multiple ? selectAll(assets) : undefined;
}
const allowedAssets = getAllowedFiles(allowedTypes, assets);
return multiple ? selectAll(allowedAssets) : undefined;
if (!multiple) {
return undefined;
}
// selected files in current folder
const alreadySelected = allowedAssets.filter(
(asset) => selectedAssets.findIndex((selectedAsset) => selectedAsset.id === asset.id) !== -1
);
if (alreadySelected.length > 0) {
deselectMultiple(alreadySelected);
} else {
selectMultiple(allowedAssets);
}
};
const handleSelectAsset = (asset) => {