@strapi/upload 5.60.0 → 5.61.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (91) hide show
  1. package/dist/admin/components/AssetPickerDialog/MediaLibraryPickerDialog.js +29 -0
  2. package/dist/admin/components/AssetPickerDialog/MediaLibraryPickerDialog.js.map +1 -0
  3. package/dist/admin/components/AssetPickerDialog/MediaLibraryPickerDialog.mjs +27 -0
  4. package/dist/admin/components/AssetPickerDialog/MediaLibraryPickerDialog.mjs.map +1 -0
  5. package/dist/admin/components/Drawer.js +12 -7
  6. package/dist/admin/components/Drawer.js.map +1 -1
  7. package/dist/admin/components/Drawer.mjs +12 -7
  8. package/dist/admin/components/Drawer.mjs.map +1 -1
  9. package/dist/admin/components/EditorFileDropZone/EditorFileDropZone.js +188 -0
  10. package/dist/admin/components/EditorFileDropZone/EditorFileDropZone.js.map +1 -0
  11. package/dist/admin/components/EditorFileDropZone/EditorFileDropZone.mjs +186 -0
  12. package/dist/admin/components/EditorFileDropZone/EditorFileDropZone.mjs.map +1 -0
  13. package/dist/admin/components/MediaLibraryInput/AddAssetMenu.js +5 -1
  14. package/dist/admin/components/MediaLibraryInput/AddAssetMenu.js.map +1 -1
  15. package/dist/admin/components/MediaLibraryInput/AddAssetMenu.mjs +5 -1
  16. package/dist/admin/components/MediaLibraryInput/AddAssetMenu.mjs.map +1 -1
  17. package/dist/admin/components/MediaLibraryInput/MediaLibraryInput.js +37 -27
  18. package/dist/admin/components/MediaLibraryInput/MediaLibraryInput.js.map +1 -1
  19. package/dist/admin/components/MediaLibraryInput/MediaLibraryInput.mjs +37 -27
  20. package/dist/admin/components/MediaLibraryInput/MediaLibraryInput.mjs.map +1 -1
  21. package/dist/admin/components/MediaLibraryInput/openAssetDetails.js +46 -0
  22. package/dist/admin/components/MediaLibraryInput/openAssetDetails.js.map +1 -0
  23. package/dist/admin/components/MediaLibraryInput/openAssetDetails.mjs +43 -0
  24. package/dist/admin/components/MediaLibraryInput/openAssetDetails.mjs.map +1 -0
  25. package/dist/admin/index.js +10 -1
  26. package/dist/admin/index.js.map +1 -1
  27. package/dist/admin/index.mjs +10 -1
  28. package/dist/admin/index.mjs.map +1 -1
  29. package/dist/admin/pages/Assets/AssetsPage.js +1 -1
  30. package/dist/admin/pages/Assets/AssetsPage.js.map +1 -1
  31. package/dist/admin/pages/Assets/AssetsPage.mjs +2 -2
  32. package/dist/admin/pages/Assets/AssetsPage.mjs.map +1 -1
  33. package/dist/admin/pages/Assets/components/AssetDetails/AssetCropEditor.mjs +2 -2
  34. package/dist/admin/pages/Assets/components/AssetDetails/AssetDetailsDrawer.js +181 -65
  35. package/dist/admin/pages/Assets/components/AssetDetails/AssetDetailsDrawer.js.map +1 -1
  36. package/dist/admin/pages/Assets/components/AssetDetails/AssetDetailsDrawer.mjs +184 -69
  37. package/dist/admin/pages/Assets/components/AssetDetails/AssetDetailsDrawer.mjs.map +1 -1
  38. package/dist/admin/pages/Assets/components/AssetDetails/AssetPreview.mjs +1 -1
  39. package/dist/admin/pages/Assets/hooks/useIsAssetDetailsOpen.js +2 -6
  40. package/dist/admin/pages/Assets/hooks/useIsAssetDetailsOpen.js.map +1 -1
  41. package/dist/admin/pages/Assets/hooks/useIsAssetDetailsOpen.mjs +2 -6
  42. package/dist/admin/pages/Assets/hooks/useIsAssetDetailsOpen.mjs.map +1 -1
  43. package/dist/admin/src/components/AssetPickerDialog/MediaLibraryPickerDialog.d.ts +19 -0
  44. package/dist/admin/src/components/Drawer.d.ts +8 -0
  45. package/dist/admin/src/components/EditorFileDropZone/EditorFileDropZone.d.ts +21 -0
  46. package/dist/admin/src/components/MediaLibraryInput/AddAssetMenu.d.ts +7 -1
  47. package/dist/admin/src/components/MediaLibraryInput/openAssetDetails.d.ts +10 -0
  48. package/dist/admin/src/pages/Assets/components/AssetDetails/AssetDetailsDrawer.d.ts +41 -5
  49. package/dist/admin/src/pages/Assets/hooks/useIsAssetDetailsOpen.d.ts +2 -6
  50. package/dist/admin/translations/en.json.js +4 -0
  51. package/dist/admin/translations/en.json.js.map +1 -1
  52. package/dist/admin/translations/en.json.mjs +4 -0
  53. package/dist/admin/translations/en.json.mjs.map +1 -1
  54. package/dist/server/audit-logs.js +264 -0
  55. package/dist/server/audit-logs.js.map +1 -0
  56. package/dist/server/audit-logs.mjs +255 -0
  57. package/dist/server/audit-logs.mjs.map +1 -0
  58. package/dist/server/bootstrap.js +4 -0
  59. package/dist/server/bootstrap.js.map +1 -1
  60. package/dist/server/bootstrap.mjs +4 -0
  61. package/dist/server/bootstrap.mjs.map +1 -1
  62. package/dist/server/controllers/admin-folder-file.js +23 -1
  63. package/dist/server/controllers/admin-folder-file.js.map +1 -1
  64. package/dist/server/controllers/admin-folder-file.mjs +23 -1
  65. package/dist/server/controllers/admin-folder-file.mjs.map +1 -1
  66. package/dist/server/services/folder.js +48 -1
  67. package/dist/server/services/folder.js.map +1 -1
  68. package/dist/server/services/folder.mjs +48 -1
  69. package/dist/server/services/folder.mjs.map +1 -1
  70. package/dist/server/services/image-manipulation.js +12 -5
  71. package/dist/server/services/image-manipulation.js.map +1 -1
  72. package/dist/server/services/image-manipulation.mjs +12 -5
  73. package/dist/server/services/image-manipulation.mjs.map +1 -1
  74. package/dist/server/services/upload.js +100 -16
  75. package/dist/server/services/upload.js.map +1 -1
  76. package/dist/server/services/upload.mjs +102 -18
  77. package/dist/server/services/upload.mjs.map +1 -1
  78. package/dist/server/src/audit-logs.d.ts +142 -0
  79. package/dist/server/src/audit-logs.d.ts.map +1 -0
  80. package/dist/server/src/bootstrap.d.ts.map +1 -1
  81. package/dist/server/src/controllers/admin-folder-file.d.ts.map +1 -1
  82. package/dist/server/src/index.d.ts +3 -3
  83. package/dist/server/src/index.d.ts.map +1 -1
  84. package/dist/server/src/mcp/ambient-instance.d.ts.map +1 -1
  85. package/dist/server/src/services/folder.d.ts.map +1 -1
  86. package/dist/server/src/services/image-manipulation.d.ts +3 -3
  87. package/dist/server/src/services/image-manipulation.d.ts.map +1 -1
  88. package/dist/server/src/services/index.d.ts +3 -3
  89. package/dist/server/src/services/index.d.ts.map +1 -1
  90. package/dist/server/src/services/upload.d.ts.map +1 -1
  91. package/package.json +9 -16
