@strapi/upload 5.59.0 → 5.60.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 (231) hide show
  1. package/dist/admin/components/AssetPickerDialog/AssetPickerDialog.js +434 -0
  2. package/dist/admin/components/AssetPickerDialog/AssetPickerDialog.js.map +1 -0
  3. package/dist/admin/components/AssetPickerDialog/AssetPickerDialog.mjs +432 -0
  4. package/dist/admin/components/AssetPickerDialog/AssetPickerDialog.mjs.map +1 -0
  5. package/dist/admin/components/AssetPickerDialog/FolderBreadcrumbs.js +91 -0
  6. package/dist/admin/components/AssetPickerDialog/FolderBreadcrumbs.js.map +1 -0
  7. package/dist/admin/components/AssetPickerDialog/FolderBreadcrumbs.mjs +89 -0
  8. package/dist/admin/components/AssetPickerDialog/FolderBreadcrumbs.mjs.map +1 -0
  9. package/dist/admin/components/AssetPickerDialog/PickerSelectionProvider.js +178 -0
  10. package/dist/admin/components/AssetPickerDialog/PickerSelectionProvider.js.map +1 -0
  11. package/dist/admin/components/AssetPickerDialog/PickerSelectionProvider.mjs +175 -0
  12. package/dist/admin/components/AssetPickerDialog/PickerSelectionProvider.mjs.map +1 -0
  13. package/dist/admin/components/AssetPickerDialog/SortableSelection.js +143 -0
  14. package/dist/admin/components/AssetPickerDialog/SortableSelection.js.map +1 -0
  15. package/dist/admin/components/AssetPickerDialog/SortableSelection.mjs +141 -0
  16. package/dist/admin/components/AssetPickerDialog/SortableSelection.mjs.map +1 -0
  17. package/dist/admin/components/AssetPickerDialog/pickerSelection.js +49 -0
  18. package/dist/admin/components/AssetPickerDialog/pickerSelection.js.map +1 -0
  19. package/dist/admin/components/AssetPickerDialog/pickerSelection.mjs +41 -0
  20. package/dist/admin/components/AssetPickerDialog/pickerSelection.mjs.map +1 -0
  21. package/dist/admin/components/MediaLibraryInput/AddAssetMenu.js +4 -3
  22. package/dist/admin/components/MediaLibraryInput/AddAssetMenu.js.map +1 -1
  23. package/dist/admin/components/MediaLibraryInput/AddAssetMenu.mjs +4 -3
  24. package/dist/admin/components/MediaLibraryInput/AddAssetMenu.mjs.map +1 -1
  25. package/dist/admin/components/MediaLibraryInput/AssetCard.js +240 -0
  26. package/dist/admin/components/MediaLibraryInput/AssetCard.js.map +1 -0
  27. package/dist/admin/components/MediaLibraryInput/AssetCard.mjs +237 -0
  28. package/dist/admin/components/MediaLibraryInput/AssetCard.mjs.map +1 -0
  29. package/dist/admin/components/MediaLibraryInput/AssetCarousel.js +161 -0
  30. package/dist/admin/components/MediaLibraryInput/AssetCarousel.js.map +1 -0
  31. package/dist/admin/components/MediaLibraryInput/AssetCarousel.mjs +159 -0
  32. package/dist/admin/components/MediaLibraryInput/AssetCarousel.mjs.map +1 -0
  33. package/dist/admin/components/MediaLibraryInput/AssetDropZone.js +76 -49
  34. package/dist/admin/components/MediaLibraryInput/AssetDropZone.js.map +1 -1
  35. package/dist/admin/components/MediaLibraryInput/AssetDropZone.mjs +77 -50
  36. package/dist/admin/components/MediaLibraryInput/AssetDropZone.mjs.map +1 -1
  37. package/dist/admin/components/MediaLibraryInput/AssetPreview.js +109 -0
  38. package/dist/admin/components/MediaLibraryInput/AssetPreview.js.map +1 -0
  39. package/dist/admin/components/MediaLibraryInput/AssetPreview.mjs +106 -0
  40. package/dist/admin/components/MediaLibraryInput/AssetPreview.mjs.map +1 -0
  41. package/dist/admin/components/MediaLibraryInput/AssetRow.js +146 -79
  42. package/dist/admin/components/MediaLibraryInput/AssetRow.js.map +1 -1
  43. package/dist/admin/components/MediaLibraryInput/AssetRow.mjs +148 -82
  44. package/dist/admin/components/MediaLibraryInput/AssetRow.mjs.map +1 -1
  45. package/dist/admin/components/MediaLibraryInput/FieldControls.js +32 -0
  46. package/dist/admin/components/MediaLibraryInput/FieldControls.js.map +1 -0
  47. package/dist/admin/components/MediaLibraryInput/FieldControls.mjs +29 -0
  48. package/dist/admin/components/MediaLibraryInput/FieldControls.mjs.map +1 -0
  49. package/dist/admin/components/MediaLibraryInput/MediaLibraryInput.js +130 -88
  50. package/dist/admin/components/MediaLibraryInput/MediaLibraryInput.js.map +1 -1
  51. package/dist/admin/components/MediaLibraryInput/MediaLibraryInput.mjs +129 -91
  52. package/dist/admin/components/MediaLibraryInput/MediaLibraryInput.mjs.map +1 -1
  53. package/dist/admin/components/MediaLibraryInput/UploadProgressBar.js +42 -0
  54. package/dist/admin/components/MediaLibraryInput/UploadProgressBar.js.map +1 -0
  55. package/dist/admin/components/MediaLibraryInput/UploadProgressBar.mjs +40 -0
  56. package/dist/admin/components/MediaLibraryInput/UploadProgressBar.mjs.map +1 -0
  57. package/dist/admin/components/MediaLibraryInput/useFieldUploads.js +122 -0
  58. package/dist/admin/components/MediaLibraryInput/useFieldUploads.js.map +1 -0
  59. package/dist/admin/components/MediaLibraryInput/useFieldUploads.mjs +120 -0
  60. package/dist/admin/components/MediaLibraryInput/useFieldUploads.mjs.map +1 -0
  61. package/dist/admin/components/UploadProgressDialog.js +2 -1
  62. package/dist/admin/components/UploadProgressDialog.js.map +1 -1
  63. package/dist/admin/components/UploadProgressDialog.mjs +2 -1
  64. package/dist/admin/components/UploadProgressDialog.mjs.map +1 -1
  65. package/dist/admin/hooks/useMediaLibraryPermissions.js +12 -2
  66. package/dist/admin/hooks/useMediaLibraryPermissions.js.map +1 -1
  67. package/dist/admin/hooks/useMediaLibraryPermissions.mjs +12 -2
  68. package/dist/admin/hooks/useMediaLibraryPermissions.mjs.map +1 -1
  69. package/dist/admin/pages/Assets/AssetsPage.js +13 -302
  70. package/dist/admin/pages/Assets/AssetsPage.js.map +1 -1
  71. package/dist/admin/pages/Assets/AssetsPage.mjs +11 -280
  72. package/dist/admin/pages/Assets/AssetsPage.mjs.map +1 -1
  73. package/dist/admin/pages/Assets/components/AssetsGrid.js +142 -31
  74. package/dist/admin/pages/Assets/components/AssetsGrid.js.map +1 -1
  75. package/dist/admin/pages/Assets/components/AssetsGrid.mjs +145 -34
  76. package/dist/admin/pages/Assets/components/AssetsGrid.mjs.map +1 -1
  77. package/dist/admin/pages/Assets/components/AssetsSearchInput.js +43 -2
  78. package/dist/admin/pages/Assets/components/AssetsSearchInput.js.map +1 -1
  79. package/dist/admin/pages/Assets/components/AssetsSearchInput.mjs +45 -4
  80. package/dist/admin/pages/Assets/components/AssetsSearchInput.mjs.map +1 -1
  81. package/dist/admin/pages/Assets/components/AssetsTable.js +58 -34
  82. package/dist/admin/pages/Assets/components/AssetsTable.js.map +1 -1
  83. package/dist/admin/pages/Assets/components/AssetsTable.mjs +60 -36
  84. package/dist/admin/pages/Assets/components/AssetsTable.mjs.map +1 -1
  85. package/dist/admin/pages/Assets/components/AssetsView.js +145 -0
  86. package/dist/admin/pages/Assets/components/AssetsView.js.map +1 -0
  87. package/dist/admin/pages/Assets/components/AssetsView.mjs +143 -0
  88. package/dist/admin/pages/Assets/components/AssetsView.mjs.map +1 -0
  89. package/dist/admin/pages/Assets/components/BulkActionsBar.mjs +1 -1
  90. package/dist/admin/pages/Assets/components/BusyOverlay.mjs +1 -1
  91. package/dist/admin/pages/Assets/components/Dnd/DragOverlayChip.mjs +1 -1
  92. package/dist/admin/pages/Assets/components/Dnd/ReorderHandle.js +40 -0
  93. package/dist/admin/pages/Assets/components/Dnd/ReorderHandle.js.map +1 -0
  94. package/dist/admin/pages/Assets/components/Dnd/ReorderHandle.mjs +38 -0
  95. package/dist/admin/pages/Assets/components/Dnd/ReorderHandle.mjs.map +1 -0
  96. package/dist/admin/pages/Assets/components/Dnd/assetSortable.js +29 -0
  97. package/dist/admin/pages/Assets/components/Dnd/assetSortable.js.map +1 -0
  98. package/dist/admin/pages/Assets/components/Dnd/assetSortable.mjs +24 -0
  99. package/dist/admin/pages/Assets/components/Dnd/assetSortable.mjs.map +1 -0
  100. package/dist/admin/pages/Assets/components/Dnd/dndIds.js +5 -0
  101. package/dist/admin/pages/Assets/components/Dnd/dndIds.js.map +1 -1
  102. package/dist/admin/pages/Assets/components/Dnd/dndIds.mjs +5 -1
  103. package/dist/admin/pages/Assets/components/Dnd/dndIds.mjs.map +1 -1
  104. package/dist/admin/pages/Assets/components/Dnd/useAssetDnd.js +41 -13
  105. package/dist/admin/pages/Assets/components/Dnd/useAssetDnd.js.map +1 -1
  106. package/dist/admin/pages/Assets/components/Dnd/useAssetDnd.mjs +41 -13
  107. package/dist/admin/pages/Assets/components/Dnd/useAssetDnd.mjs.map +1 -1
  108. package/dist/admin/pages/Assets/components/FilterBadges.mjs +2 -2
  109. package/dist/admin/pages/Assets/components/FilterMenu.mjs +2 -2
  110. package/dist/admin/pages/Assets/components/FolderTree/FolderTree.js +274 -55
  111. package/dist/admin/pages/Assets/components/FolderTree/FolderTree.js.map +1 -1
  112. package/dist/admin/pages/Assets/components/FolderTree/FolderTree.mjs +277 -59
  113. package/dist/admin/pages/Assets/components/FolderTree/FolderTree.mjs.map +1 -1
  114. package/dist/admin/pages/Assets/components/FolderTree/collapsedBranch.js +32 -0
  115. package/dist/admin/pages/Assets/components/FolderTree/collapsedBranch.js.map +1 -0
  116. package/dist/admin/pages/Assets/components/FolderTree/collapsedBranch.mjs +29 -0
  117. package/dist/admin/pages/Assets/components/FolderTree/collapsedBranch.mjs.map +1 -0
  118. package/dist/admin/pages/Assets/components/ViewToggle.js +126 -0
  119. package/dist/admin/pages/Assets/components/ViewToggle.js.map +1 -0
  120. package/dist/admin/pages/Assets/components/ViewToggle.mjs +104 -0
  121. package/dist/admin/pages/Assets/components/ViewToggle.mjs.map +1 -0
  122. package/dist/admin/pages/Assets/hooks/useAssetSearch.js +2 -2
  123. package/dist/admin/pages/Assets/hooks/useAssetSearch.js.map +1 -1
  124. package/dist/admin/pages/Assets/hooks/useAssetSearch.mjs +2 -2
  125. package/dist/admin/pages/Assets/hooks/useAssetSearch.mjs.map +1 -1
  126. package/dist/admin/pages/Assets/hooks/useAssetSelection.js +19 -1
  127. package/dist/admin/pages/Assets/hooks/useAssetSelection.js.map +1 -1
  128. package/dist/admin/pages/Assets/hooks/useAssetSelection.mjs +20 -3
  129. package/dist/admin/pages/Assets/hooks/useAssetSelection.mjs.map +1 -1
  130. package/dist/admin/pages/Assets/hooks/useAssetsList.js +87 -0
  131. package/dist/admin/pages/Assets/hooks/useAssetsList.js.map +1 -0
  132. package/dist/admin/pages/Assets/hooks/useAssetsList.mjs +85 -0
  133. package/dist/admin/pages/Assets/hooks/useAssetsList.mjs.map +1 -0
  134. package/dist/admin/pages/Assets/hooks/useBusyAssets.mjs +1 -1
  135. package/dist/admin/pages/Assets/hooks/useFolderNavigation.js +2 -1
  136. package/dist/admin/pages/Assets/hooks/useFolderNavigation.js.map +1 -1
  137. package/dist/admin/pages/Assets/hooks/useFolderNavigation.mjs +3 -2
  138. package/dist/admin/pages/Assets/hooks/useFolderNavigation.mjs.map +1 -1
  139. package/dist/admin/pages/Assets/hooks/useListFilters.js +2 -1
  140. package/dist/admin/pages/Assets/hooks/useListFilters.js.map +1 -1
  141. package/dist/admin/pages/Assets/hooks/useListFilters.mjs +3 -2
  142. package/dist/admin/pages/Assets/hooks/useListFilters.mjs.map +1 -1
  143. package/dist/admin/pages/Assets/hooks/useListQueryParams.js +80 -0
  144. package/dist/admin/pages/Assets/hooks/useListQueryParams.js.map +1 -0
  145. package/dist/admin/pages/Assets/hooks/useListQueryParams.mjs +77 -0
  146. package/dist/admin/pages/Assets/hooks/useListQueryParams.mjs.map +1 -0
  147. package/dist/admin/pages/Assets/hooks/useListSettings.js +32 -0
  148. package/dist/admin/pages/Assets/hooks/useListSettings.js.map +1 -0
  149. package/dist/admin/pages/Assets/hooks/useListSettings.mjs +29 -0
  150. package/dist/admin/pages/Assets/hooks/useListSettings.mjs.map +1 -0
  151. package/dist/admin/pages/Assets/hooks/useListSort.js +2 -1
  152. package/dist/admin/pages/Assets/hooks/useListSort.js.map +1 -1
  153. package/dist/admin/pages/Assets/hooks/useListSort.mjs +3 -2
  154. package/dist/admin/pages/Assets/hooks/useListSort.mjs.map +1 -1
  155. package/dist/admin/services/api.js +92 -7
  156. package/dist/admin/services/api.js.map +1 -1
  157. package/dist/admin/services/api.mjs +91 -9
  158. package/dist/admin/services/api.mjs.map +1 -1
  159. package/dist/admin/src/components/AssetPickerDialog/AssetPickerDialog.d.ts +19 -0
  160. package/dist/admin/src/components/AssetPickerDialog/FolderBreadcrumbs.d.ts +10 -0
  161. package/dist/admin/src/components/AssetPickerDialog/PickerSelectionProvider.d.ts +28 -0
  162. package/dist/admin/src/components/AssetPickerDialog/SortableSelection.d.ts +12 -0
  163. package/dist/admin/src/components/AssetPickerDialog/pickerSelection.d.ts +26 -0
  164. package/dist/admin/src/components/MediaLibraryInput/AssetCard.d.ts +25 -0
  165. package/dist/admin/src/components/MediaLibraryInput/AssetCarousel.d.ts +16 -0
  166. package/dist/admin/src/components/MediaLibraryInput/AssetDropZone.d.ts +11 -3
  167. package/dist/admin/src/components/MediaLibraryInput/AssetPreview.d.ts +17 -0
  168. package/dist/admin/src/components/MediaLibraryInput/AssetRow.d.ts +13 -3
  169. package/dist/admin/src/components/MediaLibraryInput/FieldControls.d.ts +19 -0
  170. package/dist/admin/src/components/MediaLibraryInput/MediaLibraryInput.d.ts +3 -1
  171. package/dist/admin/src/components/MediaLibraryInput/UploadProgressBar.d.ts +7 -0
  172. package/dist/admin/src/components/MediaLibraryInput/useFieldUploads.d.ts +31 -0
  173. package/dist/admin/src/hooks/useMediaLibraryPermissions.d.ts +2 -0
  174. package/dist/admin/src/pages/Assets/components/AssetsGrid.d.ts +3 -1
  175. package/dist/admin/src/pages/Assets/components/AssetsSearchInput.d.ts +11 -1
  176. package/dist/admin/src/pages/Assets/components/AssetsView.d.ts +29 -0
  177. package/dist/admin/src/pages/Assets/components/Dnd/ReorderHandle.d.ts +12 -0
  178. package/dist/admin/src/pages/Assets/components/Dnd/assetSortable.d.ts +37 -0
  179. package/dist/admin/src/pages/Assets/components/Dnd/dndIds.d.ts +5 -0
  180. package/dist/admin/src/pages/Assets/components/Dnd/useAssetDnd.d.ts +23 -2
  181. package/dist/admin/src/pages/Assets/components/FolderTree/FolderTree.d.ts +1 -0
  182. package/dist/admin/src/pages/Assets/components/FolderTree/collapsedBranch.d.ts +21 -0
  183. package/dist/admin/src/pages/Assets/components/ViewToggle.d.ts +8 -0
  184. package/dist/admin/src/pages/Assets/hooks/useAssetSelection.d.ts +26 -0
  185. package/dist/admin/src/pages/Assets/hooks/useAssetsList.d.ts +30 -0
  186. package/dist/admin/src/pages/Assets/hooks/useListQueryParams.d.ts +27 -0
  187. package/dist/admin/src/pages/Assets/hooks/useListSettings.d.ts +29 -0
  188. package/dist/admin/src/services/api.d.ts +24 -1
  189. package/dist/admin/src/store/uploadProgress.d.ts +14 -1
  190. package/dist/admin/src/utils/findFolderPath.d.ts +6 -0
  191. package/dist/admin/src/utils/isAllowedAssetType.d.ts +14 -0
  192. package/dist/admin/store/uploadProgress.js +30 -3
  193. package/dist/admin/store/uploadProgress.js.map +1 -1
  194. package/dist/admin/store/uploadProgress.mjs +29 -4
  195. package/dist/admin/store/uploadProgress.mjs.map +1 -1
  196. package/dist/admin/translations/en.json.js +20 -0
  197. package/dist/admin/translations/en.json.js.map +1 -1
  198. package/dist/admin/translations/en.json.mjs +20 -0
  199. package/dist/admin/translations/en.json.mjs.map +1 -1
  200. package/dist/admin/utils/findFolderPath.js +26 -0
  201. package/dist/admin/utils/findFolderPath.js.map +1 -0
  202. package/dist/admin/utils/findFolderPath.mjs +24 -0
  203. package/dist/admin/utils/findFolderPath.mjs.map +1 -0
  204. package/dist/admin/utils/isAllowedAssetType.js +33 -0
  205. package/dist/admin/utils/isAllowedAssetType.js.map +1 -0
  206. package/dist/admin/utils/isAllowedAssetType.mjs +31 -0
  207. package/dist/admin/utils/isAllowedAssetType.mjs.map +1 -0
  208. package/dist/server/controllers/admin-settings.js +5 -1
  209. package/dist/server/controllers/admin-settings.js.map +1 -1
  210. package/dist/server/controllers/admin-settings.mjs +5 -1
  211. package/dist/server/controllers/admin-settings.mjs.map +1 -1
  212. package/dist/server/services/image-manipulation.js +2 -2
  213. package/dist/server/services/image-manipulation.js.map +1 -1
  214. package/dist/server/services/image-manipulation.mjs +2 -2
  215. package/dist/server/services/image-manipulation.mjs.map +1 -1
  216. package/dist/server/services/upload.js.map +1 -1
  217. package/dist/server/services/upload.mjs.map +1 -1
  218. package/dist/server/src/controllers/admin-settings.d.ts.map +1 -1
  219. package/dist/server/src/index.d.ts +1 -1
  220. package/dist/server/src/services/extensions/utils.d.ts +11 -11
  221. package/dist/server/src/services/image-manipulation.d.ts +1 -1
  222. package/dist/server/src/services/image-manipulation.d.ts.map +1 -1
  223. package/dist/server/src/services/index.d.ts +1 -1
  224. package/dist/server/src/types.d.ts +63 -12
  225. package/dist/server/src/types.d.ts.map +1 -1
  226. package/package.json +8 -6
  227. package/dist/admin/components/MediaLibraryInput/NoLibraryAccessDialog.js +0 -45
  228. package/dist/admin/components/MediaLibraryInput/NoLibraryAccessDialog.js.map +0 -1
  229. package/dist/admin/components/MediaLibraryInput/NoLibraryAccessDialog.mjs +0 -43
  230. package/dist/admin/components/MediaLibraryInput/NoLibraryAccessDialog.mjs.map +0 -1
  231. package/dist/admin/src/components/MediaLibraryInput/NoLibraryAccessDialog.d.ts +0 -10
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AssetsView.js","sources":["../../../../../admin/src/pages/Assets/components/AssetsView.tsx"],"sourcesContent":["import { useMemo } from 'react';\n\nimport { Box, Flex, Loader, Typography } from '@strapi/design-system';\nimport { useIntl } from 'react-intl';\n\nimport { type ItemLocations } from '../../../utils/itemLocations';\nimport { getTranslationKey } from '../../../utils/translations';\nimport { viewOptions } from '../constants';\nimport { useInfiniteScrollSentinel } from '../hooks/useInfiniteScrollSentinel';\nimport { useListSettings } from '../hooks/useListSettings';\nimport { type FoldersPosition } from '../hooks/useListSort';\nimport { mergeMixedList } from '../utils/mergeMixedList';\nimport { buildRenderedKeys } from '../utils/renderedKeys';\n\nimport { AssetsGrid } from './AssetsGrid';\nimport { AssetsTable } from './AssetsTable';\nimport { BulkActionsBar } from './BulkActionsBar';\nimport { EmptyState, FilteredEmptyState } from './EmptyState';\nimport { ItemContextMenuProvider } from './ItemContextMenu';\n\nimport type { File } from '../../../../../shared/contracts/files';\nimport type { Folder } from '../../../../../shared/contracts/folders';\n\n// The negative bottom margin shrinks the trigger area by a pixel so the 1px\n// sentinel sitting exactly at the fold (when a page's rows happen to fill the\n// viewport) reads as \"not visible\" and doesn't pull an extra page. It still\n// triggers as soon as the sentinel scrolls a hair into view. Tune the bottom\n// value if the list over- or under-fetches near the fold.\nconst INTERSECTION_OPTIONS: IntersectionObserverInit = {\n threshold: 0,\n rootMargin: '0px 0px -1px 0px',\n};\n\n/* -------------------------------------------------------------------------------------------------\n * AssetsView\n * -----------------------------------------------------------------------------------------------*/\n\ninterface AssetsViewProps {\n view: number;\n folders: Folder[];\n isLoadingFolders: boolean;\n assets: File[];\n /** Total matching assets on the server, beyond the pages loaded so far. */\n assetsTotal?: number;\n isLoadingAssets: boolean;\n isFetchingMore: boolean;\n hasNextPage: boolean;\n fetchNextPage: () => void;\n error: unknown;\n locations: ItemLocations;\n searchQuery: string;\n assetsSort: string;\n foldersPosition: FoldersPosition;\n hasActiveFilters: boolean;\n onClearFilters: () => void;\n onAssetItemClick: (assetId: number) => void;\n onAddAssets: () => void;\n canAddAssets: boolean;\n onClearSearch: () => void;\n}\n\nexport const AssetsView = ({\n view,\n folders,\n isLoadingFolders,\n assets,\n assetsTotal,\n isLoadingAssets,\n isFetchingMore,\n hasNextPage,\n fetchNextPage,\n error,\n locations,\n searchQuery,\n assetsSort,\n foldersPosition,\n hasActiveFilters,\n onClearFilters,\n onAssetItemClick,\n onAddAssets,\n canAddAssets,\n onClearSearch,\n}: AssetsViewProps) => {\n const { formatMessage } = useIntl();\n const { showItemActions } = useListSettings();\n\n const isGridView = view === viewOptions.GRID;\n const isLoading = isLoadingAssets || isLoadingFolders;\n\n // \"Folders: Mixed with files\" — interleave the complete folder list into the\n // loaded asset stream client-side, following the active sort. Table view\n // only: the grid always keeps folders in their own band on top.\n const mixedItems = useMemo(\n () =>\n foldersPosition === 'mixed' && !isGridView\n ? mergeMixedList({ folders, assets, sort: assetsSort, hasNextPage })\n : null,\n [foldersPosition, isGridView, folders, assets, assetsSort, hasNextPage]\n );\n\n // Derived once here so the table, the grid and the bulk bar all agree on what\n // is on screen — in mixed mode that is not simply every folder.\n const renderedKeys = buildRenderedKeys({ folders, assets, mixedItems });\n\n const loadMoreRef = useInfiniteScrollSentinel({\n hasNextPage,\n isFetchingMore,\n onLoadMore: fetchNextPage,\n options: INTERSECTION_OPTIONS,\n });\n\n const list = isGridView ? (\n <AssetsGrid\n folders={folders}\n assets={assets}\n assetsTotal={assetsTotal}\n renderedKeys={renderedKeys}\n onAssetItemClick={onAssetItemClick}\n />\n ) : (\n <AssetsTable\n assets={assets}\n folders={folders}\n mixedItems={mixedItems}\n renderedKeys={renderedKeys}\n onAssetItemClick={onAssetItemClick}\n />\n );\n\n if (isLoading) {\n return (\n <Flex justifyContent=\"center\" padding={8}>\n <Loader>{formatMessage({ id: 'app.loading', defaultMessage: 'Loading...' })}</Loader>\n </Flex>\n );\n }\n\n if (error) {\n return (\n <Box padding={8}>\n <Typography textColor=\"danger600\">\n {formatMessage({\n id: getTranslationKey('list.assets.error'),\n defaultMessage: 'An error occurred while fetching assets.',\n })}\n </Typography>\n </Box>\n );\n }\n\n if (folders.length === 0 && assets.length === 0) {\n // While searching, the search empty state wins (it names the query); a\n // filter-only dead end gets the filtered variant with its Clear action.\n return hasActiveFilters && !searchQuery ? (\n <FilteredEmptyState onClearFilters={onClearFilters} />\n ) : (\n <EmptyState\n onAddAssets={onAddAssets}\n canAddAssets={canAddAssets}\n searchQuery={searchQuery}\n onClearSearch={onClearSearch}\n />\n );\n }\n return (\n <>\n {showItemActions ? (\n // Above both views so one instance serves either, and so the selection\n // menu has the `locations` its move dialog validates against.\n <ItemContextMenuProvider locations={locations}>{list}</ItemContextMenuProvider>\n ) : (\n list\n )}\n <div ref={loadMoreRef} style={{ height: 1 }} />\n {isFetchingMore && (\n <Flex justifyContent=\"center\" padding={4}>\n <Loader>\n {formatMessage({\n id: getTranslationKey('list.assets.loading-more'),\n defaultMessage: 'Loading more assets...',\n })}\n </Loader>\n </Flex>\n )}\n {/* Lives here rather than in `AssetsPage` so it can read the loaded\n assets: the AI metadata action needs their mime types to know what\n the provider can handle. `position: fixed` keeps it visually anchored\n regardless of where it sits in the tree. */}\n {showItemActions && (\n <BulkActionsBar assets={assets} renderedKeys={renderedKeys} locations={locations} />\n )}\n </>\n );\n};\n"],"names":["INTERSECTION_OPTIONS","threshold","rootMargin","AssetsView","view","folders","isLoadingFolders","assets","assetsTotal","isLoadingAssets","isFetchingMore","hasNextPage","fetchNextPage","error","locations","searchQuery","assetsSort","foldersPosition","hasActiveFilters","onClearFilters","onAssetItemClick","onAddAssets","canAddAssets","onClearSearch","formatMessage","useIntl","showItemActions","useListSettings","isGridView","viewOptions","GRID","isLoading","mixedItems","useMemo","mergeMixedList","sort","renderedKeys","buildRenderedKeys","loadMoreRef","useInfiniteScrollSentinel","onLoadMore","options","list","_jsx","AssetsGrid","AssetsTable","Flex","justifyContent","padding","Loader","id","defaultMessage","Box","Typography","textColor","getTranslationKey","length","FilteredEmptyState","EmptyState","_jsxs","_Fragment","ItemContextMenuProvider","div","ref","style","height","BulkActionsBar"],"mappings":"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"}
@@ -0,0 +1,143 @@
1
+ import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
2
+ import { useMemo } from 'react';
3
+ import { Flex, Loader, Box, Typography } from '@strapi/design-system';
4
+ import { useIntl } from 'react-intl';
5
+ import { getTranslationKey } from '../../../utils/translations.mjs';
6
+ import { viewOptions } from '../constants.mjs';
7
+ import { useInfiniteScrollSentinel } from '../hooks/useInfiniteScrollSentinel.mjs';
8
+ import { useListSettings } from '../hooks/useListSettings.mjs';
9
+ import { mergeMixedList } from '../utils/mergeMixedList.mjs';
10
+ import { buildRenderedKeys } from '../utils/renderedKeys.mjs';
11
+ import { AssetsGrid } from './AssetsGrid.mjs';
12
+ import { AssetsTable } from './AssetsTable.mjs';
13
+ import { BulkActionsBar } from './BulkActionsBar.mjs';
14
+ import { FilteredEmptyState, EmptyState } from './EmptyState.mjs';
15
+ import { ItemContextMenuProvider } from './ItemContextMenu.mjs';
16
+
17
+ // The negative bottom margin shrinks the trigger area by a pixel so the 1px
18
+ // sentinel sitting exactly at the fold (when a page's rows happen to fill the
19
+ // viewport) reads as "not visible" and doesn't pull an extra page. It still
20
+ // triggers as soon as the sentinel scrolls a hair into view. Tune the bottom
21
+ // value if the list over- or under-fetches near the fold.
22
+ const INTERSECTION_OPTIONS = {
23
+ threshold: 0,
24
+ rootMargin: '0px 0px -1px 0px'
25
+ };
26
+ const AssetsView = ({ view, folders, isLoadingFolders, assets, assetsTotal, isLoadingAssets, isFetchingMore, hasNextPage, fetchNextPage, error, locations, searchQuery, assetsSort, foldersPosition, hasActiveFilters, onClearFilters, onAssetItemClick, onAddAssets, canAddAssets, onClearSearch })=>{
27
+ const { formatMessage } = useIntl();
28
+ const { showItemActions } = useListSettings();
29
+ const isGridView = view === viewOptions.GRID;
30
+ const isLoading = isLoadingAssets || isLoadingFolders;
31
+ // "Folders: Mixed with files" — interleave the complete folder list into the
32
+ // loaded asset stream client-side, following the active sort. Table view
33
+ // only: the grid always keeps folders in their own band on top.
34
+ const mixedItems = useMemo(()=>foldersPosition === 'mixed' && !isGridView ? mergeMixedList({
35
+ folders,
36
+ assets,
37
+ sort: assetsSort,
38
+ hasNextPage
39
+ }) : null, [
40
+ foldersPosition,
41
+ isGridView,
42
+ folders,
43
+ assets,
44
+ assetsSort,
45
+ hasNextPage
46
+ ]);
47
+ // Derived once here so the table, the grid and the bulk bar all agree on what
48
+ // is on screen — in mixed mode that is not simply every folder.
49
+ const renderedKeys = buildRenderedKeys({
50
+ folders,
51
+ assets,
52
+ mixedItems
53
+ });
54
+ const loadMoreRef = useInfiniteScrollSentinel({
55
+ hasNextPage,
56
+ isFetchingMore,
57
+ onLoadMore: fetchNextPage,
58
+ options: INTERSECTION_OPTIONS
59
+ });
60
+ const list = isGridView ? /*#__PURE__*/ jsx(AssetsGrid, {
61
+ folders: folders,
62
+ assets: assets,
63
+ assetsTotal: assetsTotal,
64
+ renderedKeys: renderedKeys,
65
+ onAssetItemClick: onAssetItemClick
66
+ }) : /*#__PURE__*/ jsx(AssetsTable, {
67
+ assets: assets,
68
+ folders: folders,
69
+ mixedItems: mixedItems,
70
+ renderedKeys: renderedKeys,
71
+ onAssetItemClick: onAssetItemClick
72
+ });
73
+ if (isLoading) {
74
+ return /*#__PURE__*/ jsx(Flex, {
75
+ justifyContent: "center",
76
+ padding: 8,
77
+ children: /*#__PURE__*/ jsx(Loader, {
78
+ children: formatMessage({
79
+ id: 'app.loading',
80
+ defaultMessage: 'Loading...'
81
+ })
82
+ })
83
+ });
84
+ }
85
+ if (error) {
86
+ return /*#__PURE__*/ jsx(Box, {
87
+ padding: 8,
88
+ children: /*#__PURE__*/ jsx(Typography, {
89
+ textColor: "danger600",
90
+ children: formatMessage({
91
+ id: getTranslationKey('list.assets.error'),
92
+ defaultMessage: 'An error occurred while fetching assets.'
93
+ })
94
+ })
95
+ });
96
+ }
97
+ if (folders.length === 0 && assets.length === 0) {
98
+ // While searching, the search empty state wins (it names the query); a
99
+ // filter-only dead end gets the filtered variant with its Clear action.
100
+ return hasActiveFilters && !searchQuery ? /*#__PURE__*/ jsx(FilteredEmptyState, {
101
+ onClearFilters: onClearFilters
102
+ }) : /*#__PURE__*/ jsx(EmptyState, {
103
+ onAddAssets: onAddAssets,
104
+ canAddAssets: canAddAssets,
105
+ searchQuery: searchQuery,
106
+ onClearSearch: onClearSearch
107
+ });
108
+ }
109
+ return /*#__PURE__*/ jsxs(Fragment, {
110
+ children: [
111
+ showItemActions ? // Above both views so one instance serves either, and so the selection
112
+ // menu has the `locations` its move dialog validates against.
113
+ /*#__PURE__*/ jsx(ItemContextMenuProvider, {
114
+ locations: locations,
115
+ children: list
116
+ }) : list,
117
+ /*#__PURE__*/ jsx("div", {
118
+ ref: loadMoreRef,
119
+ style: {
120
+ height: 1
121
+ }
122
+ }),
123
+ isFetchingMore && /*#__PURE__*/ jsx(Flex, {
124
+ justifyContent: "center",
125
+ padding: 4,
126
+ children: /*#__PURE__*/ jsx(Loader, {
127
+ children: formatMessage({
128
+ id: getTranslationKey('list.assets.loading-more'),
129
+ defaultMessage: 'Loading more assets...'
130
+ })
131
+ })
132
+ }),
133
+ showItemActions && /*#__PURE__*/ jsx(BulkActionsBar, {
134
+ assets: assets,
135
+ renderedKeys: renderedKeys,
136
+ locations: locations
137
+ })
138
+ ]
139
+ });
140
+ };
141
+
142
+ export { AssetsView };
143
+ //# sourceMappingURL=AssetsView.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AssetsView.mjs","sources":["../../../../../admin/src/pages/Assets/components/AssetsView.tsx"],"sourcesContent":["import { useMemo } from 'react';\n\nimport { Box, Flex, Loader, Typography } from '@strapi/design-system';\nimport { useIntl } from 'react-intl';\n\nimport { type ItemLocations } from '../../../utils/itemLocations';\nimport { getTranslationKey } from '../../../utils/translations';\nimport { viewOptions } from '../constants';\nimport { useInfiniteScrollSentinel } from '../hooks/useInfiniteScrollSentinel';\nimport { useListSettings } from '../hooks/useListSettings';\nimport { type FoldersPosition } from '../hooks/useListSort';\nimport { mergeMixedList } from '../utils/mergeMixedList';\nimport { buildRenderedKeys } from '../utils/renderedKeys';\n\nimport { AssetsGrid } from './AssetsGrid';\nimport { AssetsTable } from './AssetsTable';\nimport { BulkActionsBar } from './BulkActionsBar';\nimport { EmptyState, FilteredEmptyState } from './EmptyState';\nimport { ItemContextMenuProvider } from './ItemContextMenu';\n\nimport type { File } from '../../../../../shared/contracts/files';\nimport type { Folder } from '../../../../../shared/contracts/folders';\n\n// The negative bottom margin shrinks the trigger area by a pixel so the 1px\n// sentinel sitting exactly at the fold (when a page's rows happen to fill the\n// viewport) reads as \"not visible\" and doesn't pull an extra page. It still\n// triggers as soon as the sentinel scrolls a hair into view. Tune the bottom\n// value if the list over- or under-fetches near the fold.\nconst INTERSECTION_OPTIONS: IntersectionObserverInit = {\n threshold: 0,\n rootMargin: '0px 0px -1px 0px',\n};\n\n/* -------------------------------------------------------------------------------------------------\n * AssetsView\n * -----------------------------------------------------------------------------------------------*/\n\ninterface AssetsViewProps {\n view: number;\n folders: Folder[];\n isLoadingFolders: boolean;\n assets: File[];\n /** Total matching assets on the server, beyond the pages loaded so far. */\n assetsTotal?: number;\n isLoadingAssets: boolean;\n isFetchingMore: boolean;\n hasNextPage: boolean;\n fetchNextPage: () => void;\n error: unknown;\n locations: ItemLocations;\n searchQuery: string;\n assetsSort: string;\n foldersPosition: FoldersPosition;\n hasActiveFilters: boolean;\n onClearFilters: () => void;\n onAssetItemClick: (assetId: number) => void;\n onAddAssets: () => void;\n canAddAssets: boolean;\n onClearSearch: () => void;\n}\n\nexport const AssetsView = ({\n view,\n folders,\n isLoadingFolders,\n assets,\n assetsTotal,\n isLoadingAssets,\n isFetchingMore,\n hasNextPage,\n fetchNextPage,\n error,\n locations,\n searchQuery,\n assetsSort,\n foldersPosition,\n hasActiveFilters,\n onClearFilters,\n onAssetItemClick,\n onAddAssets,\n canAddAssets,\n onClearSearch,\n}: AssetsViewProps) => {\n const { formatMessage } = useIntl();\n const { showItemActions } = useListSettings();\n\n const isGridView = view === viewOptions.GRID;\n const isLoading = isLoadingAssets || isLoadingFolders;\n\n // \"Folders: Mixed with files\" — interleave the complete folder list into the\n // loaded asset stream client-side, following the active sort. Table view\n // only: the grid always keeps folders in their own band on top.\n const mixedItems = useMemo(\n () =>\n foldersPosition === 'mixed' && !isGridView\n ? mergeMixedList({ folders, assets, sort: assetsSort, hasNextPage })\n : null,\n [foldersPosition, isGridView, folders, assets, assetsSort, hasNextPage]\n );\n\n // Derived once here so the table, the grid and the bulk bar all agree on what\n // is on screen — in mixed mode that is not simply every folder.\n const renderedKeys = buildRenderedKeys({ folders, assets, mixedItems });\n\n const loadMoreRef = useInfiniteScrollSentinel({\n hasNextPage,\n isFetchingMore,\n onLoadMore: fetchNextPage,\n options: INTERSECTION_OPTIONS,\n });\n\n const list = isGridView ? (\n <AssetsGrid\n folders={folders}\n assets={assets}\n assetsTotal={assetsTotal}\n renderedKeys={renderedKeys}\n onAssetItemClick={onAssetItemClick}\n />\n ) : (\n <AssetsTable\n assets={assets}\n folders={folders}\n mixedItems={mixedItems}\n renderedKeys={renderedKeys}\n onAssetItemClick={onAssetItemClick}\n />\n );\n\n if (isLoading) {\n return (\n <Flex justifyContent=\"center\" padding={8}>\n <Loader>{formatMessage({ id: 'app.loading', defaultMessage: 'Loading...' })}</Loader>\n </Flex>\n );\n }\n\n if (error) {\n return (\n <Box padding={8}>\n <Typography textColor=\"danger600\">\n {formatMessage({\n id: getTranslationKey('list.assets.error'),\n defaultMessage: 'An error occurred while fetching assets.',\n })}\n </Typography>\n </Box>\n );\n }\n\n if (folders.length === 0 && assets.length === 0) {\n // While searching, the search empty state wins (it names the query); a\n // filter-only dead end gets the filtered variant with its Clear action.\n return hasActiveFilters && !searchQuery ? (\n <FilteredEmptyState onClearFilters={onClearFilters} />\n ) : (\n <EmptyState\n onAddAssets={onAddAssets}\n canAddAssets={canAddAssets}\n searchQuery={searchQuery}\n onClearSearch={onClearSearch}\n />\n );\n }\n return (\n <>\n {showItemActions ? (\n // Above both views so one instance serves either, and so the selection\n // menu has the `locations` its move dialog validates against.\n <ItemContextMenuProvider locations={locations}>{list}</ItemContextMenuProvider>\n ) : (\n list\n )}\n <div ref={loadMoreRef} style={{ height: 1 }} />\n {isFetchingMore && (\n <Flex justifyContent=\"center\" padding={4}>\n <Loader>\n {formatMessage({\n id: getTranslationKey('list.assets.loading-more'),\n defaultMessage: 'Loading more assets...',\n })}\n </Loader>\n </Flex>\n )}\n {/* Lives here rather than in `AssetsPage` so it can read the loaded\n assets: the AI metadata action needs their mime types to know what\n the provider can handle. `position: fixed` keeps it visually anchored\n regardless of where it sits in the tree. */}\n {showItemActions && (\n <BulkActionsBar assets={assets} renderedKeys={renderedKeys} locations={locations} />\n )}\n </>\n );\n};\n"],"names":["INTERSECTION_OPTIONS","threshold","rootMargin","AssetsView","view","folders","isLoadingFolders","assets","assetsTotal","isLoadingAssets","isFetchingMore","hasNextPage","fetchNextPage","error","locations","searchQuery","assetsSort","foldersPosition","hasActiveFilters","onClearFilters","onAssetItemClick","onAddAssets","canAddAssets","onClearSearch","formatMessage","useIntl","showItemActions","useListSettings","isGridView","viewOptions","GRID","isLoading","mixedItems","useMemo","mergeMixedList","sort","renderedKeys","buildRenderedKeys","loadMoreRef","useInfiniteScrollSentinel","onLoadMore","options","list","_jsx","AssetsGrid","AssetsTable","Flex","justifyContent","padding","Loader","id","defaultMessage","Box","Typography","textColor","getTranslationKey","length","FilteredEmptyState","EmptyState","_jsxs","_Fragment","ItemContextMenuProvider","div","ref","style","height","BulkActionsBar"],"mappings":"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"}
@@ -1,7 +1,7 @@
1
1
  import { jsxs, Fragment, jsx } from 'react/jsx-runtime';
