@strapi/upload 5.51.1 → 5.51.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (262) hide show
  1. package/dist/admin/components/AssetCard/VideoPreview.js +1 -1
  2. package/dist/admin/components/AssetCard/VideoPreview.js.map +1 -1
  3. package/dist/admin/components/AssetCard/VideoPreview.mjs +1 -1
  4. package/dist/admin/components/AssetCard/VideoPreview.mjs.map +1 -1
  5. package/dist/admin/components/TableList/TableList.js +1 -1
  6. package/dist/admin/components/TableList/TableList.js.map +1 -1
  7. package/dist/admin/components/TableList/TableList.mjs +1 -1
  8. package/dist/admin/components/TableList/TableList.mjs.map +1 -1
  9. package/dist/admin/components/UploadAssetDialog/AddAssetStep/FromUrlForm.js +21 -4
  10. package/dist/admin/components/UploadAssetDialog/AddAssetStep/FromUrlForm.js.map +1 -1
  11. package/dist/admin/components/UploadAssetDialog/AddAssetStep/FromUrlForm.mjs +21 -4
  12. package/dist/admin/components/UploadAssetDialog/AddAssetStep/FromUrlForm.mjs.map +1 -1
  13. package/dist/admin/future/components/Drawer.js +3 -1
  14. package/dist/admin/future/components/Drawer.js.map +1 -1
  15. package/dist/admin/future/components/Drawer.mjs +3 -1
  16. package/dist/admin/future/components/Drawer.mjs.map +1 -1
  17. package/dist/admin/future/components/UploadProgressDialog.js +200 -27
  18. package/dist/admin/future/components/UploadProgressDialog.js.map +1 -1
  19. package/dist/admin/future/components/UploadProgressDialog.mjs +203 -30
  20. package/dist/admin/future/components/UploadProgressDialog.mjs.map +1 -1
  21. package/dist/admin/future/hooks/useMediaLibraryPermissions.js +35 -0
  22. package/dist/admin/future/hooks/useMediaLibraryPermissions.js.map +1 -0
  23. package/dist/admin/future/hooks/useMediaLibraryPermissions.mjs +33 -0
  24. package/dist/admin/future/hooks/useMediaLibraryPermissions.mjs.map +1 -0
  25. package/dist/admin/future/pages/Assets/AssetsPage.js +203 -78
  26. package/dist/admin/future/pages/Assets/AssetsPage.js.map +1 -1
  27. package/dist/admin/future/pages/Assets/AssetsPage.mjs +200 -75
  28. package/dist/admin/future/pages/Assets/AssetsPage.mjs.map +1 -1
  29. package/dist/admin/future/pages/Assets/components/AssetDetails/AssetCropEditor.js +75 -32
  30. package/dist/admin/future/pages/Assets/components/AssetDetails/AssetCropEditor.js.map +1 -1
  31. package/dist/admin/future/pages/Assets/components/AssetDetails/AssetCropEditor.mjs +75 -32
  32. package/dist/admin/future/pages/Assets/components/AssetDetails/AssetCropEditor.mjs.map +1 -1
  33. package/dist/admin/future/pages/Assets/components/AssetDetails/AssetDetailsDrawer.js +46 -19
  34. package/dist/admin/future/pages/Assets/components/AssetDetails/AssetDetailsDrawer.js.map +1 -1
  35. package/dist/admin/future/pages/Assets/components/AssetDetails/AssetDetailsDrawer.mjs +47 -20
  36. package/dist/admin/future/pages/Assets/components/AssetDetails/AssetDetailsDrawer.mjs.map +1 -1
  37. package/dist/admin/future/pages/Assets/components/AssetsGrid.js +5 -2
  38. package/dist/admin/future/pages/Assets/components/AssetsGrid.js.map +1 -1
  39. package/dist/admin/future/pages/Assets/components/AssetsGrid.mjs +5 -2
  40. package/dist/admin/future/pages/Assets/components/AssetsGrid.mjs.map +1 -1
  41. package/dist/admin/future/pages/Assets/components/AssetsSearchInput.js +100 -0
  42. package/dist/admin/future/pages/Assets/components/AssetsSearchInput.js.map +1 -0
  43. package/dist/admin/future/pages/Assets/components/AssetsSearchInput.mjs +98 -0
  44. package/dist/admin/future/pages/Assets/components/AssetsSearchInput.mjs.map +1 -0
  45. package/dist/admin/future/pages/Assets/components/AssetsTable.js +10 -4
  46. package/dist/admin/future/pages/Assets/components/AssetsTable.js.map +1 -1
  47. package/dist/admin/future/pages/Assets/components/AssetsTable.mjs +10 -4
  48. package/dist/admin/future/pages/Assets/components/AssetsTable.mjs.map +1 -1
  49. package/dist/admin/future/pages/Assets/components/BulkActionsBar.js +140 -22
  50. package/dist/admin/future/pages/Assets/components/BulkActionsBar.js.map +1 -1
  51. package/dist/admin/future/pages/Assets/components/BulkActionsBar.mjs +142 -24
  52. package/dist/admin/future/pages/Assets/components/BulkActionsBar.mjs.map +1 -1
  53. package/dist/admin/future/pages/Assets/components/DateRangeCalendar.js +193 -0
  54. package/dist/admin/future/pages/Assets/components/DateRangeCalendar.js.map +1 -0
  55. package/dist/admin/future/pages/Assets/components/DateRangeCalendar.mjs +191 -0
  56. package/dist/admin/future/pages/Assets/components/DateRangeCalendar.mjs.map +1 -0
  57. package/dist/admin/future/pages/Assets/components/Dnd/AssetsDndProvider.js +18 -1
  58. package/dist/admin/future/pages/Assets/components/Dnd/AssetsDndProvider.js.map +1 -1
  59. package/dist/admin/future/pages/Assets/components/Dnd/AssetsDndProvider.mjs +18 -1
  60. package/dist/admin/future/pages/Assets/components/Dnd/AssetsDndProvider.mjs.map +1 -1
  61. package/dist/admin/future/pages/Assets/components/DropZone/UploadDropZoneContext.js +13 -3
  62. package/dist/admin/future/pages/Assets/components/DropZone/UploadDropZoneContext.js.map +1 -1
  63. package/dist/admin/future/pages/Assets/components/DropZone/UploadDropZoneContext.mjs +13 -3
  64. package/dist/admin/future/pages/Assets/components/DropZone/UploadDropZoneContext.mjs.map +1 -1
  65. package/dist/admin/future/pages/Assets/components/EmptyState.js +62 -3
  66. package/dist/admin/future/pages/Assets/components/EmptyState.js.map +1 -1
  67. package/dist/admin/future/pages/Assets/components/EmptyState.mjs +62 -4
  68. package/dist/admin/future/pages/Assets/components/EmptyState.mjs.map +1 -1
  69. package/dist/admin/future/pages/Assets/components/FilterBadges.js +408 -0
  70. package/dist/admin/future/pages/Assets/components/FilterBadges.js.map +1 -0
  71. package/dist/admin/future/pages/Assets/components/FilterBadges.mjs +406 -0
  72. package/dist/admin/future/pages/Assets/components/FilterBadges.mjs.map +1 -0
  73. package/dist/admin/future/pages/Assets/components/FilterMenu.js +273 -0
  74. package/dist/admin/future/pages/Assets/components/FilterMenu.js.map +1 -0
  75. package/dist/admin/future/pages/Assets/components/FilterMenu.mjs +267 -0
  76. package/dist/admin/future/pages/Assets/components/FilterMenu.mjs.map +1 -0
  77. package/dist/admin/future/pages/Assets/components/FolderTree/FolderTree.js +76 -19
  78. package/dist/admin/future/pages/Assets/components/FolderTree/FolderTree.js.map +1 -1
  79. package/dist/admin/future/pages/Assets/components/FolderTree/FolderTree.mjs +78 -21
  80. package/dist/admin/future/pages/Assets/components/FolderTree/FolderTree.mjs.map +1 -1
  81. package/dist/admin/future/pages/Assets/components/FolderTree/filterFolderTree.js +33 -0
  82. package/dist/admin/future/pages/Assets/components/FolderTree/filterFolderTree.js.map +1 -0
  83. package/dist/admin/future/pages/Assets/components/FolderTree/filterFolderTree.mjs +31 -0
  84. package/dist/admin/future/pages/Assets/components/FolderTree/filterFolderTree.mjs.map +1 -0
  85. package/dist/admin/future/pages/Assets/components/SortMenu.js +21 -32
  86. package/dist/admin/future/pages/Assets/components/SortMenu.js.map +1 -1
  87. package/dist/admin/future/pages/Assets/components/SortMenu.mjs +22 -33
  88. package/dist/admin/future/pages/Assets/components/SortMenu.mjs.map +1 -1
  89. package/dist/admin/future/pages/Assets/hooks/useAssetSearch.js +40 -0
  90. package/dist/admin/future/pages/Assets/hooks/useAssetSearch.js.map +1 -0
  91. package/dist/admin/future/pages/Assets/hooks/useAssetSearch.mjs +38 -0
  92. package/dist/admin/future/pages/Assets/hooks/useAssetSearch.mjs.map +1 -0
  93. package/dist/admin/future/pages/Assets/hooks/useAssetSelection.js +21 -5
  94. package/dist/admin/future/pages/Assets/hooks/useAssetSelection.js.map +1 -1
  95. package/dist/admin/future/pages/Assets/hooks/useAssetSelection.mjs +21 -5
  96. package/dist/admin/future/pages/Assets/hooks/useAssetSelection.mjs.map +1 -1
  97. package/dist/admin/future/pages/Assets/hooks/useFolderNavigation.js +33 -12
  98. package/dist/admin/future/pages/Assets/hooks/useFolderNavigation.js.map +1 -1
  99. package/dist/admin/future/pages/Assets/hooks/useFolderNavigation.mjs +33 -12
  100. package/dist/admin/future/pages/Assets/hooks/useFolderNavigation.mjs.map +1 -1
  101. package/dist/admin/future/pages/Assets/hooks/useInfiniteAssets.js +40 -4
  102. package/dist/admin/future/pages/Assets/hooks/useInfiniteAssets.js.map +1 -1
  103. package/dist/admin/future/pages/Assets/hooks/useInfiniteAssets.mjs +40 -4
  104. package/dist/admin/future/pages/Assets/hooks/useInfiniteAssets.mjs.map +1 -1
  105. package/dist/admin/future/pages/Assets/hooks/useListFilters.js +168 -0
  106. package/dist/admin/future/pages/Assets/hooks/useListFilters.js.map +1 -0
  107. package/dist/admin/future/pages/Assets/hooks/useListFilters.mjs +162 -0
  108. package/dist/admin/future/pages/Assets/hooks/useListFilters.mjs.map +1 -0
  109. package/dist/admin/future/pages/Assets/utils/buildAssetFilters.js +201 -0
  110. package/dist/admin/future/pages/Assets/utils/buildAssetFilters.js.map +1 -0
  111. package/dist/admin/future/pages/Assets/utils/buildAssetFilters.mjs +198 -0
  112. package/dist/admin/future/pages/Assets/utils/buildAssetFilters.mjs.map +1 -0
  113. package/dist/admin/future/pages/Assets/utils/listQueryKey.js +2 -2
  114. package/dist/admin/future/pages/Assets/utils/listQueryKey.js.map +1 -1
  115. package/dist/admin/future/pages/Assets/utils/listQueryKey.mjs +2 -2
  116. package/dist/admin/future/pages/Assets/utils/listQueryKey.mjs.map +1 -1
  117. package/dist/admin/future/services/api.js +163 -28
  118. package/dist/admin/future/services/api.js.map +1 -1
  119. package/dist/admin/future/services/api.mjs +163 -30
  120. package/dist/admin/future/services/api.mjs.map +1 -1
  121. package/dist/admin/future/services/assets.js +29 -17
  122. package/dist/admin/future/services/assets.js.map +1 -1
  123. package/dist/admin/future/services/assets.mjs +29 -17
  124. package/dist/admin/future/services/assets.mjs.map +1 -1
  125. package/dist/admin/future/services/folders.js +29 -17
  126. package/dist/admin/future/services/folders.js.map +1 -1
  127. package/dist/admin/future/services/folders.mjs +29 -17
  128. package/dist/admin/future/services/folders.mjs.map +1 -1
  129. package/dist/admin/future/services/settings.js +10 -3
  130. package/dist/admin/future/services/settings.js.map +1 -1
  131. package/dist/admin/future/services/settings.mjs +10 -3
  132. package/dist/admin/future/services/settings.mjs.map +1 -1
  133. package/dist/admin/future/store/uploadProgress.js +109 -2
  134. package/dist/admin/future/store/uploadProgress.js.map +1 -1
  135. package/dist/admin/future/store/uploadProgress.mjs +105 -3
  136. package/dist/admin/future/store/uploadProgress.mjs.map +1 -1
  137. package/dist/admin/future/utils/searchQueryParam.js +11 -0
  138. package/dist/admin/future/utils/searchQueryParam.js.map +1 -0
  139. package/dist/admin/future/utils/searchQueryParam.mjs +9 -0
  140. package/dist/admin/future/utils/searchQueryParam.mjs.map +1 -0
  141. package/dist/admin/hooks/useSelectionState.js +2 -4
  142. package/dist/admin/hooks/useSelectionState.js.map +1 -1
  143. package/dist/admin/hooks/useSelectionState.mjs +2 -4
  144. package/dist/admin/hooks/useSelectionState.mjs.map +1 -1
  145. package/dist/admin/shared/constants.js +43 -0
  146. package/dist/admin/shared/constants.js.map +1 -0
  147. package/dist/admin/shared/constants.mjs +38 -0
  148. package/dist/admin/shared/constants.mjs.map +1 -0
  149. package/dist/admin/src/future/hooks/useMediaLibraryPermissions.d.ts +21 -0
  150. package/dist/admin/src/future/pages/Assets/components/AssetDetails/AssetCropEditor.d.ts +7 -1
  151. package/dist/admin/src/future/pages/Assets/components/AssetsSearchInput.d.ts +5 -0
  152. package/dist/admin/src/future/pages/Assets/components/BulkActionsBar.d.ts +14 -1
  153. package/dist/admin/src/future/pages/Assets/components/DateRangeCalendar.d.ts +8 -0
  154. package/dist/admin/src/future/pages/Assets/components/DropZone/UploadDropZoneContext.d.ts +8 -1
  155. package/dist/admin/src/future/pages/Assets/components/EmptyState.d.ts +18 -1
  156. package/dist/admin/src/future/pages/Assets/components/FilterBadges.d.ts +6 -0
  157. package/dist/admin/src/future/pages/Assets/components/FilterMenu.d.ts +22 -0
  158. package/dist/admin/src/future/pages/Assets/components/FolderTree/FolderTree.d.ts +13 -4
  159. package/dist/admin/src/future/pages/Assets/components/FolderTree/filterFolderTree.d.ts +16 -0
  160. package/dist/admin/src/future/pages/Assets/components/SortMenu.d.ts +6 -0
  161. package/dist/admin/src/future/pages/Assets/hooks/useAssetSearch.d.ts +12 -0
  162. package/dist/admin/src/future/pages/Assets/hooks/useAssetSelection.d.ts +8 -1
  163. package/dist/admin/src/future/pages/Assets/hooks/useInfiniteAssets.d.ts +13 -3
  164. package/dist/admin/src/future/pages/Assets/hooks/useListFilters.d.ts +69 -0
  165. package/dist/admin/src/future/pages/Assets/utils/buildAssetFilters.d.ts +46 -0
  166. package/dist/admin/src/future/pages/Assets/utils/listQueryKey.d.ts +3 -4
  167. package/dist/admin/src/future/services/api.d.ts +53 -5
  168. package/dist/admin/src/future/services/assets.d.ts +9 -1
  169. package/dist/admin/src/future/services/folders.d.ts +3 -0
  170. package/dist/admin/src/future/services/settings.d.ts +2 -2
  171. package/dist/admin/src/future/store/uploadProgress.d.ts +83 -1
  172. package/dist/admin/src/future/utils/searchQueryParam.d.ts +7 -0
  173. package/dist/admin/src/hooks/useAiAvailability.d.ts +1 -1
  174. package/dist/admin/src/hooks/useEditAsset.d.ts +4 -4
  175. package/dist/admin/src/hooks/useEditFolder.d.ts +4 -4
  176. package/dist/admin/src/hooks/useSettings.d.ts +1 -0
  177. package/dist/admin/src/hooks/useTracking.d.ts +1 -1
  178. package/dist/admin/src/hooks/useUpload.d.ts +1 -1
  179. package/dist/admin/translations/en.json.js +53 -3
  180. package/dist/admin/translations/en.json.js.map +1 -1
  181. package/dist/admin/translations/en.json.mjs +53 -3
  182. package/dist/admin/translations/en.json.mjs.map +1 -1
  183. package/dist/admin/utils/urlYupSchema.js +33 -9
  184. package/dist/admin/utils/urlYupSchema.js.map +1 -1
  185. package/dist/admin/utils/urlYupSchema.mjs +33 -9
  186. package/dist/admin/utils/urlYupSchema.mjs.map +1 -1
  187. package/dist/server/config.js +13 -5
  188. package/dist/server/config.js.map +1 -1
  189. package/dist/server/config.mjs +13 -5
  190. package/dist/server/config.mjs.map +1 -1
  191. package/dist/server/constants.js.map +1 -1
  192. package/dist/server/constants.mjs.map +1 -1
  193. package/dist/server/controllers/admin-file.js +30 -0
  194. package/dist/server/controllers/admin-file.js.map +1 -1
  195. package/dist/server/controllers/admin-file.mjs +30 -0
  196. package/dist/server/controllers/admin-file.mjs.map +1 -1
  197. package/dist/server/controllers/admin-settings.js +20 -2
  198. package/dist/server/controllers/admin-settings.js.map +1 -1
  199. package/dist/server/controllers/admin-settings.mjs +21 -3
  200. package/dist/server/controllers/admin-settings.mjs.map +1 -1
  201. package/dist/server/controllers/content-api.js +1 -2
  202. package/dist/server/controllers/content-api.js.map +1 -1
  203. package/dist/server/controllers/content-api.mjs +2 -2
  204. package/dist/server/controllers/content-api.mjs.map +1 -1
  205. package/dist/server/controllers/validation/admin/ai-metadata.js +12 -0
  206. package/dist/server/controllers/validation/admin/ai-metadata.js.map +1 -0
  207. package/dist/server/controllers/validation/admin/ai-metadata.mjs +10 -0
  208. package/dist/server/controllers/validation/admin/ai-metadata.mjs.map +1 -0
  209. package/dist/server/controllers/validation/admin/settings.js +4 -1
  210. package/dist/server/controllers/validation/admin/settings.js.map +1 -1
  211. package/dist/server/controllers/validation/admin/settings.mjs +1 -1
  212. package/dist/server/controllers/validation/admin/settings.mjs.map +1 -1
  213. package/dist/server/routes/admin.js +18 -0
  214. package/dist/server/routes/admin.js.map +1 -1
  215. package/dist/server/routes/admin.mjs +18 -0
  216. package/dist/server/routes/admin.mjs.map +1 -1
  217. package/dist/server/services/ai-metadata.js +108 -11
  218. package/dist/server/services/ai-metadata.js.map +1 -1
  219. package/dist/server/services/ai-metadata.mjs +108 -11
  220. package/dist/server/services/ai-metadata.mjs.map +1 -1
  221. package/dist/server/services/file.js +86 -13
  222. package/dist/server/services/file.js.map +1 -1
  223. package/dist/server/services/file.mjs +87 -14
  224. package/dist/server/services/file.mjs.map +1 -1
  225. package/dist/server/services/image-manipulation.js +4 -4
  226. package/dist/server/services/image-manipulation.js.map +1 -1
  227. package/dist/server/services/image-manipulation.mjs +4 -4
  228. package/dist/server/services/image-manipulation.mjs.map +1 -1
  229. package/dist/server/shared/constants.js +43 -0
  230. package/dist/server/shared/constants.js.map +1 -0
  231. package/dist/server/shared/constants.mjs +38 -0
  232. package/dist/server/shared/constants.mjs.map +1 -0
  233. package/dist/server/src/config.d.ts +2 -0
  234. package/dist/server/src/config.d.ts.map +1 -1
  235. package/dist/server/src/constants.d.ts +2 -1
  236. package/dist/server/src/constants.d.ts.map +1 -1
  237. package/dist/server/src/controllers/admin-file.d.ts +10 -0
  238. package/dist/server/src/controllers/admin-file.d.ts.map +1 -1
  239. package/dist/server/src/controllers/admin-settings.d.ts.map +1 -1
  240. package/dist/server/src/controllers/index.d.ts +1 -0
  241. package/dist/server/src/controllers/index.d.ts.map +1 -1
  242. package/dist/server/src/controllers/validation/admin/ai-metadata.d.ts +2 -0
  243. package/dist/server/src/controllers/validation/admin/ai-metadata.d.ts.map +1 -0
  244. package/dist/server/src/controllers/validation/admin/settings.d.ts +1 -1
  245. package/dist/server/src/controllers/validation/admin/settings.d.ts.map +1 -1
  246. package/dist/server/src/index.d.ts +7 -1
  247. package/dist/server/src/index.d.ts.map +1 -1
  248. package/dist/server/src/routes/admin.d.ts.map +1 -1
  249. package/dist/server/src/services/ai-metadata.d.ts +19 -0
  250. package/dist/server/src/services/ai-metadata.d.ts.map +1 -1
  251. package/dist/server/src/services/file.d.ts +12 -2
  252. package/dist/server/src/services/file.d.ts.map +1 -1
  253. package/dist/server/src/services/index.d.ts +4 -1
  254. package/dist/server/src/services/index.d.ts.map +1 -1
  255. package/dist/server/src/types.d.ts +3 -0
  256. package/dist/server/src/types.d.ts.map +1 -1
  257. package/dist/shared/constants.d.ts +35 -0
  258. package/dist/shared/constants.d.ts.map +1 -0
  259. package/dist/shared/contracts/files.d.ts +25 -0
  260. package/dist/shared/contracts/files.d.ts.map +1 -1
  261. package/dist/shared/contracts/settings.d.ts +7 -0
  262. package/package.json +7 -7