@@ -1 +1 @@
1
- {"version":3,"file":"MediaLibraryInput.js","sources":["../../../../admin/src/components/MediaLibraryInput/MediaLibraryInput.tsx"],"sourcesContent":["import { useRef, useState, type ChangeEvent, type ReactNode } from 'react';\n\nimport { useClipboard, useField, useForm, useNotification } from '@strapi/admin/strapi-admin';\nimport { Field, Flex, VisuallyHidden } from '@strapi/design-system';\nimport get from 'lodash/get';\nimport { useIntl } from 'react-intl';\n\nimport { useAIMetadataEnabled } from '../../hooks/useAIMetadataEnabled';\nimport { useMediaLibraryPermissions } from '../../hooks/useMediaLibraryPermissions';\nimport { useTracking } from '../../hooks/useTracking';\nimport {\n EditAssetDialog,\n type Asset as EditableAsset,\n} from '../../legacy/components/EditAssetDialog/EditAssetContent';\nimport { ImportFromUrlDialog } from '../../pages/Assets/components/ImportFromUrlDialog';\nimport { useUploadFilesMutation, useUploadFromUrlsMutation } from '../../services/api';\nimport { useGetUploadSettingsQuery } from '../../services/settings';\nimport {\n filterAllowedFiles,\n isMediaTypeAllowed,\n type AllowedMediaType,\n} from '../../utils/allowedMediaTypes';\nimport { prefixFileUrlWithBackendUrl } from '../../utils/files';\nimport { getTranslationKey } from '../../utils/translations';\nimport { typeFromMime } from '../../utils/typeFromMime';\nimport { AssetPickerDialog } from '../AssetPickerDialog/AssetPickerDialog';\n\nimport { AddAssetMenu } from './AddAssetMenu';\nimport { AssetCard, UploadCard } from './AssetCard';\nimport { AssetCarousel } from './AssetCarousel';\nimport { AssetDropZone, type ZoneVariant } from './AssetDropZone';\nimport { AssetRow, UploadRow } from './AssetRow';\nimport { useFieldUploads, type FieldUpload } from './useFieldUploads';\n\nimport type { File } from '../../../../shared/contracts/files';\n\n/**\n * What a field wrote that its form has not rendered yet, per form and field.\n * `getValues()` only catches up on render, and two uploads can complete before\n * the next one. Kept outside the input so it survives a remount.\n */\nconst unrenderedWrites = new WeakMap<object, Map<string, { seen: unknown; written: File[] }>>();\n\nconst toAssets = (value: unknown): File[] =>\n Array.isArray(value) ? value : value ? [value as File] : [];\n\n/**\n * `location` for every event this field fires. The standalone Media Library\n * tags its events `'upload'`; the picker inside an entry form has always been\n * `'content-manager'`, and analytics still splits the two on that axis.\n */\nconst CONTENT_MANAGER_LOCATION = 'content-manager';\n\n/**\n * Uploads from here land at the root of the Media Library. An entry form has no\n * current folder to inherit, and the field offers no destination picker — same\n * place the legacy upload wizard put them when none was chosen.\n */\nconst UPLOAD_FOLDER_ID = null;\n\ntype Step = 'browse';\n\nexport interface MediaLibraryInputProps {\n name: string;\n label?: string;\n labelAction?: ReactNode;\n hint?: string;\n required?: boolean;\n disabled?: boolean;\n attribute?: {\n allowedTypes?: AllowedMediaType[] | null;\n multiple?: boolean;\n };\n /** The field's width in the edit layout, out of 12. Set by the Content Manager. */\n layoutSize?: number;\n}\n\nconst EMPTY_ATTRIBUTE: NonNullable<MediaLibraryInputProps['attribute']> = {};\n\n/**\n * The Content Manager's `media` field, on the current Media Library stack.\n *\n * Files dropped here (or picked from the device) upload straight through\n * `uploadFiles`, which is what drives the global upload progress dialog — so the\n * entry form stays usable while they go, instead of being covered by the legacy\n * wizard.\n *\n * The legacy input is still registered when `useLegacyMediaLibrary` is on, and\n * is untouched by this.\n */\nexport const MediaLibraryInput = ({\n name,\n label,\n labelAction,\n hint,\n required = false,\n disabled = false,\n attribute = EMPTY_ATTRIBUTE,\n layoutSize,\n}: MediaLibraryInputProps) => {\n const { allowedTypes = null, multiple = false } = attribute;\n const { formatMessage } = useIntl();\n const { onChange, value, error } = useField<File | File[] | null>(name);\n const { toggleNotification } = useNotification();\n const { trackUsage } = useTracking();\n const { copy } = useClipboard();\n const getValues = useForm('MediaLibraryInput', (state) => state.getValues);\n\n const [step, setStep] = useState<Step | undefined>(undefined);\n const [editedAsset, setEditedAsset] = useState<File | null>(null);\n const [isUrlDialogOpen, setIsUrlDialogOpen] = useState(false);\n const fileInputRef = useRef<HTMLInputElement>(null);\n\n const [uploadFiles] = useUploadFilesMutation();\n const [uploadFromUrls] = useUploadFromUrlsMutation();\n // Echoes the app config; a missing payload (still loading) falls back to\n // sequential rather than outpacing what the server asked for.\n const { isLoading, canRead, canCreate, canUpdate, canCopyLink, canDownload } =\n useMediaLibraryPermissions();\n // Not while permissions load: `useRBAC` starts with every flag false, and an\n // upload sent before it settles can end in a 403.\n const canUpload = !isLoading && canCreate;\n const { data: settings } = useGetUploadSettingsQuery(undefined, { skip: !canRead });\n const concurrency = settings?.data?.concurrentUploadRequests ?? 1;\n const isAiMetadataEnabled = useAIMetadataEnabled();\n\n const assets: File[] = Array.isArray(value) ? value : value ? [value] : [];\n\n // An upload resumes long after the render that started it, and the dialog is\n // non-blocking precisely so a second batch can be dropped meanwhile. Reading\n // the closed-over `assets` on resume would then append to whatever the field\n // held when that drop began, dropping every asset that landed since.\n const assetsRef = useRef(assets);\n assetsRef.current = assets;\n\n const setAssets = (nextAssets: File[]) => {\n if (multiple) {\n onChange(name, nextAssets.length > 0 ? nextAssets : null);\n return;\n }\n onChange(name, nextAssets[0] ?? null);\n };\n\n const handleRemove = (asset: File) => {\n setAssets(assets.filter((current) => current.id !== asset.id));\n };\n\n // Bound to the form, not to this input: a component collapsed mid-upload\n // unmounts the field, and the file must still land on the entry.\n const attachUploadedFile = (file: File) => {\n const writes = unrenderedWrites.get(getValues) ?? new Map();\n unrenderedWrites.set(getValues, writes);\n\n const value = get(getValues(), name);\n const pending = writes.get(name);\n const current = pending && pending.seen === value ? pending.written : toAssets(value);\n const next = multiple ? [...current, file] : [file];\n\n writes.set(name, { seen: value, written: next });\n setAssets(next);\n };\n\n const { uploads, cancel, retry, dismiss } = useFieldUploads(name);\n\n const handleCopyLink = async (asset: File) => {\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 handleEditClose = (result?: EditableAsset | null | boolean) => {\n const asset = editedAsset;\n setEditedAsset(null);\n\n if (!asset) {\n return;\n }\n\n // `null` means the asset was deleted from the library from inside the dialog.\n if (result === null) {\n setAssets(assetsRef.current.filter((current) => current.id !== asset.id));\n return;\n }\n\n if (result && typeof result !== 'boolean') {\n setAssets(\n assetsRef.current.map((current) => (current.id === asset.id ? (result as File) : current))\n );\n }\n };\n\n const handleSelect = (selectedAssets: File[]) => {\n setAssets(selectedAssets);\n setStep(undefined);\n };\n\n const notifyUnsupported = () => {\n toggleNotification({\n type: 'danger',\n timeout: 4000,\n message: formatMessage(\n {\n // Legacy key: translated everywhere, and it names the accepted types,\n // which the field already passes as `fileTypes`.\n id: getTranslationKey('input.notification.not-supported'),\n defaultMessage: `You can't upload this type of file, only the following types are accepted – {fileTypes}`,\n },\n { fileTypes: (allowedTypes ?? []).join(',') }\n ),\n });\n };\n\n /**\n * True when the batch is more than a single-value field can take. Counted on\n * what was handed in rather than on what survives filtering: uploading one of\n * several would leave the user guessing which one the field kept.\n */\n const rejectsBatch = (count: number) => {\n if (multiple || count <= 1) {\n return false;\n }\n\n toggleNotification({\n type: 'danger',\n timeout: 4000,\n message: formatMessage({\n id: getTranslationKey('content-manager.input.notification.single-file'),\n defaultMessage: 'This field accepts only one file.',\n }),\n });\n\n return true;\n };\n\n const handleUpload = (files: globalThis.File[]) => {\n if (disabled || !canUpload || files.length === 0) {\n return;\n }\n\n // The device picker can't reach this — it carries `multiple` — so a drop is\n // the only way in.\n if (rejectsBatch(files.length)) {\n return;\n }\n\n const allowedFiles = filterAllowedFiles(allowedTypes, files);\n\n if (allowedFiles.length === 0) {\n notifyUnsupported();\n return;\n }\n\n // A mixed drop uploads what it can and says so, rather than silently\n // dropping the rest.\n if (allowedFiles.length < files.length) {\n notifyUnsupported();\n }\n\n const assetsCountByType = allowedFiles.reduce<Record<string, number>>((acc, file) => {\n const type = typeFromMime(file.type);\n acc[type] = (acc[type] ?? 0) + 1;\n return acc;\n }, {});\n trackUsage('didSelectFile', { source: 'computer', location: CONTENT_MANAGER_LOCATION });\n trackUsage('willAddMediaLibraryAssets', {\n location: CONTENT_MANAGER_LOCATION,\n ...assetsCountByType,\n });\n\n startUpload(allowedFiles);\n };\n\n /**\n * Hands the files to the shared upload pool. The field picks the results up\n * from `onFileUploaded`, which also runs for retries of the same rows.\n */\n const startUpload = (allowedFiles: globalThis.File[]) => {\n const formData = new FormData();\n allowedFiles.forEach((file) => formData.append('files', file));\n formData.append(\n 'fileInfo',\n JSON.stringify(\n allowedFiles.map((file) => ({\n name: file.name,\n caption: null,\n alternativeText: null,\n folder: UPLOAD_FOLDER_ID,\n }))\n )\n );\n\n uploadFiles({\n formData,\n totalFiles: allowedFiles.length,\n concurrency,\n generateAiMetadata: Boolean(isAiMetadataEnabled),\n onFileUploaded: attachUploadedFile,\n owner: name,\n });\n };\n\n const handleRetry = (upload: FieldUpload) => retry(upload, (file) => startUpload([file]));\n\n /**\n * The server fetches each URL and uploads what it finds, so the file's type\n * is not known here — `allowedTypes` can only be enforced on what comes back.\n * A URL whose file the field does not accept is uploaded to the library and\n * left off the field, which is also what the Media Library page does with it.\n */\n const handleUrlUpload = async (urls: string[]) => {\n if (disabled || urls.length === 0 || rejectsBatch(urls.length)) {\n return;\n }\n\n trackUsage('didSelectFile', { source: 'url', location: CONTENT_MANAGER_LOCATION });\n trackUsage('willAddMediaLibraryAssets', { location: CONTENT_MANAGER_LOCATION });\n\n try {\n const { data: uploadedFiles } = await uploadFromUrls({\n urls,\n folderId: UPLOAD_FOLDER_ID,\n generateAiMetadata: Boolean(isAiMetadataEnabled),\n }).unwrap();\n\n const allowedFiles = uploadedFiles.filter((file) =>\n isMediaTypeAllowed(allowedTypes, file.mime)\n );\n const notAttachedFiles = uploadedFiles.filter((file) => !allowedFiles.includes(file));\n\n if (notAttachedFiles.length > 0) {\n toggleNotification({\n type: 'warning',\n timeout: 4000,\n message: formatMessage(\n {\n id: getTranslationKey('content-manager.input.notification.not-attached'),\n defaultMessage:\n '{fileNames} {count, plural, one {was} other {were}} added to the Media Library, but this field only accepts {fileTypes}.',\n },\n {\n fileNames: notAttachedFiles.map((file) => file.name).join(', '),\n count: notAttachedFiles.length,\n fileTypes: (allowedTypes ?? []).join(', '),\n }\n ),\n });\n }\n\n if (allowedFiles.length > 0) {\n setAssets(multiple ? [...assetsRef.current, ...allowedFiles] : [allowedFiles[0]]);\n }\n } catch {\n // Errors reach the user through the progress dialog, which the mutation\n // populates itself.\n }\n };\n\n const handleFileInputChange = (event: ChangeEvent<HTMLInputElement>) => {\n // Copied before the reset, not after: `event.target.files` is the input's\n // live FileList, and clearing `value` empties it in place. Reading it\n // afterwards yields nothing and the upload never starts.\n const files = Array.from(event.target.files ?? []);\n // Reset so picking the same file twice in a row still fires `change`.\n event.target.value = '';\n\n if (files.length > 0) {\n handleUpload(files);\n }\n };\n\n const renderValue = () => {\n const dropZone = (variant: ZoneVariant) => (\n <AssetDropZone\n variant={variant}\n disabled={disabled || !canUpload}\n onDropFiles={handleUpload}\n />\n );\n\n if (assets.length === 0 && uploads.length === 0) {\n return dropZone('bar');\n }\n\n const uploadHandlers = {\n disabled,\n onCancel: cancel,\n onRetry: handleRetry,\n onRemove: (upload: FieldUpload) => dismiss(upload.key),\n };\n\n if (!multiple) {\n // A replacement in flight, or one that failed, stands in for the current\n // asset until it lands or is removed.\n if (uploads.length > 0) {\n return (\n <Flex direction=\"column\" alignItems=\"stretch\" gap={2}>\n {uploads.map((upload) => (\n <UploadRow key={upload.key} upload={upload} {...uploadHandlers} />\n ))}\n </Flex>\n );\n }\n\n return (\n <AssetRow\n asset={assets[0]}\n disabled={disabled}\n onCopyLink={handleCopyLink}\n // The details dialog needs the library's folder tree, which needs read access.\n onEdit={canRead ? setEditedAsset : undefined}\n onRemove={handleRemove}\n />\n );\n }\n\n return (\n <AssetCarousel renderDropZone={dropZone} layoutSize={layoutSize}>\n {assets.map((asset) => (\n <AssetCard\n key={asset.id}\n asset={asset}\n disabled={disabled}\n onCopyLink={handleCopyLink}\n onEdit={canRead ? setEditedAsset : undefined}\n onRemove={handleRemove}\n />\n ))}\n {uploads.map((upload) => (\n <UploadCard key={upload.key} upload={upload} {...uploadHandlers} />\n ))}\n </AssetCarousel>\n );\n };\n\n return (\n <Field.Root name={name} error={error} hint={hint} required={required}>\n <Flex justifyContent=\"space-between\" alignItems=\"center\" gap={2}>\n <Field.Label action={labelAction}>{label}</Field.Label>\n <AddAssetMenu\n disabled={disabled}\n onBrowseLibrary={() => setStep('browse')}\n onUploadFromDevice={() => fileInputRef.current?.click()}\n onUploadFromUrl={() => setIsUrlDialogOpen(true)}\n />\n </Flex>\n\n {renderValue()}\n\n <Field.Error />\n <Field.Hint />\n\n <VisuallyHidden>\n <input\n ref={fileInputRef}\n type=\"file\"\n multiple={multiple}\n onChange={handleFileInputChange}\n tabIndex={-1}\n aria-hidden\n />\n </VisuallyHidden>\n\n {step === 'browse' && (\n <AssetPickerDialog\n open\n title={formatMessage(\n {\n id: getTranslationKey('asset-picker.title'),\n defaultMessage: 'Add asset for {fieldName}',\n },\n { fieldName: label ?? name }\n )}\n initialSelection={assets}\n multiple={multiple}\n allowedTypes={allowedTypes}\n onClose={() => setStep(undefined)}\n onConfirm={handleSelect}\n />\n )}\n\n {editedAsset && (\n <EditAssetDialog\n open\n asset={editedAsset as EditableAsset}\n canUpdate={canUpdate && !disabled}\n canCopyLink={canCopyLink}\n canDownload={canDownload}\n trackedLocation={CONTENT_MANAGER_LOCATION}\n onClose={handleEditClose}\n />\n )}\n\n <ImportFromUrlDialog\n open={isUrlDialogOpen}\n onClose={() => setIsUrlDialogOpen(false)}\n onUpload={handleUrlUpload}\n />\n </Field.Root>\n );\n};\n"],"names":["unrenderedWrites","WeakMap","toAssets","value","Array","isArray","CONTENT_MANAGER_LOCATION","UPLOAD_FOLDER_ID","EMPTY_ATTRIBUTE","MediaLibraryInput","name","label","labelAction","hint","required","disabled","attribute","layoutSize","allowedTypes","multiple","formatMessage","useIntl","onChange","error","useField","toggleNotification","useNotification","trackUsage","useTracking","copy","useClipboard","getValues","useForm","state","step","setStep","useState","undefined","editedAsset","setEditedAsset","isUrlDialogOpen","setIsUrlDialogOpen","fileInputRef","useRef","uploadFiles","useUploadFilesMutation","uploadFromUrls","useUploadFromUrlsMutation","isLoading","canRead","canCreate","canUpdate","canCopyLink","canDownload","useMediaLibraryPermissions","canUpload","data","settings","useGetUploadSettingsQuery","skip","concurrency","concurrentUploadRequests","isAiMetadataEnabled","useAIMetadataEnabled","assets","assetsRef","current","setAssets","nextAssets","length","handleRemove","asset","filter","id","attachUploadedFile","file","writes","get","Map","set","pending","seen","written","next","uploads","cancel","retry","dismiss","useFieldUploads","handleCopyLink","url","prefixFileUrlWithBackendUrl","didCopy","type","message","getTranslationKey","defaultMessage","handleEditClose","result","map","handleSelect","selectedAssets","notifyUnsupported","timeout","fileTypes","join","rejectsBatch","count","handleUpload","files","allowedFiles","filterAllowedFiles","assetsCountByType","reduce","acc","typeFromMime","source","location","startUpload","formData","FormData","forEach","append","JSON","stringify","caption","alternativeText","folder","totalFiles","generateAiMetadata","Boolean","onFileUploaded","owner","handleRetry","upload","handleUrlUpload","urls","uploadedFiles","folderId","unwrap","isMediaTypeAllowed","mime","notAttachedFiles","includes","fileNames","handleFileInputChange","event","from","target","renderValue","dropZone","variant","_jsx","AssetDropZone","onDropFiles","uploadHandlers","onCancel","onRetry","onRemove","key","Flex","direction","alignItems","gap","UploadRow","AssetRow","onCopyLink","onEdit","_jsxs","AssetCarousel","renderDropZone","AssetCard","UploadCard","Field","Root","justifyContent","Label","action","AddAssetMenu","onBrowseLibrary","onUploadFromDevice","click","onUploadFromUrl","Error","Hint","VisuallyHidden","input","ref","tabIndex","aria-hidden","AssetPickerDialog","open","title","fieldName","initialSelection","onClose","onConfirm","EditAssetDialog","trackedLocation","ImportFromUrlDialog","onUpload"],"mappings":"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"}
1
+ {"version":3,"file":"MediaLibraryInput.js","sources":["../../../../admin/src/components/MediaLibraryInput/MediaLibraryInput.tsx"],"sourcesContent":["import { useRef, useState, type ChangeEvent, type ReactNode } from 'react';\n\nimport { useClipboard, useField, useForm, useNotification } from '@strapi/admin/strapi-admin';\nimport { Field, Flex, VisuallyHidden } from '@strapi/design-system';\nimport get from 'lodash/get';\nimport { useIntl } from 'react-intl';\n\nimport { useAIMetadataEnabled } from '../../hooks/useAIMetadataEnabled';\nimport { useMediaLibraryPermissions } from '../../hooks/useMediaLibraryPermissions';\nimport { useTracking } from '../../hooks/useTracking';\nimport { AssetDetailsDrawer } from '../../pages/Assets/components/AssetDetails/AssetDetailsDrawer';\nimport { ImportFromUrlDialog } from '../../pages/Assets/components/ImportFromUrlDialog';\nimport { useUploadFilesMutation, useUploadFromUrlsMutation } from '../../services/api';\nimport { useGetUploadSettingsQuery } from '../../services/settings';\nimport {\n filterAllowedFiles,\n isMediaTypeAllowed,\n type AllowedMediaType,\n} from '../../utils/allowedMediaTypes';\nimport { prefixFileUrlWithBackendUrl } from '../../utils/files';\nimport { getTranslationKey } from '../../utils/translations';\nimport { typeFromMime } from '../../utils/typeFromMime';\nimport { AssetPickerDialog } from '../AssetPickerDialog/AssetPickerDialog';\n\nimport { AddAssetMenu } from './AddAssetMenu';\nimport { AssetCard, UploadCard } from './AssetCard';\nimport { AssetCarousel } from './AssetCarousel';\nimport { AssetDropZone, type ZoneVariant } from './AssetDropZone';\nimport { AssetRow, UploadRow } from './AssetRow';\nimport { isAnyAssetDetailsOpen, useOpenAssetDetails } from './openAssetDetails';\nimport { useFieldUploads, type FieldUpload } from './useFieldUploads';\n\nimport type { AssetWithPopulatedCreatedBy, File } from '../../../../shared/contracts/files';\n\n/**\n * What a field wrote that its form has not rendered yet, per form and field.\n * `getValues()` only catches up on render, and two uploads can complete before\n * the next one. Kept outside the input so it survives a remount.\n */\nconst unrenderedWrites = new WeakMap<object, Map<string, { seen: unknown; written: File[] }>>();\n\nconst toAssets = (value: unknown): File[] =>\n Array.isArray(value) ? value : value ? [value as File] : [];\n\n/**\n * `location` for every event this field fires. The standalone Media Library\n * tags its events `'upload'`; the picker inside an entry form has always been\n * `'content-manager'`, and analytics still splits the two on that axis.\n */\nconst CONTENT_MANAGER_LOCATION = 'content-manager';\n\n/**\n * Uploads from here land at the root of the Media Library. An entry form has no\n * current folder to inherit, and the field offers no destination picker — same\n * place the legacy upload wizard put them when none was chosen.\n */\nconst UPLOAD_FOLDER_ID = null;\n\ntype Step = 'browse';\n\nexport interface MediaLibraryInputProps {\n name: string;\n label?: string;\n labelAction?: ReactNode;\n hint?: string;\n required?: boolean;\n disabled?: boolean;\n attribute?: {\n allowedTypes?: AllowedMediaType[] | null;\n multiple?: boolean;\n };\n /** The field's width in the edit layout, out of 12. Set by the Content Manager. */\n layoutSize?: number;\n}\n\nconst EMPTY_ATTRIBUTE: NonNullable<MediaLibraryInputProps['attribute']> = {};\n\n/**\n * The Content Manager's `media` field, on the current Media Library stack.\n *\n * Files dropped here (or picked from the device) upload straight through\n * `uploadFiles`, which is what drives the global upload progress dialog — so the\n * entry form stays usable while they go, instead of being covered by the legacy\n * wizard.\n *\n * The legacy input is still registered when `useLegacyMediaLibrary` is on, and\n * is untouched by this.\n */\nexport const MediaLibraryInput = ({\n name,\n label,\n labelAction,\n hint,\n required = false,\n disabled = false,\n attribute = EMPTY_ATTRIBUTE,\n layoutSize,\n}: MediaLibraryInputProps) => {\n const { allowedTypes = null, multiple = false } = attribute;\n const { formatMessage } = useIntl();\n const { onChange, value, error } = useField<File | File[] | null>(name);\n const { toggleNotification } = useNotification();\n const { trackUsage } = useTracking();\n const { copy } = useClipboard();\n const getValues = useForm('MediaLibraryInput', (state) => state.getValues);\n\n const [step, setStep] = useState<Step | undefined>(undefined);\n const [editedAssetId, setEditedAssetId] = useState<number | null>(null);\n const isAnyDrawerOpen = useOpenAssetDetails(editedAssetId !== null);\n const [isUrlDialogOpen, setIsUrlDialogOpen] = useState(false);\n const fileInputRef = useRef<HTMLInputElement>(null);\n\n const [uploadFiles] = useUploadFilesMutation();\n const [uploadFromUrls] = useUploadFromUrlsMutation();\n // Echoes the app config; a missing payload (still loading) falls back to\n // sequential rather than outpacing what the server asked for.\n const { isLoading, canRead, canCreate } = useMediaLibraryPermissions();\n // Not while permissions load: `useRBAC` starts with every flag false, and an\n // upload sent before it settles can end in a 403.\n const canUpload = !isLoading && canCreate;\n const { data: settings } = useGetUploadSettingsQuery(undefined, { skip: !canRead });\n const concurrency = settings?.data?.concurrentUploadRequests ?? 1;\n const isAiMetadataEnabled = useAIMetadataEnabled();\n\n const assets: File[] = Array.isArray(value) ? value : value ? [value] : [];\n\n // An upload resumes long after the render that started it, and the dialog is\n // non-blocking precisely so a second batch can be dropped meanwhile. Reading\n // the closed-over `assets` on resume would then append to whatever the field\n // held when that drop began, dropping every asset that landed since.\n const assetsRef = useRef(assets);\n assetsRef.current = assets;\n\n const setAssets = (nextAssets: File[]) => {\n if (multiple) {\n onChange(name, nextAssets.length > 0 ? nextAssets : null);\n return;\n }\n onChange(name, nextAssets[0] ?? null);\n };\n\n const handleRemove = (asset: File) => {\n setAssets(assets.filter((current) => current.id !== asset.id));\n };\n\n // Bound to the form, not to this input: a component collapsed mid-upload\n // unmounts the field, and the file must still land on the entry.\n const attachUploadedFile = (file: File) => {\n const writes = unrenderedWrites.get(getValues) ?? new Map();\n unrenderedWrites.set(getValues, writes);\n\n const value = get(getValues(), name);\n const pending = writes.get(name);\n const current = pending && pending.seen === value ? pending.written : toAssets(value);\n const next = multiple ? [...current, file] : [file];\n\n writes.set(name, { seen: value, written: next });\n setAssets(next);\n };\n\n const { uploads, cancel, retry, dismiss } = useFieldUploads(name);\n\n const handleCopyLink = async (asset: File) => {\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 /**\n * Opens only when no drawer is open, in this field or another. Pressing a row's\n * button is a press outside the open drawer, which closes it — or, with unsaved\n * edits, asks first. Opening on the click that follows would put a second\n * drawer, or a new asset, under that question and drop the edits it is asking\n * about.\n */\n const handleEdit = (asset: File) => {\n if (!isAnyAssetDetailsOpen()) {\n setEditedAssetId(asset.id);\n }\n };\n\n // The drawer saves to the library itself; the field holds its own copy of the\n // asset, so it takes the server's after every change. Read from the ref: the\n // drawer reports after a request, by which time this render's `assets` may\n // be stale.\n const handleAssetChange = (changedAsset: AssetWithPopulatedCreatedBy) => {\n setAssets(\n assetsRef.current.map((current) =>\n // The populated `createdBy` is the one shape difference, and the entry\n // only keeps the asset's id on save.\n current.id === changedAsset.id ? (changedAsset as unknown as File) : current\n )\n );\n };\n\n // Deleting from the library leaves nothing for the field to point at.\n const handleAssetDelete = (id: number) => {\n setAssets(assetsRef.current.filter((current) => current.id !== id));\n };\n\n const handleSelect = (selectedAssets: File[]) => {\n setAssets(selectedAssets);\n setStep(undefined);\n };\n\n const notifyUnsupported = () => {\n toggleNotification({\n type: 'danger',\n timeout: 4000,\n message: formatMessage(\n {\n // Legacy key: translated everywhere, and it names the accepted types,\n // which the field already passes as `fileTypes`.\n id: getTranslationKey('input.notification.not-supported'),\n defaultMessage: `You can't upload this type of file, only the following types are accepted – {fileTypes}`,\n },\n { fileTypes: (allowedTypes ?? []).join(',') }\n ),\n });\n };\n\n /**\n * True when the batch is more than a single-value field can take. Counted on\n * what was handed in rather than on what survives filtering: uploading one of\n * several would leave the user guessing which one the field kept.\n */\n const rejectsBatch = (count: number) => {\n if (multiple || count <= 1) {\n return false;\n }\n\n toggleNotification({\n type: 'danger',\n timeout: 4000,\n message: formatMessage({\n id: getTranslationKey('content-manager.input.notification.single-file'),\n defaultMessage: 'This field accepts only one file.',\n }),\n });\n\n return true;\n };\n\n const handleUpload = (files: globalThis.File[]) => {\n if (disabled || !canUpload || files.length === 0) {\n return;\n }\n\n // The device picker can't reach this — it carries `multiple` — so a drop is\n // the only way in.\n if (rejectsBatch(files.length)) {\n return;\n }\n\n const allowedFiles = filterAllowedFiles(allowedTypes, files);\n\n if (allowedFiles.length === 0) {\n notifyUnsupported();\n return;\n }\n\n // A mixed drop uploads what it can and says so, rather than silently\n // dropping the rest.\n if (allowedFiles.length < files.length) {\n notifyUnsupported();\n }\n\n const assetsCountByType = allowedFiles.reduce<Record<string, number>>((acc, file) => {\n const type = typeFromMime(file.type);\n acc[type] = (acc[type] ?? 0) + 1;\n return acc;\n }, {});\n trackUsage('didSelectFile', { source: 'computer', location: CONTENT_MANAGER_LOCATION });\n trackUsage('willAddMediaLibraryAssets', {\n location: CONTENT_MANAGER_LOCATION,\n ...assetsCountByType,\n });\n\n startUpload(allowedFiles);\n };\n\n /**\n * Hands the files to the shared upload pool. The field picks the results up\n * from `onFileUploaded`, which also runs for retries of the same rows.\n */\n const startUpload = (allowedFiles: globalThis.File[]) => {\n const formData = new FormData();\n allowedFiles.forEach((file) => formData.append('files', file));\n formData.append(\n 'fileInfo',\n JSON.stringify(\n allowedFiles.map((file) => ({\n name: file.name,\n caption: null,\n alternativeText: null,\n folder: UPLOAD_FOLDER_ID,\n }))\n )\n );\n\n uploadFiles({\n formData,\n totalFiles: allowedFiles.length,\n concurrency,\n generateAiMetadata: Boolean(isAiMetadataEnabled),\n onFileUploaded: attachUploadedFile,\n owner: name,\n });\n };\n\n const handleRetry = (upload: FieldUpload) => retry(upload, (file) => startUpload([file]));\n\n /**\n * The server fetches each URL and uploads what it finds, so the file's type\n * is not known here — `allowedTypes` can only be enforced on what comes back.\n * A URL whose file the field does not accept is uploaded to the library and\n * left off the field, which is also what the Media Library page does with it.\n */\n const handleUrlUpload = async (urls: string[]) => {\n if (disabled || urls.length === 0 || rejectsBatch(urls.length)) {\n return;\n }\n\n trackUsage('didSelectFile', { source: 'url', location: CONTENT_MANAGER_LOCATION });\n trackUsage('willAddMediaLibraryAssets', { location: CONTENT_MANAGER_LOCATION });\n\n try {\n const { data: uploadedFiles } = await uploadFromUrls({\n urls,\n folderId: UPLOAD_FOLDER_ID,\n generateAiMetadata: Boolean(isAiMetadataEnabled),\n }).unwrap();\n\n const allowedFiles = uploadedFiles.filter((file) =>\n isMediaTypeAllowed(allowedTypes, file.mime)\n );\n const notAttachedFiles = uploadedFiles.filter((file) => !allowedFiles.includes(file));\n\n if (notAttachedFiles.length > 0) {\n toggleNotification({\n type: 'warning',\n timeout: 4000,\n message: formatMessage(\n {\n id: getTranslationKey('content-manager.input.notification.not-attached'),\n defaultMessage:\n '{fileNames} {count, plural, one {was} other {were}} added to the Media Library, but this field only accepts {fileTypes}.',\n },\n {\n fileNames: notAttachedFiles.map((file) => file.name).join(', '),\n count: notAttachedFiles.length,\n fileTypes: (allowedTypes ?? []).join(', '),\n }\n ),\n });\n }\n\n if (allowedFiles.length > 0) {\n setAssets(multiple ? [...assetsRef.current, ...allowedFiles] : [allowedFiles[0]]);\n }\n } catch {\n // Errors reach the user through the progress dialog, which the mutation\n // populates itself.\n }\n };\n\n const handleFileInputChange = (event: ChangeEvent<HTMLInputElement>) => {\n // Copied before the reset, not after: `event.target.files` is the input's\n // live FileList, and clearing `value` empties it in place. Reading it\n // afterwards yields nothing and the upload never starts.\n const files = Array.from(event.target.files ?? []);\n // Reset so picking the same file twice in a row still fires `change`.\n event.target.value = '';\n\n if (files.length > 0) {\n handleUpload(files);\n }\n };\n\n const renderValue = () => {\n const dropZone = (variant: ZoneVariant) => (\n <AssetDropZone\n variant={variant}\n disabled={disabled || !canUpload}\n onDropFiles={handleUpload}\n />\n );\n\n if (assets.length === 0 && uploads.length === 0) {\n return dropZone('bar');\n }\n\n const uploadHandlers = {\n disabled,\n onCancel: cancel,\n onRetry: handleRetry,\n onRemove: (upload: FieldUpload) => dismiss(upload.key),\n };\n\n if (!multiple) {\n // A replacement in flight, or one that failed, stands in for the current\n // asset until it lands or is removed.\n if (uploads.length > 0) {\n return (\n <Flex direction=\"column\" alignItems=\"stretch\" gap={2}>\n {uploads.map((upload) => (\n <UploadRow key={upload.key} upload={upload} {...uploadHandlers} />\n ))}\n </Flex>\n );\n }\n\n return (\n <AssetRow\n asset={assets[0]}\n disabled={disabled}\n onCopyLink={handleCopyLink}\n // The details drawer fetches the asset from the library, which needs read access.\n onEdit={canRead ? handleEdit : undefined}\n onRemove={handleRemove}\n />\n );\n }\n\n return (\n <AssetCarousel renderDropZone={dropZone} layoutSize={layoutSize}>\n {assets.map((asset) => (\n <AssetCard\n key={asset.id}\n asset={asset}\n disabled={disabled}\n onCopyLink={handleCopyLink}\n onEdit={canRead ? handleEdit : undefined}\n onRemove={handleRemove}\n />\n ))}\n {uploads.map((upload) => (\n <UploadCard key={upload.key} upload={upload} {...uploadHandlers} />\n ))}\n </AssetCarousel>\n );\n };\n\n return (\n <Field.Root name={name} error={error} hint={hint} required={required}>\n <Flex justifyContent=\"space-between\" alignItems=\"center\" gap={2}>\n <Field.Label action={labelAction}>{label}</Field.Label>\n <AddAssetMenu\n disabled={disabled}\n preventOpen={isAnyDrawerOpen}\n onBrowseLibrary={() => setStep('browse')}\n onUploadFromDevice={() => fileInputRef.current?.click()}\n onUploadFromUrl={() => setIsUrlDialogOpen(true)}\n />\n </Flex>\n\n {renderValue()}\n\n <Field.Error />\n <Field.Hint />\n\n <VisuallyHidden>\n <input\n ref={fileInputRef}\n type=\"file\"\n multiple={multiple}\n onChange={handleFileInputChange}\n tabIndex={-1}\n aria-hidden\n />\n </VisuallyHidden>\n\n {step === 'browse' && (\n <AssetPickerDialog\n open\n title={formatMessage(\n {\n id: getTranslationKey('asset-picker.title'),\n defaultMessage: 'Add asset for {fieldName}',\n },\n { fieldName: label ?? name }\n )}\n initialSelection={assets}\n multiple={multiple}\n allowedTypes={allowedTypes}\n onClose={() => setStep(undefined)}\n onConfirm={handleSelect}\n />\n )}\n\n <AssetDetailsDrawer\n assetId={editedAssetId}\n onClose={() => setEditedAssetId(null)}\n onAssetChange={handleAssetChange}\n onAssetDelete={handleAssetDelete}\n trackedLocation={CONTENT_MANAGER_LOCATION}\n />\n\n <ImportFromUrlDialog\n open={isUrlDialogOpen}\n onClose={() => setIsUrlDialogOpen(false)}\n onUpload={handleUrlUpload}\n />\n </Field.Root>\n );\n};\n"],"names":["unrenderedWrites","WeakMap","toAssets","value","Array","isArray","CONTENT_MANAGER_LOCATION","UPLOAD_FOLDER_ID","EMPTY_ATTRIBUTE","MediaLibraryInput","name","label","labelAction","hint","required","disabled","attribute","layoutSize","allowedTypes","multiple","formatMessage","useIntl","onChange","error","useField","toggleNotification","useNotification","trackUsage","useTracking","copy","useClipboard","getValues","useForm","state","step","setStep","useState","undefined","editedAssetId","setEditedAssetId","isAnyDrawerOpen","useOpenAssetDetails","isUrlDialogOpen","setIsUrlDialogOpen","fileInputRef","useRef","uploadFiles","useUploadFilesMutation","uploadFromUrls","useUploadFromUrlsMutation","isLoading","canRead","canCreate","useMediaLibraryPermissions","canUpload","data","settings","useGetUploadSettingsQuery","skip","concurrency","concurrentUploadRequests","isAiMetadataEnabled","useAIMetadataEnabled","assets","assetsRef","current","setAssets","nextAssets","length","handleRemove","asset","filter","id","attachUploadedFile","file","writes","get","Map","set","pending","seen","written","next","uploads","cancel","retry","dismiss","useFieldUploads","handleCopyLink","url","prefixFileUrlWithBackendUrl","didCopy","type","message","getTranslationKey","defaultMessage","handleEdit","isAnyAssetDetailsOpen","handleAssetChange","changedAsset","map","handleAssetDelete","handleSelect","selectedAssets","notifyUnsupported","timeout","fileTypes","join","rejectsBatch","count","handleUpload","files","allowedFiles","filterAllowedFiles","assetsCountByType","reduce","acc","typeFromMime","source","location","startUpload","formData","FormData","forEach","append","JSON","stringify","caption","alternativeText","folder","totalFiles","generateAiMetadata","Boolean","onFileUploaded","owner","handleRetry","upload","handleUrlUpload","urls","uploadedFiles","folderId","unwrap","isMediaTypeAllowed","mime","notAttachedFiles","includes","fileNames","handleFileInputChange","event","from","target","renderValue","dropZone","variant","_jsx","AssetDropZone","onDropFiles","uploadHandlers","onCancel","onRetry","onRemove","key","Flex","direction","alignItems","gap","UploadRow","AssetRow","onCopyLink","onEdit","_jsxs","AssetCarousel","renderDropZone","AssetCard","UploadCard","Field","Root","justifyContent","Label","action","AddAssetMenu","preventOpen","onBrowseLibrary","onUploadFromDevice","click","onUploadFromUrl","Error","Hint","VisuallyHidden","input","ref","tabIndex","aria-hidden","AssetPickerDialog","open","title","fieldName","initialSelection","onClose","onConfirm","AssetDetailsDrawer","assetId","onAssetChange","onAssetDelete","trackedLocation","ImportFromUrlDialog","onUpload"],"mappings":"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"}
@@ -7,7 +7,7 @@ import { useIntl } from 'react-intl';
7
7
  import { useAIMetadataEnabled } from '../../hooks/useAIMetadataEnabled.mjs';
