@strapi/upload 5.51.0 → 5.51.2
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/AssetCard/VideoPreview.js +1 -1
- package/dist/admin/components/AssetCard/VideoPreview.js.map +1 -1
- package/dist/admin/components/AssetCard/VideoPreview.mjs +1 -1
- package/dist/admin/components/AssetCard/VideoPreview.mjs.map +1 -1
- package/dist/admin/components/TableList/TableList.js +1 -1
- package/dist/admin/components/TableList/TableList.js.map +1 -1
- package/dist/admin/components/TableList/TableList.mjs +1 -1
- package/dist/admin/components/TableList/TableList.mjs.map +1 -1
- package/dist/admin/components/UploadAssetDialog/AddAssetStep/FromUrlForm.js +21 -4
- package/dist/admin/components/UploadAssetDialog/AddAssetStep/FromUrlForm.js.map +1 -1
- package/dist/admin/components/UploadAssetDialog/AddAssetStep/FromUrlForm.mjs +21 -4
- package/dist/admin/components/UploadAssetDialog/AddAssetStep/FromUrlForm.mjs.map +1 -1
- package/dist/admin/future/components/Drawer.js +3 -1
- package/dist/admin/future/components/Drawer.js.map +1 -1
- package/dist/admin/future/components/Drawer.mjs +3 -1
- package/dist/admin/future/components/Drawer.mjs.map +1 -1
- package/dist/admin/future/components/UploadProgressDialog.js +200 -27
- package/dist/admin/future/components/UploadProgressDialog.js.map +1 -1
- package/dist/admin/future/components/UploadProgressDialog.mjs +203 -30
- package/dist/admin/future/components/UploadProgressDialog.mjs.map +1 -1
- package/dist/admin/future/hooks/useMediaLibraryPermissions.js +35 -0
- package/dist/admin/future/hooks/useMediaLibraryPermissions.js.map +1 -0
- package/dist/admin/future/hooks/useMediaLibraryPermissions.mjs +33 -0
- package/dist/admin/future/hooks/useMediaLibraryPermissions.mjs.map +1 -0
- package/dist/admin/future/pages/Assets/AssetsPage.js +344 -150
- package/dist/admin/future/pages/Assets/AssetsPage.js.map +1 -1
- package/dist/admin/future/pages/Assets/AssetsPage.mjs +343 -149
- package/dist/admin/future/pages/Assets/AssetsPage.mjs.map +1 -1
- package/dist/admin/future/pages/Assets/components/AssetDetails/AssetCropEditor.js +75 -32
- package/dist/admin/future/pages/Assets/components/AssetDetails/AssetCropEditor.js.map +1 -1
- package/dist/admin/future/pages/Assets/components/AssetDetails/AssetCropEditor.mjs +75 -32
- package/dist/admin/future/pages/Assets/components/AssetDetails/AssetCropEditor.mjs.map +1 -1
- package/dist/admin/future/pages/Assets/components/AssetDetails/AssetDetailsDrawer.js +46 -19
- package/dist/admin/future/pages/Assets/components/AssetDetails/AssetDetailsDrawer.js.map +1 -1
- package/dist/admin/future/pages/Assets/components/AssetDetails/AssetDetailsDrawer.mjs +47 -20
- package/dist/admin/future/pages/Assets/components/AssetDetails/AssetDetailsDrawer.mjs.map +1 -1
- package/dist/admin/future/pages/Assets/components/AssetsGrid.js +161 -19
- package/dist/admin/future/pages/Assets/components/AssetsGrid.js.map +1 -1
- package/dist/admin/future/pages/Assets/components/AssetsGrid.mjs +162 -20
- package/dist/admin/future/pages/Assets/components/AssetsGrid.mjs.map +1 -1
- package/dist/admin/future/pages/Assets/components/AssetsSearchInput.js +100 -0
- package/dist/admin/future/pages/Assets/components/AssetsSearchInput.js.map +1 -0
- package/dist/admin/future/pages/Assets/components/AssetsSearchInput.mjs +98 -0
- package/dist/admin/future/pages/Assets/components/AssetsSearchInput.mjs.map +1 -0
- package/dist/admin/future/pages/Assets/components/AssetsTable.js +218 -37
- package/dist/admin/future/pages/Assets/components/AssetsTable.js.map +1 -1
- package/dist/admin/future/pages/Assets/components/AssetsTable.mjs +219 -38
- package/dist/admin/future/pages/Assets/components/AssetsTable.mjs.map +1 -1
- package/dist/admin/future/pages/Assets/components/BulkActionsBar.js +370 -0
- package/dist/admin/future/pages/Assets/components/BulkActionsBar.js.map +1 -0
- package/dist/admin/future/pages/Assets/components/BulkActionsBar.mjs +368 -0
- package/dist/admin/future/pages/Assets/components/BulkActionsBar.mjs.map +1 -0
- package/dist/admin/future/pages/Assets/components/BulkMoveDialog.js +209 -0
- package/dist/admin/future/pages/Assets/components/BulkMoveDialog.js.map +1 -0
- package/dist/admin/future/pages/Assets/components/BulkMoveDialog.mjs +207 -0
- package/dist/admin/future/pages/Assets/components/BulkMoveDialog.mjs.map +1 -0
- package/dist/admin/future/pages/Assets/components/DateRangeCalendar.js +193 -0
- package/dist/admin/future/pages/Assets/components/DateRangeCalendar.js.map +1 -0
- package/dist/admin/future/pages/Assets/components/DateRangeCalendar.mjs +191 -0
- package/dist/admin/future/pages/Assets/components/DateRangeCalendar.mjs.map +1 -0
- package/dist/admin/future/pages/Assets/components/Dnd/AssetsDndProvider.js +129 -37
- package/dist/admin/future/pages/Assets/components/Dnd/AssetsDndProvider.js.map +1 -1
- package/dist/admin/future/pages/Assets/components/Dnd/AssetsDndProvider.mjs +131 -39
- package/dist/admin/future/pages/Assets/components/Dnd/AssetsDndProvider.mjs.map +1 -1
- package/dist/admin/future/pages/Assets/components/Dnd/DragOverlayChip.js +120 -13
- package/dist/admin/future/pages/Assets/components/Dnd/DragOverlayChip.js.map +1 -1
- package/dist/admin/future/pages/Assets/components/Dnd/DragOverlayChip.mjs +120 -13
- package/dist/admin/future/pages/Assets/components/Dnd/DragOverlayChip.mjs.map +1 -1
- package/dist/admin/future/pages/Assets/components/Dnd/buildDragSet.js +71 -0
- package/dist/admin/future/pages/Assets/components/Dnd/buildDragSet.js.map +1 -0
- package/dist/admin/future/pages/Assets/components/Dnd/buildDragSet.mjs +69 -0
- package/dist/admin/future/pages/Assets/components/Dnd/buildDragSet.mjs.map +1 -0
- package/dist/admin/future/pages/Assets/components/Dnd/computeValidDropTargets.js +34 -0
- package/dist/admin/future/pages/Assets/components/Dnd/computeValidDropTargets.js.map +1 -0
- package/dist/admin/future/pages/Assets/components/Dnd/computeValidDropTargets.mjs +32 -0
- package/dist/admin/future/pages/Assets/components/Dnd/computeValidDropTargets.mjs.map +1 -0
- package/dist/admin/future/pages/Assets/components/Dnd/dndIds.js +15 -0
- package/dist/admin/future/pages/Assets/components/Dnd/dndIds.js.map +1 -1
- package/dist/admin/future/pages/Assets/components/Dnd/dndIds.mjs +13 -1
- package/dist/admin/future/pages/Assets/components/Dnd/dndIds.mjs.map +1 -1
- package/dist/admin/future/pages/Assets/components/Dnd/useAssetDnd.js +19 -25
- package/dist/admin/future/pages/Assets/components/Dnd/useAssetDnd.js.map +1 -1
- package/dist/admin/future/pages/Assets/components/Dnd/useAssetDnd.mjs +19 -25
- package/dist/admin/future/pages/Assets/components/Dnd/useAssetDnd.mjs.map +1 -1
- package/dist/admin/future/pages/Assets/components/Dnd/useFolderTreeDroppable.js +35 -0
- package/dist/admin/future/pages/Assets/components/Dnd/useFolderTreeDroppable.js.map +1 -0
- package/dist/admin/future/pages/Assets/components/Dnd/useFolderTreeDroppable.mjs +33 -0
- package/dist/admin/future/pages/Assets/components/Dnd/useFolderTreeDroppable.mjs.map +1 -0
- package/dist/admin/future/pages/Assets/components/DropZone/UploadDropZoneContext.js +13 -3
- package/dist/admin/future/pages/Assets/components/DropZone/UploadDropZoneContext.js.map +1 -1
- package/dist/admin/future/pages/Assets/components/DropZone/UploadDropZoneContext.mjs +13 -3
- package/dist/admin/future/pages/Assets/components/DropZone/UploadDropZoneContext.mjs.map +1 -1
- package/dist/admin/future/pages/Assets/components/EmptyState.js +62 -3
- package/dist/admin/future/pages/Assets/components/EmptyState.js.map +1 -1
- package/dist/admin/future/pages/Assets/components/EmptyState.mjs +62 -4
- package/dist/admin/future/pages/Assets/components/EmptyState.mjs.map +1 -1
- package/dist/admin/future/pages/Assets/components/FilterBadges.js +408 -0
- package/dist/admin/future/pages/Assets/components/FilterBadges.js.map +1 -0
- package/dist/admin/future/pages/Assets/components/FilterBadges.mjs +406 -0
- package/dist/admin/future/pages/Assets/components/FilterBadges.mjs.map +1 -0
- package/dist/admin/future/pages/Assets/components/FilterMenu.js +273 -0
- package/dist/admin/future/pages/Assets/components/FilterMenu.js.map +1 -0
- package/dist/admin/future/pages/Assets/components/FilterMenu.mjs +267 -0
- package/dist/admin/future/pages/Assets/components/FilterMenu.mjs.map +1 -0
- package/dist/admin/future/pages/Assets/components/FolderTree/FolderTree.js +195 -40
- package/dist/admin/future/pages/Assets/components/FolderTree/FolderTree.js.map +1 -1
- package/dist/admin/future/pages/Assets/components/FolderTree/FolderTree.mjs +198 -43
- package/dist/admin/future/pages/Assets/components/FolderTree/FolderTree.mjs.map +1 -1
- package/dist/admin/future/pages/Assets/components/FolderTree/filterFolderTree.js +33 -0
- package/dist/admin/future/pages/Assets/components/FolderTree/filterFolderTree.js.map +1 -0
- package/dist/admin/future/pages/Assets/components/FolderTree/filterFolderTree.mjs +31 -0
- package/dist/admin/future/pages/Assets/components/FolderTree/filterFolderTree.mjs.map +1 -0
- package/dist/admin/future/pages/Assets/components/FolderTree/useSpringLoadedExpand.js +22 -0
- package/dist/admin/future/pages/Assets/components/FolderTree/useSpringLoadedExpand.js.map +1 -0
- package/dist/admin/future/pages/Assets/components/FolderTree/useSpringLoadedExpand.mjs +19 -0
- package/dist/admin/future/pages/Assets/components/FolderTree/useSpringLoadedExpand.mjs.map +1 -0
- package/dist/admin/future/pages/Assets/components/SortMenu.js +154 -0
- package/dist/admin/future/pages/Assets/components/SortMenu.js.map +1 -0
- package/dist/admin/future/pages/Assets/components/SortMenu.mjs +152 -0
- package/dist/admin/future/pages/Assets/components/SortMenu.mjs.map +1 -0
- package/dist/admin/future/pages/Assets/hooks/useAssetSearch.js +40 -0
- package/dist/admin/future/pages/Assets/hooks/useAssetSearch.js.map +1 -0
- package/dist/admin/future/pages/Assets/hooks/useAssetSearch.mjs +38 -0
- package/dist/admin/future/pages/Assets/hooks/useAssetSearch.mjs.map +1 -0
- package/dist/admin/future/pages/Assets/hooks/useAssetSelection.js +75 -0
- package/dist/admin/future/pages/Assets/hooks/useAssetSelection.js.map +1 -0
- package/dist/admin/future/pages/Assets/hooks/useAssetSelection.mjs +71 -0
- package/dist/admin/future/pages/Assets/hooks/useAssetSelection.mjs.map +1 -0
- package/dist/admin/future/pages/Assets/hooks/useFolderNavigation.js +33 -12
- package/dist/admin/future/pages/Assets/hooks/useFolderNavigation.js.map +1 -1
- package/dist/admin/future/pages/Assets/hooks/useFolderNavigation.mjs +33 -12
- package/dist/admin/future/pages/Assets/hooks/useFolderNavigation.mjs.map +1 -1
- package/dist/admin/future/pages/Assets/hooks/useInfiniteAssets.js +40 -4
- package/dist/admin/future/pages/Assets/hooks/useInfiniteAssets.js.map +1 -1
- package/dist/admin/future/pages/Assets/hooks/useInfiniteAssets.mjs +40 -4
- package/dist/admin/future/pages/Assets/hooks/useInfiniteAssets.mjs.map +1 -1
- package/dist/admin/future/pages/Assets/hooks/useListFilters.js +168 -0
- package/dist/admin/future/pages/Assets/hooks/useListFilters.js.map +1 -0
- package/dist/admin/future/pages/Assets/hooks/useListFilters.mjs +162 -0
- package/dist/admin/future/pages/Assets/hooks/useListFilters.mjs.map +1 -0
- package/dist/admin/future/pages/Assets/hooks/useListSort.js +124 -0
- package/dist/admin/future/pages/Assets/hooks/useListSort.js.map +1 -0
- package/dist/admin/future/pages/Assets/hooks/useListSort.mjs +120 -0
- package/dist/admin/future/pages/Assets/hooks/useListSort.mjs.map +1 -0
- package/dist/admin/future/pages/Assets/utils/buildAssetFilters.js +201 -0
- package/dist/admin/future/pages/Assets/utils/buildAssetFilters.js.map +1 -0
- package/dist/admin/future/pages/Assets/utils/buildAssetFilters.mjs +198 -0
- package/dist/admin/future/pages/Assets/utils/buildAssetFilters.mjs.map +1 -0
- package/dist/admin/future/pages/Assets/utils/listQueryKey.js +29 -0
- package/dist/admin/future/pages/Assets/utils/listQueryKey.js.map +1 -0
- package/dist/admin/future/pages/Assets/utils/listQueryKey.mjs +27 -0
- package/dist/admin/future/pages/Assets/utils/listQueryKey.mjs.map +1 -0
- package/dist/admin/future/pages/Assets/utils/mergeMixedList.js +84 -0
- package/dist/admin/future/pages/Assets/utils/mergeMixedList.js.map +1 -0
- package/dist/admin/future/pages/Assets/utils/mergeMixedList.mjs +81 -0
- package/dist/admin/future/pages/Assets/utils/mergeMixedList.mjs.map +1 -0
- package/dist/admin/future/pages/Assets/utils/selection.js +104 -0
- package/dist/admin/future/pages/Assets/utils/selection.js.map +1 -0
- package/dist/admin/future/pages/Assets/utils/selection.mjs +94 -0
- package/dist/admin/future/pages/Assets/utils/selection.mjs.map +1 -0
- package/dist/admin/future/services/api.js +163 -28
- package/dist/admin/future/services/api.js.map +1 -1
- package/dist/admin/future/services/api.mjs +163 -30
- package/dist/admin/future/services/api.mjs.map +1 -1
- package/dist/admin/future/services/assets.js +62 -18
- package/dist/admin/future/services/assets.js.map +1 -1
- package/dist/admin/future/services/assets.mjs +62 -19
- package/dist/admin/future/services/assets.mjs.map +1 -1
- package/dist/admin/future/services/folders.js +31 -19
- package/dist/admin/future/services/folders.js.map +1 -1
- package/dist/admin/future/services/folders.mjs +31 -19
- package/dist/admin/future/services/folders.mjs.map +1 -1
- package/dist/admin/future/services/settings.js +10 -3
- package/dist/admin/future/services/settings.js.map +1 -1
- package/dist/admin/future/services/settings.mjs +10 -3
- package/dist/admin/future/services/settings.mjs.map +1 -1
- package/dist/admin/future/store/uploadProgress.js +109 -2
- package/dist/admin/future/store/uploadProgress.js.map +1 -1
- package/dist/admin/future/store/uploadProgress.mjs +105 -3
- package/dist/admin/future/store/uploadProgress.mjs.map +1 -1
- package/dist/admin/future/utils/buildDragSetFromSelection.js +33 -0
- package/dist/admin/future/utils/buildDragSetFromSelection.js.map +1 -0
- package/dist/admin/future/utils/buildDragSetFromSelection.mjs +31 -0
- package/dist/admin/future/utils/buildDragSetFromSelection.mjs.map +1 -0
- package/dist/admin/future/utils/canDropItemOnFolder.js +4 -0
- package/dist/admin/future/utils/canDropItemOnFolder.js.map +1 -1
- package/dist/admin/future/utils/canDropItemOnFolder.mjs +4 -0
- package/dist/admin/future/utils/canDropItemOnFolder.mjs.map +1 -1
- package/dist/admin/future/utils/flattenFolderStructure.js +28 -0
- package/dist/admin/future/utils/flattenFolderStructure.js.map +1 -0
- package/dist/admin/future/utils/flattenFolderStructure.mjs +26 -0
- package/dist/admin/future/utils/flattenFolderStructure.mjs.map +1 -0
- package/dist/admin/future/utils/formatMoveSuccessMessage.js +19 -0
- package/dist/admin/future/utils/formatMoveSuccessMessage.js.map +1 -0
- package/dist/admin/future/utils/formatMoveSuccessMessage.mjs +17 -0
- package/dist/admin/future/utils/formatMoveSuccessMessage.mjs.map +1 -0
- package/dist/admin/future/utils/getFolderLabel.js +31 -0
- package/dist/admin/future/utils/getFolderLabel.js.map +1 -0
- package/dist/admin/future/utils/getFolderLabel.mjs +29 -0
- package/dist/admin/future/utils/getFolderLabel.mjs.map +1 -0
- package/dist/admin/future/utils/searchQueryParam.js +11 -0
- package/dist/admin/future/utils/searchQueryParam.js.map +1 -0
- package/dist/admin/future/utils/searchQueryParam.mjs +9 -0
- package/dist/admin/future/utils/searchQueryParam.mjs.map +1 -0
- package/dist/admin/hooks/useSelectionState.js +2 -4
- package/dist/admin/hooks/useSelectionState.js.map +1 -1
- package/dist/admin/hooks/useSelectionState.mjs +2 -4
- package/dist/admin/hooks/useSelectionState.mjs.map +1 -1
- package/dist/admin/shared/constants.js +43 -0
- package/dist/admin/shared/constants.js.map +1 -0
- package/dist/admin/shared/constants.mjs +38 -0
- package/dist/admin/shared/constants.mjs.map +1 -0
- package/dist/admin/src/future/hooks/useMediaLibraryPermissions.d.ts +21 -0
- package/dist/admin/src/future/pages/Assets/components/AssetDetails/AssetCropEditor.d.ts +7 -1
- package/dist/admin/src/future/pages/Assets/components/AssetsSearchInput.d.ts +5 -0
- package/dist/admin/src/future/pages/Assets/components/AssetsTable.d.ts +7 -1
- package/dist/admin/src/future/pages/Assets/components/BulkActionsBar.d.ts +14 -0
- package/dist/admin/src/future/pages/Assets/components/BulkMoveDialog.d.ts +13 -0
- package/dist/admin/src/future/pages/Assets/components/DateRangeCalendar.d.ts +8 -0
- package/dist/admin/src/future/pages/Assets/components/Dnd/AssetsDndProvider.d.ts +2 -0
- package/dist/admin/src/future/pages/Assets/components/Dnd/DragOverlayChip.d.ts +2 -2
- package/dist/admin/src/future/pages/Assets/components/Dnd/buildDragSet.d.ts +17 -0
- package/dist/admin/src/future/pages/Assets/components/Dnd/computeValidDropTargets.d.ts +7 -0
- package/dist/admin/src/future/pages/Assets/components/Dnd/dndIds.d.ts +3 -0
- package/dist/admin/src/future/pages/Assets/components/Dnd/useAssetDnd.d.ts +3 -1
- package/dist/admin/src/future/pages/Assets/components/Dnd/useFolderTreeDroppable.d.ts +19 -0
- package/dist/admin/src/future/pages/Assets/components/DropZone/UploadDropZoneContext.d.ts +8 -1
- package/dist/admin/src/future/pages/Assets/components/EmptyState.d.ts +18 -1
- package/dist/admin/src/future/pages/Assets/components/FilterBadges.d.ts +6 -0
- package/dist/admin/src/future/pages/Assets/components/FilterMenu.d.ts +22 -0
- package/dist/admin/src/future/pages/Assets/components/FolderTree/FolderTree.d.ts +13 -4
- package/dist/admin/src/future/pages/Assets/components/FolderTree/filterFolderTree.d.ts +16 -0
- package/dist/admin/src/future/pages/Assets/components/FolderTree/useSpringLoadedExpand.d.ts +6 -0
- package/dist/admin/src/future/pages/Assets/components/SortMenu.d.ts +23 -0
- package/dist/admin/src/future/pages/Assets/hooks/useAssetSearch.d.ts +12 -0
- package/dist/admin/src/future/pages/Assets/hooks/useAssetSelection.d.ts +46 -0
- package/dist/admin/src/future/pages/Assets/hooks/useInfiniteAssets.d.ts +13 -3
- package/dist/admin/src/future/pages/Assets/hooks/useListFilters.d.ts +69 -0
- package/dist/admin/src/future/pages/Assets/hooks/useListSort.d.ts +47 -0
- package/dist/admin/src/future/pages/Assets/utils/buildAssetFilters.d.ts +46 -0
- package/dist/admin/src/future/pages/Assets/utils/listQueryKey.d.ts +29 -0
- package/dist/admin/src/future/pages/Assets/utils/mergeMixedList.d.ts +40 -0
- package/dist/admin/src/future/pages/Assets/utils/selection.d.ts +50 -0
- package/dist/admin/src/future/services/api.d.ts +53 -5
- package/dist/admin/src/future/services/assets.d.ts +13 -2
- package/dist/admin/src/future/services/folders.d.ts +7 -1
- package/dist/admin/src/future/services/settings.d.ts +2 -2
- package/dist/admin/src/future/store/uploadProgress.d.ts +83 -1
- package/dist/admin/src/future/types/dnd.d.ts +5 -0
- package/dist/admin/src/future/utils/buildDragSetFromSelection.d.ts +11 -0
- package/dist/admin/src/future/utils/canDropItemOnFolder.d.ts +1 -1
- package/dist/admin/src/future/utils/flattenFolderStructure.d.ts +18 -0
- package/dist/admin/src/future/utils/formatMoveSuccessMessage.d.ts +14 -0
- package/dist/admin/src/future/utils/getFolderLabel.d.ts +11 -0
- package/dist/admin/src/future/utils/searchQueryParam.d.ts +7 -0
- package/dist/admin/src/hooks/useAiAvailability.d.ts +1 -1
- package/dist/admin/src/hooks/useEditAsset.d.ts +4 -4
- package/dist/admin/src/hooks/useEditFolder.d.ts +4 -4
- package/dist/admin/src/hooks/useSettings.d.ts +1 -0
- package/dist/admin/src/hooks/useTracking.d.ts +1 -1
- package/dist/admin/src/hooks/useUpload.d.ts +1 -1
- package/dist/admin/translations/en.json.js +85 -2
- package/dist/admin/translations/en.json.js.map +1 -1
- package/dist/admin/translations/en.json.mjs +85 -2
- package/dist/admin/translations/en.json.mjs.map +1 -1
- package/dist/admin/utils/urlYupSchema.js +33 -9
- package/dist/admin/utils/urlYupSchema.js.map +1 -1
- package/dist/admin/utils/urlYupSchema.mjs +33 -9
- package/dist/admin/utils/urlYupSchema.mjs.map +1 -1
- package/dist/server/config.js +13 -5
- package/dist/server/config.js.map +1 -1
- package/dist/server/config.mjs +13 -5
- package/dist/server/config.mjs.map +1 -1
- package/dist/server/constants.js.map +1 -1
- package/dist/server/constants.mjs.map +1 -1
- package/dist/server/controllers/admin-file.js +30 -0
- package/dist/server/controllers/admin-file.js.map +1 -1
- package/dist/server/controllers/admin-file.mjs +30 -0
- package/dist/server/controllers/admin-file.mjs.map +1 -1
- package/dist/server/controllers/admin-settings.js +20 -2
- package/dist/server/controllers/admin-settings.js.map +1 -1
- package/dist/server/controllers/admin-settings.mjs +21 -3
- package/dist/server/controllers/admin-settings.mjs.map +1 -1
- package/dist/server/controllers/content-api.js +1 -2
- package/dist/server/controllers/content-api.js.map +1 -1
- package/dist/server/controllers/content-api.mjs +2 -2
- package/dist/server/controllers/content-api.mjs.map +1 -1
- package/dist/server/controllers/validation/admin/ai-metadata.js +12 -0
- package/dist/server/controllers/validation/admin/ai-metadata.js.map +1 -0
- package/dist/server/controllers/validation/admin/ai-metadata.mjs +10 -0
- package/dist/server/controllers/validation/admin/ai-metadata.mjs.map +1 -0
- package/dist/server/controllers/validation/admin/settings.js +4 -1
- package/dist/server/controllers/validation/admin/settings.js.map +1 -1
- package/dist/server/controllers/validation/admin/settings.mjs +1 -1
- package/dist/server/controllers/validation/admin/settings.mjs.map +1 -1
- package/dist/server/routes/admin.js +18 -0
- package/dist/server/routes/admin.js.map +1 -1
- package/dist/server/routes/admin.mjs +18 -0
- package/dist/server/routes/admin.mjs.map +1 -1
- package/dist/server/services/ai-metadata.js +108 -11
- package/dist/server/services/ai-metadata.js.map +1 -1
- package/dist/server/services/ai-metadata.mjs +108 -11
- package/dist/server/services/ai-metadata.mjs.map +1 -1
- package/dist/server/services/file.js +86 -13
- package/dist/server/services/file.js.map +1 -1
- package/dist/server/services/file.mjs +87 -14
- package/dist/server/services/file.mjs.map +1 -1
- package/dist/server/services/image-manipulation.js +4 -4
- package/dist/server/services/image-manipulation.js.map +1 -1
- package/dist/server/services/image-manipulation.mjs +4 -4
- package/dist/server/services/image-manipulation.mjs.map +1 -1
- package/dist/server/shared/constants.js +43 -0
- package/dist/server/shared/constants.js.map +1 -0
- package/dist/server/shared/constants.mjs +38 -0
- package/dist/server/shared/constants.mjs.map +1 -0
- package/dist/server/src/config.d.ts +2 -0
- package/dist/server/src/config.d.ts.map +1 -1
- package/dist/server/src/constants.d.ts +2 -1
- package/dist/server/src/constants.d.ts.map +1 -1
- package/dist/server/src/controllers/admin-file.d.ts +10 -0
- package/dist/server/src/controllers/admin-file.d.ts.map +1 -1
- package/dist/server/src/controllers/admin-settings.d.ts.map +1 -1
- package/dist/server/src/controllers/index.d.ts +1 -0
- package/dist/server/src/controllers/index.d.ts.map +1 -1
- package/dist/server/src/controllers/validation/admin/ai-metadata.d.ts +2 -0
- package/dist/server/src/controllers/validation/admin/ai-metadata.d.ts.map +1 -0
- package/dist/server/src/controllers/validation/admin/settings.d.ts +1 -1
- package/dist/server/src/controllers/validation/admin/settings.d.ts.map +1 -1
- package/dist/server/src/index.d.ts +7 -1
- package/dist/server/src/index.d.ts.map +1 -1
- package/dist/server/src/routes/admin.d.ts.map +1 -1
- package/dist/server/src/services/ai-metadata.d.ts +19 -0
- package/dist/server/src/services/ai-metadata.d.ts.map +1 -1
- package/dist/server/src/services/file.d.ts +12 -2
- package/dist/server/src/services/file.d.ts.map +1 -1
- package/dist/server/src/services/index.d.ts +4 -1
- package/dist/server/src/services/index.d.ts.map +1 -1
- package/dist/server/src/types.d.ts +3 -0
- package/dist/server/src/types.d.ts.map +1 -1
- package/dist/shared/constants.d.ts +35 -0
- package/dist/shared/constants.d.ts.map +1 -0
- package/dist/shared/contracts/files.d.ts +25 -0
- package/dist/shared/contracts/files.d.ts.map +1 -1
- package/dist/shared/contracts/folders.d.ts +1 -1
- package/dist/shared/contracts/settings.d.ts +7 -0
- package/package.json +8 -8
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import { useState, useCallback, useMemo, createElement, createContext, useContext } from 'react';
|
|
2
|
+
import { createEmptySelection, toggleSelection, selectRange, selectAll, clearSelection, getIdsOfKind } from '../utils/selection.mjs';
|
|
3
|
+
|
|
4
|
+
const AssetSelectionContext = createContext(null);
|
|
5
|
+
const AssetSelectionProvider = ({ children, disabled = false })=>{
|
|
6
|
+
const [state, setState] = useState(createEmptySelection);
|
|
7
|
+
const isSelected = useCallback((key)=>!disabled && state.selectedKeys.has(key), [
|
|
8
|
+
disabled,
|
|
9
|
+
state.selectedKeys
|
|
10
|
+
]);
|
|
11
|
+
const toggle = useCallback((key)=>{
|
|
12
|
+
if (disabled) return;
|
|
13
|
+
setState((prev)=>toggleSelection(prev, key));
|
|
14
|
+
}, [
|
|
15
|
+
disabled
|
|
16
|
+
]);
|
|
17
|
+
const selectRange$1 = useCallback((orderedKeys, targetKey)=>{
|
|
18
|
+
if (disabled) return;
|
|
19
|
+
setState((prev)=>selectRange(prev, orderedKeys, targetKey));
|
|
20
|
+
}, [
|
|
21
|
+
disabled
|
|
22
|
+
]);
|
|
23
|
+
const selectAll$1 = useCallback((orderedKeys)=>{
|
|
24
|
+
if (disabled) return;
|
|
25
|
+
setState(selectAll(orderedKeys));
|
|
26
|
+
}, [
|
|
27
|
+
disabled
|
|
28
|
+
]);
|
|
29
|
+
const clear = useCallback(()=>setState(clearSelection()), []);
|
|
30
|
+
const selectedIds = useMemo(()=>getIdsOfKind(state.selectedKeys, 'asset'), [
|
|
31
|
+
state.selectedKeys
|
|
32
|
+
]);
|
|
33
|
+
const selectedFolderIds = useMemo(()=>getIdsOfKind(state.selectedKeys, 'folder'), [
|
|
34
|
+
state.selectedKeys
|
|
35
|
+
]);
|
|
36
|
+
const value = useMemo(()=>({
|
|
37
|
+
selectedKeys: state.selectedKeys,
|
|
38
|
+
selectedIds,
|
|
39
|
+
selectedFolderIds,
|
|
40
|
+
anchorKey: state.anchorKey,
|
|
41
|
+
isSelected,
|
|
42
|
+
toggle,
|
|
43
|
+
selectRange: selectRange$1,
|
|
44
|
+
selectAll: selectAll$1,
|
|
45
|
+
clear
|
|
46
|
+
}), [
|
|
47
|
+
state.selectedKeys,
|
|
48
|
+
selectedIds,
|
|
49
|
+
selectedFolderIds,
|
|
50
|
+
state.anchorKey,
|
|
51
|
+
isSelected,
|
|
52
|
+
toggle,
|
|
53
|
+
selectRange$1,
|
|
54
|
+
selectAll$1,
|
|
55
|
+
clear
|
|
56
|
+
]);
|
|
57
|
+
return createElement(AssetSelectionContext.Provider, {
|
|
58
|
+
value
|
|
59
|
+
}, children);
|
|
60
|
+
};
|
|
61
|
+
const useAssetSelection = ()=>{
|
|
62
|
+
const context = useContext(AssetSelectionContext);
|
|
63
|
+
if (!context) {
|
|
64
|
+
throw new Error('useAssetSelection must be used within an AssetSelectionProvider');
|
|
65
|
+
}
|
|
66
|
+
return context;
|
|
67
|
+
};
|
|
68
|
+
const useAssetSelectionOptional = ()=>useContext(AssetSelectionContext);
|
|
69
|
+
|
|
70
|
+
export { AssetSelectionProvider, useAssetSelection, useAssetSelectionOptional };
|
|
71
|
+
//# sourceMappingURL=useAssetSelection.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useAssetSelection.mjs","sources":["../../../../../../admin/src/future/pages/Assets/hooks/useAssetSelection.ts"],"sourcesContent":["import {\n createContext,\n createElement,\n useCallback,\n useContext,\n useMemo,\n useState,\n type ReactNode,\n} from 'react';\n\nimport {\n clearSelection,\n createEmptySelection,\n getIdsOfKind,\n selectAll as selectAllState,\n selectRange as selectRangeState,\n toggleSelection,\n type ItemKey,\n type SelectionState,\n} from '../utils/selection';\n\n/**\n * Ephemeral, view-state-only multi-select for the future Media Library. Selection\n * is page-scoped and reset on folder navigation or sort/filter changes (the\n * table/grid toggle keeps it — same list, different presentation).\n *\n * The actual computation lives in `../utils/selection.ts` (pure + unit-tested);\n * this hook is a thin React wrapper. Assets and folders share one mechanism —\n * items are tracked as namespaced keys (`asset:1` / `folder:1`) so toggle, range\n * and select-all behave the same for both. Range / select-all receive the\n * ordered key array from the caller (the view owns the rendered order), keeping\n * the context data-source-agnostic.\n */\nexport interface AssetSelection {\n /** Every selected item key (assets and folders), render-order agnostic. */\n selectedKeys: Set<ItemKey>;\n /** Selected asset ids, derived from {@link selectedKeys}. */\n selectedIds: Set<number>;\n /** Selected folder ids, derived from {@link selectedKeys}. */\n selectedFolderIds: Set<number>;\n anchorKey: ItemKey | null;\n isSelected: (key: ItemKey) => boolean;\n /** Additive toggle (Cmd/Ctrl+click, item checkbox). */\n toggle: (key: ItemKey) => void;\n /** Shift+click — selects the contiguous range from the anchor to the target. */\n selectRange: (orderedKeys: ItemKey[], targetKey: ItemKey) => void;\n /** Header checkbox — selects every rendered item (folders and assets). */\n selectAll: (orderedKeys: ItemKey[]) => void;\n /** Close button / folder navigation / list-identity changes. */\n clear: () => void;\n}\n\nconst AssetSelectionContext = createContext<AssetSelection | null>(null);\n\ninterface AssetSelectionProviderProps {\n children: ReactNode;\n /**\n * When true, selection is inert: every mutator is a no-op and nothing ever\n * reads as selected. Every bulk action is gated on `assets.update`, so a user\n * without it has nothing to select for — the views also hide the checkboxes,\n * and this makes the remaining paths (click-to-select, Space key) do nothing.\n */\n disabled?: boolean;\n}\n\nexport const AssetSelectionProvider = ({\n children,\n disabled = false,\n}: AssetSelectionProviderProps) => {\n const [state, setState] = useState<SelectionState>(createEmptySelection);\n\n const isSelected = useCallback(\n (key: ItemKey) => !disabled && state.selectedKeys.has(key),\n [disabled, state.selectedKeys]\n );\n\n const toggle = useCallback(\n (key: ItemKey) => {\n if (disabled) return;\n setState((prev) => toggleSelection(prev, key));\n },\n [disabled]\n );\n\n const selectRange = useCallback(\n (orderedKeys: ItemKey[], targetKey: ItemKey) => {\n if (disabled) return;\n setState((prev) => selectRangeState(prev, orderedKeys, targetKey));\n },\n [disabled]\n );\n\n const selectAll = useCallback(\n (orderedKeys: ItemKey[]) => {\n if (disabled) return;\n setState(selectAllState(orderedKeys));\n },\n [disabled]\n );\n\n const clear = useCallback(() => setState(clearSelection()), []);\n\n const selectedIds = useMemo(\n () => getIdsOfKind(state.selectedKeys, 'asset'),\n [state.selectedKeys]\n );\n const selectedFolderIds = useMemo(\n () => getIdsOfKind(state.selectedKeys, 'folder'),\n [state.selectedKeys]\n );\n\n const value = useMemo<AssetSelection>(\n () => ({\n selectedKeys: state.selectedKeys,\n selectedIds,\n selectedFolderIds,\n anchorKey: state.anchorKey,\n isSelected,\n toggle,\n selectRange,\n selectAll,\n clear,\n }),\n [\n state.selectedKeys,\n selectedIds,\n selectedFolderIds,\n state.anchorKey,\n isSelected,\n toggle,\n selectRange,\n selectAll,\n clear,\n ]\n );\n\n return createElement(AssetSelectionContext.Provider, { value }, children);\n};\n\nexport const useAssetSelection = () => {\n const context = useContext(AssetSelectionContext);\n\n if (!context) {\n throw new Error('useAssetSelection must be used within an AssetSelectionProvider');\n }\n\n return context;\n};\n\nexport const useAssetSelectionOptional = () => useContext(AssetSelectionContext);\n"],"names":["AssetSelectionContext","createContext","AssetSelectionProvider","children","disabled","state","setState","useState","createEmptySelection","isSelected","useCallback","key","selectedKeys","has","toggle","prev","toggleSelection","selectRange","orderedKeys","targetKey","selectRangeState","selectAll","selectAllState","clear","clearSelection","selectedIds","useMemo","getIdsOfKind","selectedFolderIds","value","anchorKey","createElement","Provider","useAssetSelection","context","useContext","Error","useAssetSelectionOptional"],"mappings":"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"}
|
|
@@ -13,17 +13,34 @@ const parseFolderIdFromQuery = (folder)=>{
|
|
|
13
13
|
const useFolderNavigation = ()=>{
|
|
14
14
|
const [{ query }, setQuery] = strapiAdmin.useQueryParams();
|
|
15
15
|
const currentFolderId = parseFolderIdFromQuery(query?.folder);
|
|
16
|
-
|
|
16
|
+
/**
|
|
17
|
+
* Asset search is global, so keeping `_q` after a folder navigation would show
|
|
18
|
+
* byte-identical results and make the navigation look broken. Clearing it here
|
|
19
|
+
* — rather than at each call site — means no caller can forget.
|
|
20
|
+
*/ const navigateToFolder = React.useCallback((folder)=>{
|
|
17
21
|
setQuery({
|
|
18
|
-
folder: String(folder.id)
|
|
22
|
+
folder: String(folder.id),
|
|
23
|
+
_q: undefined
|
|
19
24
|
});
|
|
20
|
-
}
|
|
25
|
+
}, [
|
|
26
|
+
setQuery
|
|
27
|
+
]);
|
|
21
28
|
/**
|
|
22
|
-
* Move to the Media Library root by removing the `folder` query param
|
|
23
|
-
* `setQuery(_, 'remove')` deletes the keys present on the
|
|
24
|
-
* (
|
|
25
|
-
* is preserved.
|
|
29
|
+
* Move to the Media Library root by removing the `folder` query param, and the
|
|
30
|
+
* search term with it. `setQuery(_, 'remove')` deletes the keys present on the
|
|
31
|
+
* first argument (values are ignored) in one navigation, so any other query
|
|
32
|
+
* state (pagination, the details drawer, etc.) is preserved.
|
|
26
33
|
*/ const navigateToRoot = React.useCallback(()=>{
|
|
34
|
+
setQuery({
|
|
35
|
+
folder: '',
|
|
36
|
+
_q: ''
|
|
37
|
+
}, 'remove');
|
|
38
|
+
}, [
|
|
39
|
+
setQuery
|
|
40
|
+
]);
|
|
41
|
+
/**
|
|
42
|
+
* Strips a `?folder=` value we can't parse.
|
|
43
|
+
*/ const stripFolderParam = React.useCallback(()=>{
|
|
27
44
|
setQuery({
|
|
28
45
|
folder: ''
|
|
29
46
|
}, 'remove');
|
|
@@ -34,26 +51,30 @@ const useFolderNavigation = ()=>{
|
|
|
34
51
|
// Deleted/missing folders (404) are handled in AssetsPage — that needs a fetch.
|
|
35
52
|
React.useEffect(()=>{
|
|
36
53
|
if (query?.folder && currentFolderId === null) {
|
|
37
|
-
|
|
54
|
+
stripFolderParam();
|
|
38
55
|
}
|
|
39
56
|
}, [
|
|
40
57
|
query?.folder,
|
|
41
58
|
currentFolderId,
|
|
42
|
-
|
|
59
|
+
stripFolderParam
|
|
43
60
|
]);
|
|
44
61
|
/**
|
|
45
62
|
* Convenience for the FolderTree sidebar: a single entry point that handles
|
|
46
63
|
* both "go home" and "go to folder X" without forcing the caller to know
|
|
47
64
|
* whether to call navigateToFolder or navigateToRoot.
|
|
48
|
-
*/ const navigateToFolderId = (folderId)=>{
|
|
65
|
+
*/ const navigateToFolderId = React.useCallback((folderId)=>{
|
|
49
66
|
if (folderId == null) {
|
|
50
67
|
navigateToRoot();
|
|
51
68
|
} else {
|
|
52
69
|
setQuery({
|
|
53
|
-
folder: String(folderId)
|
|
70
|
+
folder: String(folderId),
|
|
71
|
+
_q: undefined
|
|
54
72
|
});
|
|
55
73
|
}
|
|
56
|
-
}
|
|
74
|
+
}, [
|
|
75
|
+
navigateToRoot,
|
|
76
|
+
setQuery
|
|
77
|
+
]);
|
|
57
78
|
return {
|
|
58
79
|
currentFolderId,
|
|
59
80
|
navigateToFolder,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useFolderNavigation.js","sources":["../../../../../../admin/src/future/pages/Assets/hooks/useFolderNavigation.ts"],"sourcesContent":["import { useCallback, useEffect } from 'react';\n\nimport { useQueryParams } from '@strapi/admin/strapi-admin';\n\nimport type { Folder } from '../../../../../../shared/contracts/folders';\n\nconst parseFolderIdFromQuery = (folder: string | undefined): number | null => {\n if (!folder) {\n return null;\n }\n\n const id = Number(folder);\n\n return Number.isFinite(id) ? id : null;\n};\n\nexport const useFolderNavigation = () => {\n const [{ query }, setQuery] = useQueryParams<
|
|
1
|
+
{"version":3,"file":"useFolderNavigation.js","sources":["../../../../../../admin/src/future/pages/Assets/hooks/useFolderNavigation.ts"],"sourcesContent":["import { useCallback, useEffect } from 'react';\n\nimport { useQueryParams } from '@strapi/admin/strapi-admin';\n\nimport type { Folder } from '../../../../../../shared/contracts/folders';\n\nconst parseFolderIdFromQuery = (folder: string | undefined): number | null => {\n if (!folder) {\n return null;\n }\n\n const id = Number(folder);\n\n return Number.isFinite(id) ? id : null;\n};\n\ninterface FolderNavigationQuery {\n folder?: string;\n _q?: string;\n}\n\nexport const useFolderNavigation = () => {\n const [{ query }, setQuery] = useQueryParams<FolderNavigationQuery>();\n\n const currentFolderId = parseFolderIdFromQuery(query?.folder);\n\n /**\n * Asset search is global, so keeping `_q` after a folder navigation would show\n * byte-identical results and make the navigation look broken. Clearing it here\n * — rather than at each call site — means no caller can forget.\n */\n const navigateToFolder = useCallback(\n (folder: Folder) => {\n setQuery({ folder: String(folder.id), _q: undefined });\n },\n [setQuery]\n );\n\n /**\n * Move to the Media Library root by removing the `folder` query param, and the\n * search term with it. `setQuery(_, 'remove')` deletes the keys present on the\n * first argument (values are ignored) in one navigation, so any other query\n * state (pagination, the details drawer, etc.) is preserved.\n */\n const navigateToRoot = useCallback(() => {\n setQuery({ folder: '', _q: '' }, 'remove');\n }, [setQuery]);\n\n /**\n * Strips a `?folder=` value we can't parse.\n */\n const stripFolderParam = useCallback(() => {\n setQuery({ folder: '' }, 'remove');\n }, [setQuery]);\n\n // Malformed ?folder= values (e.g. abc) parse as null; strip the param from the URL.\n // Deleted/missing folders (404) are handled in AssetsPage — that needs a fetch.\n useEffect(() => {\n if (query?.folder && currentFolderId === null) {\n stripFolderParam();\n }\n }, [query?.folder, currentFolderId, stripFolderParam]);\n\n /**\n * Convenience for the FolderTree sidebar: a single entry point that handles\n * both \"go home\" and \"go to folder X\" without forcing the caller to know\n * whether to call navigateToFolder or navigateToRoot.\n */\n const navigateToFolderId = useCallback(\n (folderId: number | null) => {\n if (folderId == null) {\n navigateToRoot();\n } else {\n setQuery({ folder: String(folderId), _q: undefined });\n }\n },\n [navigateToRoot, setQuery]\n );\n\n return {\n currentFolderId,\n navigateToFolder,\n navigateToRoot,\n navigateToFolderId,\n };\n};\n"],"names":["parseFolderIdFromQuery","folder","id","Number","isFinite","useFolderNavigation","query","setQuery","useQueryParams","currentFolderId","navigateToFolder","useCallback","String","_q","undefined","navigateToRoot","stripFolderParam","useEffect","navigateToFolderId","folderId"],"mappings":";;;;;AAMA,MAAMA,yBAAyB,CAACC,MAAAA,GAAAA;AAC9B,IAAA,IAAI,CAACA,MAAAA,EAAQ;QACX,OAAO,IAAA;AACT,IAAA;AAEA,IAAA,MAAMC,KAAKC,MAAAA,CAAOF,MAAAA,CAAAA;AAElB,IAAA,OAAOE,MAAAA,CAAOC,QAAQ,CAACF,EAAAA,CAAAA,GAAMA,EAAAA,GAAK,IAAA;AACpC,CAAA;MAOaG,mBAAAA,GAAsB,IAAA;AACjC,IAAA,MAAM,CAAC,EAAEC,KAAK,EAAE,EAAEC,SAAS,GAAGC,0BAAAA,EAAAA;IAE9B,MAAMC,eAAAA,GAAkBT,uBAAuBM,KAAAA,EAAOL,MAAAA,CAAAA;AAEtD;;;;MAKA,MAAMS,gBAAAA,GAAmBC,iBAAAA,CACvB,CAACV,MAAAA,GAAAA;QACCM,QAAAA,CAAS;YAAEN,MAAAA,EAAQW,MAAAA,CAAOX,OAAOC,EAAE,CAAA;YAAGW,EAAAA,EAAIC;AAAU,SAAA,CAAA;IACtD,CAAA,EACA;AAACP,QAAAA;AAAS,KAAA,CAAA;AAGZ;;;;;MAMA,MAAMQ,iBAAiBJ,iBAAAA,CAAY,IAAA;QACjCJ,QAAAA,CAAS;YAAEN,MAAAA,EAAQ,EAAA;YAAIY,EAAAA,EAAI;SAAG,EAAG,QAAA,CAAA;IACnC,CAAA,EAAG;AAACN,QAAAA;AAAS,KAAA,CAAA;AAEb;;MAGA,MAAMS,mBAAmBL,iBAAAA,CAAY,IAAA;QACnCJ,QAAAA,CAAS;YAAEN,MAAAA,EAAQ;SAAG,EAAG,QAAA,CAAA;IAC3B,CAAA,EAAG;AAACM,QAAAA;AAAS,KAAA,CAAA;;;IAIbU,eAAAA,CAAU,IAAA;QACR,IAAIX,KAAAA,EAAOL,MAAAA,IAAUQ,eAAAA,KAAoB,IAAA,EAAM;AAC7CO,YAAAA,gBAAAA,EAAAA;AACF,QAAA;IACF,CAAA,EAAG;QAACV,KAAAA,EAAOL,MAAAA;AAAQQ,QAAAA,eAAAA;AAAiBO,QAAAA;AAAiB,KAAA,CAAA;AAErD;;;;MAKA,MAAME,kBAAAA,GAAqBP,iBAAAA,CACzB,CAACQ,QAAAA,GAAAA;AACC,QAAA,IAAIA,YAAY,IAAA,EAAM;AACpBJ,YAAAA,cAAAA,EAAAA;QACF,CAAA,MAAO;YACLR,QAAAA,CAAS;AAAEN,gBAAAA,MAAAA,EAAQW,MAAAA,CAAOO,QAAAA,CAAAA;gBAAWN,EAAAA,EAAIC;AAAU,aAAA,CAAA;AACrD,QAAA;IACF,CAAA,EACA;AAACC,QAAAA,cAAAA;AAAgBR,QAAAA;AAAS,KAAA,CAAA;IAG5B,OAAO;AACLE,QAAAA,eAAAA;AACAC,QAAAA,gBAAAA;AACAK,QAAAA,cAAAA;AACAG,QAAAA;AACF,KAAA;AACF;;;;"}
|
|
@@ -11,17 +11,34 @@ const parseFolderIdFromQuery = (folder)=>{
|
|
|
11
11
|
const useFolderNavigation = ()=>{
|
|
12
12
|
const [{ query }, setQuery] = useQueryParams();
|
|
13
13
|
const currentFolderId = parseFolderIdFromQuery(query?.folder);
|
|
14
|
-
|
|
14
|
+
/**
|
|
15
|
+
* Asset search is global, so keeping `_q` after a folder navigation would show
|
|
16
|
+
* byte-identical results and make the navigation look broken. Clearing it here
|
|
17
|
+
* — rather than at each call site — means no caller can forget.
|
|
18
|
+
*/ const navigateToFolder = useCallback((folder)=>{
|
|
15
19
|
setQuery({
|
|
16
|
-
folder: String(folder.id)
|
|
20
|
+
folder: String(folder.id),
|
|
21
|
+
_q: undefined
|
|
17
22
|
});
|
|
18
|
-
}
|
|
23
|
+
}, [
|
|
24
|
+
setQuery
|
|
25
|
+
]);
|
|
19
26
|
/**
|
|
20
|
-
* Move to the Media Library root by removing the `folder` query param
|
|
21
|
-
* `setQuery(_, 'remove')` deletes the keys present on the
|
|
22
|
-
* (
|
|
23
|
-
* is preserved.
|
|
27
|
+
* Move to the Media Library root by removing the `folder` query param, and the
|
|
28
|
+
* search term with it. `setQuery(_, 'remove')` deletes the keys present on the
|
|
29
|
+
* first argument (values are ignored) in one navigation, so any other query
|
|
30
|
+
* state (pagination, the details drawer, etc.) is preserved.
|
|
24
31
|
*/ const navigateToRoot = useCallback(()=>{
|
|
32
|
+
setQuery({
|
|
33
|
+
folder: '',
|
|
34
|
+
_q: ''
|
|
35
|
+
}, 'remove');
|
|
36
|
+
}, [
|
|
37
|
+
setQuery
|
|
38
|
+
]);
|
|
39
|
+
/**
|
|
40
|
+
* Strips a `?folder=` value we can't parse.
|
|
41
|
+
*/ const stripFolderParam = useCallback(()=>{
|
|
25
42
|
setQuery({
|
|
26
43
|
folder: ''
|
|
27
44
|
}, 'remove');
|
|
@@ -32,26 +49,30 @@ const useFolderNavigation = ()=>{
|
|
|
32
49
|
// Deleted/missing folders (404) are handled in AssetsPage — that needs a fetch.
|
|
33
50
|
useEffect(()=>{
|
|
34
51
|
if (query?.folder && currentFolderId === null) {
|
|
35
|
-
|
|
52
|
+
stripFolderParam();
|
|
36
53
|
}
|
|
37
54
|
}, [
|
|
38
55
|
query?.folder,
|
|
39
56
|
currentFolderId,
|
|
40
|
-
|
|
57
|
+
stripFolderParam
|
|
41
58
|
]);
|
|
42
59
|
/**
|
|
43
60
|
* Convenience for the FolderTree sidebar: a single entry point that handles
|
|
44
61
|
* both "go home" and "go to folder X" without forcing the caller to know
|
|
45
62
|
* whether to call navigateToFolder or navigateToRoot.
|
|
46
|
-
*/ const navigateToFolderId = (folderId)=>{
|
|
63
|
+
*/ const navigateToFolderId = useCallback((folderId)=>{
|
|
47
64
|
if (folderId == null) {
|
|
48
65
|
navigateToRoot();
|
|
49
66
|
} else {
|
|
50
67
|
setQuery({
|
|
51
|
-
folder: String(folderId)
|
|
68
|
+
folder: String(folderId),
|
|
69
|
+
_q: undefined
|
|
52
70
|
});
|
|
53
71
|
}
|
|
54
|
-
}
|
|
72
|
+
}, [
|
|
73
|
+
navigateToRoot,
|
|
74
|
+
setQuery
|
|
75
|
+
]);
|
|
55
76
|
return {
|
|
56
77
|
currentFolderId,
|
|
57
78
|
navigateToFolder,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useFolderNavigation.mjs","sources":["../../../../../../admin/src/future/pages/Assets/hooks/useFolderNavigation.ts"],"sourcesContent":["import { useCallback, useEffect } from 'react';\n\nimport { useQueryParams } from '@strapi/admin/strapi-admin';\n\nimport type { Folder } from '../../../../../../shared/contracts/folders';\n\nconst parseFolderIdFromQuery = (folder: string | undefined): number | null => {\n if (!folder) {\n return null;\n }\n\n const id = Number(folder);\n\n return Number.isFinite(id) ? id : null;\n};\n\nexport const useFolderNavigation = () => {\n const [{ query }, setQuery] = useQueryParams<
|
|
1
|
+
{"version":3,"file":"useFolderNavigation.mjs","sources":["../../../../../../admin/src/future/pages/Assets/hooks/useFolderNavigation.ts"],"sourcesContent":["import { useCallback, useEffect } from 'react';\n\nimport { useQueryParams } from '@strapi/admin/strapi-admin';\n\nimport type { Folder } from '../../../../../../shared/contracts/folders';\n\nconst parseFolderIdFromQuery = (folder: string | undefined): number | null => {\n if (!folder) {\n return null;\n }\n\n const id = Number(folder);\n\n return Number.isFinite(id) ? id : null;\n};\n\ninterface FolderNavigationQuery {\n folder?: string;\n _q?: string;\n}\n\nexport const useFolderNavigation = () => {\n const [{ query }, setQuery] = useQueryParams<FolderNavigationQuery>();\n\n const currentFolderId = parseFolderIdFromQuery(query?.folder);\n\n /**\n * Asset search is global, so keeping `_q` after a folder navigation would show\n * byte-identical results and make the navigation look broken. Clearing it here\n * — rather than at each call site — means no caller can forget.\n */\n const navigateToFolder = useCallback(\n (folder: Folder) => {\n setQuery({ folder: String(folder.id), _q: undefined });\n },\n [setQuery]\n );\n\n /**\n * Move to the Media Library root by removing the `folder` query param, and the\n * search term with it. `setQuery(_, 'remove')` deletes the keys present on the\n * first argument (values are ignored) in one navigation, so any other query\n * state (pagination, the details drawer, etc.) is preserved.\n */\n const navigateToRoot = useCallback(() => {\n setQuery({ folder: '', _q: '' }, 'remove');\n }, [setQuery]);\n\n /**\n * Strips a `?folder=` value we can't parse.\n */\n const stripFolderParam = useCallback(() => {\n setQuery({ folder: '' }, 'remove');\n }, [setQuery]);\n\n // Malformed ?folder= values (e.g. abc) parse as null; strip the param from the URL.\n // Deleted/missing folders (404) are handled in AssetsPage — that needs a fetch.\n useEffect(() => {\n if (query?.folder && currentFolderId === null) {\n stripFolderParam();\n }\n }, [query?.folder, currentFolderId, stripFolderParam]);\n\n /**\n * Convenience for the FolderTree sidebar: a single entry point that handles\n * both \"go home\" and \"go to folder X\" without forcing the caller to know\n * whether to call navigateToFolder or navigateToRoot.\n */\n const navigateToFolderId = useCallback(\n (folderId: number | null) => {\n if (folderId == null) {\n navigateToRoot();\n } else {\n setQuery({ folder: String(folderId), _q: undefined });\n }\n },\n [navigateToRoot, setQuery]\n );\n\n return {\n currentFolderId,\n navigateToFolder,\n navigateToRoot,\n navigateToFolderId,\n };\n};\n"],"names":["parseFolderIdFromQuery","folder","id","Number","isFinite","useFolderNavigation","query","setQuery","useQueryParams","currentFolderId","navigateToFolder","useCallback","String","_q","undefined","navigateToRoot","stripFolderParam","useEffect","navigateToFolderId","folderId"],"mappings":";;;AAMA,MAAMA,yBAAyB,CAACC,MAAAA,GAAAA;AAC9B,IAAA,IAAI,CAACA,MAAAA,EAAQ;QACX,OAAO,IAAA;AACT,IAAA;AAEA,IAAA,MAAMC,KAAKC,MAAAA,CAAOF,MAAAA,CAAAA;AAElB,IAAA,OAAOE,MAAAA,CAAOC,QAAQ,CAACF,EAAAA,CAAAA,GAAMA,EAAAA,GAAK,IAAA;AACpC,CAAA;MAOaG,mBAAAA,GAAsB,IAAA;AACjC,IAAA,MAAM,CAAC,EAAEC,KAAK,EAAE,EAAEC,SAAS,GAAGC,cAAAA,EAAAA;IAE9B,MAAMC,eAAAA,GAAkBT,uBAAuBM,KAAAA,EAAOL,MAAAA,CAAAA;AAEtD;;;;MAKA,MAAMS,gBAAAA,GAAmBC,WAAAA,CACvB,CAACV,MAAAA,GAAAA;QACCM,QAAAA,CAAS;YAAEN,MAAAA,EAAQW,MAAAA,CAAOX,OAAOC,EAAE,CAAA;YAAGW,EAAAA,EAAIC;AAAU,SAAA,CAAA;IACtD,CAAA,EACA;AAACP,QAAAA;AAAS,KAAA,CAAA;AAGZ;;;;;MAMA,MAAMQ,iBAAiBJ,WAAAA,CAAY,IAAA;QACjCJ,QAAAA,CAAS;YAAEN,MAAAA,EAAQ,EAAA;YAAIY,EAAAA,EAAI;SAAG,EAAG,QAAA,CAAA;IACnC,CAAA,EAAG;AAACN,QAAAA;AAAS,KAAA,CAAA;AAEb;;MAGA,MAAMS,mBAAmBL,WAAAA,CAAY,IAAA;QACnCJ,QAAAA,CAAS;YAAEN,MAAAA,EAAQ;SAAG,EAAG,QAAA,CAAA;IAC3B,CAAA,EAAG;AAACM,QAAAA;AAAS,KAAA,CAAA;;;IAIbU,SAAAA,CAAU,IAAA;QACR,IAAIX,KAAAA,EAAOL,MAAAA,IAAUQ,eAAAA,KAAoB,IAAA,EAAM;AAC7CO,YAAAA,gBAAAA,EAAAA;AACF,QAAA;IACF,CAAA,EAAG;QAACV,KAAAA,EAAOL,MAAAA;AAAQQ,QAAAA,eAAAA;AAAiBO,QAAAA;AAAiB,KAAA,CAAA;AAErD;;;;MAKA,MAAME,kBAAAA,GAAqBP,WAAAA,CACzB,CAACQ,QAAAA,GAAAA;AACC,QAAA,IAAIA,YAAY,IAAA,EAAM;AACpBJ,YAAAA,cAAAA,EAAAA;QACF,CAAA,MAAO;YACLR,QAAAA,CAAS;AAAEN,gBAAAA,MAAAA,EAAQW,MAAAA,CAAOO,QAAAA,CAAAA;gBAAWN,EAAAA,EAAIC;AAAU,aAAA,CAAA;AACrD,QAAA;IACF,CAAA,EACA;AAACC,QAAAA,cAAAA;AAAgBR,QAAAA;AAAS,KAAA,CAAA;IAG5B,OAAO;AACLE,QAAAA,eAAAA;AACAC,QAAAA,gBAAAA;AACAK,QAAAA,cAAAA;AACAG,QAAAA;AACF,KAAA;AACF;;;;"}
|
|
@@ -4,17 +4,26 @@ var React = require('react');
|
|
|
4
4
|
var assets = require('../../../services/assets.js');
|
|
5
5
|
|
|
6
6
|
const PAGE_SIZE = 20;
|
|
7
|
-
const useInfiniteAssets = ({ folder = null, sort } = {})=>{
|
|
7
|
+
const useInfiniteAssets = ({ folder = null, sort, search, filters, filtersKey = '', enabled = true } = {})=>{
|
|
8
8
|
const [page, setPage] = React.useState(1);
|
|
9
9
|
const lastResultsRef = React.useRef([]);
|
|
10
|
+
const lastPaginationRef = React.useRef(undefined);
|
|
10
11
|
const isMountRef = React.useRef(true);
|
|
12
|
+
const isSearchMountRef = React.useRef(true);
|
|
11
13
|
const { currentData: data, isLoading, isFetching, error } = assets.useGetAssetsQuery({
|
|
12
14
|
folder,
|
|
13
15
|
page,
|
|
14
16
|
pageSize: PAGE_SIZE,
|
|
15
|
-
sort
|
|
17
|
+
sort,
|
|
18
|
+
search,
|
|
19
|
+
filters
|
|
20
|
+
}, {
|
|
21
|
+
skip: !enabled
|
|
16
22
|
});
|
|
17
23
|
const pagination = data?.pagination;
|
|
24
|
+
if (pagination) {
|
|
25
|
+
lastPaginationRef.current = pagination;
|
|
26
|
+
}
|
|
18
27
|
// Accumulate pages. When cache is invalidated the current page is refetched
|
|
19
28
|
// detect this and reset to avoid a gap in the results.
|
|
20
29
|
const assets$1 = React.useMemo(()=>{
|
|
@@ -54,16 +63,43 @@ const useInfiniteAssets = ({ folder = null, sort } = {})=>{
|
|
|
54
63
|
lastResultsRef.current = [];
|
|
55
64
|
}, [
|
|
56
65
|
folder,
|
|
57
|
-
sort
|
|
66
|
+
sort,
|
|
67
|
+
filtersKey
|
|
58
68
|
]);
|
|
69
|
+
// A search change resets pagination but keeps the previous results rendered
|
|
70
|
+
// until the new page 1 lands, which replaces them.
|
|
71
|
+
React.useEffect(()=>{
|
|
72
|
+
if (isSearchMountRef.current) {
|
|
73
|
+
isSearchMountRef.current = false;
|
|
74
|
+
return;
|
|
75
|
+
}
|
|
76
|
+
setPage(1);
|
|
77
|
+
}, [
|
|
78
|
+
search
|
|
79
|
+
]);
|
|
80
|
+
// Deliberately the live value, not the stale-tolerant one below: paging must
|
|
81
|
+
// never be driven by a total that belongs to the previous query.
|
|
59
82
|
const hasNextPage = pagination ? page < pagination.pageCount : false;
|
|
60
83
|
const isFetchingMore = isFetching && page > 1;
|
|
61
84
|
const fetchNextPage = React.useCallback(()=>{
|
|
62
85
|
setPage((prev)=>prev + 1);
|
|
63
86
|
}, []);
|
|
87
|
+
if (!enabled) {
|
|
88
|
+
return {
|
|
89
|
+
assets: [],
|
|
90
|
+
pagination: undefined,
|
|
91
|
+
isLoading: false,
|
|
92
|
+
isFetchingMore: false,
|
|
93
|
+
hasNextPage: false,
|
|
94
|
+
fetchNextPage,
|
|
95
|
+
error: undefined
|
|
96
|
+
};
|
|
97
|
+
}
|
|
64
98
|
return {
|
|
65
99
|
assets: assets$1,
|
|
66
|
-
|
|
100
|
+
// Reported alongside the stale `assets` above so a consumer showing the total
|
|
101
|
+
// doesn't flash zero mid-transition.
|
|
102
|
+
pagination: pagination ?? lastPaginationRef.current,
|
|
67
103
|
isLoading,
|
|
68
104
|
isFetchingMore,
|
|
69
105
|
hasNextPage,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useInfiniteAssets.js","sources":["../../../../../../admin/src/future/pages/Assets/hooks/useInfiniteAssets.ts"],"sourcesContent":["import { useState, useCallback, useMemo, useEffect, useRef } from 'react';\n\nimport { useGetAssetsQuery } from '../../../services/assets';\n\nimport type { File } from '../../../../../../shared/contracts/files';\n\nconst PAGE_SIZE = 20;\n\ninterface UseInfiniteAssetsOptions {\n folder?: number | null;\n sort?: string;\n}\n\nconst useInfiniteAssets = ({
|
|
1
|
+
{"version":3,"file":"useInfiniteAssets.js","sources":["../../../../../../admin/src/future/pages/Assets/hooks/useInfiniteAssets.ts"],"sourcesContent":["import { useState, useCallback, useMemo, useEffect, useRef } from 'react';\n\nimport { useGetAssetsQuery } from '../../../services/assets';\n\nimport type { File, Pagination } from '../../../../../../shared/contracts/files';\n\nconst PAGE_SIZE = 20;\n\ninterface UseInfiniteAssetsOptions {\n folder?: number | null;\n sort?: string;\n search?: string;\n /** Extra `filters[$and]` entries for the files query. */\n filters?: Record<string, unknown>[];\n /**\n * Stable fingerprint of `filters` — a change resets the accumulated pages\n * (the array identity itself changes every render).\n */\n filtersKey?: string;\n /** Structural switch: an `is [folder]`-only type badge means no file can match. */\n enabled?: boolean;\n}\n\nconst useInfiniteAssets = ({\n folder = null,\n sort,\n search,\n filters,\n filtersKey = '',\n enabled = true,\n}: UseInfiniteAssetsOptions = {}) => {\n const [page, setPage] = useState(1);\n const lastResultsRef = useRef<File[]>([]);\n const lastPaginationRef = useRef<Pagination | undefined>(undefined);\n const isMountRef = useRef(true);\n const isSearchMountRef = useRef(true);\n\n const {\n currentData: data,\n isLoading,\n isFetching,\n error,\n } = useGetAssetsQuery(\n {\n folder,\n page,\n pageSize: PAGE_SIZE,\n sort,\n search,\n filters,\n },\n { skip: !enabled }\n );\n\n const pagination = data?.pagination;\n\n if (pagination) {\n lastPaginationRef.current = pagination;\n }\n\n // Accumulate pages. When cache is invalidated the current page is refetched\n // detect this and reset to avoid a gap in the results.\n const assets = useMemo(() => {\n if (!data) {\n return lastResultsRef.current;\n }\n\n const currentPageResults = data.results;\n\n if (page === 1) {\n lastResultsRef.current = currentPageResults;\n } else {\n // If accumulated length doesn't match expectation, cache was cleared\n const expectedPrior = (page - 1) * PAGE_SIZE;\n if (lastResultsRef.current.length < expectedPrior - PAGE_SIZE) {\n return lastResultsRef.current;\n }\n\n // Only append if these aren't already accumulated\n if (lastResultsRef.current.length < page * PAGE_SIZE) {\n lastResultsRef.current = [...lastResultsRef.current, ...currentPageResults];\n }\n }\n\n return lastResultsRef.current;\n }, [data, page]);\n\n // Reset on filter/sort change — skip the initial mount since the memo\n // already handles page 1 correctly\n useEffect(() => {\n if (isMountRef.current) {\n isMountRef.current = false;\n\n return;\n }\n setPage(1);\n lastResultsRef.current = [];\n }, [folder, sort, filtersKey]);\n\n // A search change resets pagination but keeps the previous results rendered\n // until the new page 1 lands, which replaces them.\n useEffect(() => {\n if (isSearchMountRef.current) {\n isSearchMountRef.current = false;\n\n return;\n }\n setPage(1);\n }, [search]);\n\n // Deliberately the live value, not the stale-tolerant one below: paging must\n // never be driven by a total that belongs to the previous query.\n const hasNextPage = pagination ? page < pagination.pageCount : false;\n const isFetchingMore = isFetching && page > 1;\n\n const fetchNextPage = useCallback(() => {\n setPage((prev) => prev + 1);\n }, []);\n\n if (!enabled) {\n return {\n assets: [] as File[],\n pagination: undefined,\n isLoading: false,\n isFetchingMore: false,\n hasNextPage: false,\n fetchNextPage,\n error: undefined,\n };\n }\n\n return {\n assets,\n // Reported alongside the stale `assets` above so a consumer showing the total\n // doesn't flash zero mid-transition.\n pagination: pagination ?? lastPaginationRef.current,\n isLoading,\n isFetchingMore,\n hasNextPage,\n fetchNextPage,\n error,\n };\n};\n\nexport { useInfiniteAssets };\nexport { PAGE_SIZE };\n"],"names":["PAGE_SIZE","useInfiniteAssets","folder","sort","search","filters","filtersKey","enabled","page","setPage","useState","lastResultsRef","useRef","lastPaginationRef","undefined","isMountRef","isSearchMountRef","currentData","data","isLoading","isFetching","error","useGetAssetsQuery","pageSize","skip","pagination","current","assets","useMemo","currentPageResults","results","expectedPrior","length","useEffect","hasNextPage","pageCount","isFetchingMore","fetchNextPage","useCallback","prev"],"mappings":"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"}
|
|
@@ -2,17 +2,26 @@ import { useState, useRef, useMemo, useEffect, useCallback } from 'react';
|
|
|
2
2
|
import { useGetAssetsQuery } from '../../../services/assets.mjs';
|
|
3
3
|
|
|
4
4
|
const PAGE_SIZE = 20;
|
|
5
|
-
const useInfiniteAssets = ({ folder = null, sort } = {})=>{
|
|
5
|
+
const useInfiniteAssets = ({ folder = null, sort, search, filters, filtersKey = '', enabled = true } = {})=>{
|
|
6
6
|
const [page, setPage] = useState(1);
|
|
7
7
|
const lastResultsRef = useRef([]);
|
|
8
|
+
const lastPaginationRef = useRef(undefined);
|
|
8
9
|
const isMountRef = useRef(true);
|
|
10
|
+
const isSearchMountRef = useRef(true);
|
|
9
11
|
const { currentData: data, isLoading, isFetching, error } = useGetAssetsQuery({
|
|
10
12
|
folder,
|
|
11
13
|
page,
|
|
12
14
|
pageSize: PAGE_SIZE,
|
|
13
|
-
sort
|
|
15
|
+
sort,
|
|
16
|
+
search,
|
|
17
|
+
filters
|
|
18
|
+
}, {
|
|
19
|
+
skip: !enabled
|
|
14
20
|
});
|
|
15
21
|
const pagination = data?.pagination;
|
|
22
|
+
if (pagination) {
|
|
23
|
+
lastPaginationRef.current = pagination;
|
|
24
|
+
}
|
|
16
25
|
// Accumulate pages. When cache is invalidated the current page is refetched
|
|
17
26
|
// detect this and reset to avoid a gap in the results.
|
|
18
27
|
const assets = useMemo(()=>{
|
|
@@ -52,16 +61,43 @@ const useInfiniteAssets = ({ folder = null, sort } = {})=>{
|
|
|
52
61
|
lastResultsRef.current = [];
|
|
53
62
|
}, [
|
|
54
63
|
folder,
|
|
55
|
-
sort
|
|
64
|
+
sort,
|
|
65
|
+
filtersKey
|
|
56
66
|
]);
|
|
67
|
+
// A search change resets pagination but keeps the previous results rendered
|
|
68
|
+
// until the new page 1 lands, which replaces them.
|
|
69
|
+
useEffect(()=>{
|
|
70
|
+
if (isSearchMountRef.current) {
|
|
71
|
+
isSearchMountRef.current = false;
|
|
72
|
+
return;
|
|
73
|
+
}
|
|
74
|
+
setPage(1);
|
|
75
|
+
}, [
|
|
76
|
+
search
|
|
77
|
+
]);
|
|
78
|
+
// Deliberately the live value, not the stale-tolerant one below: paging must
|
|
79
|
+
// never be driven by a total that belongs to the previous query.
|
|
57
80
|
const hasNextPage = pagination ? page < pagination.pageCount : false;
|
|
58
81
|
const isFetchingMore = isFetching && page > 1;
|
|
59
82
|
const fetchNextPage = useCallback(()=>{
|
|
60
83
|
setPage((prev)=>prev + 1);
|
|
61
84
|
}, []);
|
|
85
|
+
if (!enabled) {
|
|
86
|
+
return {
|
|
87
|
+
assets: [],
|
|
88
|
+
pagination: undefined,
|
|
89
|
+
isLoading: false,
|
|
90
|
+
isFetchingMore: false,
|
|
91
|
+
hasNextPage: false,
|
|
92
|
+
fetchNextPage,
|
|
93
|
+
error: undefined
|
|
94
|
+
};
|
|
95
|
+
}
|
|
62
96
|
return {
|
|
63
97
|
assets,
|
|
64
|
-
|
|
98
|
+
// Reported alongside the stale `assets` above so a consumer showing the total
|
|
99
|
+
// doesn't flash zero mid-transition.
|
|
100
|
+
pagination: pagination ?? lastPaginationRef.current,
|
|
65
101
|
isLoading,
|
|
66
102
|
isFetchingMore,
|
|
67
103
|
hasNextPage,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useInfiniteAssets.mjs","sources":["../../../../../../admin/src/future/pages/Assets/hooks/useInfiniteAssets.ts"],"sourcesContent":["import { useState, useCallback, useMemo, useEffect, useRef } from 'react';\n\nimport { useGetAssetsQuery } from '../../../services/assets';\n\nimport type { File } from '../../../../../../shared/contracts/files';\n\nconst PAGE_SIZE = 20;\n\ninterface UseInfiniteAssetsOptions {\n folder?: number | null;\n sort?: string;\n}\n\nconst useInfiniteAssets = ({
|
|
1
|
+
{"version":3,"file":"useInfiniteAssets.mjs","sources":["../../../../../../admin/src/future/pages/Assets/hooks/useInfiniteAssets.ts"],"sourcesContent":["import { useState, useCallback, useMemo, useEffect, useRef } from 'react';\n\nimport { useGetAssetsQuery } from '../../../services/assets';\n\nimport type { File, Pagination } from '../../../../../../shared/contracts/files';\n\nconst PAGE_SIZE = 20;\n\ninterface UseInfiniteAssetsOptions {\n folder?: number | null;\n sort?: string;\n search?: string;\n /** Extra `filters[$and]` entries for the files query. */\n filters?: Record<string, unknown>[];\n /**\n * Stable fingerprint of `filters` — a change resets the accumulated pages\n * (the array identity itself changes every render).\n */\n filtersKey?: string;\n /** Structural switch: an `is [folder]`-only type badge means no file can match. */\n enabled?: boolean;\n}\n\nconst useInfiniteAssets = ({\n folder = null,\n sort,\n search,\n filters,\n filtersKey = '',\n enabled = true,\n}: UseInfiniteAssetsOptions = {}) => {\n const [page, setPage] = useState(1);\n const lastResultsRef = useRef<File[]>([]);\n const lastPaginationRef = useRef<Pagination | undefined>(undefined);\n const isMountRef = useRef(true);\n const isSearchMountRef = useRef(true);\n\n const {\n currentData: data,\n isLoading,\n isFetching,\n error,\n } = useGetAssetsQuery(\n {\n folder,\n page,\n pageSize: PAGE_SIZE,\n sort,\n search,\n filters,\n },\n { skip: !enabled }\n );\n\n const pagination = data?.pagination;\n\n if (pagination) {\n lastPaginationRef.current = pagination;\n }\n\n // Accumulate pages. When cache is invalidated the current page is refetched\n // detect this and reset to avoid a gap in the results.\n const assets = useMemo(() => {\n if (!data) {\n return lastResultsRef.current;\n }\n\n const currentPageResults = data.results;\n\n if (page === 1) {\n lastResultsRef.current = currentPageResults;\n } else {\n // If accumulated length doesn't match expectation, cache was cleared\n const expectedPrior = (page - 1) * PAGE_SIZE;\n if (lastResultsRef.current.length < expectedPrior - PAGE_SIZE) {\n return lastResultsRef.current;\n }\n\n // Only append if these aren't already accumulated\n if (lastResultsRef.current.length < page * PAGE_SIZE) {\n lastResultsRef.current = [...lastResultsRef.current, ...currentPageResults];\n }\n }\n\n return lastResultsRef.current;\n }, [data, page]);\n\n // Reset on filter/sort change — skip the initial mount since the memo\n // already handles page 1 correctly\n useEffect(() => {\n if (isMountRef.current) {\n isMountRef.current = false;\n\n return;\n }\n setPage(1);\n lastResultsRef.current = [];\n }, [folder, sort, filtersKey]);\n\n // A search change resets pagination but keeps the previous results rendered\n // until the new page 1 lands, which replaces them.\n useEffect(() => {\n if (isSearchMountRef.current) {\n isSearchMountRef.current = false;\n\n return;\n }\n setPage(1);\n }, [search]);\n\n // Deliberately the live value, not the stale-tolerant one below: paging must\n // never be driven by a total that belongs to the previous query.\n const hasNextPage = pagination ? page < pagination.pageCount : false;\n const isFetchingMore = isFetching && page > 1;\n\n const fetchNextPage = useCallback(() => {\n setPage((prev) => prev + 1);\n }, []);\n\n if (!enabled) {\n return {\n assets: [] as File[],\n pagination: undefined,\n isLoading: false,\n isFetchingMore: false,\n hasNextPage: false,\n fetchNextPage,\n error: undefined,\n };\n }\n\n return {\n assets,\n // Reported alongside the stale `assets` above so a consumer showing the total\n // doesn't flash zero mid-transition.\n pagination: pagination ?? lastPaginationRef.current,\n isLoading,\n isFetchingMore,\n hasNextPage,\n fetchNextPage,\n error,\n };\n};\n\nexport { useInfiniteAssets };\nexport { PAGE_SIZE };\n"],"names":["PAGE_SIZE","useInfiniteAssets","folder","sort","search","filters","filtersKey","enabled","page","setPage","useState","lastResultsRef","useRef","lastPaginationRef","undefined","isMountRef","isSearchMountRef","currentData","data","isLoading","isFetching","error","useGetAssetsQuery","pageSize","skip","pagination","current","assets","useMemo","currentPageResults","results","expectedPrior","length","useEffect","hasNextPage","pageCount","isFetchingMore","fetchNextPage","useCallback","prev"],"mappings":"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"}
|