@@ -1,48 +1,76 @@
1
1
  import { jsxs, Fragment, jsx } from 'react/jsx-runtime';
2
- import { useEffect, useState, useRef, useMemo, useCallback } from 'react';
2
+ import { useEffect, useMemo, useState, useRef, useCallback } from 'react';
3
3
  import * as ToggleGroup from '@radix-ui/react-toggle-group';
4
4
  import { usePersistentState, Layouts, useElementOnScreen } from '@strapi/admin/strapi-admin';
5
5
  import { Box, VisuallyHidden, Flex, SimpleMenu, MenuItem, Loader, Typography } from '@strapi/design-system';
6
6
  import { List, GridFour, Folder, Files, Link, ChevronDown } from '@strapi/icons';
7
7
  import { useIntl } from 'react-intl';
8
8
  import { styled } from 'styled-components';
9
+ import { useAIAvailability } from '../../../hooks/useAiAvailability.mjs';
10
+ import { useMediaLibraryPermissions } from '../../hooks/useMediaLibraryPermissions.mjs';
9
11
  import { useUploadFilesMutation, useUploadFromUrlsMutation } from '../../services/api.mjs';
10
12
  import { useGetFolderQuery, useGetFoldersQuery } from '../../services/folders.mjs';
13
+ import { useGetUploadSettingsQuery } from '../../services/settings.mjs';
11
14
  import { getTranslationKey } from '../../utils/translations.mjs';