8
8
  import { useMediaLibraryPermissions } from '../../hooks/useMediaLibraryPermissions.mjs';
9
9
  import { useTracking } from '../../hooks/useTracking.mjs';
10
- import { EditAssetDialog } from '../../legacy/components/EditAssetDialog/EditAssetContent.mjs';
10
+ import { AssetDetailsDrawer } from '../../pages/Assets/components/AssetDetails/AssetDetailsDrawer.mjs';
11
11
  import { ImportFromUrlDialog } from '../../pages/Assets/components/ImportFromUrlDialog.mjs';
12
12
  import { useUploadFilesMutation, useUploadFromUrlsMutation } from '../../services/api.mjs';
13
13
  import { useGetUploadSettingsQuery } from '../../services/settings.mjs';
@@ -21,6 +21,7 @@ import { AssetCard, UploadCard } from './AssetCard.mjs';
21
21
  import { AssetCarousel } from './AssetCarousel.mjs';
22
22
  import { AssetDropZone } from './AssetDropZone.mjs';
23
23
  import { UploadRow, AssetRow } from './AssetRow.mjs';
24
+ import { useOpenAssetDetails, isAnyAssetDetailsOpen } from './openAssetDetails.mjs';
24
25
  import { useFieldUploads } from './useFieldUploads.mjs';
