@strapi/upload 5.51.0 → 5.51.2

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 (346) hide show
  1. package/dist/admin/components/AssetCard/VideoPreview.js +1 -1
  2. package/dist/admin/components/AssetCard/VideoPreview.js.map +1 -1
  3. package/dist/admin/components/AssetCard/VideoPreview.mjs +1 -1
  4. package/dist/admin/components/AssetCard/VideoPreview.mjs.map +1 -1
  5. package/dist/admin/components/TableList/TableList.js +1 -1
  6. package/dist/admin/components/TableList/TableList.js.map +1 -1
  7. package/dist/admin/components/TableList/TableList.mjs +1 -1
  8. package/dist/admin/components/TableList/TableList.mjs.map +1 -1
  9. package/dist/admin/components/UploadAssetDialog/AddAssetStep/FromUrlForm.js +21 -4
  10. package/dist/admin/components/UploadAssetDialog/AddAssetStep/FromUrlForm.js.map +1 -1
  11. package/dist/admin/components/UploadAssetDialog/AddAssetStep/FromUrlForm.mjs +21 -4
  12. package/dist/admin/components/UploadAssetDialog/AddAssetStep/FromUrlForm.mjs.map +1 -1
  13. package/dist/admin/future/components/Drawer.js +3 -1
  14. package/dist/admin/future/components/Drawer.js.map +1 -1
  15. package/dist/admin/future/components/Drawer.mjs +3 -1
  16. package/dist/admin/future/components/Drawer.mjs.map +1 -1
  17. package/dist/admin/future/components/UploadProgressDialog.js +200 -27
  18. package/dist/admin/future/components/UploadProgressDialog.js.map +1 -1
  19. package/dist/admin/future/components/UploadProgressDialog.mjs +203 -30
  20. package/dist/admin/future/components/UploadProgressDialog.mjs.map +1 -1
  21. package/dist/admin/future/hooks/useMediaLibraryPermissions.js +35 -0
  22. package/dist/admin/future/hooks/useMediaLibraryPermissions.js.map +1 -0
  23. package/dist/admin/future/hooks/useMediaLibraryPermissions.mjs +33 -0
  24. package/dist/admin/future/hooks/useMediaLibraryPermissions.mjs.map +1 -0
  25. package/dist/admin/future/pages/Assets/AssetsPage.js +344 -150
  26. package/dist/admin/future/pages/Assets/AssetsPage.js.map +1 -1
  27. package/dist/admin/future/pages/Assets/AssetsPage.mjs +343 -149
  28. package/dist/admin/future/pages/Assets/AssetsPage.mjs.map +1 -1
  29. package/dist/admin/future/pages/Assets/components/AssetDetails/AssetCropEditor.js +75 -32
  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 +75 -32
  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 +46 -19
  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 +47 -20
  36. package/dist/admin/future/pages/Assets/components/AssetDetails/AssetDetailsDrawer.mjs.map +1 -1
  37. package/dist/admin/future/pages/Assets/components/AssetsGrid.js +161 -19
  38. package/dist/admin/future/pages/Assets/components/AssetsGrid.js.map +1 -1
  39. package/dist/admin/future/pages/Assets/components/AssetsGrid.mjs +162 -20
  40. package/dist/admin/future/pages/Assets/components/AssetsGrid.mjs.map +1 -1
  41. package/dist/admin/future/pages/Assets/components/AssetsSearchInput.js +100 -0
  42. package/dist/admin/future/pages/Assets/components/AssetsSearchInput.js.map +1 -0
  43. package/dist/admin/future/pages/Assets/components/AssetsSearchInput.mjs +98 -0
  44. package/dist/admin/future/pages/Assets/components/AssetsSearchInput.mjs.map +1 -0
  45. package/dist/admin/future/pages/Assets/components/AssetsTable.js +218 -37
  46. package/dist/admin/future/pages/Assets/components/AssetsTable.js.map +1 -1
  47. package/dist/admin/future/pages/Assets/components/AssetsTable.mjs +219 -38
  48. package/dist/admin/future/pages/Assets/components/AssetsTable.mjs.map +1 -1
  49. package/dist/admin/future/pages/Assets/components/BulkActionsBar.js +370 -0
  50. package/dist/admin/future/pages/Assets/components/BulkActionsBar.js.map +1 -0
  51. package/dist/admin/future/pages/Assets/components/BulkActionsBar.mjs +368 -0
  52. package/dist/admin/future/pages/Assets/components/BulkActionsBar.mjs.map +1 -0
  53. package/dist/admin/future/pages/Assets/components/BulkMoveDialog.js +209 -0
  54. package/dist/admin/future/pages/Assets/components/BulkMoveDialog.js.map +1 -0
  55. package/dist/admin/future/pages/Assets/components/BulkMoveDialog.mjs +207 -0
  56. package/dist/admin/future/pages/Assets/components/BulkMoveDialog.mjs.map +1 -0
  57. package/dist/admin/future/pages/Assets/components/DateRangeCalendar.js +193 -0
  58. package/dist/admin/future/pages/Assets/components/DateRangeCalendar.js.map +1 -0
  59. package/dist/admin/future/pages/Assets/components/DateRangeCalendar.mjs +191 -0
  60. package/dist/admin/future/pages/Assets/components/DateRangeCalendar.mjs.map +1 -0
  61. package/dist/admin/future/pages/Assets/components/Dnd/AssetsDndProvider.js +129 -37
  62. package/dist/admin/future/pages/Assets/components/Dnd/AssetsDndProvider.js.map +1 -1
  63. package/dist/admin/future/pages/Assets/components/Dnd/AssetsDndProvider.mjs +131 -39
  64. package/dist/admin/future/pages/Assets/components/Dnd/AssetsDndProvider.mjs.map +1 -1
  65. package/dist/admin/future/pages/Assets/components/Dnd/DragOverlayChip.js +120 -13
  66. package/dist/admin/future/pages/Assets/components/Dnd/DragOverlayChip.js.map +1 -1
  67. package/dist/admin/future/pages/Assets/components/Dnd/DragOverlayChip.mjs +120 -13
  68. package/dist/admin/future/pages/Assets/components/Dnd/DragOverlayChip.mjs.map +1 -1
  69. package/dist/admin/future/pages/Assets/components/Dnd/buildDragSet.js +71 -0
  70. package/dist/admin/future/pages/Assets/components/Dnd/buildDragSet.js.map +1 -0
  71. package/dist/admin/future/pages/Assets/components/Dnd/buildDragSet.mjs +69 -0
  72. package/dist/admin/future/pages/Assets/components/Dnd/buildDragSet.mjs.map +1 -0
  73. package/dist/admin/future/pages/Assets/components/Dnd/computeValidDropTargets.js +34 -0
  74. package/dist/admin/future/pages/Assets/components/Dnd/computeValidDropTargets.js.map +1 -0
  75. package/dist/admin/future/pages/Assets/components/Dnd/computeValidDropTargets.mjs +32 -0
  76. package/dist/admin/future/pages/Assets/components/Dnd/computeValidDropTargets.mjs.map +1 -0
  77. package/dist/admin/future/pages/Assets/components/Dnd/dndIds.js +15 -0
  78. package/dist/admin/future/pages/Assets/components/Dnd/dndIds.js.map +1 -1
  79. package/dist/admin/future/pages/Assets/components/Dnd/dndIds.mjs +13 -1
  80. package/dist/admin/future/pages/Assets/components/Dnd/dndIds.mjs.map +1 -1
  81. package/dist/admin/future/pages/Assets/components/Dnd/useAssetDnd.js +19 -25
  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 +19 -25
  84. package/dist/admin/future/pages/Assets/components/Dnd/useAssetDnd.mjs.map +1 -1
  85. package/dist/admin/future/pages/Assets/components/Dnd/useFolderTreeDroppable.js +35 -0
  86. package/dist/admin/future/pages/Assets/components/Dnd/useFolderTreeDroppable.js.map +1 -0
  87. package/dist/admin/future/pages/Assets/components/Dnd/useFolderTreeDroppable.mjs +33 -0
  88. package/dist/admin/future/pages/Assets/components/Dnd/useFolderTreeDroppable.mjs.map +1 -0
  89. package/dist/admin/future/pages/Assets/components/DropZone/UploadDropZoneContext.js +13 -3
  90. package/dist/admin/future/pages/Assets/components/DropZone/UploadDropZoneContext.js.map +1 -1
  91. package/dist/admin/future/pages/Assets/components/DropZone/UploadDropZoneContext.mjs +13 -3
  92. package/dist/admin/future/pages/Assets/components/DropZone/UploadDropZoneContext.mjs.map +1 -1
  93. package/dist/admin/future/pages/Assets/components/EmptyState.js +62 -3
  94. package/dist/admin/future/pages/Assets/components/EmptyState.js.map +1 -1
  95. package/dist/admin/future/pages/Assets/components/EmptyState.mjs +62 -4
  96. package/dist/admin/future/pages/Assets/components/EmptyState.mjs.map +1 -1
  97. package/dist/admin/future/pages/Assets/components/FilterBadges.js +408 -0
  98. package/dist/admin/future/pages/Assets/components/FilterBadges.js.map +1 -0
  99. package/dist/admin/future/pages/Assets/components/FilterBadges.mjs +406 -0
  100. package/dist/admin/future/pages/Assets/components/FilterBadges.mjs.map +1 -0
  101. package/dist/admin/future/pages/Assets/components/FilterMenu.js +273 -0
  102. package/dist/admin/future/pages/Assets/components/FilterMenu.js.map +1 -0
  103. package/dist/admin/future/pages/Assets/components/FilterMenu.mjs +267 -0
  104. package/dist/admin/future/pages/Assets/components/FilterMenu.mjs.map +1 -0
  105. package/dist/admin/future/pages/Assets/components/FolderTree/FolderTree.js +195 -40
  106. package/dist/admin/future/pages/Assets/components/FolderTree/FolderTree.js.map +1 -1
  107. package/dist/admin/future/pages/Assets/components/FolderTree/FolderTree.mjs +198 -43
  108. package/dist/admin/future/pages/Assets/components/FolderTree/FolderTree.mjs.map +1 -1
  109. package/dist/admin/future/pages/Assets/components/FolderTree/filterFolderTree.js +33 -0
  110. package/dist/admin/future/pages/Assets/components/FolderTree/filterFolderTree.js.map +1 -0
  111. package/dist/admin/future/pages/Assets/components/FolderTree/filterFolderTree.mjs +31 -0
  112. package/dist/admin/future/pages/Assets/components/FolderTree/filterFolderTree.mjs.map +1 -0
  113. package/dist/admin/future/pages/Assets/components/FolderTree/useSpringLoadedExpand.js +22 -0
  114. package/dist/admin/future/pages/Assets/components/FolderTree/useSpringLoadedExpand.js.map +1 -0
  115. package/dist/admin/future/pages/Assets/components/FolderTree/useSpringLoadedExpand.mjs +19 -0
  116. package/dist/admin/future/pages/Assets/components/FolderTree/useSpringLoadedExpand.mjs.map +1 -0
  117. package/dist/admin/future/pages/Assets/components/SortMenu.js +154 -0
  118. package/dist/admin/future/pages/Assets/components/SortMenu.js.map +1 -0
  119. package/dist/admin/future/pages/Assets/components/SortMenu.mjs +152 -0
  120. package/dist/admin/future/pages/Assets/components/SortMenu.mjs.map +1 -0
  121. package/dist/admin/future/pages/Assets/hooks/useAssetSearch.js +40 -0
  122. package/dist/admin/future/pages/Assets/hooks/useAssetSearch.js.map +1 -0
  123. package/dist/admin/future/pages/Assets/hooks/useAssetSearch.mjs +38 -0
  124. package/dist/admin/future/pages/Assets/hooks/useAssetSearch.mjs.map +1 -0
  125. package/dist/admin/future/pages/Assets/hooks/useAssetSelection.js +75 -0
  126. package/dist/admin/future/pages/Assets/hooks/useAssetSelection.js.map +1 -0
  127. package/dist/admin/future/pages/Assets/hooks/useAssetSelection.mjs +71 -0
  128. package/dist/admin/future/pages/Assets/hooks/useAssetSelection.mjs.map +1 -0
  129. package/dist/admin/future/pages/Assets/hooks/useFolderNavigation.js +33 -12
  130. package/dist/admin/future/pages/Assets/hooks/useFolderNavigation.js.map +1 -1
  131. package/dist/admin/future/pages/Assets/hooks/useFolderNavigation.mjs +33 -12
  132. package/dist/admin/future/pages/Assets/hooks/useFolderNavigation.mjs.map +1 -1
  133. package/dist/admin/future/pages/Assets/hooks/useInfiniteAssets.js +40 -4
  134. package/dist/admin/future/pages/Assets/hooks/useInfiniteAssets.js.map +1 -1
  135. package/dist/admin/future/pages/Assets/hooks/useInfiniteAssets.mjs +40 -4
  136. package/dist/admin/future/pages/Assets/hooks/useInfiniteAssets.mjs.map +1 -1
  137. package/dist/admin/future/pages/Assets/hooks/useListFilters.js +168 -0
  138. package/dist/admin/future/pages/Assets/hooks/useListFilters.js.map +1 -0
  139. package/dist/admin/future/pages/Assets/hooks/useListFilters.mjs +162 -0
  140. package/dist/admin/future/pages/Assets/hooks/useListFilters.mjs.map +1 -0
  141. package/dist/admin/future/pages/Assets/hooks/useListSort.js +124 -0
  142. package/dist/admin/future/pages/Assets/hooks/useListSort.js.map +1 -0
  143. package/dist/admin/future/pages/Assets/hooks/useListSort.mjs +120 -0
  144. package/dist/admin/future/pages/Assets/hooks/useListSort.mjs.map +1 -0
  145. package/dist/admin/future/pages/Assets/utils/buildAssetFilters.js +201 -0
  146. package/dist/admin/future/pages/Assets/utils/buildAssetFilters.js.map +1 -0
  147. package/dist/admin/future/pages/Assets/utils/buildAssetFilters.mjs +198 -0
  148. package/dist/admin/future/pages/Assets/utils/buildAssetFilters.mjs.map +1 -0
  149. package/dist/admin/future/pages/Assets/utils/listQueryKey.js +29 -0
  150. package/dist/admin/future/pages/Assets/utils/listQueryKey.js.map +1 -0
  151. package/dist/admin/future/pages/Assets/utils/listQueryKey.mjs +27 -0
  152. package/dist/admin/future/pages/Assets/utils/listQueryKey.mjs.map +1 -0
  153. package/dist/admin/future/pages/Assets/utils/mergeMixedList.js +84 -0
  154. package/dist/admin/future/pages/Assets/utils/mergeMixedList.js.map +1 -0
  155. package/dist/admin/future/pages/Assets/utils/mergeMixedList.mjs +81 -0
  156. package/dist/admin/future/pages/Assets/utils/mergeMixedList.mjs.map +1 -0
  157. package/dist/admin/future/pages/Assets/utils/selection.js +104 -0
  158. package/dist/admin/future/pages/Assets/utils/selection.js.map +1 -0
  159. package/dist/admin/future/pages/Assets/utils/selection.mjs +94 -0
  160. package/dist/admin/future/pages/Assets/utils/selection.mjs.map +1 -0
  161. package/dist/admin/future/services/api.js +163 -28
  162. package/dist/admin/future/services/api.js.map +1 -1
  163. package/dist/admin/future/services/api.mjs +163 -30
  164. package/dist/admin/future/services/api.mjs.map +1 -1
  165. package/dist/admin/future/services/assets.js +62 -18
  166. package/dist/admin/future/services/assets.js.map +1 -1
  167. package/dist/admin/future/services/assets.mjs +62 -19
  168. package/dist/admin/future/services/assets.mjs.map +1 -1
  169. package/dist/admin/future/services/folders.js +31 -19
  170. package/dist/admin/future/services/folders.js.map +1 -1
  171. package/dist/admin/future/services/folders.mjs +31 -19
  172. package/dist/admin/future/services/folders.mjs.map +1 -1
  173. package/dist/admin/future/services/settings.js +10 -3
  174. package/dist/admin/future/services/settings.js.map +1 -1
  175. package/dist/admin/future/services/settings.mjs +10 -3
  176. package/dist/admin/future/services/settings.mjs.map +1 -1
  177. package/dist/admin/future/store/uploadProgress.js +109 -2
  178. package/dist/admin/future/store/uploadProgress.js.map +1 -1
  179. package/dist/admin/future/store/uploadProgress.mjs +105 -3
  180. package/dist/admin/future/store/uploadProgress.mjs.map +1 -1
  181. package/dist/admin/future/utils/buildDragSetFromSelection.js +33 -0
  182. package/dist/admin/future/utils/buildDragSetFromSelection.js.map +1 -0
  183. package/dist/admin/future/utils/buildDragSetFromSelection.mjs +31 -0
  184. package/dist/admin/future/utils/buildDragSetFromSelection.mjs.map +1 -0
  185. package/dist/admin/future/utils/canDropItemOnFolder.js +4 -0
  186. package/dist/admin/future/utils/canDropItemOnFolder.js.map +1 -1
  187. package/dist/admin/future/utils/canDropItemOnFolder.mjs +4 -0
  188. package/dist/admin/future/utils/canDropItemOnFolder.mjs.map +1 -1
  189. package/dist/admin/future/utils/flattenFolderStructure.js +28 -0
  190. package/dist/admin/future/utils/flattenFolderStructure.js.map +1 -0
  191. package/dist/admin/future/utils/flattenFolderStructure.mjs +26 -0
  192. package/dist/admin/future/utils/flattenFolderStructure.mjs.map +1 -0
  193. package/dist/admin/future/utils/formatMoveSuccessMessage.js +19 -0
  194. package/dist/admin/future/utils/formatMoveSuccessMessage.js.map +1 -0
  195. package/dist/admin/future/utils/formatMoveSuccessMessage.mjs +17 -0
  196. package/dist/admin/future/utils/formatMoveSuccessMessage.mjs.map +1 -0
  197. package/dist/admin/future/utils/getFolderLabel.js +31 -0
  198. package/dist/admin/future/utils/getFolderLabel.js.map +1 -0
  199. package/dist/admin/future/utils/getFolderLabel.mjs +29 -0
  200. package/dist/admin/future/utils/getFolderLabel.mjs.map +1 -0
  201. package/dist/admin/future/utils/searchQueryParam.js +11 -0
  202. package/dist/admin/future/utils/searchQueryParam.js.map +1 -0
  203. package/dist/admin/future/utils/searchQueryParam.mjs +9 -0
  204. package/dist/admin/future/utils/searchQueryParam.mjs.map +1 -0
  205. package/dist/admin/hooks/useSelectionState.js +2 -4
  206. package/dist/admin/hooks/useSelectionState.js.map +1 -1
  207. package/dist/admin/hooks/useSelectionState.mjs +2 -4
  208. package/dist/admin/hooks/useSelectionState.mjs.map +1 -1
  209. package/dist/admin/shared/constants.js +43 -0
  210. package/dist/admin/shared/constants.js.map +1 -0
  211. package/dist/admin/shared/constants.mjs +38 -0
  212. package/dist/admin/shared/constants.mjs.map +1 -0
  213. package/dist/admin/src/future/hooks/useMediaLibraryPermissions.d.ts +21 -0
  214. package/dist/admin/src/future/pages/Assets/components/AssetDetails/AssetCropEditor.d.ts +7 -1
  215. package/dist/admin/src/future/pages/Assets/components/AssetsSearchInput.d.ts +5 -0
  216. package/dist/admin/src/future/pages/Assets/components/AssetsTable.d.ts +7 -1
  217. package/dist/admin/src/future/pages/Assets/components/BulkActionsBar.d.ts +14 -0
  218. package/dist/admin/src/future/pages/Assets/components/BulkMoveDialog.d.ts +13 -0
  219. package/dist/admin/src/future/pages/Assets/components/DateRangeCalendar.d.ts +8 -0
  220. package/dist/admin/src/future/pages/Assets/components/Dnd/AssetsDndProvider.d.ts +2 -0
  221. package/dist/admin/src/future/pages/Assets/components/Dnd/DragOverlayChip.d.ts +2 -2
  222. package/dist/admin/src/future/pages/Assets/components/Dnd/buildDragSet.d.ts +17 -0
  223. package/dist/admin/src/future/pages/Assets/components/Dnd/computeValidDropTargets.d.ts +7 -0
  224. package/dist/admin/src/future/pages/Assets/components/Dnd/dndIds.d.ts +3 -0
  225. package/dist/admin/src/future/pages/Assets/components/Dnd/useAssetDnd.d.ts +3 -1
  226. package/dist/admin/src/future/pages/Assets/components/Dnd/useFolderTreeDroppable.d.ts +19 -0
  227. package/dist/admin/src/future/pages/Assets/components/DropZone/UploadDropZoneContext.d.ts +8 -1
  228. package/dist/admin/src/future/pages/Assets/components/EmptyState.d.ts +18 -1
  229. package/dist/admin/src/future/pages/Assets/components/FilterBadges.d.ts +6 -0
  230. package/dist/admin/src/future/pages/Assets/components/FilterMenu.d.ts +22 -0
  231. package/dist/admin/src/future/pages/Assets/components/FolderTree/FolderTree.d.ts +13 -4
  232. package/dist/admin/src/future/pages/Assets/components/FolderTree/filterFolderTree.d.ts +16 -0
  233. package/dist/admin/src/future/pages/Assets/components/FolderTree/useSpringLoadedExpand.d.ts +6 -0
  234. package/dist/admin/src/future/pages/Assets/components/SortMenu.d.ts +23 -0
  235. package/dist/admin/src/future/pages/Assets/hooks/useAssetSearch.d.ts +12 -0
  236. package/dist/admin/src/future/pages/Assets/hooks/useAssetSelection.d.ts +46 -0
  237. package/dist/admin/src/future/pages/Assets/hooks/useInfiniteAssets.d.ts +13 -3
  238. package/dist/admin/src/future/pages/Assets/hooks/useListFilters.d.ts +69 -0
  239. package/dist/admin/src/future/pages/Assets/hooks/useListSort.d.ts +47 -0
  240. package/dist/admin/src/future/pages/Assets/utils/buildAssetFilters.d.ts +46 -0
  241. package/dist/admin/src/future/pages/Assets/utils/listQueryKey.d.ts +29 -0
  242. package/dist/admin/src/future/pages/Assets/utils/mergeMixedList.d.ts +40 -0
  243. package/dist/admin/src/future/pages/Assets/utils/selection.d.ts +50 -0
  244. package/dist/admin/src/future/services/api.d.ts +53 -5
  245. package/dist/admin/src/future/services/assets.d.ts +13 -2
  246. package/dist/admin/src/future/services/folders.d.ts +7 -1
  247. package/dist/admin/src/future/services/settings.d.ts +2 -2
  248. package/dist/admin/src/future/store/uploadProgress.d.ts +83 -1
  249. package/dist/admin/src/future/types/dnd.d.ts +5 -0
  250. package/dist/admin/src/future/utils/buildDragSetFromSelection.d.ts +11 -0
  251. package/dist/admin/src/future/utils/canDropItemOnFolder.d.ts +1 -1
  252. package/dist/admin/src/future/utils/flattenFolderStructure.d.ts +18 -0
  253. package/dist/admin/src/future/utils/formatMoveSuccessMessage.d.ts +14 -0
  254. package/dist/admin/src/future/utils/getFolderLabel.d.ts +11 -0
  255. package/dist/admin/src/future/utils/searchQueryParam.d.ts +7 -0
  256. package/dist/admin/src/hooks/useAiAvailability.d.ts +1 -1
  257. package/dist/admin/src/hooks/useEditAsset.d.ts +4 -4
  258. package/dist/admin/src/hooks/useEditFolder.d.ts +4 -4
  259. package/dist/admin/src/hooks/useSettings.d.ts +1 -0
  260. package/dist/admin/src/hooks/useTracking.d.ts +1 -1
  261. package/dist/admin/src/hooks/useUpload.d.ts +1 -1
  262. package/dist/admin/translations/en.json.js +85 -2
  263. package/dist/admin/translations/en.json.js.map +1 -1
  264. package/dist/admin/translations/en.json.mjs +85 -2
  265. package/dist/admin/translations/en.json.mjs.map +1 -1
  266. package/dist/admin/utils/urlYupSchema.js +33 -9
  267. package/dist/admin/utils/urlYupSchema.js.map +1 -1
  268. package/dist/admin/utils/urlYupSchema.mjs +33 -9
  269. package/dist/admin/utils/urlYupSchema.mjs.map +1 -1
  270. package/dist/server/config.js +13 -5
  271. package/dist/server/config.js.map +1 -1
  272. package/dist/server/config.mjs +13 -5
  273. package/dist/server/config.mjs.map +1 -1
  274. package/dist/server/constants.js.map +1 -1
  275. package/dist/server/constants.mjs.map +1 -1
  276. package/dist/server/controllers/admin-file.js +30 -0
  277. package/dist/server/controllers/admin-file.js.map +1 -1
  278. package/dist/server/controllers/admin-file.mjs +30 -0
  279. package/dist/server/controllers/admin-file.mjs.map +1 -1
  280. package/dist/server/controllers/admin-settings.js +20 -2
  281. package/dist/server/controllers/admin-settings.js.map +1 -1
  282. package/dist/server/controllers/admin-settings.mjs +21 -3
  283. package/dist/server/controllers/admin-settings.mjs.map +1 -1
  284. package/dist/server/controllers/content-api.js +1 -2
  285. package/dist/server/controllers/content-api.js.map +1 -1
  286. package/dist/server/controllers/content-api.mjs +2 -2
  287. package/dist/server/controllers/content-api.mjs.map +1 -1
  288. package/dist/server/controllers/validation/admin/ai-metadata.js +12 -0
  289. package/dist/server/controllers/validation/admin/ai-metadata.js.map +1 -0
  290. package/dist/server/controllers/validation/admin/ai-metadata.mjs +10 -0
  291. package/dist/server/controllers/validation/admin/ai-metadata.mjs.map +1 -0
  292. package/dist/server/controllers/validation/admin/settings.js +4 -1
  293. package/dist/server/controllers/validation/admin/settings.js.map +1 -1
  294. package/dist/server/controllers/validation/admin/settings.mjs +1 -1
  295. package/dist/server/controllers/validation/admin/settings.mjs.map +1 -1
  296. package/dist/server/routes/admin.js +18 -0
  297. package/dist/server/routes/admin.js.map +1 -1
  298. package/dist/server/routes/admin.mjs +18 -0
  299. package/dist/server/routes/admin.mjs.map +1 -1
  300. package/dist/server/services/ai-metadata.js +108 -11
  301. package/dist/server/services/ai-metadata.js.map +1 -1
  302. package/dist/server/services/ai-metadata.mjs +108 -11
  303. package/dist/server/services/ai-metadata.mjs.map +1 -1
  304. package/dist/server/services/file.js +86 -13
  305. package/dist/server/services/file.js.map +1 -1
  306. package/dist/server/services/file.mjs +87 -14
  307. package/dist/server/services/file.mjs.map +1 -1
  308. package/dist/server/services/image-manipulation.js +4 -4
  309. package/dist/server/services/image-manipulation.js.map +1 -1
  310. package/dist/server/services/image-manipulation.mjs +4 -4
  311. package/dist/server/services/image-manipulation.mjs.map +1 -1
  312. package/dist/server/shared/constants.js +43 -0
  313. package/dist/server/shared/constants.js.map +1 -0
  314. package/dist/server/shared/constants.mjs +38 -0
  315. package/dist/server/shared/constants.mjs.map +1 -0
  316. package/dist/server/src/config.d.ts +2 -0
  317. package/dist/server/src/config.d.ts.map +1 -1
  318. package/dist/server/src/constants.d.ts +2 -1
  319. package/dist/server/src/constants.d.ts.map +1 -1
  320. package/dist/server/src/controllers/admin-file.d.ts +10 -0
  321. package/dist/server/src/controllers/admin-file.d.ts.map +1 -1
  322. package/dist/server/src/controllers/admin-settings.d.ts.map +1 -1
  323. package/dist/server/src/controllers/index.d.ts +1 -0
  324. package/dist/server/src/controllers/index.d.ts.map +1 -1
  325. package/dist/server/src/controllers/validation/admin/ai-metadata.d.ts +2 -0
  326. package/dist/server/src/controllers/validation/admin/ai-metadata.d.ts.map +1 -0
  327. package/dist/server/src/controllers/validation/admin/settings.d.ts +1 -1
  328. package/dist/server/src/controllers/validation/admin/settings.d.ts.map +1 -1
  329. package/dist/server/src/index.d.ts +7 -1
  330. package/dist/server/src/index.d.ts.map +1 -1
  331. package/dist/server/src/routes/admin.d.ts.map +1 -1
  332. package/dist/server/src/services/ai-metadata.d.ts +19 -0
  333. package/dist/server/src/services/ai-metadata.d.ts.map +1 -1
  334. package/dist/server/src/services/file.d.ts +12 -2
  335. package/dist/server/src/services/file.d.ts.map +1 -1
  336. package/dist/server/src/services/index.d.ts +4 -1
  337. package/dist/server/src/services/index.d.ts.map +1 -1
  338. package/dist/server/src/types.d.ts +3 -0
  339. package/dist/server/src/types.d.ts.map +1 -1
  340. package/dist/shared/constants.d.ts +35 -0
  341. package/dist/shared/constants.d.ts.map +1 -0
  342. package/dist/shared/contracts/files.d.ts +25 -0
  343. package/dist/shared/contracts/files.d.ts.map +1 -1
  344. package/dist/shared/contracts/folders.d.ts +1 -1
  345. package/dist/shared/contracts/settings.d.ts +7 -0
  346. package/package.json +8 -8