2
2
  import { useState, useEffect, useMemo } from 'react';
3
3
  import { useNotification } from '@strapi/admin/strapi-admin';
4
- import { Box, Typography, TextButton, Tooltip, Button, IconButton, Flex } from '@strapi/design-system';
4
+ import { Flex, Box, Typography, TextButton, Tooltip, Button, IconButton } from '@strapi/design-system';
5
5
  import { Sparkle, ArrowRight, Trash, Cross } from '@strapi/icons';
6
6
  import { useIntl } from 'react-intl';
7
7
  import { css, styled } from 'styled-components';
@@ -1,5 +1,5 @@
1
1
  import { jsx } from 'react/jsx-runtime';
2
- import { Loader, Flex } from '@strapi/design-system';
2
+ import { Flex, Loader } from '@strapi/design-system';
3
3
  import { styled } from 'styled-components';
4
4
 
5
5
  /**
@@ -1,5 +1,5 @@
1
1
  import { jsxs, jsx } from 'react/jsx-runtime';
2
- import { Typography, Flex } from '@strapi/design-system';
2
+ import { Flex, Typography } from '@strapi/design-system';
3
3
  import { Folder, File } from '@strapi/icons';
4
4
  import { useIntl } from 'react-intl';
5
5
  import { styled } from 'styled-components';
@@ -0,0 +1,40 @@
1
+ 'use strict';
2
+
3
+ var jsxRuntime = require('react/jsx-runtime');
4
+ var designSystem = require('@strapi/design-system');
5
+ var icons = require('@strapi/icons');
6
+ var reactIntl = require('react-intl');
7
+ var translations = require('../../../../utils/translations.js');
8
+ var assetSortable = require('./assetSortable.js');
9
+
10
+ /**
11
+ * The keyboard path into reordering (Space picks the item up, arrows move it,
12
+ * Space drops it). Pointer drags start from anywhere on the item, this grip
13
+ * included.
14
+ */ const ReorderHandle = ({ name, handle })=>{
15
+ const { formatMessage } = reactIntl.useIntl();
16
+ const { ref, onKeyDown, ...attributes } = handle;
17
+ return /*#__PURE__*/ jsxRuntime.jsx(designSystem.IconButton, {
18
+ ...attributes,
19
+ ref: ref,
20
+ size: "XS",
21
+ variant: "ghost",
22
+ withTooltip: false,
23
+ label: formatMessage({
24
+ id: translations.getTranslationKey('list.item.reorder'),
25
+ defaultMessage: 'Reorder {name}'
26
+ }, {
27
+ name
28
+ }),
29
+ ...assetSortable.REORDER_HANDLE_PROPS,
30
+ // Not stopped: once a drag starts, the arrows and the drop key are read on
31
+ // the document. The item ignores keys from here (`isFromReorderHandle`).
32
+ onKeyDown: onKeyDown,
33
+ // A click on the grip is not a click on the item.
34
+ onClick: (event)=>event.stopPropagation(),
35
+ children: /*#__PURE__*/ jsxRuntime.jsx(icons.Drag, {})
36
+ });
37
+ };
38
+
39
+ exports.ReorderHandle = ReorderHandle;
40
+ //# sourceMappingURL=ReorderHandle.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ReorderHandle.js","sources":["../../../../../../admin/src/pages/Assets/components/Dnd/ReorderHandle.tsx"],"sourcesContent":["import { IconButton } from '@strapi/design-system';\nimport { Drag } from '@strapi/icons';\nimport { useIntl } from 'react-intl';\n\nimport { getTranslationKey } from '../../../../utils/translations';\n\nimport { REORDER_HANDLE_PROPS, type AssetSortable } from './assetSortable';\n\ninterface ReorderHandleProps {\n name: string;\n handle: AssetSortable['handle'];\n}\n\n/**\n * The keyboard path into reordering (Space picks the item up, arrows move it,\n * Space drops it). Pointer drags start from anywhere on the item, this grip\n * included.\n */\nexport const ReorderHandle = ({ name, handle }: ReorderHandleProps) => {\n const { formatMessage } = useIntl();\n const { ref, onKeyDown, ...attributes } = handle;\n\n return (\n <IconButton\n {...attributes}\n ref={ref}\n size=\"XS\"\n variant=\"ghost\"\n withTooltip={false}\n label={formatMessage(\n { id: getTranslationKey('list.item.reorder'), defaultMessage: 'Reorder {name}' },\n { name }\n )}\n {...REORDER_HANDLE_PROPS}\n // Not stopped: once a drag starts, the arrows and the drop key are read on\n // the document. The item ignores keys from here (`isFromReorderHandle`).\n onKeyDown={onKeyDown}\n // A click on the grip is not a click on the item.\n onClick={(event) => event.stopPropagation()}\n >\n <Drag />\n </IconButton>\n );\n};\n"],"names":["ReorderHandle","name","handle","formatMessage","useIntl","ref","onKeyDown","attributes","_jsx","IconButton","size","variant","withTooltip","label","id","getTranslationKey","defaultMessage","REORDER_HANDLE_PROPS","onClick","event","stopPropagation","Drag"],"mappings":";;;;;;;;;AAaA;;;;UAKaA,aAAAA,GAAgB,CAAC,EAAEC,IAAI,EAAEC,MAAM,EAAsB,GAAA;IAChE,MAAM,EAAEC,aAAa,EAAE,GAAGC,iBAAAA,EAAAA;AAC1B,IAAA,MAAM,EAAEC,GAAG,EAAEC,SAAS,EAAE,GAAGC,YAAY,GAAGL,MAAAA;AAE1C,IAAA,qBACEM,cAAA,CAACC,uBAAAA,EAAAA;AACE,QAAA,GAAGF,UAAU;QACdF,GAAAA,EAAKA,GAAAA;QACLK,IAAAA,EAAK,IAAA;QACLC,OAAAA,EAAQ,OAAA;QACRC,WAAAA,EAAa,KAAA;AACbC,QAAAA,KAAAA,EAAOV,aAAAA,CACL;AAAEW,YAAAA,EAAAA,EAAIC,8BAAAA,CAAkB,mBAAA,CAAA;YAAsBC,cAAAA,EAAgB;SAAiB,EAC/E;AAAEf,YAAAA;AAAK,SAAA,CAAA;AAER,QAAA,GAAGgB,kCAAoB;;;QAGxBX,SAAAA,EAAWA,SAAAA;;QAEXY,OAAAA,EAAS,CAACC,KAAAA,GAAUA,KAAAA,CAAMC,eAAe,EAAA;AAEzC,QAAA,QAAA,gBAAAZ,cAAA,CAACa,UAAAA,EAAAA,EAAAA;;AAGP;;;;"}
@@ -0,0 +1,38 @@
1
+ import { jsx } from 'react/jsx-runtime';
2
+ import { IconButton } from '@strapi/design-system';
3
+ import { Drag } from '@strapi/icons';
4
+ import { useIntl } from 'react-intl';
5
+ import { getTranslationKey } from '../../../../utils/translations.mjs';
6
+ import { REORDER_HANDLE_PROPS } from './assetSortable.mjs';
7
+
8
+ /**
9
+ * The keyboard path into reordering (Space picks the item up, arrows move it,
10
+ * Space drops it). Pointer drags start from anywhere on the item, this grip
11
+ * included.
12
+ */ const ReorderHandle = ({ name, handle })=>{
13
+ const { formatMessage } = useIntl();
14
+ const { ref, onKeyDown, ...attributes } = handle;
15
+ return /*#__PURE__*/ jsx(IconButton, {
16
+ ...attributes,
17
+ ref: ref,
18
+ size: "XS",
19
+ variant: "ghost",
20
+ withTooltip: false,
21
+ label: formatMessage({
22
+ id: getTranslationKey('list.item.reorder'),
23
+ defaultMessage: 'Reorder {name}'
24
+ }, {
25
+ name
26
+ }),
27
+ ...REORDER_HANDLE_PROPS,
28
+ // Not stopped: once a drag starts, the arrows and the drop key are read on
29
+ // the document. The item ignores keys from here (`isFromReorderHandle`).
30
+ onKeyDown: onKeyDown,
31
+ // A click on the grip is not a click on the item.
32
+ onClick: (event)=>event.stopPropagation(),
33
+ children: /*#__PURE__*/ jsx(Drag, {})
34
+ });
35
+ };
36
+
37
+ export { ReorderHandle };
38
+ //# sourceMappingURL=ReorderHandle.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ReorderHandle.mjs","sources":["../../../../../../admin/src/pages/Assets/components/Dnd/ReorderHandle.tsx"],"sourcesContent":["import { IconButton } from '@strapi/design-system';\nimport { Drag } from '@strapi/icons';\nimport { useIntl } from 'react-intl';\n\nimport { getTranslationKey } from '../../../../utils/translations';\n\nimport { REORDER_HANDLE_PROPS, type AssetSortable } from './assetSortable';\n\ninterface ReorderHandleProps {\n name: string;\n handle: AssetSortable['handle'];\n}\n\n/**\n * The keyboard path into reordering (Space picks the item up, arrows move it,\n * Space drops it). Pointer drags start from anywhere on the item, this grip\n * included.\n */\nexport const ReorderHandle = ({ name, handle }: ReorderHandleProps) => {\n const { formatMessage } = useIntl();\n const { ref, onKeyDown, ...attributes } = handle;\n\n return (\n <IconButton\n {...attributes}\n ref={ref}\n size=\"XS\"\n variant=\"ghost\"\n withTooltip={false}\n label={formatMessage(\n { id: getTranslationKey('list.item.reorder'), defaultMessage: 'Reorder {name}' },\n { name }\n )}\n {...REORDER_HANDLE_PROPS}\n // Not stopped: once a drag starts, the arrows and the drop key are read on\n // the document. The item ignores keys from here (`isFromReorderHandle`).\n onKeyDown={onKeyDown}\n // A click on the grip is not a click on the item.\n onClick={(event) => event.stopPropagation()}\n >\n <Drag />\n </IconButton>\n );\n};\n"],"names":["ReorderHandle","name","handle","formatMessage","useIntl","ref","onKeyDown","attributes","_jsx","IconButton","size","variant","withTooltip","label","id","getTranslationKey","defaultMessage","REORDER_HANDLE_PROPS","onClick","event","stopPropagation","Drag"],"mappings":";;;;;;;AAaA;;;;UAKaA,aAAAA,GAAgB,CAAC,EAAEC,IAAI,EAAEC,MAAM,EAAsB,GAAA;IAChE,MAAM,EAAEC,aAAa,EAAE,GAAGC,OAAAA,EAAAA;AAC1B,IAAA,MAAM,EAAEC,GAAG,EAAEC,SAAS,EAAE,GAAGC,YAAY,GAAGL,MAAAA;AAE1C,IAAA,qBACEM,GAAA,CAACC,UAAAA,EAAAA;AACE,QAAA,GAAGF,UAAU;QACdF,GAAAA,EAAKA,GAAAA;QACLK,IAAAA,EAAK,IAAA;QACLC,OAAAA,EAAQ,OAAA;QACRC,WAAAA,EAAa,KAAA;AACbC,QAAAA,KAAAA,EAAOV,aAAAA,CACL;AAAEW,YAAAA,EAAAA,EAAIC,iBAAAA,CAAkB,mBAAA,CAAA;YAAsBC,cAAAA,EAAgB;SAAiB,EAC/E;AAAEf,YAAAA;AAAK,SAAA,CAAA;AAER,QAAA,GAAGgB,oBAAoB;;;QAGxBX,SAAAA,EAAWA,SAAAA;;QAEXY,OAAAA,EAAS,CAACC,KAAAA,GAAUA,KAAAA,CAAMC,eAAe,EAAA;AAEzC,QAAA,QAAA,gBAAAZ,GAAA,CAACa,IAAAA,EAAAA,EAAAA;;AAGP;;;;"}
@@ -0,0 +1,29 @@
1
+ 'use strict';
2
+
3
+ var React = require('react');
4
+
5
+ const useNotSortable = ()=>null;
6
+ /**
7
+ * Holds the hook that makes an asset sortable, rather than a value: the hook
8
+ * needs each item's id. A given subtree always gets the same hook, so calling
9
+ * it from `useAssetSortable` keeps the rules of hooks.
10
+ */ const AssetSortableContext = React.createContext(useNotSortable);
11
+ const useAssetSortable = (assetId)=>{
12
+ const useSortableAsset = React.useContext(AssetSortableContext);
13
+ return useSortableAsset(assetId);
14
+ };
15
+ const REORDER_HANDLE_ATTRIBUTE = 'data-reorder-handle';
16
+ /** Marks the reorder grip, so the item can tell its keys apart. */ const REORDER_HANDLE_PROPS = {
17
+ [REORDER_HANDLE_ATTRIBUTE]: ''
18
+ };
19
+ /**
20
+ * Keys pressed on the grip, including the arrows and the drop key mid-drag,
21
+ * belong to reordering. The item must not also read them as its own
22
+ * Enter/Space.
23
+ */ const isFromReorderHandle = (event)=>event.target instanceof Element && event.target.closest(`[${REORDER_HANDLE_ATTRIBUTE}]`) !== null;
24
+
25
+ exports.AssetSortableContext = AssetSortableContext;
26
+ exports.REORDER_HANDLE_PROPS = REORDER_HANDLE_PROPS;
27
+ exports.isFromReorderHandle = isFromReorderHandle;
28
+ exports.useAssetSortable = useAssetSortable;
29
+ //# sourceMappingURL=assetSortable.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"assetSortable.js","sources":["../../../../../../admin/src/pages/Assets/components/Dnd/assetSortable.ts"],"sourcesContent":["import {\n createContext,\n useContext,\n type CSSProperties,\n type KeyboardEvent,\n type SyntheticEvent,\n} from 'react';\n\nimport type { DraggableAttributes, DraggableSyntheticListeners } from '@dnd-kit/core';\n\n/**\n * What a list item needs to take part in reordering: the whole item drags with\n * the pointer, and a grip button carries the keyboard path (Space to pick up,\n * arrows to move) so it doesn't collide with the item's own Space/click.\n */\nexport interface AssetSortable {\n setNodeRef: (node: HTMLElement | null) => void;\n isDragging: boolean;\n style: CSSProperties;\n /** Pointer activation, for the item itself. */\n listeners: DraggableSyntheticListeners;\n handle: Partial<DraggableAttributes> & {\n ref: (node: HTMLElement | null) => void;\n onKeyDown?: (event: KeyboardEvent) => void;\n };\n}\n\ntype UseAssetSortable = (assetId: number) => AssetSortable | null;\n\nconst useNotSortable: UseAssetSortable = () => null;\n\n/**\n * Holds the hook that makes an asset sortable, rather than a value: the hook\n * needs each item's id. A given subtree always gets the same hook, so calling\n * it from `useAssetSortable` keeps the rules of hooks.\n */\nexport const AssetSortableContext = createContext<UseAssetSortable>(useNotSortable);\n\nexport const useAssetSortable = (assetId: number) => {\n const useSortableAsset = useContext(AssetSortableContext);\n\n return useSortableAsset(assetId);\n};\n\nconst REORDER_HANDLE_ATTRIBUTE = 'data-reorder-handle';\n\n/** Marks the reorder grip, so the item can tell its keys apart. */\nexport const REORDER_HANDLE_PROPS = { [REORDER_HANDLE_ATTRIBUTE]: '' };\n\n/**\n * Keys pressed on the grip, including the arrows and the drop key mid-drag,\n * belong to reordering. The item must not also read them as its own\n * Enter/Space.\n */\nexport const isFromReorderHandle = (event: SyntheticEvent) =>\n event.target instanceof Element && event.target.closest(`[${REORDER_HANDLE_ATTRIBUTE}]`) !== null;\n"],"names":["useNotSortable","AssetSortableContext","createContext","useAssetSortable","assetId","useSortableAsset","useContext","REORDER_HANDLE_ATTRIBUTE","REORDER_HANDLE_PROPS","isFromReorderHandle","event","target","Element","closest"],"mappings":";;;;AA6BA,MAAMA,iBAAmC,IAAM,IAAA;AAE/C;;;;AAIC,IACM,MAAMC,oBAAAA,GAAuBC,mBAAAA,CAAgCF,cAAAA;AAE7D,MAAMG,mBAAmB,CAACC,OAAAA,GAAAA;AAC/B,IAAA,MAAMC,mBAAmBC,gBAAAA,CAAWL,oBAAAA,CAAAA;AAEpC,IAAA,OAAOI,gBAAAA,CAAiBD,OAAAA,CAAAA;AAC1B;AAEA,MAAMG,wBAAAA,GAA2B,qBAAA;AAEjC,oEACO,MAAMC,oBAAAA,GAAuB;AAAE,IAAA,CAACD,2BAA2B;AAAG;AAErE;;;;UAKaE,mBAAAA,GAAsB,CAACC,QAClCA,KAAAA,CAAMC,MAAM,YAAYC,OAAAA,IAAWF,KAAAA,CAAMC,MAAM,CAACE,OAAO,CAAC,CAAC,CAAC,EAAEN,wBAAAA,CAAyB,CAAC,CAAC,CAAA,KAAM;;;;;;;"}
@@ -0,0 +1,24 @@
1
+ import { createContext, useContext } from 'react';
2
+
3
+ const useNotSortable = ()=>null;
4
+ /**
5
+ * Holds the hook that makes an asset sortable, rather than a value: the hook
6
+ * needs each item's id. A given subtree always gets the same hook, so calling
7
+ * it from `useAssetSortable` keeps the rules of hooks.
8
+ */ const AssetSortableContext = createContext(useNotSortable);
9
+ const useAssetSortable = (assetId)=>{
10
+ const useSortableAsset = useContext(AssetSortableContext);
11
+ return useSortableAsset(assetId);
12
+ };
13
+ const REORDER_HANDLE_ATTRIBUTE = 'data-reorder-handle';
14
+ /** Marks the reorder grip, so the item can tell its keys apart. */ const REORDER_HANDLE_PROPS = {
15
+ [REORDER_HANDLE_ATTRIBUTE]: ''
16
+ };
17
+ /**
18
+ * Keys pressed on the grip, including the arrows and the drop key mid-drag,
19
+ * belong to reordering. The item must not also read them as its own
20
+ * Enter/Space.
21
+ */ const isFromReorderHandle = (event)=>event.target instanceof Element && event.target.closest(`[${REORDER_HANDLE_ATTRIBUTE}]`) !== null;
22
+
23
+ export { AssetSortableContext, REORDER_HANDLE_PROPS, isFromReorderHandle, useAssetSortable };
24
+ //# sourceMappingURL=assetSortable.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"assetSortable.mjs","sources":["../../../../../../admin/src/pages/Assets/components/Dnd/assetSortable.ts"],"sourcesContent":["import {\n createContext,\n useContext,\n type CSSProperties,\n type KeyboardEvent,\n type SyntheticEvent,\n} from 'react';\n\nimport type { DraggableAttributes, DraggableSyntheticListeners } from '@dnd-kit/core';\n\n/**\n * What a list item needs to take part in reordering: the whole item drags with\n * the pointer, and a grip button carries the keyboard path (Space to pick up,\n * arrows to move) so it doesn't collide with the item's own Space/click.\n */\nexport interface AssetSortable {\n setNodeRef: (node: HTMLElement | null) => void;\n isDragging: boolean;\n style: CSSProperties;\n /** Pointer activation, for the item itself. */\n listeners: DraggableSyntheticListeners;\n handle: Partial<DraggableAttributes> & {\n ref: (node: HTMLElement | null) => void;\n onKeyDown?: (event: KeyboardEvent) => void;\n };\n}\n\ntype UseAssetSortable = (assetId: number) => AssetSortable | null;\n\nconst useNotSortable: UseAssetSortable = () => null;\n\n/**\n * Holds the hook that makes an asset sortable, rather than a value: the hook\n * needs each item's id. A given subtree always gets the same hook, so calling\n * it from `useAssetSortable` keeps the rules of hooks.\n */\nexport const AssetSortableContext = createContext<UseAssetSortable>(useNotSortable);\n\nexport const useAssetSortable = (assetId: number) => {\n const useSortableAsset = useContext(AssetSortableContext);\n\n return useSortableAsset(assetId);\n};\n\nconst REORDER_HANDLE_ATTRIBUTE = 'data-reorder-handle';\n\n/** Marks the reorder grip, so the item can tell its keys apart. */\nexport const REORDER_HANDLE_PROPS = { [REORDER_HANDLE_ATTRIBUTE]: '' };\n\n/**\n * Keys pressed on the grip, including the arrows and the drop key mid-drag,\n * belong to reordering. The item must not also read them as its own\n * Enter/Space.\n */\nexport const isFromReorderHandle = (event: SyntheticEvent) =>\n event.target instanceof Element && event.target.closest(`[${REORDER_HANDLE_ATTRIBUTE}]`) !== null;\n"],"names":["useNotSortable","AssetSortableContext","createContext","useAssetSortable","assetId","useSortableAsset","useContext","REORDER_HANDLE_ATTRIBUTE","REORDER_HANDLE_PROPS","isFromReorderHandle","event","target","Element","closest"],"mappings":";;AA6BA,MAAMA,iBAAmC,IAAM,IAAA;AAE/C;;;;AAIC,IACM,MAAMC,oBAAAA,GAAuBC,aAAAA,CAAgCF,cAAAA;AAE7D,MAAMG,mBAAmB,CAACC,OAAAA,GAAAA;AAC/B,IAAA,MAAMC,mBAAmBC,UAAAA,CAAWL,oBAAAA,CAAAA;AAEpC,IAAA,OAAOI,gBAAAA,CAAiBD,OAAAA,CAAAA;AAC1B;AAEA,MAAMG,wBAAAA,GAA2B,qBAAA;AAEjC,oEACO,MAAMC,oBAAAA,GAAuB;AAAE,IAAA,CAACD,2BAA2B;AAAG;AAErE;;;;UAKaE,mBAAAA,GAAsB,CAACC,QAClCA,KAAAA,CAAMC,MAAM,YAAYC,OAAAA,IAAWF,KAAAA,CAAMC,MAAM,CAACE,OAAO,CAAC,CAAC,CAAC,EAAEN,wBAAAA,CAAyB,CAAC,CAAC,CAAA,KAAM;;;;"}
@@ -11,6 +11,10 @@ const parseFolderTargetId = (dndId)=>{
11
11
  return match ? Number(match[1]) : null;
12
12
  };
