@strapi/upload 5.56.0 → 5.57.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/hooks/useTracking.js +2 -8
- package/dist/admin/hooks/useTracking.js.map +1 -1
- package/dist/admin/hooks/useTracking.mjs +3 -8
- package/dist/admin/hooks/useTracking.mjs.map +1 -1
- package/dist/admin/legacy/hooks/useTracking.js +3 -1
- package/dist/admin/legacy/hooks/useTracking.js.map +1 -1
- package/dist/admin/legacy/hooks/useTracking.mjs +3 -1
- package/dist/admin/legacy/hooks/useTracking.mjs.map +1 -1
- package/dist/admin/legacy/pages/App/ConfigureTheView/ConfigureTheView.js +2 -1
- package/dist/admin/legacy/pages/App/ConfigureTheView/ConfigureTheView.js.map +1 -1
- package/dist/admin/legacy/pages/App/ConfigureTheView/ConfigureTheView.mjs +2 -1
- package/dist/admin/legacy/pages/App/ConfigureTheView/ConfigureTheView.mjs.map +1 -1
- package/dist/admin/legacy/pages/App/MediaLibrary.js +2 -1
- package/dist/admin/legacy/pages/App/MediaLibrary.js.map +1 -1
- package/dist/admin/legacy/pages/App/MediaLibrary.mjs +2 -1
- package/dist/admin/legacy/pages/App/MediaLibrary.mjs.map +1 -1
- package/dist/admin/pages/Assets/AssetsPage.js +24 -12
- package/dist/admin/pages/Assets/AssetsPage.js.map +1 -1
- package/dist/admin/pages/Assets/AssetsPage.mjs +25 -13
- package/dist/admin/pages/Assets/AssetsPage.mjs.map +1 -1
- package/dist/admin/pages/Assets/components/AssetActions.js +326 -0
- package/dist/admin/pages/Assets/components/AssetActions.js.map +1 -0
- package/dist/admin/pages/Assets/components/AssetActions.mjs +324 -0
- package/dist/admin/pages/Assets/components/AssetActions.mjs.map +1 -0
- package/dist/admin/pages/Assets/components/AssetActionsMenu.js +28 -309
- package/dist/admin/pages/Assets/components/AssetActionsMenu.js.map +1 -1
- package/dist/admin/pages/Assets/components/AssetActionsMenu.mjs +31 -312
- package/dist/admin/pages/Assets/components/AssetActionsMenu.mjs.map +1 -1
- package/dist/admin/pages/Assets/components/AssetContextMenu.js +79 -0
- package/dist/admin/pages/Assets/components/AssetContextMenu.js.map +1 -0
- package/dist/admin/pages/Assets/components/AssetContextMenu.mjs +77 -0
- package/dist/admin/pages/Assets/components/AssetContextMenu.mjs.map +1 -0
- package/dist/admin/pages/Assets/components/AssetDetails/AssetCropEditor.js +87 -5
- package/dist/admin/pages/Assets/components/AssetDetails/AssetCropEditor.js.map +1 -1
- package/dist/admin/pages/Assets/components/AssetDetails/AssetCropEditor.mjs +89 -7
- package/dist/admin/pages/Assets/components/AssetDetails/AssetCropEditor.mjs.map +1 -1
- package/dist/admin/pages/Assets/components/AssetDetails/AssetDetailsDrawer.js +3 -3
- package/dist/admin/pages/Assets/components/AssetDetails/AssetDetailsDrawer.js.map +1 -1
- package/dist/admin/pages/Assets/components/AssetDetails/AssetDetailsDrawer.mjs +3 -3
- package/dist/admin/pages/Assets/components/AssetDetails/AssetDetailsDrawer.mjs.map +1 -1
- package/dist/admin/pages/Assets/components/AssetDetails/useCropImg.js +62 -5
- package/dist/admin/pages/Assets/components/AssetDetails/useCropImg.js.map +1 -1
- package/dist/admin/pages/Assets/components/AssetDetails/useCropImg.mjs +60 -6
- package/dist/admin/pages/Assets/components/AssetDetails/useCropImg.mjs.map +1 -1
- package/dist/admin/pages/Assets/components/AssetsGrid.js +27 -4
- package/dist/admin/pages/Assets/components/AssetsGrid.js.map +1 -1
- package/dist/admin/pages/Assets/components/AssetsGrid.mjs +27 -4
- package/dist/admin/pages/Assets/components/AssetsGrid.mjs.map +1 -1
- package/dist/admin/pages/Assets/components/AssetsTable.js +27 -4
- package/dist/admin/pages/Assets/components/AssetsTable.js.map +1 -1
- package/dist/admin/pages/Assets/components/AssetsTable.mjs +27 -4
- package/dist/admin/pages/Assets/components/AssetsTable.mjs.map +1 -1
- package/dist/admin/pages/Assets/components/CursorAnchoredMenu.js +77 -0
- package/dist/admin/pages/Assets/components/CursorAnchoredMenu.js.map +1 -0
- package/dist/admin/pages/Assets/components/CursorAnchoredMenu.mjs +75 -0
- package/dist/admin/pages/Assets/components/CursorAnchoredMenu.mjs.map +1 -0
- package/dist/admin/pages/Assets/components/FolderActions.js +139 -0
- package/dist/admin/pages/Assets/components/FolderActions.js.map +1 -0
- package/dist/admin/pages/Assets/components/FolderActions.mjs +137 -0
- package/dist/admin/pages/Assets/components/FolderActions.mjs.map +1 -0
- package/dist/admin/pages/Assets/components/FolderActionsMenu.js +25 -119
- package/dist/admin/pages/Assets/components/FolderActionsMenu.js.map +1 -1
- package/dist/admin/pages/Assets/components/FolderActionsMenu.mjs +27 -121
- package/dist/admin/pages/Assets/components/FolderActionsMenu.mjs.map +1 -1
- package/dist/admin/pages/Assets/components/FolderContextMenu.js +67 -0
- package/dist/admin/pages/Assets/components/FolderContextMenu.js.map +1 -0
- package/dist/admin/pages/Assets/components/FolderContextMenu.mjs +65 -0
- package/dist/admin/pages/Assets/components/FolderContextMenu.mjs.map +1 -0
- package/dist/admin/pages/Assets/components/FolderTree/FolderTree.js +139 -45
- package/dist/admin/pages/Assets/components/FolderTree/FolderTree.js.map +1 -1
- package/dist/admin/pages/Assets/components/FolderTree/FolderTree.mjs +140 -47
- package/dist/admin/pages/Assets/components/FolderTree/FolderTree.mjs.map +1 -1
- package/dist/admin/pages/Assets/components/FolderTree/FolderTreeRowMenu.js +115 -0
- package/dist/admin/pages/Assets/components/FolderTree/FolderTreeRowMenu.js.map +1 -0
- package/dist/admin/pages/Assets/components/FolderTree/FolderTreeRowMenu.mjs +113 -0
- package/dist/admin/pages/Assets/components/FolderTree/FolderTreeRowMenu.mjs.map +1 -0
- package/dist/admin/pages/Assets/components/ItemContextMenu.js +125 -0
- package/dist/admin/pages/Assets/components/ItemContextMenu.js.map +1 -0
- package/dist/admin/pages/Assets/components/ItemContextMenu.mjs +122 -0
- package/dist/admin/pages/Assets/components/ItemContextMenu.mjs.map +1 -0
- package/dist/admin/pages/Assets/components/MainAreaContextMenu.js +88 -63
- package/dist/admin/pages/Assets/components/MainAreaContextMenu.js.map +1 -1
- package/dist/admin/pages/Assets/components/MainAreaContextMenu.mjs +88 -63
- package/dist/admin/pages/Assets/components/MainAreaContextMenu.mjs.map +1 -1
- package/dist/admin/pages/Assets/components/SelectionActions.js +111 -0
- package/dist/admin/pages/Assets/components/SelectionActions.js.map +1 -0
- package/dist/admin/pages/Assets/components/SelectionActions.mjs +109 -0
- package/dist/admin/pages/Assets/components/SelectionActions.mjs.map +1 -0
- package/dist/admin/pages/Assets/components/SelectionContextMenu.js +82 -0
- package/dist/admin/pages/Assets/components/SelectionContextMenu.js.map +1 -0
- package/dist/admin/pages/Assets/components/SelectionContextMenu.mjs +80 -0
- package/dist/admin/pages/Assets/components/SelectionContextMenu.mjs.map +1 -0
- package/dist/admin/pages/Assets/hooks/useAssetSelection.js +10 -0
- package/dist/admin/pages/Assets/hooks/useAssetSelection.js.map +1 -1
- package/dist/admin/pages/Assets/hooks/useAssetSelection.mjs +10 -0
- package/dist/admin/pages/Assets/hooks/useAssetSelection.mjs.map +1 -1
- package/dist/admin/pages/SettingsPage/SettingsPage.js +8 -1
- package/dist/admin/pages/SettingsPage/SettingsPage.js.map +1 -1
- package/dist/admin/pages/SettingsPage/SettingsPage.mjs +8 -1
- package/dist/admin/pages/SettingsPage/SettingsPage.mjs.map +1 -1
- package/dist/admin/src/hooks/useTracking.d.ts +0 -7
- package/dist/admin/src/pages/Assets/components/AssetActions.d.ts +70 -0
- package/dist/admin/src/pages/Assets/components/AssetActionsMenu.d.ts +5 -14
- package/dist/admin/src/pages/Assets/components/AssetContextMenu.d.ts +27 -0
- package/dist/admin/src/pages/Assets/components/AssetDetails/useCropImg.d.ts +16 -0
- package/dist/admin/src/pages/Assets/components/CursorAnchoredMenu.d.ts +32 -0
- package/dist/admin/src/pages/Assets/components/FolderActions.d.ts +48 -0
- package/dist/admin/src/pages/Assets/components/FolderActionsMenu.d.ts +4 -8
- package/dist/admin/src/pages/Assets/components/FolderContextMenu.d.ts +21 -0
- package/dist/admin/src/pages/Assets/components/FolderTree/FolderTree.d.ts +5 -1
- package/dist/admin/src/pages/Assets/components/FolderTree/FolderTreeRowMenu.d.ts +25 -0
- package/dist/admin/src/pages/Assets/components/ItemContextMenu.d.ts +53 -0
- package/dist/admin/src/pages/Assets/components/MainAreaContextMenu.d.ts +15 -1
- package/dist/admin/src/pages/Assets/components/SelectionActions.d.ts +40 -0
- package/dist/admin/src/pages/Assets/components/SelectionContextMenu.d.ts +25 -0
- package/dist/admin/src/pages/Assets/hooks/useAssetSelection.d.ts +5 -0
- package/dist/admin/src/utils/mediaLibraryVersion.d.ts +18 -0
- package/dist/admin/translations/en.json.js +8 -3
- package/dist/admin/translations/en.json.js.map +1 -1
- package/dist/admin/translations/en.json.mjs +8 -3
- package/dist/admin/translations/en.json.mjs.map +1 -1
- package/dist/admin/utils/mediaLibraryVersion.js +24 -0
- package/dist/admin/utils/mediaLibraryVersion.js.map +1 -0
- package/dist/admin/utils/mediaLibraryVersion.mjs +20 -0
- package/dist/admin/utils/mediaLibraryVersion.mjs.map +1 -0
- package/dist/server/controllers/admin-file.js +2 -2
- package/dist/server/controllers/admin-file.js.map +1 -1
- package/dist/server/controllers/admin-file.mjs +2 -2
- package/dist/server/controllers/admin-file.mjs.map +1 -1
- package/dist/server/controllers/admin-folder.js +5 -5
- package/dist/server/controllers/admin-folder.js.map +1 -1
- package/dist/server/controllers/admin-folder.mjs +5 -5
- package/dist/server/controllers/admin-folder.mjs.map +1 -1
- package/dist/server/controllers/content-api.js +30 -7
- package/dist/server/controllers/content-api.js.map +1 -1
- package/dist/server/controllers/content-api.mjs +30 -7
- package/dist/server/controllers/content-api.mjs.map +1 -1
- package/dist/server/controllers/validation/admin/folder-file.js +4 -4
- package/dist/server/controllers/validation/admin/folder-file.js.map +1 -1
- package/dist/server/controllers/validation/admin/folder-file.mjs +2 -2
- package/dist/server/controllers/validation/admin/folder-file.mjs.map +1 -1
- package/dist/server/controllers/validation/admin/folder.js +3 -4
- package/dist/server/controllers/validation/admin/folder.js.map +1 -1
- package/dist/server/controllers/validation/admin/folder.mjs +3 -4
- package/dist/server/controllers/validation/admin/folder.mjs.map +1 -1
- package/dist/server/controllers/validation/admin/upload.js +1 -2
- package/dist/server/controllers/validation/admin/upload.js.map +1 -1
- package/dist/server/controllers/validation/admin/upload.mjs +1 -2
- package/dist/server/controllers/validation/admin/upload.mjs.map +1 -1
- package/dist/server/controllers/validation/admin/utils.js +1 -2
- package/dist/server/controllers/validation/admin/utils.js.map +1 -1
- package/dist/server/controllers/validation/admin/utils.mjs +1 -2
- package/dist/server/controllers/validation/admin/utils.mjs.map +1 -1
- package/dist/server/migrations/unsign-richtext-and-blocks-urls.js +2 -2
- package/dist/server/migrations/unsign-richtext-and-blocks-urls.js.map +1 -1
- package/dist/server/migrations/unsign-richtext-and-blocks-urls.mjs +1 -1
- package/dist/server/migrations/unsign-richtext-and-blocks-urls.mjs.map +1 -1
- package/dist/server/routes/content-api.js +3 -3
- package/dist/server/routes/content-api.js.map +1 -1
- package/dist/server/routes/content-api.mjs +3 -3
- package/dist/server/routes/content-api.mjs.map +1 -1
- package/dist/server/routes/validation/upload.js +8 -0
- package/dist/server/routes/validation/upload.js.map +1 -1
- package/dist/server/routes/validation/upload.mjs +8 -0
- package/dist/server/routes/validation/upload.mjs.map +1 -1
- package/dist/server/services/api-upload-folder.js +3 -3
- package/dist/server/services/api-upload-folder.js.map +1 -1
- package/dist/server/services/api-upload-folder.mjs +3 -3
- package/dist/server/services/api-upload-folder.mjs.map +1 -1
- package/dist/server/services/extensions/utils.js +19 -15
- package/dist/server/services/extensions/utils.js.map +1 -1
- package/dist/server/services/extensions/utils.mjs +19 -15
- package/dist/server/services/extensions/utils.mjs.map +1 -1
- package/dist/server/services/file.js +2 -2
- package/dist/server/services/file.js.map +1 -1
- package/dist/server/services/file.mjs +1 -1
- package/dist/server/services/file.mjs.map +1 -1
- package/dist/server/services/folder.js +5 -5
- package/dist/server/services/folder.js.map +1 -1
- package/dist/server/services/folder.mjs +5 -5
- package/dist/server/services/folder.mjs.map +1 -1
- package/dist/server/services/provider.js +3 -4
- package/dist/server/services/provider.js.map +1 -1
- package/dist/server/services/provider.mjs +3 -4
- package/dist/server/services/provider.mjs.map +1 -1
- package/dist/server/services/upload.js +5 -6
- package/dist/server/services/upload.js.map +1 -1
- package/dist/server/services/upload.mjs +4 -5
- package/dist/server/services/upload.mjs.map +1 -1
- package/dist/server/services/weekly-metrics.js +2 -2
- package/dist/server/services/weekly-metrics.js.map +1 -1
- package/dist/server/services/weekly-metrics.mjs +2 -2
- package/dist/server/services/weekly-metrics.mjs.map +1 -1
- package/dist/server/src/controllers/admin-folder.d.ts.map +1 -1
- package/dist/server/src/controllers/content-api.d.ts.map +1 -1
- package/dist/server/src/controllers/validation/admin/folder.d.ts.map +1 -1
- package/dist/server/src/controllers/validation/admin/upload.d.ts.map +1 -1
- package/dist/server/src/controllers/validation/admin/utils.d.ts.map +1 -1
- package/dist/server/src/index.d.ts.map +1 -1
- package/dist/server/src/mcp/ambient-instance.d.ts.map +1 -1
- package/dist/server/src/routes/validation/upload.d.ts +4 -0
- package/dist/server/src/routes/validation/upload.d.ts.map +1 -1
- package/dist/server/src/services/extensions/utils.d.ts +33 -1
- package/dist/server/src/services/extensions/utils.d.ts.map +1 -1
- package/dist/server/src/services/index.d.ts.map +1 -1
- package/dist/server/src/services/provider.d.ts.map +1 -1
- package/dist/server/src/services/upload.d.ts.map +1 -1
- package/package.json +6 -6
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var jsxRuntime = require('react/jsx-runtime');
|
|
4
|
+
var React = require('react');
|
|
5
|
+
var reactIntl = require('react-intl');
|
|
6
|
+
var translations = require('../../../utils/translations.js');
|
|
7
|
+
var CursorAnchoredMenu = require('./CursorAnchoredMenu.js');
|
|
8
|
+
var FolderActions = require('./FolderActions.js');
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* The right-click twin of `FolderActionsMenu`: same actions, opened at the
|
|
12
|
+
* cursor. Mirrors `AssetContextMenu`, including keeping "the menu is shut" and
|
|
13
|
+
* "this is unmounted" as separate things — a dialog opened from an item is
|
|
14
|
+
* rendered here and would go with an early unmount.
|
|
15
|
+
*/ const FolderContextMenu = ({ folder, dragData, showRename, position, returnFocusTo, onClose })=>{
|
|
16
|
+
const { formatMessage } = reactIntl.useIntl();
|
|
17
|
+
const [isMenuOpen, setIsMenuOpen] = React.useState(true);
|
|
18
|
+
return /*#__PURE__*/ jsxRuntime.jsx(FolderActions.FolderActions, {
|
|
19
|
+
folder: folder,
|
|
20
|
+
dragData: dragData,
|
|
21
|
+
showRename: showRename,
|
|
22
|
+
children: ({ items, dialogs, isBusy })=>/*#__PURE__*/ jsxRuntime.jsx(FolderContextMenuBody, {
|
|
23
|
+
isBusy: isBusy,
|
|
24
|
+
isMenuOpen: isMenuOpen,
|
|
25
|
+
onMenuClose: ()=>setIsMenuOpen(false),
|
|
26
|
+
onClose: onClose,
|
|
27
|
+
position: position,
|
|
28
|
+
returnFocusTo: returnFocusTo,
|
|
29
|
+
label: formatMessage({
|
|
30
|
+
id: translations.getTranslationKey('list.folder.context-menu.label'),
|
|
31
|
+
defaultMessage: 'Folder actions'
|
|
32
|
+
}),
|
|
33
|
+
items: items,
|
|
34
|
+
dialogs: dialogs
|
|
35
|
+
})
|
|
36
|
+
});
|
|
37
|
+
};
|
|
38
|
+
/**
|
|
39
|
+
* Split out because the "nothing left on screen" effect can't run inside the
|
|
40
|
+
* render prop above — hooks don't belong in a callback.
|
|
41
|
+
*/ const FolderContextMenuBody = ({ isBusy, isMenuOpen, onMenuClose, onClose, position, returnFocusTo, label, items, dialogs })=>{
|
|
42
|
+
React.useEffect(()=>{
|
|
43
|
+
if (!isMenuOpen && !isBusy) {
|
|
44
|
+
onClose();
|
|
45
|
+
}
|
|
46
|
+
}, [
|
|
47
|
+
isMenuOpen,
|
|
48
|
+
isBusy,
|
|
49
|
+
onClose
|
|
50
|
+
]);
|
|
51
|
+
return /*#__PURE__*/ jsxRuntime.jsxs(jsxRuntime.Fragment, {
|
|
52
|
+
children: [
|
|
53
|
+
/*#__PURE__*/ jsxRuntime.jsx(CursorAnchoredMenu.CursorAnchoredMenu, {
|
|
54
|
+
position: position,
|
|
55
|
+
open: isMenuOpen,
|
|
56
|
+
label: label,
|
|
57
|
+
returnFocusTo: returnFocusTo,
|
|
58
|
+
onClose: onMenuClose,
|
|
59
|
+
children: items
|
|
60
|
+
}),
|
|
61
|
+
dialogs
|
|
62
|
+
]
|
|
63
|
+
});
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
exports.FolderContextMenu = FolderContextMenu;
|
|
67
|
+
//# sourceMappingURL=FolderContextMenu.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"FolderContextMenu.js","sources":["../../../../../admin/src/pages/Assets/components/FolderContextMenu.tsx"],"sourcesContent":["import { useEffect, useState, type ReactNode } from 'react';\n\nimport { useIntl } from 'react-intl';\n\nimport { getTranslationKey } from '../../../utils/translations';\n\nimport { CursorAnchoredMenu, type CursorPosition } from './CursorAnchoredMenu';\nimport { FolderActions } from './FolderActions';\n\nimport type { Folder } from '../../../../../shared/contracts/folders';\nimport type { DragFolderData } from '../../../types/dnd';\n\ninterface FolderContextMenuProps {\n folder: Pick<Folder, 'id' | 'name'>;\n dragData: DragFolderData;\n /** Passed through — the folder tree offers the menu without Rename. */\n showRename?: boolean;\n position: CursorPosition;\n returnFocusTo: HTMLElement | null;\n /** Mounted only while it has something on screen, so the parent drops it on this. */\n onClose: () => void;\n}\n\n/**\n * The right-click twin of `FolderActionsMenu`: same actions, opened at the\n * cursor. Mirrors `AssetContextMenu`, including keeping \"the menu is shut\" and\n * \"this is unmounted\" as separate things — a dialog opened from an item is\n * rendered here and would go with an early unmount.\n */\nexport const FolderContextMenu = ({\n folder,\n dragData,\n showRename,\n position,\n returnFocusTo,\n onClose,\n}: FolderContextMenuProps) => {\n const { formatMessage } = useIntl();\n const [isMenuOpen, setIsMenuOpen] = useState(true);\n\n return (\n <FolderActions folder={folder} dragData={dragData} showRename={showRename}>\n {({ items, dialogs, isBusy }) => (\n <FolderContextMenuBody\n isBusy={isBusy}\n isMenuOpen={isMenuOpen}\n onMenuClose={() => setIsMenuOpen(false)}\n onClose={onClose}\n position={position}\n returnFocusTo={returnFocusTo}\n label={formatMessage({\n id: getTranslationKey('list.folder.context-menu.label'),\n defaultMessage: 'Folder actions',\n })}\n items={items}\n dialogs={dialogs}\n />\n )}\n </FolderActions>\n );\n};\n\ninterface FolderContextMenuBodyProps {\n isBusy: boolean;\n isMenuOpen: boolean;\n onMenuClose: () => void;\n onClose: () => void;\n position: CursorPosition;\n returnFocusTo: HTMLElement | null;\n label: string;\n items: ReactNode;\n dialogs: ReactNode;\n}\n\n/**\n * Split out because the \"nothing left on screen\" effect can't run inside the\n * render prop above — hooks don't belong in a callback.\n */\nconst FolderContextMenuBody = ({\n isBusy,\n isMenuOpen,\n onMenuClose,\n onClose,\n position,\n returnFocusTo,\n label,\n items,\n dialogs,\n}: FolderContextMenuBodyProps) => {\n useEffect(() => {\n if (!isMenuOpen && !isBusy) {\n onClose();\n }\n }, [isMenuOpen, isBusy, onClose]);\n\n return (\n <>\n <CursorAnchoredMenu\n position={position}\n open={isMenuOpen}\n label={label}\n returnFocusTo={returnFocusTo}\n onClose={onMenuClose}\n >\n {items}\n </CursorAnchoredMenu>\n {dialogs}\n </>\n );\n};\n"],"names":["FolderContextMenu","folder","dragData","showRename","position","returnFocusTo","onClose","formatMessage","useIntl","isMenuOpen","setIsMenuOpen","useState","_jsx","FolderActions","items","dialogs","isBusy","FolderContextMenuBody","onMenuClose","label","id","getTranslationKey","defaultMessage","useEffect","_jsxs","_Fragment","CursorAnchoredMenu","open"],"mappings":";;;;;;;;;AAuBA;;;;;AAKC,IACM,MAAMA,iBAAAA,GAAoB,CAAC,EAChCC,MAAM,EACNC,QAAQ,EACRC,UAAU,EACVC,QAAQ,EACRC,aAAa,EACbC,OAAO,EACgB,GAAA;IACvB,MAAM,EAAEC,aAAa,EAAE,GAAGC,iBAAAA,EAAAA;AAC1B,IAAA,MAAM,CAACC,UAAAA,EAAYC,aAAAA,CAAc,GAAGC,cAAAA,CAAS,IAAA,CAAA;AAE7C,IAAA,qBACEC,cAAA,CAACC,2BAAAA,EAAAA;QAAcZ,MAAAA,EAAQA,MAAAA;QAAQC,QAAAA,EAAUA,QAAAA;QAAUC,UAAAA,EAAYA,UAAAA;kBAC5D,CAAC,EAAEW,KAAK,EAAEC,OAAO,EAAEC,MAAM,EAAE,iBAC1BJ,cAAA,CAACK,qBAAAA,EAAAA;gBACCD,MAAAA,EAAQA,MAAAA;gBACRP,UAAAA,EAAYA,UAAAA;AACZS,gBAAAA,WAAAA,EAAa,IAAMR,aAAAA,CAAc,KAAA,CAAA;gBACjCJ,OAAAA,EAASA,OAAAA;gBACTF,QAAAA,EAAUA,QAAAA;gBACVC,aAAAA,EAAeA,aAAAA;AACfc,gBAAAA,KAAAA,EAAOZ,aAAAA,CAAc;AACnBa,oBAAAA,EAAAA,EAAIC,8BAAAA,CAAkB,gCAAA,CAAA;oBACtBC,cAAAA,EAAgB;AAClB,iBAAA,CAAA;gBACAR,KAAAA,EAAOA,KAAAA;gBACPC,OAAAA,EAASA;;;AAKnB;AAcA;;;IAIA,MAAME,wBAAwB,CAAC,EAC7BD,MAAM,EACNP,UAAU,EACVS,WAAW,EACXZ,OAAO,EACPF,QAAQ,EACRC,aAAa,EACbc,KAAK,EACLL,KAAK,EACLC,OAAO,EACoB,GAAA;IAC3BQ,eAAAA,CAAU,IAAA;QACR,IAAI,CAACd,UAAAA,IAAc,CAACO,MAAAA,EAAQ;AAC1BV,YAAAA,OAAAA,EAAAA;AACF,QAAA;IACF,CAAA,EAAG;AAACG,QAAAA,UAAAA;AAAYO,QAAAA,MAAAA;AAAQV,QAAAA;AAAQ,KAAA,CAAA;IAEhC,qBACEkB,eAAA,CAAAC,mBAAA,EAAA;;0BACEb,cAAA,CAACc,qCAAAA,EAAAA;gBACCtB,QAAAA,EAAUA,QAAAA;gBACVuB,IAAAA,EAAMlB,UAAAA;gBACNU,KAAAA,EAAOA,KAAAA;gBACPd,aAAAA,EAAeA,aAAAA;gBACfC,OAAAA,EAASY,WAAAA;AAERJ,gBAAAA,QAAAA,EAAAA;;AAEFC,YAAAA;;;AAGP,CAAA;;;;"}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
2
|
+
import { useState, useEffect } from 'react';
|
|
3
|
+
import { useIntl } from 'react-intl';
|
|
4
|
+
import { getTranslationKey } from '../../../utils/translations.mjs';
|
|
5
|
+
import { CursorAnchoredMenu } from './CursorAnchoredMenu.mjs';
|
|
6
|
+
import { FolderActions } from './FolderActions.mjs';
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* The right-click twin of `FolderActionsMenu`: same actions, opened at the
|
|
10
|
+
* cursor. Mirrors `AssetContextMenu`, including keeping "the menu is shut" and
|
|
11
|
+
* "this is unmounted" as separate things — a dialog opened from an item is
|
|
12
|
+
* rendered here and would go with an early unmount.
|
|
13
|
+
*/ const FolderContextMenu = ({ folder, dragData, showRename, position, returnFocusTo, onClose })=>{
|
|
14
|
+
const { formatMessage } = useIntl();
|
|
15
|
+
const [isMenuOpen, setIsMenuOpen] = useState(true);
|
|
16
|
+
return /*#__PURE__*/ jsx(FolderActions, {
|
|
17
|
+
folder: folder,
|
|
18
|
+
dragData: dragData,
|
|
19
|
+
showRename: showRename,
|
|
20
|
+
children: ({ items, dialogs, isBusy })=>/*#__PURE__*/ jsx(FolderContextMenuBody, {
|
|
21
|
+
isBusy: isBusy,
|
|
22
|
+
isMenuOpen: isMenuOpen,
|
|
23
|
+
onMenuClose: ()=>setIsMenuOpen(false),
|
|
24
|
+
onClose: onClose,
|
|
25
|
+
position: position,
|
|
26
|
+
returnFocusTo: returnFocusTo,
|
|
27
|
+
label: formatMessage({
|
|
28
|
+
id: getTranslationKey('list.folder.context-menu.label'),
|
|
29
|
+
defaultMessage: 'Folder actions'
|
|
30
|
+
}),
|
|
31
|
+
items: items,
|
|
32
|
+
dialogs: dialogs
|
|
33
|
+
})
|
|
34
|
+
});
|
|
35
|
+
};
|
|
36
|
+
/**
|
|
37
|
+
* Split out because the "nothing left on screen" effect can't run inside the
|
|
38
|
+
* render prop above — hooks don't belong in a callback.
|
|
39
|
+
*/ const FolderContextMenuBody = ({ isBusy, isMenuOpen, onMenuClose, onClose, position, returnFocusTo, label, items, dialogs })=>{
|
|
40
|
+
useEffect(()=>{
|
|
41
|
+
if (!isMenuOpen && !isBusy) {
|
|
42
|
+
onClose();
|
|
43
|
+
}
|
|
44
|
+
}, [
|
|
45
|
+
isMenuOpen,
|
|
46
|
+
isBusy,
|
|
47
|
+
onClose
|
|
48
|
+
]);
|
|
49
|
+
return /*#__PURE__*/ jsxs(Fragment, {
|
|
50
|
+
children: [
|
|
51
|
+
/*#__PURE__*/ jsx(CursorAnchoredMenu, {
|
|
52
|
+
position: position,
|
|
53
|
+
open: isMenuOpen,
|
|
54
|
+
label: label,
|
|
55
|
+
returnFocusTo: returnFocusTo,
|
|
56
|
+
onClose: onMenuClose,
|
|
57
|
+
children: items
|
|
58
|
+
}),
|
|
59
|
+
dialogs
|
|
60
|
+
]
|
|
61
|
+
});
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
export { FolderContextMenu };
|
|
65
|
+
//# sourceMappingURL=FolderContextMenu.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"FolderContextMenu.mjs","sources":["../../../../../admin/src/pages/Assets/components/FolderContextMenu.tsx"],"sourcesContent":["import { useEffect, useState, type ReactNode } from 'react';\n\nimport { useIntl } from 'react-intl';\n\nimport { getTranslationKey } from '../../../utils/translations';\n\nimport { CursorAnchoredMenu, type CursorPosition } from './CursorAnchoredMenu';\nimport { FolderActions } from './FolderActions';\n\nimport type { Folder } from '../../../../../shared/contracts/folders';\nimport type { DragFolderData } from '../../../types/dnd';\n\ninterface FolderContextMenuProps {\n folder: Pick<Folder, 'id' | 'name'>;\n dragData: DragFolderData;\n /** Passed through — the folder tree offers the menu without Rename. */\n showRename?: boolean;\n position: CursorPosition;\n returnFocusTo: HTMLElement | null;\n /** Mounted only while it has something on screen, so the parent drops it on this. */\n onClose: () => void;\n}\n\n/**\n * The right-click twin of `FolderActionsMenu`: same actions, opened at the\n * cursor. Mirrors `AssetContextMenu`, including keeping \"the menu is shut\" and\n * \"this is unmounted\" as separate things — a dialog opened from an item is\n * rendered here and would go with an early unmount.\n */\nexport const FolderContextMenu = ({\n folder,\n dragData,\n showRename,\n position,\n returnFocusTo,\n onClose,\n}: FolderContextMenuProps) => {\n const { formatMessage } = useIntl();\n const [isMenuOpen, setIsMenuOpen] = useState(true);\n\n return (\n <FolderActions folder={folder} dragData={dragData} showRename={showRename}>\n {({ items, dialogs, isBusy }) => (\n <FolderContextMenuBody\n isBusy={isBusy}\n isMenuOpen={isMenuOpen}\n onMenuClose={() => setIsMenuOpen(false)}\n onClose={onClose}\n position={position}\n returnFocusTo={returnFocusTo}\n label={formatMessage({\n id: getTranslationKey('list.folder.context-menu.label'),\n defaultMessage: 'Folder actions',\n })}\n items={items}\n dialogs={dialogs}\n />\n )}\n </FolderActions>\n );\n};\n\ninterface FolderContextMenuBodyProps {\n isBusy: boolean;\n isMenuOpen: boolean;\n onMenuClose: () => void;\n onClose: () => void;\n position: CursorPosition;\n returnFocusTo: HTMLElement | null;\n label: string;\n items: ReactNode;\n dialogs: ReactNode;\n}\n\n/**\n * Split out because the \"nothing left on screen\" effect can't run inside the\n * render prop above — hooks don't belong in a callback.\n */\nconst FolderContextMenuBody = ({\n isBusy,\n isMenuOpen,\n onMenuClose,\n onClose,\n position,\n returnFocusTo,\n label,\n items,\n dialogs,\n}: FolderContextMenuBodyProps) => {\n useEffect(() => {\n if (!isMenuOpen && !isBusy) {\n onClose();\n }\n }, [isMenuOpen, isBusy, onClose]);\n\n return (\n <>\n <CursorAnchoredMenu\n position={position}\n open={isMenuOpen}\n label={label}\n returnFocusTo={returnFocusTo}\n onClose={onMenuClose}\n >\n {items}\n </CursorAnchoredMenu>\n {dialogs}\n </>\n );\n};\n"],"names":["FolderContextMenu","folder","dragData","showRename","position","returnFocusTo","onClose","formatMessage","useIntl","isMenuOpen","setIsMenuOpen","useState","_jsx","FolderActions","items","dialogs","isBusy","FolderContextMenuBody","onMenuClose","label","id","getTranslationKey","defaultMessage","useEffect","_jsxs","_Fragment","CursorAnchoredMenu","open"],"mappings":";;;;;;;AAuBA;;;;;AAKC,IACM,MAAMA,iBAAAA,GAAoB,CAAC,EAChCC,MAAM,EACNC,QAAQ,EACRC,UAAU,EACVC,QAAQ,EACRC,aAAa,EACbC,OAAO,EACgB,GAAA;IACvB,MAAM,EAAEC,aAAa,EAAE,GAAGC,OAAAA,EAAAA;AAC1B,IAAA,MAAM,CAACC,UAAAA,EAAYC,aAAAA,CAAc,GAAGC,QAAAA,CAAS,IAAA,CAAA;AAE7C,IAAA,qBACEC,GAAA,CAACC,aAAAA,EAAAA;QAAcZ,MAAAA,EAAQA,MAAAA;QAAQC,QAAAA,EAAUA,QAAAA;QAAUC,UAAAA,EAAYA,UAAAA;kBAC5D,CAAC,EAAEW,KAAK,EAAEC,OAAO,EAAEC,MAAM,EAAE,iBAC1BJ,GAAA,CAACK,qBAAAA,EAAAA;gBACCD,MAAAA,EAAQA,MAAAA;gBACRP,UAAAA,EAAYA,UAAAA;AACZS,gBAAAA,WAAAA,EAAa,IAAMR,aAAAA,CAAc,KAAA,CAAA;gBACjCJ,OAAAA,EAASA,OAAAA;gBACTF,QAAAA,EAAUA,QAAAA;gBACVC,aAAAA,EAAeA,aAAAA;AACfc,gBAAAA,KAAAA,EAAOZ,aAAAA,CAAc;AACnBa,oBAAAA,EAAAA,EAAIC,iBAAAA,CAAkB,gCAAA,CAAA;oBACtBC,cAAAA,EAAgB;AAClB,iBAAA,CAAA;gBACAR,KAAAA,EAAOA,KAAAA;gBACPC,OAAAA,EAASA;;;AAKnB;AAcA;;;IAIA,MAAME,wBAAwB,CAAC,EAC7BD,MAAM,EACNP,UAAU,EACVS,WAAW,EACXZ,OAAO,EACPF,QAAQ,EACRC,aAAa,EACbc,KAAK,EACLL,KAAK,EACLC,OAAO,EACoB,GAAA;IAC3BQ,SAAAA,CAAU,IAAA;QACR,IAAI,CAACd,UAAAA,IAAc,CAACO,MAAAA,EAAQ;AAC1BV,YAAAA,OAAAA,EAAAA;AACF,QAAA;IACF,CAAA,EAAG;AAACG,QAAAA,UAAAA;AAAYO,QAAAA,MAAAA;AAAQV,QAAAA;AAAQ,KAAA,CAAA;IAEhC,qBACEkB,IAAA,CAAAC,QAAA,EAAA;;0BACEb,GAAA,CAACc,kBAAAA,EAAAA;gBACCtB,QAAAA,EAAUA,QAAAA;gBACVuB,IAAAA,EAAMlB,UAAAA;gBACNU,KAAAA,EAAOA,KAAAA;gBACPd,aAAAA,EAAeA,aAAAA;gBACfC,OAAAA,EAASY,WAAAA;AAERJ,gBAAAA,QAAAA,EAAAA;;AAEFC,YAAAA;;;AAGP,CAAA;;;;"}
|
|
@@ -9,9 +9,11 @@ var reactIntl = require('react-intl');
|
|
|
9
9
|
var styledComponents = require('styled-components');
|
|
10
10
|
var TruncatedText = require('../../../../components/TruncatedText.js');
|
|
11
11
|
var folders = require('../../../../services/folders.js');
|
|
12
|
+
var isEventFromWithin = require('../../../../utils/isEventFromWithin.js');
|
|
12
13
|
var translations = require('../../../../utils/translations.js');
|
|
13
14
|
var AssetsDndProvider = require('../Dnd/AssetsDndProvider.js');
|
|
14
15
|
var useFolderTreeDroppable = require('../Dnd/useFolderTreeDroppable.js');
|
|
16
|
+
var FolderTreeRowMenu = require('./FolderTreeRowMenu.js');
|
|
15
17
|
var useSpringLoadedExpand = require('./useSpringLoadedExpand.js');
|
|
16
18
|
|
|
17
19
|
/* -------------------------------------------------------------------------------------------------
|
|
@@ -19,17 +21,19 @@ var useSpringLoadedExpand = require('./useSpringLoadedExpand.js');
|
|
|
19
21
|
* -----------------------------------------------------------------------------------------------*/ const RowButton = styledComponents.styled.button`
|
|
20
22
|
display: flex;
|
|
21
23
|
align-items: center;
|
|
22
|
-
gap
|
|
24
|
+
// Matches the row's own gap, so Home — the one row whose icon sits inside
|
|
25
|
+
// this button rather than beside it — puts its label on the same line as a
|
|
26
|
+
// folder's.
|
|
27
|
+
gap: ${({ theme })=>theme.spaces[1]};
|
|
23
28
|
width: 100%;
|
|
24
29
|
min-height: 3.2rem;
|
|
25
|
-
padding:
|
|
30
|
+
// No padding of its own: the row owns the inset, so the label lines up with
|
|
31
|
+
// the icon boxes instead of being pushed in by a second layer of spacing.
|
|
32
|
+
padding: 0;
|
|
26
33
|
border: 0;
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
}
|
|
31
|
-
return $isActive ? theme.colors.primary100 : 'transparent';
|
|
32
|
-
}};
|
|
34
|
+
// The surface — hover, active, drop target — is painted by the row behind
|
|
35
|
+
// this, so it spans the chevron and the actions menu too, not just the label.
|
|
36
|
+
background: transparent;
|
|
33
37
|
color: ${({ $isActive, theme })=>$isActive ? theme.colors.primary700 : theme.colors.neutral800};
|
|
34
38
|
border-radius: ${({ theme })=>theme.borderRadius};
|
|
35
39
|
cursor: ${({ $isMovePending, $isInvalidDropCursor })=>{
|
|
@@ -47,15 +51,6 @@ var useSpringLoadedExpand = require('./useSpringLoadedExpand.js');
|
|
|
47
51
|
outline-offset: -1px;
|
|
48
52
|
`}
|
|
49
53
|
|
|
50
|
-
&:hover {
|
|
51
|
-
background: ${({ $isActive, $isValidDropTarget, theme })=>{
|
|
52
|
-
if ($isValidDropTarget) {
|
|
53
|
-
return theme.colors.primary100;
|
|
54
|
-
}
|
|
55
|
-
return $isActive ? theme.colors.primary100 : theme.colors.neutral100;
|
|
56
|
-
}};
|
|
57
|
-
}
|
|
58
|
-
|
|
59
54
|
&:focus-visible {
|
|
60
55
|
outline: 2px solid ${({ theme })=>theme.colors.primary600};
|
|
61
56
|
outline-offset: -2px;
|
|
@@ -70,11 +65,22 @@ const TreeRow = styledComponents.styled(designSystem.Flex)`
|
|
|
70
65
|
}};
|
|
71
66
|
pointer-events: ${({ $isMovePending })=>$isMovePending ? 'none' : 'auto'};
|
|
72
67
|
border-radius: ${({ theme })=>theme.borderRadius};
|
|
68
|
+
background: ${({ $isActive, theme })=>$isActive ? theme.colors.primary100 : 'transparent'};
|
|
69
|
+
|
|
70
|
+
// The whole row lights up, so pointing anywhere along it — chevron, label or
|
|
71
|
+
// the actions trigger — reads as one target.
|
|
72
|
+
&:hover {
|
|
73
|
+
background: ${({ $isActive, theme })=>$isActive ? theme.colors.primary100 : theme.colors.neutral100};
|
|
74
|
+
}
|
|
73
75
|
|
|
74
76
|
${({ $isValidDropTarget, theme })=>$isValidDropTarget && styledComponents.css`
|
|
75
77
|
background: ${theme.colors.primary100};
|
|
76
78
|
outline: 1px dashed ${theme.colors.primary600};
|
|
77
79
|
outline-offset: -1px;
|
|
80
|
+
|
|
81
|
+
&:hover {
|
|
82
|
+
background: ${theme.colors.primary100};
|
|
83
|
+
}
|
|
78
84
|
`}
|
|
79
85
|
`;
|
|
80
86
|
/* -------------------------------------------------------------------------------------------------
|
|
@@ -178,12 +184,46 @@ const useExpandedFolders = (folderStructure, currentFolderId)=>{
|
|
|
178
184
|
/* -------------------------------------------------------------------------------------------------
|
|
179
185
|
* FolderTreeItem — single tree row (internal)
|
|
180
186
|
* -----------------------------------------------------------------------------------------------*/ const INDENT_PER_LEVEL_REM = 1.6;
|
|
187
|
+
/**
|
|
188
|
+
* Breathing room between the row's highlight and the controls at either end.
|
|
189
|
+
* Asymmetric on purpose: the chevron reads as part of the indent, while the
|
|
190
|
+
* actions trigger sits closer to the edge so it stays out of the name's way.
|
|
191
|
+
*/ const ROW_INSET_LEFT_REM = 0.8;
|
|
192
|
+
const ROW_INSET_RIGHT_REM = 0.4;
|
|
193
|
+
/**
|
|
194
|
+
* Every icon in the rail occupies the same 24px box, whether or not it is a
|
|
195
|
+
* control: the chevron and the actions trigger are buttons, the home and folder
|
|
196
|
+
* marks are not. Sizing the box rather than the glyph is what keeps the labels
|
|
197
|
+
* on one vertical line across rows that mix the two.
|
|
198
|
+
*/ const IconSlot = styledComponents.styled(designSystem.Flex)`
|
|
199
|
+
width: 2.4rem;
|
|
200
|
+
height: 2.4rem;
|
|
201
|
+
min-width: 2.4rem;
|
|
202
|
+
flex-shrink: 0;
|
|
203
|
+
align-items: center;
|
|
204
|
+
justify-content: center;
|
|
205
|
+
`;
|
|
181
206
|
/**
|
|
182
207
|
* A leaf's chevron is present only to keep the folder names aligned, so it
|
|
183
208
|
* should read as absent. The design system's disabled state is built for real
|
|
184
209
|
* controls — a filled, bordered pill — which draws more attention than the
|
|
185
210
|
* enabled chevron next to it. Doubled selector to outrank that rule.
|
|
186
211
|
*/ const ChevronButton = styledComponents.styled(designSystem.IconButton)`
|
|
212
|
+
// Square, so it and the actions trigger read as one pair of controls.
|
|
213
|
+
&& {
|
|
214
|
+
width: 2.4rem;
|
|
215
|
+
height: 2.4rem;
|
|
216
|
+
min-width: 2.4rem;
|
|
217
|
+
min-height: 2.4rem;
|
|
218
|
+
padding: 0.4rem;
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
// The row paints its own hover, so the control needs a stronger one of its own
|
|
222
|
+
// to read as a separate target sitting on top of it.
|
|
223
|
+
&&:hover:not([aria-disabled='true']) {
|
|
224
|
+
background: ${({ theme })=>theme.colors.primary200};
|
|
225
|
+
}
|
|
226
|
+
|
|
187
227
|
&&[aria-disabled='true'] {
|
|
188
228
|
background: transparent;
|
|
189
229
|
border-color: transparent;
|
|
@@ -194,10 +234,13 @@ const RotatingChevron = styledComponents.styled(icons.ChevronDown)`
|
|
|
194
234
|
transform: rotate(${({ $expanded })=>$expanded ? '0deg' : '-90deg'});
|
|
195
235
|
transition: transform 0.2s ease;
|
|
196
236
|
`;
|
|
197
|
-
const FolderTreeItemInner = ({ id, name, folderChildren, level, currentFolderId, showActiveFolder, isExpanded, onToggle, onExpand, onSelect, isMovePending })=>{
|
|
237
|
+
const FolderTreeItemInner = ({ id, name, parentId, folderChildren, level, currentFolderId, showActiveFolder, isExpanded, onToggle, onExpand, onSelect, isMovePending })=>{
|
|
198
238
|
const { formatMessage } = reactIntl.useIntl();
|
|
199
239
|
const hasChildren = folderChildren.length > 0;
|
|
200
|
-
|
|
240
|
+
// A folder keeps its entry in the expanded set after its last subfolder is
|
|
241
|
+
// moved away, so "expanded" has to mean "expanded *and* still has something to
|
|
242
|
+
// show" — otherwise the chevron stays rotated on what is now a leaf.
|
|
243
|
+
const isFolderExpanded = isExpanded(id) && hasChildren;
|
|
201
244
|
const isActive = showActiveFolder && currentFolderId === id;
|
|
202
245
|
const { droppable: { setNodeRef }, isOver, showValidDropHighlight, showInvalidDropCursor } = useFolderTreeDroppable.useFolderTreeDroppable({
|
|
203
246
|
id,
|
|
@@ -207,6 +250,10 @@ const FolderTreeItemInner = ({ id, name, folderChildren, level, currentFolderId,
|
|
|
207
250
|
id,
|
|
208
251
|
onExpand
|
|
209
252
|
]);
|
|
253
|
+
// Tree rows carry no selection, so a right-click always means "this folder" —
|
|
254
|
+
// none of the list's selection rules apply here.
|
|
255
|
+
const [menuPosition, setMenuPosition] = React.useState(null);
|
|
256
|
+
const rowButtonRef = React.useRef(null);
|
|
210
257
|
useSpringLoadedExpand.useSpringLoadedExpand({
|
|
211
258
|
isOver,
|
|
212
259
|
canExpand: hasChildren && !isFolderExpanded,
|
|
@@ -218,12 +265,27 @@ const FolderTreeItemInner = ({ id, name, folderChildren, level, currentFolderId,
|
|
|
218
265
|
children: [
|
|
219
266
|
/*#__PURE__*/ jsxRuntime.jsxs(TreeRow, {
|
|
220
267
|
ref: setNodeRef,
|
|
268
|
+
"data-native-context-menu": true,
|
|
221
269
|
alignItems: "center",
|
|
222
|
-
|
|
270
|
+
// Indent plus the row's own inset, so the chevron never sits flush
|
|
271
|
+
// against the edge of the highlight at any depth.
|
|
272
|
+
paddingLeft: `${level * INDENT_PER_LEVEL_REM + ROW_INSET_LEFT_REM}rem`,
|
|
273
|
+
paddingRight: `${ROW_INSET_RIGHT_REM}rem`,
|
|
223
274
|
gap: 1,
|
|
275
|
+
$isActive: isActive,
|
|
224
276
|
$isValidDropTarget: showValidDropHighlight,
|
|
225
277
|
$isInvalidDropCursor: showInvalidDropCursor,
|
|
226
278
|
$isMovePending: isMovePending,
|
|
279
|
+
onContextMenu: (event)=>{
|
|
280
|
+
if (!isEventFromWithin.isEventFromWithin(event)) {
|
|
281
|
+
return;
|
|
282
|
+
}
|
|
283
|
+
event.preventDefault();
|
|
284
|
+
setMenuPosition({
|
|
285
|
+
x: event.clientX,
|
|
286
|
+
y: event.clientY
|
|
287
|
+
});
|
|
288
|
+
},
|
|
227
289
|
children: [
|
|
228
290
|
/*#__PURE__*/ jsxRuntime.jsx(ChevronButton, {
|
|
229
291
|
label: hasChildren ? formatMessage({
|
|
@@ -254,6 +316,7 @@ const FolderTreeItemInner = ({ id, name, folderChildren, level, currentFolderId,
|
|
|
254
316
|
flex: "1",
|
|
255
317
|
minWidth: 0,
|
|
256
318
|
children: /*#__PURE__*/ jsxRuntime.jsx(RowButton, {
|
|
319
|
+
ref: rowButtonRef,
|
|
257
320
|
type: "button",
|
|
258
321
|
$isActive: isActive,
|
|
259
322
|
$isValidDropTarget: showValidDropHighlight,
|
|
@@ -269,12 +332,23 @@ const FolderTreeItemInner = ({ id, name, folderChildren, level, currentFolderId,
|
|
|
269
332
|
children: name
|
|
270
333
|
})
|
|
271
334
|
})
|
|
335
|
+
}),
|
|
336
|
+
/*#__PURE__*/ jsxRuntime.jsx(FolderTreeRowMenu.FolderTreeRowMenu, {
|
|
337
|
+
folder: {
|
|
338
|
+
id,
|
|
339
|
+
name
|
|
340
|
+
},
|
|
341
|
+
parentId: parentId,
|
|
342
|
+
menuPosition: menuPosition,
|
|
343
|
+
returnFocusTo: rowButtonRef.current,
|
|
344
|
+
onCloseMenu: ()=>setMenuPosition(null)
|
|
272
345
|
})
|
|
273
346
|
]
|
|
274
347
|
}),
|
|
275
348
|
hasChildren && isFolderExpanded && /*#__PURE__*/ jsxRuntime.jsx(NavList, {
|
|
276
349
|
children: folderChildren.map((child)=>/*#__PURE__*/ jsxRuntime.jsx(FolderTreeItem, {
|
|
277
350
|
node: child,
|
|
351
|
+
parentId: id,
|
|
278
352
|
level: level + 1,
|
|
279
353
|
currentFolderId: currentFolderId,
|
|
280
354
|
showActiveFolder: showActiveFolder,
|
|
@@ -299,6 +373,7 @@ const FolderTreeItem = ({ node, ...props })=>{
|
|
|
299
373
|
folderChildren: node.children ?? []
|
|
300
374
|
});
|
|
301
375
|
};
|
|
376
|
+
const FOLDER_TREE_ROOT_SELECTOR = '[data-folder-tree-root]';
|
|
302
377
|
/**
|
|
303
378
|
* Left-rail navigation for the Media Library. Fetches folder structure internally
|
|
304
379
|
* and renders:
|
|
@@ -315,7 +390,7 @@ const FolderTreeItem = ({ node, ...props })=>{
|
|
|
315
390
|
* Presentational with respect to routing — navigation is delegated to the parent
|
|
316
391
|
* via `onSelectFolder` so the URL stays the single source of truth (see
|
|
317
392
|
* `useFolderNavigation`).
|
|
318
|
-
*/ const FolderTree = ({ currentFolderId, showActiveFolder = true, onSelectFolder })=>{
|
|
393
|
+
*/ const FolderTree = ({ currentFolderId, showActiveFolder = true, onSelectFolder, backgroundContextMenu })=>{
|
|
319
394
|
const { formatMessage } = reactIntl.useIntl();
|
|
320
395
|
const { data: folderStructure = [], isLoading, isError } = folders.useGetFolderStructureQuery();
|
|
321
396
|
const { isExpanded, toggleExpanded, expandFolder } = useExpandedFolders(folderStructure, currentFolderId);
|
|
@@ -332,11 +407,13 @@ const FolderTreeItem = ({ node, ...props })=>{
|
|
|
332
407
|
name: homeLabel
|
|
333
408
|
});
|
|
334
409
|
return /*#__PURE__*/ jsxRuntime.jsxs(strapiAdmin.SubNav.Main, {
|
|
410
|
+
"data-folder-tree-root": true,
|
|
335
411
|
"aria-label": formatMessage({
|
|
336
412
|
id: translations.getTranslationKey('sidebar.tree.aria-label'),
|
|
337
413
|
defaultMessage: 'Media library folders'
|
|
338
414
|
}),
|
|
339
415
|
children: [
|
|
416
|
+
backgroundContextMenu,
|
|
340
417
|
/*#__PURE__*/ jsxRuntime.jsx(strapiAdmin.SubNav.Header, {
|
|
341
418
|
label: formatMessage({
|
|
342
419
|
id: translations.getTranslationKey('sidebar.title'),
|
|
@@ -347,31 +424,44 @@ const FolderTreeItem = ({ node, ...props })=>{
|
|
|
347
424
|
children: /*#__PURE__*/ jsxRuntime.jsxs(designSystem.Flex, {
|
|
348
425
|
direction: "column",
|
|
349
426
|
alignItems: "stretch",
|
|
350
|
-
gap: 1,
|
|
351
427
|
padding: 3,
|
|
352
428
|
children: [
|
|
353
|
-
/*#__PURE__*/ jsxRuntime.
|
|
429
|
+
/*#__PURE__*/ jsxRuntime.jsx(TreeRow, {
|
|
354
430
|
ref: setHomeDropRef,
|
|
355
|
-
|
|
431
|
+
"data-native-context-menu": true,
|
|
432
|
+
alignItems: "center",
|
|
433
|
+
// Level 0, so the indent contributes nothing — but the row's own
|
|
434
|
+
// inset still applies, exactly as it does for a top-level folder.
|
|
435
|
+
paddingLeft: `${ROW_INSET_LEFT_REM}rem`,
|
|
436
|
+
paddingRight: `${ROW_INSET_RIGHT_REM}rem`,
|
|
356
437
|
$isActive: isHomeActive,
|
|
357
438
|
$isValidDropTarget: showHomeValidDropHighlight,
|
|
358
439
|
$isInvalidDropCursor: showHomeInvalidDropCursor,
|
|
359
440
|
$isMovePending: isMovePending,
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
441
|
+
children: /*#__PURE__*/ jsxRuntime.jsxs(RowButton, {
|
|
442
|
+
type: "button",
|
|
443
|
+
$isActive: isHomeActive,
|
|
444
|
+
$isValidDropTarget: showHomeValidDropHighlight,
|
|
445
|
+
$isInvalidDropCursor: showHomeInvalidDropCursor,
|
|
446
|
+
$isMovePending: isMovePending,
|
|
447
|
+
"aria-current": isHomeActive ? 'page' : undefined,
|
|
448
|
+
onClick: ()=>onSelectFolder(null),
|
|
449
|
+
"data-testid": "folder-tree-home",
|
|
450
|
+
children: [
|
|
451
|
+
/*#__PURE__*/ jsxRuntime.jsx(IconSlot, {
|
|
452
|
+
children: /*#__PURE__*/ jsxRuntime.jsx(icons.House, {
|
|
453
|
+
"aria-hidden": true,
|
|
454
|
+
width: "1.6rem",
|
|
455
|
+
height: "1.6rem"
|
|
456
|
+
})
|
|
457
|
+
}),
|
|
458
|
+
/*#__PURE__*/ jsxRuntime.jsx(designSystem.Typography, {
|
|
459
|
+
variant: "omega",
|
|
460
|
+
fontWeight: isHomeActive ? 'semiBold' : 'regular',
|
|
461
|
+
children: homeLabel
|
|
462
|
+
})
|
|
463
|
+
]
|
|
464
|
+
})
|
|
375
465
|
}),
|
|
376
466
|
/*#__PURE__*/ jsxRuntime.jsxs(designSystem.Box, {
|
|
377
467
|
marginTop: 4,
|
|
@@ -383,13 +473,14 @@ const FolderTreeItem = ({ node, ...props })=>{
|
|
|
383
473
|
paddingBottom: 1,
|
|
384
474
|
paddingLeft: 2,
|
|
385
475
|
paddingRight: 2,
|
|
386
|
-
marginBottom: 2,
|
|
387
476
|
children: [
|
|
388
|
-
/*#__PURE__*/ jsxRuntime.jsx(
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
477
|
+
/*#__PURE__*/ jsxRuntime.jsx(IconSlot, {
|
|
478
|
+
children: /*#__PURE__*/ jsxRuntime.jsx(icons.Folder, {
|
|
479
|
+
"aria-hidden": true,
|
|
480
|
+
width: "1.6rem",
|
|
481
|
+
height: "1.6rem",
|
|
482
|
+
fill: "neutral500"
|
|
483
|
+
})
|
|
393
484
|
}),
|
|
394
485
|
/*#__PURE__*/ jsxRuntime.jsx(designSystem.Typography, {
|
|
395
486
|
variant: "sigma",
|
|
@@ -442,6 +533,8 @@ const FolderTreeItem = ({ node, ...props })=>{
|
|
|
442
533
|
}) : /*#__PURE__*/ jsxRuntime.jsx(NavList, {
|
|
443
534
|
children: folderStructure.map((node)=>/*#__PURE__*/ jsxRuntime.jsx(FolderTreeItem, {
|
|
444
535
|
node: node,
|
|
536
|
+
// Top of the tree — these sit at the library root.
|
|
537
|
+
parentId: null,
|
|
445
538
|
level: 0,
|
|
446
539
|
currentFolderId: currentFolderId,
|
|
447
540
|
showActiveFolder: showActiveFolder,
|
|
@@ -461,5 +554,6 @@ const FolderTreeItem = ({ node, ...props })=>{
|
|
|
461
554
|
});
|
|
462
555
|
};
|
|
463
556
|
|
|
557
|
+
exports.FOLDER_TREE_ROOT_SELECTOR = FOLDER_TREE_ROOT_SELECTOR;
|
|
464
558
|
exports.FolderTree = FolderTree;
|
|
465
559
|
//# sourceMappingURL=FolderTree.js.map
|