@strapi/upload 5.51.2 → 5.52.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (253) hide show
  1. package/dist/admin/future/App.js +3 -3
  2. package/dist/admin/future/App.js.map +1 -1
  3. package/dist/admin/future/App.mjs +4 -4
  4. package/dist/admin/future/App.mjs.map +1 -1
  5. package/dist/admin/future/components/BetaNotice.js +72 -0
  6. package/dist/admin/future/components/BetaNotice.js.map +1 -0
  7. package/dist/admin/future/components/BetaNotice.mjs +70 -0
  8. package/dist/admin/future/components/BetaNotice.mjs.map +1 -0
  9. package/dist/admin/future/components/Drawer.js +16 -3
  10. package/dist/admin/future/components/Drawer.js.map +1 -1
  11. package/dist/admin/future/components/Drawer.mjs +16 -3
  12. package/dist/admin/future/components/Drawer.mjs.map +1 -1
  13. package/dist/admin/future/components/TruncatedText.js +76 -0
  14. package/dist/admin/future/components/TruncatedText.js.map +1 -0
  15. package/dist/admin/future/components/TruncatedText.mjs +74 -0
  16. package/dist/admin/future/components/TruncatedText.mjs.map +1 -0
  17. package/dist/admin/future/hooks/useAIMetadataEnabled.js +39 -0
  18. package/dist/admin/future/hooks/useAIMetadataEnabled.js.map +1 -0
  19. package/dist/admin/future/hooks/useAIMetadataEnabled.mjs +37 -0
  20. package/dist/admin/future/hooks/useAIMetadataEnabled.mjs.map +1 -0
  21. package/dist/admin/future/hooks/useTracking.js +57 -0
  22. package/dist/admin/future/hooks/useTracking.js.map +1 -0
  23. package/dist/admin/future/hooks/useTracking.mjs +53 -0
  24. package/dist/admin/future/hooks/useTracking.mjs.map +1 -0
  25. package/dist/admin/future/pages/Assets/AssetsPage.js +328 -139
  26. package/dist/admin/future/pages/Assets/AssetsPage.js.map +1 -1
  27. package/dist/admin/future/pages/Assets/AssetsPage.mjs +332 -143
  28. package/dist/admin/future/pages/Assets/AssetsPage.mjs.map +1 -1
  29. package/dist/admin/future/pages/Assets/components/ActionsMenuContent.js +46 -0
  30. package/dist/admin/future/pages/Assets/components/ActionsMenuContent.js.map +1 -0
  31. package/dist/admin/future/pages/Assets/components/ActionsMenuContent.mjs +44 -0
  32. package/dist/admin/future/pages/Assets/components/ActionsMenuContent.mjs.map +1 -0
  33. package/dist/admin/future/pages/Assets/components/AssetActionsMenu.js +328 -0
  34. package/dist/admin/future/pages/Assets/components/AssetActionsMenu.js.map +1 -0
  35. package/dist/admin/future/pages/Assets/components/AssetActionsMenu.mjs +326 -0
  36. package/dist/admin/future/pages/Assets/components/AssetActionsMenu.mjs.map +1 -0
  37. package/dist/admin/future/pages/Assets/components/AssetDetails/AssetCropEditor.js +35 -14
  38. package/dist/admin/future/pages/Assets/components/AssetDetails/AssetCropEditor.js.map +1 -1
  39. package/dist/admin/future/pages/Assets/components/AssetDetails/AssetCropEditor.mjs +35 -14
  40. package/dist/admin/future/pages/Assets/components/AssetDetails/AssetCropEditor.mjs.map +1 -1
  41. package/dist/admin/future/pages/Assets/components/AssetDetails/AssetDetailsDrawer.js +74 -53
  42. package/dist/admin/future/pages/Assets/components/AssetDetails/AssetDetailsDrawer.js.map +1 -1
  43. package/dist/admin/future/pages/Assets/components/AssetDetails/AssetDetailsDrawer.mjs +74 -54
  44. package/dist/admin/future/pages/Assets/components/AssetDetails/AssetDetailsDrawer.mjs.map +1 -1
  45. package/dist/admin/future/pages/Assets/components/AssetsGrid.js +92 -28
  46. package/dist/admin/future/pages/Assets/components/AssetsGrid.js.map +1 -1
  47. package/dist/admin/future/pages/Assets/components/AssetsGrid.mjs +94 -30
  48. package/dist/admin/future/pages/Assets/components/AssetsGrid.mjs.map +1 -1
  49. package/dist/admin/future/pages/Assets/components/AssetsSearchInput.js +26 -4
  50. package/dist/admin/future/pages/Assets/components/AssetsSearchInput.js.map +1 -1
  51. package/dist/admin/future/pages/Assets/components/AssetsSearchInput.mjs +27 -5
  52. package/dist/admin/future/pages/Assets/components/AssetsSearchInput.mjs.map +1 -1
  53. package/dist/admin/future/pages/Assets/components/AssetsTable.js +172 -60
  54. package/dist/admin/future/pages/Assets/components/AssetsTable.js.map +1 -1
  55. package/dist/admin/future/pages/Assets/components/AssetsTable.mjs +175 -63
  56. package/dist/admin/future/pages/Assets/components/AssetsTable.mjs.map +1 -1
  57. package/dist/admin/future/pages/Assets/components/BulkActionsBar.js +64 -132
  58. package/dist/admin/future/pages/Assets/components/BulkActionsBar.js.map +1 -1
  59. package/dist/admin/future/pages/Assets/components/BulkActionsBar.mjs +64 -132
  60. package/dist/admin/future/pages/Assets/components/BulkActionsBar.mjs.map +1 -1
  61. package/dist/admin/future/pages/Assets/components/BulkMoveDialog.js +123 -76
  62. package/dist/admin/future/pages/Assets/components/BulkMoveDialog.js.map +1 -1
  63. package/dist/admin/future/pages/Assets/components/BulkMoveDialog.mjs +126 -79
  64. package/dist/admin/future/pages/Assets/components/BulkMoveDialog.mjs.map +1 -1
  65. package/dist/admin/future/pages/Assets/components/BusyOverlay.js +36 -0
  66. package/dist/admin/future/pages/Assets/components/BusyOverlay.js.map +1 -0
  67. package/dist/admin/future/pages/Assets/components/BusyOverlay.mjs +34 -0
  68. package/dist/admin/future/pages/Assets/components/BusyOverlay.mjs.map +1 -0
  69. package/dist/admin/future/pages/Assets/components/DeleteItemsDialog.js +131 -0
  70. package/dist/admin/future/pages/Assets/components/DeleteItemsDialog.js.map +1 -0
  71. package/dist/admin/future/pages/Assets/components/DeleteItemsDialog.mjs +129 -0
  72. package/dist/admin/future/pages/Assets/components/DeleteItemsDialog.mjs.map +1 -0
  73. package/dist/admin/future/pages/Assets/components/Dnd/AssetsDndProvider.js +27 -17
  74. package/dist/admin/future/pages/Assets/components/Dnd/AssetsDndProvider.js.map +1 -1
  75. package/dist/admin/future/pages/Assets/components/Dnd/AssetsDndProvider.mjs +28 -18
  76. package/dist/admin/future/pages/Assets/components/Dnd/AssetsDndProvider.mjs.map +1 -1
  77. package/dist/admin/future/pages/Assets/components/Dnd/buildDragSet.js +28 -31
  78. package/dist/admin/future/pages/Assets/components/Dnd/buildDragSet.js.map +1 -1
  79. package/dist/admin/future/pages/Assets/components/Dnd/buildDragSet.mjs +28 -31
  80. package/dist/admin/future/pages/Assets/components/Dnd/buildDragSet.mjs.map +1 -1
  81. package/dist/admin/future/pages/Assets/components/Dnd/useAssetDnd.js +10 -15
  82. package/dist/admin/future/pages/Assets/components/Dnd/useAssetDnd.js.map +1 -1
  83. package/dist/admin/future/pages/Assets/components/Dnd/useAssetDnd.mjs +10 -15
  84. package/dist/admin/future/pages/Assets/components/Dnd/useAssetDnd.mjs.map +1 -1
  85. package/dist/admin/future/pages/Assets/components/FilterBadges.js +13 -4
  86. package/dist/admin/future/pages/Assets/components/FilterBadges.js.map +1 -1
  87. package/dist/admin/future/pages/Assets/components/FilterBadges.mjs +13 -4
  88. package/dist/admin/future/pages/Assets/components/FilterBadges.mjs.map +1 -1
  89. package/dist/admin/future/pages/Assets/components/FilterMenu.js +259 -63
  90. package/dist/admin/future/pages/Assets/components/FilterMenu.js.map +1 -1
  91. package/dist/admin/future/pages/Assets/components/FilterMenu.mjs +262 -66
  92. package/dist/admin/future/pages/Assets/components/FilterMenu.mjs.map +1 -1
  93. package/dist/admin/future/pages/Assets/components/FolderActionsMenu.js +146 -0
  94. package/dist/admin/future/pages/Assets/components/FolderActionsMenu.js.map +1 -0
  95. package/dist/admin/future/pages/Assets/components/FolderActionsMenu.mjs +144 -0
  96. package/dist/admin/future/pages/Assets/components/FolderActionsMenu.mjs.map +1 -0
  97. package/dist/admin/future/pages/Assets/components/{CreateFolderDialog.js → FolderFormDialog.js} +62 -16
  98. package/dist/admin/future/pages/Assets/components/FolderFormDialog.js.map +1 -0
  99. package/dist/admin/future/pages/Assets/components/{CreateFolderDialog.mjs → FolderFormDialog.mjs} +64 -18
  100. package/dist/admin/future/pages/Assets/components/FolderFormDialog.mjs.map +1 -0
  101. package/dist/admin/future/pages/Assets/components/FolderTree/FolderTree.js +132 -229
  102. package/dist/admin/future/pages/Assets/components/FolderTree/FolderTree.js.map +1 -1
  103. package/dist/admin/future/pages/Assets/components/FolderTree/FolderTree.mjs +135 -232
  104. package/dist/admin/future/pages/Assets/components/FolderTree/FolderTree.mjs.map +1 -1
  105. package/dist/admin/future/pages/Assets/components/SortMenu.js +14 -0
  106. package/dist/admin/future/pages/Assets/components/SortMenu.js.map +1 -1
  107. package/dist/admin/future/pages/Assets/components/SortMenu.mjs +14 -0
  108. package/dist/admin/future/pages/Assets/components/SortMenu.mjs.map +1 -1
  109. package/dist/admin/future/pages/Assets/hooks/useAssetSelection.js +5 -0
  110. package/dist/admin/future/pages/Assets/hooks/useAssetSelection.js.map +1 -1
  111. package/dist/admin/future/pages/Assets/hooks/useAssetSelection.mjs +6 -1
  112. package/dist/admin/future/pages/Assets/hooks/useAssetSelection.mjs.map +1 -1
  113. package/dist/admin/future/pages/Assets/hooks/useBusyAssets.js +47 -0
  114. package/dist/admin/future/pages/Assets/hooks/useBusyAssets.js.map +1 -0
  115. package/dist/admin/future/pages/Assets/hooks/useBusyAssets.mjs +44 -0
  116. package/dist/admin/future/pages/Assets/hooks/useBusyAssets.mjs.map +1 -0
  117. package/dist/admin/future/pages/Assets/hooks/useInfiniteAssets.js +203 -62
  118. package/dist/admin/future/pages/Assets/hooks/useInfiniteAssets.js.map +1 -1
  119. package/dist/admin/future/pages/Assets/hooks/useInfiniteAssets.mjs +204 -63
  120. package/dist/admin/future/pages/Assets/hooks/useInfiniteAssets.mjs.map +1 -1
  121. package/dist/admin/future/pages/Assets/hooks/useInfiniteScrollSentinel.js +75 -0
  122. package/dist/admin/future/pages/Assets/hooks/useInfiniteScrollSentinel.js.map +1 -0
  123. package/dist/admin/future/pages/Assets/hooks/useInfiniteScrollSentinel.mjs +73 -0
  124. package/dist/admin/future/pages/Assets/hooks/useInfiniteScrollSentinel.mjs.map +1 -0
  125. package/dist/admin/future/pages/Assets/utils/selection.js +17 -0
  126. package/dist/admin/future/pages/Assets/utils/selection.js.map +1 -1
  127. package/dist/admin/future/pages/Assets/utils/selection.mjs +17 -1
  128. package/dist/admin/future/pages/Assets/utils/selection.mjs.map +1 -1
  129. package/dist/admin/future/services/api.js +31 -8
  130. package/dist/admin/future/services/api.js.map +1 -1
  131. package/dist/admin/future/services/api.mjs +31 -8
  132. package/dist/admin/future/services/api.mjs.map +1 -1
  133. package/dist/admin/future/services/assets.js +22 -23
  134. package/dist/admin/future/services/assets.js.map +1 -1
  135. package/dist/admin/future/services/assets.mjs +22 -23
  136. package/dist/admin/future/services/assets.mjs.map +1 -1
  137. package/dist/admin/future/services/folders.js +37 -2
  138. package/dist/admin/future/services/folders.js.map +1 -1
  139. package/dist/admin/future/services/folders.mjs +37 -3
  140. package/dist/admin/future/services/folders.mjs.map +1 -1
  141. package/dist/admin/future/utils/buildDragSetFromSelection.js +7 -5
  142. package/dist/admin/future/utils/buildDragSetFromSelection.js.map +1 -1
  143. package/dist/admin/future/utils/buildDragSetFromSelection.mjs +7 -5
  144. package/dist/admin/future/utils/buildDragSetFromSelection.mjs.map +1 -1
  145. package/dist/admin/future/utils/formatMoveSuccessMessage.js +12 -1
  146. package/dist/admin/future/utils/formatMoveSuccessMessage.js.map +1 -1
  147. package/dist/admin/future/utils/formatMoveSuccessMessage.mjs +12 -1
  148. package/dist/admin/future/utils/formatMoveSuccessMessage.mjs.map +1 -1
  149. package/dist/admin/future/utils/getRelationId.js +24 -0
  150. package/dist/admin/future/utils/getRelationId.js.map +1 -0
  151. package/dist/admin/future/utils/getRelationId.mjs +22 -0
  152. package/dist/admin/future/utils/getRelationId.mjs.map +1 -0
  153. package/dist/admin/future/utils/isEventFromWithin.js +14 -0
  154. package/dist/admin/future/utils/isEventFromWithin.js.map +1 -0
  155. package/dist/admin/future/utils/isEventFromWithin.mjs +12 -0
  156. package/dist/admin/future/utils/isEventFromWithin.mjs.map +1 -0
  157. package/dist/admin/future/utils/itemLocations.js +40 -0
  158. package/dist/admin/future/utils/itemLocations.js.map +1 -0
  159. package/dist/admin/future/utils/itemLocations.mjs +36 -0
  160. package/dist/admin/future/utils/itemLocations.mjs.map +1 -0
  161. package/dist/admin/future/utils/itemSource.js +36 -0
  162. package/dist/admin/future/utils/itemSource.js.map +1 -0
  163. package/dist/admin/future/utils/itemSource.mjs +32 -0
  164. package/dist/admin/future/utils/itemSource.mjs.map +1 -0
  165. package/dist/admin/hooks/useAIMetadataJob.js +1 -1
  166. package/dist/admin/hooks/useAIMetadataJob.js.map +1 -1
  167. package/dist/admin/hooks/useAIMetadataJob.mjs +1 -1
  168. package/dist/admin/hooks/useAIMetadataJob.mjs.map +1 -1
  169. package/dist/admin/index.js +11 -17
  170. package/dist/admin/index.js.map +1 -1
  171. package/dist/admin/index.mjs +12 -18
  172. package/dist/admin/index.mjs.map +1 -1
  173. package/dist/admin/pages/SettingsPage/SettingsPage.js +2 -2
  174. package/dist/admin/pages/SettingsPage/SettingsPage.js.map +1 -1
  175. package/dist/admin/pages/SettingsPage/SettingsPage.mjs +2 -2
  176. package/dist/admin/pages/SettingsPage/SettingsPage.mjs.map +1 -1
  177. package/dist/admin/src/future/App.d.ts +1 -1
  178. package/dist/admin/src/future/components/BetaNotice.d.ts +11 -0
  179. package/dist/admin/src/future/components/Drawer.d.ts +5 -1
  180. package/dist/admin/src/future/components/TruncatedText.d.ts +32 -0
  181. package/dist/admin/src/future/hooks/useAIMetadataEnabled.d.ts +26 -0
  182. package/dist/admin/src/future/hooks/useTracking.d.ts +29 -0
  183. package/dist/admin/src/future/pages/Assets/components/ActionsMenuContent.d.ts +33 -0
  184. package/dist/admin/src/future/pages/Assets/components/AssetActionsMenu.d.ts +26 -0
  185. package/dist/admin/src/future/pages/Assets/components/AssetDetails/AssetDetailsDrawer.d.ts +16 -0
  186. package/dist/admin/src/future/pages/Assets/components/BulkActionsBar.d.ts +8 -1
  187. package/dist/admin/src/future/pages/Assets/components/BulkMoveDialog.d.ts +17 -6
  188. package/dist/admin/src/future/pages/Assets/components/BusyOverlay.d.ts +9 -0
  189. package/dist/admin/src/future/pages/Assets/components/DeleteItemsDialog.d.ts +27 -0
  190. package/dist/admin/src/future/pages/Assets/components/Dnd/AssetsDndProvider.d.ts +8 -1
  191. package/dist/admin/src/future/pages/Assets/components/Dnd/buildDragSet.d.ts +18 -3
  192. package/dist/admin/src/future/pages/Assets/components/Dnd/useAssetDnd.d.ts +2 -1
  193. package/dist/admin/src/future/pages/Assets/components/FilterBadges.d.ts +3 -1
  194. package/dist/admin/src/future/pages/Assets/components/FilterMenu.d.ts +4 -0
  195. package/dist/admin/src/future/pages/Assets/components/FolderActionsMenu.d.ts +21 -0
  196. package/dist/admin/src/future/pages/Assets/components/FolderFormDialog.d.ts +16 -0
  197. package/dist/admin/src/future/pages/Assets/hooks/useAssetSelection.d.ts +2 -0
  198. package/dist/admin/src/future/pages/Assets/hooks/useBusyAssets.d.ts +38 -0
  199. package/dist/admin/src/future/pages/Assets/hooks/useInfiniteAssets.d.ts +20 -6
  200. package/dist/admin/src/future/pages/Assets/hooks/useInfiniteScrollSentinel.d.ts +41 -0
  201. package/dist/admin/src/future/pages/Assets/utils/selection.d.ts +10 -0
  202. package/dist/admin/src/future/services/api.d.ts +6 -7
  203. package/dist/admin/src/future/services/folders.d.ts +6 -1
  204. package/dist/admin/src/future/utils/buildDragSetFromSelection.d.ts +4 -3
  205. package/dist/admin/src/future/utils/formatMoveSuccessMessage.d.ts +7 -1
  206. package/dist/admin/src/future/utils/getRelationId.d.ts +11 -0
  207. package/dist/admin/src/future/utils/isEventFromWithin.d.ts +11 -0
  208. package/dist/admin/src/future/utils/itemLocations.d.ts +31 -0
  209. package/dist/admin/src/future/utils/itemSource.d.ts +22 -0
  210. package/dist/admin/translations/en.json.js +25 -4
  211. package/dist/admin/translations/en.json.js.map +1 -1
  212. package/dist/admin/translations/en.json.mjs +25 -4
  213. package/dist/admin/translations/en.json.mjs.map +1 -1
  214. package/dist/server/controllers/admin-file.js +27 -9
  215. package/dist/server/controllers/admin-file.js.map +1 -1
  216. package/dist/server/controllers/admin-file.mjs +27 -9
  217. package/dist/server/controllers/admin-file.mjs.map +1 -1
  218. package/dist/server/controllers/admin-upload.js +24 -8
  219. package/dist/server/controllers/admin-upload.js.map +1 -1
  220. package/dist/server/controllers/admin-upload.mjs +24 -8
  221. package/dist/server/controllers/admin-upload.mjs.map +1 -1
  222. package/dist/server/routes/admin.js +41 -21
  223. package/dist/server/routes/admin.js.map +1 -1
  224. package/dist/server/routes/admin.mjs +41 -21
  225. package/dist/server/routes/admin.mjs.map +1 -1
  226. package/dist/server/services/ai-metadata.js.map +1 -1
  227. package/dist/server/services/ai-metadata.mjs.map +1 -1
  228. package/dist/server/services/image-manipulation.js.map +1 -1
  229. package/dist/server/services/image-manipulation.mjs.map +1 -1
  230. package/dist/server/src/controllers/admin-file.d.ts +29 -8
  231. package/dist/server/src/controllers/admin-file.d.ts.map +1 -1
  232. package/dist/server/src/controllers/admin-upload.d.ts +20 -4
  233. package/dist/server/src/controllers/admin-upload.d.ts.map +1 -1
  234. package/dist/server/src/controllers/index.d.ts +4 -4
  235. package/dist/server/src/index.d.ts +4 -4
  236. package/dist/server/src/routes/admin.d.ts.map +1 -1
  237. package/dist/server/src/services/ai-metadata.d.ts +2 -2
  238. package/dist/server/src/services/ai-metadata.d.ts.map +1 -1
  239. package/dist/server/src/services/image-manipulation.d.ts +0 -5
  240. package/dist/server/src/services/image-manipulation.d.ts.map +1 -1
  241. package/dist/shared/contracts/ai-metadata-jobs.d.ts +10 -32
  242. package/dist/shared/contracts/ai-metadata-jobs.d.ts.map +1 -1
  243. package/dist/shared/contracts/files.d.ts +10 -10
  244. package/dist/shared/contracts/files.d.ts.map +1 -1
  245. package/package.json +9 -9
  246. package/dist/admin/future/pages/Assets/components/CreateFolderDialog.js.map +0 -1
  247. package/dist/admin/future/pages/Assets/components/CreateFolderDialog.mjs.map +0 -1
  248. package/dist/admin/future/pages/Assets/components/FolderTree/filterFolderTree.js +0 -33
  249. package/dist/admin/future/pages/Assets/components/FolderTree/filterFolderTree.js.map +0 -1
  250. package/dist/admin/future/pages/Assets/components/FolderTree/filterFolderTree.mjs +0 -31
  251. package/dist/admin/future/pages/Assets/components/FolderTree/filterFolderTree.mjs.map +0 -1
  252. package/dist/admin/src/future/pages/Assets/components/CreateFolderDialog.d.ts +0 -8
  253. package/dist/admin/src/future/pages/Assets/components/FolderTree/filterFolderTree.d.ts +0 -16
