@strapi/upload 5.52.0 → 5.52.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (198) hide show
  1. package/dist/admin/future/components/TruncatedText.js +76 -0
  2. package/dist/admin/future/components/TruncatedText.js.map +1 -0
  3. package/dist/admin/future/components/TruncatedText.mjs +74 -0
  4. package/dist/admin/future/components/TruncatedText.mjs.map +1 -0
  5. package/dist/admin/future/components/UploadProgressDialog.js +36 -1
  6. package/dist/admin/future/components/UploadProgressDialog.js.map +1 -1
  7. package/dist/admin/future/components/UploadProgressDialog.mjs +37 -2
  8. package/dist/admin/future/components/UploadProgressDialog.mjs.map +1 -1
  9. package/dist/admin/future/hooks/useApiErrorMessage.js +61 -0
  10. package/dist/admin/future/hooks/useApiErrorMessage.js.map +1 -0
  11. package/dist/admin/future/hooks/useApiErrorMessage.mjs +39 -0
  12. package/dist/admin/future/hooks/useApiErrorMessage.mjs.map +1 -0
  13. package/dist/admin/future/hooks/useTracking.js +57 -0
  14. package/dist/admin/future/hooks/useTracking.js.map +1 -0
  15. package/dist/admin/future/hooks/useTracking.mjs +53 -0
  16. package/dist/admin/future/hooks/useTracking.mjs.map +1 -0
  17. package/dist/admin/future/pages/Assets/AssetsPage.js +31 -0
  18. package/dist/admin/future/pages/Assets/AssetsPage.js.map +1 -1
  19. package/dist/admin/future/pages/Assets/AssetsPage.mjs +31 -0
  20. package/dist/admin/future/pages/Assets/AssetsPage.mjs.map +1 -1
  21. package/dist/admin/future/pages/Assets/components/AssetActionsMenu.js +13 -11
  22. package/dist/admin/future/pages/Assets/components/AssetActionsMenu.js.map +1 -1
  23. package/dist/admin/future/pages/Assets/components/AssetActionsMenu.mjs +13 -11
  24. package/dist/admin/future/pages/Assets/components/AssetActionsMenu.mjs.map +1 -1
  25. package/dist/admin/future/pages/Assets/components/AssetDetails/AssetDetailsDrawer.js +62 -51
  26. package/dist/admin/future/pages/Assets/components/AssetDetails/AssetDetailsDrawer.js.map +1 -1
  27. package/dist/admin/future/pages/Assets/components/AssetDetails/AssetDetailsDrawer.mjs +62 -51
  28. package/dist/admin/future/pages/Assets/components/AssetDetails/AssetDetailsDrawer.mjs.map +1 -1
  29. package/dist/admin/future/pages/Assets/components/AssetsGrid.js +3 -4
  30. package/dist/admin/future/pages/Assets/components/AssetsGrid.js.map +1 -1
  31. package/dist/admin/future/pages/Assets/components/AssetsGrid.mjs +4 -5
  32. package/dist/admin/future/pages/Assets/components/AssetsGrid.mjs.map +1 -1
  33. package/dist/admin/future/pages/Assets/components/AssetsSearchInput.js +11 -1
  34. package/dist/admin/future/pages/Assets/components/AssetsSearchInput.js.map +1 -1
  35. package/dist/admin/future/pages/Assets/components/AssetsSearchInput.mjs +11 -1
  36. package/dist/admin/future/pages/Assets/components/AssetsSearchInput.mjs.map +1 -1
  37. package/dist/admin/future/pages/Assets/components/AssetsTable.js +6 -4
  38. package/dist/admin/future/pages/Assets/components/AssetsTable.js.map +1 -1
  39. package/dist/admin/future/pages/Assets/components/AssetsTable.mjs +6 -4
  40. package/dist/admin/future/pages/Assets/components/AssetsTable.mjs.map +1 -1
  41. package/dist/admin/future/pages/Assets/components/BulkActionsBar.js +10 -1
  42. package/dist/admin/future/pages/Assets/components/BulkActionsBar.js.map +1 -1
  43. package/dist/admin/future/pages/Assets/components/BulkActionsBar.mjs +10 -1
  44. package/dist/admin/future/pages/Assets/components/BulkActionsBar.mjs.map +1 -1
  45. package/dist/admin/future/pages/Assets/components/BulkMoveDialog.js +3 -2
  46. package/dist/admin/future/pages/Assets/components/BulkMoveDialog.js.map +1 -1
  47. package/dist/admin/future/pages/Assets/components/BulkMoveDialog.mjs +3 -2
  48. package/dist/admin/future/pages/Assets/components/BulkMoveDialog.mjs.map +1 -1
  49. package/dist/admin/future/pages/Assets/components/Dnd/AssetsDndProvider.js +4 -2
  50. package/dist/admin/future/pages/Assets/components/Dnd/AssetsDndProvider.js.map +1 -1
  51. package/dist/admin/future/pages/Assets/components/Dnd/AssetsDndProvider.mjs +4 -2
  52. package/dist/admin/future/pages/Assets/components/Dnd/AssetsDndProvider.mjs.map +1 -1
  53. package/dist/admin/future/pages/Assets/components/FilterMenu.js +18 -2
  54. package/dist/admin/future/pages/Assets/components/FilterMenu.js.map +1 -1
  55. package/dist/admin/future/pages/Assets/components/FilterMenu.mjs +18 -2
  56. package/dist/admin/future/pages/Assets/components/FilterMenu.mjs.map +1 -1
  57. package/dist/admin/future/pages/Assets/components/FolderActionsMenu.js +9 -7
  58. package/dist/admin/future/pages/Assets/components/FolderActionsMenu.js.map +1 -1
  59. package/dist/admin/future/pages/Assets/components/FolderActionsMenu.mjs +9 -7
  60. package/dist/admin/future/pages/Assets/components/FolderActionsMenu.mjs.map +1 -1
  61. package/dist/admin/future/pages/Assets/components/FolderFormDialog.js +12 -0
  62. package/dist/admin/future/pages/Assets/components/FolderFormDialog.js.map +1 -1
  63. package/dist/admin/future/pages/Assets/components/FolderFormDialog.mjs +12 -0
  64. package/dist/admin/future/pages/Assets/components/FolderFormDialog.mjs.map +1 -1
  65. package/dist/admin/future/pages/Assets/components/FolderTree/FolderTree.js +21 -38
  66. package/dist/admin/future/pages/Assets/components/FolderTree/FolderTree.js.map +1 -1
  67. package/dist/admin/future/pages/Assets/components/FolderTree/FolderTree.mjs +23 -40
  68. package/dist/admin/future/pages/Assets/components/FolderTree/FolderTree.mjs.map +1 -1
  69. package/dist/admin/future/pages/Assets/components/SortMenu.js +14 -0
  70. package/dist/admin/future/pages/Assets/components/SortMenu.js.map +1 -1
  71. package/dist/admin/future/pages/Assets/components/SortMenu.mjs +14 -0
  72. package/dist/admin/future/pages/Assets/components/SortMenu.mjs.map +1 -1
  73. package/dist/admin/future/pages/Assets/hooks/useAssetSelection.js +5 -0
  74. package/dist/admin/future/pages/Assets/hooks/useAssetSelection.js.map +1 -1
  75. package/dist/admin/future/pages/Assets/hooks/useAssetSelection.mjs +6 -1
  76. package/dist/admin/future/pages/Assets/hooks/useAssetSelection.mjs.map +1 -1
  77. package/dist/admin/future/pages/Assets/hooks/useIsAssetDetailsOpen.js +30 -0
  78. package/dist/admin/future/pages/Assets/hooks/useIsAssetDetailsOpen.js.map +1 -0
  79. package/dist/admin/future/pages/Assets/hooks/useIsAssetDetailsOpen.mjs +26 -0
  80. package/dist/admin/future/pages/Assets/hooks/useIsAssetDetailsOpen.mjs.map +1 -0
  81. package/dist/admin/future/pages/Assets/utils/selection.js +17 -0
  82. package/dist/admin/future/pages/Assets/utils/selection.js.map +1 -1
  83. package/dist/admin/future/pages/Assets/utils/selection.mjs +17 -1
  84. package/dist/admin/future/pages/Assets/utils/selection.mjs.map +1 -1
  85. package/dist/admin/future/services/api.js +123 -19
  86. package/dist/admin/future/services/api.js.map +1 -1
  87. package/dist/admin/future/services/api.mjs +125 -21
  88. package/dist/admin/future/services/api.mjs.map +1 -1
  89. package/dist/admin/future/services/assets.js +11 -23
  90. package/dist/admin/future/services/assets.js.map +1 -1
  91. package/dist/admin/future/services/assets.mjs +11 -23
  92. package/dist/admin/future/services/assets.mjs.map +1 -1
  93. package/dist/admin/future/services/uploadFileViaXHR.js +9 -3
  94. package/dist/admin/future/services/uploadFileViaXHR.js.map +1 -1
  95. package/dist/admin/future/services/uploadFileViaXHR.mjs +9 -3
  96. package/dist/admin/future/services/uploadFileViaXHR.mjs.map +1 -1
  97. package/dist/admin/future/store/uploadProgress.js +44 -5
  98. package/dist/admin/future/store/uploadProgress.js.map +1 -1
  99. package/dist/admin/future/store/uploadProgress.mjs +43 -6
  100. package/dist/admin/future/store/uploadProgress.mjs.map +1 -1
  101. package/dist/admin/future/utils/getApiErrorMessage.js +20 -0
  102. package/dist/admin/future/utils/getApiErrorMessage.js.map +1 -0
  103. package/dist/admin/future/utils/getApiErrorMessage.mjs +18 -0
  104. package/dist/admin/future/utils/getApiErrorMessage.mjs.map +1 -0
  105. package/dist/admin/hooks/useAIMetadataJob.js +1 -1
  106. package/dist/admin/hooks/useAIMetadataJob.js.map +1 -1
  107. package/dist/admin/hooks/useAIMetadataJob.mjs +1 -1
  108. package/dist/admin/hooks/useAIMetadataJob.mjs.map +1 -1
  109. package/dist/admin/pages/SettingsPage/SettingsPage.js +2 -2
  110. package/dist/admin/pages/SettingsPage/SettingsPage.js.map +1 -1
  111. package/dist/admin/pages/SettingsPage/SettingsPage.mjs +2 -2
  112. package/dist/admin/pages/SettingsPage/SettingsPage.mjs.map +1 -1
  113. package/dist/admin/src/future/components/TruncatedText.d.ts +32 -0
  114. package/dist/admin/src/future/hooks/useApiErrorMessage.d.ts +17 -0
  115. package/dist/admin/src/future/hooks/useTracking.d.ts +29 -0
  116. package/dist/admin/src/future/pages/Assets/components/AssetActionsMenu.d.ts +5 -3
  117. package/dist/admin/src/future/pages/Assets/components/FolderActionsMenu.d.ts +5 -4
  118. package/dist/admin/src/future/pages/Assets/hooks/useAssetSelection.d.ts +2 -0
  119. package/dist/admin/src/future/pages/Assets/hooks/useIsAssetDetailsOpen.d.ts +18 -0
  120. package/dist/admin/src/future/pages/Assets/utils/selection.d.ts +10 -0
  121. package/dist/admin/src/future/services/api.d.ts +6 -7
  122. package/dist/admin/src/future/services/uploadFileViaXHR.d.ts +6 -1
  123. package/dist/admin/src/future/store/uploadProgress.d.ts +16 -1
  124. package/dist/admin/src/future/utils/getApiErrorMessage.d.ts +1 -0
  125. package/dist/admin/translations/ca.json.js +1 -1
  126. package/dist/admin/translations/ca.json.mjs +1 -1
  127. package/dist/admin/translations/de.json.js +1 -1
  128. package/dist/admin/translations/de.json.mjs +1 -1
  129. package/dist/admin/translations/en.json.js +2 -1
  130. package/dist/admin/translations/en.json.js.map +1 -1
  131. package/dist/admin/translations/en.json.mjs +2 -1
  132. package/dist/admin/translations/en.json.mjs.map +1 -1
  133. package/dist/admin/translations/es.json.js +1 -1
  134. package/dist/admin/translations/es.json.mjs +1 -1
  135. package/dist/admin/translations/fr.json.js +1 -1
  136. package/dist/admin/translations/fr.json.mjs +1 -1
  137. package/dist/admin/translations/ja.json.js +1 -1
  138. package/dist/admin/translations/ja.json.mjs +1 -1
  139. package/dist/admin/translations/ko.json.js +1 -1
  140. package/dist/admin/translations/ko.json.mjs +1 -1
  141. package/dist/admin/translations/nl.json.js +1 -1
  142. package/dist/admin/translations/nl.json.mjs +1 -1
  143. package/dist/admin/translations/pl.json.js +1 -1
  144. package/dist/admin/translations/pl.json.mjs +1 -1
  145. package/dist/admin/translations/pt-BR.json.js +1 -1
  146. package/dist/admin/translations/pt-BR.json.mjs +1 -1
  147. package/dist/admin/translations/ru.json.js +1 -1
  148. package/dist/admin/translations/ru.json.mjs +1 -1
  149. package/dist/admin/translations/sk.json.js +1 -1
  150. package/dist/admin/translations/sk.json.mjs +1 -1
  151. package/dist/admin/translations/tr.json.js +1 -1
  152. package/dist/admin/translations/tr.json.mjs +1 -1
  153. package/dist/admin/translations/uk.json.js +1 -1
  154. package/dist/admin/translations/uk.json.mjs +1 -1
  155. package/dist/admin/translations/zh-Hans.json.js +1 -1
  156. package/dist/admin/translations/zh-Hans.json.mjs +1 -1
  157. package/dist/admin/translations/zh.json.js +1 -1
  158. package/dist/admin/translations/zh.json.mjs +1 -1
  159. package/dist/server/controllers/admin-file.js +27 -9
  160. package/dist/server/controllers/admin-file.js.map +1 -1
  161. package/dist/server/controllers/admin-file.mjs +27 -9
  162. package/dist/server/controllers/admin-file.mjs.map +1 -1
  163. package/dist/server/controllers/admin-upload.js +24 -8
  164. package/dist/server/controllers/admin-upload.js.map +1 -1
  165. package/dist/server/controllers/admin-upload.mjs +24 -8
  166. package/dist/server/controllers/admin-upload.mjs.map +1 -1
  167. package/dist/server/routes/admin.js +41 -21
  168. package/dist/server/routes/admin.js.map +1 -1
  169. package/dist/server/routes/admin.mjs +41 -21
  170. package/dist/server/routes/admin.mjs.map +1 -1
  171. package/dist/server/services/ai-metadata.js +25 -5
  172. package/dist/server/services/ai-metadata.js.map +1 -1
  173. package/dist/server/services/ai-metadata.mjs +1 -1
  174. package/dist/server/services/ai-metadata.mjs.map +1 -1
  175. package/dist/server/services/upload.js +4 -0
  176. package/dist/server/services/upload.js.map +1 -1
  177. package/dist/server/services/upload.mjs +4 -0
  178. package/dist/server/services/upload.mjs.map +1 -1
  179. package/dist/server/src/controllers/admin-file.d.ts +29 -8
  180. package/dist/server/src/controllers/admin-file.d.ts.map +1 -1
  181. package/dist/server/src/controllers/admin-upload.d.ts +20 -4
  182. package/dist/server/src/controllers/admin-upload.d.ts.map +1 -1
  183. package/dist/server/src/controllers/index.d.ts +4 -4
  184. package/dist/server/src/index.d.ts +4 -4
  185. package/dist/server/src/routes/admin.d.ts.map +1 -1
  186. package/dist/server/src/services/ai-metadata.d.ts +2 -2
  187. package/dist/server/src/services/ai-metadata.d.ts.map +1 -1
  188. package/dist/server/src/services/upload.d.ts.map +1 -1
  189. package/dist/shared/contracts/ai-metadata-jobs.d.ts +10 -32
  190. package/dist/shared/contracts/ai-metadata-jobs.d.ts.map +1 -1
  191. package/dist/shared/contracts/files.d.ts +10 -10
  192. package/dist/shared/contracts/files.d.ts.map +1 -1
  193. package/package.json +7 -7
  194. package/dist/admin/future/utils/getBulkMoveErrorMessage.js +0 -23
  195. package/dist/admin/future/utils/getBulkMoveErrorMessage.js.map +0 -1
  196. package/dist/admin/future/utils/getBulkMoveErrorMessage.mjs +0 -21
  197. package/dist/admin/future/utils/getBulkMoveErrorMessage.mjs.map +0 -1
  198. package/dist/admin/src/future/utils/getBulkMoveErrorMessage.d.ts +0 -1
