@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.
Files changed (253) hide show
  1. package/dist/admin/future/App.js +3 -3
  2. package/dist/admin/future/App.js.map +1 -1
  3. package/dist/admin/future/App.mjs +4 -4
  4. package/dist/admin/future/App.mjs.map +1 -1
  5. package/dist/admin/future/components/BetaNotice.js +72 -0
  6. package/dist/admin/future/components/BetaNotice.js.map +1 -0
  7. package/dist/admin/future/components/BetaNotice.mjs +70 -0
  8. package/dist/admin/future/components/BetaNotice.mjs.map +1 -0
  9. package/dist/admin/future/components/Drawer.js +16 -3
  10. package/dist/admin/future/components/Drawer.js.map +1 -1
  11. package/dist/admin/future/components/Drawer.mjs +16 -3
  12. package/dist/admin/future/components/Drawer.mjs.map +1 -1
  13. package/dist/admin/future/components/TruncatedText.js +76 -0
  14. package/dist/admin/future/components/TruncatedText.js.map +1 -0
  15. package/dist/admin/future/components/TruncatedText.mjs +74 -0
  16. package/dist/admin/future/components/TruncatedText.mjs.map +1 -0
  17. package/dist/admin/future/hooks/useAIMetadataEnabled.js +39 -0
  18. package/dist/admin/future/hooks/useAIMetadataEnabled.js.map +1 -0
  19. package/dist/admin/future/hooks/useAIMetadataEnabled.mjs +37 -0
  20. package/dist/admin/future/hooks/useAIMetadataEnabled.mjs.map +1 -0
  21. package/dist/admin/future/hooks/useTracking.js +57 -0
  22. package/dist/admin/future/hooks/useTracking.js.map +1 -0
  23. package/dist/admin/future/hooks/useTracking.mjs +53 -0
  24. package/dist/admin/future/hooks/useTracking.mjs.map +1 -0
  25. package/dist/admin/future/pages/Assets/AssetsPage.js +328 -139
  26. package/dist/admin/future/pages/Assets/AssetsPage.js.map +1 -1
  27. package/dist/admin/future/pages/Assets/AssetsPage.mjs +332 -143
  28. package/dist/admin/future/pages/Assets/AssetsPage.mjs.map +1 -1
  29. package/dist/admin/future/pages/Assets/components/ActionsMenuContent.js +46 -0
  30. package/dist/admin/future/pages/Assets/components/ActionsMenuContent.js.map +1 -0
  31. package/dist/admin/future/pages/Assets/components/ActionsMenuContent.mjs +44 -0
  32. package/dist/admin/future/pages/Assets/components/ActionsMenuContent.mjs.map +1 -0
  33. package/dist/admin/future/pages/Assets/components/AssetActionsMenu.js +328 -0
  34. package/dist/admin/future/pages/Assets/components/AssetActionsMenu.js.map +1 -0
  35. package/dist/admin/future/pages/Assets/components/AssetActionsMenu.mjs +326 -0
  36. package/dist/admin/future/pages/Assets/components/AssetActionsMenu.mjs.map +1 -0
  37. package/dist/admin/future/pages/Assets/components/AssetDetails/AssetCropEditor.js +35 -14
  38. package/dist/admin/future/pages/Assets/components/AssetDetails/AssetCropEditor.js.map +1 -1
  39. package/dist/admin/future/pages/Assets/components/AssetDetails/AssetCropEditor.mjs +35 -14
  40. package/dist/admin/future/pages/Assets/components/AssetDetails/AssetCropEditor.mjs.map +1 -1
  41. package/dist/admin/future/pages/Assets/components/AssetDetails/AssetDetailsDrawer.js +74 -53
  42. package/dist/admin/future/pages/Assets/components/AssetDetails/AssetDetailsDrawer.js.map +1 -1
  43. package/dist/admin/future/pages/Assets/components/AssetDetails/AssetDetailsDrawer.mjs +74 -54
  44. package/dist/admin/future/pages/Assets/components/AssetDetails/AssetDetailsDrawer.mjs.map +1 -1
  45. package/dist/admin/future/pages/Assets/components/AssetsGrid.js +92 -28
  46. package/dist/admin/future/pages/Assets/components/AssetsGrid.js.map +1 -1
  47. package/dist/admin/future/pages/Assets/components/AssetsGrid.mjs +94 -30
  48. package/dist/admin/future/pages/Assets/components/AssetsGrid.mjs.map +1 -1
  49. package/dist/admin/future/pages/Assets/components/AssetsSearchInput.js +26 -4
  50. package/dist/admin/future/pages/Assets/components/AssetsSearchInput.js.map +1 -1
  51. package/dist/admin/future/pages/Assets/components/AssetsSearchInput.mjs +27 -5
  52. package/dist/admin/future/pages/Assets/components/AssetsSearchInput.mjs.map +1 -1
  53. package/dist/admin/future/pages/Assets/components/AssetsTable.js +172 -60
  54. package/dist/admin/future/pages/Assets/components/AssetsTable.js.map +1 -1
  55. package/dist/admin/future/pages/Assets/components/AssetsTable.mjs +175 -63
  56. package/dist/admin/future/pages/Assets/components/AssetsTable.mjs.map +1 -1
  57. package/dist/admin/future/pages/Assets/components/BulkActionsBar.js +64 -132
  58. package/dist/admin/future/pages/Assets/components/BulkActionsBar.js.map +1 -1
  59. package/dist/admin/future/pages/Assets/components/BulkActionsBar.mjs +64 -132
  60. package/dist/admin/future/pages/Assets/components/BulkActionsBar.mjs.map +1 -1
  61. package/dist/admin/future/pages/Assets/components/BulkMoveDialog.js +123 -76
  62. package/dist/admin/future/pages/Assets/components/BulkMoveDialog.js.map +1 -1
  63. package/dist/admin/future/pages/Assets/components/BulkMoveDialog.mjs +126 -79
  64. package/dist/admin/future/pages/Assets/components/BulkMoveDialog.mjs.map +1 -1
  65. package/dist/admin/future/pages/Assets/components/BusyOverlay.js +36 -0
  66. package/dist/admin/future/pages/Assets/components/BusyOverlay.js.map +1 -0
  67. package/dist/admin/future/pages/Assets/components/BusyOverlay.mjs +34 -0
  68. package/dist/admin/future/pages/Assets/components/BusyOverlay.mjs.map +1 -0
  69. package/dist/admin/future/pages/Assets/components/DeleteItemsDialog.js +131 -0
  70. package/dist/admin/future/pages/Assets/components/DeleteItemsDialog.js.map +1 -0
  71. package/dist/admin/future/pages/Assets/components/DeleteItemsDialog.mjs +129 -0
  72. package/dist/admin/future/pages/Assets/components/DeleteItemsDialog.mjs.map +1 -0
  73. package/dist/admin/future/pages/Assets/components/Dnd/AssetsDndProvider.js +27 -17
  74. package/dist/admin/future/pages/Assets/components/Dnd/AssetsDndProvider.js.map +1 -1
  75. package/dist/admin/future/pages/Assets/components/Dnd/AssetsDndProvider.mjs +28 -18
  76. package/dist/admin/future/pages/Assets/components/Dnd/AssetsDndProvider.mjs.map +1 -1
  77. package/dist/admin/future/pages/Assets/components/Dnd/buildDragSet.js +28 -31
  78. package/dist/admin/future/pages/Assets/components/Dnd/buildDragSet.js.map +1 -1
  79. package/dist/admin/future/pages/Assets/components/Dnd/buildDragSet.mjs +28 -31
  80. package/dist/admin/future/pages/Assets/components/Dnd/buildDragSet.mjs.map +1 -1
  81. package/dist/admin/future/pages/Assets/components/Dnd/useAssetDnd.js +10 -15
  82. package/dist/admin/future/pages/Assets/components/Dnd/useAssetDnd.js.map +1 -1
  83. package/dist/admin/future/pages/Assets/components/Dnd/useAssetDnd.mjs +10 -15
  84. package/dist/admin/future/pages/Assets/components/Dnd/useAssetDnd.mjs.map +1 -1
  85. package/dist/admin/future/pages/Assets/components/FilterBadges.js +13 -4
  86. package/dist/admin/future/pages/Assets/components/FilterBadges.js.map +1 -1
  87. package/dist/admin/future/pages/Assets/components/FilterBadges.mjs +13 -4
  88. package/dist/admin/future/pages/Assets/components/FilterBadges.mjs.map +1 -1
  89. package/dist/admin/future/pages/Assets/components/FilterMenu.js +259 -63
  90. package/dist/admin/future/pages/Assets/components/FilterMenu.js.map +1 -1
  91. package/dist/admin/future/pages/Assets/components/FilterMenu.mjs +262 -66
  92. package/dist/admin/future/pages/Assets/components/FilterMenu.mjs.map +1 -1
  93. package/dist/admin/future/pages/Assets/components/FolderActionsMenu.js +146 -0
  94. package/dist/admin/future/pages/Assets/components/FolderActionsMenu.js.map +1 -0
  95. package/dist/admin/future/pages/Assets/components/FolderActionsMenu.mjs +144 -0
  96. package/dist/admin/future/pages/Assets/components/FolderActionsMenu.mjs.map +1 -0
  97. package/dist/admin/future/pages/Assets/components/{CreateFolderDialog.js → FolderFormDialog.js} +62 -16
  98. package/dist/admin/future/pages/Assets/components/FolderFormDialog.js.map +1 -0
  99. package/dist/admin/future/pages/Assets/components/{CreateFolderDialog.mjs → FolderFormDialog.mjs} +64 -18
  100. package/dist/admin/future/pages/Assets/components/FolderFormDialog.mjs.map +1 -0
  101. package/dist/admin/future/pages/Assets/components/FolderTree/FolderTree.js +132 -229
  102. package/dist/admin/future/pages/Assets/components/FolderTree/FolderTree.js.map +1 -1
  103. package/dist/admin/future/pages/Assets/components/FolderTree/FolderTree.mjs +135 -232
  104. package/dist/admin/future/pages/Assets/components/FolderTree/FolderTree.mjs.map +1 -1
  105. package/dist/admin/future/pages/Assets/components/SortMenu.js +14 -0
  106. package/dist/admin/future/pages/Assets/components/SortMenu.js.map +1 -1
  107. package/dist/admin/future/pages/Assets/components/SortMenu.mjs +14 -0
  108. package/dist/admin/future/pages/Assets/components/SortMenu.mjs.map +1 -1
  109. package/dist/admin/future/pages/Assets/hooks/useAssetSelection.js +5 -0
  110. package/dist/admin/future/pages/Assets/hooks/useAssetSelection.js.map +1 -1
  111. package/dist/admin/future/pages/Assets/hooks/useAssetSelection.mjs +6 -1
  112. package/dist/admin/future/pages/Assets/hooks/useAssetSelection.mjs.map +1 -1
  113. package/dist/admin/future/pages/Assets/hooks/useBusyAssets.js +47 -0
  114. package/dist/admin/future/pages/Assets/hooks/useBusyAssets.js.map +1 -0
  115. package/dist/admin/future/pages/Assets/hooks/useBusyAssets.mjs +44 -0
  116. package/dist/admin/future/pages/Assets/hooks/useBusyAssets.mjs.map +1 -0
  117. package/dist/admin/future/pages/Assets/hooks/useInfiniteAssets.js +203 -62
  118. package/dist/admin/future/pages/Assets/hooks/useInfiniteAssets.js.map +1 -1
  119. package/dist/admin/future/pages/Assets/hooks/useInfiniteAssets.mjs +204 -63
  120. package/dist/admin/future/pages/Assets/hooks/useInfiniteAssets.mjs.map +1 -1
  121. package/dist/admin/future/pages/Assets/hooks/useInfiniteScrollSentinel.js +75 -0
  122. package/dist/admin/future/pages/Assets/hooks/useInfiniteScrollSentinel.js.map +1 -0
  123. package/dist/admin/future/pages/Assets/hooks/useInfiniteScrollSentinel.mjs +73 -0
  124. package/dist/admin/future/pages/Assets/hooks/useInfiniteScrollSentinel.mjs.map +1 -0
  125. package/dist/admin/future/pages/Assets/utils/selection.js +17 -0
  126. package/dist/admin/future/pages/Assets/utils/selection.js.map +1 -1
  127. package/dist/admin/future/pages/Assets/utils/selection.mjs +17 -1
  128. package/dist/admin/future/pages/Assets/utils/selection.mjs.map +1 -1
  129. package/dist/admin/future/services/api.js +31 -8
  130. package/dist/admin/future/services/api.js.map +1 -1
  131. package/dist/admin/future/services/api.mjs +31 -8
  132. package/dist/admin/future/services/api.mjs.map +1 -1
  133. package/dist/admin/future/services/assets.js +22 -23
  134. package/dist/admin/future/services/assets.js.map +1 -1
  135. package/dist/admin/future/services/assets.mjs +22 -23
  136. package/dist/admin/future/services/assets.mjs.map +1 -1
  137. package/dist/admin/future/services/folders.js +37 -2
  138. package/dist/admin/future/services/folders.js.map +1 -1
  139. package/dist/admin/future/services/folders.mjs +37 -3
  140. package/dist/admin/future/services/folders.mjs.map +1 -1
  141. package/dist/admin/future/utils/buildDragSetFromSelection.js +7 -5
  142. package/dist/admin/future/utils/buildDragSetFromSelection.js.map +1 -1
  143. package/dist/admin/future/utils/buildDragSetFromSelection.mjs +7 -5
  144. package/dist/admin/future/utils/buildDragSetFromSelection.mjs.map +1 -1
  145. package/dist/admin/future/utils/formatMoveSuccessMessage.js +12 -1
  146. package/dist/admin/future/utils/formatMoveSuccessMessage.js.map +1 -1
  147. package/dist/admin/future/utils/formatMoveSuccessMessage.mjs +12 -1
  148. package/dist/admin/future/utils/formatMoveSuccessMessage.mjs.map +1 -1
  149. package/dist/admin/future/utils/getRelationId.js +24 -0
  150. package/dist/admin/future/utils/getRelationId.js.map +1 -0
  151. package/dist/admin/future/utils/getRelationId.mjs +22 -0
  152. package/dist/admin/future/utils/getRelationId.mjs.map +1 -0
  153. package/dist/admin/future/utils/isEventFromWithin.js +14 -0
  154. package/dist/admin/future/utils/isEventFromWithin.js.map +1 -0
  155. package/dist/admin/future/utils/isEventFromWithin.mjs +12 -0
  156. package/dist/admin/future/utils/isEventFromWithin.mjs.map +1 -0
  157. package/dist/admin/future/utils/itemLocations.js +40 -0
  158. package/dist/admin/future/utils/itemLocations.js.map +1 -0
  159. package/dist/admin/future/utils/itemLocations.mjs +36 -0
  160. package/dist/admin/future/utils/itemLocations.mjs.map +1 -0
  161. package/dist/admin/future/utils/itemSource.js +36 -0
  162. package/dist/admin/future/utils/itemSource.js.map +1 -0
  163. package/dist/admin/future/utils/itemSource.mjs +32 -0
  164. package/dist/admin/future/utils/itemSource.mjs.map +1 -0
  165. package/dist/admin/hooks/useAIMetadataJob.js +1 -1
  166. package/dist/admin/hooks/useAIMetadataJob.js.map +1 -1
  167. package/dist/admin/hooks/useAIMetadataJob.mjs +1 -1
  168. package/dist/admin/hooks/useAIMetadataJob.mjs.map +1 -1
  169. package/dist/admin/index.js +11 -17
  170. package/dist/admin/index.js.map +1 -1
  171. package/dist/admin/index.mjs +12 -18
  172. package/dist/admin/index.mjs.map +1 -1
  173. package/dist/admin/pages/SettingsPage/SettingsPage.js +2 -2
  174. package/dist/admin/pages/SettingsPage/SettingsPage.js.map +1 -1
  175. package/dist/admin/pages/SettingsPage/SettingsPage.mjs +2 -2
  176. package/dist/admin/pages/SettingsPage/SettingsPage.mjs.map +1 -1
  177. package/dist/admin/src/future/App.d.ts +1 -1
  178. package/dist/admin/src/future/components/BetaNotice.d.ts +11 -0
  179. package/dist/admin/src/future/components/Drawer.d.ts +5 -1
  180. package/dist/admin/src/future/components/TruncatedText.d.ts +32 -0
  181. package/dist/admin/src/future/hooks/useAIMetadataEnabled.d.ts +26 -0
  182. package/dist/admin/src/future/hooks/useTracking.d.ts +29 -0
  183. package/dist/admin/src/future/pages/Assets/components/ActionsMenuContent.d.ts +33 -0
  184. package/dist/admin/src/future/pages/Assets/components/AssetActionsMenu.d.ts +26 -0
  185. package/dist/admin/src/future/pages/Assets/components/AssetDetails/AssetDetailsDrawer.d.ts +16 -0
  186. package/dist/admin/src/future/pages/Assets/components/BulkActionsBar.d.ts +8 -1
  187. package/dist/admin/src/future/pages/Assets/components/BulkMoveDialog.d.ts +17 -6
  188. package/dist/admin/src/future/pages/Assets/components/BusyOverlay.d.ts +9 -0
  189. package/dist/admin/src/future/pages/Assets/components/DeleteItemsDialog.d.ts +27 -0
  190. package/dist/admin/src/future/pages/Assets/components/Dnd/AssetsDndProvider.d.ts +8 -1
  191. package/dist/admin/src/future/pages/Assets/components/Dnd/buildDragSet.d.ts +18 -3
  192. package/dist/admin/src/future/pages/Assets/components/Dnd/useAssetDnd.d.ts +2 -1
  193. package/dist/admin/src/future/pages/Assets/components/FilterBadges.d.ts +3 -1
  194. package/dist/admin/src/future/pages/Assets/components/FilterMenu.d.ts +4 -0
  195. package/dist/admin/src/future/pages/Assets/components/FolderActionsMenu.d.ts +21 -0
  196. package/dist/admin/src/future/pages/Assets/components/FolderFormDialog.d.ts +16 -0
  197. package/dist/admin/src/future/pages/Assets/hooks/useAssetSelection.d.ts +2 -0
  198. package/dist/admin/src/future/pages/Assets/hooks/useBusyAssets.d.ts +38 -0
  199. package/dist/admin/src/future/pages/Assets/hooks/useInfiniteAssets.d.ts +20 -6
  200. package/dist/admin/src/future/pages/Assets/hooks/useInfiniteScrollSentinel.d.ts +41 -0
  201. package/dist/admin/src/future/pages/Assets/utils/selection.d.ts +10 -0
  202. package/dist/admin/src/future/services/api.d.ts +6 -7
  203. package/dist/admin/src/future/services/folders.d.ts +6 -1
  204. package/dist/admin/src/future/utils/buildDragSetFromSelection.d.ts +4 -3
  205. package/dist/admin/src/future/utils/formatMoveSuccessMessage.d.ts +7 -1
  206. package/dist/admin/src/future/utils/getRelationId.d.ts +11 -0
  207. package/dist/admin/src/future/utils/isEventFromWithin.d.ts +11 -0
  208. package/dist/admin/src/future/utils/itemLocations.d.ts +31 -0
  209. package/dist/admin/src/future/utils/itemSource.d.ts +22 -0
  210. package/dist/admin/translations/en.json.js +25 -4
  211. package/dist/admin/translations/en.json.js.map +1 -1
  212. package/dist/admin/translations/en.json.mjs +25 -4
  213. package/dist/admin/translations/en.json.mjs.map +1 -1
  214. package/dist/server/controllers/admin-file.js +27 -9
  215. package/dist/server/controllers/admin-file.js.map +1 -1
  216. package/dist/server/controllers/admin-file.mjs +27 -9
  217. package/dist/server/controllers/admin-file.mjs.map +1 -1
  218. package/dist/server/controllers/admin-upload.js +24 -8
  219. package/dist/server/controllers/admin-upload.js.map +1 -1
  220. package/dist/server/controllers/admin-upload.mjs +24 -8
  221. package/dist/server/controllers/admin-upload.mjs.map +1 -1
  222. package/dist/server/routes/admin.js +41 -21
  223. package/dist/server/routes/admin.js.map +1 -1
  224. package/dist/server/routes/admin.mjs +41 -21
  225. package/dist/server/routes/admin.mjs.map +1 -1
  226. package/dist/server/services/ai-metadata.js.map +1 -1
  227. package/dist/server/services/ai-metadata.mjs.map +1 -1
  228. package/dist/server/services/image-manipulation.js.map +1 -1
  229. package/dist/server/services/image-manipulation.mjs.map +1 -1
  230. package/dist/server/src/controllers/admin-file.d.ts +29 -8
  231. package/dist/server/src/controllers/admin-file.d.ts.map +1 -1
  232. package/dist/server/src/controllers/admin-upload.d.ts +20 -4
  233. package/dist/server/src/controllers/admin-upload.d.ts.map +1 -1
  234. package/dist/server/src/controllers/index.d.ts +4 -4
  235. package/dist/server/src/index.d.ts +4 -4
  236. package/dist/server/src/routes/admin.d.ts.map +1 -1
  237. package/dist/server/src/services/ai-metadata.d.ts +2 -2
  238. package/dist/server/src/services/ai-metadata.d.ts.map +1 -1
  239. package/dist/server/src/services/image-manipulation.d.ts +0 -5
  240. package/dist/server/src/services/image-manipulation.d.ts.map +1 -1
  241. package/dist/shared/contracts/ai-metadata-jobs.d.ts +10 -32
  242. package/dist/shared/contracts/ai-metadata-jobs.d.ts.map +1 -1
  243. package/dist/shared/contracts/files.d.ts +10 -10
  244. package/dist/shared/contracts/files.d.ts.map +1 -1
  245. package/package.json +9 -9
  246. package/dist/admin/future/pages/Assets/components/CreateFolderDialog.js.map +0 -1
  247. package/dist/admin/future/pages/Assets/components/CreateFolderDialog.mjs.map +0 -1
  248. package/dist/admin/future/pages/Assets/components/FolderTree/filterFolderTree.js +0 -33
  249. package/dist/admin/future/pages/Assets/components/FolderTree/filterFolderTree.js.map +0 -1
  250. package/dist/admin/future/pages/Assets/components/FolderTree/filterFolderTree.mjs +0 -31
  251. package/dist/admin/future/pages/Assets/components/FolderTree/filterFolderTree.mjs.map +0 -1
  252. package/dist/admin/src/future/pages/Assets/components/CreateFolderDialog.d.ts +0 -8
  253. 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
- * -----------------------------------------------------------------------------------------------*/ // Top-left selection checkbox overlaid on the asset preview, always visible.
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
- pointer-events: ${({ $isMovePending })=>$isMovePending ? 'none' : 'auto'};
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(designSystem.Typography)`
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.IconButton, {
180
- label: formatMessage({
181
- id: translations.getTranslationKey('control-card.more-actions'),
182
- defaultMessage: 'More actions'
183
- }),
184
- variant: "ghost",
185
- onClick: (e)=>e.stopPropagation(),
186
- children: /*#__PURE__*/ jsxRuntime.jsx(icons.More, {})
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
- const mediaURL = files.prefixFileUrlWithBackendUrl(formats?.thumbnail?.url) ?? files.prefixFileUrlWithBackendUrl(url);
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(designSystem.Typography)`
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.IconButton, {
393
- label: formatMessage({
394
- id: translations.getTranslationKey('control-card.more-actions'),
395
- defaultMessage: 'More actions'
396
- }),
397
- variant: "ghost",
398
- onClick: (e)=>e.stopPropagation(),
399
- children: /*#__PURE__*/ jsxRuntime.jsx(icons.More, {})
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":"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"}
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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"}