12
15
  import { useAssetDetailsParam, AssetDetailsDrawer } from './components/AssetDetails/AssetDetailsDrawer.mjs';
13
16
  import { AssetsGrid } from './components/AssetsGrid.mjs';
17
+ import { AssetsSearchInput } from './components/AssetsSearchInput.mjs';
14
18
  import { AssetsTable } from './components/AssetsTable.mjs';
15
19
  import { BulkActionsBar } from './components/BulkActionsBar.mjs';
16
20
  import { CreateFolderDialog } from './components/CreateFolderDialog.mjs';
17
21
  import { AssetsDndProvider } from './components/Dnd/AssetsDndProvider.mjs';
18
22
  import { DropZoneWithOverlay, DropFilesMessage } from './components/DropZone/UploadDropZone.mjs';
19
23
  import { UploadDropZoneProvider } from './components/DropZone/UploadDropZoneContext.mjs';
20
- import { EmptyState } from './components/EmptyState.mjs';
24
+ import { FilteredEmptyState, EmptyState } from './components/EmptyState.mjs';
25
+ import { FilterBadges } from './components/FilterBadges.mjs';
26
+ import { FilterMenu } from './components/FilterMenu.mjs';
21
27
  import { FolderTree } from './components/FolderTree/FolderTree.mjs';
