@strapi/upload 5.47.1 → 5.48.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.
- package/dist/admin/components/EditAssetDialog/EditAssetContent.js +12 -2
- package/dist/admin/components/EditAssetDialog/EditAssetContent.js.map +1 -1
- package/dist/admin/components/EditAssetDialog/EditAssetContent.mjs +12 -2
- package/dist/admin/components/EditAssetDialog/EditAssetContent.mjs.map +1 -1
- package/dist/admin/components/UploadAssetDialog/UploadAssetDialog.js +1 -0
- package/dist/admin/components/UploadAssetDialog/UploadAssetDialog.js.map +1 -1
- package/dist/admin/components/UploadAssetDialog/UploadAssetDialog.mjs +1 -0
- package/dist/admin/components/UploadAssetDialog/UploadAssetDialog.mjs.map +1 -1
- package/dist/admin/future/components/Drawer.js +7 -8
- package/dist/admin/future/components/Drawer.js.map +1 -1
- package/dist/admin/future/components/Drawer.mjs +7 -8
- package/dist/admin/future/components/Drawer.mjs.map +1 -1
- package/dist/admin/future/components/UploadProgressDialog.js +33 -29
- package/dist/admin/future/components/UploadProgressDialog.js.map +1 -1
- package/dist/admin/future/components/UploadProgressDialog.mjs +36 -32
- package/dist/admin/future/components/UploadProgressDialog.mjs.map +1 -1
- package/dist/admin/future/pages/Assets/AssetsPage.js +2 -2
- package/dist/admin/future/pages/Assets/AssetsPage.js.map +1 -1
- package/dist/admin/future/pages/Assets/AssetsPage.mjs +3 -3
- package/dist/admin/future/pages/Assets/AssetsPage.mjs.map +1 -1
- package/dist/admin/future/pages/Assets/components/AssetDetails/AssetDetailsDrawer.js +626 -169
- package/dist/admin/future/pages/Assets/components/AssetDetails/AssetDetailsDrawer.js.map +1 -1
- package/dist/admin/future/pages/Assets/components/AssetDetails/AssetDetailsDrawer.mjs +630 -175
- package/dist/admin/future/pages/Assets/components/AssetDetails/AssetDetailsDrawer.mjs.map +1 -1
- package/dist/admin/future/pages/Assets/components/AssetDetails/AssetPreview.js +25 -5
- package/dist/admin/future/pages/Assets/components/AssetDetails/AssetPreview.js.map +1 -1
- package/dist/admin/future/pages/Assets/components/AssetDetails/AssetPreview.mjs +25 -5
- package/dist/admin/future/pages/Assets/components/AssetDetails/AssetPreview.mjs.map +1 -1
- package/dist/admin/future/services/api.js +124 -200
- package/dist/admin/future/services/api.js.map +1 -1
- package/dist/admin/future/services/api.mjs +124 -200
- package/dist/admin/future/services/api.mjs.map +1 -1
- package/dist/admin/future/services/assets.js +57 -1
- package/dist/admin/future/services/assets.js.map +1 -1
- package/dist/admin/future/services/assets.mjs +56 -2
- package/dist/admin/future/services/assets.mjs.map +1 -1
- package/dist/admin/future/services/settings.js +18 -0
- package/dist/admin/future/services/settings.js.map +1 -0
- package/dist/admin/future/services/settings.mjs +16 -0
- package/dist/admin/future/services/settings.mjs.map +1 -0
- package/dist/admin/future/services/uploadFileViaXHR.js +92 -0
- package/dist/admin/future/services/uploadFileViaXHR.js.map +1 -0
- package/dist/admin/future/services/uploadFileViaXHR.mjs +88 -0
- package/dist/admin/future/services/uploadFileViaXHR.mjs.map +1 -0
- package/dist/admin/future/store/uploadProgress.js +32 -26
- package/dist/admin/future/store/uploadProgress.js.map +1 -1
- package/dist/admin/future/store/uploadProgress.mjs +32 -27
- package/dist/admin/future/store/uploadProgress.mjs.map +1 -1
- package/dist/admin/future/utils/createRafBatcher.js +42 -0
- package/dist/admin/future/utils/createRafBatcher.js.map +1 -0
- package/dist/admin/future/utils/createRafBatcher.mjs +40 -0
- package/dist/admin/future/utils/createRafBatcher.mjs.map +1 -0
- package/dist/admin/future/utils/downloadFile.js +19 -0
- package/dist/admin/future/utils/downloadFile.js.map +1 -0
- package/dist/admin/future/utils/downloadFile.mjs +17 -0
- package/dist/admin/future/utils/downloadFile.mjs.map +1 -0
- package/dist/admin/hooks/useAssets.js +5 -3
- package/dist/admin/hooks/useAssets.js.map +1 -1
- package/dist/admin/hooks/useAssets.mjs +5 -3
- package/dist/admin/hooks/useAssets.mjs.map +1 -1
- package/dist/admin/src/components/EditAssetDialog/EditAssetContent.d.ts +2 -1
- package/dist/admin/src/future/pages/Assets/components/AssetDetails/AssetDetailsDrawer.d.ts +15 -1
- package/dist/admin/src/future/pages/Assets/components/AssetDetails/AssetPreview.d.ts +4 -1
- package/dist/admin/src/future/services/api.d.ts +9 -8
- package/dist/admin/src/future/services/assets.d.ts +6 -1
- package/dist/admin/src/future/services/uploadFileViaXHR.d.ts +34 -0
- package/dist/admin/src/future/store/uploadProgress.d.ts +17 -4
- package/dist/admin/src/future/utils/createRafBatcher.d.ts +23 -0
- package/dist/admin/src/future/utils/downloadFile.d.ts +6 -0
- package/dist/admin/translations/en.json.js +21 -0
- package/dist/admin/translations/en.json.js.map +1 -1
- package/dist/admin/translations/en.json.mjs +21 -0
- package/dist/admin/translations/en.json.mjs.map +1 -1
- package/dist/server/controllers/admin-upload.js +69 -118
- package/dist/server/controllers/admin-upload.js.map +1 -1
- package/dist/server/controllers/admin-upload.mjs +69 -118
- package/dist/server/controllers/admin-upload.mjs.map +1 -1
- package/dist/server/routes/admin.js +2 -2
- package/dist/server/routes/admin.js.map +1 -1
- package/dist/server/routes/admin.mjs +2 -2
- package/dist/server/routes/admin.mjs.map +1 -1
- package/dist/server/services/image-manipulation.js +16 -8
- package/dist/server/services/image-manipulation.js.map +1 -1
- package/dist/server/services/image-manipulation.mjs +16 -8
- package/dist/server/services/image-manipulation.mjs.map +1 -1
- package/dist/server/services/upload.js +1 -1
- package/dist/server/services/upload.js.map +1 -1
- package/dist/server/services/upload.mjs +1 -1
- package/dist/server/services/upload.mjs.map +1 -1
- package/dist/server/src/controllers/admin-upload.d.ts +6 -8
- package/dist/server/src/controllers/admin-upload.d.ts.map +1 -1
- package/dist/server/src/controllers/index.d.ts +1 -1
- package/dist/server/src/index.d.ts +1 -1
- package/dist/server/src/services/image-manipulation.d.ts +5 -0
- package/dist/server/src/services/image-manipulation.d.ts.map +1 -1
- package/dist/server/src/services/upload.d.ts.map +1 -1
- package/dist/server/src/types.d.ts +2 -2
- package/dist/server/src/types.d.ts.map +1 -1
- package/dist/shared/contracts/files.d.ts +19 -2
- package/dist/shared/contracts/files.d.ts.map +1 -1
- package/package.json +7 -7
|
@@ -1,21 +1,40 @@
|
|
|
1
1
|
import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
|
|
2
2
|
import * as React from 'react';
|
|
3
|
-
import { useQueryParams, useNotification, Form, Blocker, getDisplayName, useField, useForm } from '@strapi/admin/strapi-admin';
|
|
4
|
-
import { VisuallyHidden, Flex, Loader, Alert, Typography, Box, Button, Field, TextInput, Tooltip, SingleSelect, SingleSelectOption } from '@strapi/design-system';
|
|
5
|
-
import { FileError, ArrowLineRight, WarningCircle } from '@strapi/icons';
|
|
3
|
+
import { useQueryParams, useNotification, Form, Blocker, getDisplayName, useField, useForm, useClipboard } from '@strapi/admin/strapi-admin';
|
|
4
|
+
import { VisuallyHidden, Flex, Loader, Alert, Typography, Box, Button, IconButton, Dialog, Field, TextInput, Tooltip, SingleSelect, SingleSelectOption } from '@strapi/design-system';
|
|
5
|
+
import { FileError, ArrowLineRight, ArrowsCounterClockwise, Trash, WarningCircle, Link, Download } from '@strapi/icons';
|
|
6
6
|
import { useIntl } from 'react-intl';
|
|
7
7
|
import { styled } from 'styled-components';
|
|
8
8
|
import { Drawer } from '../../../../components/Drawer.mjs';
|
|
9
9
|
import { AssetType } from '../../../../enums.mjs';
|
|
10
|
-
import { useGetAssetQuery, useUpdateAssetMutation } from '../../../../services/assets.mjs';
|
|
10
|
+
import { useGetAssetQuery, useUpdateAssetMutation, useReplaceAssetMutation, useDeleteAssetMutation } from '../../../../services/assets.mjs';
|
|
11
11
|
import { useGetAllFoldersQuery } from '../../../../services/folders.mjs';
|
|
12
|
-
import {
|
|
12
|
+
import { useGetSettingsQuery } from '../../../../services/settings.mjs';
|
|
13
|
+
import { downloadFile } from '../../../../utils/downloadFile.mjs';
|
|
14
|
+
import { formatBytes, getFileExtension, prefixFileUrlWithBackendUrl } from '../../../../utils/files.mjs';
|
|
13
15
|
import { getAssetIcon } from '../../../../utils/getAssetIcon.mjs';
|
|
14
16
|
import { getTranslationKey } from '../../../../utils/translations.mjs';
|
|
17
|
+
import { useFolderInfo } from '../../hooks/useFolderInfo.mjs';
|
|
15
18
|
import { AssetPreview } from './AssetPreview.mjs';
|
|
16
19
|
|
|
17
20
|
// Name of the parameter to look for in the URL to open the drawer
|
|
18
21
|
const URL_PARAM = 'assetId';
|
|
22
|
+
const DrawerNotifyContext = /*#__PURE__*/ React.createContext(null);
|
|
23
|
+
const useDrawerNotify = ()=>{
|
|
24
|
+
const ctx = React.useContext(DrawerNotifyContext);
|
|
25
|
+
if (!ctx) {
|
|
26
|
+
throw new Error('useDrawerNotify must be used within AssetDetails');
|
|
27
|
+
}
|
|
28
|
+
return ctx;
|
|
29
|
+
};
|
|
30
|
+
const AssetOperationsContext = /*#__PURE__*/ React.createContext(null);
|
|
31
|
+
const useAssetOperation = ()=>{
|
|
32
|
+
const ctx = React.useContext(AssetOperationsContext);
|
|
33
|
+
if (!ctx) {
|
|
34
|
+
throw new Error('useAssetOperation must be used within AssetDetails');
|
|
35
|
+
}
|
|
36
|
+
return ctx;
|
|
37
|
+
};
|
|
19
38
|
/* -------------------------------------------------------------------------------------------------
|
|
20
39
|
* useAssetDetailsParam - sync drawer visibility with URL ?{URL_PARAM}={id}
|
|
21
40
|
* -----------------------------------------------------------------------------------------------*/ const useAssetDetailsParam = ()=>{
|
|
@@ -95,7 +114,50 @@ const DetailItem = ({ label, value })=>/*#__PURE__*/ jsxs(DetailItemContainer, {
|
|
|
95
114
|
});
|
|
96
115
|
/* -------------------------------------------------------------------------------------------------
|
|
97
116
|
* DetailField
|
|
98
|
-
* -----------------------------------------------------------------------------------------------*/
|
|
117
|
+
* -----------------------------------------------------------------------------------------------*/ /**
|
|
118
|
+
* Make the asset details Form behave as a flex column inside Drawer.Body so
|
|
119
|
+
* the scrollable area can grow while the footer stays pinned at the bottom.
|
|
120
|
+
* The Form component from `@strapi/admin/strapi-admin` only forwards `width`
|
|
121
|
+
* + `height` to its Box, so we target the rendered `<form>` element via a
|
|
122
|
+
* styled-components descendant rule.
|
|
123
|
+
*/ const FormShell = styled(Box)`
|
|
124
|
+
display: flex;
|
|
125
|
+
flex-direction: column;
|
|
126
|
+
flex: 1;
|
|
127
|
+
min-height: 0;
|
|
128
|
+
|
|
129
|
+
> form {
|
|
130
|
+
display: flex;
|
|
131
|
+
flex-direction: column;
|
|
132
|
+
flex: 1;
|
|
133
|
+
min-height: 0;
|
|
134
|
+
position: relative;
|
|
135
|
+
}
|
|
136
|
+
`;
|
|
137
|
+
/**
|
|
138
|
+
* In-drawer toast container
|
|
139
|
+
*/ const DrawerToastSlot = styled(Box)`
|
|
140
|
+
position: absolute;
|
|
141
|
+
top: ${({ theme })=>theme.spaces[2]};
|
|
142
|
+
left: 50%;
|
|
143
|
+
transform: translateX(-50%);
|
|
144
|
+
z-index: 10;
|
|
145
|
+
width: calc(100% - ${({ theme })=>theme.spaces[2]});
|
|
146
|
+
`;
|
|
147
|
+
/**
|
|
148
|
+
* Full-form overlay rendered during long-running drawer-scoped mutations
|
|
149
|
+
* (e.g. replacing the binary). Sits above the toast slot (z-index 10) and
|
|
150
|
+
* the in-drawer Alert so the user can't interact with the form mid-flight.
|
|
151
|
+
*/ const DrawerBusyOverlay = styled(Flex)`
|
|
152
|
+
position: absolute;
|
|
153
|
+
inset: 0;
|
|
154
|
+
z-index: 20;
|
|
155
|
+
align-items: center;
|
|
156
|
+
justify-content: center;
|
|
157
|
+
background: ${({ theme })=>theme.colors.neutral0};
|
|
158
|
+
opacity: 0.7;
|
|
159
|
+
`;
|
|
160
|
+
const StyledWarning = styled(WarningCircle)`
|
|
99
161
|
width: 1.6rem;
|
|
100
162
|
height: 1.6rem;
|
|
101
163
|
|
|
@@ -168,11 +230,283 @@ const LocationField = ({ label, rootLabel, folders })=>{
|
|
|
168
230
|
]
|
|
169
231
|
});
|
|
170
232
|
};
|
|
171
|
-
|
|
233
|
+
/* -------------------------------------------------------------------------------------------------
|
|
234
|
+
* DeleteAssetButton
|
|
235
|
+
* -----------------------------------------------------------------------------------------------*/ const DeleteAssetButton = ()=>{
|
|
236
|
+
const { formatMessage } = useIntl();
|
|
237
|
+
const { deleteAsset, isDeleting } = useAssetOperation();
|
|
238
|
+
const [isOpen, setIsOpen] = React.useState(false);
|
|
239
|
+
const handleConfirm = async ()=>{
|
|
240
|
+
await deleteAsset();
|
|
241
|
+
setIsOpen(false);
|
|
242
|
+
};
|
|
243
|
+
const triggerLabel = formatMessage({
|
|
244
|
+
id: getTranslationKey('asset-details.delete.trigger'),
|
|
245
|
+
defaultMessage: 'Delete this file'
|
|
246
|
+
});
|
|
247
|
+
return /*#__PURE__*/ jsxs(Dialog.Root, {
|
|
248
|
+
open: isOpen,
|
|
249
|
+
onOpenChange: setIsOpen,
|
|
250
|
+
children: [
|
|
251
|
+
/*#__PURE__*/ jsx(Dialog.Trigger, {
|
|
252
|
+
children: /*#__PURE__*/ jsx(IconButton, {
|
|
253
|
+
withTooltip: false,
|
|
254
|
+
label: triggerLabel,
|
|
255
|
+
variant: "danger-light",
|
|
256
|
+
children: /*#__PURE__*/ jsx(Trash, {})
|
|
257
|
+
})
|
|
258
|
+
}),
|
|
259
|
+
/*#__PURE__*/ jsxs(Dialog.Content, {
|
|
260
|
+
children: [
|
|
261
|
+
/*#__PURE__*/ jsx(Dialog.Header, {
|
|
262
|
+
children: formatMessage({
|
|
263
|
+
id: getTranslationKey('asset-details.delete.title'),
|
|
264
|
+
defaultMessage: 'Delete this media file?'
|
|
265
|
+
})
|
|
266
|
+
}),
|
|
267
|
+
/*#__PURE__*/ jsx(Dialog.Body, {
|
|
268
|
+
icon: /*#__PURE__*/ jsx(WarningCircle, {
|
|
269
|
+
width: "24px",
|
|
270
|
+
height: "24px",
|
|
271
|
+
fill: "danger600"
|
|
272
|
+
}),
|
|
273
|
+
textAlign: "center",
|
|
274
|
+
children: formatMessage({
|
|
275
|
+
id: getTranslationKey('asset-details.delete.description'),
|
|
276
|
+
defaultMessage: 'This file cannot be recovered once deleted. If it is currently in use, linked content will break and image containers will be empty.'
|
|
277
|
+
})
|
|
278
|
+
}),
|
|
279
|
+
/*#__PURE__*/ jsxs(Dialog.Footer, {
|
|
280
|
+
children: [
|
|
281
|
+
/*#__PURE__*/ jsx(Dialog.Cancel, {
|
|
282
|
+
children: /*#__PURE__*/ jsx(Button, {
|
|
283
|
+
variant: "tertiary",
|
|
284
|
+
disabled: isDeleting,
|
|
285
|
+
fullWidth: true,
|
|
286
|
+
children: formatMessage({
|
|
287
|
+
id: 'app.components.Button.cancel',
|
|
288
|
+
defaultMessage: 'Cancel'
|
|
289
|
+
})
|
|
290
|
+
})
|
|
291
|
+
}),
|
|
292
|
+
/*#__PURE__*/ jsx(Dialog.Action, {
|
|
293
|
+
children: /*#__PURE__*/ jsx(Button, {
|
|
294
|
+
variant: "danger-light",
|
|
295
|
+
loading: isDeleting,
|
|
296
|
+
onClick: handleConfirm,
|
|
297
|
+
fullWidth: true,
|
|
298
|
+
children: formatMessage({
|
|
299
|
+
id: 'app.components.Button.confirm',
|
|
300
|
+
defaultMessage: 'Confirm'
|
|
301
|
+
})
|
|
302
|
+
})
|
|
303
|
+
})
|
|
304
|
+
]
|
|
305
|
+
})
|
|
306
|
+
]
|
|
307
|
+
})
|
|
308
|
+
]
|
|
309
|
+
});
|
|
310
|
+
};
|
|
311
|
+
const CopyLinkButton = ({ asset })=>{
|
|
312
|
+
const { formatMessage } = useIntl();
|
|
313
|
+
const { copy } = useClipboard();
|
|
314
|
+
const notify = useDrawerNotify();
|
|
315
|
+
const handleCopy = async ()=>{
|
|
316
|
+
const url = prefixFileUrlWithBackendUrl(asset.url);
|
|
317
|
+
if (!url) return;
|
|
318
|
+
const didCopy = await copy(url);
|
|
319
|
+
notify({
|
|
320
|
+
type: didCopy ? 'success' : 'danger',
|
|
321
|
+
message: didCopy ? formatMessage({
|
|
322
|
+
id: getTranslationKey('asset-details.copy-link.success'),
|
|
323
|
+
defaultMessage: 'Link copied.'
|
|
324
|
+
}) : formatMessage({
|
|
325
|
+
id: getTranslationKey('asset-details.copy-link.error'),
|
|
326
|
+
defaultMessage: 'Failed to copy the link.'
|
|
327
|
+
})
|
|
328
|
+
});
|
|
329
|
+
};
|
|
330
|
+
return /*#__PURE__*/ jsx(IconButton, {
|
|
331
|
+
withTooltip: false,
|
|
332
|
+
label: formatMessage({
|
|
333
|
+
id: getTranslationKey('asset-details.copy-link.trigger'),
|
|
334
|
+
defaultMessage: 'Copy link'
|
|
335
|
+
}),
|
|
336
|
+
variant: "tertiary",
|
|
337
|
+
onClick: handleCopy,
|
|
338
|
+
children: /*#__PURE__*/ jsx(Link, {})
|
|
339
|
+
});
|
|
340
|
+
};
|
|
341
|
+
const DownloadAssetButton = ({ asset })=>{
|
|
342
|
+
const { formatMessage } = useIntl();
|
|
343
|
+
const notify = useDrawerNotify();
|
|
344
|
+
const [isDownloading, setIsDownloading] = React.useState(false);
|
|
345
|
+
const handleDownload = async ()=>{
|
|
346
|
+
const url = prefixFileUrlWithBackendUrl(asset.url);
|
|
347
|
+
if (!url) return;
|
|
348
|
+
setIsDownloading(true);
|
|
349
|
+
try {
|
|
350
|
+
await downloadFile(url, asset.name);
|
|
351
|
+
} catch {
|
|
352
|
+
notify({
|
|
353
|
+
type: 'danger',
|
|
354
|
+
message: formatMessage({
|
|
355
|
+
id: getTranslationKey('asset-details.download.error'),
|
|
356
|
+
defaultMessage: 'Failed to download the file.'
|
|
357
|
+
})
|
|
358
|
+
});
|
|
359
|
+
} finally{
|
|
360
|
+
setIsDownloading(false);
|
|
361
|
+
}
|
|
362
|
+
};
|
|
363
|
+
return /*#__PURE__*/ jsx(IconButton, {
|
|
364
|
+
withTooltip: false,
|
|
365
|
+
label: formatMessage({
|
|
366
|
+
id: getTranslationKey('asset-details.download.trigger'),
|
|
367
|
+
defaultMessage: 'Download'
|
|
368
|
+
}),
|
|
369
|
+
variant: "tertiary",
|
|
370
|
+
onClick: handleDownload,
|
|
371
|
+
disabled: isDownloading,
|
|
372
|
+
children: /*#__PURE__*/ jsx(Download, {})
|
|
373
|
+
});
|
|
374
|
+
};
|
|
375
|
+
/* -------------------------------------------------------------------------------------------------
|
|
376
|
+
* ReplaceAssetButton
|
|
377
|
+
* -----------------------------------------------------------------------------------------------*/ const ReplaceAssetButton = ()=>{
|
|
378
|
+
const { formatMessage } = useIntl();
|
|
379
|
+
const { replaceAsset, isReplacing } = useAssetOperation();
|
|
380
|
+
const fileInputRef = React.useRef(null);
|
|
381
|
+
const [isDialogOpen, setIsDialogOpen] = React.useState(false);
|
|
382
|
+
const { data: settings } = useGetSettingsQuery();
|
|
383
|
+
const aiEnabled = settings?.data?.aiMetadata ?? false;
|
|
384
|
+
const handleTriggerClick = ()=>{
|
|
385
|
+
setIsDialogOpen(true);
|
|
386
|
+
};
|
|
387
|
+
const handleContinue = ()=>{
|
|
388
|
+
// Confirm first, then open the native picker so the user only commits to
|
|
389
|
+
// replacing after acknowledging the warning. The actual POST is delegated
|
|
390
|
+
// to the parent (which owns the mutation + loading state).
|
|
391
|
+
setIsDialogOpen(false);
|
|
392
|
+
fileInputRef.current?.click();
|
|
393
|
+
};
|
|
394
|
+
const handleFileChange = async (event)=>{
|
|
395
|
+
const file = event.target.files?.[0];
|
|
396
|
+
// Reset the native input so the same file can be picked again later.
|
|
397
|
+
event.target.value = '';
|
|
398
|
+
if (!file) {
|
|
399
|
+
return;
|
|
400
|
+
}
|
|
401
|
+
await replaceAsset(file);
|
|
402
|
+
};
|
|
403
|
+
return /*#__PURE__*/ jsxs(Fragment, {
|
|
404
|
+
children: [
|
|
405
|
+
/*#__PURE__*/ jsx(VisuallyHidden, {
|
|
406
|
+
children: /*#__PURE__*/ jsx("input", {
|
|
407
|
+
ref: fileInputRef,
|
|
408
|
+
type: "file",
|
|
409
|
+
multiple: false,
|
|
410
|
+
onChange: handleFileChange,
|
|
411
|
+
"aria-hidden": true,
|
|
412
|
+
tabIndex: -1
|
|
413
|
+
})
|
|
414
|
+
}),
|
|
415
|
+
/*#__PURE__*/ jsx(IconButton, {
|
|
416
|
+
withTooltip: false,
|
|
417
|
+
label: formatMessage({
|
|
418
|
+
id: getTranslationKey('asset-details.replace.trigger'),
|
|
419
|
+
defaultMessage: 'Replace this file'
|
|
420
|
+
}),
|
|
421
|
+
variant: "tertiary",
|
|
422
|
+
onClick: handleTriggerClick,
|
|
423
|
+
disabled: isReplacing,
|
|
424
|
+
children: /*#__PURE__*/ jsx(ArrowsCounterClockwise, {})
|
|
425
|
+
}),
|
|
426
|
+
/*#__PURE__*/ jsx(Dialog.Root, {
|
|
427
|
+
open: isDialogOpen,
|
|
428
|
+
onOpenChange: setIsDialogOpen,
|
|
429
|
+
children: /*#__PURE__*/ jsxs(Dialog.Content, {
|
|
430
|
+
children: [
|
|
431
|
+
/*#__PURE__*/ jsx(Dialog.Header, {
|
|
432
|
+
children: formatMessage({
|
|
433
|
+
id: getTranslationKey('asset-details.replace.title'),
|
|
434
|
+
defaultMessage: 'Replace this media file?'
|
|
435
|
+
})
|
|
436
|
+
}),
|
|
437
|
+
/*#__PURE__*/ jsx(Dialog.Body, {
|
|
438
|
+
textAlign: "center",
|
|
439
|
+
children: /*#__PURE__*/ jsxs(Flex, {
|
|
440
|
+
direction: "column",
|
|
441
|
+
textAlign: "center",
|
|
442
|
+
children: [
|
|
443
|
+
/*#__PURE__*/ jsx(Typography, {
|
|
444
|
+
variant: "omega",
|
|
445
|
+
children: formatMessage({
|
|
446
|
+
id: getTranslationKey('asset-details.replace.description'),
|
|
447
|
+
defaultMessage: 'Current content will be permanently replaced.'
|
|
448
|
+
})
|
|
449
|
+
}),
|
|
450
|
+
aiEnabled ? /*#__PURE__*/ jsx(Typography, {
|
|
451
|
+
variant: "omega",
|
|
452
|
+
children: formatMessage({
|
|
453
|
+
id: getTranslationKey('asset-details.replace.description.ai'),
|
|
454
|
+
defaultMessage: 'AI will generate new metadata after upload.'
|
|
455
|
+
})
|
|
456
|
+
}) : null
|
|
457
|
+
]
|
|
458
|
+
})
|
|
459
|
+
}),
|
|
460
|
+
/*#__PURE__*/ jsxs(Dialog.Footer, {
|
|
461
|
+
children: [
|
|
462
|
+
/*#__PURE__*/ jsx(Dialog.Cancel, {
|
|
463
|
+
children: /*#__PURE__*/ jsx(Button, {
|
|
464
|
+
variant: "tertiary",
|
|
465
|
+
fullWidth: true,
|
|
466
|
+
children: formatMessage({
|
|
467
|
+
id: 'app.components.Button.cancel',
|
|
468
|
+
defaultMessage: 'Cancel'
|
|
469
|
+
})
|
|
470
|
+
})
|
|
471
|
+
}),
|
|
472
|
+
/*#__PURE__*/ jsx(Dialog.Action, {
|
|
473
|
+
children: /*#__PURE__*/ jsx(Button, {
|
|
474
|
+
variant: "secondary",
|
|
475
|
+
onClick: handleContinue,
|
|
476
|
+
fullWidth: true,
|
|
477
|
+
children: formatMessage({
|
|
478
|
+
id: getTranslationKey('asset-details.replace.continue'),
|
|
479
|
+
defaultMessage: 'Continue'
|
|
480
|
+
})
|
|
481
|
+
})
|
|
482
|
+
})
|
|
483
|
+
]
|
|
484
|
+
})
|
|
485
|
+
]
|
|
486
|
+
})
|
|
487
|
+
})
|
|
488
|
+
]
|
|
489
|
+
});
|
|
490
|
+
};
|
|
491
|
+
const AssetDetails = ({ asset, closeDetails })=>{
|
|
172
492
|
const { formatMessage, formatDate } = useIntl();
|
|
173
|
-
const { toggleNotification } = useNotification();
|
|
174
493
|
const { data: folders = [] } = useGetAllFoldersQuery();
|
|
494
|
+
const { toggleNotification } = useNotification();
|
|
175
495
|
const [updateAsset] = useUpdateAssetMutation();
|
|
496
|
+
const [replaceMutation, { isLoading: isReplacing }] = useReplaceAssetMutation();
|
|
497
|
+
const [deleteMutation, { isLoading: isDeleting }] = useDeleteAssetMutation();
|
|
498
|
+
// In-drawer toast slot
|
|
499
|
+
const [drawerToast, setDrawerToast] = React.useState(null);
|
|
500
|
+
React.useEffect(()=>{
|
|
501
|
+
if (!drawerToast) return;
|
|
502
|
+
const timer = window.setTimeout(()=>setDrawerToast(null), 5000);
|
|
503
|
+
return ()=>window.clearTimeout(timer);
|
|
504
|
+
}, [
|
|
505
|
+
drawerToast
|
|
506
|
+
]);
|
|
507
|
+
// Local alias matching the DrawerNotifyContext signature, so the drawer's
|
|
508
|
+
// own handlers (replace, update) read like the consumers do.
|
|
509
|
+
const notify = React.useCallback((toast)=>setDrawerToast(toast), []);
|
|
176
510
|
const isImage = asset.mime?.includes(AssetType.Image);
|
|
177
511
|
const initialValues = {
|
|
178
512
|
name: asset.name ?? '',
|
|
@@ -191,7 +525,7 @@ const AssetDetails = ({ asset })=>{
|
|
|
191
525
|
}
|
|
192
526
|
});
|
|
193
527
|
if ('error' in res) {
|
|
194
|
-
|
|
528
|
+
notify({
|
|
195
529
|
type: 'danger',
|
|
196
530
|
message: formatMessage({
|
|
197
531
|
id: getTranslationKey('asset-details.update.error'),
|
|
@@ -200,7 +534,7 @@ const AssetDetails = ({ asset })=>{
|
|
|
200
534
|
});
|
|
201
535
|
return;
|
|
202
536
|
}
|
|
203
|
-
|
|
537
|
+
notify({
|
|
204
538
|
type: 'success',
|
|
205
539
|
message: formatMessage({
|
|
206
540
|
id: getTranslationKey('asset-details.update.success'),
|
|
@@ -208,168 +542,292 @@ const AssetDetails = ({ asset })=>{
|
|
|
208
542
|
})
|
|
209
543
|
});
|
|
210
544
|
};
|
|
545
|
+
const { title: folderName } = useFolderInfo(typeof asset.folder === 'object' && asset.folder !== null ? asset.folder.id ?? null : asset.folder ?? null);
|
|
546
|
+
// Owns the replace upload so isReplacing can drive the busy overlay.
|
|
547
|
+
const handleReplace = async (file)=>{
|
|
548
|
+
const res = await replaceMutation({
|
|
549
|
+
id: asset.id,
|
|
550
|
+
file
|
|
551
|
+
});
|
|
552
|
+
if ('error' in res) {
|
|
553
|
+
const error = res.error;
|
|
554
|
+
const message = error?.data?.error?.message ?? error?.data?.message ?? formatMessage({
|
|
555
|
+
id: getTranslationKey('asset-details.replace.error'),
|
|
556
|
+
defaultMessage: 'Failed to replace the file.'
|
|
557
|
+
});
|
|
558
|
+
notify({
|
|
559
|
+
type: 'danger',
|
|
560
|
+
message
|
|
561
|
+
});
|
|
562
|
+
return;
|
|
563
|
+
}
|
|
564
|
+
notify({
|
|
565
|
+
type: 'success',
|
|
566
|
+
message: formatMessage({
|
|
567
|
+
id: getTranslationKey('asset-details.replace.success'),
|
|
568
|
+
defaultMessage: 'File replaced.'
|
|
569
|
+
})
|
|
570
|
+
});
|
|
571
|
+
};
|
|
572
|
+
// Owns the delete: on error notify in-drawer (drawer stays), on success fire
|
|
573
|
+
// a persistent global notification then close the drawer.
|
|
574
|
+
const handleDelete = async ()=>{
|
|
575
|
+
const res = await deleteMutation(asset.id);
|
|
576
|
+
if ('error' in res) {
|
|
577
|
+
const error = res.error;
|
|
578
|
+
const message = error?.data?.error?.message ?? error?.data?.message ?? formatMessage({
|
|
579
|
+
id: getTranslationKey('asset-details.delete.error'),
|
|
580
|
+
defaultMessage: 'Failed to delete the asset.'
|
|
581
|
+
});
|
|
582
|
+
notify({
|
|
583
|
+
type: 'danger',
|
|
584
|
+
message
|
|
585
|
+
});
|
|
586
|
+
return;
|
|
587
|
+
}
|
|
588
|
+
toggleNotification({
|
|
589
|
+
type: 'success',
|
|
590
|
+
message: formatMessage({
|
|
591
|
+
id: getTranslationKey('asset-details.delete.success'),
|
|
592
|
+
defaultMessage: '1 element have been deleted from {folderName}'
|
|
593
|
+
}, {
|
|
594
|
+
folderName
|
|
595
|
+
})
|
|
596
|
+
});
|
|
597
|
+
closeDetails();
|
|
598
|
+
};
|
|
599
|
+
const operations = React.useMemo(()=>({
|
|
600
|
+
replaceAsset: handleReplace,
|
|
601
|
+
deleteAsset: handleDelete,
|
|
602
|
+
isReplacing,
|
|
603
|
+
isDeleting
|
|
604
|
+
}), // handleReplace / handleDelete close over asset+mutations and don't need a
|
|
605
|
+
// stable identity here; the consumers re-render with the new context value.
|
|
606
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
607
|
+
[
|
|
608
|
+
isReplacing,
|
|
609
|
+
isDeleting
|
|
610
|
+
]);
|
|
211
611
|
return(// `key={asset.id}` resets the form when the drawer switches to a different
|
|
212
612
|
// asset so cached values from the previous asset don't bleed in.
|
|
213
|
-
/*#__PURE__*/ jsx(
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
paddingTop: 4,
|
|
229
|
-
paddingBottom: 4,
|
|
230
|
-
paddingLeft: 5,
|
|
231
|
-
paddingRight: 5,
|
|
232
|
-
children: [
|
|
233
|
-
/*#__PURE__*/ jsx(Typography, {
|
|
234
|
-
variant: "beta",
|
|
235
|
-
fontWeight: "semiBold",
|
|
236
|
-
tag: "h3",
|
|
237
|
-
children: formatMessage({
|
|
238
|
-
id: getTranslationKey('asset-details.fileInfo'),
|
|
239
|
-
defaultMessage: 'File info'
|
|
240
|
-
})
|
|
241
|
-
}),
|
|
242
|
-
/*#__PURE__*/ jsxs(Flex, {
|
|
243
|
-
wrap: "wrap",
|
|
244
|
-
gap: 4,
|
|
245
|
-
background: "neutral100",
|
|
246
|
-
paddingTop: 4,
|
|
247
|
-
paddingBottom: 4,
|
|
248
|
-
paddingLeft: 6,
|
|
249
|
-
paddingRight: 6,
|
|
250
|
-
alignItems: "flex-start",
|
|
251
|
-
children: [
|
|
252
|
-
/*#__PURE__*/ jsx(DetailItem, {
|
|
253
|
-
label: formatMessage({
|
|
254
|
-
id: getTranslationKey('asset-details.creationDate'),
|
|
255
|
-
defaultMessage: 'Creation date'
|
|
256
|
-
}),
|
|
257
|
-
value: asset.createdAt ? formatDate(new Date(asset.createdAt), {
|
|
258
|
-
dateStyle: 'long',
|
|
259
|
-
timeStyle: 'short'
|
|
260
|
-
}) : null
|
|
261
|
-
}),
|
|
262
|
-
/*#__PURE__*/ jsx(DetailItem, {
|
|
263
|
-
label: formatMessage({
|
|
264
|
-
id: getTranslationKey('asset-details.lastUpdated'),
|
|
265
|
-
defaultMessage: 'Last updated'
|
|
266
|
-
}),
|
|
267
|
-
value: asset.updatedAt ? formatDate(new Date(asset.updatedAt), {
|
|
268
|
-
dateStyle: 'long',
|
|
269
|
-
timeStyle: 'short'
|
|
270
|
-
}) : null
|
|
271
|
-
}),
|
|
272
|
-
/*#__PURE__*/ jsx(DetailItem, {
|
|
273
|
-
label: formatMessage({
|
|
274
|
-
id: getTranslationKey('asset-details.createdBy'),
|
|
275
|
-
defaultMessage: 'Created by'
|
|
276
|
-
}),
|
|
277
|
-
value: asset.createdBy ? getDisplayName({
|
|
278
|
-
firstname: asset.createdBy.firstname ?? undefined,
|
|
279
|
-
lastname: asset.createdBy.lastname ?? undefined,
|
|
280
|
-
username: asset.createdBy.username ?? undefined,
|
|
281
|
-
email: asset.createdBy.email ?? undefined
|
|
282
|
-
}) ?? '-' : null
|
|
283
|
-
}),
|
|
284
|
-
/*#__PURE__*/ jsx(DetailItem, {
|
|
285
|
-
label: formatMessage({
|
|
286
|
-
id: getTranslationKey('asset-details.size'),
|
|
287
|
-
defaultMessage: 'Size'
|
|
288
|
-
}),
|
|
289
|
-
value: asset.size ? formatBytes(asset.size, 1) : null
|
|
290
|
-
}),
|
|
291
|
-
isImage && (asset.width != null || asset.height != null) && /*#__PURE__*/ jsx(DetailItem, {
|
|
292
|
-
label: formatMessage({
|
|
293
|
-
id: getTranslationKey('asset-details.dimensions'),
|
|
294
|
-
defaultMessage: 'Dimensions'
|
|
295
|
-
}),
|
|
296
|
-
value: asset.width != null && asset.height != null ? `${asset.width} × ${asset.height}` : null
|
|
297
|
-
}),
|
|
298
|
-
/*#__PURE__*/ jsx(DetailItem, {
|
|
299
|
-
label: formatMessage({
|
|
300
|
-
id: getTranslationKey('asset-details.extension'),
|
|
301
|
-
defaultMessage: 'Extension'
|
|
302
|
-
}),
|
|
303
|
-
value: getFileExtension(asset.ext)
|
|
304
|
-
}),
|
|
305
|
-
/*#__PURE__*/ jsx(DetailItem, {
|
|
306
|
-
label: formatMessage({
|
|
307
|
-
id: getTranslationKey('asset-details.assetId'),
|
|
308
|
-
defaultMessage: 'Asset ID'
|
|
309
|
-
}),
|
|
310
|
-
value: String(asset.id)
|
|
311
|
-
})
|
|
312
|
-
]
|
|
313
|
-
}),
|
|
314
|
-
/*#__PURE__*/ jsx(DetailField, {
|
|
315
|
-
name: "name",
|
|
316
|
-
label: formatMessage({
|
|
317
|
-
id: getTranslationKey('asset-details.fileName'),
|
|
318
|
-
defaultMessage: 'File name'
|
|
319
|
-
}),
|
|
320
|
-
required: true
|
|
321
|
-
}),
|
|
322
|
-
/*#__PURE__*/ jsx(LocationField, {
|
|
323
|
-
label: formatMessage({
|
|
324
|
-
id: getTranslationKey('asset-details.location'),
|
|
325
|
-
defaultMessage: 'Location'
|
|
326
|
-
}),
|
|
327
|
-
rootLabel: formatMessage({
|
|
328
|
-
id: getTranslationKey('plugin.home'),
|
|
329
|
-
defaultMessage: 'Home'
|
|
613
|
+
/*#__PURE__*/ jsx(DrawerNotifyContext.Provider, {
|
|
614
|
+
value: notify,
|
|
615
|
+
children: /*#__PURE__*/ jsx(AssetOperationsContext.Provider, {
|
|
616
|
+
value: operations,
|
|
617
|
+
children: /*#__PURE__*/ jsx(FormShell, {
|
|
618
|
+
children: /*#__PURE__*/ jsx(Form, {
|
|
619
|
+
method: "POST",
|
|
620
|
+
initialValues: initialValues,
|
|
621
|
+
onSubmit: handleSubmit,
|
|
622
|
+
children: ({ modified, isSubmitting, values, resetForm })=>{
|
|
623
|
+
const nameIsEmpty = (values.name ?? '').trim() === '';
|
|
624
|
+
return /*#__PURE__*/ jsxs(Fragment, {
|
|
625
|
+
children: [
|
|
626
|
+
/*#__PURE__*/ jsx(Blocker, {
|
|
627
|
+
onProceed: resetForm
|
|
330
628
|
}),
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
name: "caption",
|
|
337
|
-
label: formatMessage({
|
|
338
|
-
id: getTranslationKey('asset-details.caption'),
|
|
339
|
-
defaultMessage: 'Caption'
|
|
340
|
-
})
|
|
341
|
-
}),
|
|
342
|
-
/*#__PURE__*/ jsx(DetailField, {
|
|
343
|
-
name: "alternativeText",
|
|
344
|
-
label: formatMessage({
|
|
345
|
-
id: getTranslationKey('asset-details.alternativeText'),
|
|
346
|
-
defaultMessage: 'Alternative text'
|
|
629
|
+
isReplacing || isDeleting ? /*#__PURE__*/ jsx(DrawerBusyOverlay, {
|
|
630
|
+
children: /*#__PURE__*/ jsx(Loader, {
|
|
631
|
+
children: formatMessage({
|
|
632
|
+
id: getTranslationKey(isDeleting ? 'asset-details.delete.loading' : 'asset-details.replace.loading'),
|
|
633
|
+
defaultMessage: isDeleting ? 'Deleting the file…' : 'Replacing the file…'
|
|
347
634
|
})
|
|
348
635
|
})
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
// File name is required; block submit when it's empty or whitespace so the API can't 400 on a blank value.
|
|
360
|
-
disabled: !modified || isSubmitting || nameIsEmpty,
|
|
361
|
-
children: formatMessage({
|
|
362
|
-
id: getTranslationKey('asset-details.save'),
|
|
363
|
-
defaultMessage: 'Save changes'
|
|
636
|
+
}) : null,
|
|
637
|
+
drawerToast ? /*#__PURE__*/ jsx(DrawerToastSlot, {
|
|
638
|
+
children: /*#__PURE__*/ jsx(Alert, {
|
|
639
|
+
variant: drawerToast.type === 'success' ? 'success' : 'danger',
|
|
640
|
+
closeLabel: formatMessage({
|
|
641
|
+
id: 'global.close',
|
|
642
|
+
defaultMessage: 'Close'
|
|
643
|
+
}),
|
|
644
|
+
onClose: ()=>setDrawerToast(null),
|
|
645
|
+
children: drawerToast.message
|
|
364
646
|
})
|
|
647
|
+
}) : null,
|
|
648
|
+
/*#__PURE__*/ jsxs(Drawer.ScrollableContent, {
|
|
649
|
+
children: [
|
|
650
|
+
/*#__PURE__*/ jsx(AssetPreview, {
|
|
651
|
+
asset: asset,
|
|
652
|
+
actions: isImage ? /*#__PURE__*/ jsx(Flex, {
|
|
653
|
+
direction: "column",
|
|
654
|
+
gap: 2,
|
|
655
|
+
children: /*#__PURE__*/ jsx(ReplaceAssetButton, {})
|
|
656
|
+
}) : null
|
|
657
|
+
}),
|
|
658
|
+
/*#__PURE__*/ jsxs(Flex, {
|
|
659
|
+
direction: "column",
|
|
660
|
+
alignItems: "stretch",
|
|
661
|
+
gap: 4,
|
|
662
|
+
paddingTop: 4,
|
|
663
|
+
paddingBottom: 4,
|
|
664
|
+
paddingLeft: 5,
|
|
665
|
+
paddingRight: 5,
|
|
666
|
+
children: [
|
|
667
|
+
/*#__PURE__*/ jsx(Typography, {
|
|
668
|
+
variant: "beta",
|
|
669
|
+
fontWeight: "semiBold",
|
|
670
|
+
tag: "h3",
|
|
671
|
+
children: formatMessage({
|
|
672
|
+
id: getTranslationKey('asset-details.fileInfo'),
|
|
673
|
+
defaultMessage: 'File info'
|
|
674
|
+
})
|
|
675
|
+
}),
|
|
676
|
+
/*#__PURE__*/ jsxs(Flex, {
|
|
677
|
+
wrap: "wrap",
|
|
678
|
+
gap: 4,
|
|
679
|
+
background: "neutral100",
|
|
680
|
+
paddingTop: 4,
|
|
681
|
+
paddingBottom: 4,
|
|
682
|
+
paddingLeft: 6,
|
|
683
|
+
paddingRight: 6,
|
|
684
|
+
alignItems: "flex-start",
|
|
685
|
+
children: [
|
|
686
|
+
/*#__PURE__*/ jsx(DetailItem, {
|
|
687
|
+
label: formatMessage({
|
|
688
|
+
id: getTranslationKey('asset-details.creationDate'),
|
|
689
|
+
defaultMessage: 'Creation date'
|
|
690
|
+
}),
|
|
691
|
+
value: asset.createdAt ? formatDate(new Date(asset.createdAt), {
|
|
692
|
+
dateStyle: 'long',
|
|
693
|
+
timeStyle: 'short'
|
|
694
|
+
}) : null
|
|
695
|
+
}),
|
|
696
|
+
/*#__PURE__*/ jsx(DetailItem, {
|
|
697
|
+
label: formatMessage({
|
|
698
|
+
id: getTranslationKey('asset-details.lastUpdated'),
|
|
699
|
+
defaultMessage: 'Last updated'
|
|
700
|
+
}),
|
|
701
|
+
value: asset.updatedAt ? formatDate(new Date(asset.updatedAt), {
|
|
702
|
+
dateStyle: 'long',
|
|
703
|
+
timeStyle: 'short'
|
|
704
|
+
}) : null
|
|
705
|
+
}),
|
|
706
|
+
/*#__PURE__*/ jsx(DetailItem, {
|
|
707
|
+
label: formatMessage({
|
|
708
|
+
id: getTranslationKey('asset-details.createdBy'),
|
|
709
|
+
defaultMessage: 'Created by'
|
|
710
|
+
}),
|
|
711
|
+
value: asset.createdBy ? getDisplayName({
|
|
712
|
+
firstname: asset.createdBy.firstname ?? undefined,
|
|
713
|
+
lastname: asset.createdBy.lastname ?? undefined,
|
|
714
|
+
username: asset.createdBy.username ?? undefined,
|
|
715
|
+
email: asset.createdBy.email ?? undefined
|
|
716
|
+
}) ?? '-' : null
|
|
717
|
+
}),
|
|
718
|
+
/*#__PURE__*/ jsx(DetailItem, {
|
|
719
|
+
label: formatMessage({
|
|
720
|
+
id: getTranslationKey('asset-details.size'),
|
|
721
|
+
defaultMessage: 'Size'
|
|
722
|
+
}),
|
|
723
|
+
value: asset.size ? formatBytes(asset.size, 1) : null
|
|
724
|
+
}),
|
|
725
|
+
isImage && (asset.width != null || asset.height != null) && /*#__PURE__*/ jsx(DetailItem, {
|
|
726
|
+
label: formatMessage({
|
|
727
|
+
id: getTranslationKey('asset-details.dimensions'),
|
|
728
|
+
defaultMessage: 'Dimensions'
|
|
729
|
+
}),
|
|
730
|
+
value: asset.width != null && asset.height != null ? `${asset.width} × ${asset.height}` : null
|
|
731
|
+
}),
|
|
732
|
+
/*#__PURE__*/ jsx(DetailItem, {
|
|
733
|
+
label: formatMessage({
|
|
734
|
+
id: getTranslationKey('asset-details.extension'),
|
|
735
|
+
defaultMessage: 'Extension'
|
|
736
|
+
}),
|
|
737
|
+
value: getFileExtension(asset.ext)
|
|
738
|
+
}),
|
|
739
|
+
/*#__PURE__*/ jsx(DetailItem, {
|
|
740
|
+
label: formatMessage({
|
|
741
|
+
id: getTranslationKey('asset-details.assetId'),
|
|
742
|
+
defaultMessage: 'Asset ID'
|
|
743
|
+
}),
|
|
744
|
+
value: String(asset.id)
|
|
745
|
+
})
|
|
746
|
+
]
|
|
747
|
+
}),
|
|
748
|
+
/*#__PURE__*/ jsx(DetailField, {
|
|
749
|
+
name: "name",
|
|
750
|
+
label: formatMessage({
|
|
751
|
+
id: getTranslationKey('asset-details.fileName'),
|
|
752
|
+
defaultMessage: 'File name'
|
|
753
|
+
}),
|
|
754
|
+
required: true
|
|
755
|
+
}),
|
|
756
|
+
/*#__PURE__*/ jsx(LocationField, {
|
|
757
|
+
label: formatMessage({
|
|
758
|
+
id: getTranslationKey('asset-details.location'),
|
|
759
|
+
defaultMessage: 'Location'
|
|
760
|
+
}),
|
|
761
|
+
rootLabel: formatMessage({
|
|
762
|
+
id: getTranslationKey('plugin.home'),
|
|
763
|
+
defaultMessage: 'Home'
|
|
764
|
+
}),
|
|
765
|
+
folders: folders
|
|
766
|
+
}),
|
|
767
|
+
isImage && /*#__PURE__*/ jsxs(Fragment, {
|
|
768
|
+
children: [
|
|
769
|
+
/*#__PURE__*/ jsx(DetailField, {
|
|
770
|
+
name: "caption",
|
|
771
|
+
label: formatMessage({
|
|
772
|
+
id: getTranslationKey('asset-details.caption'),
|
|
773
|
+
defaultMessage: 'Caption'
|
|
774
|
+
})
|
|
775
|
+
}),
|
|
776
|
+
/*#__PURE__*/ jsx(DetailField, {
|
|
777
|
+
name: "alternativeText",
|
|
778
|
+
label: formatMessage({
|
|
779
|
+
id: getTranslationKey('asset-details.alternativeText'),
|
|
780
|
+
defaultMessage: 'Alternative text'
|
|
781
|
+
})
|
|
782
|
+
})
|
|
783
|
+
]
|
|
784
|
+
})
|
|
785
|
+
]
|
|
786
|
+
})
|
|
787
|
+
]
|
|
788
|
+
}),
|
|
789
|
+
/*#__PURE__*/ jsxs(Flex, {
|
|
790
|
+
justifyContent: "space-between",
|
|
791
|
+
alignItems: "center",
|
|
792
|
+
gap: 2,
|
|
793
|
+
padding: 3,
|
|
794
|
+
borderColor: "neutral150",
|
|
795
|
+
borderStyle: "solid",
|
|
796
|
+
borderWidth: "1px 0 0 0",
|
|
797
|
+
background: "neutral0",
|
|
798
|
+
children: [
|
|
799
|
+
/*#__PURE__*/ jsxs(Flex, {
|
|
800
|
+
gap: 2,
|
|
801
|
+
children: [
|
|
802
|
+
/*#__PURE__*/ jsx(DeleteAssetButton, {}),
|
|
803
|
+
/*#__PURE__*/ jsx(CopyLinkButton, {
|
|
804
|
+
asset: asset
|
|
805
|
+
}),
|
|
806
|
+
/*#__PURE__*/ jsx(DownloadAssetButton, {
|
|
807
|
+
asset: asset
|
|
808
|
+
})
|
|
809
|
+
]
|
|
810
|
+
}),
|
|
811
|
+
/*#__PURE__*/ jsx(Button, {
|
|
812
|
+
type: "submit",
|
|
813
|
+
variant: "default",
|
|
814
|
+
loading: isSubmitting,
|
|
815
|
+
// File name is required; block submit when it's empty or whitespace so the API can't 400 on a blank value.
|
|
816
|
+
disabled: !modified || isSubmitting || nameIsEmpty,
|
|
817
|
+
children: formatMessage({
|
|
818
|
+
id: getTranslationKey('asset-details.save'),
|
|
819
|
+
defaultMessage: 'Save changes'
|
|
820
|
+
})
|
|
821
|
+
})
|
|
822
|
+
]
|
|
365
823
|
})
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
}
|
|
369
|
-
|
|
370
|
-
})
|
|
371
|
-
}
|
|
372
|
-
}
|
|
824
|
+
]
|
|
825
|
+
});
|
|
826
|
+
}
|
|
827
|
+
}, asset.id)
|
|
828
|
+
})
|
|
829
|
+
})
|
|
830
|
+
}));
|
|
373
831
|
};
|
|
374
832
|
const DrawerHeader = ({ asset, closeDetails })=>{
|
|
375
833
|
const DocIcon = asset ? getAssetIcon(asset.mime, asset.ext) : FileError;
|
|
@@ -379,6 +837,9 @@ const DrawerHeader = ({ asset, closeDetails })=>{
|
|
|
379
837
|
paddingTop: 3,
|
|
380
838
|
paddingBottom: 3,
|
|
381
839
|
paddingRight: 3,
|
|
840
|
+
borderColor: "neutral150",
|
|
841
|
+
borderStyle: "solid",
|
|
842
|
+
borderWidth: "0 0 1px 0",
|
|
382
843
|
children: [
|
|
383
844
|
/*#__PURE__*/ jsx(DocIcon, {
|
|
384
845
|
width: 20,
|
|
@@ -450,15 +911,9 @@ const DrawerContent = ({ assetId, closeDetails })=>{
|
|
|
450
911
|
asset: asset,
|
|
451
912
|
closeDetails: closeDetails
|
|
452
913
|
}),
|
|
453
|
-
/*#__PURE__*/
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
asset: asset
|
|
457
|
-
}),
|
|
458
|
-
/*#__PURE__*/ jsx(AssetDetails, {
|
|
459
|
-
asset: asset
|
|
460
|
-
})
|
|
461
|
-
]
|
|
914
|
+
/*#__PURE__*/ jsx(AssetDetails, {
|
|
915
|
+
asset: asset,
|
|
916
|
+
closeDetails: closeDetails
|
|
462
917
|
})
|
|
463
918
|
]
|
|
464
919
|
});
|
|
@@ -507,5 +962,5 @@ const DrawerContent = ({ assetId, closeDetails })=>{
|
|
|
507
962
|
});
|
|
508
963
|
};
|
|
509
964
|
|
|
510
|
-
export { AssetDetails, AssetDetailsDrawer, useAssetDetailsParam };
|
|
965
|
+
export { AssetDetails, AssetDetailsDrawer, AssetOperationsContext, DrawerNotifyContext, useAssetDetailsParam };
|
|
511
966
|
//# sourceMappingURL=AssetDetailsDrawer.mjs.map
|