@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
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AssetsDndProvider.mjs","sources":["../../../../../../../admin/src/future/pages/Assets/components/Dnd/AssetsDndProvider.tsx"],"sourcesContent":["import {\n createContext,\n useCallback,\n useContext,\n useMemo,\n useRef,\n useState,\n type ReactNode,\n} from 'react';\n\nimport {\n DndContext,\n DragOverlay,\n PointerSensor,\n pointerWithin,\n useSensor,\n useSensors,\n type DragEndEvent,\n type DragStartEvent,\n} from '@dnd-kit/core';\nimport { useNotification } from '@strapi/admin/strapi-admin';\nimport { Box, VisuallyHidden } from '@strapi/design-system';\nimport { useIntl } from 'react-intl';\n\nimport { useMediaLibraryPermissions } from '../../../../hooks/useMediaLibraryPermissions';\nimport { useBulkMoveMutation, useGetFolderStructureQuery } from '../../../../services/folders';\nimport { buildBulkMovePayload } from '../../../../utils/buildBulkMovePayload';\nimport { canDropItemOnFolder } from '../../../../utils/canDropItemOnFolder';\nimport { formatMoveSuccessMessage } from '../../../../utils/formatMoveSuccessMessage';\nimport { getBulkMoveErrorMessage } from '../../../../utils/getBulkMoveErrorMessage';\nimport { getFolderLabel } from '../../../../utils/getFolderLabel';\nimport { getTranslationKey } from '../../../../utils/translations';\nimport { useAssetSelectionOptional } from '../../hooks/useAssetSelection';\nimport { useFolderNavigation } from '../../hooks/useFolderNavigation';\n\nimport { buildDragSet } from './buildDragSet';\nimport { computeValidDropTargets } from './computeValidDropTargets';\nimport { parseFolderTargetId, parseFolderTreeTargetId } from './dndIds';\nimport { DragOverlayChip } from './DragOverlayChip';\n\nimport type { DragItemData } from '../../../../types/dnd';\n\n/* -------------------------------------------------------------------------------------------------\n * Context — shared with UploadDropZoneProvider for bidirectional drag guard.\n * See UploadDropZoneContext.tsx TODO linking both providers.\n * -----------------------------------------------------------------------------------------------*/\n\ninterface AssetsDndContextValue {\n isInternalDragActive: boolean;\n isMovePending: boolean;\n /** O(1) lookup of whether the current drag set may drop on this destination. */\n isValidDropTarget: (targetFolderId: number | null) => boolean;\n}\n\nconst AssetsDndContext = createContext<AssetsDndContextValue | null>(null);\n\nexport const useAssetsDnd = () => {\n const context = useContext(AssetsDndContext);\n\n if (!context) {\n throw new Error('useAssetsDnd must be used within AssetsDndProvider');\n }\n\n return context;\n};\n\nexport const useAssetsDndOptional = () => useContext(AssetsDndContext);\n\n/* -------------------------------------------------------------------------------------------------\n * Provider\n * -----------------------------------------------------------------------------------------------*/\n\ninterface AssetsDndProviderProps {\n children: ReactNode;\n}\n\ninterface DragSession {\n items: DragItemData[];\n fromSelection: boolean;\n}\n\nconst resolveDestination = (\n overId: string | number\n): { destinationFolderId: number | null } | null => {\n const inView = parseFolderTargetId(overId);\n\n if (inView != null) {\n return { destinationFolderId: inView };\n }\n\n const tree = parseFolderTreeTargetId(overId);\n\n if (tree === 'root') {\n return { destinationFolderId: null };\n }\n\n if (typeof tree === 'number') {\n return { destinationFolderId: tree };\n }\n\n return null;\n};\n\n// Activation distance no real pointer gesture will ever reach — used to keep a\n// constant-length sensor array while disabling drag for users without the move\n// permission (see the note in the provider).\nconst DRAG_DISABLED_DISTANCE = Number.MAX_SAFE_INTEGER;\n\nexport const AssetsDndProvider = ({ children }: AssetsDndProviderProps) => {\n const { formatMessage } = useIntl();\n const { toggleNotification } = useNotification();\n const selection = useAssetSelectionOptional();\n const { currentFolderId } = useFolderNavigation();\n const { data: folderStructure = [] } = useGetFolderStructureQuery();\n const rootLabel = formatMessage({\n id: getTranslationKey('plugin.name'),\n defaultMessage: 'Media Library',\n });\n const [bulkMove, { isLoading: isMovePending }] = useBulkMoveMutation();\n const [dragItems, setDragItems] = useState<DragItemData[]>([]);\n const [liveAnnouncement, setLiveAnnouncement] = useState('');\n // Sync session for drag-end — state alone can lag one render behind dragStart.\n const dragSessionRef = useRef<DragSession>({ items: [], fromSelection: false });\n\n const announceToLiveRegion = useCallback((message: string) => {\n setLiveAnnouncement('');\n requestAnimationFrame(() => setLiveAnnouncement(message));\n }, []);\n\n // Moving is a mutation (bulk-move → `assets.update`); without the permission\n // pointer drag must never activate. Keyboard moves go through BulkMoveDialog,\n // which is itself gated.\n //\n // The gate has to keep BOTH the `useSensor`/`useSensors` calls AND the sensor\n // array's length constant across renders: `canUpdate` starts false and flips\n // true once the RBAC check resolves, and dnd-kit keys internal memos/effects\n // on the sensor list, erroring if its size changes (\"argument changed size\n // between renders\"). So adding/removing a sensor is out — instead keep one\n // PointerSensor always and push its activation distance out of reach when the\n // user can't move, which no real drag gesture will ever satisfy.\n const { canUpdate } = useMediaLibraryPermissions();\n const sensors = useSensors(\n useSensor(PointerSensor, {\n activationConstraint: { distance: canUpdate ? 8 : DRAG_DISABLED_DISTANCE },\n })\n );\n\n const validDropTargets = useMemo(\n () => computeValidDropTargets(dragItems, folderStructure),\n [dragItems, folderStructure]\n );\n\n const isValidDropTarget = useCallback(\n (targetFolderId: number | null) => validDropTargets.has(targetFolderId),\n [validDropTargets]\n );\n\n const contextValue = useMemo<AssetsDndContextValue>(\n () => ({\n isInternalDragActive: dragItems.length > 0,\n isMovePending,\n isValidDropTarget,\n }),\n [dragItems.length, isMovePending, isValidDropTarget]\n );\n\n const clearDragState = useCallback(() => {\n dragSessionRef.current = { items: [], fromSelection: false };\n setDragItems([]);\n }, []);\n\n const handleDragStart = useCallback(\n (event: DragStartEvent) => {\n const data = event.active.data.current as DragItemData | undefined;\n\n if (!data) {\n clearDragState();\n return;\n }\n\n const { items, fromSelection } = buildDragSet(data, selection?.selectedKeys, currentFolderId);\n dragSessionRef.current = { items, fromSelection };\n setDragItems(items);\n },\n [clearDragState, currentFolderId, selection?.selectedKeys]\n );\n\n const handleDragEnd = useCallback(\n async (event: DragEndEvent) => {\n const { over } = event;\n const { items, fromSelection } = dragSessionRef.current;\n clearDragState();\n\n if (isMovePending || !over || items.length === 0) {\n return;\n }\n\n const destination = resolveDestination(over.id);\n\n if (!destination) {\n return;\n }\n\n const { destinationFolderId: targetFolderId } = destination;\n\n if (\n !canDropItemOnFolder({\n items,\n targetFolderId,\n folderStructure,\n })\n ) {\n return;\n }\n\n const payload = buildBulkMovePayload(items);\n // Source is always the current folder — dragged items are, by definition,\n // visible in the current view. Destination is the drop target. Both use\n // leaf names so the DnD toast reads identically to the dialog's.\n const successMessage = formatMoveSuccessMessage({\n formatMessage,\n count: items.length,\n source: getFolderLabel(folderStructure, currentFolderId, rootLabel),\n destination: getFolderLabel(folderStructure, targetFolderId, rootLabel),\n });\n const errorFallback = formatMessage({\n id: getTranslationKey('list.bulk-actions.move.error'),\n defaultMessage: 'An error occurred while moving the items.',\n });\n\n try {\n await bulkMove({ ...payload, destinationFolderId: targetFolderId }).unwrap();\n\n if (fromSelection) {\n selection?.clear();\n }\n\n announceToLiveRegion(successMessage);\n\n toggleNotification({\n type: 'success',\n message: successMessage,\n });\n } catch (error) {\n const errorMessage = getBulkMoveErrorMessage(error, errorFallback);\n\n announceToLiveRegion(\n formatMessage(\n {\n id: getTranslationKey('dnd.announce.move-failure'),\n defaultMessage: 'Move failed. {message}',\n },\n { message: errorMessage }\n )\n );\n\n toggleNotification({\n type: 'danger',\n message: errorMessage,\n });\n }\n },\n [\n announceToLiveRegion,\n bulkMove,\n clearDragState,\n currentFolderId,\n folderStructure,\n formatMessage,\n isMovePending,\n rootLabel,\n selection,\n toggleNotification,\n ]\n );\n\n const handleDragCancel = useCallback(() => {\n clearDragState();\n }, [clearDragState]);\n\n const announcements = useMemo(\n () => ({\n onDragStart: ({ active }: DragStartEvent) => {\n const data = active.data.current as DragItemData | undefined;\n return data\n ? formatMessage(\n {\n id: getTranslationKey('dnd.announce.drag-start'),\n defaultMessage: 'Picked up {name}. Drop on a folder to move.',\n },\n { name: data.name }\n )\n : '';\n },\n onDragOver: () => '',\n onDragEnd: ({ active, over }: DragEndEvent) => {\n if (!over) {\n return formatMessage({\n id: getTranslationKey('dnd.announce.cancel'),\n defaultMessage: 'Drag cancelled.',\n });\n }\n\n const destination = resolveDestination(over.id);\n const activeData = active.data.current as DragItemData | undefined;\n\n if (!destination || !activeData) {\n return '';\n }\n\n const { items } = buildDragSet(activeData, selection?.selectedKeys, currentFolderId);\n\n if (\n !canDropItemOnFolder({\n items,\n targetFolderId: destination.destinationFolderId,\n folderStructure,\n })\n ) {\n return formatMessage({\n id: getTranslationKey('dnd.announce.invalid-drop'),\n defaultMessage: 'Cannot move item to this folder.',\n });\n }\n\n return '';\n },\n onDragCancel: () =>\n formatMessage({\n id: getTranslationKey('dnd.announce.cancel'),\n defaultMessage: 'Drag cancelled.',\n }),\n }),\n [currentFolderId, folderStructure, formatMessage, selection?.selectedKeys]\n );\n\n return (\n <AssetsDndContext.Provider value={contextValue}>\n <DndContext\n sensors={sensors}\n collisionDetection={pointerWithin}\n onDragStart={handleDragStart}\n onDragEnd={handleDragEnd}\n onDragCancel={handleDragCancel}\n accessibility={{ announcements }}\n >\n <VisuallyHidden aria-live=\"polite\" aria-atomic=\"true\">\n {liveAnnouncement}\n </VisuallyHidden>\n <Box position=\"relative\">{children}</Box>\n <DragOverlay dropAnimation={null}>\n {dragItems.length > 0 ? <DragOverlayChip items={dragItems} /> : null}\n </DragOverlay>\n </DndContext>\n </AssetsDndContext.Provider>\n );\n};\n\n// Keyboard-accessible moves are handled by `BulkMoveDialog` (reachable from the\n// bulk-actions bar): pointer drag is a mouse-only enhancement, the dialog is the\n// a11y path. No `KeyboardSensor` by design.\n"],"names":["AssetsDndContext","createContext","useAssetsDndOptional","useContext","resolveDestination","overId","inView","parseFolderTargetId","destinationFolderId","tree","parseFolderTreeTargetId","DRAG_DISABLED_DISTANCE","Number","MAX_SAFE_INTEGER","AssetsDndProvider","children","formatMessage","useIntl","toggleNotification","useNotification","selection","useAssetSelectionOptional","currentFolderId","useFolderNavigation","data","folderStructure","useGetFolderStructureQuery","rootLabel","id","getTranslationKey","defaultMessage","bulkMove","isLoading","isMovePending","useBulkMoveMutation","dragItems","setDragItems","useState","liveAnnouncement","setLiveAnnouncement","dragSessionRef","useRef","items","fromSelection","announceToLiveRegion","useCallback","message","requestAnimationFrame","canUpdate","useMediaLibraryPermissions","sensors","useSensors","useSensor","PointerSensor","activationConstraint","distance","validDropTargets","useMemo","computeValidDropTargets","isValidDropTarget","targetFolderId","has","contextValue","isInternalDragActive","length","clearDragState","current","handleDragStart","event","active","buildDragSet","selectedKeys","handleDragEnd","over","destination","canDropItemOnFolder","payload","buildBulkMovePayload","successMessage","formatMoveSuccessMessage","count","source","getFolderLabel","errorFallback","unwrap","clear","type","error","errorMessage","getBulkMoveErrorMessage","handleDragCancel","announcements","onDragStart","name","onDragOver","onDragEnd","activeData","onDragCancel","_jsx","Provider","value","_jsxs","DndContext","collisionDetection","pointerWithin","accessibility","VisuallyHidden","aria-live","aria-atomic","Box","position","DragOverlay","dropAnimation","DragOverlayChip"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"AssetsDndProvider.mjs","sources":["../../../../../../../admin/src/future/pages/Assets/components/Dnd/AssetsDndProvider.tsx"],"sourcesContent":["import {\n createContext,\n useCallback,\n useContext,\n useMemo,\n useRef,\n useState,\n type ReactNode,\n} from 'react';\n\nimport {\n DndContext,\n DragOverlay,\n PointerSensor,\n pointerWithin,\n useSensor,\n useSensors,\n type DragEndEvent,\n type DragStartEvent,\n} from '@dnd-kit/core';\nimport { useNotification } from '@strapi/admin/strapi-admin';\nimport { Flex, VisuallyHidden } from '@strapi/design-system';\nimport { useIntl } from 'react-intl';\n\nimport { useMediaLibraryPermissions } from '../../../../hooks/useMediaLibraryPermissions';\nimport { useBulkMoveMutation, useGetFolderStructureQuery } from '../../../../services/folders';\nimport { buildBulkMovePayload } from '../../../../utils/buildBulkMovePayload';\nimport { canDropItemOnFolder } from '../../../../utils/canDropItemOnFolder';\nimport { formatMoveSuccessMessage } from '../../../../utils/formatMoveSuccessMessage';\nimport { getBulkMoveErrorMessage } from '../../../../utils/getBulkMoveErrorMessage';\nimport { getFolderLabel } from '../../../../utils/getFolderLabel';\nimport { emptyItemLocations, type ItemLocations } from '../../../../utils/itemLocations';\nimport { getTranslationKey } from '../../../../utils/translations';\nimport { useAssetSelectionOptional } from '../../hooks/useAssetSelection';\nimport { useFolderNavigation } from '../../hooks/useFolderNavigation';\n\nimport { buildDragSet } from './buildDragSet';\nimport { computeValidDropTargets } from './computeValidDropTargets';\nimport { parseFolderTargetId, parseFolderTreeTargetId } from './dndIds';\nimport { DragOverlayChip } from './DragOverlayChip';\n\nimport type { DragItemData } from '../../../../types/dnd';\n\n/* -------------------------------------------------------------------------------------------------\n * Context — shared with UploadDropZoneProvider for bidirectional drag guard.\n * See UploadDropZoneContext.tsx TODO linking both providers.\n * -----------------------------------------------------------------------------------------------*/\n\ninterface AssetsDndContextValue {\n isInternalDragActive: boolean;\n isMovePending: boolean;\n /** O(1) lookup of whether the current drag set may drop on this destination. */\n isValidDropTarget: (targetFolderId: number | null) => boolean;\n}\n\nconst AssetsDndContext = createContext<AssetsDndContextValue | null>(null);\n\nexport const useAssetsDnd = () => {\n const context = useContext(AssetsDndContext);\n\n if (!context) {\n throw new Error('useAssetsDnd must be used within AssetsDndProvider');\n }\n\n return context;\n};\n\nexport const useAssetsDndOptional = () => useContext(AssetsDndContext);\n\n/* -------------------------------------------------------------------------------------------------\n * Provider\n * -----------------------------------------------------------------------------------------------*/\n\ninterface AssetsDndProviderProps {\n children: ReactNode;\n /**\n * Real location of every loaded row, so a multi-item drag validates against\n * each item's own parent. Defaults to a lookup that misses everything, which\n * falls back to the folder currently open.\n */\n locations?: ItemLocations;\n}\n\ninterface DragSession {\n items: DragItemData[];\n fromSelection: boolean;\n /** Location of the grabbed row — names the source in the success toast. */\n activeSourceFolderId: number | null;\n /** True when the set spans several source folders, so none can be named. */\n spansMultipleSources: boolean;\n}\n\nconst resolveDestination = (\n overId: string | number\n): { destinationFolderId: number | null } | null => {\n const inView = parseFolderTargetId(overId);\n\n if (inView != null) {\n return { destinationFolderId: inView };\n }\n\n const tree = parseFolderTreeTargetId(overId);\n\n if (tree === 'root') {\n return { destinationFolderId: null };\n }\n\n if (typeof tree === 'number') {\n return { destinationFolderId: tree };\n }\n\n return null;\n};\n\n// Activation distance no real pointer gesture will ever reach — used to keep a\n// constant-length sensor array while disabling drag for users without the move\n// permission (see the note in the provider).\nconst DRAG_DISABLED_DISTANCE = Number.MAX_SAFE_INTEGER;\n\nexport const AssetsDndProvider = ({\n children,\n locations = emptyItemLocations,\n}: AssetsDndProviderProps) => {\n const { formatMessage } = useIntl();\n const { toggleNotification } = useNotification();\n const selection = useAssetSelectionOptional();\n const { currentFolderId } = useFolderNavigation();\n const { data: folderStructure = [] } = useGetFolderStructureQuery();\n const rootLabel = formatMessage({\n id: getTranslationKey('plugin.name'),\n defaultMessage: 'Media Library',\n });\n const [bulkMove, { isLoading: isMovePending }] = useBulkMoveMutation();\n const [dragItems, setDragItems] = useState<DragItemData[]>([]);\n const [liveAnnouncement, setLiveAnnouncement] = useState('');\n // Sync session for drag-end — state alone can lag one render behind dragStart.\n const dragSessionRef = useRef<DragSession>({\n items: [],\n fromSelection: false,\n activeSourceFolderId: null,\n spansMultipleSources: false,\n });\n\n const announceToLiveRegion = useCallback((message: string) => {\n setLiveAnnouncement('');\n requestAnimationFrame(() => setLiveAnnouncement(message));\n }, []);\n\n // Moving is a mutation (bulk-move → `assets.update`); without the permission\n // pointer drag must never activate. Keyboard moves go through BulkMoveDialog,\n // which is itself gated.\n //\n // The gate has to keep BOTH the `useSensor`/`useSensors` calls AND the sensor\n // array's length constant across renders: `canUpdate` starts false and flips\n // true once the RBAC check resolves, and dnd-kit keys internal memos/effects\n // on the sensor list, erroring if its size changes (\"argument changed size\n // between renders\"). So adding/removing a sensor is out — instead keep one\n // PointerSensor always and push its activation distance out of reach when the\n // user can't move, which no real drag gesture will ever satisfy.\n const { canUpdate } = useMediaLibraryPermissions();\n const sensors = useSensors(\n useSensor(PointerSensor, {\n activationConstraint: { distance: canUpdate ? 8 : DRAG_DISABLED_DISTANCE },\n })\n );\n\n const validDropTargets = useMemo(\n () => computeValidDropTargets(dragItems, folderStructure),\n [dragItems, folderStructure]\n );\n\n const isValidDropTarget = useCallback(\n (targetFolderId: number | null) => validDropTargets.has(targetFolderId),\n [validDropTargets]\n );\n\n const contextValue = useMemo<AssetsDndContextValue>(\n () => ({\n isInternalDragActive: dragItems.length > 0,\n isMovePending,\n isValidDropTarget,\n }),\n [dragItems.length, isMovePending, isValidDropTarget]\n );\n\n const clearDragState = useCallback(() => {\n dragSessionRef.current = {\n items: [],\n fromSelection: false,\n activeSourceFolderId: null,\n spansMultipleSources: false,\n };\n setDragItems([]);\n }, []);\n\n const handleDragStart = useCallback(\n (event: DragStartEvent) => {\n const data = event.active.data.current as DragItemData | undefined;\n\n if (!data) {\n clearDragState();\n return;\n }\n\n const dragSet = buildDragSet(data, selection?.selectedKeys, locations, currentFolderId);\n dragSessionRef.current = dragSet;\n setDragItems(dragSet.items);\n },\n [clearDragState, currentFolderId, locations, selection?.selectedKeys]\n );\n\n const handleDragEnd = useCallback(\n async (event: DragEndEvent) => {\n const { over } = event;\n const { items, fromSelection, activeSourceFolderId, spansMultipleSources } =\n dragSessionRef.current;\n clearDragState();\n\n if (isMovePending || !over || items.length === 0) {\n return;\n }\n\n const destination = resolveDestination(over.id);\n\n if (!destination) {\n return;\n }\n\n const { destinationFolderId: targetFolderId } = destination;\n\n if (\n !canDropItemOnFolder({\n items,\n targetFolderId,\n folderStructure,\n })\n ) {\n return;\n }\n\n const payload = buildBulkMovePayload(items);\n // Source is the grabbed row's own location, not the folder currently open:\n // a global search result can be dragged out of a folder the user isn't in.\n // A search-built selection can also span folders, and then no single\n // source is true for the whole set — `null` drops it from the wording\n // instead of naming one item's folder for all of them. Destination is the\n // drop target. Both use leaf names so the DnD toast reads identically to\n // the dialog's.\n const successMessage = formatMoveSuccessMessage({\n formatMessage,\n count: items.length,\n source: spansMultipleSources\n ? null\n : getFolderLabel(folderStructure, activeSourceFolderId, rootLabel),\n destination: getFolderLabel(folderStructure, targetFolderId, rootLabel),\n });\n const errorFallback = formatMessage({\n id: getTranslationKey('list.bulk-actions.move.error'),\n defaultMessage: 'An error occurred while moving the items.',\n });\n\n try {\n await bulkMove({ ...payload, destinationFolderId: targetFolderId }).unwrap();\n\n if (fromSelection) {\n selection?.clear();\n }\n\n announceToLiveRegion(successMessage);\n\n toggleNotification({\n type: 'success',\n message: successMessage,\n });\n } catch (error) {\n const errorMessage = getBulkMoveErrorMessage(error, errorFallback);\n\n announceToLiveRegion(\n formatMessage(\n {\n id: getTranslationKey('dnd.announce.move-failure'),\n defaultMessage: 'Move failed. {message}',\n },\n { message: errorMessage }\n )\n );\n\n toggleNotification({\n type: 'danger',\n message: errorMessage,\n });\n }\n },\n [\n announceToLiveRegion,\n bulkMove,\n clearDragState,\n folderStructure,\n formatMessage,\n isMovePending,\n rootLabel,\n selection,\n toggleNotification,\n ]\n );\n\n const handleDragCancel = useCallback(() => {\n clearDragState();\n }, [clearDragState]);\n\n const announcements = useMemo(\n () => ({\n onDragStart: ({ active }: DragStartEvent) => {\n const data = active.data.current as DragItemData | undefined;\n return data\n ? formatMessage(\n {\n id: getTranslationKey('dnd.announce.drag-start'),\n defaultMessage: 'Picked up {name}. Drop on a folder to move.',\n },\n { name: data.name }\n )\n : '';\n },\n onDragOver: () => '',\n onDragEnd: ({ active, over }: DragEndEvent) => {\n if (!over) {\n return formatMessage({\n id: getTranslationKey('dnd.announce.cancel'),\n defaultMessage: 'Drag cancelled.',\n });\n }\n\n const destination = resolveDestination(over.id);\n const activeData = active.data.current as DragItemData | undefined;\n\n if (!destination || !activeData) {\n return '';\n }\n\n const { items } = buildDragSet(\n activeData,\n selection?.selectedKeys,\n locations,\n currentFolderId\n );\n\n if (\n !canDropItemOnFolder({\n items,\n targetFolderId: destination.destinationFolderId,\n folderStructure,\n })\n ) {\n return formatMessage({\n id: getTranslationKey('dnd.announce.invalid-drop'),\n defaultMessage: 'Cannot move item to this folder.',\n });\n }\n\n return '';\n },\n onDragCancel: () =>\n formatMessage({\n id: getTranslationKey('dnd.announce.cancel'),\n defaultMessage: 'Drag cancelled.',\n }),\n }),\n [currentFolderId, folderStructure, formatMessage, locations, selection?.selectedKeys]\n );\n\n return (\n <AssetsDndContext.Provider value={contextValue}>\n <DndContext\n sensors={sensors}\n collisionDetection={pointerWithin}\n onDragStart={handleDragStart}\n onDragEnd={handleDragEnd}\n onDragCancel={handleDragCancel}\n accessibility={{ announcements }}\n >\n <VisuallyHidden aria-live=\"polite\" aria-atomic=\"true\">\n {liveAnnouncement}\n </VisuallyHidden>\n <Flex position=\"relative\" alignItems=\"stretch\" direction=\"column\" height=\"100%\">\n {children}\n </Flex>\n <DragOverlay dropAnimation={null}>\n {dragItems.length > 0 ? <DragOverlayChip items={dragItems} /> : null}\n </DragOverlay>\n </DndContext>\n </AssetsDndContext.Provider>\n );\n};\n\n// Keyboard-accessible moves are handled by `BulkMoveDialog` (reachable from the\n// bulk-actions bar): pointer drag is a mouse-only enhancement, the dialog is the\n// a11y path. No `KeyboardSensor` by design.\n"],"names":["AssetsDndContext","createContext","useAssetsDndOptional","useContext","resolveDestination","overId","inView","parseFolderTargetId","destinationFolderId","tree","parseFolderTreeTargetId","DRAG_DISABLED_DISTANCE","Number","MAX_SAFE_INTEGER","AssetsDndProvider","children","locations","emptyItemLocations","formatMessage","useIntl","toggleNotification","useNotification","selection","useAssetSelectionOptional","currentFolderId","useFolderNavigation","data","folderStructure","useGetFolderStructureQuery","rootLabel","id","getTranslationKey","defaultMessage","bulkMove","isLoading","isMovePending","useBulkMoveMutation","dragItems","setDragItems","useState","liveAnnouncement","setLiveAnnouncement","dragSessionRef","useRef","items","fromSelection","activeSourceFolderId","spansMultipleSources","announceToLiveRegion","useCallback","message","requestAnimationFrame","canUpdate","useMediaLibraryPermissions","sensors","useSensors","useSensor","PointerSensor","activationConstraint","distance","validDropTargets","useMemo","computeValidDropTargets","isValidDropTarget","targetFolderId","has","contextValue","isInternalDragActive","length","clearDragState","current","handleDragStart","event","active","dragSet","buildDragSet","selectedKeys","handleDragEnd","over","destination","canDropItemOnFolder","payload","buildBulkMovePayload","successMessage","formatMoveSuccessMessage","count","source","getFolderLabel","errorFallback","unwrap","clear","type","error","errorMessage","getBulkMoveErrorMessage","handleDragCancel","announcements","onDragStart","name","onDragOver","onDragEnd","activeData","onDragCancel","_jsx","Provider","value","_jsxs","DndContext","collisionDetection","pointerWithin","accessibility","VisuallyHidden","aria-live","aria-atomic","Flex","position","alignItems","direction","height","DragOverlay","dropAnimation","DragOverlayChip"],"mappings":"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"}
|
|
@@ -1,43 +1,30 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
+
var itemLocations = require('../../../../utils/itemLocations.js');
|
|
4
|
+
var itemSource = require('../../../../utils/itemSource.js');
|
|
3
5
|
var selection = require('../../utils/selection.js');
|
|
4
6
|
|
|
5
|
-
/**
|
|
6
|
-
* Stamp an item with the authoritative current-folder location. Drag/selection is
|
|
7
|
-
* page-scoped to the current folder, so this is more reliable than the item's own
|
|
8
|
-
* `folderId`/`parentId` — a dragged folder's `parent` is not populated by the
|
|
9
|
-
* folders query, so its `parentId` would otherwise collapse to `null`.
|
|
10
|
-
*/ const locateItem = (item, currentFolderId)=>item.kind === 'file' ? {
|
|
11
|
-
...item,
|
|
12
|
-
folderId: currentFolderId
|
|
13
|
-
} : {
|
|
14
|
-
...item,
|
|
15
|
-
parentId: currentFolderId
|
|
16
|
-
};
|
|
17
7
|
/**
|
|
18
8
|
* Derive the drag payload once at drag start.
|
|
19
9
|
*
|
|
20
10
|
* - Dragging a selected item moves the complete current selection.
|
|
21
11
|
* - Dragging an unselected item moves only that item.
|
|
22
12
|
*
|
|
23
|
-
*
|
|
24
|
-
*
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
items: [
|
|
29
|
-
locateItem(activeData, currentFolderId)
|
|
30
|
-
],
|
|
31
|
-
fromSelection: false
|
|
32
|
-
};
|
|
33
|
-
}
|
|
13
|
+
* The active item carries its own location on `dragData` (the row it was
|
|
14
|
+
* grabbed from); the rest of the selection is resolved through `locations`.
|
|
15
|
+
* Neither is derived from the folder currently open, because search results are
|
|
16
|
+
* global — see `utils/itemLocations.ts`.
|
|
17
|
+
*/ const buildDragSet = (activeData, selectedKeys, locations, fallbackFolderId)=>{
|
|
34
18
|
const activeKey = activeData.kind === 'file' ? selection.assetKey(activeData.id) : selection.folderKey(activeData.id);
|
|
35
|
-
|
|
19
|
+
const activeSourceFolderId = itemSource.sourceFolderIdOf(activeData);
|
|
20
|
+
if (!selectedKeys || !selectedKeys.has(activeKey)) {
|
|
36
21
|
return {
|
|
37
22
|
items: [
|
|
38
|
-
|
|
23
|
+
activeData
|
|
39
24
|
],
|
|
40
|
-
fromSelection: false
|
|
25
|
+
fromSelection: false,
|
|
26
|
+
activeSourceFolderId,
|
|
27
|
+
spansMultipleSources: false
|
|
41
28
|
};
|
|
42
29
|
}
|
|
43
30
|
const items = [];
|
|
@@ -46,24 +33,34 @@ var selection = require('../../utils/selection.js');
|
|
|
46
33
|
const kind = key.slice(0, separator);
|
|
47
34
|
const id = Number(key.slice(separator + 1));
|
|
48
35
|
if (kind === 'asset') {
|
|
36
|
+
if (activeData.kind === 'file' && activeData.id === id) {
|
|
37
|
+
items.push(activeData);
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
49
40
|
items.push({
|
|
50
41
|
kind: 'file',
|
|
51
42
|
id,
|
|
52
|
-
name:
|
|
53
|
-
folderId:
|
|
43
|
+
name: '',
|
|
44
|
+
folderId: itemLocations.locateItem(locations, 'file', id, fallbackFolderId)
|
|
54
45
|
});
|
|
55
46
|
return;
|
|
56
47
|
}
|
|
48
|
+
if (activeData.kind === 'folder' && activeData.id === id) {
|
|
49
|
+
items.push(activeData);
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
57
52
|
items.push({
|
|
58
53
|
kind: 'folder',
|
|
59
54
|
id,
|
|
60
|
-
name:
|
|
61
|
-
parentId:
|
|
55
|
+
name: '',
|
|
56
|
+
parentId: itemLocations.locateItem(locations, 'folder', id, fallbackFolderId)
|
|
62
57
|
});
|
|
63
58
|
});
|
|
64
59
|
return {
|
|
65
60
|
items,
|
|
66
|
-
fromSelection: true
|
|
61
|
+
fromSelection: true,
|
|
62
|
+
activeSourceFolderId,
|
|
63
|
+
spansMultipleSources: items.some((item)=>itemSource.sourceFolderIdOf(item) !== activeSourceFolderId)
|
|
67
64
|
};
|
|
68
65
|
};
|
|
69
66
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"buildDragSet.js","sources":["../../../../../../../admin/src/future/pages/Assets/components/Dnd/buildDragSet.ts"],"sourcesContent":["import { assetKey, folderKey, type ItemKey } from '../../utils/selection';\n\nimport type { DragItemData } from '../../../../types/dnd';\n\nexport interface DragSet {\n items: DragItemData[];\n /** True when the active item was already selected — membership is the full selection. */\n fromSelection: boolean;\n
|
|
1
|
+
{"version":3,"file":"buildDragSet.js","sources":["../../../../../../../admin/src/future/pages/Assets/components/Dnd/buildDragSet.ts"],"sourcesContent":["import { locateItem, type ItemLocations } from '../../../../utils/itemLocations';\nimport { sourceFolderIdOf } from '../../../../utils/itemSource';\nimport { assetKey, folderKey, type ItemKey } from '../../utils/selection';\n\nimport type { DragItemData } from '../../../../types/dnd';\n\nexport interface DragSet {\n items: DragItemData[];\n /** True when the active item was already selected — membership is the full selection. */\n fromSelection: boolean;\n /**\n * Location of the row the user actually grabbed — the only item in the set\n * whose origin the user can point at. Names the source in the success toast.\n */\n activeSourceFolderId: number | null;\n /**\n * True when the set spans more than one source folder, which a global search\n * selection can. There is then no single source to name, so the toast has to\n * drop it rather than pick one item's folder and imply the others came from\n * there too.\n */\n spansMultipleSources: boolean;\n}\n\n/**\n * Derive the drag payload once at drag start.\n *\n * - Dragging a selected item moves the complete current selection.\n * - Dragging an unselected item moves only that item.\n *\n * The active item carries its own location on `dragData` (the row it was\n * grabbed from); the rest of the selection is resolved through `locations`.\n * Neither is derived from the folder currently open, because search results are\n * global — see `utils/itemLocations.ts`.\n */\nexport const buildDragSet = (\n activeData: DragItemData,\n selectedKeys: Set<ItemKey> | undefined,\n locations: ItemLocations,\n fallbackFolderId: number | null\n): DragSet => {\n const activeKey: ItemKey =\n activeData.kind === 'file' ? assetKey(activeData.id) : folderKey(activeData.id);\n\n const activeSourceFolderId = sourceFolderIdOf(activeData);\n\n if (!selectedKeys || !selectedKeys.has(activeKey)) {\n return {\n items: [activeData],\n fromSelection: false,\n activeSourceFolderId,\n spansMultipleSources: false,\n };\n }\n\n const items: DragItemData[] = [];\n\n selectedKeys.forEach((key) => {\n const separator = key.indexOf(':');\n const kind = key.slice(0, separator);\n const id = Number(key.slice(separator + 1));\n\n if (kind === 'asset') {\n if (activeData.kind === 'file' && activeData.id === id) {\n items.push(activeData);\n return;\n }\n\n items.push({\n kind: 'file',\n id,\n name: '',\n folderId: locateItem(locations, 'file', id, fallbackFolderId),\n });\n return;\n }\n\n if (activeData.kind === 'folder' && activeData.id === id) {\n items.push(activeData);\n return;\n }\n\n items.push({\n kind: 'folder',\n id,\n name: '',\n parentId: locateItem(locations, 'folder', id, fallbackFolderId),\n });\n });\n\n return {\n items,\n fromSelection: true,\n activeSourceFolderId,\n spansMultipleSources: items.some((item) => sourceFolderIdOf(item) !== activeSourceFolderId),\n };\n};\n"],"names":["buildDragSet","activeData","selectedKeys","locations","fallbackFolderId","activeKey","kind","assetKey","id","folderKey","activeSourceFolderId","sourceFolderIdOf","has","items","fromSelection","spansMultipleSources","forEach","key","separator","indexOf","slice","Number","push","name","folderId","locateItem","parentId","some","item"],"mappings":";;;;;;AAwBA;;;;;;;;;;AAUC,IACM,MAAMA,YAAAA,GAAe,CAC1BC,UAAAA,EACAC,cACAC,SAAAA,EACAC,gBAAAA,GAAAA;IAEA,MAAMC,SAAAA,GACJJ,UAAAA,CAAWK,IAAI,KAAK,MAAA,GAASC,kBAAAA,CAASN,UAAAA,CAAWO,EAAE,CAAA,GAAIC,mBAAAA,CAAUR,UAAAA,CAAWO,EAAE,CAAA;AAEhF,IAAA,MAAME,uBAAuBC,2BAAAA,CAAiBV,UAAAA,CAAAA;AAE9C,IAAA,IAAI,CAACC,YAAAA,IAAgB,CAACA,YAAAA,CAAaU,GAAG,CAACP,SAAAA,CAAAA,EAAY;QACjD,OAAO;YACLQ,KAAAA,EAAO;AAACZ,gBAAAA;AAAW,aAAA;YACnBa,aAAAA,EAAe,KAAA;AACfJ,YAAAA,oBAAAA;YACAK,oBAAAA,EAAsB;AACxB,SAAA;AACF,IAAA;AAEA,IAAA,MAAMF,QAAwB,EAAE;IAEhCX,YAAAA,CAAac,OAAO,CAAC,CAACC,GAAAA,GAAAA;QACpB,MAAMC,SAAAA,GAAYD,GAAAA,CAAIE,OAAO,CAAC,GAAA,CAAA;AAC9B,QAAA,MAAMb,IAAAA,GAAOW,GAAAA,CAAIG,KAAK,CAAC,CAAA,EAAGF,SAAAA,CAAAA;AAC1B,QAAA,MAAMV,EAAAA,GAAKa,MAAAA,CAAOJ,GAAAA,CAAIG,KAAK,CAACF,SAAAA,GAAY,CAAA,CAAA,CAAA;AAExC,QAAA,IAAIZ,SAAS,OAAA,EAAS;AACpB,YAAA,IAAIL,WAAWK,IAAI,KAAK,UAAUL,UAAAA,CAAWO,EAAE,KAAKA,EAAAA,EAAI;AACtDK,gBAAAA,KAAAA,CAAMS,IAAI,CAACrB,UAAAA,CAAAA;AACX,gBAAA;AACF,YAAA;AAEAY,YAAAA,KAAAA,CAAMS,IAAI,CAAC;gBACThB,IAAAA,EAAM,MAAA;AACNE,gBAAAA,EAAAA;gBACAe,IAAAA,EAAM,EAAA;gBACNC,QAAAA,EAAUC,wBAAAA,CAAWtB,SAAAA,EAAW,MAAA,EAAQK,EAAAA,EAAIJ,gBAAAA;AAC9C,aAAA,CAAA;AACA,YAAA;AACF,QAAA;AAEA,QAAA,IAAIH,WAAWK,IAAI,KAAK,YAAYL,UAAAA,CAAWO,EAAE,KAAKA,EAAAA,EAAI;AACxDK,YAAAA,KAAAA,CAAMS,IAAI,CAACrB,UAAAA,CAAAA;AACX,YAAA;AACF,QAAA;AAEAY,QAAAA,KAAAA,CAAMS,IAAI,CAAC;YACThB,IAAAA,EAAM,QAAA;AACNE,YAAAA,EAAAA;YACAe,IAAAA,EAAM,EAAA;YACNG,QAAAA,EAAUD,wBAAAA,CAAWtB,SAAAA,EAAW,QAAA,EAAUK,EAAAA,EAAIJ,gBAAAA;AAChD,SAAA,CAAA;AACF,IAAA,CAAA,CAAA;IAEA,OAAO;AACLS,QAAAA,KAAAA;QACAC,aAAAA,EAAe,IAAA;AACfJ,QAAAA,oBAAAA;AACAK,QAAAA,oBAAAA,EAAsBF,MAAMc,IAAI,CAAC,CAACC,IAAAA,GAASjB,4BAAiBiB,IAAAA,CAAAA,KAAUlB,oBAAAA;AACxE,KAAA;AACF;;;;"}
|
|
@@ -1,41 +1,28 @@
|
|
|
1
|
+
import { locateItem } from '../../../../utils/itemLocations.mjs';
|
|
2
|
+
import { sourceFolderIdOf } from '../../../../utils/itemSource.mjs';
|
|
1
3
|
import { assetKey, folderKey } from '../../utils/selection.mjs';
|
|
2
4
|
|
|
3
|
-
/**
|
|
4
|
-
* Stamp an item with the authoritative current-folder location. Drag/selection is
|
|
5
|
-
* page-scoped to the current folder, so this is more reliable than the item's own
|
|
6
|
-
* `folderId`/`parentId` — a dragged folder's `parent` is not populated by the
|
|
7
|
-
* folders query, so its `parentId` would otherwise collapse to `null`.
|
|
8
|
-
*/ const locateItem = (item, currentFolderId)=>item.kind === 'file' ? {
|
|
9
|
-
...item,
|
|
10
|
-
folderId: currentFolderId
|
|
11
|
-
} : {
|
|
12
|
-
...item,
|
|
13
|
-
parentId: currentFolderId
|
|
14
|
-
};
|
|
15
5
|
/**
|
|
16
6
|
* Derive the drag payload once at drag start.
|
|
17
7
|
*
|
|
18
8
|
* - Dragging a selected item moves the complete current selection.
|
|
19
9
|
* - Dragging an unselected item moves only that item.
|
|
20
10
|
*
|
|
21
|
-
*
|
|
22
|
-
*
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
items: [
|
|
27
|
-
locateItem(activeData, currentFolderId)
|
|
28
|
-
],
|
|
29
|
-
fromSelection: false
|
|
30
|
-
};
|
|
31
|
-
}
|
|
11
|
+
* The active item carries its own location on `dragData` (the row it was
|
|
12
|
+
* grabbed from); the rest of the selection is resolved through `locations`.
|
|
13
|
+
* Neither is derived from the folder currently open, because search results are
|
|
14
|
+
* global — see `utils/itemLocations.ts`.
|
|
15
|
+
*/ const buildDragSet = (activeData, selectedKeys, locations, fallbackFolderId)=>{
|
|
32
16
|
const activeKey = activeData.kind === 'file' ? assetKey(activeData.id) : folderKey(activeData.id);
|
|
33
|
-
|
|
17
|
+
const activeSourceFolderId = sourceFolderIdOf(activeData);
|
|
18
|
+
if (!selectedKeys || !selectedKeys.has(activeKey)) {
|
|
34
19
|
return {
|
|
35
20
|
items: [
|
|
36
|
-
|
|
21
|
+
activeData
|
|
37
22
|
],
|
|
38
|
-
fromSelection: false
|
|
23
|
+
fromSelection: false,
|
|
24
|
+
activeSourceFolderId,
|
|
25
|
+
spansMultipleSources: false
|
|
39
26
|
};
|
|
40
27
|
}
|
|
41
28
|
const items = [];
|
|
@@ -44,24 +31,34 @@ import { assetKey, folderKey } from '../../utils/selection.mjs';
|
|
|
44
31
|
const kind = key.slice(0, separator);
|
|
45
32
|
const id = Number(key.slice(separator + 1));
|
|
46
33
|
if (kind === 'asset') {
|
|
34
|
+
if (activeData.kind === 'file' && activeData.id === id) {
|
|
35
|
+
items.push(activeData);
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
47
38
|
items.push({
|
|
48
39
|
kind: 'file',
|
|
49
40
|
id,
|
|
50
|
-
name:
|
|
51
|
-
folderId:
|
|
41
|
+
name: '',
|
|
42
|
+
folderId: locateItem(locations, 'file', id, fallbackFolderId)
|
|
52
43
|
});
|
|
53
44
|
return;
|
|
54
45
|
}
|
|
46
|
+
if (activeData.kind === 'folder' && activeData.id === id) {
|
|
47
|
+
items.push(activeData);
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
55
50
|
items.push({
|
|
56
51
|
kind: 'folder',
|
|
57
52
|
id,
|
|
58
|
-
name:
|
|
59
|
-
parentId:
|
|
53
|
+
name: '',
|
|
54
|
+
parentId: locateItem(locations, 'folder', id, fallbackFolderId)
|
|
60
55
|
});
|
|
61
56
|
});
|
|
62
57
|
return {
|
|
63
58
|
items,
|
|
64
|
-
fromSelection: true
|
|
59
|
+
fromSelection: true,
|
|
60
|
+
activeSourceFolderId,
|
|
61
|
+
spansMultipleSources: items.some((item)=>sourceFolderIdOf(item) !== activeSourceFolderId)
|
|
65
62
|
};
|
|
66
63
|
};
|
|
67
64
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"buildDragSet.mjs","sources":["../../../../../../../admin/src/future/pages/Assets/components/Dnd/buildDragSet.ts"],"sourcesContent":["import { assetKey, folderKey, type ItemKey } from '../../utils/selection';\n\nimport type { DragItemData } from '../../../../types/dnd';\n\nexport interface DragSet {\n items: DragItemData[];\n /** True when the active item was already selected — membership is the full selection. */\n fromSelection: boolean;\n
|
|
1
|
+
{"version":3,"file":"buildDragSet.mjs","sources":["../../../../../../../admin/src/future/pages/Assets/components/Dnd/buildDragSet.ts"],"sourcesContent":["import { locateItem, type ItemLocations } from '../../../../utils/itemLocations';\nimport { sourceFolderIdOf } from '../../../../utils/itemSource';\nimport { assetKey, folderKey, type ItemKey } from '../../utils/selection';\n\nimport type { DragItemData } from '../../../../types/dnd';\n\nexport interface DragSet {\n items: DragItemData[];\n /** True when the active item was already selected — membership is the full selection. */\n fromSelection: boolean;\n /**\n * Location of the row the user actually grabbed — the only item in the set\n * whose origin the user can point at. Names the source in the success toast.\n */\n activeSourceFolderId: number | null;\n /**\n * True when the set spans more than one source folder, which a global search\n * selection can. There is then no single source to name, so the toast has to\n * drop it rather than pick one item's folder and imply the others came from\n * there too.\n */\n spansMultipleSources: boolean;\n}\n\n/**\n * Derive the drag payload once at drag start.\n *\n * - Dragging a selected item moves the complete current selection.\n * - Dragging an unselected item moves only that item.\n *\n * The active item carries its own location on `dragData` (the row it was\n * grabbed from); the rest of the selection is resolved through `locations`.\n * Neither is derived from the folder currently open, because search results are\n * global — see `utils/itemLocations.ts`.\n */\nexport const buildDragSet = (\n activeData: DragItemData,\n selectedKeys: Set<ItemKey> | undefined,\n locations: ItemLocations,\n fallbackFolderId: number | null\n): DragSet => {\n const activeKey: ItemKey =\n activeData.kind === 'file' ? assetKey(activeData.id) : folderKey(activeData.id);\n\n const activeSourceFolderId = sourceFolderIdOf(activeData);\n\n if (!selectedKeys || !selectedKeys.has(activeKey)) {\n return {\n items: [activeData],\n fromSelection: false,\n activeSourceFolderId,\n spansMultipleSources: false,\n };\n }\n\n const items: DragItemData[] = [];\n\n selectedKeys.forEach((key) => {\n const separator = key.indexOf(':');\n const kind = key.slice(0, separator);\n const id = Number(key.slice(separator + 1));\n\n if (kind === 'asset') {\n if (activeData.kind === 'file' && activeData.id === id) {\n items.push(activeData);\n return;\n }\n\n items.push({\n kind: 'file',\n id,\n name: '',\n folderId: locateItem(locations, 'file', id, fallbackFolderId),\n });\n return;\n }\n\n if (activeData.kind === 'folder' && activeData.id === id) {\n items.push(activeData);\n return;\n }\n\n items.push({\n kind: 'folder',\n id,\n name: '',\n parentId: locateItem(locations, 'folder', id, fallbackFolderId),\n });\n });\n\n return {\n items,\n fromSelection: true,\n activeSourceFolderId,\n spansMultipleSources: items.some((item) => sourceFolderIdOf(item) !== activeSourceFolderId),\n };\n};\n"],"names":["buildDragSet","activeData","selectedKeys","locations","fallbackFolderId","activeKey","kind","assetKey","id","folderKey","activeSourceFolderId","sourceFolderIdOf","has","items","fromSelection","spansMultipleSources","forEach","key","separator","indexOf","slice","Number","push","name","folderId","locateItem","parentId","some","item"],"mappings":";;;;AAwBA;;;;;;;;;;AAUC,IACM,MAAMA,YAAAA,GAAe,CAC1BC,UAAAA,EACAC,cACAC,SAAAA,EACAC,gBAAAA,GAAAA;IAEA,MAAMC,SAAAA,GACJJ,UAAAA,CAAWK,IAAI,KAAK,MAAA,GAASC,QAAAA,CAASN,UAAAA,CAAWO,EAAE,CAAA,GAAIC,SAAAA,CAAUR,UAAAA,CAAWO,EAAE,CAAA;AAEhF,IAAA,MAAME,uBAAuBC,gBAAAA,CAAiBV,UAAAA,CAAAA;AAE9C,IAAA,IAAI,CAACC,YAAAA,IAAgB,CAACA,YAAAA,CAAaU,GAAG,CAACP,SAAAA,CAAAA,EAAY;QACjD,OAAO;YACLQ,KAAAA,EAAO;AAACZ,gBAAAA;AAAW,aAAA;YACnBa,aAAAA,EAAe,KAAA;AACfJ,YAAAA,oBAAAA;YACAK,oBAAAA,EAAsB;AACxB,SAAA;AACF,IAAA;AAEA,IAAA,MAAMF,QAAwB,EAAE;IAEhCX,YAAAA,CAAac,OAAO,CAAC,CAACC,GAAAA,GAAAA;QACpB,MAAMC,SAAAA,GAAYD,GAAAA,CAAIE,OAAO,CAAC,GAAA,CAAA;AAC9B,QAAA,MAAMb,IAAAA,GAAOW,GAAAA,CAAIG,KAAK,CAAC,CAAA,EAAGF,SAAAA,CAAAA;AAC1B,QAAA,MAAMV,EAAAA,GAAKa,MAAAA,CAAOJ,GAAAA,CAAIG,KAAK,CAACF,SAAAA,GAAY,CAAA,CAAA,CAAA;AAExC,QAAA,IAAIZ,SAAS,OAAA,EAAS;AACpB,YAAA,IAAIL,WAAWK,IAAI,KAAK,UAAUL,UAAAA,CAAWO,EAAE,KAAKA,EAAAA,EAAI;AACtDK,gBAAAA,KAAAA,CAAMS,IAAI,CAACrB,UAAAA,CAAAA;AACX,gBAAA;AACF,YAAA;AAEAY,YAAAA,KAAAA,CAAMS,IAAI,CAAC;gBACThB,IAAAA,EAAM,MAAA;AACNE,gBAAAA,EAAAA;gBACAe,IAAAA,EAAM,EAAA;gBACNC,QAAAA,EAAUC,UAAAA,CAAWtB,SAAAA,EAAW,MAAA,EAAQK,EAAAA,EAAIJ,gBAAAA;AAC9C,aAAA,CAAA;AACA,YAAA;AACF,QAAA;AAEA,QAAA,IAAIH,WAAWK,IAAI,KAAK,YAAYL,UAAAA,CAAWO,EAAE,KAAKA,EAAAA,EAAI;AACxDK,YAAAA,KAAAA,CAAMS,IAAI,CAACrB,UAAAA,CAAAA;AACX,YAAA;AACF,QAAA;AAEAY,QAAAA,KAAAA,CAAMS,IAAI,CAAC;YACThB,IAAAA,EAAM,QAAA;AACNE,YAAAA,EAAAA;YACAe,IAAAA,EAAM,EAAA;YACNG,QAAAA,EAAUD,UAAAA,CAAWtB,SAAAA,EAAW,QAAA,EAAUK,EAAAA,EAAIJ,gBAAAA;AAChD,SAAA,CAAA;AACF,IAAA,CAAA,CAAA;IAEA,OAAO;AACLS,QAAAA,KAAAA;QACAC,aAAAA,EAAe,IAAA;AACfJ,QAAAA,oBAAAA;AACAK,QAAAA,oBAAAA,EAAsBF,MAAMc,IAAI,CAAC,CAACC,IAAAA,GAASjB,iBAAiBiB,IAAAA,CAAAA,KAAUlB,oBAAAA;AACxE,KAAA;AACF;;;;"}
|
|
@@ -2,21 +2,10 @@
|
|
|
2
2
|
|
|
3
3
|
var React = require('react');
|
|
4
4
|
var core = require('@dnd-kit/core');
|
|
5
|
+
var getRelationId = require('../../../../utils/getRelationId.js');
|
|
5
6
|
var AssetsDndProvider = require('./AssetsDndProvider.js');
|
|
6
7
|
var dndIds = require('./dndIds.js');
|
|
7
8
|
|
|
8
|
-
const getFileFolderId = (folder)=>{
|
|
9
|
-
if (folder == null) {
|
|
10
|
-
return null;
|
|
11
|
-
}
|
|
12
|
-
if (typeof folder === 'object') {
|
|
13
|
-
return folder.id ?? null;
|
|
14
|
-
}
|
|
15
|
-
if (typeof folder === 'number') {
|
|
16
|
-
return folder;
|
|
17
|
-
}
|
|
18
|
-
return Number(folder) || null;
|
|
19
|
-
};
|
|
20
9
|
const useFileDraggable = (asset)=>{
|
|
21
10
|
const { isMovePending } = AssetsDndProvider.useAssetsDndOptional() ?? {
|
|
22
11
|
isMovePending: false
|
|
@@ -25,17 +14,23 @@ const useFileDraggable = (asset)=>{
|
|
|
25
14
|
kind: 'file',
|
|
26
15
|
id: asset.id,
|
|
27
16
|
name: asset.name,
|
|
28
|
-
folderId:
|
|
17
|
+
folderId: getRelationId.getRelationId(asset.folder)
|
|
29
18
|
}), [
|
|
30
19
|
asset.folder,
|
|
31
20
|
asset.id,
|
|
32
21
|
asset.name
|
|
33
22
|
]);
|
|
34
|
-
|
|
23
|
+
const draggable = core.useDraggable({
|
|
35
24
|
id: dndIds.toFileDraggableId(asset.id),
|
|
36
25
|
data,
|
|
37
26
|
disabled: isMovePending
|
|
38
27
|
});
|
|
28
|
+
// `dragData` is re-exposed (like `useFolderDraggableDroppable` does) so the
|
|
29
|
+
// row's actions menu can hand the move dialog the asset's real folder.
|
|
30
|
+
return {
|
|
31
|
+
...draggable,
|
|
32
|
+
dragData: data
|
|
33
|
+
};
|
|
39
34
|
};
|
|
40
35
|
const useFolderDraggableDroppable = (folder)=>{
|
|
41
36
|
const { isMovePending, isValidDropTarget } = AssetsDndProvider.useAssetsDndOptional() ?? {
|
|
@@ -43,7 +38,7 @@ const useFolderDraggableDroppable = (folder)=>{
|
|
|
43
38
|
isValidDropTarget: ()=>false
|
|
44
39
|
};
|
|
45
40
|
const { active } = core.useDndContext();
|
|
46
|
-
const parentId =
|
|
41
|
+
const parentId = getRelationId.getRelationId(folder.parent);
|
|
47
42
|
const dragData = React.useMemo(()=>({
|
|
48
43
|
kind: 'folder',
|
|
49
44
|
id: folder.id,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useAssetDnd.js","sources":["../../../../../../../admin/src/future/pages/Assets/components/Dnd/useAssetDnd.ts"],"sourcesContent":["import { useMemo } from 'react';\n\nimport { useDndContext, useDraggable, useDroppable } from '@dnd-kit/core';\n\nimport { useAssetsDndOptional } from './AssetsDndProvider';\nimport { toFileDraggableId, toFolderDraggableId, toFolderTargetId } from './dndIds';\n\nimport type { DragFileData, DragFolderData, FolderTargetData } from '../../../../types/dnd';\n\
|
|
1
|
+
{"version":3,"file":"useAssetDnd.js","sources":["../../../../../../../admin/src/future/pages/Assets/components/Dnd/useAssetDnd.ts"],"sourcesContent":["import { useMemo } from 'react';\n\nimport { useDndContext, useDraggable, useDroppable } from '@dnd-kit/core';\n\nimport { getRelationId } from '../../../../utils/getRelationId';\n\nimport { useAssetsDndOptional } from './AssetsDndProvider';\nimport { toFileDraggableId, toFolderDraggableId, toFolderTargetId } from './dndIds';\n\nimport type { DragFileData, DragFolderData, FolderTargetData } from '../../../../types/dnd';\n\nexport const useFileDraggable = (asset: {\n id: number;\n name: string;\n folder?: number | string | { id?: number } | null;\n}) => {\n const { isMovePending } = useAssetsDndOptional() ?? { isMovePending: false };\n\n const data = useMemo<DragFileData>(\n () => ({\n kind: 'file',\n id: asset.id,\n name: asset.name,\n folderId: getRelationId(asset.folder),\n }),\n [asset.folder, asset.id, asset.name]\n );\n\n const draggable = useDraggable({\n id: toFileDraggableId(asset.id),\n data,\n disabled: isMovePending,\n });\n\n // `dragData` is re-exposed (like `useFolderDraggableDroppable` does) so the\n // row's actions menu can hand the move dialog the asset's real folder.\n return { ...draggable, dragData: data };\n};\n\nexport const useFolderDraggableDroppable = (folder: {\n id: number;\n name: string;\n parent?: number | null | { id?: number };\n}) => {\n const { isMovePending, isValidDropTarget } = useAssetsDndOptional() ?? {\n isMovePending: false,\n isValidDropTarget: () => false,\n };\n const { active } = useDndContext();\n\n const parentId = getRelationId(folder.parent);\n\n const dragData = useMemo<DragFolderData>(\n () => ({\n kind: 'folder',\n id: folder.id,\n name: folder.name,\n parentId,\n }),\n [folder.id, folder.name, parentId]\n );\n\n const dropData = useMemo<FolderTargetData>(\n () => ({\n kind: 'folder-target',\n id: folder.id,\n name: folder.name,\n }),\n [folder.id, folder.name]\n );\n\n const draggable = useDraggable({\n id: toFolderDraggableId(folder.id),\n data: dragData,\n disabled: isMovePending,\n });\n\n const droppable = useDroppable({\n id: toFolderTargetId(folder.id),\n data: dropData,\n disabled: isMovePending,\n });\n\n const isValidTarget = isValidDropTarget(folder.id);\n const isOver = droppable.isOver;\n const showValidDropHighlight = isOver && isValidTarget;\n const showInvalidDropCursor = isOver && !isValidTarget && active != null;\n\n return {\n dragData,\n draggable,\n droppable,\n isDragging: draggable.isDragging,\n showValidDropHighlight,\n showInvalidDropCursor,\n };\n};\n"],"names":["useFileDraggable","asset","isMovePending","useAssetsDndOptional","data","useMemo","kind","id","name","folderId","getRelationId","folder","draggable","useDraggable","toFileDraggableId","disabled","dragData","useFolderDraggableDroppable","isValidDropTarget","active","useDndContext","parentId","parent","dropData","toFolderDraggableId","droppable","useDroppable","toFolderTargetId","isValidTarget","isOver","showValidDropHighlight","showInvalidDropCursor","isDragging"],"mappings":"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"}
|
|
@@ -1,20 +1,9 @@
|
|
|
1
1
|
import { useMemo } from 'react';
|
|
2
2
|
import { useDndContext, useDraggable, useDroppable } from '@dnd-kit/core';
|
|
3
|
+
import { getRelationId } from '../../../../utils/getRelationId.mjs';
|
|
3
4
|
import { useAssetsDndOptional } from './AssetsDndProvider.mjs';
|
|
4
5
|
import { toFolderDraggableId, toFolderTargetId, toFileDraggableId } from './dndIds.mjs';
|
|
5
6
|
|
|
6
|
-
const getFileFolderId = (folder)=>{
|
|
7
|
-
if (folder == null) {
|
|
8
|
-
return null;
|
|
9
|
-
}
|
|
10
|
-
if (typeof folder === 'object') {
|
|
11
|
-
return folder.id ?? null;
|
|
12
|
-
}
|
|
13
|
-
if (typeof folder === 'number') {
|
|
14
|
-
return folder;
|
|
15
|
-
}
|
|
16
|
-
return Number(folder) || null;
|
|
17
|
-
};
|
|
18
7
|
const useFileDraggable = (asset)=>{
|
|
19
8
|
const { isMovePending } = useAssetsDndOptional() ?? {
|
|
20
9
|
isMovePending: false
|
|
@@ -23,17 +12,23 @@ const useFileDraggable = (asset)=>{
|
|
|
23
12
|
kind: 'file',
|
|
24
13
|
id: asset.id,
|
|
25
14
|
name: asset.name,
|
|
26
|
-
folderId:
|
|
15
|
+
folderId: getRelationId(asset.folder)
|
|
27
16
|
}), [
|
|
28
17
|
asset.folder,
|
|
29
18
|
asset.id,
|
|
30
19
|
asset.name
|
|
31
20
|
]);
|
|
32
|
-
|
|
21
|
+
const draggable = useDraggable({
|
|
33
22
|
id: toFileDraggableId(asset.id),
|
|
34
23
|
data,
|
|
35
24
|
disabled: isMovePending
|
|
36
25
|
});
|
|
26
|
+
// `dragData` is re-exposed (like `useFolderDraggableDroppable` does) so the
|
|
27
|
+
// row's actions menu can hand the move dialog the asset's real folder.
|
|
28
|
+
return {
|
|
29
|
+
...draggable,
|
|
30
|
+
dragData: data
|
|
31
|
+
};
|
|
37
32
|
};
|
|
38
33
|
const useFolderDraggableDroppable = (folder)=>{
|
|
39
34
|
const { isMovePending, isValidDropTarget } = useAssetsDndOptional() ?? {
|
|
@@ -41,7 +36,7 @@ const useFolderDraggableDroppable = (folder)=>{
|
|
|
41
36
|
isValidDropTarget: ()=>false
|
|
42
37
|
};
|
|
43
38
|
const { active } = useDndContext();
|
|
44
|
-
const parentId =
|
|
39
|
+
const parentId = getRelationId(folder.parent);
|
|
45
40
|
const dragData = useMemo(()=>({
|
|
46
41
|
kind: 'folder',
|
|
47
42
|
id: folder.id,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useAssetDnd.mjs","sources":["../../../../../../../admin/src/future/pages/Assets/components/Dnd/useAssetDnd.ts"],"sourcesContent":["import { useMemo } from 'react';\n\nimport { useDndContext, useDraggable, useDroppable } from '@dnd-kit/core';\n\nimport { useAssetsDndOptional } from './AssetsDndProvider';\nimport { toFileDraggableId, toFolderDraggableId, toFolderTargetId } from './dndIds';\n\nimport type { DragFileData, DragFolderData, FolderTargetData } from '../../../../types/dnd';\n\
|
|
1
|
+
{"version":3,"file":"useAssetDnd.mjs","sources":["../../../../../../../admin/src/future/pages/Assets/components/Dnd/useAssetDnd.ts"],"sourcesContent":["import { useMemo } from 'react';\n\nimport { useDndContext, useDraggable, useDroppable } from '@dnd-kit/core';\n\nimport { getRelationId } from '../../../../utils/getRelationId';\n\nimport { useAssetsDndOptional } from './AssetsDndProvider';\nimport { toFileDraggableId, toFolderDraggableId, toFolderTargetId } from './dndIds';\n\nimport type { DragFileData, DragFolderData, FolderTargetData } from '../../../../types/dnd';\n\nexport const useFileDraggable = (asset: {\n id: number;\n name: string;\n folder?: number | string | { id?: number } | null;\n}) => {\n const { isMovePending } = useAssetsDndOptional() ?? { isMovePending: false };\n\n const data = useMemo<DragFileData>(\n () => ({\n kind: 'file',\n id: asset.id,\n name: asset.name,\n folderId: getRelationId(asset.folder),\n }),\n [asset.folder, asset.id, asset.name]\n );\n\n const draggable = useDraggable({\n id: toFileDraggableId(asset.id),\n data,\n disabled: isMovePending,\n });\n\n // `dragData` is re-exposed (like `useFolderDraggableDroppable` does) so the\n // row's actions menu can hand the move dialog the asset's real folder.\n return { ...draggable, dragData: data };\n};\n\nexport const useFolderDraggableDroppable = (folder: {\n id: number;\n name: string;\n parent?: number | null | { id?: number };\n}) => {\n const { isMovePending, isValidDropTarget } = useAssetsDndOptional() ?? {\n isMovePending: false,\n isValidDropTarget: () => false,\n };\n const { active } = useDndContext();\n\n const parentId = getRelationId(folder.parent);\n\n const dragData = useMemo<DragFolderData>(\n () => ({\n kind: 'folder',\n id: folder.id,\n name: folder.name,\n parentId,\n }),\n [folder.id, folder.name, parentId]\n );\n\n const dropData = useMemo<FolderTargetData>(\n () => ({\n kind: 'folder-target',\n id: folder.id,\n name: folder.name,\n }),\n [folder.id, folder.name]\n );\n\n const draggable = useDraggable({\n id: toFolderDraggableId(folder.id),\n data: dragData,\n disabled: isMovePending,\n });\n\n const droppable = useDroppable({\n id: toFolderTargetId(folder.id),\n data: dropData,\n disabled: isMovePending,\n });\n\n const isValidTarget = isValidDropTarget(folder.id);\n const isOver = droppable.isOver;\n const showValidDropHighlight = isOver && isValidTarget;\n const showInvalidDropCursor = isOver && !isValidTarget && active != null;\n\n return {\n dragData,\n draggable,\n droppable,\n isDragging: draggable.isDragging,\n showValidDropHighlight,\n showInvalidDropCursor,\n };\n};\n"],"names":["useFileDraggable","asset","isMovePending","useAssetsDndOptional","data","useMemo","kind","id","name","folderId","getRelationId","folder","draggable","useDraggable","toFileDraggableId","disabled","dragData","useFolderDraggableDroppable","isValidDropTarget","active","useDndContext","parentId","parent","dropData","toFolderDraggableId","droppable","useDroppable","toFolderTargetId","isValidTarget","isOver","showValidDropHighlight","showInvalidDropCursor","isDragging"],"mappings":"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"}
|
|
@@ -26,10 +26,13 @@ const Segment = styledComponents.styled.button`
|
|
|
26
26
|
border: none;
|
|
27
27
|
background: transparent;
|
|
28
28
|
font: inherit;
|
|
29
|
-
padding: ${({ theme })=>`${theme.spaces[
|
|
29
|
+
padding: ${({ theme })=>`${theme.spaces[2]} ${theme.spaces[3]}`};
|
|
30
30
|
cursor: ${({ $interactive })=>$interactive ? 'pointer' : 'default'};
|
|
31
31
|
border-right: 1px solid ${({ theme })=>theme.colors.neutral200};
|
|
32
32
|
|
|
33
|
+
${({ theme })=>theme.breakpoints.medium} {
|
|
34
|
+
padding: ${({ theme })=>`${theme.spaces[1]} ${theme.spaces[2]}`};
|
|
35
|
+
}
|
|
33
36
|
${({ $interactive, theme })=>$interactive && `&:hover { background: ${theme.colors.primary100}; }`}
|
|
34
37
|
|
|
35
38
|
&:focus-visible {
|
|
@@ -386,15 +389,21 @@ const FilterBadge = ({ filter, onChange, onRemove })=>{
|
|
|
386
389
|
]
|
|
387
390
|
});
|
|
388
391
|
};
|
|
389
|
-
|
|
392
|
+
// Tighten the gap above the badges when the sticky header is in its compact
|
|
393
|
+
// (scrolled) state, matching the header's own shrink.
|
|
394
|
+
const BadgesRoot = styledComponents.styled(designSystem.Flex)`
|
|
395
|
+
padding-top: ${({ theme, $compact })=>$compact ? theme.spaces[1] : theme.spaces[6]};
|
|
396
|
+
transition: padding-top 0.2s ease;
|
|
397
|
+
`;
|
|
398
|
+
const FilterBadges = ({ listFilters, compact = false })=>{
|
|
390
399
|
const { filters, updateFilter, removeFilter } = listFilters;
|
|
391
400
|
if (filters.length === 0) {
|
|
392
401
|
return null;
|
|
393
402
|
}
|
|
394
|
-
return /*#__PURE__*/ jsxRuntime.jsx(
|
|
403
|
+
return /*#__PURE__*/ jsxRuntime.jsx(BadgesRoot, {
|
|
404
|
+
$compact: compact,
|
|
395
405
|
gap: 2,
|
|
396
406
|
wrap: "wrap",
|
|
397
|
-
paddingTop: 2,
|
|
398
407
|
"data-testid": "filter-badges",
|
|
399
408
|
children: filters.map((filter, index)=>/*#__PURE__*/ jsxRuntime.jsx(FilterBadge, {
|
|
400
409
|
filter: filter,
|