@strapi/upload 5.56.0 → 5.57.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 (208) hide show
  1. package/dist/admin/hooks/useTracking.js +2 -8
  2. package/dist/admin/hooks/useTracking.js.map +1 -1
  3. package/dist/admin/hooks/useTracking.mjs +3 -8
  4. package/dist/admin/hooks/useTracking.mjs.map +1 -1
  5. package/dist/admin/legacy/hooks/useTracking.js +3 -1
  6. package/dist/admin/legacy/hooks/useTracking.js.map +1 -1
  7. package/dist/admin/legacy/hooks/useTracking.mjs +3 -1
  8. package/dist/admin/legacy/hooks/useTracking.mjs.map +1 -1
  9. package/dist/admin/legacy/pages/App/ConfigureTheView/ConfigureTheView.js +2 -1
  10. package/dist/admin/legacy/pages/App/ConfigureTheView/ConfigureTheView.js.map +1 -1
  11. package/dist/admin/legacy/pages/App/ConfigureTheView/ConfigureTheView.mjs +2 -1
  12. package/dist/admin/legacy/pages/App/ConfigureTheView/ConfigureTheView.mjs.map +1 -1
  13. package/dist/admin/legacy/pages/App/MediaLibrary.js +2 -1
  14. package/dist/admin/legacy/pages/App/MediaLibrary.js.map +1 -1
  15. package/dist/admin/legacy/pages/App/MediaLibrary.mjs +2 -1
  16. package/dist/admin/legacy/pages/App/MediaLibrary.mjs.map +1 -1
  17. package/dist/admin/pages/Assets/AssetsPage.js +24 -12
  18. package/dist/admin/pages/Assets/AssetsPage.js.map +1 -1
  19. package/dist/admin/pages/Assets/AssetsPage.mjs +25 -13
  20. package/dist/admin/pages/Assets/AssetsPage.mjs.map +1 -1
  21. package/dist/admin/pages/Assets/components/AssetActions.js +326 -0
  22. package/dist/admin/pages/Assets/components/AssetActions.js.map +1 -0
  23. package/dist/admin/pages/Assets/components/AssetActions.mjs +324 -0
  24. package/dist/admin/pages/Assets/components/AssetActions.mjs.map +1 -0
  25. package/dist/admin/pages/Assets/components/AssetActionsMenu.js +28 -309
  26. package/dist/admin/pages/Assets/components/AssetActionsMenu.js.map +1 -1
  27. package/dist/admin/pages/Assets/components/AssetActionsMenu.mjs +31 -312
  28. package/dist/admin/pages/Assets/components/AssetActionsMenu.mjs.map +1 -1
  29. package/dist/admin/pages/Assets/components/AssetContextMenu.js +79 -0
  30. package/dist/admin/pages/Assets/components/AssetContextMenu.js.map +1 -0
  31. package/dist/admin/pages/Assets/components/AssetContextMenu.mjs +77 -0
  32. package/dist/admin/pages/Assets/components/AssetContextMenu.mjs.map +1 -0
  33. package/dist/admin/pages/Assets/components/AssetDetails/AssetCropEditor.js +87 -5
  34. package/dist/admin/pages/Assets/components/AssetDetails/AssetCropEditor.js.map +1 -1
  35. package/dist/admin/pages/Assets/components/AssetDetails/AssetCropEditor.mjs +89 -7
  36. package/dist/admin/pages/Assets/components/AssetDetails/AssetCropEditor.mjs.map +1 -1
  37. package/dist/admin/pages/Assets/components/AssetDetails/AssetDetailsDrawer.js +3 -3
  38. package/dist/admin/pages/Assets/components/AssetDetails/AssetDetailsDrawer.js.map +1 -1
  39. package/dist/admin/pages/Assets/components/AssetDetails/AssetDetailsDrawer.mjs +3 -3
  40. package/dist/admin/pages/Assets/components/AssetDetails/AssetDetailsDrawer.mjs.map +1 -1
  41. package/dist/admin/pages/Assets/components/AssetDetails/useCropImg.js +62 -5
  42. package/dist/admin/pages/Assets/components/AssetDetails/useCropImg.js.map +1 -1
  43. package/dist/admin/pages/Assets/components/AssetDetails/useCropImg.mjs +60 -6
  44. package/dist/admin/pages/Assets/components/AssetDetails/useCropImg.mjs.map +1 -1
  45. package/dist/admin/pages/Assets/components/AssetsGrid.js +27 -4
  46. package/dist/admin/pages/Assets/components/AssetsGrid.js.map +1 -1
  47. package/dist/admin/pages/Assets/components/AssetsGrid.mjs +27 -4
  48. package/dist/admin/pages/Assets/components/AssetsGrid.mjs.map +1 -1
  49. package/dist/admin/pages/Assets/components/AssetsTable.js +27 -4
  50. package/dist/admin/pages/Assets/components/AssetsTable.js.map +1 -1
  51. package/dist/admin/pages/Assets/components/AssetsTable.mjs +27 -4
  52. package/dist/admin/pages/Assets/components/AssetsTable.mjs.map +1 -1
  53. package/dist/admin/pages/Assets/components/CursorAnchoredMenu.js +77 -0
  54. package/dist/admin/pages/Assets/components/CursorAnchoredMenu.js.map +1 -0
  55. package/dist/admin/pages/Assets/components/CursorAnchoredMenu.mjs +75 -0
  56. package/dist/admin/pages/Assets/components/CursorAnchoredMenu.mjs.map +1 -0
  57. package/dist/admin/pages/Assets/components/FolderActions.js +139 -0
  58. package/dist/admin/pages/Assets/components/FolderActions.js.map +1 -0
  59. package/dist/admin/pages/Assets/components/FolderActions.mjs +137 -0
  60. package/dist/admin/pages/Assets/components/FolderActions.mjs.map +1 -0
  61. package/dist/admin/pages/Assets/components/FolderActionsMenu.js +25 -119
  62. package/dist/admin/pages/Assets/components/FolderActionsMenu.js.map +1 -1
  63. package/dist/admin/pages/Assets/components/FolderActionsMenu.mjs +27 -121
  64. package/dist/admin/pages/Assets/components/FolderActionsMenu.mjs.map +1 -1
  65. package/dist/admin/pages/Assets/components/FolderContextMenu.js +67 -0
  66. package/dist/admin/pages/Assets/components/FolderContextMenu.js.map +1 -0
  67. package/dist/admin/pages/Assets/components/FolderContextMenu.mjs +65 -0
  68. package/dist/admin/pages/Assets/components/FolderContextMenu.mjs.map +1 -0
  69. package/dist/admin/pages/Assets/components/FolderTree/FolderTree.js +139 -45
  70. package/dist/admin/pages/Assets/components/FolderTree/FolderTree.js.map +1 -1
  71. package/dist/admin/pages/Assets/components/FolderTree/FolderTree.mjs +140 -47
  72. package/dist/admin/pages/Assets/components/FolderTree/FolderTree.mjs.map +1 -1
  73. package/dist/admin/pages/Assets/components/FolderTree/FolderTreeRowMenu.js +115 -0
  74. package/dist/admin/pages/Assets/components/FolderTree/FolderTreeRowMenu.js.map +1 -0
  75. package/dist/admin/pages/Assets/components/FolderTree/FolderTreeRowMenu.mjs +113 -0
  76. package/dist/admin/pages/Assets/components/FolderTree/FolderTreeRowMenu.mjs.map +1 -0
  77. package/dist/admin/pages/Assets/components/ItemContextMenu.js +125 -0
  78. package/dist/admin/pages/Assets/components/ItemContextMenu.js.map +1 -0
  79. package/dist/admin/pages/Assets/components/ItemContextMenu.mjs +122 -0
  80. package/dist/admin/pages/Assets/components/ItemContextMenu.mjs.map +1 -0
  81. package/dist/admin/pages/Assets/components/MainAreaContextMenu.js +88 -63
  82. package/dist/admin/pages/Assets/components/MainAreaContextMenu.js.map +1 -1
  83. package/dist/admin/pages/Assets/components/MainAreaContextMenu.mjs +88 -63
  84. package/dist/admin/pages/Assets/components/MainAreaContextMenu.mjs.map +1 -1
  85. package/dist/admin/pages/Assets/components/SelectionActions.js +111 -0
  86. package/dist/admin/pages/Assets/components/SelectionActions.js.map +1 -0
  87. package/dist/admin/pages/Assets/components/SelectionActions.mjs +109 -0
  88. package/dist/admin/pages/Assets/components/SelectionActions.mjs.map +1 -0
  89. package/dist/admin/pages/Assets/components/SelectionContextMenu.js +82 -0
  90. package/dist/admin/pages/Assets/components/SelectionContextMenu.js.map +1 -0
  91. package/dist/admin/pages/Assets/components/SelectionContextMenu.mjs +80 -0
  92. package/dist/admin/pages/Assets/components/SelectionContextMenu.mjs.map +1 -0
  93. package/dist/admin/pages/Assets/hooks/useAssetSelection.js +10 -0
  94. package/dist/admin/pages/Assets/hooks/useAssetSelection.js.map +1 -1
  95. package/dist/admin/pages/Assets/hooks/useAssetSelection.mjs +10 -0
  96. package/dist/admin/pages/Assets/hooks/useAssetSelection.mjs.map +1 -1
  97. package/dist/admin/pages/SettingsPage/SettingsPage.js +8 -1
  98. package/dist/admin/pages/SettingsPage/SettingsPage.js.map +1 -1
  99. package/dist/admin/pages/SettingsPage/SettingsPage.mjs +8 -1
  100. package/dist/admin/pages/SettingsPage/SettingsPage.mjs.map +1 -1
  101. package/dist/admin/src/hooks/useTracking.d.ts +0 -7
  102. package/dist/admin/src/pages/Assets/components/AssetActions.d.ts +70 -0
  103. package/dist/admin/src/pages/Assets/components/AssetActionsMenu.d.ts +5 -14
  104. package/dist/admin/src/pages/Assets/components/AssetContextMenu.d.ts +27 -0
  105. package/dist/admin/src/pages/Assets/components/AssetDetails/useCropImg.d.ts +16 -0
  106. package/dist/admin/src/pages/Assets/components/CursorAnchoredMenu.d.ts +32 -0
  107. package/dist/admin/src/pages/Assets/components/FolderActions.d.ts +48 -0
  108. package/dist/admin/src/pages/Assets/components/FolderActionsMenu.d.ts +4 -8
  109. package/dist/admin/src/pages/Assets/components/FolderContextMenu.d.ts +21 -0
  110. package/dist/admin/src/pages/Assets/components/FolderTree/FolderTree.d.ts +5 -1
  111. package/dist/admin/src/pages/Assets/components/FolderTree/FolderTreeRowMenu.d.ts +25 -0
  112. package/dist/admin/src/pages/Assets/components/ItemContextMenu.d.ts +53 -0
  113. package/dist/admin/src/pages/Assets/components/MainAreaContextMenu.d.ts +15 -1
  114. package/dist/admin/src/pages/Assets/components/SelectionActions.d.ts +40 -0
  115. package/dist/admin/src/pages/Assets/components/SelectionContextMenu.d.ts +25 -0
  116. package/dist/admin/src/pages/Assets/hooks/useAssetSelection.d.ts +5 -0
  117. package/dist/admin/src/utils/mediaLibraryVersion.d.ts +18 -0
  118. package/dist/admin/translations/en.json.js +8 -3
  119. package/dist/admin/translations/en.json.js.map +1 -1
  120. package/dist/admin/translations/en.json.mjs +8 -3
  121. package/dist/admin/translations/en.json.mjs.map +1 -1
  122. package/dist/admin/utils/mediaLibraryVersion.js +24 -0
  123. package/dist/admin/utils/mediaLibraryVersion.js.map +1 -0
  124. package/dist/admin/utils/mediaLibraryVersion.mjs +20 -0
  125. package/dist/admin/utils/mediaLibraryVersion.mjs.map +1 -0
  126. package/dist/server/controllers/admin-file.js +2 -2
  127. package/dist/server/controllers/admin-file.js.map +1 -1
  128. package/dist/server/controllers/admin-file.mjs +2 -2
  129. package/dist/server/controllers/admin-file.mjs.map +1 -1
  130. package/dist/server/controllers/admin-folder.js +5 -5
  131. package/dist/server/controllers/admin-folder.js.map +1 -1
  132. package/dist/server/controllers/admin-folder.mjs +5 -5
  133. package/dist/server/controllers/admin-folder.mjs.map +1 -1
  134. package/dist/server/controllers/content-api.js +30 -7
  135. package/dist/server/controllers/content-api.js.map +1 -1
  136. package/dist/server/controllers/content-api.mjs +30 -7
  137. package/dist/server/controllers/content-api.mjs.map +1 -1
  138. package/dist/server/controllers/validation/admin/folder-file.js +4 -4
  139. package/dist/server/controllers/validation/admin/folder-file.js.map +1 -1
  140. package/dist/server/controllers/validation/admin/folder-file.mjs +2 -2
  141. package/dist/server/controllers/validation/admin/folder-file.mjs.map +1 -1
  142. package/dist/server/controllers/validation/admin/folder.js +3 -4
  143. package/dist/server/controllers/validation/admin/folder.js.map +1 -1
  144. package/dist/server/controllers/validation/admin/folder.mjs +3 -4
  145. package/dist/server/controllers/validation/admin/folder.mjs.map +1 -1
  146. package/dist/server/controllers/validation/admin/upload.js +1 -2
  147. package/dist/server/controllers/validation/admin/upload.js.map +1 -1
  148. package/dist/server/controllers/validation/admin/upload.mjs +1 -2
  149. package/dist/server/controllers/validation/admin/upload.mjs.map +1 -1
  150. package/dist/server/controllers/validation/admin/utils.js +1 -2
  151. package/dist/server/controllers/validation/admin/utils.js.map +1 -1
  152. package/dist/server/controllers/validation/admin/utils.mjs +1 -2
  153. package/dist/server/controllers/validation/admin/utils.mjs.map +1 -1
  154. package/dist/server/migrations/unsign-richtext-and-blocks-urls.js +2 -2
  155. package/dist/server/migrations/unsign-richtext-and-blocks-urls.js.map +1 -1
  156. package/dist/server/migrations/unsign-richtext-and-blocks-urls.mjs +1 -1
  157. package/dist/server/migrations/unsign-richtext-and-blocks-urls.mjs.map +1 -1
  158. package/dist/server/routes/content-api.js +3 -3
  159. package/dist/server/routes/content-api.js.map +1 -1
  160. package/dist/server/routes/content-api.mjs +3 -3
  161. package/dist/server/routes/content-api.mjs.map +1 -1
  162. package/dist/server/routes/validation/upload.js +8 -0
  163. package/dist/server/routes/validation/upload.js.map +1 -1
  164. package/dist/server/routes/validation/upload.mjs +8 -0
  165. package/dist/server/routes/validation/upload.mjs.map +1 -1
  166. package/dist/server/services/api-upload-folder.js +3 -3
  167. package/dist/server/services/api-upload-folder.js.map +1 -1
  168. package/dist/server/services/api-upload-folder.mjs +3 -3
  169. package/dist/server/services/api-upload-folder.mjs.map +1 -1
  170. package/dist/server/services/extensions/utils.js +19 -15
  171. package/dist/server/services/extensions/utils.js.map +1 -1
  172. package/dist/server/services/extensions/utils.mjs +19 -15
  173. package/dist/server/services/extensions/utils.mjs.map +1 -1
  174. package/dist/server/services/file.js +2 -2
  175. package/dist/server/services/file.js.map +1 -1
  176. package/dist/server/services/file.mjs +1 -1
  177. package/dist/server/services/file.mjs.map +1 -1
  178. package/dist/server/services/folder.js +5 -5
  179. package/dist/server/services/folder.js.map +1 -1
  180. package/dist/server/services/folder.mjs +5 -5
  181. package/dist/server/services/folder.mjs.map +1 -1
  182. package/dist/server/services/provider.js +3 -4
  183. package/dist/server/services/provider.js.map +1 -1
  184. package/dist/server/services/provider.mjs +3 -4
  185. package/dist/server/services/provider.mjs.map +1 -1
  186. package/dist/server/services/upload.js +5 -6
  187. package/dist/server/services/upload.js.map +1 -1
  188. package/dist/server/services/upload.mjs +4 -5
  189. package/dist/server/services/upload.mjs.map +1 -1
  190. package/dist/server/services/weekly-metrics.js +2 -2
  191. package/dist/server/services/weekly-metrics.js.map +1 -1
  192. package/dist/server/services/weekly-metrics.mjs +2 -2
  193. package/dist/server/services/weekly-metrics.mjs.map +1 -1
  194. package/dist/server/src/controllers/admin-folder.d.ts.map +1 -1
  195. package/dist/server/src/controllers/content-api.d.ts.map +1 -1
  196. package/dist/server/src/controllers/validation/admin/folder.d.ts.map +1 -1
  197. package/dist/server/src/controllers/validation/admin/upload.d.ts.map +1 -1
  198. package/dist/server/src/controllers/validation/admin/utils.d.ts.map +1 -1
  199. package/dist/server/src/index.d.ts.map +1 -1
  200. package/dist/server/src/mcp/ambient-instance.d.ts.map +1 -1
  201. package/dist/server/src/routes/validation/upload.d.ts +4 -0
  202. package/dist/server/src/routes/validation/upload.d.ts.map +1 -1
  203. package/dist/server/src/services/extensions/utils.d.ts +33 -1
  204. package/dist/server/src/services/extensions/utils.d.ts.map +1 -1
  205. package/dist/server/src/services/index.d.ts.map +1 -1
  206. package/dist/server/src/services/provider.d.ts.map +1 -1
  207. package/dist/server/src/services/upload.d.ts.map +1 -1
  208. package/package.json +6 -6