25
26
 
26
27
  /**
@@ -61,14 +62,15 @@ const EMPTY_ATTRIBUTE = {};
61
62
  const { copy } = useClipboard();
62
63
  const getValues = useForm('MediaLibraryInput', (state)=>state.getValues);
63
64
  const [step, setStep] = useState(undefined);
64
- const [editedAsset, setEditedAsset] = useState(null);
65
+ const [editedAssetId, setEditedAssetId] = useState(null);
66
+ const isAnyDrawerOpen = useOpenAssetDetails(editedAssetId !== null);
65
67
  const [isUrlDialogOpen, setIsUrlDialogOpen] = useState(false);
66
68
  const fileInputRef = useRef(null);
67
69
  const [uploadFiles] = useUploadFilesMutation();
68
70
  const [uploadFromUrls] = useUploadFromUrlsMutation();
69
71
  // Echoes the app config; a missing payload (still loading) falls back to
70
72
  // sequential rather than outpacing what the server asked for.
71
- const { isLoading, canRead, canCreate, canUpdate, canCopyLink, canDownload } = useMediaLibraryPermissions();
73
+ const { isLoading, canRead, canCreate } = useMediaLibraryPermissions();
72
74
  // Not while permissions load: `useRBAC` starts with every flag false, and an
73
75
  // upload sent before it settles can end in a 403.
74
76
  const canUpload = !isLoading && canCreate;
@@ -134,21 +136,30 @@ const EMPTY_ATTRIBUTE = {};
134
136
  })
135
137
  });
136
138
  };
137
- const handleEditClose = (result)=>{
138
- const asset = editedAsset;
139
- setEditedAsset(null);
140
- if (!asset) {
141
- return;
142
- }
143
- // `null` means the asset was deleted from the library from inside the dialog.
144
- if (result === null) {
145
- setAssets(assetsRef.current.filter((current)=>current.id !== asset.id));
146
- return;
147
- }
148
- if (result && typeof result !== 'boolean') {
149
- setAssets(assetsRef.current.map((current)=>current.id === asset.id ? result : current));
139
+ /**
140
+ * Opens only when no drawer is open, in this field or another. Pressing a row's
141
+ * button is a press outside the open drawer, which closes it — or, with unsaved
142
+ * edits, asks first. Opening on the click that follows would put a second
143
+ * drawer, or a new asset, under that question and drop the edits it is asking
144
+ * about.
145
+ */ const handleEdit = (asset)=>{
146
+ if (!isAnyAssetDetailsOpen()) {
147
+ setEditedAssetId(asset.id);
150
148
  }
151
149
  };
150
+ // The drawer saves to the library itself; the field holds its own copy of the
151
+ // asset, so it takes the server's after every change. Read from the ref: the
152
+ // drawer reports after a request, by which time this render's `assets` may
153
+ // be stale.
154
+ const handleAssetChange = (changedAsset)=>{
155
+ setAssets(assetsRef.current.map((current)=>// The populated `createdBy` is the one shape difference, and the entry
156
+ // only keeps the asset's id on save.
157
+ current.id === changedAsset.id ? changedAsset : current));
158
+ };
159
+ // Deleting from the library leaves nothing for the field to point at.
160
+ const handleAssetDelete = (id)=>{
161
+ setAssets(assetsRef.current.filter((current)=>current.id !== id));
162
+ };
152
163
  const handleSelect = (selectedAssets)=>{
153
164
  setAssets(selectedAssets);
154
165
  setStep(undefined);
@@ -338,8 +349,8 @@ const EMPTY_ATTRIBUTE = {};
338
349
  asset: assets[0],
339
350
  disabled: disabled,
340
351
  onCopyLink: handleCopyLink,
341
- // The details dialog needs the library's folder tree, which needs read access.
342
- onEdit: canRead ? setEditedAsset : undefined,
352
+ // The details drawer fetches the asset from the library, which needs read access.
353
+ onEdit: canRead ? handleEdit : undefined,
343
354
  onRemove: handleRemove
344
355
  });
345
356
  }
@@ -351,7 +362,7 @@ const EMPTY_ATTRIBUTE = {};
351
362
  asset: asset,
352
363
  disabled: disabled,
353
364
  onCopyLink: handleCopyLink,
354
- onEdit: canRead ? setEditedAsset : undefined,
365
+ onEdit: canRead ? handleEdit : undefined,
355
366
  onRemove: handleRemove
356
367
  }, asset.id)),