@@ -1,28 +1,42 @@
1
1
  import { jsx, jsxs } from 'react/jsx-runtime';
2
- import { useState, useEffect } from 'react';
2
+ import { useState, useRef, useEffect } from 'react';
3
3
  import { useNotification } from '@strapi/admin/strapi-admin';
4
4
  import { Modal, Field, TextInput, Flex, Button } from '@strapi/design-system';
5
5
  import { useIntl } from 'react-intl';
6
6
  import { styled } from 'styled-components';
7
- import { useCreateFolderMutation } from '../../../services/folders.mjs';
7
+ import { useTracking, MEDIA_LIBRARY_LOCATION } from '../../../hooks/useTracking.mjs';
8
+ import { useCreateFolderMutation, useUpdateFolderMutation } from '../../../services/folders.mjs';
8
9
  import { getTranslationKey } from '../../../utils/translations.mjs';
9
10
 
10
11
  const StyledModalContent = styled(Modal.Content)`
11
12
  max-width: 51.6rem;
12
13
  `;
13
- const CreateFolderDialog = ({ open, folderName, parentFolderId, onClose })=>{
14
+ const FolderFormDialog = (props)=>{
15
+ const { open, parentFolderId, onClose, mode } = props;
16
+ const initialName = props.mode === 'rename' ? props.initialName : '';
14
17
  const { formatMessage } = useIntl();
15
18
  const { toggleNotification } = useNotification();
16
- const [name, setName] = useState('');
19
+ const { trackUsage } = useTracking();
20
+ const [name, setName] = useState(initialName);
17
21
  const [fieldError, setFieldError] = useState();
18
- const [createFolder, { isLoading }] = useCreateFolderMutation();
22
+ const inputRef = useRef(null);
23
+ const [createFolder, { isLoading: isCreating }] = useCreateFolderMutation();
24
+ const [updateFolder, { isLoading: isUpdating }] = useUpdateFolderMutation();
25
+ const isLoading = mode === 'rename' ? isUpdating : isCreating;
19
26
  useEffect(()=>{
20
27
  if (open) {
21
- setName('');
28
+ setName(initialName);
22
29
  setFieldError(undefined);
30
+ // Renaming starts from the current name, so select it: typing replaces
31
+ // the whole thing, as in Finder / VS Code / GitHub.
32
+ if (mode === 'rename') {
33
+ inputRef.current?.select();
34
+ }
23
35
  }
24
36
  }, [
25
- open
37
+ open,
38
+ initialName,
39
+ mode
26
40
  ]);
27
41
  const handleSubmit = async (e)=>{
28
42
  e.preventDefault();
@@ -35,13 +49,34 @@ const CreateFolderDialog = ({ open, folderName, parentFolderId, onClose })=>{
35
49
  return;
36
50
  }
37
51
  try {
38
- await createFolder({
39
- name: trimmedName,
40
- parent: parentFolderId
41
- }).unwrap();
52
+ if (props.mode === 'rename') {
53
+ await updateFolder({
54
+ id: props.folderId,
55
+ name: trimmedName,
56
+ parent: parentFolderId
57
+ }).unwrap();
58
+ // Matches the legacy folder-edit payload. This dialog only renames
59
+ // (parent is fixed), so the location never changes here.
60
+ trackUsage('didEditMediaLibraryElements', {
61
+ location: MEDIA_LIBRARY_LOCATION,
62
+ type: 'folder',
63
+ changeLocation: false
64
+ });
65
+ } else {
66
+ await createFolder({
67
+ name: trimmedName,
68
+ parent: parentFolderId
69
+ }).unwrap();
70
+ trackUsage('didAddMediaLibraryFolders', {
71
+ location: MEDIA_LIBRARY_LOCATION
72
+ });
73
+ }
42
74
  toggleNotification({
43
75
  type: 'success',
44
- message: formatMessage({
76
+ message: mode === 'rename' ? formatMessage({
77
+ id: getTranslationKey('folder.rename.success'),
78
+ defaultMessage: 'Folder has been renamed'
79
+ }) : formatMessage({
45
80
  id: getTranslationKey('folder.create.success'),
46
81
  defaultMessage: 'Folder has been created'
47
82
  })
@@ -54,7 +89,10 @@ const CreateFolderDialog = ({ open, folderName, parentFolderId, onClose })=>{
54
89
  } else {
55
90
  toggleNotification({
56
91
  type: 'danger',
57
- message: formatMessage({
92
+ message: mode === 'rename' ? formatMessage({
93
+ id: getTranslationKey('folder.rename.form.error.unknown'),
94
+ defaultMessage: 'An error occurred while renaming the folder'
95
+ }) : formatMessage({
58
96
  id: getTranslationKey('folder.create.form.error.unknown'),
59
97
  defaultMessage: 'An error occurred while creating the folder'
60
98
  })
@@ -69,11 +107,14 @@ const CreateFolderDialog = ({ open, folderName, parentFolderId, onClose })=>{
69
107
  children: [
70
108
  /*#__PURE__*/ jsx(Modal.Header, {
71
109
  children: /*#__PURE__*/ jsx(Modal.Title, {
72
- children: formatMessage({
110
+ children: props.mode === 'rename' ? formatMessage({
111
+ id: getTranslationKey('folder.rename.title'),
112
+ defaultMessage: 'Rename folder'
113
+ }) : formatMessage({
73
114
  id: getTranslationKey('folder.create.title-in'),
74
115
  defaultMessage: 'New folder in {folderName}'
75
116
  }, {
76
- folderName
117
+ folderName: props.parentFolderName
77
118
  })
78
119
  })
79
120
  }),
@@ -93,6 +134,7 @@ const CreateFolderDialog = ({ open, folderName, parentFolderId, onClose })=>{
93
134
  })
94
135
  }),
95
136
  /*#__PURE__*/ jsx(TextInput, {
137
+ ref: inputRef,
96
138
  value: name,
97
139
  onChange: (e)=>{
98
140
  setName(e.target.value);
@@ -122,7 +164,11 @@ const CreateFolderDialog = ({ open, folderName, parentFolderId, onClose })=>{
122
164
  /*#__PURE__*/ jsx(Button, {
123
165
  type: "submit",
124
166
  loading: isLoading,
125
- children: formatMessage({
167
+ disabled: mode === 'rename' && name.trim() === initialName.trim(),
168
+ children: mode === 'rename' ? formatMessage({
169
+ id: getTranslationKey('folder.rename.submit'),
170
+ defaultMessage: 'Save'
171
+ }) : formatMessage({
126
172
  id: getTranslationKey('folder.create.submit'),
127
173
  defaultMessage: 'Create folder'
128
174
  })
@@ -137,5 +183,5 @@ const CreateFolderDialog = ({ open, folderName, parentFolderId, onClose })=>{
137
183
  });
138
184
  };
139
185
 
140
- export { CreateFolderDialog };
141
- //# sourceMappingURL=CreateFolderDialog.mjs.map
186
+ export { FolderFormDialog };
187
+ //# sourceMappingURL=FolderFormDialog.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"FolderFormDialog.mjs","sources":["../../../../../../admin/src/future/pages/Assets/components/FolderFormDialog.tsx"],"sourcesContent":["import { useEffect, useRef, useState } from 'react';\n\nimport { useNotification } from '@strapi/admin/strapi-admin';\nimport { Button, Field, Flex, Modal, TextInput } from '@strapi/design-system';\nimport { useIntl } from 'react-intl';\nimport { styled } from 'styled-components';\n\nimport { useTracking, MEDIA_LIBRARY_LOCATION } from '../../../hooks/useTracking';\nimport { useCreateFolderMutation, useUpdateFolderMutation } from '../../../services/folders';\nimport { getTranslationKey } from '../../../utils/translations';\n\ninterface FolderFormDialogBaseProps {\n open: boolean;\n onClose: () => void;\n /** Sent as `parent`. Create: the folder being created in. Rename: the folder's existing parent. */\n parentFolderId: number | null;\n}\n\ntype FolderFormDialogProps = FolderFormDialogBaseProps &\n (\n | { mode: 'create'; parentFolderName: string }\n | { mode: 'rename'; folderId: number; initialName: string }\n );\n\nconst StyledModalContent = styled(Modal.Content)`\n max-width: 51.6rem;\n`;\n\nexport const FolderFormDialog = (props: FolderFormDialogProps) => {\n const { open, parentFolderId, onClose, mode } = props;\n const initialName = props.mode === 'rename' ? props.initialName : '';\n\n const { formatMessage } = useIntl();\n const { toggleNotification } = useNotification();\n const { trackUsage } = useTracking();\n const [name, setName] = useState(initialName);\n const [fieldError, setFieldError] = useState<string | undefined>();\n const inputRef = useRef<HTMLInputElement>(null);\n const [createFolder, { isLoading: isCreating }] = useCreateFolderMutation();\n const [updateFolder, { isLoading: isUpdating }] = useUpdateFolderMutation();\n\n const isLoading = mode === 'rename' ? isUpdating : isCreating;\n\n useEffect(() => {\n if (open) {\n setName(initialName);\n setFieldError(undefined);\n\n // Renaming starts from the current name, so select it: typing replaces\n // the whole thing, as in Finder / VS Code / GitHub.\n if (mode === 'rename') {\n inputRef.current?.select();\n }\n }\n }, [open, initialName, mode]);\n\n const handleSubmit = async (e: React.FormEvent) => {\n e.preventDefault();\n\n const trimmedName = name.trim();\n\n if (!trimmedName) {\n setFieldError(\n formatMessage({\n id: getTranslationKey('folder.create.form.error.name-required'),\n defaultMessage: 'Name is required',\n })\n );\n return;\n }\n\n try {\n if (props.mode === 'rename') {\n await updateFolder({\n id: props.folderId,\n name: trimmedName,\n parent: parentFolderId,\n }).unwrap();\n // Matches the legacy folder-edit payload. This dialog only renames\n // (parent is fixed), so the location never changes here.\n trackUsage('didEditMediaLibraryElements', {\n location: MEDIA_LIBRARY_LOCATION,\n type: 'folder',\n changeLocation: false,\n });\n } else {\n await createFolder({ name: trimmedName, parent: parentFolderId }).unwrap();\n trackUsage('didAddMediaLibraryFolders', { location: MEDIA_LIBRARY_LOCATION });\n }\n\n toggleNotification({\n type: 'success',\n message:\n mode === 'rename'\n ? formatMessage({\n id: getTranslationKey('folder.rename.success'),\n defaultMessage: 'Folder has been renamed',\n })\n : formatMessage({\n id: getTranslationKey('folder.create.success'),\n defaultMessage: 'Folder has been created',\n }),\n });\n\n onClose();\n } catch (err) {\n const apiError = err as { message?: string };\n\n if (apiError?.message) {\n setFieldError(apiError.message);\n } else {\n toggleNotification({\n type: 'danger',\n message:\n mode === 'rename'\n ? formatMessage({\n id: getTranslationKey('folder.rename.form.error.unknown'),\n defaultMessage: 'An error occurred while renaming the folder',\n })\n : formatMessage({\n id: getTranslationKey('folder.create.form.error.unknown'),\n defaultMessage: 'An error occurred while creating the folder',\n }),\n });\n }\n }\n };\n\n return (\n <Modal.Root open={open} onOpenChange={onClose}>\n <StyledModalContent>\n <Modal.Header>\n <Modal.Title>\n {props.mode === 'rename'\n ? formatMessage({\n id: getTranslationKey('folder.rename.title'),\n defaultMessage: 'Rename folder',\n })\n : formatMessage(\n {\n id: getTranslationKey('folder.create.title-in'),\n defaultMessage: 'New folder in {folderName}',\n },\n { folderName: props.parentFolderName }\n )}\n </Modal.Title>\n </Modal.Header>\n <form onSubmit={handleSubmit}>\n <Modal.Body>\n <Field.Root error={fieldError} name=\"name\" required>\n <Field.Label>\n {formatMessage({\n id: getTranslationKey('folder.form.name.label'),\n defaultMessage: 'Folder name',\n })}\n </Field.Label>\n <TextInput\n ref={inputRef}\n value={name}\n onChange={(e: React.ChangeEvent<HTMLInputElement>) => {\n setName(e.target.value);\n setFieldError(undefined);\n }}\n autoFocus\n />\n <Field.Error />\n </Field.Root>\n </Modal.Body>\n <Modal.Footer>\n <Flex gap={2} justifyContent=\"space-between\" width=\"100%\">\n <Button variant=\"tertiary\" onClick={onClose} type=\"button\">\n {formatMessage({ id: 'app.components.Button.cancel', defaultMessage: 'Cancel' })}\n </Button>\n <Button\n type=\"submit\"\n loading={isLoading}\n disabled={mode === 'rename' && name.trim() === initialName.trim()}\n >\n {mode === 'rename'\n ? formatMessage({\n id: getTranslationKey('folder.rename.submit'),\n defaultMessage: 'Save',\n })\n : formatMessage({\n id: getTranslationKey('folder.create.submit'),\n defaultMessage: 'Create folder',\n })}\n </Button>\n </Flex>\n </Modal.Footer>\n </form>\n </StyledModalContent>\n </Modal.Root>\n );\n};\n"],"names":["StyledModalContent","styled","Modal","Content","FolderFormDialog","props","open","parentFolderId","onClose","mode","initialName","formatMessage","useIntl","toggleNotification","useNotification","trackUsage","useTracking","name","setName","useState","fieldError","setFieldError","inputRef","useRef","createFolder","isLoading","isCreating","useCreateFolderMutation","updateFolder","isUpdating","useUpdateFolderMutation","useEffect","undefined","current","select","handleSubmit","e","preventDefault","trimmedName","trim","id","getTranslationKey","defaultMessage","folderId","parent","unwrap","location","MEDIA_LIBRARY_LOCATION","type","changeLocation","message","err","apiError","_jsx","Root","onOpenChange","_jsxs","Header","Title","folderName","parentFolderName","form","onSubmit","Body","Field","error","required","Label","TextInput","ref","value","onChange","target","autoFocus","Error","Footer","Flex","gap","justifyContent","width","Button","variant","onClick","loading","disabled"],"mappings":"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"}
@@ -2,15 +2,16 @@
2
2
 
3
3
  var jsxRuntime = require('react/jsx-runtime');
4
4
  var React = require('react');
5
+ var strapiAdmin = require('@strapi/admin/strapi-admin');
5
6
  var designSystem = require('@strapi/design-system');
6
7
  var icons = require('@strapi/icons');
7
8
  var reactIntl = require('react-intl');
8
9
  var styledComponents = require('styled-components');
10
+ var TruncatedText = require('../../../../components/TruncatedText.js');
9
11
  var folders = require('../../../../services/folders.js');
10
12
  var translations = require('../../../../utils/translations.js');
11
13
  var AssetsDndProvider = require('../Dnd/AssetsDndProvider.js');
12
14
  var useFolderTreeDroppable = require('../Dnd/useFolderTreeDroppable.js');
13
- var filterFolderTree = require('./filterFolderTree.js');
14
15
  var useSpringLoadedExpand = require('./useSpringLoadedExpand.js');
15
16
 
16
17
  /* -------------------------------------------------------------------------------------------------
@@ -151,47 +152,28 @@ const useExpandedFolders = (folderStructure, currentFolderId)=>{
151
152
  expandFolder
152
153
  };
153
154
  };
154
- /* -------------------------------------------------------------------------------------------------
155
- * TruncatedFolderName — tooltip when the label is ellipsized
156
- * -----------------------------------------------------------------------------------------------*/ const TruncatedFolderName = ({ name, isActive })=>{
157
- const textRef = React.useRef(null);
158
- const [isTruncated, setIsTruncated] = React.useState(false);
159
- React.useLayoutEffect(()=>{
160
- const el = textRef.current;
161
- if (!el) {
162
- return;
163
- }
164
- const checkTruncation = ()=>{
165
- setIsTruncated(el.scrollWidth > el.clientWidth);
166
- };
167
- checkTruncation();
168
- const observer = new ResizeObserver(checkTruncation);
169
- observer.observe(el);
170
- return ()=>observer.disconnect();
171
- }, [
172
- name
173
- ]);
174
- const label = /*#__PURE__*/ jsxRuntime.jsx(designSystem.Typography, {
175
- ref: textRef,
176
- variant: "omega",
177
- fontWeight: isActive ? 'semiBold' : 'regular',
178
- ellipsis: true,
179
- children: name
180
- });
181
- if (isTruncated) {
182
- return /*#__PURE__*/ jsxRuntime.jsx(designSystem.Tooltip, {
183
- label: name,
184
- children: label
185
- });
186
- }
187
- return label;
188
- };
189
155
  /* -------------------------------------------------------------------------------------------------
190
156
  * NavList — unstyled list for tree rows
191
157
  * -----------------------------------------------------------------------------------------------*/ const NavList = styledComponents.styled.ul`
192
158
  list-style: none;
193
159
  margin: 0;
194
160
  padding: 0;
161
+
162
+ /* Grid rather than block, and load-bearing despite rendering a single column:
163
+ a minmax(0, 1fr) track contributes a minimum of 0, which is what stops each
164
+ row propagating the min-content width of its own label.
165
+
166
+ Folder names ellipsize, and text-overflow needs white-space: nowrap — so a
167
+ label's min-content width is the entire name, and no box lays out narrower
168
+ than its min-content. In block flow that floor travels up to the SubNav
169
+ ScrollArea, which widens the rail and shows a horizontal scrollbar instead of
170
+ truncating the name. Nesting makes it worse: the indent is spent before the
171
+ label is measured, so shorter names trigger it the deeper you go.
172
+
173
+ Measured in Chromium — dropping either declaration brings the scrollbar
174
+ back, and neither min-width nor overflow on the row is a substitute. */
175
+ display: grid;
176
+ grid-template-columns: minmax(0, 1fr);
195
177
  `;
196
178
  /* -------------------------------------------------------------------------------------------------
197
179
  * FolderTreeItem — single tree row (internal)
@@ -263,9 +245,10 @@ const FolderTreeItemInner = ({ id, name, folderChildren, level, currentFolderId,
263
245
  onClick: ()=>onSelect(id),
264
246
  "data-testid": `folder-tree-node-${id}`,
265
247
  "data-folder-id": id,
266
- children: /*#__PURE__*/ jsxRuntime.jsx(TruncatedFolderName, {
267
- name: name,
268
- isActive: isActive
248
+ children: /*#__PURE__*/ jsxRuntime.jsx(TruncatedText.TruncatedText, {
249
+ variant: "omega",
250
+ fontWeight: isActive ? 'semiBold' : 'regular',
251
+ children: name
269
252
  })
270
253
  })
271
254
  })
@@ -298,27 +281,6 @@ const FolderTreeItem = ({ node, ...props })=>{
298
281
  folderChildren: node.children ?? []
299
282
  });
300
283
  };
301
- /* -------------------------------------------------------------------------------------------------
302
- * FolderTree — public sidebar component
303
- * -----------------------------------------------------------------------------------------------*/ const SidebarNav = styledComponents.styled(designSystem.Flex)`
304
- /* TODO: reconcile 25.6rem (Figma) with admin WIDTH_SIDE_NAVIGATION (23.2rem) */
305
- width: 25.6rem;
306
- height: 100%;
307
- min-height: 100%;
308
- background: ${({ theme })=>theme.colors.neutral0};
309
- flex-shrink: 0;
310
- flex-direction: column;
311
- border-right: 1px solid ${({ theme })=>theme.colors.neutral150};
312
- `;
313
- const SidebarHeader = styledComponents.styled(designSystem.Box)`
314
- flex-shrink: 0;
315
- border-bottom: 1px solid ${({ theme })=>theme.colors.neutral150};
316
- `;
317
- const SidebarBody = styledComponents.styled(designSystem.Flex)`
318
- flex: 1;
319
- min-height: 0;
320
- overflow-y: auto;
321
- `;
322
284
  /**
323
285
  * Left-rail navigation for the Media Library. Fetches folder structure internally
324
286
  * and renders:
@@ -336,31 +298,12 @@ const SidebarBody = styledComponents.styled(designSystem.Flex)`
336
298
  * via `onSelectFolder` so the URL stays the single source of truth (see
337
299
  * `useFolderNavigation`).
338
300
  */ const FolderTree = ({ currentFolderId, showActiveFolder = true, onSelectFolder })=>{
339
- const { formatMessage, locale } = reactIntl.useIntl();
301
+ const { formatMessage } = reactIntl.useIntl();
340
302
  const { data: folderStructure = [], isLoading, isError } = folders.useGetFolderStructureQuery();
341
303
  const { isExpanded, toggleExpanded, expandFolder } = useExpandedFolders(folderStructure, currentFolderId);
342
304
  const { isMovePending } = AssetsDndProvider.useAssetsDndOptional() ?? {
343
305
  isMovePending: false
344
306
  };
345
- const [treeFilter, setTreeFilter] = React.useState('');
346
- const { contains } = designSystem.useFilter(locale, {
347
- sensitivity: 'base'
348
- });
349
- const trimmedFilter = treeFilter.trim();
350
- const { nodes: visibleNodes, expandedIds: filterExpandedIds } = React.useMemo(()=>trimmedFilter ? filterFolderTree.filterFolderTree(folderStructure, (name)=>contains(name, trimmedFilter)) : {
351
- nodes: folderStructure,
352
- expandedIds: []
353
- }, [
354
- folderStructure,
355
- trimmedFilter,
356
- contains
357
- ]);
358
- // An override layered on top of the user's own expansion rather than written
359
- // into it, so clearing the filter restores exactly what they had open.
360
- const isExpandedForRender = React.useCallback((id)=>filterExpandedIds.includes(id) || isExpanded(id), [
361
- filterExpandedIds,
362
- isExpanded
363
- ]);
364
307
  const isHomeActive = showActiveFolder && currentFolderId == null;
365
308
  const homeLabel = formatMessage({
366
309
  id: translations.getTranslationKey('sidebar.home'),
@@ -370,171 +313,131 @@ const SidebarBody = styledComponents.styled(designSystem.Flex)`
370
313
  id: null,
371
314
  name: homeLabel
372
315
  });
373
- return /*#__PURE__*/ jsxRuntime.jsxs(SidebarNav, {
374
- direction: "column",
375
- alignItems: "stretch",
376
- tag: "nav",
316
+ return /*#__PURE__*/ jsxRuntime.jsxs(strapiAdmin.SubNav.Main, {
377
317
  "aria-label": formatMessage({
378
318
  id: translations.getTranslationKey('sidebar.tree.aria-label'),
379
319
  defaultMessage: 'Media library folders'
380
320
  }),
381
321
  children: [
382
- /*#__PURE__*/ jsxRuntime.jsx(SidebarHeader, {
383
- paddingTop: 4,
384
- paddingBottom: 4,
385
- paddingLeft: 5,
386
- paddingRight: 5,
322
+ /*#__PURE__*/ jsxRuntime.jsx(strapiAdmin.SubNav.Header, {
323
+ label: formatMessage({
324
+ id: translations.getTranslationKey('sidebar.title'),
325
+ defaultMessage: 'Media library'
326
+ })
327
+ }),
328
+ /*#__PURE__*/ jsxRuntime.jsx(strapiAdmin.SubNav.Content, {
387
329
  children: /*#__PURE__*/ jsxRuntime.jsxs(designSystem.Flex, {
388
330
  direction: "column",
389
331
  alignItems: "stretch",
390
- gap: 4,
332
+ gap: 1,
333
+ padding: 3,
391
334
  children: [
392
- /*#__PURE__*/ jsxRuntime.jsx(designSystem.Typography, {
393
- variant: "beta",
394
- tag: "h2",
395
- children: formatMessage({
396
- id: translations.getTranslationKey('sidebar.title'),
397
- defaultMessage: 'Media library'
398
- })
335
+ /*#__PURE__*/ jsxRuntime.jsxs(RowButton, {
336
+ ref: setHomeDropRef,
337
+ type: "button",
338
+ $isActive: isHomeActive,
339
+ $isValidDropTarget: showHomeValidDropHighlight,
340
+ $isInvalidDropCursor: showHomeInvalidDropCursor,
341
+ $isMovePending: isMovePending,
342
+ "aria-current": isHomeActive ? 'page' : undefined,
343
+ onClick: ()=>onSelectFolder(null),
344
+ "data-testid": "folder-tree-home",
345
+ children: [
346
+ /*#__PURE__*/ jsxRuntime.jsx(icons.House, {
347
+ "aria-hidden": true,
348
+ width: "1.6rem",
349
+ height: "1.6rem"
350
+ }),
351
+ /*#__PURE__*/ jsxRuntime.jsx(designSystem.Typography, {
352
+ variant: "omega",
353
+ fontWeight: isHomeActive ? 'semiBold' : 'regular',
354
+ children: homeLabel
355
+ })
356
+ ]
399
357
  }),
400
- /*#__PURE__*/ jsxRuntime.jsx(designSystem.Searchbar, {
401
- name: "search-folders",
402
- value: treeFilter,
403
- onChange: (event)=>setTreeFilter(event.target.value),
404
- onClear: ()=>setTreeFilter(''),
405
- clearLabel: formatMessage({
406
- id: 'clearLabel',
407
- defaultMessage: 'Clear'
408
- }),
409
- placeholder: formatMessage({
410
- id: translations.getTranslationKey('sidebar.search.placeholder'),
411
- defaultMessage: 'Search folders'
412
- }),
413
- size: "S",
414
- children: formatMessage({
415
- id: translations.getTranslationKey('sidebar.search.label'),
416
- defaultMessage: 'Search folders'
417
- })
418
- })
419
- ]
420
- })
421
- }),
422
- /*#__PURE__*/ jsxRuntime.jsxs(SidebarBody, {
423
- direction: "column",
424
- alignItems: "stretch",
425
- gap: 1,
426
- padding: 3,
427
- children: [
428
- /*#__PURE__*/ jsxRuntime.jsxs(RowButton, {
429
- ref: setHomeDropRef,
430
- type: "button",
431
- $isActive: isHomeActive,
432
- $isValidDropTarget: showHomeValidDropHighlight,
433
- $isInvalidDropCursor: showHomeInvalidDropCursor,
434
- $isMovePending: isMovePending,
435
- "aria-current": isHomeActive ? 'page' : undefined,
436
- onClick: ()=>onSelectFolder(null),
437
- "data-testid": "folder-tree-home",
438
- children: [
439
- /*#__PURE__*/ jsxRuntime.jsx(icons.House, {
440
- "aria-hidden": true,
441
- width: "1.6rem",
442
- height: "1.6rem"
443
- }),
444
- /*#__PURE__*/ jsxRuntime.jsx(designSystem.Typography, {
445
- variant: "omega",
446
- fontWeight: isHomeActive ? 'semiBold' : 'regular',
447
- children: homeLabel
448
- })
449
- ]
450
- }),
451
- /*#__PURE__*/ jsxRuntime.jsxs(designSystem.Box, {
452
- marginTop: 4,
453
- children: [
454
- /*#__PURE__*/ jsxRuntime.jsxs(designSystem.Flex, {
455
- alignItems: "center",
456
- gap: 1,
457
- paddingTop: 1,
458
- paddingBottom: 1,
459
- paddingLeft: 2,
460
- paddingRight: 2,
461
- marginBottom: 2,
462
- children: [
463
- /*#__PURE__*/ jsxRuntime.jsx(icons.Folder, {
464
- "aria-hidden": true,
465
- width: "1.6rem",
466
- height: "1.6rem",
467
- fill: "neutral500"
468
- }),
469
- /*#__PURE__*/ jsxRuntime.jsx(designSystem.Typography, {
470
- variant: "sigma",
471
- textColor: "neutral600",
472
- style: {
473
- textTransform: 'uppercase'
474
- },
358
+ /*#__PURE__*/ jsxRuntime.jsxs(designSystem.Box, {
359
+ marginTop: 4,
360
+ children: [
361
+ /*#__PURE__*/ jsxRuntime.jsxs(designSystem.Flex, {
362
+ alignItems: "center",
363
+ gap: 1,
364
+ paddingTop: 1,
365
+ paddingBottom: 1,
366
+ paddingLeft: 2,
367
+ paddingRight: 2,
368
+ marginBottom: 2,
369
+ children: [
370
+ /*#__PURE__*/ jsxRuntime.jsx(icons.Folder, {
371
+ "aria-hidden": true,
372
+ width: "1.6rem",
373
+ height: "1.6rem",
374
+ fill: "neutral500"
375
+ }),
376
+ /*#__PURE__*/ jsxRuntime.jsx(designSystem.Typography, {
377
+ variant: "sigma",
378
+ textColor: "neutral600",
379
+ style: {
380
+ textTransform: 'uppercase'
381
+ },
382
+ children: formatMessage({
383
+ id: translations.getTranslationKey('sidebar.folders'),
384
+ defaultMessage: 'Folders'
385
+ })
386
+ })
387
+ ]
388
+ }),
389
+ isLoading ? // TODO: revisit loading state before revamp GA
390
+ /*#__PURE__*/ jsxRuntime.jsx(designSystem.Flex, {
391
+ justifyContent: "center",
392
+ padding: 1,
393
+ paddingTop: 2,
394
+ children: /*#__PURE__*/ jsxRuntime.jsx(designSystem.Loader, {
475
395
  children: formatMessage({
476
- id: translations.getTranslationKey('sidebar.folders'),
477
- defaultMessage: 'Folders'
396
+ id: translations.getTranslationKey('sidebar.tree.loading'),
397
+ defaultMessage: 'Loading folders...'
478
398
  })
479
399
  })
480
- ]
481
- }),
482
- isLoading ? // TODO: revisit loading state before revamp GA
483
- /*#__PURE__*/ jsxRuntime.jsx(designSystem.Flex, {
484
- justifyContent: "center",
485
- padding: 1,
486
- paddingTop: 2,
487
- children: /*#__PURE__*/ jsxRuntime.jsx(designSystem.Loader, {
488
- children: formatMessage({
489
- id: translations.getTranslationKey('sidebar.tree.loading'),
490
- defaultMessage: 'Loading folders...'
491
- })
492
- })
493
- }) : isError ? // TODO: revisit error state before revamp GA
494
- /*#__PURE__*/ jsxRuntime.jsx(designSystem.Box, {
495
- padding: 1,
496
- paddingTop: 2,
497
- children: /*#__PURE__*/ jsxRuntime.jsx(designSystem.Typography, {
498
- variant: "pi",
499
- textColor: "danger600",
500
- children: formatMessage({
501
- id: translations.getTranslationKey('sidebar.tree.error'),
502
- defaultMessage: 'Could not load folders.'
400
+ }) : isError ? // TODO: revisit error state before revamp GA
401
+ /*#__PURE__*/ jsxRuntime.jsx(designSystem.Box, {
402
+ padding: 1,
403
+ paddingTop: 2,
404
+ children: /*#__PURE__*/ jsxRuntime.jsx(designSystem.Typography, {
405
+ variant: "pi",
406
+ textColor: "danger600",
407
+ children: formatMessage({
408
+ id: translations.getTranslationKey('sidebar.tree.error'),
409
+ defaultMessage: 'Could not load folders.'
410
+ })
503
411
  })
504
- })
505
- }) : visibleNodes.length === 0 ? // TODO: revisit empty state before revamp GA
506
- /*#__PURE__*/ jsxRuntime.jsx(designSystem.Box, {
507
- padding: 1,
508
- paddingTop: 2,
509
- children: /*#__PURE__*/ jsxRuntime.jsx(designSystem.Typography, {
510
- variant: "pi",
511
- textColor: "neutral500",
512
- children: trimmedFilter ? formatMessage({
513
- id: translations.getTranslationKey('sidebar.tree.no-results'),
514
- defaultMessage: 'No folders match "{query}"'
515
- }, {
516
- query: trimmedFilter
517
- }) : formatMessage({
518
- id: translations.getTranslationKey('sidebar.tree.empty'),
519
- defaultMessage: 'No folders yet'
412
+ }) : folderStructure.length === 0 ? // TODO: revisit empty state before revamp GA
413
+ /*#__PURE__*/ jsxRuntime.jsx(designSystem.Box, {
414
+ padding: 1,
415
+ paddingTop: 2,
416
+ children: /*#__PURE__*/ jsxRuntime.jsx(designSystem.Typography, {
417
+ variant: "pi",
418
+ textColor: "neutral500",
419
+ children: formatMessage({
420
+ id: translations.getTranslationKey('sidebar.tree.empty'),
421
+ defaultMessage: 'No folders yet'
422
+ })
520
423
  })
424
+ }) : /*#__PURE__*/ jsxRuntime.jsx(NavList, {
425
+ children: folderStructure.map((node)=>/*#__PURE__*/ jsxRuntime.jsx(FolderTreeItem, {
426
+ node: node,
427
+ level: 0,
428
+ currentFolderId: currentFolderId,
429
+ showActiveFolder: showActiveFolder,
430
+ isExpanded: isExpanded,
431
+ onToggle: toggleExpanded,
432
+ onExpand: expandFolder,
433
+ onSelect: onSelectFolder,
434
+ isMovePending: isMovePending
435
+ }, node.id ?? node.name))
521
436
  })
522
- }) : /*#__PURE__*/ jsxRuntime.jsx(NavList, {
523
- children: visibleNodes.map((node)=>/*#__PURE__*/ jsxRuntime.jsx(FolderTreeItem, {
524
- node: node,
525
- level: 0,
526
- currentFolderId: currentFolderId,
527
- showActiveFolder: showActiveFolder,
528
- isExpanded: isExpandedForRender,
529
- onToggle: toggleExpanded,
530
- onExpand: expandFolder,
531
- onSelect: onSelectFolder,
532
- isMovePending: isMovePending
533
- }, node.id ?? node.name))
534
- })
535
- ]
536
- })
537
- ]
437
+ ]
438
+ })
439
+ ]
440
+ })
538
441
  })
539
442
  ]
540
443
  });