22
28
  import { ImportFromUrlDialog } from './components/ImportFromUrlDialog.mjs';
23
29
  import { SortMenu } from './components/SortMenu.mjs';
24
30
  import { localStorageKeys, viewOptions } from './constants.mjs';
31
+ import { useAssetSearch } from './hooks/useAssetSearch.mjs';
25
32
  import { AssetSelectionProvider, useAssetSelection } from './hooks/useAssetSelection.mjs';
26
33
  import { useFolderInfo } from './hooks/useFolderInfo.mjs';
27
34
  import { useFolderNavigation } from './hooks/useFolderNavigation.mjs';
28
35
  import { useInfiniteAssets } from './hooks/useInfiniteAssets.mjs';
36
+ import { useListFilters } from './hooks/useListFilters.mjs';
29
37
  import { useListSort } from './hooks/useListSort.mjs';
38
+ import { buildAssetFilters } from './utils/buildAssetFilters.mjs';
30
39
  import { getListQueryKey } from './utils/listQueryKey.mjs';
31
40
  import { mergeMixedList } from './utils/mergeMixedList.mjs';
32
41
 
33
42
  const INTERSECTION_OPTIONS = {
34
43
  threshold: 0.1
35
44
  };
36
- const AssetsView = ({ view, folderId, assetsSort, foldersSort, foldersPosition, onAssetItemClick, onAddAssets })=>{
45
+ const ITEM_COUNT_MESSAGE = {
46
+ id: getTranslationKey('header.content.item-count'),
47
+ defaultMessage: '{count, plural, =1 {# item} other {# items}}'
48
+ };
49
+ const SEARCH_RESULTS_COUNT_MESSAGES = {
50
+ both: {
51
+ id: getTranslationKey('header.search-results.count'),
52
+ defaultMessage: '{numberFolders, plural, one {1 folder} other {# folders}} - {numberAssets, plural, one {1 asset} other {# assets}}'
53
+ },
54
+ folders: {
55
+ id: getTranslationKey('header.search-results.count.folders'),
56
+ defaultMessage: '{numberFolders, plural, one {1 folder} other {# folders}}'
57
+ },
58
+ assets: {
59
+ id: getTranslationKey('header.search-results.count.assets'),
60
+ defaultMessage: '{numberAssets, plural, =0 {0 assets} one {1 asset} other {# assets}}'
61
+ }
62
+ };
63
+ const getSearchResultsCountMessage = (numberFolders, numberAssets)=>{
64
+ if (numberFolders === 0) {
65
+ return SEARCH_RESULTS_COUNT_MESSAGES.assets;
66
+ }
67
+ if (numberAssets === 0) {
68
+ return SEARCH_RESULTS_COUNT_MESSAGES.folders;
69
+ }
70
+ return SEARCH_RESULTS_COUNT_MESSAGES.both;
71
+ };
72
+ const AssetsView = ({ view, folders, isLoadingFolders, assets, isLoadingAssets, isFetchingMore, hasNextPage, fetchNextPage, error, searchQuery, assetsSort, foldersPosition, hasActiveFilters, onClearFilters, onAssetItemClick, onAddAssets, canAddAssets, onClearSearch })=>{
37
73
  const { formatMessage } = useIntl();
38
- const { assets, isLoading: isLoadingAssets, isFetchingMore, hasNextPage, fetchNextPage, error } = useInfiniteAssets({
39
- folder: folderId,
40
- sort: assetsSort
41
- });
42
- const { data: folders = [], isLoading: isLoadingFolders } = useGetFoldersQuery({
43
- parentId: folderId,
44
- sort: foldersSort
45
- });
46
74
  const isGridView = view === viewOptions.GRID;
47
75
  const isLoading = isLoadingAssets || isLoadingFolders;
48
76
  // "Folders: Mixed with files" — interleave the complete folder list into the
@@ -95,8 +123,15 @@ const AssetsView = ({ view, folderId, assetsSort, foldersSort, foldersPosition,
95
123
  });
96
124
  }
97
125
  if (folders.length === 0 && assets.length === 0) {
98
- return /*#__PURE__*/ jsx(EmptyState, {
99
- onAddAssets: onAddAssets
126
+ // While searching, the search empty state wins (it names the query); a
127
+ // filter-only dead end gets the filtered variant with its Clear action.
128
+ return hasActiveFilters && !searchQuery ? /*#__PURE__*/ jsx(FilteredEmptyState, {
129
+ onClearFilters: onClearFilters
130
+ }) : /*#__PURE__*/ jsx(EmptyState, {
131
+ onAddAssets: onAddAssets,
132
+ canAddAssets: canAddAssets,
133
+ searchQuery: searchQuery,
134
+ onClearSearch: onClearSearch
100
135
  });
101
136
  }
102
137
  return /*#__PURE__*/ jsxs(Fragment, {
@@ -126,6 +161,9 @@ const AssetsView = ({ view, folderId, assetsSort, foldersSort, foldersPosition,
126
161
  defaultMessage: 'Loading more assets...'
127
162
  })
128
163
  })
164
+ }),
165
+ /*#__PURE__*/ jsx(BulkActionsBar, {
166
+ assets: assets
129
167
  })
130
168
  ]
