@strapi/upload 5.59.0 → 5.60.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/AssetPickerDialog/AssetPickerDialog.js +434 -0
- package/dist/admin/components/AssetPickerDialog/AssetPickerDialog.js.map +1 -0
- package/dist/admin/components/AssetPickerDialog/AssetPickerDialog.mjs +432 -0
- package/dist/admin/components/AssetPickerDialog/AssetPickerDialog.mjs.map +1 -0
- package/dist/admin/components/AssetPickerDialog/FolderBreadcrumbs.js +91 -0
- package/dist/admin/components/AssetPickerDialog/FolderBreadcrumbs.js.map +1 -0
- package/dist/admin/components/AssetPickerDialog/FolderBreadcrumbs.mjs +89 -0
- package/dist/admin/components/AssetPickerDialog/FolderBreadcrumbs.mjs.map +1 -0
- package/dist/admin/components/AssetPickerDialog/PickerSelectionProvider.js +178 -0
- package/dist/admin/components/AssetPickerDialog/PickerSelectionProvider.js.map +1 -0
- package/dist/admin/components/AssetPickerDialog/PickerSelectionProvider.mjs +175 -0
- package/dist/admin/components/AssetPickerDialog/PickerSelectionProvider.mjs.map +1 -0
- package/dist/admin/components/AssetPickerDialog/SortableSelection.js +143 -0
- package/dist/admin/components/AssetPickerDialog/SortableSelection.js.map +1 -0
- package/dist/admin/components/AssetPickerDialog/SortableSelection.mjs +141 -0
- package/dist/admin/components/AssetPickerDialog/SortableSelection.mjs.map +1 -0
- package/dist/admin/components/AssetPickerDialog/pickerSelection.js +49 -0
- package/dist/admin/components/AssetPickerDialog/pickerSelection.js.map +1 -0
- package/dist/admin/components/AssetPickerDialog/pickerSelection.mjs +41 -0
- package/dist/admin/components/AssetPickerDialog/pickerSelection.mjs.map +1 -0
- package/dist/admin/components/MediaLibraryInput/AddAssetMenu.js +4 -3
- package/dist/admin/components/MediaLibraryInput/AddAssetMenu.js.map +1 -1
- package/dist/admin/components/MediaLibraryInput/AddAssetMenu.mjs +4 -3
- package/dist/admin/components/MediaLibraryInput/AddAssetMenu.mjs.map +1 -1
- package/dist/admin/components/MediaLibraryInput/AssetCard.js +240 -0
- package/dist/admin/components/MediaLibraryInput/AssetCard.js.map +1 -0
- package/dist/admin/components/MediaLibraryInput/AssetCard.mjs +237 -0
- package/dist/admin/components/MediaLibraryInput/AssetCard.mjs.map +1 -0
- package/dist/admin/components/MediaLibraryInput/AssetCarousel.js +161 -0
- package/dist/admin/components/MediaLibraryInput/AssetCarousel.js.map +1 -0
- package/dist/admin/components/MediaLibraryInput/AssetCarousel.mjs +159 -0
- package/dist/admin/components/MediaLibraryInput/AssetCarousel.mjs.map +1 -0
- package/dist/admin/components/MediaLibraryInput/AssetDropZone.js +76 -49
- package/dist/admin/components/MediaLibraryInput/AssetDropZone.js.map +1 -1
- package/dist/admin/components/MediaLibraryInput/AssetDropZone.mjs +77 -50
- package/dist/admin/components/MediaLibraryInput/AssetDropZone.mjs.map +1 -1
- package/dist/admin/components/MediaLibraryInput/AssetPreview.js +109 -0
- package/dist/admin/components/MediaLibraryInput/AssetPreview.js.map +1 -0
- package/dist/admin/components/MediaLibraryInput/AssetPreview.mjs +106 -0
- package/dist/admin/components/MediaLibraryInput/AssetPreview.mjs.map +1 -0
- package/dist/admin/components/MediaLibraryInput/AssetRow.js +146 -79
- package/dist/admin/components/MediaLibraryInput/AssetRow.js.map +1 -1
- package/dist/admin/components/MediaLibraryInput/AssetRow.mjs +148 -82
- package/dist/admin/components/MediaLibraryInput/AssetRow.mjs.map +1 -1
- package/dist/admin/components/MediaLibraryInput/FieldControls.js +32 -0
- package/dist/admin/components/MediaLibraryInput/FieldControls.js.map +1 -0
- package/dist/admin/components/MediaLibraryInput/FieldControls.mjs +29 -0
- package/dist/admin/components/MediaLibraryInput/FieldControls.mjs.map +1 -0
- package/dist/admin/components/MediaLibraryInput/MediaLibraryInput.js +130 -88
- package/dist/admin/components/MediaLibraryInput/MediaLibraryInput.js.map +1 -1
- package/dist/admin/components/MediaLibraryInput/MediaLibraryInput.mjs +129 -91
- package/dist/admin/components/MediaLibraryInput/MediaLibraryInput.mjs.map +1 -1
- package/dist/admin/components/MediaLibraryInput/UploadProgressBar.js +42 -0
- package/dist/admin/components/MediaLibraryInput/UploadProgressBar.js.map +1 -0
- package/dist/admin/components/MediaLibraryInput/UploadProgressBar.mjs +40 -0
- package/dist/admin/components/MediaLibraryInput/UploadProgressBar.mjs.map +1 -0
- package/dist/admin/components/MediaLibraryInput/useFieldUploads.js +122 -0
- package/dist/admin/components/MediaLibraryInput/useFieldUploads.js.map +1 -0
- package/dist/admin/components/MediaLibraryInput/useFieldUploads.mjs +120 -0
- package/dist/admin/components/MediaLibraryInput/useFieldUploads.mjs.map +1 -0
- package/dist/admin/components/UploadProgressDialog.js +2 -1
- package/dist/admin/components/UploadProgressDialog.js.map +1 -1
- package/dist/admin/components/UploadProgressDialog.mjs +2 -1
- package/dist/admin/components/UploadProgressDialog.mjs.map +1 -1
- package/dist/admin/hooks/useMediaLibraryPermissions.js +12 -2
- package/dist/admin/hooks/useMediaLibraryPermissions.js.map +1 -1
- package/dist/admin/hooks/useMediaLibraryPermissions.mjs +12 -2
- package/dist/admin/hooks/useMediaLibraryPermissions.mjs.map +1 -1
- package/dist/admin/pages/Assets/AssetsPage.js +13 -302
- package/dist/admin/pages/Assets/AssetsPage.js.map +1 -1
- package/dist/admin/pages/Assets/AssetsPage.mjs +11 -280
- package/dist/admin/pages/Assets/AssetsPage.mjs.map +1 -1
- package/dist/admin/pages/Assets/components/AssetsGrid.js +142 -31
- package/dist/admin/pages/Assets/components/AssetsGrid.js.map +1 -1
- package/dist/admin/pages/Assets/components/AssetsGrid.mjs +145 -34
- package/dist/admin/pages/Assets/components/AssetsGrid.mjs.map +1 -1
- package/dist/admin/pages/Assets/components/AssetsSearchInput.js +43 -2
- package/dist/admin/pages/Assets/components/AssetsSearchInput.js.map +1 -1
- package/dist/admin/pages/Assets/components/AssetsSearchInput.mjs +45 -4
- package/dist/admin/pages/Assets/components/AssetsSearchInput.mjs.map +1 -1
- package/dist/admin/pages/Assets/components/AssetsTable.js +58 -34
- package/dist/admin/pages/Assets/components/AssetsTable.js.map +1 -1
- package/dist/admin/pages/Assets/components/AssetsTable.mjs +60 -36
- package/dist/admin/pages/Assets/components/AssetsTable.mjs.map +1 -1
- package/dist/admin/pages/Assets/components/AssetsView.js +145 -0
- package/dist/admin/pages/Assets/components/AssetsView.js.map +1 -0
- package/dist/admin/pages/Assets/components/AssetsView.mjs +143 -0
- package/dist/admin/pages/Assets/components/AssetsView.mjs.map +1 -0
- package/dist/admin/pages/Assets/components/BulkActionsBar.mjs +1 -1
- package/dist/admin/pages/Assets/components/BusyOverlay.mjs +1 -1
- package/dist/admin/pages/Assets/components/Dnd/DragOverlayChip.mjs +1 -1
- package/dist/admin/pages/Assets/components/Dnd/ReorderHandle.js +40 -0
- package/dist/admin/pages/Assets/components/Dnd/ReorderHandle.js.map +1 -0
- package/dist/admin/pages/Assets/components/Dnd/ReorderHandle.mjs +38 -0
- package/dist/admin/pages/Assets/components/Dnd/ReorderHandle.mjs.map +1 -0
- package/dist/admin/pages/Assets/components/Dnd/assetSortable.js +29 -0
- package/dist/admin/pages/Assets/components/Dnd/assetSortable.js.map +1 -0
- package/dist/admin/pages/Assets/components/Dnd/assetSortable.mjs +24 -0
- package/dist/admin/pages/Assets/components/Dnd/assetSortable.mjs.map +1 -0
- package/dist/admin/pages/Assets/components/Dnd/dndIds.js +5 -0
- package/dist/admin/pages/Assets/components/Dnd/dndIds.js.map +1 -1
- package/dist/admin/pages/Assets/components/Dnd/dndIds.mjs +5 -1
- package/dist/admin/pages/Assets/components/Dnd/dndIds.mjs.map +1 -1
- package/dist/admin/pages/Assets/components/Dnd/useAssetDnd.js +41 -13
- package/dist/admin/pages/Assets/components/Dnd/useAssetDnd.js.map +1 -1
- package/dist/admin/pages/Assets/components/Dnd/useAssetDnd.mjs +41 -13
- package/dist/admin/pages/Assets/components/Dnd/useAssetDnd.mjs.map +1 -1
- package/dist/admin/pages/Assets/components/FilterBadges.mjs +2 -2
- package/dist/admin/pages/Assets/components/FilterMenu.mjs +2 -2
- package/dist/admin/pages/Assets/components/FolderTree/FolderTree.js +274 -55
- package/dist/admin/pages/Assets/components/FolderTree/FolderTree.js.map +1 -1
- package/dist/admin/pages/Assets/components/FolderTree/FolderTree.mjs +277 -59
- package/dist/admin/pages/Assets/components/FolderTree/FolderTree.mjs.map +1 -1
- package/dist/admin/pages/Assets/components/FolderTree/collapsedBranch.js +32 -0
- package/dist/admin/pages/Assets/components/FolderTree/collapsedBranch.js.map +1 -0
- package/dist/admin/pages/Assets/components/FolderTree/collapsedBranch.mjs +29 -0
- package/dist/admin/pages/Assets/components/FolderTree/collapsedBranch.mjs.map +1 -0
- package/dist/admin/pages/Assets/components/ViewToggle.js +126 -0
- package/dist/admin/pages/Assets/components/ViewToggle.js.map +1 -0
- package/dist/admin/pages/Assets/components/ViewToggle.mjs +104 -0
- package/dist/admin/pages/Assets/components/ViewToggle.mjs.map +1 -0
- package/dist/admin/pages/Assets/hooks/useAssetSearch.js +2 -2
- package/dist/admin/pages/Assets/hooks/useAssetSearch.js.map +1 -1
- package/dist/admin/pages/Assets/hooks/useAssetSearch.mjs +2 -2
- package/dist/admin/pages/Assets/hooks/useAssetSearch.mjs.map +1 -1
- package/dist/admin/pages/Assets/hooks/useAssetSelection.js +19 -1
- package/dist/admin/pages/Assets/hooks/useAssetSelection.js.map +1 -1
- package/dist/admin/pages/Assets/hooks/useAssetSelection.mjs +20 -3
- package/dist/admin/pages/Assets/hooks/useAssetSelection.mjs.map +1 -1
- package/dist/admin/pages/Assets/hooks/useAssetsList.js +87 -0
- package/dist/admin/pages/Assets/hooks/useAssetsList.js.map +1 -0
- package/dist/admin/pages/Assets/hooks/useAssetsList.mjs +85 -0
- package/dist/admin/pages/Assets/hooks/useAssetsList.mjs.map +1 -0
- package/dist/admin/pages/Assets/hooks/useBusyAssets.mjs +1 -1
- package/dist/admin/pages/Assets/hooks/useFolderNavigation.js +2 -1
- package/dist/admin/pages/Assets/hooks/useFolderNavigation.js.map +1 -1
- package/dist/admin/pages/Assets/hooks/useFolderNavigation.mjs +3 -2
- package/dist/admin/pages/Assets/hooks/useFolderNavigation.mjs.map +1 -1
- package/dist/admin/pages/Assets/hooks/useListFilters.js +2 -1
- package/dist/admin/pages/Assets/hooks/useListFilters.js.map +1 -1
- package/dist/admin/pages/Assets/hooks/useListFilters.mjs +3 -2
- package/dist/admin/pages/Assets/hooks/useListFilters.mjs.map +1 -1
- package/dist/admin/pages/Assets/hooks/useListQueryParams.js +80 -0
- package/dist/admin/pages/Assets/hooks/useListQueryParams.js.map +1 -0
- package/dist/admin/pages/Assets/hooks/useListQueryParams.mjs +77 -0
- package/dist/admin/pages/Assets/hooks/useListQueryParams.mjs.map +1 -0
- package/dist/admin/pages/Assets/hooks/useListSettings.js +32 -0
- package/dist/admin/pages/Assets/hooks/useListSettings.js.map +1 -0
- package/dist/admin/pages/Assets/hooks/useListSettings.mjs +29 -0
- package/dist/admin/pages/Assets/hooks/useListSettings.mjs.map +1 -0
- package/dist/admin/pages/Assets/hooks/useListSort.js +2 -1
- package/dist/admin/pages/Assets/hooks/useListSort.js.map +1 -1
- package/dist/admin/pages/Assets/hooks/useListSort.mjs +3 -2
- package/dist/admin/pages/Assets/hooks/useListSort.mjs.map +1 -1
- package/dist/admin/services/api.js +92 -7
- package/dist/admin/services/api.js.map +1 -1
- package/dist/admin/services/api.mjs +91 -9
- package/dist/admin/services/api.mjs.map +1 -1
- package/dist/admin/src/components/AssetPickerDialog/AssetPickerDialog.d.ts +19 -0
- package/dist/admin/src/components/AssetPickerDialog/FolderBreadcrumbs.d.ts +10 -0
- package/dist/admin/src/components/AssetPickerDialog/PickerSelectionProvider.d.ts +28 -0
- package/dist/admin/src/components/AssetPickerDialog/SortableSelection.d.ts +12 -0
- package/dist/admin/src/components/AssetPickerDialog/pickerSelection.d.ts +26 -0
- package/dist/admin/src/components/MediaLibraryInput/AssetCard.d.ts +25 -0
- package/dist/admin/src/components/MediaLibraryInput/AssetCarousel.d.ts +16 -0
- package/dist/admin/src/components/MediaLibraryInput/AssetDropZone.d.ts +11 -3
- package/dist/admin/src/components/MediaLibraryInput/AssetPreview.d.ts +17 -0
- package/dist/admin/src/components/MediaLibraryInput/AssetRow.d.ts +13 -3
- package/dist/admin/src/components/MediaLibraryInput/FieldControls.d.ts +19 -0
- package/dist/admin/src/components/MediaLibraryInput/MediaLibraryInput.d.ts +3 -1
- package/dist/admin/src/components/MediaLibraryInput/UploadProgressBar.d.ts +7 -0
- package/dist/admin/src/components/MediaLibraryInput/useFieldUploads.d.ts +31 -0
- package/dist/admin/src/hooks/useMediaLibraryPermissions.d.ts +2 -0
- package/dist/admin/src/pages/Assets/components/AssetsGrid.d.ts +3 -1
- package/dist/admin/src/pages/Assets/components/AssetsSearchInput.d.ts +11 -1
- package/dist/admin/src/pages/Assets/components/AssetsView.d.ts +29 -0
- package/dist/admin/src/pages/Assets/components/Dnd/ReorderHandle.d.ts +12 -0
- package/dist/admin/src/pages/Assets/components/Dnd/assetSortable.d.ts +37 -0
- package/dist/admin/src/pages/Assets/components/Dnd/dndIds.d.ts +5 -0
- package/dist/admin/src/pages/Assets/components/Dnd/useAssetDnd.d.ts +23 -2
- package/dist/admin/src/pages/Assets/components/FolderTree/FolderTree.d.ts +1 -0
- package/dist/admin/src/pages/Assets/components/FolderTree/collapsedBranch.d.ts +21 -0
- package/dist/admin/src/pages/Assets/components/ViewToggle.d.ts +8 -0
- package/dist/admin/src/pages/Assets/hooks/useAssetSelection.d.ts +26 -0
- package/dist/admin/src/pages/Assets/hooks/useAssetsList.d.ts +30 -0
- package/dist/admin/src/pages/Assets/hooks/useListQueryParams.d.ts +27 -0
- package/dist/admin/src/pages/Assets/hooks/useListSettings.d.ts +29 -0
- package/dist/admin/src/services/api.d.ts +24 -1
- package/dist/admin/src/store/uploadProgress.d.ts +14 -1
- package/dist/admin/src/utils/findFolderPath.d.ts +6 -0
- package/dist/admin/src/utils/isAllowedAssetType.d.ts +14 -0
- package/dist/admin/store/uploadProgress.js +30 -3
- package/dist/admin/store/uploadProgress.js.map +1 -1
- package/dist/admin/store/uploadProgress.mjs +29 -4
- package/dist/admin/store/uploadProgress.mjs.map +1 -1
- package/dist/admin/translations/en.json.js +20 -0
- package/dist/admin/translations/en.json.js.map +1 -1
- package/dist/admin/translations/en.json.mjs +20 -0
- package/dist/admin/translations/en.json.mjs.map +1 -1
- package/dist/admin/utils/findFolderPath.js +26 -0
- package/dist/admin/utils/findFolderPath.js.map +1 -0
- package/dist/admin/utils/findFolderPath.mjs +24 -0
- package/dist/admin/utils/findFolderPath.mjs.map +1 -0
- package/dist/admin/utils/isAllowedAssetType.js +33 -0
- package/dist/admin/utils/isAllowedAssetType.js.map +1 -0
- package/dist/admin/utils/isAllowedAssetType.mjs +31 -0
- package/dist/admin/utils/isAllowedAssetType.mjs.map +1 -0
- package/dist/server/controllers/admin-settings.js +5 -1
- package/dist/server/controllers/admin-settings.js.map +1 -1
- package/dist/server/controllers/admin-settings.mjs +5 -1
- package/dist/server/controllers/admin-settings.mjs.map +1 -1
- package/dist/server/services/image-manipulation.js +2 -2
- package/dist/server/services/image-manipulation.js.map +1 -1
- package/dist/server/services/image-manipulation.mjs +2 -2
- package/dist/server/services/image-manipulation.mjs.map +1 -1
- package/dist/server/services/upload.js.map +1 -1
- package/dist/server/services/upload.mjs.map +1 -1
- package/dist/server/src/controllers/admin-settings.d.ts.map +1 -1
- package/dist/server/src/index.d.ts +1 -1
- package/dist/server/src/services/extensions/utils.d.ts +11 -11
- package/dist/server/src/services/image-manipulation.d.ts +1 -1
- package/dist/server/src/services/image-manipulation.d.ts.map +1 -1
- package/dist/server/src/services/index.d.ts +1 -1
- package/dist/server/src/types.d.ts +63 -12
- package/dist/server/src/types.d.ts.map +1 -1
- package/package.json +8 -6
- package/dist/admin/components/MediaLibraryInput/NoLibraryAccessDialog.js +0 -45
- package/dist/admin/components/MediaLibraryInput/NoLibraryAccessDialog.js.map +0 -1
- package/dist/admin/components/MediaLibraryInput/NoLibraryAccessDialog.mjs +0 -43
- package/dist/admin/components/MediaLibraryInput/NoLibraryAccessDialog.mjs.map +0 -1
- package/dist/admin/src/components/MediaLibraryInput/NoLibraryAccessDialog.d.ts +0 -10
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SortableSelection.js","sources":["../../../../admin/src/components/AssetPickerDialog/SortableSelection.tsx"],"sourcesContent":["import { useMemo, type ReactNode } from 'react';\n\nimport {\n closestCenter,\n DndContext,\n KeyboardSensor,\n PointerSensor,\n useSensor,\n useSensors,\n type Announcements,\n type DragCancelEvent,\n type DragEndEvent,\n} from '@dnd-kit/core';\nimport {\n rectSortingStrategy,\n SortableContext,\n sortableKeyboardCoordinates,\n useSortable,\n} from '@dnd-kit/sortable';\nimport { CSS } from '@dnd-kit/utilities';\nimport { useIntl } from 'react-intl';\n\nimport {\n AssetSortableContext,\n type AssetSortable,\n} from '../../pages/Assets/components/Dnd/assetSortable';\nimport { getTranslationKey } from '../../utils/translations';\n\nimport { usePickerSelection } from './PickerSelectionProvider';\n\n/** Module scope, so every item of the list gets the same hook (see `AssetSortableContext`). */\nconst usePickerSortableAsset = (assetId: number): AssetSortable => {\n const {\n attributes,\n listeners,\n setNodeRef,\n setActivatorNodeRef,\n transform,\n transition,\n isDragging,\n } = useSortable({ id: assetId });\n\n return {\n setNodeRef,\n isDragging,\n style: { transform: CSS.Transform.toString(transform), transition },\n // The item drags with the pointer from anywhere; the keyboard starts from the grip.\n listeners: listeners?.onPointerDown ? { onPointerDown: listeners.onPointerDown } : undefined,\n handle: {\n ...attributes,\n ref: setActivatorNodeRef,\n onKeyDown: (event) => listeners?.onKeyDown?.(event),\n },\n };\n};\n\n/**\n * A pointer release over the item it was dragging would also count as a click,\n * which on a selected item un-picks it. Swallow that one click.\n */\nconst swallowNextClick = () => {\n const swallow = (event: MouseEvent) => {\n event.stopPropagation();\n event.preventDefault();\n };\n\n window.addEventListener('click', swallow, { capture: true, once: true });\n // No click follows a keyboard drop: don't leave the listener behind.\n setTimeout(() => window.removeEventListener('click', swallow, { capture: true }), 0);\n};\n\ninterface SortableSelectionProps {\n children: ReactNode;\n /**\n * Called with `true` when a drag starts and `false` when it ends or is\n * cancelled, so the dialog can keep Escape for cancelling the drag.\n */\n onReorderingChange?: (reordering: boolean) => void;\n}\n\n/** Makes the picker's selected assets reorderable (the Selected tab is always a grid). */\nexport const SortableSelection = ({ children, onReorderingChange }: SortableSelectionProps) => {\n const { formatMessage } = useIntl();\n const { selection, moveFile } = usePickerSelection();\n\n const sensors = useSensors(\n // A few pixels of travel before it counts as a drag, so clicks still pick.\n useSensor(PointerSensor, { activationConstraint: { distance: 8 } }),\n useSensor(KeyboardSensor, { coordinateGetter: sortableKeyboardCoordinates })\n );\n\n const ids = useMemo(() => selection.map(({ id }) => id), [selection]);\n\n const announcements = useMemo<Announcements>(() => {\n const describe = (id: string | number) => {\n const index = ids.indexOf(Number(id));\n\n return {\n name: selection[index]?.name ?? '',\n position: index + 1,\n count: ids.length,\n };\n };\n\n return {\n onDragStart: ({ active }) =>\n formatMessage(\n {\n id: getTranslationKey('list.reorder.picked-up'),\n defaultMessage: 'Picked up {name}. Position {position} of {count}.',\n },\n describe(active.id)\n ),\n onDragOver: ({ active, over }) =>\n over\n ? formatMessage(\n {\n id: getTranslationKey('list.reorder.moved'),\n defaultMessage: '{name} moved to position {position} of {count}.',\n },\n { ...describe(active.id), position: describe(over.id).position }\n )\n : undefined,\n onDragEnd: ({ active, over }) =>\n formatMessage(\n {\n id: getTranslationKey('list.reorder.dropped'),\n defaultMessage: '{name} dropped at position {position} of {count}.',\n },\n { ...describe(active.id), position: describe((over ?? active).id).position }\n ),\n onDragCancel: ({ active }) =>\n formatMessage(\n {\n id: getTranslationKey('list.reorder.cancelled'),\n defaultMessage:\n 'Reordering cancelled. {name} is back at position {position} of {count}.',\n },\n describe(active.id)\n ),\n };\n }, [formatMessage, ids, selection]);\n\n const handleDragEnd = ({ active, over }: DragEndEvent) => {\n if (active.data.current?.sortable && over) {\n moveFile(Number(active.id), Number(over.id));\n }\n\n onReorderingChange?.(false);\n swallowNextClick();\n };\n\n // Escape cancels a pointer drag while the button is still down, so the click\n // that would un-pick the item comes with the release, possibly much later.\n const handleDragCancel = ({ activatorEvent }: DragCancelEvent) => {\n onReorderingChange?.(false);\n\n if (activatorEvent.type === 'pointerdown') {\n window.addEventListener('pointerup', swallowNextClick, { capture: true, once: true });\n }\n };\n\n return (\n <DndContext\n sensors={sensors}\n collisionDetection={closestCenter}\n onDragStart={() => onReorderingChange?.(true)}\n onDragEnd={handleDragEnd}\n onDragCancel={handleDragCancel}\n accessibility={{ announcements }}\n >\n <SortableContext items={ids} strategy={rectSortingStrategy}>\n <AssetSortableContext.Provider value={usePickerSortableAsset}>\n {children}\n </AssetSortableContext.Provider>\n </SortableContext>\n </DndContext>\n );\n};\n"],"names":["usePickerSortableAsset","assetId","attributes","listeners","setNodeRef","setActivatorNodeRef","transform","transition","isDragging","useSortable","id","style","CSS","Transform","toString","onPointerDown","undefined","handle","ref","onKeyDown","event","swallowNextClick","swallow","stopPropagation","preventDefault","window","addEventListener","capture","once","setTimeout","removeEventListener","SortableSelection","children","onReorderingChange","formatMessage","useIntl","selection","moveFile","usePickerSelection","sensors","useSensors","useSensor","PointerSensor","activationConstraint","distance","KeyboardSensor","coordinateGetter","sortableKeyboardCoordinates","ids","useMemo","map","announcements","describe","index","indexOf","Number","name","position","count","length","onDragStart","active","getTranslationKey","defaultMessage","onDragOver","over","onDragEnd","onDragCancel","handleDragEnd","data","current","sortable","handleDragCancel","activatorEvent","type","_jsx","DndContext","collisionDetection","closestCenter","accessibility","SortableContext","items","strategy","rectSortingStrategy","AssetSortableContext","Provider","value"],"mappings":"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"}
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
import { jsx } from 'react/jsx-runtime';
|
|
2
|
+
import { useMemo } from 'react';
|
|
3
|
+
import { useSensors, useSensor, PointerSensor, KeyboardSensor, DndContext, closestCenter } from '@dnd-kit/core';
|
|
4
|
+
import { sortableKeyboardCoordinates, SortableContext, rectSortingStrategy, useSortable } from '@dnd-kit/sortable';
|
|
5
|
+
import { CSS } from '@dnd-kit/utilities';
|
|
6
|
+
import { useIntl } from 'react-intl';
|
|
7
|
+
import { AssetSortableContext } from '../../pages/Assets/components/Dnd/assetSortable.mjs';
|
|
8
|
+
import { getTranslationKey } from '../../utils/translations.mjs';
|
|
9
|
+
import { usePickerSelection } from './PickerSelectionProvider.mjs';
|
|
10
|
+
|
|
11
|
+
/** Module scope, so every item of the list gets the same hook (see `AssetSortableContext`). */ const usePickerSortableAsset = (assetId)=>{
|
|
12
|
+
const { attributes, listeners, setNodeRef, setActivatorNodeRef, transform, transition, isDragging } = useSortable({
|
|
13
|
+
id: assetId
|
|
14
|
+
});
|
|
15
|
+
return {
|
|
16
|
+
setNodeRef,
|
|
17
|
+
isDragging,
|
|
18
|
+
style: {
|
|
19
|
+
transform: CSS.Transform.toString(transform),
|
|
20
|
+
transition
|
|
21
|
+
},
|
|
22
|
+
// The item drags with the pointer from anywhere; the keyboard starts from the grip.
|
|
23
|
+
listeners: listeners?.onPointerDown ? {
|
|
24
|
+
onPointerDown: listeners.onPointerDown
|
|
25
|
+
} : undefined,
|
|
26
|
+
handle: {
|
|
27
|
+
...attributes,
|
|
28
|
+
ref: setActivatorNodeRef,
|
|
29
|
+
onKeyDown: (event)=>listeners?.onKeyDown?.(event)
|
|
30
|
+
}
|
|
31
|
+
};
|
|
32
|
+
};
|
|
33
|
+
/**
|
|
34
|
+
* A pointer release over the item it was dragging would also count as a click,
|
|
35
|
+
* which on a selected item un-picks it. Swallow that one click.
|
|
36
|
+
*/ const swallowNextClick = ()=>{
|
|
37
|
+
const swallow = (event)=>{
|
|
38
|
+
event.stopPropagation();
|
|
39
|
+
event.preventDefault();
|
|
40
|
+
};
|
|
41
|
+
window.addEventListener('click', swallow, {
|
|
42
|
+
capture: true,
|
|
43
|
+
once: true
|
|
44
|
+
});
|
|
45
|
+
// No click follows a keyboard drop: don't leave the listener behind.
|
|
46
|
+
setTimeout(()=>window.removeEventListener('click', swallow, {
|
|
47
|
+
capture: true
|
|
48
|
+
}), 0);
|
|
49
|
+
};
|
|
50
|
+
/** Makes the picker's selected assets reorderable (the Selected tab is always a grid). */ const SortableSelection = ({ children, onReorderingChange })=>{
|
|
51
|
+
const { formatMessage } = useIntl();
|
|
52
|
+
const { selection, moveFile } = usePickerSelection();
|
|
53
|
+
const sensors = useSensors(// A few pixels of travel before it counts as a drag, so clicks still pick.
|
|
54
|
+
useSensor(PointerSensor, {
|
|
55
|
+
activationConstraint: {
|
|
56
|
+
distance: 8
|
|
57
|
+
}
|
|
58
|
+
}), useSensor(KeyboardSensor, {
|
|
59
|
+
coordinateGetter: sortableKeyboardCoordinates
|
|
60
|
+
}));
|
|
61
|
+
const ids = useMemo(()=>selection.map(({ id })=>id), [
|
|
62
|
+
selection
|
|
63
|
+
]);
|
|
64
|
+
const announcements = useMemo(()=>{
|
|
65
|
+
const describe = (id)=>{
|
|
66
|
+
const index = ids.indexOf(Number(id));
|
|
67
|
+
return {
|
|
68
|
+
name: selection[index]?.name ?? '',
|
|
69
|
+
position: index + 1,
|
|
70
|
+
count: ids.length
|
|
71
|
+
};
|
|
72
|
+
};
|
|
73
|
+
return {
|
|
74
|
+
onDragStart: ({ active })=>formatMessage({
|
|
75
|
+
id: getTranslationKey('list.reorder.picked-up'),
|
|
76
|
+
defaultMessage: 'Picked up {name}. Position {position} of {count}.'
|
|
77
|
+
}, describe(active.id)),
|
|
78
|
+
onDragOver: ({ active, over })=>over ? formatMessage({
|
|
79
|
+
id: getTranslationKey('list.reorder.moved'),
|
|
80
|
+
defaultMessage: '{name} moved to position {position} of {count}.'
|
|
81
|
+
}, {
|
|
82
|
+
...describe(active.id),
|
|
83
|
+
position: describe(over.id).position
|
|
84
|
+
}) : undefined,
|
|
85
|
+
onDragEnd: ({ active, over })=>formatMessage({
|
|
86
|
+
id: getTranslationKey('list.reorder.dropped'),
|
|
87
|
+
defaultMessage: '{name} dropped at position {position} of {count}.'
|
|
88
|
+
}, {
|
|
89
|
+
...describe(active.id),
|
|
90
|
+
position: describe((over ?? active).id).position
|
|
91
|
+
}),
|
|
92
|
+
onDragCancel: ({ active })=>formatMessage({
|
|
93
|
+
id: getTranslationKey('list.reorder.cancelled'),
|
|
94
|
+
defaultMessage: 'Reordering cancelled. {name} is back at position {position} of {count}.'
|
|
95
|
+
}, describe(active.id))
|
|
96
|
+
};
|
|
97
|
+
}, [
|
|
98
|
+
formatMessage,
|
|
99
|
+
ids,
|
|
100
|
+
selection
|
|
101
|
+
]);
|
|
102
|
+
const handleDragEnd = ({ active, over })=>{
|
|
103
|
+
if (active.data.current?.sortable && over) {
|
|
104
|
+
moveFile(Number(active.id), Number(over.id));
|
|
105
|
+
}
|
|
106
|
+
onReorderingChange?.(false);
|
|
107
|
+
swallowNextClick();
|
|
108
|
+
};
|
|
109
|
+
// Escape cancels a pointer drag while the button is still down, so the click
|
|
110
|
+
// that would un-pick the item comes with the release, possibly much later.
|
|
111
|
+
const handleDragCancel = ({ activatorEvent })=>{
|
|
112
|
+
onReorderingChange?.(false);
|
|
113
|
+
if (activatorEvent.type === 'pointerdown') {
|
|
114
|
+
window.addEventListener('pointerup', swallowNextClick, {
|
|
115
|
+
capture: true,
|
|
116
|
+
once: true
|
|
117
|
+
});
|
|
118
|
+
}
|
|
119
|
+
};
|
|
120
|
+
return /*#__PURE__*/ jsx(DndContext, {
|
|
121
|
+
sensors: sensors,
|
|
122
|
+
collisionDetection: closestCenter,
|
|
123
|
+
onDragStart: ()=>onReorderingChange?.(true),
|
|
124
|
+
onDragEnd: handleDragEnd,
|
|
125
|
+
onDragCancel: handleDragCancel,
|
|
126
|
+
accessibility: {
|
|
127
|
+
announcements
|
|
128
|
+
},
|
|
129
|
+
children: /*#__PURE__*/ jsx(SortableContext, {
|
|
130
|
+
items: ids,
|
|
131
|
+
strategy: rectSortingStrategy,
|
|
132
|
+
children: /*#__PURE__*/ jsx(AssetSortableContext.Provider, {
|
|
133
|
+
value: usePickerSortableAsset,
|
|
134
|
+
children: children
|
|
135
|
+
})
|
|
136
|
+
})
|
|
137
|
+
});
|
|
138
|
+
};
|
|
139
|
+
|
|
140
|
+
export { SortableSelection };
|
|
141
|
+
//# sourceMappingURL=SortableSelection.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SortableSelection.mjs","sources":["../../../../admin/src/components/AssetPickerDialog/SortableSelection.tsx"],"sourcesContent":["import { useMemo, type ReactNode } from 'react';\n\nimport {\n closestCenter,\n DndContext,\n KeyboardSensor,\n PointerSensor,\n useSensor,\n useSensors,\n type Announcements,\n type DragCancelEvent,\n type DragEndEvent,\n} from '@dnd-kit/core';\nimport {\n rectSortingStrategy,\n SortableContext,\n sortableKeyboardCoordinates,\n useSortable,\n} from '@dnd-kit/sortable';\nimport { CSS } from '@dnd-kit/utilities';\nimport { useIntl } from 'react-intl';\n\nimport {\n AssetSortableContext,\n type AssetSortable,\n} from '../../pages/Assets/components/Dnd/assetSortable';\nimport { getTranslationKey } from '../../utils/translations';\n\nimport { usePickerSelection } from './PickerSelectionProvider';\n\n/** Module scope, so every item of the list gets the same hook (see `AssetSortableContext`). */\nconst usePickerSortableAsset = (assetId: number): AssetSortable => {\n const {\n attributes,\n listeners,\n setNodeRef,\n setActivatorNodeRef,\n transform,\n transition,\n isDragging,\n } = useSortable({ id: assetId });\n\n return {\n setNodeRef,\n isDragging,\n style: { transform: CSS.Transform.toString(transform), transition },\n // The item drags with the pointer from anywhere; the keyboard starts from the grip.\n listeners: listeners?.onPointerDown ? { onPointerDown: listeners.onPointerDown } : undefined,\n handle: {\n ...attributes,\n ref: setActivatorNodeRef,\n onKeyDown: (event) => listeners?.onKeyDown?.(event),\n },\n };\n};\n\n/**\n * A pointer release over the item it was dragging would also count as a click,\n * which on a selected item un-picks it. Swallow that one click.\n */\nconst swallowNextClick = () => {\n const swallow = (event: MouseEvent) => {\n event.stopPropagation();\n event.preventDefault();\n };\n\n window.addEventListener('click', swallow, { capture: true, once: true });\n // No click follows a keyboard drop: don't leave the listener behind.\n setTimeout(() => window.removeEventListener('click', swallow, { capture: true }), 0);\n};\n\ninterface SortableSelectionProps {\n children: ReactNode;\n /**\n * Called with `true` when a drag starts and `false` when it ends or is\n * cancelled, so the dialog can keep Escape for cancelling the drag.\n */\n onReorderingChange?: (reordering: boolean) => void;\n}\n\n/** Makes the picker's selected assets reorderable (the Selected tab is always a grid). */\nexport const SortableSelection = ({ children, onReorderingChange }: SortableSelectionProps) => {\n const { formatMessage } = useIntl();\n const { selection, moveFile } = usePickerSelection();\n\n const sensors = useSensors(\n // A few pixels of travel before it counts as a drag, so clicks still pick.\n useSensor(PointerSensor, { activationConstraint: { distance: 8 } }),\n useSensor(KeyboardSensor, { coordinateGetter: sortableKeyboardCoordinates })\n );\n\n const ids = useMemo(() => selection.map(({ id }) => id), [selection]);\n\n const announcements = useMemo<Announcements>(() => {\n const describe = (id: string | number) => {\n const index = ids.indexOf(Number(id));\n\n return {\n name: selection[index]?.name ?? '',\n position: index + 1,\n count: ids.length,\n };\n };\n\n return {\n onDragStart: ({ active }) =>\n formatMessage(\n {\n id: getTranslationKey('list.reorder.picked-up'),\n defaultMessage: 'Picked up {name}. Position {position} of {count}.',\n },\n describe(active.id)\n ),\n onDragOver: ({ active, over }) =>\n over\n ? formatMessage(\n {\n id: getTranslationKey('list.reorder.moved'),\n defaultMessage: '{name} moved to position {position} of {count}.',\n },\n { ...describe(active.id), position: describe(over.id).position }\n )\n : undefined,\n onDragEnd: ({ active, over }) =>\n formatMessage(\n {\n id: getTranslationKey('list.reorder.dropped'),\n defaultMessage: '{name} dropped at position {position} of {count}.',\n },\n { ...describe(active.id), position: describe((over ?? active).id).position }\n ),\n onDragCancel: ({ active }) =>\n formatMessage(\n {\n id: getTranslationKey('list.reorder.cancelled'),\n defaultMessage:\n 'Reordering cancelled. {name} is back at position {position} of {count}.',\n },\n describe(active.id)\n ),\n };\n }, [formatMessage, ids, selection]);\n\n const handleDragEnd = ({ active, over }: DragEndEvent) => {\n if (active.data.current?.sortable && over) {\n moveFile(Number(active.id), Number(over.id));\n }\n\n onReorderingChange?.(false);\n swallowNextClick();\n };\n\n // Escape cancels a pointer drag while the button is still down, so the click\n // that would un-pick the item comes with the release, possibly much later.\n const handleDragCancel = ({ activatorEvent }: DragCancelEvent) => {\n onReorderingChange?.(false);\n\n if (activatorEvent.type === 'pointerdown') {\n window.addEventListener('pointerup', swallowNextClick, { capture: true, once: true });\n }\n };\n\n return (\n <DndContext\n sensors={sensors}\n collisionDetection={closestCenter}\n onDragStart={() => onReorderingChange?.(true)}\n onDragEnd={handleDragEnd}\n onDragCancel={handleDragCancel}\n accessibility={{ announcements }}\n >\n <SortableContext items={ids} strategy={rectSortingStrategy}>\n <AssetSortableContext.Provider value={usePickerSortableAsset}>\n {children}\n </AssetSortableContext.Provider>\n </SortableContext>\n </DndContext>\n );\n};\n"],"names":["usePickerSortableAsset","assetId","attributes","listeners","setNodeRef","setActivatorNodeRef","transform","transition","isDragging","useSortable","id","style","CSS","Transform","toString","onPointerDown","undefined","handle","ref","onKeyDown","event","swallowNextClick","swallow","stopPropagation","preventDefault","window","addEventListener","capture","once","setTimeout","removeEventListener","SortableSelection","children","onReorderingChange","formatMessage","useIntl","selection","moveFile","usePickerSelection","sensors","useSensors","useSensor","PointerSensor","activationConstraint","distance","KeyboardSensor","coordinateGetter","sortableKeyboardCoordinates","ids","useMemo","map","announcements","describe","index","indexOf","Number","name","position","count","length","onDragStart","active","getTranslationKey","defaultMessage","onDragOver","over","onDragEnd","onDragCancel","handleDragEnd","data","current","sortable","handleDragCancel","activatorEvent","type","_jsx","DndContext","collisionDetection","closestCenter","accessibility","SortableContext","items","strategy","rectSortingStrategy","AssetSortableContext","Provider","value"],"mappings":"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"}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const hasFile = (selection, id)=>selection.some((file)=>file.id === id);
|
|
4
|
+
/**
|
|
5
|
+
* Adds the file, or removes it if it is already there. On a single-value field
|
|
6
|
+
* a new pick replaces whatever was selected.
|
|
7
|
+
*/ const toggleFile = (selection, file, { multiple })=>{
|
|
8
|
+
if (hasFile(selection, file.id)) {
|
|
9
|
+
return selection.filter(({ id })=>id !== file.id);
|
|
10
|
+
}
|
|
11
|
+
return multiple ? [
|
|
12
|
+
...selection,
|
|
13
|
+
file
|
|
14
|
+
] : [
|
|
15
|
+
file
|
|
16
|
+
];
|
|
17
|
+
};
|
|
18
|
+
/** Appends every file not already selected, keeping their order (select-all). */ const addFiles = (selection, files)=>[
|
|
19
|
+
...selection,
|
|
20
|
+
...files.filter((file)=>!hasFile(selection, file.id))
|
|
21
|
+
];
|
|
22
|
+
const removeFile = (selection, id)=>selection.filter((file)=>file.id !== id);
|
|
23
|
+
const removeFiles = (selection, ids)=>selection.filter((file)=>!ids.has(file.id));
|
|
24
|
+
/**
|
|
25
|
+
* Moves one file to where another one is, the others shifting to make room.
|
|
26
|
+
* Unknown ids leave the selection as it is.
|
|
27
|
+
*/ const moveFile = (selection, activeId, overId)=>{
|
|
28
|
+
const from = selection.findIndex(({ id })=>id === activeId);
|
|
29
|
+
const to = selection.findIndex(({ id })=>id === overId);
|
|
30
|
+
if (from === -1 || to === -1 || from === to) {
|
|
31
|
+
return selection;
|
|
32
|
+
}
|
|
33
|
+
const next = [
|
|
34
|
+
...selection
|
|
35
|
+
];
|
|
36
|
+
const [file] = next.splice(from, 1);
|
|
37
|
+
next.splice(to, 0, file);
|
|
38
|
+
return next;
|
|
39
|
+
};
|
|
40
|
+
/** Same files in the same order: confirming would change nothing. */ const isSameSelection = (a, b)=>a.length === b.length && a.every((file, index)=>file.id === b[index].id);
|
|
41
|
+
|
|
42
|
+
exports.addFiles = addFiles;
|
|
43
|
+
exports.hasFile = hasFile;
|
|
44
|
+
exports.isSameSelection = isSameSelection;
|
|
45
|
+
exports.moveFile = moveFile;
|
|
46
|
+
exports.removeFile = removeFile;
|
|
47
|
+
exports.removeFiles = removeFiles;
|
|
48
|
+
exports.toggleFile = toggleFile;
|
|
49
|
+
//# sourceMappingURL=pickerSelection.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pickerSelection.js","sources":["../../../../admin/src/components/AssetPickerDialog/pickerSelection.ts"],"sourcesContent":["import type { File } from '../../../../shared/contracts/files';\n\n/**\n * The picker's selection is the value the field will hold once confirmed:\n * whole `File` objects, in order. Assets already in the field come first, new\n * picks are appended in the order they are clicked.\n */\nexport type PickerSelection = File[];\n\nexport const hasFile = (selection: PickerSelection, id: number) =>\n selection.some((file) => file.id === id);\n\n/**\n * Adds the file, or removes it if it is already there. On a single-value field\n * a new pick replaces whatever was selected.\n */\nexport const toggleFile = (\n selection: PickerSelection,\n file: File,\n { multiple }: { multiple: boolean }\n): PickerSelection => {\n if (hasFile(selection, file.id)) {\n return selection.filter(({ id }) => id !== file.id);\n }\n\n return multiple ? [...selection, file] : [file];\n};\n\n/** Appends every file not already selected, keeping their order (select-all). */\nexport const addFiles = (selection: PickerSelection, files: File[]): PickerSelection => [\n ...selection,\n ...files.filter((file) => !hasFile(selection, file.id)),\n];\n\nexport const removeFile = (selection: PickerSelection, id: number): PickerSelection =>\n selection.filter((file) => file.id !== id);\n\nexport const removeFiles = (selection: PickerSelection, ids: Set<number>): PickerSelection =>\n selection.filter((file) => !ids.has(file.id));\n\n/**\n * Moves one file to where another one is, the others shifting to make room.\n * Unknown ids leave the selection as it is.\n */\nexport const moveFile = (\n selection: PickerSelection,\n activeId: number,\n overId: number\n): PickerSelection => {\n const from = selection.findIndex(({ id }) => id === activeId);\n const to = selection.findIndex(({ id }) => id === overId);\n\n if (from === -1 || to === -1 || from === to) {\n return selection;\n }\n\n const next = [...selection];\n const [file] = next.splice(from, 1);\n next.splice(to, 0, file);\n\n return next;\n};\n\n/** Same files in the same order: confirming would change nothing. */\nexport const isSameSelection = (a: PickerSelection, b: PickerSelection) =>\n a.length === b.length && a.every((file, index) => file.id === b[index].id);\n"],"names":["hasFile","selection","id","some","file","toggleFile","multiple","filter","addFiles","files","removeFile","removeFiles","ids","has","moveFile","activeId","overId","from","findIndex","to","next","splice","isSameSelection","a","b","length","every","index"],"mappings":";;AASO,MAAMA,OAAAA,GAAU,CAACC,SAAAA,EAA4BC,EAAAA,GAClDD,SAAAA,CAAUE,IAAI,CAAC,CAACC,IAAAA,GAASA,IAAAA,CAAKF,EAAE,KAAKA,EAAAA;AAEvC;;;UAIaG,UAAAA,GAAa,CACxBJ,WACAG,IAAAA,EACA,EAAEE,QAAQ,EAAyB,GAAA;AAEnC,IAAA,IAAIN,OAAAA,CAAQC,SAAAA,EAAWG,IAAAA,CAAKF,EAAE,CAAA,EAAG;QAC/B,OAAOD,SAAAA,CAAUM,MAAM,CAAC,CAAC,EAAEL,EAAE,EAAE,GAAKA,EAAAA,KAAOE,IAAAA,CAAKF,EAAE,CAAA;AACpD,IAAA;AAEA,IAAA,OAAOI,QAAAA,GAAW;AAAIL,QAAAA,GAAAA,SAAAA;AAAWG,QAAAA;KAAK,GAAG;AAACA,QAAAA;AAAK,KAAA;AACjD;AAEA,kFACO,MAAMI,QAAAA,GAAW,CAACP,WAA4BQ,KAAAA,GAAmC;AACnFR,QAAAA,GAAAA,SAAAA;WACAQ,KAAAA,CAAMF,MAAM,CAAC,CAACH,IAAAA,GAAS,CAACJ,OAAAA,CAAQC,SAAAA,EAAWG,KAAKF,EAAE,CAAA;;AAGhD,MAAMQ,UAAAA,GAAa,CAACT,SAAAA,EAA4BC,EAAAA,GACrDD,SAAAA,CAAUM,MAAM,CAAC,CAACH,IAAAA,GAASA,IAAAA,CAAKF,EAAE,KAAKA,EAAAA;MAE5BS,WAAAA,GAAc,CAACV,SAAAA,EAA4BW,GAAAA,GACtDX,UAAUM,MAAM,CAAC,CAACH,IAAAA,GAAS,CAACQ,GAAAA,CAAIC,GAAG,CAACT,IAAAA,CAAKF,EAAE,CAAA;AAE7C;;;AAGC,IACM,MAAMY,QAAAA,GAAW,CACtBb,WACAc,QAAAA,EACAC,MAAAA,GAAAA;IAEA,MAAMC,IAAAA,GAAOhB,UAAUiB,SAAS,CAAC,CAAC,EAAEhB,EAAE,EAAE,GAAKA,EAAAA,KAAOa,QAAAA,CAAAA;IACpD,MAAMI,EAAAA,GAAKlB,UAAUiB,SAAS,CAAC,CAAC,EAAEhB,EAAE,EAAE,GAAKA,EAAAA,KAAOc,MAAAA,CAAAA;AAElD,IAAA,IAAIC,SAAS,EAAC,IAAKE,OAAO,EAAC,IAAKF,SAASE,EAAAA,EAAI;QAC3C,OAAOlB,SAAAA;AACT,IAAA;AAEA,IAAA,MAAMmB,IAAAA,GAAO;AAAInB,QAAAA,GAAAA;AAAU,KAAA;AAC3B,IAAA,MAAM,CAACG,IAAAA,CAAK,GAAGgB,IAAAA,CAAKC,MAAM,CAACJ,IAAAA,EAAM,CAAA,CAAA;IACjCG,IAAAA,CAAKC,MAAM,CAACF,EAAAA,EAAI,CAAA,EAAGf,IAAAA,CAAAA;IAEnB,OAAOgB,IAAAA;AACT;AAEA,sEACO,MAAME,eAAAA,GAAkB,CAACC,CAAAA,EAAoBC,CAAAA,GAClDD,CAAAA,CAAEE,MAAM,KAAKD,CAAAA,CAAEC,MAAM,IAAIF,CAAAA,CAAEG,KAAK,CAAC,CAACtB,IAAAA,EAAMuB,KAAAA,GAAUvB,IAAAA,CAAKF,EAAE,KAAKsB,CAAC,CAACG,KAAAA,CAAM,CAACzB,EAAE;;;;;;;;;;"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
const hasFile = (selection, id)=>selection.some((file)=>file.id === id);
|
|
2
|
+
/**
|
|
3
|
+
* Adds the file, or removes it if it is already there. On a single-value field
|
|
4
|
+
* a new pick replaces whatever was selected.
|
|
5
|
+
*/ const toggleFile = (selection, file, { multiple })=>{
|
|
6
|
+
if (hasFile(selection, file.id)) {
|
|
7
|
+
return selection.filter(({ id })=>id !== file.id);
|
|
8
|
+
}
|
|
9
|
+
return multiple ? [
|
|
10
|
+
...selection,
|
|
11
|
+
file
|
|
12
|
+
] : [
|
|
13
|
+
file
|
|
14
|
+
];
|
|
15
|
+
};
|
|
16
|
+
/** Appends every file not already selected, keeping their order (select-all). */ const addFiles = (selection, files)=>[
|
|
17
|
+
...selection,
|
|
18
|
+
...files.filter((file)=>!hasFile(selection, file.id))
|
|
19
|
+
];
|
|
20
|
+
const removeFile = (selection, id)=>selection.filter((file)=>file.id !== id);
|
|
21
|
+
const removeFiles = (selection, ids)=>selection.filter((file)=>!ids.has(file.id));
|
|
22
|
+
/**
|
|
23
|
+
* Moves one file to where another one is, the others shifting to make room.
|
|
24
|
+
* Unknown ids leave the selection as it is.
|
|
25
|
+
*/ const moveFile = (selection, activeId, overId)=>{
|
|
26
|
+
const from = selection.findIndex(({ id })=>id === activeId);
|
|
27
|
+
const to = selection.findIndex(({ id })=>id === overId);
|
|
28
|
+
if (from === -1 || to === -1 || from === to) {
|
|
29
|
+
return selection;
|
|
30
|
+
}
|
|
31
|
+
const next = [
|
|
32
|
+
...selection
|
|
33
|
+
];
|
|
34
|
+
const [file] = next.splice(from, 1);
|
|
35
|
+
next.splice(to, 0, file);
|
|
36
|
+
return next;
|
|
37
|
+
};
|
|
38
|
+
/** Same files in the same order: confirming would change nothing. */ const isSameSelection = (a, b)=>a.length === b.length && a.every((file, index)=>file.id === b[index].id);
|
|
39
|
+
|
|
40
|
+
export { addFiles, hasFile, isSameSelection, moveFile, removeFile, removeFiles, toggleFile };
|
|
41
|
+
//# sourceMappingURL=pickerSelection.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pickerSelection.mjs","sources":["../../../../admin/src/components/AssetPickerDialog/pickerSelection.ts"],"sourcesContent":["import type { File } from '../../../../shared/contracts/files';\n\n/**\n * The picker's selection is the value the field will hold once confirmed:\n * whole `File` objects, in order. Assets already in the field come first, new\n * picks are appended in the order they are clicked.\n */\nexport type PickerSelection = File[];\n\nexport const hasFile = (selection: PickerSelection, id: number) =>\n selection.some((file) => file.id === id);\n\n/**\n * Adds the file, or removes it if it is already there. On a single-value field\n * a new pick replaces whatever was selected.\n */\nexport const toggleFile = (\n selection: PickerSelection,\n file: File,\n { multiple }: { multiple: boolean }\n): PickerSelection => {\n if (hasFile(selection, file.id)) {\n return selection.filter(({ id }) => id !== file.id);\n }\n\n return multiple ? [...selection, file] : [file];\n};\n\n/** Appends every file not already selected, keeping their order (select-all). */\nexport const addFiles = (selection: PickerSelection, files: File[]): PickerSelection => [\n ...selection,\n ...files.filter((file) => !hasFile(selection, file.id)),\n];\n\nexport const removeFile = (selection: PickerSelection, id: number): PickerSelection =>\n selection.filter((file) => file.id !== id);\n\nexport const removeFiles = (selection: PickerSelection, ids: Set<number>): PickerSelection =>\n selection.filter((file) => !ids.has(file.id));\n\n/**\n * Moves one file to where another one is, the others shifting to make room.\n * Unknown ids leave the selection as it is.\n */\nexport const moveFile = (\n selection: PickerSelection,\n activeId: number,\n overId: number\n): PickerSelection => {\n const from = selection.findIndex(({ id }) => id === activeId);\n const to = selection.findIndex(({ id }) => id === overId);\n\n if (from === -1 || to === -1 || from === to) {\n return selection;\n }\n\n const next = [...selection];\n const [file] = next.splice(from, 1);\n next.splice(to, 0, file);\n\n return next;\n};\n\n/** Same files in the same order: confirming would change nothing. */\nexport const isSameSelection = (a: PickerSelection, b: PickerSelection) =>\n a.length === b.length && a.every((file, index) => file.id === b[index].id);\n"],"names":["hasFile","selection","id","some","file","toggleFile","multiple","filter","addFiles","files","removeFile","removeFiles","ids","has","moveFile","activeId","overId","from","findIndex","to","next","splice","isSameSelection","a","b","length","every","index"],"mappings":"AASO,MAAMA,OAAAA,GAAU,CAACC,SAAAA,EAA4BC,EAAAA,GAClDD,SAAAA,CAAUE,IAAI,CAAC,CAACC,IAAAA,GAASA,IAAAA,CAAKF,EAAE,KAAKA,EAAAA;AAEvC;;;UAIaG,UAAAA,GAAa,CACxBJ,WACAG,IAAAA,EACA,EAAEE,QAAQ,EAAyB,GAAA;AAEnC,IAAA,IAAIN,OAAAA,CAAQC,SAAAA,EAAWG,IAAAA,CAAKF,EAAE,CAAA,EAAG;QAC/B,OAAOD,SAAAA,CAAUM,MAAM,CAAC,CAAC,EAAEL,EAAE,EAAE,GAAKA,EAAAA,KAAOE,IAAAA,CAAKF,EAAE,CAAA;AACpD,IAAA;AAEA,IAAA,OAAOI,QAAAA,GAAW;AAAIL,QAAAA,GAAAA,SAAAA;AAAWG,QAAAA;KAAK,GAAG;AAACA,QAAAA;AAAK,KAAA;AACjD;AAEA,kFACO,MAAMI,QAAAA,GAAW,CAACP,WAA4BQ,KAAAA,GAAmC;AACnFR,QAAAA,GAAAA,SAAAA;WACAQ,KAAAA,CAAMF,MAAM,CAAC,CAACH,IAAAA,GAAS,CAACJ,OAAAA,CAAQC,SAAAA,EAAWG,KAAKF,EAAE,CAAA;;AAGhD,MAAMQ,UAAAA,GAAa,CAACT,SAAAA,EAA4BC,EAAAA,GACrDD,SAAAA,CAAUM,MAAM,CAAC,CAACH,IAAAA,GAASA,IAAAA,CAAKF,EAAE,KAAKA,EAAAA;MAE5BS,WAAAA,GAAc,CAACV,SAAAA,EAA4BW,GAAAA,GACtDX,UAAUM,MAAM,CAAC,CAACH,IAAAA,GAAS,CAACQ,GAAAA,CAAIC,GAAG,CAACT,IAAAA,CAAKF,EAAE,CAAA;AAE7C;;;AAGC,IACM,MAAMY,QAAAA,GAAW,CACtBb,WACAc,QAAAA,EACAC,MAAAA,GAAAA;IAEA,MAAMC,IAAAA,GAAOhB,UAAUiB,SAAS,CAAC,CAAC,EAAEhB,EAAE,EAAE,GAAKA,EAAAA,KAAOa,QAAAA,CAAAA;IACpD,MAAMI,EAAAA,GAAKlB,UAAUiB,SAAS,CAAC,CAAC,EAAEhB,EAAE,EAAE,GAAKA,EAAAA,KAAOc,MAAAA,CAAAA;AAElD,IAAA,IAAIC,SAAS,EAAC,IAAKE,OAAO,EAAC,IAAKF,SAASE,EAAAA,EAAI;QAC3C,OAAOlB,SAAAA;AACT,IAAA;AAEA,IAAA,MAAMmB,IAAAA,GAAO;AAAInB,QAAAA,GAAAA;AAAU,KAAA;AAC3B,IAAA,MAAM,CAACG,IAAAA,CAAK,GAAGgB,IAAAA,CAAKC,MAAM,CAACJ,IAAAA,EAAM,CAAA,CAAA;IACjCG,IAAAA,CAAKC,MAAM,CAACF,EAAAA,EAAI,CAAA,EAAGf,IAAAA,CAAAA;IAEnB,OAAOgB,IAAAA;AACT;AAEA,sEACO,MAAME,eAAAA,GAAkB,CAACC,CAAAA,EAAoBC,CAAAA,GAClDD,CAAAA,CAAEE,MAAM,KAAKD,CAAAA,CAAEC,MAAM,IAAIF,CAAAA,CAAEG,KAAK,CAAC,CAACtB,IAAAA,EAAMuB,KAAAA,GAAUvB,IAAAA,CAAKF,EAAE,KAAKsB,CAAC,CAACG,KAAAA,CAAM,CAACzB,EAAE;;;;"}
|
|
@@ -8,6 +8,7 @@ var styledComponents = require('styled-components');
|
|
|
8
8
|
var useMediaLibraryPermissions = require('../../hooks/useMediaLibraryPermissions.js');
|
|
9
9
|
var ActionsMenuContent = require('../../pages/Assets/components/ActionsMenuContent.js');
|
|
10
10
|
var translations = require('../../utils/translations.js');
|
|
11
|
+
var FieldControls = require('./FieldControls.js');
|
|
11
12
|
|
|
12
13
|
// The trigger reads as a link on the label row, not as a button: no padding, no
|
|
13
14
|
// ghost background, primary text. `Menu.Trigger` takes no `textColor`, so the
|
|
@@ -100,7 +101,7 @@ const AddAssetTrigger = styledComponents.styled(designSystem.Menu.Trigger)`
|
|
|
100
101
|
zIndex: 2,
|
|
101
102
|
minWidth: "22rem",
|
|
102
103
|
children: [
|
|
103
|
-
canBrowse && /*#__PURE__*/ jsxRuntime.jsx(
|
|
104
|
+
canBrowse && /*#__PURE__*/ jsxRuntime.jsx(FieldControls.FieldMenuItem, {
|
|
104
105
|
startIcon: /*#__PURE__*/ jsxRuntime.jsx(icons.Images, {}),
|
|
105
106
|
disabled: isLoading,
|
|
106
107
|
onSelect: onBrowseLibrary,
|
|
@@ -111,7 +112,7 @@ const AddAssetTrigger = styledComponents.styled(designSystem.Menu.Trigger)`
|
|
|
111
112
|
}),
|
|
112
113
|
canUpload && /*#__PURE__*/ jsxRuntime.jsxs(jsxRuntime.Fragment, {
|
|
113
114
|
children: [
|
|
114
|
-
/*#__PURE__*/ jsxRuntime.jsx(
|
|
115
|
+
/*#__PURE__*/ jsxRuntime.jsx(FieldControls.FieldMenuItem, {
|
|
115
116
|
startIcon: /*#__PURE__*/ jsxRuntime.jsx(icons.Upload, {}),
|
|
116
117
|
disabled: isLoading,
|
|
117
118
|
onSelect: onUploadFromDevice,
|
|
@@ -120,7 +121,7 @@ const AddAssetTrigger = styledComponents.styled(designSystem.Menu.Trigger)`
|
|
|
120
121
|
defaultMessage: 'Upload from device'
|
|
121
122
|
})
|
|
122
123
|
}),
|
|
123
|
-
/*#__PURE__*/ jsxRuntime.jsx(
|
|
124
|
+
/*#__PURE__*/ jsxRuntime.jsx(FieldControls.FieldMenuItem, {
|
|
124
125
|
startIcon: /*#__PURE__*/ jsxRuntime.jsx(icons.Link, {}),
|
|
125
126
|
disabled: isLoading,
|
|
126
127
|
onSelect: onUploadFromUrl,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AddAssetMenu.js","sources":["../../../../admin/src/components/MediaLibraryInput/AddAssetMenu.tsx"],"sourcesContent":["import { Menu } from '@strapi/design-system';\nimport { ChevronDown, Images, Link, Upload } from '@strapi/icons';\nimport { useIntl } from 'react-intl';\nimport { styled } from 'styled-components';\n\nimport { useMediaLibraryPermissions } from '../../hooks/useMediaLibraryPermissions';\nimport { ActionsMenuContent } from '../../pages/Assets/components/ActionsMenuContent';\nimport { getTranslationKey } from '../../utils/translations';\n\n// The trigger reads as a link on the label row, not as a button: no padding, no\n// ghost background, primary text. `Menu.Trigger` takes no `textColor`, so the\n// colour is set here and forced past the design system's own span rule.\nconst AddAssetTrigger = styled(Menu.Trigger)`\n padding: 0;\n\n // No hover treatment at all: this reads as a link on the label row, and the\n // design system's ghost button paints a primary100 plate behind it (also while\n // the menu is open, via data-state).\n &,\n &:hover,\n &[data-state='open'] {\n background: transparent;\n background-color: transparent;\n }\n\n &,\n & span,\n &:hover span {\n color: ${({ theme }) => theme.colors.primary600};\n }\n\n & span {\n font-weight: ${({ theme }) => theme.fontWeights.regular};\n }\n\n // The chevron needs the fill, not the colour: the design system paints button\n // icons with its own \"svg path { fill }\" rule per variant, and repaints them\n // again on hover — both beat an inherited color and the icon's own\n // fill=\"currentColor\". Doubled specificity so these land after those rules\n // whatever order they are injected in.\n && svg path,\n &&:hover svg path {\n fill: ${({ theme }) => theme.colors.primary600};\n }\n\n // The design system's disabled button is a bordered grey plate; this stays a\n // greyed-out link instead.\n &&[aria-disabled='true'] {\n border-color: transparent;\n background: transparent;\n }\n\n &[aria-disabled='true'],\n &[aria-disabled='true'] span {\n color: ${({ theme }) => theme.colors.neutral500};\n }\n\n &&[aria-disabled='true'] svg path {\n fill: ${({ theme }) => theme.colors.neutral500};\n }\n`;\n\ninterface AddAssetMenuProps {\n disabled?: boolean;\n onBrowseLibrary: () => void;\n onUploadFromDevice: () => void;\n onUploadFromUrl: () => void;\n}\n\n/**\n * The field's \"Add asset\" menu, on the label row.\n *\n * Browsing needs the Media Library's read permission, the two upload entries\n * `assets.create`; each entry disappears without its permission, and the\n * trigger itself goes when nothing is left to offer, rather than opening an\n * empty menu.\n *\n * The drop zone below keeps working whatever this shows — it is a second way\n * in, not the only one.\n */\nexport const AddAssetMenu = ({\n disabled = false,\n onBrowseLibrary,\n onUploadFromDevice,\n onUploadFromUrl,\n}: AddAssetMenuProps) => {\n const { formatMessage } = useIntl();\n const { canRead, canCreate, isLoading } = useMediaLibraryPermissions();\n\n // `useRBAC` starts every instance at `isLoading: true` with the flags false.\n // Until it settles, every entry shows but none can be picked: hiding them\n // would flash a smaller menu, enabling them would lead to a 403.\n const canBrowse = isLoading || canRead;\n const canUpload = isLoading || canCreate;\n\n if (!canBrowse && !canUpload) {\n return null;\n }\n\n return (\n <Menu.Root>\n <AddAssetTrigger variant=\"ghost\" disabled={disabled} endIcon={<ChevronDown aria-hidden />}>\n {formatMessage({\n id: getTranslationKey('content-manager.input.add-asset'),\n defaultMessage: 'Add asset',\n })}\n </AddAssetTrigger>\n\n <ActionsMenuContent popoverPlacement=\"bottom-end\" zIndex={2} minWidth=\"22rem\">\n {canBrowse && (\n <
|
|
1
|
+
{"version":3,"file":"AddAssetMenu.js","sources":["../../../../admin/src/components/MediaLibraryInput/AddAssetMenu.tsx"],"sourcesContent":["import { Menu } from '@strapi/design-system';\nimport { ChevronDown, Images, Link, Upload } from '@strapi/icons';\nimport { useIntl } from 'react-intl';\nimport { styled } from 'styled-components';\n\nimport { useMediaLibraryPermissions } from '../../hooks/useMediaLibraryPermissions';\nimport { ActionsMenuContent } from '../../pages/Assets/components/ActionsMenuContent';\nimport { getTranslationKey } from '../../utils/translations';\n\nimport { FieldMenuItem } from './FieldControls';\n\n// The trigger reads as a link on the label row, not as a button: no padding, no\n// ghost background, primary text. `Menu.Trigger` takes no `textColor`, so the\n// colour is set here and forced past the design system's own span rule.\nconst AddAssetTrigger = styled(Menu.Trigger)`\n padding: 0;\n\n // No hover treatment at all: this reads as a link on the label row, and the\n // design system's ghost button paints a primary100 plate behind it (also while\n // the menu is open, via data-state).\n &,\n &:hover,\n &[data-state='open'] {\n background: transparent;\n background-color: transparent;\n }\n\n &,\n & span,\n &:hover span {\n color: ${({ theme }) => theme.colors.primary600};\n }\n\n & span {\n font-weight: ${({ theme }) => theme.fontWeights.regular};\n }\n\n // The chevron needs the fill, not the colour: the design system paints button\n // icons with its own \"svg path { fill }\" rule per variant, and repaints them\n // again on hover — both beat an inherited color and the icon's own\n // fill=\"currentColor\". Doubled specificity so these land after those rules\n // whatever order they are injected in.\n && svg path,\n &&:hover svg path {\n fill: ${({ theme }) => theme.colors.primary600};\n }\n\n // The design system's disabled button is a bordered grey plate; this stays a\n // greyed-out link instead.\n &&[aria-disabled='true'] {\n border-color: transparent;\n background: transparent;\n }\n\n &[aria-disabled='true'],\n &[aria-disabled='true'] span {\n color: ${({ theme }) => theme.colors.neutral500};\n }\n\n &&[aria-disabled='true'] svg path {\n fill: ${({ theme }) => theme.colors.neutral500};\n }\n`;\n\ninterface AddAssetMenuProps {\n disabled?: boolean;\n onBrowseLibrary: () => void;\n onUploadFromDevice: () => void;\n onUploadFromUrl: () => void;\n}\n\n/**\n * The field's \"Add asset\" menu, on the label row.\n *\n * Browsing needs the Media Library's read permission, the two upload entries\n * `assets.create`; each entry disappears without its permission, and the\n * trigger itself goes when nothing is left to offer, rather than opening an\n * empty menu.\n *\n * The drop zone below keeps working whatever this shows — it is a second way\n * in, not the only one.\n */\nexport const AddAssetMenu = ({\n disabled = false,\n onBrowseLibrary,\n onUploadFromDevice,\n onUploadFromUrl,\n}: AddAssetMenuProps) => {\n const { formatMessage } = useIntl();\n const { canRead, canCreate, isLoading } = useMediaLibraryPermissions();\n\n // `useRBAC` starts every instance at `isLoading: true` with the flags false.\n // Until it settles, every entry shows but none can be picked: hiding them\n // would flash a smaller menu, enabling them would lead to a 403.\n const canBrowse = isLoading || canRead;\n const canUpload = isLoading || canCreate;\n\n if (!canBrowse && !canUpload) {\n return null;\n }\n\n return (\n <Menu.Root>\n <AddAssetTrigger variant=\"ghost\" disabled={disabled} endIcon={<ChevronDown aria-hidden />}>\n {formatMessage({\n id: getTranslationKey('content-manager.input.add-asset'),\n defaultMessage: 'Add asset',\n })}\n </AddAssetTrigger>\n\n <ActionsMenuContent popoverPlacement=\"bottom-end\" zIndex={2} minWidth=\"22rem\">\n {canBrowse && (\n <FieldMenuItem startIcon={<Images />} disabled={isLoading} onSelect={onBrowseLibrary}>\n {formatMessage({\n id: getTranslationKey('content-manager.input.add-asset.browse'),\n defaultMessage: 'Browse library',\n })}\n </FieldMenuItem>\n )}\n\n {canUpload && (\n <>\n <FieldMenuItem\n startIcon={<Upload />}\n disabled={isLoading}\n onSelect={onUploadFromDevice}\n >\n {formatMessage({\n id: getTranslationKey('content-manager.input.add-asset.device'),\n defaultMessage: 'Upload from device',\n })}\n </FieldMenuItem>\n\n <FieldMenuItem startIcon={<Link />} disabled={isLoading} onSelect={onUploadFromUrl}>\n {formatMessage({\n id: getTranslationKey('content-manager.input.add-asset.url'),\n defaultMessage: 'Upload from URL',\n })}\n </FieldMenuItem>\n </>\n )}\n </ActionsMenuContent>\n </Menu.Root>\n );\n};\n"],"names":["AddAssetTrigger","styled","Menu","Trigger","theme","colors","primary600","fontWeights","regular","neutral500","AddAssetMenu","disabled","onBrowseLibrary","onUploadFromDevice","onUploadFromUrl","formatMessage","useIntl","canRead","canCreate","isLoading","useMediaLibraryPermissions","canBrowse","canUpload","_jsxs","Root","_jsx","variant","endIcon","ChevronDown","aria-hidden","id","getTranslationKey","defaultMessage","ActionsMenuContent","popoverPlacement","zIndex","minWidth","FieldMenuItem","startIcon","Images","onSelect","_Fragment","Upload","Link"],"mappings":"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"}
|
|
@@ -6,6 +6,7 @@ import { styled } from 'styled-components';
|
|
|
6
6
|
import { useMediaLibraryPermissions } from '../../hooks/useMediaLibraryPermissions.mjs';
|
|
7
7
|
import { ActionsMenuContent } from '../../pages/Assets/components/ActionsMenuContent.mjs';
|
|
8
8
|
import { getTranslationKey } from '../../utils/translations.mjs';
|
|
9
|
+
import { FieldMenuItem } from './FieldControls.mjs';
|
|
9
10
|
|
|
10
11
|
// The trigger reads as a link on the label row, not as a button: no padding, no
|
|
11
12
|
// ghost background, primary text. `Menu.Trigger` takes no `textColor`, so the
|
|
@@ -98,7 +99,7 @@ const AddAssetTrigger = styled(Menu.Trigger)`
|
|
|
98
99
|
zIndex: 2,
|
|
99
100
|
minWidth: "22rem",
|
|
100
101
|
children: [
|
|
101
|
-
canBrowse && /*#__PURE__*/ jsx(
|
|
102
|
+
canBrowse && /*#__PURE__*/ jsx(FieldMenuItem, {
|
|
102
103
|
startIcon: /*#__PURE__*/ jsx(Images, {}),
|
|
103
104
|
disabled: isLoading,
|
|
104
105
|
onSelect: onBrowseLibrary,
|
|
@@ -109,7 +110,7 @@ const AddAssetTrigger = styled(Menu.Trigger)`
|
|
|
109
110
|
}),
|
|
110
111
|
canUpload && /*#__PURE__*/ jsxs(Fragment, {
|
|
111
112
|
children: [
|
|
112
|
-
/*#__PURE__*/ jsx(
|
|
113
|
+
/*#__PURE__*/ jsx(FieldMenuItem, {
|
|
113
114
|
startIcon: /*#__PURE__*/ jsx(Upload, {}),
|
|
114
115
|
disabled: isLoading,
|
|
115
116
|
onSelect: onUploadFromDevice,
|
|
@@ -118,7 +119,7 @@ const AddAssetTrigger = styled(Menu.Trigger)`
|
|
|
118
119
|
defaultMessage: 'Upload from device'
|
|
119
120
|
})
|
|
120
121
|
}),
|
|
121
|
-
/*#__PURE__*/ jsx(
|
|
122
|
+
/*#__PURE__*/ jsx(FieldMenuItem, {
|
|
122
123
|
startIcon: /*#__PURE__*/ jsx(Link, {}),
|
|
123
124
|
disabled: isLoading,
|
|
124
125
|
onSelect: onUploadFromUrl,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AddAssetMenu.mjs","sources":["../../../../admin/src/components/MediaLibraryInput/AddAssetMenu.tsx"],"sourcesContent":["import { Menu } from '@strapi/design-system';\nimport { ChevronDown, Images, Link, Upload } from '@strapi/icons';\nimport { useIntl } from 'react-intl';\nimport { styled } from 'styled-components';\n\nimport { useMediaLibraryPermissions } from '../../hooks/useMediaLibraryPermissions';\nimport { ActionsMenuContent } from '../../pages/Assets/components/ActionsMenuContent';\nimport { getTranslationKey } from '../../utils/translations';\n\n// The trigger reads as a link on the label row, not as a button: no padding, no\n// ghost background, primary text. `Menu.Trigger` takes no `textColor`, so the\n// colour is set here and forced past the design system's own span rule.\nconst AddAssetTrigger = styled(Menu.Trigger)`\n padding: 0;\n\n // No hover treatment at all: this reads as a link on the label row, and the\n // design system's ghost button paints a primary100 plate behind it (also while\n // the menu is open, via data-state).\n &,\n &:hover,\n &[data-state='open'] {\n background: transparent;\n background-color: transparent;\n }\n\n &,\n & span,\n &:hover span {\n color: ${({ theme }) => theme.colors.primary600};\n }\n\n & span {\n font-weight: ${({ theme }) => theme.fontWeights.regular};\n }\n\n // The chevron needs the fill, not the colour: the design system paints button\n // icons with its own \"svg path { fill }\" rule per variant, and repaints them\n // again on hover — both beat an inherited color and the icon's own\n // fill=\"currentColor\". Doubled specificity so these land after those rules\n // whatever order they are injected in.\n && svg path,\n &&:hover svg path {\n fill: ${({ theme }) => theme.colors.primary600};\n }\n\n // The design system's disabled button is a bordered grey plate; this stays a\n // greyed-out link instead.\n &&[aria-disabled='true'] {\n border-color: transparent;\n background: transparent;\n }\n\n &[aria-disabled='true'],\n &[aria-disabled='true'] span {\n color: ${({ theme }) => theme.colors.neutral500};\n }\n\n &&[aria-disabled='true'] svg path {\n fill: ${({ theme }) => theme.colors.neutral500};\n }\n`;\n\ninterface AddAssetMenuProps {\n disabled?: boolean;\n onBrowseLibrary: () => void;\n onUploadFromDevice: () => void;\n onUploadFromUrl: () => void;\n}\n\n/**\n * The field's \"Add asset\" menu, on the label row.\n *\n * Browsing needs the Media Library's read permission, the two upload entries\n * `assets.create`; each entry disappears without its permission, and the\n * trigger itself goes when nothing is left to offer, rather than opening an\n * empty menu.\n *\n * The drop zone below keeps working whatever this shows — it is a second way\n * in, not the only one.\n */\nexport const AddAssetMenu = ({\n disabled = false,\n onBrowseLibrary,\n onUploadFromDevice,\n onUploadFromUrl,\n}: AddAssetMenuProps) => {\n const { formatMessage } = useIntl();\n const { canRead, canCreate, isLoading } = useMediaLibraryPermissions();\n\n // `useRBAC` starts every instance at `isLoading: true` with the flags false.\n // Until it settles, every entry shows but none can be picked: hiding them\n // would flash a smaller menu, enabling them would lead to a 403.\n const canBrowse = isLoading || canRead;\n const canUpload = isLoading || canCreate;\n\n if (!canBrowse && !canUpload) {\n return null;\n }\n\n return (\n <Menu.Root>\n <AddAssetTrigger variant=\"ghost\" disabled={disabled} endIcon={<ChevronDown aria-hidden />}>\n {formatMessage({\n id: getTranslationKey('content-manager.input.add-asset'),\n defaultMessage: 'Add asset',\n })}\n </AddAssetTrigger>\n\n <ActionsMenuContent popoverPlacement=\"bottom-end\" zIndex={2} minWidth=\"22rem\">\n {canBrowse && (\n <
|
|
1
|
+
{"version":3,"file":"AddAssetMenu.mjs","sources":["../../../../admin/src/components/MediaLibraryInput/AddAssetMenu.tsx"],"sourcesContent":["import { Menu } from '@strapi/design-system';\nimport { ChevronDown, Images, Link, Upload } from '@strapi/icons';\nimport { useIntl } from 'react-intl';\nimport { styled } from 'styled-components';\n\nimport { useMediaLibraryPermissions } from '../../hooks/useMediaLibraryPermissions';\nimport { ActionsMenuContent } from '../../pages/Assets/components/ActionsMenuContent';\nimport { getTranslationKey } from '../../utils/translations';\n\nimport { FieldMenuItem } from './FieldControls';\n\n// The trigger reads as a link on the label row, not as a button: no padding, no\n// ghost background, primary text. `Menu.Trigger` takes no `textColor`, so the\n// colour is set here and forced past the design system's own span rule.\nconst AddAssetTrigger = styled(Menu.Trigger)`\n padding: 0;\n\n // No hover treatment at all: this reads as a link on the label row, and the\n // design system's ghost button paints a primary100 plate behind it (also while\n // the menu is open, via data-state).\n &,\n &:hover,\n &[data-state='open'] {\n background: transparent;\n background-color: transparent;\n }\n\n &,\n & span,\n &:hover span {\n color: ${({ theme }) => theme.colors.primary600};\n }\n\n & span {\n font-weight: ${({ theme }) => theme.fontWeights.regular};\n }\n\n // The chevron needs the fill, not the colour: the design system paints button\n // icons with its own \"svg path { fill }\" rule per variant, and repaints them\n // again on hover — both beat an inherited color and the icon's own\n // fill=\"currentColor\". Doubled specificity so these land after those rules\n // whatever order they are injected in.\n && svg path,\n &&:hover svg path {\n fill: ${({ theme }) => theme.colors.primary600};\n }\n\n // The design system's disabled button is a bordered grey plate; this stays a\n // greyed-out link instead.\n &&[aria-disabled='true'] {\n border-color: transparent;\n background: transparent;\n }\n\n &[aria-disabled='true'],\n &[aria-disabled='true'] span {\n color: ${({ theme }) => theme.colors.neutral500};\n }\n\n &&[aria-disabled='true'] svg path {\n fill: ${({ theme }) => theme.colors.neutral500};\n }\n`;\n\ninterface AddAssetMenuProps {\n disabled?: boolean;\n onBrowseLibrary: () => void;\n onUploadFromDevice: () => void;\n onUploadFromUrl: () => void;\n}\n\n/**\n * The field's \"Add asset\" menu, on the label row.\n *\n * Browsing needs the Media Library's read permission, the two upload entries\n * `assets.create`; each entry disappears without its permission, and the\n * trigger itself goes when nothing is left to offer, rather than opening an\n * empty menu.\n *\n * The drop zone below keeps working whatever this shows — it is a second way\n * in, not the only one.\n */\nexport const AddAssetMenu = ({\n disabled = false,\n onBrowseLibrary,\n onUploadFromDevice,\n onUploadFromUrl,\n}: AddAssetMenuProps) => {\n const { formatMessage } = useIntl();\n const { canRead, canCreate, isLoading } = useMediaLibraryPermissions();\n\n // `useRBAC` starts every instance at `isLoading: true` with the flags false.\n // Until it settles, every entry shows but none can be picked: hiding them\n // would flash a smaller menu, enabling them would lead to a 403.\n const canBrowse = isLoading || canRead;\n const canUpload = isLoading || canCreate;\n\n if (!canBrowse && !canUpload) {\n return null;\n }\n\n return (\n <Menu.Root>\n <AddAssetTrigger variant=\"ghost\" disabled={disabled} endIcon={<ChevronDown aria-hidden />}>\n {formatMessage({\n id: getTranslationKey('content-manager.input.add-asset'),\n defaultMessage: 'Add asset',\n })}\n </AddAssetTrigger>\n\n <ActionsMenuContent popoverPlacement=\"bottom-end\" zIndex={2} minWidth=\"22rem\">\n {canBrowse && (\n <FieldMenuItem startIcon={<Images />} disabled={isLoading} onSelect={onBrowseLibrary}>\n {formatMessage({\n id: getTranslationKey('content-manager.input.add-asset.browse'),\n defaultMessage: 'Browse library',\n })}\n </FieldMenuItem>\n )}\n\n {canUpload && (\n <>\n <FieldMenuItem\n startIcon={<Upload />}\n disabled={isLoading}\n onSelect={onUploadFromDevice}\n >\n {formatMessage({\n id: getTranslationKey('content-manager.input.add-asset.device'),\n defaultMessage: 'Upload from device',\n })}\n </FieldMenuItem>\n\n <FieldMenuItem startIcon={<Link />} disabled={isLoading} onSelect={onUploadFromUrl}>\n {formatMessage({\n id: getTranslationKey('content-manager.input.add-asset.url'),\n defaultMessage: 'Upload from URL',\n })}\n </FieldMenuItem>\n </>\n )}\n </ActionsMenuContent>\n </Menu.Root>\n );\n};\n"],"names":["AddAssetTrigger","styled","Menu","Trigger","theme","colors","primary600","fontWeights","regular","neutral500","AddAssetMenu","disabled","onBrowseLibrary","onUploadFromDevice","onUploadFromUrl","formatMessage","useIntl","canRead","canCreate","isLoading","useMediaLibraryPermissions","canBrowse","canUpload","_jsxs","Root","_jsx","variant","endIcon","ChevronDown","aria-hidden","id","getTranslationKey","defaultMessage","ActionsMenuContent","popoverPlacement","zIndex","minWidth","FieldMenuItem","startIcon","Images","onSelect","_Fragment","Upload","Link"],"mappings":"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"}
|