357
368
  uploads.map((upload)=>/*#__PURE__*/ jsx(UploadCard, {
@@ -378,6 +389,7 @@ const EMPTY_ATTRIBUTE = {};
378
389
  }),
379
390
  /*#__PURE__*/ jsx(AddAssetMenu, {
380
391
  disabled: disabled,
392
+ preventOpen: isAnyDrawerOpen,
381
393
  onBrowseLibrary: ()=>setStep('browse'),
382
394
  onUploadFromDevice: ()=>fileInputRef.current?.click(),
383
395
  onUploadFromUrl: ()=>setIsUrlDialogOpen(true)
@@ -411,14 +423,12 @@ const EMPTY_ATTRIBUTE = {};
411
423
  onClose: ()=>setStep(undefined),
412
424
  onConfirm: handleSelect
413
425
  }),
414
- editedAsset && /*#__PURE__*/ jsx(EditAssetDialog, {
415
- open: true,
416
- asset: editedAsset,
417
- canUpdate: canUpdate && !disabled,
418
- canCopyLink: canCopyLink,
419
- canDownload: canDownload,
420
- trackedLocation: CONTENT_MANAGER_LOCATION,
421
- onClose: handleEditClose
426
+ /*#__PURE__*/ jsx(AssetDetailsDrawer, {
427
+ assetId: editedAssetId,
428
+ onClose: ()=>setEditedAssetId(null),
429
+ onAssetChange: handleAssetChange,
430
+ onAssetDelete: handleAssetDelete,
431
+ trackedLocation: CONTENT_MANAGER_LOCATION
422
432
  }),
423
433
  /*#__PURE__*/ jsx(ImportFromUrlDialog, {
424
434
  open: isUrlDialogOpen,
@@ -1 +1 @@
1
- {"version":3,"file":"MediaLibraryInput.mjs","sources":["../../../../admin/src/components/MediaLibraryInput/MediaLibraryInput.tsx"],"sourcesContent":["import { useRef, useState, type ChangeEvent, type ReactNode } from 'react';\n\nimport { useClipboard, useField, useForm, useNotification } from '@strapi/admin/strapi-admin';\nimport { Field, Flex, VisuallyHidden } from '@strapi/design-system';\nimport get from 'lodash/get';\nimport { useIntl } from 'react-intl';\n\nimport { useAIMetadataEnabled } from '../../hooks/useAIMetadataEnabled';\nimport { useMediaLibraryPermissions } from '../../hooks/useMediaLibraryPermissions';\nimport { useTracking } from '../../hooks/useTracking';\nimport {\n EditAssetDialog,\n type Asset as EditableAsset,\n} from '../../legacy/components/EditAssetDialog/EditAssetContent';\nimport { ImportFromUrlDialog } from '../../pages/Assets/components/ImportFromUrlDialog';\nimport { useUploadFilesMutation, useUploadFromUrlsMutation } from '../../services/api';\nimport { useGetUploadSettingsQuery } from '../../services/settings';\nimport {\n filterAllowedFiles,\n isMediaTypeAllowed,\n type AllowedMediaType,\n} from '../../utils/allowedMediaTypes';\nimport { prefixFileUrlWithBackendUrl } from '../../utils/files';\nimport { getTranslationKey } from '../../utils/translations';\nimport { typeFromMime } from '../../utils/typeFromMime';\nimport { AssetPickerDialog } from '../AssetPickerDialog/AssetPickerDialog';\n\nimport { AddAssetMenu } from './AddAssetMenu';\nimport { AssetCard, UploadCard } from './AssetCard';\nimport { AssetCarousel } from './AssetCarousel';\nimport { AssetDropZone, type ZoneVariant } from './AssetDropZone';\nimport { AssetRow, UploadRow } from './AssetRow';\nimport { useFieldUploads, type FieldUpload } from './useFieldUploads';\n\nimport type { File } from '../../../../shared/contracts/files';\n\n/**\n * What a field wrote that its form has not rendered yet, per form and field.\n * `getValues()` only catches up on render, and two uploads can complete before\n * the next one. Kept outside the input so it survives a remount.\n */\nconst unrenderedWrites = new WeakMap<object, Map<string, { seen: unknown; written: File[] }>>();\n\nconst toAssets = (value: unknown): File[] =>\n Array.isArray(value) ? value : value ? [value as File] : [];\n\n/**\n * `location` for every event this field fires. The standalone Media Library\n * tags its events `'upload'`; the picker inside an entry form has always been\n * `'content-manager'`, and analytics still splits the two on that axis.\n */\nconst CONTENT_MANAGER_LOCATION = 'content-manager';\n\n/**\n * Uploads from here land at the root of the Media Library. An entry form has no\n * current folder to inherit, and the field offers no destination picker — same\n * place the legacy upload wizard put them when none was chosen.\n */\nconst UPLOAD_FOLDER_ID = null;\n\ntype Step = 'browse';\n\nexport interface MediaLibraryInputProps {\n name: string;\n label?: string;\n labelAction?: ReactNode;\n hint?: string;\n required?: boolean;\n disabled?: boolean;\n attribute?: {\n allowedTypes?: AllowedMediaType[] | null;\n multiple?: boolean;\n };\n /** The field's width in the edit layout, out of 12. Set by the Content Manager. */\n layoutSize?: number;\n}\n\nconst EMPTY_ATTRIBUTE: NonNullable<MediaLibraryInputProps['attribute']> = {};\n\n/**\n * The Content Manager's `media` field, on the current Media Library stack.\n *\n * Files dropped here (or picked from the device) upload straight through\n * `uploadFiles`, which is what drives the global upload progress dialog — so the\n * entry form stays usable while they go, instead of being covered by the legacy\n * wizard.\n *\n * The legacy input is still registered when `useLegacyMediaLibrary` is on, and\n * is untouched by this.\n */\nexport const MediaLibraryInput = ({\n name,\n label,\n labelAction,\n hint,\n required = false,\n disabled = false,\n attribute = EMPTY_ATTRIBUTE,\n layoutSize,\n}: MediaLibraryInputProps) => {\n const { allowedTypes = null, multiple = false } = attribute;\n const { formatMessage } = useIntl();\n const { onChange, value, error } = useField<File | File[] | null>(name);\n const { toggleNotification } = useNotification();\n const { trackUsage } = useTracking();\n const { copy } = useClipboard();\n const getValues = useForm('MediaLibraryInput', (state) => state.getValues);\n\n const [step, setStep] = useState<Step | undefined>(undefined);\n const [editedAsset, setEditedAsset] = useState<File | null>(null);\n const [isUrlDialogOpen, setIsUrlDialogOpen] = useState(false);\n const fileInputRef = useRef<HTMLInputElement>(null);\n\n const [uploadFiles] = useUploadFilesMutation();\n const [uploadFromUrls] = useUploadFromUrlsMutation();\n // Echoes the app config; a missing payload (still loading) falls back to\n // sequential rather than outpacing what the server asked for.\n const { isLoading, canRead, canCreate, canUpdate, canCopyLink, canDownload } =\n useMediaLibraryPermissions();\n // Not while permissions load: `useRBAC` starts with every flag false, and an\n // upload sent before it settles can end in a 403.\n const canUpload = !isLoading && canCreate;\n const { data: settings } = useGetUploadSettingsQuery(undefined, { skip: !canRead });\n const concurrency = settings?.data?.concurrentUploadRequests ?? 1;\n const isAiMetadataEnabled = useAIMetadataEnabled();\n\n const assets: File[] = Array.isArray(value) ? value : value ? [value] : [];\n\n // An upload resumes long after the render that started it, and the dialog is\n // non-blocking precisely so a second batch can be dropped meanwhile. Reading\n // the closed-over `assets` on resume would then append to whatever the field\n // held when that drop began, dropping every asset that landed since.\n const assetsRef = useRef(assets);\n assetsRef.current = assets;\n\n const setAssets = (nextAssets: File[]) => {\n if (multiple) {\n onChange(name, nextAssets.length > 0 ? nextAssets : null);\n return;\n }\n onChange(name, nextAssets[0] ?? null);\n };\n\n const handleRemove = (asset: File) => {\n setAssets(assets.filter((current) => current.id !== asset.id));\n };\n\n // Bound to the form, not to this input: a component collapsed mid-upload\n // unmounts the field, and the file must still land on the entry.\n const attachUploadedFile = (file: File) => {\n const writes = unrenderedWrites.get(getValues) ?? new Map();\n unrenderedWrites.set(getValues, writes);\n\n const value = get(getValues(), name);\n const pending = writes.get(name);\n const current = pending && pending.seen === value ? pending.written : toAssets(value);\n const next = multiple ? [...current, file] : [file];\n\n writes.set(name, { seen: value, written: next });\n setAssets(next);\n };\n\n const { uploads, cancel, retry, dismiss } = useFieldUploads(name);\n\n const handleCopyLink = async (asset: File) => {\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 handleEditClose = (result?: EditableAsset | null | boolean) => {\n const asset = editedAsset;\n setEditedAsset(null);\n\n if (!asset) {\n return;\n }\n\n // `null` means the asset was deleted from the library from inside the dialog.\n if (result === null) {\n setAssets(assetsRef.current.filter((current) => current.id !== asset.id));\n return;\n }\n\n if (result && typeof result !== 'boolean') {\n setAssets(\n assetsRef.current.map((current) => (current.id === asset.id ? (result as File) : current))\n );\n }\n };\n\n const handleSelect = (selectedAssets: File[]) => {\n setAssets(selectedAssets);\n setStep(undefined);\n };\n\n const notifyUnsupported = () => {\n toggleNotification({\n type: 'danger',\n timeout: 4000,\n message: formatMessage(\n {\n // Legacy key: translated everywhere, and it names the accepted types,\n // which the field already passes as `fileTypes`.\n id: getTranslationKey('input.notification.not-supported'),\n defaultMessage: `You can't upload this type of file, only the following types are accepted – {fileTypes}`,\n },\n { fileTypes: (allowedTypes ?? []).join(',') }\n ),\n });\n };\n\n /**\n * True when the batch is more than a single-value field can take. Counted on\n * what was handed in rather than on what survives filtering: uploading one of\n * several would leave the user guessing which one the field kept.\n */\n const rejectsBatch = (count: number) => {\n if (multiple || count <= 1) {\n return false;\n }\n\n toggleNotification({\n type: 'danger',\n timeout: 4000,\n message: formatMessage({\n id: getTranslationKey('content-manager.input.notification.single-file'),\n defaultMessage: 'This field accepts only one file.',\n }),\n });\n\n return true;\n };\n\n const handleUpload = (files: globalThis.File[]) => {\n if (disabled || !canUpload || files.length === 0) {\n return;\n }\n\n // The device picker can't reach this — it carries `multiple` — so a drop is\n // the only way in.\n if (rejectsBatch(files.length)) {\n return;\n }\n\n const allowedFiles = filterAllowedFiles(allowedTypes, files);\n\n if (allowedFiles.length === 0) {\n notifyUnsupported();\n return;\n }\n\n // A mixed drop uploads what it can and says so, rather than silently\n // dropping the rest.\n if (allowedFiles.length < files.length) {\n notifyUnsupported();\n }\n\n const assetsCountByType = allowedFiles.reduce<Record<string, number>>((acc, file) => {\n const type = typeFromMime(file.type);\n acc[type] = (acc[type] ?? 0) + 1;\n return acc;\n }, {});\n trackUsage('didSelectFile', { source: 'computer', location: CONTENT_MANAGER_LOCATION });\n trackUsage('willAddMediaLibraryAssets', {\n location: CONTENT_MANAGER_LOCATION,\n ...assetsCountByType,\n });\n\n startUpload(allowedFiles);\n };\n\n /**\n * Hands the files to the shared upload pool. The field picks the results up\n * from `onFileUploaded`, which also runs for retries of the same rows.\n */\n const startUpload = (allowedFiles: globalThis.File[]) => {\n const formData = new FormData();\n allowedFiles.forEach((file) => formData.append('files', file));\n formData.append(\n 'fileInfo',\n JSON.stringify(\n allowedFiles.map((file) => ({\n name: file.name,\n caption: null,\n alternativeText: null,\n folder: UPLOAD_FOLDER_ID,\n }))\n )\n );\n\n uploadFiles({\n formData,\n totalFiles: allowedFiles.length,\n concurrency,\n generateAiMetadata: Boolean(isAiMetadataEnabled),\n onFileUploaded: attachUploadedFile,\n owner: name,\n });\n };\n\n const handleRetry = (upload: FieldUpload) => retry(upload, (file) => startUpload([file]));\n\n /**\n * The server fetches each URL and uploads what it finds, so the file's type\n * is not known here — `allowedTypes` can only be enforced on what comes back.\n * A URL whose file the field does not accept is uploaded to the library and\n * left off the field, which is also what the Media Library page does with it.\n */\n const handleUrlUpload = async (urls: string[]) => {\n if (disabled || urls.length === 0 || rejectsBatch(urls.length)) {\n return;\n }\n\n trackUsage('didSelectFile', { source: 'url', location: CONTENT_MANAGER_LOCATION });\n trackUsage('willAddMediaLibraryAssets', { location: CONTENT_MANAGER_LOCATION });\n\n try {\n const { data: uploadedFiles } = await uploadFromUrls({\n urls,\n folderId: UPLOAD_FOLDER_ID,\n generateAiMetadata: Boolean(isAiMetadataEnabled),\n }).unwrap();\n\n const allowedFiles = uploadedFiles.filter((file) =>\n isMediaTypeAllowed(allowedTypes, file.mime)\n );\n const notAttachedFiles = uploadedFiles.filter((file) => !allowedFiles.includes(file));\n\n if (notAttachedFiles.length > 0) {\n toggleNotification({\n type: 'warning',\n timeout: 4000,\n message: formatMessage(\n {\n id: getTranslationKey('content-manager.input.notification.not-attached'),\n defaultMessage:\n '{fileNames} {count, plural, one {was} other {were}} added to the Media Library, but this field only accepts {fileTypes}.',\n },\n {\n fileNames: notAttachedFiles.map((file) => file.name).join(', '),\n count: notAttachedFiles.length,\n fileTypes: (allowedTypes ?? []).join(', '),\n }\n ),\n });\n }\n\n if (allowedFiles.length > 0) {\n setAssets(multiple ? [...assetsRef.current, ...allowedFiles] : [allowedFiles[0]]);\n }\n } catch {\n // Errors reach the user through the progress dialog, which the mutation\n // populates itself.\n }\n };\n\n const handleFileInputChange = (event: ChangeEvent<HTMLInputElement>) => {\n // Copied before the reset, not after: `event.target.files` is the input's\n // live FileList, and clearing `value` empties it in place. Reading it\n // afterwards yields nothing and the upload never starts.\n const files = Array.from(event.target.files ?? []);\n // Reset so picking the same file twice in a row still fires `change`.\n event.target.value = '';\n\n if (files.length > 0) {\n handleUpload(files);\n }\n };\n\n const renderValue = () => {\n const dropZone = (variant: ZoneVariant) => (\n <AssetDropZone\n variant={variant}\n disabled={disabled || !canUpload}\n onDropFiles={handleUpload}\n />\n );\n\n if (assets.length === 0 && uploads.length === 0) {\n return dropZone('bar');\n }\n\n const uploadHandlers = {\n disabled,\n onCancel: cancel,\n onRetry: handleRetry,\n onRemove: (upload: FieldUpload) => dismiss(upload.key),\n };\n\n if (!multiple) {\n // A replacement in flight, or one that failed, stands in for the current\n // asset until it lands or is removed.\n if (uploads.length > 0) {\n return (\n <Flex direction=\"column\" alignItems=\"stretch\" gap={2}>\n {uploads.map((upload) => (\n <UploadRow key={upload.key} upload={upload} {...uploadHandlers} />\n ))}\n </Flex>\n );\n }\n\n return (\n <AssetRow\n asset={assets[0]}\n disabled={disabled}\n onCopyLink={handleCopyLink}\n // The details dialog needs the library's folder tree, which needs read access.\n onEdit={canRead ? setEditedAsset : undefined}\n onRemove={handleRemove}\n />\n );\n }\n\n return (\n <AssetCarousel renderDropZone={dropZone} layoutSize={layoutSize}>\n {assets.map((asset) => (\n <AssetCard\n key={asset.id}\n asset={asset}\n disabled={disabled}\n onCopyLink={handleCopyLink}\n onEdit={canRead ? setEditedAsset : undefined}\n onRemove={handleRemove}\n />\n ))}\n {uploads.map((upload) => (\n <UploadCard key={upload.key} upload={upload} {...uploadHandlers} />\n ))}\n </AssetCarousel>\n );\n };\n\n return (\n <Field.Root name={name} error={error} hint={hint} required={required}>\n <Flex justifyContent=\"space-between\" alignItems=\"center\" gap={2}>\n <Field.Label action={labelAction}>{label}</Field.Label>\n <AddAssetMenu\n disabled={disabled}\n onBrowseLibrary={() => setStep('browse')}\n onUploadFromDevice={() => fileInputRef.current?.click()}\n onUploadFromUrl={() => setIsUrlDialogOpen(true)}\n />\n </Flex>\n\n {renderValue()}\n\n <Field.Error />\n <Field.Hint />\n\n <VisuallyHidden>\n <input\n ref={fileInputRef}\n type=\"file\"\n multiple={multiple}\n onChange={handleFileInputChange}\n tabIndex={-1}\n aria-hidden\n />\n </VisuallyHidden>\n\n {step === 'browse' && (\n <AssetPickerDialog\n open\n title={formatMessage(\n {\n id: getTranslationKey('asset-picker.title'),\n defaultMessage: 'Add asset for {fieldName}',\n },\n { fieldName: label ?? name }\n )}\n initialSelection={assets}\n multiple={multiple}\n allowedTypes={allowedTypes}\n onClose={() => setStep(undefined)}\n onConfirm={handleSelect}\n />\n )}\n\n {editedAsset && (\n <EditAssetDialog\n open\n asset={editedAsset as EditableAsset}\n canUpdate={canUpdate && !disabled}\n canCopyLink={canCopyLink}\n canDownload={canDownload}\n trackedLocation={CONTENT_MANAGER_LOCATION}\n onClose={handleEditClose}\n />\n )}\n\n <ImportFromUrlDialog\n open={isUrlDialogOpen}\n onClose={() => setIsUrlDialogOpen(false)}\n onUpload={handleUrlUpload}\n />\n </Field.Root>\n );\n};\n"],"names":["unrenderedWrites","WeakMap","toAssets","value","Array","isArray","CONTENT_MANAGER_LOCATION","UPLOAD_FOLDER_ID","EMPTY_ATTRIBUTE","MediaLibraryInput","name","label","labelAction","hint","required","disabled","attribute","layoutSize","allowedTypes","multiple","formatMessage","useIntl","onChange","error","useField","toggleNotification","useNotification","trackUsage","useTracking","copy","useClipboard","getValues","useForm","state","step","setStep","useState","undefined","editedAsset","setEditedAsset","isUrlDialogOpen","setIsUrlDialogOpen","fileInputRef","useRef","uploadFiles","useUploadFilesMutation","uploadFromUrls","useUploadFromUrlsMutation","isLoading","canRead","canCreate","canUpdate","canCopyLink","canDownload","useMediaLibraryPermissions","canUpload","data","settings","useGetUploadSettingsQuery","skip","concurrency","concurrentUploadRequests","isAiMetadataEnabled","useAIMetadataEnabled","assets","assetsRef","current","setAssets","nextAssets","length","handleRemove","asset","filter","id","attachUploadedFile","file","writes","get","Map","set","pending","seen","written","next","uploads","cancel","retry","dismiss","useFieldUploads","handleCopyLink","url","prefixFileUrlWithBackendUrl","didCopy","type","message","getTranslationKey","defaultMessage","handleEditClose","result","map","handleSelect","selectedAssets","notifyUnsupported","timeout","fileTypes","join","rejectsBatch","count","handleUpload","files","allowedFiles","filterAllowedFiles","assetsCountByType","reduce","acc","typeFromMime","source","location","startUpload","formData","FormData","forEach","append","JSON","stringify","caption","alternativeText","folder","totalFiles","generateAiMetadata","Boolean","onFileUploaded","owner","handleRetry","upload","handleUrlUpload","urls","uploadedFiles","folderId","unwrap","isMediaTypeAllowed","mime","notAttachedFiles","includes","fileNames","handleFileInputChange","event","from","target","renderValue","dropZone","variant","_jsx","AssetDropZone","onDropFiles","uploadHandlers","onCancel","onRetry","onRemove","key","Flex","direction","alignItems","gap","UploadRow","AssetRow","onCopyLink","onEdit","_jsxs","AssetCarousel","renderDropZone","AssetCard","UploadCard","Field","Root","justifyContent","Label","action","AddAssetMenu","onBrowseLibrary","onUploadFromDevice","click","onUploadFromUrl","Error","Hint","VisuallyHidden","input","ref","tabIndex","aria-hidden","AssetPickerDialog","open","title","fieldName","initialSelection","onClose","onConfirm","EditAssetDialog","trackedLocation","ImportFromUrlDialog","onUpload"],"mappings":"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"}
1
+ {"version":3,"file":"MediaLibraryInput.mjs","sources":["../../../../admin/src/components/MediaLibraryInput/MediaLibraryInput.tsx"],"sourcesContent":["import { useRef, useState, type ChangeEvent, type ReactNode } from 'react';\n\nimport { useClipboard, useField, useForm, useNotification } from '@strapi/admin/strapi-admin';\nimport { Field, Flex, VisuallyHidden } from '@strapi/design-system';\nimport get from 'lodash/get';\nimport { useIntl } from 'react-intl';\n\nimport { useAIMetadataEnabled } from '../../hooks/useAIMetadataEnabled';\nimport { useMediaLibraryPermissions } from '../../hooks/useMediaLibraryPermissions';\nimport { useTracking } from '../../hooks/useTracking';\nimport { AssetDetailsDrawer } from '../../pages/Assets/components/AssetDetails/AssetDetailsDrawer';\nimport { ImportFromUrlDialog } from '../../pages/Assets/components/ImportFromUrlDialog';\nimport { useUploadFilesMutation, useUploadFromUrlsMutation } from '../../services/api';\nimport { useGetUploadSettingsQuery } from '../../services/settings';\nimport {\n filterAllowedFiles,\n isMediaTypeAllowed,\n type AllowedMediaType,\n} from '../../utils/allowedMediaTypes';\nimport { prefixFileUrlWithBackendUrl } from '../../utils/files';\nimport { getTranslationKey } from '../../utils/translations';\nimport { typeFromMime } from '../../utils/typeFromMime';\nimport { AssetPickerDialog } from '../AssetPickerDialog/AssetPickerDialog';\n\nimport { AddAssetMenu } from './AddAssetMenu';\nimport { AssetCard, UploadCard } from './AssetCard';\nimport { AssetCarousel } from './AssetCarousel';\nimport { AssetDropZone, type ZoneVariant } from './AssetDropZone';\nimport { AssetRow, UploadRow } from './AssetRow';\nimport { isAnyAssetDetailsOpen, useOpenAssetDetails } from './openAssetDetails';\nimport { useFieldUploads, type FieldUpload } from './useFieldUploads';\n\nimport type { AssetWithPopulatedCreatedBy, File } from '../../../../shared/contracts/files';\n\n/**\n * What a field wrote that its form has not rendered yet, per form and field.\n * `getValues()` only catches up on render, and two uploads can complete before\n * the next one. Kept outside the input so it survives a remount.\n */\nconst unrenderedWrites = new WeakMap<object, Map<string, { seen: unknown; written: File[] }>>();\n\nconst toAssets = (value: unknown): File[] =>\n Array.isArray(value) ? value : value ? [value as File] : [];\n\n/**\n * `location` for every event this field fires. The standalone Media Library\n * tags its events `'upload'`; the picker inside an entry form has always been\n * `'content-manager'`, and analytics still splits the two on that axis.\n */\nconst CONTENT_MANAGER_LOCATION = 'content-manager';\n\n/**\n * Uploads from here land at the root of the Media Library. An entry form has no\n * current folder to inherit, and the field offers no destination picker — same\n * place the legacy upload wizard put them when none was chosen.\n */\nconst UPLOAD_FOLDER_ID = null;\n\ntype Step = 'browse';\n\nexport interface MediaLibraryInputProps {\n name: string;\n label?: string;\n labelAction?: ReactNode;\n hint?: string;\n required?: boolean;\n disabled?: boolean;\n attribute?: {\n allowedTypes?: AllowedMediaType[] | null;\n multiple?: boolean;\n };\n /** The field's width in the edit layout, out of 12. Set by the Content Manager. */\n layoutSize?: number;\n}\n\nconst EMPTY_ATTRIBUTE: NonNullable<MediaLibraryInputProps['attribute']> = {};\n\n/**\n * The Content Manager's `media` field, on the current Media Library stack.\n *\n * Files dropped here (or picked from the device) upload straight through\n * `uploadFiles`, which is what drives the global upload progress dialog — so the\n * entry form stays usable while they go, instead of being covered by the legacy\n * wizard.\n *\n * The legacy input is still registered when `useLegacyMediaLibrary` is on, and\n * is untouched by this.\n */\nexport const MediaLibraryInput = ({\n name,\n label,\n labelAction,\n hint,\n required = false,\n disabled = false,\n attribute = EMPTY_ATTRIBUTE,\n layoutSize,\n}: MediaLibraryInputProps) => {\n const { allowedTypes = null, multiple = false } = attribute;\n const { formatMessage } = useIntl();\n const { onChange, value, error } = useField<File | File[] | null>(name);\n const { toggleNotification } = useNotification();\n const { trackUsage } = useTracking();\n const { copy } = useClipboard();\n const getValues = useForm('MediaLibraryInput', (state) => state.getValues);\n\n const [step, setStep] = useState<Step | undefined>(undefined);\n const [editedAssetId, setEditedAssetId] = useState<number | null>(null);\n const isAnyDrawerOpen = useOpenAssetDetails(editedAssetId !== null);\n const [isUrlDialogOpen, setIsUrlDialogOpen] = useState(false);\n const fileInputRef = useRef<HTMLInputElement>(null);\n\n const [uploadFiles] = useUploadFilesMutation();\n const [uploadFromUrls] = useUploadFromUrlsMutation();\n // Echoes the app config; a missing payload (still loading) falls back to\n // sequential rather than outpacing what the server asked for.\n const { isLoading, canRead, canCreate } = useMediaLibraryPermissions();\n // Not while permissions load: `useRBAC` starts with every flag false, and an\n // upload sent before it settles can end in a 403.\n const canUpload = !isLoading && canCreate;\n const { data: settings } = useGetUploadSettingsQuery(undefined, { skip: !canRead });\n const concurrency = settings?.data?.concurrentUploadRequests ?? 1;\n const isAiMetadataEnabled = useAIMetadataEnabled();\n\n const assets: File[] = Array.isArray(value) ? value : value ? [value] : [];\n\n // An upload resumes long after the render that started it, and the dialog is\n // non-blocking precisely so a second batch can be dropped meanwhile. Reading\n // the closed-over `assets` on resume would then append to whatever the field\n // held when that drop began, dropping every asset that landed since.\n const assetsRef = useRef(assets);\n assetsRef.current = assets;\n\n const setAssets = (nextAssets: File[]) => {\n if (multiple) {\n onChange(name, nextAssets.length > 0 ? nextAssets : null);\n return;\n }\n onChange(name, nextAssets[0] ?? null);\n };\n\n const handleRemove = (asset: File) => {\n setAssets(assets.filter((current) => current.id !== asset.id));\n };\n\n // Bound to the form, not to this input: a component collapsed mid-upload\n // unmounts the field, and the file must still land on the entry.\n const attachUploadedFile = (file: File) => {\n const writes = unrenderedWrites.get(getValues) ?? new Map();\n unrenderedWrites.set(getValues, writes);\n\n const value = get(getValues(), name);\n const pending = writes.get(name);\n const current = pending && pending.seen === value ? pending.written : toAssets(value);\n const next = multiple ? [...current, file] : [file];\n\n writes.set(name, { seen: value, written: next });\n setAssets(next);\n };\n\n const { uploads, cancel, retry, dismiss } = useFieldUploads(name);\n\n const handleCopyLink = async (asset: File) => {\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 /**\n * Opens only when no drawer is open, in this field or another. Pressing a row's\n * button is a press outside the open drawer, which closes it — or, with unsaved\n * edits, asks first. Opening on the click that follows would put a second\n * drawer, or a new asset, under that question and drop the edits it is asking\n * about.\n */\n const handleEdit = (asset: File) => {\n if (!isAnyAssetDetailsOpen()) {\n setEditedAssetId(asset.id);\n }\n };\n\n // The drawer saves to the library itself; the field holds its own copy of the\n // asset, so it takes the server's after every change. Read from the ref: the\n // drawer reports after a request, by which time this render's `assets` may\n // be stale.\n const handleAssetChange = (changedAsset: AssetWithPopulatedCreatedBy) => {\n setAssets(\n assetsRef.current.map((current) =>\n // The populated `createdBy` is the one shape difference, and the entry\n // only keeps the asset's id on save.\n current.id === changedAsset.id ? (changedAsset as unknown as File) : current\n )\n );\n };\n\n // Deleting from the library leaves nothing for the field to point at.\n const handleAssetDelete = (id: number) => {\n setAssets(assetsRef.current.filter((current) => current.id !== id));\n };\n\n const handleSelect = (selectedAssets: File[]) => {\n setAssets(selectedAssets);\n setStep(undefined);\n };\n\n const notifyUnsupported = () => {\n toggleNotification({\n type: 'danger',\n timeout: 4000,\n message: formatMessage(\n {\n // Legacy key: translated everywhere, and it names the accepted types,\n // which the field already passes as `fileTypes`.\n id: getTranslationKey('input.notification.not-supported'),\n defaultMessage: `You can't upload this type of file, only the following types are accepted – {fileTypes}`,\n },\n { fileTypes: (allowedTypes ?? []).join(',') }\n ),\n });\n };\n\n /**\n * True when the batch is more than a single-value field can take. Counted on\n * what was handed in rather than on what survives filtering: uploading one of\n * several would leave the user guessing which one the field kept.\n */\n const rejectsBatch = (count: number) => {\n if (multiple || count <= 1) {\n return false;\n }\n\n toggleNotification({\n type: 'danger',\n timeout: 4000,\n message: formatMessage({\n id: getTranslationKey('content-manager.input.notification.single-file'),\n defaultMessage: 'This field accepts only one file.',\n }),\n });\n\n return true;\n };\n\n const handleUpload = (files: globalThis.File[]) => {\n if (disabled || !canUpload || files.length === 0) {\n return;\n }\n\n // The device picker can't reach this — it carries `multiple` — so a drop is\n // the only way in.\n if (rejectsBatch(files.length)) {\n return;\n }\n\n const allowedFiles = filterAllowedFiles(allowedTypes, files);\n\n if (allowedFiles.length === 0) {\n notifyUnsupported();\n return;\n }\n\n // A mixed drop uploads what it can and says so, rather than silently\n // dropping the rest.\n if (allowedFiles.length < files.length) {\n notifyUnsupported();\n }\n\n const assetsCountByType = allowedFiles.reduce<Record<string, number>>((acc, file) => {\n const type = typeFromMime(file.type);\n acc[type] = (acc[type] ?? 0) + 1;\n return acc;\n }, {});\n trackUsage('didSelectFile', { source: 'computer', location: CONTENT_MANAGER_LOCATION });\n trackUsage('willAddMediaLibraryAssets', {\n location: CONTENT_MANAGER_LOCATION,\n ...assetsCountByType,\n });\n\n startUpload(allowedFiles);\n };\n\n /**\n * Hands the files to the shared upload pool. The field picks the results up\n * from `onFileUploaded`, which also runs for retries of the same rows.\n */\n const startUpload = (allowedFiles: globalThis.File[]) => {\n const formData = new FormData();\n allowedFiles.forEach((file) => formData.append('files', file));\n formData.append(\n 'fileInfo',\n JSON.stringify(\n allowedFiles.map((file) => ({\n name: file.name,\n caption: null,\n alternativeText: null,\n folder: UPLOAD_FOLDER_ID,\n }))\n )\n );\n\n uploadFiles({\n formData,\n totalFiles: allowedFiles.length,\n concurrency,\n generateAiMetadata: Boolean(isAiMetadataEnabled),\n onFileUploaded: attachUploadedFile,\n owner: name,\n });\n };\n\n const handleRetry = (upload: FieldUpload) => retry(upload, (file) => startUpload([file]));\n\n /**\n * The server fetches each URL and uploads what it finds, so the file's type\n * is not known here — `allowedTypes` can only be enforced on what comes back.\n * A URL whose file the field does not accept is uploaded to the library and\n * left off the field, which is also what the Media Library page does with it.\n */\n const handleUrlUpload = async (urls: string[]) => {\n if (disabled || urls.length === 0 || rejectsBatch(urls.length)) {\n return;\n }\n\n trackUsage('didSelectFile', { source: 'url', location: CONTENT_MANAGER_LOCATION });\n trackUsage('willAddMediaLibraryAssets', { location: CONTENT_MANAGER_LOCATION });\n\n try {\n const { data: uploadedFiles } = await uploadFromUrls({\n urls,\n folderId: UPLOAD_FOLDER_ID,\n generateAiMetadata: Boolean(isAiMetadataEnabled),\n }).unwrap();\n\n const allowedFiles = uploadedFiles.filter((file) =>\n isMediaTypeAllowed(allowedTypes, file.mime)\n );\n const notAttachedFiles = uploadedFiles.filter((file) => !allowedFiles.includes(file));\n\n if (notAttachedFiles.length > 0) {\n toggleNotification({\n type: 'warning',\n timeout: 4000,\n message: formatMessage(\n {\n id: getTranslationKey('content-manager.input.notification.not-attached'),\n defaultMessage:\n '{fileNames} {count, plural, one {was} other {were}} added to the Media Library, but this field only accepts {fileTypes}.',\n },\n {\n fileNames: notAttachedFiles.map((file) => file.name).join(', '),\n count: notAttachedFiles.length,\n fileTypes: (allowedTypes ?? []).join(', '),\n }\n ),\n });\n }\n\n if (allowedFiles.length > 0) {\n setAssets(multiple ? [...assetsRef.current, ...allowedFiles] : [allowedFiles[0]]);\n }\n } catch {\n // Errors reach the user through the progress dialog, which the mutation\n // populates itself.\n }\n };\n\n const handleFileInputChange = (event: ChangeEvent<HTMLInputElement>) => {\n // Copied before the reset, not after: `event.target.files` is the input's\n // live FileList, and clearing `value` empties it in place. Reading it\n // afterwards yields nothing and the upload never starts.\n const files = Array.from(event.target.files ?? []);\n // Reset so picking the same file twice in a row still fires `change`.\n event.target.value = '';\n\n if (files.length > 0) {\n handleUpload(files);\n }\n };\n\n const renderValue = () => {\n const dropZone = (variant: ZoneVariant) => (\n <AssetDropZone\n variant={variant}\n disabled={disabled || !canUpload}\n onDropFiles={handleUpload}\n />\n );\n\n if (assets.length === 0 && uploads.length === 0) {\n return dropZone('bar');\n }\n\n const uploadHandlers = {\n disabled,\n onCancel: cancel,\n onRetry: handleRetry,\n onRemove: (upload: FieldUpload) => dismiss(upload.key),\n };\n\n if (!multiple) {\n // A replacement in flight, or one that failed, stands in for the current\n // asset until it lands or is removed.\n if (uploads.length > 0) {\n return (\n <Flex direction=\"column\" alignItems=\"stretch\" gap={2}>\n {uploads.map((upload) => (\n <UploadRow key={upload.key} upload={upload} {...uploadHandlers} />\n ))}\n </Flex>\n );\n }\n\n return (\n <AssetRow\n asset={assets[0]}\n disabled={disabled}\n onCopyLink={handleCopyLink}\n // The details drawer fetches the asset from the library, which needs read access.\n onEdit={canRead ? handleEdit : undefined}\n onRemove={handleRemove}\n />\n );\n }\n\n return (\n <AssetCarousel renderDropZone={dropZone} layoutSize={layoutSize}>\n {assets.map((asset) => (\n <AssetCard\n key={asset.id}\n asset={asset}\n disabled={disabled}\n onCopyLink={handleCopyLink}\n onEdit={canRead ? handleEdit : undefined}\n onRemove={handleRemove}\n />\n ))}\n {uploads.map((upload) => (\n <UploadCard key={upload.key} upload={upload} {...uploadHandlers} />\n ))}\n </AssetCarousel>\n );\n };\n\n return (\n <Field.Root name={name} error={error} hint={hint} required={required}>\n <Flex justifyContent=\"space-between\" alignItems=\"center\" gap={2}>\n <Field.Label action={labelAction}>{label}</Field.Label>\n <AddAssetMenu\n disabled={disabled}\n preventOpen={isAnyDrawerOpen}\n onBrowseLibrary={() => setStep('browse')}\n onUploadFromDevice={() => fileInputRef.current?.click()}\n onUploadFromUrl={() => setIsUrlDialogOpen(true)}\n />\n </Flex>\n\n {renderValue()}\n\n <Field.Error />\n <Field.Hint />\n\n <VisuallyHidden>\n <input\n ref={fileInputRef}\n type=\"file\"\n multiple={multiple}\n onChange={handleFileInputChange}\n tabIndex={-1}\n aria-hidden\n />\n </VisuallyHidden>\n\n {step === 'browse' && (\n <AssetPickerDialog\n open\n title={formatMessage(\n {\n id: getTranslationKey('asset-picker.title'),\n defaultMessage: 'Add asset for {fieldName}',\n },\n { fieldName: label ?? name }\n )}\n initialSelection={assets}\n multiple={multiple}\n allowedTypes={allowedTypes}\n onClose={() => setStep(undefined)}\n onConfirm={handleSelect}\n />\n )}\n\n <AssetDetailsDrawer\n assetId={editedAssetId}\n onClose={() => setEditedAssetId(null)}\n onAssetChange={handleAssetChange}\n onAssetDelete={handleAssetDelete}\n trackedLocation={CONTENT_MANAGER_LOCATION}\n />\n\n <ImportFromUrlDialog\n open={isUrlDialogOpen}\n onClose={() => setIsUrlDialogOpen(false)}\n onUpload={handleUrlUpload}\n />\n </Field.Root>\n );\n};\n"],"names":["unrenderedWrites","WeakMap","toAssets","value","Array","isArray","CONTENT_MANAGER_LOCATION","UPLOAD_FOLDER_ID","EMPTY_ATTRIBUTE","MediaLibraryInput","name","label","labelAction","hint","required","disabled","attribute","layoutSize","allowedTypes","multiple","formatMessage","useIntl","onChange","error","useField","toggleNotification","useNotification","trackUsage","useTracking","copy","useClipboard","getValues","useForm","state","step","setStep","useState","undefined","editedAssetId","setEditedAssetId","isAnyDrawerOpen","useOpenAssetDetails","isUrlDialogOpen","setIsUrlDialogOpen","fileInputRef","useRef","uploadFiles","useUploadFilesMutation","uploadFromUrls","useUploadFromUrlsMutation","isLoading","canRead","canCreate","useMediaLibraryPermissions","canUpload","data","settings","useGetUploadSettingsQuery","skip","concurrency","concurrentUploadRequests","isAiMetadataEnabled","useAIMetadataEnabled","assets","assetsRef","current","setAssets","nextAssets","length","handleRemove","asset","filter","id","attachUploadedFile","file","writes","get","Map","set","pending","seen","written","next","uploads","cancel","retry","dismiss","useFieldUploads","handleCopyLink","url","prefixFileUrlWithBackendUrl","didCopy","type","message","getTranslationKey","defaultMessage","handleEdit","isAnyAssetDetailsOpen","handleAssetChange","changedAsset","map","handleAssetDelete","handleSelect","selectedAssets","notifyUnsupported","timeout","fileTypes","join","rejectsBatch","count","handleUpload","files","allowedFiles","filterAllowedFiles","assetsCountByType","reduce","acc","typeFromMime","source","location","startUpload","formData","FormData","forEach","append","JSON","stringify","caption","alternativeText","folder","totalFiles","generateAiMetadata","Boolean","onFileUploaded","owner","handleRetry","upload","handleUrlUpload","urls","uploadedFiles","folderId","unwrap","isMediaTypeAllowed","mime","notAttachedFiles","includes","fileNames","handleFileInputChange","event","from","target","renderValue","dropZone","variant","_jsx","AssetDropZone","onDropFiles","uploadHandlers","onCancel","onRetry","onRemove","key","Flex","direction","alignItems","gap","UploadRow","AssetRow","onCopyLink","onEdit","_jsxs","AssetCarousel","renderDropZone","AssetCard","UploadCard","Field","Root","justifyContent","Label","action","AddAssetMenu","preventOpen","onBrowseLibrary","onUploadFromDevice","click","onUploadFromUrl","Error","Hint","VisuallyHidden","input","ref","tabIndex","aria-hidden","AssetPickerDialog","open","title","fieldName","initialSelection","onClose","onConfirm","AssetDetailsDrawer","assetId","onAssetChange","onAssetDelete","trackedLocation","ImportFromUrlDialog","onUpload"],"mappings":"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"}
@@ -0,0 +1,46 @@
1
+ 'use strict';
2
+
3
+ var React = require('react');
4
+
5
+ /**
6
+ * The media fields that have their asset details drawer open. An entry's media
7
+ * fields share no parent this package owns, yet a press on any of them is a
8
+ * press outside another field's open drawer — which closes it, or asks about its
9
+ * unsaved edits. Nothing should open over that, from any field.
10
+ */ const openFields = new Set();
11
+ const listeners = new Set();
12
+ const subscribe = (listener)=>{
13
+ listeners.add(listener);
14
+ return ()=>{
15
+ listeners.delete(listener);
16
+ };
17
+ };
18
+ /** Read at event time, so a handler never acts on a stale render. */ const isAnyAssetDetailsOpen = ()=>openFields.size > 0;
19
+ /**
20
+ * Registers this field's drawer while `isOpen`, and returns whether any field —
21
+ * this one included — has one open.
22
+ *
23
+ * A layout effect, not a plain one: the drawer that a press closes must be gone
24
+ * from the set before that press's click reaches the next field.
25
+ */ const useOpenAssetDetails = (isOpen)=>{
26
+ const id = React.useId();
27
+ React.useLayoutEffect(()=>{
28
+ if (!isOpen) {
29
+ return;
30
+ }
31
+ openFields.add(id);
32
+ listeners.forEach((listener)=>listener());
33
+ return ()=>{
34
+ openFields.delete(id);
35
+ listeners.forEach((listener)=>listener());
36
+ };
37
+ }, [
38
+ id,
39
+ isOpen
40
+ ]);
41
+ return React.useSyncExternalStore(subscribe, isAnyAssetDetailsOpen);
42
+ };
43
+
44
+ exports.isAnyAssetDetailsOpen = isAnyAssetDetailsOpen;
45
+ exports.useOpenAssetDetails = useOpenAssetDetails;
46
+ //# sourceMappingURL=openAssetDetails.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"openAssetDetails.js","sources":["../../../../admin/src/components/MediaLibraryInput/openAssetDetails.ts"],"sourcesContent":["import { useId, useLayoutEffect, useSyncExternalStore } from 'react';\n\n/**\n * The media fields that have their asset details drawer open. An entry's media\n * fields share no parent this package owns, yet a press on any of them is a\n * press outside another field's open drawer — which closes it, or asks about its\n * unsaved edits. Nothing should open over that, from any field.\n */\nconst openFields = new Set<string>();\nconst listeners = new Set<() => void>();\n\nconst subscribe = (listener: () => void) => {\n listeners.add(listener);\n\n return () => {\n listeners.delete(listener);\n };\n};\n\n/** Read at event time, so a handler never acts on a stale render. */\nexport const isAnyAssetDetailsOpen = () => openFields.size > 0;\n\n/**\n * Registers this field's drawer while `isOpen`, and returns whether any field —\n * this one included — has one open.\n *\n * A layout effect, not a plain one: the drawer that a press closes must be gone\n * from the set before that press's click reaches the next field.\n */\nexport const useOpenAssetDetails = (isOpen: boolean) => {\n const id = useId();\n\n useLayoutEffect(() => {\n if (!isOpen) {\n return;\n }\n\n openFields.add(id);\n listeners.forEach((listener) => listener());\n\n return () => {\n openFields.delete(id);\n listeners.forEach((listener) => listener());\n };\n }, [id, isOpen]);\n\n return useSyncExternalStore(subscribe, isAnyAssetDetailsOpen);\n};\n"],"names":["openFields","Set","listeners","subscribe","listener","add","delete","isAnyAssetDetailsOpen","size","useOpenAssetDetails","isOpen","id","useId","useLayoutEffect","forEach","useSyncExternalStore"],"mappings":";;;;AAEA;;;;;IAMA,MAAMA,aAAa,IAAIC,GAAAA,EAAAA;AACvB,MAAMC,YAAY,IAAID,GAAAA,EAAAA;AAEtB,MAAME,YAAY,CAACC,QAAAA,GAAAA;AACjBF,IAAAA,SAAAA,CAAUG,GAAG,CAACD,QAAAA,CAAAA;IAEd,OAAO,IAAA;AACLF,QAAAA,SAAAA,CAAUI,MAAM,CAACF,QAAAA,CAAAA;AACnB,IAAA,CAAA;AACF,CAAA;AAEA,sEACO,MAAMG,qBAAAA,GAAwB,IAAMP,UAAAA,CAAWQ,IAAI,GAAG;AAE7D;;;;;;IAOO,MAAMC,mBAAAA,GAAsB,CAACC,MAAAA,GAAAA;AAClC,IAAA,MAAMC,EAAAA,GAAKC,WAAAA,EAAAA;IAEXC,qBAAAA,CAAgB,IAAA;AACd,QAAA,IAAI,CAACH,MAAAA,EAAQ;AACX,YAAA;AACF,QAAA;AAEAV,QAAAA,UAAAA,CAAWK,GAAG,CAACM,EAAAA,CAAAA;QACfT,SAAAA,CAAUY,OAAO,CAAC,CAACV,QAAAA,GAAaA,QAAAA,EAAAA,CAAAA;QAEhC,OAAO,IAAA;AACLJ,YAAAA,UAAAA,CAAWM,MAAM,CAACK,EAAAA,CAAAA;YAClBT,SAAAA,CAAUY,OAAO,CAAC,CAACV,QAAAA,GAAaA,QAAAA,EAAAA,CAAAA;AAClC,QAAA,CAAA;IACF,CAAA,EAAG;AAACO,QAAAA,EAAAA;AAAID,QAAAA;AAAO,KAAA,CAAA;AAEf,IAAA,OAAOK,2BAAqBZ,SAAAA,EAAWI,qBAAAA,CAAAA;AACzC;;;;;"}
@@ -0,0 +1,43 @@
1
+ import { useId, useLayoutEffect, useSyncExternalStore } from 'react';
2
+
3
+ /**
4
+ * The media fields that have their asset details drawer open. An entry's media
5
+ * fields share no parent this package owns, yet a press on any of them is a
6
+ * press outside another field's open drawer — which closes it, or asks about its
7
+ * unsaved edits. Nothing should open over that, from any field.
8
+ */ const openFields = new Set();
9
+ const listeners = new Set();
10
+ const subscribe = (listener)=>{
11
+ listeners.add(listener);
12
+ return ()=>{
13
+ listeners.delete(listener);
14
+ };
15
+ };
16
+ /** Read at event time, so a handler never acts on a stale render. */ const isAnyAssetDetailsOpen = ()=>openFields.size > 0;
17
+ /**
18
+ * Registers this field's drawer while `isOpen`, and returns whether any field —
19
+ * this one included — has one open.
20
+ *
21
+ * A layout effect, not a plain one: the drawer that a press closes must be gone
22
+ * from the set before that press's click reaches the next field.
23
+ */ const useOpenAssetDetails = (isOpen)=>{
24
+ const id = useId();
25
+ useLayoutEffect(()=>{
26
+ if (!isOpen) {
27
+ return;
28
+ }
29
+ openFields.add(id);
30
+ listeners.forEach((listener)=>listener());
31
+ return ()=>{
32
+ openFields.delete(id);
33
+ listeners.forEach((listener)=>listener());
34
+ };
35
+ }, [
36
+ id,
37
+ isOpen
38
+ ]);
39
+ return useSyncExternalStore(subscribe, isAnyAssetDetailsOpen);
40
+ };
41
+
42
+ export { isAnyAssetDetailsOpen, useOpenAssetDetails };
43
+ //# sourceMappingURL=openAssetDetails.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"openAssetDetails.mjs","sources":["../../../../admin/src/components/MediaLibraryInput/openAssetDetails.ts"],"sourcesContent":["import { useId, useLayoutEffect, useSyncExternalStore } from 'react';\n\n/**\n * The media fields that have their asset details drawer open. An entry's media\n * fields share no parent this package owns, yet a press on any of them is a\n * press outside another field's open drawer — which closes it, or asks about its\n * unsaved edits. Nothing should open over that, from any field.\n */\nconst openFields = new Set<string>();\nconst listeners = new Set<() => void>();\n\nconst subscribe = (listener: () => void) => {\n listeners.add(listener);\n\n return () => {\n listeners.delete(listener);\n };\n};\n\n/** Read at event time, so a handler never acts on a stale render. */\nexport const isAnyAssetDetailsOpen = () => openFields.size > 0;\n\n/**\n * Registers this field's drawer while `isOpen`, and returns whether any field —\n * this one included — has one open.\n *\n * A layout effect, not a plain one: the drawer that a press closes must be gone\n * from the set before that press's click reaches the next field.\n */\nexport const useOpenAssetDetails = (isOpen: boolean) => {\n const id = useId();\n\n useLayoutEffect(() => {\n if (!isOpen) {\n return;\n }\n\n openFields.add(id);\n listeners.forEach((listener) => listener());\n\n return () => {\n openFields.delete(id);\n listeners.forEach((listener) => listener());\n };\n }, [id, isOpen]);\n\n return useSyncExternalStore(subscribe, isAnyAssetDetailsOpen);\n};\n"],"names":["openFields","Set","listeners","subscribe","listener","add","delete","isAnyAssetDetailsOpen","size","useOpenAssetDetails","isOpen","id","useId","useLayoutEffect","forEach","useSyncExternalStore"],"mappings":";;AAEA;;;;;IAMA,MAAMA,aAAa,IAAIC,GAAAA,EAAAA;AACvB,MAAMC,YAAY,IAAID,GAAAA,EAAAA;AAEtB,MAAME,YAAY,CAACC,QAAAA,GAAAA;AACjBF,IAAAA,SAAAA,CAAUG,GAAG,CAACD,QAAAA,CAAAA;IAEd,OAAO,IAAA;AACLF,QAAAA,SAAAA,CAAUI,MAAM,CAACF,QAAAA,CAAAA;AACnB,IAAA,CAAA;AACF,CAAA;AAEA,sEACO,MAAMG,qBAAAA,GAAwB,IAAMP,UAAAA,CAAWQ,IAAI,GAAG;AAE7D;;;;;;IAOO,MAAMC,mBAAAA,GAAsB,CAACC,MAAAA,GAAAA;AAClC,IAAA,MAAMC,EAAAA,GAAKC,KAAAA,EAAAA;IAEXC,eAAAA,CAAgB,IAAA;AACd,QAAA,IAAI,CAACH,MAAAA,EAAQ;AACX,YAAA;AACF,QAAA;AAEAV,QAAAA,UAAAA,CAAWK,GAAG,CAACM,EAAAA,CAAAA;QACfT,SAAAA,CAAUY,OAAO,CAAC,CAACV,QAAAA,GAAaA,QAAAA,EAAAA,CAAAA;QAEhC,OAAO,IAAA;AACLJ,YAAAA,UAAAA,CAAWM,MAAM,CAACK,EAAAA,CAAAA;YAClBT,SAAAA,CAAUY,OAAO,CAAC,CAACV,QAAAA,GAAaA,QAAAA,EAAAA,CAAAA;AAClC,QAAA,CAAA;IACF,CAAA,EAAG;AAACO,QAAAA,EAAAA;AAAID,QAAAA;AAAO,KAAA,CAAA;AAEf,IAAA,OAAOK,qBAAqBZ,SAAAA,EAAWI,qBAAAA,CAAAA;AACzC;;;;"}
@@ -2,6 +2,8 @@
2
2
 
3
3
  var icons = require('@strapi/icons');
4
4
  var _package = require('./package.json.js');
5
+ var MediaLibraryPickerDialog = require('./components/AssetPickerDialog/MediaLibraryPickerDialog.js');
6
+ var EditorFileDropZone = require('./components/EditorFileDropZone/EditorFileDropZone.js');
5
7
  var MediaLibraryInput$1 = require('./components/MediaLibraryInput/MediaLibraryInput.js');
6
8
  var UploadProgressDialog = require('./components/UploadProgressDialog.js');
7
9
  var constants = require('./constants.js');
@@ -81,6 +83,12 @@ const admin = {
81
83
  {
82
84
  name: 'future-global::upload-progress',
83
85
  Component: UploadProgressDialog.UploadProgressDialog
86
+ },
87
+ // Lets the Blocks editor take files dropped onto it. Not registered on the
88
+ // legacy Media Library, which has no upload progress dialog to report to.
89
+ {
90
+ name: 'media-library-file-drop-zone',
91
+ Component: EditorFileDropZone.EditorFileDropZone
84
92
  }
85
93
  ]);
86
94
  }
@@ -106,10 +114,11 @@ const admin = {
106
114
  type: 'media',
107
115
  Component: isLegacyMediaLibrary ? MediaLibraryInput.MediaLibraryInput : MediaLibraryInput$1.MediaLibraryInput
108
116
  });
117
+ // The picker the Wysiwyg and Blocks editors insert images with.
109
118
  app.addComponents([
110
119
  {
111
120
  name: 'media-library',
112
- Component: MediaLibraryDialog.MediaLibraryDialog
121
+ Component: isLegacyMediaLibrary ? MediaLibraryDialog.MediaLibraryDialog : MediaLibraryPickerDialog.MediaLibraryPickerDialog
113
122
  }
114
123
  ]);
115
124
  app.registerPlugin({