@strapi/upload 5.51.2 → 5.52.0

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 (193) 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/hooks/useAIMetadataEnabled.js +39 -0
  14. package/dist/admin/future/hooks/useAIMetadataEnabled.js.map +1 -0
  15. package/dist/admin/future/hooks/useAIMetadataEnabled.mjs +37 -0
  16. package/dist/admin/future/hooks/useAIMetadataEnabled.mjs.map +1 -0
  17. package/dist/admin/future/pages/Assets/AssetsPage.js +297 -139
  18. package/dist/admin/future/pages/Assets/AssetsPage.js.map +1 -1
  19. package/dist/admin/future/pages/Assets/AssetsPage.mjs +301 -143
  20. package/dist/admin/future/pages/Assets/AssetsPage.mjs.map +1 -1
  21. package/dist/admin/future/pages/Assets/components/ActionsMenuContent.js +46 -0
  22. package/dist/admin/future/pages/Assets/components/ActionsMenuContent.js.map +1 -0
  23. package/dist/admin/future/pages/Assets/components/ActionsMenuContent.mjs +44 -0
  24. package/dist/admin/future/pages/Assets/components/ActionsMenuContent.mjs.map +1 -0
  25. package/dist/admin/future/pages/Assets/components/AssetActionsMenu.js +325 -0
  26. package/dist/admin/future/pages/Assets/components/AssetActionsMenu.js.map +1 -0
  27. package/dist/admin/future/pages/Assets/components/AssetActionsMenu.mjs +323 -0
  28. package/dist/admin/future/pages/Assets/components/AssetActionsMenu.mjs.map +1 -0
  29. package/dist/admin/future/pages/Assets/components/AssetDetails/AssetCropEditor.js +35 -14
  30. package/dist/admin/future/pages/Assets/components/AssetDetails/AssetCropEditor.js.map +1 -1
  31. package/dist/admin/future/pages/Assets/components/AssetDetails/AssetCropEditor.mjs +35 -14
  32. package/dist/admin/future/pages/Assets/components/AssetDetails/AssetCropEditor.mjs.map +1 -1
  33. package/dist/admin/future/pages/Assets/components/AssetDetails/AssetDetailsDrawer.js +54 -53
  34. package/dist/admin/future/pages/Assets/components/AssetDetails/AssetDetailsDrawer.js.map +1 -1
  35. package/dist/admin/future/pages/Assets/components/AssetDetails/AssetDetailsDrawer.mjs +54 -54
  36. package/dist/admin/future/pages/Assets/components/AssetDetails/AssetDetailsDrawer.mjs.map +1 -1
  37. package/dist/admin/future/pages/Assets/components/AssetsGrid.js +89 -24
  38. package/dist/admin/future/pages/Assets/components/AssetsGrid.js.map +1 -1
  39. package/dist/admin/future/pages/Assets/components/AssetsGrid.mjs +91 -26
  40. package/dist/admin/future/pages/Assets/components/AssetsGrid.mjs.map +1 -1
  41. package/dist/admin/future/pages/Assets/components/AssetsSearchInput.js +15 -3
  42. package/dist/admin/future/pages/Assets/components/AssetsSearchInput.js.map +1 -1
  43. package/dist/admin/future/pages/Assets/components/AssetsSearchInput.mjs +16 -4
  44. package/dist/admin/future/pages/Assets/components/AssetsSearchInput.mjs.map +1 -1
  45. package/dist/admin/future/pages/Assets/components/AssetsTable.js +168 -58
  46. package/dist/admin/future/pages/Assets/components/AssetsTable.js.map +1 -1
  47. package/dist/admin/future/pages/Assets/components/AssetsTable.mjs +171 -61
  48. package/dist/admin/future/pages/Assets/components/AssetsTable.mjs.map +1 -1
  49. package/dist/admin/future/pages/Assets/components/BulkActionsBar.js +64 -132
  50. package/dist/admin/future/pages/Assets/components/BulkActionsBar.js.map +1 -1
  51. package/dist/admin/future/pages/Assets/components/BulkActionsBar.mjs +64 -132
  52. package/dist/admin/future/pages/Assets/components/BulkActionsBar.mjs.map +1 -1
  53. package/dist/admin/future/pages/Assets/components/BulkMoveDialog.js +123 -76
  54. package/dist/admin/future/pages/Assets/components/BulkMoveDialog.js.map +1 -1
  55. package/dist/admin/future/pages/Assets/components/BulkMoveDialog.mjs +126 -79
  56. package/dist/admin/future/pages/Assets/components/BulkMoveDialog.mjs.map +1 -1
  57. package/dist/admin/future/pages/Assets/components/BusyOverlay.js +36 -0
  58. package/dist/admin/future/pages/Assets/components/BusyOverlay.js.map +1 -0
  59. package/dist/admin/future/pages/Assets/components/BusyOverlay.mjs +34 -0
  60. package/dist/admin/future/pages/Assets/components/BusyOverlay.mjs.map +1 -0
  61. package/dist/admin/future/pages/Assets/components/DeleteItemsDialog.js +131 -0
  62. package/dist/admin/future/pages/Assets/components/DeleteItemsDialog.js.map +1 -0
  63. package/dist/admin/future/pages/Assets/components/DeleteItemsDialog.mjs +129 -0
  64. package/dist/admin/future/pages/Assets/components/DeleteItemsDialog.mjs.map +1 -0
  65. package/dist/admin/future/pages/Assets/components/Dnd/AssetsDndProvider.js +27 -17
  66. package/dist/admin/future/pages/Assets/components/Dnd/AssetsDndProvider.js.map +1 -1
  67. package/dist/admin/future/pages/Assets/components/Dnd/AssetsDndProvider.mjs +28 -18
  68. package/dist/admin/future/pages/Assets/components/Dnd/AssetsDndProvider.mjs.map +1 -1
  69. package/dist/admin/future/pages/Assets/components/Dnd/buildDragSet.js +28 -31
  70. package/dist/admin/future/pages/Assets/components/Dnd/buildDragSet.js.map +1 -1
  71. package/dist/admin/future/pages/Assets/components/Dnd/buildDragSet.mjs +28 -31
  72. package/dist/admin/future/pages/Assets/components/Dnd/buildDragSet.mjs.map +1 -1
  73. package/dist/admin/future/pages/Assets/components/Dnd/useAssetDnd.js +10 -15
  74. package/dist/admin/future/pages/Assets/components/Dnd/useAssetDnd.js.map +1 -1
  75. package/dist/admin/future/pages/Assets/components/Dnd/useAssetDnd.mjs +10 -15
  76. package/dist/admin/future/pages/Assets/components/Dnd/useAssetDnd.mjs.map +1 -1
  77. package/dist/admin/future/pages/Assets/components/FilterBadges.js +13 -4
  78. package/dist/admin/future/pages/Assets/components/FilterBadges.js.map +1 -1
  79. package/dist/admin/future/pages/Assets/components/FilterBadges.mjs +13 -4
  80. package/dist/admin/future/pages/Assets/components/FilterBadges.mjs.map +1 -1
  81. package/dist/admin/future/pages/Assets/components/FilterMenu.js +241 -61
  82. package/dist/admin/future/pages/Assets/components/FilterMenu.js.map +1 -1
  83. package/dist/admin/future/pages/Assets/components/FilterMenu.mjs +244 -64
  84. package/dist/admin/future/pages/Assets/components/FilterMenu.mjs.map +1 -1
  85. package/dist/admin/future/pages/Assets/components/FolderActionsMenu.js +144 -0
  86. package/dist/admin/future/pages/Assets/components/FolderActionsMenu.js.map +1 -0
  87. package/dist/admin/future/pages/Assets/components/FolderActionsMenu.mjs +142 -0
  88. package/dist/admin/future/pages/Assets/components/FolderActionsMenu.mjs.map +1 -0
  89. package/dist/admin/future/pages/Assets/components/{CreateFolderDialog.js → FolderFormDialog.js} +50 -16
  90. package/dist/admin/future/pages/Assets/components/FolderFormDialog.js.map +1 -0
  91. package/dist/admin/future/pages/Assets/components/{CreateFolderDialog.mjs → FolderFormDialog.mjs} +52 -18
  92. package/dist/admin/future/pages/Assets/components/FolderFormDialog.mjs.map +1 -0
  93. package/dist/admin/future/pages/Assets/components/FolderTree/FolderTree.js +111 -191
  94. package/dist/admin/future/pages/Assets/components/FolderTree/FolderTree.js.map +1 -1
  95. package/dist/admin/future/pages/Assets/components/FolderTree/FolderTree.mjs +114 -194
  96. package/dist/admin/future/pages/Assets/components/FolderTree/FolderTree.mjs.map +1 -1
  97. package/dist/admin/future/pages/Assets/hooks/useBusyAssets.js +47 -0
  98. package/dist/admin/future/pages/Assets/hooks/useBusyAssets.js.map +1 -0
  99. package/dist/admin/future/pages/Assets/hooks/useBusyAssets.mjs +44 -0
  100. package/dist/admin/future/pages/Assets/hooks/useBusyAssets.mjs.map +1 -0
  101. package/dist/admin/future/pages/Assets/hooks/useInfiniteAssets.js +203 -62
  102. package/dist/admin/future/pages/Assets/hooks/useInfiniteAssets.js.map +1 -1
  103. package/dist/admin/future/pages/Assets/hooks/useInfiniteAssets.mjs +204 -63
  104. package/dist/admin/future/pages/Assets/hooks/useInfiniteAssets.mjs.map +1 -1
  105. package/dist/admin/future/pages/Assets/hooks/useInfiniteScrollSentinel.js +75 -0
  106. package/dist/admin/future/pages/Assets/hooks/useInfiniteScrollSentinel.js.map +1 -0
  107. package/dist/admin/future/pages/Assets/hooks/useInfiniteScrollSentinel.mjs +73 -0
  108. package/dist/admin/future/pages/Assets/hooks/useInfiniteScrollSentinel.mjs.map +1 -0
  109. package/dist/admin/future/services/api.js +24 -0
  110. package/dist/admin/future/services/api.js.map +1 -1
  111. package/dist/admin/future/services/api.mjs +24 -0
  112. package/dist/admin/future/services/api.mjs.map +1 -1
  113. package/dist/admin/future/services/assets.js +11 -0
  114. package/dist/admin/future/services/assets.js.map +1 -1
  115. package/dist/admin/future/services/assets.mjs +11 -0
  116. package/dist/admin/future/services/assets.mjs.map +1 -1
  117. package/dist/admin/future/services/folders.js +37 -2
  118. package/dist/admin/future/services/folders.js.map +1 -1
  119. package/dist/admin/future/services/folders.mjs +37 -3
  120. package/dist/admin/future/services/folders.mjs.map +1 -1
  121. package/dist/admin/future/utils/buildDragSetFromSelection.js +7 -5
  122. package/dist/admin/future/utils/buildDragSetFromSelection.js.map +1 -1
  123. package/dist/admin/future/utils/buildDragSetFromSelection.mjs +7 -5
  124. package/dist/admin/future/utils/buildDragSetFromSelection.mjs.map +1 -1
  125. package/dist/admin/future/utils/formatMoveSuccessMessage.js +12 -1
  126. package/dist/admin/future/utils/formatMoveSuccessMessage.js.map +1 -1
  127. package/dist/admin/future/utils/formatMoveSuccessMessage.mjs +12 -1
  128. package/dist/admin/future/utils/formatMoveSuccessMessage.mjs.map +1 -1
  129. package/dist/admin/future/utils/getRelationId.js +24 -0
  130. package/dist/admin/future/utils/getRelationId.js.map +1 -0
  131. package/dist/admin/future/utils/getRelationId.mjs +22 -0
  132. package/dist/admin/future/utils/getRelationId.mjs.map +1 -0
  133. package/dist/admin/future/utils/isEventFromWithin.js +14 -0
  134. package/dist/admin/future/utils/isEventFromWithin.js.map +1 -0
  135. package/dist/admin/future/utils/isEventFromWithin.mjs +12 -0
  136. package/dist/admin/future/utils/isEventFromWithin.mjs.map +1 -0
  137. package/dist/admin/future/utils/itemLocations.js +40 -0
  138. package/dist/admin/future/utils/itemLocations.js.map +1 -0
  139. package/dist/admin/future/utils/itemLocations.mjs +36 -0
  140. package/dist/admin/future/utils/itemLocations.mjs.map +1 -0
  141. package/dist/admin/future/utils/itemSource.js +36 -0
  142. package/dist/admin/future/utils/itemSource.js.map +1 -0
  143. package/dist/admin/future/utils/itemSource.mjs +32 -0
  144. package/dist/admin/future/utils/itemSource.mjs.map +1 -0
  145. package/dist/admin/index.js +11 -17
  146. package/dist/admin/index.js.map +1 -1
  147. package/dist/admin/index.mjs +12 -18
  148. package/dist/admin/index.mjs.map +1 -1
  149. package/dist/admin/src/future/App.d.ts +1 -1
  150. package/dist/admin/src/future/components/BetaNotice.d.ts +11 -0
  151. package/dist/admin/src/future/components/Drawer.d.ts +5 -1
  152. package/dist/admin/src/future/hooks/useAIMetadataEnabled.d.ts +26 -0
  153. package/dist/admin/src/future/pages/Assets/components/ActionsMenuContent.d.ts +33 -0
  154. package/dist/admin/src/future/pages/Assets/components/AssetActionsMenu.d.ts +24 -0
  155. package/dist/admin/src/future/pages/Assets/components/AssetDetails/AssetDetailsDrawer.d.ts +16 -0
  156. package/dist/admin/src/future/pages/Assets/components/BulkActionsBar.d.ts +8 -1
  157. package/dist/admin/src/future/pages/Assets/components/BulkMoveDialog.d.ts +17 -6
  158. package/dist/admin/src/future/pages/Assets/components/BusyOverlay.d.ts +9 -0
  159. package/dist/admin/src/future/pages/Assets/components/DeleteItemsDialog.d.ts +27 -0
  160. package/dist/admin/src/future/pages/Assets/components/Dnd/AssetsDndProvider.d.ts +8 -1
  161. package/dist/admin/src/future/pages/Assets/components/Dnd/buildDragSet.d.ts +18 -3
  162. package/dist/admin/src/future/pages/Assets/components/Dnd/useAssetDnd.d.ts +2 -1
  163. package/dist/admin/src/future/pages/Assets/components/FilterBadges.d.ts +3 -1
  164. package/dist/admin/src/future/pages/Assets/components/FilterMenu.d.ts +4 -0
  165. package/dist/admin/src/future/pages/Assets/components/FolderActionsMenu.d.ts +20 -0
  166. package/dist/admin/src/future/pages/Assets/components/FolderFormDialog.d.ts +16 -0
  167. package/dist/admin/src/future/pages/Assets/hooks/useBusyAssets.d.ts +38 -0
  168. package/dist/admin/src/future/pages/Assets/hooks/useInfiniteAssets.d.ts +20 -6
  169. package/dist/admin/src/future/pages/Assets/hooks/useInfiniteScrollSentinel.d.ts +41 -0
  170. package/dist/admin/src/future/services/folders.d.ts +6 -1
  171. package/dist/admin/src/future/utils/buildDragSetFromSelection.d.ts +4 -3
  172. package/dist/admin/src/future/utils/formatMoveSuccessMessage.d.ts +7 -1
  173. package/dist/admin/src/future/utils/getRelationId.d.ts +11 -0
  174. package/dist/admin/src/future/utils/isEventFromWithin.d.ts +11 -0
  175. package/dist/admin/src/future/utils/itemLocations.d.ts +31 -0
  176. package/dist/admin/src/future/utils/itemSource.d.ts +22 -0
  177. package/dist/admin/translations/en.json.js +25 -4
  178. package/dist/admin/translations/en.json.js.map +1 -1
  179. package/dist/admin/translations/en.json.mjs +25 -4
  180. package/dist/admin/translations/en.json.mjs.map +1 -1
  181. package/dist/server/services/image-manipulation.js.map +1 -1
  182. package/dist/server/services/image-manipulation.mjs.map +1 -1
  183. package/dist/server/src/services/image-manipulation.d.ts +0 -5
  184. package/dist/server/src/services/image-manipulation.d.ts.map +1 -1
  185. package/package.json +9 -9
  186. package/dist/admin/future/pages/Assets/components/CreateFolderDialog.js.map +0 -1
  187. package/dist/admin/future/pages/Assets/components/CreateFolderDialog.mjs.map +0 -1
  188. package/dist/admin/future/pages/Assets/components/FolderTree/filterFolderTree.js +0 -33
  189. package/dist/admin/future/pages/Assets/components/FolderTree/filterFolderTree.js.map +0 -1
  190. package/dist/admin/future/pages/Assets/components/FolderTree/filterFolderTree.mjs +0 -31
  191. package/dist/admin/future/pages/Assets/components/FolderTree/filterFolderTree.mjs.map +0 -1
  192. package/dist/admin/src/future/pages/Assets/components/CreateFolderDialog.d.ts +0 -8
  193. package/dist/admin/src/future/pages/Assets/components/FolderTree/filterFolderTree.d.ts +0 -16