131
169
  });
@@ -197,6 +235,7 @@ const HeaderWrapper = styled(Box)`
197
235
  const AssetsPage = ()=>{
198
236
  const { formatMessage } = useIntl();
199
237
  const { openDetails } = useAssetDetailsParam();
238
+ const { canCreate, canUpdate } = useMediaLibraryPermissions();
200
239
  const { currentFolderId, navigateToFolderId, navigateToRoot } = useFolderNavigation();
201
240
  // Deleted or missing folders (404) need a fetch — handled here, not in
202
241
  // `useFolderNavigation` (which only strips malformed ?folder= values).
@@ -214,16 +253,65 @@ const AssetsPage = ()=>{
214
253
  navigateToRoot
215
254
  ]);
216
255
  const { title, itemCount } = useFolderInfo(currentFolderId);
217
- const itemCountLabel = formatMessage({
218
- id: getTranslationKey('header.content.item-count'),
219
- defaultMessage: '{count, plural, =1 {# item} other {# items}}'
256
+ const { searchQuery, isSearching, clearSearch } = useAssetSearch();
257
+ const listSort = useListSort();
258
+ const listFilters = useListFilters();
259
+ // Resolve relative presets against "now" only when the filters change —
260
+ // keeps the query args (and RTK cache keys) stable between renders.
261
+ const builtFilters = useMemo(()=>buildAssetFilters(listFilters.filters, new Date()), // eslint-disable-next-line react-hooks/exhaustive-deps -- serialized is the value identity of filters
262
+ [
263
+ listFilters.serialized
264
+ ]);
265
+ const { assets, pagination, isLoading: isLoadingAssets, isFetchingMore, hasNextPage, fetchNextPage, error: assetsError } = useInfiniteAssets({
266
+ // The real folder is passed even while searching: the service drops the folder
267
+ // filter when `search` is set, so results are still global. List filters
268
+ // compose with both modes.
269
+ folder: currentFolderId,
270
+ search: searchQuery || undefined,
271
+ sort: listSort.assetsSort,
272
+ filters: builtFilters.fileClauses,
273
+ filtersKey: listFilters.serialized,
274
+ enabled: builtFilters.showFiles
275
+ });
276
+ const { data: fetchedFolders = [], isLoading: isLoadingFolders } = useGetFoldersQuery({
277
+ parentId: currentFolderId,
278
+ search: searchQuery || undefined,
279
+ sort: listSort.foldersSort,
280
+ filters: builtFilters.folderClauses
220
281
  }, {
282
+ skip: !builtFilters.showFolders
283
+ });
284
+ // A type badge can exclude folders structurally (e.g. "Type is Picture").
285
+ const folders = useMemo(()=>builtFilters.showFolders ? fetchedFolders : [], [
286
+ builtFilters.showFolders,
287
+ fetchedFolders
288
+ ]);
289
+ const itemCountLabel = formatMessage(ITEM_COUNT_MESSAGE, {
221
290
  count: itemCount
222
291
  });
223
- const pageHeaderTitle = title ? `${title} (${itemCountLabel})` : formatMessage({
224
- id: 'app.loading',
225
- defaultMessage: 'Loading...'
292
+ const searchResultsTitle = formatMessage({
293
+ id: getTranslationKey('header.search-results'),
294
+ defaultMessage: 'Search results for "{query}"'
295
+ }, {
296
+ query: searchQuery
297
+ });
298
+ const numberFolders = folders.length;
299
+ const numberAssets = pagination?.total ?? 0;
300
+ const searchResultsCountLabel = formatMessage(getSearchResultsCountMessage(numberFolders, numberAssets), {
301
+ numberFolders,
302
+ numberAssets
226
303
  });
304
+ let pageHeaderTitle;
305
+ if (isSearching) {
306
+ pageHeaderTitle = `${searchResultsTitle} (${searchResultsCountLabel})`;
307
+ } else if (title) {
308
+ pageHeaderTitle = `${title} (${itemCountLabel})`;
309
+ } else {
310
+ pageHeaderTitle = formatMessage({
311
+ id: 'app.loading',
312
+ defaultMessage: 'Loading...'
313
+ });
314
+ }
227
315
  const [isCreateFolderDialogOpen, setIsCreateFolderDialogOpen] = useState(false);
228
316
  // View state
229
317
  const [view, setView] = usePersistentState(localStorageKeys.view, viewOptions.GRID);
@@ -236,6 +324,13 @@ const AssetsPage = ()=>{
236
324
  // Upload handlers
237
325
  const [uploadFiles] = useUploadFilesMutation();
238
326
  const [uploadFromUrls] = useUploadFromUrlsMutation();
327
+ // `concurrentUploadRequests` echoes the app config. Missing settings (still
328
+ // loading, no permission) fall back to sequential — never faster than the
329
+ // server asked for.
330
+ const { data: settings } = useGetUploadSettingsQuery();
331
+ const concurrency = settings?.data?.concurrentUploadRequests ?? 1;
332
+ // Drives the post-upload AI metadata phase shown per row in the progress dialog.
333
+ const { isEnabled: isAiMetadataEnabled } = useAIAvailability();
239
334
  const uploadFilesToFolder = async (files, folderId)=>{
240
335
  if (files.length === 0) return;
241
336
  const formData = new FormData();
@@ -253,9 +348,11 @@ const AssetsPage = ()=>{
253
348
  try {
254
349
  await uploadFiles({
255
350
  formData,
256
- totalFiles: files.length
351
+ totalFiles: files.length,
352
+ concurrency,
353
+ generateAiMetadata: Boolean(isAiMetadataEnabled)
257
354
  }).unwrap();
258
- } catch (error) {
355
+ } catch {
259
356
  // Error is already dispatched to store from the API queryFn
260
357
  }
261
358
  };
@@ -270,33 +367,38 @@ const AssetsPage = ()=>{
270
367
  e.target.value = '';
271
368
  };
272
369
  const handleDrop = async (files)=>{
370
+ // Defence in depth: the provider is `disabled` without `assets.create`
371
+ // (so onDrop won't fire), but guard here too in case it's ever wired live.
372
+ if (!canCreate) return;
273
373
  await uploadFilesToFolder(files, currentFolderId);
274
374
  };
275
375
  const handleUrlUpload = async (urls)=>{
276
376
  try {
277
377
  await uploadFromUrls({
278
378
  urls,
279
- folderId: currentFolderId
379
+ folderId: currentFolderId,
380
+ generateAiMetadata: Boolean(isAiMetadataEnabled)
280
381
  }).unwrap();
281
- } catch (error) {
382
+ } catch {
282
383
  // Error is already dispatched to store from the API queryFn
283
384
  }
284
385
  };
285
- const listSort = useListSort();
286
386
  // The view is deliberately absent: table and grid render the same list, so
287
387
  // toggling views keeps the selection.
288
388
  const listQueryKey = getListQueryKey({
289
389
  folderId: currentFolderId,
290
- search: '',
390
+ search: searchQuery,
291
391
  // Folder position changes the render order too — selection must reset.
292
392
  sort: `${listSort.assetsSort};folders=${listSort.foldersPosition}`,
293
- filter: null
393
+ filter: listFilters.serialized || null
294
394
  });
295
395
  return /*#__PURE__*/ jsxs(Fragment, {
296
396
  children: [
297
397
  /*#__PURE__*/ jsx(UploadDropZoneProvider, {
298
398
  onDrop: handleDrop,
399
+ disabled: !canCreate,
299
400
  children: /*#__PURE__*/ jsx(AssetSelectionProvider, {
401
+ disabled: !canUpdate,
300
402
  children: /*#__PURE__*/ jsxs(AssetsDndProvider, {
301
403
  children: [
302
404
  /*#__PURE__*/ jsx(ClearSelectionOnChange, {
@@ -309,6 +411,7 @@ const AssetsPage = ()=>{
309
411
  background: "neutral0",
310
412
  sideNav: /*#__PURE__*/ jsx(FolderTree, {
311
413
  currentFolderId: currentFolderId,
414
+ showActiveFolder: !isSearching,
312
415
  onSelectFolder: navigateToFolderId
313
416
  }),
314
417
  children: [
@@ -323,7 +426,7 @@ const AssetsPage = ()=>{
323
426
  /*#__PURE__*/ jsx(HeaderWrapper, {
324
427
  children: /*#__PURE__*/ jsx(Layouts.Header, {
325
428
  title: pageHeaderTitle,
326
- primaryAction: /*#__PURE__*/ jsxs(SimpleMenu, {
429
+ primaryAction: canCreate && /*#__PURE__*/ jsxs(SimpleMenu, {
327
430
  popoverPlacement: "bottom-end",
328
431
  variant: "default",
329
432
  endIcon: /*#__PURE__*/ jsx(ChevronDown, {}),
@@ -358,65 +461,77 @@ const AssetsPage = ()=>{
358
461
  })
359
462
  ]
360
463
  }),
361
- subtitle: /*#__PURE__*/ jsxs(Flex, {
362
- justifyContent: "space-between",
363
- alignItems: "center",
364
- gap: 4,
365
- width: "100%",
464
+ subtitle: /*#__PURE__*/ jsxs(Fragment, {
366
465
  children: [
367
- /*#__PURE__*/ jsx(Flex, {
368
- gap: 4,
369
- alignItems: "center",
370
- children: "TODO: Filters and search"
371
- }),
372
466
  /*#__PURE__*/ jsxs(Flex, {
467
+ justifyContent: "space-between",
468
+ alignItems: "center",
373
469
  gap: 4,
374
- alignItems: "stretch",
470
+ width: "100%",
375
471
  children: [
376
- /*#__PURE__*/ jsx(SortMenu, {
377
- sort: listSort,
378
- showFoldersGroup: !isGridView
472
+ /*#__PURE__*/ jsxs(Flex, {
473
+ gap: 4,
474
+ alignItems: "center",
475
+ children: [
476
+ /*#__PURE__*/ jsx(FilterMenu, {
477
+ listFilters: listFilters
478
+ }),
479
+ /*#__PURE__*/ jsx(AssetsSearchInput, {})
480
+ ]
379
481
  }),
380
- /*#__PURE__*/ jsxs(StyledToggleGroup, {
381
- type: "single",
382
- value: isGridView ? 'grid' : 'table',
383
- onValueChange: (value)=>value && setView(value === 'grid' ? viewOptions.GRID : viewOptions.TABLE),
384
- "aria-label": formatMessage({
385
- id: getTranslationKey('view.switch.label'),
386
- defaultMessage: 'View options'
387
- }),
482
+ /*#__PURE__*/ jsxs(Flex, {
483
+ gap: 4,
484
+ alignItems: "center",
388
485
  children: [
389
- /*#__PURE__*/ jsxs(StyledToggleItem, {
390
- value: "table",
391
- "aria-label": formatMessage({
392
- id: getTranslationKey('view.table'),
393
- defaultMessage: 'Table view'
394
- }),
395
- children: [
396
- /*#__PURE__*/ jsx(List, {}),
397
- formatMessage({
398
- id: getTranslationKey('view.table'),
399
- defaultMessage: 'Table view'
400
- })
401
- ]
486
+ /*#__PURE__*/ jsx(SortMenu, {
487
+ sort: listSort,
488
+ showFoldersGroup: !isGridView
402
489
  }),
403
- /*#__PURE__*/ jsxs(StyledToggleItem, {
404
- value: "grid",
490
+ /*#__PURE__*/ jsxs(StyledToggleGroup, {
491
+ type: "single",
492
+ value: isGridView ? 'grid' : 'table',
493
+ onValueChange: (value)=>value && setView(value === 'grid' ? viewOptions.GRID : viewOptions.TABLE),
405
494
  "aria-label": formatMessage({
406
- id: getTranslationKey('view.grid'),
407
- defaultMessage: 'Grid view'
495
+ id: getTranslationKey('view.switch.label'),
496
+ defaultMessage: 'View options'
408
497
  }),
409
498
  children: [
410
- /*#__PURE__*/ jsx(GridFour, {}),
411
- formatMessage({
412
- id: getTranslationKey('view.grid'),
413
- defaultMessage: 'Grid view'
499
+ /*#__PURE__*/ jsxs(StyledToggleItem, {
500
+ value: "table",
501
+ "aria-label": formatMessage({
502
+ id: getTranslationKey('view.table'),
503
+ defaultMessage: 'Table view'
504
+ }),
505
+ children: [
506
+ /*#__PURE__*/ jsx(List, {}),
507
+ formatMessage({
508
+ id: getTranslationKey('view.table'),
509
+ defaultMessage: 'Table view'
510
+ })
511
+ ]
512
+ }),
513
+ /*#__PURE__*/ jsxs(StyledToggleItem, {
514
+ value: "grid",
515
+ "aria-label": formatMessage({
516
+ id: getTranslationKey('view.grid'),
517
+ defaultMessage: 'Grid view'
518
+ }),
519
+ children: [
520
+ /*#__PURE__*/ jsx(GridFour, {}),
521
+ formatMessage({
522
+ id: getTranslationKey('view.grid'),
523
+ defaultMessage: 'Grid view'
524
+ })
525
+ ]
414
526
  })
415
527
  ]
416
528
  })
417
529
  ]
418
530
  })
419
531
  ]
532
+ }),
533
+ /*#__PURE__*/ jsx(FilterBadges, {
534
+ listFilters: listFilters
420
535
  })
421
536
  ]
422
537
  })
@@ -431,20 +546,30 @@ const AssetsPage = ()=>{
431
546
  }),
432
547
  /*#__PURE__*/ jsx(AssetsView, {
433
548
  view: view,
434
- folderId: currentFolderId,
549
+ folders: folders,
550
+ isLoadingFolders: isLoadingFolders,
551
+ assets: assets,
552
+ isLoadingAssets: isLoadingAssets,
553
+ isFetchingMore: isFetchingMore,
554
+ hasNextPage: hasNextPage,
555
+ fetchNextPage: fetchNextPage,
556
+ error: assetsError,
557
+ searchQuery: searchQuery,
435
558
  assetsSort: listSort.assetsSort,
436
- foldersSort: listSort.foldersSort,
437
559
  foldersPosition: listSort.foldersPosition,
560
+ hasActiveFilters: listFilters.filters.length > 0,
561
+ onClearFilters: listFilters.clearFilters,
438
562
  onAssetItemClick: openDetails,
439
- onAddAssets: handleFileSelect
563
+ onAddAssets: handleFileSelect,
564
+ canAddAssets: canCreate,
565
+ onClearSearch: clearSearch
440
566
  })
441
567
  ]
442
568
  })
443
569
  })
444
570
  ]
445
571
  })
446
- }),
447
- /*#__PURE__*/ jsx(BulkActionsBar, {})
572
+ })
448
573
  ]
449
574
  })
450
575
  })