@strapi/upload 5.52.0 → 5.52.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/admin/future/components/TruncatedText.js +76 -0
- package/dist/admin/future/components/TruncatedText.js.map +1 -0
- package/dist/admin/future/components/TruncatedText.mjs +74 -0
- package/dist/admin/future/components/TruncatedText.mjs.map +1 -0
- package/dist/admin/future/hooks/useTracking.js +57 -0
- package/dist/admin/future/hooks/useTracking.js.map +1 -0
- package/dist/admin/future/hooks/useTracking.mjs +53 -0
- package/dist/admin/future/hooks/useTracking.mjs.map +1 -0
- package/dist/admin/future/pages/Assets/AssetsPage.js +31 -0
- package/dist/admin/future/pages/Assets/AssetsPage.js.map +1 -1
- package/dist/admin/future/pages/Assets/AssetsPage.mjs +31 -0
- package/dist/admin/future/pages/Assets/AssetsPage.mjs.map +1 -1
- package/dist/admin/future/pages/Assets/components/AssetActionsMenu.js +9 -6
- package/dist/admin/future/pages/Assets/components/AssetActionsMenu.js.map +1 -1
- package/dist/admin/future/pages/Assets/components/AssetActionsMenu.mjs +9 -6
- package/dist/admin/future/pages/Assets/components/AssetActionsMenu.mjs.map +1 -1
- package/dist/admin/future/pages/Assets/components/AssetDetails/AssetDetailsDrawer.js +21 -1
- package/dist/admin/future/pages/Assets/components/AssetDetails/AssetDetailsDrawer.js.map +1 -1
- package/dist/admin/future/pages/Assets/components/AssetDetails/AssetDetailsDrawer.mjs +21 -1
- package/dist/admin/future/pages/Assets/components/AssetDetails/AssetDetailsDrawer.mjs.map +1 -1
- package/dist/admin/future/pages/Assets/components/AssetsGrid.js +3 -4
- package/dist/admin/future/pages/Assets/components/AssetsGrid.js.map +1 -1
- package/dist/admin/future/pages/Assets/components/AssetsGrid.mjs +4 -5
- package/dist/admin/future/pages/Assets/components/AssetsGrid.mjs.map +1 -1
- package/dist/admin/future/pages/Assets/components/AssetsSearchInput.js +11 -1
- package/dist/admin/future/pages/Assets/components/AssetsSearchInput.js.map +1 -1
- package/dist/admin/future/pages/Assets/components/AssetsSearchInput.mjs +11 -1
- package/dist/admin/future/pages/Assets/components/AssetsSearchInput.mjs.map +1 -1
- package/dist/admin/future/pages/Assets/components/AssetsTable.js +6 -4
- package/dist/admin/future/pages/Assets/components/AssetsTable.js.map +1 -1
- package/dist/admin/future/pages/Assets/components/AssetsTable.mjs +6 -4
- package/dist/admin/future/pages/Assets/components/AssetsTable.mjs.map +1 -1
- package/dist/admin/future/pages/Assets/components/FilterMenu.js +18 -2
- package/dist/admin/future/pages/Assets/components/FilterMenu.js.map +1 -1
- package/dist/admin/future/pages/Assets/components/FilterMenu.mjs +18 -2
- package/dist/admin/future/pages/Assets/components/FilterMenu.mjs.map +1 -1
- package/dist/admin/future/pages/Assets/components/FolderActionsMenu.js +9 -7
- package/dist/admin/future/pages/Assets/components/FolderActionsMenu.js.map +1 -1
- package/dist/admin/future/pages/Assets/components/FolderActionsMenu.mjs +9 -7
- package/dist/admin/future/pages/Assets/components/FolderActionsMenu.mjs.map +1 -1
- package/dist/admin/future/pages/Assets/components/FolderFormDialog.js +12 -0
- package/dist/admin/future/pages/Assets/components/FolderFormDialog.js.map +1 -1
- package/dist/admin/future/pages/Assets/components/FolderFormDialog.mjs +12 -0
- package/dist/admin/future/pages/Assets/components/FolderFormDialog.mjs.map +1 -1
- package/dist/admin/future/pages/Assets/components/FolderTree/FolderTree.js +21 -38
- package/dist/admin/future/pages/Assets/components/FolderTree/FolderTree.js.map +1 -1
- package/dist/admin/future/pages/Assets/components/FolderTree/FolderTree.mjs +23 -40
- package/dist/admin/future/pages/Assets/components/FolderTree/FolderTree.mjs.map +1 -1
- package/dist/admin/future/pages/Assets/components/SortMenu.js +14 -0
- package/dist/admin/future/pages/Assets/components/SortMenu.js.map +1 -1
- package/dist/admin/future/pages/Assets/components/SortMenu.mjs +14 -0
- package/dist/admin/future/pages/Assets/components/SortMenu.mjs.map +1 -1
- package/dist/admin/future/pages/Assets/hooks/useAssetSelection.js +5 -0
- package/dist/admin/future/pages/Assets/hooks/useAssetSelection.js.map +1 -1
- package/dist/admin/future/pages/Assets/hooks/useAssetSelection.mjs +6 -1
- package/dist/admin/future/pages/Assets/hooks/useAssetSelection.mjs.map +1 -1
- package/dist/admin/future/pages/Assets/utils/selection.js +17 -0
- package/dist/admin/future/pages/Assets/utils/selection.js.map +1 -1
- package/dist/admin/future/pages/Assets/utils/selection.mjs +17 -1
- package/dist/admin/future/pages/Assets/utils/selection.mjs.map +1 -1
- package/dist/admin/future/services/api.js +7 -8
- package/dist/admin/future/services/api.js.map +1 -1
- package/dist/admin/future/services/api.mjs +7 -8
- package/dist/admin/future/services/api.mjs.map +1 -1
- package/dist/admin/future/services/assets.js +11 -23
- package/dist/admin/future/services/assets.js.map +1 -1
- package/dist/admin/future/services/assets.mjs +11 -23
- package/dist/admin/future/services/assets.mjs.map +1 -1
- package/dist/admin/hooks/useAIMetadataJob.js +1 -1
- package/dist/admin/hooks/useAIMetadataJob.js.map +1 -1
- package/dist/admin/hooks/useAIMetadataJob.mjs +1 -1
- package/dist/admin/hooks/useAIMetadataJob.mjs.map +1 -1
- package/dist/admin/pages/SettingsPage/SettingsPage.js +2 -2
- package/dist/admin/pages/SettingsPage/SettingsPage.js.map +1 -1
- package/dist/admin/pages/SettingsPage/SettingsPage.mjs +2 -2
- package/dist/admin/pages/SettingsPage/SettingsPage.mjs.map +1 -1
- package/dist/admin/src/future/components/TruncatedText.d.ts +32 -0
- package/dist/admin/src/future/hooks/useTracking.d.ts +29 -0
- package/dist/admin/src/future/pages/Assets/components/AssetActionsMenu.d.ts +5 -3
- package/dist/admin/src/future/pages/Assets/components/FolderActionsMenu.d.ts +5 -4
- package/dist/admin/src/future/pages/Assets/hooks/useAssetSelection.d.ts +2 -0
- package/dist/admin/src/future/pages/Assets/utils/selection.d.ts +10 -0
- package/dist/admin/src/future/services/api.d.ts +6 -7
- package/dist/server/controllers/admin-file.js +27 -9
- package/dist/server/controllers/admin-file.js.map +1 -1
- package/dist/server/controllers/admin-file.mjs +27 -9
- package/dist/server/controllers/admin-file.mjs.map +1 -1
- package/dist/server/controllers/admin-upload.js +24 -8
- package/dist/server/controllers/admin-upload.js.map +1 -1
- package/dist/server/controllers/admin-upload.mjs +24 -8
- package/dist/server/controllers/admin-upload.mjs.map +1 -1
- package/dist/server/routes/admin.js +41 -21
- package/dist/server/routes/admin.js.map +1 -1
- package/dist/server/routes/admin.mjs +41 -21
- package/dist/server/routes/admin.mjs.map +1 -1
- package/dist/server/services/ai-metadata.js.map +1 -1
- package/dist/server/services/ai-metadata.mjs.map +1 -1
- package/dist/server/src/controllers/admin-file.d.ts +29 -8
- package/dist/server/src/controllers/admin-file.d.ts.map +1 -1
- package/dist/server/src/controllers/admin-upload.d.ts +20 -4
- package/dist/server/src/controllers/admin-upload.d.ts.map +1 -1
- package/dist/server/src/controllers/index.d.ts +4 -4
- package/dist/server/src/index.d.ts +4 -4
- package/dist/server/src/routes/admin.d.ts.map +1 -1
- package/dist/server/src/services/ai-metadata.d.ts +2 -2
- package/dist/server/src/services/ai-metadata.d.ts.map +1 -1
- package/dist/shared/contracts/ai-metadata-jobs.d.ts +10 -32
- package/dist/shared/contracts/ai-metadata-jobs.d.ts.map +1 -1
- package/dist/shared/contracts/files.d.ts +10 -10
- package/dist/shared/contracts/files.d.ts.map +1 -1
- package/package.json +6 -6
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AssetActionsMenu.mjs","sources":["../../../../../../admin/src/future/pages/Assets/components/AssetActionsMenu.tsx"],"sourcesContent":["import { useMemo, useRef, useState } from 'react';\n\nimport { useClipboard, useNotification } from '@strapi/admin/strapi-admin';\nimport {\n Button,\n Dialog,\n Flex,\n IconButton,\n Menu,\n Typography,\n VisuallyHidden,\n} from '@strapi/design-system';\nimport { ArrowRight, ArrowsCounterClockwise, Download, Link, More, Trash } from '@strapi/icons';\nimport { useIntl } from 'react-intl';\n\nimport { useAIMetadataEnabled } from '../../../hooks/useAIMetadataEnabled';\nimport { useMediaLibraryPermissions } from '../../../hooks/useMediaLibraryPermissions';\nimport { useReplaceAssetMutation } from '../../../services/assets';\nimport { downloadFile } from '../../../utils/downloadFile';\nimport { prefixFileUrlWithBackendUrl } from '../../../utils/files';\nimport { getTranslationKey } from '../../../utils/translations';\nimport { useAssetSelection } from '../hooks/useAssetSelection';\nimport { useBusyAssetsOptional } from '../hooks/useBusyAssets';\n\nimport { ActionsMenuContent } from './ActionsMenuContent';\nimport { BulkMoveDialog } from './BulkMoveDialog';\nimport { DeleteItemsDialog } from './DeleteItemsDialog';\n\nimport type { File } from '../../../../../../shared/contracts/files';\nimport type { DragFileData } from '../../../types/dnd';\n\ninterface AssetActionsMenuProps {\n asset: File;\n /** Drag data for this asset, so the move dialog validates against its real folder. */\n dragData: DragFileData;\n}\n\n/**\n * The \"...\" menu on an asset row/card. Always acts on that one asset, whatever\n * the current multi-selection is (the bulk actions bar is the selection-scoped\n * affordance) — the file mirror of `FolderActionsMenu`.\n *\n * Replace / copy link / download duplicate what the details drawer offers as\n * icon buttons, so the same action is one click away without opening the asset\n * first. They are re-implemented rather than lifted out of the drawer: the\n * drawer versions render as `IconButton`s and report through its in-drawer toast\n * slot, neither of which fits a menu item on a row.\n *\n * Any successful move or delete clears the whole selection: a delete only\n * invalidates RTK tags, so without it an `asset:<id>` key for a file that no\n * longer exists would linger in the selection.\n */\nexport const AssetActionsMenu = ({ asset, dragData }: AssetActionsMenuProps) => {\n const { formatMessage } = useIntl();\n const { copy } = useClipboard();\n const { toggleNotification } = useNotification();\n const { clear } = useAssetSelection();\n // Absent in the asset picker and in unit tests: the replace still runs, it\n // just renders no row-level overlay.\n const markBusy = useBusyAssetsOptional()?.markBusy ?? (() => () => {});\n const {\n canUpdate,\n canDownload,\n canCopyLink,\n isLoading: isLoadingPermissions,\n } = useMediaLibraryPermissions();\n const [replaceAsset, { isLoading: isReplacing }] = useReplaceAssetMutation();\n const aiEnabled = useAIMetadataEnabled({ mime: asset.mime });\n\n const fileInputRef = useRef<HTMLInputElement>(null);\n const [isReplaceOpen, setIsReplaceOpen] = useState(false);\n const [isMoveOpen, setIsMoveOpen] = useState(false);\n const [isDeleteOpen, setIsDeleteOpen] = useState(false);\n const [isDownloading, setIsDownloading] = useState(false);\n\n // Stable identity: the move dialog memoizes its destination walk on it.\n const moveItems = useMemo(() => [dragData], [dragData]);\n\n // Confirm first, then open the native picker, so the user only commits to\n // replacing after acknowledging the warning (same order as the drawer).\n const handleReplaceContinue = () => {\n setIsReplaceOpen(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\n if (!file) {\n return;\n }\n\n // The menu has closed by the time the picker returns, so `isReplacing` has\n // nothing left to disable and the row would otherwise sit inert for the\n // whole upload. Marking the asset busy puts the same overlay the drawer\n // uses on the row/card, cleared when the mutation settles either way.\n const releaseBusy = markBusy(\n asset.id,\n formatMessage({\n id: getTranslationKey('asset-details.replace.loading'),\n defaultMessage: 'Replacing the file…',\n })\n );\n\n let res;\n try {\n res = await replaceAsset({ id: asset.id, file });\n } finally {\n releaseBusy();\n }\n\n if ('error' in res) {\n // `fetchBaseQuery` already unwraps the API envelope, so a server-sent\n // reason (file too large, unsupported type) lands directly on `message`.\n const { message } = res.error as { message?: string };\n toggleNotification({\n type: 'danger',\n message:\n message ??\n formatMessage({\n id: getTranslationKey('asset-details.replace.error'),\n defaultMessage: 'Failed to replace the file.',\n }),\n });\n return;\n }\n\n toggleNotification({\n type: 'success',\n message: formatMessage({\n id: getTranslationKey('asset-details.replace.success'),\n defaultMessage: 'File replaced.',\n }),\n });\n };\n\n const handleCopyLink = async () => {\n const url = prefixFileUrlWithBackendUrl(asset.url);\n\n if (!url) {\n return;\n }\n\n const didCopy = await copy(url);\n\n toggleNotification({\n type: didCopy ? 'success' : 'danger',\n message: formatMessage(\n didCopy\n ? {\n id: getTranslationKey('asset-details.copy-link.success'),\n defaultMessage: 'Link copied.',\n }\n : {\n id: getTranslationKey('asset-details.copy-link.error'),\n defaultMessage: 'Failed to copy the link.',\n }\n ),\n });\n };\n\n const handleDownload = async () => {\n const url = prefixFileUrlWithBackendUrl(asset.url);\n\n if (!url) {\n return;\n }\n\n setIsDownloading(true);\n\n try {\n await downloadFile(url, asset.name);\n } catch {\n toggleNotification({\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 // Two permission-gated groups: replace/copy-link/download above, move/delete\n // below. The separator earns its place only when both survive the gate —\n // `canUpdate` alone puts Replace in the top group, which is not enough.\n const hasTopGroup = canUpdate || canCopyLink || canDownload;\n const hasBottomGroup = canUpdate;\n const showSeparator = (canCopyLink || canDownload) && hasBottomGroup;\n\n // A role can read the library while holding none of these, and an empty\n // popup is worse than no trigger at all. Every flag is `false` until the\n // RBAC check settles, so wait for it — otherwise the trigger unmounts and\n // remounts on first paint for everyone.\n if (!isLoadingPermissions && !hasTopGroup && !hasBottomGroup) {\n return null;\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 {/* Non-modal: Radix's default `modal` marks the rest of the document\n `aria-hidden` and blocks pointer events while the menu is open, so\n clicking a sibling row's trigger only dismissed this one — leaving\n every menu you touched to be closed one click at a time. Non-modal\n dismissal treats that click as both \"close this\" and \"open that\". */}\n <Menu.Root modal={false}>\n <Menu.Trigger\n tag={IconButton}\n icon={<More />}\n variant=\"ghost\"\n label={formatMessage({\n id: getTranslationKey('control-card.more-actions'),\n defaultMessage: 'More actions',\n })}\n />\n {/* `ActionsMenuContent` replaces the design system's flat 15rem clamp\n with the height Radix actually measured, and un-hides the scrollbar\n it would otherwise overflow into. See that file for why. */}\n <ActionsMenuContent popoverPlacement=\"bottom-end\" zIndex={2} minWidth=\"22rem\">\n {canUpdate && (\n <Menu.Item\n startIcon={<ArrowsCounterClockwise />}\n disabled={isReplacing}\n onSelect={() => setIsReplaceOpen(true)}\n >\n {formatMessage({\n id: getTranslationKey('list.assets.actions.replace'),\n defaultMessage: 'Replace media',\n })}\n </Menu.Item>\n )}\n {canCopyLink && (\n <Menu.Item startIcon={<Link />} onSelect={handleCopyLink}>\n {formatMessage({\n id: getTranslationKey('list.assets.actions.copy-link'),\n defaultMessage: 'Copy link to media',\n })}\n </Menu.Item>\n )}\n {canDownload && (\n <Menu.Item startIcon={<Download />} disabled={isDownloading} onSelect={handleDownload}>\n {formatMessage({\n id: getTranslationKey('list.assets.actions.download'),\n defaultMessage: 'Download media',\n })}\n </Menu.Item>\n )}\n {showSeparator && <Menu.Separator />}\n {canUpdate && (\n <>\n <Menu.Item startIcon={<ArrowRight />} onSelect={() => setIsMoveOpen(true)}>\n {formatMessage({\n id: getTranslationKey('list.assets.actions.move'),\n defaultMessage: 'Move to folder',\n })}\n </Menu.Item>\n <Menu.Item\n startIcon={<Trash />}\n variant=\"danger\"\n onSelect={() => setIsDeleteOpen(true)}\n >\n {formatMessage({\n id: getTranslationKey('list.assets.actions.delete'),\n defaultMessage: 'Delete',\n })}\n </Menu.Item>\n </>\n )}\n </ActionsMenuContent>\n </Menu.Root>\n <Dialog.Root open={isReplaceOpen} onOpenChange={setIsReplaceOpen}>\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={handleReplaceContinue} 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 {isMoveOpen && (\n <BulkMoveDialog\n open\n onClose={() => setIsMoveOpen(false)}\n items={moveItems}\n onSuccess={clear}\n />\n )}\n {/* Both dialogs live inside the row, so a background refetch that drops the\n row would take an open dialog with it. Nothing invalidates until the\n mutation resolves, and the dialog closes in the same tick, so the\n flows themselves can't trigger it. */}\n {isDeleteOpen && (\n <DeleteItemsDialog\n open\n onClose={() => setIsDeleteOpen(false)}\n target={{ fileIds: [asset.id], folderIds: [] }}\n onSuccess={clear}\n />\n )}\n </>\n );\n};\n"],"names":["AssetActionsMenu","asset","dragData","formatMessage","useIntl","copy","useClipboard","toggleNotification","useNotification","clear","useAssetSelection","markBusy","useBusyAssetsOptional","canUpdate","canDownload","canCopyLink","isLoading","isLoadingPermissions","useMediaLibraryPermissions","replaceAsset","isReplacing","useReplaceAssetMutation","aiEnabled","useAIMetadataEnabled","mime","fileInputRef","useRef","isReplaceOpen","setIsReplaceOpen","useState","isMoveOpen","setIsMoveOpen","isDeleteOpen","setIsDeleteOpen","isDownloading","setIsDownloading","moveItems","useMemo","handleReplaceContinue","current","click","handleFileChange","event","file","target","files","value","releaseBusy","id","getTranslationKey","defaultMessage","res","message","error","type","handleCopyLink","url","prefixFileUrlWithBackendUrl","didCopy","handleDownload","downloadFile","name","hasTopGroup","hasBottomGroup","showSeparator","_jsxs","_Fragment","_jsx","VisuallyHidden","input","ref","multiple","onChange","aria-hidden","tabIndex","Menu","Root","modal","Trigger","tag","IconButton","icon","More","variant","label","ActionsMenuContent","popoverPlacement","zIndex","minWidth","Item","startIcon","ArrowsCounterClockwise","disabled","onSelect","Link","Download","Separator","ArrowRight","Trash","Dialog","open","onOpenChange","Content","Header","Body","textAlign","Flex","direction","Typography","Footer","Cancel","Button","fullWidth","Action","onClick","BulkMoveDialog","onClose","items","onSuccess","DeleteItemsDialog","fileIds","folderIds"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"AssetActionsMenu.mjs","sources":["../../../../../../admin/src/future/pages/Assets/components/AssetActionsMenu.tsx"],"sourcesContent":["import { useMemo, useRef, useState } from 'react';\n\nimport { useClipboard, useNotification } from '@strapi/admin/strapi-admin';\nimport {\n Button,\n Dialog,\n Flex,\n IconButton,\n Menu,\n Typography,\n VisuallyHidden,\n} from '@strapi/design-system';\nimport { ArrowRight, ArrowsCounterClockwise, Download, Link, More, Trash } from '@strapi/icons';\nimport { useIntl } from 'react-intl';\n\nimport { useAIMetadataEnabled } from '../../../hooks/useAIMetadataEnabled';\nimport { useMediaLibraryPermissions } from '../../../hooks/useMediaLibraryPermissions';\nimport { useReplaceAssetMutation } from '../../../services/assets';\nimport { downloadFile } from '../../../utils/downloadFile';\nimport { prefixFileUrlWithBackendUrl } from '../../../utils/files';\nimport { getTranslationKey } from '../../../utils/translations';\nimport { useAssetSelection } from '../hooks/useAssetSelection';\nimport { useBusyAssetsOptional } from '../hooks/useBusyAssets';\nimport { assetKey } from '../utils/selection';\n\nimport { ActionsMenuContent } from './ActionsMenuContent';\nimport { BulkMoveDialog } from './BulkMoveDialog';\nimport { DeleteItemsDialog } from './DeleteItemsDialog';\n\nimport type { File } from '../../../../../../shared/contracts/files';\nimport type { DragFileData } from '../../../types/dnd';\n\ninterface AssetActionsMenuProps {\n asset: File;\n /** Drag data for this asset, so the move dialog validates against its real folder. */\n dragData: DragFileData;\n}\n\n/**\n * The \"...\" menu on an asset row/card. Always acts on that one asset, whatever\n * the current multi-selection is (the bulk actions bar is the selection-scoped\n * affordance) — the file mirror of `FolderActionsMenu`.\n *\n * Replace / copy link / download duplicate what the details drawer offers as\n * icon buttons, so the same action is one click away without opening the asset\n * first. They are re-implemented rather than lifted out of the drawer: the\n * drawer versions render as `IconButton`s and report through its in-drawer toast\n * slot, neither of which fits a menu item on a row.\n *\n * A successful move or delete deselects this one asset and leaves the rest of\n * the selection intact: the mutations only invalidate RTK tags, so without it an\n * `asset:<id>` key for a file that has been deleted — or has moved out of this\n * list — would linger. The other selected rows are untouched, which is the whole\n * point of the menu being a single-item affordance.\n */\nexport const AssetActionsMenu = ({ asset, dragData }: AssetActionsMenuProps) => {\n const { formatMessage } = useIntl();\n const { copy } = useClipboard();\n const { toggleNotification } = useNotification();\n const { deselect } = useAssetSelection();\n // Absent in the asset picker and in unit tests: the replace still runs, it\n // just renders no row-level overlay.\n const markBusy = useBusyAssetsOptional()?.markBusy ?? (() => () => {});\n const {\n canUpdate,\n canDownload,\n canCopyLink,\n isLoading: isLoadingPermissions,\n } = useMediaLibraryPermissions();\n const [replaceAsset, { isLoading: isReplacing }] = useReplaceAssetMutation();\n const aiEnabled = useAIMetadataEnabled({ mime: asset.mime });\n\n const fileInputRef = useRef<HTMLInputElement>(null);\n const [isReplaceOpen, setIsReplaceOpen] = useState(false);\n const [isMoveOpen, setIsMoveOpen] = useState(false);\n const [isDeleteOpen, setIsDeleteOpen] = useState(false);\n const [isDownloading, setIsDownloading] = useState(false);\n\n // Stable identity: the move dialog memoizes its destination walk on it.\n const moveItems = useMemo(() => [dragData], [dragData]);\n\n // Confirm first, then open the native picker, so the user only commits to\n // replacing after acknowledging the warning (same order as the drawer).\n const handleReplaceContinue = () => {\n setIsReplaceOpen(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\n if (!file) {\n return;\n }\n\n // The menu has closed by the time the picker returns, so `isReplacing` has\n // nothing left to disable and the row would otherwise sit inert for the\n // whole upload. Marking the asset busy puts the same overlay the drawer\n // uses on the row/card, cleared when the mutation settles either way.\n const releaseBusy = markBusy(\n asset.id,\n formatMessage({\n id: getTranslationKey('asset-details.replace.loading'),\n defaultMessage: 'Replacing the file…',\n })\n );\n\n let res;\n try {\n res = await replaceAsset({ id: asset.id, file });\n } finally {\n releaseBusy();\n }\n\n if ('error' in res) {\n // `fetchBaseQuery` already unwraps the API envelope, so a server-sent\n // reason (file too large, unsupported type) lands directly on `message`.\n const { message } = res.error as { message?: string };\n toggleNotification({\n type: 'danger',\n message:\n message ??\n formatMessage({\n id: getTranslationKey('asset-details.replace.error'),\n defaultMessage: 'Failed to replace the file.',\n }),\n });\n return;\n }\n\n toggleNotification({\n type: 'success',\n message: formatMessage({\n id: getTranslationKey('asset-details.replace.success'),\n defaultMessage: 'File replaced.',\n }),\n });\n };\n\n const handleCopyLink = async () => {\n const url = prefixFileUrlWithBackendUrl(asset.url);\n\n if (!url) {\n return;\n }\n\n const didCopy = await copy(url);\n\n toggleNotification({\n type: didCopy ? 'success' : 'danger',\n message: formatMessage(\n didCopy\n ? {\n id: getTranslationKey('asset-details.copy-link.success'),\n defaultMessage: 'Link copied.',\n }\n : {\n id: getTranslationKey('asset-details.copy-link.error'),\n defaultMessage: 'Failed to copy the link.',\n }\n ),\n });\n };\n\n const handleDownload = async () => {\n const url = prefixFileUrlWithBackendUrl(asset.url);\n\n if (!url) {\n return;\n }\n\n setIsDownloading(true);\n\n try {\n await downloadFile(url, asset.name);\n } catch {\n toggleNotification({\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 // Two permission-gated groups: replace/copy-link/download above, move/delete\n // below. The separator earns its place only when both survive the gate —\n // `canUpdate` alone puts Replace in the top group, which is not enough.\n const hasTopGroup = canUpdate || canCopyLink || canDownload;\n const hasBottomGroup = canUpdate;\n const showSeparator = (canCopyLink || canDownload) && hasBottomGroup;\n\n // A role can read the library while holding none of these, and an empty\n // popup is worse than no trigger at all. Every flag is `false` until the\n // RBAC check settles, so wait for it — otherwise the trigger unmounts and\n // remounts on first paint for everyone.\n if (!isLoadingPermissions && !hasTopGroup && !hasBottomGroup) {\n return null;\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 {/* Non-modal: Radix's default `modal` marks the rest of the document\n `aria-hidden` and blocks pointer events while the menu is open, so\n clicking a sibling row's trigger only dismissed this one — leaving\n every menu you touched to be closed one click at a time. Non-modal\n dismissal treats that click as both \"close this\" and \"open that\". */}\n <Menu.Root modal={false}>\n <Menu.Trigger\n tag={IconButton}\n icon={<More />}\n variant=\"ghost\"\n label={formatMessage({\n id: getTranslationKey('control-card.more-actions'),\n defaultMessage: 'More actions',\n })}\n />\n {/* `ActionsMenuContent` replaces the design system's flat 15rem clamp\n with the height Radix actually measured, and un-hides the scrollbar\n it would otherwise overflow into. See that file for why. */}\n <ActionsMenuContent popoverPlacement=\"bottom-end\" zIndex={2} minWidth=\"22rem\">\n {canUpdate && (\n <Menu.Item\n startIcon={<ArrowsCounterClockwise />}\n disabled={isReplacing}\n onSelect={() => setIsReplaceOpen(true)}\n >\n {formatMessage({\n id: getTranslationKey('list.assets.actions.replace'),\n defaultMessage: 'Replace media',\n })}\n </Menu.Item>\n )}\n {canCopyLink && (\n <Menu.Item startIcon={<Link />} onSelect={handleCopyLink}>\n {formatMessage({\n id: getTranslationKey('list.assets.actions.copy-link'),\n defaultMessage: 'Copy link to media',\n })}\n </Menu.Item>\n )}\n {canDownload && (\n <Menu.Item startIcon={<Download />} disabled={isDownloading} onSelect={handleDownload}>\n {formatMessage({\n id: getTranslationKey('list.assets.actions.download'),\n defaultMessage: 'Download media',\n })}\n </Menu.Item>\n )}\n {showSeparator && <Menu.Separator />}\n {canUpdate && (\n <>\n <Menu.Item startIcon={<ArrowRight />} onSelect={() => setIsMoveOpen(true)}>\n {formatMessage({\n id: getTranslationKey('list.assets.actions.move'),\n defaultMessage: 'Move to folder',\n })}\n </Menu.Item>\n <Menu.Item\n startIcon={<Trash />}\n variant=\"danger\"\n onSelect={() => setIsDeleteOpen(true)}\n >\n {formatMessage({\n id: getTranslationKey('list.assets.actions.delete'),\n defaultMessage: 'Delete',\n })}\n </Menu.Item>\n </>\n )}\n </ActionsMenuContent>\n </Menu.Root>\n <Dialog.Root open={isReplaceOpen} onOpenChange={setIsReplaceOpen}>\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={handleReplaceContinue} 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 {isMoveOpen && (\n <BulkMoveDialog\n open\n onClose={() => setIsMoveOpen(false)}\n items={moveItems}\n onSuccess={() => deselect(assetKey(asset.id))}\n />\n )}\n {/* Both dialogs live inside the row, so a background refetch that drops the\n row would take an open dialog with it. Nothing invalidates until the\n mutation resolves, and the dialog closes in the same tick, so the\n flows themselves can't trigger it. */}\n {isDeleteOpen && (\n <DeleteItemsDialog\n open\n onClose={() => setIsDeleteOpen(false)}\n target={{ fileIds: [asset.id], folderIds: [] }}\n onSuccess={() => deselect(assetKey(asset.id))}\n />\n )}\n </>\n );\n};\n"],"names":["AssetActionsMenu","asset","dragData","formatMessage","useIntl","copy","useClipboard","toggleNotification","useNotification","deselect","useAssetSelection","markBusy","useBusyAssetsOptional","canUpdate","canDownload","canCopyLink","isLoading","isLoadingPermissions","useMediaLibraryPermissions","replaceAsset","isReplacing","useReplaceAssetMutation","aiEnabled","useAIMetadataEnabled","mime","fileInputRef","useRef","isReplaceOpen","setIsReplaceOpen","useState","isMoveOpen","setIsMoveOpen","isDeleteOpen","setIsDeleteOpen","isDownloading","setIsDownloading","moveItems","useMemo","handleReplaceContinue","current","click","handleFileChange","event","file","target","files","value","releaseBusy","id","getTranslationKey","defaultMessage","res","message","error","type","handleCopyLink","url","prefixFileUrlWithBackendUrl","didCopy","handleDownload","downloadFile","name","hasTopGroup","hasBottomGroup","showSeparator","_jsxs","_Fragment","_jsx","VisuallyHidden","input","ref","multiple","onChange","aria-hidden","tabIndex","Menu","Root","modal","Trigger","tag","IconButton","icon","More","variant","label","ActionsMenuContent","popoverPlacement","zIndex","minWidth","Item","startIcon","ArrowsCounterClockwise","disabled","onSelect","Link","Download","Separator","ArrowRight","Trash","Dialog","open","onOpenChange","Content","Header","Body","textAlign","Flex","direction","Typography","Footer","Cancel","Button","fullWidth","Action","onClick","BulkMoveDialog","onClose","items","onSuccess","assetKey","DeleteItemsDialog","fileIds","folderIds"],"mappings":"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"}
|
|
@@ -11,6 +11,7 @@ var enums = require('../../../../../enums.js');
|
|
|
11
11
|
var Drawer = require('../../../../components/Drawer.js');
|
|
12
12
|
var useAIMetadataEnabled = require('../../../../hooks/useAIMetadataEnabled.js');
|
|
13
13
|
var useMediaLibraryPermissions = require('../../../../hooks/useMediaLibraryPermissions.js');
|
|
14
|
+
var useTracking = require('../../../../hooks/useTracking.js');
|
|
14
15
|
var api = require('../../../../services/api.js');
|
|
15
16
|
var assets = require('../../../../services/assets.js');
|
|
16
17
|
var folders = require('../../../../services/folders.js');
|
|
@@ -574,6 +575,7 @@ const AssetDetails = ({ asset, closeDetails })=>{
|
|
|
574
575
|
const { data: folders$1 = [] } = folders.useGetAllFoldersQuery();
|
|
575
576
|
const { toggleNotification } = strapiAdmin.useNotification();
|
|
576
577
|
const [updateAsset] = assets.useUpdateAssetMutation();
|
|
578
|
+
const { trackUsage } = useTracking.useTracking();
|
|
577
579
|
const [replaceMutation, { isLoading: isReplacing }] = assets.useReplaceAssetMutation();
|
|
578
580
|
const [deleteMutation, { isLoading: isDeleting }] = assets.useDeleteAssetMutation();
|
|
579
581
|
const [uploadCroppedCopy, { isLoading: isCropCopying }] = api.useUploadFileSilentlyMutation();
|
|
@@ -618,6 +620,12 @@ const AssetDetails = ({ asset, closeDetails })=>{
|
|
|
618
620
|
});
|
|
619
621
|
return;
|
|
620
622
|
}
|
|
623
|
+
trackUsage('didEditMediaLibraryElements', {
|
|
624
|
+
location: useTracking.MEDIA_LIBRARY_LOCATION,
|
|
625
|
+
// Legacy sends the mime top-level type (image/video/audio/application…).
|
|
626
|
+
type: asset.mime?.split('/')[0],
|
|
627
|
+
changeLocation: values.folder !== initialValues.folder
|
|
628
|
+
});
|
|
621
629
|
notify({
|
|
622
630
|
type: 'success',
|
|
623
631
|
message: formatMessage({
|
|
@@ -645,6 +653,9 @@ const AssetDetails = ({ asset, closeDetails })=>{
|
|
|
645
653
|
});
|
|
646
654
|
return;
|
|
647
655
|
}
|
|
656
|
+
trackUsage('didReplaceMedia', {
|
|
657
|
+
location: useTracking.MEDIA_LIBRARY_LOCATION
|
|
658
|
+
});
|
|
648
659
|
notify({
|
|
649
660
|
type: 'success',
|
|
650
661
|
message: formatMessage({
|
|
@@ -656,7 +667,8 @@ const AssetDetails = ({ asset, closeDetails })=>{
|
|
|
656
667
|
asset.id,
|
|
657
668
|
formatMessage,
|
|
658
669
|
notify,
|
|
659
|
-
replaceMutation
|
|
670
|
+
replaceMutation,
|
|
671
|
+
trackUsage
|
|
660
672
|
]);
|
|
661
673
|
// Owns the delete: on error notify in-drawer (drawer stays), on success fire
|
|
662
674
|
// a persistent global notification then close the drawer.
|
|
@@ -718,6 +730,10 @@ const AssetDetails = ({ asset, closeDetails })=>{
|
|
|
718
730
|
notifyCropError();
|
|
719
731
|
return;
|
|
720
732
|
}
|
|
733
|
+
trackUsage('didCropFile', {
|
|
734
|
+
location: useTracking.MEDIA_LIBRARY_LOCATION,
|
|
735
|
+
duplicatedFile: false
|
|
736
|
+
});
|
|
721
737
|
notify({
|
|
722
738
|
type: 'success',
|
|
723
739
|
message: formatMessage({
|
|
@@ -745,6 +761,10 @@ const AssetDetails = ({ asset, closeDetails })=>{
|
|
|
745
761
|
notifyCropError();
|
|
746
762
|
return;
|
|
747
763
|
}
|
|
764
|
+
trackUsage('didCropFile', {
|
|
765
|
+
location: useTracking.MEDIA_LIBRARY_LOCATION,
|
|
766
|
+
duplicatedFile: true
|
|
767
|
+
});
|
|
748
768
|
notify({
|
|
749
769
|
type: 'success',
|
|
750
770
|
message: formatMessage({
|
|
@@ -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 { useAIMetadataEnabled } from '../../../../hooks/useAIMetadataEnabled';\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 { 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';\nimport { BusyOverlay } from '../BusyOverlay';\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 * 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 *\n * Exported for the unit test: the branch order only matters when two flags are\n * true at once, which the UI makes hard to stage through the rendered drawer\n * (each trigger disables itself while its own mutation runs).\n */\nexport const 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\ninterface ReplaceAssetButtonProps {\n /** The asset's mime, so the dialog only promises AI metadata when it applies. */\n mime?: string | null;\n}\n\nconst ReplaceAssetButton = ({ mime }: ReplaceAssetButtonProps) => {\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 aiEnabled = useAIMetadataEnabled({ mime });\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 extends ReplaceAssetButtonProps {\n onCrop?: () => void;\n}\n\nconst AssetImageActions = ({ onCrop, mime }: 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 mime={mime} />\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 = React.useCallback(\n 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 [asset.id, formatMessage, notify, replaceMutation]\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 = React.useCallback(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 asset.id,\n closeDetails,\n deleteMutation,\n folderName,\n formatMessage,\n notify,\n toggleNotification,\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, 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 ? <BusyOverlay>{formatMessage(busyMessage)}</BusyOverlay> : 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)} mime={asset.mime} />\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 {/* Caption and alternative text apply to every file type\n (matches the legacy Media Library), not images only. */}\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 </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","getBusyMessage","state","isDeleting","getTranslationKey","defaultMessage","isCropCopying","isReplacing","StyledWarning","WarningCircle","colors","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","mime","replaceAsset","fileInputRef","isDialogOpen","setIsDialogOpen","aiEnabled","useAIMetadataEnabled","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","data","useGetAllFoldersQuery","toggleNotification","useNotification","updateAsset","useUpdateAssetMutation","replaceMutation","isLoading","useReplaceAssetMutation","deleteMutation","useDeleteAssetMutation","uploadCroppedCopy","useUploadFileSilentlyMutation","isCropOpen","setIsCropOpen","drawerToast","setDrawerToast","timer","window","setTimeout","clearTimeout","toast","isImage","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","BusyOverlay","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","Loader","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 { useAIMetadataEnabled } from '../../../../hooks/useAIMetadataEnabled';\nimport { useMediaLibraryPermissions } from '../../../../hooks/useMediaLibraryPermissions';\nimport { useTracking, MEDIA_LIBRARY_LOCATION } from '../../../../hooks/useTracking';\nimport { useUploadFileSilentlyMutation } from '../../../../services/api';\nimport {\n useDeleteAssetMutation,\n useGetAssetQuery,\n useReplaceAssetMutation,\n useUpdateAssetMutation,\n} from '../../../../services/assets';\nimport { useGetAllFoldersQuery } from '../../../../services/folders';\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';\nimport { BusyOverlay } from '../BusyOverlay';\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 * 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 *\n * Exported for the unit test: the branch order only matters when two flags are\n * true at once, which the UI makes hard to stage through the rendered drawer\n * (each trigger disables itself while its own mutation runs).\n */\nexport const 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\ninterface ReplaceAssetButtonProps {\n /** The asset's mime, so the dialog only promises AI metadata when it applies. */\n mime?: string | null;\n}\n\nconst ReplaceAssetButton = ({ mime }: ReplaceAssetButtonProps) => {\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 aiEnabled = useAIMetadataEnabled({ mime });\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 extends ReplaceAssetButtonProps {\n onCrop?: () => void;\n}\n\nconst AssetImageActions = ({ onCrop, mime }: 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 mime={mime} />\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 { trackUsage } = useTracking();\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 trackUsage('didEditMediaLibraryElements', {\n location: MEDIA_LIBRARY_LOCATION,\n // Legacy sends the mime top-level type (image/video/audio/application…).\n type: asset.mime?.split('/')[0],\n changeLocation: values.folder !== initialValues.folder,\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 = React.useCallback(\n 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 trackUsage('didReplaceMedia', { location: MEDIA_LIBRARY_LOCATION });\n notify({\n type: 'success',\n message: formatMessage({\n id: getTranslationKey('asset-details.replace.success'),\n defaultMessage: 'File replaced.',\n }),\n });\n },\n [asset.id, formatMessage, notify, replaceMutation, trackUsage]\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 = React.useCallback(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 asset.id,\n closeDetails,\n deleteMutation,\n folderName,\n formatMessage,\n notify,\n toggleNotification,\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 trackUsage('didCropFile', { location: MEDIA_LIBRARY_LOCATION, duplicatedFile: false });\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 trackUsage('didCropFile', { location: MEDIA_LIBRARY_LOCATION, duplicatedFile: true });\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, 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 ? <BusyOverlay>{formatMessage(busyMessage)}</BusyOverlay> : 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)} mime={asset.mime} />\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 {/* Caption and alternative text apply to every file type\n (matches the legacy Media Library), not images only. */}\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 </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","getBusyMessage","state","isDeleting","getTranslationKey","defaultMessage","isCropCopying","isReplacing","StyledWarning","WarningCircle","colors","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","mime","replaceAsset","fileInputRef","isDialogOpen","setIsDialogOpen","aiEnabled","useAIMetadataEnabled","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","data","useGetAllFoldersQuery","toggleNotification","useNotification","updateAsset","useUpdateAssetMutation","trackUsage","useTracking","replaceMutation","isLoading","useReplaceAssetMutation","deleteMutation","useDeleteAssetMutation","uploadCroppedCopy","useUploadFileSilentlyMutation","isCropOpen","setIsCropOpen","drawerToast","setDrawerToast","timer","window","setTimeout","clearTimeout","toast","isImage","includes","ASSET_TYPES","Image","initialValues","caption","alternativeText","handleSubmit","values","fileInfo","res","location","MEDIA_LIBRARY_LOCATION","split","changeLocation","title","folderName","useFolderInfo","handleReplace","error","handleDelete","notifyCropError","handleCropApply","focalPoint","duplicatedFile","handleCropSaveAsCopy","operations","useMemo","Provider","Form","method","onSubmit","modified","resetForm","nameIsEmpty","trim","busyMessage","Blocker","onProceed","AssetCropEditor","onClose","onApply","onSaveAsCopy","canSaveAsCopy","BusyOverlay","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","Loader","AssetDetailsDrawer","div","Description","animationDirection","onAnimationEnd"],"mappings":"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"}
|