13
13
  const toFolderTreeTargetId = (id)=>`folder-tree-target:${id}`;
14
+ /**
15
+ * The "N parent folders" row in the sidebar. Only there so hovering it during a
16
+ * drag opens it; no parser recognises it, so a drop on it moves nothing.
17
+ */ const toFolderTreeSummaryId = (rootId)=>`folder-tree-summary:${rootId}`;
14
18
  const HOME_TREE_TARGET_ID = 'folder-tree-target:home';
15
19
  const parseFolderTreeTargetId = (dndId)=>{
16
20
  if (typeof dndId !== 'string') {
@@ -29,5 +33,6 @@ exports.parseFolderTreeTargetId = parseFolderTreeTargetId;
29
33
  exports.toFileDraggableId = toFileDraggableId;
30
34
  exports.toFolderDraggableId = toFolderDraggableId;
31
35
  exports.toFolderTargetId = toFolderTargetId;
36
+ exports.toFolderTreeSummaryId = toFolderTreeSummaryId;
32
37
  exports.toFolderTreeTargetId = toFolderTreeTargetId;
33
38
  //# sourceMappingURL=dndIds.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"dndIds.js","sources":["../../../../../../admin/src/pages/Assets/components/Dnd/dndIds.ts"],"sourcesContent":["export const toFileDraggableId = (id: number) => `file:${id}` as const;\n\nexport const toFolderDraggableId = (id: number) => `folder:${id}` as const;\n\nexport const toFolderTargetId = (id: number) => `folder-target:${id}` as const;\n\nexport const parseFolderTargetId = (dndId: string | number): number | null => {\n if (typeof dndId !== 'string') {\n return null;\n }\n\n const match = /^folder-target:(\\d+)$/.exec(dndId);\n return match ? Number(match[1]) : null;\n};\n\nexport const toFolderTreeTargetId = (id: number) => `folder-tree-target:${id}` as const;\n\nexport const HOME_TREE_TARGET_ID = 'folder-tree-target:home' as const;\n\nexport const parseFolderTreeTargetId = (dndId: string | number): number | 'root' | null => {\n if (typeof dndId !== 'string') {\n return null;\n }\n\n if (dndId === HOME_TREE_TARGET_ID) {\n return 'root';\n }\n\n const match = /^folder-tree-target:(\\d+)$/.exec(dndId);\n return match ? Number(match[1]) : null;\n};\n"],"names":["toFileDraggableId","id","toFolderDraggableId","toFolderTargetId","parseFolderTargetId","dndId","match","exec","Number","toFolderTreeTargetId","HOME_TREE_TARGET_ID","parseFolderTreeTargetId"],"mappings":";;AAAO,MAAMA,oBAAoB,CAACC,EAAAA,GAAe,CAAC,KAAK,EAAEA;AAElD,MAAMC,sBAAsB,CAACD,EAAAA,GAAe,CAAC,OAAO,EAAEA;AAEtD,MAAME,mBAAmB,CAACF,EAAAA,GAAe,CAAC,cAAc,EAAEA;AAE1D,MAAMG,sBAAsB,CAACC,KAAAA,GAAAA;IAClC,IAAI,OAAOA,UAAU,QAAA,EAAU;QAC7B,OAAO,IAAA;AACT,IAAA;IAEA,MAAMC,KAAAA,GAAQ,uBAAA,CAAwBC,IAAI,CAACF,KAAAA,CAAAA;AAC3C,IAAA,OAAOC,KAAAA,GAAQE,MAAAA,CAAOF,KAAK,CAAC,EAAE,CAAA,GAAI,IAAA;AACpC;AAEO,MAAMG,uBAAuB,CAACR,EAAAA,GAAe,CAAC,mBAAmB,EAAEA;AAEnE,MAAMS,sBAAsB;AAE5B,MAAMC,0BAA0B,CAACN,KAAAA,GAAAA;IACtC,IAAI,OAAOA,UAAU,QAAA,EAAU;QAC7B,OAAO,IAAA;AACT,IAAA;AAEA,IAAA,IAAIA,UAAUK,mBAAAA,EAAqB;QACjC,OAAO,MAAA;AACT,IAAA;IAEA,MAAMJ,KAAAA,GAAQ,4BAAA,CAA6BC,IAAI,CAACF,KAAAA,CAAAA;AAChD,IAAA,OAAOC,KAAAA,GAAQE,MAAAA,CAAOF,KAAK,CAAC,EAAE,CAAA,GAAI,IAAA;AACpC;;;;;;;;;;"}
1
+ {"version":3,"file":"dndIds.js","sources":["../../../../../../admin/src/pages/Assets/components/Dnd/dndIds.ts"],"sourcesContent":["export const toFileDraggableId = (id: number) => `file:${id}` as const;\n\nexport const toFolderDraggableId = (id: number) => `folder:${id}` as const;\n\nexport const toFolderTargetId = (id: number) => `folder-target:${id}` as const;\n\nexport const parseFolderTargetId = (dndId: string | number): number | null => {\n if (typeof dndId !== 'string') {\n return null;\n }\n\n const match = /^folder-target:(\\d+)$/.exec(dndId);\n return match ? Number(match[1]) : null;\n};\n\nexport const toFolderTreeTargetId = (id: number) => `folder-tree-target:${id}` as const;\n\n/**\n * The \"N parent folders\" row in the sidebar. Only there so hovering it during a\n * drag opens it; no parser recognises it, so a drop on it moves nothing.\n */\nexport const toFolderTreeSummaryId = (rootId: number) => `folder-tree-summary:${rootId}` as const;\n\nexport const HOME_TREE_TARGET_ID = 'folder-tree-target:home' as const;\n\nexport const parseFolderTreeTargetId = (dndId: string | number): number | 'root' | null => {\n if (typeof dndId !== 'string') {\n return null;\n }\n\n if (dndId === HOME_TREE_TARGET_ID) {\n return 'root';\n }\n\n const match = /^folder-tree-target:(\\d+)$/.exec(dndId);\n return match ? Number(match[1]) : null;\n};\n"],"names":["toFileDraggableId","id","toFolderDraggableId","toFolderTargetId","parseFolderTargetId","dndId","match","exec","Number","toFolderTreeTargetId","toFolderTreeSummaryId","rootId","HOME_TREE_TARGET_ID","parseFolderTreeTargetId"],"mappings":";;AAAO,MAAMA,oBAAoB,CAACC,EAAAA,GAAe,CAAC,KAAK,EAAEA;AAElD,MAAMC,sBAAsB,CAACD,EAAAA,GAAe,CAAC,OAAO,EAAEA;AAEtD,MAAME,mBAAmB,CAACF,EAAAA,GAAe,CAAC,cAAc,EAAEA;AAE1D,MAAMG,sBAAsB,CAACC,KAAAA,GAAAA;IAClC,IAAI,OAAOA,UAAU,QAAA,EAAU;QAC7B,OAAO,IAAA;AACT,IAAA;IAEA,MAAMC,KAAAA,GAAQ,uBAAA,CAAwBC,IAAI,CAACF,KAAAA,CAAAA;AAC3C,IAAA,OAAOC,KAAAA,GAAQE,MAAAA,CAAOF,KAAK,CAAC,EAAE,CAAA,GAAI,IAAA;AACpC;AAEO,MAAMG,uBAAuB,CAACR,EAAAA,GAAe,CAAC,mBAAmB,EAAEA;AAE1E;;;UAIaS,qBAAAA,GAAwB,CAACC,SAAmB,CAAC,oBAAoB,EAAEA,MAAAA,CAAAA;AAEzE,MAAMC,sBAAsB;AAE5B,MAAMC,0BAA0B,CAACR,KAAAA,GAAAA;IACtC,IAAI,OAAOA,UAAU,QAAA,EAAU;QAC7B,OAAO,IAAA;AACT,IAAA;AAEA,IAAA,IAAIA,UAAUO,mBAAAA,EAAqB;QACjC,OAAO,MAAA;AACT,IAAA;IAEA,MAAMN,KAAAA,GAAQ,4BAAA,CAA6BC,IAAI,CAACF,KAAAA,CAAAA;AAChD,IAAA,OAAOC,KAAAA,GAAQE,MAAAA,CAAOF,KAAK,CAAC,EAAE,CAAA,GAAI,IAAA;AACpC;;;;;;;;;;;"}
@@ -9,6 +9,10 @@ const parseFolderTargetId = (dndId)=>{
9
9
  return match ? Number(match[1]) : null;
10
10
  };
11
11
  const toFolderTreeTargetId = (id)=>`folder-tree-target:${id}`;
12
+ /**
13
+ * The "N parent folders" row in the sidebar. Only there so hovering it during a
14
+ * drag opens it; no parser recognises it, so a drop on it moves nothing.
15
+ */ const toFolderTreeSummaryId = (rootId)=>`folder-tree-summary:${rootId}`;
12
16
  const HOME_TREE_TARGET_ID = 'folder-tree-target:home';
13
17
  const parseFolderTreeTargetId = (dndId)=>{
14
18
  if (typeof dndId !== 'string') {
@@ -21,5 +25,5 @@ const parseFolderTreeTargetId = (dndId)=>{
21
25
  return match ? Number(match[1]) : null;
22
26
  };
23
27
 
24
- export { HOME_TREE_TARGET_ID, parseFolderTargetId, parseFolderTreeTargetId, toFileDraggableId, toFolderDraggableId, toFolderTargetId, toFolderTreeTargetId };
28
+ export { HOME_TREE_TARGET_ID, parseFolderTargetId, parseFolderTreeTargetId, toFileDraggableId, toFolderDraggableId, toFolderTargetId, toFolderTreeSummaryId, toFolderTreeTargetId };
25
29
  //# sourceMappingURL=dndIds.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"dndIds.mjs","sources":["../../../../../../admin/src/pages/Assets/components/Dnd/dndIds.ts"],"sourcesContent":["export const toFileDraggableId = (id: number) => `file:${id}` as const;\n\nexport const toFolderDraggableId = (id: number) => `folder:${id}` as const;\n\nexport const toFolderTargetId = (id: number) => `folder-target:${id}` as const;\n\nexport const parseFolderTargetId = (dndId: string | number): number | null => {\n if (typeof dndId !== 'string') {\n return null;\n }\n\n const match = /^folder-target:(\\d+)$/.exec(dndId);\n return match ? Number(match[1]) : null;\n};\n\nexport const toFolderTreeTargetId = (id: number) => `folder-tree-target:${id}` as const;\n\nexport const HOME_TREE_TARGET_ID = 'folder-tree-target:home' as const;\n\nexport const parseFolderTreeTargetId = (dndId: string | number): number | 'root' | null => {\n if (typeof dndId !== 'string') {\n return null;\n }\n\n if (dndId === HOME_TREE_TARGET_ID) {\n return 'root';\n }\n\n const match = /^folder-tree-target:(\\d+)$/.exec(dndId);\n return match ? Number(match[1]) : null;\n};\n"],"names":["toFileDraggableId","id","toFolderDraggableId","toFolderTargetId","parseFolderTargetId","dndId","match","exec","Number","toFolderTreeTargetId","HOME_TREE_TARGET_ID","parseFolderTreeTargetId"],"mappings":"AAAO,MAAMA,oBAAoB,CAACC,EAAAA,GAAe,CAAC,KAAK,EAAEA;AAElD,MAAMC,sBAAsB,CAACD,EAAAA,GAAe,CAAC,OAAO,EAAEA;AAEtD,MAAME,mBAAmB,CAACF,EAAAA,GAAe,CAAC,cAAc,EAAEA;AAE1D,MAAMG,sBAAsB,CAACC,KAAAA,GAAAA;IAClC,IAAI,OAAOA,UAAU,QAAA,EAAU;QAC7B,OAAO,IAAA;AACT,IAAA;IAEA,MAAMC,KAAAA,GAAQ,uBAAA,CAAwBC,IAAI,CAACF,KAAAA,CAAAA;AAC3C,IAAA,OAAOC,KAAAA,GAAQE,MAAAA,CAAOF,KAAK,CAAC,EAAE,CAAA,GAAI,IAAA;AACpC;AAEO,MAAMG,uBAAuB,CAACR,EAAAA,GAAe,CAAC,mBAAmB,EAAEA;AAEnE,MAAMS,sBAAsB;AAE5B,MAAMC,0BAA0B,CAACN,KAAAA,GAAAA;IACtC,IAAI,OAAOA,UAAU,QAAA,EAAU;QAC7B,OAAO,IAAA;AACT,IAAA;AAEA,IAAA,IAAIA,UAAUK,mBAAAA,EAAqB;QACjC,OAAO,MAAA;AACT,IAAA;IAEA,MAAMJ,KAAAA,GAAQ,4BAAA,CAA6BC,IAAI,CAACF,KAAAA,CAAAA;AAChD,IAAA,OAAOC,KAAAA,GAAQE,MAAAA,CAAOF,KAAK,CAAC,EAAE,CAAA,GAAI,IAAA;AACpC;;;;"}
1
+ {"version":3,"file":"dndIds.mjs","sources":["../../../../../../admin/src/pages/Assets/components/Dnd/dndIds.ts"],"sourcesContent":["export const toFileDraggableId = (id: number) => `file:${id}` as const;\n\nexport const toFolderDraggableId = (id: number) => `folder:${id}` as const;\n\nexport const toFolderTargetId = (id: number) => `folder-target:${id}` as const;\n\nexport const parseFolderTargetId = (dndId: string | number): number | null => {\n if (typeof dndId !== 'string') {\n return null;\n }\n\n const match = /^folder-target:(\\d+)$/.exec(dndId);\n return match ? Number(match[1]) : null;\n};\n\nexport const toFolderTreeTargetId = (id: number) => `folder-tree-target:${id}` as const;\n\n/**\n * The \"N parent folders\" row in the sidebar. Only there so hovering it during a\n * drag opens it; no parser recognises it, so a drop on it moves nothing.\n */\nexport const toFolderTreeSummaryId = (rootId: number) => `folder-tree-summary:${rootId}` as const;\n\nexport const HOME_TREE_TARGET_ID = 'folder-tree-target:home' as const;\n\nexport const parseFolderTreeTargetId = (dndId: string | number): number | 'root' | null => {\n if (typeof dndId !== 'string') {\n return null;\n }\n\n if (dndId === HOME_TREE_TARGET_ID) {\n return 'root';\n }\n\n const match = /^folder-tree-target:(\\d+)$/.exec(dndId);\n return match ? Number(match[1]) : null;\n};\n"],"names":["toFileDraggableId","id","toFolderDraggableId","toFolderTargetId","parseFolderTargetId","dndId","match","exec","Number","toFolderTreeTargetId","toFolderTreeSummaryId","rootId","HOME_TREE_TARGET_ID","parseFolderTreeTargetId"],"mappings":"AAAO,MAAMA,oBAAoB,CAACC,EAAAA,GAAe,CAAC,KAAK,EAAEA;AAElD,MAAMC,sBAAsB,CAACD,EAAAA,GAAe,CAAC,OAAO,EAAEA;AAEtD,MAAME,mBAAmB,CAACF,EAAAA,GAAe,CAAC,cAAc,EAAEA;AAE1D,MAAMG,sBAAsB,CAACC,KAAAA,GAAAA;IAClC,IAAI,OAAOA,UAAU,QAAA,EAAU;QAC7B,OAAO,IAAA;AACT,IAAA;IAEA,MAAMC,KAAAA,GAAQ,uBAAA,CAAwBC,IAAI,CAACF,KAAAA,CAAAA;AAC3C,IAAA,OAAOC,KAAAA,GAAQE,MAAAA,CAAOF,KAAK,CAAC,EAAE,CAAA,GAAI,IAAA;AACpC;AAEO,MAAMG,uBAAuB,CAACR,EAAAA,GAAe,CAAC,mBAAmB,EAAEA;AAE1E;;;UAIaS,qBAAAA,GAAwB,CAACC,SAAmB,CAAC,oBAAoB,EAAEA,MAAAA,CAAAA;AAEzE,MAAMC,sBAAsB;AAE5B,MAAMC,0BAA0B,CAACR,KAAAA,GAAAA;IACtC,IAAI,OAAOA,UAAU,QAAA,EAAU;QAC7B,OAAO,IAAA;AACT,IAAA;AAEA,IAAA,IAAIA,UAAUO,mBAAAA,EAAqB;QACjC,OAAO,MAAA;AACT,IAAA;IAEA,MAAMN,KAAAA,GAAQ,4BAAA,CAA6BC,IAAI,CAACF,KAAAA,CAAAA;AAChD,IAAA,OAAOC,KAAAA,GAAQE,MAAAA,CAAOF,KAAK,CAAC,EAAE,CAAA,GAAI,IAAA;AACpC;;;;"}
@@ -4,12 +4,23 @@ var React = require('react');
4
4
  var core = require('@dnd-kit/core');
5
5
  var getRelationId = require('../../../../utils/getRelationId.js');
6
6
  var AssetsDndProvider = require('./AssetsDndProvider.js');
7
+ var assetSortable = require('./assetSortable.js');
7
8
  var dndIds = require('./dndIds.js');
8
9
 
9
- const useFileDraggable = (asset)=>{
10
- const { isMovePending } = AssetsDndProvider.useAssetsDndOptional() ?? {
11
- isMovePending: false
10
+ /**
11
+ * Without an `AssetsDndProvider` (the Content Manager asset picker mounts none)
12
+ * items are not draggable: nothing handles the drop. Their drag attributes are
13
+ * withheld too, so they aren't announced as draggable.
14
+ */ const NO_DRAG_ATTRIBUTES = {};
15
+ const withoutDrag = (draggable, isDndEnabled)=>isDndEnabled ? draggable : {
16
+ ...draggable,
17
+ attributes: NO_DRAG_ATTRIBUTES,
18
+ listeners: undefined
12
19
  };
20
+ const useFileDraggable = (asset)=>{
21
+ const dnd = AssetsDndProvider.useAssetsDndOptional();
22
+ const isDndEnabled = dnd !== null;
23
+ const isMovePending = dnd?.isMovePending ?? false;
13
24
  const data = React.useMemo(()=>({
14
25
  kind: 'file',
15
26
  id: asset.id,
@@ -23,20 +34,37 @@ const useFileDraggable = (asset)=>{
23
34
  const draggable = core.useDraggable({
24
35
  id: dndIds.toFileDraggableId(asset.id),
25
36
  data,
26
- disabled: isMovePending
37
+ disabled: !isDndEnabled || isMovePending
27
38
  });
39
+ const sortable = assetSortable.useAssetSortable(asset.id);
40
+ // In a reorderable list (the picker's Selected tab) dragging reorders
41
+ // instead of moving between folders: the item takes the sortable's node,
42
+ // pointer listeners and transform, and exposes a grip for the keyboard.
43
+ if (sortable) {
44
+ return {
45
+ ...withoutDrag(draggable, false),
46
+ setNodeRef: sortable.setNodeRef,
47
+ isDragging: sortable.isDragging,
48
+ listeners: sortable.listeners,
49
+ dragStyle: sortable.style,
50
+ dragHandle: sortable.handle,
51
+ dragData: data
52
+ };
53
+ }
28
54
  // `dragData` is re-exposed (like `useFolderDraggableDroppable` does) so the
29
55
  // row's actions menu can hand the move dialog the asset's real folder.
30
56
  return {
31
- ...draggable,
57
+ ...withoutDrag(draggable, isDndEnabled),
58
+ dragStyle: undefined,
59
+ dragHandle: undefined,
32
60
  dragData: data
33
61
  };
34
62
  };
35
63
  const useFolderDraggableDroppable = (folder)=>{
36
- const { isMovePending, isValidDropTarget } = AssetsDndProvider.useAssetsDndOptional() ?? {
37
- isMovePending: false,
38
- isValidDropTarget: ()=>false
39
- };
64
+ const dnd = AssetsDndProvider.useAssetsDndOptional();
65
+ const isDndEnabled = dnd !== null;
66
+ const isMovePending = dnd?.isMovePending ?? false;
67
+ const isValidDropTarget = dnd?.isValidDropTarget ?? (()=>false);
40
68
  const { active } = core.useDndContext();
41
69
  const parentId = getRelationId.getRelationId(folder.parent);
42
70
  const dragData = React.useMemo(()=>({
@@ -57,15 +85,15 @@ const useFolderDraggableDroppable = (folder)=>{
57
85
  folder.id,
58
86
  folder.name
59
87
  ]);
60
- const draggable = core.useDraggable({
88
+ const draggable = withoutDrag(core.useDraggable({
61
89
  id: dndIds.toFolderDraggableId(folder.id),
62
90
  data: dragData,
63
- disabled: isMovePending
64
- });
91
+ disabled: !isDndEnabled || isMovePending
92
+ }), isDndEnabled);
65
93
  const droppable = core.useDroppable({
66
94
  id: dndIds.toFolderTargetId(folder.id),
67
95
  data: dropData,
68
- disabled: isMovePending
96
+ disabled: !isDndEnabled || isMovePending
69
97
  });
70
98
  const isValidTarget = isValidDropTarget(folder.id);
71
99
  const isOver = droppable.isOver;
@@ -1 +1 @@
1
- {"version":3,"file":"useAssetDnd.js","sources":["../../../../../../admin/src/pages/Assets/components/Dnd/useAssetDnd.ts"],"sourcesContent":["import { useMemo } from 'react';\n\nimport { useDndContext, useDraggable, useDroppable } from '@dnd-kit/core';\n\nimport { getRelationId } from '../../../../utils/getRelationId';\n\nimport { useAssetsDndOptional } from './AssetsDndProvider';\nimport { toFileDraggableId, toFolderDraggableId, toFolderTargetId } from './dndIds';\n\nimport type { DragFileData, DragFolderData, FolderTargetData } from '../../../../types/dnd';\n\nexport const useFileDraggable = (asset: {\n id: number;\n name: string;\n folder?: number | string | { id?: number } | null;\n}) => {\n const { isMovePending } = useAssetsDndOptional() ?? { isMovePending: false };\n\n const data = useMemo<DragFileData>(\n () => ({\n kind: 'file',\n id: asset.id,\n name: asset.name,\n folderId: getRelationId(asset.folder),\n }),\n [asset.folder, asset.id, asset.name]\n );\n\n const draggable = useDraggable({\n id: toFileDraggableId(asset.id),\n data,\n disabled: isMovePending,\n });\n\n // `dragData` is re-exposed (like `useFolderDraggableDroppable` does) so the\n // row's actions menu can hand the move dialog the asset's real folder.\n return { ...draggable, dragData: data };\n};\n\nexport const useFolderDraggableDroppable = (folder: {\n id: number;\n name: string;\n parent?: number | null | { id?: number };\n}) => {\n const { isMovePending, isValidDropTarget } = useAssetsDndOptional() ?? {\n isMovePending: false,\n isValidDropTarget: () => false,\n };\n const { active } = useDndContext();\n\n const parentId = getRelationId(folder.parent);\n\n const dragData = useMemo<DragFolderData>(\n () => ({\n kind: 'folder',\n id: folder.id,\n name: folder.name,\n parentId,\n }),\n [folder.id, folder.name, parentId]\n );\n\n const dropData = useMemo<FolderTargetData>(\n () => ({\n kind: 'folder-target',\n id: folder.id,\n name: folder.name,\n }),\n [folder.id, folder.name]\n );\n\n const draggable = useDraggable({\n id: toFolderDraggableId(folder.id),\n data: dragData,\n disabled: isMovePending,\n });\n\n const droppable = useDroppable({\n id: toFolderTargetId(folder.id),\n data: dropData,\n disabled: isMovePending,\n });\n\n const isValidTarget = isValidDropTarget(folder.id);\n const isOver = droppable.isOver;\n const showValidDropHighlight = isOver && isValidTarget;\n const showInvalidDropCursor = isOver && !isValidTarget && active != null;\n\n return {\n dragData,\n draggable,\n droppable,\n isDragging: draggable.isDragging,\n showValidDropHighlight,\n showInvalidDropCursor,\n };\n};\n"],"names":["useFileDraggable","asset","isMovePending","useAssetsDndOptional","data","useMemo","kind","id","name","folderId","getRelationId","folder","draggable","useDraggable","toFileDraggableId","disabled","dragData","useFolderDraggableDroppable","isValidDropTarget","active","useDndContext","parentId","parent","dropData","toFolderDraggableId","droppable","useDroppable","toFolderTargetId","isValidTarget","isOver","showValidDropHighlight","showInvalidDropCursor","isDragging"],"mappings":"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"}
1
+ {"version":3,"file":"useAssetDnd.js","sources":["../../../../../../admin/src/pages/Assets/components/Dnd/useAssetDnd.ts"],"sourcesContent":["import { useMemo } from 'react';\n\nimport { useDndContext, useDraggable, useDroppable, type DraggableAttributes } from '@dnd-kit/core';\n\nimport { getRelationId } from '../../../../utils/getRelationId';\n\nimport { useAssetsDndOptional } from './AssetsDndProvider';\nimport { useAssetSortable } from './assetSortable';\nimport { toFileDraggableId, toFolderDraggableId, toFolderTargetId } from './dndIds';\n\nimport type { DragFileData, DragFolderData, FolderTargetData } from '../../../../types/dnd';\n\n/**\n * Without an `AssetsDndProvider` (the Content Manager asset picker mounts none)\n * items are not draggable: nothing handles the drop. Their drag attributes are\n * withheld too, so they aren't announced as draggable.\n */\nconst NO_DRAG_ATTRIBUTES: Partial<DraggableAttributes> = {};\n\nconst withoutDrag = <T extends { attributes: DraggableAttributes }>(\n draggable: T,\n isDndEnabled: boolean\n) =>\n isDndEnabled ? draggable : { ...draggable, attributes: NO_DRAG_ATTRIBUTES, listeners: undefined };\n\nexport const useFileDraggable = (asset: {\n id: number;\n name: string;\n folder?: number | string | { id?: number } | null;\n}) => {\n const dnd = useAssetsDndOptional();\n const isDndEnabled = dnd !== null;\n const isMovePending = dnd?.isMovePending ?? false;\n\n const data = useMemo<DragFileData>(\n () => ({\n kind: 'file',\n id: asset.id,\n name: asset.name,\n folderId: getRelationId(asset.folder),\n }),\n [asset.folder, asset.id, asset.name]\n );\n\n const draggable = useDraggable({\n id: toFileDraggableId(asset.id),\n data,\n disabled: !isDndEnabled || isMovePending,\n });\n\n const sortable = useAssetSortable(asset.id);\n\n // In a reorderable list (the picker's Selected tab) dragging reorders\n // instead of moving between folders: the item takes the sortable's node,\n // pointer listeners and transform, and exposes a grip for the keyboard.\n if (sortable) {\n return {\n ...withoutDrag(draggable, false),\n setNodeRef: sortable.setNodeRef,\n isDragging: sortable.isDragging,\n listeners: sortable.listeners,\n dragStyle: sortable.style,\n dragHandle: sortable.handle,\n dragData: data,\n };\n }\n\n // `dragData` is re-exposed (like `useFolderDraggableDroppable` does) so the\n // row's actions menu can hand the move dialog the asset's real folder.\n return {\n ...withoutDrag(draggable, isDndEnabled),\n dragStyle: undefined,\n dragHandle: undefined,\n dragData: data,\n };\n};\n\nexport const useFolderDraggableDroppable = (folder: {\n id: number;\n name: string;\n parent?: number | null | { id?: number };\n}) => {\n const dnd = useAssetsDndOptional();\n const isDndEnabled = dnd !== null;\n const isMovePending = dnd?.isMovePending ?? false;\n const isValidDropTarget = dnd?.isValidDropTarget ?? (() => false);\n const { active } = useDndContext();\n\n const parentId = getRelationId(folder.parent);\n\n const dragData = useMemo<DragFolderData>(\n () => ({\n kind: 'folder',\n id: folder.id,\n name: folder.name,\n parentId,\n }),\n [folder.id, folder.name, parentId]\n );\n\n const dropData = useMemo<FolderTargetData>(\n () => ({\n kind: 'folder-target',\n id: folder.id,\n name: folder.name,\n }),\n [folder.id, folder.name]\n );\n\n const draggable = withoutDrag(\n useDraggable({\n id: toFolderDraggableId(folder.id),\n data: dragData,\n disabled: !isDndEnabled || isMovePending,\n }),\n isDndEnabled\n );\n\n const droppable = useDroppable({\n id: toFolderTargetId(folder.id),\n data: dropData,\n disabled: !isDndEnabled || isMovePending,\n });\n\n const isValidTarget = isValidDropTarget(folder.id);\n const isOver = droppable.isOver;\n const showValidDropHighlight = isOver && isValidTarget;\n const showInvalidDropCursor = isOver && !isValidTarget && active != null;\n\n return {\n dragData,\n draggable,\n droppable,\n isDragging: draggable.isDragging,\n showValidDropHighlight,\n showInvalidDropCursor,\n };\n};\n"],"names":["NO_DRAG_ATTRIBUTES","withoutDrag","draggable","isDndEnabled","attributes","listeners","undefined","useFileDraggable","asset","dnd","useAssetsDndOptional","isMovePending","data","useMemo","kind","id","name","folderId","getRelationId","folder","useDraggable","toFileDraggableId","disabled","sortable","useAssetSortable","setNodeRef","isDragging","dragStyle","style","dragHandle","handle","dragData","useFolderDraggableDroppable","isValidDropTarget","active","useDndContext","parentId","parent","dropData","toFolderDraggableId","droppable","useDroppable","toFolderTargetId","isValidTarget","isOver","showValidDropHighlight","showInvalidDropCursor"],"mappings":"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"}