@@ -0,0 +1,191 @@
1
+ import { jsxs, jsx } from 'react/jsx-runtime';
2
+ import { useState } from 'react';
3
+ import { Box, Flex, IconButton, Typography, VisuallyHidden } from '@strapi/design-system';
4
+ import { ChevronLeft, ChevronRight } from '@strapi/icons';
5
+ import { useIntl } from 'react-intl';
6
+ import { styled } from 'styled-components';
7
+ import { getTranslationKey } from '../../../utils/translations.mjs';
8
+
9
+ /**
10
+ * Month-grid range picker: first click sets the start, second click the end
11
+ * (clicks are reordered when the second date is before the first). The DS only
12
+ * ships a single-value DatePicker, so the range grid is built locally.
13
+ *
14
+ * Month/year move via chevrons rather than the mock's dropdowns — nested
15
+ * popovers inside a dropdown menu fight Radix's outside-interaction handling.
16
+ */ const DayCell = styled.button`
17
+ width: 3rem;
18
+ height: 3rem;
19
+ border: none;
20
+ border-radius: ${({ theme })=>theme.borderRadius};
21
+ cursor: pointer;
22
+ font: inherit;
23
+ color: ${({ theme, $isEdge, $isMuted })=>{
24
+ if ($isEdge) return theme.colors.primary600;
25
+ if ($isMuted) return theme.colors.neutral400;
26
+ return theme.colors.neutral800;
27
+ }};
28
+ background: ${({ theme, $inRange, $isEdge })=>{
29
+ if ($isEdge) return theme.colors.primary200;
30
+ if ($inRange) return theme.colors.primary100;
31
+ return 'transparent';
32
+ }};
33
+
34
+ &:hover {
35
+ background: ${({ theme })=>theme.colors.primary100};
36
+ }
37
+
38
+ &:focus-visible {
39
+ outline: 2px solid ${({ theme })=>theme.colors.primary600};
40
+ outline-offset: -2px;
41
+ }
42
+ `;
43
+ const toKey = (date)=>{
44
+ const month = `${date.getMonth() + 1}`.padStart(2, '0');
45
+ const day = `${date.getDate()}`.padStart(2, '0');
46
+ return `${date.getFullYear()}-${month}-${day}`;
47
+ };
48
+ const fromKey = (key)=>{
49
+ const [year, month, day] = key.split('-').map(Number);
50
+ return new Date(year, month - 1, day);
51
+ };
52
+ /** Monday-first weeks covering the given month, padded with adjacent days. */ const buildWeeks = (year, month)=>{
53
+ const first = new Date(year, month, 1);
54
+ const start = new Date(first.getTime());
55
+ start.setDate(first.getDate() - (first.getDay() + 6) % 7);
56
+ const weeks = [];
57
+ const cursor = new Date(start.getTime());
58
+ do {
59
+ const week = [];
60
+ for(let i = 0; i < 7; i += 1){
61
+ week.push(new Date(cursor.getTime()));
62
+ cursor.setDate(cursor.getDate() + 1);
63
+ }
64
+ weeks.push(week);
65
+ }while (cursor.getMonth() === month && cursor.getFullYear() === year)
66
+ return weeks;
67
+ };
68
+ const DateRangeCalendar = ({ from, to, onSelect })=>{
69
+ const { formatMessage, formatDate } = useIntl();
70
+ const initialMonth = from ? fromKey(from) : new Date();
71
+ const [viewYear, setViewYear] = useState(initialMonth.getFullYear());
72
+ const [viewMonth, setViewMonth] = useState(initialMonth.getMonth());
73
+ // In-progress selection: set on the first click, cleared on commit.
74
+ const [pendingStart, setPendingStart] = useState(null);
75
+ const rangeStart = pendingStart ?? from ?? null;
76
+ const rangeEnd = pendingStart ? null : to ?? null;
77
+ const moveMonth = (delta)=>{
78
+ const next = new Date(viewYear, viewMonth + delta, 1);
79
+ setViewYear(next.getFullYear());
80
+ setViewMonth(next.getMonth());
81
+ };
82
+ const handleDayClick = (day)=>{
83
+ const key = toKey(day);
84
+ if (!pendingStart) {
85
+ setPendingStart(key);
86
+ return;
87
+ }
88
+ const [start, end] = key < pendingStart ? [
89
+ key,
90
+ pendingStart
91
+ ] : [
92
+ pendingStart,
93
+ key
94
+ ];
95
+ setPendingStart(null);
96
+ onSelect(start, end);
97
+ };
98
+ const weeks = buildWeeks(viewYear, viewMonth);
99
+ const weekDayLabels = weeks[0].map((day)=>formatDate(day, {
100
+ weekday: 'short'
101
+ }).slice(0, 2));
102
+ return(// role="group" (not "application"): these are plain buttons — hijacking
103
+ // the screen reader's own key handling would take away navigation and
104
+ // give nothing back.
105
+ /*#__PURE__*/ jsxs(Box, {
106
+ padding: 2,
107
+ width: "100%",
108
+ role: "group",
109
+ "aria-label": formatMessage({
110
+ id: getTranslationKey('list.filters.calendar.label'),
111
+ defaultMessage: 'Select date range'
112
+ }),
113
+ "data-testid": "date-range-calendar",
114
+ children: [
115
+ /*#__PURE__*/ jsxs(Flex, {
116
+ justifyContent: "space-between",
117
+ alignItems: "center",
118
+ paddingBottom: 2,
119
+ children: [
120
+ /*#__PURE__*/ jsx(IconButton, {
121
+ variant: "ghost",
122
+ label: formatMessage({
123
+ id: getTranslationKey('list.filters.calendar.previous-month'),
124
+ defaultMessage: 'Previous month'
125
+ }),
126
+ onClick: ()=>moveMonth(-1),
127
+ children: /*#__PURE__*/ jsx(ChevronLeft, {})
128
+ }),
129
+ /*#__PURE__*/ jsx(Typography, {
130
+ fontWeight: "semiBold",
131
+ textColor: "neutral800",
132
+ children: formatDate(new Date(viewYear, viewMonth, 1), {
133
+ month: 'long',
134
+ year: 'numeric'
135
+ })
136
+ }),
137
+ /*#__PURE__*/ jsx(IconButton, {
138
+ variant: "ghost",
139
+ label: formatMessage({
140
+ id: getTranslationKey('list.filters.calendar.next-month'),
141
+ defaultMessage: 'Next month'
142
+ }),
143
+ onClick: ()=>moveMonth(1),
144
+ children: /*#__PURE__*/ jsx(ChevronRight, {})
145
+ })
146
+ ]
147
+ }),
148
+ /*#__PURE__*/ jsx(Flex, {
149
+ children: weekDayLabels.map((label, index)=>/*#__PURE__*/ jsx(Flex, {
150
+ width: "3rem",
151
+ height: "2.4rem",
152
+ justifyContent: "center",
153
+ children: /*#__PURE__*/ jsx(Typography, {
154
+ variant: "pi",
155
+ fontWeight: "semiBold",
156
+ textColor: "neutral600",
157
+ children: label
158
+ })
159
+ }, index))
160
+ }),
161
+ weeks.map((week, weekIndex)=>/*#__PURE__*/ jsx(Flex, {
162
+ children: week.map((day)=>{
163
+ const key = toKey(day);
164
+ const isEdge = key === rangeStart || key === rangeEnd;
165
+ const inRange = rangeStart !== null && rangeEnd !== null && key > rangeStart && key < rangeEnd;
166
+ return /*#__PURE__*/ jsxs(DayCell, {
167
+ type: "button",
168
+ $isEdge: isEdge,
169
+ $inRange: inRange,
170
+ $isMuted: day.getMonth() !== viewMonth,
171
+ onClick: ()=>handleDayClick(day),
172
+ children: [
173
+ /*#__PURE__*/ jsx(VisuallyHidden, {
174
+ children: formatDate(day, {
175
+ dateStyle: 'long'
176
+ })
177
+ }),
178
+ /*#__PURE__*/ jsx("span", {
179
+ "aria-hidden": true,
180
+ children: day.getDate()
181
+ })
182
+ ]
183
+ }, key);
184
+ })
185
+ }, weekIndex))
186
+ ]
187
+ }));
188
+ };
189
+
190
+ export { DateRangeCalendar };
191
+ //# sourceMappingURL=DateRangeCalendar.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"DateRangeCalendar.mjs","sources":["../../../../../../admin/src/future/pages/Assets/components/DateRangeCalendar.tsx"],"sourcesContent":["import { useState } from 'react';\n\nimport { Box, Flex, IconButton, Typography, VisuallyHidden } from '@strapi/design-system';\nimport { ChevronLeft, ChevronRight } from '@strapi/icons';\nimport { useIntl } from 'react-intl';\nimport { styled } from 'styled-components';\n\nimport { getTranslationKey } from '../../../utils/translations';\n\n/**\n * Month-grid range picker: first click sets the start, second click the end\n * (clicks are reordered when the second date is before the first). The DS only\n * ships a single-value DatePicker, so the range grid is built locally.\n *\n * Month/year move via chevrons rather than the mock's dropdowns — nested\n * popovers inside a dropdown menu fight Radix's outside-interaction handling.\n */\n\nconst DayCell = styled.button<{ $inRange?: boolean; $isEdge?: boolean; $isMuted?: boolean }>`\n width: 3rem;\n height: 3rem;\n border: none;\n border-radius: ${({ theme }) => theme.borderRadius};\n cursor: pointer;\n font: inherit;\n color: ${({ theme, $isEdge, $isMuted }) => {\n if ($isEdge) return theme.colors.primary600;\n if ($isMuted) return theme.colors.neutral400;\n return theme.colors.neutral800;\n }};\n background: ${({ theme, $inRange, $isEdge }) => {\n if ($isEdge) return theme.colors.primary200;\n if ($inRange) return theme.colors.primary100;\n return 'transparent';\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 toKey = (date: Date): string => {\n const month = `${date.getMonth() + 1}`.padStart(2, '0');\n const day = `${date.getDate()}`.padStart(2, '0');\n return `${date.getFullYear()}-${month}-${day}`;\n};\n\nconst fromKey = (key: string): Date => {\n const [year, month, day] = key.split('-').map(Number);\n return new Date(year, month - 1, day);\n};\n\n/** Monday-first weeks covering the given month, padded with adjacent days. */\nconst buildWeeks = (year: number, month: number): Date[][] => {\n const first = new Date(year, month, 1);\n const start = new Date(first.getTime());\n start.setDate(first.getDate() - ((first.getDay() + 6) % 7));\n\n const weeks: Date[][] = [];\n const cursor = new Date(start.getTime());\n\n do {\n const week: Date[] = [];\n for (let i = 0; i < 7; i += 1) {\n week.push(new Date(cursor.getTime()));\n cursor.setDate(cursor.getDate() + 1);\n }\n weeks.push(week);\n } while (cursor.getMonth() === month && cursor.getFullYear() === year);\n\n return weeks;\n};\n\ninterface DateRangeCalendarProps {\n /** `YYYY-MM-DD`, both set when editing an existing range badge. */\n from?: string;\n to?: string;\n onSelect: (from: string, to: string) => void;\n}\n\nexport const DateRangeCalendar = ({ from, to, onSelect }: DateRangeCalendarProps) => {\n const { formatMessage, formatDate } = useIntl();\n\n const initialMonth = from ? fromKey(from) : new Date();\n const [viewYear, setViewYear] = useState(initialMonth.getFullYear());\n const [viewMonth, setViewMonth] = useState(initialMonth.getMonth());\n // In-progress selection: set on the first click, cleared on commit.\n const [pendingStart, setPendingStart] = useState<string | null>(null);\n\n const rangeStart = pendingStart ?? from ?? null;\n const rangeEnd = pendingStart ? null : (to ?? null);\n\n const moveMonth = (delta: number) => {\n const next = new Date(viewYear, viewMonth + delta, 1);\n setViewYear(next.getFullYear());\n setViewMonth(next.getMonth());\n };\n\n const handleDayClick = (day: Date) => {\n const key = toKey(day);\n\n if (!pendingStart) {\n setPendingStart(key);\n return;\n }\n\n const [start, end] = key < pendingStart ? [key, pendingStart] : [pendingStart, key];\n setPendingStart(null);\n onSelect(start, end);\n };\n\n const weeks = buildWeeks(viewYear, viewMonth);\n const weekDayLabels = weeks[0].map((day) => formatDate(day, { weekday: 'short' }).slice(0, 2));\n\n return (\n // role=\"group\" (not \"application\"): these are plain buttons — hijacking\n // the screen reader's own key handling would take away navigation and\n // give nothing back.\n <Box\n padding={2}\n width=\"100%\"\n role=\"group\"\n aria-label={formatMessage({\n id: getTranslationKey('list.filters.calendar.label'),\n defaultMessage: 'Select date range',\n })}\n data-testid=\"date-range-calendar\"\n >\n <Flex justifyContent=\"space-between\" alignItems=\"center\" paddingBottom={2}>\n <IconButton\n variant=\"ghost\"\n label={formatMessage({\n id: getTranslationKey('list.filters.calendar.previous-month'),\n defaultMessage: 'Previous month',\n })}\n onClick={() => moveMonth(-1)}\n >\n <ChevronLeft />\n </IconButton>\n <Typography fontWeight=\"semiBold\" textColor=\"neutral800\">\n {formatDate(new Date(viewYear, viewMonth, 1), { month: 'long', year: 'numeric' })}\n </Typography>\n <IconButton\n variant=\"ghost\"\n label={formatMessage({\n id: getTranslationKey('list.filters.calendar.next-month'),\n defaultMessage: 'Next month',\n })}\n onClick={() => moveMonth(1)}\n >\n <ChevronRight />\n </IconButton>\n </Flex>\n\n <Flex>\n {weekDayLabels.map((label, index) => (\n <Flex key={index} width=\"3rem\" height=\"2.4rem\" justifyContent=\"center\">\n <Typography variant=\"pi\" fontWeight=\"semiBold\" textColor=\"neutral600\">\n {label}\n </Typography>\n </Flex>\n ))}\n </Flex>\n\n {weeks.map((week, weekIndex) => (\n <Flex key={weekIndex}>\n {week.map((day) => {\n const key = toKey(day);\n const isEdge = key === rangeStart || key === rangeEnd;\n const inRange =\n rangeStart !== null && rangeEnd !== null && key > rangeStart && key < rangeEnd;\n\n return (\n <DayCell\n key={key}\n type=\"button\"\n $isEdge={isEdge}\n $inRange={inRange}\n $isMuted={day.getMonth() !== viewMonth}\n onClick={() => handleDayClick(day)}\n >\n <VisuallyHidden>{formatDate(day, { dateStyle: 'long' })}</VisuallyHidden>\n <span aria-hidden>{day.getDate()}</span>\n </DayCell>\n );\n })}\n </Flex>\n ))}\n </Box>\n );\n};\n"],"names":["DayCell","styled","button","theme","borderRadius","$isEdge","$isMuted","colors","primary600","neutral400","neutral800","$inRange","primary200","primary100","toKey","date","month","getMonth","padStart","day","getDate","getFullYear","fromKey","key","year","split","map","Number","Date","buildWeeks","first","start","getTime","setDate","getDay","weeks","cursor","week","i","push","DateRangeCalendar","from","to","onSelect","formatMessage","formatDate","useIntl","initialMonth","viewYear","setViewYear","useState","viewMonth","setViewMonth","pendingStart","setPendingStart","rangeStart","rangeEnd","moveMonth","delta","next","handleDayClick","end","weekDayLabels","weekday","slice","_jsxs","Box","padding","width","role","aria-label","id","getTranslationKey","defaultMessage","data-testid","Flex","justifyContent","alignItems","paddingBottom","_jsx","IconButton","variant","label","onClick","ChevronLeft","Typography","fontWeight","textColor","ChevronRight","index","height","weekIndex","isEdge","inRange","type","VisuallyHidden","dateStyle","span","aria-hidden"],"mappings":"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"}
@@ -6,64 +6,138 @@ var core = require('@dnd-kit/core');
6
6
  var strapiAdmin = require('@strapi/admin/strapi-admin');
