@strapi/upload 5.51.2 → 5.52.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/admin/future/App.js +3 -3
- package/dist/admin/future/App.js.map +1 -1
- package/dist/admin/future/App.mjs +4 -4
- package/dist/admin/future/App.mjs.map +1 -1
- package/dist/admin/future/components/BetaNotice.js +72 -0
- package/dist/admin/future/components/BetaNotice.js.map +1 -0
- package/dist/admin/future/components/BetaNotice.mjs +70 -0
- package/dist/admin/future/components/BetaNotice.mjs.map +1 -0
- package/dist/admin/future/components/Drawer.js +16 -3
- package/dist/admin/future/components/Drawer.js.map +1 -1
- package/dist/admin/future/components/Drawer.mjs +16 -3
- package/dist/admin/future/components/Drawer.mjs.map +1 -1
- package/dist/admin/future/components/TruncatedText.js +76 -0
- package/dist/admin/future/components/TruncatedText.js.map +1 -0
- package/dist/admin/future/components/TruncatedText.mjs +74 -0
- package/dist/admin/future/components/TruncatedText.mjs.map +1 -0
- package/dist/admin/future/hooks/useAIMetadataEnabled.js +39 -0
- package/dist/admin/future/hooks/useAIMetadataEnabled.js.map +1 -0
- package/dist/admin/future/hooks/useAIMetadataEnabled.mjs +37 -0
- package/dist/admin/future/hooks/useAIMetadataEnabled.mjs.map +1 -0
- package/dist/admin/future/hooks/useTracking.js +57 -0
- package/dist/admin/future/hooks/useTracking.js.map +1 -0
- package/dist/admin/future/hooks/useTracking.mjs +53 -0
- package/dist/admin/future/hooks/useTracking.mjs.map +1 -0
- package/dist/admin/future/pages/Assets/AssetsPage.js +328 -139
- package/dist/admin/future/pages/Assets/AssetsPage.js.map +1 -1
- package/dist/admin/future/pages/Assets/AssetsPage.mjs +332 -143
- package/dist/admin/future/pages/Assets/AssetsPage.mjs.map +1 -1
- package/dist/admin/future/pages/Assets/components/ActionsMenuContent.js +46 -0
- package/dist/admin/future/pages/Assets/components/ActionsMenuContent.js.map +1 -0
- package/dist/admin/future/pages/Assets/components/ActionsMenuContent.mjs +44 -0
- package/dist/admin/future/pages/Assets/components/ActionsMenuContent.mjs.map +1 -0
- package/dist/admin/future/pages/Assets/components/AssetActionsMenu.js +328 -0
- package/dist/admin/future/pages/Assets/components/AssetActionsMenu.js.map +1 -0
- package/dist/admin/future/pages/Assets/components/AssetActionsMenu.mjs +326 -0
- package/dist/admin/future/pages/Assets/components/AssetActionsMenu.mjs.map +1 -0
- package/dist/admin/future/pages/Assets/components/AssetDetails/AssetCropEditor.js +35 -14
- package/dist/admin/future/pages/Assets/components/AssetDetails/AssetCropEditor.js.map +1 -1
- package/dist/admin/future/pages/Assets/components/AssetDetails/AssetCropEditor.mjs +35 -14
- package/dist/admin/future/pages/Assets/components/AssetDetails/AssetCropEditor.mjs.map +1 -1
- package/dist/admin/future/pages/Assets/components/AssetDetails/AssetDetailsDrawer.js +74 -53
- package/dist/admin/future/pages/Assets/components/AssetDetails/AssetDetailsDrawer.js.map +1 -1
- package/dist/admin/future/pages/Assets/components/AssetDetails/AssetDetailsDrawer.mjs +74 -54
- package/dist/admin/future/pages/Assets/components/AssetDetails/AssetDetailsDrawer.mjs.map +1 -1
- package/dist/admin/future/pages/Assets/components/AssetsGrid.js +92 -28
- package/dist/admin/future/pages/Assets/components/AssetsGrid.js.map +1 -1
- package/dist/admin/future/pages/Assets/components/AssetsGrid.mjs +94 -30
- package/dist/admin/future/pages/Assets/components/AssetsGrid.mjs.map +1 -1
- package/dist/admin/future/pages/Assets/components/AssetsSearchInput.js +26 -4
- package/dist/admin/future/pages/Assets/components/AssetsSearchInput.js.map +1 -1
- package/dist/admin/future/pages/Assets/components/AssetsSearchInput.mjs +27 -5
- package/dist/admin/future/pages/Assets/components/AssetsSearchInput.mjs.map +1 -1
- package/dist/admin/future/pages/Assets/components/AssetsTable.js +172 -60
- package/dist/admin/future/pages/Assets/components/AssetsTable.js.map +1 -1
- package/dist/admin/future/pages/Assets/components/AssetsTable.mjs +175 -63
- package/dist/admin/future/pages/Assets/components/AssetsTable.mjs.map +1 -1
- package/dist/admin/future/pages/Assets/components/BulkActionsBar.js +64 -132
- package/dist/admin/future/pages/Assets/components/BulkActionsBar.js.map +1 -1
- package/dist/admin/future/pages/Assets/components/BulkActionsBar.mjs +64 -132
- package/dist/admin/future/pages/Assets/components/BulkActionsBar.mjs.map +1 -1
- package/dist/admin/future/pages/Assets/components/BulkMoveDialog.js +123 -76
- package/dist/admin/future/pages/Assets/components/BulkMoveDialog.js.map +1 -1
- package/dist/admin/future/pages/Assets/components/BulkMoveDialog.mjs +126 -79
- package/dist/admin/future/pages/Assets/components/BulkMoveDialog.mjs.map +1 -1
- package/dist/admin/future/pages/Assets/components/BusyOverlay.js +36 -0
- package/dist/admin/future/pages/Assets/components/BusyOverlay.js.map +1 -0
- package/dist/admin/future/pages/Assets/components/BusyOverlay.mjs +34 -0
- package/dist/admin/future/pages/Assets/components/BusyOverlay.mjs.map +1 -0
- package/dist/admin/future/pages/Assets/components/DeleteItemsDialog.js +131 -0
- package/dist/admin/future/pages/Assets/components/DeleteItemsDialog.js.map +1 -0
- package/dist/admin/future/pages/Assets/components/DeleteItemsDialog.mjs +129 -0
- package/dist/admin/future/pages/Assets/components/DeleteItemsDialog.mjs.map +1 -0
- package/dist/admin/future/pages/Assets/components/Dnd/AssetsDndProvider.js +27 -17
- package/dist/admin/future/pages/Assets/components/Dnd/AssetsDndProvider.js.map +1 -1
- package/dist/admin/future/pages/Assets/components/Dnd/AssetsDndProvider.mjs +28 -18
- package/dist/admin/future/pages/Assets/components/Dnd/AssetsDndProvider.mjs.map +1 -1
- package/dist/admin/future/pages/Assets/components/Dnd/buildDragSet.js +28 -31
- package/dist/admin/future/pages/Assets/components/Dnd/buildDragSet.js.map +1 -1
- package/dist/admin/future/pages/Assets/components/Dnd/buildDragSet.mjs +28 -31
- package/dist/admin/future/pages/Assets/components/Dnd/buildDragSet.mjs.map +1 -1
- package/dist/admin/future/pages/Assets/components/Dnd/useAssetDnd.js +10 -15
- package/dist/admin/future/pages/Assets/components/Dnd/useAssetDnd.js.map +1 -1
- package/dist/admin/future/pages/Assets/components/Dnd/useAssetDnd.mjs +10 -15
- package/dist/admin/future/pages/Assets/components/Dnd/useAssetDnd.mjs.map +1 -1
- package/dist/admin/future/pages/Assets/components/FilterBadges.js +13 -4
- package/dist/admin/future/pages/Assets/components/FilterBadges.js.map +1 -1
- package/dist/admin/future/pages/Assets/components/FilterBadges.mjs +13 -4
- package/dist/admin/future/pages/Assets/components/FilterBadges.mjs.map +1 -1
- package/dist/admin/future/pages/Assets/components/FilterMenu.js +259 -63
- package/dist/admin/future/pages/Assets/components/FilterMenu.js.map +1 -1
- package/dist/admin/future/pages/Assets/components/FilterMenu.mjs +262 -66
- package/dist/admin/future/pages/Assets/components/FilterMenu.mjs.map +1 -1
- package/dist/admin/future/pages/Assets/components/FolderActionsMenu.js +146 -0
- package/dist/admin/future/pages/Assets/components/FolderActionsMenu.js.map +1 -0
- package/dist/admin/future/pages/Assets/components/FolderActionsMenu.mjs +144 -0
- package/dist/admin/future/pages/Assets/components/FolderActionsMenu.mjs.map +1 -0
- package/dist/admin/future/pages/Assets/components/{CreateFolderDialog.js → FolderFormDialog.js} +62 -16
- package/dist/admin/future/pages/Assets/components/FolderFormDialog.js.map +1 -0
- package/dist/admin/future/pages/Assets/components/{CreateFolderDialog.mjs → FolderFormDialog.mjs} +64 -18
- package/dist/admin/future/pages/Assets/components/FolderFormDialog.mjs.map +1 -0
- package/dist/admin/future/pages/Assets/components/FolderTree/FolderTree.js +132 -229
- package/dist/admin/future/pages/Assets/components/FolderTree/FolderTree.js.map +1 -1
- package/dist/admin/future/pages/Assets/components/FolderTree/FolderTree.mjs +135 -232
- package/dist/admin/future/pages/Assets/components/FolderTree/FolderTree.mjs.map +1 -1
- package/dist/admin/future/pages/Assets/components/SortMenu.js +14 -0
- package/dist/admin/future/pages/Assets/components/SortMenu.js.map +1 -1
- package/dist/admin/future/pages/Assets/components/SortMenu.mjs +14 -0
- package/dist/admin/future/pages/Assets/components/SortMenu.mjs.map +1 -1
- package/dist/admin/future/pages/Assets/hooks/useAssetSelection.js +5 -0
- package/dist/admin/future/pages/Assets/hooks/useAssetSelection.js.map +1 -1
- package/dist/admin/future/pages/Assets/hooks/useAssetSelection.mjs +6 -1
- package/dist/admin/future/pages/Assets/hooks/useAssetSelection.mjs.map +1 -1
- package/dist/admin/future/pages/Assets/hooks/useBusyAssets.js +47 -0
- package/dist/admin/future/pages/Assets/hooks/useBusyAssets.js.map +1 -0
- package/dist/admin/future/pages/Assets/hooks/useBusyAssets.mjs +44 -0
- package/dist/admin/future/pages/Assets/hooks/useBusyAssets.mjs.map +1 -0
- package/dist/admin/future/pages/Assets/hooks/useInfiniteAssets.js +203 -62
- package/dist/admin/future/pages/Assets/hooks/useInfiniteAssets.js.map +1 -1
- package/dist/admin/future/pages/Assets/hooks/useInfiniteAssets.mjs +204 -63
- package/dist/admin/future/pages/Assets/hooks/useInfiniteAssets.mjs.map +1 -1
- package/dist/admin/future/pages/Assets/hooks/useInfiniteScrollSentinel.js +75 -0
- package/dist/admin/future/pages/Assets/hooks/useInfiniteScrollSentinel.js.map +1 -0
- package/dist/admin/future/pages/Assets/hooks/useInfiniteScrollSentinel.mjs +73 -0
- package/dist/admin/future/pages/Assets/hooks/useInfiniteScrollSentinel.mjs.map +1 -0
- package/dist/admin/future/pages/Assets/utils/selection.js +17 -0
- package/dist/admin/future/pages/Assets/utils/selection.js.map +1 -1
- package/dist/admin/future/pages/Assets/utils/selection.mjs +17 -1
- package/dist/admin/future/pages/Assets/utils/selection.mjs.map +1 -1
- package/dist/admin/future/services/api.js +31 -8
- package/dist/admin/future/services/api.js.map +1 -1
- package/dist/admin/future/services/api.mjs +31 -8
- package/dist/admin/future/services/api.mjs.map +1 -1
- package/dist/admin/future/services/assets.js +22 -23
- package/dist/admin/future/services/assets.js.map +1 -1
- package/dist/admin/future/services/assets.mjs +22 -23
- package/dist/admin/future/services/assets.mjs.map +1 -1
- package/dist/admin/future/services/folders.js +37 -2
- package/dist/admin/future/services/folders.js.map +1 -1
- package/dist/admin/future/services/folders.mjs +37 -3
- package/dist/admin/future/services/folders.mjs.map +1 -1
- package/dist/admin/future/utils/buildDragSetFromSelection.js +7 -5
- package/dist/admin/future/utils/buildDragSetFromSelection.js.map +1 -1
- package/dist/admin/future/utils/buildDragSetFromSelection.mjs +7 -5
- package/dist/admin/future/utils/buildDragSetFromSelection.mjs.map +1 -1
- package/dist/admin/future/utils/formatMoveSuccessMessage.js +12 -1
- package/dist/admin/future/utils/formatMoveSuccessMessage.js.map +1 -1
- package/dist/admin/future/utils/formatMoveSuccessMessage.mjs +12 -1
- package/dist/admin/future/utils/formatMoveSuccessMessage.mjs.map +1 -1
- package/dist/admin/future/utils/getRelationId.js +24 -0
- package/dist/admin/future/utils/getRelationId.js.map +1 -0
- package/dist/admin/future/utils/getRelationId.mjs +22 -0
- package/dist/admin/future/utils/getRelationId.mjs.map +1 -0
- package/dist/admin/future/utils/isEventFromWithin.js +14 -0
- package/dist/admin/future/utils/isEventFromWithin.js.map +1 -0
- package/dist/admin/future/utils/isEventFromWithin.mjs +12 -0
- package/dist/admin/future/utils/isEventFromWithin.mjs.map +1 -0
- package/dist/admin/future/utils/itemLocations.js +40 -0
- package/dist/admin/future/utils/itemLocations.js.map +1 -0
- package/dist/admin/future/utils/itemLocations.mjs +36 -0
- package/dist/admin/future/utils/itemLocations.mjs.map +1 -0
- package/dist/admin/future/utils/itemSource.js +36 -0
- package/dist/admin/future/utils/itemSource.js.map +1 -0
- package/dist/admin/future/utils/itemSource.mjs +32 -0
- package/dist/admin/future/utils/itemSource.mjs.map +1 -0
- package/dist/admin/hooks/useAIMetadataJob.js +1 -1
- package/dist/admin/hooks/useAIMetadataJob.js.map +1 -1
- package/dist/admin/hooks/useAIMetadataJob.mjs +1 -1
- package/dist/admin/hooks/useAIMetadataJob.mjs.map +1 -1
- package/dist/admin/index.js +11 -17
- package/dist/admin/index.js.map +1 -1
- package/dist/admin/index.mjs +12 -18
- package/dist/admin/index.mjs.map +1 -1
- package/dist/admin/pages/SettingsPage/SettingsPage.js +2 -2
- package/dist/admin/pages/SettingsPage/SettingsPage.js.map +1 -1
- package/dist/admin/pages/SettingsPage/SettingsPage.mjs +2 -2
- package/dist/admin/pages/SettingsPage/SettingsPage.mjs.map +1 -1
- package/dist/admin/src/future/App.d.ts +1 -1
- package/dist/admin/src/future/components/BetaNotice.d.ts +11 -0
- package/dist/admin/src/future/components/Drawer.d.ts +5 -1
- package/dist/admin/src/future/components/TruncatedText.d.ts +32 -0
- package/dist/admin/src/future/hooks/useAIMetadataEnabled.d.ts +26 -0
- package/dist/admin/src/future/hooks/useTracking.d.ts +29 -0
- package/dist/admin/src/future/pages/Assets/components/ActionsMenuContent.d.ts +33 -0
- package/dist/admin/src/future/pages/Assets/components/AssetActionsMenu.d.ts +26 -0
- package/dist/admin/src/future/pages/Assets/components/AssetDetails/AssetDetailsDrawer.d.ts +16 -0
- package/dist/admin/src/future/pages/Assets/components/BulkActionsBar.d.ts +8 -1
- package/dist/admin/src/future/pages/Assets/components/BulkMoveDialog.d.ts +17 -6
- package/dist/admin/src/future/pages/Assets/components/BusyOverlay.d.ts +9 -0
- package/dist/admin/src/future/pages/Assets/components/DeleteItemsDialog.d.ts +27 -0
- package/dist/admin/src/future/pages/Assets/components/Dnd/AssetsDndProvider.d.ts +8 -1
- package/dist/admin/src/future/pages/Assets/components/Dnd/buildDragSet.d.ts +18 -3
- package/dist/admin/src/future/pages/Assets/components/Dnd/useAssetDnd.d.ts +2 -1
- package/dist/admin/src/future/pages/Assets/components/FilterBadges.d.ts +3 -1
- package/dist/admin/src/future/pages/Assets/components/FilterMenu.d.ts +4 -0
- package/dist/admin/src/future/pages/Assets/components/FolderActionsMenu.d.ts +21 -0
- package/dist/admin/src/future/pages/Assets/components/FolderFormDialog.d.ts +16 -0
- package/dist/admin/src/future/pages/Assets/hooks/useAssetSelection.d.ts +2 -0
- package/dist/admin/src/future/pages/Assets/hooks/useBusyAssets.d.ts +38 -0
- package/dist/admin/src/future/pages/Assets/hooks/useInfiniteAssets.d.ts +20 -6
- package/dist/admin/src/future/pages/Assets/hooks/useInfiniteScrollSentinel.d.ts +41 -0
- package/dist/admin/src/future/pages/Assets/utils/selection.d.ts +10 -0
- package/dist/admin/src/future/services/api.d.ts +6 -7
- package/dist/admin/src/future/services/folders.d.ts +6 -1
- package/dist/admin/src/future/utils/buildDragSetFromSelection.d.ts +4 -3
- package/dist/admin/src/future/utils/formatMoveSuccessMessage.d.ts +7 -1
- package/dist/admin/src/future/utils/getRelationId.d.ts +11 -0
- package/dist/admin/src/future/utils/isEventFromWithin.d.ts +11 -0
- package/dist/admin/src/future/utils/itemLocations.d.ts +31 -0
- package/dist/admin/src/future/utils/itemSource.d.ts +22 -0
- package/dist/admin/translations/en.json.js +25 -4
- package/dist/admin/translations/en.json.js.map +1 -1
- package/dist/admin/translations/en.json.mjs +25 -4
- package/dist/admin/translations/en.json.mjs.map +1 -1
- package/dist/server/controllers/admin-file.js +27 -9
- package/dist/server/controllers/admin-file.js.map +1 -1
- package/dist/server/controllers/admin-file.mjs +27 -9
- package/dist/server/controllers/admin-file.mjs.map +1 -1
- package/dist/server/controllers/admin-upload.js +24 -8
- package/dist/server/controllers/admin-upload.js.map +1 -1
- package/dist/server/controllers/admin-upload.mjs +24 -8
- package/dist/server/controllers/admin-upload.mjs.map +1 -1
- package/dist/server/routes/admin.js +41 -21
- package/dist/server/routes/admin.js.map +1 -1
- package/dist/server/routes/admin.mjs +41 -21
- package/dist/server/routes/admin.mjs.map +1 -1
- package/dist/server/services/ai-metadata.js.map +1 -1
- package/dist/server/services/ai-metadata.mjs.map +1 -1
- package/dist/server/services/image-manipulation.js.map +1 -1
- package/dist/server/services/image-manipulation.mjs.map +1 -1
- package/dist/server/src/controllers/admin-file.d.ts +29 -8
- package/dist/server/src/controllers/admin-file.d.ts.map +1 -1
- package/dist/server/src/controllers/admin-upload.d.ts +20 -4
- package/dist/server/src/controllers/admin-upload.d.ts.map +1 -1
- package/dist/server/src/controllers/index.d.ts +4 -4
- package/dist/server/src/index.d.ts +4 -4
- package/dist/server/src/routes/admin.d.ts.map +1 -1
- package/dist/server/src/services/ai-metadata.d.ts +2 -2
- package/dist/server/src/services/ai-metadata.d.ts.map +1 -1
- package/dist/server/src/services/image-manipulation.d.ts +0 -5
- package/dist/server/src/services/image-manipulation.d.ts.map +1 -1
- package/dist/shared/contracts/ai-metadata-jobs.d.ts +10 -32
- package/dist/shared/contracts/ai-metadata-jobs.d.ts.map +1 -1
- package/dist/shared/contracts/files.d.ts +10 -10
- package/dist/shared/contracts/files.d.ts.map +1 -1
- package/package.json +9 -9
- package/dist/admin/future/pages/Assets/components/CreateFolderDialog.js.map +0 -1
- package/dist/admin/future/pages/Assets/components/CreateFolderDialog.mjs.map +0 -1
- package/dist/admin/future/pages/Assets/components/FolderTree/filterFolderTree.js +0 -33
- package/dist/admin/future/pages/Assets/components/FolderTree/filterFolderTree.js.map +0 -1
- package/dist/admin/future/pages/Assets/components/FolderTree/filterFolderTree.mjs +0 -31
- package/dist/admin/future/pages/Assets/components/FolderTree/filterFolderTree.mjs.map +0 -1
- package/dist/admin/src/future/pages/Assets/components/CreateFolderDialog.d.ts +0 -8
- package/dist/admin/src/future/pages/Assets/components/FolderTree/filterFolderTree.d.ts +0 -16
|
@@ -7,93 +7,115 @@ var designSystem = require('@strapi/design-system');
|
|
|
7
7
|
var reactIntl = require('react-intl');
|
|
8
8
|
var styledComponents = require('styled-components');
|
|
9
9
|
var folders = require('../../../services/folders.js');
|
|
10
|
-
var buildDragSetFromSelection = require('../../../utils/buildDragSetFromSelection.js');
|
|
11
10
|
var canDropItemOnFolder = require('../../../utils/canDropItemOnFolder.js');
|
|
12
11
|
var flattenFolderStructure = require('../../../utils/flattenFolderStructure.js');
|
|
12
|
+
var formatMoveSuccessMessage = require('../../../utils/formatMoveSuccessMessage.js');
|
|
13
13
|
var getBulkMoveErrorMessage = require('../../../utils/getBulkMoveErrorMessage.js');
|
|
14
|
+
var itemSource = require('../../../utils/itemSource.js');
|
|
14
15
|
var translations = require('../../../utils/translations.js');
|
|
15
|
-
var useAssetSelection = require('../hooks/useAssetSelection.js');
|
|
16
|
-
var useFolderNavigation = require('../hooks/useFolderNavigation.js');
|
|
17
16
|
|
|
18
17
|
const StyledModalContent = styledComponents.styled(designSystem.Modal.Content)`
|
|
19
18
|
max-width: 51.6rem;
|
|
20
19
|
`;
|
|
21
20
|
/**
|
|
22
|
-
* "Move elements to" modal
|
|
23
|
-
*
|
|
24
|
-
*
|
|
25
|
-
* folder
|
|
26
|
-
*
|
|
27
|
-
|
|
21
|
+
* "Move elements to" modal. Moves the given items (assets and/or folders) into
|
|
22
|
+
* the picked destination folder via `POST /upload/actions/bulk-move`. The
|
|
23
|
+
* mutation invalidates the asset list, folder list and the sidebar
|
|
24
|
+
* folder-structure, so both panes refresh on success. On failure the modal stays
|
|
25
|
+
* open so the user can retry or cancel.
|
|
26
|
+
*
|
|
27
|
+
* Used both by the bulk actions bar (the whole selection) and by a folder's
|
|
28
|
+
* actions menu (that one folder).
|
|
29
|
+
*/ const BulkMoveDialog = ({ open, onClose, items, onSuccess })=>{
|
|
28
30
|
const { formatMessage } = reactIntl.useIntl();
|
|
29
31
|
const { toggleNotification } = strapiAdmin.useNotification();
|
|
30
|
-
const {
|
|
31
|
-
const { currentFolderId } = useFolderNavigation.useFolderNavigation();
|
|
32
|
-
const { data: folderStructure = [] } = folders.useGetFolderStructureQuery(undefined, {
|
|
32
|
+
const { data: folderStructure = [], isUninitialized: isStructureUninitialized, isLoading: isLoadingStructure, isError: isStructureError } = folders.useGetFolderStructureQuery(undefined, {
|
|
33
33
|
skip: !open
|
|
34
34
|
});
|
|
35
|
-
const {
|
|
36
|
-
|
|
35
|
+
const [bulkMove, { isLoading: isMoving }] = folders.useBulkMoveMutation();
|
|
36
|
+
const fileIds = React.useMemo(()=>items.filter((item)=>item.kind === 'file').map((item)=>item.id), [
|
|
37
|
+
items
|
|
38
|
+
]);
|
|
39
|
+
const folderIds = React.useMemo(()=>items.filter((item)=>item.kind === 'folder').map((item)=>item.id), [
|
|
40
|
+
items
|
|
41
|
+
]);
|
|
42
|
+
// A selection made under a global search can span folders, so the source is
|
|
43
|
+
// nameable only when every item agrees on it — `null` otherwise, and the toast
|
|
44
|
+
// then omits the source rather than crediting one item's folder to all of them.
|
|
45
|
+
// The bar can also hand over an empty set, which is likewise unnameable.
|
|
46
|
+
const isSourceUniform = itemSource.hasUniformSource(items);
|
|
47
|
+
const sourceFolderId = itemSource.uniformSourceFolderId(items);
|
|
48
|
+
const { data: sourceFolder } = folders.useGetFolderQuery({
|
|
49
|
+
id: sourceFolderId
|
|
37
50
|
}, {
|
|
38
|
-
skip:
|
|
51
|
+
skip: sourceFolderId === null
|
|
39
52
|
});
|
|
40
|
-
const [bulkMove, { isLoading: isMoving }] = folders.useBulkMoveMutation();
|
|
41
53
|
// '' is the DOM-only sentinel for the Media Library root (null everywhere else).
|
|
42
54
|
const [destination, setDestination] = React.useState('');
|
|
43
|
-
React.useEffect(()=>{
|
|
44
|
-
if (open) {
|
|
45
|
-
setDestination('');
|
|
46
|
-
}
|
|
47
|
-
}, [
|
|
48
|
-
open
|
|
49
|
-
]);
|
|
50
55
|
const rootLabel = formatMessage({
|
|
51
56
|
id: translations.getTranslationKey('plugin.name'),
|
|
52
57
|
defaultMessage: 'Media Library'
|
|
53
58
|
});
|
|
54
|
-
// Reconstruct the selection as a drag set so the dialog validates destinations
|
|
55
|
-
// through the exact same canonical predicate as the DnD highlight.
|
|
56
|
-
const dragSet = React.useMemo(()=>buildDragSetFromSelection.buildDragSetFromSelection(selectedIds, selectedFolderIds, currentFolderId), [
|
|
57
|
-
selectedIds,
|
|
58
|
-
selectedFolderIds,
|
|
59
|
-
currentFolderId
|
|
60
|
-
]);
|
|
61
59
|
// Options carry the full ancestry ("About / Images" vs "Tech / Images") so
|
|
62
60
|
// same-named folders stay distinguishable, listed depth-first under their
|
|
63
|
-
// parent.
|
|
61
|
+
// parent. The moved folders and their descendants are pruned during the same
|
|
64
62
|
// single walk — an item can't be moved into itself or below itself (the
|
|
65
|
-
// server would reject it). The
|
|
66
|
-
//
|
|
67
|
-
//
|
|
68
|
-
const destinationOptions = React.useMemo(()=>flattenFolderStructure.flattenFolderStructure(folderStructure,
|
|
69
|
-
items
|
|
63
|
+
// server would reject it). The folder the items already live in is filtered
|
|
64
|
+
// out too via `canDropItemOnFolder`, so we never offer a no-op move.
|
|
65
|
+
// Memoized: large libraries shouldn't re-walk the tree on every render.
|
|
66
|
+
const destinationOptions = React.useMemo(()=>flattenFolderStructure.flattenFolderStructure(folderStructure, new Set(folderIds)).filter((option)=>canDropItemOnFolder.canDropItemOnFolder({
|
|
67
|
+
items,
|
|
70
68
|
targetFolderId: option.id,
|
|
71
69
|
folderStructure
|
|
72
70
|
})), [
|
|
73
71
|
folderStructure,
|
|
74
|
-
|
|
75
|
-
|
|
72
|
+
folderIds,
|
|
73
|
+
items
|
|
76
74
|
]);
|
|
77
75
|
// Hide the root option when the items already live at root — dropping there
|
|
78
76
|
// would be a no-op. Uses the same predicate as the DnD highlight.
|
|
79
77
|
const canMoveToRoot = React.useMemo(()=>canDropItemOnFolder.canDropItemOnFolder({
|
|
80
|
-
items
|
|
78
|
+
items,
|
|
81
79
|
targetFolderId: null,
|
|
82
80
|
folderStructure
|
|
83
81
|
}), [
|
|
84
|
-
|
|
82
|
+
items,
|
|
85
83
|
folderStructure
|
|
86
84
|
]);
|
|
87
|
-
|
|
85
|
+
// The default has to be an option that is actually rendered, or the select
|
|
86
|
+
// shows blank: root is absent when the items already live there, and the
|
|
87
|
+
// folder options only exist once the structure query has resolved.
|
|
88
|
+
const defaultDestination = canMoveToRoot ? '' : destinationOptions[0]?.id.toString() ?? '';
|
|
89
|
+
// Re-derived rather than only reset on open, because the options arrive after
|
|
90
|
+
// the first render. It is a primitive, so a background refetch that produces
|
|
91
|
+
// the same default won't discard a destination the user already picked.
|
|
92
|
+
React.useEffect(()=>{
|
|
93
|
+
setDestination(defaultDestination);
|
|
94
|
+
}, [
|
|
95
|
+
open,
|
|
96
|
+
defaultDestination
|
|
97
|
+
]);
|
|
98
|
+
// Until the structure resolves there are no options, so the default falls
|
|
99
|
+
// back to root ('') — which for a root-level item is the no-op destination
|
|
100
|
+
// that was deliberately filtered out. Nothing may be submitted before this.
|
|
101
|
+
const isStructureReady = !isStructureUninitialized && !isLoadingStructure && !isStructureError;
|
|
102
|
+
// Moving a single folder that already sits next to every other folder leaves
|
|
103
|
+
// nowhere to go; say so instead of showing an empty select. Only once the
|
|
104
|
+
// structure has arrived — an in-flight or failed fetch also has no options,
|
|
105
|
+
// and a failure is a different story to tell.
|
|
106
|
+
const hasNoDestination = isStructureReady && destinationOptions.length === 0 && !canMoveToRoot;
|
|
107
|
+
const count = items.length;
|
|
88
108
|
const handleMove = async ()=>{
|
|
89
|
-
|
|
109
|
+
// The button is disabled in both cases; the dialog can also be submitted
|
|
110
|
+
// from the keyboard, so guard here too.
|
|
111
|
+
if (isMoving || !isStructureReady) {
|
|
90
112
|
return;
|
|
91
113
|
}
|
|
92
114
|
const destinationFolderId = destination === '' ? null : Number(destination);
|
|
93
115
|
try {
|
|
94
116
|
await bulkMove({
|
|
95
|
-
fileIds
|
|
96
|
-
folderIds
|
|
117
|
+
fileIds,
|
|
118
|
+
folderIds,
|
|
97
119
|
destinationFolderId
|
|
98
120
|
}).unwrap();
|
|
99
121
|
} catch (error) {
|
|
@@ -110,22 +132,71 @@ const StyledModalContent = styledComponents.styled(designSystem.Modal.Content)`
|
|
|
110
132
|
});
|
|
111
133
|
return;
|
|
112
134
|
}
|
|
113
|
-
|
|
135
|
+
// A uniform source with a `null` id is the Media Library root — a real name.
|
|
136
|
+
// Only a set that genuinely spans folders has no source to report.
|
|
137
|
+
const sourceName = !isSourceUniform ? null : sourceFolderId === null ? rootLabel : sourceFolder?.name ?? rootLabel;
|
|
114
138
|
const destinationName = destinationFolderId === null ? rootLabel : destinationOptions.find((option)=>option.id === destinationFolderId)?.label ?? rootLabel;
|
|
115
139
|
toggleNotification({
|
|
116
140
|
type: 'success',
|
|
117
|
-
message:
|
|
118
|
-
|
|
119
|
-
defaultMessage: '{count, plural, =1 {# element has} other {# elements have}} been moved from {source} to {destination}'
|
|
120
|
-
}, {
|
|
141
|
+
message: formatMoveSuccessMessage.formatMoveSuccessMessage({
|
|
142
|
+
formatMessage,
|
|
121
143
|
count,
|
|
122
144
|
source: sourceName,
|
|
123
145
|
destination: destinationName
|
|
124
146
|
})
|
|
125
147
|
});
|
|
126
|
-
|
|
148
|
+
onSuccess?.();
|
|
127
149
|
onClose();
|
|
128
150
|
};
|
|
151
|
+
// Three states: a failed structure request, a genuine dead end, and the
|
|
152
|
+
// select — which also covers the loading window, so the hint and the error
|
|
153
|
+
// don't flash in ahead of the options.
|
|
154
|
+
const renderBody = ()=>{
|
|
155
|
+
if (isStructureError) {
|
|
156
|
+
return /*#__PURE__*/ jsxRuntime.jsx(designSystem.Typography, {
|
|
157
|
+
textColor: "danger600",
|
|
158
|
+
children: formatMessage({
|
|
159
|
+
id: translations.getTranslationKey('list.bulk-actions.move.load-error'),
|
|
160
|
+
defaultMessage: "Couldn't load the folder list. Please try again."
|
|
161
|
+
})
|
|
162
|
+
});
|
|
163
|
+
}
|
|
164
|
+
if (hasNoDestination) {
|
|
165
|
+
return /*#__PURE__*/ jsxRuntime.jsx(designSystem.Typography, {
|
|
166
|
+
textColor: "neutral600",
|
|
167
|
+
children: formatMessage({
|
|
168
|
+
id: translations.getTranslationKey('list.bulk-actions.move.no-destination'),
|
|
169
|
+
defaultMessage: 'There is no other folder to move this to.'
|
|
170
|
+
})
|
|
171
|
+
});
|
|
172
|
+
}
|
|
173
|
+
return /*#__PURE__*/ jsxRuntime.jsxs(designSystem.Field.Root, {
|
|
174
|
+
name: "destination",
|
|
175
|
+
children: [
|
|
176
|
+
/*#__PURE__*/ jsxRuntime.jsx(designSystem.Field.Label, {
|
|
177
|
+
children: formatMessage({
|
|
178
|
+
id: translations.getTranslationKey('list.bulk-actions.move.location'),
|
|
179
|
+
defaultMessage: 'Location'
|
|
180
|
+
})
|
|
181
|
+
}),
|
|
182
|
+
/*#__PURE__*/ jsxRuntime.jsxs(designSystem.SingleSelect, {
|
|
183
|
+
value: destination,
|
|
184
|
+
onChange: (value)=>setDestination(String(value)),
|
|
185
|
+
disabled: isMoving || !isStructureReady,
|
|
186
|
+
children: [
|
|
187
|
+
canMoveToRoot && /*#__PURE__*/ jsxRuntime.jsx(designSystem.SingleSelectOption, {
|
|
188
|
+
value: "",
|
|
189
|
+
children: rootLabel
|
|
190
|
+
}),
|
|
191
|
+
destinationOptions.map((option)=>/*#__PURE__*/ jsxRuntime.jsx(designSystem.SingleSelectOption, {
|
|
192
|
+
value: String(option.id),
|
|
193
|
+
children: option.label
|
|
194
|
+
}, option.id))
|
|
195
|
+
]
|
|
196
|
+
})
|
|
197
|
+
]
|
|
198
|
+
});
|
|
199
|
+
};
|
|
129
200
|
return /*#__PURE__*/ jsxRuntime.jsx(designSystem.Modal.Root, {
|
|
130
201
|
open: open,
|
|
131
202
|
onOpenChange: (nextOpen)=>{
|
|
@@ -146,32 +217,7 @@ const StyledModalContent = styledComponents.styled(designSystem.Modal.Content)`
|
|
|
146
217
|
})
|
|
147
218
|
}),
|
|
148
219
|
/*#__PURE__*/ jsxRuntime.jsx(designSystem.Modal.Body, {
|
|
149
|
-
children:
|
|
150
|
-
name: "destination",
|
|
151
|
-
children: [
|
|
152
|
-
/*#__PURE__*/ jsxRuntime.jsx(designSystem.Field.Label, {
|
|
153
|
-
children: formatMessage({
|
|
154
|
-
id: translations.getTranslationKey('list.bulk-actions.move.location'),
|
|
155
|
-
defaultMessage: 'Location'
|
|
156
|
-
})
|
|
157
|
-
}),
|
|
158
|
-
/*#__PURE__*/ jsxRuntime.jsxs(designSystem.SingleSelect, {
|
|
159
|
-
value: destination,
|
|
160
|
-
onChange: (value)=>setDestination(String(value)),
|
|
161
|
-
disabled: isMoving,
|
|
162
|
-
children: [
|
|
163
|
-
canMoveToRoot && /*#__PURE__*/ jsxRuntime.jsx(designSystem.SingleSelectOption, {
|
|
164
|
-
value: "",
|
|
165
|
-
children: rootLabel
|
|
166
|
-
}),
|
|
167
|
-
destinationOptions.map((option)=>/*#__PURE__*/ jsxRuntime.jsx(designSystem.SingleSelectOption, {
|
|
168
|
-
value: String(option.id),
|
|
169
|
-
children: option.label
|
|
170
|
-
}, option.id))
|
|
171
|
-
]
|
|
172
|
-
})
|
|
173
|
-
]
|
|
174
|
-
})
|
|
220
|
+
children: renderBody()
|
|
175
221
|
}),
|
|
176
222
|
/*#__PURE__*/ jsxRuntime.jsx(designSystem.Modal.Footer, {
|
|
177
223
|
children: /*#__PURE__*/ jsxRuntime.jsxs(designSystem.Flex, {
|
|
@@ -192,6 +238,7 @@ const StyledModalContent = styledComponents.styled(designSystem.Modal.Content)`
|
|
|
192
238
|
/*#__PURE__*/ jsxRuntime.jsx(designSystem.Button, {
|
|
193
239
|
onClick: handleMove,
|
|
194
240
|
loading: isMoving,
|
|
241
|
+
disabled: !isStructureReady || hasNoDestination,
|
|
195
242
|
children: formatMessage({
|
|
196
243
|
id: translations.getTranslationKey('list.bulk-actions.move.submit'),
|
|
197
244
|
defaultMessage: 'Move'
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"BulkMoveDialog.js","sources":["../../../../../../admin/src/future/pages/Assets/components/BulkMoveDialog.tsx"],"sourcesContent":["import { useEffect, useMemo, useState } from 'react';\n\nimport { useNotification } from '@strapi/admin/strapi-admin';\nimport {\n Button,\n Field,\n Flex,\n Modal,\n SingleSelect,\n SingleSelectOption,\n} from '@strapi/design-system';\nimport { useIntl } from 'react-intl';\nimport { styled } from 'styled-components';\n\nimport {\n useBulkMoveMutation,\n useGetFolderQuery,\n useGetFolderStructureQuery,\n} from '../../../services/folders';\nimport { buildDragSetFromSelection } from '../../../utils/buildDragSetFromSelection';\nimport { canDropItemOnFolder } from '../../../utils/canDropItemOnFolder';\nimport { flattenFolderStructure } from '../../../utils/flattenFolderStructure';\nimport { getBulkMoveErrorMessage } from '../../../utils/getBulkMoveErrorMessage';\nimport { getTranslationKey } from '../../../utils/translations';\nimport { useAssetSelection } from '../hooks/useAssetSelection';\nimport { useFolderNavigation } from '../hooks/useFolderNavigation';\n\nconst StyledModalContent = styled(Modal.Content)`\n max-width: 51.6rem;\n`;\n\ninterface BulkMoveDialogProps {\n open: boolean;\n onClose: () => void;\n}\n\n/**\n * \"Move elements to\" modal for the bulk actions bar. Moves the current\n * selection (assets and/or folders) into the picked destination folder via\n * `POST /upload/actions/bulk-move`. The mutation invalidates the asset list,\n * folder list and the sidebar folder-structure, so both panes refresh on\n * success. On failure the modal stays open so the user can retry or cancel.\n */\nexport const BulkMoveDialog = ({ open, onClose }: BulkMoveDialogProps) => {\n const { formatMessage } = useIntl();\n const { toggleNotification } = useNotification();\n const { selectedIds, selectedFolderIds, clear } = useAssetSelection();\n const { currentFolderId } = useFolderNavigation();\n const { data: folderStructure = [] } = useGetFolderStructureQuery(undefined, { skip: !open });\n const { data: currentFolder } = useGetFolderQuery(\n { id: currentFolderId! },\n { skip: currentFolderId === null }\n );\n const [bulkMove, { isLoading: isMoving }] = useBulkMoveMutation();\n\n // '' is the DOM-only sentinel for the Media Library root (null everywhere else).\n const [destination, setDestination] = useState<string>('');\n\n useEffect(() => {\n if (open) {\n setDestination('');\n }\n }, [open]);\n\n const rootLabel = formatMessage({\n id: getTranslationKey('plugin.name'),\n defaultMessage: 'Media Library',\n });\n\n // Reconstruct the selection as a drag set so the dialog validates destinations\n // through the exact same canonical predicate as the DnD highlight.\n const dragSet = useMemo(\n () => buildDragSetFromSelection(selectedIds, selectedFolderIds, currentFolderId),\n [selectedIds, selectedFolderIds, currentFolderId]\n );\n\n // Options carry the full ancestry (\"About / Images\" vs \"Tech / Images\") so\n // same-named folders stay distinguishable, listed depth-first under their\n // parent. Selected folders and their descendants are pruned during the same\n // single walk — an item can't be moved into itself or below itself (the\n // server would reject it). The current folder (where the items already live)\n // is filtered out too via `canDropItemOnFolder`, so we never offer a no-op\n // move. Memoized: large libraries shouldn't re-walk the tree on every render.\n const destinationOptions = useMemo(\n () =>\n flattenFolderStructure(folderStructure, selectedFolderIds).filter((option) =>\n canDropItemOnFolder({ items: dragSet, targetFolderId: option.id, folderStructure })\n ),\n [folderStructure, selectedFolderIds, dragSet]\n );\n\n // Hide the root option when the items already live at root — dropping there\n // would be a no-op. Uses the same predicate as the DnD highlight.\n const canMoveToRoot = useMemo(\n () => canDropItemOnFolder({ items: dragSet, targetFolderId: null, folderStructure }),\n [dragSet, folderStructure]\n );\n\n const count = selectedIds.size + selectedFolderIds.size;\n\n const handleMove = async () => {\n if (isMoving) {\n return;\n }\n\n const destinationFolderId = destination === '' ? null : Number(destination);\n\n try {\n await bulkMove({\n fileIds: Array.from(selectedIds),\n folderIds: Array.from(selectedFolderIds),\n destinationFolderId,\n }).unwrap();\n } catch (error) {\n // Keep the modal open and the selection intact so the user can retry\n // (e.g. after picking a valid destination) or cancel. Surface the server\n // message when there is one — it carries actionable causes like moving a\n // folder into its own descendant or a name collision in the destination.\n toggleNotification({\n type: 'danger',\n message: getBulkMoveErrorMessage(\n error,\n formatMessage({\n id: getTranslationKey('list.bulk-actions.move.error'),\n defaultMessage: 'An error occurred while moving the items.',\n })\n ),\n });\n return;\n }\n\n const sourceName = currentFolderId === null ? rootLabel : (currentFolder?.name ?? rootLabel);\n const destinationName =\n destinationFolderId === null\n ? rootLabel\n : (destinationOptions.find((option) => option.id === destinationFolderId)?.label ??\n rootLabel);\n\n toggleNotification({\n type: 'success',\n message: formatMessage(\n {\n id: getTranslationKey('list.bulk-actions.move.success'),\n defaultMessage:\n '{count, plural, =1 {# element has} other {# elements have}} been moved from {source} to {destination}',\n },\n { count, source: sourceName, destination: destinationName }\n ),\n });\n clear();\n onClose();\n };\n\n return (\n <Modal.Root\n open={open}\n onOpenChange={(nextOpen: boolean) => {\n // The modal must stay open while the request runs — the loader on the\n // Move button is the source of truth for the pending state.\n if (!nextOpen && !isMoving) {\n onClose();\n }\n }}\n >\n <StyledModalContent>\n <Modal.Header>\n <Modal.Title>\n {formatMessage({\n id: getTranslationKey('list.bulk-actions.move.title'),\n defaultMessage: 'Move elements to',\n })}\n </Modal.Title>\n </Modal.Header>\n <Modal.Body>\n <Field.Root name=\"destination\">\n <Field.Label>\n {formatMessage({\n id: getTranslationKey('list.bulk-actions.move.location'),\n defaultMessage: 'Location',\n })}\n </Field.Label>\n <SingleSelect\n value={destination}\n onChange={(value) => setDestination(String(value))}\n disabled={isMoving}\n >\n {canMoveToRoot && <SingleSelectOption value=\"\">{rootLabel}</SingleSelectOption>}\n {destinationOptions.map((option) => (\n <SingleSelectOption key={option.id} value={String(option.id)}>\n {option.label}\n </SingleSelectOption>\n ))}\n </SingleSelect>\n </Field.Root>\n </Modal.Body>\n <Modal.Footer>\n <Flex gap={2} justifyContent=\"space-between\" width=\"100%\">\n <Button variant=\"tertiary\" onClick={onClose} disabled={isMoving} type=\"button\">\n {formatMessage({ id: 'app.components.Button.cancel', defaultMessage: 'Cancel' })}\n </Button>\n <Button onClick={handleMove} loading={isMoving}>\n {formatMessage({\n id: getTranslationKey('list.bulk-actions.move.submit'),\n defaultMessage: 'Move',\n })}\n </Button>\n </Flex>\n </Modal.Footer>\n </StyledModalContent>\n </Modal.Root>\n );\n};\n"],"names":["StyledModalContent","styled","Modal","Content","BulkMoveDialog","open","onClose","formatMessage","useIntl","toggleNotification","useNotification","selectedIds","selectedFolderIds","clear","useAssetSelection","currentFolderId","useFolderNavigation","data","folderStructure","useGetFolderStructureQuery","undefined","skip","currentFolder","useGetFolderQuery","id","bulkMove","isLoading","isMoving","useBulkMoveMutation","destination","setDestination","useState","useEffect","rootLabel","getTranslationKey","defaultMessage","dragSet","useMemo","buildDragSetFromSelection","destinationOptions","flattenFolderStructure","filter","option","canDropItemOnFolder","items","targetFolderId","canMoveToRoot","count","size","handleMove","destinationFolderId","Number","fileIds","Array","from","folderIds","unwrap","error","type","message","getBulkMoveErrorMessage","sourceName","name","destinationName","find","label","source","_jsx","Root","onOpenChange","nextOpen","_jsxs","Header","Title","Body","Field","Label","SingleSelect","value","onChange","String","disabled","SingleSelectOption","map","Footer","Flex","gap","justifyContent","width","Button","variant","onClick","loading"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"BulkMoveDialog.js","sources":["../../../../../../admin/src/future/pages/Assets/components/BulkMoveDialog.tsx"],"sourcesContent":["import { useEffect, useMemo, useState } from 'react';\n\nimport { useNotification } from '@strapi/admin/strapi-admin';\nimport {\n Button,\n Field,\n Flex,\n Modal,\n SingleSelect,\n SingleSelectOption,\n Typography,\n} from '@strapi/design-system';\nimport { useIntl } from 'react-intl';\nimport { styled } from 'styled-components';\n\nimport {\n useBulkMoveMutation,\n useGetFolderQuery,\n useGetFolderStructureQuery,\n} from '../../../services/folders';\nimport { canDropItemOnFolder } from '../../../utils/canDropItemOnFolder';\nimport { flattenFolderStructure } from '../../../utils/flattenFolderStructure';\nimport { formatMoveSuccessMessage } from '../../../utils/formatMoveSuccessMessage';\nimport { getBulkMoveErrorMessage } from '../../../utils/getBulkMoveErrorMessage';\nimport { hasUniformSource, uniformSourceFolderId } from '../../../utils/itemSource';\nimport { getTranslationKey } from '../../../utils/translations';\n\nimport type { DragItemData } from '../../../types/dnd';\n\nconst StyledModalContent = styled(Modal.Content)`\n max-width: 51.6rem;\n`;\n\ninterface BulkMoveDialogProps {\n open: boolean;\n onClose: () => void;\n /**\n * Items to move, as drag data so destination validation sees each item's real\n * parent — the current folder is not a reliable stand-in once results come\n * from a global search.\n */\n items: DragItemData[];\n onSuccess?: () => void;\n}\n\n/**\n * \"Move elements to\" modal. Moves the given items (assets and/or folders) into\n * the picked destination folder via `POST /upload/actions/bulk-move`. The\n * mutation invalidates the asset list, folder list and the sidebar\n * folder-structure, so both panes refresh on success. On failure the modal stays\n * open so the user can retry or cancel.\n *\n * Used both by the bulk actions bar (the whole selection) and by a folder's\n * actions menu (that one folder).\n */\nexport const BulkMoveDialog = ({ open, onClose, items, onSuccess }: BulkMoveDialogProps) => {\n const { formatMessage } = useIntl();\n const { toggleNotification } = useNotification();\n const {\n data: folderStructure = [],\n isUninitialized: isStructureUninitialized,\n isLoading: isLoadingStructure,\n isError: isStructureError,\n } = useGetFolderStructureQuery(undefined, { skip: !open });\n const [bulkMove, { isLoading: isMoving }] = useBulkMoveMutation();\n\n const fileIds = useMemo(\n () => items.filter((item) => item.kind === 'file').map((item) => item.id),\n [items]\n );\n const folderIds = useMemo(\n () => items.filter((item) => item.kind === 'folder').map((item) => item.id),\n [items]\n );\n\n // A selection made under a global search can span folders, so the source is\n // nameable only when every item agrees on it — `null` otherwise, and the toast\n // then omits the source rather than crediting one item's folder to all of them.\n // The bar can also hand over an empty set, which is likewise unnameable.\n const isSourceUniform = hasUniformSource(items);\n const sourceFolderId = uniformSourceFolderId(items);\n const { data: sourceFolder } = useGetFolderQuery(\n { id: sourceFolderId! },\n { skip: sourceFolderId === null }\n );\n\n // '' is the DOM-only sentinel for the Media Library root (null everywhere else).\n const [destination, setDestination] = useState<string>('');\n\n const rootLabel = formatMessage({\n id: getTranslationKey('plugin.name'),\n defaultMessage: 'Media Library',\n });\n\n // Options carry the full ancestry (\"About / Images\" vs \"Tech / Images\") so\n // same-named folders stay distinguishable, listed depth-first under their\n // parent. The moved folders and their descendants are pruned during the same\n // single walk — an item can't be moved into itself or below itself (the\n // server would reject it). The folder the items already live in is filtered\n // out too via `canDropItemOnFolder`, so we never offer a no-op move.\n // Memoized: large libraries shouldn't re-walk the tree on every render.\n const destinationOptions = useMemo(\n () =>\n flattenFolderStructure(folderStructure, new Set(folderIds)).filter((option) =>\n canDropItemOnFolder({ items, targetFolderId: option.id, folderStructure })\n ),\n [folderStructure, folderIds, items]\n );\n\n // Hide the root option when the items already live at root — dropping there\n // would be a no-op. Uses the same predicate as the DnD highlight.\n const canMoveToRoot = useMemo(\n () => canDropItemOnFolder({ items, targetFolderId: null, folderStructure }),\n [items, folderStructure]\n );\n\n // The default has to be an option that is actually rendered, or the select\n // shows blank: root is absent when the items already live there, and the\n // folder options only exist once the structure query has resolved.\n const defaultDestination = canMoveToRoot ? '' : (destinationOptions[0]?.id.toString() ?? '');\n\n // Re-derived rather than only reset on open, because the options arrive after\n // the first render. It is a primitive, so a background refetch that produces\n // the same default won't discard a destination the user already picked.\n useEffect(() => {\n setDestination(defaultDestination);\n }, [open, defaultDestination]);\n\n // Until the structure resolves there are no options, so the default falls\n // back to root ('') — which for a root-level item is the no-op destination\n // that was deliberately filtered out. Nothing may be submitted before this.\n const isStructureReady = !isStructureUninitialized && !isLoadingStructure && !isStructureError;\n\n // Moving a single folder that already sits next to every other folder leaves\n // nowhere to go; say so instead of showing an empty select. Only once the\n // structure has arrived — an in-flight or failed fetch also has no options,\n // and a failure is a different story to tell.\n const hasNoDestination = isStructureReady && destinationOptions.length === 0 && !canMoveToRoot;\n\n const count = items.length;\n\n const handleMove = async () => {\n // The button is disabled in both cases; the dialog can also be submitted\n // from the keyboard, so guard here too.\n if (isMoving || !isStructureReady) {\n return;\n }\n\n const destinationFolderId = destination === '' ? null : Number(destination);\n\n try {\n await bulkMove({ fileIds, folderIds, destinationFolderId }).unwrap();\n } catch (error) {\n // Keep the modal open and the selection intact so the user can retry\n // (e.g. after picking a valid destination) or cancel. Surface the server\n // message when there is one — it carries actionable causes like moving a\n // folder into its own descendant or a name collision in the destination.\n toggleNotification({\n type: 'danger',\n message: getBulkMoveErrorMessage(\n error,\n formatMessage({\n id: getTranslationKey('list.bulk-actions.move.error'),\n defaultMessage: 'An error occurred while moving the items.',\n })\n ),\n });\n return;\n }\n\n // A uniform source with a `null` id is the Media Library root — a real name.\n // Only a set that genuinely spans folders has no source to report.\n const sourceName = !isSourceUniform\n ? null\n : sourceFolderId === null\n ? rootLabel\n : (sourceFolder?.name ?? rootLabel);\n const destinationName =\n destinationFolderId === null\n ? rootLabel\n : (destinationOptions.find((option) => option.id === destinationFolderId)?.label ??\n rootLabel);\n\n toggleNotification({\n type: 'success',\n message: formatMoveSuccessMessage({\n formatMessage,\n count,\n source: sourceName,\n destination: destinationName,\n }),\n });\n onSuccess?.();\n onClose();\n };\n\n // Three states: a failed structure request, a genuine dead end, and the\n // select — which also covers the loading window, so the hint and the error\n // don't flash in ahead of the options.\n const renderBody = () => {\n if (isStructureError) {\n return (\n <Typography textColor=\"danger600\">\n {formatMessage({\n id: getTranslationKey('list.bulk-actions.move.load-error'),\n defaultMessage: \"Couldn't load the folder list. Please try again.\",\n })}\n </Typography>\n );\n }\n\n if (hasNoDestination) {\n return (\n <Typography textColor=\"neutral600\">\n {formatMessage({\n id: getTranslationKey('list.bulk-actions.move.no-destination'),\n defaultMessage: 'There is no other folder to move this to.',\n })}\n </Typography>\n );\n }\n\n return (\n <Field.Root name=\"destination\">\n <Field.Label>\n {formatMessage({\n id: getTranslationKey('list.bulk-actions.move.location'),\n defaultMessage: 'Location',\n })}\n </Field.Label>\n <SingleSelect\n value={destination}\n onChange={(value) => setDestination(String(value))}\n disabled={isMoving || !isStructureReady}\n >\n {canMoveToRoot && <SingleSelectOption value=\"\">{rootLabel}</SingleSelectOption>}\n {destinationOptions.map((option) => (\n <SingleSelectOption key={option.id} value={String(option.id)}>\n {option.label}\n </SingleSelectOption>\n ))}\n </SingleSelect>\n </Field.Root>\n );\n };\n\n return (\n <Modal.Root\n open={open}\n onOpenChange={(nextOpen: boolean) => {\n // The modal must stay open while the request runs — the loader on the\n // Move button is the source of truth for the pending state.\n if (!nextOpen && !isMoving) {\n onClose();\n }\n }}\n >\n <StyledModalContent>\n <Modal.Header>\n <Modal.Title>\n {formatMessage({\n id: getTranslationKey('list.bulk-actions.move.title'),\n defaultMessage: 'Move elements to',\n })}\n </Modal.Title>\n </Modal.Header>\n <Modal.Body>{renderBody()}</Modal.Body>\n <Modal.Footer>\n <Flex gap={2} justifyContent=\"space-between\" width=\"100%\">\n <Button variant=\"tertiary\" onClick={onClose} disabled={isMoving} type=\"button\">\n {formatMessage({ id: 'app.components.Button.cancel', defaultMessage: 'Cancel' })}\n </Button>\n <Button\n onClick={handleMove}\n loading={isMoving}\n disabled={!isStructureReady || hasNoDestination}\n >\n {formatMessage({\n id: getTranslationKey('list.bulk-actions.move.submit'),\n defaultMessage: 'Move',\n })}\n </Button>\n </Flex>\n </Modal.Footer>\n </StyledModalContent>\n </Modal.Root>\n );\n};\n"],"names":["StyledModalContent","styled","Modal","Content","BulkMoveDialog","open","onClose","items","onSuccess","formatMessage","useIntl","toggleNotification","useNotification","data","folderStructure","isUninitialized","isStructureUninitialized","isLoading","isLoadingStructure","isError","isStructureError","useGetFolderStructureQuery","undefined","skip","bulkMove","isMoving","useBulkMoveMutation","fileIds","useMemo","filter","item","kind","map","id","folderIds","isSourceUniform","hasUniformSource","sourceFolderId","uniformSourceFolderId","sourceFolder","useGetFolderQuery","destination","setDestination","useState","rootLabel","getTranslationKey","defaultMessage","destinationOptions","flattenFolderStructure","Set","option","canDropItemOnFolder","targetFolderId","canMoveToRoot","defaultDestination","toString","useEffect","isStructureReady","hasNoDestination","length","count","handleMove","destinationFolderId","Number","unwrap","error","type","message","getBulkMoveErrorMessage","sourceName","name","destinationName","find","label","formatMoveSuccessMessage","source","renderBody","_jsx","Typography","textColor","_jsxs","Field","Root","Label","SingleSelect","value","onChange","String","disabled","SingleSelectOption","onOpenChange","nextOpen","Header","Title","Body","Footer","Flex","gap","justifyContent","width","Button","variant","onClick","loading"],"mappings":"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"}
|