mirror of
https://github.com/strapi/strapi.git
synced 2025-09-25 00:09:18 +00:00
Merge pull request #16802 from damuso/fix/media-library-multiple-selection
This commit is contained in:
commit
c43d25328b
@ -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 },
|
||||
];
|
||||
};
|
||||
|
@ -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]]);
|
||||
});
|
||||
});
|
||||
|
@ -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 (
|
||||
|
@ -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>
|
||||
|
@ -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) => {
|
||||
|
Loading…
x
Reference in New Issue
Block a user