7
7
  var designSystem = require('@strapi/design-system');
8
8
  var reactIntl = require('react-intl');
9
+ var useMediaLibraryPermissions = require('../../../../hooks/useMediaLibraryPermissions.js');
9
10
  var folders = require('../../../../services/folders.js');
10
11
  var buildBulkMovePayload = require('../../../../utils/buildBulkMovePayload.js');
11
12
  var canDropItemOnFolder = require('../../../../utils/canDropItemOnFolder.js');
13
+ var formatMoveSuccessMessage = require('../../../../utils/formatMoveSuccessMessage.js');
12
14
  var getBulkMoveErrorMessage = require('../../../../utils/getBulkMoveErrorMessage.js');
15
+ var getFolderLabel = require('../../../../utils/getFolderLabel.js');
13
16
  var translations = require('../../../../utils/translations.js');
17
+ var useAssetSelection = require('../../hooks/useAssetSelection.js');
18
+ var useFolderNavigation = require('../../hooks/useFolderNavigation.js');
19
+ var buildDragSet = require('./buildDragSet.js');
20
+ var computeValidDropTargets = require('./computeValidDropTargets.js');
14
21
  var dndIds = require('./dndIds.js');
15
22
  var DragOverlayChip = require('./DragOverlayChip.js');
16
23
 
