@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":"AssetsView.js","sources":["../../../../../admin/src/pages/Assets/components/AssetsView.tsx"],"sourcesContent":["import { useMemo } from 'react';\n\nimport { Box, Flex, Loader, Typography } from '@strapi/design-system';\nimport { useIntl } from 'react-intl';\n\nimport { type ItemLocations } from '../../../utils/itemLocations';\nimport { getTranslationKey } from '../../../utils/translations';\nimport { viewOptions } from '../constants';\nimport { useInfiniteScrollSentinel } from '../hooks/useInfiniteScrollSentinel';\nimport { useListSettings } from '../hooks/useListSettings';\nimport { type FoldersPosition } from '../hooks/useListSort';\nimport { mergeMixedList } from '../utils/mergeMixedList';\nimport { buildRenderedKeys } from '../utils/renderedKeys';\n\nimport { AssetsGrid } from './AssetsGrid';\nimport { AssetsTable } from './AssetsTable';\nimport { BulkActionsBar } from './BulkActionsBar';\nimport { EmptyState, FilteredEmptyState } from './EmptyState';\nimport { ItemContextMenuProvider } from './ItemContextMenu';\n\nimport type { File } from '../../../../../shared/contracts/files';\nimport type { Folder } from '../../../../../shared/contracts/folders';\n\n// The negative bottom margin shrinks the trigger area by a pixel so the 1px\n// sentinel sitting exactly at the fold (when a page's rows happen to fill the\n// viewport) reads as \"not visible\" and doesn't pull an extra page. It still\n// triggers as soon as the sentinel scrolls a hair into view. Tune the bottom\n// value if the list over- or under-fetches near the fold.\nconst INTERSECTION_OPTIONS: IntersectionObserverInit = {\n threshold: 0,\n rootMargin: '0px 0px -1px 0px',\n};\n\n/* -------------------------------------------------------------------------------------------------\n * AssetsView\n * -----------------------------------------------------------------------------------------------*/\n\ninterface AssetsViewProps {\n view: number;\n folders: Folder[];\n isLoadingFolders: boolean;\n assets: File[];\n /** Total matching assets on the server, beyond the pages loaded so far. */\n assetsTotal?: number;\n isLoadingAssets: boolean;\n isFetchingMore: boolean;\n hasNextPage: boolean;\n fetchNextPage: () => void;\n error: unknown;\n locations: ItemLocations;\n searchQuery: string;\n assetsSort: string;\n foldersPosition: FoldersPosition;\n hasActiveFilters: boolean;\n onClearFilters: () => void;\n onAssetItemClick: (assetId: number) => void;\n onAddAssets: () => void;\n canAddAssets: boolean;\n onClearSearch: () => void;\n}\n\nexport const AssetsView = ({\n view,\n folders,\n isLoadingFolders,\n assets,\n assetsTotal,\n isLoadingAssets,\n isFetchingMore,\n hasNextPage,\n fetchNextPage,\n error,\n locations,\n searchQuery,\n assetsSort,\n foldersPosition,\n hasActiveFilters,\n onClearFilters,\n onAssetItemClick,\n onAddAssets,\n canAddAssets,\n onClearSearch,\n}: AssetsViewProps) => {\n const { formatMessage } = useIntl();\n const { showItemActions } = useListSettings();\n\n const isGridView = view === viewOptions.GRID;\n const isLoading = isLoadingAssets || isLoadingFolders;\n\n // \"Folders: Mixed with files\" — interleave the complete folder list into the\n // loaded asset stream client-side, following the active sort. Table view\n // only: the grid always keeps folders in their own band on top.\n const mixedItems = useMemo(\n () =>\n foldersPosition === 'mixed' && !isGridView\n ? mergeMixedList({ folders, assets, sort: assetsSort, hasNextPage })\n : null,\n [foldersPosition, isGridView, folders, assets, assetsSort, hasNextPage]\n );\n\n // Derived once here so the table, the grid and the bulk bar all agree on what\n // is on screen — in mixed mode that is not simply every folder.\n const renderedKeys = buildRenderedKeys({ folders, assets, mixedItems });\n\n const loadMoreRef = useInfiniteScrollSentinel({\n hasNextPage,\n isFetchingMore,\n onLoadMore: fetchNextPage,\n options: INTERSECTION_OPTIONS,\n });\n\n const list = isGridView ? (\n <AssetsGrid\n folders={folders}\n assets={assets}\n assetsTotal={assetsTotal}\n renderedKeys={renderedKeys}\n onAssetItemClick={onAssetItemClick}\n />\n ) : (\n <AssetsTable\n assets={assets}\n folders={folders}\n mixedItems={mixedItems}\n renderedKeys={renderedKeys}\n onAssetItemClick={onAssetItemClick}\n />\n );\n\n if (isLoading) {\n return (\n <Flex justifyContent=\"center\" padding={8}>\n <Loader>{formatMessage({ id: 'app.loading', defaultMessage: 'Loading...' })}</Loader>\n </Flex>\n );\n }\n\n if (error) {\n return (\n <Box padding={8}>\n <Typography textColor=\"danger600\">\n {formatMessage({\n id: getTranslationKey('list.assets.error'),\n defaultMessage: 'An error occurred while fetching assets.',\n })}\n </Typography>\n </Box>\n );\n }\n\n if (folders.length === 0 && assets.length === 0) {\n // While searching, the search empty state wins (it names the query); a\n // filter-only dead end gets the filtered variant with its Clear action.\n return hasActiveFilters && !searchQuery ? (\n <FilteredEmptyState onClearFilters={onClearFilters} />\n ) : (\n <EmptyState\n onAddAssets={onAddAssets}\n canAddAssets={canAddAssets}\n searchQuery={searchQuery}\n onClearSearch={onClearSearch}\n />\n );\n }\n return (\n <>\n {showItemActions ? (\n // Above both views so one instance serves either, and so the selection\n // menu has the `locations` its move dialog validates against.\n <ItemContextMenuProvider locations={locations}>{list}</ItemContextMenuProvider>\n ) : (\n list\n )}\n <div ref={loadMoreRef} style={{ height: 1 }} />\n {isFetchingMore && (\n <Flex justifyContent=\"center\" padding={4}>\n <Loader>\n {formatMessage({\n id: getTranslationKey('list.assets.loading-more'),\n defaultMessage: 'Loading more assets...',\n })}\n </Loader>\n </Flex>\n )}\n {/* Lives here rather than in `AssetsPage` so it can read the loaded\n assets: the AI metadata action needs their mime types to know what\n the provider can handle. `position: fixed` keeps it visually anchored\n regardless of where it sits in the tree. */}\n {showItemActions && (\n <BulkActionsBar assets={assets} renderedKeys={renderedKeys} locations={locations} />\n )}\n </>\n );\n};\n"],"names":["INTERSECTION_OPTIONS","threshold","rootMargin","AssetsView","view","folders","isLoadingFolders","assets","assetsTotal","isLoadingAssets","isFetchingMore","hasNextPage","fetchNextPage","error","locations","searchQuery","assetsSort","foldersPosition","hasActiveFilters","onClearFilters","onAssetItemClick","onAddAssets","canAddAssets","onClearSearch","formatMessage","useIntl","showItemActions","useListSettings","isGridView","viewOptions","GRID","isLoading","mixedItems","useMemo","mergeMixedList","sort","renderedKeys","buildRenderedKeys","loadMoreRef","useInfiniteScrollSentinel","onLoadMore","options","list","_jsx","AssetsGrid","AssetsTable","Flex","justifyContent","padding","Loader","id","defaultMessage","Box","Typography","textColor","getTranslationKey","length","FilteredEmptyState","EmptyState","_jsxs","_Fragment","ItemContextMenuProvider","div","ref","style","height","BulkActionsBar"],"mappings":"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"}
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
2
|
+
import { useMemo } from 'react';
|
|
3
|
+
import { Flex, Loader, Box, Typography } from '@strapi/design-system';
|
|
4
|
+
import { useIntl } from 'react-intl';
|
|
5
|
+
import { getTranslationKey } from '../../../utils/translations.mjs';
|
|
6
|
+
import { viewOptions } from '../constants.mjs';
|
|
7
|
+
import { useInfiniteScrollSentinel } from '../hooks/useInfiniteScrollSentinel.mjs';
|
|
8
|
+
import { useListSettings } from '../hooks/useListSettings.mjs';
|
|
9
|
+
import { mergeMixedList } from '../utils/mergeMixedList.mjs';
|
|
10
|
+
import { buildRenderedKeys } from '../utils/renderedKeys.mjs';
|
|
11
|
+
import { AssetsGrid } from './AssetsGrid.mjs';
|
|
12
|
+
import { AssetsTable } from './AssetsTable.mjs';
|
|
13
|
+
import { BulkActionsBar } from './BulkActionsBar.mjs';
|
|
14
|
+
import { FilteredEmptyState, EmptyState } from './EmptyState.mjs';
|
|
15
|
+
import { ItemContextMenuProvider } from './ItemContextMenu.mjs';
|
|
16
|
+
|
|
17
|
+
// The negative bottom margin shrinks the trigger area by a pixel so the 1px
|
|
18
|
+
// sentinel sitting exactly at the fold (when a page's rows happen to fill the
|
|
19
|
+
// viewport) reads as "not visible" and doesn't pull an extra page. It still
|
|
20
|
+
// triggers as soon as the sentinel scrolls a hair into view. Tune the bottom
|
|
21
|
+
// value if the list over- or under-fetches near the fold.
|
|
22
|
+
const INTERSECTION_OPTIONS = {
|
|
23
|
+
threshold: 0,
|
|
24
|
+
rootMargin: '0px 0px -1px 0px'
|
|
25
|
+
};
|
|
26
|
+
const AssetsView = ({ view, folders, isLoadingFolders, assets, assetsTotal, isLoadingAssets, isFetchingMore, hasNextPage, fetchNextPage, error, locations, searchQuery, assetsSort, foldersPosition, hasActiveFilters, onClearFilters, onAssetItemClick, onAddAssets, canAddAssets, onClearSearch })=>{
|
|
27
|
+
const { formatMessage } = useIntl();
|
|
28
|
+
const { showItemActions } = useListSettings();
|
|
29
|
+
const isGridView = view === viewOptions.GRID;
|
|
30
|
+
const isLoading = isLoadingAssets || isLoadingFolders;
|
|
31
|
+
// "Folders: Mixed with files" — interleave the complete folder list into the
|
|
32
|
+
// loaded asset stream client-side, following the active sort. Table view
|
|
33
|
+
// only: the grid always keeps folders in their own band on top.
|
|
34
|
+
const mixedItems = useMemo(()=>foldersPosition === 'mixed' && !isGridView ? mergeMixedList({
|
|
35
|
+
folders,
|
|
36
|
+
assets,
|
|
37
|
+
sort: assetsSort,
|
|
38
|
+
hasNextPage
|
|
39
|
+
}) : null, [
|
|
40
|
+
foldersPosition,
|
|
41
|
+
isGridView,
|
|
42
|
+
folders,
|
|
43
|
+
assets,
|
|
44
|
+
assetsSort,
|
|
45
|
+
hasNextPage
|
|
46
|
+
]);
|
|
47
|
+
// Derived once here so the table, the grid and the bulk bar all agree on what
|
|
48
|
+
// is on screen — in mixed mode that is not simply every folder.
|
|
49
|
+
const renderedKeys = buildRenderedKeys({
|
|
50
|
+
folders,
|
|
51
|
+
assets,
|
|
52
|
+
mixedItems
|
|
53
|
+
});
|
|
54
|
+
const loadMoreRef = useInfiniteScrollSentinel({
|
|
55
|
+
hasNextPage,
|
|
56
|
+
isFetchingMore,
|
|
57
|
+
onLoadMore: fetchNextPage,
|
|
58
|
+
options: INTERSECTION_OPTIONS
|
|
59
|
+
});
|
|
60
|
+
const list = isGridView ? /*#__PURE__*/ jsx(AssetsGrid, {
|
|
61
|
+
folders: folders,
|
|
62
|
+
assets: assets,
|
|
63
|
+
assetsTotal: assetsTotal,
|
|
64
|
+
renderedKeys: renderedKeys,
|
|
65
|
+
onAssetItemClick: onAssetItemClick
|
|
66
|
+
}) : /*#__PURE__*/ jsx(AssetsTable, {
|
|
67
|
+
assets: assets,
|
|
68
|
+
folders: folders,
|
|
69
|
+
mixedItems: mixedItems,
|
|
70
|
+
renderedKeys: renderedKeys,
|
|
71
|
+
onAssetItemClick: onAssetItemClick
|
|
72
|
+
});
|
|
73
|
+
if (isLoading) {
|
|
74
|
+
return /*#__PURE__*/ jsx(Flex, {
|
|
75
|
+
justifyContent: "center",
|
|
76
|
+
padding: 8,
|
|
77
|
+
children: /*#__PURE__*/ jsx(Loader, {
|
|
78
|
+
children: formatMessage({
|
|
79
|
+
id: 'app.loading',
|
|
80
|
+
defaultMessage: 'Loading...'
|
|
81
|
+
})
|
|
82
|
+
})
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
if (error) {
|
|
86
|
+
return /*#__PURE__*/ jsx(Box, {
|
|
87
|
+
padding: 8,
|
|
88
|
+
children: /*#__PURE__*/ jsx(Typography, {
|
|
89
|
+
textColor: "danger600",
|
|
90
|
+
children: formatMessage({
|
|
91
|
+
id: getTranslationKey('list.assets.error'),
|
|
92
|
+
defaultMessage: 'An error occurred while fetching assets.'
|
|
93
|
+
})
|
|
94
|
+
})
|
|
95
|
+
});
|
|
96
|
+
}
|
|
97
|
+
if (folders.length === 0 && assets.length === 0) {
|
|
98
|
+
// While searching, the search empty state wins (it names the query); a
|
|
99
|
+
// filter-only dead end gets the filtered variant with its Clear action.
|
|
100
|
+
return hasActiveFilters && !searchQuery ? /*#__PURE__*/ jsx(FilteredEmptyState, {
|
|
101
|
+
onClearFilters: onClearFilters
|
|
102
|
+
}) : /*#__PURE__*/ jsx(EmptyState, {
|
|
103
|
+
onAddAssets: onAddAssets,
|
|
104
|
+
canAddAssets: canAddAssets,
|
|
105
|
+
searchQuery: searchQuery,
|
|
106
|
+
onClearSearch: onClearSearch
|
|
107
|
+
});
|
|
108
|
+
}
|
|
109
|
+
return /*#__PURE__*/ jsxs(Fragment, {
|
|
110
|
+
children: [
|
|
111
|
+
showItemActions ? // Above both views so one instance serves either, and so the selection
|
|
112
|
+
// menu has the `locations` its move dialog validates against.
|
|
113
|
+
/*#__PURE__*/ jsx(ItemContextMenuProvider, {
|
|
114
|
+
locations: locations,
|
|
115
|
+
children: list
|
|
116
|
+
}) : list,
|
|
117
|
+
/*#__PURE__*/ jsx("div", {
|
|
118
|
+
ref: loadMoreRef,
|
|
119
|
+
style: {
|
|
120
|
+
height: 1
|
|
121
|
+
}
|
|
122
|
+
}),
|
|
123
|
+
isFetchingMore && /*#__PURE__*/ jsx(Flex, {
|
|
124
|
+
justifyContent: "center",
|
|
125
|
+
padding: 4,
|
|
126
|
+
children: /*#__PURE__*/ jsx(Loader, {
|
|
127
|
+
children: formatMessage({
|
|
128
|
+
id: getTranslationKey('list.assets.loading-more'),
|
|
129
|
+
defaultMessage: 'Loading more assets...'
|
|
130
|
+
})
|
|
131
|
+
})
|
|
132
|
+
}),
|
|
133
|
+
showItemActions && /*#__PURE__*/ jsx(BulkActionsBar, {
|
|
134
|
+
assets: assets,
|
|
135
|
+
renderedKeys: renderedKeys,
|
|
136
|
+
locations: locations
|
|
137
|
+
})
|
|
138
|
+
]
|
|
139
|
+
});
|
|
140
|
+
};
|
|
141
|
+
|
|
142
|
+
export { AssetsView };
|
|
143
|
+
//# sourceMappingURL=AssetsView.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AssetsView.mjs","sources":["../../../../../admin/src/pages/Assets/components/AssetsView.tsx"],"sourcesContent":["import { useMemo } from 'react';\n\nimport { Box, Flex, Loader, Typography } from '@strapi/design-system';\nimport { useIntl } from 'react-intl';\n\nimport { type ItemLocations } from '../../../utils/itemLocations';\nimport { getTranslationKey } from '../../../utils/translations';\nimport { viewOptions } from '../constants';\nimport { useInfiniteScrollSentinel } from '../hooks/useInfiniteScrollSentinel';\nimport { useListSettings } from '../hooks/useListSettings';\nimport { type FoldersPosition } from '../hooks/useListSort';\nimport { mergeMixedList } from '../utils/mergeMixedList';\nimport { buildRenderedKeys } from '../utils/renderedKeys';\n\nimport { AssetsGrid } from './AssetsGrid';\nimport { AssetsTable } from './AssetsTable';\nimport { BulkActionsBar } from './BulkActionsBar';\nimport { EmptyState, FilteredEmptyState } from './EmptyState';\nimport { ItemContextMenuProvider } from './ItemContextMenu';\n\nimport type { File } from '../../../../../shared/contracts/files';\nimport type { Folder } from '../../../../../shared/contracts/folders';\n\n// The negative bottom margin shrinks the trigger area by a pixel so the 1px\n// sentinel sitting exactly at the fold (when a page's rows happen to fill the\n// viewport) reads as \"not visible\" and doesn't pull an extra page. It still\n// triggers as soon as the sentinel scrolls a hair into view. Tune the bottom\n// value if the list over- or under-fetches near the fold.\nconst INTERSECTION_OPTIONS: IntersectionObserverInit = {\n threshold: 0,\n rootMargin: '0px 0px -1px 0px',\n};\n\n/* -------------------------------------------------------------------------------------------------\n * AssetsView\n * -----------------------------------------------------------------------------------------------*/\n\ninterface AssetsViewProps {\n view: number;\n folders: Folder[];\n isLoadingFolders: boolean;\n assets: File[];\n /** Total matching assets on the server, beyond the pages loaded so far. */\n assetsTotal?: number;\n isLoadingAssets: boolean;\n isFetchingMore: boolean;\n hasNextPage: boolean;\n fetchNextPage: () => void;\n error: unknown;\n locations: ItemLocations;\n searchQuery: string;\n assetsSort: string;\n foldersPosition: FoldersPosition;\n hasActiveFilters: boolean;\n onClearFilters: () => void;\n onAssetItemClick: (assetId: number) => void;\n onAddAssets: () => void;\n canAddAssets: boolean;\n onClearSearch: () => void;\n}\n\nexport const AssetsView = ({\n view,\n folders,\n isLoadingFolders,\n assets,\n assetsTotal,\n isLoadingAssets,\n isFetchingMore,\n hasNextPage,\n fetchNextPage,\n error,\n locations,\n searchQuery,\n assetsSort,\n foldersPosition,\n hasActiveFilters,\n onClearFilters,\n onAssetItemClick,\n onAddAssets,\n canAddAssets,\n onClearSearch,\n}: AssetsViewProps) => {\n const { formatMessage } = useIntl();\n const { showItemActions } = useListSettings();\n\n const isGridView = view === viewOptions.GRID;\n const isLoading = isLoadingAssets || isLoadingFolders;\n\n // \"Folders: Mixed with files\" — interleave the complete folder list into the\n // loaded asset stream client-side, following the active sort. Table view\n // only: the grid always keeps folders in their own band on top.\n const mixedItems = useMemo(\n () =>\n foldersPosition === 'mixed' && !isGridView\n ? mergeMixedList({ folders, assets, sort: assetsSort, hasNextPage })\n : null,\n [foldersPosition, isGridView, folders, assets, assetsSort, hasNextPage]\n );\n\n // Derived once here so the table, the grid and the bulk bar all agree on what\n // is on screen — in mixed mode that is not simply every folder.\n const renderedKeys = buildRenderedKeys({ folders, assets, mixedItems });\n\n const loadMoreRef = useInfiniteScrollSentinel({\n hasNextPage,\n isFetchingMore,\n onLoadMore: fetchNextPage,\n options: INTERSECTION_OPTIONS,\n });\n\n const list = isGridView ? (\n <AssetsGrid\n folders={folders}\n assets={assets}\n assetsTotal={assetsTotal}\n renderedKeys={renderedKeys}\n onAssetItemClick={onAssetItemClick}\n />\n ) : (\n <AssetsTable\n assets={assets}\n folders={folders}\n mixedItems={mixedItems}\n renderedKeys={renderedKeys}\n onAssetItemClick={onAssetItemClick}\n />\n );\n\n if (isLoading) {\n return (\n <Flex justifyContent=\"center\" padding={8}>\n <Loader>{formatMessage({ id: 'app.loading', defaultMessage: 'Loading...' })}</Loader>\n </Flex>\n );\n }\n\n if (error) {\n return (\n <Box padding={8}>\n <Typography textColor=\"danger600\">\n {formatMessage({\n id: getTranslationKey('list.assets.error'),\n defaultMessage: 'An error occurred while fetching assets.',\n })}\n </Typography>\n </Box>\n );\n }\n\n if (folders.length === 0 && assets.length === 0) {\n // While searching, the search empty state wins (it names the query); a\n // filter-only dead end gets the filtered variant with its Clear action.\n return hasActiveFilters && !searchQuery ? (\n <FilteredEmptyState onClearFilters={onClearFilters} />\n ) : (\n <EmptyState\n onAddAssets={onAddAssets}\n canAddAssets={canAddAssets}\n searchQuery={searchQuery}\n onClearSearch={onClearSearch}\n />\n );\n }\n return (\n <>\n {showItemActions ? (\n // Above both views so one instance serves either, and so the selection\n // menu has the `locations` its move dialog validates against.\n <ItemContextMenuProvider locations={locations}>{list}</ItemContextMenuProvider>\n ) : (\n list\n )}\n <div ref={loadMoreRef} style={{ height: 1 }} />\n {isFetchingMore && (\n <Flex justifyContent=\"center\" padding={4}>\n <Loader>\n {formatMessage({\n id: getTranslationKey('list.assets.loading-more'),\n defaultMessage: 'Loading more assets...',\n })}\n </Loader>\n </Flex>\n )}\n {/* Lives here rather than in `AssetsPage` so it can read the loaded\n assets: the AI metadata action needs their mime types to know what\n the provider can handle. `position: fixed` keeps it visually anchored\n regardless of where it sits in the tree. */}\n {showItemActions && (\n <BulkActionsBar assets={assets} renderedKeys={renderedKeys} locations={locations} />\n )}\n </>\n );\n};\n"],"names":["INTERSECTION_OPTIONS","threshold","rootMargin","AssetsView","view","folders","isLoadingFolders","assets","assetsTotal","isLoadingAssets","isFetchingMore","hasNextPage","fetchNextPage","error","locations","searchQuery","assetsSort","foldersPosition","hasActiveFilters","onClearFilters","onAssetItemClick","onAddAssets","canAddAssets","onClearSearch","formatMessage","useIntl","showItemActions","useListSettings","isGridView","viewOptions","GRID","isLoading","mixedItems","useMemo","mergeMixedList","sort","renderedKeys","buildRenderedKeys","loadMoreRef","useInfiniteScrollSentinel","onLoadMore","options","list","_jsx","AssetsGrid","AssetsTable","Flex","justifyContent","padding","Loader","id","defaultMessage","Box","Typography","textColor","getTranslationKey","length","FilteredEmptyState","EmptyState","_jsxs","_Fragment","ItemContextMenuProvider","div","ref","style","height","BulkActionsBar"],"mappings":"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"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { jsxs, Fragment, jsx } from 'react/jsx-runtime';
|
|
2
2
|
import { useState, useEffect, useMemo } from 'react';
|
|
3
3
|
import { useNotification } from '@strapi/admin/strapi-admin';
|
|
4
|
-
import { Box, Typography, TextButton, Tooltip, Button, IconButton
|
|
4
|
+
import { Flex, Box, Typography, TextButton, Tooltip, Button, IconButton } from '@strapi/design-system';
|
|
5
5
|
import { Sparkle, ArrowRight, Trash, Cross } from '@strapi/icons';
|
|
6
6
|
import { useIntl } from 'react-intl';
|
|
7
7
|
import { css, styled } from 'styled-components';
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
2
|
-
import {
|
|
2
|
+
import { Flex, Typography } from '@strapi/design-system';
|
|
3
3
|
import { Folder, File } from '@strapi/icons';
|
|
4
4
|
import { useIntl } from 'react-intl';
|
|
5
5
|
import { styled } from 'styled-components';
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var jsxRuntime = require('react/jsx-runtime');
|
|
4
|
+
var designSystem = require('@strapi/design-system');
|
|
5
|
+
var icons = require('@strapi/icons');
|
|
6
|
+
var reactIntl = require('react-intl');
|
|
7
|
+
var translations = require('../../../../utils/translations.js');
|
|
8
|
+
var assetSortable = require('./assetSortable.js');
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* The keyboard path into reordering (Space picks the item up, arrows move it,
|
|
12
|
+
* Space drops it). Pointer drags start from anywhere on the item, this grip
|
|
13
|
+
* included.
|
|
14
|
+
*/ const ReorderHandle = ({ name, handle })=>{
|
|
15
|
+
const { formatMessage } = reactIntl.useIntl();
|
|
16
|
+
const { ref, onKeyDown, ...attributes } = handle;
|
|
17
|
+
return /*#__PURE__*/ jsxRuntime.jsx(designSystem.IconButton, {
|
|
18
|
+
...attributes,
|
|
19
|
+
ref: ref,
|
|
20
|
+
size: "XS",
|
|
21
|
+
variant: "ghost",
|
|
22
|
+
withTooltip: false,
|
|
23
|
+
label: formatMessage({
|
|
24
|
+
id: translations.getTranslationKey('list.item.reorder'),
|
|
25
|
+
defaultMessage: 'Reorder {name}'
|
|
26
|
+
}, {
|
|
27
|
+
name
|
|
28
|
+
}),
|
|
29
|
+
...assetSortable.REORDER_HANDLE_PROPS,
|
|
30
|
+
// Not stopped: once a drag starts, the arrows and the drop key are read on
|
|
31
|
+
// the document. The item ignores keys from here (`isFromReorderHandle`).
|
|
32
|
+
onKeyDown: onKeyDown,
|
|
33
|
+
// A click on the grip is not a click on the item.
|
|
34
|
+
onClick: (event)=>event.stopPropagation(),
|
|
35
|
+
children: /*#__PURE__*/ jsxRuntime.jsx(icons.Drag, {})
|
|
36
|
+
});
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
exports.ReorderHandle = ReorderHandle;
|
|
40
|
+
//# sourceMappingURL=ReorderHandle.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ReorderHandle.js","sources":["../../../../../../admin/src/pages/Assets/components/Dnd/ReorderHandle.tsx"],"sourcesContent":["import { IconButton } from '@strapi/design-system';\nimport { Drag } from '@strapi/icons';\nimport { useIntl } from 'react-intl';\n\nimport { getTranslationKey } from '../../../../utils/translations';\n\nimport { REORDER_HANDLE_PROPS, type AssetSortable } from './assetSortable';\n\ninterface ReorderHandleProps {\n name: string;\n handle: AssetSortable['handle'];\n}\n\n/**\n * The keyboard path into reordering (Space picks the item up, arrows move it,\n * Space drops it). Pointer drags start from anywhere on the item, this grip\n * included.\n */\nexport const ReorderHandle = ({ name, handle }: ReorderHandleProps) => {\n const { formatMessage } = useIntl();\n const { ref, onKeyDown, ...attributes } = handle;\n\n return (\n <IconButton\n {...attributes}\n ref={ref}\n size=\"XS\"\n variant=\"ghost\"\n withTooltip={false}\n label={formatMessage(\n { id: getTranslationKey('list.item.reorder'), defaultMessage: 'Reorder {name}' },\n { name }\n )}\n {...REORDER_HANDLE_PROPS}\n // Not stopped: once a drag starts, the arrows and the drop key are read on\n // the document. The item ignores keys from here (`isFromReorderHandle`).\n onKeyDown={onKeyDown}\n // A click on the grip is not a click on the item.\n onClick={(event) => event.stopPropagation()}\n >\n <Drag />\n </IconButton>\n );\n};\n"],"names":["ReorderHandle","name","handle","formatMessage","useIntl","ref","onKeyDown","attributes","_jsx","IconButton","size","variant","withTooltip","label","id","getTranslationKey","defaultMessage","REORDER_HANDLE_PROPS","onClick","event","stopPropagation","Drag"],"mappings":";;;;;;;;;AAaA;;;;UAKaA,aAAAA,GAAgB,CAAC,EAAEC,IAAI,EAAEC,MAAM,EAAsB,GAAA;IAChE,MAAM,EAAEC,aAAa,EAAE,GAAGC,iBAAAA,EAAAA;AAC1B,IAAA,MAAM,EAAEC,GAAG,EAAEC,SAAS,EAAE,GAAGC,YAAY,GAAGL,MAAAA;AAE1C,IAAA,qBACEM,cAAA,CAACC,uBAAAA,EAAAA;AACE,QAAA,GAAGF,UAAU;QACdF,GAAAA,EAAKA,GAAAA;QACLK,IAAAA,EAAK,IAAA;QACLC,OAAAA,EAAQ,OAAA;QACRC,WAAAA,EAAa,KAAA;AACbC,QAAAA,KAAAA,EAAOV,aAAAA,CACL;AAAEW,YAAAA,EAAAA,EAAIC,8BAAAA,CAAkB,mBAAA,CAAA;YAAsBC,cAAAA,EAAgB;SAAiB,EAC/E;AAAEf,YAAAA;AAAK,SAAA,CAAA;AAER,QAAA,GAAGgB,kCAAoB;;;QAGxBX,SAAAA,EAAWA,SAAAA;;QAEXY,OAAAA,EAAS,CAACC,KAAAA,GAAUA,KAAAA,CAAMC,eAAe,EAAA;AAEzC,QAAA,QAAA,gBAAAZ,cAAA,CAACa,UAAAA,EAAAA,EAAAA;;AAGP;;;;"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { jsx } from 'react/jsx-runtime';
|
|
2
|
+
import { IconButton } from '@strapi/design-system';
|
|
3
|
+
import { Drag } from '@strapi/icons';
|
|
4
|
+
import { useIntl } from 'react-intl';
|
|
5
|
+
import { getTranslationKey } from '../../../../utils/translations.mjs';
|
|
6
|
+
import { REORDER_HANDLE_PROPS } from './assetSortable.mjs';
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* The keyboard path into reordering (Space picks the item up, arrows move it,
|
|
10
|
+
* Space drops it). Pointer drags start from anywhere on the item, this grip
|
|
11
|
+
* included.
|
|
12
|
+
*/ const ReorderHandle = ({ name, handle })=>{
|
|
13
|
+
const { formatMessage } = useIntl();
|
|
14
|
+
const { ref, onKeyDown, ...attributes } = handle;
|
|
15
|
+
return /*#__PURE__*/ jsx(IconButton, {
|
|
16
|
+
...attributes,
|
|
17
|
+
ref: ref,
|
|
18
|
+
size: "XS",
|
|
19
|
+
variant: "ghost",
|
|
20
|
+
withTooltip: false,
|
|
21
|
+
label: formatMessage({
|
|
22
|
+
id: getTranslationKey('list.item.reorder'),
|
|
23
|
+
defaultMessage: 'Reorder {name}'
|
|
24
|
+
}, {
|
|
25
|
+
name
|
|
26
|
+
}),
|
|
27
|
+
...REORDER_HANDLE_PROPS,
|
|
28
|
+
// Not stopped: once a drag starts, the arrows and the drop key are read on
|
|
29
|
+
// the document. The item ignores keys from here (`isFromReorderHandle`).
|
|
30
|
+
onKeyDown: onKeyDown,
|
|
31
|
+
// A click on the grip is not a click on the item.
|
|
32
|
+
onClick: (event)=>event.stopPropagation(),
|
|
33
|
+
children: /*#__PURE__*/ jsx(Drag, {})
|
|
34
|
+
});
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
export { ReorderHandle };
|
|
38
|
+
//# sourceMappingURL=ReorderHandle.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ReorderHandle.mjs","sources":["../../../../../../admin/src/pages/Assets/components/Dnd/ReorderHandle.tsx"],"sourcesContent":["import { IconButton } from '@strapi/design-system';\nimport { Drag } from '@strapi/icons';\nimport { useIntl } from 'react-intl';\n\nimport { getTranslationKey } from '../../../../utils/translations';\n\nimport { REORDER_HANDLE_PROPS, type AssetSortable } from './assetSortable';\n\ninterface ReorderHandleProps {\n name: string;\n handle: AssetSortable['handle'];\n}\n\n/**\n * The keyboard path into reordering (Space picks the item up, arrows move it,\n * Space drops it). Pointer drags start from anywhere on the item, this grip\n * included.\n */\nexport const ReorderHandle = ({ name, handle }: ReorderHandleProps) => {\n const { formatMessage } = useIntl();\n const { ref, onKeyDown, ...attributes } = handle;\n\n return (\n <IconButton\n {...attributes}\n ref={ref}\n size=\"XS\"\n variant=\"ghost\"\n withTooltip={false}\n label={formatMessage(\n { id: getTranslationKey('list.item.reorder'), defaultMessage: 'Reorder {name}' },\n { name }\n )}\n {...REORDER_HANDLE_PROPS}\n // Not stopped: once a drag starts, the arrows and the drop key are read on\n // the document. The item ignores keys from here (`isFromReorderHandle`).\n onKeyDown={onKeyDown}\n // A click on the grip is not a click on the item.\n onClick={(event) => event.stopPropagation()}\n >\n <Drag />\n </IconButton>\n );\n};\n"],"names":["ReorderHandle","name","handle","formatMessage","useIntl","ref","onKeyDown","attributes","_jsx","IconButton","size","variant","withTooltip","label","id","getTranslationKey","defaultMessage","REORDER_HANDLE_PROPS","onClick","event","stopPropagation","Drag"],"mappings":";;;;;;;AAaA;;;;UAKaA,aAAAA,GAAgB,CAAC,EAAEC,IAAI,EAAEC,MAAM,EAAsB,GAAA;IAChE,MAAM,EAAEC,aAAa,EAAE,GAAGC,OAAAA,EAAAA;AAC1B,IAAA,MAAM,EAAEC,GAAG,EAAEC,SAAS,EAAE,GAAGC,YAAY,GAAGL,MAAAA;AAE1C,IAAA,qBACEM,GAAA,CAACC,UAAAA,EAAAA;AACE,QAAA,GAAGF,UAAU;QACdF,GAAAA,EAAKA,GAAAA;QACLK,IAAAA,EAAK,IAAA;QACLC,OAAAA,EAAQ,OAAA;QACRC,WAAAA,EAAa,KAAA;AACbC,QAAAA,KAAAA,EAAOV,aAAAA,CACL;AAAEW,YAAAA,EAAAA,EAAIC,iBAAAA,CAAkB,mBAAA,CAAA;YAAsBC,cAAAA,EAAgB;SAAiB,EAC/E;AAAEf,YAAAA;AAAK,SAAA,CAAA;AAER,QAAA,GAAGgB,oBAAoB;;;QAGxBX,SAAAA,EAAWA,SAAAA;;QAEXY,OAAAA,EAAS,CAACC,KAAAA,GAAUA,KAAAA,CAAMC,eAAe,EAAA;AAEzC,QAAA,QAAA,gBAAAZ,GAAA,CAACa,IAAAA,EAAAA,EAAAA;;AAGP;;;;"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var React = require('react');
|
|
4
|
+
|
|
5
|
+
const useNotSortable = ()=>null;
|
|
6
|
+
/**
|
|
7
|
+
* Holds the hook that makes an asset sortable, rather than a value: the hook
|
|
8
|
+
* needs each item's id. A given subtree always gets the same hook, so calling
|
|
9
|
+
* it from `useAssetSortable` keeps the rules of hooks.
|
|
10
|
+
*/ const AssetSortableContext = React.createContext(useNotSortable);
|
|
11
|
+
const useAssetSortable = (assetId)=>{
|
|
12
|
+
const useSortableAsset = React.useContext(AssetSortableContext);
|
|
13
|
+
return useSortableAsset(assetId);
|
|
14
|
+
};
|
|
15
|
+
const REORDER_HANDLE_ATTRIBUTE = 'data-reorder-handle';
|
|
16
|
+
/** Marks the reorder grip, so the item can tell its keys apart. */ const REORDER_HANDLE_PROPS = {
|
|
17
|
+
[REORDER_HANDLE_ATTRIBUTE]: ''
|
|
18
|
+
};
|
|
19
|
+
/**
|
|
20
|
+
* Keys pressed on the grip, including the arrows and the drop key mid-drag,
|
|
21
|
+
* belong to reordering. The item must not also read them as its own
|
|
22
|
+
* Enter/Space.
|
|
23
|
+
*/ const isFromReorderHandle = (event)=>event.target instanceof Element && event.target.closest(`[${REORDER_HANDLE_ATTRIBUTE}]`) !== null;
|
|
24
|
+
|
|
25
|
+
exports.AssetSortableContext = AssetSortableContext;
|
|
26
|
+
exports.REORDER_HANDLE_PROPS = REORDER_HANDLE_PROPS;
|
|
27
|
+
exports.isFromReorderHandle = isFromReorderHandle;
|
|
28
|
+
exports.useAssetSortable = useAssetSortable;
|
|
29
|
+
//# sourceMappingURL=assetSortable.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"assetSortable.js","sources":["../../../../../../admin/src/pages/Assets/components/Dnd/assetSortable.ts"],"sourcesContent":["import {\n createContext,\n useContext,\n type CSSProperties,\n type KeyboardEvent,\n type SyntheticEvent,\n} from 'react';\n\nimport type { DraggableAttributes, DraggableSyntheticListeners } from '@dnd-kit/core';\n\n/**\n * What a list item needs to take part in reordering: the whole item drags with\n * the pointer, and a grip button carries the keyboard path (Space to pick up,\n * arrows to move) so it doesn't collide with the item's own Space/click.\n */\nexport interface AssetSortable {\n setNodeRef: (node: HTMLElement | null) => void;\n isDragging: boolean;\n style: CSSProperties;\n /** Pointer activation, for the item itself. */\n listeners: DraggableSyntheticListeners;\n handle: Partial<DraggableAttributes> & {\n ref: (node: HTMLElement | null) => void;\n onKeyDown?: (event: KeyboardEvent) => void;\n };\n}\n\ntype UseAssetSortable = (assetId: number) => AssetSortable | null;\n\nconst useNotSortable: UseAssetSortable = () => null;\n\n/**\n * Holds the hook that makes an asset sortable, rather than a value: the hook\n * needs each item's id. A given subtree always gets the same hook, so calling\n * it from `useAssetSortable` keeps the rules of hooks.\n */\nexport const AssetSortableContext = createContext<UseAssetSortable>(useNotSortable);\n\nexport const useAssetSortable = (assetId: number) => {\n const useSortableAsset = useContext(AssetSortableContext);\n\n return useSortableAsset(assetId);\n};\n\nconst REORDER_HANDLE_ATTRIBUTE = 'data-reorder-handle';\n\n/** Marks the reorder grip, so the item can tell its keys apart. */\nexport const REORDER_HANDLE_PROPS = { [REORDER_HANDLE_ATTRIBUTE]: '' };\n\n/**\n * Keys pressed on the grip, including the arrows and the drop key mid-drag,\n * belong to reordering. The item must not also read them as its own\n * Enter/Space.\n */\nexport const isFromReorderHandle = (event: SyntheticEvent) =>\n event.target instanceof Element && event.target.closest(`[${REORDER_HANDLE_ATTRIBUTE}]`) !== null;\n"],"names":["useNotSortable","AssetSortableContext","createContext","useAssetSortable","assetId","useSortableAsset","useContext","REORDER_HANDLE_ATTRIBUTE","REORDER_HANDLE_PROPS","isFromReorderHandle","event","target","Element","closest"],"mappings":";;;;AA6BA,MAAMA,iBAAmC,IAAM,IAAA;AAE/C;;;;AAIC,IACM,MAAMC,oBAAAA,GAAuBC,mBAAAA,CAAgCF,cAAAA;AAE7D,MAAMG,mBAAmB,CAACC,OAAAA,GAAAA;AAC/B,IAAA,MAAMC,mBAAmBC,gBAAAA,CAAWL,oBAAAA,CAAAA;AAEpC,IAAA,OAAOI,gBAAAA,CAAiBD,OAAAA,CAAAA;AAC1B;AAEA,MAAMG,wBAAAA,GAA2B,qBAAA;AAEjC,oEACO,MAAMC,oBAAAA,GAAuB;AAAE,IAAA,CAACD,2BAA2B;AAAG;AAErE;;;;UAKaE,mBAAAA,GAAsB,CAACC,QAClCA,KAAAA,CAAMC,MAAM,YAAYC,OAAAA,IAAWF,KAAAA,CAAMC,MAAM,CAACE,OAAO,CAAC,CAAC,CAAC,EAAEN,wBAAAA,CAAyB,CAAC,CAAC,CAAA,KAAM;;;;;;;"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { createContext, useContext } from 'react';
|
|
2
|
+
|
|
3
|
+
const useNotSortable = ()=>null;
|
|
4
|
+
/**
|
|
5
|
+
* Holds the hook that makes an asset sortable, rather than a value: the hook
|
|
6
|
+
* needs each item's id. A given subtree always gets the same hook, so calling
|
|
7
|
+
* it from `useAssetSortable` keeps the rules of hooks.
|
|
8
|
+
*/ const AssetSortableContext = createContext(useNotSortable);
|
|
9
|
+
const useAssetSortable = (assetId)=>{
|
|
10
|
+
const useSortableAsset = useContext(AssetSortableContext);
|
|
11
|
+
return useSortableAsset(assetId);
|
|
12
|
+
};
|
|
13
|
+
const REORDER_HANDLE_ATTRIBUTE = 'data-reorder-handle';
|
|
14
|
+
/** Marks the reorder grip, so the item can tell its keys apart. */ const REORDER_HANDLE_PROPS = {
|
|
15
|
+
[REORDER_HANDLE_ATTRIBUTE]: ''
|
|
16
|
+
};
|
|
17
|
+
/**
|
|
18
|
+
* Keys pressed on the grip, including the arrows and the drop key mid-drag,
|
|
19
|
+
* belong to reordering. The item must not also read them as its own
|
|
20
|
+
* Enter/Space.
|
|
21
|
+
*/ const isFromReorderHandle = (event)=>event.target instanceof Element && event.target.closest(`[${REORDER_HANDLE_ATTRIBUTE}]`) !== null;
|
|
22
|
+
|
|
23
|
+
export { AssetSortableContext, REORDER_HANDLE_PROPS, isFromReorderHandle, useAssetSortable };
|
|
24
|
+
//# sourceMappingURL=assetSortable.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"assetSortable.mjs","sources":["../../../../../../admin/src/pages/Assets/components/Dnd/assetSortable.ts"],"sourcesContent":["import {\n createContext,\n useContext,\n type CSSProperties,\n type KeyboardEvent,\n type SyntheticEvent,\n} from 'react';\n\nimport type { DraggableAttributes, DraggableSyntheticListeners } from '@dnd-kit/core';\n\n/**\n * What a list item needs to take part in reordering: the whole item drags with\n * the pointer, and a grip button carries the keyboard path (Space to pick up,\n * arrows to move) so it doesn't collide with the item's own Space/click.\n */\nexport interface AssetSortable {\n setNodeRef: (node: HTMLElement | null) => void;\n isDragging: boolean;\n style: CSSProperties;\n /** Pointer activation, for the item itself. */\n listeners: DraggableSyntheticListeners;\n handle: Partial<DraggableAttributes> & {\n ref: (node: HTMLElement | null) => void;\n onKeyDown?: (event: KeyboardEvent) => void;\n };\n}\n\ntype UseAssetSortable = (assetId: number) => AssetSortable | null;\n\nconst useNotSortable: UseAssetSortable = () => null;\n\n/**\n * Holds the hook that makes an asset sortable, rather than a value: the hook\n * needs each item's id. A given subtree always gets the same hook, so calling\n * it from `useAssetSortable` keeps the rules of hooks.\n */\nexport const AssetSortableContext = createContext<UseAssetSortable>(useNotSortable);\n\nexport const useAssetSortable = (assetId: number) => {\n const useSortableAsset = useContext(AssetSortableContext);\n\n return useSortableAsset(assetId);\n};\n\nconst REORDER_HANDLE_ATTRIBUTE = 'data-reorder-handle';\n\n/** Marks the reorder grip, so the item can tell its keys apart. */\nexport const REORDER_HANDLE_PROPS = { [REORDER_HANDLE_ATTRIBUTE]: '' };\n\n/**\n * Keys pressed on the grip, including the arrows and the drop key mid-drag,\n * belong to reordering. The item must not also read them as its own\n * Enter/Space.\n */\nexport const isFromReorderHandle = (event: SyntheticEvent) =>\n event.target instanceof Element && event.target.closest(`[${REORDER_HANDLE_ATTRIBUTE}]`) !== null;\n"],"names":["useNotSortable","AssetSortableContext","createContext","useAssetSortable","assetId","useSortableAsset","useContext","REORDER_HANDLE_ATTRIBUTE","REORDER_HANDLE_PROPS","isFromReorderHandle","event","target","Element","closest"],"mappings":";;AA6BA,MAAMA,iBAAmC,IAAM,IAAA;AAE/C;;;;AAIC,IACM,MAAMC,oBAAAA,GAAuBC,aAAAA,CAAgCF,cAAAA;AAE7D,MAAMG,mBAAmB,CAACC,OAAAA,GAAAA;AAC/B,IAAA,MAAMC,mBAAmBC,UAAAA,CAAWL,oBAAAA,CAAAA;AAEpC,IAAA,OAAOI,gBAAAA,CAAiBD,OAAAA,CAAAA;AAC1B;AAEA,MAAMG,wBAAAA,GAA2B,qBAAA;AAEjC,oEACO,MAAMC,oBAAAA,GAAuB;AAAE,IAAA,CAACD,2BAA2B;AAAG;AAErE;;;;UAKaE,mBAAAA,GAAsB,CAACC,QAClCA,KAAAA,CAAMC,MAAM,YAAYC,OAAAA,IAAWF,KAAAA,CAAMC,MAAM,CAACE,OAAO,CAAC,CAAC,CAAC,EAAEN,wBAAAA,CAAyB,CAAC,CAAC,CAAA,KAAM;;;;"}
|
|
@@ -11,6 +11,10 @@ const parseFolderTargetId = (dndId)=>{
|
|
|
11
11
|
return match ? Number(match[1]) : null;
|
|
12
12
|
};
|
|
13
13
|
const toFolderTreeTargetId = (id)=>`folder-tree-target:${id}`;
|
|
14
|
+
/**
|
|
15
|
+
* The "N parent folders" row in the sidebar. Only there so hovering it during a
|
|
16
|
+
* drag opens it; no parser recognises it, so a drop on it moves nothing.
|
|
17
|
+
*/ const toFolderTreeSummaryId = (rootId)=>`folder-tree-summary:${rootId}`;
|
|
14
18
|
const HOME_TREE_TARGET_ID = 'folder-tree-target:home';
|
|
15
19
|
const parseFolderTreeTargetId = (dndId)=>{
|
|
16
20
|
if (typeof dndId !== 'string') {
|
|
@@ -29,5 +33,6 @@ exports.parseFolderTreeTargetId = parseFolderTreeTargetId;
|
|
|
29
33
|
exports.toFileDraggableId = toFileDraggableId;
|
|
30
34
|
exports.toFolderDraggableId = toFolderDraggableId;
|
|
31
35
|
exports.toFolderTargetId = toFolderTargetId;
|
|
36
|
+
exports.toFolderTreeSummaryId = toFolderTreeSummaryId;
|
|
32
37
|
exports.toFolderTreeTargetId = toFolderTreeTargetId;
|
|
33
38
|
//# sourceMappingURL=dndIds.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dndIds.js","sources":["../../../../../../admin/src/pages/Assets/components/Dnd/dndIds.ts"],"sourcesContent":["export const toFileDraggableId = (id: number) => `file:${id}` as const;\n\nexport const toFolderDraggableId = (id: number) => `folder:${id}` as const;\n\nexport const toFolderTargetId = (id: number) => `folder-target:${id}` as const;\n\nexport const parseFolderTargetId = (dndId: string | number): number | null => {\n if (typeof dndId !== 'string') {\n return null;\n }\n\n const match = /^folder-target:(\\d+)$/.exec(dndId);\n return match ? Number(match[1]) : null;\n};\n\nexport const toFolderTreeTargetId = (id: number) => `folder-tree-target:${id}` as const;\n\nexport const HOME_TREE_TARGET_ID = 'folder-tree-target:home' as const;\n\nexport const parseFolderTreeTargetId = (dndId: string | number): number | 'root' | null => {\n if (typeof dndId !== 'string') {\n return null;\n }\n\n if (dndId === HOME_TREE_TARGET_ID) {\n return 'root';\n }\n\n const match = /^folder-tree-target:(\\d+)$/.exec(dndId);\n return match ? Number(match[1]) : null;\n};\n"],"names":["toFileDraggableId","id","toFolderDraggableId","toFolderTargetId","parseFolderTargetId","dndId","match","exec","Number","toFolderTreeTargetId","HOME_TREE_TARGET_ID","parseFolderTreeTargetId"],"mappings":";;AAAO,MAAMA,oBAAoB,CAACC,EAAAA,GAAe,CAAC,KAAK,EAAEA;AAElD,MAAMC,sBAAsB,CAACD,EAAAA,GAAe,CAAC,OAAO,EAAEA;AAEtD,MAAME,mBAAmB,CAACF,EAAAA,GAAe,CAAC,cAAc,EAAEA;AAE1D,MAAMG,sBAAsB,CAACC,KAAAA,GAAAA;IAClC,IAAI,OAAOA,UAAU,QAAA,EAAU;QAC7B,OAAO,IAAA;AACT,IAAA;IAEA,MAAMC,KAAAA,GAAQ,uBAAA,CAAwBC,IAAI,CAACF,KAAAA,CAAAA;AAC3C,IAAA,OAAOC,KAAAA,GAAQE,MAAAA,CAAOF,KAAK,CAAC,EAAE,CAAA,GAAI,IAAA;AACpC;AAEO,MAAMG,uBAAuB,CAACR,EAAAA,GAAe,CAAC,mBAAmB,EAAEA;
|
|
1
|
+
{"version":3,"file":"dndIds.js","sources":["../../../../../../admin/src/pages/Assets/components/Dnd/dndIds.ts"],"sourcesContent":["export const toFileDraggableId = (id: number) => `file:${id}` as const;\n\nexport const toFolderDraggableId = (id: number) => `folder:${id}` as const;\n\nexport const toFolderTargetId = (id: number) => `folder-target:${id}` as const;\n\nexport const parseFolderTargetId = (dndId: string | number): number | null => {\n if (typeof dndId !== 'string') {\n return null;\n }\n\n const match = /^folder-target:(\\d+)$/.exec(dndId);\n return match ? Number(match[1]) : null;\n};\n\nexport const toFolderTreeTargetId = (id: number) => `folder-tree-target:${id}` as const;\n\n/**\n * The \"N parent folders\" row in the sidebar. Only there so hovering it during a\n * drag opens it; no parser recognises it, so a drop on it moves nothing.\n */\nexport const toFolderTreeSummaryId = (rootId: number) => `folder-tree-summary:${rootId}` as const;\n\nexport const HOME_TREE_TARGET_ID = 'folder-tree-target:home' as const;\n\nexport const parseFolderTreeTargetId = (dndId: string | number): number | 'root' | null => {\n if (typeof dndId !== 'string') {\n return null;\n }\n\n if (dndId === HOME_TREE_TARGET_ID) {\n return 'root';\n }\n\n const match = /^folder-tree-target:(\\d+)$/.exec(dndId);\n return match ? Number(match[1]) : null;\n};\n"],"names":["toFileDraggableId","id","toFolderDraggableId","toFolderTargetId","parseFolderTargetId","dndId","match","exec","Number","toFolderTreeTargetId","toFolderTreeSummaryId","rootId","HOME_TREE_TARGET_ID","parseFolderTreeTargetId"],"mappings":";;AAAO,MAAMA,oBAAoB,CAACC,EAAAA,GAAe,CAAC,KAAK,EAAEA;AAElD,MAAMC,sBAAsB,CAACD,EAAAA,GAAe,CAAC,OAAO,EAAEA;AAEtD,MAAME,mBAAmB,CAACF,EAAAA,GAAe,CAAC,cAAc,EAAEA;AAE1D,MAAMG,sBAAsB,CAACC,KAAAA,GAAAA;IAClC,IAAI,OAAOA,UAAU,QAAA,EAAU;QAC7B,OAAO,IAAA;AACT,IAAA;IAEA,MAAMC,KAAAA,GAAQ,uBAAA,CAAwBC,IAAI,CAACF,KAAAA,CAAAA;AAC3C,IAAA,OAAOC,KAAAA,GAAQE,MAAAA,CAAOF,KAAK,CAAC,EAAE,CAAA,GAAI,IAAA;AACpC;AAEO,MAAMG,uBAAuB,CAACR,EAAAA,GAAe,CAAC,mBAAmB,EAAEA;AAE1E;;;UAIaS,qBAAAA,GAAwB,CAACC,SAAmB,CAAC,oBAAoB,EAAEA,MAAAA,CAAAA;AAEzE,MAAMC,sBAAsB;AAE5B,MAAMC,0BAA0B,CAACR,KAAAA,GAAAA;IACtC,IAAI,OAAOA,UAAU,QAAA,EAAU;QAC7B,OAAO,IAAA;AACT,IAAA;AAEA,IAAA,IAAIA,UAAUO,mBAAAA,EAAqB;QACjC,OAAO,MAAA;AACT,IAAA;IAEA,MAAMN,KAAAA,GAAQ,4BAAA,CAA6BC,IAAI,CAACF,KAAAA,CAAAA;AAChD,IAAA,OAAOC,KAAAA,GAAQE,MAAAA,CAAOF,KAAK,CAAC,EAAE,CAAA,GAAI,IAAA;AACpC;;;;;;;;;;;"}
|
|
@@ -9,6 +9,10 @@ const parseFolderTargetId = (dndId)=>{
|
|
|
9
9
|
return match ? Number(match[1]) : null;
|
|
10
10
|
};
|
|
11
11
|
const toFolderTreeTargetId = (id)=>`folder-tree-target:${id}`;
|
|
12
|
+
/**
|
|
13
|
+
* The "N parent folders" row in the sidebar. Only there so hovering it during a
|
|
14
|
+
* drag opens it; no parser recognises it, so a drop on it moves nothing.
|
|
15
|
+
*/ const toFolderTreeSummaryId = (rootId)=>`folder-tree-summary:${rootId}`;
|
|
12
16
|
const HOME_TREE_TARGET_ID = 'folder-tree-target:home';
|
|
13
17
|
const parseFolderTreeTargetId = (dndId)=>{
|
|
14
18
|
if (typeof dndId !== 'string') {
|
|
@@ -21,5 +25,5 @@ const parseFolderTreeTargetId = (dndId)=>{
|
|
|
21
25
|
return match ? Number(match[1]) : null;
|
|
22
26
|
};
|
|
23
27
|
|
|
24
|
-
export { HOME_TREE_TARGET_ID, parseFolderTargetId, parseFolderTreeTargetId, toFileDraggableId, toFolderDraggableId, toFolderTargetId, toFolderTreeTargetId };
|
|
28
|
+
export { HOME_TREE_TARGET_ID, parseFolderTargetId, parseFolderTreeTargetId, toFileDraggableId, toFolderDraggableId, toFolderTargetId, toFolderTreeSummaryId, toFolderTreeTargetId };
|
|
25
29
|
//# sourceMappingURL=dndIds.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dndIds.mjs","sources":["../../../../../../admin/src/pages/Assets/components/Dnd/dndIds.ts"],"sourcesContent":["export const toFileDraggableId = (id: number) => `file:${id}` as const;\n\nexport const toFolderDraggableId = (id: number) => `folder:${id}` as const;\n\nexport const toFolderTargetId = (id: number) => `folder-target:${id}` as const;\n\nexport const parseFolderTargetId = (dndId: string | number): number | null => {\n if (typeof dndId !== 'string') {\n return null;\n }\n\n const match = /^folder-target:(\\d+)$/.exec(dndId);\n return match ? Number(match[1]) : null;\n};\n\nexport const toFolderTreeTargetId = (id: number) => `folder-tree-target:${id}` as const;\n\nexport const HOME_TREE_TARGET_ID = 'folder-tree-target:home' as const;\n\nexport const parseFolderTreeTargetId = (dndId: string | number): number | 'root' | null => {\n if (typeof dndId !== 'string') {\n return null;\n }\n\n if (dndId === HOME_TREE_TARGET_ID) {\n return 'root';\n }\n\n const match = /^folder-tree-target:(\\d+)$/.exec(dndId);\n return match ? Number(match[1]) : null;\n};\n"],"names":["toFileDraggableId","id","toFolderDraggableId","toFolderTargetId","parseFolderTargetId","dndId","match","exec","Number","toFolderTreeTargetId","HOME_TREE_TARGET_ID","parseFolderTreeTargetId"],"mappings":"AAAO,MAAMA,oBAAoB,CAACC,EAAAA,GAAe,CAAC,KAAK,EAAEA;AAElD,MAAMC,sBAAsB,CAACD,EAAAA,GAAe,CAAC,OAAO,EAAEA;AAEtD,MAAME,mBAAmB,CAACF,EAAAA,GAAe,CAAC,cAAc,EAAEA;AAE1D,MAAMG,sBAAsB,CAACC,KAAAA,GAAAA;IAClC,IAAI,OAAOA,UAAU,QAAA,EAAU;QAC7B,OAAO,IAAA;AACT,IAAA;IAEA,MAAMC,KAAAA,GAAQ,uBAAA,CAAwBC,IAAI,CAACF,KAAAA,CAAAA;AAC3C,IAAA,OAAOC,KAAAA,GAAQE,MAAAA,CAAOF,KAAK,CAAC,EAAE,CAAA,GAAI,IAAA;AACpC;AAEO,MAAMG,uBAAuB,CAACR,EAAAA,GAAe,CAAC,mBAAmB,EAAEA;
|
|
1
|
+
{"version":3,"file":"dndIds.mjs","sources":["../../../../../../admin/src/pages/Assets/components/Dnd/dndIds.ts"],"sourcesContent":["export const toFileDraggableId = (id: number) => `file:${id}` as const;\n\nexport const toFolderDraggableId = (id: number) => `folder:${id}` as const;\n\nexport const toFolderTargetId = (id: number) => `folder-target:${id}` as const;\n\nexport const parseFolderTargetId = (dndId: string | number): number | null => {\n if (typeof dndId !== 'string') {\n return null;\n }\n\n const match = /^folder-target:(\\d+)$/.exec(dndId);\n return match ? Number(match[1]) : null;\n};\n\nexport const toFolderTreeTargetId = (id: number) => `folder-tree-target:${id}` as const;\n\n/**\n * The \"N parent folders\" row in the sidebar. Only there so hovering it during a\n * drag opens it; no parser recognises it, so a drop on it moves nothing.\n */\nexport const toFolderTreeSummaryId = (rootId: number) => `folder-tree-summary:${rootId}` as const;\n\nexport const HOME_TREE_TARGET_ID = 'folder-tree-target:home' as const;\n\nexport const parseFolderTreeTargetId = (dndId: string | number): number | 'root' | null => {\n if (typeof dndId !== 'string') {\n return null;\n }\n\n if (dndId === HOME_TREE_TARGET_ID) {\n return 'root';\n }\n\n const match = /^folder-tree-target:(\\d+)$/.exec(dndId);\n return match ? Number(match[1]) : null;\n};\n"],"names":["toFileDraggableId","id","toFolderDraggableId","toFolderTargetId","parseFolderTargetId","dndId","match","exec","Number","toFolderTreeTargetId","toFolderTreeSummaryId","rootId","HOME_TREE_TARGET_ID","parseFolderTreeTargetId"],"mappings":"AAAO,MAAMA,oBAAoB,CAACC,EAAAA,GAAe,CAAC,KAAK,EAAEA;AAElD,MAAMC,sBAAsB,CAACD,EAAAA,GAAe,CAAC,OAAO,EAAEA;AAEtD,MAAME,mBAAmB,CAACF,EAAAA,GAAe,CAAC,cAAc,EAAEA;AAE1D,MAAMG,sBAAsB,CAACC,KAAAA,GAAAA;IAClC,IAAI,OAAOA,UAAU,QAAA,EAAU;QAC7B,OAAO,IAAA;AACT,IAAA;IAEA,MAAMC,KAAAA,GAAQ,uBAAA,CAAwBC,IAAI,CAACF,KAAAA,CAAAA;AAC3C,IAAA,OAAOC,KAAAA,GAAQE,MAAAA,CAAOF,KAAK,CAAC,EAAE,CAAA,GAAI,IAAA;AACpC;AAEO,MAAMG,uBAAuB,CAACR,EAAAA,GAAe,CAAC,mBAAmB,EAAEA;AAE1E;;;UAIaS,qBAAAA,GAAwB,CAACC,SAAmB,CAAC,oBAAoB,EAAEA,MAAAA,CAAAA;AAEzE,MAAMC,sBAAsB;AAE5B,MAAMC,0BAA0B,CAACR,KAAAA,GAAAA;IACtC,IAAI,OAAOA,UAAU,QAAA,EAAU;QAC7B,OAAO,IAAA;AACT,IAAA;AAEA,IAAA,IAAIA,UAAUO,mBAAAA,EAAqB;QACjC,OAAO,MAAA;AACT,IAAA;IAEA,MAAMN,KAAAA,GAAQ,4BAAA,CAA6BC,IAAI,CAACF,KAAAA,CAAAA;AAChD,IAAA,OAAOC,KAAAA,GAAQE,MAAAA,CAAOF,KAAK,CAAC,EAAE,CAAA,GAAI,IAAA;AACpC;;;;"}
|
|
@@ -4,12 +4,23 @@ var React = require('react');
|
|
|
4
4
|
var core = require('@dnd-kit/core');
|
|
5
5
|
var getRelationId = require('../../../../utils/getRelationId.js');
|
|
6
6
|
var AssetsDndProvider = require('./AssetsDndProvider.js');
|
|
7
|
+
var assetSortable = require('./assetSortable.js');
|
|
7
8
|
var dndIds = require('./dndIds.js');
|
|
8
9
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
10
|
+
/**
|
|
11
|
+
* Without an `AssetsDndProvider` (the Content Manager asset picker mounts none)
|
|
12
|
+
* items are not draggable: nothing handles the drop. Their drag attributes are
|
|
13
|
+
* withheld too, so they aren't announced as draggable.
|
|
14
|
+
*/ const NO_DRAG_ATTRIBUTES = {};
|
|
15
|
+
const withoutDrag = (draggable, isDndEnabled)=>isDndEnabled ? draggable : {
|
|
16
|
+
...draggable,
|
|
17
|
+
attributes: NO_DRAG_ATTRIBUTES,
|
|
18
|
+
listeners: undefined
|
|
12
19
|
};
|
|
20
|
+
const useFileDraggable = (asset)=>{
|
|
21
|
+
const dnd = AssetsDndProvider.useAssetsDndOptional();
|
|
22
|
+
const isDndEnabled = dnd !== null;
|
|
23
|
+
const isMovePending = dnd?.isMovePending ?? false;
|
|
13
24
|
const data = React.useMemo(()=>({
|
|
14
25
|
kind: 'file',
|
|
15
26
|
id: asset.id,
|
|
@@ -23,20 +34,37 @@ const useFileDraggable = (asset)=>{
|
|
|
23
34
|
const draggable = core.useDraggable({
|
|
24
35
|
id: dndIds.toFileDraggableId(asset.id),
|
|
25
36
|
data,
|
|
26
|
-
disabled: isMovePending
|
|
37
|
+
disabled: !isDndEnabled || isMovePending
|
|
27
38
|
});
|
|
39
|
+
const sortable = assetSortable.useAssetSortable(asset.id);
|
|
40
|
+
// In a reorderable list (the picker's Selected tab) dragging reorders
|
|
41
|
+
// instead of moving between folders: the item takes the sortable's node,
|
|
42
|
+
// pointer listeners and transform, and exposes a grip for the keyboard.
|
|
43
|
+
if (sortable) {
|
|
44
|
+
return {
|
|
45
|
+
...withoutDrag(draggable, false),
|
|
46
|
+
setNodeRef: sortable.setNodeRef,
|
|
47
|
+
isDragging: sortable.isDragging,
|
|
48
|
+
listeners: sortable.listeners,
|
|
49
|
+
dragStyle: sortable.style,
|
|
50
|
+
dragHandle: sortable.handle,
|
|
51
|
+
dragData: data
|
|
52
|
+
};
|
|
53
|
+
}
|
|
28
54
|
// `dragData` is re-exposed (like `useFolderDraggableDroppable` does) so the
|
|
29
55
|
// row's actions menu can hand the move dialog the asset's real folder.
|
|
30
56
|
return {
|
|
31
|
-
...draggable,
|
|
57
|
+
...withoutDrag(draggable, isDndEnabled),
|
|
58
|
+
dragStyle: undefined,
|
|
59
|
+
dragHandle: undefined,
|
|
32
60
|
dragData: data
|
|
33
61
|
};
|
|
34
62
|
};
|
|
35
63
|
const useFolderDraggableDroppable = (folder)=>{
|
|
36
|
-
const
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
64
|
+
const dnd = AssetsDndProvider.useAssetsDndOptional();
|
|
65
|
+
const isDndEnabled = dnd !== null;
|
|
66
|
+
const isMovePending = dnd?.isMovePending ?? false;
|
|
67
|
+
const isValidDropTarget = dnd?.isValidDropTarget ?? (()=>false);
|
|
40
68
|
const { active } = core.useDndContext();
|
|
41
69
|
const parentId = getRelationId.getRelationId(folder.parent);
|
|
42
70
|
const dragData = React.useMemo(()=>({
|
|
@@ -57,15 +85,15 @@ const useFolderDraggableDroppable = (folder)=>{
|
|
|
57
85
|
folder.id,
|
|
58
86
|
folder.name
|
|
59
87
|
]);
|
|
60
|
-
const draggable = core.useDraggable({
|
|
88
|
+
const draggable = withoutDrag(core.useDraggable({
|
|
61
89
|
id: dndIds.toFolderDraggableId(folder.id),
|
|
62
90
|
data: dragData,
|
|
63
|
-
disabled: isMovePending
|
|
64
|
-
});
|
|
91
|
+
disabled: !isDndEnabled || isMovePending
|
|
92
|
+
}), isDndEnabled);
|
|
65
93
|
const droppable = core.useDroppable({
|
|
66
94
|
id: dndIds.toFolderTargetId(folder.id),
|
|
67
95
|
data: dropData,
|
|
68
|
-
disabled: isMovePending
|
|
96
|
+
disabled: !isDndEnabled || isMovePending
|
|
69
97
|
});
|
|
70
98
|
const isValidTarget = isValidDropTarget(folder.id);
|
|
71
99
|
const isOver = droppable.isOver;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useAssetDnd.js","sources":["../../../../../../admin/src/pages/Assets/components/Dnd/useAssetDnd.ts"],"sourcesContent":["import { useMemo } from 'react';\n\nimport { useDndContext, useDraggable, useDroppable } from '@dnd-kit/core';\n\nimport { getRelationId } from '../../../../utils/getRelationId';\n\nimport { useAssetsDndOptional } from './AssetsDndProvider';\nimport { toFileDraggableId, toFolderDraggableId, toFolderTargetId } from './dndIds';\n\nimport type { DragFileData, DragFolderData, FolderTargetData } from '../../../../types/dnd';\n\nexport const useFileDraggable = (asset: {\n id: number;\n name: string;\n folder?: number | string | { id?: number } | null;\n}) => {\n const
|
|
1
|
+
{"version":3,"file":"useAssetDnd.js","sources":["../../../../../../admin/src/pages/Assets/components/Dnd/useAssetDnd.ts"],"sourcesContent":["import { useMemo } from 'react';\n\nimport { useDndContext, useDraggable, useDroppable, type DraggableAttributes } from '@dnd-kit/core';\n\nimport { getRelationId } from '../../../../utils/getRelationId';\n\nimport { useAssetsDndOptional } from './AssetsDndProvider';\nimport { useAssetSortable } from './assetSortable';\nimport { toFileDraggableId, toFolderDraggableId, toFolderTargetId } from './dndIds';\n\nimport type { DragFileData, DragFolderData, FolderTargetData } from '../../../../types/dnd';\n\n/**\n * Without an `AssetsDndProvider` (the Content Manager asset picker mounts none)\n * items are not draggable: nothing handles the drop. Their drag attributes are\n * withheld too, so they aren't announced as draggable.\n */\nconst NO_DRAG_ATTRIBUTES: Partial<DraggableAttributes> = {};\n\nconst withoutDrag = <T extends { attributes: DraggableAttributes }>(\n draggable: T,\n isDndEnabled: boolean\n) =>\n isDndEnabled ? draggable : { ...draggable, attributes: NO_DRAG_ATTRIBUTES, listeners: undefined };\n\nexport const useFileDraggable = (asset: {\n id: number;\n name: string;\n folder?: number | string | { id?: number } | null;\n}) => {\n const dnd = useAssetsDndOptional();\n const isDndEnabled = dnd !== null;\n const isMovePending = dnd?.isMovePending ?? false;\n\n const data = useMemo<DragFileData>(\n () => ({\n kind: 'file',\n id: asset.id,\n name: asset.name,\n folderId: getRelationId(asset.folder),\n }),\n [asset.folder, asset.id, asset.name]\n );\n\n const draggable = useDraggable({\n id: toFileDraggableId(asset.id),\n data,\n disabled: !isDndEnabled || isMovePending,\n });\n\n const sortable = useAssetSortable(asset.id);\n\n // In a reorderable list (the picker's Selected tab) dragging reorders\n // instead of moving between folders: the item takes the sortable's node,\n // pointer listeners and transform, and exposes a grip for the keyboard.\n if (sortable) {\n return {\n ...withoutDrag(draggable, false),\n setNodeRef: sortable.setNodeRef,\n isDragging: sortable.isDragging,\n listeners: sortable.listeners,\n dragStyle: sortable.style,\n dragHandle: sortable.handle,\n dragData: data,\n };\n }\n\n // `dragData` is re-exposed (like `useFolderDraggableDroppable` does) so the\n // row's actions menu can hand the move dialog the asset's real folder.\n return {\n ...withoutDrag(draggable, isDndEnabled),\n dragStyle: undefined,\n dragHandle: undefined,\n dragData: data,\n };\n};\n\nexport const useFolderDraggableDroppable = (folder: {\n id: number;\n name: string;\n parent?: number | null | { id?: number };\n}) => {\n const dnd = useAssetsDndOptional();\n const isDndEnabled = dnd !== null;\n const isMovePending = dnd?.isMovePending ?? false;\n const isValidDropTarget = dnd?.isValidDropTarget ?? (() => false);\n const { active } = useDndContext();\n\n const parentId = getRelationId(folder.parent);\n\n const dragData = useMemo<DragFolderData>(\n () => ({\n kind: 'folder',\n id: folder.id,\n name: folder.name,\n parentId,\n }),\n [folder.id, folder.name, parentId]\n );\n\n const dropData = useMemo<FolderTargetData>(\n () => ({\n kind: 'folder-target',\n id: folder.id,\n name: folder.name,\n }),\n [folder.id, folder.name]\n );\n\n const draggable = withoutDrag(\n useDraggable({\n id: toFolderDraggableId(folder.id),\n data: dragData,\n disabled: !isDndEnabled || isMovePending,\n }),\n isDndEnabled\n );\n\n const droppable = useDroppable({\n id: toFolderTargetId(folder.id),\n data: dropData,\n disabled: !isDndEnabled || isMovePending,\n });\n\n const isValidTarget = isValidDropTarget(folder.id);\n const isOver = droppable.isOver;\n const showValidDropHighlight = isOver && isValidTarget;\n const showInvalidDropCursor = isOver && !isValidTarget && active != null;\n\n return {\n dragData,\n draggable,\n droppable,\n isDragging: draggable.isDragging,\n showValidDropHighlight,\n showInvalidDropCursor,\n };\n};\n"],"names":["NO_DRAG_ATTRIBUTES","withoutDrag","draggable","isDndEnabled","attributes","listeners","undefined","useFileDraggable","asset","dnd","useAssetsDndOptional","isMovePending","data","useMemo","kind","id","name","folderId","getRelationId","folder","useDraggable","toFileDraggableId","disabled","sortable","useAssetSortable","setNodeRef","isDragging","dragStyle","style","dragHandle","handle","dragData","useFolderDraggableDroppable","isValidDropTarget","active","useDndContext","parentId","parent","dropData","toFolderDraggableId","droppable","useDroppable","toFolderTargetId","isValidTarget","isOver","showValidDropHighlight","showInvalidDropCursor"],"mappings":"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"}
|