@strapi/upload 5.51.2 → 5.52.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (193) hide show
  1. package/dist/admin/future/App.js +3 -3
  2. package/dist/admin/future/App.js.map +1 -1
  3. package/dist/admin/future/App.mjs +4 -4
  4. package/dist/admin/future/App.mjs.map +1 -1
  5. package/dist/admin/future/components/BetaNotice.js +72 -0
  6. package/dist/admin/future/components/BetaNotice.js.map +1 -0
  7. package/dist/admin/future/components/BetaNotice.mjs +70 -0
  8. package/dist/admin/future/components/BetaNotice.mjs.map +1 -0
  9. package/dist/admin/future/components/Drawer.js +16 -3
  10. package/dist/admin/future/components/Drawer.js.map +1 -1
  11. package/dist/admin/future/components/Drawer.mjs +16 -3
  12. package/dist/admin/future/components/Drawer.mjs.map +1 -1
  13. package/dist/admin/future/hooks/useAIMetadataEnabled.js +39 -0
  14. package/dist/admin/future/hooks/useAIMetadataEnabled.js.map +1 -0
  15. package/dist/admin/future/hooks/useAIMetadataEnabled.mjs +37 -0
  16. package/dist/admin/future/hooks/useAIMetadataEnabled.mjs.map +1 -0
  17. package/dist/admin/future/pages/Assets/AssetsPage.js +297 -139
  18. package/dist/admin/future/pages/Assets/AssetsPage.js.map +1 -1
  19. package/dist/admin/future/pages/Assets/AssetsPage.mjs +301 -143
  20. package/dist/admin/future/pages/Assets/AssetsPage.mjs.map +1 -1
  21. package/dist/admin/future/pages/Assets/components/ActionsMenuContent.js +46 -0
  22. package/dist/admin/future/pages/Assets/components/ActionsMenuContent.js.map +1 -0
  23. package/dist/admin/future/pages/Assets/components/ActionsMenuContent.mjs +44 -0
  24. package/dist/admin/future/pages/Assets/components/ActionsMenuContent.mjs.map +1 -0
  25. package/dist/admin/future/pages/Assets/components/AssetActionsMenu.js +325 -0
  26. package/dist/admin/future/pages/Assets/components/AssetActionsMenu.js.map +1 -0
  27. package/dist/admin/future/pages/Assets/components/AssetActionsMenu.mjs +323 -0
  28. package/dist/admin/future/pages/Assets/components/AssetActionsMenu.mjs.map +1 -0
  29. package/dist/admin/future/pages/Assets/components/AssetDetails/AssetCropEditor.js +35 -14
  30. package/dist/admin/future/pages/Assets/components/AssetDetails/AssetCropEditor.js.map +1 -1
  31. package/dist/admin/future/pages/Assets/components/AssetDetails/AssetCropEditor.mjs +35 -14
  32. package/dist/admin/future/pages/Assets/components/AssetDetails/AssetCropEditor.mjs.map +1 -1
  33. package/dist/admin/future/pages/Assets/components/AssetDetails/AssetDetailsDrawer.js +54 -53
  34. package/dist/admin/future/pages/Assets/components/AssetDetails/AssetDetailsDrawer.js.map +1 -1
  35. package/dist/admin/future/pages/Assets/components/AssetDetails/AssetDetailsDrawer.mjs +54 -54
  36. package/dist/admin/future/pages/Assets/components/AssetDetails/AssetDetailsDrawer.mjs.map +1 -1
  37. package/dist/admin/future/pages/Assets/components/AssetsGrid.js +89 -24
  38. package/dist/admin/future/pages/Assets/components/AssetsGrid.js.map +1 -1
  39. package/dist/admin/future/pages/Assets/components/AssetsGrid.mjs +91 -26
  40. package/dist/admin/future/pages/Assets/components/AssetsGrid.mjs.map +1 -1
  41. package/dist/admin/future/pages/Assets/components/AssetsSearchInput.js +15 -3
  42. package/dist/admin/future/pages/Assets/components/AssetsSearchInput.js.map +1 -1
  43. package/dist/admin/future/pages/Assets/components/AssetsSearchInput.mjs +16 -4
  44. package/dist/admin/future/pages/Assets/components/AssetsSearchInput.mjs.map +1 -1
  45. package/dist/admin/future/pages/Assets/components/AssetsTable.js +168 -58
  46. package/dist/admin/future/pages/Assets/components/AssetsTable.js.map +1 -1
  47. package/dist/admin/future/pages/Assets/components/AssetsTable.mjs +171 -61
  48. package/dist/admin/future/pages/Assets/components/AssetsTable.mjs.map +1 -1
  49. package/dist/admin/future/pages/Assets/components/BulkActionsBar.js +64 -132
  50. package/dist/admin/future/pages/Assets/components/BulkActionsBar.js.map +1 -1
  51. package/dist/admin/future/pages/Assets/components/BulkActionsBar.mjs +64 -132
  52. package/dist/admin/future/pages/Assets/components/BulkActionsBar.mjs.map +1 -1
  53. package/dist/admin/future/pages/Assets/components/BulkMoveDialog.js +123 -76
  54. package/dist/admin/future/pages/Assets/components/BulkMoveDialog.js.map +1 -1
  55. package/dist/admin/future/pages/Assets/components/BulkMoveDialog.mjs +126 -79
  56. package/dist/admin/future/pages/Assets/components/BulkMoveDialog.mjs.map +1 -1
  57. package/dist/admin/future/pages/Assets/components/BusyOverlay.js +36 -0
  58. package/dist/admin/future/pages/Assets/components/BusyOverlay.js.map +1 -0
  59. package/dist/admin/future/pages/Assets/components/BusyOverlay.mjs +34 -0
  60. package/dist/admin/future/pages/Assets/components/BusyOverlay.mjs.map +1 -0
  61. package/dist/admin/future/pages/Assets/components/DeleteItemsDialog.js +131 -0
  62. package/dist/admin/future/pages/Assets/components/DeleteItemsDialog.js.map +1 -0
  63. package/dist/admin/future/pages/Assets/components/DeleteItemsDialog.mjs +129 -0
  64. package/dist/admin/future/pages/Assets/components/DeleteItemsDialog.mjs.map +1 -0
  65. package/dist/admin/future/pages/Assets/components/Dnd/AssetsDndProvider.js +27 -17
  66. package/dist/admin/future/pages/Assets/components/Dnd/AssetsDndProvider.js.map +1 -1
  67. package/dist/admin/future/pages/Assets/components/Dnd/AssetsDndProvider.mjs +28 -18
  68. package/dist/admin/future/pages/Assets/components/Dnd/AssetsDndProvider.mjs.map +1 -1
  69. package/dist/admin/future/pages/Assets/components/Dnd/buildDragSet.js +28 -31
  70. package/dist/admin/future/pages/Assets/components/Dnd/buildDragSet.js.map +1 -1
  71. package/dist/admin/future/pages/Assets/components/Dnd/buildDragSet.mjs +28 -31
  72. package/dist/admin/future/pages/Assets/components/Dnd/buildDragSet.mjs.map +1 -1
  73. package/dist/admin/future/pages/Assets/components/Dnd/useAssetDnd.js +10 -15
  74. package/dist/admin/future/pages/Assets/components/Dnd/useAssetDnd.js.map +1 -1
  75. package/dist/admin/future/pages/Assets/components/Dnd/useAssetDnd.mjs +10 -15
  76. package/dist/admin/future/pages/Assets/components/Dnd/useAssetDnd.mjs.map +1 -1
  77. package/dist/admin/future/pages/Assets/components/FilterBadges.js +13 -4
  78. package/dist/admin/future/pages/Assets/components/FilterBadges.js.map +1 -1
  79. package/dist/admin/future/pages/Assets/components/FilterBadges.mjs +13 -4
  80. package/dist/admin/future/pages/Assets/components/FilterBadges.mjs.map +1 -1
  81. package/dist/admin/future/pages/Assets/components/FilterMenu.js +241 -61
  82. package/dist/admin/future/pages/Assets/components/FilterMenu.js.map +1 -1
  83. package/dist/admin/future/pages/Assets/components/FilterMenu.mjs +244 -64
  84. package/dist/admin/future/pages/Assets/components/FilterMenu.mjs.map +1 -1
  85. package/dist/admin/future/pages/Assets/components/FolderActionsMenu.js +144 -0
  86. package/dist/admin/future/pages/Assets/components/FolderActionsMenu.js.map +1 -0
  87. package/dist/admin/future/pages/Assets/components/FolderActionsMenu.mjs +142 -0
  88. package/dist/admin/future/pages/Assets/components/FolderActionsMenu.mjs.map +1 -0
  89. package/dist/admin/future/pages/Assets/components/{CreateFolderDialog.js → FolderFormDialog.js} +50 -16
  90. package/dist/admin/future/pages/Assets/components/FolderFormDialog.js.map +1 -0
  91. package/dist/admin/future/pages/Assets/components/{CreateFolderDialog.mjs → FolderFormDialog.mjs} +52 -18
  92. package/dist/admin/future/pages/Assets/components/FolderFormDialog.mjs.map +1 -0
  93. package/dist/admin/future/pages/Assets/components/FolderTree/FolderTree.js +111 -191
  94. package/dist/admin/future/pages/Assets/components/FolderTree/FolderTree.js.map +1 -1
  95. package/dist/admin/future/pages/Assets/components/FolderTree/FolderTree.mjs +114 -194
  96. package/dist/admin/future/pages/Assets/components/FolderTree/FolderTree.mjs.map +1 -1
  97. package/dist/admin/future/pages/Assets/hooks/useBusyAssets.js +47 -0
  98. package/dist/admin/future/pages/Assets/hooks/useBusyAssets.js.map +1 -0
  99. package/dist/admin/future/pages/Assets/hooks/useBusyAssets.mjs +44 -0
  100. package/dist/admin/future/pages/Assets/hooks/useBusyAssets.mjs.map +1 -0
  101. package/dist/admin/future/pages/Assets/hooks/useInfiniteAssets.js +203 -62
  102. package/dist/admin/future/pages/Assets/hooks/useInfiniteAssets.js.map +1 -1
  103. package/dist/admin/future/pages/Assets/hooks/useInfiniteAssets.mjs +204 -63
  104. package/dist/admin/future/pages/Assets/hooks/useInfiniteAssets.mjs.map +1 -1
  105. package/dist/admin/future/pages/Assets/hooks/useInfiniteScrollSentinel.js +75 -0
  106. package/dist/admin/future/pages/Assets/hooks/useInfiniteScrollSentinel.js.map +1 -0
  107. package/dist/admin/future/pages/Assets/hooks/useInfiniteScrollSentinel.mjs +73 -0
  108. package/dist/admin/future/pages/Assets/hooks/useInfiniteScrollSentinel.mjs.map +1 -0
  109. package/dist/admin/future/services/api.js +24 -0
  110. package/dist/admin/future/services/api.js.map +1 -1
  111. package/dist/admin/future/services/api.mjs +24 -0
  112. package/dist/admin/future/services/api.mjs.map +1 -1
  113. package/dist/admin/future/services/assets.js +11 -0
  114. package/dist/admin/future/services/assets.js.map +1 -1
  115. package/dist/admin/future/services/assets.mjs +11 -0
  116. package/dist/admin/future/services/assets.mjs.map +1 -1
  117. package/dist/admin/future/services/folders.js +37 -2
  118. package/dist/admin/future/services/folders.js.map +1 -1
  119. package/dist/admin/future/services/folders.mjs +37 -3
  120. package/dist/admin/future/services/folders.mjs.map +1 -1
  121. package/dist/admin/future/utils/buildDragSetFromSelection.js +7 -5
  122. package/dist/admin/future/utils/buildDragSetFromSelection.js.map +1 -1
  123. package/dist/admin/future/utils/buildDragSetFromSelection.mjs +7 -5
  124. package/dist/admin/future/utils/buildDragSetFromSelection.mjs.map +1 -1
  125. package/dist/admin/future/utils/formatMoveSuccessMessage.js +12 -1
  126. package/dist/admin/future/utils/formatMoveSuccessMessage.js.map +1 -1
  127. package/dist/admin/future/utils/formatMoveSuccessMessage.mjs +12 -1
  128. package/dist/admin/future/utils/formatMoveSuccessMessage.mjs.map +1 -1
  129. package/dist/admin/future/utils/getRelationId.js +24 -0
  130. package/dist/admin/future/utils/getRelationId.js.map +1 -0
  131. package/dist/admin/future/utils/getRelationId.mjs +22 -0
  132. package/dist/admin/future/utils/getRelationId.mjs.map +1 -0
  133. package/dist/admin/future/utils/isEventFromWithin.js +14 -0
  134. package/dist/admin/future/utils/isEventFromWithin.js.map +1 -0
  135. package/dist/admin/future/utils/isEventFromWithin.mjs +12 -0
  136. package/dist/admin/future/utils/isEventFromWithin.mjs.map +1 -0
  137. package/dist/admin/future/utils/itemLocations.js +40 -0
  138. package/dist/admin/future/utils/itemLocations.js.map +1 -0
  139. package/dist/admin/future/utils/itemLocations.mjs +36 -0
  140. package/dist/admin/future/utils/itemLocations.mjs.map +1 -0
  141. package/dist/admin/future/utils/itemSource.js +36 -0
  142. package/dist/admin/future/utils/itemSource.js.map +1 -0
  143. package/dist/admin/future/utils/itemSource.mjs +32 -0
  144. package/dist/admin/future/utils/itemSource.mjs.map +1 -0
  145. package/dist/admin/index.js +11 -17
  146. package/dist/admin/index.js.map +1 -1
  147. package/dist/admin/index.mjs +12 -18
  148. package/dist/admin/index.mjs.map +1 -1
  149. package/dist/admin/src/future/App.d.ts +1 -1
  150. package/dist/admin/src/future/components/BetaNotice.d.ts +11 -0
  151. package/dist/admin/src/future/components/Drawer.d.ts +5 -1
  152. package/dist/admin/src/future/hooks/useAIMetadataEnabled.d.ts +26 -0
  153. package/dist/admin/src/future/pages/Assets/components/ActionsMenuContent.d.ts +33 -0
  154. package/dist/admin/src/future/pages/Assets/components/AssetActionsMenu.d.ts +24 -0
  155. package/dist/admin/src/future/pages/Assets/components/AssetDetails/AssetDetailsDrawer.d.ts +16 -0
  156. package/dist/admin/src/future/pages/Assets/components/BulkActionsBar.d.ts +8 -1
  157. package/dist/admin/src/future/pages/Assets/components/BulkMoveDialog.d.ts +17 -6
  158. package/dist/admin/src/future/pages/Assets/components/BusyOverlay.d.ts +9 -0
  159. package/dist/admin/src/future/pages/Assets/components/DeleteItemsDialog.d.ts +27 -0
  160. package/dist/admin/src/future/pages/Assets/components/Dnd/AssetsDndProvider.d.ts +8 -1
  161. package/dist/admin/src/future/pages/Assets/components/Dnd/buildDragSet.d.ts +18 -3
  162. package/dist/admin/src/future/pages/Assets/components/Dnd/useAssetDnd.d.ts +2 -1
  163. package/dist/admin/src/future/pages/Assets/components/FilterBadges.d.ts +3 -1
  164. package/dist/admin/src/future/pages/Assets/components/FilterMenu.d.ts +4 -0
  165. package/dist/admin/src/future/pages/Assets/components/FolderActionsMenu.d.ts +20 -0
  166. package/dist/admin/src/future/pages/Assets/components/FolderFormDialog.d.ts +16 -0
  167. package/dist/admin/src/future/pages/Assets/hooks/useBusyAssets.d.ts +38 -0
  168. package/dist/admin/src/future/pages/Assets/hooks/useInfiniteAssets.d.ts +20 -6
  169. package/dist/admin/src/future/pages/Assets/hooks/useInfiniteScrollSentinel.d.ts +41 -0
  170. package/dist/admin/src/future/services/folders.d.ts +6 -1
  171. package/dist/admin/src/future/utils/buildDragSetFromSelection.d.ts +4 -3
  172. package/dist/admin/src/future/utils/formatMoveSuccessMessage.d.ts +7 -1
  173. package/dist/admin/src/future/utils/getRelationId.d.ts +11 -0
  174. package/dist/admin/src/future/utils/isEventFromWithin.d.ts +11 -0
  175. package/dist/admin/src/future/utils/itemLocations.d.ts +31 -0
  176. package/dist/admin/src/future/utils/itemSource.d.ts +22 -0
  177. package/dist/admin/translations/en.json.js +25 -4
  178. package/dist/admin/translations/en.json.js.map +1 -1
  179. package/dist/admin/translations/en.json.mjs +25 -4
  180. package/dist/admin/translations/en.json.mjs.map +1 -1
  181. package/dist/server/services/image-manipulation.js.map +1 -1
  182. package/dist/server/services/image-manipulation.mjs.map +1 -1
  183. package/dist/server/src/services/image-manipulation.d.ts +0 -5
  184. package/dist/server/src/services/image-manipulation.d.ts.map +1 -1
  185. package/package.json +9 -9
  186. package/dist/admin/future/pages/Assets/components/CreateFolderDialog.js.map +0 -1
  187. package/dist/admin/future/pages/Assets/components/CreateFolderDialog.mjs.map +0 -1
  188. package/dist/admin/future/pages/Assets/components/FolderTree/filterFolderTree.js +0 -33
  189. package/dist/admin/future/pages/Assets/components/FolderTree/filterFolderTree.js.map +0 -1
  190. package/dist/admin/future/pages/Assets/components/FolderTree/filterFolderTree.mjs +0 -31
  191. package/dist/admin/future/pages/Assets/components/FolderTree/filterFolderTree.mjs.map +0 -1
  192. package/dist/admin/src/future/pages/Assets/components/CreateFolderDialog.d.ts +0 -8
  193. package/dist/admin/src/future/pages/Assets/components/FolderTree/filterFolderTree.d.ts +0 -16