17
24
  const AssetsDndContext = /*#__PURE__*/ React.createContext(null);
18
25
  const useAssetsDndOptional = ()=>React.useContext(AssetsDndContext);
19
- const getDragItems = (activeData)=>{
20
- if (!activeData) {
21
- return [];
26
+ const resolveDestination = (overId)=>{
27
+ const inView = dndIds.parseFolderTargetId(overId);
28
+ if (inView != null) {
29
+ return {
30
+ destinationFolderId: inView
31
+ };
22
32
  }
23
- // TODO(CMS-433): include selectedItems from active data for multi-drag payload members.
24
- return [
25
- activeData
26
- ];
33
+ const tree = dndIds.parseFolderTreeTargetId(overId);
34
+ if (tree === 'root') {
35
+ return {
36
+ destinationFolderId: null
37
+ };
38
+ }
39
+ if (typeof tree === 'number') {
40
+ return {
41
+ destinationFolderId: tree
42
+ };
43
+ }
44
+ return null;
27
45
  };
46
+ // Activation distance no real pointer gesture will ever reach — used to keep a
47
+ // constant-length sensor array while disabling drag for users without the move
48
+ // permission (see the note in the provider).
49
+ const DRAG_DISABLED_DISTANCE = Number.MAX_SAFE_INTEGER;
28
50
  const AssetsDndProvider = ({ children })=>{
29
51
  const { formatMessage } = reactIntl.useIntl();
30
52
  const { toggleNotification } = strapiAdmin.useNotification();
53
+ const selection = useAssetSelection.useAssetSelectionOptional();
54
+ const { currentFolderId } = useFolderNavigation.useFolderNavigation();
31
55
  const { data: folderStructure = [] } = folders.useGetFolderStructureQuery();
56
+ const rootLabel = formatMessage({
57
+ id: translations.getTranslationKey('plugin.name'),
58
+ defaultMessage: 'Media Library'
59
+ });
32
60
  const [bulkMove, { isLoading: isMovePending }] = folders.useBulkMoveMutation();
33
- const [activeItem, setActiveItem] = React.useState(null);
61
+ const [dragItems, setDragItems] = React.useState([]);
34
62
  const [liveAnnouncement, setLiveAnnouncement] = React.useState('');
63
+ // Sync session for drag-end — state alone can lag one render behind dragStart.
64
+ const dragSessionRef = React.useRef({
65
+ items: [],
66
+ fromSelection: false
67
+ });
35
68
  const announceToLiveRegion = React.useCallback((message)=>{
36
69
  setLiveAnnouncement('');
37
70
  requestAnimationFrame(()=>setLiveAnnouncement(message));
38
71
  }, []);
72
+ // Moving is a mutation (bulk-move → `assets.update`); without the permission
73
+ // pointer drag must never activate. Keyboard moves go through BulkMoveDialog,
74
+ // which is itself gated.
75
+ //
76
+ // The gate has to keep BOTH the `useSensor`/`useSensors` calls AND the sensor
77
+ // array's length constant across renders: `canUpdate` starts false and flips
78
+ // true once the RBAC check resolves, and dnd-kit keys internal memos/effects
79
+ // on the sensor list, erroring if its size changes ("argument changed size
80
+ // between renders"). So adding/removing a sensor is out — instead keep one
81
+ // PointerSensor always and push its activation distance out of reach when the
82
+ // user can't move, which no real drag gesture will ever satisfy.
83
+ const { canUpdate } = useMediaLibraryPermissions.useMediaLibraryPermissions();
39
84
  const sensors = core.useSensors(core.useSensor(core.PointerSensor, {
40
85
  activationConstraint: {
41
- distance: 8
86
+ distance: canUpdate ? 8 : DRAG_DISABLED_DISTANCE
42
87
  }
43
88
  }));
89
+ const validDropTargets = React.useMemo(()=>computeValidDropTargets.computeValidDropTargets(dragItems, folderStructure), [
90
+ dragItems,
91
+ folderStructure
92
+ ]);
93
+ const isValidDropTarget = React.useCallback((targetFolderId)=>validDropTargets.has(targetFolderId), [
94
+ validDropTargets
95
+ ]);
44
96
  const contextValue = React.useMemo(()=>({
45
- isInternalDragActive: activeItem !== null,
46
- isMovePending
97
+ isInternalDragActive: dragItems.length > 0,
98
+ isMovePending,
99
+ isValidDropTarget
47
100
  }), [
48
- activeItem,
49
- isMovePending
101
+ dragItems.length,
102
+ isMovePending,
103
+ isValidDropTarget
50
104
  ]);
105
+ const clearDragState = React.useCallback(()=>{
106
+ dragSessionRef.current = {
107
+ items: [],
108
+ fromSelection: false
109
+ };
110
+ setDragItems([]);
111
+ }, []);
51
112
  const handleDragStart = React.useCallback((event)=>{
52
113
  const data = event.active.data.current;
53
- setActiveItem(data ?? null);
54
- }, []);
114
+ if (!data) {
115
+ clearDragState();
116
+ return;
117
+ }
118
+ const { items, fromSelection } = buildDragSet.buildDragSet(data, selection?.selectedKeys, currentFolderId);
119
+ dragSessionRef.current = {
120
+ items,
121
+ fromSelection
122
+ };
123
+ setDragItems(items);
124
+ }, [
125
+ clearDragState,
126
+ currentFolderId,
127
+ selection?.selectedKeys
128
+ ]);
55
129
  const handleDragEnd = React.useCallback(async (event)=>{
56
- const { active, over } = event;
57
- setActiveItem(null);
58
- if (isMovePending || !over) {
130
+ const { over } = event;
131
+ const { items, fromSelection } = dragSessionRef.current;
132
+ clearDragState();
133
+ if (isMovePending || !over || items.length === 0) {
59
134
  return;
60
135
  }
61
- const targetFolderId = dndIds.parseFolderTargetId(over.id);
62
- const activeData = active.data.current;
63
- if (targetFolderId == null || !activeData) {
136
+ const destination = resolveDestination(over.id);
137
+ if (!destination) {
64
138
  return;
65
139
  }
66
- const items = getDragItems(activeData);
140
+ const { destinationFolderId: targetFolderId } = destination;
67
141
  if (!canDropItemOnFolder.canDropItemOnFolder({
68
142
  items,
69
143
  targetFolderId,
@@ -72,19 +146,27 @@ const AssetsDndProvider = ({ children })=>{
72
146
  return;
73
147
  }
74
148
  const payload = buildBulkMovePayload.buildBulkMovePayload(items);
75
- const successMessage = formatMessage({
76
- id: translations.getTranslationKey('modal.move.success-label'),
77
- defaultMessage: 'Elements have been moved successfully.'
149
+ // Source is always the current folder — dragged items are, by definition,
150
+ // visible in the current view. Destination is the drop target. Both use
151
+ // leaf names so the DnD toast reads identically to the dialog's.
152
+ const successMessage = formatMoveSuccessMessage.formatMoveSuccessMessage({
153
+ formatMessage,
154
+ count: items.length,
155
+ source: getFolderLabel.getFolderLabel(folderStructure, currentFolderId, rootLabel),
156
+ destination: getFolderLabel.getFolderLabel(folderStructure, targetFolderId, rootLabel)
78
157
  });
79
158
  const errorFallback = formatMessage({
80
- id: translations.getTranslationKey('modal.move.error-label'),
81
- defaultMessage: 'An error occurred while moving the elements.'
159
+ id: translations.getTranslationKey('list.bulk-actions.move.error'),
160
+ defaultMessage: 'An error occurred while moving the items.'
82
161
  });
83
162
  try {
84
163
  await bulkMove({
85
164
  ...payload,
86
165
  destinationFolderId: targetFolderId
87
166
  }).unwrap();
167
+ if (fromSelection) {
168
+ selection?.clear();
169
+ }
88
170
  announceToLiveRegion(successMessage);
89
171
  toggleNotification({
90
172
  type: 'success',
@@ -106,14 +188,20 @@ const AssetsDndProvider = ({ children })=>{
106
188
  }, [
107
189
  announceToLiveRegion,
108
190
  bulkMove,
191
+ clearDragState,
192
+ currentFolderId,
109
193
  folderStructure,
110
194
  formatMessage,
111
195
  isMovePending,
196
+ rootLabel,
197
+ selection,
112
198
  toggleNotification
113
199
  ]);
114
200
  const handleDragCancel = React.useCallback(()=>{
115
- setActiveItem(null);
116
- }, []);
201
+ clearDragState();
202
+ }, [
203
+ clearDragState
204
+ ]);
117
205
  const announcements = React.useMemo(()=>({
118
206
  onDragStart: ({ active })=>{
119
207
  const data = active.data.current;
@@ -132,15 +220,15 @@ const AssetsDndProvider = ({ children })=>{
132
220
  defaultMessage: 'Drag cancelled.'
133
221
  });
134
222
  }
135
- const targetFolderId = dndIds.parseFolderTargetId(over.id);
223
+ const destination = resolveDestination(over.id);
136
224
  const activeData = active.data.current;
137
- if (targetFolderId == null || !activeData) {
225
+ if (!destination || !activeData) {
138
226
  return '';
139
227
  }
140
- const items = getDragItems(activeData);
228
+ const { items } = buildDragSet.buildDragSet(activeData, selection?.selectedKeys, currentFolderId);
141
229
  if (!canDropItemOnFolder.canDropItemOnFolder({
142
230
  items,
143
- targetFolderId,
231
+ targetFolderId: destination.destinationFolderId,
144
232
  folderStructure
145
233
  })) {
146
234
  return formatMessage({
@@ -155,8 +243,10 @@ const AssetsDndProvider = ({ children })=>{
155
243
  defaultMessage: 'Drag cancelled.'
156
244
  })
157
245
  }), [
246
+ currentFolderId,
158
247
  folderStructure,
159
- formatMessage
248
+ formatMessage,
249
+ selection?.selectedKeys
160
250
  ]);
161
251
  return /*#__PURE__*/ jsxRuntime.jsx(AssetsDndContext.Provider, {
162
252
  value: contextValue,
@@ -181,14 +271,16 @@ const AssetsDndProvider = ({ children })=>{
181
271
  }),
182
272
  /*#__PURE__*/ jsxRuntime.jsx(core.DragOverlay, {
183
273
  dropAnimation: null,
184
- children: activeItem ? /*#__PURE__*/ jsxRuntime.jsx(DragOverlayChip.DragOverlayChip, {
185
- item: activeItem
274
+ children: dragItems.length > 0 ? /*#__PURE__*/ jsxRuntime.jsx(DragOverlayChip.DragOverlayChip, {
275
+ items: dragItems
186
276
  }) : null
187
277
  })
188
278
  ]
189
279
  })
190
280
  });
191
- }; // TODO(CMS-229): FolderTree droppables + keyboard move path.
281
+ }; // Keyboard-accessible moves are handled by `BulkMoveDialog` (reachable from the
282
+ // bulk-actions bar): pointer drag is a mouse-only enhancement, the dialog is the
283
+ // a11y path. No `KeyboardSensor` by design.
192
284
 
193
285
  exports.AssetsDndProvider = AssetsDndProvider;
194
286
  exports.useAssetsDndOptional = useAssetsDndOptional;
@@ -1 +1 @@
1
- {"version":3,"file":"AssetsDndProvider.js","sources":["../../../../../../../admin/src/future/pages/Assets/components/Dnd/AssetsDndProvider.tsx"],"sourcesContent":["import { createContext, useCallback, useContext, useMemo, useState, type ReactNode } from 'react';\n\nimport {\n DndContext,\n DragOverlay,\n PointerSensor,\n pointerWithin,\n useSensor,\n useSensors,\n type DragEndEvent,\n type DragStartEvent,\n} from '@dnd-kit/core';\nimport { useNotification } from '@strapi/admin/strapi-admin';\nimport { Box, VisuallyHidden } from '@strapi/design-system';\nimport { useIntl } from 'react-intl';\n\nimport { useBulkMoveMutation, useGetFolderStructureQuery } from '../../../../services/folders';\nimport { buildBulkMovePayload } from '../../../../utils/buildBulkMovePayload';\nimport { canDropItemOnFolder } from '../../../../utils/canDropItemOnFolder';\nimport { getBulkMoveErrorMessage } from '../../../../utils/getBulkMoveErrorMessage';\nimport { getTranslationKey } from '../../../../utils/translations';\n\nimport { parseFolderTargetId } from './dndIds';\nimport { DragOverlayChip } from './DragOverlayChip';\n\nimport type { DragItemData } from '../../../../types/dnd';\n\n/* -------------------------------------------------------------------------------------------------\n * Context — shared with UploadDropZoneProvider for bidirectional drag guard.\n * See UploadDropZoneContext.tsx TODO linking both providers.\n * -----------------------------------------------------------------------------------------------*/\n\ninterface AssetsDndContextValue {\n isInternalDragActive: boolean;\n isMovePending: boolean;\n}\n\nconst AssetsDndContext = createContext<AssetsDndContextValue | null>(null);\n\nexport const useAssetsDnd = () => {\n const context = useContext(AssetsDndContext);\n\n if (!context) {\n throw new Error('useAssetsDnd must be used within AssetsDndProvider');\n }\n\n return context;\n};\n\nexport const useAssetsDndOptional = () => useContext(AssetsDndContext);\n\n/* -------------------------------------------------------------------------------------------------\n * Provider\n * -----------------------------------------------------------------------------------------------*/\n\ninterface AssetsDndProviderProps {\n children: ReactNode;\n}\n\nconst getDragItems = (activeData: DragItemData | undefined): DragItemData[] => {\n if (!activeData) {\n return [];\n }\n\n // TODO(CMS-433): include selectedItems from active data for multi-drag payload members.\n return [activeData];\n};\n\nexport const AssetsDndProvider = ({ children }: AssetsDndProviderProps) => {\n const { formatMessage } = useIntl();\n const { toggleNotification } = useNotification();\n const { data: folderStructure = [] } = useGetFolderStructureQuery();\n const [bulkMove, { isLoading: isMovePending }] = useBulkMoveMutation();\n const [activeItem, setActiveItem] = useState<DragItemData | null>(null);\n const [liveAnnouncement, setLiveAnnouncement] = useState('');\n\n const announceToLiveRegion = useCallback((message: string) => {\n setLiveAnnouncement('');\n requestAnimationFrame(() => setLiveAnnouncement(message));\n }, []);\n\n const sensors = useSensors(\n useSensor(PointerSensor, {\n activationConstraint: { distance: 8 },\n })\n );\n\n const contextValue = useMemo<AssetsDndContextValue>(\n () => ({\n isInternalDragActive: activeItem !== null,\n isMovePending,\n }),\n [activeItem, isMovePending]\n );\n\n const handleDragStart = useCallback((event: DragStartEvent) => {\n const data = event.active.data.current as DragItemData | undefined;\n setActiveItem(data ?? null);\n }, []);\n\n const handleDragEnd = useCallback(\n async (event: DragEndEvent) => {\n const { active, over } = event;\n setActiveItem(null);\n\n if (isMovePending || !over) {\n return;\n }\n\n const targetFolderId = parseFolderTargetId(over.id);\n const activeData = active.data.current as DragItemData | undefined;\n\n if (targetFolderId == null || !activeData) {\n return;\n }\n\n const items = getDragItems(activeData);\n\n if (\n !canDropItemOnFolder({\n items,\n targetFolderId,\n folderStructure,\n })\n ) {\n return;\n }\n\n const payload = buildBulkMovePayload(items);\n const successMessage = formatMessage({\n id: getTranslationKey('modal.move.success-label'),\n defaultMessage: 'Elements have been moved successfully.',\n });\n const errorFallback = formatMessage({\n id: getTranslationKey('modal.move.error-label'),\n defaultMessage: 'An error occurred while moving the elements.',\n });\n\n try {\n await bulkMove({ ...payload, destinationFolderId: targetFolderId }).unwrap();\n\n announceToLiveRegion(successMessage);\n\n toggleNotification({\n type: 'success',\n message: successMessage,\n });\n } catch (error) {\n const errorMessage = getBulkMoveErrorMessage(error, errorFallback);\n\n announceToLiveRegion(\n formatMessage(\n {\n id: getTranslationKey('dnd.announce.move-failure'),\n defaultMessage: 'Move failed. {message}',\n },\n { message: errorMessage }\n )\n );\n\n toggleNotification({\n type: 'danger',\n message: errorMessage,\n });\n }\n },\n [\n announceToLiveRegion,\n bulkMove,\n folderStructure,\n formatMessage,\n isMovePending,\n toggleNotification,\n ]\n );\n\n const handleDragCancel = useCallback(() => {\n setActiveItem(null);\n }, []);\n\n const announcements = useMemo(\n () => ({\n onDragStart: ({ active }: DragStartEvent) => {\n const data = active.data.current as DragItemData | undefined;\n return data\n ? formatMessage(\n {\n id: getTranslationKey('dnd.announce.drag-start'),\n defaultMessage: 'Picked up {name}. Drop on a folder to move.',\n },\n { name: data.name }\n )\n : '';\n },\n onDragOver: () => '',\n onDragEnd: ({ active, over }: DragEndEvent) => {\n if (!over) {\n return formatMessage({\n id: getTranslationKey('dnd.announce.cancel'),\n defaultMessage: 'Drag cancelled.',\n });\n }\n\n const targetFolderId = parseFolderTargetId(over.id);\n const activeData = active.data.current as DragItemData | undefined;\n\n if (targetFolderId == null || !activeData) {\n return '';\n }\n\n const items = getDragItems(activeData);\n\n if (\n !canDropItemOnFolder({\n items,\n targetFolderId,\n folderStructure,\n })\n ) {\n return formatMessage({\n id: getTranslationKey('dnd.announce.invalid-drop'),\n defaultMessage: 'Cannot move item to this folder.',\n });\n }\n\n return '';\n },\n onDragCancel: () =>\n formatMessage({\n id: getTranslationKey('dnd.announce.cancel'),\n defaultMessage: 'Drag cancelled.',\n }),\n }),\n [folderStructure, formatMessage]\n );\n\n return (\n <AssetsDndContext.Provider value={contextValue}>\n <DndContext\n sensors={sensors}\n collisionDetection={pointerWithin}\n onDragStart={handleDragStart}\n onDragEnd={handleDragEnd}\n onDragCancel={handleDragCancel}\n accessibility={{ announcements }}\n >\n <VisuallyHidden aria-live=\"polite\" aria-atomic=\"true\">\n {liveAnnouncement}\n </VisuallyHidden>\n <Box position=\"relative\">{children}</Box>\n <DragOverlay dropAnimation={null}>\n {activeItem ? <DragOverlayChip item={activeItem} /> : null}\n </DragOverlay>\n </DndContext>\n </AssetsDndContext.Provider>\n );\n};\n\n// TODO(CMS-229): FolderTree droppables + keyboard move path.\n"],"names":["AssetsDndContext","createContext","useAssetsDndOptional","useContext","getDragItems","activeData","AssetsDndProvider","children","formatMessage","useIntl","toggleNotification","useNotification","data","folderStructure","useGetFolderStructureQuery","bulkMove","isLoading","isMovePending","useBulkMoveMutation","activeItem","setActiveItem","useState","liveAnnouncement","setLiveAnnouncement","announceToLiveRegion","useCallback","message","requestAnimationFrame","sensors","useSensors","useSensor","PointerSensor","activationConstraint","distance","contextValue","useMemo","isInternalDragActive","handleDragStart","event","active","current","handleDragEnd","over","targetFolderId","parseFolderTargetId","id","items","canDropItemOnFolder","payload","buildBulkMovePayload","successMessage","getTranslationKey","defaultMessage","errorFallback","destinationFolderId","unwrap","type","error","errorMessage","getBulkMoveErrorMessage","handleDragCancel","announcements","onDragStart","name","onDragOver","onDragEnd","onDragCancel","_jsx","Provider","value","_jsxs","DndContext","collisionDetection","pointerWithin","accessibility","VisuallyHidden","aria-live","aria-atomic","Box","position","DragOverlay","dropAnimation","DragOverlayChip","item"],"mappings":"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"}
1
+ {"version":3,"file":"AssetsDndProvider.js","sources":["../../../../../../../admin/src/future/pages/Assets/components/Dnd/AssetsDndProvider.tsx"],"sourcesContent":["import {\n createContext,\n useCallback,\n useContext,\n useMemo,\n useRef,\n useState,\n type ReactNode,\n} from 'react';\n\nimport {\n DndContext,\n DragOverlay,\n PointerSensor,\n pointerWithin,\n useSensor,\n useSensors,\n type DragEndEvent,\n type DragStartEvent,\n} from '@dnd-kit/core';\nimport { useNotification } from '@strapi/admin/strapi-admin';\nimport { Box, VisuallyHidden } from '@strapi/design-system';\nimport { useIntl } from 'react-intl';\n\nimport { useMediaLibraryPermissions } from '../../../../hooks/useMediaLibraryPermissions';\nimport { useBulkMoveMutation, useGetFolderStructureQuery } from '../../../../services/folders';\nimport { buildBulkMovePayload } from '../../../../utils/buildBulkMovePayload';\nimport { canDropItemOnFolder } from '../../../../utils/canDropItemOnFolder';\nimport { formatMoveSuccessMessage } from '../../../../utils/formatMoveSuccessMessage';\nimport { getBulkMoveErrorMessage } from '../../../../utils/getBulkMoveErrorMessage';\nimport { getFolderLabel } from '../../../../utils/getFolderLabel';\nimport { getTranslationKey } from '../../../../utils/translations';\nimport { useAssetSelectionOptional } from '../../hooks/useAssetSelection';\nimport { useFolderNavigation } from '../../hooks/useFolderNavigation';\n\nimport { buildDragSet } from './buildDragSet';\nimport { computeValidDropTargets } from './computeValidDropTargets';\nimport { parseFolderTargetId, parseFolderTreeTargetId } from './dndIds';\nimport { DragOverlayChip } from './DragOverlayChip';\n\nimport type { DragItemData } from '../../../../types/dnd';\n\n/* -------------------------------------------------------------------------------------------------\n * Context — shared with UploadDropZoneProvider for bidirectional drag guard.\n * See UploadDropZoneContext.tsx TODO linking both providers.\n * -----------------------------------------------------------------------------------------------*/\n\ninterface AssetsDndContextValue {\n isInternalDragActive: boolean;\n isMovePending: boolean;\n /** O(1) lookup of whether the current drag set may drop on this destination. */\n isValidDropTarget: (targetFolderId: number | null) => boolean;\n}\n\nconst AssetsDndContext = createContext<AssetsDndContextValue | null>(null);\n\nexport const useAssetsDnd = () => {\n const context = useContext(AssetsDndContext);\n\n if (!context) {\n throw new Error('useAssetsDnd must be used within AssetsDndProvider');\n }\n\n return context;\n};\n\nexport const useAssetsDndOptional = () => useContext(AssetsDndContext);\n\n/* -------------------------------------------------------------------------------------------------\n * Provider\n * -----------------------------------------------------------------------------------------------*/\n\ninterface AssetsDndProviderProps {\n children: ReactNode;\n}\n\ninterface DragSession {\n items: DragItemData[];\n fromSelection: boolean;\n}\n\nconst resolveDestination = (\n overId: string | number\n): { destinationFolderId: number | null } | null => {\n const inView = parseFolderTargetId(overId);\n\n if (inView != null) {\n return { destinationFolderId: inView };\n }\n\n const tree = parseFolderTreeTargetId(overId);\n\n if (tree === 'root') {\n return { destinationFolderId: null };\n }\n\n if (typeof tree === 'number') {\n return { destinationFolderId: tree };\n }\n\n return null;\n};\n\n// Activation distance no real pointer gesture will ever reach — used to keep a\n// constant-length sensor array while disabling drag for users without the move\n// permission (see the note in the provider).\nconst DRAG_DISABLED_DISTANCE = Number.MAX_SAFE_INTEGER;\n\nexport const AssetsDndProvider = ({ children }: AssetsDndProviderProps) => {\n const { formatMessage } = useIntl();\n const { toggleNotification } = useNotification();\n const selection = useAssetSelectionOptional();\n const { currentFolderId } = useFolderNavigation();\n const { data: folderStructure = [] } = useGetFolderStructureQuery();\n const rootLabel = formatMessage({\n id: getTranslationKey('plugin.name'),\n defaultMessage: 'Media Library',\n });\n const [bulkMove, { isLoading: isMovePending }] = useBulkMoveMutation();\n const [dragItems, setDragItems] = useState<DragItemData[]>([]);\n const [liveAnnouncement, setLiveAnnouncement] = useState('');\n // Sync session for drag-end — state alone can lag one render behind dragStart.\n const dragSessionRef = useRef<DragSession>({ items: [], fromSelection: false });\n\n const announceToLiveRegion = useCallback((message: string) => {\n setLiveAnnouncement('');\n requestAnimationFrame(() => setLiveAnnouncement(message));\n }, []);\n\n // Moving is a mutation (bulk-move → `assets.update`); without the permission\n // pointer drag must never activate. Keyboard moves go through BulkMoveDialog,\n // which is itself gated.\n //\n // The gate has to keep BOTH the `useSensor`/`useSensors` calls AND the sensor\n // array's length constant across renders: `canUpdate` starts false and flips\n // true once the RBAC check resolves, and dnd-kit keys internal memos/effects\n // on the sensor list, erroring if its size changes (\"argument changed size\n // between renders\"). So adding/removing a sensor is out — instead keep one\n // PointerSensor always and push its activation distance out of reach when the\n // user can't move, which no real drag gesture will ever satisfy.\n const { canUpdate } = useMediaLibraryPermissions();\n const sensors = useSensors(\n useSensor(PointerSensor, {\n activationConstraint: { distance: canUpdate ? 8 : DRAG_DISABLED_DISTANCE },\n })\n );\n\n const validDropTargets = useMemo(\n () => computeValidDropTargets(dragItems, folderStructure),\n [dragItems, folderStructure]\n );\n\n const isValidDropTarget = useCallback(\n (targetFolderId: number | null) => validDropTargets.has(targetFolderId),\n [validDropTargets]\n );\n\n const contextValue = useMemo<AssetsDndContextValue>(\n () => ({\n isInternalDragActive: dragItems.length > 0,\n isMovePending,\n isValidDropTarget,\n }),\n [dragItems.length, isMovePending, isValidDropTarget]\n );\n\n const clearDragState = useCallback(() => {\n dragSessionRef.current = { items: [], fromSelection: false };\n setDragItems([]);\n }, []);\n\n const handleDragStart = useCallback(\n (event: DragStartEvent) => {\n const data = event.active.data.current as DragItemData | undefined;\n\n if (!data) {\n clearDragState();\n return;\n }\n\n const { items, fromSelection } = buildDragSet(data, selection?.selectedKeys, currentFolderId);\n dragSessionRef.current = { items, fromSelection };\n setDragItems(items);\n },\n [clearDragState, currentFolderId, selection?.selectedKeys]\n );\n\n const handleDragEnd = useCallback(\n async (event: DragEndEvent) => {\n const { over } = event;\n const { items, fromSelection } = dragSessionRef.current;\n clearDragState();\n\n if (isMovePending || !over || items.length === 0) {\n return;\n }\n\n const destination = resolveDestination(over.id);\n\n if (!destination) {\n return;\n }\n\n const { destinationFolderId: targetFolderId } = destination;\n\n if (\n !canDropItemOnFolder({\n items,\n targetFolderId,\n folderStructure,\n })\n ) {\n return;\n }\n\n const payload = buildBulkMovePayload(items);\n // Source is always the current folder — dragged items are, by definition,\n // visible in the current view. Destination is the drop target. Both use\n // leaf names so the DnD toast reads identically to the dialog's.\n const successMessage = formatMoveSuccessMessage({\n formatMessage,\n count: items.length,\n source: getFolderLabel(folderStructure, currentFolderId, rootLabel),\n destination: getFolderLabel(folderStructure, targetFolderId, rootLabel),\n });\n const errorFallback = formatMessage({\n id: getTranslationKey('list.bulk-actions.move.error'),\n defaultMessage: 'An error occurred while moving the items.',\n });\n\n try {\n await bulkMove({ ...payload, destinationFolderId: targetFolderId }).unwrap();\n\n if (fromSelection) {\n selection?.clear();\n }\n\n announceToLiveRegion(successMessage);\n\n toggleNotification({\n type: 'success',\n message: successMessage,\n });\n } catch (error) {\n const errorMessage = getBulkMoveErrorMessage(error, errorFallback);\n\n announceToLiveRegion(\n formatMessage(\n {\n id: getTranslationKey('dnd.announce.move-failure'),\n defaultMessage: 'Move failed. {message}',\n },\n { message: errorMessage }\n )\n );\n\n toggleNotification({\n type: 'danger',\n message: errorMessage,\n });\n }\n },\n [\n announceToLiveRegion,\n bulkMove,\n clearDragState,\n currentFolderId,\n folderStructure,\n formatMessage,\n isMovePending,\n rootLabel,\n selection,\n toggleNotification,\n ]\n );\n\n const handleDragCancel = useCallback(() => {\n clearDragState();\n }, [clearDragState]);\n\n const announcements = useMemo(\n () => ({\n onDragStart: ({ active }: DragStartEvent) => {\n const data = active.data.current as DragItemData | undefined;\n return data\n ? formatMessage(\n {\n id: getTranslationKey('dnd.announce.drag-start'),\n defaultMessage: 'Picked up {name}. Drop on a folder to move.',\n },\n { name: data.name }\n )\n : '';\n },\n onDragOver: () => '',\n onDragEnd: ({ active, over }: DragEndEvent) => {\n if (!over) {\n return formatMessage({\n id: getTranslationKey('dnd.announce.cancel'),\n defaultMessage: 'Drag cancelled.',\n });\n }\n\n const destination = resolveDestination(over.id);\n const activeData = active.data.current as DragItemData | undefined;\n\n if (!destination || !activeData) {\n return '';\n }\n\n const { items } = buildDragSet(activeData, selection?.selectedKeys, currentFolderId);\n\n if (\n !canDropItemOnFolder({\n items,\n targetFolderId: destination.destinationFolderId,\n folderStructure,\n })\n ) {\n return formatMessage({\n id: getTranslationKey('dnd.announce.invalid-drop'),\n defaultMessage: 'Cannot move item to this folder.',\n });\n }\n\n return '';\n },\n onDragCancel: () =>\n formatMessage({\n id: getTranslationKey('dnd.announce.cancel'),\n defaultMessage: 'Drag cancelled.',\n }),\n }),\n [currentFolderId, folderStructure, formatMessage, selection?.selectedKeys]\n );\n\n return (\n <AssetsDndContext.Provider value={contextValue}>\n <DndContext\n sensors={sensors}\n collisionDetection={pointerWithin}\n onDragStart={handleDragStart}\n onDragEnd={handleDragEnd}\n onDragCancel={handleDragCancel}\n accessibility={{ announcements }}\n >\n <VisuallyHidden aria-live=\"polite\" aria-atomic=\"true\">\n {liveAnnouncement}\n </VisuallyHidden>\n <Box position=\"relative\">{children}</Box>\n <DragOverlay dropAnimation={null}>\n {dragItems.length > 0 ? <DragOverlayChip items={dragItems} /> : null}\n </DragOverlay>\n </DndContext>\n </AssetsDndContext.Provider>\n );\n};\n\n// Keyboard-accessible moves are handled by `BulkMoveDialog` (reachable from the\n// bulk-actions bar): pointer drag is a mouse-only enhancement, the dialog is the\n// a11y path. No `KeyboardSensor` by design.\n"],"names":["AssetsDndContext","createContext","useAssetsDndOptional","useContext","resolveDestination","overId","inView","parseFolderTargetId","destinationFolderId","tree","parseFolderTreeTargetId","DRAG_DISABLED_DISTANCE","Number","MAX_SAFE_INTEGER","AssetsDndProvider","children","formatMessage","useIntl","toggleNotification","useNotification","selection","useAssetSelectionOptional","currentFolderId","useFolderNavigation","data","folderStructure","useGetFolderStructureQuery","rootLabel","id","getTranslationKey","defaultMessage","bulkMove","isLoading","isMovePending","useBulkMoveMutation","dragItems","setDragItems","useState","liveAnnouncement","setLiveAnnouncement","dragSessionRef","useRef","items","fromSelection","announceToLiveRegion","useCallback","message","requestAnimationFrame","canUpdate","useMediaLibraryPermissions","sensors","useSensors","useSensor","PointerSensor","activationConstraint","distance","validDropTargets","useMemo","computeValidDropTargets","isValidDropTarget","targetFolderId","has","contextValue","isInternalDragActive","length","clearDragState","current","handleDragStart","event","active","buildDragSet","selectedKeys","handleDragEnd","over","destination","canDropItemOnFolder","payload","buildBulkMovePayload","successMessage","formatMoveSuccessMessage","count","source","getFolderLabel","errorFallback","unwrap","clear","type","error","errorMessage","getBulkMoveErrorMessage","handleDragCancel","announcements","onDragStart","name","onDragOver","onDragEnd","activeData","onDragCancel","_jsx","Provider","value","_jsxs","DndContext","collisionDetection","pointerWithin","accessibility","VisuallyHidden","aria-live","aria-atomic","Box","position","DragOverlay","dropAnimation","DragOverlayChip"],"mappings":"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"}