@@ -0,0 +1 @@
1
+ {"version":3,"file":"getRelationId.mjs","sources":["../../../../admin/src/future/utils/getRelationId.ts"],"sourcesContent":["/**\n * Normalise a to-one relation down to its id.\n *\n * The contracts type `File['folder']` and `Folder['parent']` as ids, but the\n * admin populates both (`populate: { folder: true }` on `/upload/files`,\n * `populate: { parent: true }` on `/upload/folders`), so the wire value is an\n * object. Only the id is ever read — move validation compares locations by id.\n */\nexport const getRelationId = (\n relation: number | string | { id?: number } | null | undefined\n): number | null => {\n if (relation == null) {\n return null;\n }\n\n if (typeof relation === 'object') {\n return relation.id ?? null;\n }\n\n if (typeof relation === 'number') {\n return relation;\n }\n\n return Number(relation) || null;\n};\n"],"names":["getRelationId","relation","id","Number"],"mappings":"AAAA;;;;;;;IAQO,MAAMA,aAAAA,GAAgB,CAC3BC,QAAAA,GAAAA;AAEA,IAAA,IAAIA,YAAY,IAAA,EAAM;QACpB,OAAO,IAAA;AACT,IAAA;IAEA,IAAI,OAAOA,aAAa,QAAA,EAAU;QAChC,OAAOA,QAAAA,CAASC,EAAE,IAAI,IAAA;AACxB,IAAA;IAEA,IAAI,OAAOD,aAAa,QAAA,EAAU;QAChC,OAAOA,QAAAA;AACT,IAAA;AAEA,IAAA,OAAOE,OAAOF,QAAAA,CAAAA,IAAa,IAAA;AAC7B;;;;"}
@@ -0,0 +1,14 @@
1
+ 'use strict';
2
+
3
+ /**
4
+ * True when the event really originated inside `currentTarget`'s DOM subtree.
5
+ *
6
+ * Portaled content (Radix menus, modals, select popovers) bubbles through the
7
+ * React tree, so a row's handlers see events coming from dialogs rendered by
8
+ * its own children. Guarding on DOM containment keeps those out — without
9
+ * calling `stopPropagation`, which would also kill the native event before it
10
+ * reaches `document`, where Radix listens in order to dismiss its layers.
11
+ */ const isEventFromWithin = (event)=>event.currentTarget instanceof Node && event.target instanceof Node && event.currentTarget.contains(event.target);
12
+
13
+ exports.isEventFromWithin = isEventFromWithin;
14
+ //# sourceMappingURL=isEventFromWithin.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"isEventFromWithin.js","sources":["../../../../admin/src/future/utils/isEventFromWithin.ts"],"sourcesContent":["import type { SyntheticEvent } from 'react';\n\n/**\n * True when the event really originated inside `currentTarget`'s DOM subtree.\n *\n * Portaled content (Radix menus, modals, select popovers) bubbles through the\n * React tree, so a row's handlers see events coming from dialogs rendered by\n * its own children. Guarding on DOM containment keeps those out — without\n * calling `stopPropagation`, which would also kill the native event before it\n * reaches `document`, where Radix listens in order to dismiss its layers.\n */\nexport const isEventFromWithin = (event: SyntheticEvent) =>\n event.currentTarget instanceof Node &&\n event.target instanceof Node &&\n event.currentTarget.contains(event.target);\n"],"names":["isEventFromWithin","event","currentTarget","Node","target","contains"],"mappings":";;AAEA;;;;;;;;UASaA,iBAAAA,GAAoB,CAACC,QAChCA,KAAAA,CAAMC,aAAa,YAAYC,IAAAA,IAC/BF,KAAAA,CAAMG,MAAM,YAAYD,IAAAA,IACxBF,MAAMC,aAAa,CAACG,QAAQ,CAACJ,KAAAA,CAAMG,MAAM;;;;"}
@@ -0,0 +1,12 @@
1
+ /**
2
+ * True when the event really originated inside `currentTarget`'s DOM subtree.
3
+ *
4
+ * Portaled content (Radix menus, modals, select popovers) bubbles through the
5
+ * React tree, so a row's handlers see events coming from dialogs rendered by
6
+ * its own children. Guarding on DOM containment keeps those out — without
7
+ * calling `stopPropagation`, which would also kill the native event before it
8
+ * reaches `document`, where Radix listens in order to dismiss its layers.
9
+ */ const isEventFromWithin = (event)=>event.currentTarget instanceof Node && event.target instanceof Node && event.currentTarget.contains(event.target);
10
+
11
+ export { isEventFromWithin };
12
+ //# sourceMappingURL=isEventFromWithin.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"isEventFromWithin.mjs","sources":["../../../../admin/src/future/utils/isEventFromWithin.ts"],"sourcesContent":["import type { SyntheticEvent } from 'react';\n\n/**\n * True when the event really originated inside `currentTarget`'s DOM subtree.\n *\n * Portaled content (Radix menus, modals, select popovers) bubbles through the\n * React tree, so a row's handlers see events coming from dialogs rendered by\n * its own children. Guarding on DOM containment keeps those out — without\n * calling `stopPropagation`, which would also kill the native event before it\n * reaches `document`, where Radix listens in order to dismiss its layers.\n */\nexport const isEventFromWithin = (event: SyntheticEvent) =>\n event.currentTarget instanceof Node &&\n event.target instanceof Node &&\n event.currentTarget.contains(event.target);\n"],"names":["isEventFromWithin","event","currentTarget","Node","target","contains"],"mappings":"AAEA;;;;;;;;UASaA,iBAAAA,GAAoB,CAACC,QAChCA,KAAAA,CAAMC,aAAa,YAAYC,IAAAA,IAC/BF,KAAAA,CAAMG,MAAM,YAAYD,IAAAA,IACxBF,MAAMC,aAAa,CAACG,QAAQ,CAACJ,KAAAA,CAAMG,MAAM;;;;"}
@@ -0,0 +1,40 @@
1
+ 'use strict';
2
+
3
+ var getRelationId = require('./getRelationId.js');
4
+
5
+ /** Every id misses — used where no list is loaded (e.g. an isolated provider). */ const emptyItemLocations = {
6
+ fileFolderId: ()=>undefined,
7
+ folderParentId: ()=>undefined
8
+ };
9
+ /**
10
+ * Build the lookup once per list. Callers memoize on the rows so the identity
11
+ * stays stable: `BulkMoveDialog` memoizes its destination walk on the items
12
+ * derived from it.
13
+ */ const buildItemLocations = (assets, folders)=>{
14
+ const fileFolderIds = new Map();
15
+ const folderParentIds = new Map();
16
+ assets.forEach((asset)=>{
17
+ fileFolderIds.set(asset.id, getRelationId.getRelationId(asset.folder));
18
+ });
19
+ folders.forEach((folder)=>{
20
+ folderParentIds.set(folder.id, getRelationId.getRelationId(folder.parent));
21
+ });
22
+ return {
23
+ fileFolderId: (id)=>fileFolderIds.get(id),
24
+ folderParentId: (id)=>folderParentIds.get(id)
25
+ };
26
+ };
27
+ /**
28
+ * Resolve an item's location, falling back to the folder currently open when it
29
+ * is not in the loaded list. The fallback is unreachable in practice — selection
30
+ * clears whenever the list identity changes and infinite scroll only appends —
31
+ * but a stale parent beats silently dropping the item from the move.
32
+ */ const locateItem = (locations, kind, id, fallbackFolderId)=>{
33
+ const located = kind === 'file' ? locations.fileFolderId(id) : locations.folderParentId(id);
34
+ return located === undefined ? fallbackFolderId : located;
35
+ };
36
+
37
+ exports.buildItemLocations = buildItemLocations;
38
+ exports.emptyItemLocations = emptyItemLocations;
39
+ exports.locateItem = locateItem;
40
+ //# sourceMappingURL=itemLocations.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"itemLocations.js","sources":["../../../../admin/src/future/utils/itemLocations.ts"],"sourcesContent":["import { getRelationId } from './getRelationId';\n\nimport type { File } from '../../../../shared/contracts/files';\nimport type { Folder } from '../../../../shared/contracts/folders';\n\n/**\n * Where each loaded item actually lives, keyed by id.\n *\n * Search results are global, so the folder currently open (`?folder=`) says\n * nothing about a selected item's location. The loaded lists do: the server\n * populates `folder` on `/upload/files` and `parent` on `/upload/folders`.\n *\n * `undefined` means \"not in the loaded list\" and is distinct from `null`\n * (\"lives at the root\") — the two lead to different move validation.\n */\nexport interface ItemLocations {\n fileFolderId: (id: number) => number | null | undefined;\n folderParentId: (id: number) => number | null | undefined;\n}\n\n/** Every id misses — used where no list is loaded (e.g. an isolated provider). */\nexport const emptyItemLocations: ItemLocations = {\n fileFolderId: () => undefined,\n folderParentId: () => undefined,\n};\n\n/**\n * Build the lookup once per list. Callers memoize on the rows so the identity\n * stays stable: `BulkMoveDialog` memoizes its destination walk on the items\n * derived from it.\n */\nexport const buildItemLocations = (assets: File[], folders: Folder[]): ItemLocations => {\n const fileFolderIds = new Map<number, number | null>();\n const folderParentIds = new Map<number, number | null>();\n\n assets.forEach((asset) => {\n fileFolderIds.set(asset.id, getRelationId(asset.folder));\n });\n\n folders.forEach((folder) => {\n folderParentIds.set(folder.id, getRelationId(folder.parent));\n });\n\n return {\n fileFolderId: (id) => fileFolderIds.get(id),\n folderParentId: (id) => folderParentIds.get(id),\n };\n};\n\n/**\n * Resolve an item's location, falling back to the folder currently open when it\n * is not in the loaded list. The fallback is unreachable in practice — selection\n * clears whenever the list identity changes and infinite scroll only appends —\n * but a stale parent beats silently dropping the item from the move.\n */\nexport const locateItem = (\n locations: ItemLocations,\n kind: 'file' | 'folder',\n id: number,\n fallbackFolderId: number | null\n): number | null => {\n const located = kind === 'file' ? locations.fileFolderId(id) : locations.folderParentId(id);\n\n return located === undefined ? fallbackFolderId : located;\n};\n"],"names":["emptyItemLocations","fileFolderId","undefined","folderParentId","buildItemLocations","assets","folders","fileFolderIds","Map","folderParentIds","forEach","asset","set","id","getRelationId","folder","parent","get","locateItem","locations","kind","fallbackFolderId","located"],"mappings":";;;;AAoBA,mFACO,MAAMA,kBAAAA,GAAoC;AAC/CC,IAAAA,YAAAA,EAAc,IAAMC,SAAAA;AACpBC,IAAAA,cAAAA,EAAgB,IAAMD;AACxB;AAEA;;;;AAIC,IACM,MAAME,kBAAAA,GAAqB,CAACC,MAAAA,EAAgBC,OAAAA,GAAAA;AACjD,IAAA,MAAMC,gBAAgB,IAAIC,GAAAA,EAAAA;AAC1B,IAAA,MAAMC,kBAAkB,IAAID,GAAAA,EAAAA;IAE5BH,MAAAA,CAAOK,OAAO,CAAC,CAACC,KAAAA,GAAAA;AACdJ,QAAAA,aAAAA,CAAcK,GAAG,CAACD,KAAAA,CAAME,EAAE,EAAEC,2BAAAA,CAAcH,MAAMI,MAAM,CAAA,CAAA;AACxD,IAAA,CAAA,CAAA;IAEAT,OAAAA,CAAQI,OAAO,CAAC,CAACK,MAAAA,GAAAA;AACfN,QAAAA,eAAAA,CAAgBG,GAAG,CAACG,MAAAA,CAAOF,EAAE,EAAEC,2BAAAA,CAAcC,OAAOC,MAAM,CAAA,CAAA;AAC5D,IAAA,CAAA,CAAA;IAEA,OAAO;AACLf,QAAAA,YAAAA,EAAc,CAACY,EAAAA,GAAON,aAAAA,CAAcU,GAAG,CAACJ,EAAAA,CAAAA;AACxCV,QAAAA,cAAAA,EAAgB,CAACU,EAAAA,GAAOJ,eAAAA,CAAgBQ,GAAG,CAACJ,EAAAA;AAC9C,KAAA;AACF;AAEA;;;;;AAKC,IACM,MAAMK,UAAAA,GAAa,CACxBC,SAAAA,EACAC,MACAP,EAAAA,EACAQ,gBAAAA,GAAAA;IAEA,MAAMC,OAAAA,GAAUF,SAAS,MAAA,GAASD,SAAAA,CAAUlB,YAAY,CAACY,EAAAA,CAAAA,GAAMM,SAAAA,CAAUhB,cAAc,CAACU,EAAAA,CAAAA;IAExF,OAAOS,OAAAA,KAAYpB,YAAYmB,gBAAAA,GAAmBC,OAAAA;AACpD;;;;;;"}
@@ -0,0 +1,36 @@
1
+ import { getRelationId } from './getRelationId.mjs';
2
+
3
+ /** Every id misses — used where no list is loaded (e.g. an isolated provider). */ const emptyItemLocations = {
4
+ fileFolderId: ()=>undefined,
5
+ folderParentId: ()=>undefined
6
+ };
7
+ /**
8
+ * Build the lookup once per list. Callers memoize on the rows so the identity
9
+ * stays stable: `BulkMoveDialog` memoizes its destination walk on the items
10
+ * derived from it.
11
+ */ const buildItemLocations = (assets, folders)=>{
12
+ const fileFolderIds = new Map();
13
+ const folderParentIds = new Map();
14
+ assets.forEach((asset)=>{
15
+ fileFolderIds.set(asset.id, getRelationId(asset.folder));
16
+ });
17
+ folders.forEach((folder)=>{
18
+ folderParentIds.set(folder.id, getRelationId(folder.parent));
19
+ });
20
+ return {
21
+ fileFolderId: (id)=>fileFolderIds.get(id),
22
+ folderParentId: (id)=>folderParentIds.get(id)
23
+ };
24
+ };
25
+ /**
26
+ * Resolve an item's location, falling back to the folder currently open when it
27
+ * is not in the loaded list. The fallback is unreachable in practice — selection
28
+ * clears whenever the list identity changes and infinite scroll only appends —
29
+ * but a stale parent beats silently dropping the item from the move.
30
+ */ const locateItem = (locations, kind, id, fallbackFolderId)=>{
31
+ const located = kind === 'file' ? locations.fileFolderId(id) : locations.folderParentId(id);
32
+ return located === undefined ? fallbackFolderId : located;
33
+ };
34
+
35
+ export { buildItemLocations, emptyItemLocations, locateItem };
36
+ //# sourceMappingURL=itemLocations.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"itemLocations.mjs","sources":["../../../../admin/src/future/utils/itemLocations.ts"],"sourcesContent":["import { getRelationId } from './getRelationId';\n\nimport type { File } from '../../../../shared/contracts/files';\nimport type { Folder } from '../../../../shared/contracts/folders';\n\n/**\n * Where each loaded item actually lives, keyed by id.\n *\n * Search results are global, so the folder currently open (`?folder=`) says\n * nothing about a selected item's location. The loaded lists do: the server\n * populates `folder` on `/upload/files` and `parent` on `/upload/folders`.\n *\n * `undefined` means \"not in the loaded list\" and is distinct from `null`\n * (\"lives at the root\") — the two lead to different move validation.\n */\nexport interface ItemLocations {\n fileFolderId: (id: number) => number | null | undefined;\n folderParentId: (id: number) => number | null | undefined;\n}\n\n/** Every id misses — used where no list is loaded (e.g. an isolated provider). */\nexport const emptyItemLocations: ItemLocations = {\n fileFolderId: () => undefined,\n folderParentId: () => undefined,\n};\n\n/**\n * Build the lookup once per list. Callers memoize on the rows so the identity\n * stays stable: `BulkMoveDialog` memoizes its destination walk on the items\n * derived from it.\n */\nexport const buildItemLocations = (assets: File[], folders: Folder[]): ItemLocations => {\n const fileFolderIds = new Map<number, number | null>();\n const folderParentIds = new Map<number, number | null>();\n\n assets.forEach((asset) => {\n fileFolderIds.set(asset.id, getRelationId(asset.folder));\n });\n\n folders.forEach((folder) => {\n folderParentIds.set(folder.id, getRelationId(folder.parent));\n });\n\n return {\n fileFolderId: (id) => fileFolderIds.get(id),\n folderParentId: (id) => folderParentIds.get(id),\n };\n};\n\n/**\n * Resolve an item's location, falling back to the folder currently open when it\n * is not in the loaded list. The fallback is unreachable in practice — selection\n * clears whenever the list identity changes and infinite scroll only appends —\n * but a stale parent beats silently dropping the item from the move.\n */\nexport const locateItem = (\n locations: ItemLocations,\n kind: 'file' | 'folder',\n id: number,\n fallbackFolderId: number | null\n): number | null => {\n const located = kind === 'file' ? locations.fileFolderId(id) : locations.folderParentId(id);\n\n return located === undefined ? fallbackFolderId : located;\n};\n"],"names":["emptyItemLocations","fileFolderId","undefined","folderParentId","buildItemLocations","assets","folders","fileFolderIds","Map","folderParentIds","forEach","asset","set","id","getRelationId","folder","parent","get","locateItem","locations","kind","fallbackFolderId","located"],"mappings":";;AAoBA,mFACO,MAAMA,kBAAAA,GAAoC;AAC/CC,IAAAA,YAAAA,EAAc,IAAMC,SAAAA;AACpBC,IAAAA,cAAAA,EAAgB,IAAMD;AACxB;AAEA;;;;AAIC,IACM,MAAME,kBAAAA,GAAqB,CAACC,MAAAA,EAAgBC,OAAAA,GAAAA;AACjD,IAAA,MAAMC,gBAAgB,IAAIC,GAAAA,EAAAA;AAC1B,IAAA,MAAMC,kBAAkB,IAAID,GAAAA,EAAAA;IAE5BH,MAAAA,CAAOK,OAAO,CAAC,CAACC,KAAAA,GAAAA;AACdJ,QAAAA,aAAAA,CAAcK,GAAG,CAACD,KAAAA,CAAME,EAAE,EAAEC,aAAAA,CAAcH,MAAMI,MAAM,CAAA,CAAA;AACxD,IAAA,CAAA,CAAA;IAEAT,OAAAA,CAAQI,OAAO,CAAC,CAACK,MAAAA,GAAAA;AACfN,QAAAA,eAAAA,CAAgBG,GAAG,CAACG,MAAAA,CAAOF,EAAE,EAAEC,aAAAA,CAAcC,OAAOC,MAAM,CAAA,CAAA;AAC5D,IAAA,CAAA,CAAA;IAEA,OAAO;AACLf,QAAAA,YAAAA,EAAc,CAACY,EAAAA,GAAON,aAAAA,CAAcU,GAAG,CAACJ,EAAAA,CAAAA;AACxCV,QAAAA,cAAAA,EAAgB,CAACU,EAAAA,GAAOJ,eAAAA,CAAgBQ,GAAG,CAACJ,EAAAA;AAC9C,KAAA;AACF;AAEA;;;;;AAKC,IACM,MAAMK,UAAAA,GAAa,CACxBC,SAAAA,EACAC,MACAP,EAAAA,EACAQ,gBAAAA,GAAAA;IAEA,MAAMC,OAAAA,GAAUF,SAAS,MAAA,GAASD,SAAAA,CAAUlB,YAAY,CAACY,EAAAA,CAAAA,GAAMM,SAAAA,CAAUhB,cAAc,CAACU,EAAAA,CAAAA;IAExF,OAAOS,OAAAA,KAAYpB,YAAYmB,gBAAAA,GAAmBC,OAAAA;AACpD;;;;"}
@@ -0,0 +1,36 @@
1
+ 'use strict';
2
+
3
+ /**
4
+ * Where an item currently lives, regardless of its kind — folders carry their
5
+ * location on `parentId`, files on `folderId`.
6
+ */ const sourceFolderIdOf = (item)=>item.kind === 'folder' ? item.parentId : item.folderId;
7
+ /**
8
+ * The one folder every item in a move came from, or `null` when there isn't one.
9
+ *
10
+ * A selection made under a global search can hold items from anywhere, so a move
11
+ * has a nameable source only when the whole set agrees on it. `null` also covers
12
+ * the empty set. Callers pass the result straight to `formatMoveSuccessMessage`,
13
+ * which drops the source from the wording rather than crediting one item's
14
+ * folder to all of them.
15
+ *
16
+ * Note `null` is overloaded on purpose at the *label* level: an item at the
17
+ * Media Library root also has a `null` location, and both cases end up reading
18
+ * as "no folder to name". Use `hasUniformSource` when the difference matters.
19
+ */ const uniformSourceFolderId = (items)=>{
20
+ if (!hasUniformSource(items)) {
21
+ return null;
22
+ }
23
+ return sourceFolderIdOf(items[0]);
24
+ };
25
+ /** Whether every item in the set came from the same folder. False for an empty set. */ const hasUniformSource = (items)=>{
26
+ if (items.length === 0) {
27
+ return false;
28
+ }
29
+ const first = sourceFolderIdOf(items[0]);
30
+ return items.every((item)=>sourceFolderIdOf(item) === first);
31
+ };
32
+
33
+ exports.hasUniformSource = hasUniformSource;
34
+ exports.sourceFolderIdOf = sourceFolderIdOf;
35
+ exports.uniformSourceFolderId = uniformSourceFolderId;
36
+ //# sourceMappingURL=itemSource.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"itemSource.js","sources":["../../../../admin/src/future/utils/itemSource.ts"],"sourcesContent":["import type { DragItemData } from '../types/dnd';\n\n/**\n * Where an item currently lives, regardless of its kind — folders carry their\n * location on `parentId`, files on `folderId`.\n */\nexport const sourceFolderIdOf = (item: DragItemData): number | null =>\n item.kind === 'folder' ? item.parentId : item.folderId;\n\n/**\n * The one folder every item in a move came from, or `null` when there isn't one.\n *\n * A selection made under a global search can hold items from anywhere, so a move\n * has a nameable source only when the whole set agrees on it. `null` also covers\n * the empty set. Callers pass the result straight to `formatMoveSuccessMessage`,\n * which drops the source from the wording rather than crediting one item's\n * folder to all of them.\n *\n * Note `null` is overloaded on purpose at the *label* level: an item at the\n * Media Library root also has a `null` location, and both cases end up reading\n * as \"no folder to name\". Use `hasUniformSource` when the difference matters.\n */\nexport const uniformSourceFolderId = (items: DragItemData[]): number | null => {\n if (!hasUniformSource(items)) {\n return null;\n }\n\n return sourceFolderIdOf(items[0]);\n};\n\n/** Whether every item in the set came from the same folder. False for an empty set. */\nexport const hasUniformSource = (items: DragItemData[]): boolean => {\n if (items.length === 0) {\n return false;\n }\n\n const first = sourceFolderIdOf(items[0]);\n\n return items.every((item) => sourceFolderIdOf(item) === first);\n};\n"],"names":["sourceFolderIdOf","item","kind","parentId","folderId","uniformSourceFolderId","items","hasUniformSource","length","first","every"],"mappings":";;AAEA;;;AAGC,IACM,MAAMA,gBAAAA,GAAmB,CAACC,OAC/BA,IAAAA,CAAKC,IAAI,KAAK,QAAA,GAAWD,IAAAA,CAAKE,QAAQ,GAAGF,IAAAA,CAAKG;AAEhD;;;;;;;;;;;;IAaO,MAAMC,qBAAAA,GAAwB,CAACC,KAAAA,GAAAA;IACpC,IAAI,CAACC,iBAAiBD,KAAAA,CAAAA,EAAQ;QAC5B,OAAO,IAAA;AACT,IAAA;IAEA,OAAON,gBAAAA,CAAiBM,KAAK,CAAC,CAAA,CAAE,CAAA;AAClC;AAEA,wFACO,MAAMC,gBAAAA,GAAmB,CAACD,KAAAA,GAAAA;IAC/B,IAAIA,KAAAA,CAAME,MAAM,KAAK,CAAA,EAAG;QACtB,OAAO,KAAA;AACT,IAAA;AAEA,IAAA,MAAMC,KAAAA,GAAQT,gBAAAA,CAAiBM,KAAK,CAAC,CAAA,CAAE,CAAA;AAEvC,IAAA,OAAOA,MAAMI,KAAK,CAAC,CAACT,IAAAA,GAASD,iBAAiBC,IAAAA,CAAAA,KAAUQ,KAAAA,CAAAA;AAC1D;;;;;;"}
@@ -0,0 +1,32 @@
1
+ /**
2
+ * Where an item currently lives, regardless of its kind — folders carry their
3
+ * location on `parentId`, files on `folderId`.
4
+ */ const sourceFolderIdOf = (item)=>item.kind === 'folder' ? item.parentId : item.folderId;
5
+ /**
6
+ * The one folder every item in a move came from, or `null` when there isn't one.
7
+ *
8
+ * A selection made under a global search can hold items from anywhere, so a move
9
+ * has a nameable source only when the whole set agrees on it. `null` also covers
10
+ * the empty set. Callers pass the result straight to `formatMoveSuccessMessage`,
11
+ * which drops the source from the wording rather than crediting one item's
12
+ * folder to all of them.
13
+ *
14
+ * Note `null` is overloaded on purpose at the *label* level: an item at the
15
+ * Media Library root also has a `null` location, and both cases end up reading
16
+ * as "no folder to name". Use `hasUniformSource` when the difference matters.
17
+ */ const uniformSourceFolderId = (items)=>{
18
+ if (!hasUniformSource(items)) {
19
+ return null;
20
+ }
21
+ return sourceFolderIdOf(items[0]);
22
+ };
23
+ /** Whether every item in the set came from the same folder. False for an empty set. */ const hasUniformSource = (items)=>{
24
+ if (items.length === 0) {
25
+ return false;
26
+ }
27
+ const first = sourceFolderIdOf(items[0]);
28
+ return items.every((item)=>sourceFolderIdOf(item) === first);
29
+ };
30
+
31
+ export { hasUniformSource, sourceFolderIdOf, uniformSourceFolderId };
32
+ //# sourceMappingURL=itemSource.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"itemSource.mjs","sources":["../../../../admin/src/future/utils/itemSource.ts"],"sourcesContent":["import type { DragItemData } from '../types/dnd';\n\n/**\n * Where an item currently lives, regardless of its kind — folders carry their\n * location on `parentId`, files on `folderId`.\n */\nexport const sourceFolderIdOf = (item: DragItemData): number | null =>\n item.kind === 'folder' ? item.parentId : item.folderId;\n\n/**\n * The one folder every item in a move came from, or `null` when there isn't one.\n *\n * A selection made under a global search can hold items from anywhere, so a move\n * has a nameable source only when the whole set agrees on it. `null` also covers\n * the empty set. Callers pass the result straight to `formatMoveSuccessMessage`,\n * which drops the source from the wording rather than crediting one item's\n * folder to all of them.\n *\n * Note `null` is overloaded on purpose at the *label* level: an item at the\n * Media Library root also has a `null` location, and both cases end up reading\n * as \"no folder to name\". Use `hasUniformSource` when the difference matters.\n */\nexport const uniformSourceFolderId = (items: DragItemData[]): number | null => {\n if (!hasUniformSource(items)) {\n return null;\n }\n\n return sourceFolderIdOf(items[0]);\n};\n\n/** Whether every item in the set came from the same folder. False for an empty set. */\nexport const hasUniformSource = (items: DragItemData[]): boolean => {\n if (items.length === 0) {\n return false;\n }\n\n const first = sourceFolderIdOf(items[0]);\n\n return items.every((item) => sourceFolderIdOf(item) === first);\n};\n"],"names":["sourceFolderIdOf","item","kind","parentId","folderId","uniformSourceFolderId","items","hasUniformSource","length","first","every"],"mappings":"AAEA;;;AAGC,IACM,MAAMA,gBAAAA,GAAmB,CAACC,OAC/BA,IAAAA,CAAKC,IAAI,KAAK,QAAA,GAAWD,IAAAA,CAAKE,QAAQ,GAAGF,IAAAA,CAAKG;AAEhD;;;;;;;;;;;;IAaO,MAAMC,qBAAAA,GAAwB,CAACC,KAAAA,GAAAA;IACpC,IAAI,CAACC,iBAAiBD,KAAAA,CAAAA,EAAQ;QAC5B,OAAO,IAAA;AACT,IAAA;IAEA,OAAON,gBAAAA,CAAiBM,KAAK,CAAC,CAAA,CAAE,CAAA;AAClC;AAEA,wFACO,MAAMC,gBAAAA,GAAmB,CAACD,KAAAA,GAAAA;IAC/B,IAAIA,KAAAA,CAAME,MAAM,KAAK,CAAA,EAAG;QACtB,OAAO,KAAA;AACT,IAAA;AAEA,IAAA,MAAMC,KAAAA,GAAQT,gBAAAA,CAAiBM,KAAK,CAAC,CAAA,CAAE,CAAA;AAEvC,IAAA,OAAOA,MAAMI,KAAK,CAAC,CAACT,IAAAA,GAASD,iBAAiBC,IAAAA,CAAAA,KAAUQ,KAAAA,CAAAA;AAC1D;;;;"}
@@ -51,6 +51,11 @@ function __variableDynamicImportRuntime3__(path) {
51
51
  const name = _package.default.strapi.name;
52
52
  const admin = {
53
53
  register (app) {
54
+ /**
55
+ * The beta Media Library owns `plugins/upload` outright when the flag is on:
56
+ * the legacy app is not registered at all, so there is exactly one Media
57
+ * Library entry in the menu and no route to rename at GA.
58
+ */ const isBetaMediaLibrary = window.strapi.future.isEnabled('betaMediaLibrary');
54
59
  app.addMenuLink({
55
60
  to: `plugins/${pluginId.pluginId}`,
56
61
  icon: icons.Images,
@@ -59,14 +64,18 @@ const admin = {
59
64
  defaultMessage: 'Media Library'
60
65
  },
61
66
  permissions: constants.PERMISSIONS.main,
62
- Component: ()=>{
67
+ Component: isBetaMediaLibrary ? ()=>{
68
+ return Promise.resolve().then(function () { return require('./future/App.js'); }).then((mod)=>({
69
+ default: mod.BetaMediaLibrary
70
+ }));
71
+ } : ()=>{
63
72
  return Promise.resolve().then(function () { return require('./pages/App/App.js'); }).then((mod)=>({
64
73
  default: mod.Upload
65
74
  }));
66
75
  },
67
76
  position: 4
68
77
  });
69
- if (window.strapi.future.isEnabled('unstableMediaLibrary')) {
78
+ if (isBetaMediaLibrary) {
70
79
  app.addReducers({
71
80
  uploadProgress: uploadProgress.uploadProgressReducer
72
81
  });
@@ -76,21 +85,6 @@ const admin = {
76
85
  Component: UploadProgressDialog.UploadProgressDialog
77
86
  }
78
87
  ]);
79
- app.addMenuLink({
80
- to: `plugins/unstable-${pluginId.pluginId}`,
81
- icon: icons.WarningCircle,
82
- intlLabel: {
83
- id: `${pluginId.pluginId}.plugin.name`,
84
- defaultMessage: 'Media Library'
85
- },
86
- permissions: constants.PERMISSIONS.main,
87
- Component: ()=>{
88
- return Promise.resolve().then(function () { return require('./future/App.js'); }).then((mod)=>({
89
- default: mod.UnstableMediaLibrary
90
- }));
91
- },
92
- position: 5
93
- });
94
88
  }
95
89
  app.addSettingsLink('global', {
96
90
  id: 'media-library-settings',
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":["../../admin/src/index.ts"],"sourcesContent":["import { Images, WarningCircle } from '@strapi/icons';\n\nimport pluginPkg from '../../package.json';\n\nimport { MediaLibraryDialog } from './components/MediaLibraryDialog/MediaLibraryDialog';\nimport { MediaLibraryInput } from './components/MediaLibraryInput/MediaLibraryInput';\nimport { PERMISSIONS } from './constants';\nimport { UploadProgressDialog } from './future/components/UploadProgressDialog';\nimport { uploadProgressReducer } from './future/store/uploadProgress';\nimport { pluginId } from './pluginId';\nimport { getTrad, prefixPluginTranslations } from './utils';\n\nimport type { MediaLibraryDialogProps } from './components/MediaLibraryDialog/MediaLibraryDialog';\nimport type { MediaLibraryInputProps } from './components/MediaLibraryInput/MediaLibraryInput';\nimport type { StrapiApp } from '@strapi/admin/strapi-admin';\nimport type { Plugin } from '@strapi/types';\n\nconst name = pluginPkg.strapi.name;\n\nconst admin: Plugin.Config.AdminInput = {\n register(app: StrapiApp) {\n app.addMenuLink({\n to: `plugins/${pluginId}`,\n icon: Images,\n intlLabel: {\n id: `${pluginId}.plugin.name`,\n defaultMessage: 'Media Library',\n },\n permissions: PERMISSIONS.main,\n Component: () => {\n return import('./pages/App/App').then((mod) => ({ default: mod.Upload }));\n },\n position: 4,\n });\n\n if (window.strapi.future.isEnabled('unstableMediaLibrary')) {\n app.addReducers({ uploadProgress: uploadProgressReducer });\n\n app.addComponents([\n {\n name: 'future-global::upload-progress',\n Component: UploadProgressDialog,\n },\n ]);\n\n app.addMenuLink({\n to: `plugins/unstable-${pluginId}`,\n icon: WarningCircle,\n intlLabel: {\n id: `${pluginId}.plugin.name`,\n defaultMessage: 'Media Library',\n },\n permissions: PERMISSIONS.main,\n Component: () => {\n return import('./future/App').then((mod) => ({\n default: mod.UnstableMediaLibrary,\n }));\n },\n position: 5,\n });\n }\n\n app.addSettingsLink('global', {\n id: 'media-library-settings',\n to: 'media-library',\n intlLabel: {\n id: getTrad('plugin.name'),\n defaultMessage: 'Media Library',\n },\n Component() {\n return import('./pages/SettingsPage/SettingsPage').then((mod) => ({\n default: mod.ProtectedSettingsPage,\n }));\n },\n permissions: PERMISSIONS.settings,\n });\n\n app.addFields({\n type: 'media',\n Component: MediaLibraryInput as React.FC<Partial<MediaLibraryInputProps>>,\n });\n app.addComponents([\n {\n name: 'media-library',\n Component: MediaLibraryDialog as React.FC<Partial<MediaLibraryDialogProps>>,\n },\n ]);\n\n app.registerPlugin({\n id: pluginId,\n name,\n });\n },\n async registerTrads({ locales }: { locales: string[] }) {\n const importedTrads = await Promise.all(\n locales.map((locale) => {\n return import(`./translations/${locale}.json`)\n .then(({ default: data }) => {\n return {\n data: prefixPluginTranslations(data, pluginId),\n locale,\n };\n })\n .catch(() => {\n return {\n data: {},\n locale,\n };\n });\n })\n );\n\n return Promise.resolve(importedTrads);\n },\n};\n\n// eslint-disable-next-line import/no-default-export\nexport default admin;\n"],"names":["name","pluginPkg","strapi","admin","register","app","addMenuLink","to","pluginId","icon","Images","intlLabel","id","defaultMessage","permissions","PERMISSIONS","main","Component","then","mod","default","Upload","position","window","future","isEnabled","addReducers","uploadProgress","uploadProgressReducer","addComponents","UploadProgressDialog","WarningCircle","UnstableMediaLibrary","addSettingsLink","getTrad","ProtectedSettingsPage","settings","addFields","type","MediaLibraryInput","MediaLibraryDialog","registerPlugin","registerTrads","locales","importedTrads","Promise","all","map","locale","data","prefixPluginTranslations","catch","resolve"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sources":["../../admin/src/index.ts"],"sourcesContent":["import { Images } from '@strapi/icons';\n\nimport pluginPkg from '../../package.json';\n\nimport { MediaLibraryDialog } from './components/MediaLibraryDialog/MediaLibraryDialog';\nimport { MediaLibraryInput } from './components/MediaLibraryInput/MediaLibraryInput';\nimport { PERMISSIONS } from './constants';\nimport { UploadProgressDialog } from './future/components/UploadProgressDialog';\nimport { uploadProgressReducer } from './future/store/uploadProgress';\nimport { pluginId } from './pluginId';\nimport { getTrad, prefixPluginTranslations } from './utils';\n\nimport type { MediaLibraryDialogProps } from './components/MediaLibraryDialog/MediaLibraryDialog';\nimport type { MediaLibraryInputProps } from './components/MediaLibraryInput/MediaLibraryInput';\nimport type { StrapiApp } from '@strapi/admin/strapi-admin';\nimport type { Plugin } from '@strapi/types';\n\nconst name = pluginPkg.strapi.name;\n\nconst admin: Plugin.Config.AdminInput = {\n register(app: StrapiApp) {\n /**\n * The beta Media Library owns `plugins/upload` outright when the flag is on:\n * the legacy app is not registered at all, so there is exactly one Media\n * Library entry in the menu and no route to rename at GA.\n */\n const isBetaMediaLibrary = window.strapi.future.isEnabled('betaMediaLibrary');\n\n app.addMenuLink({\n to: `plugins/${pluginId}`,\n icon: Images,\n intlLabel: {\n id: `${pluginId}.plugin.name`,\n defaultMessage: 'Media Library',\n },\n permissions: PERMISSIONS.main,\n Component: isBetaMediaLibrary\n ? () => {\n return import('./future/App').then((mod) => ({\n default: mod.BetaMediaLibrary,\n }));\n }\n : () => {\n return import('./pages/App/App').then((mod) => ({ default: mod.Upload }));\n },\n position: 4,\n });\n\n if (isBetaMediaLibrary) {\n app.addReducers({ uploadProgress: uploadProgressReducer });\n\n app.addComponents([\n {\n name: 'future-global::upload-progress',\n Component: UploadProgressDialog,\n },\n ]);\n }\n\n app.addSettingsLink('global', {\n id: 'media-library-settings',\n to: 'media-library',\n intlLabel: {\n id: getTrad('plugin.name'),\n defaultMessage: 'Media Library',\n },\n Component() {\n return import('./pages/SettingsPage/SettingsPage').then((mod) => ({\n default: mod.ProtectedSettingsPage,\n }));\n },\n permissions: PERMISSIONS.settings,\n });\n\n app.addFields({\n type: 'media',\n Component: MediaLibraryInput as React.FC<Partial<MediaLibraryInputProps>>,\n });\n app.addComponents([\n {\n name: 'media-library',\n Component: MediaLibraryDialog as React.FC<Partial<MediaLibraryDialogProps>>,\n },\n ]);\n\n app.registerPlugin({\n id: pluginId,\n name,\n });\n },\n async registerTrads({ locales }: { locales: string[] }) {\n const importedTrads = await Promise.all(\n locales.map((locale) => {\n return import(`./translations/${locale}.json`)\n .then(({ default: data }) => {\n return {\n data: prefixPluginTranslations(data, pluginId),\n locale,\n };\n })\n .catch(() => {\n return {\n data: {},\n locale,\n };\n });\n })\n );\n\n return Promise.resolve(importedTrads);\n },\n};\n\n// eslint-disable-next-line import/no-default-export\nexport default admin;\n"],"names":["name","pluginPkg","strapi","admin","register","app","isBetaMediaLibrary","window","future","isEnabled","addMenuLink","to","pluginId","icon","Images","intlLabel","id","defaultMessage","permissions","PERMISSIONS","main","Component","then","mod","default","BetaMediaLibrary","Upload","position","addReducers","uploadProgress","uploadProgressReducer","addComponents","UploadProgressDialog","addSettingsLink","getTrad","ProtectedSettingsPage","settings","addFields","type","MediaLibraryInput","MediaLibraryDialog","registerPlugin","registerTrads","locales","importedTrads","Promise","all","map","locale","data","prefixPluginTranslations","catch","resolve"],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- import { Images, WarningCircle } from '@strapi/icons';
1
+ import { Images } from '@strapi/icons';
2
2
  import pluginPkg from './package.json.mjs';
3
3
  import { MediaLibraryDialog } from './components/MediaLibraryDialog/MediaLibraryDialog.mjs';
4
4
  import { MediaLibraryInput } from './components/MediaLibraryInput/MediaLibraryInput.mjs';
@@ -47,6 +47,11 @@ function __variableDynamicImportRuntime3__(path) {
47
47
  const name = pluginPkg.strapi.name;
48
48
  const admin = {
49
49
  register (app) {
50
+ /**
51
+ * The beta Media Library owns `plugins/upload` outright when the flag is on:
52
+ * the legacy app is not registered at all, so there is exactly one Media
53
+ * Library entry in the menu and no route to rename at GA.
54
+ */ const isBetaMediaLibrary = window.strapi.future.isEnabled('betaMediaLibrary');
50
55
  app.addMenuLink({
51
56
  to: `plugins/${pluginId}`,
52
57
  icon: Images,
@@ -55,14 +60,18 @@ const admin = {
55
60
  defaultMessage: 'Media Library'
56
61
  },
57
62
  permissions: PERMISSIONS.main,
58
- Component: ()=>{
63
+ Component: isBetaMediaLibrary ? ()=>{
64
+ return import('./future/App.mjs').then((mod)=>({
65
+ default: mod.BetaMediaLibrary
66
+ }));
67
+ } : ()=>{
59
68
  return import('./pages/App/App.mjs').then((mod)=>({
60
69
  default: mod.Upload
61
70
  }));
62
71
  },
63
72
  position: 4
64
73
  });
65
- if (window.strapi.future.isEnabled('unstableMediaLibrary')) {
74
+ if (isBetaMediaLibrary) {
66
75
  app.addReducers({
67
76
  uploadProgress: uploadProgressReducer
68
77
  });
@@ -72,21 +81,6 @@ const admin = {
72
81
  Component: UploadProgressDialog
73
82
  }
74
83
  ]);
75
- app.addMenuLink({
76
- to: `plugins/unstable-${pluginId}`,
77
- icon: WarningCircle,
78
- intlLabel: {
79
- id: `${pluginId}.plugin.name`,
80
- defaultMessage: 'Media Library'
81
- },
82
- permissions: PERMISSIONS.main,
83
- Component: ()=>{
84
- return import('./future/App.mjs').then((mod)=>({
85
- default: mod.UnstableMediaLibrary
86
- }));
87
- },
88
- position: 5
89
- });
90
84
  }
91
85
  app.addSettingsLink('global', {
92
86
  id: 'media-library-settings',
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","sources":["../../admin/src/index.ts"],"sourcesContent":["import { Images, WarningCircle } from '@strapi/icons';\n\nimport pluginPkg from '../../package.json';\n\nimport { MediaLibraryDialog } from './components/MediaLibraryDialog/MediaLibraryDialog';\nimport { MediaLibraryInput } from './components/MediaLibraryInput/MediaLibraryInput';\nimport { PERMISSIONS } from './constants';\nimport { UploadProgressDialog } from './future/components/UploadProgressDialog';\nimport { uploadProgressReducer } from './future/store/uploadProgress';\nimport { pluginId } from './pluginId';\nimport { getTrad, prefixPluginTranslations } from './utils';\n\nimport type { MediaLibraryDialogProps } from './components/MediaLibraryDialog/MediaLibraryDialog';\nimport type { MediaLibraryInputProps } from './components/MediaLibraryInput/MediaLibraryInput';\nimport type { StrapiApp } from '@strapi/admin/strapi-admin';\nimport type { Plugin } from '@strapi/types';\n\nconst name = pluginPkg.strapi.name;\n\nconst admin: Plugin.Config.AdminInput = {\n register(app: StrapiApp) {\n app.addMenuLink({\n to: `plugins/${pluginId}`,\n icon: Images,\n intlLabel: {\n id: `${pluginId}.plugin.name`,\n defaultMessage: 'Media Library',\n },\n permissions: PERMISSIONS.main,\n Component: () => {\n return import('./pages/App/App').then((mod) => ({ default: mod.Upload }));\n },\n position: 4,\n });\n\n if (window.strapi.future.isEnabled('unstableMediaLibrary')) {\n app.addReducers({ uploadProgress: uploadProgressReducer });\n\n app.addComponents([\n {\n name: 'future-global::upload-progress',\n Component: UploadProgressDialog,\n },\n ]);\n\n app.addMenuLink({\n to: `plugins/unstable-${pluginId}`,\n icon: WarningCircle,\n intlLabel: {\n id: `${pluginId}.plugin.name`,\n defaultMessage: 'Media Library',\n },\n permissions: PERMISSIONS.main,\n Component: () => {\n return import('./future/App').then((mod) => ({\n default: mod.UnstableMediaLibrary,\n }));\n },\n position: 5,\n });\n }\n\n app.addSettingsLink('global', {\n id: 'media-library-settings',\n to: 'media-library',\n intlLabel: {\n id: getTrad('plugin.name'),\n defaultMessage: 'Media Library',\n },\n Component() {\n return import('./pages/SettingsPage/SettingsPage').then((mod) => ({\n default: mod.ProtectedSettingsPage,\n }));\n },\n permissions: PERMISSIONS.settings,\n });\n\n app.addFields({\n type: 'media',\n Component: MediaLibraryInput as React.FC<Partial<MediaLibraryInputProps>>,\n });\n app.addComponents([\n {\n name: 'media-library',\n Component: MediaLibraryDialog as React.FC<Partial<MediaLibraryDialogProps>>,\n },\n ]);\n\n app.registerPlugin({\n id: pluginId,\n name,\n });\n },\n async registerTrads({ locales }: { locales: string[] }) {\n const importedTrads = await Promise.all(\n locales.map((locale) => {\n return import(`./translations/${locale}.json`)\n .then(({ default: data }) => {\n return {\n data: prefixPluginTranslations(data, pluginId),\n locale,\n };\n })\n .catch(() => {\n return {\n data: {},\n locale,\n };\n });\n })\n );\n\n return Promise.resolve(importedTrads);\n },\n};\n\n// eslint-disable-next-line import/no-default-export\nexport default admin;\n"],"names":["name","pluginPkg","strapi","admin","register","app","addMenuLink","to","pluginId","icon","Images","intlLabel","id","defaultMessage","permissions","PERMISSIONS","main","Component","then","mod","default","Upload","position","window","future","isEnabled","addReducers","uploadProgress","uploadProgressReducer","addComponents","UploadProgressDialog","WarningCircle","UnstableMediaLibrary","addSettingsLink","getTrad","ProtectedSettingsPage","settings","addFields","type","MediaLibraryInput","MediaLibraryDialog","registerPlugin","registerTrads","locales","importedTrads","Promise","all","map","locale","data","prefixPluginTranslations","catch","resolve"],"mappings":"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"}
1
+ {"version":3,"file":"index.mjs","sources":["../../admin/src/index.ts"],"sourcesContent":["import { Images } from '@strapi/icons';\n\nimport pluginPkg from '../../package.json';\n\nimport { MediaLibraryDialog } from './components/MediaLibraryDialog/MediaLibraryDialog';\nimport { MediaLibraryInput } from './components/MediaLibraryInput/MediaLibraryInput';\nimport { PERMISSIONS } from './constants';\nimport { UploadProgressDialog } from './future/components/UploadProgressDialog';\nimport { uploadProgressReducer } from './future/store/uploadProgress';\nimport { pluginId } from './pluginId';\nimport { getTrad, prefixPluginTranslations } from './utils';\n\nimport type { MediaLibraryDialogProps } from './components/MediaLibraryDialog/MediaLibraryDialog';\nimport type { MediaLibraryInputProps } from './components/MediaLibraryInput/MediaLibraryInput';\nimport type { StrapiApp } from '@strapi/admin/strapi-admin';\nimport type { Plugin } from '@strapi/types';\n\nconst name = pluginPkg.strapi.name;\n\nconst admin: Plugin.Config.AdminInput = {\n register(app: StrapiApp) {\n /**\n * The beta Media Library owns `plugins/upload` outright when the flag is on:\n * the legacy app is not registered at all, so there is exactly one Media\n * Library entry in the menu and no route to rename at GA.\n */\n const isBetaMediaLibrary = window.strapi.future.isEnabled('betaMediaLibrary');\n\n app.addMenuLink({\n to: `plugins/${pluginId}`,\n icon: Images,\n intlLabel: {\n id: `${pluginId}.plugin.name`,\n defaultMessage: 'Media Library',\n },\n permissions: PERMISSIONS.main,\n Component: isBetaMediaLibrary\n ? () => {\n return import('./future/App').then((mod) => ({\n default: mod.BetaMediaLibrary,\n }));\n }\n : () => {\n return import('./pages/App/App').then((mod) => ({ default: mod.Upload }));\n },\n position: 4,\n });\n\n if (isBetaMediaLibrary) {\n app.addReducers({ uploadProgress: uploadProgressReducer });\n\n app.addComponents([\n {\n name: 'future-global::upload-progress',\n Component: UploadProgressDialog,\n },\n ]);\n }\n\n app.addSettingsLink('global', {\n id: 'media-library-settings',\n to: 'media-library',\n intlLabel: {\n id: getTrad('plugin.name'),\n defaultMessage: 'Media Library',\n },\n Component() {\n return import('./pages/SettingsPage/SettingsPage').then((mod) => ({\n default: mod.ProtectedSettingsPage,\n }));\n },\n permissions: PERMISSIONS.settings,\n });\n\n app.addFields({\n type: 'media',\n Component: MediaLibraryInput as React.FC<Partial<MediaLibraryInputProps>>,\n });\n app.addComponents([\n {\n name: 'media-library',\n Component: MediaLibraryDialog as React.FC<Partial<MediaLibraryDialogProps>>,\n },\n ]);\n\n app.registerPlugin({\n id: pluginId,\n name,\n });\n },\n async registerTrads({ locales }: { locales: string[] }) {\n const importedTrads = await Promise.all(\n locales.map((locale) => {\n return import(`./translations/${locale}.json`)\n .then(({ default: data }) => {\n return {\n data: prefixPluginTranslations(data, pluginId),\n locale,\n };\n })\n .catch(() => {\n return {\n data: {},\n locale,\n };\n });\n })\n );\n\n return Promise.resolve(importedTrads);\n },\n};\n\n// eslint-disable-next-line import/no-default-export\nexport default admin;\n"],"names":["name","pluginPkg","strapi","admin","register","app","isBetaMediaLibrary","window","future","isEnabled","addMenuLink","to","pluginId","icon","Images","intlLabel","id","defaultMessage","permissions","PERMISSIONS","main","Component","then","mod","default","BetaMediaLibrary","Upload","position","addReducers","uploadProgress","uploadProgressReducer","addComponents","UploadProgressDialog","addSettingsLink","getTrad","ProtectedSettingsPage","settings","addFields","type","MediaLibraryInput","MediaLibraryDialog","registerPlugin","registerTrads","locales","importedTrads","Promise","all","map","locale","data","prefixPluginTranslations","catch","resolve"],"mappings":"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"}
@@ -1 +1 @@
1
- export declare const UnstableMediaLibrary: () => import("react/jsx-runtime").JSX.Element;
1
+ export declare const BetaMediaLibrary: () => import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,11 @@
1
+ /**
2
+ * The beta indicator is a notice rather than a badge on the page header: that
3
+ * header's title follows the folder you are in, so a badge attached to it would
4
+ * read as "this folder is beta". This notice covers the whole Media Library, and
5
+ * stays dismissed once a tester has read it.
6
+ *
7
+ * It renders inside `Layouts.Content` so it picks up the content column's gutter.
8
+ * Rendered above the layout instead, it would span the full viewport width and
9
+ * sit over the folder sidebar.
10
+ */
11
+ export declare const BetaNotice: () => import("react/jsx-runtime").JSX.Element | null;
@@ -3,8 +3,12 @@ import * as Dialog from '@radix-ui/react-dialog';
3
3
  import { FlexProps } from '@strapi/design-system';
4
4
  /** Duration of the close animation in ms. Use for timing cleanup (e.g. removing URL params). */
5
5
  export declare const DRAWER_CLOSE_ANIMATION_MS = 300;
6
- interface DrawerBodyProps extends FlexProps {
6
+ interface DrawerBodyProps extends Omit<FlexProps, 'width' | 'maxHeight'> {
7
7
  animationDirection?: 'up' | 'left';
8
+ /** Width of the panel from the medium breakpoint up. Mobile is always full-bleed. */
9
+ width?: string;
10
+ /** Cap on the panel height. Defaults to the dynamic viewport height. */
11
+ maxHeight?: string;
8
12
  children: React.ReactNode;
9
13
  }
10
14
  interface DrawerRootProps {
@@ -0,0 +1,26 @@
1
+ /**
2
+ * Whether the replace flow will actually regenerate AI metadata, so the UI only
3
+ * promises it when it happens.
4
+ *
5
+ * Two independent gates, both required — `GET /upload/settings` returns the
6
+ * stored `aiMetadata` toggle on its own, which stays `true` (its default) on
7
+ * licenses without AI, so the setting alone over-promises. The server's own
8
+ * check (`aiMetadata.isEnabled()`) ANDs the same two conditions.
9
+ *
10
+ * Pass `{ mime }` to add the third gate the replace flow applies: it only
11
+ * regenerates metadata for images the AI provider can read
12
+ * (`admin-upload.replaceFile` → `aiMetadata.processFiles`, which filters on this
13
+ * same allowlist). Promising it for a PDF — or for a GIF, which clears the
14
+ * server's looser `image/*` gate but is skipped by the provider — would describe
15
+ * something that never happens.
16
+ *
17
+ * The argument is an object rather than a bare `mime` so the two intents stay
18
+ * distinguishable: `File.mime` is optional on the contract, so a positional
19
+ * parameter let `useAIMetadataEnabled(asset.mime)` collapse into the ungated
20
+ * call whenever the mime was missing — silently taking the permissive path this
21
+ * hook exists to close. `useAIMetadataEnabled({ mime: undefined })` still gates
22
+ * (and fails closed); only an omitted `options` skips the mime check.
23
+ */
24
+ export declare const useAIMetadataEnabled: (options?: {
25
+ mime?: string | null;
26
+ }) => boolean;
@@ -0,0 +1,33 @@
1
+ import { Menu } from '@strapi/design-system';
2
+ /**
3
+ * `Menu.Content` for the row-level "..." menus, with the design system's height
4
+ * clamp replaced by a viewport-aware one.
5
+ *
6
+ * The DS caps its menus at a flat `15rem` and hides the scrollbar
7
+ * (`scrollbar-width: none` + `::-webkit-scrollbar { display: none }`). Under a
8
+ * last-row trigger that clamp cut items off with nothing on screen to hint they
9
+ * were there — Delete simply wasn't reachable.
10
+ *
11
+ * Raising the cap to `fit-content` fixed that, but it removes the fallback too:
12
+ * the box then grows to its content and the DS's `overflow: auto` can never
13
+ * fire. At 200% zoom or in a short window the menu ends up taller than the
14
+ * viewport with no way to scroll it — the same items-you-can't-reach bug, moved
15
+ * to a different trigger condition (WCAG 1.4.4 / 1.4.10).
16
+ *
17
+ * So cap to the space Radix measured instead. `--radix-popper-available-height`
18
+ * is set on the content element by `@radix-ui/react-popper`, and the DS mounts
19
+ * this box as the popper content (`asChild`), so it resolves here. The fallback
20
+ * in `min()` covers the first paint, before the property is written. Radix's
21
+ * collision flip still picks the side with more room; this only decides what
22
+ * happens when neither side has enough. The scrollbar is un-hidden so the
23
+ * overflow is visible when it does happen.
24
+ */
25
+ export declare const ActionsMenuContent: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<import("styled-components").FastOmit<Omit<Omit<Menu.ContentProps, "ref"> & import("react").RefAttributes<HTMLDivElement>, "ref"> & {
26
+ ref?: ((instance: HTMLDivElement | null) => void | import("react").DO_NOT_USE_OR_YOU_WILL_BE_FIRED_CALLBACK_REF_RETURN_VALUES[keyof import("react").DO_NOT_USE_OR_YOU_WILL_BE_FIRED_CALLBACK_REF_RETURN_VALUES]) | import("react").RefObject<HTMLDivElement> | null | undefined;
27
+ }, "key" | "id" | "slot" | "style" | "title" | "children" | keyof import("@strapi/design-system").TransientBoxProps | "ref" | keyof import("@strapi/design-system").TransientFlexProps | "defaultChecked" | "defaultValue" | "suppressContentEditableWarning" | "suppressHydrationWarning" | "accessKey" | "autoFocus" | "className" | "contentEditable" | "contextMenu" | "dir" | "draggable" | "hidden" | "lang" | "nonce" | "spellCheck" | "tabIndex" | "translate" | "radioGroup" | "role" | "about" | "content" | "datatype" | "inlist" | "prefix" | "property" | "rel" | "resource" | "rev" | "typeof" | "vocab" | "autoCapitalize" | "autoCorrect" | "autoSave" | "itemProp" | "itemScope" | "itemType" | "itemID" | "itemRef" | "results" | "security" | "unselectable" | "inputMode" | "is" | "aria-activedescendant" | "aria-atomic" | "aria-autocomplete" | "aria-braillelabel" | "aria-brailleroledescription" | "aria-busy" | "aria-checked" | "aria-colcount" | "aria-colindex" | "aria-colindextext" | "aria-colspan" | "aria-controls" | "aria-current" | "aria-describedby" | "aria-description" | "aria-details" | "aria-disabled" | "aria-dropeffect" | "aria-errormessage" | "aria-expanded" | "aria-flowto" | "aria-grabbed" | "aria-haspopup" | "aria-hidden" | "aria-invalid" | "aria-keyshortcuts" | "aria-label" | "aria-labelledby" | "aria-level" | "aria-live" | "aria-modal" | "aria-multiline" | "aria-multiselectable" | "aria-orientation" | "aria-owns" | "aria-placeholder" | "aria-posinset" | "aria-pressed" | "aria-readonly" | "aria-relevant" | "aria-required" | "aria-roledescription" | "aria-rowcount" | "aria-rowindex" | "aria-rowindextext" | "aria-rowspan" | "aria-selected" | "aria-setsize" | "aria-sort" | "aria-valuemax" | "aria-valuemin" | "aria-valuenow" | "aria-valuetext" | "dangerouslySetInnerHTML" | "onCopy" | "onCopyCapture" | "onCut" | "onCutCapture" | "onPaste" | "onPasteCapture" | "onCompositionEnd" | "onCompositionEndCapture" | "onCompositionStart" | "onCompositionStartCapture" | "onCompositionUpdate" | "onCompositionUpdateCapture" | "onFocus" | "onFocusCapture" | "onBlur" | "onBlurCapture" | "onChange" | "onChangeCapture" | "onBeforeInput" | "onBeforeInputCapture" | "onInput" | "onInputCapture" | "onReset" | "onResetCapture" | "onSubmit" | "onSubmitCapture" | "onInvalid" | "onInvalidCapture" | "onLoad" | "onLoadCapture" | "onError" | "onErrorCapture" | "onKeyDown" | "onKeyDownCapture" | "onKeyPress" | "onKeyPressCapture" | "onKeyUp" | "onKeyUpCapture" | "onAbort" | "onAbortCapture" | "onCanPlay" | "onCanPlayCapture" | "onCanPlayThrough" | "onCanPlayThroughCapture" | "onDurationChange" | "onDurationChangeCapture" | "onEmptied" | "onEmptiedCapture" | "onEncrypted" | "onEncryptedCapture" | "onEnded" | "onEndedCapture" | "onLoadedData" | "onLoadedDataCapture" | "onLoadedMetadata" | "onLoadedMetadataCapture" | "onLoadStart" | "onLoadStartCapture" | "onPause" | "onPauseCapture" | "onPlay" | "onPlayCapture" | "onPlaying" | "onPlayingCapture" | "onProgress" | "onProgressCapture" | "onRateChange" | "onRateChangeCapture" | "onResize" | "onResizeCapture" | "onSeeked" | "onSeekedCapture" | "onSeeking" | "onSeekingCapture" | "onStalled" | "onStalledCapture" | "onSuspend" | "onSuspendCapture" | "onTimeUpdate" | "onTimeUpdateCapture" | "onVolumeChange" | "onVolumeChangeCapture" | "onWaiting" | "onWaitingCapture" | "onAuxClick" | "onAuxClickCapture" | "onClick" | "onClickCapture" | "onContextMenu" | "onContextMenuCapture" | "onDoubleClick" | "onDoubleClickCapture" | "onDrag" | "onDragCapture" | "onDragEnd" | "onDragEndCapture" | "onDragEnter" | "onDragEnterCapture" | "onDragExit" | "onDragExitCapture" | "onDragLeave" | "onDragLeaveCapture" | "onDragOver" | "onDragOverCapture" | "onDragStart" | "onDragStartCapture" | "onDrop" | "onDropCapture" | "onMouseDown" | "onMouseDownCapture" | "onMouseEnter" | "onMouseLeave" | "onMouseMove" | "onMouseMoveCapture" | "onMouseOut" | "onMouseOutCapture" | "onMouseOver" | "onMouseOverCapture" | "onMouseUp" | "onMouseUpCapture" | "onSelect" | "onSelectCapture" | "onTouchCancel" | "onTouchCancelCapture" | "onTouchEnd" | "onTouchEndCapture" | "onTouchMove" | "onTouchMoveCapture" | "onTouchStart" | "onTouchStartCapture" | "onPointerDown" | "onPointerDownCapture" | "onPointerMove" | "onPointerMoveCapture" | "onPointerUp" | "onPointerUpCapture" | "onPointerCancel" | "onPointerCancelCapture" | "onPointerEnter" | "onPointerLeave" | "onPointerOver" | "onPointerOverCapture" | "onPointerOut" | "onPointerOutCapture" | "onGotPointerCapture" | "onGotPointerCaptureCapture" | "onLostPointerCapture" | "onLostPointerCaptureCapture" | "onScroll" | "onScrollCapture" | "onWheel" | "onWheelCapture" | "onAnimationStart" | "onAnimationStartCapture" | "onAnimationEnd" | "onAnimationEndCapture" | "onAnimationIteration" | "onAnimationIterationCapture" | "onTransitionEnd" | "onTransitionEndCapture" | keyof import("@strapi/design-system/dist/types").AsProp<"div"> | "onCloseAutoFocus" | "intersectionId" | "popoverPlacement"> & Omit<Omit<Menu.ContentProps, "ref"> & import("react").RefAttributes<HTMLDivElement>, "ref"> & {
28
+ ref?: ((instance: HTMLDivElement | null) => void | import("react").DO_NOT_USE_OR_YOU_WILL_BE_FIRED_CALLBACK_REF_RETURN_VALUES[keyof import("react").DO_NOT_USE_OR_YOU_WILL_BE_FIRED_CALLBACK_REF_RETURN_VALUES]) | import("react").RefObject<HTMLDivElement> | null | undefined;
29
+ }, "maxHeight"> & Partial<Pick<import("styled-components").FastOmit<Omit<Omit<Menu.ContentProps, "ref"> & import("react").RefAttributes<HTMLDivElement>, "ref"> & {
30
+ ref?: ((instance: HTMLDivElement | null) => void | import("react").DO_NOT_USE_OR_YOU_WILL_BE_FIRED_CALLBACK_REF_RETURN_VALUES[keyof import("react").DO_NOT_USE_OR_YOU_WILL_BE_FIRED_CALLBACK_REF_RETURN_VALUES]) | import("react").RefObject<HTMLDivElement> | null | undefined;
31
+ }, "key" | "id" | "slot" | "style" | "title" | "children" | keyof import("@strapi/design-system").TransientBoxProps | "ref" | keyof import("@strapi/design-system").TransientFlexProps | "defaultChecked" | "defaultValue" | "suppressContentEditableWarning" | "suppressHydrationWarning" | "accessKey" | "autoFocus" | "className" | "contentEditable" | "contextMenu" | "dir" | "draggable" | "hidden" | "lang" | "nonce" | "spellCheck" | "tabIndex" | "translate" | "radioGroup" | "role" | "about" | "content" | "datatype" | "inlist" | "prefix" | "property" | "rel" | "resource" | "rev" | "typeof" | "vocab" | "autoCapitalize" | "autoCorrect" | "autoSave" | "itemProp" | "itemScope" | "itemType" | "itemID" | "itemRef" | "results" | "security" | "unselectable" | "inputMode" | "is" | "aria-activedescendant" | "aria-atomic" | "aria-autocomplete" | "aria-braillelabel" | "aria-brailleroledescription" | "aria-busy" | "aria-checked" | "aria-colcount" | "aria-colindex" | "aria-colindextext" | "aria-colspan" | "aria-controls" | "aria-current" | "aria-describedby" | "aria-description" | "aria-details" | "aria-disabled" | "aria-dropeffect" | "aria-errormessage" | "aria-expanded" | "aria-flowto" | "aria-grabbed" | "aria-haspopup" | "aria-hidden" | "aria-invalid" | "aria-keyshortcuts" | "aria-label" | "aria-labelledby" | "aria-level" | "aria-live" | "aria-modal" | "aria-multiline" | "aria-multiselectable" | "aria-orientation" | "aria-owns" | "aria-placeholder" | "aria-posinset" | "aria-pressed" | "aria-readonly" | "aria-relevant" | "aria-required" | "aria-roledescription" | "aria-rowcount" | "aria-rowindex" | "aria-rowindextext" | "aria-rowspan" | "aria-selected" | "aria-setsize" | "aria-sort" | "aria-valuemax" | "aria-valuemin" | "aria-valuenow" | "aria-valuetext" | "dangerouslySetInnerHTML" | "onCopy" | "onCopyCapture" | "onCut" | "onCutCapture" | "onPaste" | "onPasteCapture" | "onCompositionEnd" | "onCompositionEndCapture" | "onCompositionStart" | "onCompositionStartCapture" | "onCompositionUpdate" | "onCompositionUpdateCapture" | "onFocus" | "onFocusCapture" | "onBlur" | "onBlurCapture" | "onChange" | "onChangeCapture" | "onBeforeInput" | "onBeforeInputCapture" | "onInput" | "onInputCapture" | "onReset" | "onResetCapture" | "onSubmit" | "onSubmitCapture" | "onInvalid" | "onInvalidCapture" | "onLoad" | "onLoadCapture" | "onError" | "onErrorCapture" | "onKeyDown" | "onKeyDownCapture" | "onKeyPress" | "onKeyPressCapture" | "onKeyUp" | "onKeyUpCapture" | "onAbort" | "onAbortCapture" | "onCanPlay" | "onCanPlayCapture" | "onCanPlayThrough" | "onCanPlayThroughCapture" | "onDurationChange" | "onDurationChangeCapture" | "onEmptied" | "onEmptiedCapture" | "onEncrypted" | "onEncryptedCapture" | "onEnded" | "onEndedCapture" | "onLoadedData" | "onLoadedDataCapture" | "onLoadedMetadata" | "onLoadedMetadataCapture" | "onLoadStart" | "onLoadStartCapture" | "onPause" | "onPauseCapture" | "onPlay" | "onPlayCapture" | "onPlaying" | "onPlayingCapture" | "onProgress" | "onProgressCapture" | "onRateChange" | "onRateChangeCapture" | "onResize" | "onResizeCapture" | "onSeeked" | "onSeekedCapture" | "onSeeking" | "onSeekingCapture" | "onStalled" | "onStalledCapture" | "onSuspend" | "onSuspendCapture" | "onTimeUpdate" | "onTimeUpdateCapture" | "onVolumeChange" | "onVolumeChangeCapture" | "onWaiting" | "onWaitingCapture" | "onAuxClick" | "onAuxClickCapture" | "onClick" | "onClickCapture" | "onContextMenu" | "onContextMenuCapture" | "onDoubleClick" | "onDoubleClickCapture" | "onDrag" | "onDragCapture" | "onDragEnd" | "onDragEndCapture" | "onDragEnter" | "onDragEnterCapture" | "onDragExit" | "onDragExitCapture" | "onDragLeave" | "onDragLeaveCapture" | "onDragOver" | "onDragOverCapture" | "onDragStart" | "onDragStartCapture" | "onDrop" | "onDropCapture" | "onMouseDown" | "onMouseDownCapture" | "onMouseEnter" | "onMouseLeave" | "onMouseMove" | "onMouseMoveCapture" | "onMouseOut" | "onMouseOutCapture" | "onMouseOver" | "onMouseOverCapture" | "onMouseUp" | "onMouseUpCapture" | "onSelect" | "onSelectCapture" | "onTouchCancel" | "onTouchCancelCapture" | "onTouchEnd" | "onTouchEndCapture" | "onTouchMove" | "onTouchMoveCapture" | "onTouchStart" | "onTouchStartCapture" | "onPointerDown" | "onPointerDownCapture" | "onPointerMove" | "onPointerMoveCapture" | "onPointerUp" | "onPointerUpCapture" | "onPointerCancel" | "onPointerCancelCapture" | "onPointerEnter" | "onPointerLeave" | "onPointerOver" | "onPointerOverCapture" | "onPointerOut" | "onPointerOutCapture" | "onGotPointerCapture" | "onGotPointerCaptureCapture" | "onLostPointerCapture" | "onLostPointerCaptureCapture" | "onScroll" | "onScrollCapture" | "onWheel" | "onWheelCapture" | "onAnimationStart" | "onAnimationStartCapture" | "onAnimationEnd" | "onAnimationEndCapture" | "onAnimationIteration" | "onAnimationIterationCapture" | "onTransitionEnd" | "onTransitionEndCapture" | keyof import("@strapi/design-system/dist/types").AsProp<"div"> | "onCloseAutoFocus" | "intersectionId" | "popoverPlacement"> & Omit<Omit<Menu.ContentProps, "ref"> & import("react").RefAttributes<HTMLDivElement>, "ref"> & {
32
+ ref?: ((instance: HTMLDivElement | null) => void | import("react").DO_NOT_USE_OR_YOU_WILL_BE_FIRED_CALLBACK_REF_RETURN_VALUES[keyof import("react").DO_NOT_USE_OR_YOU_WILL_BE_FIRED_CALLBACK_REF_RETURN_VALUES]) | import("react").RefObject<HTMLDivElement> | null | undefined;
33
+ }, "maxHeight">>> & string & Omit<import("react").ForwardRefExoticComponent<Omit<Menu.ContentProps, "ref"> & import("react").RefAttributes<HTMLDivElement>>, keyof import("react").Component<any, {}, any>>;
@@ -0,0 +1,24 @@
1
+ import type { File } from '../../../../../../shared/contracts/files';
2
+ import type { DragFileData } from '../../../types/dnd';
3
+ interface AssetActionsMenuProps {
4
+ asset: File;
5
+ /** Drag data for this asset, so the move dialog validates against its real folder. */
6
+ dragData: DragFileData;
7
+ }
8
+ /**
9
+ * The "..." menu on an asset row/card. Always acts on that one asset, whatever
10
+ * the current multi-selection is (the bulk actions bar is the selection-scoped
11
+ * affordance) — the file mirror of `FolderActionsMenu`.
12
+ *
13
+ * Replace / copy link / download duplicate what the details drawer offers as
14
+ * icon buttons, so the same action is one click away without opening the asset
15
+ * first. They are re-implemented rather than lifted out of the drawer: the
16
+ * drawer versions render as `IconButton`s and report through its in-drawer toast
17
+ * slot, neither of which fits a menu item on a row.
18
+ *
19
+ * Any successful move or delete clears the whole selection: a delete only
20
+ * invalidates RTK tags, so without it an `asset:<id>` key for a file that no
21
+ * longer exists would linger in the selection.
22
+ */
23
+ export declare const AssetActionsMenu: ({ asset, dragData }: AssetActionsMenuProps) => import("react/jsx-runtime").JSX.Element | null;
24
+ export {};
@@ -21,6 +21,22 @@ export declare const useAssetDetailsParam: () => {
21
21
  openDetails: (id: number) => void;
22
22
  closeDetails: () => void;
23
23
  };
24
+ /**
25
+ * Map the drawer-scoped mutation flags to a single i18n message for the busy
26
+ * overlay loader. Returns `null` when nothing is in flight.
27
+ *
28
+ * Exported for the unit test: the branch order only matters when two flags are
29
+ * true at once, which the UI makes hard to stage through the rendered drawer
30
+ * (each trigger disables itself while its own mutation runs).
31
+ */
32
+ export declare const getBusyMessage: (state: {
33
+ isDeleting: boolean;
34
+ isReplacing: boolean;
35
+ isCropCopying: boolean;
36
+ }) => {
37
+ id: string;
38
+ defaultMessage: string;
39
+ } | null;
24
40
  interface AssetDetailsProps {
25
41
  asset: AssetWithPopulatedCreatedBy;
26
42
  closeDetails: () => void;