@@ -8,7 +8,9 @@ import { styled } from 'styled-components';
8
8
  import { ASSET_TYPES } from '../../../../../enums.mjs';
9
9
  import { Drawer } from '../../../../components/Drawer.mjs';
10
10
  import { useAIMetadataEnabled } from '../../../../hooks/useAIMetadataEnabled.mjs';
11
+ import { useApiErrorMessage } from '../../../../hooks/useApiErrorMessage.mjs';
11
12
  import { useMediaLibraryPermissions } from '../../../../hooks/useMediaLibraryPermissions.mjs';
13
+ import { useTracking, MEDIA_LIBRARY_LOCATION } from '../../../../hooks/useTracking.mjs';
12
14
  import { useUploadFileSilentlyMutation } from '../../../../services/api.mjs';
13
15
  import { useGetAssetQuery, useUpdateAssetMutation, useReplaceAssetMutation, useDeleteAssetMutation } from '../../../../services/assets.mjs';
14
16
  import { useGetAllFoldersQuery } from '../../../../services/folders.mjs';
@@ -17,12 +19,11 @@ import { formatBytes, getFileExtension, prefixFileUrlWithBackendUrl } from '../.
17
19
  import { getAssetIcon } from '../../../../utils/getAssetIcon.mjs';
18
20
  import { getTranslationKey } from '../../../../utils/translations.mjs';
