@strapi/upload 5.52.2 → 5.53.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/AssetCard/AssetCard.js +1 -0
- package/dist/admin/components/AssetCard/AssetCard.js.map +1 -1
- package/dist/admin/components/AssetCard/AssetCard.mjs +1 -0
- package/dist/admin/components/AssetCard/AssetCard.mjs.map +1 -1
- package/dist/admin/components/AssetCard/AssetCardBase.js +1 -0
- package/dist/admin/components/AssetCard/AssetCardBase.js.map +1 -1
- package/dist/admin/components/AssetCard/AssetCardBase.mjs +1 -0
- package/dist/admin/components/AssetCard/AssetCardBase.mjs.map +1 -1
- package/dist/admin/components/AssetCard/ImageAssetCard.js +1 -0
- package/dist/admin/components/AssetCard/ImageAssetCard.js.map +1 -1
- package/dist/admin/components/AssetCard/ImageAssetCard.mjs +1 -0
- package/dist/admin/components/AssetCard/ImageAssetCard.mjs.map +1 -1
- package/dist/admin/components/AssetCard/UploadingAssetCard.js +1 -0
- package/dist/admin/components/AssetCard/UploadingAssetCard.js.map +1 -1
- package/dist/admin/components/AssetCard/UploadingAssetCard.mjs +1 -0
- package/dist/admin/components/AssetCard/UploadingAssetCard.mjs.map +1 -1
- package/dist/admin/components/AssetCard/VideoAssetCard.js +1 -0
- package/dist/admin/components/AssetCard/VideoAssetCard.js.map +1 -1
- package/dist/admin/components/AssetCard/VideoAssetCard.mjs +1 -0
- package/dist/admin/components/AssetCard/VideoAssetCard.mjs.map +1 -1
- package/dist/admin/components/AssetDialog/BrowseStep/BrowseStep.js +1 -0
- package/dist/admin/components/AssetDialog/BrowseStep/BrowseStep.js.map +1 -1
- package/dist/admin/components/AssetDialog/BrowseStep/BrowseStep.mjs +1 -0
- package/dist/admin/components/AssetDialog/BrowseStep/BrowseStep.mjs.map +1 -1
- package/dist/admin/components/AssetDialog/BrowseStep/Filters.js +1 -0
- package/dist/admin/components/AssetDialog/BrowseStep/Filters.js.map +1 -1
- package/dist/admin/components/AssetDialog/BrowseStep/Filters.mjs +1 -0
- package/dist/admin/components/AssetDialog/BrowseStep/Filters.mjs.map +1 -1
- package/dist/admin/components/AssetDialog/BrowseStep/SearchAsset/SearchAsset.js +1 -0
- package/dist/admin/components/AssetDialog/BrowseStep/SearchAsset/SearchAsset.js.map +1 -1
- package/dist/admin/components/AssetDialog/BrowseStep/SearchAsset/SearchAsset.mjs +1 -0
- package/dist/admin/components/AssetDialog/BrowseStep/SearchAsset/SearchAsset.mjs.map +1 -1
- package/dist/admin/components/AssetDialog/SelectedStep/SelectedStep.js +1 -0
- package/dist/admin/components/AssetDialog/SelectedStep/SelectedStep.js.map +1 -1
- package/dist/admin/components/AssetDialog/SelectedStep/SelectedStep.mjs +1 -0
- package/dist/admin/components/AssetDialog/SelectedStep/SelectedStep.mjs.map +1 -1
- package/dist/admin/components/BulkMoveDialog/BulkMoveDialog.js +1 -0
- package/dist/admin/components/BulkMoveDialog/BulkMoveDialog.js.map +1 -1
- package/dist/admin/components/BulkMoveDialog/BulkMoveDialog.mjs +1 -0
- package/dist/admin/components/BulkMoveDialog/BulkMoveDialog.mjs.map +1 -1
- package/dist/admin/components/EditAssetDialog/EditAssetContent.js +1 -0
- package/dist/admin/components/EditAssetDialog/EditAssetContent.js.map +1 -1
- package/dist/admin/components/EditAssetDialog/EditAssetContent.mjs +1 -0
- package/dist/admin/components/EditAssetDialog/EditAssetContent.mjs.map +1 -1
- package/dist/admin/components/EditAssetDialog/PreviewBox/AssetPreview.js +1 -0
- package/dist/admin/components/EditAssetDialog/PreviewBox/AssetPreview.js.map +1 -1
- package/dist/admin/components/EditAssetDialog/PreviewBox/AssetPreview.mjs +1 -0
- package/dist/admin/components/EditAssetDialog/PreviewBox/AssetPreview.mjs.map +1 -1
- package/dist/admin/components/EditAssetDialog/PreviewBox/CroppingActions.js +1 -0
- package/dist/admin/components/EditAssetDialog/PreviewBox/CroppingActions.js.map +1 -1
- package/dist/admin/components/EditAssetDialog/PreviewBox/CroppingActions.mjs +1 -0
- package/dist/admin/components/EditAssetDialog/PreviewBox/CroppingActions.mjs.map +1 -1
- package/dist/admin/components/EditAssetDialog/PreviewBox/FocalPointActions.js +1 -0
- package/dist/admin/components/EditAssetDialog/PreviewBox/FocalPointActions.js.map +1 -1
- package/dist/admin/components/EditAssetDialog/PreviewBox/FocalPointActions.mjs +1 -0
- package/dist/admin/components/EditAssetDialog/PreviewBox/FocalPointActions.mjs.map +1 -1
- package/dist/admin/components/EditAssetDialog/PreviewBox/PreviewBox.js +1 -0
- package/dist/admin/components/EditAssetDialog/PreviewBox/PreviewBox.js.map +1 -1
- package/dist/admin/components/EditAssetDialog/PreviewBox/PreviewBox.mjs +1 -0
- package/dist/admin/components/EditAssetDialog/PreviewBox/PreviewBox.mjs.map +1 -1
- package/dist/admin/components/EditAssetDialog/ReplaceMediaButton.js +1 -0
- package/dist/admin/components/EditAssetDialog/ReplaceMediaButton.js.map +1 -1
- package/dist/admin/components/EditAssetDialog/ReplaceMediaButton.mjs +1 -0
- package/dist/admin/components/EditAssetDialog/ReplaceMediaButton.mjs.map +1 -1
- package/dist/admin/components/EditFolderDialog/ModalHeader/ModalHeader.js +1 -0
- package/dist/admin/components/EditFolderDialog/ModalHeader/ModalHeader.js.map +1 -1
- package/dist/admin/components/EditFolderDialog/ModalHeader/ModalHeader.mjs +1 -0
- package/dist/admin/components/EditFolderDialog/ModalHeader/ModalHeader.mjs.map +1 -1
- package/dist/admin/components/FilterList/FilterList.js +2 -2
- package/dist/admin/components/FilterList/FilterList.js.map +1 -1
- package/dist/admin/components/FilterList/FilterList.mjs +2 -2
- package/dist/admin/components/FilterList/FilterList.mjs.map +1 -1
- package/dist/admin/components/FilterPopover/FilterPopover.js +4 -4
- package/dist/admin/components/FilterPopover/FilterPopover.js.map +1 -1
- package/dist/admin/components/FilterPopover/FilterPopover.mjs +4 -4
- package/dist/admin/components/FilterPopover/FilterPopover.mjs.map +1 -1
- package/dist/admin/components/MediaLibraryInput/Carousel/CarouselAsset.js +1 -0
- package/dist/admin/components/MediaLibraryInput/Carousel/CarouselAsset.js.map +1 -1
- package/dist/admin/components/MediaLibraryInput/Carousel/CarouselAsset.mjs +1 -0
- package/dist/admin/components/MediaLibraryInput/Carousel/CarouselAsset.mjs.map +1 -1
- package/dist/admin/components/MediaLibraryInput/Carousel/CarouselAssetActions.js +1 -0
- package/dist/admin/components/MediaLibraryInput/Carousel/CarouselAssetActions.js.map +1 -1
- package/dist/admin/components/MediaLibraryInput/Carousel/CarouselAssetActions.mjs +1 -0
- package/dist/admin/components/MediaLibraryInput/Carousel/CarouselAssetActions.mjs.map +1 -1
- package/dist/admin/components/MediaLibraryInput/Carousel/EmptyStateAsset.js +4 -10
- package/dist/admin/components/MediaLibraryInput/Carousel/EmptyStateAsset.js.map +1 -1
- package/dist/admin/components/MediaLibraryInput/Carousel/EmptyStateAsset.mjs +4 -10
- package/dist/admin/components/MediaLibraryInput/Carousel/EmptyStateAsset.mjs.map +1 -1
- package/dist/admin/components/SortPicker/SortPicker.js +1 -0
- package/dist/admin/components/SortPicker/SortPicker.js.map +1 -1
- package/dist/admin/components/SortPicker/SortPicker.mjs +1 -0
- package/dist/admin/components/SortPicker/SortPicker.mjs.map +1 -1
- package/dist/admin/components/TableList/CellContent.js +1 -0
- package/dist/admin/components/TableList/CellContent.js.map +1 -1
- package/dist/admin/components/TableList/CellContent.mjs +1 -0
- package/dist/admin/components/TableList/CellContent.mjs.map +1 -1
- package/dist/admin/components/TableList/PreviewCell.js +1 -0
- package/dist/admin/components/TableList/PreviewCell.js.map +1 -1
- package/dist/admin/components/TableList/PreviewCell.mjs +1 -0
- package/dist/admin/components/TableList/PreviewCell.mjs.map +1 -1
- package/dist/admin/components/TableList/TableList.js +1 -0
- package/dist/admin/components/TableList/TableList.js.map +1 -1
- package/dist/admin/components/TableList/TableList.mjs +1 -0
- package/dist/admin/components/TableList/TableList.mjs.map +1 -1
- package/dist/admin/components/TableList/TableRows.js +1 -0
- package/dist/admin/components/TableList/TableRows.js.map +1 -1
- package/dist/admin/components/TableList/TableRows.mjs +1 -0
- package/dist/admin/components/TableList/TableRows.mjs.map +1 -1
- package/dist/admin/components/UploadAssetDialog/AddAssetStep/AddAssetStep.js +1 -0
- package/dist/admin/components/UploadAssetDialog/AddAssetStep/AddAssetStep.js.map +1 -1
- package/dist/admin/components/UploadAssetDialog/AddAssetStep/AddAssetStep.mjs +1 -0
- package/dist/admin/components/UploadAssetDialog/AddAssetStep/AddAssetStep.mjs.map +1 -1
- package/dist/admin/components/UploadAssetDialog/AddAssetStep/FromComputerForm.js +9 -21
- package/dist/admin/components/UploadAssetDialog/AddAssetStep/FromComputerForm.js.map +1 -1
- package/dist/admin/components/UploadAssetDialog/AddAssetStep/FromComputerForm.mjs +9 -21
- package/dist/admin/components/UploadAssetDialog/AddAssetStep/FromComputerForm.mjs.map +1 -1
- package/dist/admin/components/UploadAssetDialog/AddAssetStep/FromUrlForm.js +1 -0
- package/dist/admin/components/UploadAssetDialog/AddAssetStep/FromUrlForm.js.map +1 -1
- package/dist/admin/components/UploadAssetDialog/AddAssetStep/FromUrlForm.mjs +1 -0
- package/dist/admin/components/UploadAssetDialog/AddAssetStep/FromUrlForm.mjs.map +1 -1
- package/dist/admin/components/UploadAssetDialog/PendingAssetStep/PendingAssetStep.js +1 -0
- package/dist/admin/components/UploadAssetDialog/PendingAssetStep/PendingAssetStep.js.map +1 -1
- package/dist/admin/components/UploadAssetDialog/PendingAssetStep/PendingAssetStep.mjs +1 -0
- package/dist/admin/components/UploadAssetDialog/PendingAssetStep/PendingAssetStep.mjs.map +1 -1
- package/dist/admin/constants.js +1 -0
- package/dist/admin/constants.js.map +1 -1
- package/dist/admin/constants.mjs +1 -0
- package/dist/admin/constants.mjs.map +1 -1
- package/dist/admin/future/components/Drawer.js +17 -3
- package/dist/admin/future/components/Drawer.js.map +1 -1
- package/dist/admin/future/components/Drawer.mjs +17 -3
- package/dist/admin/future/components/Drawer.mjs.map +1 -1
- package/dist/admin/future/components/UploadProgressDialog.js +46 -12
- package/dist/admin/future/components/UploadProgressDialog.js.map +1 -1
- package/dist/admin/future/components/UploadProgressDialog.mjs +47 -13
- package/dist/admin/future/components/UploadProgressDialog.mjs.map +1 -1
- package/dist/admin/future/pages/Assets/AssetsPage.js +27 -2
- package/dist/admin/future/pages/Assets/AssetsPage.js.map +1 -1
- package/dist/admin/future/pages/Assets/AssetsPage.mjs +27 -2
- package/dist/admin/future/pages/Assets/AssetsPage.mjs.map +1 -1
- package/dist/admin/future/pages/Assets/components/AssetActionsMenu.js +9 -1
- package/dist/admin/future/pages/Assets/components/AssetActionsMenu.js.map +1 -1
- package/dist/admin/future/pages/Assets/components/AssetActionsMenu.mjs +9 -1
- package/dist/admin/future/pages/Assets/components/AssetActionsMenu.mjs.map +1 -1
- package/dist/admin/future/pages/Assets/components/AssetDetails/AssetCropEditor.js +19 -4
- package/dist/admin/future/pages/Assets/components/AssetDetails/AssetCropEditor.js.map +1 -1
- package/dist/admin/future/pages/Assets/components/AssetDetails/AssetCropEditor.mjs +19 -4
- package/dist/admin/future/pages/Assets/components/AssetDetails/AssetCropEditor.mjs.map +1 -1
- package/dist/admin/future/pages/Assets/components/AssetDetails/AssetDetailsDrawer.js +64 -10
- package/dist/admin/future/pages/Assets/components/AssetDetails/AssetDetailsDrawer.js.map +1 -1
- package/dist/admin/future/pages/Assets/components/AssetDetails/AssetDetailsDrawer.mjs +66 -12
- package/dist/admin/future/pages/Assets/components/AssetDetails/AssetDetailsDrawer.mjs.map +1 -1
- package/dist/admin/future/pages/Assets/components/AssetsGrid.js +17 -5
- package/dist/admin/future/pages/Assets/components/AssetsGrid.js.map +1 -1
- package/dist/admin/future/pages/Assets/components/AssetsGrid.mjs +17 -5
- package/dist/admin/future/pages/Assets/components/AssetsGrid.mjs.map +1 -1
- package/dist/admin/future/pages/Assets/components/AssetsTable.js +56 -28
- package/dist/admin/future/pages/Assets/components/AssetsTable.js.map +1 -1
- package/dist/admin/future/pages/Assets/components/AssetsTable.mjs +58 -30
- package/dist/admin/future/pages/Assets/components/AssetsTable.mjs.map +1 -1
- package/dist/admin/future/pages/Assets/components/BulkActionsBar.js +203 -83
- package/dist/admin/future/pages/Assets/components/BulkActionsBar.js.map +1 -1
- package/dist/admin/future/pages/Assets/components/BulkActionsBar.mjs +207 -87
- package/dist/admin/future/pages/Assets/components/BulkActionsBar.mjs.map +1 -1
- package/dist/admin/future/pages/Assets/components/FolderTree/FolderTree.js +21 -3
- package/dist/admin/future/pages/Assets/components/FolderTree/FolderTree.js.map +1 -1
- package/dist/admin/future/pages/Assets/components/FolderTree/FolderTree.mjs +21 -3
- package/dist/admin/future/pages/Assets/components/FolderTree/FolderTree.mjs.map +1 -1
- package/dist/admin/future/pages/Assets/components/MainAreaContextMenu.js +181 -0
- package/dist/admin/future/pages/Assets/components/MainAreaContextMenu.js.map +1 -0
- package/dist/admin/future/pages/Assets/components/MainAreaContextMenu.mjs +179 -0
- package/dist/admin/future/pages/Assets/components/MainAreaContextMenu.mjs.map +1 -0
- package/dist/admin/future/pages/Assets/constants.js +22 -0
- package/dist/admin/future/pages/Assets/constants.js.map +1 -1
- package/dist/admin/future/pages/Assets/constants.mjs +19 -1
- package/dist/admin/future/pages/Assets/constants.mjs.map +1 -1
- package/dist/admin/future/pages/Assets/hooks/useFolderNavigation.js +4 -3
- package/dist/admin/future/pages/Assets/hooks/useFolderNavigation.js.map +1 -1
- package/dist/admin/future/pages/Assets/hooks/useFolderNavigation.mjs +5 -4
- package/dist/admin/future/pages/Assets/hooks/useFolderNavigation.mjs.map +1 -1
- package/dist/admin/future/pages/Assets/hooks/useInfiniteAssets.js +105 -12
- package/dist/admin/future/pages/Assets/hooks/useInfiniteAssets.js.map +1 -1
- package/dist/admin/future/pages/Assets/hooks/useInfiniteAssets.mjs +106 -13
- package/dist/admin/future/pages/Assets/hooks/useInfiniteAssets.mjs.map +1 -1
- package/dist/admin/future/pages/Assets/hooks/useListFilters.js +5 -5
- package/dist/admin/future/pages/Assets/hooks/useListFilters.js.map +1 -1
- package/dist/admin/future/pages/Assets/hooks/useListFilters.mjs +6 -6
- package/dist/admin/future/pages/Assets/hooks/useListFilters.mjs.map +1 -1
- package/dist/admin/future/pages/Assets/hooks/useListScrollRestoration.js +111 -0
- package/dist/admin/future/pages/Assets/hooks/useListScrollRestoration.js.map +1 -0
- package/dist/admin/future/pages/Assets/hooks/useListScrollRestoration.mjs +109 -0
- package/dist/admin/future/pages/Assets/hooks/useListScrollRestoration.mjs.map +1 -0
- package/dist/admin/future/pages/Assets/hooks/useListSort.js +10 -10
- package/dist/admin/future/pages/Assets/hooks/useListSort.js.map +1 -1
- package/dist/admin/future/pages/Assets/hooks/useListSort.mjs +11 -11
- package/dist/admin/future/pages/Assets/hooks/useListSort.mjs.map +1 -1
- package/dist/admin/future/pages/Assets/utils/mergeUploadedAssets.js +86 -0
- package/dist/admin/future/pages/Assets/utils/mergeUploadedAssets.js.map +1 -0
- package/dist/admin/future/pages/Assets/utils/mergeUploadedAssets.mjs +83 -0
- package/dist/admin/future/pages/Assets/utils/mergeUploadedAssets.mjs.map +1 -0
- package/dist/admin/future/pages/Assets/utils/renderedKeys.js +19 -0
- package/dist/admin/future/pages/Assets/utils/renderedKeys.js.map +1 -0
- package/dist/admin/future/pages/Assets/utils/renderedKeys.mjs +17 -0
- package/dist/admin/future/pages/Assets/utils/renderedKeys.mjs.map +1 -0
- package/dist/admin/future/services/api.js +19 -6
- package/dist/admin/future/services/api.js.map +1 -1
- package/dist/admin/future/services/api.mjs +19 -6
- package/dist/admin/future/services/api.mjs.map +1 -1
- package/dist/admin/future/store/uploadProgress.js +55 -2
- package/dist/admin/future/store/uploadProgress.js.map +1 -1
- package/dist/admin/future/store/uploadProgress.mjs +53 -3
- package/dist/admin/future/store/uploadProgress.mjs.map +1 -1
- package/dist/admin/index.js +1 -0
- package/dist/admin/index.js.map +1 -1
- package/dist/admin/index.mjs +1 -0
- package/dist/admin/index.mjs.map +1 -1
- package/dist/admin/pages/App/ConfigureTheView/components/Settings.js +1 -0
- package/dist/admin/pages/App/ConfigureTheView/components/Settings.js.map +1 -1
- package/dist/admin/pages/App/ConfigureTheView/components/Settings.mjs +1 -0
- package/dist/admin/pages/App/ConfigureTheView/components/Settings.mjs.map +1 -1
- package/dist/admin/pages/App/MediaLibrary.js +7 -9
- package/dist/admin/pages/App/MediaLibrary.js.map +1 -1
- package/dist/admin/pages/App/MediaLibrary.mjs +8 -10
- package/dist/admin/pages/App/MediaLibrary.mjs.map +1 -1
- package/dist/admin/pages/App/components/BulkActions.js +1 -0
- package/dist/admin/pages/App/components/BulkActions.js.map +1 -1
- package/dist/admin/pages/App/components/BulkActions.mjs +1 -0
- package/dist/admin/pages/App/components/BulkActions.mjs.map +1 -1
- package/dist/admin/pages/App/components/EmptyOrNoPermissions.js +1 -0
- package/dist/admin/pages/App/components/EmptyOrNoPermissions.js.map +1 -1
- package/dist/admin/pages/App/components/EmptyOrNoPermissions.mjs +1 -0
- package/dist/admin/pages/App/components/EmptyOrNoPermissions.mjs.map +1 -1
- package/dist/admin/pages/App/components/Filters.js +8 -8
- package/dist/admin/pages/App/components/Filters.js.map +1 -1
- package/dist/admin/pages/App/components/Filters.mjs +9 -9
- package/dist/admin/pages/App/components/Filters.mjs.map +1 -1
- package/dist/admin/pages/App/components/Header.js +1 -1
- package/dist/admin/pages/App/components/Header.js.map +1 -1
- package/dist/admin/pages/App/components/Header.mjs +2 -2
- package/dist/admin/pages/App/components/Header.mjs.map +1 -1
- package/dist/admin/src/future/components/Drawer.d.ts +10 -0
- package/dist/admin/src/future/pages/Assets/components/AssetsGrid.d.ts +4 -1
- package/dist/admin/src/future/pages/Assets/components/AssetsTable.d.ts +4 -1
- package/dist/admin/src/future/pages/Assets/components/BulkActionsBar.d.ts +8 -1
- package/dist/admin/src/future/pages/Assets/components/MainAreaContextMenu.d.ts +28 -0
- package/dist/admin/src/future/pages/Assets/constants.d.ts +20 -0
- package/dist/admin/src/future/pages/Assets/hooks/useInfiniteAssets.d.ts +4 -0
- package/dist/admin/src/future/pages/Assets/hooks/useListScrollRestoration.d.ts +15 -0
- package/dist/admin/src/future/pages/Assets/utils/mergeUploadedAssets.d.ts +35 -0
- package/dist/admin/src/future/pages/Assets/utils/renderedKeys.d.ts +19 -0
- package/dist/admin/src/future/store/uploadProgress.d.ts +51 -0
- package/dist/admin/src/utils/index.d.ts +1 -0
- package/dist/admin/src/utils/rawFileToAsset.d.ts +2 -2
- package/dist/admin/src/utils/resolveFileMime.d.ts +13 -0
- package/dist/admin/translations/en.json.js +5 -1
- package/dist/admin/translations/en.json.js.map +1 -1
- package/dist/admin/translations/en.json.mjs +5 -1
- package/dist/admin/translations/en.json.mjs.map +1 -1
- package/dist/admin/utils/getFolderURL.js +2 -1
- package/dist/admin/utils/getFolderURL.js.map +1 -1
- package/dist/admin/utils/getFolderURL.mjs +2 -1
- package/dist/admin/utils/getFolderURL.mjs.map +1 -1
- package/dist/admin/utils/rawFileToAsset.js +5 -3
- package/dist/admin/utils/rawFileToAsset.js.map +1 -1
- package/dist/admin/utils/rawFileToAsset.mjs +5 -3
- package/dist/admin/utils/rawFileToAsset.mjs.map +1 -1
- package/dist/admin/utils/resolveFileMime.js +69 -0
- package/dist/admin/utils/resolveFileMime.js.map +1 -0
- package/dist/admin/utils/resolveFileMime.mjs +64 -0
- package/dist/admin/utils/resolveFileMime.mjs.map +1 -0
- package/dist/admin/utils/urlsToAssets.js +8 -4
- package/dist/admin/utils/urlsToAssets.js.map +1 -1
- package/dist/admin/utils/urlsToAssets.mjs +8 -4
- package/dist/admin/utils/urlsToAssets.mjs.map +1 -1
- package/dist/server/services/upload.js +20 -8
- package/dist/server/services/upload.js.map +1 -1
- package/dist/server/services/upload.mjs +20 -8
- package/dist/server/services/upload.mjs.map +1 -1
- package/dist/server/src/index.d.ts +2 -0
- package/dist/server/src/index.d.ts.map +1 -1
- package/dist/server/src/services/index.d.ts +2 -0
- package/dist/server/src/services/index.d.ts.map +1 -1
- package/dist/server/src/services/upload.d.ts +2 -0
- package/dist/server/src/services/upload.d.ts.map +1 -1
- package/package.json +6 -6
|
@@ -42,24 +42,24 @@ const Filters = ()=>{
|
|
|
42
42
|
const [{ query }, setQuery] = strapiAdmin.useQueryParams();
|
|
43
43
|
const filters = query?.filters?.$and || [];
|
|
44
44
|
const handleRemoveFilter = (nextFilters)=>{
|
|
45
|
-
setQuery({
|
|
46
|
-
filters: {
|
|
45
|
+
setQuery(strapiAdmin.withEncodedUserParams(query, {
|
|
46
|
+
filters: strapiAdmin.deepEncodeQueryValues({
|
|
47
47
|
$and: nextFilters
|
|
48
|
-
},
|
|
48
|
+
}),
|
|
49
49
|
page: 1
|
|
50
|
-
});
|
|
50
|
+
}));
|
|
51
51
|
};
|
|
52
52
|
const handleSubmit = (filters)=>{
|
|
53
53
|
trackUsage('didFilterMediaLibraryElements', {
|
|
54
54
|
location: 'content-manager',
|
|
55
55
|
filter: Object.keys(filters[filters.length - 1])[0]
|
|
56
56
|
});
|
|
57
|
-
setQuery({
|
|
58
|
-
filters: {
|
|
57
|
+
setQuery(strapiAdmin.withEncodedUserParams(query, {
|
|
58
|
+
filters: strapiAdmin.deepEncodeQueryValues({
|
|
59
59
|
$and: filters
|
|
60
|
-
},
|
|
60
|
+
}),
|
|
61
61
|
page: 1
|
|
62
|
-
});
|
|
62
|
+
}));
|
|
63
63
|
};
|
|
64
64
|
return /*#__PURE__*/ jsxRuntime.jsxs(designSystem.Popover.Root, {
|
|
65
65
|
open: open,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Filters.js","sources":["../../../../../admin/src/pages/App/components/Filters.tsx"],"sourcesContent":["import * as React from 'react';\n\nimport {
|
|
1
|
+
{"version":3,"file":"Filters.js","sources":["../../../../../admin/src/pages/App/components/Filters.tsx"],"sourcesContent":["import * as React from 'react';\n\nimport {\n deepEncodeQueryValues,\n useQueryParams,\n withEncodedUserParams,\n} from '@strapi/admin/strapi-admin';\nimport { Button, Popover } from '@strapi/design-system';\nimport { Filter } from '@strapi/icons';\nimport { useIntl } from 'react-intl';\n\nimport { FilterList } from '../../../components/FilterList/FilterList';\nimport { FilterPopover } from '../../../components/FilterPopover/FilterPopover';\nimport { useTracking } from '../../../hooks/useTracking';\nimport { displayedFilters } from '../../../utils';\n\nimport type { Query } from '../../../../../shared/contracts/files';\nimport type { FilterListProps } from '../../../components/FilterList/FilterList';\nimport type { FilterPopoverProps } from '../../../components/FilterPopover/FilterPopover';\n\nexport const Filters = () => {\n const [open, setOpen] = React.useState(false);\n const { formatMessage } = useIntl();\n const { trackUsage } = useTracking();\n const [{ query }, setQuery] = useQueryParams<Query>();\n const filters = query?.filters?.$and || [];\n\n const handleRemoveFilter: FilterListProps['onRemoveFilter'] = (nextFilters) => {\n setQuery(\n withEncodedUserParams(query, {\n filters: deepEncodeQueryValues({ $and: nextFilters }),\n page: 1,\n }) as Query\n );\n };\n\n const handleSubmit: FilterPopoverProps['onSubmit'] = (filters) => {\n trackUsage('didFilterMediaLibraryElements', {\n location: 'content-manager',\n filter: Object.keys(filters[filters.length - 1])[0],\n });\n setQuery(\n withEncodedUserParams(query, {\n filters: deepEncodeQueryValues({ $and: filters }),\n page: 1,\n }) as Query\n );\n };\n\n return (\n <Popover.Root open={open} onOpenChange={setOpen}>\n <Popover.Trigger>\n <Button variant=\"tertiary\" startIcon={<Filter />} size=\"S\">\n {formatMessage({ id: 'app.utils.filters', defaultMessage: 'Filters' })}\n </Button>\n </Popover.Trigger>\n <FilterPopover\n displayedFilters={displayedFilters}\n filters={filters}\n onSubmit={handleSubmit}\n onToggle={setOpen as FilterPopoverProps['onToggle']}\n />\n <FilterList\n appliedFilters={filters as FilterListProps['appliedFilters']}\n filtersSchema={displayedFilters}\n onRemoveFilter={handleRemoveFilter}\n />\n </Popover.Root>\n );\n};\n"],"names":["Filters","open","setOpen","React","useState","formatMessage","useIntl","trackUsage","useTracking","query","setQuery","useQueryParams","filters","$and","handleRemoveFilter","nextFilters","withEncodedUserParams","deepEncodeQueryValues","page","handleSubmit","location","filter","Object","keys","length","_jsxs","Popover","Root","onOpenChange","_jsx","Trigger","Button","variant","startIcon","Filter","size","id","defaultMessage","FilterPopover","displayedFilters","onSubmit","onToggle","FilterList","appliedFilters","filtersSchema","onRemoveFilter"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;MAoBaA,OAAAA,GAAU,IAAA;AACrB,IAAA,MAAM,CAACC,IAAAA,EAAMC,OAAAA,CAAQ,GAAGC,gBAAAA,CAAMC,QAAQ,CAAC,KAAA,CAAA;IACvC,MAAM,EAAEC,aAAa,EAAE,GAAGC,iBAAAA,EAAAA;IAC1B,MAAM,EAAEC,UAAU,EAAE,GAAGC,uBAAAA,EAAAA;AACvB,IAAA,MAAM,CAAC,EAAEC,KAAK,EAAE,EAAEC,SAAS,GAAGC,0BAAAA,EAAAA;AAC9B,IAAA,MAAMC,OAAAA,GAAUH,KAAAA,EAAOG,OAAAA,EAASC,IAAAA,IAAQ,EAAE;AAE1C,IAAA,MAAMC,qBAAwD,CAACC,WAAAA,GAAAA;AAC7DL,QAAAA,QAAAA,CACEM,kCAAsBP,KAAAA,EAAO;AAC3BG,YAAAA,OAAAA,EAASK,iCAAAA,CAAsB;gBAAEJ,IAAAA,EAAME;AAAY,aAAA,CAAA;YACnDG,IAAAA,EAAM;AACR,SAAA,CAAA,CAAA;AAEJ,IAAA,CAAA;AAEA,IAAA,MAAMC,eAA+C,CAACP,OAAAA,GAAAA;AACpDL,QAAAA,UAAAA,CAAW,+BAAA,EAAiC;YAC1Ca,QAAAA,EAAU,iBAAA;YACVC,MAAAA,EAAQC,MAAAA,CAAOC,IAAI,CAACX,OAAO,CAACA,OAAAA,CAAQY,MAAM,GAAG,CAAA,CAAE,CAAC,CAAC,CAAA;AACnD,SAAA,CAAA;AACAd,QAAAA,QAAAA,CACEM,kCAAsBP,KAAAA,EAAO;AAC3BG,YAAAA,OAAAA,EAASK,iCAAAA,CAAsB;gBAAEJ,IAAAA,EAAMD;AAAQ,aAAA,CAAA;YAC/CM,IAAAA,EAAM;AACR,SAAA,CAAA,CAAA;AAEJ,IAAA,CAAA;IAEA,qBACEO,eAAA,CAACC,qBAAQC,IAAI,EAAA;QAAC1B,IAAAA,EAAMA,IAAAA;QAAM2B,YAAAA,EAAc1B,OAAAA;;AACtC,0BAAA2B,cAAA,CAACH,qBAAQI,OAAO,EAAA;AACd,gBAAA,QAAA,gBAAAD,cAAA,CAACE,mBAAAA,EAAAA;oBAAOC,OAAAA,EAAQ,UAAA;AAAWC,oBAAAA,SAAAA,gBAAWJ,cAAA,CAACK,YAAAA,EAAAA,EAAAA,CAAAA;oBAAWC,IAAAA,EAAK,GAAA;8BACpD9B,aAAAA,CAAc;wBAAE+B,EAAAA,EAAI,mBAAA;wBAAqBC,cAAAA,EAAgB;AAAU,qBAAA;;;0BAGxER,cAAA,CAACS,2BAAAA,EAAAA;gBACCC,gBAAAA,EAAkBA,iCAAAA;gBAClB3B,OAAAA,EAASA,OAAAA;gBACT4B,QAAAA,EAAUrB,YAAAA;gBACVsB,QAAAA,EAAUvC;;0BAEZ2B,cAAA,CAACa,qBAAAA,EAAAA;gBACCC,cAAAA,EAAgB/B,OAAAA;gBAChBgC,aAAAA,EAAeL,iCAAAA;gBACfM,cAAAA,EAAgB/B;;;;AAIxB;;;;"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
2
2
|
import * as React from 'react';
|
|
3
|
-
import { useQueryParams } from '@strapi/admin/strapi-admin';
|
|
3
|
+
import { useQueryParams, withEncodedUserParams, deepEncodeQueryValues } from '@strapi/admin/strapi-admin';
|
|
4
4
|
import { Popover, Button } from '@strapi/design-system';
|
|
5
5
|
import { Filter } from '@strapi/icons';
|
|
6
6
|
import { useIntl } from 'react-intl';
|
|
@@ -20,24 +20,24 @@ const Filters = ()=>{
|
|
|
20
20
|
const [{ query }, setQuery] = useQueryParams();
|
|
21
21
|
const filters = query?.filters?.$and || [];
|
|
22
22
|
const handleRemoveFilter = (nextFilters)=>{
|
|
23
|
-
setQuery({
|
|
24
|
-
filters: {
|
|
23
|
+
setQuery(withEncodedUserParams(query, {
|
|
24
|
+
filters: deepEncodeQueryValues({
|
|
25
25
|
$and: nextFilters
|
|
26
|
-
},
|
|
26
|
+
}),
|
|
27
27
|
page: 1
|
|
28
|
-
});
|
|
28
|
+
}));
|
|
29
29
|
};
|
|
30
30
|
const handleSubmit = (filters)=>{
|
|
31
31
|
trackUsage('didFilterMediaLibraryElements', {
|
|
32
32
|
location: 'content-manager',
|
|
33
33
|
filter: Object.keys(filters[filters.length - 1])[0]
|
|
34
34
|
});
|
|
35
|
-
setQuery({
|
|
36
|
-
filters: {
|
|
35
|
+
setQuery(withEncodedUserParams(query, {
|
|
36
|
+
filters: deepEncodeQueryValues({
|
|
37
37
|
$and: filters
|
|
38
|
-
},
|
|
38
|
+
}),
|
|
39
39
|
page: 1
|
|
40
|
-
});
|
|
40
|
+
}));
|
|
41
41
|
};
|
|
42
42
|
return /*#__PURE__*/ jsxs(Popover.Root, {
|
|
43
43
|
open: open,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Filters.mjs","sources":["../../../../../admin/src/pages/App/components/Filters.tsx"],"sourcesContent":["import * as React from 'react';\n\nimport {
|
|
1
|
+
{"version":3,"file":"Filters.mjs","sources":["../../../../../admin/src/pages/App/components/Filters.tsx"],"sourcesContent":["import * as React from 'react';\n\nimport {\n deepEncodeQueryValues,\n useQueryParams,\n withEncodedUserParams,\n} from '@strapi/admin/strapi-admin';\nimport { Button, Popover } from '@strapi/design-system';\nimport { Filter } from '@strapi/icons';\nimport { useIntl } from 'react-intl';\n\nimport { FilterList } from '../../../components/FilterList/FilterList';\nimport { FilterPopover } from '../../../components/FilterPopover/FilterPopover';\nimport { useTracking } from '../../../hooks/useTracking';\nimport { displayedFilters } from '../../../utils';\n\nimport type { Query } from '../../../../../shared/contracts/files';\nimport type { FilterListProps } from '../../../components/FilterList/FilterList';\nimport type { FilterPopoverProps } from '../../../components/FilterPopover/FilterPopover';\n\nexport const Filters = () => {\n const [open, setOpen] = React.useState(false);\n const { formatMessage } = useIntl();\n const { trackUsage } = useTracking();\n const [{ query }, setQuery] = useQueryParams<Query>();\n const filters = query?.filters?.$and || [];\n\n const handleRemoveFilter: FilterListProps['onRemoveFilter'] = (nextFilters) => {\n setQuery(\n withEncodedUserParams(query, {\n filters: deepEncodeQueryValues({ $and: nextFilters }),\n page: 1,\n }) as Query\n );\n };\n\n const handleSubmit: FilterPopoverProps['onSubmit'] = (filters) => {\n trackUsage('didFilterMediaLibraryElements', {\n location: 'content-manager',\n filter: Object.keys(filters[filters.length - 1])[0],\n });\n setQuery(\n withEncodedUserParams(query, {\n filters: deepEncodeQueryValues({ $and: filters }),\n page: 1,\n }) as Query\n );\n };\n\n return (\n <Popover.Root open={open} onOpenChange={setOpen}>\n <Popover.Trigger>\n <Button variant=\"tertiary\" startIcon={<Filter />} size=\"S\">\n {formatMessage({ id: 'app.utils.filters', defaultMessage: 'Filters' })}\n </Button>\n </Popover.Trigger>\n <FilterPopover\n displayedFilters={displayedFilters}\n filters={filters}\n onSubmit={handleSubmit}\n onToggle={setOpen as FilterPopoverProps['onToggle']}\n />\n <FilterList\n appliedFilters={filters as FilterListProps['appliedFilters']}\n filtersSchema={displayedFilters}\n onRemoveFilter={handleRemoveFilter}\n />\n </Popover.Root>\n );\n};\n"],"names":["Filters","open","setOpen","React","useState","formatMessage","useIntl","trackUsage","useTracking","query","setQuery","useQueryParams","filters","$and","handleRemoveFilter","nextFilters","withEncodedUserParams","deepEncodeQueryValues","page","handleSubmit","location","filter","Object","keys","length","_jsxs","Popover","Root","onOpenChange","_jsx","Trigger","Button","variant","startIcon","Filter","size","id","defaultMessage","FilterPopover","displayedFilters","onSubmit","onToggle","FilterList","appliedFilters","filtersSchema","onRemoveFilter"],"mappings":";;;;;;;;;;;;;;;MAoBaA,OAAAA,GAAU,IAAA;AACrB,IAAA,MAAM,CAACC,IAAAA,EAAMC,OAAAA,CAAQ,GAAGC,KAAAA,CAAMC,QAAQ,CAAC,KAAA,CAAA;IACvC,MAAM,EAAEC,aAAa,EAAE,GAAGC,OAAAA,EAAAA;IAC1B,MAAM,EAAEC,UAAU,EAAE,GAAGC,WAAAA,EAAAA;AACvB,IAAA,MAAM,CAAC,EAAEC,KAAK,EAAE,EAAEC,SAAS,GAAGC,cAAAA,EAAAA;AAC9B,IAAA,MAAMC,OAAAA,GAAUH,KAAAA,EAAOG,OAAAA,EAASC,IAAAA,IAAQ,EAAE;AAE1C,IAAA,MAAMC,qBAAwD,CAACC,WAAAA,GAAAA;AAC7DL,QAAAA,QAAAA,CACEM,sBAAsBP,KAAAA,EAAO;AAC3BG,YAAAA,OAAAA,EAASK,qBAAAA,CAAsB;gBAAEJ,IAAAA,EAAME;AAAY,aAAA,CAAA;YACnDG,IAAAA,EAAM;AACR,SAAA,CAAA,CAAA;AAEJ,IAAA,CAAA;AAEA,IAAA,MAAMC,eAA+C,CAACP,OAAAA,GAAAA;AACpDL,QAAAA,UAAAA,CAAW,+BAAA,EAAiC;YAC1Ca,QAAAA,EAAU,iBAAA;YACVC,MAAAA,EAAQC,MAAAA,CAAOC,IAAI,CAACX,OAAO,CAACA,OAAAA,CAAQY,MAAM,GAAG,CAAA,CAAE,CAAC,CAAC,CAAA;AACnD,SAAA,CAAA;AACAd,QAAAA,QAAAA,CACEM,sBAAsBP,KAAAA,EAAO;AAC3BG,YAAAA,OAAAA,EAASK,qBAAAA,CAAsB;gBAAEJ,IAAAA,EAAMD;AAAQ,aAAA,CAAA;YAC/CM,IAAAA,EAAM;AACR,SAAA,CAAA,CAAA;AAEJ,IAAA,CAAA;IAEA,qBACEO,IAAA,CAACC,QAAQC,IAAI,EAAA;QAAC1B,IAAAA,EAAMA,IAAAA;QAAM2B,YAAAA,EAAc1B,OAAAA;;AACtC,0BAAA2B,GAAA,CAACH,QAAQI,OAAO,EAAA;AACd,gBAAA,QAAA,gBAAAD,GAAA,CAACE,MAAAA,EAAAA;oBAAOC,OAAAA,EAAQ,UAAA;AAAWC,oBAAAA,SAAAA,gBAAWJ,GAAA,CAACK,MAAAA,EAAAA,EAAAA,CAAAA;oBAAWC,IAAAA,EAAK,GAAA;8BACpD9B,aAAAA,CAAc;wBAAE+B,EAAAA,EAAI,mBAAA;wBAAqBC,cAAAA,EAAgB;AAAU,qBAAA;;;0BAGxER,GAAA,CAACS,aAAAA,EAAAA;gBACCC,gBAAAA,EAAkBA,gBAAAA;gBAClB3B,OAAAA,EAASA,OAAAA;gBACT4B,QAAAA,EAAUrB,YAAAA;gBACVsB,QAAAA,EAAUvC;;0BAEZ2B,GAAA,CAACa,UAAAA,EAAAA;gBACCC,cAAAA,EAAgB/B,OAAAA;gBAChBgC,aAAAA,EAAeL,gBAAAA;gBACfM,cAAAA,EAAgB/B;;;;AAIxB;;;;"}
|
|
@@ -18,7 +18,7 @@ const Header = ({ breadcrumbs = null, canCreate, folder = null, onToggleEditFold
|
|
|
18
18
|
const { pathname } = reactRouterDom.useLocation();
|
|
19
19
|
const [{ query }] = strapiAdmin.useQueryParams();
|
|
20
20
|
const backQuery = {
|
|
21
|
-
...query,
|
|
21
|
+
...strapiAdmin.deepEncodeQueryValues(query),
|
|
22
22
|
folder: folder?.parent && typeof folder.parent !== 'number' && folder.parent.id ? folder.parent.id : undefined,
|
|
23
23
|
folderPath: folder?.parent && typeof folder.parent !== 'number' && folder.parent.path ? folder.parent.path : undefined
|
|
24
24
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Header.js","sources":["../../../../../admin/src/pages/App/components/Header.tsx"],"sourcesContent":["import { useQueryParams, Layouts } from '@strapi/admin/strapi-admin';\nimport { Button, Flex, Link } from '@strapi/design-system';\nimport { ArrowLeft, Plus } from '@strapi/icons';\nimport { stringify } from 'qs';\nimport { useIntl } from 'react-intl';\nimport { useLocation, NavLink } from 'react-router-dom';\n\nimport { Breadcrumbs } from '../../../components/Breadcrumbs/Breadcrumbs';\nimport { getTrad } from '../../../utils';\n\nimport type { Folder } from '../../../../../shared/contracts/folders';\nimport type { CrumbDefinition } from '../../../components/Breadcrumbs/Breadcrumbs';\n\ninterface FolderDefinition extends Omit<Folder, 'children' | 'files' | 'parent'> {\n children: {\n count: number;\n };\n files: {\n count: number;\n };\n parent?: FolderDefinition;\n}\n\nexport interface HeaderProps {\n breadcrumbs?: Array<CrumbDefinition> | null;\n canCreate: boolean;\n folder?: FolderDefinition | null;\n onToggleEditFolderDialog: (args?: { created?: boolean }) => void;\n onToggleUploadAssetDialog: () => void;\n}\n\nexport const Header = ({\n breadcrumbs = null,\n canCreate,\n folder = null,\n onToggleEditFolderDialog,\n onToggleUploadAssetDialog,\n}: HeaderProps) => {\n const { formatMessage } = useIntl();\n const { pathname } = useLocation();\n const [{ query }] = useQueryParams();\n const backQuery = {\n ...query,\n folder:\n folder?.parent && typeof folder.parent !== 'number' && folder.parent.id\n ? folder.parent.id\n : undefined,\n folderPath:\n folder?.parent && typeof folder.parent !== 'number' && folder.parent.path\n ? folder.parent.path\n : undefined,\n };\n\n return (\n <Layouts.Header\n title={formatMessage({\n id: getTrad('plugin.name'),\n defaultMessage: `Media Library`,\n })}\n subtitle={\n breadcrumbs &&\n typeof breadcrumbs !== 'boolean' &&\n folder && (\n <Breadcrumbs\n label={formatMessage({\n id: getTrad('header.breadcrumbs.nav.label'),\n defaultMessage: 'Folders navigation',\n })}\n breadcrumbs={breadcrumbs}\n currentFolderId={folder?.id}\n />\n )\n }\n navigationAction={\n folder && (\n <Link\n tag={NavLink}\n startIcon={<ArrowLeft />}\n to={`${pathname}?${stringify(backQuery, { encode: false })}`}\n >\n {formatMessage({\n id: getTrad('header.actions.folder-level-up'),\n defaultMessage: 'Back',\n })}\n </Link>\n )\n }\n primaryAction={\n canCreate && (\n <Flex gap={2} width=\"100%\">\n <Button\n startIcon={<Plus />}\n variant=\"secondary\"\n onClick={onToggleEditFolderDialog}\n fullWidth\n >\n {formatMessage({\n id: getTrad('header.actions.add-folder'),\n defaultMessage: 'Add new folder',\n })}\n </Button>\n\n <Button startIcon={<Plus />} onClick={onToggleUploadAssetDialog} fullWidth>\n {formatMessage({\n id: getTrad('header.actions.add-assets'),\n defaultMessage: 'Add new assets',\n })}\n </Button>\n </Flex>\n )\n }\n />\n );\n};\n"],"names":["Header","breadcrumbs","canCreate","folder","onToggleEditFolderDialog","onToggleUploadAssetDialog","formatMessage","useIntl","pathname","useLocation","query","useQueryParams","backQuery","parent","id","undefined","folderPath","path","_jsx","Layouts","title","getTrad","defaultMessage","subtitle","Breadcrumbs","label","currentFolderId","navigationAction","Link","tag","NavLink","startIcon","ArrowLeft","to","stringify","encode","primaryAction","_jsxs","Flex","gap","width","Button","Plus","variant","onClick","fullWidth"],"mappings":";;;;;;;;;;;;;;;AA+BO,MAAMA,MAAAA,GAAS,CAAC,EACrBC,cAAc,IAAI,EAClBC,SAAS,EACTC,SAAS,IAAI,EACbC,wBAAwB,EACxBC,yBAAyB,EACb,GAAA;IACZ,MAAM,EAAEC,aAAa,EAAE,GAAGC,iBAAAA,EAAAA;IAC1B,MAAM,EAAEC,QAAQ,EAAE,GAAGC,0BAAAA,EAAAA;AACrB,IAAA,MAAM,CAAC,EAAEC,KAAK,EAAE,CAAC,GAAGC,0BAAAA,EAAAA;AACpB,IAAA,MAAMC,SAAAA,GAAY;AAChB,QAAA,
|
|
1
|
+
{"version":3,"file":"Header.js","sources":["../../../../../admin/src/pages/App/components/Header.tsx"],"sourcesContent":["import { deepEncodeQueryValues, useQueryParams, Layouts } from '@strapi/admin/strapi-admin';\nimport { Button, Flex, Link } from '@strapi/design-system';\nimport { ArrowLeft, Plus } from '@strapi/icons';\nimport { stringify } from 'qs';\nimport { useIntl } from 'react-intl';\nimport { useLocation, NavLink } from 'react-router-dom';\n\nimport { Breadcrumbs } from '../../../components/Breadcrumbs/Breadcrumbs';\nimport { getTrad } from '../../../utils';\n\nimport type { Folder } from '../../../../../shared/contracts/folders';\nimport type { CrumbDefinition } from '../../../components/Breadcrumbs/Breadcrumbs';\n\ninterface FolderDefinition extends Omit<Folder, 'children' | 'files' | 'parent'> {\n children: {\n count: number;\n };\n files: {\n count: number;\n };\n parent?: FolderDefinition;\n}\n\nexport interface HeaderProps {\n breadcrumbs?: Array<CrumbDefinition> | null;\n canCreate: boolean;\n folder?: FolderDefinition | null;\n onToggleEditFolderDialog: (args?: { created?: boolean }) => void;\n onToggleUploadAssetDialog: () => void;\n}\n\nexport const Header = ({\n breadcrumbs = null,\n canCreate,\n folder = null,\n onToggleEditFolderDialog,\n onToggleUploadAssetDialog,\n}: HeaderProps) => {\n const { formatMessage } = useIntl();\n const { pathname } = useLocation();\n const [{ query }] = useQueryParams();\n const backQuery = {\n ...deepEncodeQueryValues(query),\n folder:\n folder?.parent && typeof folder.parent !== 'number' && folder.parent.id\n ? folder.parent.id\n : undefined,\n folderPath:\n folder?.parent && typeof folder.parent !== 'number' && folder.parent.path\n ? folder.parent.path\n : undefined,\n };\n\n return (\n <Layouts.Header\n title={formatMessage({\n id: getTrad('plugin.name'),\n defaultMessage: `Media Library`,\n })}\n subtitle={\n breadcrumbs &&\n typeof breadcrumbs !== 'boolean' &&\n folder && (\n <Breadcrumbs\n label={formatMessage({\n id: getTrad('header.breadcrumbs.nav.label'),\n defaultMessage: 'Folders navigation',\n })}\n breadcrumbs={breadcrumbs}\n currentFolderId={folder?.id}\n />\n )\n }\n navigationAction={\n folder && (\n <Link\n tag={NavLink}\n startIcon={<ArrowLeft />}\n to={`${pathname}?${stringify(backQuery, { encode: false })}`}\n >\n {formatMessage({\n id: getTrad('header.actions.folder-level-up'),\n defaultMessage: 'Back',\n })}\n </Link>\n )\n }\n primaryAction={\n canCreate && (\n <Flex gap={2} width=\"100%\">\n <Button\n startIcon={<Plus />}\n variant=\"secondary\"\n onClick={onToggleEditFolderDialog}\n fullWidth\n >\n {formatMessage({\n id: getTrad('header.actions.add-folder'),\n defaultMessage: 'Add new folder',\n })}\n </Button>\n\n <Button startIcon={<Plus />} onClick={onToggleUploadAssetDialog} fullWidth>\n {formatMessage({\n id: getTrad('header.actions.add-assets'),\n defaultMessage: 'Add new assets',\n })}\n </Button>\n </Flex>\n )\n }\n />\n );\n};\n"],"names":["Header","breadcrumbs","canCreate","folder","onToggleEditFolderDialog","onToggleUploadAssetDialog","formatMessage","useIntl","pathname","useLocation","query","useQueryParams","backQuery","deepEncodeQueryValues","parent","id","undefined","folderPath","path","_jsx","Layouts","title","getTrad","defaultMessage","subtitle","Breadcrumbs","label","currentFolderId","navigationAction","Link","tag","NavLink","startIcon","ArrowLeft","to","stringify","encode","primaryAction","_jsxs","Flex","gap","width","Button","Plus","variant","onClick","fullWidth"],"mappings":"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"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { jsx, jsxs } from 'react/jsx-runtime';
|
|
2
|
-
import { useQueryParams, Layouts } from '@strapi/admin/strapi-admin';
|
|
2
|
+
import { useQueryParams, deepEncodeQueryValues, Layouts } from '@strapi/admin/strapi-admin';
|
|
3
3
|
import { Flex, Button, Link } from '@strapi/design-system';
|
|
4
4
|
import { Plus, ArrowLeft } from '@strapi/icons';
|
|
5
5
|
import { stringify } from 'qs';
|
|
@@ -16,7 +16,7 @@ const Header = ({ breadcrumbs = null, canCreate, folder = null, onToggleEditFold
|
|
|
16
16
|
const { pathname } = useLocation();
|
|
17
17
|
const [{ query }] = useQueryParams();
|
|
18
18
|
const backQuery = {
|
|
19
|
-
...query,
|
|
19
|
+
...deepEncodeQueryValues(query),
|
|
20
20
|
folder: folder?.parent && typeof folder.parent !== 'number' && folder.parent.id ? folder.parent.id : undefined,
|
|
21
21
|
folderPath: folder?.parent && typeof folder.parent !== 'number' && folder.parent.path ? folder.parent.path : undefined
|
|
22
22
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Header.mjs","sources":["../../../../../admin/src/pages/App/components/Header.tsx"],"sourcesContent":["import { useQueryParams, Layouts } from '@strapi/admin/strapi-admin';\nimport { Button, Flex, Link } from '@strapi/design-system';\nimport { ArrowLeft, Plus } from '@strapi/icons';\nimport { stringify } from 'qs';\nimport { useIntl } from 'react-intl';\nimport { useLocation, NavLink } from 'react-router-dom';\n\nimport { Breadcrumbs } from '../../../components/Breadcrumbs/Breadcrumbs';\nimport { getTrad } from '../../../utils';\n\nimport type { Folder } from '../../../../../shared/contracts/folders';\nimport type { CrumbDefinition } from '../../../components/Breadcrumbs/Breadcrumbs';\n\ninterface FolderDefinition extends Omit<Folder, 'children' | 'files' | 'parent'> {\n children: {\n count: number;\n };\n files: {\n count: number;\n };\n parent?: FolderDefinition;\n}\n\nexport interface HeaderProps {\n breadcrumbs?: Array<CrumbDefinition> | null;\n canCreate: boolean;\n folder?: FolderDefinition | null;\n onToggleEditFolderDialog: (args?: { created?: boolean }) => void;\n onToggleUploadAssetDialog: () => void;\n}\n\nexport const Header = ({\n breadcrumbs = null,\n canCreate,\n folder = null,\n onToggleEditFolderDialog,\n onToggleUploadAssetDialog,\n}: HeaderProps) => {\n const { formatMessage } = useIntl();\n const { pathname } = useLocation();\n const [{ query }] = useQueryParams();\n const backQuery = {\n ...query,\n folder:\n folder?.parent && typeof folder.parent !== 'number' && folder.parent.id\n ? folder.parent.id\n : undefined,\n folderPath:\n folder?.parent && typeof folder.parent !== 'number' && folder.parent.path\n ? folder.parent.path\n : undefined,\n };\n\n return (\n <Layouts.Header\n title={formatMessage({\n id: getTrad('plugin.name'),\n defaultMessage: `Media Library`,\n })}\n subtitle={\n breadcrumbs &&\n typeof breadcrumbs !== 'boolean' &&\n folder && (\n <Breadcrumbs\n label={formatMessage({\n id: getTrad('header.breadcrumbs.nav.label'),\n defaultMessage: 'Folders navigation',\n })}\n breadcrumbs={breadcrumbs}\n currentFolderId={folder?.id}\n />\n )\n }\n navigationAction={\n folder && (\n <Link\n tag={NavLink}\n startIcon={<ArrowLeft />}\n to={`${pathname}?${stringify(backQuery, { encode: false })}`}\n >\n {formatMessage({\n id: getTrad('header.actions.folder-level-up'),\n defaultMessage: 'Back',\n })}\n </Link>\n )\n }\n primaryAction={\n canCreate && (\n <Flex gap={2} width=\"100%\">\n <Button\n startIcon={<Plus />}\n variant=\"secondary\"\n onClick={onToggleEditFolderDialog}\n fullWidth\n >\n {formatMessage({\n id: getTrad('header.actions.add-folder'),\n defaultMessage: 'Add new folder',\n })}\n </Button>\n\n <Button startIcon={<Plus />} onClick={onToggleUploadAssetDialog} fullWidth>\n {formatMessage({\n id: getTrad('header.actions.add-assets'),\n defaultMessage: 'Add new assets',\n })}\n </Button>\n </Flex>\n )\n }\n />\n );\n};\n"],"names":["Header","breadcrumbs","canCreate","folder","onToggleEditFolderDialog","onToggleUploadAssetDialog","formatMessage","useIntl","pathname","useLocation","query","useQueryParams","backQuery","parent","id","undefined","folderPath","path","_jsx","Layouts","title","getTrad","defaultMessage","subtitle","Breadcrumbs","label","currentFolderId","navigationAction","Link","tag","NavLink","startIcon","ArrowLeft","to","stringify","encode","primaryAction","_jsxs","Flex","gap","width","Button","Plus","variant","onClick","fullWidth"],"mappings":";;;;;;;;;;;;;AA+BO,MAAMA,MAAAA,GAAS,CAAC,EACrBC,cAAc,IAAI,EAClBC,SAAS,EACTC,SAAS,IAAI,EACbC,wBAAwB,EACxBC,yBAAyB,EACb,GAAA;IACZ,MAAM,EAAEC,aAAa,EAAE,GAAGC,OAAAA,EAAAA;IAC1B,MAAM,EAAEC,QAAQ,EAAE,GAAGC,WAAAA,EAAAA;AACrB,IAAA,MAAM,CAAC,EAAEC,KAAK,EAAE,CAAC,GAAGC,cAAAA,EAAAA;AACpB,IAAA,MAAMC,SAAAA,GAAY;AAChB,QAAA,
|
|
1
|
+
{"version":3,"file":"Header.mjs","sources":["../../../../../admin/src/pages/App/components/Header.tsx"],"sourcesContent":["import { deepEncodeQueryValues, useQueryParams, Layouts } from '@strapi/admin/strapi-admin';\nimport { Button, Flex, Link } from '@strapi/design-system';\nimport { ArrowLeft, Plus } from '@strapi/icons';\nimport { stringify } from 'qs';\nimport { useIntl } from 'react-intl';\nimport { useLocation, NavLink } from 'react-router-dom';\n\nimport { Breadcrumbs } from '../../../components/Breadcrumbs/Breadcrumbs';\nimport { getTrad } from '../../../utils';\n\nimport type { Folder } from '../../../../../shared/contracts/folders';\nimport type { CrumbDefinition } from '../../../components/Breadcrumbs/Breadcrumbs';\n\ninterface FolderDefinition extends Omit<Folder, 'children' | 'files' | 'parent'> {\n children: {\n count: number;\n };\n files: {\n count: number;\n };\n parent?: FolderDefinition;\n}\n\nexport interface HeaderProps {\n breadcrumbs?: Array<CrumbDefinition> | null;\n canCreate: boolean;\n folder?: FolderDefinition | null;\n onToggleEditFolderDialog: (args?: { created?: boolean }) => void;\n onToggleUploadAssetDialog: () => void;\n}\n\nexport const Header = ({\n breadcrumbs = null,\n canCreate,\n folder = null,\n onToggleEditFolderDialog,\n onToggleUploadAssetDialog,\n}: HeaderProps) => {\n const { formatMessage } = useIntl();\n const { pathname } = useLocation();\n const [{ query }] = useQueryParams();\n const backQuery = {\n ...deepEncodeQueryValues(query),\n folder:\n folder?.parent && typeof folder.parent !== 'number' && folder.parent.id\n ? folder.parent.id\n : undefined,\n folderPath:\n folder?.parent && typeof folder.parent !== 'number' && folder.parent.path\n ? folder.parent.path\n : undefined,\n };\n\n return (\n <Layouts.Header\n title={formatMessage({\n id: getTrad('plugin.name'),\n defaultMessage: `Media Library`,\n })}\n subtitle={\n breadcrumbs &&\n typeof breadcrumbs !== 'boolean' &&\n folder && (\n <Breadcrumbs\n label={formatMessage({\n id: getTrad('header.breadcrumbs.nav.label'),\n defaultMessage: 'Folders navigation',\n })}\n breadcrumbs={breadcrumbs}\n currentFolderId={folder?.id}\n />\n )\n }\n navigationAction={\n folder && (\n <Link\n tag={NavLink}\n startIcon={<ArrowLeft />}\n to={`${pathname}?${stringify(backQuery, { encode: false })}`}\n >\n {formatMessage({\n id: getTrad('header.actions.folder-level-up'),\n defaultMessage: 'Back',\n })}\n </Link>\n )\n }\n primaryAction={\n canCreate && (\n <Flex gap={2} width=\"100%\">\n <Button\n startIcon={<Plus />}\n variant=\"secondary\"\n onClick={onToggleEditFolderDialog}\n fullWidth\n >\n {formatMessage({\n id: getTrad('header.actions.add-folder'),\n defaultMessage: 'Add new folder',\n })}\n </Button>\n\n <Button startIcon={<Plus />} onClick={onToggleUploadAssetDialog} fullWidth>\n {formatMessage({\n id: getTrad('header.actions.add-assets'),\n defaultMessage: 'Add new assets',\n })}\n </Button>\n </Flex>\n )\n }\n />\n );\n};\n"],"names":["Header","breadcrumbs","canCreate","folder","onToggleEditFolderDialog","onToggleUploadAssetDialog","formatMessage","useIntl","pathname","useLocation","query","useQueryParams","backQuery","deepEncodeQueryValues","parent","id","undefined","folderPath","path","_jsx","Layouts","title","getTrad","defaultMessage","subtitle","Breadcrumbs","label","currentFolderId","navigationAction","Link","tag","NavLink","startIcon","ArrowLeft","to","stringify","encode","primaryAction","_jsxs","Flex","gap","width","Button","Plus","variant","onClick","fullWidth"],"mappings":";;;;;;;;;;;;;AA+BO,MAAMA,MAAAA,GAAS,CAAC,EACrBC,cAAc,IAAI,EAClBC,SAAS,EACTC,SAAS,IAAI,EACbC,wBAAwB,EACxBC,yBAAyB,EACb,GAAA;IACZ,MAAM,EAAEC,aAAa,EAAE,GAAGC,OAAAA,EAAAA;IAC1B,MAAM,EAAEC,QAAQ,EAAE,GAAGC,WAAAA,EAAAA;AACrB,IAAA,MAAM,CAAC,EAAEC,KAAK,EAAE,CAAC,GAAGC,cAAAA,EAAAA;AACpB,IAAA,MAAMC,SAAAA,GAAY;AAChB,QAAA,GAAGC,sBAAsBH,KAAAA,CAAM;AAC/BP,QAAAA,MAAAA,EACEA,QAAQW,MAAAA,IAAU,OAAOX,MAAAA,CAAOW,MAAM,KAAK,QAAA,IAAYX,MAAAA,CAAOW,MAAM,CAACC,EAAE,GACnEZ,MAAAA,CAAOW,MAAM,CAACC,EAAE,GAChBC,SAAAA;AACNC,QAAAA,UAAAA,EACEd,QAAQW,MAAAA,IAAU,OAAOX,MAAAA,CAAOW,MAAM,KAAK,QAAA,IAAYX,MAAAA,CAAOW,MAAM,CAACI,IAAI,GACrEf,MAAAA,CAAOW,MAAM,CAACI,IAAI,GAClBF;AACR,KAAA;IAEA,qBACEG,GAAA,CAACC,QAAQpB,MAAM,EAAA;AACbqB,QAAAA,KAAAA,EAAOf,aAAAA,CAAc;AACnBS,YAAAA,EAAAA,EAAIO,OAAAA,CAAQ,aAAA,CAAA;YACZC,cAAAA,EAAgB,CAAC,aAAa;AAChC,SAAA,CAAA;AACAC,QAAAA,QAAAA,EACEvB,WAAAA,IACA,OAAOA,WAAAA,KAAgB,SAAA,IACvBE,wBACEgB,GAAA,CAACM,WAAAA,EAAAA;AACCC,YAAAA,KAAAA,EAAOpB,aAAAA,CAAc;AACnBS,gBAAAA,EAAAA,EAAIO,OAAAA,CAAQ,8BAAA,CAAA;gBACZC,cAAAA,EAAgB;AAClB,aAAA,CAAA;YACAtB,WAAAA,EAAaA,WAAAA;AACb0B,YAAAA,eAAAA,EAAiBxB,MAAAA,EAAQY;;AAI/Ba,QAAAA,gBAAAA,EACEzB,wBACEgB,GAAA,CAACU,IAAAA,EAAAA;YACCC,GAAAA,EAAKC,OAAAA;AACLC,YAAAA,SAAAA,gBAAWb,GAAA,CAACc,SAAAA,EAAAA,EAAAA,CAAAA;AACZC,YAAAA,EAAAA,EAAI,CAAA,EAAG1B,QAAAA,CAAS,CAAC,EAAE2B,UAAUvB,SAAAA,EAAW;gBAAEwB,MAAAA,EAAQ;aAAM,CAAA,CAAA,CAAI;sBAE3D9B,aAAAA,CAAc;AACbS,gBAAAA,EAAAA,EAAIO,OAAAA,CAAQ,gCAAA,CAAA;gBACZC,cAAAA,EAAgB;AAClB,aAAA;;AAINc,QAAAA,aAAAA,EACEnC,2BACEoC,IAAA,CAACC,IAAAA,EAAAA;YAAKC,GAAAA,EAAK,CAAA;YAAGC,KAAAA,EAAM,MAAA;;8BAClBtB,GAAA,CAACuB,MAAAA,EAAAA;AACCV,oBAAAA,SAAAA,gBAAWb,GAAA,CAACwB,IAAAA,EAAAA,EAAAA,CAAAA;oBACZC,OAAAA,EAAQ,WAAA;oBACRC,OAAAA,EAASzC,wBAAAA;oBACT0C,SAAS,EAAA,IAAA;8BAERxC,aAAAA,CAAc;AACbS,wBAAAA,EAAAA,EAAIO,OAAAA,CAAQ,2BAAA,CAAA;wBACZC,cAAAA,EAAgB;AAClB,qBAAA;;8BAGFJ,GAAA,CAACuB,MAAAA,EAAAA;AAAOV,oBAAAA,SAAAA,gBAAWb,GAAA,CAACwB,IAAAA,EAAAA,EAAAA,CAAAA;oBAASE,OAAAA,EAASxC,yBAAAA;oBAA2ByC,SAAS,EAAA,IAAA;8BACvExC,aAAAA,CAAc;AACbS,wBAAAA,EAAAA,EAAIO,OAAAA,CAAQ,2BAAA,CAAA;wBACZC,cAAAA,EAAgB;AAClB,qBAAA;;;;;AAOd;;;;"}
|
|
@@ -3,12 +3,22 @@ import * as Dialog from '@radix-ui/react-dialog';
|
|
|
3
3
|
import { FlexProps } from '@strapi/design-system';
|
|
4
4
|
/** Duration of the close animation in ms. Use for timing cleanup (e.g. removing URL params). */
|
|
5
5
|
export declare const DRAWER_CLOSE_ANIMATION_MS = 300;
|
|
6
|
+
type PointerDownOutsideHandler = NonNullable<Dialog.DialogContentProps['onPointerDownOutside']>;
|
|
6
7
|
interface DrawerBodyProps extends Omit<FlexProps, 'width' | 'maxHeight'> {
|
|
7
8
|
animationDirection?: 'up' | 'left';
|
|
8
9
|
/** Width of the panel from the medium breakpoint up. Mobile is always full-bleed. */
|
|
9
10
|
width?: string;
|
|
10
11
|
/** Cap on the panel height. Defaults to the dynamic viewport height. */
|
|
11
12
|
maxHeight?: string;
|
|
13
|
+
/**
|
|
14
|
+
* Opt in to dismiss-on-outside-click. Omitted, an outside pointer press never
|
|
15
|
+
* closes the drawer — it must be closed explicitly, as long-running panels
|
|
16
|
+
* like the upload progress dialog need. Passed, the handler can still veto
|
|
17
|
+
* individual presses via `event.preventDefault()`. Content rendered from
|
|
18
|
+
* inside the panel but portaled elsewhere (DS dialogs, popovers, tooltips)
|
|
19
|
+
* never counts as outside — Radix reads the React tree, not the DOM.
|
|
20
|
+
*/
|
|
21
|
+
onPointerDownOutside?: PointerDownOutsideHandler;
|
|
12
22
|
children: React.ReactNode;
|
|
13
23
|
}
|
|
14
24
|
interface DrawerRootProps {
|
|
@@ -1,9 +1,12 @@
|
|
|
1
|
+
import { type ItemKey } from '../utils/selection';
|
|
1
2
|
import type { File } from '../../../../../../shared/contracts/files';
|
|
2
3
|
import type { Folder } from '../../../../../../shared/contracts/folders';
|
|
3
4
|
interface AssetsGridProps {
|
|
4
5
|
assets: File[];
|
|
5
6
|
folders?: Folder[];
|
|
7
|
+
/** Keys of the rendered items, in render order. Owned by the view. */
|
|
8
|
+
renderedKeys?: ItemKey[];
|
|
6
9
|
onAssetItemClick: (assetId: number) => void;
|
|
7
10
|
}
|
|
8
|
-
export declare const AssetsGrid: ({ assets, folders, onAssetItemClick }: AssetsGridProps) => import("react/jsx-runtime").JSX.Element | null;
|
|
11
|
+
export declare const AssetsGrid: ({ assets, folders, renderedKeys, onAssetItemClick, }: AssetsGridProps) => import("react/jsx-runtime").JSX.Element | null;
|
|
9
12
|
export {};
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { type MixedItem } from '../utils/mergeMixedList';
|
|
2
|
+
import { type ItemKey } from '../utils/selection';
|
|
2
3
|
import type { File } from '../../../../../../shared/contracts/files';
|
|
3
4
|
import type { Folder } from '../../../../../../shared/contracts/folders';
|
|
4
5
|
interface AssetsTableProps {
|
|
@@ -9,7 +10,9 @@ interface AssetsTableProps {
|
|
|
9
10
|
* order instead of folders-first. Range selection follows the same order.
|
|
10
11
|
*/
|
|
11
12
|
mixedItems?: MixedItem[] | null;
|
|
13
|
+
/** Keys of the rendered rows, in render order. Owned by the view. */
|
|
14
|
+
renderedKeys?: ItemKey[];
|
|
12
15
|
onAssetItemClick: (assetId: number) => void;
|
|
13
16
|
}
|
|
14
|
-
export declare const AssetsTable: ({ assets, folders, mixedItems, onAssetItemClick, }: AssetsTableProps) => import("react/jsx-runtime").JSX.Element | null;
|
|
17
|
+
export declare const AssetsTable: ({ assets, folders, mixedItems, renderedKeys, onAssetItemClick, }: AssetsTableProps) => import("react/jsx-runtime").JSX.Element | null;
|
|
15
18
|
export {};
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { type ItemLocations } from '../../../utils/itemLocations';
|
|
2
|
+
import { type ItemKey } from '../utils/selection';
|
|
2
3
|
import type { File } from '../../../../../../shared/contracts/files';
|
|
3
4
|
interface BulkActionsBarProps {
|
|
4
5
|
/**
|
|
@@ -16,6 +17,12 @@ interface BulkActionsBarProps {
|
|
|
16
17
|
* everything, which falls back to the folder currently open.
|
|
17
18
|
*/
|
|
18
19
|
locations?: ItemLocations;
|
|
20
|
+
/**
|
|
21
|
+
* Keys of the items on screen, in render order. Owned by the view so
|
|
22
|
+
* select-all covers exactly what the user can see — in mixed mode that is not
|
|
23
|
+
* every folder.
|
|
24
|
+
*/
|
|
25
|
+
renderedKeys?: ItemKey[];
|
|
19
26
|
}
|
|
20
|
-
export declare const BulkActionsBar: ({ assets, locations, }: BulkActionsBarProps) => import("react/jsx-runtime").JSX.Element | null;
|
|
27
|
+
export declare const BulkActionsBar: ({ assets, locations, renderedKeys, }: BulkActionsBarProps) => import("react/jsx-runtime").JSX.Element | null;
|
|
21
28
|
export {};
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
interface MainAreaContextMenuProps {
|
|
2
|
+
/** Opens the "new folder" dialog in the folder currently on screen. */
|
|
3
|
+
onCreateFolder: () => void;
|
|
4
|
+
/** Opens the native file picker — same entry point as the header "New" menu. */
|
|
5
|
+
onImportFiles: () => void;
|
|
6
|
+
/** Opens the "import from URL" dialog. */
|
|
7
|
+
onImportFromUrl: () => void;
|
|
8
|
+
/**
|
|
9
|
+
* RBAC gate — without `assets.create` there is nothing to offer, so the
|
|
10
|
+
* right-click falls through to the browser. Required (not defaulted) so a
|
|
11
|
+
* permission gate can't silently regress to permissive.
|
|
12
|
+
*/
|
|
13
|
+
disabled: boolean;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Drive/Dropbox-style right-click on the empty parts of the assets area: the
|
|
17
|
+
* same creation actions the header "New" menu offers, acting on the folder
|
|
18
|
+
* currently open.
|
|
19
|
+
*
|
|
20
|
+
* Renders no wrapper — it finds the scrolling column and listens there, so the
|
|
21
|
+
* hit area is the whole column including the padding below the list.
|
|
22
|
+
*
|
|
23
|
+
* Deliberately background-only. Right-clicking an asset, a folder or a table
|
|
24
|
+
* row is left alone — those carry `data-native-context-menu` and keep the
|
|
25
|
+
* browser's menu (which is what you want over a thumbnail or a filename).
|
|
26
|
+
*/
|
|
27
|
+
export declare const MainAreaContextMenu: ({ onCreateFolder, onImportFiles, onImportFromUrl, disabled, }: MainAreaContextMenuProps) => import("react/jsx-runtime").JSX.Element;
|
|
28
|
+
export {};
|
|
@@ -5,6 +5,26 @@ export declare const viewOptions: {
|
|
|
5
5
|
GRID: number;
|
|
6
6
|
TABLE: number;
|
|
7
7
|
};
|
|
8
|
+
/**
|
|
9
|
+
* Spread onto grid cards and table rows, whose click opens or switches the
|
|
10
|
+
* asset details drawer. The drawer's outside-click dismissal skips presses
|
|
11
|
+
* landing on one of these, so switching assets doesn't close-then-reopen it.
|
|
12
|
+
*/
|
|
13
|
+
export declare const ASSET_DETAILS_TRIGGER_PROPS: {
|
|
14
|
+
"data-asset-details-trigger": string;
|
|
15
|
+
};
|
|
16
|
+
/**
|
|
17
|
+
* Spread onto the controls inside an asset card or row that act on the item
|
|
18
|
+
* rather than opening it — its selection checkbox and its actions menu. They
|
|
19
|
+
* stop the card's own click, so no details switch follows them.
|
|
20
|
+
*/
|
|
21
|
+
export declare const ASSET_ITEM_CONTROL_PROPS: {
|
|
22
|
+
"data-asset-item-control": string;
|
|
23
|
+
};
|
|
24
|
+
/** Matches an element carrying {@link ASSET_ITEM_CONTROL_PROPS}. */
|
|
25
|
+
export declare const ASSET_ITEM_CONTROL_SELECTOR = "[data-asset-item-control]";
|
|
26
|
+
/** Matches an element carrying {@link ASSET_DETAILS_TRIGGER_PROPS}. */
|
|
27
|
+
export declare const ASSET_DETAILS_TRIGGER_SELECTOR = "[data-asset-details-trigger]";
|
|
8
28
|
interface TableHeader {
|
|
9
29
|
name: string;
|
|
10
30
|
label: {
|
|
@@ -15,6 +15,10 @@ interface UseInfiniteAssetsOptions {
|
|
|
15
15
|
* The caller MUST render the returned `subscribers` node — that is what keeps
|
|
16
16
|
* every loaded page subscribed, so `{Asset, LIST}` invalidations keep the whole
|
|
17
17
|
* list consistent rather than only the current page.
|
|
18
|
+
*
|
|
19
|
+
* Loaded pages survive navigating away and back: each list's accumulator is
|
|
20
|
+
* remembered (LRU, `MAX_REMEMBERED_LISTS`) and restored when its key returns, so
|
|
21
|
+
* stepping into a subfolder and back out keeps the rows the user scrolled for.
|
|
18
22
|
*/
|
|
19
23
|
declare const useInfiniteAssets: ({ folder, sort, search, filters, enabled, }?: UseInfiniteAssetsOptions) => {
|
|
20
24
|
assets: File[];
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Remembers where each list was scrolled to and puts it back on return.
|
|
3
|
+
*
|
|
4
|
+
* `key` fingerprints the list on screen (folder, search, sort, filters). While
|
|
5
|
+
* it holds steady the current offset is recorded; when it changes the incoming
|
|
6
|
+
* key's saved offset is restored, or the list is sent to the top if it has none
|
|
7
|
+
* — a first visit, or one whose entry has been dropped.
|
|
8
|
+
*
|
|
9
|
+
* Returns a callback ref to place on any element inside the scrolling column;
|
|
10
|
+
* it only locates that column, it is never scrolled itself.
|
|
11
|
+
*
|
|
12
|
+
* Restoring a *position* only helps if the rows that filled it come back too —
|
|
13
|
+
* that is `useInfiniteAssets`' job.
|
|
14
|
+
*/
|
|
15
|
+
export declare const useListScrollRestoration: (key: string) => (node: HTMLElement | null) => void;
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Merges just-uploaded assets into the loaded asset list so each one appears as
|
|
3
|
+
* soon as its own upload finishes, rather than when the whole batch settles.
|
|
4
|
+
*
|
|
5
|
+
* The upload is one mutation per batch, so its cache invalidation fires once at
|
|
6
|
+
* the end. These helpers bridge that gap purely client-side: the completed
|
|
7
|
+
* uploads already sit in the progress store as full `File` objects, so they can
|
|
8
|
+
* be placed into the list at their sort position with no extra request.
|
|
9
|
+
*
|
|
10
|
+
* The server list stays authoritative — merging never reorders it, and an id it
|
|
11
|
+
* already contains wins over the local copy, so the end-of-batch refetch
|
|
12
|
+
* silently takes over.
|
|
13
|
+
*/
|
|
14
|
+
import type { File } from '../../../../../../shared/contracts/files';
|
|
15
|
+
/**
|
|
16
|
+
* Comparator matching a `<field>:<ASC|DESC>` sort rule, as sent to the API.
|
|
17
|
+
*
|
|
18
|
+
* Ties break on id so the order is total: without it, two files sharing a
|
|
19
|
+
* timestamp could swap places between renders.
|
|
20
|
+
*/
|
|
21
|
+
export declare const getAssetComparator: (rule?: string) => (a: File, b: File) => number;
|
|
22
|
+
/**
|
|
23
|
+
* Places `uploaded` into `assets` at their sort position.
|
|
24
|
+
*
|
|
25
|
+
* An upload that sorts past everything loaded is dropped unless the list is
|
|
26
|
+
* fully loaded: it belongs on a page the user has not reached, and appending it
|
|
27
|
+
* would show it adjacent to the last loaded item instead of at its real place.
|
|
28
|
+
*/
|
|
29
|
+
export declare const mergeUploadedAssets: ({ assets, uploaded, sort, hasNextPage, }: {
|
|
30
|
+
assets: File[];
|
|
31
|
+
uploaded: File[];
|
|
32
|
+
sort?: string;
|
|
33
|
+
/** Whether more pages remain, i.e. the tail of the list is not loaded. */
|
|
34
|
+
hasNextPage: boolean;
|
|
35
|
+
}) => File[];
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { type ItemKey } from './selection';
|
|
2
|
+
import type { MixedItem } from './mergeMixedList';
|
|
3
|
+
import type { File } from '../../../../../../shared/contracts/files';
|
|
4
|
+
import type { Folder } from '../../../../../../shared/contracts/folders';
|
|
5
|
+
/**
|
|
6
|
+
* The keys of the items actually on screen, in render order.
|
|
7
|
+
*
|
|
8
|
+
* Single source for every consumer of the rendered set — range selection,
|
|
9
|
+
* select-all and the bulk action bar. Derived once so they cannot disagree:
|
|
10
|
+
* in "Folders: Mixed with files" the rows come from `mergeMixedList`, which
|
|
11
|
+
* withholds folders sorting after the last loaded asset, so `folders` is not
|
|
12
|
+
* the rendered folder set.
|
|
13
|
+
*/
|
|
14
|
+
export declare const buildRenderedKeys: ({ folders, assets, mixedItems, }: {
|
|
15
|
+
folders: Folder[];
|
|
16
|
+
assets: File[];
|
|
17
|
+
/** The interleaved rows, when the table is in mixed mode. */
|
|
18
|
+
mixedItems?: MixedItem[] | null;
|
|
19
|
+
}) => ItemKey[];
|
|
@@ -19,6 +19,8 @@ export interface FileProgress {
|
|
|
19
19
|
size: number;
|
|
20
20
|
uploadedBytes: number;
|
|
21
21
|
file?: File;
|
|
22
|
+
/** When the server confirmed the upload. Set with the row's asset. */
|
|
23
|
+
completedAt?: number;
|
|
22
24
|
error?: string;
|
|
23
25
|
metadataStatus?: FileMetadataStatus;
|
|
24
26
|
}
|
|
@@ -29,10 +31,26 @@ export interface UploadProgressState {
|
|
|
29
31
|
files: FileProgress[];
|
|
30
32
|
errors: FileUploadError[];
|
|
31
33
|
uploadId: number;
|
|
34
|
+
/**
|
|
35
|
+
* Whether this batch reports transferred bytes at all. The direct-file flow streams
|
|
36
|
+
* byte counts from XHR; the URL flow leaves the fetch to the server and gets none back
|
|
37
|
+
* so its byte-weighted aggregate is stuck at 0%.
|
|
38
|
+
*/
|
|
39
|
+
reportsByteProgress: boolean;
|
|
32
40
|
}
|
|
33
41
|
export interface RootState {
|
|
34
42
|
uploadProgress: UploadProgressState;
|
|
35
43
|
}
|
|
44
|
+
/** An uploaded asset, with the moment the server confirmed it. */
|
|
45
|
+
export interface CompletedUpload {
|
|
46
|
+
asset: File;
|
|
47
|
+
completedAt: number;
|
|
48
|
+
}
|
|
49
|
+
export declare const selectCompletedUploads: ((state: Partial<RootState>) => CompletedUpload[]) & import("reselect").OutputSelectorFields<(args_0: FileProgress[]) => CompletedUpload[], {
|
|
50
|
+
clearCache: () => void;
|
|
51
|
+
}> & {
|
|
52
|
+
clearCache: () => void;
|
|
53
|
+
};
|
|
36
54
|
/**
|
|
37
55
|
* Byte-weighted aggregate progress across the whole batch: `sum(uploadedBytes) / sum(size)`.
|
|
38
56
|
*
|
|
@@ -44,6 +62,38 @@ export declare const selectAggregateProgress: ((state: RootState) => number) & i
|
|
|
44
62
|
}> & {
|
|
45
63
|
clearCache: () => void;
|
|
46
64
|
};
|
|
65
|
+
/**
|
|
66
|
+
* Whether to show byte-weighted `selectAggregateProgress` rather than count-based progress.
|
|
67
|
+
* A batch that never reports bytes stays pinned at 0%, so the header falls back to
|
|
68
|
+
* `selectCountBasedProgress`.
|
|
69
|
+
*
|
|
70
|
+
* Checks the rows too, not just the flag: an in-flight row reporting bytes proves the batch
|
|
71
|
+
* can, so byte-weighting takes over once the URL flow starts emitting progress. Only
|
|
72
|
+
* `uploading` rows count — completion backfills `uploadedBytes` to the file size, so letting
|
|
73
|
+
* settled rows qualify would switch a multi-URL batch to byte-weighting mid-upload over only
|
|
74
|
+
* the sizes known so far (transiently 100% after the first file).
|
|
75
|
+
*/
|
|
76
|
+
export declare const selectReportsByteProgress: ((state: RootState) => boolean) & import("reselect").OutputSelectorFields<(args_0: boolean, args_1: FileProgress[]) => boolean, {
|
|
77
|
+
clearCache: () => void;
|
|
78
|
+
}> & {
|
|
79
|
+
clearCache: () => void;
|
|
80
|
+
};
|
|
81
|
+
/**
|
|
82
|
+
* Count-based progress (settled / total rows) for a batch that reports no transferred bytes
|
|
83
|
+
* (the URL flow). Used by the header whenever `selectReportsByteProgress` is false.
|
|
84
|
+
*
|
|
85
|
+
* Never byte-weights, so a multi-URL batch climbs 33 → 67 → 100 as each file lands instead
|
|
86
|
+
* of jumping to a transient 100% after the first.
|
|
87
|
+
*
|
|
88
|
+
* Returns `null` until a row settles — 0% is the frozen signal this flow exists to remove
|
|
89
|
+
* (a lone URL upload would otherwise read "Uploading 1 item (0%)" throughout), so the header
|
|
90
|
+
* stays indeterminate until there's real progress.
|
|
91
|
+
*/
|
|
92
|
+
export declare const selectCountBasedProgress: ((state: RootState) => number | null) & import("reselect").OutputSelectorFields<(args_0: FileProgress[]) => number | null, {
|
|
93
|
+
clearCache: () => void;
|
|
94
|
+
}> & {
|
|
95
|
+
clearCache: () => void;
|
|
96
|
+
};
|
|
47
97
|
/**
|
|
48
98
|
* Count-based metadata progress across the whole batch: `settled / expected`.
|
|
49
99
|
*
|
|
@@ -131,6 +181,7 @@ export declare const openUploadProgress: import("@reduxjs/toolkit").ActionCreato
|
|
|
131
181
|
index: number;
|
|
132
182
|
file: File;
|
|
133
183
|
uploadId: number;
|
|
184
|
+
completedAt: number;
|
|
134
185
|
}, "uploadProgress/setFileComplete">, setFileError: import("@reduxjs/toolkit").ActionCreatorWithPayload<{
|
|
135
186
|
index: number;
|
|
136
187
|
name: string;
|
|
@@ -19,6 +19,7 @@ export * from './normalizeAPIError';
|
|
|
19
19
|
export * from './prefixFileUrlWithBackendUrl';
|
|
20
20
|
export * from './prefixPluginTranslations';
|
|
21
21
|
export * from './rawFileToAsset';
|
|
22
|
+
export * from './resolveFileMime';
|
|
22
23
|
export * from './toSingularTypes';
|
|
23
24
|
export * from './typeFromMime';
|
|
24
25
|
export * from './urlsToAssets';
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { AssetSource } from '../constants';
|
|
2
2
|
import type { RawFile } from '../../../shared/contracts/files';
|
|
3
|
-
export declare const rawFileToAsset: (rawFile: RawFile, assetSource: AssetSource) => {
|
|
3
|
+
export declare const rawFileToAsset: (rawFile: RawFile, assetSource: AssetSource) => Promise<{
|
|
4
4
|
size: number;
|
|
5
5
|
createdAt: string;
|
|
6
6
|
name: string;
|
|
@@ -11,4 +11,4 @@ export declare const rawFileToAsset: (rawFile: RawFile, assetSource: AssetSource
|
|
|
11
11
|
mime: string;
|
|
12
12
|
rawFile: RawFile;
|
|
13
13
|
isLocal: boolean;
|
|
14
|
-
}
|
|
14
|
+
}>;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export declare const normalizeDeclaredMime: (mime?: string | null) => string;
|
|
2
|
+
export declare const isGenericMime: (mime?: string | null) => boolean;
|
|
3
|
+
/**
|
|
4
|
+
* Detect MIME from file bytes with file-type.
|
|
5
|
+
* The admin normalizes declared MIME values more permissively; server validation remains authoritative.
|
|
6
|
+
* Returns undefined when the blob cannot be read or the type is unknown.
|
|
7
|
+
*/
|
|
8
|
+
export declare const detectMimeFromBlob: (blob: Blob) => Promise<string | undefined>;
|
|
9
|
+
/**
|
|
10
|
+
* When the browser MIME is missing or generic, sniff the file contents.
|
|
11
|
+
* If there is no blob (library assets) or detection fails, keep the declared type.
|
|
12
|
+
*/
|
|
13
|
+
export declare const resolveFileMime: (mime?: string | null, blob?: Blob | null) => Promise<string>;
|
|
@@ -76,7 +76,8 @@ var en = {
|
|
|
76
76
|
"upload.progress.success": "Upload successful!",
|
|
77
77
|
"upload.progress.success.subtitle": "{count, plural, one {# file uploaded successfully} other {# files uploaded successfully}}",
|
|
78
78
|
"upload.progress.success.subtitle.withErrors": "{successCount} uploaded, {errorCount} failed",
|
|
79
|
-
"upload.progress.uploading.withCount": "Uploading {total} items ({percentage}%)",
|
|
79
|
+
"upload.progress.uploading.withCount": "Uploading {total, plural, one {# item} other {# items}} ({percentage}%)",
|
|
80
|
+
"upload.progress.uploading.indeterminate": "Uploading {total, plural, one {# item} other {# items}}",
|
|
80
81
|
"upload.progress.uploading-files": "Uploading {count, plural, one {# file} other {# files}}",
|
|
81
82
|
"upload.progress.indicator.in-progress": "Upload in progress indicator",
|
|
82
83
|
"upload.progress.indicator.complete": "Upload complete indicator",
|
|
@@ -340,8 +341,10 @@ var en = {
|
|
|
340
341
|
"list.table.row.select": "Select {name}",
|
|
341
342
|
"list.table.row.metadata-missing": "This asset is missing metadata (caption or alternative text).",
|
|
342
343
|
"list.table.content.empty-label": "This field is empty",
|
|
344
|
+
"list.context-menu.label": "Media library actions",
|
|
343
345
|
"list.bulk-actions.label": "Bulk actions",
|
|
344
346
|
"list.bulk-actions.selected-count": "{count, plural, =1 {# item selected} other {# items selected}}",
|
|
347
|
+
"list.bulk-actions.select-all": "Select all",
|
|
345
348
|
"list.bulk-actions.clear": "Clear selection",
|
|
346
349
|
"list.bulk-actions.create-metadata": "Create metadata",
|
|
347
350
|
"list.bulk-actions.create-metadata.success": "{count, plural, =1 {Metadata generated for # asset} other {Metadata generated for # assets}}",
|
|
@@ -387,6 +390,7 @@ var en = {
|
|
|
387
390
|
"sidebar.folders": "Folders",
|
|
388
391
|
"sidebar.tree.aria-label": "Media library folders",
|
|
389
392
|
"sidebar.tree.expand": "Expand {name}",
|
|
393
|
+
"sidebar.tree.no-subfolders": "The folder {name} has no subfolders",
|
|
390
394
|
"sidebar.tree.collapse": "Collapse {name}",
|
|
391
395
|
"sidebar.tree.empty": "No folders yet",
|
|
392
396
|
"sidebar.tree.loading": "Loading folders...",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"en.json.js","sources":[],"sourcesContent":[],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"en.json.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
|