@@ -1,14 +1,14 @@
1
1
  import { jsxs, jsx } from 'react/jsx-runtime';
2
- import { useState, useMemo, useCallback, useEffect, useRef, useLayoutEffect } from 'react';
3
- import { useFilter, Flex, Typography, Searchbar, Box, Loader, IconButton, Tooltip } from '@strapi/design-system';
2
+ import { useState, useEffect, useCallback, useRef, useLayoutEffect } from 'react';
3
+ import { SubNav } from '@strapi/admin/strapi-admin';
4
+ import { Flex, Typography, Box, Loader, IconButton, Tooltip } from '@strapi/design-system';
4
5
  import { House, Folder, ChevronDown } from '@strapi/icons';
5
6
  import { useIntl } from 'react-intl';
6
- import { styled, css } from 'styled-components';
7
+ import { css, styled } from 'styled-components';
7
8
  import { useGetFolderStructureQuery } from '../../../../services/folders.mjs';
8
9
  import { getTranslationKey } from '../../../../utils/translations.mjs';
9
10
  import { useAssetsDndOptional } from '../Dnd/AssetsDndProvider.mjs';
10
11
  import { useFolderTreeDroppable } from '../Dnd/useFolderTreeDroppable.mjs';
11
- import { filterFolderTree } from './filterFolderTree.mjs';
12
12
  import { useSpringLoadedExpand } from './useSpringLoadedExpand.mjs';
13
13
 