19
21
  import { useFolderInfo } from '../../hooks/useFolderInfo.mjs';
22
+ import { parseAssetDetailsId, ASSET_DETAILS_URL_PARAM } from '../../hooks/useIsAssetDetailsOpen.mjs';
20
23
  import { BusyOverlay } from '../BusyOverlay.mjs';
21
24
  import { AssetCropEditor } from './AssetCropEditor.mjs';
22
25
  import { AssetPreview } from './AssetPreview.mjs';
23
26
 
24
- // Name of the parameter to look for in the URL to open the drawer
25
- const URL_PARAM = 'assetId';
26
27
  const DrawerNotifyContext = /*#__PURE__*/ React.createContext(null);
27
28
  const useDrawerNotify = ()=>{
28
29
  const ctx = React.useContext(DrawerNotifyContext);
@@ -40,12 +41,11 @@ const useAssetOperation = ()=>{
40
41
  return ctx;
41
42
  };
42
43
  /* -------------------------------------------------------------------------------------------------
43
- * useAssetDetailsParam - sync drawer visibility with URL ?{URL_PARAM}={id}
44
+ * useAssetDetailsParam - sync drawer visibility with URL ?{ASSET_DETAILS_URL_PARAM}={id}
44
45
  * -----------------------------------------------------------------------------------------------*/ const useAssetDetailsParam = ()=>{
45
46
  const [{ query }, setQuery] = useQueryParams();
46
- const detailsId = query?.[URL_PARAM];
47
- const assetId = detailsId ? parseInt(detailsId, 10) : null;
48
- const hasValidId = assetId !== null && !Number.isNaN(assetId);
47
+ const assetId = parseAssetDetailsId(query?.[ASSET_DETAILS_URL_PARAM]);
48
+ const hasValidId = assetId !== null;
49
49
  // Closing is driven by removing the URL param (a navigation), so navigation
50
50
  // guards like <Blocker> can intercept it. `isMounted` keeps the drawer in the
51
51
  // tree through the slide-out: it stays true once opened and only flips false
@@ -72,14 +72,14 @@ const useAssetOperation = ()=>{
72
72
  ]);
73
73
  const openDetails = React.useCallback((id)=>{
74
74
  setQuery({
75
- [URL_PARAM]: String(id)
75
+ [ASSET_DETAILS_URL_PARAM]: String(id)
76
76
  }, 'push', true);
77
77
  }, [
78
78
  setQuery
79
79
  ]);
80
80
  const closeDetails = React.useCallback(()=>{
81
81
  setQuery({
82
- [URL_PARAM]: undefined
82
+ [ASSET_DETAILS_URL_PARAM]: undefined
83
83
  }, 'remove', true);
84
84
  }, [
85
85
  setQuery
@@ -285,7 +285,6 @@ const LocationField = ({ label, rootLabel, folders, disabled })=>{
285
285
  children: [
286
286
  /*#__PURE__*/ jsx(Dialog.Trigger, {
287
287
  children: /*#__PURE__*/ jsx(IconButton, {
288
- withTooltip: false,
289
288
  label: triggerLabel,
290
289
  variant: "danger-light",
291
290
  children: /*#__PURE__*/ jsx(Trash, {})
@@ -363,7 +362,6 @@ const CopyLinkButton = ({ asset })=>{
363
362
  });
364
363
  };
365
364
  return /*#__PURE__*/ jsx(IconButton, {
366
- withTooltip: false,
367
365
  label: formatMessage({
368
366
  id: getTranslationKey('asset-details.copy-link.trigger'),
369
367
  defaultMessage: 'Copy link'
@@ -396,7 +394,6 @@ const DownloadAssetButton = ({ asset })=>{
396
394
  }
397
395
  };
398
396
  return /*#__PURE__*/ jsx(IconButton, {
399
- withTooltip: false,
400
397
  label: formatMessage({
401
398
  id: getTranslationKey('asset-details.download.trigger'),
402
399
  defaultMessage: 'Download'
@@ -440,6 +437,7 @@ const ReplaceAssetButton = ({ mime })=>{
440
437
  children: /*#__PURE__*/ jsx("input", {
441
438
  ref: fileInputRef,
442
439
  type: "file",
440
+ accept: mime ?? '',
443
441
  multiple: false,
444
442
  onChange: handleFileChange,
445
443
  "aria-hidden": true,
@@ -447,7 +445,6 @@ const ReplaceAssetButton = ({ mime })=>{
447
445
  })
448
446
  }),
449
447
  /*#__PURE__*/ jsx(IconButton, {
450
- withTooltip: false,
451
448
  label: formatMessage({
452
449
  id: getTranslationKey('asset-details.replace.trigger'),
453
450
  defaultMessage: 'Replace this file'
@@ -522,36 +519,32 @@ const ReplaceAssetButton = ({ mime })=>{
522
519
  ]
523
520
  });
524
521
  };
525
- const AssetImageActions = ({ onCrop, mime })=>{
522
+ const AssetImageActions = ({ onCrop })=>{
526
523
  const { formatMessage } = useIntl();
527
524
  const isSubmitting = useForm('AssetImageActions', (state)=>state.isSubmitting);
528
- return /*#__PURE__*/ jsxs(Flex, {
525
+ return /*#__PURE__*/ jsx(Flex, {
529
526
  direction: "column",
530
527
  gap: 2,
531
- children: [
532
- /*#__PURE__*/ jsx(IconButton, {
533
- withTooltip: false,
534
- label: formatMessage({
535
- id: getTranslationKey('asset-details.crop.trigger'),
536
- defaultMessage: 'Crop'
537
- }),
538
- variant: "tertiary",
539
- onClick: onCrop,
540
- disabled: isSubmitting || !onCrop,
541
- children: /*#__PURE__*/ jsx(Crop, {})
528
+ children: /*#__PURE__*/ jsx(IconButton, {
529
+ label: formatMessage({
530
+ id: getTranslationKey('asset-details.crop.trigger'),
531
+ defaultMessage: 'Crop'
542
532
  }),
543
- /*#__PURE__*/ jsx(ReplaceAssetButton, {
544
- mime: mime
545
- })
546
- ]
533
+ variant: "tertiary",
534
+ onClick: onCrop,
535
+ disabled: isSubmitting || !onCrop,
536
+ children: /*#__PURE__*/ jsx(Crop, {})
537
+ })
547
538
  });
548
539
  };
549
540
  const AssetDetails = ({ asset, closeDetails })=>{
550
541
  const { formatMessage, formatDate } = useIntl();
542
+ const getErrorMessage = useApiErrorMessage();
551
543
  const { canCreate, canUpdate, canDownload, canCopyLink } = useMediaLibraryPermissions();
552
544
  const { data: folders = [] } = useGetAllFoldersQuery();
553
545
  const { toggleNotification } = useNotification();
554
546
  const [updateAsset] = useUpdateAssetMutation();
547
+ const { trackUsage } = useTracking();
555
548
  const [replaceMutation, { isLoading: isReplacing }] = useReplaceAssetMutation();
556
549
  const [deleteMutation, { isLoading: isDeleting }] = useDeleteAssetMutation();
557
550
  const [uploadCroppedCopy, { isLoading: isCropCopying }] = useUploadFileSilentlyMutation();
@@ -589,13 +582,19 @@ const AssetDetails = ({ asset, closeDetails })=>{
589
582
  if ('error' in res) {
590
583
  notify({
591
584
  type: 'danger',
592
- message: formatMessage({
585
+ message: getErrorMessage(res.error, formatMessage({
593
586
  id: getTranslationKey('asset-details.update.error'),
594
587
  defaultMessage: 'Failed to update the file.'
595
- })
588
+ }))
596
589
  });
597
590
  return;
598
591
  }
592
+ trackUsage('didEditMediaLibraryElements', {
593
+ location: MEDIA_LIBRARY_LOCATION,
594
+ // Legacy sends the mime top-level type (image/video/audio/application…).
595
+ type: asset.mime?.split('/')[0],
596
+ changeLocation: values.folder !== initialValues.folder
597
+ });
599
598
  notify({
600
599
  type: 'success',
601
600
  message: formatMessage({
@@ -612,17 +611,18 @@ const AssetDetails = ({ asset, closeDetails })=>{
612
611
  file
613
612
  });
614
613
  if ('error' in res) {
615
- const error = res.error;
616
- const message = error?.data?.error?.message ?? error?.data?.message ?? formatMessage({
617
- id: getTranslationKey('asset-details.replace.error'),
618
- defaultMessage: 'Failed to replace the file.'
619
- });
620
614
  notify({
621
615
  type: 'danger',
622
- message
616
+ message: getErrorMessage(res.error, formatMessage({
617
+ id: getTranslationKey('asset-details.replace.error'),
618
+ defaultMessage: 'Failed to replace the file.'
619
+ }))
623
620
  });
624
621
  return;
625
622
  }
623
+ trackUsage('didReplaceMedia', {
624
+ location: MEDIA_LIBRARY_LOCATION
625
+ });
626
626
  notify({
627
627
  type: 'success',
628
628
  message: formatMessage({
@@ -633,22 +633,22 @@ const AssetDetails = ({ asset, closeDetails })=>{
633
633
  }, [
634
634
  asset.id,
635
635
  formatMessage,
636
+ getErrorMessage,
636
637
  notify,
637
- replaceMutation
638
+ replaceMutation,
639
+ trackUsage
638
640
  ]);
639
641
  // Owns the delete: on error notify in-drawer (drawer stays), on success fire
640
642
  // a persistent global notification then close the drawer.
641
643
  const handleDelete = React.useCallback(async ()=>{
642
644
  const res = await deleteMutation(asset.id);
643
645
  if ('error' in res) {
644
- const error = res.error;
645
- const message = error?.data?.error?.message ?? error?.data?.message ?? formatMessage({
646
- id: getTranslationKey('asset-details.delete.error'),
647
- defaultMessage: 'Failed to delete the asset.'
648
- });
649
646
  notify({
650
647
  type: 'danger',
651
- message
648
+ message: getErrorMessage(res.error, formatMessage({
649
+ id: getTranslationKey('asset-details.delete.error'),
650
+ defaultMessage: 'Failed to delete the asset.'
651
+ }))
652
652
  });
653
653
  return;
654
654
  }
@@ -668,16 +668,17 @@ const AssetDetails = ({ asset, closeDetails })=>{
668
668
  deleteMutation,
669
669
  folderName,
670
670
  formatMessage,
671
+ getErrorMessage,
671
672
  notify,
672
673
  toggleNotification
673
674
  ]);
674
- const notifyCropError = ()=>{
675
+ const notifyCropError = (error)=>{
675
676
  notify({
676
677
  type: 'danger',
677
- message: formatMessage({
678
+ message: getErrorMessage(error, formatMessage({
678
679
  id: getTranslationKey('asset-details.crop.error'),
679
680
  defaultMessage: 'Failed to crop the file.'
680
- })
681
+ }))
681
682
  });
682
683
  };
683
684
  // Apply: replace the original binary with the cropped file + focal point.
@@ -693,9 +694,13 @@ const AssetDetails = ({ asset, closeDetails })=>{
693
694
  }
694
695
  });
695
696
  if ('error' in res) {
696
- notifyCropError();
697
+ notifyCropError(res.error);
697
698
  return;
698
699
  }
700
+ trackUsage('didCropFile', {
701
+ location: MEDIA_LIBRARY_LOCATION,
702
+ duplicatedFile: false
703
+ });
699
704
  notify({
700
705
  type: 'success',
701
706
  message: formatMessage({
@@ -720,9 +725,13 @@ const AssetDetails = ({ asset, closeDetails })=>{
720
725
  }
721
726
  });
722
727
  if ('error' in res) {
723
- notifyCropError();
728
+ notifyCropError(res.error);
724
729
  return;
725
730
  }
731
+ trackUsage('didCropFile', {
732
+ location: MEDIA_LIBRARY_LOCATION,
733
+ duplicatedFile: true
734
+ });
726
735
  notify({
727
736
  type: 'success',
728
737
  message: formatMessage({
@@ -791,8 +800,7 @@ const AssetDetails = ({ asset, closeDetails })=>{
791
800
  /*#__PURE__*/ jsx(AssetPreview, {
792
801
  asset: asset,
793
802
  actions: isImage && canUpdate ? /*#__PURE__*/ jsx(AssetImageActions, {
794
- onCrop: ()=>setIsCropOpen(true),
795
- mime: asset.mime
803
+ onCrop: ()=>setIsCropOpen(true)
796
804
  }) : null
797
805
  }),
798
806
  /*#__PURE__*/ jsxs(Flex, {
@@ -945,6 +953,9 @@ const AssetDetails = ({ asset, closeDetails })=>{
945
953
  }),
946
954
  canDownload && /*#__PURE__*/ jsx(DownloadAssetButton, {
947
955
  asset: asset
956
+ }),
957
+ canUpdate && /*#__PURE__*/ jsx(ReplaceAssetButton, {
958
+ mime: asset.mime
948
959
  })
949
960
  ]
950
961
  }),