@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
|
@@ -6,19 +6,35 @@ var icons = require('@strapi/icons');
|
|
|
6
6
|
var reactIntl = require('react-intl');
|
|
7
7
|
var styledComponents = require('styled-components');
|
|
8
8
|
var enums = require('../../../../enums.js');
|
|
9
|
+
var TruncatedText = require('../../../components/TruncatedText.js');
|
|
9
10
|
var useMediaLibraryPermissions = require('../../../hooks/useMediaLibraryPermissions.js');
|
|
10
11
|
var files = require('../../../utils/files.js');
|
|
11
12
|
var getAssetIcon = require('../../../utils/getAssetIcon.js');
|
|
13
|
+
var isEventFromWithin = require('../../../utils/isEventFromWithin.js');
|
|
12
14
|
var translations = require('../../../utils/translations.js');
|
|
13
15
|
var useAssetSelection = require('../hooks/useAssetSelection.js');
|
|
16
|
+
var useBusyAssets = require('../hooks/useBusyAssets.js');
|
|
14
17
|
var useFolderNavigation = require('../hooks/useFolderNavigation.js');
|
|
15
18
|
var selection = require('../utils/selection.js');
|
|
19
|
+
var AssetActionsMenu = require('./AssetActionsMenu.js');
|
|
20
|
+
var BusyOverlay = require('./BusyOverlay.js');
|
|
16
21
|
var AssetsDndProvider = require('./Dnd/AssetsDndProvider.js');
|
|
17
22
|
var useAssetDnd = require('./Dnd/useAssetDnd.js');
|
|
23
|
+
var FolderActionsMenu = require('./FolderActionsMenu.js');
|
|
18
24
|
|
|
19
25
|
/* -------------------------------------------------------------------------------------------------
|
|
20
26
|
* AssetsGrid
|
|
21
|
-
* -----------------------------------------------------------------------------------------------*/ //
|
|
27
|
+
* -----------------------------------------------------------------------------------------------*/ // Cards own click, Enter and Space; the controls sitting on them (checkbox, "..."
|
|
28
|
+
// menu) must not let those reach the card. Scoped to the wrapper's own DOM
|
|
29
|
+
// subtree so the menu's portaled content — a React child of the wrapper, but
|
|
30
|
+
// never a DOM descendant — still reaches `document`, where Radix listens in
|
|
31
|
+
// order to dismiss its layers.
|
|
32
|
+
const stopCardEvent = (e)=>{
|
|
33
|
+
if (isEventFromWithin.isEventFromWithin(e)) {
|
|
34
|
+
e.stopPropagation();
|
|
35
|
+
}
|
|
36
|
+
};
|
|
37
|
+
// Top-left selection checkbox overlaid on the asset preview, always visible.
|
|
22
38
|
const CheckboxOverlay = styledComponents.styled(designSystem.Flex)`
|
|
23
39
|
position: absolute;
|
|
24
40
|
top: ${({ theme })=>theme.spaces[3]};
|
|
@@ -31,9 +47,11 @@ const StyledCard = styledComponents.styled(designSystem.Card)`
|
|
|
31
47
|
${({ theme, $isSelected })=>$isSelected ? theme.colors.primary600 : theme.colors.neutral200};
|
|
32
48
|
border-radius: 8px;
|
|
33
49
|
overflow: hidden;
|
|
34
|
-
cursor: ${({ $isMovePending })=>$isMovePending ? 'wait' : 'pointer'};
|
|
50
|
+
cursor: ${({ $isMovePending, $isBusy })=>$isMovePending || $isBusy ? 'wait' : 'pointer'};
|
|
35
51
|
opacity: ${({ $isDragging })=>$isDragging ? 0.4 : 1};
|
|
36
|
-
|
|
52
|
+
/* No opacity change while busy — the overlay does the dimming, and stacking
|
|
53
|
+
one on the other would wash the card out. */
|
|
54
|
+
pointer-events: ${({ $isMovePending, $isBusy })=>$isMovePending || $isBusy ? 'none' : 'auto'};
|
|
37
55
|
background: ${({ theme, $isSelected })=>$isSelected ? theme.colors.primary100 : undefined};
|
|
38
56
|
/* Shift+click range selection must not highlight card text. */
|
|
39
57
|
user-select: none;
|
|
@@ -90,7 +108,7 @@ const FolderIconContainer = styledComponents.styled(designSystem.Flex)`
|
|
|
90
108
|
flex-shrink: 0;
|
|
91
109
|
color: ${({ theme })=>theme.colors.neutral600};
|
|
92
110
|
`;
|
|
93
|
-
const FolderName = styledComponents.styled(
|
|
111
|
+
const FolderName = styledComponents.styled(TruncatedText.TruncatedText)`
|
|
94
112
|
flex: 1;
|
|
95
113
|
min-width: 0;
|
|
96
114
|
`;
|
|
@@ -102,7 +120,7 @@ const FolderCard = ({ folder, orderedItemKeys })=>{
|
|
|
102
120
|
};
|
|
103
121
|
const { isSelected, toggle, selectRange } = useAssetSelection.useAssetSelection();
|
|
104
122
|
const { canUpdate } = useMediaLibraryPermissions.useMediaLibraryPermissions();
|
|
105
|
-
const { draggable: { attributes, listeners, setNodeRef: setDragRef, isDragging }, droppable: { setNodeRef: setDropRef }, showValidDropHighlight, showInvalidDropCursor } = useAssetDnd.useFolderDraggableDroppable(folder);
|
|
123
|
+
const { dragData, draggable: { attributes, listeners, setNodeRef: setDragRef, isDragging }, droppable: { setNodeRef: setDropRef }, showValidDropHighlight, showInvalidDropCursor } = useAssetDnd.useFolderDraggableDroppable(folder);
|
|
106
124
|
const key = selection.folderKey(folder.id);
|
|
107
125
|
const setNodeRef = (node)=>{
|
|
108
126
|
setDragRef(node);
|
|
@@ -111,7 +129,14 @@ const FolderCard = ({ folder, orderedItemKeys })=>{
|
|
|
111
129
|
// Folders share the selection mechanism with assets (toggle, range,
|
|
112
130
|
// select-all). Only the plain-click semantic differs: it navigates into the
|
|
113
131
|
// folder instead of selecting it.
|
|
132
|
+
//
|
|
133
|
+
// The containment guard on this and the handlers below is what keeps the
|
|
134
|
+
// actions menu's portaled dialogs — React children of this card — from
|
|
135
|
+
// navigating into the folder or starting a drag.
|
|
114
136
|
const handleClick = (e)=>{
|
|
137
|
+
if (!isEventFromWithin.isEventFromWithin(e)) {
|
|
138
|
+
return;
|
|
139
|
+
}
|
|
115
140
|
if (e.shiftKey) {
|
|
116
141
|
selectRange(orderedItemKeys, key);
|
|
117
142
|
} else if (e.metaKey || e.ctrlKey) {
|
|
@@ -121,6 +146,9 @@ const FolderCard = ({ folder, orderedItemKeys })=>{
|
|
|
121
146
|
}
|
|
122
147
|
};
|
|
123
148
|
const handleKeyDown = (e)=>{
|
|
149
|
+
if (!isEventFromWithin.isEventFromWithin(e)) {
|
|
150
|
+
return;
|
|
151
|
+
}
|
|
124
152
|
if (e.key === 'Enter') {
|
|
125
153
|
e.preventDefault();
|
|
126
154
|
navigateToFolder(folder);
|
|
@@ -149,6 +177,11 @@ const FolderCard = ({ folder, orderedItemKeys })=>{
|
|
|
149
177
|
$isSelected: isSelected(key),
|
|
150
178
|
onClick: handleClick,
|
|
151
179
|
onKeyDown: handleKeyDown,
|
|
180
|
+
onPointerDown: (e)=>{
|
|
181
|
+
if (isEventFromWithin.isEventFromWithin(e)) {
|
|
182
|
+
listeners?.onPointerDown?.(e);
|
|
183
|
+
}
|
|
184
|
+
},
|
|
152
185
|
role: "listitem",
|
|
153
186
|
tabIndex: 0,
|
|
154
187
|
children: [
|
|
@@ -173,17 +206,16 @@ const FolderCard = ({ folder, orderedItemKeys })=>{
|
|
|
173
206
|
}),
|
|
174
207
|
/*#__PURE__*/ jsxRuntime.jsx(FolderName, {
|
|
175
208
|
textColor: "neutral800",
|
|
176
|
-
ellipsis: true,
|
|
177
209
|
children: folder.name
|
|
178
210
|
}),
|
|
179
|
-
/*#__PURE__*/ jsxRuntime.jsx(designSystem.
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
211
|
+
/*#__PURE__*/ jsxRuntime.jsx(designSystem.Flex, {
|
|
212
|
+
onClick: stopCardEvent,
|
|
213
|
+
onKeyDown: stopCardEvent,
|
|
214
|
+
onPointerDown: stopCardEvent,
|
|
215
|
+
children: /*#__PURE__*/ jsxRuntime.jsx(FolderActionsMenu.FolderActionsMenu, {
|
|
216
|
+
folder: folder,
|
|
217
|
+
dragData: dragData
|
|
218
|
+
})
|
|
187
219
|
})
|
|
188
220
|
]
|
|
189
221
|
});
|
|
@@ -220,9 +252,21 @@ const IconPreview = styledComponents.styled(designSystem.Flex)`
|
|
|
220
252
|
background: ${({ theme })=>theme.colors.neutral100};
|
|
221
253
|
`;
|
|
222
254
|
const AssetPreview = ({ asset })=>{
|
|
223
|
-
const { alternativeText, ext, formats, mime, url, isLocal, isUrlSigned } = asset;
|
|
255
|
+
const { alternativeText, ext, formats, mime, url, updatedAt, isLocal, isUrlSigned } = asset;
|
|
224
256
|
if (mime?.includes(enums.ASSET_TYPES.Image)) {
|
|
225
|
-
|
|
257
|
+
// Replace keeps the same hash/URL, so without a cache-buster the browser
|
|
258
|
+
// serves the stale thumbnail after a Replace Media. `updatedAt`
|
|
259
|
+
// changes on replace, so it re-fetches exactly once per replacement.
|
|
260
|
+
// Skipped for signed URLs — an extra query param invalidates the signature.
|
|
261
|
+
const cacheKey = updatedAt && !isUrlSigned ? new Date(updatedAt).getTime() : undefined;
|
|
262
|
+
const appendCacheBuster = (raw)=>{
|
|
263
|
+
if (cacheKey === undefined) {
|
|
264
|
+
return raw;
|
|
265
|
+
}
|
|
266
|
+
return raw.includes('?') ? `${raw}&v=${cacheKey}` : `${raw}?v=${cacheKey}`;
|
|
267
|
+
};
|
|
268
|
+
const rawMediaURL = files.prefixFileUrlWithBackendUrl(formats?.thumbnail?.url) ?? files.prefixFileUrlWithBackendUrl(url);
|
|
269
|
+
const mediaURL = rawMediaURL ? appendCacheBuster(rawMediaURL) : rawMediaURL;
|
|
226
270
|
if (mediaURL) {
|
|
227
271
|
return /*#__PURE__*/ jsxRuntime.jsx(PreviewContainer, {
|
|
228
272
|
children: /*#__PURE__*/ jsxRuntime.jsx(StyledImage, {
|
|
@@ -264,7 +308,7 @@ const FileTypeIcon = styledComponents.styled(designSystem.Flex)`
|
|
|
264
308
|
color: ${({ theme })=>theme.colors.neutral600};
|
|
265
309
|
flex-shrink: 0;
|
|
266
310
|
`;
|
|
267
|
-
const FileName = styledComponents.styled(
|
|
311
|
+
const FileName = styledComponents.styled(TruncatedText.TruncatedText)`
|
|
268
312
|
flex: 1;
|
|
269
313
|
min-width: 0;
|
|
270
314
|
`;
|
|
@@ -295,15 +339,23 @@ const AssetCard = ({ asset, orderedItemKeys, onAssetItemClick })=>{
|
|
|
295
339
|
const { isMovePending } = AssetsDndProvider.useAssetsDndOptional() ?? {
|
|
296
340
|
isMovePending: false
|
|
297
341
|
};
|
|
298
|
-
const { attributes, listeners, setNodeRef, isDragging } = useAssetDnd.useFileDraggable(asset);
|
|
342
|
+
const { attributes, listeners, setNodeRef, isDragging, dragData } = useAssetDnd.useFileDraggable(asset);
|
|
299
343
|
const { isSelected, toggle, selectRange } = useAssetSelection.useAssetSelection();
|
|
300
344
|
const { canUpdate } = useMediaLibraryPermissions.useMediaLibraryPermissions();
|
|
345
|
+
const busyMessage = useBusyAssets.useBusyAssetsOptional()?.getBusyMessage(asset.id) ?? null;
|
|
301
346
|
const key = selection.assetKey(asset.id);
|
|
302
347
|
const selected = isSelected(key);
|
|
303
348
|
// Plain click opens the asset details; pointer selection lives on the
|
|
304
349
|
// checkbox only. Modifier clicks keep the selection semantics: shift selects
|
|
305
350
|
// a range, cmd/ctrl toggles.
|
|
351
|
+
//
|
|
352
|
+
// The containment guard on this and the handler below is what keeps the
|
|
353
|
+
// actions menu's portaled dialogs — React children of this card — from
|
|
354
|
+
// opening the details drawer or toggling the selection.
|
|
306
355
|
const handleCardClick = (e)=>{
|
|
356
|
+
if (!isEventFromWithin.isEventFromWithin(e)) {
|
|
357
|
+
return;
|
|
358
|
+
}
|
|
307
359
|
if (e.shiftKey) {
|
|
308
360
|
selectRange(orderedItemKeys, key);
|
|
309
361
|
} else if (e.metaKey || e.ctrlKey) {
|
|
@@ -314,6 +366,9 @@ const AssetCard = ({ asset, orderedItemKeys, onAssetItemClick })=>{
|
|
|
314
366
|
};
|
|
315
367
|
// Space toggles selection (additive), Enter opens the details drawer.
|
|
316
368
|
const handleKeyDown = (e)=>{
|
|
369
|
+
if (!isEventFromWithin.isEventFromWithin(e)) {
|
|
370
|
+
return;
|
|
371
|
+
}
|
|
317
372
|
if (e.key === 'Enter') {
|
|
318
373
|
e.preventDefault();
|
|
319
374
|
onAssetItemClick(asset.id);
|
|
@@ -342,12 +397,18 @@ const AssetCard = ({ asset, orderedItemKeys, onAssetItemClick })=>{
|
|
|
342
397
|
...listeners,
|
|
343
398
|
$isDragging: isDragging,
|
|
344
399
|
$isMovePending: isMovePending,
|
|
400
|
+
$isBusy: busyMessage !== null,
|
|
345
401
|
$isSelected: selected,
|
|
346
402
|
tabIndex: 0,
|
|
347
403
|
role: "listitem",
|
|
348
404
|
onDragStart: (e)=>e.preventDefault(),
|
|
349
405
|
onClick: handleCardClick,
|
|
350
406
|
onKeyDown: handleKeyDown,
|
|
407
|
+
onPointerDown: (e)=>{
|
|
408
|
+
if (isEventFromWithin.isEventFromWithin(e)) {
|
|
409
|
+
listeners?.onPointerDown?.(e);
|
|
410
|
+
}
|
|
411
|
+
},
|
|
351
412
|
children: [
|
|
352
413
|
/*#__PURE__*/ jsxRuntime.jsxs(StyledCardHeader, {
|
|
353
414
|
children: [
|
|
@@ -366,7 +427,11 @@ const AssetCard = ({ asset, orderedItemKeys, onAssetItemClick })=>{
|
|
|
366
427
|
}),
|
|
367
428
|
/*#__PURE__*/ jsxRuntime.jsx(AssetPreview, {
|
|
368
429
|
asset: asset
|
|
369
|
-
})
|
|
430
|
+
}),
|
|
431
|
+
busyMessage !== null ? /*#__PURE__*/ jsxRuntime.jsx(BusyOverlay.BusyOverlay, {
|
|
432
|
+
zIndex: 2,
|
|
433
|
+
children: busyMessage
|
|
434
|
+
}) : null
|
|
370
435
|
]
|
|
371
436
|
}),
|
|
372
437
|
/*#__PURE__*/ jsxRuntime.jsx(designSystem.CardBody, {
|
|
@@ -385,18 +450,17 @@ const AssetCard = ({ asset, orderedItemKeys, onAssetItemClick })=>{
|
|
|
385
450
|
onClick: handleNameClick,
|
|
386
451
|
children: /*#__PURE__*/ jsxRuntime.jsx(FileName, {
|
|
387
452
|
textColor: "primary800",
|
|
388
|
-
ellipsis: true,
|
|
389
453
|
children: asset.name
|
|
390
454
|
})
|
|
391
455
|
}),
|
|
392
|
-
/*#__PURE__*/ jsxRuntime.jsx(designSystem.
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
456
|
+
/*#__PURE__*/ jsxRuntime.jsx(designSystem.Flex, {
|
|
457
|
+
onClick: stopCardEvent,
|
|
458
|
+
onKeyDown: stopCardEvent,
|
|
459
|
+
onPointerDown: stopCardEvent,
|
|
460
|
+
children: /*#__PURE__*/ jsxRuntime.jsx(AssetActionsMenu.AssetActionsMenu, {
|
|
461
|
+
asset: asset,
|
|
462
|
+
dragData: dragData
|
|
463
|
+
})
|
|
400
464
|
})
|
|
401
465
|
]
|
|
402
466
|
})
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AssetsGrid.js","sources":["../../../../../../admin/src/future/pages/Assets/components/AssetsGrid.tsx"],"sourcesContent":["import {\n Box,\n Card,\n CardBody,\n CardHeader,\n Checkbox,\n Flex,\n Grid,\n IconButton,\n Typography,\n} from '@strapi/design-system';\nimport { Folder as FolderIcon, More } from '@strapi/icons';\nimport { useIntl } from 'react-intl';\nimport { styled, css } from 'styled-components';\n\nimport { ASSET_TYPES } from '../../../../enums';\nimport { useMediaLibraryPermissions } from '../../../hooks/useMediaLibraryPermissions';\nimport { prefixFileUrlWithBackendUrl } from '../../../utils/files';\nimport { getAssetIcon } from '../../../utils/getAssetIcon';\nimport { getTranslationKey } from '../../../utils/translations';\nimport { useAssetSelection } from '../hooks/useAssetSelection';\nimport { useFolderNavigation } from '../hooks/useFolderNavigation';\nimport { assetKey, folderKey, type ItemKey } from '../utils/selection';\n\nimport { useAssetsDndOptional } from './Dnd/AssetsDndProvider';\nimport { useFileDraggable, useFolderDraggableDroppable } from './Dnd/useAssetDnd';\n\nimport type { File } from '../../../../../../shared/contracts/files';\nimport type { Folder } from '../../../../../../shared/contracts/folders';\n\n/* -------------------------------------------------------------------------------------------------\n * AssetsGrid\n * -----------------------------------------------------------------------------------------------*/\n\n// Top-left selection checkbox overlaid on the asset preview, always visible.\nconst CheckboxOverlay = styled(Flex)`\n position: absolute;\n top: ${({ theme }) => theme.spaces[3]};\n left: ${({ theme }) => theme.spaces[3]};\n z-index: 1;\n box-shadow: ${({ theme }) => theme.shadows.filterShadow};\n`;\n\nconst StyledCard = styled(Card)<{\n $isDragging?: boolean;\n $isMovePending?: boolean;\n $isSelected?: boolean;\n}>`\n border: 1px solid\n ${({ theme, $isSelected }) => ($isSelected ? theme.colors.primary600 : theme.colors.neutral200)};\n border-radius: 8px;\n overflow: hidden;\n cursor: ${({ $isMovePending }) => ($isMovePending ? 'wait' : 'pointer')};\n opacity: ${({ $isDragging }) => ($isDragging ? 0.4 : 1)};\n pointer-events: ${({ $isMovePending }) => ($isMovePending ? 'none' : 'auto')};\n background: ${({ theme, $isSelected }) => ($isSelected ? theme.colors.primary100 : undefined)};\n /* Shift+click range selection must not highlight card text. */\n user-select: none;\n\n &:hover {\n background: ${({ theme }) => theme.colors.primary100};\n }\n\n &:focus-visible {\n outline: 2px solid ${({ theme }) => theme.colors.primary600};\n outline-offset: 2px;\n }\n`;\n\n/* -------------------------------------------------------------------------------------------------\n * FolderCard\n * -----------------------------------------------------------------------------------------------*/\n\nconst FoldersRow = styled(Box)`\n grid-column: 1 / -1;\n`;\n\nconst StyledFolderCard = styled(Flex)<{\n $isDragging?: boolean;\n $isMovePending?: boolean;\n $isValidDropTarget?: boolean;\n $isInvalidDropTarget?: boolean;\n $isSelected?: boolean;\n}>`\n width: 100%;\n user-select: none;\n padding: ${({ theme }) => `${theme.spaces[2]} ${theme.spaces[3]}`}; // 8px 12px\n align-items: center;\n gap: ${({ theme }) => theme.spaces[2]}; // 8px\n border: 1px solid\n ${({ theme, $isSelected }) => ($isSelected ? theme.colors.primary600 : theme.colors.neutral200)};\n border-radius: ${({ theme }) => theme.borderRadius};\n background: ${({ theme, $isSelected }) =>\n $isSelected ? theme.colors.primary100 : theme.colors.neutral0};\n cursor: ${({ $isMovePending, $isInvalidDropTarget }) => {\n if ($isMovePending) {\n return 'wait';\n }\n\n return $isInvalidDropTarget ? 'not-allowed' : 'pointer';\n }};\n opacity: ${({ $isDragging }) => ($isDragging ? 0.4 : 1)};\n pointer-events: ${({ $isMovePending }) => ($isMovePending ? 'none' : 'auto')};\n transition: background 0.2s;\n\n ${({ $isValidDropTarget, theme }) =>\n $isValidDropTarget &&\n css`\n background: ${theme.colors.primary100};\n border: 1px dashed ${theme.colors.primary600};\n `}\n\n &:hover {\n background: ${({ theme }) => theme.colors.primary100};\n }\n\n &:focus-visible {\n outline: 2px solid ${({ theme }) => theme.colors.primary600};\n outline-offset: 2px;\n }\n`;\n\nconst FolderIconContainer = styled(Flex)`\n flex-shrink: 0;\n color: ${({ theme }) => theme.colors.neutral600};\n`;\n\nconst FolderName = styled(Typography)`\n flex: 1;\n min-width: 0;\n`;\n\ninterface FolderCardProps {\n folder: Folder;\n orderedItemKeys: ItemKey[];\n}\n\nconst FolderCard = ({ folder, orderedItemKeys }: FolderCardProps) => {\n const { formatMessage } = useIntl();\n const { navigateToFolder } = useFolderNavigation();\n const { isMovePending } = useAssetsDndOptional() ?? { isMovePending: false };\n const { isSelected, toggle, selectRange } = useAssetSelection();\n const { canUpdate } = useMediaLibraryPermissions();\n const {\n draggable: { attributes, listeners, setNodeRef: setDragRef, isDragging },\n droppable: { setNodeRef: setDropRef },\n showValidDropHighlight,\n showInvalidDropCursor,\n } = useFolderDraggableDroppable(folder);\n\n const key = folderKey(folder.id);\n\n const setNodeRef = (node: HTMLElement | null) => {\n setDragRef(node);\n setDropRef(node);\n };\n\n // Folders share the selection mechanism with assets (toggle, range,\n // select-all). Only the plain-click semantic differs: it navigates into the\n // folder instead of selecting it.\n const handleClick = (e: React.MouseEvent) => {\n if (e.shiftKey) {\n selectRange(orderedItemKeys, key);\n } else if (e.metaKey || e.ctrlKey) {\n toggle(key);\n } else {\n navigateToFolder(folder);\n }\n };\n\n const handleKeyDown = (e: React.KeyboardEvent) => {\n if (e.key === 'Enter') {\n e.preventDefault();\n navigateToFolder(folder);\n } else if (e.key === ' ') {\n e.preventDefault();\n toggle(key);\n }\n };\n\n // Checkbox is the pointer path to selection; Shift extends the range.\n const handleCheckboxClick = (e: React.MouseEvent) => {\n e.stopPropagation();\n if (e.shiftKey) {\n selectRange(orderedItemKeys, key);\n } else {\n toggle(key);\n }\n };\n\n return (\n <StyledFolderCard\n ref={setNodeRef}\n {...attributes}\n {...listeners}\n $isDragging={isDragging}\n $isMovePending={isMovePending}\n $isValidDropTarget={showValidDropHighlight}\n $isInvalidDropTarget={showInvalidDropCursor}\n $isSelected={isSelected(key)}\n onClick={handleClick}\n onKeyDown={handleKeyDown}\n role=\"listitem\"\n tabIndex={0}\n >\n {canUpdate && (\n <Flex onKeyDown={(e: React.KeyboardEvent) => e.stopPropagation()}>\n <Checkbox\n checked={isSelected(key)}\n onClick={handleCheckboxClick}\n aria-label={formatMessage(\n {\n id: getTranslationKey('list.table.row.select'),\n defaultMessage: 'Select {name}',\n },\n { name: folder.name }\n )}\n />\n </Flex>\n )}\n <FolderIconContainer>\n <FolderIcon width={20} height={20} />\n </FolderIconContainer>\n <FolderName textColor=\"neutral800\" ellipsis>\n {folder.name}\n </FolderName>\n <IconButton\n label={formatMessage({\n id: getTranslationKey('control-card.more-actions'),\n defaultMessage: 'More actions',\n })}\n variant=\"ghost\"\n onClick={(e: React.MouseEvent) => e.stopPropagation()}\n >\n <More />\n </IconButton>\n </StyledFolderCard>\n );\n};\n\n/* -------------------------------------------------------------------------------------------------\n * AssetPreview\n * -----------------------------------------------------------------------------------------------*/\n\nconst PreviewContainer = styled(Box)`\n position: relative;\n width: 100%;\n padding-bottom: 62.5%;\n height: 0;\n overflow: hidden;\n background: repeating-conic-gradient(\n ${({ theme }) => theme.colors.neutral100} 0% 25%,\n transparent 0% 50%\n )\n 50% / 20px 20px;\n`;\n\nconst StyledImage = styled.img`\n position: absolute;\n top: 0;\n left: 0;\n width: 100%;\n height: 100%;\n object-fit: cover;\n`;\n\nconst IconPreview = styled(Flex)`\n position: absolute;\n top: 0;\n left: 0;\n width: 100%;\n height: 100%;\n color: ${({ theme }) => theme.colors.neutral500};\n background: ${({ theme }) => theme.colors.neutral100};\n`;\n\ninterface AssetPreviewProps {\n asset: File;\n}\n\nconst AssetPreview = ({ asset }: AssetPreviewProps) => {\n const { alternativeText, ext, formats, mime, url, isLocal, isUrlSigned } = asset;\n\n if (mime?.includes(ASSET_TYPES.Image)) {\n const mediaURL =\n prefixFileUrlWithBackendUrl(formats?.thumbnail?.url) ?? prefixFileUrlWithBackendUrl(url);\n\n if (mediaURL) {\n return (\n <PreviewContainer>\n <StyledImage\n src={mediaURL}\n alt={alternativeText || ''}\n // Only signed remote URLs need crossOrigin (cache collision with\n // the preview). Public/unsigned remote thumbnails must render\n // without a bucket CORS rule. See #26581.\n crossOrigin={!isLocal && isUrlSigned ? 'anonymous' : undefined}\n draggable={false}\n onDragStart={(e) => e.preventDefault()}\n />\n </PreviewContainer>\n );\n }\n }\n\n const DocIcon = getAssetIcon(mime, ext);\n\n return (\n <PreviewContainer>\n <IconPreview justifyContent=\"center\" alignItems=\"center\">\n <DocIcon width={48} height={48} />\n </IconPreview>\n </PreviewContainer>\n );\n};\n\n/* -------------------------------------------------------------------------------------------------\n * AssetCard\n * -----------------------------------------------------------------------------------------------*/\n\nconst StyledCardHeader = styled(CardHeader)`\n position: relative;\n border-bottom: 1px solid ${({ theme }) => theme.colors.neutral200};\n`;\n\nconst CardFooter = styled(Flex)`\n min-width: 0;\n width: 100%;\n`;\n\nconst FileTypeIcon = styled(Flex)`\n color: ${({ theme }) => theme.colors.neutral600};\n flex-shrink: 0;\n`;\n\nconst FileName = styled(Typography)`\n flex: 1;\n min-width: 0;\n`;\n\n// The asset filename is its own interactive element: clicking it opens the\n// details drawer instead of selecting the card (mirrors the table view).\nconst NameButton = styled.button`\n display: inline-flex;\n flex: 1;\n min-width: 0;\n border: none;\n background: transparent;\n padding: 0;\n margin: 0;\n cursor: pointer;\n text-align: left;\n color: inherit;\n font: inherit;\n\n &:focus-visible {\n outline: 2px solid ${({ theme }) => theme.colors.primary600};\n outline-offset: 2px;\n border-radius: 2px;\n }\n`;\n\ninterface AssetCardProps {\n asset: File;\n orderedItemKeys: ItemKey[];\n onAssetItemClick: (assetId: number) => void;\n}\n\nconst AssetCard = ({ asset, orderedItemKeys, onAssetItemClick }: AssetCardProps) => {\n const { formatMessage } = useIntl();\n const TypeIcon = getAssetIcon(asset.mime, asset.ext);\n const { isMovePending } = useAssetsDndOptional() ?? { isMovePending: false };\n const { attributes, listeners, setNodeRef, isDragging } = useFileDraggable(asset);\n const { isSelected, toggle, selectRange } = useAssetSelection();\n const { canUpdate } = useMediaLibraryPermissions();\n\n const key = assetKey(asset.id);\n const selected = isSelected(key);\n\n // Plain click opens the asset details; pointer selection lives on the\n // checkbox only. Modifier clicks keep the selection semantics: shift selects\n // a range, cmd/ctrl toggles.\n const handleCardClick = (e: React.MouseEvent) => {\n if (e.shiftKey) {\n selectRange(orderedItemKeys, key);\n } else if (e.metaKey || e.ctrlKey) {\n toggle(key);\n } else {\n onAssetItemClick(asset.id);\n }\n };\n\n // Space toggles selection (additive), Enter opens the details drawer.\n const handleKeyDown = (e: React.KeyboardEvent) => {\n if (e.key === 'Enter') {\n e.preventDefault();\n onAssetItemClick(asset.id);\n } else if (e.key === ' ') {\n e.preventDefault();\n toggle(key);\n }\n };\n\n const handleNameClick = (e: React.MouseEvent) => {\n e.stopPropagation();\n onAssetItemClick(asset.id);\n };\n\n // Same semantics as the table's row checkbox: Shift extends the range,\n // otherwise a plain additive toggle. Never bubbles into the card click.\n const handleCheckboxClick = (e: React.MouseEvent) => {\n e.stopPropagation();\n if (e.shiftKey) {\n selectRange(orderedItemKeys, key);\n } else {\n toggle(key);\n }\n };\n\n return (\n <StyledCard\n ref={setNodeRef}\n {...attributes}\n {...listeners}\n $isDragging={isDragging}\n $isMovePending={isMovePending}\n $isSelected={selected}\n tabIndex={0}\n role=\"listitem\"\n onDragStart={(e) => e.preventDefault()}\n onClick={handleCardClick}\n onKeyDown={handleKeyDown}\n >\n <StyledCardHeader>\n {canUpdate && (\n <CheckboxOverlay onKeyDown={(e: React.KeyboardEvent) => e.stopPropagation()}>\n <Checkbox\n checked={selected}\n onClick={handleCheckboxClick}\n aria-label={formatMessage(\n {\n id: getTranslationKey('list.table.row.select'),\n defaultMessage: 'Select {name}',\n },\n { name: asset.name }\n )}\n />\n </CheckboxOverlay>\n )}\n <AssetPreview asset={asset} />\n </StyledCardHeader>\n <CardBody>\n <CardFooter alignItems=\"center\" gap={2}>\n <FileTypeIcon>\n <TypeIcon width={20} height={20} />\n </FileTypeIcon>\n <NameButton type=\"button\" onClick={handleNameClick}>\n <FileName textColor=\"primary800\" ellipsis>\n {asset.name}\n </FileName>\n </NameButton>\n <IconButton\n label={formatMessage({\n id: getTranslationKey('control-card.more-actions'),\n defaultMessage: 'More actions',\n })}\n variant=\"ghost\"\n onClick={(e: React.MouseEvent) => e.stopPropagation()}\n >\n <More />\n </IconButton>\n </CardFooter>\n </CardBody>\n </StyledCard>\n );\n};\n\n/* -------------------------------------------------------------------------------------------------\n * AssetsGrid\n * -----------------------------------------------------------------------------------------------*/\n\ninterface AssetsGridProps {\n assets: File[];\n folders?: Folder[];\n onAssetItemClick: (assetId: number) => void;\n}\n\nexport const AssetsGrid = ({ assets, folders = [], onAssetItemClick }: AssetsGridProps) => {\n const totalItems = folders.length + assets.length;\n\n // Render order: folders always on top in the grid (mixing is table-only) —\n // range selection follows it.\n const orderedItemKeys: ItemKey[] = [\n ...folders.map((folder) => folderKey(folder.id)),\n ...assets.map((asset) => assetKey(asset.id)),\n ];\n\n // The empty state is owned by the page (`AssetsView` renders `EmptyState`) — an\n // empty grid renders nothing at all.\n if (totalItems === 0) {\n return null;\n }\n\n return (\n <Grid.Root gap={4} role=\"list\" data-testid=\"assets-grid\">\n {folders.length > 0 && (\n <FoldersRow>\n <Grid.Root gap={4}>\n {folders.map((folder) => (\n <Grid.Item col={3} m={4} s={6} xs={12} key={`folder-${folder.id}`}>\n <FolderCard folder={folder} orderedItemKeys={orderedItemKeys} />\n </Grid.Item>\n ))}\n </Grid.Root>\n </FoldersRow>\n )}\n {assets.map((asset) => (\n <Grid.Item\n col={3}\n m={4}\n s={6}\n xs={12}\n key={asset.id}\n direction=\"column\"\n alignItems=\"stretch\"\n >\n <AssetCard\n asset={asset}\n orderedItemKeys={orderedItemKeys}\n onAssetItemClick={onAssetItemClick}\n />\n </Grid.Item>\n ))}\n </Grid.Root>\n );\n};\n"],"names":["CheckboxOverlay","styled","Flex","theme","spaces","shadows","filterShadow","StyledCard","Card","$isSelected","colors","primary600","neutral200","$isMovePending","$isDragging","primary100","undefined","FoldersRow","Box","StyledFolderCard","borderRadius","neutral0","$isInvalidDropTarget","$isValidDropTarget","css","FolderIconContainer","neutral600","FolderName","Typography","FolderCard","folder","orderedItemKeys","formatMessage","useIntl","navigateToFolder","useFolderNavigation","isMovePending","useAssetsDndOptional","isSelected","toggle","selectRange","useAssetSelection","canUpdate","useMediaLibraryPermissions","draggable","attributes","listeners","setNodeRef","setDragRef","isDragging","droppable","setDropRef","showValidDropHighlight","showInvalidDropCursor","useFolderDraggableDroppable","key","folderKey","id","node","handleClick","e","shiftKey","metaKey","ctrlKey","handleKeyDown","preventDefault","handleCheckboxClick","stopPropagation","_jsxs","ref","onClick","onKeyDown","role","tabIndex","_jsx","Checkbox","checked","aria-label","getTranslationKey","defaultMessage","name","FolderIcon","width","height","textColor","ellipsis","IconButton","label","variant","More","PreviewContainer","neutral100","StyledImage","img","IconPreview","neutral500","AssetPreview","asset","alternativeText","ext","formats","mime","url","isLocal","isUrlSigned","includes","ASSET_TYPES","Image","mediaURL","prefixFileUrlWithBackendUrl","thumbnail","src","alt","crossOrigin","onDragStart","DocIcon","getAssetIcon","justifyContent","alignItems","StyledCardHeader","CardHeader","CardFooter","FileTypeIcon","FileName","NameButton","button","AssetCard","onAssetItemClick","TypeIcon","useFileDraggable","assetKey","selected","handleCardClick","handleNameClick","CardBody","gap","type","AssetsGrid","assets","folders","totalItems","length","map","Grid","Root","data-testid","Item","col","m","s","xs","direction"],"mappings":";;;;;;;;;;;;;;;;;;AA8BA;;AAEkG;AAGlG,MAAMA,eAAAA,GAAkBC,uBAAAA,CAAOC,iBAAAA,CAAK;;OAE7B,EAAE,CAAC,EAAEC,KAAK,EAAE,GAAKA,KAAAA,CAAMC,MAAM,CAAC,CAAA,CAAE,CAAC;QAChC,EAAE,CAAC,EAAED,KAAK,EAAE,GAAKA,KAAAA,CAAMC,MAAM,CAAC,CAAA,CAAE,CAAC;;cAE3B,EAAE,CAAC,EAAED,KAAK,EAAE,GAAKA,KAAAA,CAAME,OAAO,CAACC,YAAY,CAAC;AAC1D,CAAC;AAED,MAAMC,UAAAA,GAAaN,uBAAAA,CAAOO,iBAAAA,CAIxB;;AAEE,IAAA,EAAE,CAAC,EAAEL,KAAK,EAAEM,WAAW,EAAE,GAAMA,WAAAA,GAAcN,KAAAA,CAAMO,MAAM,CAACC,UAAU,GAAGR,MAAMO,MAAM,CAACE,UAAU,CAAE;;;AAG1F,UAAA,EAAE,CAAC,EAAEC,cAAc,EAAE,GAAMA,cAAAA,GAAiB,SAAS,SAAA,CAAW;AAC/D,WAAA,EAAE,CAAC,EAAEC,WAAW,EAAE,GAAMA,WAAAA,GAAc,MAAM,CAAA,CAAG;AACxC,kBAAA,EAAE,CAAC,EAAED,cAAc,EAAE,GAAMA,cAAAA,GAAiB,SAAS,MAAA,CAAQ;AACjE,cAAA,EAAE,CAAC,EAAEV,KAAK,EAAEM,WAAW,EAAE,GAAMA,WAAAA,GAAcN,KAAAA,CAAMO,MAAM,CAACK,UAAU,GAAGC,SAAAA,CAAW;;;;;gBAKhF,EAAE,CAAC,EAAEb,KAAK,EAAE,GAAKA,KAAAA,CAAMO,MAAM,CAACK,UAAU,CAAC;;;;uBAIlC,EAAE,CAAC,EAAEZ,KAAK,EAAE,GAAKA,KAAAA,CAAMO,MAAM,CAACC,UAAU,CAAC;;;AAGhE,CAAC;AAED;;AAEkG,qGAElG,MAAMM,UAAAA,GAAahB,uBAAAA,CAAOiB,gBAAAA,CAAI;;AAE9B,CAAC;AAED,MAAMC,gBAAAA,GAAmBlB,uBAAAA,CAAOC,iBAAAA,CAM9B;;;AAGS,WAAA,EAAE,CAAC,EAAEC,KAAK,EAAE,GAAK,CAAA,EAAGA,MAAMC,MAAM,CAAC,CAAA,CAAE,CAAC,CAAC,EAAED,KAAAA,CAAMC,MAAM,CAAC,CAAA,CAAE,EAAE,CAAC;;OAE7D,EAAE,CAAC,EAAED,KAAK,EAAE,GAAKA,KAAAA,CAAMC,MAAM,CAAC,CAAA,CAAE,CAAC;;AAEpC,IAAA,EAAE,CAAC,EAAED,KAAK,EAAEM,WAAW,EAAE,GAAMA,WAAAA,GAAcN,KAAAA,CAAMO,MAAM,CAACC,UAAU,GAAGR,MAAMO,MAAM,CAACE,UAAU,CAAE;AACnF,iBAAA,EAAE,CAAC,EAAET,KAAK,EAAE,GAAKA,KAAAA,CAAMiB,YAAY,CAAC;AACvC,cAAA,EAAE,CAAC,EAAEjB,KAAK,EAAEM,WAAW,EAAE,GACnCA,WAAAA,GAAcN,KAAAA,CAAMO,MAAM,CAACK,UAAU,GAAGZ,MAAMO,MAAM,CAACW,QAAQ,CAAC;AACxD,UAAA,EAAE,CAAC,EAAER,cAAc,EAAES,oBAAoB,EAAE,GAAA;AACjD,IAAA,IAAIT,cAAAA,EAAgB;QAClB,OAAO,MAAA;AACT,IAAA;AAEA,IAAA,OAAOS,uBAAuB,aAAA,GAAgB,SAAA;AAChD,CAAA,CAAE;AACO,WAAA,EAAE,CAAC,EAAER,WAAW,EAAE,GAAMA,WAAAA,GAAc,MAAM,CAAA,CAAG;AACxC,kBAAA,EAAE,CAAC,EAAED,cAAc,EAAE,GAAMA,cAAAA,GAAiB,SAAS,MAAA,CAAQ;;;EAG7E,EAAE,CAAC,EAAEU,kBAAkB,EAAEpB,KAAK,EAAE,GAC9BoB,kBAAAA,IACAC,oBAAG;AACW,kBAAA,EAAErB,KAAAA,CAAMO,MAAM,CAACK,UAAU,CAAC;AACnB,yBAAA,EAAEZ,KAAAA,CAAMO,MAAM,CAACC,UAAU,CAAC;AAC/C,IAAA,CAAC;;;gBAGW,EAAE,CAAC,EAAER,KAAK,EAAE,GAAKA,KAAAA,CAAMO,MAAM,CAACK,UAAU,CAAC;;;;uBAIlC,EAAE,CAAC,EAAEZ,KAAK,EAAE,GAAKA,KAAAA,CAAMO,MAAM,CAACC,UAAU,CAAC;;;AAGhE,CAAC;AAED,MAAMc,mBAAAA,GAAsBxB,uBAAAA,CAAOC,iBAAAA,CAAK;;SAE/B,EAAE,CAAC,EAAEC,KAAK,EAAE,GAAKA,KAAAA,CAAMO,MAAM,CAACgB,UAAU,CAAC;AAClD,CAAC;AAED,MAAMC,UAAAA,GAAa1B,uBAAAA,CAAO2B,uBAAAA,CAAW;;;AAGrC,CAAC;AAOD,MAAMC,aAAa,CAAC,EAAEC,MAAM,EAAEC,eAAe,EAAmB,GAAA;IAC9D,MAAM,EAAEC,aAAa,EAAE,GAAGC,iBAAAA,EAAAA;IAC1B,MAAM,EAAEC,gBAAgB,EAAE,GAAGC,uCAAAA,EAAAA;AAC7B,IAAA,MAAM,EAAEC,aAAa,EAAE,GAAGC,sCAAAA,EAAAA,IAA0B;QAAED,aAAAA,EAAe;AAAM,KAAA;AAC3E,IAAA,MAAM,EAAEE,UAAU,EAAEC,MAAM,EAAEC,WAAW,EAAE,GAAGC,mCAAAA,EAAAA;IAC5C,MAAM,EAAEC,SAAS,EAAE,GAAGC,qDAAAA,EAAAA;IACtB,MAAM,EACJC,SAAAA,EAAW,EAAEC,UAAU,EAAEC,SAAS,EAAEC,UAAAA,EAAYC,UAAU,EAAEC,UAAU,EAAE,EACxEC,SAAAA,EAAW,EAAEH,UAAAA,EAAYI,UAAU,EAAE,EACrCC,sBAAsB,EACtBC,qBAAqB,EACtB,GAAGC,uCAAAA,CAA4BxB,MAAAA,CAAAA;IAEhC,MAAMyB,GAAAA,GAAMC,mBAAAA,CAAU1B,MAAAA,CAAO2B,EAAE,CAAA;AAE/B,IAAA,MAAMV,aAAa,CAACW,IAAAA,GAAAA;QAClBV,UAAAA,CAAWU,IAAAA,CAAAA;QACXP,UAAAA,CAAWO,IAAAA,CAAAA;AACb,IAAA,CAAA;;;;AAKA,IAAA,MAAMC,cAAc,CAACC,CAAAA,GAAAA;QACnB,IAAIA,CAAAA,CAAEC,QAAQ,EAAE;AACdrB,YAAAA,WAAAA,CAAYT,eAAAA,EAAiBwB,GAAAA,CAAAA;AAC/B,QAAA,CAAA,MAAO,IAAIK,CAAAA,CAAEE,OAAO,IAAIF,CAAAA,CAAEG,OAAO,EAAE;YACjCxB,MAAAA,CAAOgB,GAAAA,CAAAA;QACT,CAAA,MAAO;YACLrB,gBAAAA,CAAiBJ,MAAAA,CAAAA;AACnB,QAAA;AACF,IAAA,CAAA;AAEA,IAAA,MAAMkC,gBAAgB,CAACJ,CAAAA,GAAAA;QACrB,IAAIA,CAAAA,CAAEL,GAAG,KAAK,OAAA,EAAS;AACrBK,YAAAA,CAAAA,CAAEK,cAAc,EAAA;YAChB/B,gBAAAA,CAAiBJ,MAAAA,CAAAA;AACnB,QAAA,CAAA,MAAO,IAAI8B,CAAAA,CAAEL,GAAG,KAAK,GAAA,EAAK;AACxBK,YAAAA,CAAAA,CAAEK,cAAc,EAAA;YAChB1B,MAAAA,CAAOgB,GAAAA,CAAAA;AACT,QAAA;AACF,IAAA,CAAA;;AAGA,IAAA,MAAMW,sBAAsB,CAACN,CAAAA,GAAAA;AAC3BA,QAAAA,CAAAA,CAAEO,eAAe,EAAA;QACjB,IAAIP,CAAAA,CAAEC,QAAQ,EAAE;AACdrB,YAAAA,WAAAA,CAAYT,eAAAA,EAAiBwB,GAAAA,CAAAA;QAC/B,CAAA,MAAO;YACLhB,MAAAA,CAAOgB,GAAAA,CAAAA;AACT,QAAA;AACF,IAAA,CAAA;AAEA,IAAA,qBACEa,eAAA,CAACjD,gBAAAA,EAAAA;QACCkD,GAAAA,EAAKtB,UAAAA;AACJ,QAAA,GAAGF,UAAU;AACb,QAAA,GAAGC,SAAS;QACbhC,WAAAA,EAAamC,UAAAA;QACbpC,cAAAA,EAAgBuB,aAAAA;QAChBb,kBAAAA,EAAoB6B,sBAAAA;QACpB9B,oBAAAA,EAAsB+B,qBAAAA;AACtB5C,QAAAA,WAAAA,EAAa6B,UAAAA,CAAWiB,GAAAA,CAAAA;QACxBe,OAAAA,EAASX,WAAAA;QACTY,SAAAA,EAAWP,aAAAA;QACXQ,IAAAA,EAAK,UAAA;QACLC,QAAAA,EAAU,CAAA;;AAET/B,YAAAA,SAAAA,kBACCgC,cAAA,CAACxE,iBAAAA,EAAAA;gBAAKqE,SAAAA,EAAW,CAACX,CAAAA,GAA2BA,CAAAA,CAAEO,eAAe,EAAA;AAC5D,gBAAA,QAAA,gBAAAO,cAAA,CAACC,qBAAAA,EAAAA;AACCC,oBAAAA,OAAAA,EAAStC,UAAAA,CAAWiB,GAAAA,CAAAA;oBACpBe,OAAAA,EAASJ,mBAAAA;AACTW,oBAAAA,YAAAA,EAAY7C,aAAAA,CACV;AACEyB,wBAAAA,EAAAA,EAAIqB,8BAAAA,CAAkB,uBAAA,CAAA;wBACtBC,cAAAA,EAAgB;qBAClB,EACA;AAAEC,wBAAAA,IAAAA,EAAMlD,OAAOkD;AAAK,qBAAA;;;0BAK5BN,cAAA,CAACjD,mBAAAA,EAAAA;AACC,gBAAA,QAAA,gBAAAiD,cAAA,CAACO,YAAAA,EAAAA;oBAAWC,KAAAA,EAAO,EAAA;oBAAIC,MAAAA,EAAQ;;;0BAEjCT,cAAA,CAAC/C,UAAAA,EAAAA;gBAAWyD,SAAAA,EAAU,YAAA;gBAAaC,QAAQ,EAAA,IAAA;AACxCvD,gBAAAA,QAAAA,EAAAA,MAAAA,CAAOkD;;0BAEVN,cAAA,CAACY,uBAAAA,EAAAA;AACCC,gBAAAA,KAAAA,EAAOvD,aAAAA,CAAc;AACnByB,oBAAAA,EAAAA,EAAIqB,8BAAAA,CAAkB,2BAAA,CAAA;oBACtBC,cAAAA,EAAgB;AAClB,iBAAA,CAAA;gBACAS,OAAAA,EAAQ,OAAA;gBACRlB,OAAAA,EAAS,CAACV,CAAAA,GAAwBA,CAAAA,CAAEO,eAAe,EAAA;AAEnD,gBAAA,QAAA,gBAAAO,cAAA,CAACe,UAAAA,EAAAA,EAAAA;;;;AAIT,CAAA;AAEA;;AAEkG,qGAElG,MAAMC,gBAAAA,GAAmBzF,uBAAAA,CAAOiB,gBAAAA,CAAI;;;;;;;MAO9B,EAAE,CAAC,EAAEf,KAAK,EAAE,GAAKA,KAAAA,CAAMO,MAAM,CAACiF,UAAU,CAAC;;;;AAI/C,CAAC;AAED,MAAMC,WAAAA,GAAc3F,uBAAAA,CAAO4F,GAAG;;;;;;;AAO9B,CAAC;AAED,MAAMC,WAAAA,GAAc7F,uBAAAA,CAAOC,iBAAAA,CAAK;;;;;;SAMvB,EAAE,CAAC,EAAEC,KAAK,EAAE,GAAKA,KAAAA,CAAMO,MAAM,CAACqF,UAAU,CAAC;cACpC,EAAE,CAAC,EAAE5F,KAAK,EAAE,GAAKA,KAAAA,CAAMO,MAAM,CAACiF,UAAU,CAAC;AACvD,CAAC;AAMD,MAAMK,YAAAA,GAAe,CAAC,EAAEC,KAAK,EAAqB,GAAA;AAChD,IAAA,MAAM,EAAEC,eAAe,EAAEC,GAAG,EAAEC,OAAO,EAAEC,IAAI,EAAEC,GAAG,EAAEC,OAAO,EAAEC,WAAW,EAAE,GAAGP,KAAAA;AAE3E,IAAA,IAAII,IAAAA,EAAMI,QAAAA,CAASC,iBAAAA,CAAYC,KAAK,CAAA,EAAG;AACrC,QAAA,MAAMC,QAAAA,GACJC,iCAAAA,CAA4BT,OAAAA,EAASU,SAAAA,EAAWR,QAAQO,iCAAAA,CAA4BP,GAAAA,CAAAA;AAEtF,QAAA,IAAIM,QAAAA,EAAU;AACZ,YAAA,qBACElC,cAAA,CAACgB,gBAAAA,EAAAA;AACC,gBAAA,QAAA,gBAAAhB,cAAA,CAACkB,WAAAA,EAAAA;oBACCmB,GAAAA,EAAKH,QAAAA;AACLI,oBAAAA,GAAAA,EAAKd,eAAAA,IAAmB,EAAA;;;;oBAIxBe,WAAAA,EAAa,CAACV,OAAAA,IAAWC,WAAAA,GAAc,WAAA,GAAcxF,SAAAA;oBACrD4B,SAAAA,EAAW,KAAA;oBACXsE,WAAAA,EAAa,CAACtD,CAAAA,GAAMA,CAAAA,CAAEK,cAAc;;;AAI5C,QAAA;AACF,IAAA;IAEA,MAAMkD,OAAAA,GAAUC,0BAAaf,IAAAA,EAAMF,GAAAA,CAAAA;AAEnC,IAAA,qBACEzB,cAAA,CAACgB,gBAAAA,EAAAA;AACC,QAAA,QAAA,gBAAAhB,cAAA,CAACoB,WAAAA,EAAAA;YAAYuB,cAAAA,EAAe,QAAA;YAASC,UAAAA,EAAW,QAAA;AAC9C,YAAA,QAAA,gBAAA5C,cAAA,CAACyC,OAAAA,EAAAA;gBAAQjC,KAAAA,EAAO,EAAA;gBAAIC,MAAAA,EAAQ;;;;AAIpC,CAAA;AAEA;;AAEkG,qGAElG,MAAMoC,gBAAAA,GAAmBtH,uBAAAA,CAAOuH,uBAAAA,CAAW;;2BAEhB,EAAE,CAAC,EAAErH,KAAK,EAAE,GAAKA,KAAAA,CAAMO,MAAM,CAACE,UAAU,CAAC;AACpE,CAAC;AAED,MAAM6G,UAAAA,GAAaxH,uBAAAA,CAAOC,iBAAAA,CAAK;;;AAG/B,CAAC;AAED,MAAMwH,YAAAA,GAAezH,uBAAAA,CAAOC,iBAAAA,CAAK;SACxB,EAAE,CAAC,EAAEC,KAAK,EAAE,GAAKA,KAAAA,CAAMO,MAAM,CAACgB,UAAU,CAAC;;AAElD,CAAC;AAED,MAAMiG,QAAAA,GAAW1H,uBAAAA,CAAO2B,uBAAAA,CAAW;;;AAGnC,CAAC;AAED;AACA;AACA,MAAMgG,UAAAA,GAAa3H,uBAAAA,CAAO4H,MAAM;;;;;;;;;;;;;;uBAcT,EAAE,CAAC,EAAE1H,KAAK,EAAE,GAAKA,KAAAA,CAAMO,MAAM,CAACC,UAAU,CAAC;;;;AAIhE,CAAC;AAQD,MAAMmH,SAAAA,GAAY,CAAC,EAAE7B,KAAK,EAAElE,eAAe,EAAEgG,gBAAgB,EAAkB,GAAA;IAC7E,MAAM,EAAE/F,aAAa,EAAE,GAAGC,iBAAAA,EAAAA;AAC1B,IAAA,MAAM+F,WAAWZ,yBAAAA,CAAanB,KAAAA,CAAMI,IAAI,EAAEJ,MAAME,GAAG,CAAA;AACnD,IAAA,MAAM,EAAE/D,aAAa,EAAE,GAAGC,sCAAAA,EAAAA,IAA0B;QAAED,aAAAA,EAAe;AAAM,KAAA;IAC3E,MAAM,EAAES,UAAU,EAAEC,SAAS,EAAEC,UAAU,EAAEE,UAAU,EAAE,GAAGgF,4BAAAA,CAAiBhC,KAAAA,CAAAA;AAC3E,IAAA,MAAM,EAAE3D,UAAU,EAAEC,MAAM,EAAEC,WAAW,EAAE,GAAGC,mCAAAA,EAAAA;IAC5C,MAAM,EAAEC,SAAS,EAAE,GAAGC,qDAAAA,EAAAA;IAEtB,MAAMY,GAAAA,GAAM2E,kBAAAA,CAASjC,KAAAA,CAAMxC,EAAE,CAAA;AAC7B,IAAA,MAAM0E,WAAW7F,UAAAA,CAAWiB,GAAAA,CAAAA;;;;AAK5B,IAAA,MAAM6E,kBAAkB,CAACxE,CAAAA,GAAAA;QACvB,IAAIA,CAAAA,CAAEC,QAAQ,EAAE;AACdrB,YAAAA,WAAAA,CAAYT,eAAAA,EAAiBwB,GAAAA,CAAAA;AAC/B,QAAA,CAAA,MAAO,IAAIK,CAAAA,CAAEE,OAAO,IAAIF,CAAAA,CAAEG,OAAO,EAAE;YACjCxB,MAAAA,CAAOgB,GAAAA,CAAAA;QACT,CAAA,MAAO;AACLwE,YAAAA,gBAAAA,CAAiB9B,MAAMxC,EAAE,CAAA;AAC3B,QAAA;AACF,IAAA,CAAA;;AAGA,IAAA,MAAMO,gBAAgB,CAACJ,CAAAA,GAAAA;QACrB,IAAIA,CAAAA,CAAEL,GAAG,KAAK,OAAA,EAAS;AACrBK,YAAAA,CAAAA,CAAEK,cAAc,EAAA;AAChB8D,YAAAA,gBAAAA,CAAiB9B,MAAMxC,EAAE,CAAA;AAC3B,QAAA,CAAA,MAAO,IAAIG,CAAAA,CAAEL,GAAG,KAAK,GAAA,EAAK;AACxBK,YAAAA,CAAAA,CAAEK,cAAc,EAAA;YAChB1B,MAAAA,CAAOgB,GAAAA,CAAAA;AACT,QAAA;AACF,IAAA,CAAA;AAEA,IAAA,MAAM8E,kBAAkB,CAACzE,CAAAA,GAAAA;AACvBA,QAAAA,CAAAA,CAAEO,eAAe,EAAA;AACjB4D,QAAAA,gBAAAA,CAAiB9B,MAAMxC,EAAE,CAAA;AAC3B,IAAA,CAAA;;;AAIA,IAAA,MAAMS,sBAAsB,CAACN,CAAAA,GAAAA;AAC3BA,QAAAA,CAAAA,CAAEO,eAAe,EAAA;QACjB,IAAIP,CAAAA,CAAEC,QAAQ,EAAE;AACdrB,YAAAA,WAAAA,CAAYT,eAAAA,EAAiBwB,GAAAA,CAAAA;QAC/B,CAAA,MAAO;YACLhB,MAAAA,CAAOgB,GAAAA,CAAAA;AACT,QAAA;AACF,IAAA,CAAA;AAEA,IAAA,qBACEa,eAAA,CAAC7D,UAAAA,EAAAA;QACC8D,GAAAA,EAAKtB,UAAAA;AACJ,QAAA,GAAGF,UAAU;AACb,QAAA,GAAGC,SAAS;QACbhC,WAAAA,EAAamC,UAAAA;QACbpC,cAAAA,EAAgBuB,aAAAA;QAChB3B,WAAAA,EAAa0H,QAAAA;QACb1D,QAAAA,EAAU,CAAA;QACVD,IAAAA,EAAK,UAAA;QACL0C,WAAAA,EAAa,CAACtD,CAAAA,GAAMA,CAAAA,CAAEK,cAAc,EAAA;QACpCK,OAAAA,EAAS8D,eAAAA;QACT7D,SAAAA,EAAWP,aAAAA;;0BAEXI,eAAA,CAACmD,gBAAAA,EAAAA;;AACE7E,oBAAAA,SAAAA,kBACCgC,cAAA,CAAC1E,eAAAA,EAAAA;wBAAgBuE,SAAAA,EAAW,CAACX,CAAAA,GAA2BA,CAAAA,CAAEO,eAAe,EAAA;AACvE,wBAAA,QAAA,gBAAAO,cAAA,CAACC,qBAAAA,EAAAA;4BACCC,OAAAA,EAASuD,QAAAA;4BACT7D,OAAAA,EAASJ,mBAAAA;AACTW,4BAAAA,YAAAA,EAAY7C,aAAAA,CACV;AACEyB,gCAAAA,EAAAA,EAAIqB,8BAAAA,CAAkB,uBAAA,CAAA;gCACtBC,cAAAA,EAAgB;6BAClB,EACA;AAAEC,gCAAAA,IAAAA,EAAMiB,MAAMjB;AAAK,6BAAA;;;kCAK3BN,cAAA,CAACsB,YAAAA,EAAAA;wBAAaC,KAAAA,EAAOA;;;;0BAEvBvB,cAAA,CAAC4D,qBAAAA,EAAAA;AACC,gBAAA,QAAA,gBAAAlE,eAAA,CAACqD,UAAAA,EAAAA;oBAAWH,UAAAA,EAAW,QAAA;oBAASiB,GAAAA,EAAK,CAAA;;sCACnC7D,cAAA,CAACgD,YAAAA,EAAAA;AACC,4BAAA,QAAA,gBAAAhD,cAAA,CAACsD,QAAAA,EAAAA;gCAAS9C,KAAAA,EAAO,EAAA;gCAAIC,MAAAA,EAAQ;;;sCAE/BT,cAAA,CAACkD,UAAAA,EAAAA;4BAAWY,IAAAA,EAAK,QAAA;4BAASlE,OAAAA,EAAS+D,eAAAA;AACjC,4BAAA,QAAA,gBAAA3D,cAAA,CAACiD,QAAAA,EAAAA;gCAASvC,SAAAA,EAAU,YAAA;gCAAaC,QAAQ,EAAA,IAAA;AACtCY,gCAAAA,QAAAA,EAAAA,KAAAA,CAAMjB;;;sCAGXN,cAAA,CAACY,uBAAAA,EAAAA;AACCC,4BAAAA,KAAAA,EAAOvD,aAAAA,CAAc;AACnByB,gCAAAA,EAAAA,EAAIqB,8BAAAA,CAAkB,2BAAA,CAAA;gCACtBC,cAAAA,EAAgB;AAClB,6BAAA,CAAA;4BACAS,OAAAA,EAAQ,OAAA;4BACRlB,OAAAA,EAAS,CAACV,CAAAA,GAAwBA,CAAAA,CAAEO,eAAe,EAAA;AAEnD,4BAAA,QAAA,gBAAAO,cAAA,CAACe,UAAAA,EAAAA,EAAAA;;;;;;;AAMb,CAAA;AAYO,MAAMgD,UAAAA,GAAa,CAAC,EAAEC,MAAM,EAAEC,OAAAA,GAAU,EAAE,EAAEZ,gBAAgB,EAAmB,GAAA;AACpF,IAAA,MAAMa,UAAAA,GAAaD,OAAAA,CAAQE,MAAM,GAAGH,OAAOG,MAAM;;;AAIjD,IAAA,MAAM9G,eAAAA,GAA6B;AAC9B4G,QAAAA,GAAAA,OAAAA,CAAQG,GAAG,CAAC,CAAChH,MAAAA,GAAW0B,mBAAAA,CAAU1B,OAAO2B,EAAE,CAAA,CAAA;AAC3CiF,QAAAA,GAAAA,MAAAA,CAAOI,GAAG,CAAC,CAAC7C,KAAAA,GAAUiC,kBAAAA,CAASjC,MAAMxC,EAAE,CAAA;AAC3C,KAAA;;;AAID,IAAA,IAAImF,eAAe,CAAA,EAAG;QACpB,OAAO,IAAA;AACT,IAAA;IAEA,qBACExE,eAAA,CAAC2E,kBAAKC,IAAI,EAAA;QAACT,GAAAA,EAAK,CAAA;QAAG/D,IAAAA,EAAK,MAAA;QAAOyE,aAAAA,EAAY,aAAA;;YACxCN,OAAAA,CAAQE,MAAM,GAAG,CAAA,kBAChBnE,cAAA,CAACzD,UAAAA,EAAAA;wCACCyD,cAAA,CAACqE,kBAAKC,IAAI,EAAA;oBAACT,GAAAA,EAAK,CAAA;AACbI,oBAAAA,QAAAA,EAAAA,OAAAA,CAAQG,GAAG,CAAC,CAAChH,MAAAA,iBACZ4C,cAAA,CAACqE,kBAAKG,IAAI,EAAA;4BAACC,GAAAA,EAAK,CAAA;4BAAGC,CAAAA,EAAG,CAAA;4BAAGC,CAAAA,EAAG,CAAA;4BAAGC,EAAAA,EAAI,EAAA;AACjC,4BAAA,QAAA,gBAAA5E,cAAA,CAAC7C,UAAAA,EAAAA;gCAAWC,MAAAA,EAAQA,MAAAA;gCAAQC,eAAAA,EAAiBA;;AADH,yBAAA,EAAA,CAAC,OAAO,EAAED,MAAAA,CAAO2B,EAAE,CAAA,CAAE,CAAA;;;AAOxEiF,YAAAA,MAAAA,CAAOI,GAAG,CAAC,CAAC7C,KAAAA,iBACXvB,cAAA,CAACqE,kBAAKG,IAAI,EAAA;oBACRC,GAAAA,EAAK,CAAA;oBACLC,CAAAA,EAAG,CAAA;oBACHC,CAAAA,EAAG,CAAA;oBACHC,EAAAA,EAAI,EAAA;oBAEJC,SAAAA,EAAU,QAAA;oBACVjC,UAAAA,EAAW,SAAA;AAEX,oBAAA,QAAA,gBAAA5C,cAAA,CAACoD,SAAAA,EAAAA;wBACC7B,KAAAA,EAAOA,KAAAA;wBACPlE,eAAAA,EAAiBA,eAAAA;wBACjBgG,gBAAAA,EAAkBA;;AAPf9B,iBAAAA,EAAAA,KAAAA,CAAMxC,EAAE,CAAA;;;AAavB;;;;"}
|
|
1
|
+
{"version":3,"file":"AssetsGrid.js","sources":["../../../../../../admin/src/future/pages/Assets/components/AssetsGrid.tsx"],"sourcesContent":["import { Box, Card, CardBody, CardHeader, Checkbox, Flex, Grid } from '@strapi/design-system';\nimport { Folder as FolderIcon } from '@strapi/icons';\nimport { useIntl } from 'react-intl';\nimport { styled, css } from 'styled-components';\n\nimport { ASSET_TYPES } from '../../../../enums';\nimport { TruncatedText } from '../../../components/TruncatedText';\nimport { useMediaLibraryPermissions } from '../../../hooks/useMediaLibraryPermissions';\nimport { prefixFileUrlWithBackendUrl } from '../../../utils/files';\nimport { getAssetIcon } from '../../../utils/getAssetIcon';\nimport { isEventFromWithin } from '../../../utils/isEventFromWithin';\nimport { getTranslationKey } from '../../../utils/translations';\nimport { useAssetSelection } from '../hooks/useAssetSelection';\nimport { useBusyAssetsOptional } from '../hooks/useBusyAssets';\nimport { useFolderNavigation } from '../hooks/useFolderNavigation';\nimport { assetKey, folderKey, type ItemKey } from '../utils/selection';\n\nimport { AssetActionsMenu } from './AssetActionsMenu';\nimport { BusyOverlay } from './BusyOverlay';\nimport { useAssetsDndOptional } from './Dnd/AssetsDndProvider';\nimport { useFileDraggable, useFolderDraggableDroppable } from './Dnd/useAssetDnd';\nimport { FolderActionsMenu } from './FolderActionsMenu';\n\nimport type { File } from '../../../../../../shared/contracts/files';\nimport type { Folder } from '../../../../../../shared/contracts/folders';\n\n/* -------------------------------------------------------------------------------------------------\n * AssetsGrid\n * -----------------------------------------------------------------------------------------------*/\n\n// Cards own click, Enter and Space; the controls sitting on them (checkbox, \"...\"\n// menu) must not let those reach the card. Scoped to the wrapper's own DOM\n// subtree so the menu's portaled content — a React child of the wrapper, but\n// never a DOM descendant — still reaches `document`, where Radix listens in\n// order to dismiss its layers.\nconst stopCardEvent = (e: React.SyntheticEvent) => {\n if (isEventFromWithin(e)) {\n e.stopPropagation();\n }\n};\n\n// Top-left selection checkbox overlaid on the asset preview, always visible.\nconst CheckboxOverlay = styled(Flex)`\n position: absolute;\n top: ${({ theme }) => theme.spaces[3]};\n left: ${({ theme }) => theme.spaces[3]};\n z-index: 1;\n box-shadow: ${({ theme }) => theme.shadows.filterShadow};\n`;\n\nconst StyledCard = styled(Card)<{\n $isDragging?: boolean;\n $isMovePending?: boolean;\n $isBusy?: boolean;\n $isSelected?: boolean;\n}>`\n border: 1px solid\n ${({ theme, $isSelected }) => ($isSelected ? theme.colors.primary600 : theme.colors.neutral200)};\n border-radius: 8px;\n overflow: hidden;\n cursor: ${({ $isMovePending, $isBusy }) => ($isMovePending || $isBusy ? 'wait' : 'pointer')};\n opacity: ${({ $isDragging }) => ($isDragging ? 0.4 : 1)};\n /* No opacity change while busy — the overlay does the dimming, and stacking\n one on the other would wash the card out. */\n pointer-events: ${({ $isMovePending, $isBusy }) => ($isMovePending || $isBusy ? 'none' : 'auto')};\n background: ${({ theme, $isSelected }) => ($isSelected ? theme.colors.primary100 : undefined)};\n /* Shift+click range selection must not highlight card text. */\n user-select: none;\n\n &:hover {\n background: ${({ theme }) => theme.colors.primary100};\n }\n\n &:focus-visible {\n outline: 2px solid ${({ theme }) => theme.colors.primary600};\n outline-offset: 2px;\n }\n`;\n\n/* -------------------------------------------------------------------------------------------------\n * FolderCard\n * -----------------------------------------------------------------------------------------------*/\n\nconst FoldersRow = styled(Box)`\n grid-column: 1 / -1;\n`;\n\nconst StyledFolderCard = styled(Flex)<{\n $isDragging?: boolean;\n $isMovePending?: boolean;\n $isValidDropTarget?: boolean;\n $isInvalidDropTarget?: boolean;\n $isSelected?: boolean;\n}>`\n width: 100%;\n user-select: none;\n padding: ${({ theme }) => `${theme.spaces[2]} ${theme.spaces[3]}`}; // 8px 12px\n align-items: center;\n gap: ${({ theme }) => theme.spaces[2]}; // 8px\n border: 1px solid\n ${({ theme, $isSelected }) => ($isSelected ? theme.colors.primary600 : theme.colors.neutral200)};\n border-radius: ${({ theme }) => theme.borderRadius};\n background: ${({ theme, $isSelected }) =>\n $isSelected ? theme.colors.primary100 : theme.colors.neutral0};\n cursor: ${({ $isMovePending, $isInvalidDropTarget }) => {\n if ($isMovePending) {\n return 'wait';\n }\n\n return $isInvalidDropTarget ? 'not-allowed' : 'pointer';\n }};\n opacity: ${({ $isDragging }) => ($isDragging ? 0.4 : 1)};\n pointer-events: ${({ $isMovePending }) => ($isMovePending ? 'none' : 'auto')};\n transition: background 0.2s;\n\n ${({ $isValidDropTarget, theme }) =>\n $isValidDropTarget &&\n css`\n background: ${theme.colors.primary100};\n border: 1px dashed ${theme.colors.primary600};\n `}\n\n &:hover {\n background: ${({ theme }) => theme.colors.primary100};\n }\n\n &:focus-visible {\n outline: 2px solid ${({ theme }) => theme.colors.primary600};\n outline-offset: 2px;\n }\n`;\n\nconst FolderIconContainer = styled(Flex)`\n flex-shrink: 0;\n color: ${({ theme }) => theme.colors.neutral600};\n`;\n\nconst FolderName = styled(TruncatedText)`\n flex: 1;\n min-width: 0;\n`;\n\ninterface FolderCardProps {\n folder: Folder;\n orderedItemKeys: ItemKey[];\n}\n\nconst FolderCard = ({ folder, orderedItemKeys }: FolderCardProps) => {\n const { formatMessage } = useIntl();\n const { navigateToFolder } = useFolderNavigation();\n const { isMovePending } = useAssetsDndOptional() ?? { isMovePending: false };\n const { isSelected, toggle, selectRange } = useAssetSelection();\n const { canUpdate } = useMediaLibraryPermissions();\n const {\n dragData,\n draggable: { attributes, listeners, setNodeRef: setDragRef, isDragging },\n droppable: { setNodeRef: setDropRef },\n showValidDropHighlight,\n showInvalidDropCursor,\n } = useFolderDraggableDroppable(folder);\n\n const key = folderKey(folder.id);\n\n const setNodeRef = (node: HTMLElement | null) => {\n setDragRef(node);\n setDropRef(node);\n };\n\n // Folders share the selection mechanism with assets (toggle, range,\n // select-all). Only the plain-click semantic differs: it navigates into the\n // folder instead of selecting it.\n //\n // The containment guard on this and the handlers below is what keeps the\n // actions menu's portaled dialogs — React children of this card — from\n // navigating into the folder or starting a drag.\n const handleClick = (e: React.MouseEvent) => {\n if (!isEventFromWithin(e)) {\n return;\n }\n\n if (e.shiftKey) {\n selectRange(orderedItemKeys, key);\n } else if (e.metaKey || e.ctrlKey) {\n toggle(key);\n } else {\n navigateToFolder(folder);\n }\n };\n\n const handleKeyDown = (e: React.KeyboardEvent) => {\n if (!isEventFromWithin(e)) {\n return;\n }\n\n if (e.key === 'Enter') {\n e.preventDefault();\n navigateToFolder(folder);\n } else if (e.key === ' ') {\n e.preventDefault();\n toggle(key);\n }\n };\n\n // Checkbox is the pointer path to selection; Shift extends the range.\n const handleCheckboxClick = (e: React.MouseEvent) => {\n e.stopPropagation();\n if (e.shiftKey) {\n selectRange(orderedItemKeys, key);\n } else {\n toggle(key);\n }\n };\n\n return (\n <StyledFolderCard\n ref={setNodeRef}\n {...attributes}\n {...listeners}\n $isDragging={isDragging}\n $isMovePending={isMovePending}\n $isValidDropTarget={showValidDropHighlight}\n $isInvalidDropTarget={showInvalidDropCursor}\n $isSelected={isSelected(key)}\n onClick={handleClick}\n onKeyDown={handleKeyDown}\n onPointerDown={(e: React.PointerEvent) => {\n if (isEventFromWithin(e)) {\n listeners?.onPointerDown?.(e);\n }\n }}\n role=\"listitem\"\n tabIndex={0}\n >\n {canUpdate && (\n <Flex onKeyDown={(e: React.KeyboardEvent) => e.stopPropagation()}>\n <Checkbox\n checked={isSelected(key)}\n onClick={handleCheckboxClick}\n aria-label={formatMessage(\n {\n id: getTranslationKey('list.table.row.select'),\n defaultMessage: 'Select {name}',\n },\n { name: folder.name }\n )}\n />\n </Flex>\n )}\n <FolderIconContainer>\n <FolderIcon width={20} height={20} />\n </FolderIconContainer>\n <FolderName textColor=\"neutral800\">{folder.name}</FolderName>\n <Flex onClick={stopCardEvent} onKeyDown={stopCardEvent} onPointerDown={stopCardEvent}>\n <FolderActionsMenu folder={folder} dragData={dragData} />\n </Flex>\n </StyledFolderCard>\n );\n};\n\n/* -------------------------------------------------------------------------------------------------\n * AssetPreview\n * -----------------------------------------------------------------------------------------------*/\n\nconst PreviewContainer = styled(Box)`\n position: relative;\n width: 100%;\n padding-bottom: 62.5%;\n height: 0;\n overflow: hidden;\n background: repeating-conic-gradient(\n ${({ theme }) => theme.colors.neutral100} 0% 25%,\n transparent 0% 50%\n )\n 50% / 20px 20px;\n`;\n\nconst StyledImage = styled.img`\n position: absolute;\n top: 0;\n left: 0;\n width: 100%;\n height: 100%;\n object-fit: cover;\n`;\n\nconst IconPreview = styled(Flex)`\n position: absolute;\n top: 0;\n left: 0;\n width: 100%;\n height: 100%;\n color: ${({ theme }) => theme.colors.neutral500};\n background: ${({ theme }) => theme.colors.neutral100};\n`;\n\ninterface AssetPreviewProps {\n asset: File;\n}\n\nconst AssetPreview = ({ asset }: AssetPreviewProps) => {\n const { alternativeText, ext, formats, mime, url, updatedAt, isLocal, isUrlSigned } = asset;\n\n if (mime?.includes(ASSET_TYPES.Image)) {\n // Replace keeps the same hash/URL, so without a cache-buster the browser\n // serves the stale thumbnail after a Replace Media. `updatedAt`\n // changes on replace, so it re-fetches exactly once per replacement.\n // Skipped for signed URLs — an extra query param invalidates the signature.\n const cacheKey = updatedAt && !isUrlSigned ? new Date(updatedAt).getTime() : undefined;\n const appendCacheBuster = (raw: string) => {\n if (cacheKey === undefined) {\n return raw;\n }\n return raw.includes('?') ? `${raw}&v=${cacheKey}` : `${raw}?v=${cacheKey}`;\n };\n\n const rawMediaURL =\n prefixFileUrlWithBackendUrl(formats?.thumbnail?.url) ?? prefixFileUrlWithBackendUrl(url);\n const mediaURL = rawMediaURL ? appendCacheBuster(rawMediaURL) : rawMediaURL;\n\n if (mediaURL) {\n return (\n <PreviewContainer>\n <StyledImage\n src={mediaURL}\n alt={alternativeText || ''}\n // Only signed remote URLs need crossOrigin (cache collision with\n // the preview). Public/unsigned remote thumbnails must render\n // without a bucket CORS rule. See #26581.\n crossOrigin={!isLocal && isUrlSigned ? 'anonymous' : undefined}\n draggable={false}\n onDragStart={(e) => e.preventDefault()}\n />\n </PreviewContainer>\n );\n }\n }\n\n const DocIcon = getAssetIcon(mime, ext);\n\n return (\n <PreviewContainer>\n <IconPreview justifyContent=\"center\" alignItems=\"center\">\n <DocIcon width={48} height={48} />\n </IconPreview>\n </PreviewContainer>\n );\n};\n\n/* -------------------------------------------------------------------------------------------------\n * AssetCard\n * -----------------------------------------------------------------------------------------------*/\n\nconst StyledCardHeader = styled(CardHeader)`\n position: relative;\n border-bottom: 1px solid ${({ theme }) => theme.colors.neutral200};\n`;\n\nconst CardFooter = styled(Flex)`\n min-width: 0;\n width: 100%;\n`;\n\nconst FileTypeIcon = styled(Flex)`\n color: ${({ theme }) => theme.colors.neutral600};\n flex-shrink: 0;\n`;\n\nconst FileName = styled(TruncatedText)`\n flex: 1;\n min-width: 0;\n`;\n\n// The asset filename is its own interactive element: clicking it opens the\n// details drawer instead of selecting the card (mirrors the table view).\nconst NameButton = styled.button`\n display: inline-flex;\n flex: 1;\n min-width: 0;\n border: none;\n background: transparent;\n padding: 0;\n margin: 0;\n cursor: pointer;\n text-align: left;\n color: inherit;\n font: inherit;\n\n &:focus-visible {\n outline: 2px solid ${({ theme }) => theme.colors.primary600};\n outline-offset: 2px;\n border-radius: 2px;\n }\n`;\n\ninterface AssetCardProps {\n asset: File;\n orderedItemKeys: ItemKey[];\n onAssetItemClick: (assetId: number) => void;\n}\n\nconst AssetCard = ({ asset, orderedItemKeys, onAssetItemClick }: AssetCardProps) => {\n const { formatMessage } = useIntl();\n const TypeIcon = getAssetIcon(asset.mime, asset.ext);\n const { isMovePending } = useAssetsDndOptional() ?? { isMovePending: false };\n const { attributes, listeners, setNodeRef, isDragging, dragData } = useFileDraggable(asset);\n const { isSelected, toggle, selectRange } = useAssetSelection();\n const { canUpdate } = useMediaLibraryPermissions();\n const busyMessage = useBusyAssetsOptional()?.getBusyMessage(asset.id) ?? null;\n\n const key = assetKey(asset.id);\n const selected = isSelected(key);\n\n // Plain click opens the asset details; pointer selection lives on the\n // checkbox only. Modifier clicks keep the selection semantics: shift selects\n // a range, cmd/ctrl toggles.\n //\n // The containment guard on this and the handler below is what keeps the\n // actions menu's portaled dialogs — React children of this card — from\n // opening the details drawer or toggling the selection.\n const handleCardClick = (e: React.MouseEvent) => {\n if (!isEventFromWithin(e)) {\n return;\n }\n\n if (e.shiftKey) {\n selectRange(orderedItemKeys, key);\n } else if (e.metaKey || e.ctrlKey) {\n toggle(key);\n } else {\n onAssetItemClick(asset.id);\n }\n };\n\n // Space toggles selection (additive), Enter opens the details drawer.\n const handleKeyDown = (e: React.KeyboardEvent) => {\n if (!isEventFromWithin(e)) {\n return;\n }\n\n if (e.key === 'Enter') {\n e.preventDefault();\n onAssetItemClick(asset.id);\n } else if (e.key === ' ') {\n e.preventDefault();\n toggle(key);\n }\n };\n\n const handleNameClick = (e: React.MouseEvent) => {\n e.stopPropagation();\n onAssetItemClick(asset.id);\n };\n\n // Same semantics as the table's row checkbox: Shift extends the range,\n // otherwise a plain additive toggle. Never bubbles into the card click.\n const handleCheckboxClick = (e: React.MouseEvent) => {\n e.stopPropagation();\n if (e.shiftKey) {\n selectRange(orderedItemKeys, key);\n } else {\n toggle(key);\n }\n };\n\n return (\n <StyledCard\n ref={setNodeRef}\n {...attributes}\n {...listeners}\n $isDragging={isDragging}\n $isMovePending={isMovePending}\n $isBusy={busyMessage !== null}\n $isSelected={selected}\n tabIndex={0}\n role=\"listitem\"\n onDragStart={(e) => e.preventDefault()}\n onClick={handleCardClick}\n onKeyDown={handleKeyDown}\n onPointerDown={(e: React.PointerEvent) => {\n if (isEventFromWithin(e)) {\n listeners?.onPointerDown?.(e);\n }\n }}\n >\n <StyledCardHeader>\n {canUpdate && (\n <CheckboxOverlay onKeyDown={(e: React.KeyboardEvent) => e.stopPropagation()}>\n <Checkbox\n checked={selected}\n onClick={handleCheckboxClick}\n aria-label={formatMessage(\n {\n id: getTranslationKey('list.table.row.select'),\n defaultMessage: 'Select {name}',\n },\n { name: asset.name }\n )}\n />\n </CheckboxOverlay>\n )}\n <AssetPreview asset={asset} />\n {/* The header is the card's only positioned ancestor, and it's the part\n worth covering — the footer keeps the name legible while the preview\n is mid-replace. Below the checkbox overlay (z-index 1) would hide\n the spinner, so it sits above it. */}\n {busyMessage !== null ? <BusyOverlay zIndex={2}>{busyMessage}</BusyOverlay> : null}\n </StyledCardHeader>\n <CardBody>\n <CardFooter alignItems=\"center\" gap={2}>\n <FileTypeIcon>\n <TypeIcon width={20} height={20} />\n </FileTypeIcon>\n <NameButton type=\"button\" onClick={handleNameClick}>\n <FileName textColor=\"primary800\">{asset.name}</FileName>\n </NameButton>\n <Flex onClick={stopCardEvent} onKeyDown={stopCardEvent} onPointerDown={stopCardEvent}>\n <AssetActionsMenu asset={asset} dragData={dragData} />\n </Flex>\n </CardFooter>\n </CardBody>\n </StyledCard>\n );\n};\n\n/* -------------------------------------------------------------------------------------------------\n * AssetsGrid\n * -----------------------------------------------------------------------------------------------*/\n\ninterface AssetsGridProps {\n assets: File[];\n folders?: Folder[];\n onAssetItemClick: (assetId: number) => void;\n}\n\nexport const AssetsGrid = ({ assets, folders = [], onAssetItemClick }: AssetsGridProps) => {\n const totalItems = folders.length + assets.length;\n\n // Render order: folders always on top in the grid (mixing is table-only) —\n // range selection follows it.\n const orderedItemKeys: ItemKey[] = [\n ...folders.map((folder) => folderKey(folder.id)),\n ...assets.map((asset) => assetKey(asset.id)),\n ];\n\n // The empty state is owned by the page (`AssetsView` renders `EmptyState`) — an\n // empty grid renders nothing at all.\n if (totalItems === 0) {\n return null;\n }\n\n return (\n <Grid.Root gap={4} role=\"list\" data-testid=\"assets-grid\">\n {folders.length > 0 && (\n <FoldersRow>\n <Grid.Root gap={4}>\n {folders.map((folder) => (\n <Grid.Item col={3} m={4} s={6} xs={12} key={`folder-${folder.id}`}>\n <FolderCard folder={folder} orderedItemKeys={orderedItemKeys} />\n </Grid.Item>\n ))}\n </Grid.Root>\n </FoldersRow>\n )}\n {assets.map((asset) => (\n <Grid.Item\n col={3}\n m={4}\n s={6}\n xs={12}\n key={asset.id}\n direction=\"column\"\n alignItems=\"stretch\"\n >\n <AssetCard\n asset={asset}\n orderedItemKeys={orderedItemKeys}\n onAssetItemClick={onAssetItemClick}\n />\n </Grid.Item>\n ))}\n </Grid.Root>\n );\n};\n"],"names":["stopCardEvent","e","isEventFromWithin","stopPropagation","CheckboxOverlay","styled","Flex","theme","spaces","shadows","filterShadow","StyledCard","Card","$isSelected","colors","primary600","neutral200","$isMovePending","$isBusy","$isDragging","primary100","undefined","FoldersRow","Box","StyledFolderCard","borderRadius","neutral0","$isInvalidDropTarget","$isValidDropTarget","css","FolderIconContainer","neutral600","FolderName","TruncatedText","FolderCard","folder","orderedItemKeys","formatMessage","useIntl","navigateToFolder","useFolderNavigation","isMovePending","useAssetsDndOptional","isSelected","toggle","selectRange","useAssetSelection","canUpdate","useMediaLibraryPermissions","dragData","draggable","attributes","listeners","setNodeRef","setDragRef","isDragging","droppable","setDropRef","showValidDropHighlight","showInvalidDropCursor","useFolderDraggableDroppable","key","folderKey","id","node","handleClick","shiftKey","metaKey","ctrlKey","handleKeyDown","preventDefault","handleCheckboxClick","_jsxs","ref","onClick","onKeyDown","onPointerDown","role","tabIndex","_jsx","Checkbox","checked","aria-label","getTranslationKey","defaultMessage","name","FolderIcon","width","height","textColor","FolderActionsMenu","PreviewContainer","neutral100","StyledImage","img","IconPreview","neutral500","AssetPreview","asset","alternativeText","ext","formats","mime","url","updatedAt","isLocal","isUrlSigned","includes","ASSET_TYPES","Image","cacheKey","Date","getTime","appendCacheBuster","raw","rawMediaURL","prefixFileUrlWithBackendUrl","thumbnail","mediaURL","src","alt","crossOrigin","onDragStart","DocIcon","getAssetIcon","justifyContent","alignItems","StyledCardHeader","CardHeader","CardFooter","FileTypeIcon","FileName","NameButton","button","AssetCard","onAssetItemClick","TypeIcon","useFileDraggable","busyMessage","useBusyAssetsOptional","getBusyMessage","assetKey","selected","handleCardClick","handleNameClick","BusyOverlay","zIndex","CardBody","gap","type","AssetActionsMenu","AssetsGrid","assets","folders","totalItems","length","map","Grid","Root","data-testid","Item","col","m","s","xs","direction"],"mappings":"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"}
|