@strapi/upload 5.51.0 → 5.51.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/admin/components/AssetCard/VideoPreview.js +1 -1
- package/dist/admin/components/AssetCard/VideoPreview.js.map +1 -1
- package/dist/admin/components/AssetCard/VideoPreview.mjs +1 -1
- package/dist/admin/components/AssetCard/VideoPreview.mjs.map +1 -1
- package/dist/admin/components/TableList/TableList.js +1 -1
- package/dist/admin/components/TableList/TableList.js.map +1 -1
- package/dist/admin/components/TableList/TableList.mjs +1 -1
- package/dist/admin/components/TableList/TableList.mjs.map +1 -1
- package/dist/admin/components/UploadAssetDialog/AddAssetStep/FromUrlForm.js +21 -4
- package/dist/admin/components/UploadAssetDialog/AddAssetStep/FromUrlForm.js.map +1 -1
- package/dist/admin/components/UploadAssetDialog/AddAssetStep/FromUrlForm.mjs +21 -4
- package/dist/admin/components/UploadAssetDialog/AddAssetStep/FromUrlForm.mjs.map +1 -1
- package/dist/admin/future/components/Drawer.js +3 -1
- package/dist/admin/future/components/Drawer.js.map +1 -1
- package/dist/admin/future/components/Drawer.mjs +3 -1
- package/dist/admin/future/components/Drawer.mjs.map +1 -1
- package/dist/admin/future/components/UploadProgressDialog.js +200 -27
- package/dist/admin/future/components/UploadProgressDialog.js.map +1 -1
- package/dist/admin/future/components/UploadProgressDialog.mjs +203 -30
- package/dist/admin/future/components/UploadProgressDialog.mjs.map +1 -1
- package/dist/admin/future/hooks/useMediaLibraryPermissions.js +35 -0
- package/dist/admin/future/hooks/useMediaLibraryPermissions.js.map +1 -0
- package/dist/admin/future/hooks/useMediaLibraryPermissions.mjs +33 -0
- package/dist/admin/future/hooks/useMediaLibraryPermissions.mjs.map +1 -0
- package/dist/admin/future/pages/Assets/AssetsPage.js +344 -150
- package/dist/admin/future/pages/Assets/AssetsPage.js.map +1 -1
- package/dist/admin/future/pages/Assets/AssetsPage.mjs +343 -149
- package/dist/admin/future/pages/Assets/AssetsPage.mjs.map +1 -1
- package/dist/admin/future/pages/Assets/components/AssetDetails/AssetCropEditor.js +75 -32
- package/dist/admin/future/pages/Assets/components/AssetDetails/AssetCropEditor.js.map +1 -1
- package/dist/admin/future/pages/Assets/components/AssetDetails/AssetCropEditor.mjs +75 -32
- package/dist/admin/future/pages/Assets/components/AssetDetails/AssetCropEditor.mjs.map +1 -1
- package/dist/admin/future/pages/Assets/components/AssetDetails/AssetDetailsDrawer.js +46 -19
- package/dist/admin/future/pages/Assets/components/AssetDetails/AssetDetailsDrawer.js.map +1 -1
- package/dist/admin/future/pages/Assets/components/AssetDetails/AssetDetailsDrawer.mjs +47 -20
- package/dist/admin/future/pages/Assets/components/AssetDetails/AssetDetailsDrawer.mjs.map +1 -1
- package/dist/admin/future/pages/Assets/components/AssetsGrid.js +161 -19
- package/dist/admin/future/pages/Assets/components/AssetsGrid.js.map +1 -1
- package/dist/admin/future/pages/Assets/components/AssetsGrid.mjs +162 -20
- package/dist/admin/future/pages/Assets/components/AssetsGrid.mjs.map +1 -1
- package/dist/admin/future/pages/Assets/components/AssetsSearchInput.js +100 -0
- package/dist/admin/future/pages/Assets/components/AssetsSearchInput.js.map +1 -0
- package/dist/admin/future/pages/Assets/components/AssetsSearchInput.mjs +98 -0
- package/dist/admin/future/pages/Assets/components/AssetsSearchInput.mjs.map +1 -0
- package/dist/admin/future/pages/Assets/components/AssetsTable.js +218 -37
- package/dist/admin/future/pages/Assets/components/AssetsTable.js.map +1 -1
- package/dist/admin/future/pages/Assets/components/AssetsTable.mjs +219 -38
- package/dist/admin/future/pages/Assets/components/AssetsTable.mjs.map +1 -1
- package/dist/admin/future/pages/Assets/components/BulkActionsBar.js +370 -0
- package/dist/admin/future/pages/Assets/components/BulkActionsBar.js.map +1 -0
- package/dist/admin/future/pages/Assets/components/BulkActionsBar.mjs +368 -0
- package/dist/admin/future/pages/Assets/components/BulkActionsBar.mjs.map +1 -0
- package/dist/admin/future/pages/Assets/components/BulkMoveDialog.js +209 -0
- package/dist/admin/future/pages/Assets/components/BulkMoveDialog.js.map +1 -0
- package/dist/admin/future/pages/Assets/components/BulkMoveDialog.mjs +207 -0
- package/dist/admin/future/pages/Assets/components/BulkMoveDialog.mjs.map +1 -0
- package/dist/admin/future/pages/Assets/components/DateRangeCalendar.js +193 -0
- package/dist/admin/future/pages/Assets/components/DateRangeCalendar.js.map +1 -0
- package/dist/admin/future/pages/Assets/components/DateRangeCalendar.mjs +191 -0
- package/dist/admin/future/pages/Assets/components/DateRangeCalendar.mjs.map +1 -0
- package/dist/admin/future/pages/Assets/components/Dnd/AssetsDndProvider.js +129 -37
- package/dist/admin/future/pages/Assets/components/Dnd/AssetsDndProvider.js.map +1 -1
- package/dist/admin/future/pages/Assets/components/Dnd/AssetsDndProvider.mjs +131 -39
- package/dist/admin/future/pages/Assets/components/Dnd/AssetsDndProvider.mjs.map +1 -1
- package/dist/admin/future/pages/Assets/components/Dnd/DragOverlayChip.js +120 -13
- package/dist/admin/future/pages/Assets/components/Dnd/DragOverlayChip.js.map +1 -1
- package/dist/admin/future/pages/Assets/components/Dnd/DragOverlayChip.mjs +120 -13
- package/dist/admin/future/pages/Assets/components/Dnd/DragOverlayChip.mjs.map +1 -1
- package/dist/admin/future/pages/Assets/components/Dnd/buildDragSet.js +71 -0
- package/dist/admin/future/pages/Assets/components/Dnd/buildDragSet.js.map +1 -0
- package/dist/admin/future/pages/Assets/components/Dnd/buildDragSet.mjs +69 -0
- package/dist/admin/future/pages/Assets/components/Dnd/buildDragSet.mjs.map +1 -0
- package/dist/admin/future/pages/Assets/components/Dnd/computeValidDropTargets.js +34 -0
- package/dist/admin/future/pages/Assets/components/Dnd/computeValidDropTargets.js.map +1 -0
- package/dist/admin/future/pages/Assets/components/Dnd/computeValidDropTargets.mjs +32 -0
- package/dist/admin/future/pages/Assets/components/Dnd/computeValidDropTargets.mjs.map +1 -0
- package/dist/admin/future/pages/Assets/components/Dnd/dndIds.js +15 -0
- package/dist/admin/future/pages/Assets/components/Dnd/dndIds.js.map +1 -1
- package/dist/admin/future/pages/Assets/components/Dnd/dndIds.mjs +13 -1
- package/dist/admin/future/pages/Assets/components/Dnd/dndIds.mjs.map +1 -1
- package/dist/admin/future/pages/Assets/components/Dnd/useAssetDnd.js +19 -25
- package/dist/admin/future/pages/Assets/components/Dnd/useAssetDnd.js.map +1 -1
- package/dist/admin/future/pages/Assets/components/Dnd/useAssetDnd.mjs +19 -25
- package/dist/admin/future/pages/Assets/components/Dnd/useAssetDnd.mjs.map +1 -1
- package/dist/admin/future/pages/Assets/components/Dnd/useFolderTreeDroppable.js +35 -0
- package/dist/admin/future/pages/Assets/components/Dnd/useFolderTreeDroppable.js.map +1 -0
- package/dist/admin/future/pages/Assets/components/Dnd/useFolderTreeDroppable.mjs +33 -0
- package/dist/admin/future/pages/Assets/components/Dnd/useFolderTreeDroppable.mjs.map +1 -0
- package/dist/admin/future/pages/Assets/components/DropZone/UploadDropZoneContext.js +13 -3
- package/dist/admin/future/pages/Assets/components/DropZone/UploadDropZoneContext.js.map +1 -1
- package/dist/admin/future/pages/Assets/components/DropZone/UploadDropZoneContext.mjs +13 -3
- package/dist/admin/future/pages/Assets/components/DropZone/UploadDropZoneContext.mjs.map +1 -1
- package/dist/admin/future/pages/Assets/components/EmptyState.js +62 -3
- package/dist/admin/future/pages/Assets/components/EmptyState.js.map +1 -1
- package/dist/admin/future/pages/Assets/components/EmptyState.mjs +62 -4
- package/dist/admin/future/pages/Assets/components/EmptyState.mjs.map +1 -1
- package/dist/admin/future/pages/Assets/components/FilterBadges.js +408 -0
- package/dist/admin/future/pages/Assets/components/FilterBadges.js.map +1 -0
- package/dist/admin/future/pages/Assets/components/FilterBadges.mjs +406 -0
- package/dist/admin/future/pages/Assets/components/FilterBadges.mjs.map +1 -0
- package/dist/admin/future/pages/Assets/components/FilterMenu.js +273 -0
- package/dist/admin/future/pages/Assets/components/FilterMenu.js.map +1 -0
- package/dist/admin/future/pages/Assets/components/FilterMenu.mjs +267 -0
- package/dist/admin/future/pages/Assets/components/FilterMenu.mjs.map +1 -0
- package/dist/admin/future/pages/Assets/components/FolderTree/FolderTree.js +195 -40
- package/dist/admin/future/pages/Assets/components/FolderTree/FolderTree.js.map +1 -1
- package/dist/admin/future/pages/Assets/components/FolderTree/FolderTree.mjs +198 -43
- package/dist/admin/future/pages/Assets/components/FolderTree/FolderTree.mjs.map +1 -1
- package/dist/admin/future/pages/Assets/components/FolderTree/filterFolderTree.js +33 -0
- package/dist/admin/future/pages/Assets/components/FolderTree/filterFolderTree.js.map +1 -0
- package/dist/admin/future/pages/Assets/components/FolderTree/filterFolderTree.mjs +31 -0
- package/dist/admin/future/pages/Assets/components/FolderTree/filterFolderTree.mjs.map +1 -0
- package/dist/admin/future/pages/Assets/components/FolderTree/useSpringLoadedExpand.js +22 -0
- package/dist/admin/future/pages/Assets/components/FolderTree/useSpringLoadedExpand.js.map +1 -0
- package/dist/admin/future/pages/Assets/components/FolderTree/useSpringLoadedExpand.mjs +19 -0
- package/dist/admin/future/pages/Assets/components/FolderTree/useSpringLoadedExpand.mjs.map +1 -0
- package/dist/admin/future/pages/Assets/components/SortMenu.js +154 -0
- package/dist/admin/future/pages/Assets/components/SortMenu.js.map +1 -0
- package/dist/admin/future/pages/Assets/components/SortMenu.mjs +152 -0
- package/dist/admin/future/pages/Assets/components/SortMenu.mjs.map +1 -0
- package/dist/admin/future/pages/Assets/hooks/useAssetSearch.js +40 -0
- package/dist/admin/future/pages/Assets/hooks/useAssetSearch.js.map +1 -0
- package/dist/admin/future/pages/Assets/hooks/useAssetSearch.mjs +38 -0
- package/dist/admin/future/pages/Assets/hooks/useAssetSearch.mjs.map +1 -0
- package/dist/admin/future/pages/Assets/hooks/useAssetSelection.js +75 -0
- package/dist/admin/future/pages/Assets/hooks/useAssetSelection.js.map +1 -0
- package/dist/admin/future/pages/Assets/hooks/useAssetSelection.mjs +71 -0
- package/dist/admin/future/pages/Assets/hooks/useAssetSelection.mjs.map +1 -0
- package/dist/admin/future/pages/Assets/hooks/useFolderNavigation.js +33 -12
- package/dist/admin/future/pages/Assets/hooks/useFolderNavigation.js.map +1 -1
- package/dist/admin/future/pages/Assets/hooks/useFolderNavigation.mjs +33 -12
- package/dist/admin/future/pages/Assets/hooks/useFolderNavigation.mjs.map +1 -1
- package/dist/admin/future/pages/Assets/hooks/useInfiniteAssets.js +40 -4
- package/dist/admin/future/pages/Assets/hooks/useInfiniteAssets.js.map +1 -1
- package/dist/admin/future/pages/Assets/hooks/useInfiniteAssets.mjs +40 -4
- package/dist/admin/future/pages/Assets/hooks/useInfiniteAssets.mjs.map +1 -1
- package/dist/admin/future/pages/Assets/hooks/useListFilters.js +168 -0
- package/dist/admin/future/pages/Assets/hooks/useListFilters.js.map +1 -0
- package/dist/admin/future/pages/Assets/hooks/useListFilters.mjs +162 -0
- package/dist/admin/future/pages/Assets/hooks/useListFilters.mjs.map +1 -0
- package/dist/admin/future/pages/Assets/hooks/useListSort.js +124 -0
- package/dist/admin/future/pages/Assets/hooks/useListSort.js.map +1 -0
- package/dist/admin/future/pages/Assets/hooks/useListSort.mjs +120 -0
- package/dist/admin/future/pages/Assets/hooks/useListSort.mjs.map +1 -0
- package/dist/admin/future/pages/Assets/utils/buildAssetFilters.js +201 -0
- package/dist/admin/future/pages/Assets/utils/buildAssetFilters.js.map +1 -0
- package/dist/admin/future/pages/Assets/utils/buildAssetFilters.mjs +198 -0
- package/dist/admin/future/pages/Assets/utils/buildAssetFilters.mjs.map +1 -0
- package/dist/admin/future/pages/Assets/utils/listQueryKey.js +29 -0
- package/dist/admin/future/pages/Assets/utils/listQueryKey.js.map +1 -0
- package/dist/admin/future/pages/Assets/utils/listQueryKey.mjs +27 -0
- package/dist/admin/future/pages/Assets/utils/listQueryKey.mjs.map +1 -0
- package/dist/admin/future/pages/Assets/utils/mergeMixedList.js +84 -0
- package/dist/admin/future/pages/Assets/utils/mergeMixedList.js.map +1 -0
- package/dist/admin/future/pages/Assets/utils/mergeMixedList.mjs +81 -0
- package/dist/admin/future/pages/Assets/utils/mergeMixedList.mjs.map +1 -0
- package/dist/admin/future/pages/Assets/utils/selection.js +104 -0
- package/dist/admin/future/pages/Assets/utils/selection.js.map +1 -0
- package/dist/admin/future/pages/Assets/utils/selection.mjs +94 -0
- package/dist/admin/future/pages/Assets/utils/selection.mjs.map +1 -0
- package/dist/admin/future/services/api.js +163 -28
- package/dist/admin/future/services/api.js.map +1 -1
- package/dist/admin/future/services/api.mjs +163 -30
- package/dist/admin/future/services/api.mjs.map +1 -1
- package/dist/admin/future/services/assets.js +62 -18
- package/dist/admin/future/services/assets.js.map +1 -1
- package/dist/admin/future/services/assets.mjs +62 -19
- package/dist/admin/future/services/assets.mjs.map +1 -1
- package/dist/admin/future/services/folders.js +31 -19
- package/dist/admin/future/services/folders.js.map +1 -1
- package/dist/admin/future/services/folders.mjs +31 -19
- package/dist/admin/future/services/folders.mjs.map +1 -1
- package/dist/admin/future/services/settings.js +10 -3
- package/dist/admin/future/services/settings.js.map +1 -1
- package/dist/admin/future/services/settings.mjs +10 -3
- package/dist/admin/future/services/settings.mjs.map +1 -1
- package/dist/admin/future/store/uploadProgress.js +109 -2
- package/dist/admin/future/store/uploadProgress.js.map +1 -1
- package/dist/admin/future/store/uploadProgress.mjs +105 -3
- package/dist/admin/future/store/uploadProgress.mjs.map +1 -1
- package/dist/admin/future/utils/buildDragSetFromSelection.js +33 -0
- package/dist/admin/future/utils/buildDragSetFromSelection.js.map +1 -0
- package/dist/admin/future/utils/buildDragSetFromSelection.mjs +31 -0
- package/dist/admin/future/utils/buildDragSetFromSelection.mjs.map +1 -0
- package/dist/admin/future/utils/canDropItemOnFolder.js +4 -0
- package/dist/admin/future/utils/canDropItemOnFolder.js.map +1 -1
- package/dist/admin/future/utils/canDropItemOnFolder.mjs +4 -0
- package/dist/admin/future/utils/canDropItemOnFolder.mjs.map +1 -1
- package/dist/admin/future/utils/flattenFolderStructure.js +28 -0
- package/dist/admin/future/utils/flattenFolderStructure.js.map +1 -0
- package/dist/admin/future/utils/flattenFolderStructure.mjs +26 -0
- package/dist/admin/future/utils/flattenFolderStructure.mjs.map +1 -0
- package/dist/admin/future/utils/formatMoveSuccessMessage.js +19 -0
- package/dist/admin/future/utils/formatMoveSuccessMessage.js.map +1 -0
- package/dist/admin/future/utils/formatMoveSuccessMessage.mjs +17 -0
- package/dist/admin/future/utils/formatMoveSuccessMessage.mjs.map +1 -0
- package/dist/admin/future/utils/getFolderLabel.js +31 -0
- package/dist/admin/future/utils/getFolderLabel.js.map +1 -0
- package/dist/admin/future/utils/getFolderLabel.mjs +29 -0
- package/dist/admin/future/utils/getFolderLabel.mjs.map +1 -0
- package/dist/admin/future/utils/searchQueryParam.js +11 -0
- package/dist/admin/future/utils/searchQueryParam.js.map +1 -0
- package/dist/admin/future/utils/searchQueryParam.mjs +9 -0
- package/dist/admin/future/utils/searchQueryParam.mjs.map +1 -0
- package/dist/admin/hooks/useSelectionState.js +2 -4
- package/dist/admin/hooks/useSelectionState.js.map +1 -1
- package/dist/admin/hooks/useSelectionState.mjs +2 -4
- package/dist/admin/hooks/useSelectionState.mjs.map +1 -1
- package/dist/admin/shared/constants.js +43 -0
- package/dist/admin/shared/constants.js.map +1 -0
- package/dist/admin/shared/constants.mjs +38 -0
- package/dist/admin/shared/constants.mjs.map +1 -0
- package/dist/admin/src/future/hooks/useMediaLibraryPermissions.d.ts +21 -0
- package/dist/admin/src/future/pages/Assets/components/AssetDetails/AssetCropEditor.d.ts +7 -1
- package/dist/admin/src/future/pages/Assets/components/AssetsSearchInput.d.ts +5 -0
- package/dist/admin/src/future/pages/Assets/components/AssetsTable.d.ts +7 -1
- package/dist/admin/src/future/pages/Assets/components/BulkActionsBar.d.ts +14 -0
- package/dist/admin/src/future/pages/Assets/components/BulkMoveDialog.d.ts +13 -0
- package/dist/admin/src/future/pages/Assets/components/DateRangeCalendar.d.ts +8 -0
- package/dist/admin/src/future/pages/Assets/components/Dnd/AssetsDndProvider.d.ts +2 -0
- package/dist/admin/src/future/pages/Assets/components/Dnd/DragOverlayChip.d.ts +2 -2
- package/dist/admin/src/future/pages/Assets/components/Dnd/buildDragSet.d.ts +17 -0
- package/dist/admin/src/future/pages/Assets/components/Dnd/computeValidDropTargets.d.ts +7 -0
- package/dist/admin/src/future/pages/Assets/components/Dnd/dndIds.d.ts +3 -0
- package/dist/admin/src/future/pages/Assets/components/Dnd/useAssetDnd.d.ts +3 -1
- package/dist/admin/src/future/pages/Assets/components/Dnd/useFolderTreeDroppable.d.ts +19 -0
- package/dist/admin/src/future/pages/Assets/components/DropZone/UploadDropZoneContext.d.ts +8 -1
- package/dist/admin/src/future/pages/Assets/components/EmptyState.d.ts +18 -1
- package/dist/admin/src/future/pages/Assets/components/FilterBadges.d.ts +6 -0
- package/dist/admin/src/future/pages/Assets/components/FilterMenu.d.ts +22 -0
- package/dist/admin/src/future/pages/Assets/components/FolderTree/FolderTree.d.ts +13 -4
- package/dist/admin/src/future/pages/Assets/components/FolderTree/filterFolderTree.d.ts +16 -0
- package/dist/admin/src/future/pages/Assets/components/FolderTree/useSpringLoadedExpand.d.ts +6 -0
- package/dist/admin/src/future/pages/Assets/components/SortMenu.d.ts +23 -0
- package/dist/admin/src/future/pages/Assets/hooks/useAssetSearch.d.ts +12 -0
- package/dist/admin/src/future/pages/Assets/hooks/useAssetSelection.d.ts +46 -0
- package/dist/admin/src/future/pages/Assets/hooks/useInfiniteAssets.d.ts +13 -3
- package/dist/admin/src/future/pages/Assets/hooks/useListFilters.d.ts +69 -0
- package/dist/admin/src/future/pages/Assets/hooks/useListSort.d.ts +47 -0
- package/dist/admin/src/future/pages/Assets/utils/buildAssetFilters.d.ts +46 -0
- package/dist/admin/src/future/pages/Assets/utils/listQueryKey.d.ts +29 -0
- package/dist/admin/src/future/pages/Assets/utils/mergeMixedList.d.ts +40 -0
- package/dist/admin/src/future/pages/Assets/utils/selection.d.ts +50 -0
- package/dist/admin/src/future/services/api.d.ts +53 -5
- package/dist/admin/src/future/services/assets.d.ts +13 -2
- package/dist/admin/src/future/services/folders.d.ts +7 -1
- package/dist/admin/src/future/services/settings.d.ts +2 -2
- package/dist/admin/src/future/store/uploadProgress.d.ts +83 -1
- package/dist/admin/src/future/types/dnd.d.ts +5 -0
- package/dist/admin/src/future/utils/buildDragSetFromSelection.d.ts +11 -0
- package/dist/admin/src/future/utils/canDropItemOnFolder.d.ts +1 -1
- package/dist/admin/src/future/utils/flattenFolderStructure.d.ts +18 -0
- package/dist/admin/src/future/utils/formatMoveSuccessMessage.d.ts +14 -0
- package/dist/admin/src/future/utils/getFolderLabel.d.ts +11 -0
- package/dist/admin/src/future/utils/searchQueryParam.d.ts +7 -0
- package/dist/admin/src/hooks/useAiAvailability.d.ts +1 -1
- package/dist/admin/src/hooks/useEditAsset.d.ts +4 -4
- package/dist/admin/src/hooks/useEditFolder.d.ts +4 -4
- package/dist/admin/src/hooks/useSettings.d.ts +1 -0
- package/dist/admin/src/hooks/useTracking.d.ts +1 -1
- package/dist/admin/src/hooks/useUpload.d.ts +1 -1
- package/dist/admin/translations/en.json.js +85 -2
- package/dist/admin/translations/en.json.js.map +1 -1
- package/dist/admin/translations/en.json.mjs +85 -2
- package/dist/admin/translations/en.json.mjs.map +1 -1
- package/dist/admin/utils/urlYupSchema.js +33 -9
- package/dist/admin/utils/urlYupSchema.js.map +1 -1
- package/dist/admin/utils/urlYupSchema.mjs +33 -9
- package/dist/admin/utils/urlYupSchema.mjs.map +1 -1
- package/dist/server/config.js +13 -5
- package/dist/server/config.js.map +1 -1
- package/dist/server/config.mjs +13 -5
- package/dist/server/config.mjs.map +1 -1
- package/dist/server/constants.js.map +1 -1
- package/dist/server/constants.mjs.map +1 -1
- package/dist/server/controllers/admin-file.js +30 -0
- package/dist/server/controllers/admin-file.js.map +1 -1
- package/dist/server/controllers/admin-file.mjs +30 -0
- package/dist/server/controllers/admin-file.mjs.map +1 -1
- package/dist/server/controllers/admin-settings.js +20 -2
- package/dist/server/controllers/admin-settings.js.map +1 -1
- package/dist/server/controllers/admin-settings.mjs +21 -3
- package/dist/server/controllers/admin-settings.mjs.map +1 -1
- package/dist/server/controllers/content-api.js +1 -2
- package/dist/server/controllers/content-api.js.map +1 -1
- package/dist/server/controllers/content-api.mjs +2 -2
- package/dist/server/controllers/content-api.mjs.map +1 -1
- package/dist/server/controllers/validation/admin/ai-metadata.js +12 -0
- package/dist/server/controllers/validation/admin/ai-metadata.js.map +1 -0
- package/dist/server/controllers/validation/admin/ai-metadata.mjs +10 -0
- package/dist/server/controllers/validation/admin/ai-metadata.mjs.map +1 -0
- package/dist/server/controllers/validation/admin/settings.js +4 -1
- package/dist/server/controllers/validation/admin/settings.js.map +1 -1
- package/dist/server/controllers/validation/admin/settings.mjs +1 -1
- package/dist/server/controllers/validation/admin/settings.mjs.map +1 -1
- package/dist/server/routes/admin.js +18 -0
- package/dist/server/routes/admin.js.map +1 -1
- package/dist/server/routes/admin.mjs +18 -0
- package/dist/server/routes/admin.mjs.map +1 -1
- package/dist/server/services/ai-metadata.js +108 -11
- package/dist/server/services/ai-metadata.js.map +1 -1
- package/dist/server/services/ai-metadata.mjs +108 -11
- package/dist/server/services/ai-metadata.mjs.map +1 -1
- package/dist/server/services/file.js +86 -13
- package/dist/server/services/file.js.map +1 -1
- package/dist/server/services/file.mjs +87 -14
- package/dist/server/services/file.mjs.map +1 -1
- package/dist/server/services/image-manipulation.js +4 -4
- package/dist/server/services/image-manipulation.js.map +1 -1
- package/dist/server/services/image-manipulation.mjs +4 -4
- package/dist/server/services/image-manipulation.mjs.map +1 -1
- package/dist/server/shared/constants.js +43 -0
- package/dist/server/shared/constants.js.map +1 -0
- package/dist/server/shared/constants.mjs +38 -0
- package/dist/server/shared/constants.mjs.map +1 -0
- package/dist/server/src/config.d.ts +2 -0
- package/dist/server/src/config.d.ts.map +1 -1
- package/dist/server/src/constants.d.ts +2 -1
- package/dist/server/src/constants.d.ts.map +1 -1
- package/dist/server/src/controllers/admin-file.d.ts +10 -0
- package/dist/server/src/controllers/admin-file.d.ts.map +1 -1
- package/dist/server/src/controllers/admin-settings.d.ts.map +1 -1
- package/dist/server/src/controllers/index.d.ts +1 -0
- package/dist/server/src/controllers/index.d.ts.map +1 -1
- package/dist/server/src/controllers/validation/admin/ai-metadata.d.ts +2 -0
- package/dist/server/src/controllers/validation/admin/ai-metadata.d.ts.map +1 -0
- package/dist/server/src/controllers/validation/admin/settings.d.ts +1 -1
- package/dist/server/src/controllers/validation/admin/settings.d.ts.map +1 -1
- package/dist/server/src/index.d.ts +7 -1
- package/dist/server/src/index.d.ts.map +1 -1
- package/dist/server/src/routes/admin.d.ts.map +1 -1
- package/dist/server/src/services/ai-metadata.d.ts +19 -0
- package/dist/server/src/services/ai-metadata.d.ts.map +1 -1
- package/dist/server/src/services/file.d.ts +12 -2
- package/dist/server/src/services/file.d.ts.map +1 -1
- package/dist/server/src/services/index.d.ts +4 -1
- package/dist/server/src/services/index.d.ts.map +1 -1
- package/dist/server/src/types.d.ts +3 -0
- package/dist/server/src/types.d.ts.map +1 -1
- package/dist/shared/constants.d.ts +35 -0
- package/dist/shared/constants.d.ts.map +1 -0
- package/dist/shared/contracts/files.d.ts +25 -0
- package/dist/shared/contracts/files.d.ts.map +1 -1
- package/dist/shared/contracts/folders.d.ts +1 -1
- package/dist/shared/contracts/settings.d.ts +7 -0
- package/package.json +8 -8
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AssetDetailsDrawer.js","sources":["../../../../../../../admin/src/future/pages/Assets/components/AssetDetails/AssetDetailsDrawer.tsx"],"sourcesContent":["import * as React from 'react';\n\nimport {\n Blocker,\n Form,\n useClipboard,\n useField,\n useForm,\n useNotification,\n useQueryParams,\n getDisplayName,\n} from '@strapi/admin/strapi-admin';\nimport {\n Alert,\n Box,\n Button,\n Dialog,\n Field,\n Flex,\n IconButton,\n Loader,\n SingleSelect,\n SingleSelectOption,\n TextInput,\n Tooltip,\n Typography,\n VisuallyHidden,\n} from '@strapi/design-system';\nimport {\n ArrowLineRight,\n ArrowsCounterClockwise,\n Crop,\n Download,\n FileError,\n Link,\n Trash,\n WarningCircle,\n} from '@strapi/icons';\nimport { useIntl } from 'react-intl';\nimport { styled } from 'styled-components';\n\nimport { ASSET_TYPES } from '../../../../../enums';\nimport { Drawer } from '../../../../components/Drawer';\nimport { useUploadFileSilentlyMutation } from '../../../../services/api';\nimport {\n useDeleteAssetMutation,\n useGetAssetQuery,\n useReplaceAssetMutation,\n useUpdateAssetMutation,\n} from '../../../../services/assets';\nimport { useGetAllFoldersQuery } from '../../../../services/folders';\nimport { useGetSettingsQuery } from '../../../../services/settings';\nimport { downloadFile } from '../../../../utils/downloadFile';\nimport {\n formatBytes,\n getFileExtension,\n prefixFileUrlWithBackendUrl,\n} from '../../../../utils/files';\nimport { getAssetIcon } from '../../../../utils/getAssetIcon';\nimport { getTranslationKey } from '../../../../utils/translations';\nimport { useFolderInfo } from '../../hooks/useFolderInfo';\n\nimport { AssetCropEditor } from './AssetCropEditor';\nimport { AssetPreview } from './AssetPreview';\n\nimport type {\n AssetWithPopulatedCreatedBy,\n FocalPoint,\n} from '../../../../../../../shared/contracts/files';\n\n// Name of the parameter to look for in the URL to open the drawer\nconst URL_PARAM = 'assetId';\n\ninterface DrawerToast {\n type: 'success' | 'danger';\n message: string;\n}\n\n/* -------------------------------------------------------------------------------------------------\n * DrawerNotifyContext — exposes the in-drawer toast setter so deep descendants\n * (footer action buttons) can report success/error without prop drilling.\n * -----------------------------------------------------------------------------------------------*/\n\ntype DrawerNotify = (toast: DrawerToast) => void;\n\nexport const DrawerNotifyContext = React.createContext<DrawerNotify | null>(null);\n\nconst useDrawerNotify = () => {\n const ctx = React.useContext(DrawerNotifyContext);\n if (!ctx) {\n throw new Error('useDrawerNotify must be used within AssetDetails');\n }\n return ctx;\n};\n\n/* -------------------------------------------------------------------------------------------------\n * AssetOperationsContext — drawer-scoped mutations + their pending state, so\n * leaf buttons (Delete, Replace) consume them without prop drilling and the\n * full-drawer busy overlay reads a single flag.\n * -----------------------------------------------------------------------------------------------*/\n\ninterface AssetOperations {\n replaceAsset: (file: globalThis.File) => Promise<void>;\n deleteAsset: () => Promise<void>;\n isReplacing: boolean;\n isDeleting: boolean;\n}\n\nexport const AssetOperationsContext = React.createContext<AssetOperations | null>(null);\n\nconst useAssetOperation = () => {\n const ctx = React.useContext(AssetOperationsContext);\n if (!ctx) {\n throw new Error('useAssetOperation must be used within AssetDetails');\n }\n return ctx;\n};\n\n/* -------------------------------------------------------------------------------------------------\n * useAssetDetailsParam - sync drawer visibility with URL ?{URL_PARAM}={id}\n * -----------------------------------------------------------------------------------------------*/\n\nexport const useAssetDetailsParam = () => {\n const [{ query }, setQuery] = useQueryParams<{ [URL_PARAM]?: string }>();\n\n const detailsId = query?.[URL_PARAM];\n const assetId = detailsId ? parseInt(detailsId, 10) : null;\n const hasValidId = assetId !== null && !Number.isNaN(assetId);\n\n // Closing is driven by removing the URL param (a navigation), so navigation\n // guards like <Blocker> can intercept it. `isMounted` keeps the drawer in the\n // tree through the slide-out: it stays true once opened and only flips false\n // when the close animation actually ends (see onCloseAnimationEnd), so the\n // close duration lives entirely in CSS — no JS timer.\n const [isMounted, setIsMounted] = React.useState(hasValidId);\n const displayAssetId = React.useRef<number | null>(null);\n\n React.useEffect(() => {\n if (hasValidId) {\n displayAssetId.current = assetId;\n setIsMounted(true);\n }\n }, [hasValidId, assetId]);\n\n const onCloseAnimationEnd = React.useCallback(\n (event: React.AnimationEvent) => {\n // Ignore animations bubbling up from descendants, and the slide-in.\n if (event.target === event.currentTarget && !hasValidId) {\n setIsMounted(false);\n }\n },\n [hasValidId]\n );\n\n const openDetails = React.useCallback(\n (id: number) => {\n setQuery({ [URL_PARAM]: String(id) }, 'push', true);\n },\n [setQuery]\n );\n\n const closeDetails = React.useCallback(() => {\n setQuery({ [URL_PARAM]: undefined }, 'remove', true);\n }, [setQuery]);\n\n return {\n assetId: hasValidId ? assetId : displayAssetId.current,\n isVisible: hasValidId,\n shouldRenderDrawer: isMounted,\n onCloseAnimationEnd,\n openDetails,\n closeDetails,\n };\n};\n\n/* -------------------------------------------------------------------------------------------------\n * DetailItem\n * -----------------------------------------------------------------------------------------------*/\n\ninterface DetailItemProps {\n label: string;\n value: React.ReactNode;\n}\n\nconst DetailItemContainer = styled(Flex)`\n flex: 0 0 calc(50% - ${({ theme }) => theme.spaces[2]});\n`;\n\nconst DetailItem = ({ label, value }: DetailItemProps) => (\n <DetailItemContainer\n direction=\"column\"\n justifyContent=\"flex-start\"\n alignItems=\"flex-start\"\n gap={1}\n >\n <Typography\n variant=\"sigma\"\n textColor=\"neutral600\"\n fontWeight=\"semiBold\"\n textTransform=\"uppercase\"\n >\n {label}\n </Typography>\n <Typography variant=\"pi\" textColor=\"neutral700\">\n {value ?? '-'}\n </Typography>\n </DetailItemContainer>\n);\n\n/* -------------------------------------------------------------------------------------------------\n * DetailField\n * -----------------------------------------------------------------------------------------------*/\n\n/**\n * Make the asset details Form behave as a flex column inside Drawer.Body so\n * the scrollable area can grow while the footer stays pinned at the bottom.\n * The Form component from `@strapi/admin/strapi-admin` only forwards `width`\n * + `height` to its Box, so we target the rendered `<form>` element via a\n * styled-components descendant rule.\n */\nconst FormShell = styled(Box)`\n display: flex;\n flex-direction: column;\n flex: 1;\n min-height: 0;\n\n > form {\n display: flex;\n flex-direction: column;\n flex: 1;\n min-height: 0;\n position: relative;\n }\n`;\n\n/**\n * In-drawer toast container\n */\nconst DrawerToastSlot = styled(Box)`\n position: absolute;\n top: ${({ theme }) => theme.spaces[2]};\n left: 50%;\n transform: translateX(-50%);\n z-index: 10;\n width: calc(100% - ${({ theme }) => theme.spaces[2]});\n`;\n\n/**\n * Full-form overlay rendered during long-running drawer-scoped mutations\n * (e.g. replacing the binary). Sits above the toast slot (z-index 10) and\n * the in-drawer Alert so the user can't interact with the form mid-flight.\n */\nconst DrawerBusyOverlay = styled(Flex)`\n position: absolute;\n inset: 0;\n z-index: 20;\n align-items: center;\n justify-content: center;\n background: ${({ theme }) => theme.colors.neutral0};\n opacity: 0.7;\n`;\n\n/**\n * Map the drawer-scoped mutation flags to a single i18n message for the busy\n * overlay loader. Returns `null` when nothing is in flight.\n */\nconst getBusyMessage = (state: {\n isDeleting: boolean;\n isReplacing: boolean;\n isCropCopying: boolean;\n}): { id: string; defaultMessage: string } | null => {\n if (state.isDeleting) {\n return {\n id: getTranslationKey('asset-details.delete.loading'),\n defaultMessage: 'Deleting the file…',\n };\n }\n if (state.isCropCopying) {\n return {\n id: getTranslationKey('asset-details.crop.loading'),\n defaultMessage: 'Saving the cropped copy…',\n };\n }\n if (state.isReplacing) {\n return {\n id: getTranslationKey('asset-details.replace.loading'),\n defaultMessage: 'Replacing the file…',\n };\n }\n return null;\n};\n\nconst StyledWarning = styled(WarningCircle)`\n width: 1.6rem;\n height: 1.6rem;\n\n path {\n fill: ${({ theme }) => theme.colors.warning500};\n }\n`;\n\ninterface DetailFieldProps {\n name: string;\n label: string;\n required?: boolean;\n}\n\nconst DetailField = ({ name, label, required }: DetailFieldProps) => {\n const { formatMessage } = useIntl();\n const field = useField<string>(name);\n const isSubmitting = useForm('DetailField', (state) => state.isSubmitting);\n const value = field.value ?? '';\n const emptyTooltipLabel = formatMessage(\n {\n id: getTranslationKey('asset-details.field.empty'),\n defaultMessage: '{label} is currently empty.',\n },\n { label }\n );\n\n return (\n <Field.Root name={name} required={required}>\n <Field.Label>{label}</Field.Label>\n <TextInput\n value={value}\n onChange={(event: React.ChangeEvent<HTMLInputElement>) =>\n field.onChange(name, event.target.value)\n }\n endAction={\n !value ? (\n <Tooltip label={emptyTooltipLabel}>\n <StyledWarning aria-label={emptyTooltipLabel} role=\"img\" />\n </Tooltip>\n ) : undefined\n }\n type=\"text\"\n disabled={isSubmitting}\n />\n </Field.Root>\n );\n};\n\n/* -------------------------------------------------------------------------------------------------\n * LocationField\n * -----------------------------------------------------------------------------------------------*/\n\ninterface LocationFieldProps {\n label: string;\n rootLabel: string;\n folders: Array<{ id: number; name: string }>;\n}\n\nconst LocationField = ({ label, rootLabel, folders }: LocationFieldProps) => {\n const field = useField<number | null>('folder');\n const isSubmitting = useForm('LocationField', (state) => state.isSubmitting);\n\n return (\n <Field.Root name=\"folder\" required>\n <Field.Label>{label}</Field.Label>\n {/* `null` is the canonical \"root of the Media Library\" value everywhere\n in the upload domain. The DS `SingleSelectOption.value` prop is typed\n `string | number`, so we use the empty string as a DOM-only sentinel\n for the root option and map it back to `null` on change. */}\n <SingleSelect\n value={field.value == null ? '' : String(field.value)}\n onChange={(value) => {\n const next = value === '' ? null : Number(value);\n field.onChange('folder', next);\n }}\n disabled={isSubmitting}\n >\n <SingleSelectOption value=\"\">{rootLabel}</SingleSelectOption>\n {folders.map((folder) => (\n <SingleSelectOption key={folder.id} value={String(folder.id)}>\n {folder.name}\n </SingleSelectOption>\n ))}\n </SingleSelect>\n </Field.Root>\n );\n};\n\n/* -------------------------------------------------------------------------------------------------\n * DeleteAssetButton\n * -----------------------------------------------------------------------------------------------*/\n\nconst DeleteAssetButton = () => {\n const { formatMessage } = useIntl();\n const { deleteAsset, isDeleting } = useAssetOperation();\n const [isOpen, setIsOpen] = React.useState(false);\n\n const handleConfirm = async () => {\n await deleteAsset();\n setIsOpen(false);\n };\n\n const triggerLabel = formatMessage({\n id: getTranslationKey('asset-details.delete.trigger'),\n defaultMessage: 'Delete this file',\n });\n\n return (\n <Dialog.Root open={isOpen} onOpenChange={setIsOpen}>\n <Dialog.Trigger>\n <IconButton withTooltip={false} label={triggerLabel} variant=\"danger-light\">\n <Trash />\n </IconButton>\n </Dialog.Trigger>\n <Dialog.Content>\n <Dialog.Header>\n {formatMessage({\n id: getTranslationKey('asset-details.delete.title'),\n defaultMessage: 'Delete this media file?',\n })}\n </Dialog.Header>\n <Dialog.Body\n icon={<WarningCircle width=\"24px\" height=\"24px\" fill=\"danger600\" />}\n textAlign=\"center\"\n >\n {formatMessage({\n id: getTranslationKey('asset-details.delete.description'),\n defaultMessage:\n 'This file cannot be recovered once deleted. If it is currently in use, linked content will break and image containers will be empty.',\n })}\n </Dialog.Body>\n <Dialog.Footer>\n <Dialog.Cancel>\n <Button variant=\"tertiary\" disabled={isDeleting} fullWidth>\n {formatMessage({ id: 'app.components.Button.cancel', defaultMessage: 'Cancel' })}\n </Button>\n </Dialog.Cancel>\n <Dialog.Action>\n <Button variant=\"danger-light\" loading={isDeleting} onClick={handleConfirm} fullWidth>\n {formatMessage({ id: 'app.components.Button.confirm', defaultMessage: 'Confirm' })}\n </Button>\n </Dialog.Action>\n </Dialog.Footer>\n </Dialog.Content>\n </Dialog.Root>\n );\n};\n\n/* -------------------------------------------------------------------------------------------------\n * CopyLinkButton — write the absolute asset URL to the clipboard.\n * -----------------------------------------------------------------------------------------------*/\n\ninterface CopyLinkButtonProps {\n asset: AssetWithPopulatedCreatedBy;\n}\n\nconst CopyLinkButton = ({ asset }: CopyLinkButtonProps) => {\n const { formatMessage } = useIntl();\n const { copy } = useClipboard();\n const notify = useDrawerNotify();\n\n const handleCopy = async () => {\n const url = prefixFileUrlWithBackendUrl(asset.url);\n if (!url) return;\n const didCopy = await copy(url);\n notify({\n type: didCopy ? 'success' : 'danger',\n message: didCopy\n ? formatMessage({\n id: getTranslationKey('asset-details.copy-link.success'),\n defaultMessage: 'Link copied.',\n })\n : formatMessage({\n id: getTranslationKey('asset-details.copy-link.error'),\n defaultMessage: 'Failed to copy the link.',\n }),\n });\n };\n\n return (\n <IconButton\n withTooltip={false}\n label={formatMessage({\n id: getTranslationKey('asset-details.copy-link.trigger'),\n defaultMessage: 'Copy link',\n })}\n variant=\"tertiary\"\n onClick={handleCopy}\n >\n <Link />\n </IconButton>\n );\n};\n\n/* -------------------------------------------------------------------------------------------------\n * DownloadAssetButton — fetch the file and trigger a browser download.\n * -----------------------------------------------------------------------------------------------*/\n\ninterface DownloadAssetButtonProps {\n asset: AssetWithPopulatedCreatedBy;\n}\n\nconst DownloadAssetButton = ({ asset }: DownloadAssetButtonProps) => {\n const { formatMessage } = useIntl();\n const notify = useDrawerNotify();\n const [isDownloading, setIsDownloading] = React.useState(false);\n\n const handleDownload = async () => {\n const url = prefixFileUrlWithBackendUrl(asset.url);\n if (!url) return;\n setIsDownloading(true);\n try {\n await downloadFile(url, asset.name);\n } catch {\n notify({\n type: 'danger',\n message: formatMessage({\n id: getTranslationKey('asset-details.download.error'),\n defaultMessage: 'Failed to download the file.',\n }),\n });\n } finally {\n setIsDownloading(false);\n }\n };\n\n return (\n <IconButton\n withTooltip={false}\n label={formatMessage({\n id: getTranslationKey('asset-details.download.trigger'),\n defaultMessage: 'Download',\n })}\n variant=\"tertiary\"\n onClick={handleDownload}\n disabled={isDownloading}\n >\n <Download />\n </IconButton>\n );\n};\n\n/* -------------------------------------------------------------------------------------------------\n * ReplaceAssetButton\n * -----------------------------------------------------------------------------------------------*/\n\nconst ReplaceAssetButton = () => {\n const { formatMessage } = useIntl();\n const { replaceAsset, isReplacing } = useAssetOperation();\n const fileInputRef = React.useRef<HTMLInputElement>(null);\n const [isDialogOpen, setIsDialogOpen] = React.useState(false);\n const { data: settings } = useGetSettingsQuery();\n const aiEnabled = settings?.data?.aiMetadata ?? false;\n\n const handleTriggerClick = () => {\n setIsDialogOpen(true);\n };\n\n const handleContinue = () => {\n // Confirm first, then open the native picker so the user only commits to\n // replacing after acknowledging the warning. The actual POST is delegated\n // to the parent (which owns the mutation + loading state).\n setIsDialogOpen(false);\n fileInputRef.current?.click();\n };\n\n const handleFileChange = async (event: React.ChangeEvent<HTMLInputElement>) => {\n const file = event.target.files?.[0];\n // Reset the native input so the same file can be picked again later.\n event.target.value = '';\n if (!file) {\n return;\n }\n await replaceAsset(file);\n };\n\n return (\n <>\n <VisuallyHidden>\n <input\n ref={fileInputRef}\n type=\"file\"\n multiple={false}\n onChange={handleFileChange}\n aria-hidden\n tabIndex={-1}\n />\n </VisuallyHidden>\n <IconButton\n withTooltip={false}\n label={formatMessage({\n id: getTranslationKey('asset-details.replace.trigger'),\n defaultMessage: 'Replace this file',\n })}\n variant=\"tertiary\"\n onClick={handleTriggerClick}\n disabled={isReplacing}\n >\n <ArrowsCounterClockwise />\n </IconButton>\n <Dialog.Root open={isDialogOpen} onOpenChange={setIsDialogOpen}>\n <Dialog.Content>\n <Dialog.Header>\n {formatMessage({\n id: getTranslationKey('asset-details.replace.title'),\n defaultMessage: 'Replace this media file?',\n })}\n </Dialog.Header>\n <Dialog.Body textAlign=\"center\">\n <Flex direction=\"column\" textAlign=\"center\">\n <Typography variant=\"omega\">\n {formatMessage({\n id: getTranslationKey('asset-details.replace.description'),\n defaultMessage: 'Current content will be permanently replaced.',\n })}\n </Typography>\n {aiEnabled ? (\n <Typography variant=\"omega\">\n {formatMessage({\n id: getTranslationKey('asset-details.replace.description.ai'),\n defaultMessage: 'AI will generate new metadata after upload.',\n })}\n </Typography>\n ) : null}\n </Flex>\n </Dialog.Body>\n <Dialog.Footer>\n <Dialog.Cancel>\n <Button variant=\"tertiary\" fullWidth>\n {formatMessage({ id: 'app.components.Button.cancel', defaultMessage: 'Cancel' })}\n </Button>\n </Dialog.Cancel>\n <Dialog.Action>\n <Button variant=\"secondary\" onClick={handleContinue} fullWidth>\n {formatMessage({\n id: getTranslationKey('asset-details.replace.continue'),\n defaultMessage: 'Continue',\n })}\n </Button>\n </Dialog.Action>\n </Dialog.Footer>\n </Dialog.Content>\n </Dialog.Root>\n </>\n );\n};\n\n/* -------------------------------------------------------------------------------------------------\n * AssetImageActions - crop and replace buttons overlaid on the image preview.\n * -----------------------------------------------------------------------------------------------*/\n\ninterface AssetImageActionsProps {\n onCrop?: () => void;\n}\n\nconst AssetImageActions = ({ onCrop }: AssetImageActionsProps) => {\n const { formatMessage } = useIntl();\n const isSubmitting = useForm('AssetImageActions', (state) => state.isSubmitting);\n\n return (\n <Flex direction=\"column\" gap={2}>\n <IconButton\n withTooltip={false}\n label={formatMessage({\n id: getTranslationKey('asset-details.crop.trigger'),\n defaultMessage: 'Crop',\n })}\n variant=\"tertiary\"\n onClick={onCrop}\n disabled={isSubmitting || !onCrop}\n >\n <Crop />\n </IconButton>\n <ReplaceAssetButton />\n </Flex>\n );\n};\n\n/* -------------------------------------------------------------------------------------------------\n * AssetDetails\n * -----------------------------------------------------------------------------------------------*/\n\ninterface AssetDetailsProps {\n asset: AssetWithPopulatedCreatedBy;\n closeDetails: () => void;\n}\n\ninterface AssetFormState {\n name: string;\n caption: string;\n alternativeText: string;\n folder: number | null;\n}\n\nexport const AssetDetails = ({ asset, closeDetails }: AssetDetailsProps) => {\n const { formatMessage, formatDate } = useIntl();\n const { data: folders = [] } = useGetAllFoldersQuery();\n const { toggleNotification } = useNotification();\n const [updateAsset] = useUpdateAssetMutation();\n const [replaceMutation, { isLoading: isReplacing }] = useReplaceAssetMutation();\n const [deleteMutation, { isLoading: isDeleting }] = useDeleteAssetMutation();\n const [uploadCroppedCopy, { isLoading: isCropCopying }] = useUploadFileSilentlyMutation();\n\n const [isCropOpen, setIsCropOpen] = React.useState(false);\n\n // In-drawer toast slot\n const [drawerToast, setDrawerToast] = React.useState<DrawerToast | null>(null);\n React.useEffect(() => {\n if (!drawerToast) return;\n const timer = window.setTimeout(() => setDrawerToast(null), 5000);\n return () => window.clearTimeout(timer);\n }, [drawerToast]);\n\n // Local alias matching the DrawerNotifyContext signature, so the drawer's\n // own handlers (replace, update) read like the consumers do.\n const notify = React.useCallback<DrawerNotify>((toast) => setDrawerToast(toast), []);\n\n const isImage = asset.mime?.includes(ASSET_TYPES.Image);\n\n const initialValues: AssetFormState = {\n name: asset.name ?? '',\n caption: asset.caption ?? '',\n alternativeText: asset.alternativeText ?? '',\n folder:\n typeof asset.folder === 'object' && asset.folder !== null\n ? ((asset.folder as { id: number }).id ?? null)\n : ((asset.folder as number | null | undefined) ?? null),\n };\n\n const handleSubmit = async (values: AssetFormState) => {\n const fileInfo = {\n name: values.name,\n caption: values.caption,\n alternativeText: values.alternativeText,\n folder: values.folder,\n };\n\n const res = await updateAsset({ id: asset.id, fileInfo });\n\n if ('error' in res) {\n notify({\n type: 'danger',\n message: formatMessage({\n id: getTranslationKey('asset-details.update.error'),\n defaultMessage: 'Failed to update the file.',\n }),\n });\n return;\n }\n\n notify({\n type: 'success',\n message: formatMessage({\n id: getTranslationKey('asset-details.update.success'),\n defaultMessage: 'File updated',\n }),\n });\n };\n\n const { title: folderName } = useFolderInfo(\n typeof asset.folder === 'object' && asset.folder !== null\n ? ((asset.folder as { id: number }).id ?? null)\n : ((asset.folder as number | null | undefined) ?? null)\n );\n\n // Owns the replace upload so isReplacing can drive the busy overlay.\n const handleReplace = async (file: globalThis.File) => {\n const res = await replaceMutation({ id: asset.id, file });\n if ('error' in res) {\n const error = res.error as { data?: { error?: { message?: string }; message?: string } };\n const message =\n error?.data?.error?.message ??\n error?.data?.message ??\n formatMessage({\n id: getTranslationKey('asset-details.replace.error'),\n defaultMessage: 'Failed to replace the file.',\n });\n notify({ type: 'danger', message });\n return;\n }\n notify({\n type: 'success',\n message: formatMessage({\n id: getTranslationKey('asset-details.replace.success'),\n defaultMessage: 'File replaced.',\n }),\n });\n };\n\n // Owns the delete: on error notify in-drawer (drawer stays), on success fire\n // a persistent global notification then close the drawer.\n const handleDelete = async () => {\n const res = await deleteMutation(asset.id);\n if ('error' in res) {\n const error = res.error as { data?: { error?: { message?: string }; message?: string } };\n const message =\n error?.data?.error?.message ??\n error?.data?.message ??\n formatMessage({\n id: getTranslationKey('asset-details.delete.error'),\n defaultMessage: 'Failed to delete the asset.',\n });\n notify({ type: 'danger', message });\n return;\n }\n toggleNotification({\n type: 'success',\n message: formatMessage(\n {\n id: getTranslationKey('asset-details.delete.success'),\n defaultMessage: '1 element have been deleted from {folderName}',\n },\n { folderName }\n ),\n });\n closeDetails();\n };\n\n const notifyCropError = () => {\n notify({\n type: 'danger',\n message: formatMessage({\n id: getTranslationKey('asset-details.crop.error'),\n defaultMessage: 'Failed to crop the file.',\n }),\n });\n };\n\n // Apply: replace the original binary with the cropped file + focal point.\n // Close the editor first so the drawer's busy overlay is visible while the\n // mutation runs (the editor renders in a Portal above the drawer).\n const handleCropApply = async (file: globalThis.File, focalPoint: FocalPoint) => {\n setIsCropOpen(false);\n const res = await replaceMutation({\n id: asset.id,\n file,\n fileInfo: { focalPoint },\n });\n if ('error' in res) {\n notifyCropError();\n return;\n }\n notify({\n type: 'success',\n message: formatMessage({\n id: getTranslationKey('asset-details.crop.success'),\n defaultMessage: 'File cropped.',\n }),\n });\n };\n\n // Save as copy: upload the cropped file as a new asset in the same folder.\n const handleCropSaveAsCopy = async (file: globalThis.File, focalPoint: FocalPoint) => {\n setIsCropOpen(false);\n // Silent single-file upload (no global progress dialog). Carry over the\n // source asset's caption/alt so the copy keeps its metadata.\n const res = await uploadCroppedCopy({\n file,\n fileInfo: {\n name: asset.name,\n caption: asset.caption ?? '',\n alternativeText: asset.alternativeText ?? '',\n folder: initialValues.folder,\n focalPoint,\n },\n });\n if ('error' in res) {\n notifyCropError();\n return;\n }\n notify({\n type: 'success',\n message: formatMessage({\n id: getTranslationKey('asset-details.crop.copy-success'),\n defaultMessage: 'Copy created.',\n }),\n });\n };\n\n const operations = React.useMemo<AssetOperations>(\n () => ({\n replaceAsset: handleReplace,\n deleteAsset: handleDelete,\n isReplacing,\n isDeleting,\n }),\n // handleReplace / handleDelete close over asset+mutations and don't need a\n // stable identity here; the consumers re-render with the new context value.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [isReplacing, isDeleting]\n );\n\n return (\n // `key={asset.id}` resets the form when the drawer switches to a different\n // asset so cached values from the previous asset don't bleed in.\n <DrawerNotifyContext.Provider value={notify}>\n <AssetOperationsContext.Provider value={operations}>\n <FormShell>\n <Form key={asset.id} method=\"POST\" initialValues={initialValues} onSubmit={handleSubmit}>\n {({ modified, isSubmitting, values, resetForm }) => {\n const nameIsEmpty = ((values as AssetFormState).name ?? '').trim() === '';\n const busyMessage = getBusyMessage({ isDeleting, isReplacing, isCropCopying });\n return (\n <>\n {/* Guards every close path (X button, ESC, route change, browser\n back) by intercepting the navigation when the form is dirty.\n `onProceed` resets the form so the held navigation can complete.\n Lives inside <Form> so it can read the form context. */}\n <Blocker onProceed={resetForm} />\n {isCropOpen && isImage ? (\n <AssetCropEditor\n asset={asset}\n onClose={() => setIsCropOpen(false)}\n onApply={handleCropApply}\n onSaveAsCopy={handleCropSaveAsCopy}\n />\n ) : null}\n {busyMessage ? (\n <DrawerBusyOverlay>\n <Loader>{formatMessage(busyMessage)}</Loader>\n </DrawerBusyOverlay>\n ) : null}\n {drawerToast ? (\n <DrawerToastSlot>\n <Alert\n variant={drawerToast.type === 'success' ? 'success' : 'danger'}\n closeLabel={formatMessage({ id: 'global.close', defaultMessage: 'Close' })}\n onClose={() => setDrawerToast(null)}\n >\n {drawerToast.message}\n </Alert>\n </DrawerToastSlot>\n ) : null}\n <Drawer.ScrollableContent>\n <AssetPreview\n asset={asset}\n actions={\n isImage ? <AssetImageActions onCrop={() => setIsCropOpen(true)} /> : null\n }\n />\n <Flex\n direction=\"column\"\n alignItems=\"stretch\"\n gap={4}\n paddingTop={4}\n paddingBottom={4}\n paddingLeft={5}\n paddingRight={5}\n >\n <Typography variant=\"beta\" fontWeight=\"semiBold\" tag=\"h3\">\n {formatMessage({\n id: getTranslationKey('asset-details.fileInfo'),\n defaultMessage: 'File info',\n })}\n </Typography>\n <Flex\n wrap=\"wrap\"\n gap={4}\n background=\"neutral100\"\n paddingTop={4}\n paddingBottom={4}\n paddingLeft={6}\n paddingRight={6}\n alignItems=\"flex-start\"\n >\n <DetailItem\n label={formatMessage({\n id: getTranslationKey('asset-details.creationDate'),\n defaultMessage: 'Creation date',\n })}\n value={\n asset.createdAt\n ? formatDate(new Date(asset.createdAt), {\n dateStyle: 'long',\n timeStyle: 'short',\n })\n : null\n }\n />\n <DetailItem\n label={formatMessage({\n id: getTranslationKey('asset-details.lastUpdated'),\n defaultMessage: 'Last updated',\n })}\n value={\n asset.updatedAt\n ? formatDate(new Date(asset.updatedAt), {\n dateStyle: 'long',\n timeStyle: 'short',\n })\n : null\n }\n />\n <DetailItem\n label={formatMessage({\n id: getTranslationKey('asset-details.createdBy'),\n defaultMessage: 'Created by',\n })}\n value={\n asset.createdBy\n ? (getDisplayName({\n firstname: asset.createdBy.firstname ?? undefined,\n lastname: asset.createdBy.lastname ?? undefined,\n username: asset.createdBy.username ?? undefined,\n email: asset.createdBy.email ?? undefined,\n }) ?? '-')\n : null\n }\n />\n <DetailItem\n label={formatMessage({\n id: getTranslationKey('asset-details.size'),\n defaultMessage: 'Size',\n })}\n value={asset.size ? formatBytes(asset.size, 1) : null}\n />\n {isImage && (asset.width != null || asset.height != null) && (\n <DetailItem\n label={formatMessage({\n id: getTranslationKey('asset-details.dimensions'),\n defaultMessage: 'Dimensions',\n })}\n value={\n asset.width != null && asset.height != null\n ? `${asset.width} × ${asset.height}`\n : null\n }\n />\n )}\n <DetailItem\n label={formatMessage({\n id: getTranslationKey('asset-details.extension'),\n defaultMessage: 'Extension',\n })}\n value={getFileExtension(asset.ext)}\n />\n <DetailItem\n label={formatMessage({\n id: getTranslationKey('asset-details.assetId'),\n defaultMessage: 'Asset ID',\n })}\n value={String(asset.id)}\n />\n </Flex>\n <DetailField\n name=\"name\"\n label={formatMessage({\n id: getTranslationKey('asset-details.fileName'),\n defaultMessage: 'File name',\n })}\n required\n />\n <LocationField\n label={formatMessage({\n id: getTranslationKey('asset-details.location'),\n defaultMessage: 'Location',\n })}\n rootLabel={formatMessage({\n id: getTranslationKey('plugin.home'),\n defaultMessage: 'Home',\n })}\n folders={folders}\n />\n {isImage && (\n <>\n <DetailField\n name=\"caption\"\n label={formatMessage({\n id: getTranslationKey('asset-details.caption'),\n defaultMessage: 'Caption',\n })}\n />\n <DetailField\n name=\"alternativeText\"\n label={formatMessage({\n id: getTranslationKey('asset-details.alternativeText'),\n defaultMessage: 'Alternative text',\n })}\n />\n </>\n )}\n </Flex>\n </Drawer.ScrollableContent>\n <Flex\n justifyContent=\"space-between\"\n alignItems=\"center\"\n gap={2}\n padding={3}\n borderColor=\"neutral150\"\n borderStyle=\"solid\"\n borderWidth=\"1px 0 0 0\"\n background=\"neutral0\"\n >\n <Flex gap={2}>\n <DeleteAssetButton />\n <CopyLinkButton asset={asset} />\n <DownloadAssetButton asset={asset} />\n </Flex>\n <Button\n type=\"submit\"\n variant=\"default\"\n loading={isSubmitting}\n // File name is required; block submit when it's empty or whitespace so the API can't 400 on a blank value.\n disabled={!modified || isSubmitting || nameIsEmpty}\n >\n {formatMessage({\n id: getTranslationKey('asset-details.save'),\n defaultMessage: 'Save changes',\n })}\n </Button>\n </Flex>\n </>\n );\n }}\n </Form>\n </FormShell>\n </AssetOperationsContext.Provider>\n </DrawerNotifyContext.Provider>\n );\n};\n\n/* -------------------------------------------------------------------------------------------------\n * DrawerHeader\n * -----------------------------------------------------------------------------------------------*/\n\ninterface DrawerHeaderProps {\n asset: AssetWithPopulatedCreatedBy;\n closeDetails: () => void;\n}\n\nconst DrawerHeader = ({ asset, closeDetails }: DrawerHeaderProps) => {\n const DocIcon = asset ? getAssetIcon(asset.mime, asset.ext) : FileError;\n return (\n <Flex\n gap={2}\n paddingLeft={5}\n paddingTop={3}\n paddingBottom={3}\n paddingRight={3}\n borderColor=\"neutral150\"\n borderStyle=\"solid\"\n borderWidth=\"0 0 1px 0\"\n >\n <DocIcon width={20} height={20} />\n <Drawer.Title asChild>\n <Typography variant=\"omega\" fontWeight=\"semiBold\" overflow=\"hidden\" ellipsis tag=\"h2\">\n {asset.name}\n </Typography>\n </Drawer.Title>\n <Box marginLeft=\"auto\">\n <Drawer.CloseButton onClose={closeDetails}>\n <ArrowLineRight />\n </Drawer.CloseButton>\n </Box>\n </Flex>\n );\n};\n\n/* -------------------------------------------------------------------------------------------------\n * DrawerContent\n * -----------------------------------------------------------------------------------------------*/\n\ninterface DrawerContentProps {\n assetId: number;\n closeDetails: () => void;\n}\n\nconst DrawerContent = ({ assetId, closeDetails }: DrawerContentProps) => {\n const { formatMessage } = useIntl();\n const {\n data: asset,\n isLoading,\n error,\n } = useGetAssetQuery(assetId, {\n refetchOnMountOrArgChange: false,\n refetchOnReconnect: false,\n refetchOnFocus: false,\n });\n\n if (isLoading) {\n return (\n <Flex justifyContent=\"center\" padding={8}>\n <Loader>{formatMessage({ id: 'app.loading', defaultMessage: 'Loading...' })}</Loader>\n </Flex>\n );\n }\n\n if (error || !asset) {\n return (\n <Flex direction=\"column\" alignItems=\"stretch\" gap={4} padding={4}>\n <Alert\n variant=\"danger\"\n closeLabel={formatMessage({ id: 'global.close', defaultMessage: 'Close' })}\n onClose={closeDetails}\n >\n {formatMessage({\n id: getTranslationKey('asset-details.error'),\n defaultMessage: 'Failed to load file details.',\n })}\n </Alert>\n </Flex>\n );\n }\n\n return (\n <>\n <DrawerHeader asset={asset} closeDetails={closeDetails} />\n <AssetDetails asset={asset} closeDetails={closeDetails} />\n </>\n );\n};\n\n/* -------------------------------------------------------------------------------------------------\n * AssetDetailsDrawer\n * -----------------------------------------------------------------------------------------------*/\n\nexport const AssetDetailsDrawer = () => {\n const { formatMessage } = useIntl();\n const { assetId, isVisible, shouldRenderDrawer, onCloseAnimationEnd, closeDetails } =\n useAssetDetailsParam();\n\n if (!shouldRenderDrawer || assetId === null) {\n return null;\n }\n\n return (\n <Drawer.Root isVisible={isVisible} onClose={closeDetails}>\n {/* Wrapper div required: Dialog.Portal uses asChild and merges ref onto each child.\n VisuallyHidden does not forward refs, so we wrap it in a div that can receive the ref. */}\n <div>\n <VisuallyHidden>\n <Drawer.Title>\n {formatMessage({\n id: getTranslationKey('asset-details.title'),\n defaultMessage: 'File details',\n })}\n </Drawer.Title>\n <Drawer.Description>\n {formatMessage({\n id: getTranslationKey('asset-details.description'),\n defaultMessage: 'Displays file information and metadata',\n })}\n </Drawer.Description>\n </VisuallyHidden>\n </div>\n <Drawer.Body\n animationDirection=\"left\"\n width=\"41.6rem\"\n height=\"100vh\"\n onAnimationEnd={onCloseAnimationEnd}\n >\n <DrawerContent assetId={assetId} closeDetails={closeDetails} />\n </Drawer.Body>\n </Drawer.Root>\n );\n};\n"],"names":["URL_PARAM","DrawerNotifyContext","React","createContext","useDrawerNotify","ctx","useContext","Error","AssetOperationsContext","useAssetOperation","useAssetDetailsParam","query","setQuery","useQueryParams","detailsId","assetId","parseInt","hasValidId","Number","isNaN","isMounted","setIsMounted","useState","displayAssetId","useRef","useEffect","current","onCloseAnimationEnd","useCallback","event","target","currentTarget","openDetails","id","String","closeDetails","undefined","isVisible","shouldRenderDrawer","DetailItemContainer","styled","Flex","theme","spaces","DetailItem","label","value","_jsxs","direction","justifyContent","alignItems","gap","_jsx","Typography","variant","textColor","fontWeight","textTransform","FormShell","Box","DrawerToastSlot","DrawerBusyOverlay","colors","neutral0","getBusyMessage","state","isDeleting","getTranslationKey","defaultMessage","isCropCopying","isReplacing","StyledWarning","WarningCircle","warning500","DetailField","name","required","formatMessage","useIntl","field","useField","isSubmitting","useForm","emptyTooltipLabel","Field","Root","Label","TextInput","onChange","endAction","Tooltip","aria-label","role","type","disabled","LocationField","rootLabel","folders","SingleSelect","next","SingleSelectOption","map","folder","DeleteAssetButton","deleteAsset","isOpen","setIsOpen","handleConfirm","triggerLabel","Dialog","open","onOpenChange","Trigger","IconButton","withTooltip","Trash","Content","Header","Body","icon","width","height","fill","textAlign","Footer","Cancel","Button","fullWidth","Action","loading","onClick","CopyLinkButton","asset","copy","useClipboard","notify","handleCopy","url","prefixFileUrlWithBackendUrl","didCopy","message","Link","DownloadAssetButton","isDownloading","setIsDownloading","handleDownload","downloadFile","Download","ReplaceAssetButton","replaceAsset","fileInputRef","isDialogOpen","setIsDialogOpen","data","settings","useGetSettingsQuery","aiEnabled","aiMetadata","handleTriggerClick","handleContinue","click","handleFileChange","file","files","_Fragment","VisuallyHidden","input","ref","multiple","aria-hidden","tabIndex","ArrowsCounterClockwise","AssetImageActions","onCrop","Crop","AssetDetails","formatDate","useGetAllFoldersQuery","toggleNotification","useNotification","updateAsset","useUpdateAssetMutation","replaceMutation","isLoading","useReplaceAssetMutation","deleteMutation","useDeleteAssetMutation","uploadCroppedCopy","useUploadFileSilentlyMutation","isCropOpen","setIsCropOpen","drawerToast","setDrawerToast","timer","window","setTimeout","clearTimeout","toast","isImage","mime","includes","ASSET_TYPES","Image","initialValues","caption","alternativeText","handleSubmit","values","fileInfo","res","title","folderName","useFolderInfo","handleReplace","error","handleDelete","notifyCropError","handleCropApply","focalPoint","handleCropSaveAsCopy","operations","useMemo","Provider","Form","method","onSubmit","modified","resetForm","nameIsEmpty","trim","busyMessage","Blocker","onProceed","AssetCropEditor","onClose","onApply","onSaveAsCopy","Loader","Alert","closeLabel","Drawer","ScrollableContent","AssetPreview","actions","paddingTop","paddingBottom","paddingLeft","paddingRight","tag","wrap","background","createdAt","Date","dateStyle","timeStyle","updatedAt","createdBy","getDisplayName","firstname","lastname","username","email","size","formatBytes","getFileExtension","ext","padding","borderColor","borderStyle","borderWidth","DrawerHeader","DocIcon","getAssetIcon","FileError","Title","asChild","overflow","ellipsis","marginLeft","CloseButton","ArrowLineRight","DrawerContent","useGetAssetQuery","refetchOnMountOrArgChange","refetchOnReconnect","refetchOnFocus","AssetDetailsDrawer","div","Description","animationDirection","onAnimationEnd"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"AssetDetailsDrawer.js","sources":["../../../../../../../admin/src/future/pages/Assets/components/AssetDetails/AssetDetailsDrawer.tsx"],"sourcesContent":["import * as React from 'react';\n\nimport {\n Blocker,\n Form,\n useClipboard,\n useField,\n useForm,\n useNotification,\n useQueryParams,\n getDisplayName,\n} from '@strapi/admin/strapi-admin';\nimport {\n Alert,\n Box,\n Button,\n Dialog,\n Field,\n Flex,\n IconButton,\n Loader,\n SingleSelect,\n SingleSelectOption,\n TextInput,\n Tooltip,\n Typography,\n VisuallyHidden,\n} from '@strapi/design-system';\nimport {\n ArrowLineRight,\n ArrowsCounterClockwise,\n Crop,\n Download,\n FileError,\n Link,\n Trash,\n WarningCircle,\n} from '@strapi/icons';\nimport { useIntl } from 'react-intl';\nimport { styled } from 'styled-components';\n\nimport { ASSET_TYPES } from '../../../../../enums';\nimport { Drawer } from '../../../../components/Drawer';\nimport { useMediaLibraryPermissions } from '../../../../hooks/useMediaLibraryPermissions';\nimport { useUploadFileSilentlyMutation } from '../../../../services/api';\nimport {\n useDeleteAssetMutation,\n useGetAssetQuery,\n useReplaceAssetMutation,\n useUpdateAssetMutation,\n} from '../../../../services/assets';\nimport { useGetAllFoldersQuery } from '../../../../services/folders';\nimport { useGetUploadSettingsQuery } from '../../../../services/settings';\nimport { downloadFile } from '../../../../utils/downloadFile';\nimport {\n formatBytes,\n getFileExtension,\n prefixFileUrlWithBackendUrl,\n} from '../../../../utils/files';\nimport { getAssetIcon } from '../../../../utils/getAssetIcon';\nimport { getTranslationKey } from '../../../../utils/translations';\nimport { useFolderInfo } from '../../hooks/useFolderInfo';\n\nimport { AssetCropEditor } from './AssetCropEditor';\nimport { AssetPreview } from './AssetPreview';\n\nimport type {\n AssetWithPopulatedCreatedBy,\n FocalPoint,\n} from '../../../../../../../shared/contracts/files';\n\n// Name of the parameter to look for in the URL to open the drawer\nconst URL_PARAM = 'assetId';\n\ninterface DrawerToast {\n type: 'success' | 'danger';\n message: string;\n}\n\n/* -------------------------------------------------------------------------------------------------\n * DrawerNotifyContext — exposes the in-drawer toast setter so deep descendants\n * (footer action buttons) can report success/error without prop drilling.\n * -----------------------------------------------------------------------------------------------*/\n\ntype DrawerNotify = (toast: DrawerToast) => void;\n\nexport const DrawerNotifyContext = React.createContext<DrawerNotify | null>(null);\n\nconst useDrawerNotify = () => {\n const ctx = React.useContext(DrawerNotifyContext);\n if (!ctx) {\n throw new Error('useDrawerNotify must be used within AssetDetails');\n }\n return ctx;\n};\n\n/* -------------------------------------------------------------------------------------------------\n * AssetOperationsContext — drawer-scoped mutations + their pending state, so\n * leaf buttons (Delete, Replace) consume them without prop drilling and the\n * full-drawer busy overlay reads a single flag.\n * -----------------------------------------------------------------------------------------------*/\n\ninterface AssetOperations {\n replaceAsset: (file: globalThis.File) => Promise<void>;\n deleteAsset: () => Promise<void>;\n isReplacing: boolean;\n isDeleting: boolean;\n}\n\nexport const AssetOperationsContext = React.createContext<AssetOperations | null>(null);\n\nconst useAssetOperation = () => {\n const ctx = React.useContext(AssetOperationsContext);\n if (!ctx) {\n throw new Error('useAssetOperation must be used within AssetDetails');\n }\n return ctx;\n};\n\n/* -------------------------------------------------------------------------------------------------\n * useAssetDetailsParam - sync drawer visibility with URL ?{URL_PARAM}={id}\n * -----------------------------------------------------------------------------------------------*/\n\nexport const useAssetDetailsParam = () => {\n const [{ query }, setQuery] = useQueryParams<{ [URL_PARAM]?: string }>();\n\n const detailsId = query?.[URL_PARAM];\n const assetId = detailsId ? parseInt(detailsId, 10) : null;\n const hasValidId = assetId !== null && !Number.isNaN(assetId);\n\n // Closing is driven by removing the URL param (a navigation), so navigation\n // guards like <Blocker> can intercept it. `isMounted` keeps the drawer in the\n // tree through the slide-out: it stays true once opened and only flips false\n // when the close animation actually ends (see onCloseAnimationEnd), so the\n // close duration lives entirely in CSS — no JS timer.\n const [isMounted, setIsMounted] = React.useState(hasValidId);\n const displayAssetId = React.useRef<number | null>(null);\n\n React.useEffect(() => {\n if (hasValidId) {\n displayAssetId.current = assetId;\n setIsMounted(true);\n }\n }, [hasValidId, assetId]);\n\n const onCloseAnimationEnd = React.useCallback(\n (event: React.AnimationEvent) => {\n // Ignore animations bubbling up from descendants, and the slide-in.\n if (event.target === event.currentTarget && !hasValidId) {\n setIsMounted(false);\n }\n },\n [hasValidId]\n );\n\n const openDetails = React.useCallback(\n (id: number) => {\n setQuery({ [URL_PARAM]: String(id) }, 'push', true);\n },\n [setQuery]\n );\n\n const closeDetails = React.useCallback(() => {\n setQuery({ [URL_PARAM]: undefined }, 'remove', true);\n }, [setQuery]);\n\n return {\n assetId: hasValidId ? assetId : displayAssetId.current,\n isVisible: hasValidId,\n shouldRenderDrawer: isMounted,\n onCloseAnimationEnd,\n openDetails,\n closeDetails,\n };\n};\n\n/* -------------------------------------------------------------------------------------------------\n * DetailItem\n * -----------------------------------------------------------------------------------------------*/\n\ninterface DetailItemProps {\n label: string;\n value: React.ReactNode;\n}\n\nconst DetailItemContainer = styled(Flex)`\n flex: 0 0 calc(50% - ${({ theme }) => theme.spaces[2]});\n`;\n\nconst DetailItem = ({ label, value }: DetailItemProps) => (\n <DetailItemContainer\n direction=\"column\"\n justifyContent=\"flex-start\"\n alignItems=\"flex-start\"\n gap={1}\n >\n <Typography\n variant=\"sigma\"\n textColor=\"neutral600\"\n fontWeight=\"semiBold\"\n textTransform=\"uppercase\"\n >\n {label}\n </Typography>\n <Typography variant=\"pi\" textColor=\"neutral700\">\n {value ?? '-'}\n </Typography>\n </DetailItemContainer>\n);\n\n/* -------------------------------------------------------------------------------------------------\n * DetailField\n * -----------------------------------------------------------------------------------------------*/\n\n/**\n * Make the asset details Form behave as a flex column inside Drawer.Body so\n * the scrollable area can grow while the footer stays pinned at the bottom.\n * The Form component from `@strapi/admin/strapi-admin` only forwards `width`\n * + `height` to its Box, so we target the rendered `<form>` element via a\n * styled-components descendant rule.\n */\nconst FormShell = styled(Box)`\n display: flex;\n flex-direction: column;\n flex: 1;\n min-height: 0;\n\n > form {\n display: flex;\n flex-direction: column;\n flex: 1;\n min-height: 0;\n position: relative;\n }\n`;\n\n/**\n * In-drawer toast container\n */\nconst DrawerToastSlot = styled(Box)`\n position: absolute;\n top: ${({ theme }) => theme.spaces[2]};\n left: 50%;\n transform: translateX(-50%);\n z-index: 10;\n width: calc(100% - ${({ theme }) => theme.spaces[2]});\n`;\n\n/**\n * Full-form overlay rendered during long-running drawer-scoped mutations\n * (e.g. replacing the binary). Sits above the toast slot (z-index 10) and\n * the in-drawer Alert so the user can't interact with the form mid-flight.\n */\nconst DrawerBusyOverlay = styled(Flex)`\n position: absolute;\n inset: 0;\n z-index: 20;\n align-items: center;\n justify-content: center;\n background: ${({ theme }) => theme.colors.neutral0};\n opacity: 0.7;\n`;\n\n/**\n * Map the drawer-scoped mutation flags to a single i18n message for the busy\n * overlay loader. Returns `null` when nothing is in flight.\n */\nconst getBusyMessage = (state: {\n isDeleting: boolean;\n isReplacing: boolean;\n isCropCopying: boolean;\n}): { id: string; defaultMessage: string } | null => {\n if (state.isDeleting) {\n return {\n id: getTranslationKey('asset-details.delete.loading'),\n defaultMessage: 'Deleting the file…',\n };\n }\n if (state.isCropCopying) {\n return {\n id: getTranslationKey('asset-details.crop.loading'),\n defaultMessage: 'Saving the cropped copy…',\n };\n }\n if (state.isReplacing) {\n return {\n id: getTranslationKey('asset-details.replace.loading'),\n defaultMessage: 'Replacing the file…',\n };\n }\n return null;\n};\n\nconst StyledWarning = styled(WarningCircle)`\n width: 1.6rem;\n height: 1.6rem;\n\n path {\n fill: ${({ theme }) => theme.colors.warning500};\n }\n`;\n\ninterface DetailFieldProps {\n name: string;\n label: string;\n required?: boolean;\n disabled?: boolean;\n}\n\nconst DetailField = ({ name, label, required, disabled }: DetailFieldProps) => {\n const { formatMessage } = useIntl();\n const field = useField<string>(name);\n const isSubmitting = useForm('DetailField', (state) => state.isSubmitting);\n\n // The form context (use-context-selector) echoes changes back\n // asynchronously — driving the input straight from `field.value` makes\n // React rewrite the DOM value after the keystroke, which throws the cursor\n // to the end of the field. The input is therefore controlled by local state\n // (synchronous, cursor-safe) and the form follows; the effect below only\n // matters for EXTERNAL value changes (discard/reset), where a cursor jump\n // is fine because the user isn't typing.\n const fieldValue = field.value ?? '';\n const [value, setValue] = React.useState(fieldValue);\n\n React.useEffect(() => {\n setValue(fieldValue);\n }, [fieldValue]);\n\n const emptyTooltipLabel = formatMessage(\n {\n id: getTranslationKey('asset-details.field.empty'),\n defaultMessage: '{label} is currently empty.',\n },\n { label }\n );\n\n return (\n <Field.Root name={name} required={required}>\n <Field.Label>{label}</Field.Label>\n <TextInput\n value={value}\n onChange={(event: React.ChangeEvent<HTMLInputElement>) => {\n setValue(event.target.value);\n field.onChange(name, event.target.value);\n }}\n endAction={\n !value ? (\n <Tooltip label={emptyTooltipLabel}>\n <StyledWarning aria-label={emptyTooltipLabel} role=\"img\" />\n </Tooltip>\n ) : undefined\n }\n type=\"text\"\n disabled={isSubmitting || disabled}\n />\n </Field.Root>\n );\n};\n\n/* -------------------------------------------------------------------------------------------------\n * LocationField\n * -----------------------------------------------------------------------------------------------*/\n\ninterface LocationFieldProps {\n label: string;\n rootLabel: string;\n folders: Array<{ id: number; name: string }>;\n disabled?: boolean;\n}\n\nconst LocationField = ({ label, rootLabel, folders, disabled }: LocationFieldProps) => {\n const field = useField<number | null>('folder');\n const isSubmitting = useForm('LocationField', (state) => state.isSubmitting);\n\n return (\n <Field.Root name=\"folder\" required>\n <Field.Label>{label}</Field.Label>\n {/* `null` is the canonical \"root of the Media Library\" value everywhere\n in the upload domain. The DS `SingleSelectOption.value` prop is typed\n `string | number`, so we use the empty string as a DOM-only sentinel\n for the root option and map it back to `null` on change. */}\n <SingleSelect\n value={field.value == null ? '' : String(field.value)}\n onChange={(value) => {\n const next = value === '' ? null : Number(value);\n field.onChange('folder', next);\n }}\n disabled={isSubmitting || disabled}\n >\n <SingleSelectOption value=\"\">{rootLabel}</SingleSelectOption>\n {folders.map((folder) => (\n <SingleSelectOption key={folder.id} value={String(folder.id)}>\n {folder.name}\n </SingleSelectOption>\n ))}\n </SingleSelect>\n </Field.Root>\n );\n};\n\n/* -------------------------------------------------------------------------------------------------\n * DeleteAssetButton\n * -----------------------------------------------------------------------------------------------*/\n\nconst DeleteAssetButton = () => {\n const { formatMessage } = useIntl();\n const { deleteAsset, isDeleting } = useAssetOperation();\n const [isOpen, setIsOpen] = React.useState(false);\n\n const handleConfirm = async () => {\n await deleteAsset();\n setIsOpen(false);\n };\n\n const triggerLabel = formatMessage({\n id: getTranslationKey('asset-details.delete.trigger'),\n defaultMessage: 'Delete this file',\n });\n\n return (\n <Dialog.Root open={isOpen} onOpenChange={setIsOpen}>\n <Dialog.Trigger>\n <IconButton withTooltip={false} label={triggerLabel} variant=\"danger-light\">\n <Trash />\n </IconButton>\n </Dialog.Trigger>\n <Dialog.Content>\n <Dialog.Header>\n {formatMessage({\n id: getTranslationKey('asset-details.delete.title'),\n defaultMessage: 'Delete this media file?',\n })}\n </Dialog.Header>\n <Dialog.Body\n icon={<WarningCircle width=\"24px\" height=\"24px\" fill=\"danger600\" />}\n textAlign=\"center\"\n >\n {formatMessage({\n id: getTranslationKey('asset-details.delete.description'),\n defaultMessage:\n 'This file cannot be recovered once deleted. If it is currently in use, linked content will break and image containers will be empty.',\n })}\n </Dialog.Body>\n <Dialog.Footer>\n <Dialog.Cancel>\n <Button variant=\"tertiary\" disabled={isDeleting} fullWidth>\n {formatMessage({ id: 'app.components.Button.cancel', defaultMessage: 'Cancel' })}\n </Button>\n </Dialog.Cancel>\n <Dialog.Action>\n <Button variant=\"danger-light\" loading={isDeleting} onClick={handleConfirm} fullWidth>\n {formatMessage({ id: 'app.components.Button.confirm', defaultMessage: 'Confirm' })}\n </Button>\n </Dialog.Action>\n </Dialog.Footer>\n </Dialog.Content>\n </Dialog.Root>\n );\n};\n\n/* -------------------------------------------------------------------------------------------------\n * CopyLinkButton — write the absolute asset URL to the clipboard.\n * -----------------------------------------------------------------------------------------------*/\n\ninterface CopyLinkButtonProps {\n asset: AssetWithPopulatedCreatedBy;\n}\n\nconst CopyLinkButton = ({ asset }: CopyLinkButtonProps) => {\n const { formatMessage } = useIntl();\n const { copy } = useClipboard();\n const notify = useDrawerNotify();\n\n const handleCopy = async () => {\n const url = prefixFileUrlWithBackendUrl(asset.url);\n if (!url) return;\n const didCopy = await copy(url);\n notify({\n type: didCopy ? 'success' : 'danger',\n message: didCopy\n ? formatMessage({\n id: getTranslationKey('asset-details.copy-link.success'),\n defaultMessage: 'Link copied.',\n })\n : formatMessage({\n id: getTranslationKey('asset-details.copy-link.error'),\n defaultMessage: 'Failed to copy the link.',\n }),\n });\n };\n\n return (\n <IconButton\n withTooltip={false}\n label={formatMessage({\n id: getTranslationKey('asset-details.copy-link.trigger'),\n defaultMessage: 'Copy link',\n })}\n variant=\"tertiary\"\n onClick={handleCopy}\n >\n <Link />\n </IconButton>\n );\n};\n\n/* -------------------------------------------------------------------------------------------------\n * DownloadAssetButton — fetch the file and trigger a browser download.\n * -----------------------------------------------------------------------------------------------*/\n\ninterface DownloadAssetButtonProps {\n asset: AssetWithPopulatedCreatedBy;\n}\n\nconst DownloadAssetButton = ({ asset }: DownloadAssetButtonProps) => {\n const { formatMessage } = useIntl();\n const notify = useDrawerNotify();\n const [isDownloading, setIsDownloading] = React.useState(false);\n\n const handleDownload = async () => {\n const url = prefixFileUrlWithBackendUrl(asset.url);\n if (!url) return;\n setIsDownloading(true);\n try {\n await downloadFile(url, asset.name);\n } catch {\n notify({\n type: 'danger',\n message: formatMessage({\n id: getTranslationKey('asset-details.download.error'),\n defaultMessage: 'Failed to download the file.',\n }),\n });\n } finally {\n setIsDownloading(false);\n }\n };\n\n return (\n <IconButton\n withTooltip={false}\n label={formatMessage({\n id: getTranslationKey('asset-details.download.trigger'),\n defaultMessage: 'Download',\n })}\n variant=\"tertiary\"\n onClick={handleDownload}\n disabled={isDownloading}\n >\n <Download />\n </IconButton>\n );\n};\n\n/* -------------------------------------------------------------------------------------------------\n * ReplaceAssetButton\n * -----------------------------------------------------------------------------------------------*/\n\nconst ReplaceAssetButton = () => {\n const { formatMessage } = useIntl();\n const { replaceAsset, isReplacing } = useAssetOperation();\n const fileInputRef = React.useRef<HTMLInputElement>(null);\n const [isDialogOpen, setIsDialogOpen] = React.useState(false);\n const { data: settings } = useGetUploadSettingsQuery();\n const aiEnabled = settings?.data?.aiMetadata ?? false;\n\n const handleTriggerClick = () => {\n setIsDialogOpen(true);\n };\n\n const handleContinue = () => {\n // Confirm first, then open the native picker so the user only commits to\n // replacing after acknowledging the warning. The actual POST is delegated\n // to the parent (which owns the mutation + loading state).\n setIsDialogOpen(false);\n fileInputRef.current?.click();\n };\n\n const handleFileChange = async (event: React.ChangeEvent<HTMLInputElement>) => {\n const file = event.target.files?.[0];\n // Reset the native input so the same file can be picked again later.\n event.target.value = '';\n if (!file) {\n return;\n }\n await replaceAsset(file);\n };\n\n return (\n <>\n <VisuallyHidden>\n <input\n ref={fileInputRef}\n type=\"file\"\n multiple={false}\n onChange={handleFileChange}\n aria-hidden\n tabIndex={-1}\n />\n </VisuallyHidden>\n <IconButton\n withTooltip={false}\n label={formatMessage({\n id: getTranslationKey('asset-details.replace.trigger'),\n defaultMessage: 'Replace this file',\n })}\n variant=\"tertiary\"\n onClick={handleTriggerClick}\n disabled={isReplacing}\n >\n <ArrowsCounterClockwise />\n </IconButton>\n <Dialog.Root open={isDialogOpen} onOpenChange={setIsDialogOpen}>\n <Dialog.Content>\n <Dialog.Header>\n {formatMessage({\n id: getTranslationKey('asset-details.replace.title'),\n defaultMessage: 'Replace this media file?',\n })}\n </Dialog.Header>\n <Dialog.Body textAlign=\"center\">\n <Flex direction=\"column\" textAlign=\"center\">\n <Typography variant=\"omega\">\n {formatMessage({\n id: getTranslationKey('asset-details.replace.description'),\n defaultMessage: 'Current content will be permanently replaced.',\n })}\n </Typography>\n {aiEnabled ? (\n <Typography variant=\"omega\">\n {formatMessage({\n id: getTranslationKey('asset-details.replace.description.ai'),\n defaultMessage: 'AI will generate new metadata after upload.',\n })}\n </Typography>\n ) : null}\n </Flex>\n </Dialog.Body>\n <Dialog.Footer>\n <Dialog.Cancel>\n <Button variant=\"tertiary\" fullWidth>\n {formatMessage({ id: 'app.components.Button.cancel', defaultMessage: 'Cancel' })}\n </Button>\n </Dialog.Cancel>\n <Dialog.Action>\n <Button variant=\"secondary\" onClick={handleContinue} fullWidth>\n {formatMessage({\n id: getTranslationKey('asset-details.replace.continue'),\n defaultMessage: 'Continue',\n })}\n </Button>\n </Dialog.Action>\n </Dialog.Footer>\n </Dialog.Content>\n </Dialog.Root>\n </>\n );\n};\n\n/* -------------------------------------------------------------------------------------------------\n * AssetImageActions - crop and replace buttons overlaid on the image preview.\n * -----------------------------------------------------------------------------------------------*/\n\ninterface AssetImageActionsProps {\n onCrop?: () => void;\n}\n\nconst AssetImageActions = ({ onCrop }: AssetImageActionsProps) => {\n const { formatMessage } = useIntl();\n const isSubmitting = useForm('AssetImageActions', (state) => state.isSubmitting);\n\n return (\n <Flex direction=\"column\" gap={2}>\n <IconButton\n withTooltip={false}\n label={formatMessage({\n id: getTranslationKey('asset-details.crop.trigger'),\n defaultMessage: 'Crop',\n })}\n variant=\"tertiary\"\n onClick={onCrop}\n disabled={isSubmitting || !onCrop}\n >\n <Crop />\n </IconButton>\n <ReplaceAssetButton />\n </Flex>\n );\n};\n\n/* -------------------------------------------------------------------------------------------------\n * AssetDetails\n * -----------------------------------------------------------------------------------------------*/\n\ninterface AssetDetailsProps {\n asset: AssetWithPopulatedCreatedBy;\n closeDetails: () => void;\n}\n\ninterface AssetFormState {\n name: string;\n caption: string;\n alternativeText: string;\n folder: number | null;\n}\n\nexport const AssetDetails = ({ asset, closeDetails }: AssetDetailsProps) => {\n const { formatMessage, formatDate } = useIntl();\n const { canCreate, canUpdate, canDownload, canCopyLink } = useMediaLibraryPermissions();\n const { data: folders = [] } = useGetAllFoldersQuery();\n const { toggleNotification } = useNotification();\n const [updateAsset] = useUpdateAssetMutation();\n const [replaceMutation, { isLoading: isReplacing }] = useReplaceAssetMutation();\n const [deleteMutation, { isLoading: isDeleting }] = useDeleteAssetMutation();\n const [uploadCroppedCopy, { isLoading: isCropCopying }] = useUploadFileSilentlyMutation();\n\n const [isCropOpen, setIsCropOpen] = React.useState(false);\n\n // In-drawer toast slot\n const [drawerToast, setDrawerToast] = React.useState<DrawerToast | null>(null);\n React.useEffect(() => {\n if (!drawerToast) return;\n const timer = window.setTimeout(() => setDrawerToast(null), 5000);\n return () => window.clearTimeout(timer);\n }, [drawerToast]);\n\n // Local alias matching the DrawerNotifyContext signature, so the drawer's\n // own handlers (replace, update) read like the consumers do.\n const notify = React.useCallback<DrawerNotify>((toast) => setDrawerToast(toast), []);\n\n const isImage = asset.mime?.includes(ASSET_TYPES.Image);\n\n const initialValues: AssetFormState = {\n name: asset.name ?? '',\n caption: asset.caption ?? '',\n alternativeText: asset.alternativeText ?? '',\n folder:\n typeof asset.folder === 'object' && asset.folder !== null\n ? ((asset.folder as { id: number }).id ?? null)\n : ((asset.folder as number | null | undefined) ?? null),\n };\n\n const handleSubmit = async (values: AssetFormState) => {\n const fileInfo = {\n name: values.name,\n caption: values.caption,\n alternativeText: values.alternativeText,\n folder: values.folder,\n };\n\n const res = await updateAsset({ id: asset.id, fileInfo });\n\n if ('error' in res) {\n notify({\n type: 'danger',\n message: formatMessage({\n id: getTranslationKey('asset-details.update.error'),\n defaultMessage: 'Failed to update the file.',\n }),\n });\n return;\n }\n\n notify({\n type: 'success',\n message: formatMessage({\n id: getTranslationKey('asset-details.update.success'),\n defaultMessage: 'File updated',\n }),\n });\n };\n\n const { title: folderName } = useFolderInfo(\n typeof asset.folder === 'object' && asset.folder !== null\n ? ((asset.folder as { id: number }).id ?? null)\n : ((asset.folder as number | null | undefined) ?? null)\n );\n\n // Owns the replace upload so isReplacing can drive the busy overlay.\n const handleReplace = async (file: globalThis.File) => {\n const res = await replaceMutation({ id: asset.id, file });\n if ('error' in res) {\n const error = res.error as { data?: { error?: { message?: string }; message?: string } };\n const message =\n error?.data?.error?.message ??\n error?.data?.message ??\n formatMessage({\n id: getTranslationKey('asset-details.replace.error'),\n defaultMessage: 'Failed to replace the file.',\n });\n notify({ type: 'danger', message });\n return;\n }\n notify({\n type: 'success',\n message: formatMessage({\n id: getTranslationKey('asset-details.replace.success'),\n defaultMessage: 'File replaced.',\n }),\n });\n };\n\n // Owns the delete: on error notify in-drawer (drawer stays), on success fire\n // a persistent global notification then close the drawer.\n const handleDelete = async () => {\n const res = await deleteMutation(asset.id);\n if ('error' in res) {\n const error = res.error as { data?: { error?: { message?: string }; message?: string } };\n const message =\n error?.data?.error?.message ??\n error?.data?.message ??\n formatMessage({\n id: getTranslationKey('asset-details.delete.error'),\n defaultMessage: 'Failed to delete the asset.',\n });\n notify({ type: 'danger', message });\n return;\n }\n toggleNotification({\n type: 'success',\n message: formatMessage(\n {\n id: getTranslationKey('asset-details.delete.success'),\n defaultMessage: '1 element have been deleted from {folderName}',\n },\n { folderName }\n ),\n });\n closeDetails();\n };\n\n const notifyCropError = () => {\n notify({\n type: 'danger',\n message: formatMessage({\n id: getTranslationKey('asset-details.crop.error'),\n defaultMessage: 'Failed to crop the file.',\n }),\n });\n };\n\n // Apply: replace the original binary with the cropped file + focal point.\n // Close the editor first so the drawer's busy overlay is visible while the\n // mutation runs (the editor renders in a Portal above the drawer).\n const handleCropApply = async (file: globalThis.File, focalPoint: FocalPoint) => {\n setIsCropOpen(false);\n const res = await replaceMutation({\n id: asset.id,\n file,\n fileInfo: { focalPoint },\n });\n if ('error' in res) {\n notifyCropError();\n return;\n }\n notify({\n type: 'success',\n message: formatMessage({\n id: getTranslationKey('asset-details.crop.success'),\n defaultMessage: 'File cropped.',\n }),\n });\n };\n\n // Save as copy: upload the cropped file as a new asset in the same folder.\n const handleCropSaveAsCopy = async (file: globalThis.File, focalPoint: FocalPoint) => {\n setIsCropOpen(false);\n // Silent single-file upload (no global progress dialog). Carry over the\n // source asset's caption/alt so the copy keeps its metadata.\n const res = await uploadCroppedCopy({\n file,\n fileInfo: {\n name: asset.name,\n caption: asset.caption ?? '',\n alternativeText: asset.alternativeText ?? '',\n folder: initialValues.folder,\n focalPoint,\n },\n });\n if ('error' in res) {\n notifyCropError();\n return;\n }\n notify({\n type: 'success',\n message: formatMessage({\n id: getTranslationKey('asset-details.crop.copy-success'),\n defaultMessage: 'Copy created.',\n }),\n });\n };\n\n const operations = React.useMemo<AssetOperations>(\n () => ({\n replaceAsset: handleReplace,\n deleteAsset: handleDelete,\n isReplacing,\n isDeleting,\n }),\n // handleReplace / handleDelete close over asset+mutations and don't need a\n // stable identity here; the consumers re-render with the new context value.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [isReplacing, isDeleting]\n );\n\n return (\n // `key={asset.id}` resets the form when the drawer switches to a different\n // asset so cached values from the previous asset don't bleed in.\n <DrawerNotifyContext.Provider value={notify}>\n <AssetOperationsContext.Provider value={operations}>\n <FormShell>\n <Form key={asset.id} method=\"POST\" initialValues={initialValues} onSubmit={handleSubmit}>\n {({ modified, isSubmitting, values, resetForm }) => {\n const nameIsEmpty = ((values as AssetFormState).name ?? '').trim() === '';\n const busyMessage = getBusyMessage({ isDeleting, isReplacing, isCropCopying });\n return (\n <>\n {/* Guards every close path (X button, ESC, route change, browser\n back) by intercepting the navigation when the form is dirty.\n `onProceed` resets the form so the held navigation can complete.\n Lives inside <Form> so it can read the form context. */}\n <Blocker onProceed={resetForm} />\n {isCropOpen && isImage ? (\n <AssetCropEditor\n asset={asset}\n onClose={() => setIsCropOpen(false)}\n onApply={handleCropApply}\n onSaveAsCopy={handleCropSaveAsCopy}\n canSaveAsCopy={canCreate}\n />\n ) : null}\n {busyMessage ? (\n <DrawerBusyOverlay>\n <Loader>{formatMessage(busyMessage)}</Loader>\n </DrawerBusyOverlay>\n ) : null}\n {drawerToast ? (\n <DrawerToastSlot>\n <Alert\n variant={drawerToast.type === 'success' ? 'success' : 'danger'}\n closeLabel={formatMessage({ id: 'global.close', defaultMessage: 'Close' })}\n onClose={() => setDrawerToast(null)}\n >\n {drawerToast.message}\n </Alert>\n </DrawerToastSlot>\n ) : null}\n <Drawer.ScrollableContent>\n <AssetPreview\n asset={asset}\n actions={\n isImage && canUpdate ? (\n <AssetImageActions onCrop={() => setIsCropOpen(true)} />\n ) : null\n }\n />\n <Flex\n direction=\"column\"\n alignItems=\"stretch\"\n gap={4}\n paddingTop={4}\n paddingBottom={4}\n paddingLeft={5}\n paddingRight={5}\n >\n <Typography variant=\"beta\" fontWeight=\"semiBold\" tag=\"h3\">\n {formatMessage({\n id: getTranslationKey('asset-details.fileInfo'),\n defaultMessage: 'File info',\n })}\n </Typography>\n <Flex\n wrap=\"wrap\"\n gap={4}\n background=\"neutral100\"\n paddingTop={4}\n paddingBottom={4}\n paddingLeft={6}\n paddingRight={6}\n alignItems=\"flex-start\"\n >\n <DetailItem\n label={formatMessage({\n id: getTranslationKey('asset-details.creationDate'),\n defaultMessage: 'Creation date',\n })}\n value={\n asset.createdAt\n ? formatDate(new Date(asset.createdAt), {\n dateStyle: 'long',\n timeStyle: 'short',\n })\n : null\n }\n />\n <DetailItem\n label={formatMessage({\n id: getTranslationKey('asset-details.lastUpdated'),\n defaultMessage: 'Last updated',\n })}\n value={\n asset.updatedAt\n ? formatDate(new Date(asset.updatedAt), {\n dateStyle: 'long',\n timeStyle: 'short',\n })\n : null\n }\n />\n <DetailItem\n label={formatMessage({\n id: getTranslationKey('asset-details.createdBy'),\n defaultMessage: 'Created by',\n })}\n value={\n asset.createdBy\n ? (getDisplayName({\n firstname: asset.createdBy.firstname ?? undefined,\n lastname: asset.createdBy.lastname ?? undefined,\n username: asset.createdBy.username ?? undefined,\n email: asset.createdBy.email ?? undefined,\n }) ?? '-')\n : null\n }\n />\n <DetailItem\n label={formatMessage({\n id: getTranslationKey('asset-details.size'),\n defaultMessage: 'Size',\n })}\n value={asset.size ? formatBytes(asset.size, 1) : null}\n />\n {isImage && (asset.width != null || asset.height != null) && (\n <DetailItem\n label={formatMessage({\n id: getTranslationKey('asset-details.dimensions'),\n defaultMessage: 'Dimensions',\n })}\n value={\n asset.width != null && asset.height != null\n ? `${asset.width} × ${asset.height}`\n : null\n }\n />\n )}\n <DetailItem\n label={formatMessage({\n id: getTranslationKey('asset-details.extension'),\n defaultMessage: 'Extension',\n })}\n value={getFileExtension(asset.ext)}\n />\n <DetailItem\n label={formatMessage({\n id: getTranslationKey('asset-details.assetId'),\n defaultMessage: 'Asset ID',\n })}\n value={String(asset.id)}\n />\n </Flex>\n <DetailField\n name=\"name\"\n label={formatMessage({\n id: getTranslationKey('asset-details.fileName'),\n defaultMessage: 'File name',\n })}\n required\n disabled={!canUpdate}\n />\n <LocationField\n label={formatMessage({\n id: getTranslationKey('asset-details.location'),\n defaultMessage: 'Location',\n })}\n rootLabel={formatMessage({\n id: getTranslationKey('plugin.home'),\n defaultMessage: 'Home',\n })}\n folders={folders}\n disabled={!canUpdate}\n />\n {isImage && (\n <>\n <DetailField\n name=\"caption\"\n label={formatMessage({\n id: getTranslationKey('asset-details.caption'),\n defaultMessage: 'Caption',\n })}\n disabled={!canUpdate}\n />\n <DetailField\n name=\"alternativeText\"\n label={formatMessage({\n id: getTranslationKey('asset-details.alternativeText'),\n defaultMessage: 'Alternative text',\n })}\n disabled={!canUpdate}\n />\n </>\n )}\n </Flex>\n </Drawer.ScrollableContent>\n {/* Every footer action is permission-gated — when none survive,\n drop the whole bar instead of showing an empty strip. */}\n {(canUpdate || canCopyLink || canDownload) && (\n <Flex\n justifyContent=\"space-between\"\n alignItems=\"center\"\n gap={2}\n padding={3}\n borderColor=\"neutral150\"\n borderStyle=\"solid\"\n borderWidth=\"1px 0 0 0\"\n background=\"neutral0\"\n >\n <Flex gap={2}>\n {canUpdate && <DeleteAssetButton />}\n {canCopyLink && <CopyLinkButton asset={asset} />}\n {canDownload && <DownloadAssetButton asset={asset} />}\n </Flex>\n {canUpdate && (\n <Button\n type=\"submit\"\n variant=\"default\"\n loading={isSubmitting}\n // File name is required; block submit when it's empty or whitespace so the API can't 400 on a blank value.\n disabled={!modified || isSubmitting || nameIsEmpty}\n >\n {formatMessage({\n id: getTranslationKey('asset-details.save'),\n defaultMessage: 'Save changes',\n })}\n </Button>\n )}\n </Flex>\n )}\n </>\n );\n }}\n </Form>\n </FormShell>\n </AssetOperationsContext.Provider>\n </DrawerNotifyContext.Provider>\n );\n};\n\n/* -------------------------------------------------------------------------------------------------\n * DrawerHeader\n * -----------------------------------------------------------------------------------------------*/\n\ninterface DrawerHeaderProps {\n asset: AssetWithPopulatedCreatedBy;\n closeDetails: () => void;\n}\n\nconst DrawerHeader = ({ asset, closeDetails }: DrawerHeaderProps) => {\n const DocIcon = asset ? getAssetIcon(asset.mime, asset.ext) : FileError;\n return (\n <Flex\n gap={2}\n paddingLeft={5}\n paddingTop={3}\n paddingBottom={3}\n paddingRight={3}\n borderColor=\"neutral150\"\n borderStyle=\"solid\"\n borderWidth=\"0 0 1px 0\"\n >\n <DocIcon width={20} height={20} />\n <Drawer.Title asChild>\n <Typography variant=\"omega\" fontWeight=\"semiBold\" overflow=\"hidden\" ellipsis tag=\"h2\">\n {asset.name}\n </Typography>\n </Drawer.Title>\n <Box marginLeft=\"auto\">\n <Drawer.CloseButton onClose={closeDetails}>\n <ArrowLineRight />\n </Drawer.CloseButton>\n </Box>\n </Flex>\n );\n};\n\n/* -------------------------------------------------------------------------------------------------\n * DrawerContent\n * -----------------------------------------------------------------------------------------------*/\n\ninterface DrawerContentProps {\n assetId: number;\n closeDetails: () => void;\n}\n\nconst DrawerContent = ({ assetId, closeDetails }: DrawerContentProps) => {\n const { formatMessage } = useIntl();\n const {\n data: asset,\n isLoading,\n error,\n } = useGetAssetQuery(assetId, {\n refetchOnMountOrArgChange: false,\n refetchOnReconnect: false,\n refetchOnFocus: false,\n });\n\n if (isLoading) {\n return (\n <Flex justifyContent=\"center\" padding={8}>\n <Loader>{formatMessage({ id: 'app.loading', defaultMessage: 'Loading...' })}</Loader>\n </Flex>\n );\n }\n\n if (error || !asset) {\n return (\n <Flex direction=\"column\" alignItems=\"stretch\" gap={4} padding={4}>\n <Alert\n variant=\"danger\"\n closeLabel={formatMessage({ id: 'global.close', defaultMessage: 'Close' })}\n onClose={closeDetails}\n >\n {formatMessage({\n id: getTranslationKey('asset-details.error'),\n defaultMessage: 'Failed to load file details.',\n })}\n </Alert>\n </Flex>\n );\n }\n\n return (\n <>\n <DrawerHeader asset={asset} closeDetails={closeDetails} />\n <AssetDetails asset={asset} closeDetails={closeDetails} />\n </>\n );\n};\n\n/* -------------------------------------------------------------------------------------------------\n * AssetDetailsDrawer\n * -----------------------------------------------------------------------------------------------*/\n\nexport const AssetDetailsDrawer = () => {\n const { formatMessage } = useIntl();\n const { assetId, isVisible, shouldRenderDrawer, onCloseAnimationEnd, closeDetails } =\n useAssetDetailsParam();\n\n if (!shouldRenderDrawer || assetId === null) {\n return null;\n }\n\n return (\n <Drawer.Root isVisible={isVisible} onClose={closeDetails}>\n {/* Wrapper div required: Dialog.Portal uses asChild and merges ref onto each child.\n VisuallyHidden does not forward refs, so we wrap it in a div that can receive the ref. */}\n <div>\n <VisuallyHidden>\n <Drawer.Title>\n {formatMessage({\n id: getTranslationKey('asset-details.title'),\n defaultMessage: 'File details',\n })}\n </Drawer.Title>\n <Drawer.Description>\n {formatMessage({\n id: getTranslationKey('asset-details.description'),\n defaultMessage: 'Displays file information and metadata',\n })}\n </Drawer.Description>\n </VisuallyHidden>\n </div>\n <Drawer.Body\n animationDirection=\"left\"\n width=\"41.6rem\"\n // dvh, not vh: the drawer is anchored to the bottom, so with 100vh on\n // mobile (where the URL bar shrinks the visual viewport below 100vh)\n // the top of the drawer — header, title, close button — is pushed\n // off-screen. dvh tracks the actual visible height.\n height=\"100dvh\"\n onAnimationEnd={onCloseAnimationEnd}\n >\n <DrawerContent assetId={assetId} closeDetails={closeDetails} />\n </Drawer.Body>\n </Drawer.Root>\n );\n};\n"],"names":["URL_PARAM","DrawerNotifyContext","React","createContext","useDrawerNotify","ctx","useContext","Error","AssetOperationsContext","useAssetOperation","useAssetDetailsParam","query","setQuery","useQueryParams","detailsId","assetId","parseInt","hasValidId","Number","isNaN","isMounted","setIsMounted","useState","displayAssetId","useRef","useEffect","current","onCloseAnimationEnd","useCallback","event","target","currentTarget","openDetails","id","String","closeDetails","undefined","isVisible","shouldRenderDrawer","DetailItemContainer","styled","Flex","theme","spaces","DetailItem","label","value","_jsxs","direction","justifyContent","alignItems","gap","_jsx","Typography","variant","textColor","fontWeight","textTransform","FormShell","Box","DrawerToastSlot","DrawerBusyOverlay","colors","neutral0","getBusyMessage","state","isDeleting","getTranslationKey","defaultMessage","isCropCopying","isReplacing","StyledWarning","WarningCircle","warning500","DetailField","name","required","disabled","formatMessage","useIntl","field","useField","isSubmitting","useForm","fieldValue","setValue","emptyTooltipLabel","Field","Root","Label","TextInput","onChange","endAction","Tooltip","aria-label","role","type","LocationField","rootLabel","folders","SingleSelect","next","SingleSelectOption","map","folder","DeleteAssetButton","deleteAsset","isOpen","setIsOpen","handleConfirm","triggerLabel","Dialog","open","onOpenChange","Trigger","IconButton","withTooltip","Trash","Content","Header","Body","icon","width","height","fill","textAlign","Footer","Cancel","Button","fullWidth","Action","loading","onClick","CopyLinkButton","asset","copy","useClipboard","notify","handleCopy","url","prefixFileUrlWithBackendUrl","didCopy","message","Link","DownloadAssetButton","isDownloading","setIsDownloading","handleDownload","downloadFile","Download","ReplaceAssetButton","replaceAsset","fileInputRef","isDialogOpen","setIsDialogOpen","data","settings","useGetUploadSettingsQuery","aiEnabled","aiMetadata","handleTriggerClick","handleContinue","click","handleFileChange","file","files","_Fragment","VisuallyHidden","input","ref","multiple","aria-hidden","tabIndex","ArrowsCounterClockwise","AssetImageActions","onCrop","Crop","AssetDetails","formatDate","canCreate","canUpdate","canDownload","canCopyLink","useMediaLibraryPermissions","useGetAllFoldersQuery","toggleNotification","useNotification","updateAsset","useUpdateAssetMutation","replaceMutation","isLoading","useReplaceAssetMutation","deleteMutation","useDeleteAssetMutation","uploadCroppedCopy","useUploadFileSilentlyMutation","isCropOpen","setIsCropOpen","drawerToast","setDrawerToast","timer","window","setTimeout","clearTimeout","toast","isImage","mime","includes","ASSET_TYPES","Image","initialValues","caption","alternativeText","handleSubmit","values","fileInfo","res","title","folderName","useFolderInfo","handleReplace","error","handleDelete","notifyCropError","handleCropApply","focalPoint","handleCropSaveAsCopy","operations","useMemo","Provider","Form","method","onSubmit","modified","resetForm","nameIsEmpty","trim","busyMessage","Blocker","onProceed","AssetCropEditor","onClose","onApply","onSaveAsCopy","canSaveAsCopy","Loader","Alert","closeLabel","Drawer","ScrollableContent","AssetPreview","actions","paddingTop","paddingBottom","paddingLeft","paddingRight","tag","wrap","background","createdAt","Date","dateStyle","timeStyle","updatedAt","createdBy","getDisplayName","firstname","lastname","username","email","size","formatBytes","getFileExtension","ext","padding","borderColor","borderStyle","borderWidth","DrawerHeader","DocIcon","getAssetIcon","FileError","Title","asChild","overflow","ellipsis","marginLeft","CloseButton","ArrowLineRight","DrawerContent","useGetAssetQuery","refetchOnMountOrArgChange","refetchOnReconnect","refetchOnFocus","AssetDetailsDrawer","div","Description","animationDirection","onAnimationEnd"],"mappings":"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"}
|
|
@@ -7,10 +7,11 @@ import { useIntl } from 'react-intl';
|
|
|
7
7
|
import { styled } from 'styled-components';
|
|
8
8
|
import { ASSET_TYPES } from '../../../../../enums.mjs';
|
|
9
9
|
import { Drawer } from '../../../../components/Drawer.mjs';
|
|
10
|
+
import { useMediaLibraryPermissions } from '../../../../hooks/useMediaLibraryPermissions.mjs';
|
|
10
11
|
import { useUploadFileSilentlyMutation } from '../../../../services/api.mjs';
|
|
11
12
|
import { useGetAssetQuery, useUpdateAssetMutation, useReplaceAssetMutation, useDeleteAssetMutation } from '../../../../services/assets.mjs';
|
|
12
13
|
import { useGetAllFoldersQuery } from '../../../../services/folders.mjs';
|
|
13
|
-
import {
|
|
14
|
+
import { useGetUploadSettingsQuery } from '../../../../services/settings.mjs';
|
|
14
15
|
import { downloadFile } from '../../../../utils/downloadFile.mjs';
|
|
15
16
|
import { formatBytes, getFileExtension, prefixFileUrlWithBackendUrl } from '../../../../utils/files.mjs';
|
|
16
17
|
import { getAssetIcon } from '../../../../utils/getAssetIcon.mjs';
|
|
@@ -191,11 +192,24 @@ const StyledWarning = styled(WarningCircle)`
|
|
|
191
192
|
fill: ${({ theme })=>theme.colors.warning500};
|
|
192
193
|
}
|
|
193
194
|
`;
|
|
194
|
-
const DetailField = ({ name, label, required })=>{
|
|
195
|
+
const DetailField = ({ name, label, required, disabled })=>{
|
|
195
196
|
const { formatMessage } = useIntl();
|
|
196
197
|
const field = useField(name);
|
|
197
198
|
const isSubmitting = useForm('DetailField', (state)=>state.isSubmitting);
|
|
198
|
-
|
|
199
|
+
// The form context (use-context-selector) echoes changes back
|
|
200
|
+
// asynchronously — driving the input straight from `field.value` makes
|
|
201
|
+
// React rewrite the DOM value after the keystroke, which throws the cursor
|
|
202
|
+
// to the end of the field. The input is therefore controlled by local state
|
|
203
|
+
// (synchronous, cursor-safe) and the form follows; the effect below only
|
|
204
|
+
// matters for EXTERNAL value changes (discard/reset), where a cursor jump
|
|
205
|
+
// is fine because the user isn't typing.
|
|
206
|
+
const fieldValue = field.value ?? '';
|
|
207
|
+
const [value, setValue] = React.useState(fieldValue);
|
|
208
|
+
React.useEffect(()=>{
|
|
209
|
+
setValue(fieldValue);
|
|
210
|
+
}, [
|
|
211
|
+
fieldValue
|
|
212
|
+
]);
|
|
199
213
|
const emptyTooltipLabel = formatMessage({
|
|
200
214
|
id: getTranslationKey('asset-details.field.empty'),
|
|
201
215
|
defaultMessage: '{label} is currently empty.'
|
|
@@ -211,7 +225,10 @@ const DetailField = ({ name, label, required })=>{
|
|
|
211
225
|
}),
|
|
212
226
|
/*#__PURE__*/ jsx(TextInput, {
|
|
213
227
|
value: value,
|
|
214
|
-
onChange: (event)=>
|
|
228
|
+
onChange: (event)=>{
|
|
229
|
+
setValue(event.target.value);
|
|
230
|
+
field.onChange(name, event.target.value);
|
|
231
|
+
},
|
|
215
232
|
endAction: !value ? /*#__PURE__*/ jsx(Tooltip, {
|
|
216
233
|
label: emptyTooltipLabel,
|
|
217
234
|
children: /*#__PURE__*/ jsx(StyledWarning, {
|
|
@@ -220,12 +237,12 @@ const DetailField = ({ name, label, required })=>{
|
|
|
220
237
|
})
|
|
221
238
|
}) : undefined,
|
|
222
239
|
type: "text",
|
|
223
|
-
disabled: isSubmitting
|
|
240
|
+
disabled: isSubmitting || disabled
|
|
224
241
|
})
|
|
225
242
|
]
|
|
226
243
|
});
|
|
227
244
|
};
|
|
228
|
-
const LocationField = ({ label, rootLabel, folders })=>{
|
|
245
|
+
const LocationField = ({ label, rootLabel, folders, disabled })=>{
|
|
229
246
|
const field = useField('folder');
|
|
230
247
|
const isSubmitting = useForm('LocationField', (state)=>state.isSubmitting);
|
|
231
248
|
return /*#__PURE__*/ jsxs(Field.Root, {
|
|
@@ -241,7 +258,7 @@ const LocationField = ({ label, rootLabel, folders })=>{
|
|
|
241
258
|
const next = value === '' ? null : Number(value);
|
|
242
259
|
field.onChange('folder', next);
|
|
243
260
|
},
|
|
244
|
-
disabled: isSubmitting,
|
|
261
|
+
disabled: isSubmitting || disabled,
|
|
245
262
|
children: [
|
|
246
263
|
/*#__PURE__*/ jsx(SingleSelectOption, {
|
|
247
264
|
value: "",
|
|
@@ -405,7 +422,7 @@ const DownloadAssetButton = ({ asset })=>{
|
|
|
405
422
|
const { replaceAsset, isReplacing } = useAssetOperation();
|
|
406
423
|
const fileInputRef = React.useRef(null);
|
|
407
424
|
const [isDialogOpen, setIsDialogOpen] = React.useState(false);
|
|
408
|
-
const { data: settings } =
|
|
425
|
+
const { data: settings } = useGetUploadSettingsQuery();
|
|
409
426
|
const aiEnabled = settings?.data?.aiMetadata ?? false;
|
|
410
427
|
const handleTriggerClick = ()=>{
|
|
411
428
|
setIsDialogOpen(true);
|
|
@@ -538,6 +555,7 @@ const AssetImageActions = ({ onCrop })=>{
|
|
|
538
555
|
};
|
|
539
556
|
const AssetDetails = ({ asset, closeDetails })=>{
|
|
540
557
|
const { formatMessage, formatDate } = useIntl();
|
|
558
|
+
const { canCreate, canUpdate, canDownload, canCopyLink } = useMediaLibraryPermissions();
|
|
541
559
|
const { data: folders = [] } = useGetAllFoldersQuery();
|
|
542
560
|
const { toggleNotification } = useNotification();
|
|
543
561
|
const [updateAsset] = useUpdateAssetMutation();
|
|
@@ -746,7 +764,8 @@ const AssetDetails = ({ asset, closeDetails })=>{
|
|
|
746
764
|
asset: asset,
|
|
747
765
|
onClose: ()=>setIsCropOpen(false),
|
|
748
766
|
onApply: handleCropApply,
|
|
749
|
-
onSaveAsCopy: handleCropSaveAsCopy
|
|
767
|
+
onSaveAsCopy: handleCropSaveAsCopy,
|
|
768
|
+
canSaveAsCopy: canCreate
|
|
750
769
|
}) : null,
|
|
751
770
|
busyMessage ? /*#__PURE__*/ jsx(DrawerBusyOverlay, {
|
|
752
771
|
children: /*#__PURE__*/ jsx(Loader, {
|
|
@@ -768,7 +787,7 @@ const AssetDetails = ({ asset, closeDetails })=>{
|
|
|
768
787
|
children: [
|
|
769
788
|
/*#__PURE__*/ jsx(AssetPreview, {
|
|
770
789
|
asset: asset,
|
|
771
|
-
actions: isImage ? /*#__PURE__*/ jsx(AssetImageActions, {
|
|
790
|
+
actions: isImage && canUpdate ? /*#__PURE__*/ jsx(AssetImageActions, {
|
|
772
791
|
onCrop: ()=>setIsCropOpen(true)
|
|
773
792
|
}) : null
|
|
774
793
|
}),
|
|
@@ -868,7 +887,8 @@ const AssetDetails = ({ asset, closeDetails })=>{
|
|
|
868
887
|
id: getTranslationKey('asset-details.fileName'),
|
|
869
888
|
defaultMessage: 'File name'
|
|
870
889
|
}),
|
|
871
|
-
required: true
|
|
890
|
+
required: true,
|
|
891
|
+
disabled: !canUpdate
|
|
872
892
|
}),
|
|
873
893
|
/*#__PURE__*/ jsx(LocationField, {
|
|
874
894
|
label: formatMessage({
|
|
@@ -879,7 +899,8 @@ const AssetDetails = ({ asset, closeDetails })=>{
|
|
|
879
899
|
id: getTranslationKey('plugin.home'),
|
|
880
900
|
defaultMessage: 'Home'
|
|
881
901
|
}),
|
|
882
|
-
folders: folders
|
|
902
|
+
folders: folders,
|
|
903
|
+
disabled: !canUpdate
|
|
883
904
|
}),
|
|
884
905
|
isImage && /*#__PURE__*/ jsxs(Fragment, {
|
|
885
906
|
children: [
|
|
@@ -888,14 +909,16 @@ const AssetDetails = ({ asset, closeDetails })=>{
|
|
|
888
909
|
label: formatMessage({
|
|
889
910
|
id: getTranslationKey('asset-details.caption'),
|
|
890
911
|
defaultMessage: 'Caption'
|
|
891
|
-
})
|
|
912
|
+
}),
|
|
913
|
+
disabled: !canUpdate
|
|
892
914
|
}),
|
|
893
915
|
/*#__PURE__*/ jsx(DetailField, {
|
|
894
916
|
name: "alternativeText",
|
|
895
917
|
label: formatMessage({
|
|
896
918
|
id: getTranslationKey('asset-details.alternativeText'),
|
|
897
919
|
defaultMessage: 'Alternative text'
|
|
898
|
-
})
|
|
920
|
+
}),
|
|
921
|
+
disabled: !canUpdate
|
|
899
922
|
})
|
|
900
923
|
]
|
|
901
924
|
})
|
|
@@ -903,7 +926,7 @@ const AssetDetails = ({ asset, closeDetails })=>{
|
|
|
903
926
|
})
|
|
904
927
|
]
|
|
905
928
|
}),
|
|
906
|
-
/*#__PURE__*/ jsxs(Flex, {
|
|
929
|
+
(canUpdate || canCopyLink || canDownload) && /*#__PURE__*/ jsxs(Flex, {
|
|
907
930
|
justifyContent: "space-between",
|
|
908
931
|
alignItems: "center",
|
|
909
932
|
gap: 2,
|
|
@@ -916,16 +939,16 @@ const AssetDetails = ({ asset, closeDetails })=>{
|
|
|
916
939
|
/*#__PURE__*/ jsxs(Flex, {
|
|
917
940
|
gap: 2,
|
|
918
941
|
children: [
|
|
919
|
-
/*#__PURE__*/ jsx(DeleteAssetButton, {}),
|
|
920
|
-
/*#__PURE__*/ jsx(CopyLinkButton, {
|
|
942
|
+
canUpdate && /*#__PURE__*/ jsx(DeleteAssetButton, {}),
|
|
943
|
+
canCopyLink && /*#__PURE__*/ jsx(CopyLinkButton, {
|
|
921
944
|
asset: asset
|
|
922
945
|
}),
|
|
923
|
-
/*#__PURE__*/ jsx(DownloadAssetButton, {
|
|
946
|
+
canDownload && /*#__PURE__*/ jsx(DownloadAssetButton, {
|
|
924
947
|
asset: asset
|
|
925
948
|
})
|
|
926
949
|
]
|
|
927
950
|
}),
|
|
928
|
-
/*#__PURE__*/ jsx(Button, {
|
|
951
|
+
canUpdate && /*#__PURE__*/ jsx(Button, {
|
|
929
952
|
type: "submit",
|
|
930
953
|
variant: "default",
|
|
931
954
|
loading: isSubmitting,
|
|
@@ -1068,7 +1091,11 @@ const DrawerContent = ({ assetId, closeDetails })=>{
|
|
|
1068
1091
|
/*#__PURE__*/ jsx(Drawer.Body, {
|
|
1069
1092
|
animationDirection: "left",
|
|
1070
1093
|
width: "41.6rem",
|
|
1071
|
-
|
|
1094
|
+
// dvh, not vh: the drawer is anchored to the bottom, so with 100vh on
|
|
1095
|
+
// mobile (where the URL bar shrinks the visual viewport below 100vh)
|
|
1096
|
+
// the top of the drawer — header, title, close button — is pushed
|
|
1097
|
+
// off-screen. dvh tracks the actual visible height.
|
|
1098
|
+
height: "100dvh",
|
|
1072
1099
|
onAnimationEnd: onCloseAnimationEnd,
|
|
1073
1100
|
children: /*#__PURE__*/ jsx(DrawerContent, {
|
|
1074
1101
|
assetId: assetId,
|