14
14
  /* -------------------------------------------------------------------------------------------------
@@ -296,27 +296,6 @@ const FolderTreeItem = ({ node, ...props })=>{
296
296
  folderChildren: node.children ?? []
297
297
  });
298
298
  };
299
- /* -------------------------------------------------------------------------------------------------
300
- * FolderTree — public sidebar component
301
- * -----------------------------------------------------------------------------------------------*/ const SidebarNav = styled(Flex)`
302
- /* TODO: reconcile 25.6rem (Figma) with admin WIDTH_SIDE_NAVIGATION (23.2rem) */
303
- width: 25.6rem;
304
- height: 100%;
305
- min-height: 100%;
306
- background: ${({ theme })=>theme.colors.neutral0};
307
- flex-shrink: 0;
308
- flex-direction: column;
309
- border-right: 1px solid ${({ theme })=>theme.colors.neutral150};
310
- `;
311
- const SidebarHeader = styled(Box)`
312
- flex-shrink: 0;
313
- border-bottom: 1px solid ${({ theme })=>theme.colors.neutral150};
314
- `;
315
- const SidebarBody = styled(Flex)`
316
- flex: 1;
317
- min-height: 0;
318
- overflow-y: auto;
319
- `;
320
299
  /**
321
300
  * Left-rail navigation for the Media Library. Fetches folder structure internally
322
301
  * and renders:
@@ -334,31 +313,12 @@ const SidebarBody = styled(Flex)`
334
313
  * via `onSelectFolder` so the URL stays the single source of truth (see
335
314
  * `useFolderNavigation`).
336
315
  */ const FolderTree = ({ currentFolderId, showActiveFolder = true, onSelectFolder })=>{
337
- const { formatMessage, locale } = useIntl();
316
+ const { formatMessage } = useIntl();
338
317
  const { data: folderStructure = [], isLoading, isError } = useGetFolderStructureQuery();
339
318
  const { isExpanded, toggleExpanded, expandFolder } = useExpandedFolders(folderStructure, currentFolderId);
340
319
  const { isMovePending } = useAssetsDndOptional() ?? {
341
320
  isMovePending: false
342
321
  };
343
- const [treeFilter, setTreeFilter] = useState('');
344
- const { contains } = useFilter(locale, {
345
- sensitivity: 'base'
346
- });
347
- const trimmedFilter = treeFilter.trim();
348
- const { nodes: visibleNodes, expandedIds: filterExpandedIds } = useMemo(()=>trimmedFilter ? filterFolderTree(folderStructure, (name)=>contains(name, trimmedFilter)) : {
349
- nodes: folderStructure,
350
- expandedIds: []
351
- }, [
352
- folderStructure,
353
- trimmedFilter,
354
- contains
355
- ]);
356
- // An override layered on top of the user's own expansion rather than written
357
- // into it, so clearing the filter restores exactly what they had open.
358
- const isExpandedForRender = useCallback((id)=>filterExpandedIds.includes(id) || isExpanded(id), [
359
- filterExpandedIds,
360
- isExpanded
361
- ]);
362
322
  const isHomeActive = showActiveFolder && currentFolderId == null;
363
323
  const homeLabel = formatMessage({
364
324
  id: getTranslationKey('sidebar.home'),
@@ -368,171 +328,131 @@ const SidebarBody = styled(Flex)`
368
328
  id: null,
369
329
  name: homeLabel
370
330
  });
371
- return /*#__PURE__*/ jsxs(SidebarNav, {
372
- direction: "column",
373
- alignItems: "stretch",
374
- tag: "nav",
331
+ return /*#__PURE__*/ jsxs(SubNav.Main, {
375
332
  "aria-label": formatMessage({
376
333
  id: getTranslationKey('sidebar.tree.aria-label'),
377
334
  defaultMessage: 'Media library folders'
378
335
  }),
379
336
  children: [
380
- /*#__PURE__*/ jsx(SidebarHeader, {
381
- paddingTop: 4,
382
- paddingBottom: 4,
383
- paddingLeft: 5,
384
- paddingRight: 5,
337
+ /*#__PURE__*/ jsx(SubNav.Header, {
338
+ label: formatMessage({
339
+ id: getTranslationKey('sidebar.title'),
340
+ defaultMessage: 'Media library'
341
+ })
342
+ }),
343
+ /*#__PURE__*/ jsx(SubNav.Content, {
385
344
  children: /*#__PURE__*/ jsxs(Flex, {
386
345
  direction: "column",
387
346
  alignItems: "stretch",
388
- gap: 4,
347
+ gap: 1,
348
+ padding: 3,
389
349
  children: [
390
- /*#__PURE__*/ jsx(Typography, {
391
- variant: "beta",
392
- tag: "h2",
393
- children: formatMessage({
394
- id: getTranslationKey('sidebar.title'),
395
- defaultMessage: 'Media library'
396
- })
350
+ /*#__PURE__*/ jsxs(RowButton, {
351
+ ref: setHomeDropRef,
352
+ type: "button",
353
+ $isActive: isHomeActive,
354
+ $isValidDropTarget: showHomeValidDropHighlight,
355
+ $isInvalidDropCursor: showHomeInvalidDropCursor,
356
+ $isMovePending: isMovePending,
357
+ "aria-current": isHomeActive ? 'page' : undefined,
358
+ onClick: ()=>onSelectFolder(null),
359
+ "data-testid": "folder-tree-home",
360
+ children: [
361
+ /*#__PURE__*/ jsx(House, {
362
+ "aria-hidden": true,
363
+ width: "1.6rem",
364
+ height: "1.6rem"
365
+ }),
366
+ /*#__PURE__*/ jsx(Typography, {
367
+ variant: "omega",
368
+ fontWeight: isHomeActive ? 'semiBold' : 'regular',
369
+ children: homeLabel
370
+ })
371
+ ]
397
372
  }),
398
- /*#__PURE__*/ jsx(Searchbar, {
399
- name: "search-folders",
400
- value: treeFilter,
401
- onChange: (event)=>setTreeFilter(event.target.value),
402
- onClear: ()=>setTreeFilter(''),
403
- clearLabel: formatMessage({
404
- id: 'clearLabel',
405
- defaultMessage: 'Clear'
406
- }),
407
- placeholder: formatMessage({
408
- id: getTranslationKey('sidebar.search.placeholder'),
409
- defaultMessage: 'Search folders'
410
- }),
411
- size: "S",
412
- children: formatMessage({
413
- id: getTranslationKey('sidebar.search.label'),
414
- defaultMessage: 'Search folders'
415
- })
416
- })
417
- ]
418
- })
419
- }),
420
- /*#__PURE__*/ jsxs(SidebarBody, {
421
- direction: "column",
422
- alignItems: "stretch",
423
- gap: 1,
424
- padding: 3,
425
- children: [
426
- /*#__PURE__*/ jsxs(RowButton, {
427
- ref: setHomeDropRef,
428
- type: "button",
429
- $isActive: isHomeActive,
430
- $isValidDropTarget: showHomeValidDropHighlight,
431
- $isInvalidDropCursor: showHomeInvalidDropCursor,
432
- $isMovePending: isMovePending,
433
- "aria-current": isHomeActive ? 'page' : undefined,
434
- onClick: ()=>onSelectFolder(null),
435
- "data-testid": "folder-tree-home",
436
- children: [
437
- /*#__PURE__*/ jsx(House, {
438
- "aria-hidden": true,
439
- width: "1.6rem",
440
- height: "1.6rem"
441
- }),
442
- /*#__PURE__*/ jsx(Typography, {
443
- variant: "omega",
444
- fontWeight: isHomeActive ? 'semiBold' : 'regular',
445
- children: homeLabel
446
- })
447
- ]
448
- }),
449
- /*#__PURE__*/ jsxs(Box, {
450
- marginTop: 4,
451
- children: [
452
- /*#__PURE__*/ jsxs(Flex, {
453
- alignItems: "center",
454
- gap: 1,
455
- paddingTop: 1,
456
- paddingBottom: 1,
457
- paddingLeft: 2,
458
- paddingRight: 2,
459
- marginBottom: 2,
460
- children: [
461
- /*#__PURE__*/ jsx(Folder, {
462
- "aria-hidden": true,
463
- width: "1.6rem",
464
- height: "1.6rem",
465
- fill: "neutral500"
466
- }),
467
- /*#__PURE__*/ jsx(Typography, {
468
- variant: "sigma",
469
- textColor: "neutral600",
470
- style: {
471
- textTransform: 'uppercase'
472
- },
373
+ /*#__PURE__*/ jsxs(Box, {
374
+ marginTop: 4,
375
+ children: [
376
+ /*#__PURE__*/ jsxs(Flex, {
377
+ alignItems: "center",
378
+ gap: 1,
379
+ paddingTop: 1,
380
+ paddingBottom: 1,
381
+ paddingLeft: 2,
382
+ paddingRight: 2,
383
+ marginBottom: 2,
384
+ children: [
385
+ /*#__PURE__*/ jsx(Folder, {
386
+ "aria-hidden": true,
387
+ width: "1.6rem",
388
+ height: "1.6rem",
389
+ fill: "neutral500"
390
+ }),
391
+ /*#__PURE__*/ jsx(Typography, {
392
+ variant: "sigma",
393
+ textColor: "neutral600",
394
+ style: {
395
+ textTransform: 'uppercase'
396
+ },
397
+ children: formatMessage({
398
+ id: getTranslationKey('sidebar.folders'),
399
+ defaultMessage: 'Folders'
400
+ })
401
+ })
402
+ ]
403
+ }),
404
+ isLoading ? // TODO: revisit loading state before revamp GA
405
+ /*#__PURE__*/ jsx(Flex, {
406
+ justifyContent: "center",
407
+ padding: 1,
408
+ paddingTop: 2,
409
+ children: /*#__PURE__*/ jsx(Loader, {
473
410
  children: formatMessage({
474
- id: getTranslationKey('sidebar.folders'),
475
- defaultMessage: 'Folders'
411
+ id: getTranslationKey('sidebar.tree.loading'),
412
+ defaultMessage: 'Loading folders...'
476
413
  })
477
414
  })
478
- ]
479
- }),
480
- isLoading ? // TODO: revisit loading state before revamp GA
481
- /*#__PURE__*/ jsx(Flex, {
482
- justifyContent: "center",
483
- padding: 1,
484
- paddingTop: 2,
485
- children: /*#__PURE__*/ jsx(Loader, {
486
- children: formatMessage({
487
- id: getTranslationKey('sidebar.tree.loading'),
488
- defaultMessage: 'Loading folders...'
489
- })
490
- })
491
- }) : isError ? // TODO: revisit error state before revamp GA
492
- /*#__PURE__*/ jsx(Box, {
493
- padding: 1,
494
- paddingTop: 2,
495
- children: /*#__PURE__*/ jsx(Typography, {
496
- variant: "pi",
497
- textColor: "danger600",
498
- children: formatMessage({
499
- id: getTranslationKey('sidebar.tree.error'),
500
- defaultMessage: 'Could not load folders.'
415
+ }) : isError ? // TODO: revisit error state before revamp GA
416
+ /*#__PURE__*/ jsx(Box, {
417
+ padding: 1,
418
+ paddingTop: 2,
419
+ children: /*#__PURE__*/ jsx(Typography, {
420
+ variant: "pi",
421
+ textColor: "danger600",
422
+ children: formatMessage({
423
+ id: getTranslationKey('sidebar.tree.error'),
424
+ defaultMessage: 'Could not load folders.'
425
+ })
501
426
  })
502
- })
503
- }) : visibleNodes.length === 0 ? // TODO: revisit empty state before revamp GA
504
- /*#__PURE__*/ jsx(Box, {
505
- padding: 1,
506
- paddingTop: 2,
507
- children: /*#__PURE__*/ jsx(Typography, {
508
- variant: "pi",
509
- textColor: "neutral500",
510
- children: trimmedFilter ? formatMessage({
511
- id: getTranslationKey('sidebar.tree.no-results'),
512
- defaultMessage: 'No folders match "{query}"'
513
- }, {
514
- query: trimmedFilter
515
- }) : formatMessage({
516
- id: getTranslationKey('sidebar.tree.empty'),
517
- defaultMessage: 'No folders yet'
427
+ }) : folderStructure.length === 0 ? // TODO: revisit empty state before revamp GA
428
+ /*#__PURE__*/ jsx(Box, {
429
+ padding: 1,
430
+ paddingTop: 2,
431
+ children: /*#__PURE__*/ jsx(Typography, {
432
+ variant: "pi",
433
+ textColor: "neutral500",
434
+ children: formatMessage({
435
+ id: getTranslationKey('sidebar.tree.empty'),
436
+ defaultMessage: 'No folders yet'
437
+ })
518
438
  })
439
+ }) : /*#__PURE__*/ jsx(NavList, {
440
+ children: folderStructure.map((node)=>/*#__PURE__*/ jsx(FolderTreeItem, {
441
+ node: node,
442
+ level: 0,
443
+ currentFolderId: currentFolderId,
444
+ showActiveFolder: showActiveFolder,
445
+ isExpanded: isExpanded,
446
+ onToggle: toggleExpanded,
447
+ onExpand: expandFolder,
448
+ onSelect: onSelectFolder,
449
+ isMovePending: isMovePending
450
+ }, node.id ?? node.name))
519
451
  })
520
- }) : /*#__PURE__*/ jsx(NavList, {
521
- children: visibleNodes.map((node)=>/*#__PURE__*/ jsx(FolderTreeItem, {
522
- node: node,
523
- level: 0,
524
- currentFolderId: currentFolderId,
525
- showActiveFolder: showActiveFolder,
526
- isExpanded: isExpandedForRender,
527
- onToggle: toggleExpanded,
528
- onExpand: expandFolder,
529
- onSelect: onSelectFolder,
530
- isMovePending: isMovePending
531
- }, node.id ?? node.name))
532
- })
533
- ]
534
- })
535
- ]
452
+ ]
453
+ })
454
+ ]
455
+ })
536
456
  })
537
457
  ]
538
458
  });
@@ -1 +1 @@
1
- {"version":3,"file":"FolderTree.mjs","sources":["../../../../../../../admin/src/future/pages/Assets/components/FolderTree/FolderTree.tsx"],"sourcesContent":["import { useCallback, useEffect, useLayoutEffect, useMemo, useRef, useState } from 'react';\n\nimport {\n Box,\n Flex,\n IconButton,\n Loader,\n Searchbar,\n Tooltip,\n Typography,\n useFilter,\n} from '@strapi/design-system';\nimport { ChevronDown, Folder as FolderIcon, House } from '@strapi/icons';\nimport { useIntl } from 'react-intl';\nimport { css, styled } from 'styled-components';\n\nimport { useGetFolderStructureQuery } from '../../../../services/folders';\nimport { getTranslationKey } from '../../../../utils/translations';\nimport { useAssetsDndOptional } from '../Dnd/AssetsDndProvider';\nimport { useFolderTreeDroppable } from '../Dnd/useFolderTreeDroppable';\n\nimport { filterFolderTree } from './filterFolderTree';\nimport { useSpringLoadedExpand } from './useSpringLoadedExpand';\n\nimport type { FolderNode } from '../../../../../../../shared/contracts/folders';\n\n/* -------------------------------------------------------------------------------------------------\n * RowButton — shared row styling aligned with admin SubNav.Link\n * -----------------------------------------------------------------------------------------------*/\n\nconst RowButton = styled.button<{\n $isActive: boolean;\n $isValidDropTarget?: boolean;\n $isInvalidDropCursor?: boolean;\n $isMovePending?: boolean;\n}>`\n display: flex;\n align-items: center;\n gap: ${({ theme }) => theme.spaces[2]};\n width: 100%;\n min-height: 3.2rem;\n padding: ${({ theme }) => `${theme.spaces[1]} ${theme.spaces[2]}`};\n border: 0;\n background: ${({ $isActive, $isValidDropTarget, theme }) => {\n if ($isValidDropTarget) {\n return theme.colors.primary100;\n }\n\n return $isActive ? theme.colors.primary100 : 'transparent';\n }};\n color: ${({ $isActive, theme }) =>\n $isActive ? theme.colors.primary700 : theme.colors.neutral800};\n border-radius: ${({ theme }) => theme.borderRadius};\n cursor: ${({ $isMovePending, $isInvalidDropCursor }) => {\n if ($isMovePending) {\n return 'wait';\n }\n\n return $isInvalidDropCursor ? 'not-allowed' : 'pointer';\n }};\n text-align: left;\n font: inherit;\n pointer-events: ${({ $isMovePending }) => ($isMovePending ? 'none' : 'auto')};\n\n ${({ $isValidDropTarget, theme }) =>\n $isValidDropTarget &&\n css`\n outline: 1px dashed ${theme.colors.primary600};\n outline-offset: -1px;\n `}\n\n &:hover {\n background: ${({ $isActive, $isValidDropTarget, theme }) => {\n if ($isValidDropTarget) {\n return theme.colors.primary100;\n }\n\n return $isActive ? theme.colors.primary100 : theme.colors.neutral100;\n }};\n }\n\n &:focus-visible {\n outline: 2px solid ${({ theme }) => theme.colors.primary600};\n outline-offset: -2px;\n }\n`;\n\nconst TreeRow = styled(Flex)<{\n $isValidDropTarget?: boolean;\n $isInvalidDropCursor?: boolean;\n $isMovePending?: boolean;\n}>`\n cursor: ${({ $isMovePending, $isInvalidDropCursor }) => {\n if ($isMovePending) {\n return 'wait';\n }\n\n return $isInvalidDropCursor ? 'not-allowed' : 'default';\n }};\n pointer-events: ${({ $isMovePending }) => ($isMovePending ? 'none' : 'auto')};\n border-radius: ${({ theme }) => theme.borderRadius};\n\n ${({ $isValidDropTarget, theme }) =>\n $isValidDropTarget &&\n css`\n background: ${theme.colors.primary100};\n outline: 1px dashed ${theme.colors.primary600};\n outline-offset: -1px;\n `}\n`;\n\n/* -------------------------------------------------------------------------------------------------\n * useExpandedFolders — local expand/collapse state\n * -----------------------------------------------------------------------------------------------*/\n\nconst findAncestorIds = (\n nodes: FolderNode[],\n targetId: number,\n trail: number[] = []\n): number[] | null => {\n for (const node of nodes) {\n if (node.id === targetId) {\n return trail;\n }\n\n if (node.children?.length) {\n const nextTrail = node.id != null ? [...trail, node.id] : trail;\n const found = findAncestorIds(node.children, targetId, nextTrail);\n if (found !== null) {\n return found;\n }\n }\n }\n\n return null;\n};\n\nconst useExpandedFolders = (folderStructure: FolderNode[], currentFolderId: number | null) => {\n const [expandedIds, setExpandedIds] = useState<Set<number>>(() => new Set());\n\n useEffect(() => {\n if (currentFolderId == null) {\n return;\n }\n\n const ancestors = findAncestorIds(folderStructure, currentFolderId);\n if (!ancestors || ancestors.length === 0) {\n return;\n }\n\n setExpandedIds((prev) => {\n const next = new Set(prev);\n let changed = false;\n for (const id of ancestors) {\n if (!next.has(id)) {\n next.add(id);\n changed = true;\n }\n }\n return changed ? next : prev;\n });\n }, [folderStructure, currentFolderId]);\n\n const toggleExpanded = useCallback((id: number) => {\n setExpandedIds((prev) => {\n const next = new Set(prev);\n if (next.has(id)) {\n next.delete(id);\n } else {\n next.add(id);\n }\n return next;\n });\n }, []);\n\n const expandFolder = useCallback((id: number) => {\n setExpandedIds((prev) => {\n if (prev.has(id)) {\n return prev;\n }\n\n const next = new Set(prev);\n next.add(id);\n return next;\n });\n }, []);\n\n const isExpanded = useCallback((id: number) => expandedIds.has(id), [expandedIds]);\n\n return { isExpanded, toggleExpanded, expandFolder };\n};\n\n/* -------------------------------------------------------------------------------------------------\n * TruncatedFolderName — tooltip when the label is ellipsized\n * -----------------------------------------------------------------------------------------------*/\n\nconst TruncatedFolderName = ({ name, isActive }: { name: string; isActive: boolean }) => {\n const textRef = useRef<HTMLSpanElement>(null);\n const [isTruncated, setIsTruncated] = useState(false);\n\n useLayoutEffect(() => {\n const el = textRef.current;\n if (!el) {\n return;\n }\n\n const checkTruncation = () => {\n setIsTruncated(el.scrollWidth > el.clientWidth);\n };\n\n checkTruncation();\n\n const observer = new ResizeObserver(checkTruncation);\n observer.observe(el);\n\n return () => observer.disconnect();\n }, [name]);\n\n const label = (\n <Typography\n ref={textRef}\n variant=\"omega\"\n fontWeight={isActive ? 'semiBold' : 'regular'}\n ellipsis\n >\n {name}\n </Typography>\n );\n\n if (isTruncated) {\n return <Tooltip label={name}>{label}</Tooltip>;\n }\n\n return label;\n};\n\n/* -------------------------------------------------------------------------------------------------\n * NavList — unstyled list for tree rows\n * -----------------------------------------------------------------------------------------------*/\n\nconst NavList = styled.ul`\n list-style: none;\n margin: 0;\n padding: 0;\n`;\n\n/* -------------------------------------------------------------------------------------------------\n * FolderTreeItem — single tree row (internal)\n * -----------------------------------------------------------------------------------------------*/\n\nconst INDENT_PER_LEVEL_REM = 1.6;\n\nconst RotatingChevron = styled(ChevronDown)<{ $expanded: boolean }>`\n transform: rotate(${({ $expanded }) => ($expanded ? '0deg' : '-90deg')});\n transition: transform 0.2s ease;\n`;\n\ninterface FolderTreeItemProps {\n node: FolderNode;\n level: number;\n currentFolderId: number | null;\n showActiveFolder: boolean;\n isExpanded: (id: number) => boolean;\n onToggle: (id: number) => void;\n onExpand: (id: number) => void;\n onSelect: (folderId: number) => void;\n isMovePending: boolean;\n}\n\ninterface FolderTreeItemInnerProps extends Omit<FolderTreeItemProps, 'node'> {\n id: number;\n name: string;\n folderChildren: FolderNode[];\n}\n\nconst FolderTreeItemInner = ({\n id,\n name,\n folderChildren,\n level,\n currentFolderId,\n showActiveFolder,\n isExpanded,\n onToggle,\n onExpand,\n onSelect,\n isMovePending,\n}: FolderTreeItemInnerProps) => {\n const { formatMessage } = useIntl();\n const hasChildren = folderChildren.length > 0;\n const isFolderExpanded = isExpanded(id);\n const isActive = showActiveFolder && currentFolderId === id;\n\n const {\n droppable: { setNodeRef },\n isOver,\n showValidDropHighlight,\n showInvalidDropCursor,\n } = useFolderTreeDroppable({ id, name });\n\n const handleExpand = useCallback(() => onExpand(id), [id, onExpand]);\n\n useSpringLoadedExpand({\n isOver,\n canExpand: hasChildren && !isFolderExpanded,\n onExpand: handleExpand,\n });\n\n // TODO: full `role=\"tree\"` + arrow-key treeview navigation before revamp GA\n // if an accessibility audit requires it (v1 is button rows only).\n return (\n <li>\n <TreeRow\n ref={setNodeRef}\n alignItems=\"center\"\n paddingLeft={`${level * INDENT_PER_LEVEL_REM}rem`}\n gap={1}\n $isValidDropTarget={showValidDropHighlight}\n $isInvalidDropCursor={showInvalidDropCursor}\n $isMovePending={isMovePending}\n >\n <IconButton\n label={formatMessage(\n {\n id: getTranslationKey(\n isFolderExpanded ? 'sidebar.tree.collapse' : 'sidebar.tree.expand'\n ),\n defaultMessage: isFolderExpanded ? 'Collapse {name}' : 'Expand {name}',\n },\n { name }\n )}\n onClick={(event: React.MouseEvent) => {\n event.stopPropagation();\n onToggle(id);\n }}\n variant=\"ghost\"\n withTooltip={false}\n aria-expanded={isFolderExpanded}\n >\n <RotatingChevron $expanded={isFolderExpanded} fill=\"neutral500\" />\n </IconButton>\n\n <Box flex=\"1\" minWidth={0}>\n <RowButton\n type=\"button\"\n $isActive={isActive}\n $isValidDropTarget={showValidDropHighlight}\n $isInvalidDropCursor={showInvalidDropCursor}\n $isMovePending={isMovePending}\n aria-current={isActive ? 'page' : undefined}\n onClick={() => onSelect(id)}\n data-testid={`folder-tree-node-${id}`}\n data-folder-id={id}\n >\n <TruncatedFolderName name={name} isActive={isActive} />\n </RowButton>\n </Box>\n </TreeRow>\n\n {hasChildren && isFolderExpanded && (\n <NavList>\n {folderChildren.map((child) => (\n <FolderTreeItem\n key={child.id ?? child.name}\n node={child}\n level={level + 1}\n currentFolderId={currentFolderId}\n showActiveFolder={showActiveFolder}\n isExpanded={isExpanded}\n onToggle={onToggle}\n onExpand={onExpand}\n onSelect={onSelect}\n isMovePending={isMovePending}\n />\n ))}\n </NavList>\n )}\n </li>\n );\n};\n\nconst FolderTreeItem = ({ node, ...props }: FolderTreeItemProps) => {\n if (node.id == null) {\n return null;\n }\n\n return (\n <FolderTreeItemInner\n {...props}\n id={node.id}\n name={node.name ?? ''}\n folderChildren={node.children ?? []}\n />\n );\n};\n\n/* -------------------------------------------------------------------------------------------------\n * FolderTree — public sidebar component\n * -----------------------------------------------------------------------------------------------*/\n\nconst SidebarNav = styled(Flex)`\n /* TODO: reconcile 25.6rem (Figma) with admin WIDTH_SIDE_NAVIGATION (23.2rem) */\n width: 25.6rem;\n height: 100%;\n min-height: 100%;\n background: ${({ theme }) => theme.colors.neutral0};\n flex-shrink: 0;\n flex-direction: column;\n border-right: 1px solid ${({ theme }) => theme.colors.neutral150};\n`;\n\nconst SidebarHeader = styled(Box)`\n flex-shrink: 0;\n border-bottom: 1px solid ${({ theme }) => theme.colors.neutral150};\n`;\n\nconst SidebarBody = styled(Flex)`\n flex: 1;\n min-height: 0;\n overflow-y: auto;\n`;\n\ninterface FolderTreeProps {\n currentFolderId: number | null;\n /**\n * Set to `false` while a global asset search is active: the results span the\n * whole library, so highlighting one folder would misrepresent them.\n * */\n showActiveFolder?: boolean;\n onSelectFolder: (folderId: number | null) => void;\n}\n\n/**\n * Left-rail navigation for the Media Library. Fetches folder structure internally\n * and renders:\n *\n * 1. A \"Media library\" title\n * 2. A filter input that prunes the tree to matching destinations\n * 3. A \"Home\" entry that clears the folder query param\n * 4. A \"FOLDERS\" section header\n * 5. The folder tree itself\n *\n * The filter is purely local: it never touches the URL and never affects the\n * asset list, which has its own independent search in the content toolbar.\n *\n * Presentational with respect to routing — navigation is delegated to the parent\n * via `onSelectFolder` so the URL stays the single source of truth (see\n * `useFolderNavigation`).\n */\nexport const FolderTree = ({\n currentFolderId,\n showActiveFolder = true,\n onSelectFolder,\n}: FolderTreeProps) => {\n const { formatMessage, locale } = useIntl();\n const { data: folderStructure = [], isLoading, isError } = useGetFolderStructureQuery();\n const { isExpanded, toggleExpanded, expandFolder } = useExpandedFolders(\n folderStructure,\n currentFolderId\n );\n const { isMovePending } = useAssetsDndOptional() ?? { isMovePending: false };\n\n const [treeFilter, setTreeFilter] = useState('');\n const { contains } = useFilter(locale, { sensitivity: 'base' });\n const trimmedFilter = treeFilter.trim();\n\n const { nodes: visibleNodes, expandedIds: filterExpandedIds } = useMemo(\n () =>\n trimmedFilter\n ? filterFolderTree(folderStructure, (name) => contains(name, trimmedFilter))\n : { nodes: folderStructure, expandedIds: [] },\n [folderStructure, trimmedFilter, contains]\n );\n\n // An override layered on top of the user's own expansion rather than written\n // into it, so clearing the filter restores exactly what they had open.\n const isExpandedForRender = useCallback(\n (id: number) => filterExpandedIds.includes(id) || isExpanded(id),\n [filterExpandedIds, isExpanded]\n );\n\n const isHomeActive = showActiveFolder && currentFolderId == null;\n const homeLabel = formatMessage({\n id: getTranslationKey('sidebar.home'),\n defaultMessage: 'Home',\n });\n\n const {\n droppable: { setNodeRef: setHomeDropRef },\n showValidDropHighlight: showHomeValidDropHighlight,\n showInvalidDropCursor: showHomeInvalidDropCursor,\n } = useFolderTreeDroppable({ id: null, name: homeLabel });\n\n return (\n <SidebarNav\n direction=\"column\"\n alignItems=\"stretch\"\n tag=\"nav\"\n aria-label={formatMessage({\n id: getTranslationKey('sidebar.tree.aria-label'),\n defaultMessage: 'Media library folders',\n })}\n >\n <SidebarHeader paddingTop={4} paddingBottom={4} paddingLeft={5} paddingRight={5}>\n <Flex direction=\"column\" alignItems=\"stretch\" gap={4}>\n <Typography variant=\"beta\" tag=\"h2\">\n {formatMessage({\n id: getTranslationKey('sidebar.title'),\n defaultMessage: 'Media library',\n })}\n </Typography>\n\n <Searchbar\n name=\"search-folders\"\n value={treeFilter}\n onChange={(event: React.ChangeEvent<HTMLInputElement>) =>\n setTreeFilter(event.target.value)\n }\n onClear={() => setTreeFilter('')}\n clearLabel={formatMessage({ id: 'clearLabel', defaultMessage: 'Clear' })}\n placeholder={formatMessage({\n id: getTranslationKey('sidebar.search.placeholder'),\n defaultMessage: 'Search folders',\n })}\n size=\"S\"\n >\n {formatMessage({\n id: getTranslationKey('sidebar.search.label'),\n defaultMessage: 'Search folders',\n })}\n </Searchbar>\n </Flex>\n </SidebarHeader>\n\n <SidebarBody direction=\"column\" alignItems=\"stretch\" gap={1} padding={3}>\n <RowButton\n ref={setHomeDropRef}\n type=\"button\"\n $isActive={isHomeActive}\n $isValidDropTarget={showHomeValidDropHighlight}\n $isInvalidDropCursor={showHomeInvalidDropCursor}\n $isMovePending={isMovePending}\n aria-current={isHomeActive ? 'page' : undefined}\n onClick={() => onSelectFolder(null)}\n data-testid=\"folder-tree-home\"\n >\n <House aria-hidden width=\"1.6rem\" height=\"1.6rem\" />\n <Typography variant=\"omega\" fontWeight={isHomeActive ? 'semiBold' : 'regular'}>\n {homeLabel}\n </Typography>\n </RowButton>\n\n <Box marginTop={4}>\n <Flex\n alignItems=\"center\"\n gap={1}\n paddingTop={1}\n paddingBottom={1}\n paddingLeft={2}\n paddingRight={2}\n marginBottom={2}\n >\n <FolderIcon aria-hidden width=\"1.6rem\" height=\"1.6rem\" fill=\"neutral500\" />\n <Typography\n variant=\"sigma\"\n textColor=\"neutral600\"\n style={{ textTransform: 'uppercase' }}\n >\n {formatMessage({\n id: getTranslationKey('sidebar.folders'),\n defaultMessage: 'Folders',\n })}\n </Typography>\n </Flex>\n\n {isLoading ? (\n // TODO: revisit loading state before revamp GA\n <Flex justifyContent=\"center\" padding={1} paddingTop={2}>\n <Loader>\n {formatMessage({\n id: getTranslationKey('sidebar.tree.loading'),\n defaultMessage: 'Loading folders...',\n })}\n </Loader>\n </Flex>\n ) : isError ? (\n // TODO: revisit error state before revamp GA\n <Box padding={1} paddingTop={2}>\n <Typography variant=\"pi\" textColor=\"danger600\">\n {formatMessage({\n id: getTranslationKey('sidebar.tree.error'),\n defaultMessage: 'Could not load folders.',\n })}\n </Typography>\n </Box>\n ) : visibleNodes.length === 0 ? (\n // TODO: revisit empty state before revamp GA\n <Box padding={1} paddingTop={2}>\n <Typography variant=\"pi\" textColor=\"neutral500\">\n {trimmedFilter\n ? formatMessage(\n {\n id: getTranslationKey('sidebar.tree.no-results'),\n defaultMessage: 'No folders match \"{query}\"',\n },\n { query: trimmedFilter }\n )\n : formatMessage({\n id: getTranslationKey('sidebar.tree.empty'),\n defaultMessage: 'No folders yet',\n })}\n </Typography>\n </Box>\n ) : (\n <NavList>\n {visibleNodes.map((node) => (\n <FolderTreeItem\n key={node.id ?? node.name}\n node={node}\n level={0}\n currentFolderId={currentFolderId}\n showActiveFolder={showActiveFolder}\n isExpanded={isExpandedForRender}\n onToggle={toggleExpanded}\n onExpand={expandFolder}\n onSelect={onSelectFolder}\n isMovePending={isMovePending}\n />\n ))}\n </NavList>\n )}\n </Box>\n </SidebarBody>\n </SidebarNav>\n );\n};\n"],"names":["RowButton","styled","button","theme","spaces","$isActive","$isValidDropTarget","colors","primary100","primary700","neutral800","borderRadius","$isMovePending","$isInvalidDropCursor","css","primary600","neutral100","TreeRow","Flex","findAncestorIds","nodes","targetId","trail","node","id","children","length","nextTrail","found","useExpandedFolders","folderStructure","currentFolderId","expandedIds","setExpandedIds","useState","Set","useEffect","ancestors","prev","next","changed","has","add","toggleExpanded","useCallback","delete","expandFolder","isExpanded","TruncatedFolderName","name","isActive","textRef","useRef","isTruncated","setIsTruncated","useLayoutEffect","el","current","checkTruncation","scrollWidth","clientWidth","observer","ResizeObserver","observe","disconnect","label","_jsx","Typography","ref","variant","fontWeight","ellipsis","Tooltip","NavList","ul","INDENT_PER_LEVEL_REM","RotatingChevron","ChevronDown","$expanded","FolderTreeItemInner","folderChildren","level","showActiveFolder","onToggle","onExpand","onSelect","isMovePending","formatMessage","useIntl","hasChildren","isFolderExpanded","droppable","setNodeRef","isOver","showValidDropHighlight","showInvalidDropCursor","useFolderTreeDroppable","handleExpand","useSpringLoadedExpand","canExpand","_jsxs","li","alignItems","paddingLeft","gap","IconButton","getTranslationKey","defaultMessage","onClick","event","stopPropagation","withTooltip","aria-expanded","fill","Box","flex","minWidth","type","aria-current","undefined","data-testid","data-folder-id","map","child","FolderTreeItem","props","SidebarNav","neutral0","neutral150","SidebarHeader","SidebarBody","FolderTree","onSelectFolder","locale","data","isLoading","isError","useGetFolderStructureQuery","useAssetsDndOptional","treeFilter","setTreeFilter","contains","useFilter","sensitivity","trimmedFilter","trim","visibleNodes","filterExpandedIds","useMemo","filterFolderTree","isExpandedForRender","includes","isHomeActive","homeLabel","setHomeDropRef","showHomeValidDropHighlight","showHomeInvalidDropCursor","direction","tag","aria-label","paddingTop","paddingBottom","paddingRight","Searchbar","value","onChange","target","onClear","clearLabel","placeholder","size","padding","House","aria-hidden","width","height","marginTop","marginBottom","FolderIcon","textColor","style","textTransform","justifyContent","Loader","query"],"mappings":"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"}
1
+ {"version":3,"file":"FolderTree.mjs","sources":["../../../../../../../admin/src/future/pages/Assets/components/FolderTree/FolderTree.tsx"],"sourcesContent":["import { useCallback, useEffect, useLayoutEffect, useRef, useState } from 'react';\n\nimport { SubNav } from '@strapi/admin/strapi-admin';\nimport { Box, Flex, IconButton, Loader, Tooltip, Typography } from '@strapi/design-system';\nimport { ChevronDown, Folder as FolderIcon, House } from '@strapi/icons';\nimport { useIntl } from 'react-intl';\nimport { css, styled } from 'styled-components';\n\nimport { useGetFolderStructureQuery } from '../../../../services/folders';\nimport { getTranslationKey } from '../../../../utils/translations';\nimport { useAssetsDndOptional } from '../Dnd/AssetsDndProvider';\nimport { useFolderTreeDroppable } from '../Dnd/useFolderTreeDroppable';\n\nimport { useSpringLoadedExpand } from './useSpringLoadedExpand';\n\nimport type { FolderNode } from '../../../../../../../shared/contracts/folders';\n\n/* -------------------------------------------------------------------------------------------------\n * RowButton — shared row styling aligned with admin SubNav.Link\n * -----------------------------------------------------------------------------------------------*/\n\nconst RowButton = styled.button<{\n $isActive: boolean;\n $isValidDropTarget?: boolean;\n $isInvalidDropCursor?: boolean;\n $isMovePending?: boolean;\n}>`\n display: flex;\n align-items: center;\n gap: ${({ theme }) => theme.spaces[2]};\n width: 100%;\n min-height: 3.2rem;\n padding: ${({ theme }) => `${theme.spaces[1]} ${theme.spaces[2]}`};\n border: 0;\n background: ${({ $isActive, $isValidDropTarget, theme }) => {\n if ($isValidDropTarget) {\n return theme.colors.primary100;\n }\n\n return $isActive ? theme.colors.primary100 : 'transparent';\n }};\n color: ${({ $isActive, theme }) =>\n $isActive ? theme.colors.primary700 : theme.colors.neutral800};\n border-radius: ${({ theme }) => theme.borderRadius};\n cursor: ${({ $isMovePending, $isInvalidDropCursor }) => {\n if ($isMovePending) {\n return 'wait';\n }\n\n return $isInvalidDropCursor ? 'not-allowed' : 'pointer';\n }};\n text-align: left;\n font: inherit;\n pointer-events: ${({ $isMovePending }) => ($isMovePending ? 'none' : 'auto')};\n\n ${({ $isValidDropTarget, theme }) =>\n $isValidDropTarget &&\n css`\n outline: 1px dashed ${theme.colors.primary600};\n outline-offset: -1px;\n `}\n\n &:hover {\n background: ${({ $isActive, $isValidDropTarget, theme }) => {\n if ($isValidDropTarget) {\n return theme.colors.primary100;\n }\n\n return $isActive ? theme.colors.primary100 : theme.colors.neutral100;\n }};\n }\n\n &:focus-visible {\n outline: 2px solid ${({ theme }) => theme.colors.primary600};\n outline-offset: -2px;\n }\n`;\n\nconst TreeRow = styled(Flex)<{\n $isValidDropTarget?: boolean;\n $isInvalidDropCursor?: boolean;\n $isMovePending?: boolean;\n}>`\n cursor: ${({ $isMovePending, $isInvalidDropCursor }) => {\n if ($isMovePending) {\n return 'wait';\n }\n\n return $isInvalidDropCursor ? 'not-allowed' : 'default';\n }};\n pointer-events: ${({ $isMovePending }) => ($isMovePending ? 'none' : 'auto')};\n border-radius: ${({ theme }) => theme.borderRadius};\n\n ${({ $isValidDropTarget, theme }) =>\n $isValidDropTarget &&\n css`\n background: ${theme.colors.primary100};\n outline: 1px dashed ${theme.colors.primary600};\n outline-offset: -1px;\n `}\n`;\n\n/* -------------------------------------------------------------------------------------------------\n * useExpandedFolders — local expand/collapse state\n * -----------------------------------------------------------------------------------------------*/\n\nconst findAncestorIds = (\n nodes: FolderNode[],\n targetId: number,\n trail: number[] = []\n): number[] | null => {\n for (const node of nodes) {\n if (node.id === targetId) {\n return trail;\n }\n\n if (node.children?.length) {\n const nextTrail = node.id != null ? [...trail, node.id] : trail;\n const found = findAncestorIds(node.children, targetId, nextTrail);\n if (found !== null) {\n return found;\n }\n }\n }\n\n return null;\n};\n\nconst useExpandedFolders = (folderStructure: FolderNode[], currentFolderId: number | null) => {\n const [expandedIds, setExpandedIds] = useState<Set<number>>(() => new Set());\n\n useEffect(() => {\n if (currentFolderId == null) {\n return;\n }\n\n const ancestors = findAncestorIds(folderStructure, currentFolderId);\n if (!ancestors || ancestors.length === 0) {\n return;\n }\n\n setExpandedIds((prev) => {\n const next = new Set(prev);\n let changed = false;\n for (const id of ancestors) {\n if (!next.has(id)) {\n next.add(id);\n changed = true;\n }\n }\n return changed ? next : prev;\n });\n }, [folderStructure, currentFolderId]);\n\n const toggleExpanded = useCallback((id: number) => {\n setExpandedIds((prev) => {\n const next = new Set(prev);\n if (next.has(id)) {\n next.delete(id);\n } else {\n next.add(id);\n }\n return next;\n });\n }, []);\n\n const expandFolder = useCallback((id: number) => {\n setExpandedIds((prev) => {\n if (prev.has(id)) {\n return prev;\n }\n\n const next = new Set(prev);\n next.add(id);\n return next;\n });\n }, []);\n\n const isExpanded = useCallback((id: number) => expandedIds.has(id), [expandedIds]);\n\n return { isExpanded, toggleExpanded, expandFolder };\n};\n\n/* -------------------------------------------------------------------------------------------------\n * TruncatedFolderName — tooltip when the label is ellipsized\n * -----------------------------------------------------------------------------------------------*/\n\nconst TruncatedFolderName = ({ name, isActive }: { name: string; isActive: boolean }) => {\n const textRef = useRef<HTMLSpanElement>(null);\n const [isTruncated, setIsTruncated] = useState(false);\n\n useLayoutEffect(() => {\n const el = textRef.current;\n if (!el) {\n return;\n }\n\n const checkTruncation = () => {\n setIsTruncated(el.scrollWidth > el.clientWidth);\n };\n\n checkTruncation();\n\n const observer = new ResizeObserver(checkTruncation);\n observer.observe(el);\n\n return () => observer.disconnect();\n }, [name]);\n\n const label = (\n <Typography\n ref={textRef}\n variant=\"omega\"\n fontWeight={isActive ? 'semiBold' : 'regular'}\n ellipsis\n >\n {name}\n </Typography>\n );\n\n if (isTruncated) {\n return <Tooltip label={name}>{label}</Tooltip>;\n }\n\n return label;\n};\n\n/* -------------------------------------------------------------------------------------------------\n * NavList — unstyled list for tree rows\n * -----------------------------------------------------------------------------------------------*/\n\nconst NavList = styled.ul`\n list-style: none;\n margin: 0;\n padding: 0;\n`;\n\n/* -------------------------------------------------------------------------------------------------\n * FolderTreeItem — single tree row (internal)\n * -----------------------------------------------------------------------------------------------*/\n\nconst INDENT_PER_LEVEL_REM = 1.6;\n\nconst RotatingChevron = styled(ChevronDown)<{ $expanded: boolean }>`\n transform: rotate(${({ $expanded }) => ($expanded ? '0deg' : '-90deg')});\n transition: transform 0.2s ease;\n`;\n\ninterface FolderTreeItemProps {\n node: FolderNode;\n level: number;\n currentFolderId: number | null;\n showActiveFolder: boolean;\n isExpanded: (id: number) => boolean;\n onToggle: (id: number) => void;\n onExpand: (id: number) => void;\n onSelect: (folderId: number) => void;\n isMovePending: boolean;\n}\n\ninterface FolderTreeItemInnerProps extends Omit<FolderTreeItemProps, 'node'> {\n id: number;\n name: string;\n folderChildren: FolderNode[];\n}\n\nconst FolderTreeItemInner = ({\n id,\n name,\n folderChildren,\n level,\n currentFolderId,\n showActiveFolder,\n isExpanded,\n onToggle,\n onExpand,\n onSelect,\n isMovePending,\n}: FolderTreeItemInnerProps) => {\n const { formatMessage } = useIntl();\n const hasChildren = folderChildren.length > 0;\n const isFolderExpanded = isExpanded(id);\n const isActive = showActiveFolder && currentFolderId === id;\n\n const {\n droppable: { setNodeRef },\n isOver,\n showValidDropHighlight,\n showInvalidDropCursor,\n } = useFolderTreeDroppable({ id, name });\n\n const handleExpand = useCallback(() => onExpand(id), [id, onExpand]);\n\n useSpringLoadedExpand({\n isOver,\n canExpand: hasChildren && !isFolderExpanded,\n onExpand: handleExpand,\n });\n\n // TODO: full `role=\"tree\"` + arrow-key treeview navigation before revamp GA\n // if an accessibility audit requires it (v1 is button rows only).\n return (\n <li>\n <TreeRow\n ref={setNodeRef}\n alignItems=\"center\"\n paddingLeft={`${level * INDENT_PER_LEVEL_REM}rem`}\n gap={1}\n $isValidDropTarget={showValidDropHighlight}\n $isInvalidDropCursor={showInvalidDropCursor}\n $isMovePending={isMovePending}\n >\n <IconButton\n label={formatMessage(\n {\n id: getTranslationKey(\n isFolderExpanded ? 'sidebar.tree.collapse' : 'sidebar.tree.expand'\n ),\n defaultMessage: isFolderExpanded ? 'Collapse {name}' : 'Expand {name}',\n },\n { name }\n )}\n onClick={(event: React.MouseEvent) => {\n event.stopPropagation();\n onToggle(id);\n }}\n variant=\"ghost\"\n withTooltip={false}\n aria-expanded={isFolderExpanded}\n >\n <RotatingChevron $expanded={isFolderExpanded} fill=\"neutral500\" />\n </IconButton>\n\n <Box flex=\"1\" minWidth={0}>\n <RowButton\n type=\"button\"\n $isActive={isActive}\n $isValidDropTarget={showValidDropHighlight}\n $isInvalidDropCursor={showInvalidDropCursor}\n $isMovePending={isMovePending}\n aria-current={isActive ? 'page' : undefined}\n onClick={() => onSelect(id)}\n data-testid={`folder-tree-node-${id}`}\n data-folder-id={id}\n >\n <TruncatedFolderName name={name} isActive={isActive} />\n </RowButton>\n </Box>\n </TreeRow>\n\n {hasChildren && isFolderExpanded && (\n <NavList>\n {folderChildren.map((child) => (\n <FolderTreeItem\n key={child.id ?? child.name}\n node={child}\n level={level + 1}\n currentFolderId={currentFolderId}\n showActiveFolder={showActiveFolder}\n isExpanded={isExpanded}\n onToggle={onToggle}\n onExpand={onExpand}\n onSelect={onSelect}\n isMovePending={isMovePending}\n />\n ))}\n </NavList>\n )}\n </li>\n );\n};\n\nconst FolderTreeItem = ({ node, ...props }: FolderTreeItemProps) => {\n if (node.id == null) {\n return null;\n }\n\n return (\n <FolderTreeItemInner\n {...props}\n id={node.id}\n name={node.name ?? ''}\n folderChildren={node.children ?? []}\n />\n );\n};\n\n/* -------------------------------------------------------------------------------------------------\n * FolderTree — public sidebar component\n * -----------------------------------------------------------------------------------------------*/\n\ninterface FolderTreeProps {\n currentFolderId: number | null;\n /**\n * Set to `false` while a global asset search is active: the results span the\n * whole library, so highlighting one folder would misrepresent them.\n * */\n showActiveFolder?: boolean;\n onSelectFolder: (folderId: number | null) => void;\n}\n\n/**\n * Left-rail navigation for the Media Library. Fetches folder structure internally\n * and renders:\n *\n * 1. A \"Media library\" title\n * 2. A filter input that prunes the tree to matching destinations\n * 3. A \"Home\" entry that clears the folder query param\n * 4. A \"FOLDERS\" section header\n * 5. The folder tree itself\n *\n * The filter is purely local: it never touches the URL and never affects the\n * asset list, which has its own independent search in the content toolbar.\n *\n * Presentational with respect to routing — navigation is delegated to the parent\n * via `onSelectFolder` so the URL stays the single source of truth (see\n * `useFolderNavigation`).\n */\nexport const FolderTree = ({\n currentFolderId,\n showActiveFolder = true,\n onSelectFolder,\n}: FolderTreeProps) => {\n const { formatMessage } = useIntl();\n const { data: folderStructure = [], isLoading, isError } = useGetFolderStructureQuery();\n const { isExpanded, toggleExpanded, expandFolder } = useExpandedFolders(\n folderStructure,\n currentFolderId\n );\n const { isMovePending } = useAssetsDndOptional() ?? { isMovePending: false };\n\n const isHomeActive = showActiveFolder && currentFolderId == null;\n const homeLabel = formatMessage({\n id: getTranslationKey('sidebar.home'),\n defaultMessage: 'Home',\n });\n\n const {\n droppable: { setNodeRef: setHomeDropRef },\n showValidDropHighlight: showHomeValidDropHighlight,\n showInvalidDropCursor: showHomeInvalidDropCursor,\n } = useFolderTreeDroppable({ id: null, name: homeLabel });\n\n return (\n <SubNav.Main\n aria-label={formatMessage({\n id: getTranslationKey('sidebar.tree.aria-label'),\n defaultMessage: 'Media library folders',\n })}\n >\n <SubNav.Header\n label={formatMessage({\n id: getTranslationKey('sidebar.title'),\n defaultMessage: 'Media library',\n })}\n />\n\n <SubNav.Content>\n <Flex direction=\"column\" alignItems=\"stretch\" gap={1} padding={3}>\n <RowButton\n ref={setHomeDropRef}\n type=\"button\"\n $isActive={isHomeActive}\n $isValidDropTarget={showHomeValidDropHighlight}\n $isInvalidDropCursor={showHomeInvalidDropCursor}\n $isMovePending={isMovePending}\n aria-current={isHomeActive ? 'page' : undefined}\n onClick={() => onSelectFolder(null)}\n data-testid=\"folder-tree-home\"\n >\n <House aria-hidden width=\"1.6rem\" height=\"1.6rem\" />\n <Typography variant=\"omega\" fontWeight={isHomeActive ? 'semiBold' : 'regular'}>\n {homeLabel}\n </Typography>\n </RowButton>\n\n <Box marginTop={4}>\n <Flex\n alignItems=\"center\"\n gap={1}\n paddingTop={1}\n paddingBottom={1}\n paddingLeft={2}\n paddingRight={2}\n marginBottom={2}\n >\n <FolderIcon aria-hidden width=\"1.6rem\" height=\"1.6rem\" fill=\"neutral500\" />\n <Typography\n variant=\"sigma\"\n textColor=\"neutral600\"\n style={{ textTransform: 'uppercase' }}\n >\n {formatMessage({\n id: getTranslationKey('sidebar.folders'),\n defaultMessage: 'Folders',\n })}\n </Typography>\n </Flex>\n\n {isLoading ? (\n // TODO: revisit loading state before revamp GA\n <Flex justifyContent=\"center\" padding={1} paddingTop={2}>\n <Loader>\n {formatMessage({\n id: getTranslationKey('sidebar.tree.loading'),\n defaultMessage: 'Loading folders...',\n })}\n </Loader>\n </Flex>\n ) : isError ? (\n // TODO: revisit error state before revamp GA\n <Box padding={1} paddingTop={2}>\n <Typography variant=\"pi\" textColor=\"danger600\">\n {formatMessage({\n id: getTranslationKey('sidebar.tree.error'),\n defaultMessage: 'Could not load folders.',\n })}\n </Typography>\n </Box>\n ) : folderStructure.length === 0 ? (\n // TODO: revisit empty state before revamp GA\n <Box padding={1} paddingTop={2}>\n <Typography variant=\"pi\" textColor=\"neutral500\">\n {formatMessage({\n id: getTranslationKey('sidebar.tree.empty'),\n defaultMessage: 'No folders yet',\n })}\n </Typography>\n </Box>\n ) : (\n <NavList>\n {folderStructure.map((node) => (\n <FolderTreeItem\n key={node.id ?? node.name}\n node={node}\n level={0}\n currentFolderId={currentFolderId}\n showActiveFolder={showActiveFolder}\n isExpanded={isExpanded}\n onToggle={toggleExpanded}\n onExpand={expandFolder}\n onSelect={onSelectFolder}\n isMovePending={isMovePending}\n />\n ))}\n </NavList>\n )}\n </Box>\n </Flex>\n </SubNav.Content>\n </SubNav.Main>\n );\n};\n"],"names":["RowButton","styled","button","theme","spaces","$isActive","$isValidDropTarget","colors","primary100","primary700","neutral800","borderRadius","$isMovePending","$isInvalidDropCursor","css","primary600","neutral100","TreeRow","Flex","findAncestorIds","nodes","targetId","trail","node","id","children","length","nextTrail","found","useExpandedFolders","folderStructure","currentFolderId","expandedIds","setExpandedIds","useState","Set","useEffect","ancestors","prev","next","changed","has","add","toggleExpanded","useCallback","delete","expandFolder","isExpanded","TruncatedFolderName","name","isActive","textRef","useRef","isTruncated","setIsTruncated","useLayoutEffect","el","current","checkTruncation","scrollWidth","clientWidth","observer","ResizeObserver","observe","disconnect","label","_jsx","Typography","ref","variant","fontWeight","ellipsis","Tooltip","NavList","ul","INDENT_PER_LEVEL_REM","RotatingChevron","ChevronDown","$expanded","FolderTreeItemInner","folderChildren","level","showActiveFolder","onToggle","onExpand","onSelect","isMovePending","formatMessage","useIntl","hasChildren","isFolderExpanded","droppable","setNodeRef","isOver","showValidDropHighlight","showInvalidDropCursor","useFolderTreeDroppable","handleExpand","useSpringLoadedExpand","canExpand","_jsxs","li","alignItems","paddingLeft","gap","IconButton","getTranslationKey","defaultMessage","onClick","event","stopPropagation","withTooltip","aria-expanded","fill","Box","flex","minWidth","type","aria-current","undefined","data-testid","data-folder-id","map","child","FolderTreeItem","props","FolderTree","onSelectFolder","data","isLoading","isError","useGetFolderStructureQuery","useAssetsDndOptional","isHomeActive","homeLabel","setHomeDropRef","showHomeValidDropHighlight","showHomeInvalidDropCursor","SubNav","Main","aria-label","Header","Content","direction","padding","House","aria-hidden","width","height","marginTop","paddingTop","paddingBottom","paddingRight","marginBottom","FolderIcon","textColor","style","textTransform","justifyContent","Loader"],"mappings":"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"}
@@ -0,0 +1,47 @@
1
+ 'use strict';
2
+
3
+ var React = require('react');
4
+
5
+ const BusyAssetsContext = React.createContext(null);
6
+ const BusyAssetsProvider = ({ children })=>{
7
+ const [busyById, setBusyById] = React.useState({});
8
+ const markBusy = React.useCallback((id, message)=>{
9
+ setBusyById((prev)=>({
10
+ ...prev,
11
+ [id]: message
12
+ }));
13
+ return ()=>setBusyById((prev)=>{
14
+ // Rebuild without the key rather than mutating — the value is compared
15
+ // by identity downstream.
16
+ const { [id]: _released, ...rest } = prev;
17
+ return rest;
18
+ });
19
+ }, []);
20
+ const isBusy = React.useCallback((id)=>busyById[id] !== undefined, [
21
+ busyById
22
+ ]);
23
+ const getBusyMessage = React.useCallback((id)=>busyById[id] ?? null, [
24
+ busyById
25
+ ]);
26
+ const value = React.useMemo(()=>({
27
+ isBusy,
28
+ getBusyMessage,
29
+ markBusy
30
+ }), [
31
+ isBusy,
32
+ getBusyMessage,
33
+ markBusy
34
+ ]);
35
+ return React.createElement(BusyAssetsContext.Provider, {
36
+ value
37
+ }, children);
38
+ };
39
+ /**
40
+ * Optional by design: `AssetActionsMenu`, `AssetRow` and `AssetCard` are also
41
+ * rendered in tests and in the asset picker, outside this provider. Without it
42
+ * the mutation still runs, it just shows no row-level feedback.
43
+ */ const useBusyAssetsOptional = ()=>React.useContext(BusyAssetsContext);
44
+
45
+ exports.BusyAssetsProvider = BusyAssetsProvider;
46
+ exports.useBusyAssetsOptional = useBusyAssetsOptional;
47
+ //# sourceMappingURL=useBusyAssets.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useBusyAssets.js","sources":["../../../../../../admin/src/future/pages/Assets/hooks/useBusyAssets.ts"],"sourcesContent":["import { createContext, createElement, useCallback, useContext, useMemo, useState } from 'react';\nimport type { ReactNode } from 'react';\n\n/**\n * Which assets have a long-running mutation in flight, so the list can show it\n * on the item itself.\n *\n * The mutation stays where it is triggered — the row's \"...\" menu — but the\n * feedback has to render on the row or card, which is an ancestor of it. The\n * menu sits in a leaf `<td>` (table) / footer `Flex` (grid), so an overlay\n * mounted there would cover the button and nothing else. Rather than hoist the\n * mutation up into both `AssetRow` and `AssetCard` (duplicating it, and moving\n * it away from the control that owns it), the busy flag travels up through\n * context and the ancestor renders the overlay.\n *\n * Scoped per asset id rather than a single boolean: a replace on one row must\n * not blank out every other row. Modelled on `isMovePending` in\n * `AssetsDndProvider`, which does the same thing for drag-moves — that one is\n * list-wide because a move genuinely blocks the whole list.\n */\nexport interface BusyAssets {\n /** Whether this asset has a mutation in flight. */\n isBusy: (id: number) => boolean;\n /** The message to show while it is, or `null`. */\n getBusyMessage: (id: number) => string | null;\n /**\n * Marks the asset busy and returns the release function. Pair it with\n * `try`/`finally` so the flag clears on failure too.\n */\n markBusy: (id: number, message: string) => () => void;\n}\n\nconst BusyAssetsContext = createContext<BusyAssets | null>(null);\n\nexport const BusyAssetsProvider = ({ children }: { children: ReactNode }) => {\n const [busyById, setBusyById] = useState<Record<number, string>>({});\n\n const markBusy = useCallback((id: number, message: string) => {\n setBusyById((prev) => ({ ...prev, [id]: message }));\n\n return () =>\n setBusyById((prev) => {\n // Rebuild without the key rather than mutating — the value is compared\n // by identity downstream.\n const { [id]: _released, ...rest } = prev;\n return rest;\n });\n }, []);\n\n const isBusy = useCallback((id: number) => busyById[id] !== undefined, [busyById]);\n\n const getBusyMessage = useCallback((id: number) => busyById[id] ?? null, [busyById]);\n\n const value = useMemo<BusyAssets>(\n () => ({ isBusy, getBusyMessage, markBusy }),\n [isBusy, getBusyMessage, markBusy]\n );\n\n return createElement(BusyAssetsContext.Provider, { value }, children);\n};\n\n/**\n * Optional by design: `AssetActionsMenu`, `AssetRow` and `AssetCard` are also\n * rendered in tests and in the asset picker, outside this provider. Without it\n * the mutation still runs, it just shows no row-level feedback.\n */\nexport const useBusyAssetsOptional = () => useContext(BusyAssetsContext);\n"],"names":["BusyAssetsContext","createContext","BusyAssetsProvider","children","busyById","setBusyById","useState","markBusy","useCallback","id","message","prev","_released","rest","isBusy","undefined","getBusyMessage","value","useMemo","createElement","Provider","useBusyAssetsOptional","useContext"],"mappings":";;;;AAgCA,MAAMA,oBAAoBC,mBAAAA,CAAiC,IAAA,CAAA;AAEpD,MAAMC,kBAAAA,GAAqB,CAAC,EAAEC,QAAQ,EAA2B,GAAA;AACtE,IAAA,MAAM,CAACC,QAAAA,EAAUC,WAAAA,CAAY,GAAGC,eAAiC,EAAC,CAAA;IAElE,MAAMC,QAAAA,GAAWC,iBAAAA,CAAY,CAACC,EAAAA,EAAYC,OAAAA,GAAAA;QACxCL,WAAAA,CAAY,CAACM,QAAU;AAAE,gBAAA,GAAGA,IAAI;AAAE,gBAAA,CAACF,KAAKC;aAAQ,CAAA,CAAA;QAEhD,OAAO,IACLL,YAAY,CAACM,IAAAA,GAAAA;;;gBAGX,MAAM,EAAE,CAACF,EAAAA,GAAKG,SAAS,EAAE,GAAGC,MAAM,GAAGF,IAAAA;gBACrC,OAAOE,IAAAA;AACT,YAAA,CAAA,CAAA;AACJ,IAAA,CAAA,EAAG,EAAE,CAAA;IAEL,MAAMC,MAAAA,GAASN,kBAAY,CAACC,EAAAA,GAAeL,QAAQ,CAACK,EAAAA,CAAG,KAAKM,SAAAA,EAAW;AAACX,QAAAA;AAAS,KAAA,CAAA;IAEjF,MAAMY,cAAAA,GAAiBR,kBAAY,CAACC,EAAAA,GAAeL,QAAQ,CAACK,EAAAA,CAAG,IAAI,IAAA,EAAM;AAACL,QAAAA;AAAS,KAAA,CAAA;IAEnF,MAAMa,KAAAA,GAAQC,aAAAA,CACZ,KAAO;AAAEJ,YAAAA,MAAAA;AAAQE,YAAAA,cAAAA;AAAgBT,YAAAA;AAAS,SAAA,CAAA,EAC1C;AAACO,QAAAA,MAAAA;AAAQE,QAAAA,cAAAA;AAAgBT,QAAAA;AAAS,KAAA,CAAA;IAGpC,OAAOY,mBAAAA,CAAcnB,iBAAAA,CAAkBoB,QAAQ,EAAE;AAAEH,QAAAA;KAAM,EAAGd,QAAAA,CAAAA;AAC9D;AAEA;;;;AAIC,IACM,MAAMkB,qBAAAA,GAAwB,IAAMC,iBAAWtB,iBAAAA;;;;;"}