@@ -1 +1 @@
1
- {"version":3,"file":"useAssetSelection.mjs","sources":["../../../../../admin/src/pages/Assets/hooks/useAssetSelection.ts"],"sourcesContent":["import {\n createContext,\n createElement,\n useCallback,\n useContext,\n useMemo,\n useState,\n type ReactNode,\n} from 'react';\n\nimport {\n clearSelection,\n createEmptySelection,\n deselect as deselectState,\n getIdsOfKind,\n selectAll as selectAllState,\n selectRange as selectRangeState,\n toggleSelection,\n type ItemKey,\n type SelectionState,\n} from '../utils/selection';\n\n/**\n * Ephemeral, view-state-only multi-select for the future Media Library. Selection\n * is page-scoped and reset on folder navigation or sort/filter changes (the\n * table/grid toggle keeps it — same list, different presentation).\n *\n * The actual computation lives in `../utils/selection.ts` (pure + unit-tested);\n * this hook is a thin React wrapper. Assets and folders share one mechanism —\n * items are tracked as namespaced keys (`asset:1` / `folder:1`) so toggle, range\n * and select-all behave the same for both. Range / select-all receive the\n * ordered key array from the caller (the view owns the rendered order), keeping\n * the context data-source-agnostic.\n */\nexport interface AssetSelection {\n /** Every selected item key (assets and folders), render-order agnostic. */\n selectedKeys: Set<ItemKey>;\n /** Selected asset ids, derived from {@link selectedKeys}. */\n selectedIds: Set<number>;\n /** Selected folder ids, derived from {@link selectedKeys}. */\n selectedFolderIds: Set<number>;\n anchorKey: ItemKey | null;\n isSelected: (key: ItemKey) => boolean;\n /** Additive toggle (Cmd/Ctrl+click, item checkbox). */\n toggle: (key: ItemKey) => void;\n /** Shift+click — selects the contiguous range from the anchor to the target. */\n selectRange: (orderedKeys: ItemKey[], targetKey: ItemKey) => void;\n /** Header checkbox — selects every rendered item (folders and assets). */\n selectAll: (orderedKeys: ItemKey[]) => void;\n /** Row-level \"...\" menu — drops one key when its item leaves the list (move, delete). */\n deselect: (key: ItemKey) => void;\n /** Close button / folder navigation / list-identity changes. */\n clear: () => void;\n}\n\nconst AssetSelectionContext = createContext<AssetSelection | null>(null);\n\ninterface AssetSelectionProviderProps {\n children: ReactNode;\n /**\n * When true, selection is inert: every mutator is a no-op and nothing ever\n * reads as selected. Every bulk action is gated on `assets.update`, so a user\n * without it has nothing to select for — the views also hide the checkboxes,\n * and this makes the remaining paths (click-to-select, Space key) do nothing.\n */\n disabled?: boolean;\n}\n\nexport const AssetSelectionProvider = ({\n children,\n disabled = false,\n}: AssetSelectionProviderProps) => {\n const [state, setState] = useState<SelectionState>(createEmptySelection);\n\n const isSelected = useCallback(\n (key: ItemKey) => !disabled && state.selectedKeys.has(key),\n [disabled, state.selectedKeys]\n );\n\n const toggle = useCallback(\n (key: ItemKey) => {\n if (disabled) return;\n setState((prev) => toggleSelection(prev, key));\n },\n [disabled]\n );\n\n const selectRange = useCallback(\n (orderedKeys: ItemKey[], targetKey: ItemKey) => {\n if (disabled) return;\n setState((prev) => selectRangeState(prev, orderedKeys, targetKey));\n },\n [disabled]\n );\n\n const selectAll = useCallback(\n (orderedKeys: ItemKey[]) => {\n if (disabled) return;\n setState(selectAllState(orderedKeys));\n },\n [disabled]\n );\n\n // No `disabled` guard, like `clear`: this only ever shrinks the selection, and a\n // disabled provider has nothing in it (every additive path is guarded).\n const deselect = useCallback((key: ItemKey) => setState((prev) => deselectState(prev, key)), []);\n\n const clear = useCallback(() => setState(clearSelection()), []);\n\n const selectedIds = useMemo(\n () => getIdsOfKind(state.selectedKeys, 'asset'),\n [state.selectedKeys]\n );\n const selectedFolderIds = useMemo(\n () => getIdsOfKind(state.selectedKeys, 'folder'),\n [state.selectedKeys]\n );\n\n const value = useMemo<AssetSelection>(\n () => ({\n selectedKeys: state.selectedKeys,\n selectedIds,\n selectedFolderIds,\n anchorKey: state.anchorKey,\n isSelected,\n toggle,\n selectRange,\n selectAll,\n deselect,\n clear,\n }),\n [\n state.selectedKeys,\n selectedIds,\n selectedFolderIds,\n state.anchorKey,\n isSelected,\n toggle,\n selectRange,\n selectAll,\n deselect,\n clear,\n ]\n );\n\n return createElement(AssetSelectionContext.Provider, { value }, children);\n};\n\nexport const useAssetSelection = () => {\n const context = useContext(AssetSelectionContext);\n\n if (!context) {\n throw new Error('useAssetSelection must be used within an AssetSelectionProvider');\n }\n\n return context;\n};\n\nexport const useAssetSelectionOptional = () => useContext(AssetSelectionContext);\n"],"names":["AssetSelectionContext","createContext","AssetSelectionProvider","children","disabled","state","setState","useState","createEmptySelection","isSelected","useCallback","key","selectedKeys","has","toggle","prev","toggleSelection","selectRange","orderedKeys","targetKey","selectRangeState","selectAll","selectAllState","deselect","deselectState","clear","clearSelection","selectedIds","useMemo","getIdsOfKind","selectedFolderIds","value","anchorKey","createElement","Provider","useAssetSelection","context","useContext","Error","useAssetSelectionOptional"],"mappings":"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"}
1
+ {"version":3,"file":"useAssetSelection.mjs","sources":["../../../../../admin/src/pages/Assets/hooks/useAssetSelection.ts"],"sourcesContent":["import {\n createContext,\n createElement,\n useCallback,\n useContext,\n useMemo,\n useState,\n type ReactNode,\n} from 'react';\n\nimport {\n clearSelection,\n createEmptySelection,\n deselect as deselectState,\n getIdsOfKind,\n selectAll as selectAllState,\n selectRange as selectRangeState,\n toggleSelection,\n type ItemKey,\n type SelectionState,\n} from '../utils/selection';\n\n/**\n * Ephemeral, view-state-only multi-select for the future Media Library. Selection\n * is page-scoped and reset on folder navigation or sort/filter changes (the\n * table/grid toggle keeps it — same list, different presentation).\n *\n * The actual computation lives in `../utils/selection.ts` (pure + unit-tested);\n * this hook is a thin React wrapper. Assets and folders share one mechanism —\n * items are tracked as namespaced keys (`asset:1` / `folder:1`) so toggle, range\n * and select-all behave the same for both. Range / select-all receive the\n * ordered key array from the caller (the view owns the rendered order), keeping\n * the context data-source-agnostic.\n */\nexport interface AssetSelection {\n /** Every selected item key (assets and folders), render-order agnostic. */\n selectedKeys: Set<ItemKey>;\n /** Selected asset ids, derived from {@link selectedKeys}. */\n selectedIds: Set<number>;\n /** Selected folder ids, derived from {@link selectedKeys}. */\n selectedFolderIds: Set<number>;\n anchorKey: ItemKey | null;\n isSelected: (key: ItemKey) => boolean;\n /** Additive toggle (Cmd/Ctrl+click, item checkbox). */\n toggle: (key: ItemKey) => void;\n /** Shift+click — selects the contiguous range from the anchor to the target. */\n selectRange: (orderedKeys: ItemKey[], targetKey: ItemKey) => void;\n /** Header checkbox — selects every rendered item (folders and assets). */\n selectAll: (orderedKeys: ItemKey[]) => void;\n /**\n * Replaces the selection with this one key, as a right-click on an unselected\n * item does: what the menu then acts on is what the user can see is selected.\n */\n selectOnly: (key: ItemKey) => void;\n /** Row-level \"...\" menu — drops one key when its item leaves the list (move, delete). */\n deselect: (key: ItemKey) => void;\n /** Close button / folder navigation / list-identity changes. */\n clear: () => void;\n}\n\nconst AssetSelectionContext = createContext<AssetSelection | null>(null);\n\ninterface AssetSelectionProviderProps {\n children: ReactNode;\n /**\n * When true, selection is inert: every mutator is a no-op and nothing ever\n * reads as selected. Every bulk action is gated on `assets.update`, so a user\n * without it has nothing to select for — the views also hide the checkboxes,\n * and this makes the remaining paths (click-to-select, Space key) do nothing.\n */\n disabled?: boolean;\n}\n\nexport const AssetSelectionProvider = ({\n children,\n disabled = false,\n}: AssetSelectionProviderProps) => {\n const [state, setState] = useState<SelectionState>(createEmptySelection);\n\n const isSelected = useCallback(\n (key: ItemKey) => !disabled && state.selectedKeys.has(key),\n [disabled, state.selectedKeys]\n );\n\n const toggle = useCallback(\n (key: ItemKey) => {\n if (disabled) return;\n setState((prev) => toggleSelection(prev, key));\n },\n [disabled]\n );\n\n const selectRange = useCallback(\n (orderedKeys: ItemKey[], targetKey: ItemKey) => {\n if (disabled) return;\n setState((prev) => selectRangeState(prev, orderedKeys, targetKey));\n },\n [disabled]\n );\n\n const selectAll = useCallback(\n (orderedKeys: ItemKey[]) => {\n if (disabled) return;\n setState(selectAllState(orderedKeys));\n },\n [disabled]\n );\n\n const selectOnly = useCallback(\n (key: ItemKey) => {\n if (disabled) return;\n setState(selectAllState([key]));\n },\n [disabled]\n );\n\n // No `disabled` guard, like `clear`: this only ever shrinks the selection, and a\n // disabled provider has nothing in it (every additive path is guarded).\n const deselect = useCallback((key: ItemKey) => setState((prev) => deselectState(prev, key)), []);\n\n const clear = useCallback(() => setState(clearSelection()), []);\n\n const selectedIds = useMemo(\n () => getIdsOfKind(state.selectedKeys, 'asset'),\n [state.selectedKeys]\n );\n const selectedFolderIds = useMemo(\n () => getIdsOfKind(state.selectedKeys, 'folder'),\n [state.selectedKeys]\n );\n\n const value = useMemo<AssetSelection>(\n () => ({\n selectedKeys: state.selectedKeys,\n selectedIds,\n selectedFolderIds,\n anchorKey: state.anchorKey,\n isSelected,\n toggle,\n selectRange,\n selectAll,\n selectOnly,\n deselect,\n clear,\n }),\n [\n state.selectedKeys,\n selectedIds,\n selectedFolderIds,\n state.anchorKey,\n isSelected,\n toggle,\n selectRange,\n selectAll,\n selectOnly,\n deselect,\n clear,\n ]\n );\n\n return createElement(AssetSelectionContext.Provider, { value }, children);\n};\n\nexport const useAssetSelection = () => {\n const context = useContext(AssetSelectionContext);\n\n if (!context) {\n throw new Error('useAssetSelection must be used within an AssetSelectionProvider');\n }\n\n return context;\n};\n\nexport const useAssetSelectionOptional = () => useContext(AssetSelectionContext);\n"],"names":["AssetSelectionContext","createContext","AssetSelectionProvider","children","disabled","state","setState","useState","createEmptySelection","isSelected","useCallback","key","selectedKeys","has","toggle","prev","toggleSelection","selectRange","orderedKeys","targetKey","selectRangeState","selectAll","selectAllState","selectOnly","deselect","deselectState","clear","clearSelection","selectedIds","useMemo","getIdsOfKind","selectedFolderIds","value","anchorKey","createElement","Provider","useAssetSelection","context","useContext","Error","useAssetSelectionOptional"],"mappings":"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"}
@@ -9,9 +9,10 @@ var isEqual = require('lodash/isEqual');
9
9
  var reactIntl = require('react-intl');
10
10
  var reactQuery = require('react-query');
11
11
  var constants = require('../../constants.js');
12
+ var useTracking = require('../../hooks/useTracking.js');
12
13
  var useAIMetadataAvailability = require('../../legacy/hooks/useAIMetadataAvailability.js');
13
14
  var useSettings = require('../../legacy/hooks/useSettings.js');
14
- var useTracking = require('../../legacy/hooks/useTracking.js');
15
+ var settings = require('../../services/settings.js');
15
16
  var translations = require('../../utils/translations.js');
16
17
  var init = require('./init.js');
17
18
  var reducer = require('./reducer.js');
@@ -145,6 +146,9 @@ const MetadataAction = ({ job, imagesWithoutMetadataCount, isConfirmDialogOpen,
145
146
  const { put, post, get } = strapiAdmin.useFetchClient();
146
147
  const [isConfirmDialogOpen, setIsConfirmDialogOpen] = React__namespace.useState(false);
147
148
  const { trackUsage } = useTracking.useTracking();
149
+ // Events read this cache. Saving must refresh it, or the next event still
150
+ // reports the value from before the save.
151
+ const { refetch: refetchUploadSettings } = settings.useGetUploadSettingsQuery();
148
152
  const [{ initialData, modifiedData }, dispatch] = React__namespace.useReducer(reducer.reducer, reducer.initialState, init.init);
149
153
  const { data, isLoading, refetch } = useSettings.useSettings();
150
154
  const isAIAvailable = useAIMetadataAvailability.useAIMetadataAvailability();
@@ -171,6 +175,9 @@ const MetadataAction = ({ job, imagesWithoutMetadataCount, isConfirmDialogOpen,
171
175
  const isSaveButtonDisabled = isEqual__default.default(initialData, modifiedData);
172
176
  const { mutateAsync, isLoading: isSubmitting } = reactQuery.useMutation(async (body)=>{
173
177
  const { data } = await put('/upload/settings', body);
178
+ // Refresh before the form's own refetch reveals actions (such as
179
+ // retroactive generation) that emit a tracking event.
180
+ await refetchUploadSettings();
174
181
  return data;
175
182
  }, {
176
183
  onSuccess () {
@@ -1 +1 @@
1
- {"version":3,"file":"SettingsPage.js","sources":["../../../../admin/src/pages/SettingsPage/SettingsPage.tsx"],"sourcesContent":["import * as React from 'react';\n\nimport {\n Page,\n useNotification,\n useFetchClient,\n Layouts,\n ConfirmDialog,\n} from '@strapi/admin/strapi-admin';\nimport {\n Box,\n Button,\n Dialog,\n Flex,\n Grid,\n Toggle,\n Typography,\n Field,\n Status,\n Divider,\n StatusProps,\n TextButton,\n} from '@strapi/design-system';\nimport { Check, Sparkle } from '@strapi/icons';\nimport isEqual from 'lodash/isEqual';\nimport { useIntl } from 'react-intl';\nimport { useMutation, useQuery } from 'react-query';\n\nimport { AIMetadataJob } from '../../../../shared/contracts/ai-metadata-jobs';\nimport { GetAIMetadataPendingCount, CreateAIMetadataJob } from '../../../../shared/contracts/files';\nimport { UpdateSettings } from '../../../../shared/contracts/settings';\nimport { PERMISSIONS } from '../../constants';\nimport { useAIMetadataAvailability } from '../../legacy/hooks/useAIMetadataAvailability';\nimport { useSettings } from '../../legacy/hooks/useSettings';\nimport { useTracking } from '../../legacy/hooks/useTracking';\nimport { getTranslationKey } from '../../utils/translations';\n\nimport { init } from './init';\nimport { initialState, reducer } from './reducer';\nimport { useAIMetadataJob } from './useAIMetadataJob';\n\nimport type { InitialState } from './reducer';\n\n/* -------------------------------------------------------------------------------------------------\n * MetadataAction\n * -----------------------------------------------------------------------------------------------*/\n\nconst BetaStatus = (props: Omit<StatusProps, 'children'>) => {\n const { formatMessage } = useIntl();\n\n return (\n <Status\n size=\"S\"\n variant=\"secondary\"\n style={{ textTransform: 'uppercase', display: 'flex' }}\n {...props}\n >\n <Typography tag=\"span\" variant=\"pi\" fontWeight=\"bold\">\n {formatMessage({\n id: 'app.components.Status.beta',\n defaultMessage: 'Beta',\n })}\n </Typography>\n </Status>\n );\n};\n\ninterface MetadataActionProps {\n job: AIMetadataJob | null;\n imagesWithoutMetadataCount: number;\n isConfirmDialogOpen: boolean;\n onConfirmDialogChange: (open: boolean) => void;\n onGenerate: () => Promise<void>;\n}\n\nconst MetadataAction = ({\n job,\n imagesWithoutMetadataCount,\n isConfirmDialogOpen,\n onConfirmDialogChange,\n onGenerate,\n}: MetadataActionProps) => {\n const { formatMessage } = useIntl();\n\n // If there's an active job processing\n if (job?.status === 'processing') {\n return (\n <Flex gap={2} alignItems=\"center\">\n <Typography variant=\"pi\" textColor=\"neutral600\">\n {formatMessage({\n id: getTranslationKey('settings.form.aiMetadata.generatingMetadata'),\n defaultMessage: 'AI is generating your metadata',\n })}\n </Typography>\n </Flex>\n );\n }\n\n // Only show completed state when all images have metadata\n if (imagesWithoutMetadataCount === 0) {\n return (\n <Typography variant=\"pi\" textColor=\"primary600\">\n <Flex gap={2} alignItems=\"center\">\n <Check width=\"16px\" height=\"16px\" />\n {formatMessage({\n id: getTranslationKey('settings.form.aiMetadata.metadataGenerated'),\n defaultMessage: 'Your metadata has been generated',\n })}\n </Flex>\n </Typography>\n );\n }\n\n return (\n <Dialog.Root open={isConfirmDialogOpen} onOpenChange={onConfirmDialogChange}>\n <Dialog.Trigger>\n <TextButton disabled={imagesWithoutMetadataCount === 0}>\n {formatMessage({\n id: getTranslationKey('settings.form.aiMetadata.generateButton'),\n defaultMessage: 'Generate metadata',\n })}\n </TextButton>\n </Dialog.Trigger>\n <ConfirmDialog\n variant=\"success-light\"\n onConfirm={onGenerate}\n title={\n <Flex gap={2}>\n <BetaStatus />\n {formatMessage({\n id: getTranslationKey('settings.form.aiMetadata.confirmDialog.title'),\n defaultMessage: 'Generate AI Metadata',\n })}\n </Flex>\n }\n >\n {formatMessage(\n {\n id: getTranslationKey('settings.form.aiMetadata.confirmDialog.message'),\n defaultMessage:\n 'This will start a process in the background to generate captions and alternative text for {count, plural, one {# image} other {# images}}. AI can make mistakes, be sure to review the generated content.',\n },\n { count: imagesWithoutMetadataCount }\n )}\n </ConfirmDialog>\n </Dialog.Root>\n );\n};\n\n/* -------------------------------------------------------------------------------------------------\n * SettingsPage\n * -----------------------------------------------------------------------------------------------*/\n\nexport const SettingsPage = () => {\n const { formatMessage } = useIntl();\n const { toggleNotification } = useNotification();\n const { put, post, get } = useFetchClient();\n const [isConfirmDialogOpen, setIsConfirmDialogOpen] = React.useState(false);\n const { trackUsage } = useTracking();\n\n const [{ initialData, modifiedData }, dispatch] = React.useReducer(reducer, initialState, init);\n\n const { data, isLoading, refetch } = useSettings();\n const isAIAvailable = useAIMetadataAvailability();\n\n const { data: imageCountResponse, isLoading: isLoadingImagesWithoutMetadataCount } = useQuery<\n GetAIMetadataPendingCount.Response['data'],\n GetAIMetadataPendingCount.Response['error']\n >(\n ['ai-metadata-count'],\n async () => {\n const { data } = await get<GetAIMetadataPendingCount.Response['data']>(\n '/upload/ai-metadata-jobs/pending-count'\n );\n return data;\n },\n {\n enabled: isAIAvailable && !!data?.aiMetadata,\n retry: false,\n }\n );\n\n const imagesWithoutMetadataCount = imageCountResponse?.imagesWithoutMetadataCount ?? 0;\n\n React.useEffect(() => {\n if (data) {\n dispatch({\n type: 'GET_DATA_SUCCEEDED',\n data,\n });\n }\n }, [data]);\n\n const isSaveButtonDisabled = isEqual(initialData, modifiedData);\n\n const { mutateAsync, isLoading: isSubmitting } = useMutation<\n UpdateSettings.Response['data'],\n UpdateSettings.Response['error'],\n UpdateSettings.Request['body']\n >(\n async (body) => {\n const { data } = await put<UpdateSettings.Response['data'], UpdateSettings.Request['body']>(\n '/upload/settings',\n body\n );\n\n return data;\n },\n {\n onSuccess() {\n refetch();\n\n toggleNotification({\n type: 'success',\n message: formatMessage({ id: 'notification.form.success.fields' }),\n });\n },\n onError(err) {\n toggleNotification({\n type: 'danger',\n message: err?.message ?? formatMessage({ id: 'notification.error' }),\n });\n },\n }\n );\n\n // Poll for latest active job - notifications are handled inside the hook\n const { data: aiMetadataJob, refetch: refetchAiMetadataJob } = useAIMetadataJob({\n enabled: isAIAvailable,\n });\n\n const { mutateAsync: startGenerateAIMetadata } = useMutation<\n CreateAIMetadataJob.Response['data'],\n CreateAIMetadataJob.Response['error'],\n void\n >(\n async () => {\n const { data } = await post<\n CreateAIMetadataJob.Response['data'],\n CreateAIMetadataJob.Request['body']\n >('/upload/ai-metadata-jobs', {});\n return data;\n },\n {\n onSuccess() {\n setIsConfirmDialogOpen(false);\n // Refetch job status to start polling the new job\n refetchAiMetadataJob();\n },\n onError(err) {\n toggleNotification({\n type: 'danger',\n message: (err as Error)?.message || formatMessage({ id: 'notification.error' }),\n });\n setIsConfirmDialogOpen(false);\n },\n }\n );\n\n const handleSubmit = async (e: React.FormEvent<HTMLFormElement>) => {\n e.preventDefault();\n\n if (isSaveButtonDisabled) {\n return;\n }\n\n await mutateAsync(modifiedData!);\n };\n\n const handleChange = ({\n target: { name, value },\n }: {\n target: { name: keyof NonNullable<InitialState['initialData']>; value: boolean };\n }) => {\n dispatch({\n type: 'ON_CHANGE',\n keys: name,\n value,\n });\n };\n\n if (isLoading) {\n return <Page.Loading />;\n }\n\n return (\n <Page.Main tabIndex={-1}>\n <Page.Title>\n {formatMessage({\n id: getTranslationKey('page.title'),\n defaultMessage: 'Settings - Media Library',\n })}\n </Page.Title>\n <form onSubmit={handleSubmit}>\n <Layouts.Header\n title={formatMessage({\n id: getTranslationKey('settings.header.label'),\n defaultMessage: 'Media Library',\n })}\n primaryAction={\n <Button\n disabled={isSaveButtonDisabled}\n loading={isSubmitting}\n type=\"submit\"\n startIcon={<Check />}\n size=\"S\"\n fullWidth\n >\n {formatMessage({\n id: 'global.save',\n defaultMessage: 'Save',\n })}\n </Button>\n }\n subtitle={formatMessage({\n id: getTranslationKey('settings.sub-header.label'),\n defaultMessage: 'Configure the settings for the Media Library',\n })}\n />\n <Layouts.Content>\n <Layouts.Root>\n <Flex direction=\"column\" alignItems=\"stretch\" gap={4}>\n {/* AI features section when ai is available */}\n {isAIAvailable && (\n <Box background=\"neutral0\" padding={6} shadow=\"filterShadow\" hasRadius>\n <Flex direction=\"column\" alignItems=\"stretch\" gap={1}>\n <Grid.Root gap={6}>\n <Grid.Item col={8} xs={12} direction=\"column\" alignItems=\"stretch\">\n <Flex gap={2}>\n <Box color=\"alternative700\">\n <Sparkle />\n </Box>\n <Typography variant=\"delta\" tag=\"h2\">\n {formatMessage({\n id: getTranslationKey('settings.form.aiMetadata.label'),\n defaultMessage:\n 'Generate AI captions and alt texts automatically on upload!',\n })}\n </Typography>\n </Flex>\n <Flex paddingTop={1}>\n <Typography variant=\"pi\" textColor=\"neutral600\">\n {formatMessage({\n id: getTranslationKey('settings.form.aiMetadata.description'),\n defaultMessage:\n 'Enable this feature to save time, optimize your SEO and increase accessibility by letting our AI generate captions and alternative texts for you.',\n })}\n </Typography>\n </Flex>\n </Grid.Item>\n <Grid.Item\n col={4}\n xs={12}\n direction=\"column\"\n alignItems=\"end\"\n justifyContent={'center'}\n >\n <Field.Root name=\"aiMetadata\" minWidth=\"200px\">\n <Toggle\n checked={modifiedData?.aiMetadata}\n offLabel={formatMessage({\n id: 'app.components.ToggleCheckbox.disabled-label',\n defaultMessage: 'Disabled',\n })}\n onLabel={formatMessage({\n id: 'app.components.ToggleCheckbox.enabled-label',\n defaultMessage: 'Enabled',\n })}\n onChange={(e) => {\n handleChange({\n target: { name: 'aiMetadata', value: e.target.checked },\n });\n }}\n />\n </Field.Root>\n </Grid.Item>\n </Grid.Root>\n {/* Retroactive metadata generation when aiMetadata is enabled */}\n {initialData?.aiMetadata &&\n !isLoadingImagesWithoutMetadataCount &&\n Boolean(imageCountResponse?.totalImages) && (\n <>\n <Divider marginTop={4} marginBottom={4} />\n <Flex justifyContent=\"space-between\" alignItems=\"center\" gap={2}>\n <Flex gap={2}>\n <BetaStatus size=\"XS\" />\n <Typography variant=\"pi\" textColor=\"neutral500\">\n {imagesWithoutMetadataCount === 0\n ? formatMessage({\n id: getTranslationKey(\n 'settings.form.aiMetadata.allAssetsHaveMetadata'\n ),\n defaultMessage: 'All assets have caption and alt text',\n })\n : formatMessage(\n {\n id: getTranslationKey(\n 'settings.form.aiMetadata.imagesWithoutMetadata'\n ),\n defaultMessage:\n '{count, plural, one {# image lacks captions or alternative text} other {# images lack captions or alternative text}}',\n },\n { count: imagesWithoutMetadataCount }\n )}\n </Typography>\n </Flex>\n <MetadataAction\n job={aiMetadataJob ?? null}\n imagesWithoutMetadataCount={imagesWithoutMetadataCount}\n isConfirmDialogOpen={isConfirmDialogOpen}\n onConfirmDialogChange={setIsConfirmDialogOpen}\n onGenerate={async () => {\n await startGenerateAIMetadata();\n trackUsage('didGenerateMetadataRetroactively');\n }}\n />\n </Flex>\n </>\n )}\n </Flex>\n </Box>\n )}\n\n <Box background=\"neutral0\" padding={6} shadow=\"filterShadow\" hasRadius>\n <Flex direction=\"column\" alignItems=\"stretch\" gap={4}>\n <Flex>\n <Typography variant=\"delta\" tag=\"h2\">\n {formatMessage({\n id: getTranslationKey('settings.blockTitle'),\n defaultMessage: 'Asset management',\n })}\n </Typography>\n </Flex>\n <Grid.Root gap={6}>\n <Grid.Item col={6} xs={12} direction=\"column\" alignItems=\"stretch\">\n <Field.Root\n hint={formatMessage({\n id: getTranslationKey('settings.form.responsiveDimensions.description'),\n defaultMessage:\n 'Enabling this option will generate multiple formats (small, medium and large) of the uploaded asset.',\n })}\n name=\"responsiveDimensions\"\n >\n <Field.Label>\n {formatMessage({\n id: getTranslationKey('settings.form.responsiveDimensions.label'),\n defaultMessage: 'Responsive friendly upload',\n })}\n </Field.Label>\n <Toggle\n checked={modifiedData?.responsiveDimensions}\n offLabel={formatMessage({\n id: 'app.components.ToggleCheckbox.off-label',\n defaultMessage: 'Off',\n })}\n onLabel={formatMessage({\n id: 'app.components.ToggleCheckbox.on-label',\n defaultMessage: 'On',\n })}\n onChange={(e) => {\n handleChange({\n target: { name: 'responsiveDimensions', value: e.target.checked },\n });\n }}\n />\n <Field.Hint />\n </Field.Root>\n </Grid.Item>\n <Grid.Item col={6} xs={12} direction=\"column\" alignItems=\"stretch\">\n <Field.Root\n hint={formatMessage({\n id: getTranslationKey('settings.form.sizeOptimization.description'),\n defaultMessage:\n 'Enabling this option will reduce the image size and slightly reduce its quality.',\n })}\n name=\"sizeOptimization\"\n >\n <Field.Label>\n {formatMessage({\n id: getTranslationKey('settings.form.sizeOptimization.label'),\n defaultMessage: 'Size optimization',\n })}\n </Field.Label>\n <Toggle\n checked={modifiedData?.sizeOptimization}\n offLabel={formatMessage({\n id: 'app.components.ToggleCheckbox.off-label',\n defaultMessage: 'Off',\n })}\n onLabel={formatMessage({\n id: 'app.components.ToggleCheckbox.on-label',\n defaultMessage: 'On',\n })}\n onChange={(e) => {\n handleChange({\n target: { name: 'sizeOptimization', value: e.target.checked },\n });\n }}\n />\n <Field.Hint />\n </Field.Root>\n </Grid.Item>\n <Grid.Item col={6} xs={12} direction=\"column\" alignItems=\"stretch\">\n <Field.Root\n hint={formatMessage({\n id: getTranslationKey('settings.form.autoOrientation.description'),\n defaultMessage:\n 'Enabling this option will automatically rotate the image according to EXIF orientation tag.',\n })}\n name=\"autoOrientation\"\n >\n <Field.Label>\n {formatMessage({\n id: getTranslationKey('settings.form.autoOrientation.label'),\n defaultMessage: 'Auto orientation',\n })}\n </Field.Label>\n <Toggle\n checked={modifiedData?.autoOrientation}\n offLabel={formatMessage({\n id: 'app.components.ToggleCheckbox.off-label',\n defaultMessage: 'Off',\n })}\n onLabel={formatMessage({\n id: 'app.components.ToggleCheckbox.on-label',\n defaultMessage: 'On',\n })}\n onChange={(e) => {\n handleChange({\n target: { name: 'autoOrientation', value: e.target.checked },\n });\n }}\n />\n <Field.Hint />\n </Field.Root>\n </Grid.Item>\n </Grid.Root>\n </Flex>\n </Box>\n </Flex>\n </Layouts.Root>\n </Layouts.Content>\n </form>\n </Page.Main>\n );\n};\n\nexport const ProtectedSettingsPage = () => (\n <Page.Protect permissions={PERMISSIONS.settings}>\n <SettingsPage />\n </Page.Protect>\n);\n"],"names":["BetaStatus","props","formatMessage","useIntl","_jsx","Status","size","variant","style","textTransform","display","Typography","tag","fontWeight","id","defaultMessage","MetadataAction","job","imagesWithoutMetadataCount","isConfirmDialogOpen","onConfirmDialogChange","onGenerate","status","Flex","gap","alignItems","textColor","getTranslationKey","_jsxs","Check","width","height","Dialog","Root","open","onOpenChange","Trigger","TextButton","disabled","ConfirmDialog","onConfirm","title","count","SettingsPage","toggleNotification","useNotification","put","post","get","useFetchClient","setIsConfirmDialogOpen","React","useState","trackUsage","useTracking","initialData","modifiedData","dispatch","useReducer","reducer","initialState","init","data","isLoading","refetch","useSettings","isAIAvailable","useAIMetadataAvailability","imageCountResponse","isLoadingImagesWithoutMetadataCount","useQuery","enabled","aiMetadata","retry","useEffect","type","isSaveButtonDisabled","isEqual","mutateAsync","isSubmitting","useMutation","body","onSuccess","message","onError","err","aiMetadataJob","refetchAiMetadataJob","useAIMetadataJob","startGenerateAIMetadata","handleSubmit","e","preventDefault","handleChange","target","name","value","keys","Page","Loading","Main","tabIndex","Title","form","onSubmit","Layouts","Header","primaryAction","Button","loading","startIcon","fullWidth","subtitle","Content","direction","Box","background","padding","shadow","hasRadius","Grid","Item","col","xs","color","Sparkle","paddingTop","justifyContent","Field","minWidth","Toggle","checked","offLabel","onLabel","onChange","Boolean","totalImages","_Fragment","Divider","marginTop","marginBottom","hint","Label","responsiveDimensions","Hint","sizeOptimization","autoOrientation","ProtectedSettingsPage","Protect","permissions","PERMISSIONS","settings"],"mappings":"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"}
1
+ {"version":3,"file":"SettingsPage.js","sources":["../../../../admin/src/pages/SettingsPage/SettingsPage.tsx"],"sourcesContent":["import * as React from 'react';\n\nimport {\n Page,\n useNotification,\n useFetchClient,\n Layouts,\n ConfirmDialog,\n} from '@strapi/admin/strapi-admin';\nimport {\n Box,\n Button,\n Dialog,\n Flex,\n Grid,\n Toggle,\n Typography,\n Field,\n Status,\n Divider,\n StatusProps,\n TextButton,\n} from '@strapi/design-system';\nimport { Check, Sparkle } from '@strapi/icons';\nimport isEqual from 'lodash/isEqual';\nimport { useIntl } from 'react-intl';\nimport { useMutation, useQuery } from 'react-query';\n\nimport { AIMetadataJob } from '../../../../shared/contracts/ai-metadata-jobs';\nimport { GetAIMetadataPendingCount, CreateAIMetadataJob } from '../../../../shared/contracts/files';\nimport { UpdateSettings } from '../../../../shared/contracts/settings';\nimport { PERMISSIONS } from '../../constants';\nimport { useTracking } from '../../hooks/useTracking';\nimport { useAIMetadataAvailability } from '../../legacy/hooks/useAIMetadataAvailability';\nimport { useSettings } from '../../legacy/hooks/useSettings';\nimport { useGetUploadSettingsQuery } from '../../services/settings';\nimport { getTranslationKey } from '../../utils/translations';\n\nimport { init } from './init';\nimport { initialState, reducer } from './reducer';\nimport { useAIMetadataJob } from './useAIMetadataJob';\n\nimport type { InitialState } from './reducer';\n\n/* -------------------------------------------------------------------------------------------------\n * MetadataAction\n * -----------------------------------------------------------------------------------------------*/\n\nconst BetaStatus = (props: Omit<StatusProps, 'children'>) => {\n const { formatMessage } = useIntl();\n\n return (\n <Status\n size=\"S\"\n variant=\"secondary\"\n style={{ textTransform: 'uppercase', display: 'flex' }}\n {...props}\n >\n <Typography tag=\"span\" variant=\"pi\" fontWeight=\"bold\">\n {formatMessage({\n id: 'app.components.Status.beta',\n defaultMessage: 'Beta',\n })}\n </Typography>\n </Status>\n );\n};\n\ninterface MetadataActionProps {\n job: AIMetadataJob | null;\n imagesWithoutMetadataCount: number;\n isConfirmDialogOpen: boolean;\n onConfirmDialogChange: (open: boolean) => void;\n onGenerate: () => Promise<void>;\n}\n\nconst MetadataAction = ({\n job,\n imagesWithoutMetadataCount,\n isConfirmDialogOpen,\n onConfirmDialogChange,\n onGenerate,\n}: MetadataActionProps) => {\n const { formatMessage } = useIntl();\n\n // If there's an active job processing\n if (job?.status === 'processing') {\n return (\n <Flex gap={2} alignItems=\"center\">\n <Typography variant=\"pi\" textColor=\"neutral600\">\n {formatMessage({\n id: getTranslationKey('settings.form.aiMetadata.generatingMetadata'),\n defaultMessage: 'AI is generating your metadata',\n })}\n </Typography>\n </Flex>\n );\n }\n\n // Only show completed state when all images have metadata\n if (imagesWithoutMetadataCount === 0) {\n return (\n <Typography variant=\"pi\" textColor=\"primary600\">\n <Flex gap={2} alignItems=\"center\">\n <Check width=\"16px\" height=\"16px\" />\n {formatMessage({\n id: getTranslationKey('settings.form.aiMetadata.metadataGenerated'),\n defaultMessage: 'Your metadata has been generated',\n })}\n </Flex>\n </Typography>\n );\n }\n\n return (\n <Dialog.Root open={isConfirmDialogOpen} onOpenChange={onConfirmDialogChange}>\n <Dialog.Trigger>\n <TextButton disabled={imagesWithoutMetadataCount === 0}>\n {formatMessage({\n id: getTranslationKey('settings.form.aiMetadata.generateButton'),\n defaultMessage: 'Generate metadata',\n })}\n </TextButton>\n </Dialog.Trigger>\n <ConfirmDialog\n variant=\"success-light\"\n onConfirm={onGenerate}\n title={\n <Flex gap={2}>\n <BetaStatus />\n {formatMessage({\n id: getTranslationKey('settings.form.aiMetadata.confirmDialog.title'),\n defaultMessage: 'Generate AI Metadata',\n })}\n </Flex>\n }\n >\n {formatMessage(\n {\n id: getTranslationKey('settings.form.aiMetadata.confirmDialog.message'),\n defaultMessage:\n 'This will start a process in the background to generate captions and alternative text for {count, plural, one {# image} other {# images}}. AI can make mistakes, be sure to review the generated content.',\n },\n { count: imagesWithoutMetadataCount }\n )}\n </ConfirmDialog>\n </Dialog.Root>\n );\n};\n\n/* -------------------------------------------------------------------------------------------------\n * SettingsPage\n * -----------------------------------------------------------------------------------------------*/\n\nexport const SettingsPage = () => {\n const { formatMessage } = useIntl();\n const { toggleNotification } = useNotification();\n const { put, post, get } = useFetchClient();\n const [isConfirmDialogOpen, setIsConfirmDialogOpen] = React.useState(false);\n const { trackUsage } = useTracking();\n // Events read this cache. Saving must refresh it, or the next event still\n // reports the value from before the save.\n const { refetch: refetchUploadSettings } = useGetUploadSettingsQuery();\n\n const [{ initialData, modifiedData }, dispatch] = React.useReducer(reducer, initialState, init);\n\n const { data, isLoading, refetch } = useSettings();\n const isAIAvailable = useAIMetadataAvailability();\n\n const { data: imageCountResponse, isLoading: isLoadingImagesWithoutMetadataCount } = useQuery<\n GetAIMetadataPendingCount.Response['data'],\n GetAIMetadataPendingCount.Response['error']\n >(\n ['ai-metadata-count'],\n async () => {\n const { data } = await get<GetAIMetadataPendingCount.Response['data']>(\n '/upload/ai-metadata-jobs/pending-count'\n );\n return data;\n },\n {\n enabled: isAIAvailable && !!data?.aiMetadata,\n retry: false,\n }\n );\n\n const imagesWithoutMetadataCount = imageCountResponse?.imagesWithoutMetadataCount ?? 0;\n\n React.useEffect(() => {\n if (data) {\n dispatch({\n type: 'GET_DATA_SUCCEEDED',\n data,\n });\n }\n }, [data]);\n\n const isSaveButtonDisabled = isEqual(initialData, modifiedData);\n\n const { mutateAsync, isLoading: isSubmitting } = useMutation<\n UpdateSettings.Response['data'],\n UpdateSettings.Response['error'],\n UpdateSettings.Request['body']\n >(\n async (body) => {\n const { data } = await put<UpdateSettings.Response['data'], UpdateSettings.Request['body']>(\n '/upload/settings',\n body\n );\n\n // Refresh before the form's own refetch reveals actions (such as\n // retroactive generation) that emit a tracking event.\n await refetchUploadSettings();\n\n return data;\n },\n {\n onSuccess() {\n refetch();\n\n toggleNotification({\n type: 'success',\n message: formatMessage({ id: 'notification.form.success.fields' }),\n });\n },\n onError(err) {\n toggleNotification({\n type: 'danger',\n message: err?.message ?? formatMessage({ id: 'notification.error' }),\n });\n },\n }\n );\n\n // Poll for latest active job - notifications are handled inside the hook\n const { data: aiMetadataJob, refetch: refetchAiMetadataJob } = useAIMetadataJob({\n enabled: isAIAvailable,\n });\n\n const { mutateAsync: startGenerateAIMetadata } = useMutation<\n CreateAIMetadataJob.Response['data'],\n CreateAIMetadataJob.Response['error'],\n void\n >(\n async () => {\n const { data } = await post<\n CreateAIMetadataJob.Response['data'],\n CreateAIMetadataJob.Request['body']\n >('/upload/ai-metadata-jobs', {});\n return data;\n },\n {\n onSuccess() {\n setIsConfirmDialogOpen(false);\n // Refetch job status to start polling the new job\n refetchAiMetadataJob();\n },\n onError(err) {\n toggleNotification({\n type: 'danger',\n message: (err as Error)?.message || formatMessage({ id: 'notification.error' }),\n });\n setIsConfirmDialogOpen(false);\n },\n }\n );\n\n const handleSubmit = async (e: React.FormEvent<HTMLFormElement>) => {\n e.preventDefault();\n\n if (isSaveButtonDisabled) {\n return;\n }\n\n await mutateAsync(modifiedData!);\n };\n\n const handleChange = ({\n target: { name, value },\n }: {\n target: { name: keyof NonNullable<InitialState['initialData']>; value: boolean };\n }) => {\n dispatch({\n type: 'ON_CHANGE',\n keys: name,\n value,\n });\n };\n\n if (isLoading) {\n return <Page.Loading />;\n }\n\n return (\n <Page.Main tabIndex={-1}>\n <Page.Title>\n {formatMessage({\n id: getTranslationKey('page.title'),\n defaultMessage: 'Settings - Media Library',\n })}\n </Page.Title>\n <form onSubmit={handleSubmit}>\n <Layouts.Header\n title={formatMessage({\n id: getTranslationKey('settings.header.label'),\n defaultMessage: 'Media Library',\n })}\n primaryAction={\n <Button\n disabled={isSaveButtonDisabled}\n loading={isSubmitting}\n type=\"submit\"\n startIcon={<Check />}\n size=\"S\"\n fullWidth\n >\n {formatMessage({\n id: 'global.save',\n defaultMessage: 'Save',\n })}\n </Button>\n }\n subtitle={formatMessage({\n id: getTranslationKey('settings.sub-header.label'),\n defaultMessage: 'Configure the settings for the Media Library',\n })}\n />\n <Layouts.Content>\n <Layouts.Root>\n <Flex direction=\"column\" alignItems=\"stretch\" gap={4}>\n {/* AI features section when ai is available */}\n {isAIAvailable && (\n <Box background=\"neutral0\" padding={6} shadow=\"filterShadow\" hasRadius>\n <Flex direction=\"column\" alignItems=\"stretch\" gap={1}>\n <Grid.Root gap={6}>\n <Grid.Item col={8} xs={12} direction=\"column\" alignItems=\"stretch\">\n <Flex gap={2}>\n <Box color=\"alternative700\">\n <Sparkle />\n </Box>\n <Typography variant=\"delta\" tag=\"h2\">\n {formatMessage({\n id: getTranslationKey('settings.form.aiMetadata.label'),\n defaultMessage:\n 'Generate AI captions and alt texts automatically on upload!',\n })}\n </Typography>\n </Flex>\n <Flex paddingTop={1}>\n <Typography variant=\"pi\" textColor=\"neutral600\">\n {formatMessage({\n id: getTranslationKey('settings.form.aiMetadata.description'),\n defaultMessage:\n 'Enable this feature to save time, optimize your SEO and increase accessibility by letting our AI generate captions and alternative texts for you.',\n })}\n </Typography>\n </Flex>\n </Grid.Item>\n <Grid.Item\n col={4}\n xs={12}\n direction=\"column\"\n alignItems=\"end\"\n justifyContent={'center'}\n >\n <Field.Root name=\"aiMetadata\" minWidth=\"200px\">\n <Toggle\n checked={modifiedData?.aiMetadata}\n offLabel={formatMessage({\n id: 'app.components.ToggleCheckbox.disabled-label',\n defaultMessage: 'Disabled',\n })}\n onLabel={formatMessage({\n id: 'app.components.ToggleCheckbox.enabled-label',\n defaultMessage: 'Enabled',\n })}\n onChange={(e) => {\n handleChange({\n target: { name: 'aiMetadata', value: e.target.checked },\n });\n }}\n />\n </Field.Root>\n </Grid.Item>\n </Grid.Root>\n {/* Retroactive metadata generation when aiMetadata is enabled */}\n {initialData?.aiMetadata &&\n !isLoadingImagesWithoutMetadataCount &&\n Boolean(imageCountResponse?.totalImages) && (\n <>\n <Divider marginTop={4} marginBottom={4} />\n <Flex justifyContent=\"space-between\" alignItems=\"center\" gap={2}>\n <Flex gap={2}>\n <BetaStatus size=\"XS\" />\n <Typography variant=\"pi\" textColor=\"neutral500\">\n {imagesWithoutMetadataCount === 0\n ? formatMessage({\n id: getTranslationKey(\n 'settings.form.aiMetadata.allAssetsHaveMetadata'\n ),\n defaultMessage: 'All assets have caption and alt text',\n })\n : formatMessage(\n {\n id: getTranslationKey(\n 'settings.form.aiMetadata.imagesWithoutMetadata'\n ),\n defaultMessage:\n '{count, plural, one {# image lacks captions or alternative text} other {# images lack captions or alternative text}}',\n },\n { count: imagesWithoutMetadataCount }\n )}\n </Typography>\n </Flex>\n <MetadataAction\n job={aiMetadataJob ?? null}\n imagesWithoutMetadataCount={imagesWithoutMetadataCount}\n isConfirmDialogOpen={isConfirmDialogOpen}\n onConfirmDialogChange={setIsConfirmDialogOpen}\n onGenerate={async () => {\n await startGenerateAIMetadata();\n trackUsage('didGenerateMetadataRetroactively');\n }}\n />\n </Flex>\n </>\n )}\n </Flex>\n </Box>\n )}\n\n <Box background=\"neutral0\" padding={6} shadow=\"filterShadow\" hasRadius>\n <Flex direction=\"column\" alignItems=\"stretch\" gap={4}>\n <Flex>\n <Typography variant=\"delta\" tag=\"h2\">\n {formatMessage({\n id: getTranslationKey('settings.blockTitle'),\n defaultMessage: 'Asset management',\n })}\n </Typography>\n </Flex>\n <Grid.Root gap={6}>\n <Grid.Item col={6} xs={12} direction=\"column\" alignItems=\"stretch\">\n <Field.Root\n hint={formatMessage({\n id: getTranslationKey('settings.form.responsiveDimensions.description'),\n defaultMessage:\n 'Enabling this option will generate multiple formats (small, medium and large) of the uploaded asset.',\n })}\n name=\"responsiveDimensions\"\n >\n <Field.Label>\n {formatMessage({\n id: getTranslationKey('settings.form.responsiveDimensions.label'),\n defaultMessage: 'Responsive friendly upload',\n })}\n </Field.Label>\n <Toggle\n checked={modifiedData?.responsiveDimensions}\n offLabel={formatMessage({\n id: 'app.components.ToggleCheckbox.off-label',\n defaultMessage: 'Off',\n })}\n onLabel={formatMessage({\n id: 'app.components.ToggleCheckbox.on-label',\n defaultMessage: 'On',\n })}\n onChange={(e) => {\n handleChange({\n target: { name: 'responsiveDimensions', value: e.target.checked },\n });\n }}\n />\n <Field.Hint />\n </Field.Root>\n </Grid.Item>\n <Grid.Item col={6} xs={12} direction=\"column\" alignItems=\"stretch\">\n <Field.Root\n hint={formatMessage({\n id: getTranslationKey('settings.form.sizeOptimization.description'),\n defaultMessage:\n 'Enabling this option will reduce the image size and slightly reduce its quality.',\n })}\n name=\"sizeOptimization\"\n >\n <Field.Label>\n {formatMessage({\n id: getTranslationKey('settings.form.sizeOptimization.label'),\n defaultMessage: 'Size optimization',\n })}\n </Field.Label>\n <Toggle\n checked={modifiedData?.sizeOptimization}\n offLabel={formatMessage({\n id: 'app.components.ToggleCheckbox.off-label',\n defaultMessage: 'Off',\n })}\n onLabel={formatMessage({\n id: 'app.components.ToggleCheckbox.on-label',\n defaultMessage: 'On',\n })}\n onChange={(e) => {\n handleChange({\n target: { name: 'sizeOptimization', value: e.target.checked },\n });\n }}\n />\n <Field.Hint />\n </Field.Root>\n </Grid.Item>\n <Grid.Item col={6} xs={12} direction=\"column\" alignItems=\"stretch\">\n <Field.Root\n hint={formatMessage({\n id: getTranslationKey('settings.form.autoOrientation.description'),\n defaultMessage:\n 'Enabling this option will automatically rotate the image according to EXIF orientation tag.',\n })}\n name=\"autoOrientation\"\n >\n <Field.Label>\n {formatMessage({\n id: getTranslationKey('settings.form.autoOrientation.label'),\n defaultMessage: 'Auto orientation',\n })}\n </Field.Label>\n <Toggle\n checked={modifiedData?.autoOrientation}\n offLabel={formatMessage({\n id: 'app.components.ToggleCheckbox.off-label',\n defaultMessage: 'Off',\n })}\n onLabel={formatMessage({\n id: 'app.components.ToggleCheckbox.on-label',\n defaultMessage: 'On',\n })}\n onChange={(e) => {\n handleChange({\n target: { name: 'autoOrientation', value: e.target.checked },\n });\n }}\n />\n <Field.Hint />\n </Field.Root>\n </Grid.Item>\n </Grid.Root>\n </Flex>\n </Box>\n </Flex>\n </Layouts.Root>\n </Layouts.Content>\n </form>\n </Page.Main>\n );\n};\n\nexport const ProtectedSettingsPage = () => (\n <Page.Protect permissions={PERMISSIONS.settings}>\n <SettingsPage />\n </Page.Protect>\n);\n"],"names":["BetaStatus","props","formatMessage","useIntl","_jsx","Status","size","variant","style","textTransform","display","Typography","tag","fontWeight","id","defaultMessage","MetadataAction","job","imagesWithoutMetadataCount","isConfirmDialogOpen","onConfirmDialogChange","onGenerate","status","Flex","gap","alignItems","textColor","getTranslationKey","_jsxs","Check","width","height","Dialog","Root","open","onOpenChange","Trigger","TextButton","disabled","ConfirmDialog","onConfirm","title","count","SettingsPage","toggleNotification","useNotification","put","post","get","useFetchClient","setIsConfirmDialogOpen","React","useState","trackUsage","useTracking","refetch","refetchUploadSettings","useGetUploadSettingsQuery","initialData","modifiedData","dispatch","useReducer","reducer","initialState","init","data","isLoading","useSettings","isAIAvailable","useAIMetadataAvailability","imageCountResponse","isLoadingImagesWithoutMetadataCount","useQuery","enabled","aiMetadata","retry","useEffect","type","isSaveButtonDisabled","isEqual","mutateAsync","isSubmitting","useMutation","body","onSuccess","message","onError","err","aiMetadataJob","refetchAiMetadataJob","useAIMetadataJob","startGenerateAIMetadata","handleSubmit","e","preventDefault","handleChange","target","name","value","keys","Page","Loading","Main","tabIndex","Title","form","onSubmit","Layouts","Header","primaryAction","Button","loading","startIcon","fullWidth","subtitle","Content","direction","Box","background","padding","shadow","hasRadius","Grid","Item","col","xs","color","Sparkle","paddingTop","justifyContent","Field","minWidth","Toggle","checked","offLabel","onLabel","onChange","Boolean","totalImages","_Fragment","Divider","marginTop","marginBottom","hint","Label","responsiveDimensions","Hint","sizeOptimization","autoOrientation","ProtectedSettingsPage","Protect","permissions","PERMISSIONS","settings"],"mappings":"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"}
@@ -7,9 +7,10 @@ import isEqual from 'lodash/isEqual';
7
7
  import { useIntl } from 'react-intl';
8
8
  import { useQuery, useMutation } from 'react-query';
9
9
  import { PERMISSIONS } from '../../constants.mjs';
10
+ import { useTracking } from '../../hooks/useTracking.mjs';
10
11
  import { useAIMetadataAvailability } from '../../legacy/hooks/useAIMetadataAvailability.mjs';
11
12
  import { useSettings } from '../../legacy/hooks/useSettings.mjs';
12
- import { useTracking } from '../../legacy/hooks/useTracking.mjs';
13
+ import { useGetUploadSettingsQuery } from '../../services/settings.mjs';
13
14
  import { getTranslationKey } from '../../utils/translations.mjs';
14
15
  import { init } from './init.mjs';
15
16
  import { reducer, initialState } from './reducer.mjs';
@@ -120,6 +121,9 @@ const MetadataAction = ({ job, imagesWithoutMetadataCount, isConfirmDialogOpen,
120
121
  const { put, post, get } = useFetchClient();
121
122
  const [isConfirmDialogOpen, setIsConfirmDialogOpen] = React.useState(false);
122
123
  const { trackUsage } = useTracking();
124
+ // Events read this cache. Saving must refresh it, or the next event still
125
+ // reports the value from before the save.
126
+ const { refetch: refetchUploadSettings } = useGetUploadSettingsQuery();
123
127
  const [{ initialData, modifiedData }, dispatch] = React.useReducer(reducer, initialState, init);
124
128
  const { data, isLoading, refetch } = useSettings();
125
129
  const isAIAvailable = useAIMetadataAvailability();
@@ -146,6 +150,9 @@ const MetadataAction = ({ job, imagesWithoutMetadataCount, isConfirmDialogOpen,
146
150
  const isSaveButtonDisabled = isEqual(initialData, modifiedData);
147
151
  const { mutateAsync, isLoading: isSubmitting } = useMutation(async (body)=>{
148
152
  const { data } = await put('/upload/settings', body);
153
+ // Refresh before the form's own refetch reveals actions (such as
154
+ // retroactive generation) that emit a tracking event.
155
+ await refetchUploadSettings();
149
156
  return data;
150
157
  }, {
151
158
  onSuccess () {
@@ -1 +1 @@
1
- {"version":3,"file":"SettingsPage.mjs","sources":["../../../../admin/src/pages/SettingsPage/SettingsPage.tsx"],"sourcesContent":["import * as React from 'react';\n\nimport {\n Page,\n useNotification,\n useFetchClient,\n Layouts,\n ConfirmDialog,\n} from '@strapi/admin/strapi-admin';\nimport {\n Box,\n Button,\n Dialog,\n Flex,\n Grid,\n Toggle,\n Typography,\n Field,\n Status,\n Divider,\n StatusProps,\n TextButton,\n} from '@strapi/design-system';\nimport { Check, Sparkle } from '@strapi/icons';\nimport isEqual from 'lodash/isEqual';\nimport { useIntl } from 'react-intl';\nimport { useMutation, useQuery } from 'react-query';\n\nimport { AIMetadataJob } from '../../../../shared/contracts/ai-metadata-jobs';\nimport { GetAIMetadataPendingCount, CreateAIMetadataJob } from '../../../../shared/contracts/files';\nimport { UpdateSettings } from '../../../../shared/contracts/settings';\nimport { PERMISSIONS } from '../../constants';\nimport { useAIMetadataAvailability } from '../../legacy/hooks/useAIMetadataAvailability';\nimport { useSettings } from '../../legacy/hooks/useSettings';\nimport { useTracking } from '../../legacy/hooks/useTracking';\nimport { getTranslationKey } from '../../utils/translations';\n\nimport { init } from './init';\nimport { initialState, reducer } from './reducer';\nimport { useAIMetadataJob } from './useAIMetadataJob';\n\nimport type { InitialState } from './reducer';\n\n/* -------------------------------------------------------------------------------------------------\n * MetadataAction\n * -----------------------------------------------------------------------------------------------*/\n\nconst BetaStatus = (props: Omit<StatusProps, 'children'>) => {\n const { formatMessage } = useIntl();\n\n return (\n <Status\n size=\"S\"\n variant=\"secondary\"\n style={{ textTransform: 'uppercase', display: 'flex' }}\n {...props}\n >\n <Typography tag=\"span\" variant=\"pi\" fontWeight=\"bold\">\n {formatMessage({\n id: 'app.components.Status.beta',\n defaultMessage: 'Beta',\n })}\n </Typography>\n </Status>\n );\n};\n\ninterface MetadataActionProps {\n job: AIMetadataJob | null;\n imagesWithoutMetadataCount: number;\n isConfirmDialogOpen: boolean;\n onConfirmDialogChange: (open: boolean) => void;\n onGenerate: () => Promise<void>;\n}\n\nconst MetadataAction = ({\n job,\n imagesWithoutMetadataCount,\n isConfirmDialogOpen,\n onConfirmDialogChange,\n onGenerate,\n}: MetadataActionProps) => {\n const { formatMessage } = useIntl();\n\n // If there's an active job processing\n if (job?.status === 'processing') {\n return (\n <Flex gap={2} alignItems=\"center\">\n <Typography variant=\"pi\" textColor=\"neutral600\">\n {formatMessage({\n id: getTranslationKey('settings.form.aiMetadata.generatingMetadata'),\n defaultMessage: 'AI is generating your metadata',\n })}\n </Typography>\n </Flex>\n );\n }\n\n // Only show completed state when all images have metadata\n if (imagesWithoutMetadataCount === 0) {\n return (\n <Typography variant=\"pi\" textColor=\"primary600\">\n <Flex gap={2} alignItems=\"center\">\n <Check width=\"16px\" height=\"16px\" />\n {formatMessage({\n id: getTranslationKey('settings.form.aiMetadata.metadataGenerated'),\n defaultMessage: 'Your metadata has been generated',\n })}\n </Flex>\n </Typography>\n );\n }\n\n return (\n <Dialog.Root open={isConfirmDialogOpen} onOpenChange={onConfirmDialogChange}>\n <Dialog.Trigger>\n <TextButton disabled={imagesWithoutMetadataCount === 0}>\n {formatMessage({\n id: getTranslationKey('settings.form.aiMetadata.generateButton'),\n defaultMessage: 'Generate metadata',\n })}\n </TextButton>\n </Dialog.Trigger>\n <ConfirmDialog\n variant=\"success-light\"\n onConfirm={onGenerate}\n title={\n <Flex gap={2}>\n <BetaStatus />\n {formatMessage({\n id: getTranslationKey('settings.form.aiMetadata.confirmDialog.title'),\n defaultMessage: 'Generate AI Metadata',\n })}\n </Flex>\n }\n >\n {formatMessage(\n {\n id: getTranslationKey('settings.form.aiMetadata.confirmDialog.message'),\n defaultMessage:\n 'This will start a process in the background to generate captions and alternative text for {count, plural, one {# image} other {# images}}. AI can make mistakes, be sure to review the generated content.',\n },\n { count: imagesWithoutMetadataCount }\n )}\n </ConfirmDialog>\n </Dialog.Root>\n );\n};\n\n/* -------------------------------------------------------------------------------------------------\n * SettingsPage\n * -----------------------------------------------------------------------------------------------*/\n\nexport const SettingsPage = () => {\n const { formatMessage } = useIntl();\n const { toggleNotification } = useNotification();\n const { put, post, get } = useFetchClient();\n const [isConfirmDialogOpen, setIsConfirmDialogOpen] = React.useState(false);\n const { trackUsage } = useTracking();\n\n const [{ initialData, modifiedData }, dispatch] = React.useReducer(reducer, initialState, init);\n\n const { data, isLoading, refetch } = useSettings();\n const isAIAvailable = useAIMetadataAvailability();\n\n const { data: imageCountResponse, isLoading: isLoadingImagesWithoutMetadataCount } = useQuery<\n GetAIMetadataPendingCount.Response['data'],\n GetAIMetadataPendingCount.Response['error']\n >(\n ['ai-metadata-count'],\n async () => {\n const { data } = await get<GetAIMetadataPendingCount.Response['data']>(\n '/upload/ai-metadata-jobs/pending-count'\n );\n return data;\n },\n {\n enabled: isAIAvailable && !!data?.aiMetadata,\n retry: false,\n }\n );\n\n const imagesWithoutMetadataCount = imageCountResponse?.imagesWithoutMetadataCount ?? 0;\n\n React.useEffect(() => {\n if (data) {\n dispatch({\n type: 'GET_DATA_SUCCEEDED',\n data,\n });\n }\n }, [data]);\n\n const isSaveButtonDisabled = isEqual(initialData, modifiedData);\n\n const { mutateAsync, isLoading: isSubmitting } = useMutation<\n UpdateSettings.Response['data'],\n UpdateSettings.Response['error'],\n UpdateSettings.Request['body']\n >(\n async (body) => {\n const { data } = await put<UpdateSettings.Response['data'], UpdateSettings.Request['body']>(\n '/upload/settings',\n body\n );\n\n return data;\n },\n {\n onSuccess() {\n refetch();\n\n toggleNotification({\n type: 'success',\n message: formatMessage({ id: 'notification.form.success.fields' }),\n });\n },\n onError(err) {\n toggleNotification({\n type: 'danger',\n message: err?.message ?? formatMessage({ id: 'notification.error' }),\n });\n },\n }\n );\n\n // Poll for latest active job - notifications are handled inside the hook\n const { data: aiMetadataJob, refetch: refetchAiMetadataJob } = useAIMetadataJob({\n enabled: isAIAvailable,\n });\n\n const { mutateAsync: startGenerateAIMetadata } = useMutation<\n CreateAIMetadataJob.Response['data'],\n CreateAIMetadataJob.Response['error'],\n void\n >(\n async () => {\n const { data } = await post<\n CreateAIMetadataJob.Response['data'],\n CreateAIMetadataJob.Request['body']\n >('/upload/ai-metadata-jobs', {});\n return data;\n },\n {\n onSuccess() {\n setIsConfirmDialogOpen(false);\n // Refetch job status to start polling the new job\n refetchAiMetadataJob();\n },\n onError(err) {\n toggleNotification({\n type: 'danger',\n message: (err as Error)?.message || formatMessage({ id: 'notification.error' }),\n });\n setIsConfirmDialogOpen(false);\n },\n }\n );\n\n const handleSubmit = async (e: React.FormEvent<HTMLFormElement>) => {\n e.preventDefault();\n\n if (isSaveButtonDisabled) {\n return;\n }\n\n await mutateAsync(modifiedData!);\n };\n\n const handleChange = ({\n target: { name, value },\n }: {\n target: { name: keyof NonNullable<InitialState['initialData']>; value: boolean };\n }) => {\n dispatch({\n type: 'ON_CHANGE',\n keys: name,\n value,\n });\n };\n\n if (isLoading) {\n return <Page.Loading />;\n }\n\n return (\n <Page.Main tabIndex={-1}>\n <Page.Title>\n {formatMessage({\n id: getTranslationKey('page.title'),\n defaultMessage: 'Settings - Media Library',\n })}\n </Page.Title>\n <form onSubmit={handleSubmit}>\n <Layouts.Header\n title={formatMessage({\n id: getTranslationKey('settings.header.label'),\n defaultMessage: 'Media Library',\n })}\n primaryAction={\n <Button\n disabled={isSaveButtonDisabled}\n loading={isSubmitting}\n type=\"submit\"\n startIcon={<Check />}\n size=\"S\"\n fullWidth\n >\n {formatMessage({\n id: 'global.save',\n defaultMessage: 'Save',\n })}\n </Button>\n }\n subtitle={formatMessage({\n id: getTranslationKey('settings.sub-header.label'),\n defaultMessage: 'Configure the settings for the Media Library',\n })}\n />\n <Layouts.Content>\n <Layouts.Root>\n <Flex direction=\"column\" alignItems=\"stretch\" gap={4}>\n {/* AI features section when ai is available */}\n {isAIAvailable && (\n <Box background=\"neutral0\" padding={6} shadow=\"filterShadow\" hasRadius>\n <Flex direction=\"column\" alignItems=\"stretch\" gap={1}>\n <Grid.Root gap={6}>\n <Grid.Item col={8} xs={12} direction=\"column\" alignItems=\"stretch\">\n <Flex gap={2}>\n <Box color=\"alternative700\">\n <Sparkle />\n </Box>\n <Typography variant=\"delta\" tag=\"h2\">\n {formatMessage({\n id: getTranslationKey('settings.form.aiMetadata.label'),\n defaultMessage:\n 'Generate AI captions and alt texts automatically on upload!',\n })}\n </Typography>\n </Flex>\n <Flex paddingTop={1}>\n <Typography variant=\"pi\" textColor=\"neutral600\">\n {formatMessage({\n id: getTranslationKey('settings.form.aiMetadata.description'),\n defaultMessage:\n 'Enable this feature to save time, optimize your SEO and increase accessibility by letting our AI generate captions and alternative texts for you.',\n })}\n </Typography>\n </Flex>\n </Grid.Item>\n <Grid.Item\n col={4}\n xs={12}\n direction=\"column\"\n alignItems=\"end\"\n justifyContent={'center'}\n >\n <Field.Root name=\"aiMetadata\" minWidth=\"200px\">\n <Toggle\n checked={modifiedData?.aiMetadata}\n offLabel={formatMessage({\n id: 'app.components.ToggleCheckbox.disabled-label',\n defaultMessage: 'Disabled',\n })}\n onLabel={formatMessage({\n id: 'app.components.ToggleCheckbox.enabled-label',\n defaultMessage: 'Enabled',\n })}\n onChange={(e) => {\n handleChange({\n target: { name: 'aiMetadata', value: e.target.checked },\n });\n }}\n />\n </Field.Root>\n </Grid.Item>\n </Grid.Root>\n {/* Retroactive metadata generation when aiMetadata is enabled */}\n {initialData?.aiMetadata &&\n !isLoadingImagesWithoutMetadataCount &&\n Boolean(imageCountResponse?.totalImages) && (\n <>\n <Divider marginTop={4} marginBottom={4} />\n <Flex justifyContent=\"space-between\" alignItems=\"center\" gap={2}>\n <Flex gap={2}>\n <BetaStatus size=\"XS\" />\n <Typography variant=\"pi\" textColor=\"neutral500\">\n {imagesWithoutMetadataCount === 0\n ? formatMessage({\n id: getTranslationKey(\n 'settings.form.aiMetadata.allAssetsHaveMetadata'\n ),\n defaultMessage: 'All assets have caption and alt text',\n })\n : formatMessage(\n {\n id: getTranslationKey(\n 'settings.form.aiMetadata.imagesWithoutMetadata'\n ),\n defaultMessage:\n '{count, plural, one {# image lacks captions or alternative text} other {# images lack captions or alternative text}}',\n },\n { count: imagesWithoutMetadataCount }\n )}\n </Typography>\n </Flex>\n <MetadataAction\n job={aiMetadataJob ?? null}\n imagesWithoutMetadataCount={imagesWithoutMetadataCount}\n isConfirmDialogOpen={isConfirmDialogOpen}\n onConfirmDialogChange={setIsConfirmDialogOpen}\n onGenerate={async () => {\n await startGenerateAIMetadata();\n trackUsage('didGenerateMetadataRetroactively');\n }}\n />\n </Flex>\n </>\n )}\n </Flex>\n </Box>\n )}\n\n <Box background=\"neutral0\" padding={6} shadow=\"filterShadow\" hasRadius>\n <Flex direction=\"column\" alignItems=\"stretch\" gap={4}>\n <Flex>\n <Typography variant=\"delta\" tag=\"h2\">\n {formatMessage({\n id: getTranslationKey('settings.blockTitle'),\n defaultMessage: 'Asset management',\n })}\n </Typography>\n </Flex>\n <Grid.Root gap={6}>\n <Grid.Item col={6} xs={12} direction=\"column\" alignItems=\"stretch\">\n <Field.Root\n hint={formatMessage({\n id: getTranslationKey('settings.form.responsiveDimensions.description'),\n defaultMessage:\n 'Enabling this option will generate multiple formats (small, medium and large) of the uploaded asset.',\n })}\n name=\"responsiveDimensions\"\n >\n <Field.Label>\n {formatMessage({\n id: getTranslationKey('settings.form.responsiveDimensions.label'),\n defaultMessage: 'Responsive friendly upload',\n })}\n </Field.Label>\n <Toggle\n checked={modifiedData?.responsiveDimensions}\n offLabel={formatMessage({\n id: 'app.components.ToggleCheckbox.off-label',\n defaultMessage: 'Off',\n })}\n onLabel={formatMessage({\n id: 'app.components.ToggleCheckbox.on-label',\n defaultMessage: 'On',\n })}\n onChange={(e) => {\n handleChange({\n target: { name: 'responsiveDimensions', value: e.target.checked },\n });\n }}\n />\n <Field.Hint />\n </Field.Root>\n </Grid.Item>\n <Grid.Item col={6} xs={12} direction=\"column\" alignItems=\"stretch\">\n <Field.Root\n hint={formatMessage({\n id: getTranslationKey('settings.form.sizeOptimization.description'),\n defaultMessage:\n 'Enabling this option will reduce the image size and slightly reduce its quality.',\n })}\n name=\"sizeOptimization\"\n >\n <Field.Label>\n {formatMessage({\n id: getTranslationKey('settings.form.sizeOptimization.label'),\n defaultMessage: 'Size optimization',\n })}\n </Field.Label>\n <Toggle\n checked={modifiedData?.sizeOptimization}\n offLabel={formatMessage({\n id: 'app.components.ToggleCheckbox.off-label',\n defaultMessage: 'Off',\n })}\n onLabel={formatMessage({\n id: 'app.components.ToggleCheckbox.on-label',\n defaultMessage: 'On',\n })}\n onChange={(e) => {\n handleChange({\n target: { name: 'sizeOptimization', value: e.target.checked },\n });\n }}\n />\n <Field.Hint />\n </Field.Root>\n </Grid.Item>\n <Grid.Item col={6} xs={12} direction=\"column\" alignItems=\"stretch\">\n <Field.Root\n hint={formatMessage({\n id: getTranslationKey('settings.form.autoOrientation.description'),\n defaultMessage:\n 'Enabling this option will automatically rotate the image according to EXIF orientation tag.',\n })}\n name=\"autoOrientation\"\n >\n <Field.Label>\n {formatMessage({\n id: getTranslationKey('settings.form.autoOrientation.label'),\n defaultMessage: 'Auto orientation',\n })}\n </Field.Label>\n <Toggle\n checked={modifiedData?.autoOrientation}\n offLabel={formatMessage({\n id: 'app.components.ToggleCheckbox.off-label',\n defaultMessage: 'Off',\n })}\n onLabel={formatMessage({\n id: 'app.components.ToggleCheckbox.on-label',\n defaultMessage: 'On',\n })}\n onChange={(e) => {\n handleChange({\n target: { name: 'autoOrientation', value: e.target.checked },\n });\n }}\n />\n <Field.Hint />\n </Field.Root>\n </Grid.Item>\n </Grid.Root>\n </Flex>\n </Box>\n </Flex>\n </Layouts.Root>\n </Layouts.Content>\n </form>\n </Page.Main>\n );\n};\n\nexport const ProtectedSettingsPage = () => (\n <Page.Protect permissions={PERMISSIONS.settings}>\n <SettingsPage />\n </Page.Protect>\n);\n"],"names":["BetaStatus","props","formatMessage","useIntl","_jsx","Status","size","variant","style","textTransform","display","Typography","tag","fontWeight","id","defaultMessage","MetadataAction","job","imagesWithoutMetadataCount","isConfirmDialogOpen","onConfirmDialogChange","onGenerate","status","Flex","gap","alignItems","textColor","getTranslationKey","_jsxs","Check","width","height","Dialog","Root","open","onOpenChange","Trigger","TextButton","disabled","ConfirmDialog","onConfirm","title","count","SettingsPage","toggleNotification","useNotification","put","post","get","useFetchClient","setIsConfirmDialogOpen","React","useState","trackUsage","useTracking","initialData","modifiedData","dispatch","useReducer","reducer","initialState","init","data","isLoading","refetch","useSettings","isAIAvailable","useAIMetadataAvailability","imageCountResponse","isLoadingImagesWithoutMetadataCount","useQuery","enabled","aiMetadata","retry","useEffect","type","isSaveButtonDisabled","isEqual","mutateAsync","isSubmitting","useMutation","body","onSuccess","message","onError","err","aiMetadataJob","refetchAiMetadataJob","useAIMetadataJob","startGenerateAIMetadata","handleSubmit","e","preventDefault","handleChange","target","name","value","keys","Page","Loading","Main","tabIndex","Title","form","onSubmit","Layouts","Header","primaryAction","Button","loading","startIcon","fullWidth","subtitle","Content","direction","Box","background","padding","shadow","hasRadius","Grid","Item","col","xs","color","Sparkle","paddingTop","justifyContent","Field","minWidth","Toggle","checked","offLabel","onLabel","onChange","Boolean","totalImages","_Fragment","Divider","marginTop","marginBottom","hint","Label","responsiveDimensions","Hint","sizeOptimization","autoOrientation","ProtectedSettingsPage","Protect","permissions","PERMISSIONS","settings"],"mappings":"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"}
1
+ {"version":3,"file":"SettingsPage.mjs","sources":["../../../../admin/src/pages/SettingsPage/SettingsPage.tsx"],"sourcesContent":["import * as React from 'react';\n\nimport {\n Page,\n useNotification,\n useFetchClient,\n Layouts,\n ConfirmDialog,\n} from '@strapi/admin/strapi-admin';\nimport {\n Box,\n Button,\n Dialog,\n Flex,\n Grid,\n Toggle,\n Typography,\n Field,\n Status,\n Divider,\n StatusProps,\n TextButton,\n} from '@strapi/design-system';\nimport { Check, Sparkle } from '@strapi/icons';\nimport isEqual from 'lodash/isEqual';\nimport { useIntl } from 'react-intl';\nimport { useMutation, useQuery } from 'react-query';\n\nimport { AIMetadataJob } from '../../../../shared/contracts/ai-metadata-jobs';\nimport { GetAIMetadataPendingCount, CreateAIMetadataJob } from '../../../../shared/contracts/files';\nimport { UpdateSettings } from '../../../../shared/contracts/settings';\nimport { PERMISSIONS } from '../../constants';\nimport { useTracking } from '../../hooks/useTracking';\nimport { useAIMetadataAvailability } from '../../legacy/hooks/useAIMetadataAvailability';\nimport { useSettings } from '../../legacy/hooks/useSettings';\nimport { useGetUploadSettingsQuery } from '../../services/settings';\nimport { getTranslationKey } from '../../utils/translations';\n\nimport { init } from './init';\nimport { initialState, reducer } from './reducer';\nimport { useAIMetadataJob } from './useAIMetadataJob';\n\nimport type { InitialState } from './reducer';\n\n/* -------------------------------------------------------------------------------------------------\n * MetadataAction\n * -----------------------------------------------------------------------------------------------*/\n\nconst BetaStatus = (props: Omit<StatusProps, 'children'>) => {\n const { formatMessage } = useIntl();\n\n return (\n <Status\n size=\"S\"\n variant=\"secondary\"\n style={{ textTransform: 'uppercase', display: 'flex' }}\n {...props}\n >\n <Typography tag=\"span\" variant=\"pi\" fontWeight=\"bold\">\n {formatMessage({\n id: 'app.components.Status.beta',\n defaultMessage: 'Beta',\n })}\n </Typography>\n </Status>\n );\n};\n\ninterface MetadataActionProps {\n job: AIMetadataJob | null;\n imagesWithoutMetadataCount: number;\n isConfirmDialogOpen: boolean;\n onConfirmDialogChange: (open: boolean) => void;\n onGenerate: () => Promise<void>;\n}\n\nconst MetadataAction = ({\n job,\n imagesWithoutMetadataCount,\n isConfirmDialogOpen,\n onConfirmDialogChange,\n onGenerate,\n}: MetadataActionProps) => {\n const { formatMessage } = useIntl();\n\n // If there's an active job processing\n if (job?.status === 'processing') {\n return (\n <Flex gap={2} alignItems=\"center\">\n <Typography variant=\"pi\" textColor=\"neutral600\">\n {formatMessage({\n id: getTranslationKey('settings.form.aiMetadata.generatingMetadata'),\n defaultMessage: 'AI is generating your metadata',\n })}\n </Typography>\n </Flex>\n );\n }\n\n // Only show completed state when all images have metadata\n if (imagesWithoutMetadataCount === 0) {\n return (\n <Typography variant=\"pi\" textColor=\"primary600\">\n <Flex gap={2} alignItems=\"center\">\n <Check width=\"16px\" height=\"16px\" />\n {formatMessage({\n id: getTranslationKey('settings.form.aiMetadata.metadataGenerated'),\n defaultMessage: 'Your metadata has been generated',\n })}\n </Flex>\n </Typography>\n );\n }\n\n return (\n <Dialog.Root open={isConfirmDialogOpen} onOpenChange={onConfirmDialogChange}>\n <Dialog.Trigger>\n <TextButton disabled={imagesWithoutMetadataCount === 0}>\n {formatMessage({\n id: getTranslationKey('settings.form.aiMetadata.generateButton'),\n defaultMessage: 'Generate metadata',\n })}\n </TextButton>\n </Dialog.Trigger>\n <ConfirmDialog\n variant=\"success-light\"\n onConfirm={onGenerate}\n title={\n <Flex gap={2}>\n <BetaStatus />\n {formatMessage({\n id: getTranslationKey('settings.form.aiMetadata.confirmDialog.title'),\n defaultMessage: 'Generate AI Metadata',\n })}\n </Flex>\n }\n >\n {formatMessage(\n {\n id: getTranslationKey('settings.form.aiMetadata.confirmDialog.message'),\n defaultMessage:\n 'This will start a process in the background to generate captions and alternative text for {count, plural, one {# image} other {# images}}. AI can make mistakes, be sure to review the generated content.',\n },\n { count: imagesWithoutMetadataCount }\n )}\n </ConfirmDialog>\n </Dialog.Root>\n );\n};\n\n/* -------------------------------------------------------------------------------------------------\n * SettingsPage\n * -----------------------------------------------------------------------------------------------*/\n\nexport const SettingsPage = () => {\n const { formatMessage } = useIntl();\n const { toggleNotification } = useNotification();\n const { put, post, get } = useFetchClient();\n const [isConfirmDialogOpen, setIsConfirmDialogOpen] = React.useState(false);\n const { trackUsage } = useTracking();\n // Events read this cache. Saving must refresh it, or the next event still\n // reports the value from before the save.\n const { refetch: refetchUploadSettings } = useGetUploadSettingsQuery();\n\n const [{ initialData, modifiedData }, dispatch] = React.useReducer(reducer, initialState, init);\n\n const { data, isLoading, refetch } = useSettings();\n const isAIAvailable = useAIMetadataAvailability();\n\n const { data: imageCountResponse, isLoading: isLoadingImagesWithoutMetadataCount } = useQuery<\n GetAIMetadataPendingCount.Response['data'],\n GetAIMetadataPendingCount.Response['error']\n >(\n ['ai-metadata-count'],\n async () => {\n const { data } = await get<GetAIMetadataPendingCount.Response['data']>(\n '/upload/ai-metadata-jobs/pending-count'\n );\n return data;\n },\n {\n enabled: isAIAvailable && !!data?.aiMetadata,\n retry: false,\n }\n );\n\n const imagesWithoutMetadataCount = imageCountResponse?.imagesWithoutMetadataCount ?? 0;\n\n React.useEffect(() => {\n if (data) {\n dispatch({\n type: 'GET_DATA_SUCCEEDED',\n data,\n });\n }\n }, [data]);\n\n const isSaveButtonDisabled = isEqual(initialData, modifiedData);\n\n const { mutateAsync, isLoading: isSubmitting } = useMutation<\n UpdateSettings.Response['data'],\n UpdateSettings.Response['error'],\n UpdateSettings.Request['body']\n >(\n async (body) => {\n const { data } = await put<UpdateSettings.Response['data'], UpdateSettings.Request['body']>(\n '/upload/settings',\n body\n );\n\n // Refresh before the form's own refetch reveals actions (such as\n // retroactive generation) that emit a tracking event.\n await refetchUploadSettings();\n\n return data;\n },\n {\n onSuccess() {\n refetch();\n\n toggleNotification({\n type: 'success',\n message: formatMessage({ id: 'notification.form.success.fields' }),\n });\n },\n onError(err) {\n toggleNotification({\n type: 'danger',\n message: err?.message ?? formatMessage({ id: 'notification.error' }),\n });\n },\n }\n );\n\n // Poll for latest active job - notifications are handled inside the hook\n const { data: aiMetadataJob, refetch: refetchAiMetadataJob } = useAIMetadataJob({\n enabled: isAIAvailable,\n });\n\n const { mutateAsync: startGenerateAIMetadata } = useMutation<\n CreateAIMetadataJob.Response['data'],\n CreateAIMetadataJob.Response['error'],\n void\n >(\n async () => {\n const { data } = await post<\n CreateAIMetadataJob.Response['data'],\n CreateAIMetadataJob.Request['body']\n >('/upload/ai-metadata-jobs', {});\n return data;\n },\n {\n onSuccess() {\n setIsConfirmDialogOpen(false);\n // Refetch job status to start polling the new job\n refetchAiMetadataJob();\n },\n onError(err) {\n toggleNotification({\n type: 'danger',\n message: (err as Error)?.message || formatMessage({ id: 'notification.error' }),\n });\n setIsConfirmDialogOpen(false);\n },\n }\n );\n\n const handleSubmit = async (e: React.FormEvent<HTMLFormElement>) => {\n e.preventDefault();\n\n if (isSaveButtonDisabled) {\n return;\n }\n\n await mutateAsync(modifiedData!);\n };\n\n const handleChange = ({\n target: { name, value },\n }: {\n target: { name: keyof NonNullable<InitialState['initialData']>; value: boolean };\n }) => {\n dispatch({\n type: 'ON_CHANGE',\n keys: name,\n value,\n });\n };\n\n if (isLoading) {\n return <Page.Loading />;\n }\n\n return (\n <Page.Main tabIndex={-1}>\n <Page.Title>\n {formatMessage({\n id: getTranslationKey('page.title'),\n defaultMessage: 'Settings - Media Library',\n })}\n </Page.Title>\n <form onSubmit={handleSubmit}>\n <Layouts.Header\n title={formatMessage({\n id: getTranslationKey('settings.header.label'),\n defaultMessage: 'Media Library',\n })}\n primaryAction={\n <Button\n disabled={isSaveButtonDisabled}\n loading={isSubmitting}\n type=\"submit\"\n startIcon={<Check />}\n size=\"S\"\n fullWidth\n >\n {formatMessage({\n id: 'global.save',\n defaultMessage: 'Save',\n })}\n </Button>\n }\n subtitle={formatMessage({\n id: getTranslationKey('settings.sub-header.label'),\n defaultMessage: 'Configure the settings for the Media Library',\n })}\n />\n <Layouts.Content>\n <Layouts.Root>\n <Flex direction=\"column\" alignItems=\"stretch\" gap={4}>\n {/* AI features section when ai is available */}\n {isAIAvailable && (\n <Box background=\"neutral0\" padding={6} shadow=\"filterShadow\" hasRadius>\n <Flex direction=\"column\" alignItems=\"stretch\" gap={1}>\n <Grid.Root gap={6}>\n <Grid.Item col={8} xs={12} direction=\"column\" alignItems=\"stretch\">\n <Flex gap={2}>\n <Box color=\"alternative700\">\n <Sparkle />\n </Box>\n <Typography variant=\"delta\" tag=\"h2\">\n {formatMessage({\n id: getTranslationKey('settings.form.aiMetadata.label'),\n defaultMessage:\n 'Generate AI captions and alt texts automatically on upload!',\n })}\n </Typography>\n </Flex>\n <Flex paddingTop={1}>\n <Typography variant=\"pi\" textColor=\"neutral600\">\n {formatMessage({\n id: getTranslationKey('settings.form.aiMetadata.description'),\n defaultMessage:\n 'Enable this feature to save time, optimize your SEO and increase accessibility by letting our AI generate captions and alternative texts for you.',\n })}\n </Typography>\n </Flex>\n </Grid.Item>\n <Grid.Item\n col={4}\n xs={12}\n direction=\"column\"\n alignItems=\"end\"\n justifyContent={'center'}\n >\n <Field.Root name=\"aiMetadata\" minWidth=\"200px\">\n <Toggle\n checked={modifiedData?.aiMetadata}\n offLabel={formatMessage({\n id: 'app.components.ToggleCheckbox.disabled-label',\n defaultMessage: 'Disabled',\n })}\n onLabel={formatMessage({\n id: 'app.components.ToggleCheckbox.enabled-label',\n defaultMessage: 'Enabled',\n })}\n onChange={(e) => {\n handleChange({\n target: { name: 'aiMetadata', value: e.target.checked },\n });\n }}\n />\n </Field.Root>\n </Grid.Item>\n </Grid.Root>\n {/* Retroactive metadata generation when aiMetadata is enabled */}\n {initialData?.aiMetadata &&\n !isLoadingImagesWithoutMetadataCount &&\n Boolean(imageCountResponse?.totalImages) && (\n <>\n <Divider marginTop={4} marginBottom={4} />\n <Flex justifyContent=\"space-between\" alignItems=\"center\" gap={2}>\n <Flex gap={2}>\n <BetaStatus size=\"XS\" />\n <Typography variant=\"pi\" textColor=\"neutral500\">\n {imagesWithoutMetadataCount === 0\n ? formatMessage({\n id: getTranslationKey(\n 'settings.form.aiMetadata.allAssetsHaveMetadata'\n ),\n defaultMessage: 'All assets have caption and alt text',\n })\n : formatMessage(\n {\n id: getTranslationKey(\n 'settings.form.aiMetadata.imagesWithoutMetadata'\n ),\n defaultMessage:\n '{count, plural, one {# image lacks captions or alternative text} other {# images lack captions or alternative text}}',\n },\n { count: imagesWithoutMetadataCount }\n )}\n </Typography>\n </Flex>\n <MetadataAction\n job={aiMetadataJob ?? null}\n imagesWithoutMetadataCount={imagesWithoutMetadataCount}\n isConfirmDialogOpen={isConfirmDialogOpen}\n onConfirmDialogChange={setIsConfirmDialogOpen}\n onGenerate={async () => {\n await startGenerateAIMetadata();\n trackUsage('didGenerateMetadataRetroactively');\n }}\n />\n </Flex>\n </>\n )}\n </Flex>\n </Box>\n )}\n\n <Box background=\"neutral0\" padding={6} shadow=\"filterShadow\" hasRadius>\n <Flex direction=\"column\" alignItems=\"stretch\" gap={4}>\n <Flex>\n <Typography variant=\"delta\" tag=\"h2\">\n {formatMessage({\n id: getTranslationKey('settings.blockTitle'),\n defaultMessage: 'Asset management',\n })}\n </Typography>\n </Flex>\n <Grid.Root gap={6}>\n <Grid.Item col={6} xs={12} direction=\"column\" alignItems=\"stretch\">\n <Field.Root\n hint={formatMessage({\n id: getTranslationKey('settings.form.responsiveDimensions.description'),\n defaultMessage:\n 'Enabling this option will generate multiple formats (small, medium and large) of the uploaded asset.',\n })}\n name=\"responsiveDimensions\"\n >\n <Field.Label>\n {formatMessage({\n id: getTranslationKey('settings.form.responsiveDimensions.label'),\n defaultMessage: 'Responsive friendly upload',\n })}\n </Field.Label>\n <Toggle\n checked={modifiedData?.responsiveDimensions}\n offLabel={formatMessage({\n id: 'app.components.ToggleCheckbox.off-label',\n defaultMessage: 'Off',\n })}\n onLabel={formatMessage({\n id: 'app.components.ToggleCheckbox.on-label',\n defaultMessage: 'On',\n })}\n onChange={(e) => {\n handleChange({\n target: { name: 'responsiveDimensions', value: e.target.checked },\n });\n }}\n />\n <Field.Hint />\n </Field.Root>\n </Grid.Item>\n <Grid.Item col={6} xs={12} direction=\"column\" alignItems=\"stretch\">\n <Field.Root\n hint={formatMessage({\n id: getTranslationKey('settings.form.sizeOptimization.description'),\n defaultMessage:\n 'Enabling this option will reduce the image size and slightly reduce its quality.',\n })}\n name=\"sizeOptimization\"\n >\n <Field.Label>\n {formatMessage({\n id: getTranslationKey('settings.form.sizeOptimization.label'),\n defaultMessage: 'Size optimization',\n })}\n </Field.Label>\n <Toggle\n checked={modifiedData?.sizeOptimization}\n offLabel={formatMessage({\n id: 'app.components.ToggleCheckbox.off-label',\n defaultMessage: 'Off',\n })}\n onLabel={formatMessage({\n id: 'app.components.ToggleCheckbox.on-label',\n defaultMessage: 'On',\n })}\n onChange={(e) => {\n handleChange({\n target: { name: 'sizeOptimization', value: e.target.checked },\n });\n }}\n />\n <Field.Hint />\n </Field.Root>\n </Grid.Item>\n <Grid.Item col={6} xs={12} direction=\"column\" alignItems=\"stretch\">\n <Field.Root\n hint={formatMessage({\n id: getTranslationKey('settings.form.autoOrientation.description'),\n defaultMessage:\n 'Enabling this option will automatically rotate the image according to EXIF orientation tag.',\n })}\n name=\"autoOrientation\"\n >\n <Field.Label>\n {formatMessage({\n id: getTranslationKey('settings.form.autoOrientation.label'),\n defaultMessage: 'Auto orientation',\n })}\n </Field.Label>\n <Toggle\n checked={modifiedData?.autoOrientation}\n offLabel={formatMessage({\n id: 'app.components.ToggleCheckbox.off-label',\n defaultMessage: 'Off',\n })}\n onLabel={formatMessage({\n id: 'app.components.ToggleCheckbox.on-label',\n defaultMessage: 'On',\n })}\n onChange={(e) => {\n handleChange({\n target: { name: 'autoOrientation', value: e.target.checked },\n });\n }}\n />\n <Field.Hint />\n </Field.Root>\n </Grid.Item>\n </Grid.Root>\n </Flex>\n </Box>\n </Flex>\n </Layouts.Root>\n </Layouts.Content>\n </form>\n </Page.Main>\n );\n};\n\nexport const ProtectedSettingsPage = () => (\n <Page.Protect permissions={PERMISSIONS.settings}>\n <SettingsPage />\n </Page.Protect>\n);\n"],"names":["BetaStatus","props","formatMessage","useIntl","_jsx","Status","size","variant","style","textTransform","display","Typography","tag","fontWeight","id","defaultMessage","MetadataAction","job","imagesWithoutMetadataCount","isConfirmDialogOpen","onConfirmDialogChange","onGenerate","status","Flex","gap","alignItems","textColor","getTranslationKey","_jsxs","Check","width","height","Dialog","Root","open","onOpenChange","Trigger","TextButton","disabled","ConfirmDialog","onConfirm","title","count","SettingsPage","toggleNotification","useNotification","put","post","get","useFetchClient","setIsConfirmDialogOpen","React","useState","trackUsage","useTracking","refetch","refetchUploadSettings","useGetUploadSettingsQuery","initialData","modifiedData","dispatch","useReducer","reducer","initialState","init","data","isLoading","useSettings","isAIAvailable","useAIMetadataAvailability","imageCountResponse","isLoadingImagesWithoutMetadataCount","useQuery","enabled","aiMetadata","retry","useEffect","type","isSaveButtonDisabled","isEqual","mutateAsync","isSubmitting","useMutation","body","onSuccess","message","onError","err","aiMetadataJob","refetchAiMetadataJob","useAIMetadataJob","startGenerateAIMetadata","handleSubmit","e","preventDefault","handleChange","target","name","value","keys","Page","Loading","Main","tabIndex","Title","form","onSubmit","Layouts","Header","primaryAction","Button","loading","startIcon","fullWidth","subtitle","Content","direction","Box","background","padding","shadow","hasRadius","Grid","Item","col","xs","color","Sparkle","paddingTop","justifyContent","Field","minWidth","Toggle","checked","offLabel","onLabel","onChange","Boolean","totalImages","_Fragment","Divider","marginTop","marginBottom","hint","Label","responsiveDimensions","Hint","sizeOptimization","autoOrientation","ProtectedSettingsPage","Protect","permissions","PERMISSIONS","settings"],"mappings":"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"}
@@ -1,11 +1,4 @@
1
1
  import { type TrackingEvent } from '@strapi/admin/strapi-admin';
2
- /**
3
- * Media Library version tag stamped on every event fired from the current
4
- * Media Library. Events from `legacy/` omit it, so analytics can filter new
5
- * usage from the old plan while both trees emit the SAME event names. Bump
6
- * this if a future revamp ever needs its own bucket.
7
- */
8
- export declare const MEDIA_LIBRARY_VERSION = "v2";
9
2
  /**
10
3
  * `location` value for every new Media Library event. The new tree is the
11
4
  * standalone Media Library page, which the legacy plan tags `'upload'` (as
@@ -0,0 +1,70 @@
1
+ import type { ReactNode } from 'react';
2
+ import type { File } from '../../../../../shared/contracts/files';
3
+ import type { DragFileData } from '../../../types/dnd';
4
+ interface AssetActionsRender {
5
+ /** The `Menu.Item`s, for whichever trigger is rendering them. */
6
+ items: ReactNode;
7
+ /**
8
+ * The replace file input and the three dialogs. Rendered outside `Menu.Root`
9
+ * by every caller: Radix unmounts menu content on close, and a dialog opened
10
+ * from a menu item has to outlive the menu that opened it.
11
+ */
12
+ dialogs: ReactNode;
13
+ /**
14
+ * False once RBAC has settled and every action is gated away. Callers render
15
+ * no trigger at all in that case — an empty popup is worse than none.
16
+ */
17
+ hasActions: boolean;
18
+ /**
19
+ * True while anything the actions own is still in play — a dialog, or the
20
+ * native file picker. A cursor-anchored caller is mounted only as long as it
21
+ * has something on screen, so it needs this to know it must stay around
22
+ * after the menu closes.
23
+ */
24
+ isBusy: boolean;
25
+ }
26
+ /**
27
+ * The asset actions themselves — items, dialogs and handlers — with no opinion
28
+ * about how the menu is opened. A render-prop rather than a hook because it
29
+ * produces JSX, and the repo reserves `use*.tsx` for tests.
30
+ *
31
+ * Both entry points (the row's `•••` trigger and the right-click menu anchored
32
+ * at the cursor) render what this returns, so neither can drift from the other:
33
+ * adding an action or changing a permission gate happens here, once.
34
+ *
35
+ * Replace / copy link / download duplicate what the details drawer offers as
36
+ * icon buttons, so the same action is one click away without opening the asset
37
+ * first. They are re-implemented rather than lifted out of the drawer: the
38
+ * drawer versions render as `IconButton`s and report through its in-drawer toast
39
+ * slot, neither of which fits a menu item on a row.
40
+ *
41
+ * A successful move or delete deselects this one asset and leaves the rest of
42
+ * the selection intact: the mutations only invalidate RTK tags, so without it an
43
+ * `asset:<id>` key for a file that has been deleted — or has moved out of this
44
+ * list — would linger.
45
+ */
46
+ /** The subset of the RBAC answer these actions are gated on. */
47
+ export interface AssetActionPermissions {
48
+ isLoading: boolean;
49
+ canUpdate: boolean;
50
+ canDownload: boolean;
51
+ canCopyLink: boolean;
52
+ }
53
+ interface AssetActionsProps {
54
+ asset: File;
55
+ dragData: DragFileData;
56
+ /**
57
+ * Already-resolved permissions, for a caller that mounts on demand.
58
+ *
59
+ * `useRBAC` starts every instance at `isLoading: true` with each flag false,
60
+ * so a menu mounted by a right-click would render empty for a tick — an open
61
+ * popup with nothing in it. A caller that has been mounted all along (the
62
+ * context menu provider) has the answer already and passes it here. Omitted
63
+ * by the `•••` trigger, which is mounted with its row and has no such gap.
64
+ */
65
+ permissions?: AssetActionPermissions;
66
+ /** Receives the items and dialogs to place around whichever trigger it owns. */
67
+ children: (actions: AssetActionsRender) => ReactNode;
68
+ }
69
+ export declare const AssetActions: ({ asset, dragData, permissions, children }: AssetActionsProps) => import("react/jsx-runtime").JSX.Element;
70
+ export {};
@@ -7,20 +7,11 @@ interface AssetActionsMenuProps {
7
7
  }
8
8
  /**
9
9
  * The "..." menu on an asset row/card. Always acts on that one asset, whatever
10
- * the current multi-selection is (the bulk actions bar is the selection-scoped
11
- * affordance) — the file mirror of `FolderActionsMenu`.
10
+ * the current multi-selection is (the bulk actions bar and the right-click menu
11
+ * are the selection-scoped affordances) — the file mirror of `FolderActionsMenu`.
12
12
  *
13
- * Replace / copy link / download duplicate what the details drawer offers as
14
- * icon buttons, so the same action is one click away without opening the asset
15
- * first. They are re-implemented rather than lifted out of the drawer: the
16
- * drawer versions render as `IconButton`s and report through its in-drawer toast
17
- * slot, neither of which fits a menu item on a row.
18
- *
19
- * A successful move or delete deselects this one asset and leaves the rest of
20
- * the selection intact: the mutations only invalidate RTK tags, so without it an
21
- * `asset:<id>` key for a file that has been deleted — or has moved out of this
22
- * list — would linger. The other selected rows are untouched, which is the whole
23
- * point of the menu being a single-item affordance.
13
+ * The actions themselves live in `AssetActions`, shared with
14
+ * `AssetContextMenu`. This component is only the trigger.
24
15
  */
25
- export declare const AssetActionsMenu: ({ asset, dragData }: AssetActionsMenuProps) => import("react/jsx-runtime").JSX.Element | null;
16
+ export declare const AssetActionsMenu: ({ asset, dragData }: AssetActionsMenuProps) => import("react/jsx-runtime").JSX.Element;
26
17
  export {};