@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
|
@@ -121,18 +121,32 @@ const CollapsibleContent = styled(Box)`
|
|
|
121
121
|
overflow: hidden;
|
|
122
122
|
min-height: 0;
|
|
123
123
|
}
|
|
124
|
+
|
|
125
|
+
/* The scroll area wraps its children in a div styled inline as
|
|
126
|
+
display: table, min-width: 100%. A table box grows to its content, so a
|
|
127
|
+
single unbreakable string (a long file name) widens it past the scrollport
|
|
128
|
+
and the panel gains a horizontal scrollbar — with nothing left to clamp the
|
|
129
|
+
row, the name never truncates. Overriding to a block box makes the
|
|
130
|
+
scrollport the width again, which is what the vertical-only list wants.
|
|
131
|
+
Inline styles, hence the important. */
|
|
132
|
+
[data-radix-scroll-area-viewport] > div {
|
|
133
|
+
display: block !important;
|
|
134
|
+
}
|
|
124
135
|
`;
|
|
125
136
|
const CloseIconButton = styled(IconButton)`
|
|
126
137
|
&:hover {
|
|
127
138
|
background: transparent;
|
|
128
139
|
}
|
|
129
140
|
`;
|
|
130
|
-
|
|
141
|
+
/** Vetoes an outside interaction that would otherwise dismiss the drawer. */ const keepOpen = (event)=>event.preventDefault();
|
|
142
|
+
const DrawerBody = /*#__PURE__*/ React.forwardRef(({ animationDirection, width, maxHeight, onPointerDownOutside = keepOpen, children, ...props }, ref)=>/*#__PURE__*/ jsx(Dialog.Content, {
|
|
131
143
|
ref: ref,
|
|
132
144
|
forceMount: true,
|
|
133
145
|
asChild: true,
|
|
134
|
-
onPointerDownOutside:
|
|
135
|
-
|
|
146
|
+
onPointerDownOutside: onPointerDownOutside,
|
|
147
|
+
// Non-modal, so focus legitimately moves outside (tabbing past the last
|
|
148
|
+
// field); only a pointer press should ever dismiss.
|
|
149
|
+
onFocusOutside: keepOpen,
|
|
136
150
|
"data-animation-direction": animationDirection,
|
|
137
151
|
children: /*#__PURE__*/ jsx(DrawerContainer, {
|
|
138
152
|
$animationDirection: animationDirection,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Drawer.mjs","sources":["../../../../admin/src/future/components/Drawer.tsx"],"sourcesContent":["import * as React from 'react';\n\nimport * as Dialog from '@radix-ui/react-dialog';\nimport { Box, ScrollArea, IconButton, Flex, FlexProps } from '@strapi/design-system';\nimport { Cross } from '@strapi/icons';\nimport { useIntl } from 'react-intl';\nimport { keyframes, styled } from 'styled-components';\n\n/** Duration of the close animation in ms. Use for timing cleanup (e.g. removing URL params). */\nexport const DRAWER_CLOSE_ANIMATION_MS = 300;\n\n/* -------------------------------------------------------------------------------------------------\n * Animations\n * -----------------------------------------------------------------------------------------------*/\n\n// Direction: up\nconst slideUpFromBottomIn = keyframes`\n from {\n opacity: 0;\n transform: translateY(100%);\n }\n to {\n opacity: 1;\n transform: translateY(0);\n }\n`;\n\nconst slideUpFromBottomOut = keyframes`\n from {\n opacity: 1;\n transform: translateY(0);\n }\n to {\n opacity: 0;\n transform: translateY(100%);\n }\n`;\n\n// Direction: left\nconst slideLeftFromRightIn = keyframes`\n from {\n opacity: 0;\n transform: translateX(100%);\n }\n to {\n opacity: 1;\n transform: translateX(0);\n }\n`;\n\nconst slideLeftFromRightOut = keyframes`\n from {\n opacity: 1;\n transform: translateX(0);\n }\n to {\n opacity: 0;\n transform: translateX(100%);\n }\n`;\n\n/* -------------------------------------------------------------------------------------------------\n * Styled components\n * -----------------------------------------------------------------------------------------------*/\n\ninterface DrawerContainerProps {\n $animationDirection?: DrawerBodyProps['animationDirection'];\n $width?: string;\n $maxHeight?: string;\n}\n\nconst DrawerContainer = styled(Flex)<DrawerContainerProps>`\n flex-direction: column;\n position: fixed;\n bottom: 0;\n /* Mobile: full-bleed sheet. Anchoring to the right at a fixed width left a\n dead gutter on every phone wider than the panel, and the panel only filled\n the screen once the viewport happened to be narrower than it. Below the\n medium breakpoint the panel is the screen; medium+ restores the\n right-anchored rail. */\n left: 0;\n right: 0;\n width: 100%;\n padding: ${({ theme }) => theme.spaces[2]};\n max-width: 100%;\n /* Sit just below the overlay token (300) so that:\n - popovers (500) and tooltips (1000) rendered from descendant components\n surface above the drawer panel,\n - AlertDialog overlays (300) and contents (310) opened from inside the\n drawer (e.g. the asset details \"delete\" confirm) cover the drawer. */\n z-index: 200;\n overflow: hidden;\n /* dvh, not vh: anchored to the bottom, a 100vh cap on mobile (visual\n viewport < 100vh under the URL bar) would push the drawer top off-screen. */\n max-height: ${({ $maxHeight }) => $maxHeight ?? '100dvh'};\n\n ${({ theme }) => theme.breakpoints.medium} {\n left: auto;\n width: ${({ $width }) => $width ?? '400px'};\n }\n\n &:focus {\n outline: none;\n }\n\n @media (prefers-reduced-motion: no-preference) {\n &[data-state='open'] {\n animation: ${({ $animationDirection }) =>\n $animationDirection === 'up' ? slideUpFromBottomIn : slideLeftFromRightIn}\n ${DRAWER_CLOSE_ANIMATION_MS}ms cubic-bezier(0.32, 0.72, 0, 1) forwards;\n }\n\n &[data-state='closed'] {\n animation: ${({ $animationDirection }) =>\n $animationDirection === 'up' ? slideUpFromBottomOut : slideLeftFromRightOut}\n ${DRAWER_CLOSE_ANIMATION_MS}ms cubic-bezier(0.32, 0.72, 0, 1) forwards;\n pointer-events: none;\n }\n }\n`;\n\nconst DrawerContent = styled(Box)`\n display: flex;\n flex-direction: column;\n flex: 1;\n min-height: 0;\n width: 100%;\n background-color: ${({ theme }) => theme.colors.neutral0};\n border-radius: ${({ theme }) => theme.borderRadius};\n box-shadow: ${({ theme }) => theme.shadows.popupShadow};\n overflow: hidden;\n border: 1px solid ${({ theme }) => theme.colors.neutral150};\n`;\n\ninterface CollapsibleContentProps {\n $isVisible: boolean;\n}\n\nconst CollapsibleContent = styled(Box)<CollapsibleContentProps>`\n display: grid;\n flex: 1;\n min-height: 0;\n grid-template-rows: ${({ $isVisible }) => ($isVisible ? '1fr' : '0fr')};\n transition: grid-template-rows 0.3s ease-in-out;\n\n > div {\n overflow: hidden;\n min-height: 0;\n }\n`;\n\nconst CloseIconButton = styled(IconButton)`\n &:hover {\n background: transparent;\n }\n`;\n\n/* -------------------------------------------------------------------------------------------------\n * Drawer.Body\n * -----------------------------------------------------------------------------------------------*/\n\ninterface DrawerBodyProps extends Omit<FlexProps, 'width' | 'maxHeight'> {\n animationDirection?: 'up' | 'left';\n /** Width of the panel from the medium breakpoint up. Mobile is always full-bleed. */\n width?: string;\n /** Cap on the panel height. Defaults to the dynamic viewport height. */\n maxHeight?: string;\n children: React.ReactNode;\n}\n\nconst DrawerBody = React.forwardRef<HTMLDivElement, DrawerBodyProps>(\n ({ animationDirection, width, maxHeight, children, ...props }, ref) => (\n <Dialog.Content\n ref={ref}\n forceMount\n asChild\n onPointerDownOutside={(e) => e.preventDefault()}\n onInteractOutside={(e) => e.preventDefault()}\n data-animation-direction={animationDirection}\n >\n {/* width/maxHeight go through transient props so the DS Flex never emits a\n competing `width` rule that would outrank the mobile full-bleed one. */}\n <DrawerContainer\n $animationDirection={animationDirection}\n $width={width}\n $maxHeight={maxHeight}\n {...props}\n >\n <DrawerContent>{children}</DrawerContent>\n </DrawerContainer>\n </Dialog.Content>\n )\n);\nDrawerBody.displayName = 'DrawerBody';\n\n/* -------------------------------------------------------------------------------------------------\n * Drawer.Root\n * -----------------------------------------------------------------------------------------------*/\n\ninterface DrawerRootProps {\n isVisible?: boolean;\n onClose?: () => void;\n children: React.ReactNode;\n}\n\nconst DrawerRoot = ({ isVisible, onClose, children }: DrawerRootProps): React.ReactElement => (\n <Dialog.Root\n open={isVisible}\n onOpenChange={(nextVisible) => !nextVisible && onClose?.()}\n modal={false}\n >\n <Dialog.Portal>{children}</Dialog.Portal>\n </Dialog.Root>\n);\n\n/* -------------------------------------------------------------------------------------------------\n * Drawer.Content - composable content slot (collapsible when isContentExpanded is used)\n * Contains a scrollable area\n * -----------------------------------------------------------------------------------------------*/\n\ninterface DrawerScrollableContentProps {\n children: React.ReactNode;\n /** When provided, content can collapse/expand (e.g. for minimize). Omit to always show. */\n isContentExpanded?: boolean;\n}\n\nconst DrawerScrollableContent = ({\n children,\n isContentExpanded = true,\n}: DrawerScrollableContentProps) => (\n <CollapsibleContent $isVisible={isContentExpanded} data-collapsed={!isContentExpanded}>\n <ScrollArea>{children}</ScrollArea>\n </CollapsibleContent>\n);\n\n/* -------------------------------------------------------------------------------------------------\n * Drawer.CloseButton - composable close icon button (Cross icon by default)\n * -----------------------------------------------------------------------------------------------*/\n\ninterface DrawerCloseButtonProps extends React.PropsWithChildren {\n onClose: () => void;\n label?: string;\n}\n\nconst DrawerCloseButton = ({ onClose, label, children }: DrawerCloseButtonProps) => {\n const { formatMessage } = useIntl();\n const labelMessage = label ?? formatMessage({ id: 'global.close', defaultMessage: 'Close' });\n return (\n <CloseIconButton onClick={onClose} label={labelMessage} variant=\"ghost\">\n {children ?? <Cross />}\n </CloseIconButton>\n );\n};\n\nconst Drawer = {\n Root: DrawerRoot,\n Body: DrawerBody,\n ScrollableContent: DrawerScrollableContent,\n CloseButton: DrawerCloseButton,\n Title: Dialog.Title,\n Description: Dialog.Description,\n};\n\nexport { Drawer };\n"],"names":["DRAWER_CLOSE_ANIMATION_MS","slideUpFromBottomIn","keyframes","slideUpFromBottomOut","slideLeftFromRightIn","slideLeftFromRightOut","DrawerContainer","styled","Flex","theme","spaces","$maxHeight","breakpoints","medium","$width","$animationDirection","DrawerContent","Box","colors","neutral0","borderRadius","shadows","popupShadow","neutral150","CollapsibleContent","$isVisible","CloseIconButton","IconButton","DrawerBody","React","forwardRef","animationDirection","width","maxHeight","children","props","ref","_jsx","Dialog","Content","forceMount","asChild","onPointerDownOutside","e","preventDefault","onInteractOutside","data-animation-direction","displayName","DrawerRoot","isVisible","onClose","Root","open","onOpenChange","nextVisible","modal","Portal","DrawerScrollableContent","isContentExpanded","data-collapsed","ScrollArea","DrawerCloseButton","label","formatMessage","useIntl","labelMessage","id","defaultMessage","onClick","variant","Cross","Drawer","Body","ScrollableContent","CloseButton","Title","Description"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"Drawer.mjs","sources":["../../../../admin/src/future/components/Drawer.tsx"],"sourcesContent":["import * as React from 'react';\n\nimport * as Dialog from '@radix-ui/react-dialog';\nimport { Box, ScrollArea, IconButton, Flex, FlexProps } from '@strapi/design-system';\nimport { Cross } from '@strapi/icons';\nimport { useIntl } from 'react-intl';\nimport { keyframes, styled } from 'styled-components';\n\n/** Duration of the close animation in ms. Use for timing cleanup (e.g. removing URL params). */\nexport const DRAWER_CLOSE_ANIMATION_MS = 300;\n\n/* -------------------------------------------------------------------------------------------------\n * Animations\n * -----------------------------------------------------------------------------------------------*/\n\n// Direction: up\nconst slideUpFromBottomIn = keyframes`\n from {\n opacity: 0;\n transform: translateY(100%);\n }\n to {\n opacity: 1;\n transform: translateY(0);\n }\n`;\n\nconst slideUpFromBottomOut = keyframes`\n from {\n opacity: 1;\n transform: translateY(0);\n }\n to {\n opacity: 0;\n transform: translateY(100%);\n }\n`;\n\n// Direction: left\nconst slideLeftFromRightIn = keyframes`\n from {\n opacity: 0;\n transform: translateX(100%);\n }\n to {\n opacity: 1;\n transform: translateX(0);\n }\n`;\n\nconst slideLeftFromRightOut = keyframes`\n from {\n opacity: 1;\n transform: translateX(0);\n }\n to {\n opacity: 0;\n transform: translateX(100%);\n }\n`;\n\n/* -------------------------------------------------------------------------------------------------\n * Styled components\n * -----------------------------------------------------------------------------------------------*/\n\ninterface DrawerContainerProps {\n $animationDirection?: DrawerBodyProps['animationDirection'];\n $width?: string;\n $maxHeight?: string;\n}\n\nconst DrawerContainer = styled(Flex)<DrawerContainerProps>`\n flex-direction: column;\n position: fixed;\n bottom: 0;\n /* Mobile: full-bleed sheet. Anchoring to the right at a fixed width left a\n dead gutter on every phone wider than the panel, and the panel only filled\n the screen once the viewport happened to be narrower than it. Below the\n medium breakpoint the panel is the screen; medium+ restores the\n right-anchored rail. */\n left: 0;\n right: 0;\n width: 100%;\n padding: ${({ theme }) => theme.spaces[2]};\n max-width: 100%;\n /* Sit just below the overlay token (300) so that:\n - popovers (500) and tooltips (1000) rendered from descendant components\n surface above the drawer panel,\n - AlertDialog overlays (300) and contents (310) opened from inside the\n drawer (e.g. the asset details \"delete\" confirm) cover the drawer. */\n z-index: 200;\n overflow: hidden;\n /* dvh, not vh: anchored to the bottom, a 100vh cap on mobile (visual\n viewport < 100vh under the URL bar) would push the drawer top off-screen. */\n max-height: ${({ $maxHeight }) => $maxHeight ?? '100dvh'};\n\n ${({ theme }) => theme.breakpoints.medium} {\n left: auto;\n width: ${({ $width }) => $width ?? '400px'};\n }\n\n &:focus {\n outline: none;\n }\n\n @media (prefers-reduced-motion: no-preference) {\n &[data-state='open'] {\n animation: ${({ $animationDirection }) =>\n $animationDirection === 'up' ? slideUpFromBottomIn : slideLeftFromRightIn}\n ${DRAWER_CLOSE_ANIMATION_MS}ms cubic-bezier(0.32, 0.72, 0, 1) forwards;\n }\n\n &[data-state='closed'] {\n animation: ${({ $animationDirection }) =>\n $animationDirection === 'up' ? slideUpFromBottomOut : slideLeftFromRightOut}\n ${DRAWER_CLOSE_ANIMATION_MS}ms cubic-bezier(0.32, 0.72, 0, 1) forwards;\n pointer-events: none;\n }\n }\n`;\n\nconst DrawerContent = styled(Box)`\n display: flex;\n flex-direction: column;\n flex: 1;\n min-height: 0;\n width: 100%;\n background-color: ${({ theme }) => theme.colors.neutral0};\n border-radius: ${({ theme }) => theme.borderRadius};\n box-shadow: ${({ theme }) => theme.shadows.popupShadow};\n overflow: hidden;\n border: 1px solid ${({ theme }) => theme.colors.neutral150};\n`;\n\ninterface CollapsibleContentProps {\n $isVisible: boolean;\n}\n\nconst CollapsibleContent = styled(Box)<CollapsibleContentProps>`\n display: grid;\n flex: 1;\n min-height: 0;\n grid-template-rows: ${({ $isVisible }) => ($isVisible ? '1fr' : '0fr')};\n transition: grid-template-rows 0.3s ease-in-out;\n\n > div {\n overflow: hidden;\n min-height: 0;\n }\n\n /* The scroll area wraps its children in a div styled inline as\n display: table, min-width: 100%. A table box grows to its content, so a\n single unbreakable string (a long file name) widens it past the scrollport\n and the panel gains a horizontal scrollbar — with nothing left to clamp the\n row, the name never truncates. Overriding to a block box makes the\n scrollport the width again, which is what the vertical-only list wants.\n Inline styles, hence the important. */\n [data-radix-scroll-area-viewport] > div {\n display: block !important;\n }\n`;\n\nconst CloseIconButton = styled(IconButton)`\n &:hover {\n background: transparent;\n }\n`;\n\n/* -------------------------------------------------------------------------------------------------\n * Drawer.Body\n * -----------------------------------------------------------------------------------------------*/\n\ntype PointerDownOutsideHandler = NonNullable<Dialog.DialogContentProps['onPointerDownOutside']>;\n\n/** Vetoes an outside interaction that would otherwise dismiss the drawer. */\nconst keepOpen = (event: { preventDefault: () => void }) => event.preventDefault();\n\ninterface DrawerBodyProps extends Omit<FlexProps, 'width' | 'maxHeight'> {\n animationDirection?: 'up' | 'left';\n /** Width of the panel from the medium breakpoint up. Mobile is always full-bleed. */\n width?: string;\n /** Cap on the panel height. Defaults to the dynamic viewport height. */\n maxHeight?: string;\n /**\n * Opt in to dismiss-on-outside-click. Omitted, an outside pointer press never\n * closes the drawer — it must be closed explicitly, as long-running panels\n * like the upload progress dialog need. Passed, the handler can still veto\n * individual presses via `event.preventDefault()`. Content rendered from\n * inside the panel but portaled elsewhere (DS dialogs, popovers, tooltips)\n * never counts as outside — Radix reads the React tree, not the DOM.\n */\n onPointerDownOutside?: PointerDownOutsideHandler;\n children: React.ReactNode;\n}\n\nconst DrawerBody = React.forwardRef<HTMLDivElement, DrawerBodyProps>(\n (\n { animationDirection, width, maxHeight, onPointerDownOutside = keepOpen, children, ...props },\n ref\n ) => (\n <Dialog.Content\n ref={ref}\n forceMount\n asChild\n onPointerDownOutside={onPointerDownOutside}\n // Non-modal, so focus legitimately moves outside (tabbing past the last\n // field); only a pointer press should ever dismiss.\n onFocusOutside={keepOpen}\n data-animation-direction={animationDirection}\n >\n {/* width/maxHeight go through transient props so the DS Flex never emits a\n competing `width` rule that would outrank the mobile full-bleed one. */}\n <DrawerContainer\n $animationDirection={animationDirection}\n $width={width}\n $maxHeight={maxHeight}\n {...props}\n >\n <DrawerContent>{children}</DrawerContent>\n </DrawerContainer>\n </Dialog.Content>\n )\n);\nDrawerBody.displayName = 'DrawerBody';\n\n/* -------------------------------------------------------------------------------------------------\n * Drawer.Root\n * -----------------------------------------------------------------------------------------------*/\n\ninterface DrawerRootProps {\n isVisible?: boolean;\n onClose?: () => void;\n children: React.ReactNode;\n}\n\nconst DrawerRoot = ({ isVisible, onClose, children }: DrawerRootProps): React.ReactElement => (\n <Dialog.Root\n open={isVisible}\n onOpenChange={(nextVisible) => !nextVisible && onClose?.()}\n modal={false}\n >\n <Dialog.Portal>{children}</Dialog.Portal>\n </Dialog.Root>\n);\n\n/* -------------------------------------------------------------------------------------------------\n * Drawer.Content - composable content slot (collapsible when isContentExpanded is used)\n * Contains a scrollable area\n * -----------------------------------------------------------------------------------------------*/\n\ninterface DrawerScrollableContentProps {\n children: React.ReactNode;\n /** When provided, content can collapse/expand (e.g. for minimize). Omit to always show. */\n isContentExpanded?: boolean;\n}\n\nconst DrawerScrollableContent = ({\n children,\n isContentExpanded = true,\n}: DrawerScrollableContentProps) => (\n <CollapsibleContent $isVisible={isContentExpanded} data-collapsed={!isContentExpanded}>\n <ScrollArea>{children}</ScrollArea>\n </CollapsibleContent>\n);\n\n/* -------------------------------------------------------------------------------------------------\n * Drawer.CloseButton - composable close icon button (Cross icon by default)\n * -----------------------------------------------------------------------------------------------*/\n\ninterface DrawerCloseButtonProps extends React.PropsWithChildren {\n onClose: () => void;\n label?: string;\n}\n\nconst DrawerCloseButton = ({ onClose, label, children }: DrawerCloseButtonProps) => {\n const { formatMessage } = useIntl();\n const labelMessage = label ?? formatMessage({ id: 'global.close', defaultMessage: 'Close' });\n return (\n <CloseIconButton onClick={onClose} label={labelMessage} variant=\"ghost\">\n {children ?? <Cross />}\n </CloseIconButton>\n );\n};\n\nconst Drawer = {\n Root: DrawerRoot,\n Body: DrawerBody,\n ScrollableContent: DrawerScrollableContent,\n CloseButton: DrawerCloseButton,\n Title: Dialog.Title,\n Description: Dialog.Description,\n};\n\nexport { Drawer };\n"],"names":["DRAWER_CLOSE_ANIMATION_MS","slideUpFromBottomIn","keyframes","slideUpFromBottomOut","slideLeftFromRightIn","slideLeftFromRightOut","DrawerContainer","styled","Flex","theme","spaces","$maxHeight","breakpoints","medium","$width","$animationDirection","DrawerContent","Box","colors","neutral0","borderRadius","shadows","popupShadow","neutral150","CollapsibleContent","$isVisible","CloseIconButton","IconButton","keepOpen","event","preventDefault","DrawerBody","React","forwardRef","animationDirection","width","maxHeight","onPointerDownOutside","children","props","ref","_jsx","Dialog","Content","forceMount","asChild","onFocusOutside","data-animation-direction","displayName","DrawerRoot","isVisible","onClose","Root","open","onOpenChange","nextVisible","modal","Portal","DrawerScrollableContent","isContentExpanded","data-collapsed","ScrollArea","DrawerCloseButton","label","formatMessage","useIntl","labelMessage","id","defaultMessage","onClick","variant","Cross","Drawer","Body","ScrollableContent","CloseButton","Title","Description"],"mappings":"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"}
|
|
@@ -11,6 +11,7 @@ var hooks = require('../store/hooks.js');
|
|
|
11
11
|
var uploadProgress = require('../store/uploadProgress.js');
|
|
12
12
|
var translations = require('../utils/translations.js');
|
|
13
13
|
var Drawer = require('./Drawer.js');
|
|
14
|
+
var TruncatedText = require('./TruncatedText.js');
|
|
14
15
|
|
|
15
16
|
/* -------------------------------------------------------------------------------------------------
|
|
16
17
|
* DialogHeader
|
|
@@ -19,6 +20,9 @@ var Drawer = require('./Drawer.js');
|
|
|
19
20
|
direction: "column",
|
|
20
21
|
alignItems: "flex-start",
|
|
21
22
|
paddingLeft: 2,
|
|
23
|
+
paddingRight: 2,
|
|
24
|
+
paddingTop: 1,
|
|
25
|
+
paddingBottom: 1,
|
|
22
26
|
children: [
|
|
23
27
|
/*#__PURE__*/ jsxRuntime.jsx(Drawer.Drawer.Title, {
|
|
24
28
|
children: /*#__PURE__*/ jsxRuntime.jsx(designSystem.Typography, {
|
|
@@ -42,6 +46,7 @@ var Drawer = require('./Drawer.js');
|
|
|
42
46
|
});
|
|
43
47
|
};
|
|
44
48
|
const HeaderStatusIcon = styledComponents.styled(designSystem.Flex)`
|
|
49
|
+
align-self: stretch;
|
|
45
50
|
padding: ${({ theme })=>theme.spaces[3]};
|
|
46
51
|
border-radius: ${({ theme })=>`${theme.borderRadius} 0 0 ${theme.borderRadius}`};
|
|
47
52
|
|
|
@@ -177,7 +182,19 @@ const HeaderStatus = ({ status, progress, totalFiles, successfulCount, errorCoun
|
|
|
177
182
|
});
|
|
178
183
|
}
|
|
179
184
|
if (status === 'uploading') {
|
|
180
|
-
|
|
185
|
+
// Two separate strings so a locale can position (or omit) the percentage itself.
|
|
186
|
+
const title = progress === null ? formatMessage({
|
|
187
|
+
id: translations.getTranslationKey('upload.progress.uploading.indeterminate'),
|
|
188
|
+
defaultMessage: 'Uploading {total, plural, one {# item} other {# items}}'
|
|
189
|
+
}, {
|
|
190
|
+
total: totalFiles
|
|
191
|
+
}) : formatMessage({
|
|
192
|
+
id: translations.getTranslationKey('upload.progress.uploading.withCount'),
|
|
193
|
+
defaultMessage: 'Uploading {total, plural, one {# item} other {# items}} ({percentage}%)'
|
|
194
|
+
}, {
|
|
195
|
+
total: totalFiles,
|
|
196
|
+
percentage: Math.round(progress)
|
|
197
|
+
});
|
|
181
198
|
return /*#__PURE__*/ jsxRuntime.jsxs(HeaderStatusWrapper, {
|
|
182
199
|
children: [
|
|
183
200
|
/*#__PURE__*/ jsxRuntime.jsx(HeaderStatusIcon, {
|
|
@@ -187,13 +204,7 @@ const HeaderStatus = ({ status, progress, totalFiles, successfulCount, errorCoun
|
|
|
187
204
|
})
|
|
188
205
|
}),
|
|
189
206
|
/*#__PURE__*/ jsxRuntime.jsx(HeaderStatusMessage, {
|
|
190
|
-
title:
|
|
191
|
-
id: translations.getTranslationKey('upload.progress.uploading.withCount'),
|
|
192
|
-
defaultMessage: 'Uploading {total} items ({percentage}%)'
|
|
193
|
-
}, {
|
|
194
|
-
total: totalFiles,
|
|
195
|
-
percentage: progressPercentage
|
|
196
|
-
}),
|
|
207
|
+
title: title,
|
|
197
208
|
metadataSubtitle: metadataSubtitle
|
|
198
209
|
})
|
|
199
210
|
]
|
|
@@ -228,7 +239,12 @@ const HEADER_COLOR_MAP = {
|
|
|
228
239
|
const DialogHeader = ({ handleClose })=>{
|
|
229
240
|
const { formatMessage } = reactIntl.useIntl();
|
|
230
241
|
const { isMinimized, files, uploadId, totalFiles } = hooks.useTypedSelector((state)=>state.uploadProgress);
|
|
231
|
-
const
|
|
242
|
+
const aggregateProgress = hooks.useTypedSelector(uploadProgress.selectAggregateProgress);
|
|
243
|
+
const reportsByteProgress = hooks.useTypedSelector(uploadProgress.selectReportsByteProgress);
|
|
244
|
+
const countBasedProgress = hooks.useTypedSelector(uploadProgress.selectCountBasedProgress);
|
|
245
|
+
// Byte-weighted when the flow streams bytes (direct-file), else count-based (settled/total).
|
|
246
|
+
// Both return `null` for an indeterminate header when there's nothing to show yet.
|
|
247
|
+
const progress = reportsByteProgress ? aggregateProgress : countBasedProgress;
|
|
232
248
|
const metadataProgress = hooks.useTypedSelector(uploadProgress.selectMetadataProgress);
|
|
233
249
|
const isGeneratingMetadata = hooks.useTypedSelector(uploadProgress.selectIsGeneratingMetadata);
|
|
234
250
|
const metadataOutcome = hooks.useTypedSelector(uploadProgress.selectMetadataOutcome);
|
|
@@ -397,6 +413,25 @@ const IndeterminateIndicator = styledComponents.styled.div`
|
|
|
397
413
|
children: /*#__PURE__*/ jsxRuntime.jsx(IndeterminateIndicator, {})
|
|
398
414
|
});
|
|
399
415
|
};
|
|
416
|
+
/**
|
|
417
|
+
* Without a floor of zero the row is as wide as its longest filename, which
|
|
418
|
+
* pushes past the panel and gives the dialog a second, horizontal scrollbar
|
|
419
|
+
* instead of truncating.
|
|
420
|
+
*
|
|
421
|
+
* The floor belongs to the name alone: the icon carries its size in SVG
|
|
422
|
+
* attributes, which flex is free to override, so letting it shrink squashes it
|
|
423
|
+
* against a long name instead of truncating the name.
|
|
424
|
+
*/ const FileRowName = styledComponents.styled(designSystem.Flex)`
|
|
425
|
+
min-width: 0;
|
|
426
|
+
|
|
427
|
+
> :first-child {
|
|
428
|
+
flex-shrink: 0;
|
|
429
|
+
}
|
|
430
|
+
|
|
431
|
+
> :last-child {
|
|
432
|
+
min-width: 0;
|
|
433
|
+
}
|
|
434
|
+
`;
|
|
400
435
|
const FileRow = ({ icon, fileName, children })=>{
|
|
401
436
|
return /*#__PURE__*/ jsxRuntime.jsxs(designSystem.Flex, {
|
|
402
437
|
direction: "column",
|
|
@@ -405,14 +440,13 @@ const FileRow = ({ icon, fileName, children })=>{
|
|
|
405
440
|
gap: 1,
|
|
406
441
|
width: "100%",
|
|
407
442
|
children: [
|
|
408
|
-
/*#__PURE__*/ jsxRuntime.jsxs(
|
|
443
|
+
/*#__PURE__*/ jsxRuntime.jsxs(FileRowName, {
|
|
409
444
|
gap: 2,
|
|
410
445
|
children: [
|
|
411
446
|
icon,
|
|
412
|
-
/*#__PURE__*/ jsxRuntime.jsx(
|
|
447
|
+
/*#__PURE__*/ jsxRuntime.jsx(TruncatedText.TruncatedText, {
|
|
413
448
|
variant: "omega",
|
|
414
449
|
fontWeight: "semiBold",
|
|
415
|
-
ellipsis: true,
|
|
416
450
|
children: fileName
|
|
417
451
|
})
|
|
418
452
|
]
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"UploadProgressDialog.js","sources":["../../../../admin/src/future/components/UploadProgressDialog.tsx"],"sourcesContent":["import * as React from 'react';\n\nimport { Flex, IconButton, TextButton, Typography } from '@strapi/design-system';\nimport {\n ArrowsCounterClockwise,\n Check,\n CheckCircle,\n ChevronDown,\n Clock,\n Cross,\n CrossCircle,\n Information,\n MinusCircle,\n Sparkle,\n Upload,\n WarningCircle,\n} from '@strapi/icons';\nimport { useIntl } from 'react-intl';\nimport { keyframes, styled } from 'styled-components';\n\nimport { abortUpload, useRetryCancelledFilesMutation } from '../services/api';\nimport { useTypedDispatch, useTypedSelector } from '../store/hooks';\nimport {\n closeUploadProgress,\n toggleMinimize,\n cancelUpload,\n selectAggregateProgress,\n selectMetadataProgress,\n selectIsGeneratingMetadata,\n selectMetadataOutcome,\n} from '../store/uploadProgress';\nimport { getTranslationKey } from '../utils/translations';\n\nimport { Drawer } from './Drawer';\n\nimport type { FileMetadataStatus, FileProgress, FileProgressStatus } from '../store/uploadProgress';\nimport type { MessageDescriptor } from 'react-intl';\n\n/* -------------------------------------------------------------------------------------------------\n * DialogHeader\n * -----------------------------------------------------------------------------------------------*/\n\nconst HeaderStatusMessage = ({\n title,\n subtitle,\n metadataSubtitle,\n}: {\n title: string;\n subtitle?: string;\n metadataSubtitle?: string;\n}) => {\n return (\n <Flex direction=\"column\" alignItems=\"flex-start\" paddingLeft={2}>\n <Drawer.Title>\n <Typography variant=\"omega\">{title}</Typography>\n </Drawer.Title>\n <Drawer.Description>\n <Typography variant=\"pi\" textColor=\"neutral600\">\n {subtitle}\n </Typography>\n </Drawer.Description>\n {metadataSubtitle && (\n <Typography variant=\"pi\" textColor=\"neutral600\">\n {metadataSubtitle}\n </Typography>\n )}\n </Flex>\n );\n};\n\nconst HeaderStatusIcon = styled(Flex)`\n padding: ${({ theme }) => theme.spaces[3]};\n border-radius: ${({ theme }) => `${theme.borderRadius} 0 0 ${theme.borderRadius}`};\n\n > svg {\n height: 24px;\n width: 24px;\n }\n`;\n\nconst HeaderStatusWrapper = styled(Flex)`\n align-items: center;\n`;\n\ntype HeaderStatusProps = {\n status: 'uploading' | 'success' | 'error' | 'canceled';\n progress?: number;\n totalFiles: number;\n successfulCount: number;\n errorCount: number;\n /**\n * Count-based metadata progress, or `null` when no row entered the metadata phase.\n * Shown as an extra subtitle while generation is still in flight.\n */\n metadataProgress: number | null;\n /** Whether any row is still generating — drives whether the subtitle shows at all. */\n isGeneratingMetadata: boolean;\n /**\n * Terminal per-outcome counts, or `null` while the phase is unfinished or was never\n * entered. Replaces the in-flight subtitle once generation settles.\n */\n metadataOutcome: { generated: number; skipped: number; failed: number } | null;\n};\n\nconst HeaderStatus = ({\n status,\n progress,\n totalFiles,\n successfulCount,\n errorCount,\n metadataProgress,\n isGeneratingMetadata,\n metadataOutcome,\n}: HeaderStatusProps) => {\n const { formatMessage } = useIntl();\n\n // Completion is upload-driven, so the terminal header can appear while metadata is\n // still generating — the subtitle keeps ticking underneath until it settles.\n //\n // Gated on work actually being in flight rather than on `progress < 100`: in a\n // sequential batch the percentage touches 100% between files, which would blink the\n // subtitle out and back in on every upload.\n //\n // Once the phase settles the line is not dropped but replaced with the outcome, so the\n // header keeps confirming what happened instead of silently losing the message.\n const metadataSubtitle = (() => {\n if (metadataProgress !== null && isGeneratingMetadata) {\n return formatMessage(\n {\n id: getTranslationKey('upload.progress.generatingMetadata.withCount'),\n defaultMessage: 'Generating metadata with AI ({percentage}%)',\n },\n { percentage: metadataProgress }\n );\n }\n\n if (metadataOutcome === null) {\n return undefined;\n }\n\n // Only `generated` rows had metadata written, so only they can be reported as a\n // success. With none, there is nothing to confirm — an all-skipped batch of\n // non-images would otherwise read as \"generated on 0 files\". Per-row sublines\n // already spell out skipped and failed outcomes.\n if (metadataOutcome.generated === 0) {\n return undefined;\n }\n\n if (metadataOutcome.failed > 0) {\n return formatMessage(\n {\n id: getTranslationKey('upload.progress.metadataGenerated.withFailures'),\n defaultMessage: '{generatedCount} generated, {failedCount} failed',\n },\n { generatedCount: metadataOutcome.generated, failedCount: metadataOutcome.failed }\n );\n }\n\n return formatMessage(\n {\n id: getTranslationKey('upload.progress.metadataGenerated.withCount'),\n defaultMessage:\n '{count, plural, one {Metadata successfully generated on # file} other {Metadata successfully generated on # files}}',\n },\n { count: metadataOutcome.generated }\n );\n })();\n\n if (status === 'error') {\n return (\n <HeaderStatusWrapper>\n <HeaderStatusIcon background=\"danger200\">\n <Cross fill=\"danger700\" />\n </HeaderStatusIcon>\n <HeaderStatusMessage\n title={formatMessage({\n id: getTranslationKey('upload.progress.failed'),\n defaultMessage: 'Upload failed',\n })}\n subtitle={formatMessage({\n id: getTranslationKey('upload.progress.failed.subtitle'),\n defaultMessage: 'Please try to upload files again',\n })}\n />\n </HeaderStatusWrapper>\n );\n }\n\n if (status === 'success') {\n const subtitle =\n errorCount > 0\n ? formatMessage(\n {\n id: getTranslationKey('upload.progress.success.subtitle.withErrors'),\n defaultMessage: '{successCount} uploaded, {errorCount} failed',\n },\n { successCount: successfulCount, errorCount }\n )\n : formatMessage(\n {\n id: getTranslationKey('upload.progress.success.subtitle'),\n defaultMessage: '{count} files uploaded successfully',\n },\n { count: successfulCount }\n );\n\n return (\n <HeaderStatusWrapper>\n <HeaderStatusIcon background=\"success200\">\n <Check fill=\"success700\" />\n </HeaderStatusIcon>\n <HeaderStatusMessage\n title={formatMessage({\n id: getTranslationKey('upload.progress.success'),\n defaultMessage: 'Upload successful!',\n })}\n subtitle={subtitle}\n metadataSubtitle={metadataSubtitle}\n />\n </HeaderStatusWrapper>\n );\n }\n\n if (status === 'canceled') {\n return (\n <HeaderStatusWrapper>\n <HeaderStatusIcon background=\"neutral200\">\n <MinusCircle fill=\"neutral700\" />\n </HeaderStatusIcon>\n <HeaderStatusMessage\n title={formatMessage({\n id: getTranslationKey('upload.progress.canceled'),\n defaultMessage: 'Upload canceled',\n })}\n subtitle={formatMessage({\n id: getTranslationKey('upload.progress.canceled.subtitle'),\n defaultMessage: 'Some files were not uploaded',\n })}\n metadataSubtitle={metadataSubtitle}\n />\n </HeaderStatusWrapper>\n );\n }\n\n if (status === 'uploading') {\n const progressPercentage = progress ? Math.round(progress) : 0;\n\n return (\n <HeaderStatusWrapper>\n <HeaderStatusIcon background=\"primary200\">\n <Upload fill=\"primary700\" />\n </HeaderStatusIcon>\n <HeaderStatusMessage\n title={formatMessage(\n {\n id: getTranslationKey('upload.progress.uploading.withCount'),\n defaultMessage: 'Uploading {total} items ({percentage}%)',\n },\n {\n total: totalFiles,\n percentage: progressPercentage,\n }\n )}\n metadataSubtitle={metadataSubtitle}\n />\n </HeaderStatusWrapper>\n );\n }\n\n return null;\n};\n\nconst HeaderIconButton = styled(IconButton)`\n &:hover {\n background: transparent;\n }\n`;\n\nconst ChevronWrapper = styled.span<{ $isMinimized: boolean }>`\n display: flex;\n transition: transform 0.5s ease-in-out;\n transform: ${({ $isMinimized }) => ($isMinimized ? 'rotate(180deg)' : 'rotate(0deg)')};\n`;\n\nconst HEADER_COLOR_MAP = {\n uploading: { background: 'primary100' },\n canceled: { background: 'neutral100' },\n success: { background: 'success100' },\n error: { background: 'danger100' },\n} as const;\n\nconst DialogHeader = ({ handleClose }: { handleClose: () => void }) => {\n const { formatMessage } = useIntl();\n\n const { isMinimized, files, uploadId, totalFiles } = useTypedSelector(\n (state) => state.uploadProgress\n );\n const progress = useTypedSelector(selectAggregateProgress);\n const metadataProgress = useTypedSelector(selectMetadataProgress);\n const isGeneratingMetadata = useTypedSelector(selectIsGeneratingMetadata);\n const metadataOutcome = useTypedSelector(selectMetadataOutcome);\n const dispatch = useTypedDispatch();\n const [retryCancelledFiles] = useRetryCancelledFilesMutation();\n\n // The batch is complete once every file has reached a terminal state. Byte-weighted\n // progress can't be used here because errored/cancelled rows never reach 100%.\n const isComplete =\n files.length > 0 &&\n files.every((f) => f.status === 'complete' || f.status === 'error' || f.status === 'cancelled');\n const isAllUploaded = isComplete;\n const isAllErrored = isComplete && files.every((f) => f.status === 'error');\n const hasCancelledFiles = files.some((f) => f.status === 'cancelled');\n const successfulCount = files.filter((f) => f.status === 'complete').length;\n const errorCount = files.filter((f) => f.status === 'error').length;\n // Success includes partial success (some files succeeded, even if some failed)\n const isSuccess = isComplete && successfulCount > 0 && !hasCancelledFiles;\n const status = ((): HeaderStatusProps['status'] => {\n if (isAllErrored) return 'error';\n if (isSuccess) return 'success';\n if (hasCancelledFiles) return 'canceled';\n\n return 'uploading';\n })();\n\n const handleCancel = () => {\n abortUpload(uploadId);\n dispatch(cancelUpload());\n };\n\n const handleRetry = async () => {\n try {\n await retryCancelledFiles().unwrap();\n } catch {\n // Error is already dispatched to store from the API queryFn\n }\n };\n\n const handleToggleMinimize = () => {\n dispatch(toggleMinimize());\n };\n\n return (\n <Flex\n background={HEADER_COLOR_MAP[status].background}\n justifyContent=\"space-between\"\n margin={1}\n hasRadius\n >\n <HeaderStatus\n status={status}\n progress={progress}\n totalFiles={totalFiles}\n successfulCount={successfulCount}\n errorCount={errorCount}\n metadataProgress={metadataProgress}\n isGeneratingMetadata={isGeneratingMetadata}\n metadataOutcome={metadataOutcome}\n />\n <Flex gap={1}>\n {!isAllUploaded && (\n <TextButton onClick={handleCancel} fontWeight=\"bold\">\n {formatMessage({\n id: getTranslationKey('upload.progress.cancel'),\n defaultMessage: 'Cancel all',\n })}\n </TextButton>\n )}\n {hasCancelledFiles && (\n <TextButton onClick={handleRetry} fontWeight=\"bold\">\n {formatMessage({\n id: getTranslationKey('upload.progress.retry'),\n defaultMessage: 'Retry',\n })}\n </TextButton>\n )}\n <HeaderIconButton\n onClick={handleToggleMinimize}\n label={formatMessage({\n id: getTranslationKey(\n isMinimized ? 'upload.progress.maximize' : 'upload.progress.minimize'\n ),\n defaultMessage: isMinimized ? 'Maximize' : 'Minimize',\n })}\n variant=\"ghost\"\n >\n <ChevronWrapper $isMinimized={isMinimized}>\n <ChevronDown />\n </ChevronWrapper>\n </HeaderIconButton>\n {isComplete && (\n <Drawer.CloseButton\n onClose={handleClose}\n label={formatMessage({\n id: getTranslationKey('upload.progress.close'),\n defaultMessage: 'Close',\n })}\n />\n )}\n </Flex>\n </Flex>\n );\n};\n\n/* -------------------------------------------------------------------------------------------------\n * UploadProgressDialog\n * -----------------------------------------------------------------------------------------------*/\n\nconst ProgressTrack = styled.div`\n width: 100%;\n height: ${({ theme }) => theme.spaces[1]};\n background-color: ${({ theme }) => theme.colors.neutral200};\n border-radius: 4px;\n overflow: hidden;\n`;\n\nconst ProgressIndicator = styled.div<{ $percent: number }>`\n height: 100%;\n width: ${({ $percent }) => $percent}%;\n background-color: ${({ theme }) => theme.colors.primary700};\n border-radius: 4px;\n transition: width 0.15s linear;\n`;\n\nconst DeterminateBar = ({ percent }: { percent: number }) => {\n const clamped = Math.min(100, Math.max(0, Math.round(percent)));\n return (\n <ProgressTrack role=\"progressbar\" aria-valuemin={0} aria-valuemax={100} aria-valuenow={clamped}>\n <ProgressIndicator $percent={clamped} />\n </ProgressTrack>\n );\n};\n\nconst INDETERMINATE_INDICATOR_WIDTH = 40;\n\n/**\n * `translateX` percentages resolve against the *indicator's* own width, not the track's.\n * So -100% is exactly \"fully off the left edge\" regardless of the width above, and the\n * end offset converts a full track width into those same own-width units. Both ends sit\n * flush off-track, which keeps entry and exit symmetric — a smaller start offset would\n * make the bar pop in already partly visible.\n */\nconst indeterminateSlide = keyframes`\n from {\n transform: translateX(-100%);\n }\n to {\n transform: translateX(${(100 / INDETERMINATE_INDICATOR_WIDTH) * 100}%);\n }\n`;\n\nconst IndeterminateIndicator = styled.div`\n height: 100%;\n width: ${INDETERMINATE_INDICATOR_WIDTH}%;\n background-color: ${({ theme }) => theme.colors.primary700};\n border-radius: 4px;\n /* Linear, not an eased curve: the DS easings decelerate to a stop, which on a loop\n reads as a stall at the wrap point. Constant speed is what makes it read as a sweep. */\n animation: ${indeterminateSlide} 1.2s linear infinite;\n\n /* A perpetually moving bar is a vestibular trigger; fall back to a static track fill. */\n @media (prefers-reduced-motion: reduce) {\n animation: none;\n width: 100%;\n opacity: 0.5;\n }\n`;\n\n/**\n * Progress bar for work whose completion fraction is genuinely unknowable, rather\n * than merely unknown-yet: the AI metadata endpoint answers in one go, and the URL\n * flow can't report bytes until the server has fetched the file and knows its size.\n *\n * Deliberately omits `aria-valuenow` — that absence is precisely how ARIA conveys\n * an indeterminate progressbar, so assistive tech announces \"busy\" instead of \"0%\".\n */\nconst IndeterminateBar = () => {\n return (\n <ProgressTrack role=\"progressbar\" aria-valuemin={0} aria-valuemax={100}>\n <IndeterminateIndicator />\n </ProgressTrack>\n );\n};\n\nconst FileRow = ({\n icon,\n fileName,\n children,\n}: {\n icon: React.ReactNode;\n fileName: string;\n children: React.ReactNode;\n}) => {\n return (\n <Flex direction=\"column\" alignItems=\"stretch\" justifyContent=\"center\" gap={1} width=\"100%\">\n <Flex gap={2}>\n {icon}\n <Typography variant=\"omega\" fontWeight=\"semiBold\" ellipsis>\n {fileName}\n </Typography>\n </Flex>\n {children}\n </Flex>\n );\n};\n\n/**\n * Icon + subline for a successfully uploaded row, keyed by its metadata phase.\n * `'none'` covers rows that never entered the phase — AI metadata disabled — and\n * renders exactly as before this feature existed. Non-images do enter the phase and\n * land on `skipped`.\n *\n * `skipped` uses a neutral `Information` icon, deliberately distinct from\n * generated/failed/cancelled — skipping is an expected outcome for a non-image, not a\n * problem to flag.\n */\nconst COMPLETED_ROW_PRESENTATION: Record<\n FileMetadataStatus | 'none',\n { icon: React.ReactNode; message: MessageDescriptor }\n> = {\n none: {\n icon: <CheckCircle fill=\"success500\" />,\n message: {\n id: getTranslationKey('upload.progress.file.uploaded'),\n defaultMessage: 'Uploaded',\n },\n },\n generating: {\n icon: <Sparkle fill=\"primary600\" />,\n message: {\n id: getTranslationKey('upload.progress.file.generatingMetadata'),\n defaultMessage: 'Uploaded • Generating metadata…',\n },\n },\n generated: {\n icon: <CheckCircle fill=\"success500\" />,\n message: {\n id: getTranslationKey('upload.progress.file.metadataGenerated'),\n defaultMessage: 'Uploaded • Metadata generated',\n },\n },\n skipped: {\n icon: <Information fill=\"neutral500\" />,\n message: {\n id: getTranslationKey('upload.progress.file.metadataSkipped'),\n defaultMessage: 'Upload complete • Metadata generation skipped',\n },\n },\n failed: {\n icon: <WarningCircle fill=\"warning500\" />,\n message: {\n id: getTranslationKey('upload.progress.file.metadataFailed'),\n defaultMessage: 'Upload complete • Metadata generation failed',\n },\n },\n};\n\nconst FileRowRenderer = ({ file }: { file: FileProgress }) => {\n const { formatMessage } = useIntl();\n const isError = file.status === 'error';\n const isCurrentFile = file.status === 'uploading';\n const isCompleted = file.status === 'complete';\n const isCancelled = file.status === 'cancelled';\n const isQueued = file.status === 'pending';\n\n if (isQueued) {\n // No bar: there is nothing to report yet, and an indeterminate bar would read\n // as \"in progress\" on a file the pool has not picked up.\n return (\n <FileRow icon={<Clock fill=\"neutral600\" />} fileName={file.name}>\n <Typography variant=\"pi\" textColor=\"neutral600\">\n {formatMessage({\n id: getTranslationKey('upload.progress.file.queued'),\n defaultMessage: 'Queued',\n })}\n </Typography>\n </FileRow>\n );\n }\n\n if (isCurrentFile) {\n // Determinate only once bytes are actually being reported — a known `size` is not\n // enough. The two upload flows differ here:\n // - the direct-file flow streams real byte counts from XHR, so `uploadedBytes`\n // climbs and a determinate bar is meaningful;\n // - the URL flow learns the size from the `file:uploading` SSE event but receives\n // no incremental counts at all (the next event is `file:complete`), so\n // `uploadedBytes` stays 0 for the whole transfer.\n // Keying off `size` alone froze URL rows at a determinate 0% for the entire upload;\n // keying off reported bytes keeps them animating until there is a fraction to show.\n const hasReportedProgress = file.size > 0 && file.uploadedBytes > 0;\n\n return (\n <FileRow icon={<ArrowsCounterClockwise fill=\"secondary600\" />} fileName={file.name}>\n <Typography variant=\"pi\" textColor=\"neutral600\">\n {formatMessage({\n id: getTranslationKey('upload.progress.file.uploading'),\n defaultMessage: 'Uploading...',\n })}\n </Typography>\n {hasReportedProgress ? (\n <DeterminateBar percent={(file.uploadedBytes / file.size) * 100} />\n ) : (\n <IndeterminateBar />\n )}\n </FileRow>\n );\n }\n\n if (isError) {\n return (\n <FileRow icon={<CrossCircle fill=\"danger500\" />} fileName={file.name}>\n <Typography variant=\"pi\" textColor=\"neutral600\">\n {file.error\n ? /**\n * The server may return a machine-readable code (e.g. `FileTooBig` from the\n * body middleware) or an already human-readable sentence (e.g. the upload\n * plugin's size-limit message). Translate the former, fall back to the latter.\n */\n formatMessage({\n id: getTranslationKey(`apiError.${file.error}`),\n defaultMessage: file.error,\n })\n : formatMessage({\n id: getTranslationKey('upload.generic-error'),\n defaultMessage: 'An error occurred while uploading the file.',\n })}\n </Typography>\n </FileRow>\n );\n }\n\n if (isCancelled) {\n return (\n <FileRow icon={<MinusCircle fill=\"neutral600\" />} fileName={file.name}>\n <Typography variant=\"pi\" textColor=\"neutral600\">\n {formatMessage({\n id: getTranslationKey('upload.progress.file.canceled'),\n defaultMessage: 'Canceled',\n })}\n </Typography>\n </FileRow>\n );\n }\n\n if (isCompleted) {\n // The upload succeeded; the metadata phase (if any) drives both the icon and the\n // subline from here on — a metadata failure shows a warning, not an upload error.\n const { icon, message } = COMPLETED_ROW_PRESENTATION[file.metadataStatus ?? 'none'];\n\n return (\n <FileRow icon={icon} fileName={file.name}>\n <Typography variant=\"pi\" textColor=\"neutral600\">\n {formatMessage(message)}\n </Typography>\n {/* Generation has no intermediate progress to report, so the bar stays indeterminate. */}\n {file.metadataStatus === 'generating' && <IndeterminateBar />}\n </FileRow>\n );\n }\n\n return null;\n};\n\nconst CompletedFilesList = styled(Flex)`\n flex-direction: column;\n gap: ${({ theme }) => theme.spaces[2]};\n width: 100%;\n`;\n\nexport const UploadProgressDialog = () => {\n const dispatch = useTypedDispatch();\n const { isVisible, isMinimized, files } = useTypedSelector((state) => state.uploadProgress);\n\n // With concurrent uploads several files are `uploading` at once — render every\n // in-flight row, not just the first (a `find` here dated to the strictly\n // sequential era and hid all but the lowest-index worker's row).\n const uploadingFiles = files.filter((f) => f.status === 'uploading');\n // Everything the pool has not reached yet. Listed in queue order, which is the\n // order `files` is already in, so a row's position tells the user where it sits.\n const queuedFiles = files.filter((f) => f.status === 'pending');\n const completedFiles = files\n .filter((f) => f.status === 'complete' || f.status === 'error' || f.status === 'cancelled')\n .sort((a, b) => {\n // Sort priority: error > cancelled > complete\n const priority: Record<FileProgressStatus, number> = {\n error: 0,\n cancelled: 1,\n complete: 2,\n uploading: 3,\n pending: 4,\n };\n return priority[a.status] - priority[b.status];\n });\n\n const handleClose = () => {\n dispatch(closeUploadProgress());\n };\n\n return (\n <Drawer.Root isVisible={isVisible} onClose={handleClose}>\n <Drawer.Body animationDirection=\"up\" width=\"41.6rem\" maxHeight=\"34.2rem\">\n <DialogHeader handleClose={handleClose} />\n <Drawer.ScrollableContent isContentExpanded={!isMinimized}>\n <Flex\n direction=\"column\"\n alignItems=\"stretch\"\n gap={4}\n paddingTop={4}\n paddingBottom={4}\n paddingLeft={4}\n paddingRight={4}\n >\n {uploadingFiles.map((file) => (\n <FileRowRenderer key={file.index} file={file} />\n ))}\n\n {queuedFiles.map((file) => (\n <FileRowRenderer key={file.index} file={file} />\n ))}\n\n {completedFiles.length > 0 && (\n <CompletedFilesList>\n {completedFiles.map((file) => (\n <FileRowRenderer key={file.index} file={file} />\n ))}\n </CompletedFilesList>\n )}\n </Flex>\n </Drawer.ScrollableContent>\n </Drawer.Body>\n </Drawer.Root>\n );\n};\n"],"names":["HeaderStatusMessage","title","subtitle","metadataSubtitle","_jsxs","Flex","direction","alignItems","paddingLeft","_jsx","Drawer","Title","Typography","variant","Description","textColor","HeaderStatusIcon","styled","theme","spaces","borderRadius","HeaderStatusWrapper","HeaderStatus","status","progress","totalFiles","successfulCount","errorCount","metadataProgress","isGeneratingMetadata","metadataOutcome","formatMessage","useIntl","id","getTranslationKey","defaultMessage","percentage","undefined","generated","failed","generatedCount","failedCount","count","background","Cross","fill","successCount","Check","MinusCircle","progressPercentage","Math","round","Upload","total","HeaderIconButton","IconButton","ChevronWrapper","span","$isMinimized","HEADER_COLOR_MAP","uploading","canceled","success","error","DialogHeader","handleClose","isMinimized","files","uploadId","useTypedSelector","state","uploadProgress","selectAggregateProgress","selectMetadataProgress","selectIsGeneratingMetadata","selectMetadataOutcome","dispatch","useTypedDispatch","retryCancelledFiles","useRetryCancelledFilesMutation","isComplete","length","every","f","isAllUploaded","isAllErrored","hasCancelledFiles","some","filter","isSuccess","handleCancel","abortUpload","cancelUpload","handleRetry","unwrap","handleToggleMinimize","toggleMinimize","justifyContent","margin","hasRadius","gap","TextButton","onClick","fontWeight","label","ChevronDown","CloseButton","onClose","ProgressTrack","div","colors","neutral200","ProgressIndicator","$percent","primary700","DeterminateBar","percent","clamped","min","max","role","aria-valuemin","aria-valuemax","aria-valuenow","INDETERMINATE_INDICATOR_WIDTH","indeterminateSlide","keyframes","IndeterminateIndicator","IndeterminateBar","FileRow","icon","fileName","children","width","ellipsis","COMPLETED_ROW_PRESENTATION","none","CheckCircle","message","generating","Sparkle","skipped","Information","WarningCircle","FileRowRenderer","file","isError","isCurrentFile","isCompleted","isCancelled","isQueued","Clock","name","hasReportedProgress","size","uploadedBytes","ArrowsCounterClockwise","CrossCircle","metadataStatus","CompletedFilesList","UploadProgressDialog","isVisible","uploadingFiles","queuedFiles","completedFiles","sort","a","b","priority","cancelled","complete","pending","closeUploadProgress","Root","Body","animationDirection","maxHeight","ScrollableContent","isContentExpanded","paddingTop","paddingBottom","paddingRight","map","index"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"UploadProgressDialog.js","sources":["../../../../admin/src/future/components/UploadProgressDialog.tsx"],"sourcesContent":["import * as React from 'react';\n\nimport { Flex, IconButton, TextButton, Typography } from '@strapi/design-system';\nimport {\n ArrowsCounterClockwise,\n Check,\n CheckCircle,\n ChevronDown,\n Clock,\n Cross,\n CrossCircle,\n Information,\n MinusCircle,\n Sparkle,\n Upload,\n WarningCircle,\n} from '@strapi/icons';\nimport { useIntl } from 'react-intl';\nimport { keyframes, styled } from 'styled-components';\n\nimport { abortUpload, useRetryCancelledFilesMutation } from '../services/api';\nimport { useTypedDispatch, useTypedSelector } from '../store/hooks';\nimport {\n closeUploadProgress,\n toggleMinimize,\n cancelUpload,\n selectAggregateProgress,\n selectReportsByteProgress,\n selectCountBasedProgress,\n selectMetadataProgress,\n selectIsGeneratingMetadata,\n selectMetadataOutcome,\n} from '../store/uploadProgress';\nimport { getTranslationKey } from '../utils/translations';\n\nimport { Drawer } from './Drawer';\nimport { TruncatedText } from './TruncatedText';\n\nimport type { FileMetadataStatus, FileProgress, FileProgressStatus } from '../store/uploadProgress';\nimport type { MessageDescriptor } from 'react-intl';\n\n/* -------------------------------------------------------------------------------------------------\n * DialogHeader\n * -----------------------------------------------------------------------------------------------*/\n\nconst HeaderStatusMessage = ({\n title,\n subtitle,\n metadataSubtitle,\n}: {\n title: string;\n subtitle?: string;\n metadataSubtitle?: string;\n}) => {\n return (\n <Flex\n direction=\"column\"\n alignItems=\"flex-start\"\n paddingLeft={2}\n paddingRight={2}\n paddingTop={1}\n paddingBottom={1}\n >\n <Drawer.Title>\n <Typography variant=\"omega\">{title}</Typography>\n </Drawer.Title>\n <Drawer.Description>\n <Typography variant=\"pi\" textColor=\"neutral600\">\n {subtitle}\n </Typography>\n </Drawer.Description>\n {metadataSubtitle && (\n <Typography variant=\"pi\" textColor=\"neutral600\">\n {metadataSubtitle}\n </Typography>\n )}\n </Flex>\n );\n};\n\nconst HeaderStatusIcon = styled(Flex)`\n align-self: stretch;\n padding: ${({ theme }) => theme.spaces[3]};\n border-radius: ${({ theme }) => `${theme.borderRadius} 0 0 ${theme.borderRadius}`};\n\n > svg {\n height: 24px;\n width: 24px;\n }\n`;\n\nconst HeaderStatusWrapper = styled(Flex)`\n align-items: center;\n`;\n\ntype HeaderStatusProps = {\n status: 'uploading' | 'success' | 'error' | 'canceled';\n /** Byte-weighted progress, or `null` for a batch that reports no bytes (the URL flow). */\n progress: number | null;\n totalFiles: number;\n successfulCount: number;\n errorCount: number;\n /**\n * Count-based metadata progress, or `null` when no row entered the metadata phase.\n * Shown as an extra subtitle while generation is still in flight.\n */\n metadataProgress: number | null;\n /** Whether any row is still generating — drives whether the subtitle shows at all. */\n isGeneratingMetadata: boolean;\n /**\n * Terminal per-outcome counts, or `null` while the phase is unfinished or was never\n * entered. Replaces the in-flight subtitle once generation settles.\n */\n metadataOutcome: { generated: number; skipped: number; failed: number } | null;\n};\n\nconst HeaderStatus = ({\n status,\n progress,\n totalFiles,\n successfulCount,\n errorCount,\n metadataProgress,\n isGeneratingMetadata,\n metadataOutcome,\n}: HeaderStatusProps) => {\n const { formatMessage } = useIntl();\n\n // Completion is upload-driven, so the terminal header can appear while metadata is\n // still generating — the subtitle keeps ticking underneath until it settles.\n //\n // Gated on work actually being in flight rather than on `progress < 100`: in a\n // sequential batch the percentage touches 100% between files, which would blink the\n // subtitle out and back in on every upload.\n //\n // Once the phase settles the line is not dropped but replaced with the outcome, so the\n // header keeps confirming what happened instead of silently losing the message.\n const metadataSubtitle = (() => {\n if (metadataProgress !== null && isGeneratingMetadata) {\n return formatMessage(\n {\n id: getTranslationKey('upload.progress.generatingMetadata.withCount'),\n defaultMessage: 'Generating metadata with AI ({percentage}%)',\n },\n { percentage: metadataProgress }\n );\n }\n\n if (metadataOutcome === null) {\n return undefined;\n }\n\n // Only `generated` rows had metadata written, so only they can be reported as a\n // success. With none, there is nothing to confirm — an all-skipped batch of\n // non-images would otherwise read as \"generated on 0 files\". Per-row sublines\n // already spell out skipped and failed outcomes.\n if (metadataOutcome.generated === 0) {\n return undefined;\n }\n\n if (metadataOutcome.failed > 0) {\n return formatMessage(\n {\n id: getTranslationKey('upload.progress.metadataGenerated.withFailures'),\n defaultMessage: '{generatedCount} generated, {failedCount} failed',\n },\n { generatedCount: metadataOutcome.generated, failedCount: metadataOutcome.failed }\n );\n }\n\n return formatMessage(\n {\n id: getTranslationKey('upload.progress.metadataGenerated.withCount'),\n defaultMessage:\n '{count, plural, one {Metadata successfully generated on # file} other {Metadata successfully generated on # files}}',\n },\n { count: metadataOutcome.generated }\n );\n })();\n\n if (status === 'error') {\n return (\n <HeaderStatusWrapper>\n <HeaderStatusIcon background=\"danger200\">\n <Cross fill=\"danger700\" />\n </HeaderStatusIcon>\n <HeaderStatusMessage\n title={formatMessage({\n id: getTranslationKey('upload.progress.failed'),\n defaultMessage: 'Upload failed',\n })}\n subtitle={formatMessage({\n id: getTranslationKey('upload.progress.failed.subtitle'),\n defaultMessage: 'Please try to upload files again',\n })}\n />\n </HeaderStatusWrapper>\n );\n }\n\n if (status === 'success') {\n const subtitle =\n errorCount > 0\n ? formatMessage(\n {\n id: getTranslationKey('upload.progress.success.subtitle.withErrors'),\n defaultMessage: '{successCount} uploaded, {errorCount} failed',\n },\n { successCount: successfulCount, errorCount }\n )\n : formatMessage(\n {\n id: getTranslationKey('upload.progress.success.subtitle'),\n defaultMessage: '{count} files uploaded successfully',\n },\n { count: successfulCount }\n );\n\n return (\n <HeaderStatusWrapper>\n <HeaderStatusIcon background=\"success200\">\n <Check fill=\"success700\" />\n </HeaderStatusIcon>\n <HeaderStatusMessage\n title={formatMessage({\n id: getTranslationKey('upload.progress.success'),\n defaultMessage: 'Upload successful!',\n })}\n subtitle={subtitle}\n metadataSubtitle={metadataSubtitle}\n />\n </HeaderStatusWrapper>\n );\n }\n\n if (status === 'canceled') {\n return (\n <HeaderStatusWrapper>\n <HeaderStatusIcon background=\"neutral200\">\n <MinusCircle fill=\"neutral700\" />\n </HeaderStatusIcon>\n <HeaderStatusMessage\n title={formatMessage({\n id: getTranslationKey('upload.progress.canceled'),\n defaultMessage: 'Upload canceled',\n })}\n subtitle={formatMessage({\n id: getTranslationKey('upload.progress.canceled.subtitle'),\n defaultMessage: 'Some files were not uploaded',\n })}\n metadataSubtitle={metadataSubtitle}\n />\n </HeaderStatusWrapper>\n );\n }\n\n if (status === 'uploading') {\n // Two separate strings so a locale can position (or omit) the percentage itself.\n const title =\n progress === null\n ? formatMessage(\n {\n id: getTranslationKey('upload.progress.uploading.indeterminate'),\n defaultMessage: 'Uploading {total, plural, one {# item} other {# items}}',\n },\n { total: totalFiles }\n )\n : formatMessage(\n {\n id: getTranslationKey('upload.progress.uploading.withCount'),\n defaultMessage:\n 'Uploading {total, plural, one {# item} other {# items}} ({percentage}%)',\n },\n {\n total: totalFiles,\n percentage: Math.round(progress),\n }\n );\n\n return (\n <HeaderStatusWrapper>\n <HeaderStatusIcon background=\"primary200\">\n <Upload fill=\"primary700\" />\n </HeaderStatusIcon>\n <HeaderStatusMessage title={title} metadataSubtitle={metadataSubtitle} />\n </HeaderStatusWrapper>\n );\n }\n\n return null;\n};\n\nconst HeaderIconButton = styled(IconButton)`\n &:hover {\n background: transparent;\n }\n`;\n\nconst ChevronWrapper = styled.span<{ $isMinimized: boolean }>`\n display: flex;\n transition: transform 0.5s ease-in-out;\n transform: ${({ $isMinimized }) => ($isMinimized ? 'rotate(180deg)' : 'rotate(0deg)')};\n`;\n\nconst HEADER_COLOR_MAP = {\n uploading: { background: 'primary100' },\n canceled: { background: 'neutral100' },\n success: { background: 'success100' },\n error: { background: 'danger100' },\n} as const;\n\nconst DialogHeader = ({ handleClose }: { handleClose: () => void }) => {\n const { formatMessage } = useIntl();\n\n const { isMinimized, files, uploadId, totalFiles } = useTypedSelector(\n (state) => state.uploadProgress\n );\n const aggregateProgress = useTypedSelector(selectAggregateProgress);\n const reportsByteProgress = useTypedSelector(selectReportsByteProgress);\n const countBasedProgress = useTypedSelector(selectCountBasedProgress);\n // Byte-weighted when the flow streams bytes (direct-file), else count-based (settled/total).\n // Both return `null` for an indeterminate header when there's nothing to show yet.\n const progress = reportsByteProgress ? aggregateProgress : countBasedProgress;\n const metadataProgress = useTypedSelector(selectMetadataProgress);\n const isGeneratingMetadata = useTypedSelector(selectIsGeneratingMetadata);\n const metadataOutcome = useTypedSelector(selectMetadataOutcome);\n const dispatch = useTypedDispatch();\n const [retryCancelledFiles] = useRetryCancelledFilesMutation();\n\n // The batch is complete once every file has reached a terminal state. Byte-weighted\n // progress can't be used here because errored/cancelled rows never reach 100%.\n const isComplete =\n files.length > 0 &&\n files.every((f) => f.status === 'complete' || f.status === 'error' || f.status === 'cancelled');\n const isAllUploaded = isComplete;\n const isAllErrored = isComplete && files.every((f) => f.status === 'error');\n const hasCancelledFiles = files.some((f) => f.status === 'cancelled');\n const successfulCount = files.filter((f) => f.status === 'complete').length;\n const errorCount = files.filter((f) => f.status === 'error').length;\n // Success includes partial success (some files succeeded, even if some failed)\n const isSuccess = isComplete && successfulCount > 0 && !hasCancelledFiles;\n const status = ((): HeaderStatusProps['status'] => {\n if (isAllErrored) return 'error';\n if (isSuccess) return 'success';\n if (hasCancelledFiles) return 'canceled';\n\n return 'uploading';\n })();\n\n const handleCancel = () => {\n abortUpload(uploadId);\n dispatch(cancelUpload());\n };\n\n const handleRetry = async () => {\n try {\n await retryCancelledFiles().unwrap();\n } catch {\n // Error is already dispatched to store from the API queryFn\n }\n };\n\n const handleToggleMinimize = () => {\n dispatch(toggleMinimize());\n };\n\n return (\n <Flex\n background={HEADER_COLOR_MAP[status].background}\n justifyContent=\"space-between\"\n margin={1}\n hasRadius\n >\n <HeaderStatus\n status={status}\n progress={progress}\n totalFiles={totalFiles}\n successfulCount={successfulCount}\n errorCount={errorCount}\n metadataProgress={metadataProgress}\n isGeneratingMetadata={isGeneratingMetadata}\n metadataOutcome={metadataOutcome}\n />\n <Flex gap={1}>\n {!isAllUploaded && (\n <TextButton onClick={handleCancel} fontWeight=\"bold\">\n {formatMessage({\n id: getTranslationKey('upload.progress.cancel'),\n defaultMessage: 'Cancel all',\n })}\n </TextButton>\n )}\n {hasCancelledFiles && (\n <TextButton onClick={handleRetry} fontWeight=\"bold\">\n {formatMessage({\n id: getTranslationKey('upload.progress.retry'),\n defaultMessage: 'Retry',\n })}\n </TextButton>\n )}\n <HeaderIconButton\n onClick={handleToggleMinimize}\n label={formatMessage({\n id: getTranslationKey(\n isMinimized ? 'upload.progress.maximize' : 'upload.progress.minimize'\n ),\n defaultMessage: isMinimized ? 'Maximize' : 'Minimize',\n })}\n variant=\"ghost\"\n >\n <ChevronWrapper $isMinimized={isMinimized}>\n <ChevronDown />\n </ChevronWrapper>\n </HeaderIconButton>\n {isComplete && (\n <Drawer.CloseButton\n onClose={handleClose}\n label={formatMessage({\n id: getTranslationKey('upload.progress.close'),\n defaultMessage: 'Close',\n })}\n />\n )}\n </Flex>\n </Flex>\n );\n};\n\n/* -------------------------------------------------------------------------------------------------\n * UploadProgressDialog\n * -----------------------------------------------------------------------------------------------*/\n\nconst ProgressTrack = styled.div`\n width: 100%;\n height: ${({ theme }) => theme.spaces[1]};\n background-color: ${({ theme }) => theme.colors.neutral200};\n border-radius: 4px;\n overflow: hidden;\n`;\n\nconst ProgressIndicator = styled.div<{ $percent: number }>`\n height: 100%;\n width: ${({ $percent }) => $percent}%;\n background-color: ${({ theme }) => theme.colors.primary700};\n border-radius: 4px;\n transition: width 0.15s linear;\n`;\n\nconst DeterminateBar = ({ percent }: { percent: number }) => {\n const clamped = Math.min(100, Math.max(0, Math.round(percent)));\n return (\n <ProgressTrack role=\"progressbar\" aria-valuemin={0} aria-valuemax={100} aria-valuenow={clamped}>\n <ProgressIndicator $percent={clamped} />\n </ProgressTrack>\n );\n};\n\nconst INDETERMINATE_INDICATOR_WIDTH = 40;\n\n/**\n * `translateX` percentages resolve against the *indicator's* own width, not the track's.\n * So -100% is exactly \"fully off the left edge\" regardless of the width above, and the\n * end offset converts a full track width into those same own-width units. Both ends sit\n * flush off-track, which keeps entry and exit symmetric — a smaller start offset would\n * make the bar pop in already partly visible.\n */\nconst indeterminateSlide = keyframes`\n from {\n transform: translateX(-100%);\n }\n to {\n transform: translateX(${(100 / INDETERMINATE_INDICATOR_WIDTH) * 100}%);\n }\n`;\n\nconst IndeterminateIndicator = styled.div`\n height: 100%;\n width: ${INDETERMINATE_INDICATOR_WIDTH}%;\n background-color: ${({ theme }) => theme.colors.primary700};\n border-radius: 4px;\n /* Linear, not an eased curve: the DS easings decelerate to a stop, which on a loop\n reads as a stall at the wrap point. Constant speed is what makes it read as a sweep. */\n animation: ${indeterminateSlide} 1.2s linear infinite;\n\n /* A perpetually moving bar is a vestibular trigger; fall back to a static track fill. */\n @media (prefers-reduced-motion: reduce) {\n animation: none;\n width: 100%;\n opacity: 0.5;\n }\n`;\n\n/**\n * Progress bar for work whose completion fraction is genuinely unknowable, rather\n * than merely unknown-yet: the AI metadata endpoint answers in one go, and the URL\n * flow can't report bytes until the server has fetched the file and knows its size.\n *\n * Deliberately omits `aria-valuenow` — that absence is precisely how ARIA conveys\n * an indeterminate progressbar, so assistive tech announces \"busy\" instead of \"0%\".\n */\nconst IndeterminateBar = () => {\n return (\n <ProgressTrack role=\"progressbar\" aria-valuemin={0} aria-valuemax={100}>\n <IndeterminateIndicator />\n </ProgressTrack>\n );\n};\n\n/**\n * Without a floor of zero the row is as wide as its longest filename, which\n * pushes past the panel and gives the dialog a second, horizontal scrollbar\n * instead of truncating.\n *\n * The floor belongs to the name alone: the icon carries its size in SVG\n * attributes, which flex is free to override, so letting it shrink squashes it\n * against a long name instead of truncating the name.\n */\nconst FileRowName = styled(Flex)`\n min-width: 0;\n\n > :first-child {\n flex-shrink: 0;\n }\n\n > :last-child {\n min-width: 0;\n }\n`;\n\nconst FileRow = ({\n icon,\n fileName,\n children,\n}: {\n icon: React.ReactNode;\n fileName: string;\n children: React.ReactNode;\n}) => {\n return (\n <Flex direction=\"column\" alignItems=\"stretch\" justifyContent=\"center\" gap={1} width=\"100%\">\n <FileRowName gap={2}>\n {icon}\n <TruncatedText variant=\"omega\" fontWeight=\"semiBold\">\n {fileName}\n </TruncatedText>\n </FileRowName>\n {children}\n </Flex>\n );\n};\n\n/**\n * Icon + subline for a successfully uploaded row, keyed by its metadata phase.\n * `'none'` covers rows that never entered the phase — AI metadata disabled — and\n * renders exactly as before this feature existed. Non-images do enter the phase and\n * land on `skipped`.\n *\n * `skipped` uses a neutral `Information` icon, deliberately distinct from\n * generated/failed/cancelled — skipping is an expected outcome for a non-image, not a\n * problem to flag.\n */\nconst COMPLETED_ROW_PRESENTATION: Record<\n FileMetadataStatus | 'none',\n { icon: React.ReactNode; message: MessageDescriptor }\n> = {\n none: {\n icon: <CheckCircle fill=\"success500\" />,\n message: {\n id: getTranslationKey('upload.progress.file.uploaded'),\n defaultMessage: 'Uploaded',\n },\n },\n generating: {\n icon: <Sparkle fill=\"primary600\" />,\n message: {\n id: getTranslationKey('upload.progress.file.generatingMetadata'),\n defaultMessage: 'Uploaded • Generating metadata…',\n },\n },\n generated: {\n icon: <CheckCircle fill=\"success500\" />,\n message: {\n id: getTranslationKey('upload.progress.file.metadataGenerated'),\n defaultMessage: 'Uploaded • Metadata generated',\n },\n },\n skipped: {\n icon: <Information fill=\"neutral500\" />,\n message: {\n id: getTranslationKey('upload.progress.file.metadataSkipped'),\n defaultMessage: 'Upload complete • Metadata generation skipped',\n },\n },\n failed: {\n icon: <WarningCircle fill=\"warning500\" />,\n message: {\n id: getTranslationKey('upload.progress.file.metadataFailed'),\n defaultMessage: 'Upload complete • Metadata generation failed',\n },\n },\n};\n\nconst FileRowRenderer = ({ file }: { file: FileProgress }) => {\n const { formatMessage } = useIntl();\n const isError = file.status === 'error';\n const isCurrentFile = file.status === 'uploading';\n const isCompleted = file.status === 'complete';\n const isCancelled = file.status === 'cancelled';\n const isQueued = file.status === 'pending';\n\n if (isQueued) {\n // No bar: there is nothing to report yet, and an indeterminate bar would read\n // as \"in progress\" on a file the pool has not picked up.\n return (\n <FileRow icon={<Clock fill=\"neutral600\" />} fileName={file.name}>\n <Typography variant=\"pi\" textColor=\"neutral600\">\n {formatMessage({\n id: getTranslationKey('upload.progress.file.queued'),\n defaultMessage: 'Queued',\n })}\n </Typography>\n </FileRow>\n );\n }\n\n if (isCurrentFile) {\n // Determinate only once bytes are actually being reported — a known `size` is not\n // enough. The two upload flows differ here:\n // - the direct-file flow streams real byte counts from XHR, so `uploadedBytes`\n // climbs and a determinate bar is meaningful;\n // - the URL flow learns the size from the `file:uploading` SSE event but receives\n // no incremental counts at all (the next event is `file:complete`), so\n // `uploadedBytes` stays 0 for the whole transfer.\n // Keying off `size` alone froze URL rows at a determinate 0% for the entire upload;\n // keying off reported bytes keeps them animating until there is a fraction to show.\n const hasReportedProgress = file.size > 0 && file.uploadedBytes > 0;\n\n return (\n <FileRow icon={<ArrowsCounterClockwise fill=\"secondary600\" />} fileName={file.name}>\n <Typography variant=\"pi\" textColor=\"neutral600\">\n {formatMessage({\n id: getTranslationKey('upload.progress.file.uploading'),\n defaultMessage: 'Uploading...',\n })}\n </Typography>\n {hasReportedProgress ? (\n <DeterminateBar percent={(file.uploadedBytes / file.size) * 100} />\n ) : (\n <IndeterminateBar />\n )}\n </FileRow>\n );\n }\n\n if (isError) {\n return (\n <FileRow icon={<CrossCircle fill=\"danger500\" />} fileName={file.name}>\n <Typography variant=\"pi\" textColor=\"neutral600\">\n {file.error\n ? /**\n * The server may return a machine-readable code (e.g. `FileTooBig` from the\n * body middleware) or an already human-readable sentence (e.g. the upload\n * plugin's size-limit message). Translate the former, fall back to the latter.\n */\n formatMessage({\n id: getTranslationKey(`apiError.${file.error}`),\n defaultMessage: file.error,\n })\n : formatMessage({\n id: getTranslationKey('upload.generic-error'),\n defaultMessage: 'An error occurred while uploading the file.',\n })}\n </Typography>\n </FileRow>\n );\n }\n\n if (isCancelled) {\n return (\n <FileRow icon={<MinusCircle fill=\"neutral600\" />} fileName={file.name}>\n <Typography variant=\"pi\" textColor=\"neutral600\">\n {formatMessage({\n id: getTranslationKey('upload.progress.file.canceled'),\n defaultMessage: 'Canceled',\n })}\n </Typography>\n </FileRow>\n );\n }\n\n if (isCompleted) {\n // The upload succeeded; the metadata phase (if any) drives both the icon and the\n // subline from here on — a metadata failure shows a warning, not an upload error.\n const { icon, message } = COMPLETED_ROW_PRESENTATION[file.metadataStatus ?? 'none'];\n\n return (\n <FileRow icon={icon} fileName={file.name}>\n <Typography variant=\"pi\" textColor=\"neutral600\">\n {formatMessage(message)}\n </Typography>\n {/* Generation has no intermediate progress to report, so the bar stays indeterminate. */}\n {file.metadataStatus === 'generating' && <IndeterminateBar />}\n </FileRow>\n );\n }\n\n return null;\n};\n\nconst CompletedFilesList = styled(Flex)`\n flex-direction: column;\n gap: ${({ theme }) => theme.spaces[2]};\n width: 100%;\n`;\n\nexport const UploadProgressDialog = () => {\n const dispatch = useTypedDispatch();\n const { isVisible, isMinimized, files } = useTypedSelector((state) => state.uploadProgress);\n\n // With concurrent uploads several files are `uploading` at once — render every\n // in-flight row, not just the first (a `find` here dated to the strictly\n // sequential era and hid all but the lowest-index worker's row).\n const uploadingFiles = files.filter((f) => f.status === 'uploading');\n // Everything the pool has not reached yet. Listed in queue order, which is the\n // order `files` is already in, so a row's position tells the user where it sits.\n const queuedFiles = files.filter((f) => f.status === 'pending');\n const completedFiles = files\n .filter((f) => f.status === 'complete' || f.status === 'error' || f.status === 'cancelled')\n .sort((a, b) => {\n // Sort priority: error > cancelled > complete\n const priority: Record<FileProgressStatus, number> = {\n error: 0,\n cancelled: 1,\n complete: 2,\n uploading: 3,\n pending: 4,\n };\n return priority[a.status] - priority[b.status];\n });\n\n const handleClose = () => {\n dispatch(closeUploadProgress());\n };\n\n return (\n <Drawer.Root isVisible={isVisible} onClose={handleClose}>\n <Drawer.Body animationDirection=\"up\" width=\"41.6rem\" maxHeight=\"34.2rem\">\n <DialogHeader handleClose={handleClose} />\n <Drawer.ScrollableContent isContentExpanded={!isMinimized}>\n <Flex\n direction=\"column\"\n alignItems=\"stretch\"\n gap={4}\n paddingTop={4}\n paddingBottom={4}\n paddingLeft={4}\n paddingRight={4}\n >\n {uploadingFiles.map((file) => (\n <FileRowRenderer key={file.index} file={file} />\n ))}\n\n {queuedFiles.map((file) => (\n <FileRowRenderer key={file.index} file={file} />\n ))}\n\n {completedFiles.length > 0 && (\n <CompletedFilesList>\n {completedFiles.map((file) => (\n <FileRowRenderer key={file.index} file={file} />\n ))}\n </CompletedFilesList>\n )}\n </Flex>\n </Drawer.ScrollableContent>\n </Drawer.Body>\n </Drawer.Root>\n );\n};\n"],"names":["HeaderStatusMessage","title","subtitle","metadataSubtitle","_jsxs","Flex","direction","alignItems","paddingLeft","paddingRight","paddingTop","paddingBottom","_jsx","Drawer","Title","Typography","variant","Description","textColor","HeaderStatusIcon","styled","theme","spaces","borderRadius","HeaderStatusWrapper","HeaderStatus","status","progress","totalFiles","successfulCount","errorCount","metadataProgress","isGeneratingMetadata","metadataOutcome","formatMessage","useIntl","id","getTranslationKey","defaultMessage","percentage","undefined","generated","failed","generatedCount","failedCount","count","background","Cross","fill","successCount","Check","MinusCircle","total","Math","round","Upload","HeaderIconButton","IconButton","ChevronWrapper","span","$isMinimized","HEADER_COLOR_MAP","uploading","canceled","success","error","DialogHeader","handleClose","isMinimized","files","uploadId","useTypedSelector","state","uploadProgress","aggregateProgress","selectAggregateProgress","reportsByteProgress","selectReportsByteProgress","countBasedProgress","selectCountBasedProgress","selectMetadataProgress","selectIsGeneratingMetadata","selectMetadataOutcome","dispatch","useTypedDispatch","retryCancelledFiles","useRetryCancelledFilesMutation","isComplete","length","every","f","isAllUploaded","isAllErrored","hasCancelledFiles","some","filter","isSuccess","handleCancel","abortUpload","cancelUpload","handleRetry","unwrap","handleToggleMinimize","toggleMinimize","justifyContent","margin","hasRadius","gap","TextButton","onClick","fontWeight","label","ChevronDown","CloseButton","onClose","ProgressTrack","div","colors","neutral200","ProgressIndicator","$percent","primary700","DeterminateBar","percent","clamped","min","max","role","aria-valuemin","aria-valuemax","aria-valuenow","INDETERMINATE_INDICATOR_WIDTH","indeterminateSlide","keyframes","IndeterminateIndicator","IndeterminateBar","FileRowName","FileRow","icon","fileName","children","width","TruncatedText","COMPLETED_ROW_PRESENTATION","none","CheckCircle","message","generating","Sparkle","skipped","Information","WarningCircle","FileRowRenderer","file","isError","isCurrentFile","isCompleted","isCancelled","isQueued","Clock","name","hasReportedProgress","size","uploadedBytes","ArrowsCounterClockwise","CrossCircle","metadataStatus","CompletedFilesList","UploadProgressDialog","isVisible","uploadingFiles","queuedFiles","completedFiles","sort","a","b","priority","cancelled","complete","pending","closeUploadProgress","Root","Body","animationDirection","maxHeight","ScrollableContent","isContentExpanded","map","index"],"mappings":";;;;;;;;;;;;;;;AAyCA;;qGAIA,MAAMA,sBAAsB,CAAC,EAC3BC,KAAK,EACLC,QAAQ,EACRC,gBAAgB,EAKjB,GAAA;AACC,IAAA,qBACEC,eAAA,CAACC,iBAAAA,EAAAA;QACCC,SAAAA,EAAU,QAAA;QACVC,UAAAA,EAAW,YAAA;QACXC,WAAAA,EAAa,CAAA;QACbC,YAAAA,EAAc,CAAA;QACdC,UAAAA,EAAY,CAAA;QACZC,aAAAA,EAAe,CAAA;;AAEf,0BAAAC,cAAA,CAACC,cAAOC,KAAK,EAAA;AACX,gBAAA,QAAA,gBAAAF,cAAA,CAACG,uBAAAA,EAAAA;oBAAWC,OAAAA,EAAQ,OAAA;AAASf,oBAAAA,QAAAA,EAAAA;;;AAE/B,0BAAAW,cAAA,CAACC,cAAOI,WAAW,EAAA;AACjB,gBAAA,QAAA,gBAAAL,cAAA,CAACG,uBAAAA,EAAAA;oBAAWC,OAAAA,EAAQ,IAAA;oBAAKE,SAAAA,EAAU,YAAA;AAChChB,oBAAAA,QAAAA,EAAAA;;;AAGJC,YAAAA,gBAAAA,kBACCS,cAAA,CAACG,uBAAAA,EAAAA;gBAAWC,OAAAA,EAAQ,IAAA;gBAAKE,SAAAA,EAAU,YAAA;AAChCf,gBAAAA,QAAAA,EAAAA;;;;AAKX,CAAA;AAEA,MAAMgB,gBAAAA,GAAmBC,uBAAAA,CAAOf,iBAAAA,CAAK;;WAE1B,EAAE,CAAC,EAAEgB,KAAK,EAAE,GAAKA,KAAAA,CAAMC,MAAM,CAAC,CAAA,CAAE,CAAC;AAC3B,iBAAA,EAAE,CAAC,EAAED,KAAK,EAAE,GAAK,CAAA,EAAGA,KAAAA,CAAME,YAAY,CAAC,KAAK,EAAEF,KAAAA,CAAME,YAAY,EAAE,CAAC;;;;;;AAMpF,CAAC;AAED,MAAMC,mBAAAA,GAAsBJ,uBAAAA,CAAOf,iBAAAA,CAAK;;AAExC,CAAC;AAuBD,MAAMoB,eAAe,CAAC,EACpBC,MAAM,EACNC,QAAQ,EACRC,UAAU,EACVC,eAAe,EACfC,UAAU,EACVC,gBAAgB,EAChBC,oBAAoB,EACpBC,eAAe,EACG,GAAA;IAClB,MAAM,EAAEC,aAAa,EAAE,GAAGC,iBAAAA,EAAAA;;;;;;;;;;IAW1B,MAAMhC,gBAAAA,GAAmB,CAAC,IAAA;QACxB,IAAI4B,gBAAAA,KAAqB,QAAQC,oBAAAA,EAAsB;AACrD,YAAA,OAAOE,aAAAA,CACL;AACEE,gBAAAA,EAAAA,EAAIC,8BAAAA,CAAkB,8CAAA,CAAA;gBACtBC,cAAAA,EAAgB;aAClB,EACA;gBAAEC,UAAAA,EAAYR;AAAiB,aAAA,CAAA;AAEnC,QAAA;AAEA,QAAA,IAAIE,oBAAoB,IAAA,EAAM;YAC5B,OAAOO,SAAAA;AACT,QAAA;;;;;QAMA,IAAIP,eAAAA,CAAgBQ,SAAS,KAAK,CAAA,EAAG;YACnC,OAAOD,SAAAA;AACT,QAAA;QAEA,IAAIP,eAAAA,CAAgBS,MAAM,GAAG,CAAA,EAAG;AAC9B,YAAA,OAAOR,aAAAA,CACL;AACEE,gBAAAA,EAAAA,EAAIC,8BAAAA,CAAkB,gDAAA,CAAA;gBACtBC,cAAAA,EAAgB;aAClB,EACA;AAAEK,gBAAAA,cAAAA,EAAgBV,gBAAgBQ,SAAS;AAAEG,gBAAAA,WAAAA,EAAaX,gBAAgBS;AAAO,aAAA,CAAA;AAErF,QAAA;AAEA,QAAA,OAAOR,aAAAA,CACL;AACEE,YAAAA,EAAAA,EAAIC,8BAAAA,CAAkB,6CAAA,CAAA;YACtBC,cAAAA,EACE;SACJ,EACA;AAAEO,YAAAA,KAAAA,EAAOZ,gBAAgBQ;AAAU,SAAA,CAAA;IAEvC,CAAA,GAAA;AAEA,IAAA,IAAIf,WAAW,OAAA,EAAS;AACtB,QAAA,qBACEtB,eAAA,CAACoB,mBAAAA,EAAAA;;8BACCZ,cAAA,CAACO,gBAAAA,EAAAA;oBAAiB2B,UAAAA,EAAW,WAAA;AAC3B,oBAAA,QAAA,gBAAAlC,cAAA,CAACmC,WAAAA,EAAAA;wBAAMC,IAAAA,EAAK;;;8BAEdpC,cAAA,CAACZ,mBAAAA,EAAAA;AACCC,oBAAAA,KAAAA,EAAOiC,aAAAA,CAAc;AACnBE,wBAAAA,EAAAA,EAAIC,8BAAAA,CAAkB,wBAAA,CAAA;wBACtBC,cAAAA,EAAgB;AAClB,qBAAA,CAAA;AACApC,oBAAAA,QAAAA,EAAUgC,aAAAA,CAAc;AACtBE,wBAAAA,EAAAA,EAAIC,8BAAAA,CAAkB,iCAAA,CAAA;wBACtBC,cAAAA,EAAgB;AAClB,qBAAA;;;;AAIR,IAAA;AAEA,IAAA,IAAIZ,WAAW,SAAA,EAAW;QACxB,MAAMxB,QAAAA,GACJ4B,UAAAA,GAAa,CAAA,GACTI,aAAAA,CACE;AACEE,YAAAA,EAAAA,EAAIC,8BAAAA,CAAkB,6CAAA,CAAA;YACtBC,cAAAA,EAAgB;SAClB,EACA;YAAEW,YAAAA,EAAcpB,eAAAA;AAAiBC,YAAAA;AAAW,SAAA,CAAA,GAE9CI,aAAAA,CACE;AACEE,YAAAA,EAAAA,EAAIC,8BAAAA,CAAkB,kCAAA,CAAA;YACtBC,cAAAA,EAAgB;SAClB,EACA;YAAEO,KAAAA,EAAOhB;AAAgB,SAAA,CAAA;AAGjC,QAAA,qBACEzB,eAAA,CAACoB,mBAAAA,EAAAA;;8BACCZ,cAAA,CAACO,gBAAAA,EAAAA;oBAAiB2B,UAAAA,EAAW,YAAA;AAC3B,oBAAA,QAAA,gBAAAlC,cAAA,CAACsC,WAAAA,EAAAA;wBAAMF,IAAAA,EAAK;;;8BAEdpC,cAAA,CAACZ,mBAAAA,EAAAA;AACCC,oBAAAA,KAAAA,EAAOiC,aAAAA,CAAc;AACnBE,wBAAAA,EAAAA,EAAIC,8BAAAA,CAAkB,yBAAA,CAAA;wBACtBC,cAAAA,EAAgB;AAClB,qBAAA,CAAA;oBACApC,QAAAA,EAAUA,QAAAA;oBACVC,gBAAAA,EAAkBA;;;;AAI1B,IAAA;AAEA,IAAA,IAAIuB,WAAW,UAAA,EAAY;AACzB,QAAA,qBACEtB,eAAA,CAACoB,mBAAAA,EAAAA;;8BACCZ,cAAA,CAACO,gBAAAA,EAAAA;oBAAiB2B,UAAAA,EAAW,YAAA;AAC3B,oBAAA,QAAA,gBAAAlC,cAAA,CAACuC,iBAAAA,EAAAA;wBAAYH,IAAAA,EAAK;;;8BAEpBpC,cAAA,CAACZ,mBAAAA,EAAAA;AACCC,oBAAAA,KAAAA,EAAOiC,aAAAA,CAAc;AACnBE,wBAAAA,EAAAA,EAAIC,8BAAAA,CAAkB,0BAAA,CAAA;wBACtBC,cAAAA,EAAgB;AAClB,qBAAA,CAAA;AACApC,oBAAAA,QAAAA,EAAUgC,aAAAA,CAAc;AACtBE,wBAAAA,EAAAA,EAAIC,8BAAAA,CAAkB,mCAAA,CAAA;wBACtBC,cAAAA,EAAgB;AAClB,qBAAA,CAAA;oBACAnC,gBAAAA,EAAkBA;;;;AAI1B,IAAA;AAEA,IAAA,IAAIuB,WAAW,WAAA,EAAa;;QAE1B,MAAMzB,KAAAA,GACJ0B,QAAAA,KAAa,IAAA,GACTO,aAAAA,CACE;AACEE,YAAAA,EAAAA,EAAIC,8BAAAA,CAAkB,yCAAA,CAAA;YACtBC,cAAAA,EAAgB;SAClB,EACA;YAAEc,KAAAA,EAAOxB;AAAW,SAAA,CAAA,GAEtBM,aAAAA,CACE;AACEE,YAAAA,EAAAA,EAAIC,8BAAAA,CAAkB,qCAAA,CAAA;YACtBC,cAAAA,EACE;SACJ,EACA;YACEc,KAAAA,EAAOxB,UAAAA;YACPW,UAAAA,EAAYc,IAAAA,CAAKC,KAAK,CAAC3B,QAAAA;AACzB,SAAA,CAAA;AAGR,QAAA,qBACEvB,eAAA,CAACoB,mBAAAA,EAAAA;;8BACCZ,cAAA,CAACO,gBAAAA,EAAAA;oBAAiB2B,UAAAA,EAAW,YAAA;AAC3B,oBAAA,QAAA,gBAAAlC,cAAA,CAAC2C,YAAAA,EAAAA;wBAAOP,IAAAA,EAAK;;;8BAEfpC,cAAA,CAACZ,mBAAAA,EAAAA;oBAAoBC,KAAAA,EAAOA,KAAAA;oBAAOE,gBAAAA,EAAkBA;;;;AAG3D,IAAA;IAEA,OAAO,IAAA;AACT,CAAA;AAEA,MAAMqD,gBAAAA,GAAmBpC,uBAAAA,CAAOqC,uBAAAA,CAAW;;;;AAI3C,CAAC;AAED,MAAMC,cAAAA,GAAiBtC,uBAAAA,CAAOuC,IAA+B;;;AAGhD,aAAA,EAAE,CAAC,EAAEC,YAAY,EAAE,GAAMA,YAAAA,GAAe,mBAAmB,cAAA,CAAgB;AACxF,CAAC;AAED,MAAMC,gBAAAA,GAAmB;IACvBC,SAAAA,EAAW;QAAEhB,UAAAA,EAAY;AAAa,KAAA;IACtCiB,QAAAA,EAAU;QAAEjB,UAAAA,EAAY;AAAa,KAAA;IACrCkB,OAAAA,EAAS;QAAElB,UAAAA,EAAY;AAAa,KAAA;IACpCmB,KAAAA,EAAO;QAAEnB,UAAAA,EAAY;AAAY;AACnC,CAAA;AAEA,MAAMoB,YAAAA,GAAe,CAAC,EAAEC,WAAW,EAA+B,GAAA;IAChE,MAAM,EAAEjC,aAAa,EAAE,GAAGC,iBAAAA,EAAAA;AAE1B,IAAA,MAAM,EAAEiC,WAAW,EAAEC,KAAK,EAAEC,QAAQ,EAAE1C,UAAU,EAAE,GAAG2C,sBAAAA,CACnD,CAACC,KAAAA,GAAUA,MAAMC,cAAc,CAAA;AAEjC,IAAA,MAAMC,oBAAoBH,sBAAAA,CAAiBI,sCAAAA,CAAAA;AAC3C,IAAA,MAAMC,sBAAsBL,sBAAAA,CAAiBM,wCAAAA,CAAAA;AAC7C,IAAA,MAAMC,qBAAqBP,sBAAAA,CAAiBQ,uCAAAA,CAAAA;;;IAG5C,MAAMpD,QAAAA,GAAWiD,sBAAsBF,iBAAAA,GAAoBI,kBAAAA;AAC3D,IAAA,MAAM/C,mBAAmBwC,sBAAAA,CAAiBS,qCAAAA,CAAAA;AAC1C,IAAA,MAAMhD,uBAAuBuC,sBAAAA,CAAiBU,yCAAAA,CAAAA;AAC9C,IAAA,MAAMhD,kBAAkBsC,sBAAAA,CAAiBW,oCAAAA,CAAAA;AACzC,IAAA,MAAMC,QAAAA,GAAWC,sBAAAA,EAAAA;IACjB,MAAM,CAACC,oBAAoB,GAAGC,kCAAAA,EAAAA;;;IAI9B,MAAMC,UAAAA,GACJlB,MAAMmB,MAAM,GAAG,KACfnB,KAAAA,CAAMoB,KAAK,CAAC,CAACC,CAAAA,GAAMA,EAAEhE,MAAM,KAAK,cAAcgE,CAAAA,CAAEhE,MAAM,KAAK,OAAA,IAAWgE,CAAAA,CAAEhE,MAAM,KAAK,WAAA,CAAA;AACrF,IAAA,MAAMiE,aAAAA,GAAgBJ,UAAAA;IACtB,MAAMK,YAAAA,GAAeL,cAAclB,KAAAA,CAAMoB,KAAK,CAAC,CAACC,CAAAA,GAAMA,CAAAA,CAAEhE,MAAM,KAAK,OAAA,CAAA;IACnE,MAAMmE,iBAAAA,GAAoBxB,MAAMyB,IAAI,CAAC,CAACJ,CAAAA,GAAMA,CAAAA,CAAEhE,MAAM,KAAK,WAAA,CAAA;IACzD,MAAMG,eAAAA,GAAkBwC,KAAAA,CAAM0B,MAAM,CAAC,CAACL,IAAMA,CAAAA,CAAEhE,MAAM,KAAK,UAAA,CAAA,CAAY8D,MAAM;IAC3E,MAAM1D,UAAAA,GAAauC,KAAAA,CAAM0B,MAAM,CAAC,CAACL,IAAMA,CAAAA,CAAEhE,MAAM,KAAK,OAAA,CAAA,CAAS8D,MAAM;;AAEnE,IAAA,MAAMQ,SAAAA,GAAYT,UAAAA,IAAc1D,eAAAA,GAAkB,CAAA,IAAK,CAACgE,iBAAAA;IACxD,MAAMnE,MAAAA,GAAS,CAAC,IAAA;AACd,QAAA,IAAIkE,cAAc,OAAO,OAAA;AACzB,QAAA,IAAII,WAAW,OAAO,SAAA;AACtB,QAAA,IAAIH,mBAAmB,OAAO,UAAA;QAE9B,OAAO,WAAA;IACT,CAAA,GAAA;AAEA,IAAA,MAAMI,YAAAA,GAAe,IAAA;QACnBC,eAAAA,CAAY5B,QAAAA,CAAAA;QACZa,QAAAA,CAASgB,2BAAAA,EAAAA,CAAAA;AACX,IAAA,CAAA;AAEA,IAAA,MAAMC,WAAAA,GAAc,UAAA;QAClB,IAAI;AACF,YAAA,MAAMf,sBAAsBgB,MAAM,EAAA;AACpC,QAAA,CAAA,CAAE,OAAM;;AAER,QAAA;AACF,IAAA,CAAA;AAEA,IAAA,MAAMC,oBAAAA,GAAuB,IAAA;QAC3BnB,QAAAA,CAASoB,6BAAAA,EAAAA,CAAAA;AACX,IAAA,CAAA;AAEA,IAAA,qBACEnG,eAAA,CAACC,iBAAAA,EAAAA;AACCyC,QAAAA,UAAAA,EAAYe,gBAAgB,CAACnC,MAAAA,CAAO,CAACoB,UAAU;QAC/C0D,cAAAA,EAAe,eAAA;QACfC,MAAAA,EAAQ,CAAA;QACRC,SAAS,EAAA,IAAA;;0BAET9F,cAAA,CAACa,YAAAA,EAAAA;gBACCC,MAAAA,EAAQA,MAAAA;gBACRC,QAAAA,EAAUA,QAAAA;gBACVC,UAAAA,EAAYA,UAAAA;gBACZC,eAAAA,EAAiBA,eAAAA;gBACjBC,UAAAA,EAAYA,UAAAA;gBACZC,gBAAAA,EAAkBA,gBAAAA;gBAClBC,oBAAAA,EAAsBA,oBAAAA;gBACtBC,eAAAA,EAAiBA;;0BAEnB7B,eAAA,CAACC,iBAAAA,EAAAA;gBAAKsG,GAAAA,EAAK,CAAA;;AACR,oBAAA,CAAChB,+BACA/E,cAAA,CAACgG,uBAAAA,EAAAA;wBAAWC,OAAAA,EAASZ,YAAAA;wBAAca,UAAAA,EAAW,MAAA;kCAC3C5E,aAAAA,CAAc;AACbE,4BAAAA,EAAAA,EAAIC,8BAAAA,CAAkB,wBAAA,CAAA;4BACtBC,cAAAA,EAAgB;AAClB,yBAAA;;AAGHuD,oBAAAA,iBAAAA,kBACCjF,cAAA,CAACgG,uBAAAA,EAAAA;wBAAWC,OAAAA,EAAST,WAAAA;wBAAaU,UAAAA,EAAW,MAAA;kCAC1C5E,aAAAA,CAAc;AACbE,4BAAAA,EAAAA,EAAIC,8BAAAA,CAAkB,uBAAA,CAAA;4BACtBC,cAAAA,EAAgB;AAClB,yBAAA;;kCAGJ1B,cAAA,CAAC4C,gBAAAA,EAAAA;wBACCqD,OAAAA,EAASP,oBAAAA;AACTS,wBAAAA,KAAAA,EAAO7E,aAAAA,CAAc;4BACnBE,EAAAA,EAAIC,8BAAAA,CACF+B,cAAc,0BAAA,GAA6B,0BAAA,CAAA;AAE7C9B,4BAAAA,cAAAA,EAAgB8B,cAAc,UAAA,GAAa;AAC7C,yBAAA,CAAA;wBACApD,OAAAA,EAAQ,OAAA;AAER,wBAAA,QAAA,gBAAAJ,cAAA,CAAC8C,cAAAA,EAAAA;4BAAeE,YAAAA,EAAcQ,WAAAA;AAC5B,4BAAA,QAAA,gBAAAxD,cAAA,CAACoG,iBAAAA,EAAAA,EAAAA;;;oBAGJzB,UAAAA,kBACC3E,cAAA,CAACC,cAAOoG,WAAW,EAAA;wBACjBC,OAAAA,EAAS/C,WAAAA;AACT4C,wBAAAA,KAAAA,EAAO7E,aAAAA,CAAc;AACnBE,4BAAAA,EAAAA,EAAIC,8BAAAA,CAAkB,uBAAA,CAAA;4BACtBC,cAAAA,EAAgB;AAClB,yBAAA;;;;;;AAMZ,CAAA;AAEA;;AAEkG,qGAElG,MAAM6E,aAAAA,GAAgB/F,uBAAAA,CAAOgG,GAAG;;UAEtB,EAAE,CAAC,EAAE/F,KAAK,EAAE,GAAKA,KAAAA,CAAMC,MAAM,CAAC,CAAA,CAAE,CAAC;oBACvB,EAAE,CAAC,EAAED,KAAK,EAAE,GAAKA,KAAAA,CAAMgG,MAAM,CAACC,UAAU,CAAC;;;AAG7D,CAAC;AAED,MAAMC,iBAAAA,GAAoBnG,uBAAAA,CAAOgG,GAAyB;;AAEjD,SAAA,EAAE,CAAC,EAAEI,QAAQ,EAAE,GAAKA,QAAAA,CAAS;oBAClB,EAAE,CAAC,EAAEnG,KAAK,EAAE,GAAKA,KAAAA,CAAMgG,MAAM,CAACI,UAAU,CAAC;;;AAG7D,CAAC;AAED,MAAMC,cAAAA,GAAiB,CAAC,EAAEC,OAAO,EAAuB,GAAA;IACtD,MAAMC,OAAAA,GAAUvE,IAAAA,CAAKwE,GAAG,CAAC,GAAA,EAAKxE,IAAAA,CAAKyE,GAAG,CAAC,CAAA,EAAGzE,IAAAA,CAAKC,KAAK,CAACqE,OAAAA,CAAAA,CAAAA,CAAAA;AACrD,IAAA,qBACE/G,cAAA,CAACuG,aAAAA,EAAAA;QAAcY,IAAAA,EAAK,aAAA;QAAcC,eAAAA,EAAe,CAAA;QAAGC,eAAAA,EAAe,GAAA;QAAKC,eAAAA,EAAeN,OAAAA;AACrF,QAAA,QAAA,gBAAAhH,cAAA,CAAC2G,iBAAAA,EAAAA;YAAkBC,QAAAA,EAAUI;;;AAGnC,CAAA;AAEA,MAAMO,6BAAAA,GAAgC,EAAA;AAEtC;;;;;;IAOA,MAAMC,kBAAAA,GAAqBC,0BAAS;;;;;0BAKV,EAAG,GAAA,GAAMF,6BAAAA,GAAiC,GAAA,CAAI;;AAExE,CAAC;AAED,MAAMG,sBAAAA,GAAyBlH,uBAAAA,CAAOgG,GAAG;;AAEhC,SAAA,EAAEe,6BAAAA,CAA8B;oBACrB,EAAE,CAAC,EAAE9G,KAAK,EAAE,GAAKA,KAAAA,CAAMgG,MAAM,CAACI,UAAU,CAAC;;;;AAIhD,aAAA,EAAEW,kBAAAA,CAAmB;;;;;;;;AAQlC,CAAC;AAED;;;;;;;AAOC,IACD,MAAMG,gBAAAA,GAAmB,IAAA;AACvB,IAAA,qBACE3H,cAAA,CAACuG,aAAAA,EAAAA;QAAcY,IAAAA,EAAK,aAAA;QAAcC,eAAAA,EAAe,CAAA;QAAGC,eAAAA,EAAe,GAAA;AACjE,QAAA,QAAA,gBAAArH,cAAA,CAAC0H,sBAAAA,EAAAA,EAAAA;;AAGP,CAAA;AAEA;;;;;;;;AAQC,IACD,MAAME,WAAAA,GAAcpH,uBAAAA,CAAOf,iBAAAA,CAAK;;;;;;;;;;AAUhC,CAAC;AAED,MAAMoI,OAAAA,GAAU,CAAC,EACfC,IAAI,EACJC,QAAQ,EACRC,QAAQ,EAKT,GAAA;AACC,IAAA,qBACExI,eAAA,CAACC,iBAAAA,EAAAA;QAAKC,SAAAA,EAAU,QAAA;QAASC,UAAAA,EAAW,SAAA;QAAUiG,cAAAA,EAAe,QAAA;QAASG,GAAAA,EAAK,CAAA;QAAGkC,KAAAA,EAAM,MAAA;;0BAClFzI,eAAA,CAACoI,WAAAA,EAAAA;gBAAY7B,GAAAA,EAAK,CAAA;;AACf+B,oBAAAA,IAAAA;kCACD9H,cAAA,CAACkI,2BAAAA,EAAAA;wBAAc9H,OAAAA,EAAQ,OAAA;wBAAQ8F,UAAAA,EAAW,UAAA;AACvC6B,wBAAAA,QAAAA,EAAAA;;;;AAGJC,YAAAA;;;AAGP,CAAA;AAEA;;;;;;;;;AASC,IACD,MAAMG,0BAAAA,GAGF;IACFC,IAAAA,EAAM;AACJN,QAAAA,IAAAA,gBAAM9H,cAAA,CAACqI,iBAAAA,EAAAA;YAAYjG,IAAAA,EAAK;;QACxBkG,OAAAA,EAAS;AACP9G,YAAAA,EAAAA,EAAIC,8BAAAA,CAAkB,+BAAA,CAAA;YACtBC,cAAAA,EAAgB;AAClB;AACF,KAAA;IACA6G,UAAAA,EAAY;AACVT,QAAAA,IAAAA,gBAAM9H,cAAA,CAACwI,aAAAA,EAAAA;YAAQpG,IAAAA,EAAK;;QACpBkG,OAAAA,EAAS;AACP9G,YAAAA,EAAAA,EAAIC,8BAAAA,CAAkB,yCAAA,CAAA;YACtBC,cAAAA,EAAgB;AAClB;AACF,KAAA;IACAG,SAAAA,EAAW;AACTiG,QAAAA,IAAAA,gBAAM9H,cAAA,CAACqI,iBAAAA,EAAAA;YAAYjG,IAAAA,EAAK;;QACxBkG,OAAAA,EAAS;AACP9G,YAAAA,EAAAA,EAAIC,8BAAAA,CAAkB,wCAAA,CAAA;YACtBC,cAAAA,EAAgB;AAClB;AACF,KAAA;IACA+G,OAAAA,EAAS;AACPX,QAAAA,IAAAA,gBAAM9H,cAAA,CAAC0I,iBAAAA,EAAAA;YAAYtG,IAAAA,EAAK;;QACxBkG,OAAAA,EAAS;AACP9G,YAAAA,EAAAA,EAAIC,8BAAAA,CAAkB,sCAAA,CAAA;YACtBC,cAAAA,EAAgB;AAClB;AACF,KAAA;IACAI,MAAAA,EAAQ;AACNgG,QAAAA,IAAAA,gBAAM9H,cAAA,CAAC2I,mBAAAA,EAAAA;YAAcvG,IAAAA,EAAK;;QAC1BkG,OAAAA,EAAS;AACP9G,YAAAA,EAAAA,EAAIC,8BAAAA,CAAkB,qCAAA,CAAA;YACtBC,cAAAA,EAAgB;AAClB;AACF;AACF,CAAA;AAEA,MAAMkH,eAAAA,GAAkB,CAAC,EAAEC,IAAI,EAA0B,GAAA;IACvD,MAAM,EAAEvH,aAAa,EAAE,GAAGC,iBAAAA,EAAAA;IAC1B,MAAMuH,OAAAA,GAAUD,IAAAA,CAAK/H,MAAM,KAAK,OAAA;IAChC,MAAMiI,aAAAA,GAAgBF,IAAAA,CAAK/H,MAAM,KAAK,WAAA;IACtC,MAAMkI,WAAAA,GAAcH,IAAAA,CAAK/H,MAAM,KAAK,UAAA;IACpC,MAAMmI,WAAAA,GAAcJ,IAAAA,CAAK/H,MAAM,KAAK,WAAA;IACpC,MAAMoI,QAAAA,GAAWL,IAAAA,CAAK/H,MAAM,KAAK,SAAA;AAEjC,IAAA,IAAIoI,QAAAA,EAAU;;;AAGZ,QAAA,qBACElJ,cAAA,CAAC6H,OAAAA,EAAAA;AAAQC,YAAAA,IAAAA,gBAAM9H,cAAA,CAACmJ,WAAAA,EAAAA;gBAAM/G,IAAAA,EAAK;;AAAiB2F,YAAAA,QAAAA,EAAUc,KAAKO,IAAI;AAC7D,YAAA,QAAA,gBAAApJ,cAAA,CAACG,uBAAAA,EAAAA;gBAAWC,OAAAA,EAAQ,IAAA;gBAAKE,SAAAA,EAAU,YAAA;0BAChCgB,aAAAA,CAAc;AACbE,oBAAAA,EAAAA,EAAIC,8BAAAA,CAAkB,6BAAA,CAAA;oBACtBC,cAAAA,EAAgB;AAClB,iBAAA;;;AAIR,IAAA;AAEA,IAAA,IAAIqH,aAAAA,EAAe;;;;;;;;;;AAUjB,QAAA,MAAMM,sBAAsBR,IAAAA,CAAKS,IAAI,GAAG,CAAA,IAAKT,IAAAA,CAAKU,aAAa,GAAG,CAAA;AAElE,QAAA,qBACE/J,eAAA,CAACqI,OAAAA,EAAAA;AAAQC,YAAAA,IAAAA,gBAAM9H,cAAA,CAACwJ,4BAAAA,EAAAA;gBAAuBpH,IAAAA,EAAK;;AAAmB2F,YAAAA,QAAAA,EAAUc,KAAKO,IAAI;;8BAChFpJ,cAAA,CAACG,uBAAAA,EAAAA;oBAAWC,OAAAA,EAAQ,IAAA;oBAAKE,SAAAA,EAAU,YAAA;8BAChCgB,aAAAA,CAAc;AACbE,wBAAAA,EAAAA,EAAIC,8BAAAA,CAAkB,gCAAA,CAAA;wBACtBC,cAAAA,EAAgB;AAClB,qBAAA;;AAED2H,gBAAAA,mBAAAA,iBACCrJ,cAAA,CAAC8G,cAAAA,EAAAA;AAAeC,oBAAAA,OAAAA,EAAS,IAAC8B,CAAKU,aAAa,GAAGV,IAAAA,CAAKS,IAAI,GAAI;mCAE5DtJ,cAAA,CAAC2H,gBAAAA,EAAAA,EAAAA;;;AAIT,IAAA;AAEA,IAAA,IAAImB,OAAAA,EAAS;AACX,QAAA,qBACE9I,cAAA,CAAC6H,OAAAA,EAAAA;AAAQC,YAAAA,IAAAA,gBAAM9H,cAAA,CAACyJ,iBAAAA,EAAAA;gBAAYrH,IAAAA,EAAK;;AAAgB2F,YAAAA,QAAAA,EAAUc,KAAKO,IAAI;AAClE,YAAA,QAAA,gBAAApJ,cAAA,CAACG,uBAAAA,EAAAA;gBAAWC,OAAAA,EAAQ,IAAA;gBAAKE,SAAAA,EAAU,YAAA;AAChCuI,gBAAAA,QAAAA,EAAAA,IAAAA,CAAKxF,KAAK;;;;AAKN,kBACD/B,aAAAA,CAAc;AACZE,oBAAAA,EAAAA,EAAIC,+BAAkB,CAAC,SAAS,EAAEoH,IAAAA,CAAKxF,KAAK,CAAA,CAAE,CAAA;AAC9C3B,oBAAAA,cAAAA,EAAgBmH,KAAKxF;AACvB,iBAAA,CAAA,GACA/B,aAAAA,CAAc;AACZE,oBAAAA,EAAAA,EAAIC,8BAAAA,CAAkB,sBAAA,CAAA;oBACtBC,cAAAA,EAAgB;AAClB,iBAAA;;;AAIZ,IAAA;AAEA,IAAA,IAAIuH,WAAAA,EAAa;AACf,QAAA,qBACEjJ,cAAA,CAAC6H,OAAAA,EAAAA;AAAQC,YAAAA,IAAAA,gBAAM9H,cAAA,CAACuC,iBAAAA,EAAAA;gBAAYH,IAAAA,EAAK;;AAAiB2F,YAAAA,QAAAA,EAAUc,KAAKO,IAAI;AACnE,YAAA,QAAA,gBAAApJ,cAAA,CAACG,uBAAAA,EAAAA;gBAAWC,OAAAA,EAAQ,IAAA;gBAAKE,SAAAA,EAAU,YAAA;0BAChCgB,aAAAA,CAAc;AACbE,oBAAAA,EAAAA,EAAIC,8BAAAA,CAAkB,+BAAA,CAAA;oBACtBC,cAAAA,EAAgB;AAClB,iBAAA;;;AAIR,IAAA;AAEA,IAAA,IAAIsH,WAAAA,EAAa;;;QAGf,MAAM,EAAElB,IAAI,EAAEQ,OAAO,EAAE,GAAGH,0BAA0B,CAACU,IAAAA,CAAKa,cAAc,IAAI,MAAA,CAAO;AAEnF,QAAA,qBACElK,eAAA,CAACqI,OAAAA,EAAAA;YAAQC,IAAAA,EAAMA,IAAAA;AAAMC,YAAAA,QAAAA,EAAUc,KAAKO,IAAI;;8BACtCpJ,cAAA,CAACG,uBAAAA,EAAAA;oBAAWC,OAAAA,EAAQ,IAAA;oBAAKE,SAAAA,EAAU,YAAA;8BAChCgB,aAAAA,CAAcgH,OAAAA;;gBAGhBO,IAAAA,CAAKa,cAAc,KAAK,YAAA,kBAAgB1J,cAAA,CAAC2H,gBAAAA,EAAAA,EAAAA;;;AAGhD,IAAA;IAEA,OAAO,IAAA;AACT,CAAA;AAEA,MAAMgC,kBAAAA,GAAqBnJ,uBAAAA,CAAOf,iBAAAA,CAAK;;OAEhC,EAAE,CAAC,EAAEgB,KAAK,EAAE,GAAKA,KAAAA,CAAMC,MAAM,CAAC,CAAA,CAAE,CAAC;;AAExC,CAAC;MAEYkJ,oBAAAA,GAAuB,IAAA;AAClC,IAAA,MAAMrF,QAAAA,GAAWC,sBAAAA,EAAAA;AACjB,IAAA,MAAM,EAAEqF,SAAS,EAAErG,WAAW,EAAEC,KAAK,EAAE,GAAGE,sBAAAA,CAAiB,CAACC,KAAAA,GAAUA,KAAAA,CAAMC,cAAc,CAAA;;;;IAK1F,MAAMiG,cAAAA,GAAiBrG,MAAM0B,MAAM,CAAC,CAACL,CAAAA,GAAMA,CAAAA,CAAEhE,MAAM,KAAK,WAAA,CAAA;;;IAGxD,MAAMiJ,WAAAA,GAActG,MAAM0B,MAAM,CAAC,CAACL,CAAAA,GAAMA,CAAAA,CAAEhE,MAAM,KAAK,SAAA,CAAA;IACrD,MAAMkJ,cAAAA,GAAiBvG,MACpB0B,MAAM,CAAC,CAACL,CAAAA,GAAMA,CAAAA,CAAEhE,MAAM,KAAK,UAAA,IAAcgE,EAAEhE,MAAM,KAAK,WAAWgE,CAAAA,CAAEhE,MAAM,KAAK,WAAA,CAAA,CAC9EmJ,IAAI,CAAC,CAACC,CAAAA,EAAGC,CAAAA,GAAAA;;AAER,QAAA,MAAMC,QAAAA,GAA+C;YACnD/G,KAAAA,EAAO,CAAA;YACPgH,SAAAA,EAAW,CAAA;YACXC,QAAAA,EAAU,CAAA;YACVpH,SAAAA,EAAW,CAAA;YACXqH,OAAAA,EAAS;AACX,SAAA;QACA,OAAOH,QAAQ,CAACF,CAAAA,CAAEpJ,MAAM,CAAC,GAAGsJ,QAAQ,CAACD,CAAAA,CAAErJ,MAAM,CAAC;AAChD,IAAA,CAAA,CAAA;AAEF,IAAA,MAAMyC,WAAAA,GAAc,IAAA;QAClBgB,QAAAA,CAASiG,kCAAAA,EAAAA,CAAAA;AACX,IAAA,CAAA;IAEA,qBACExK,cAAA,CAACC,cAAOwK,IAAI,EAAA;QAACZ,SAAAA,EAAWA,SAAAA;QAAWvD,OAAAA,EAAS/C,WAAAA;gCAC1C/D,eAAA,CAACS,cAAOyK,IAAI,EAAA;YAACC,kBAAAA,EAAmB,IAAA;YAAK1C,KAAAA,EAAM,SAAA;YAAU2C,SAAAA,EAAU,SAAA;;8BAC7D5K,cAAA,CAACsD,YAAAA,EAAAA;oBAAaC,WAAAA,EAAaA;;AAC3B,8BAAAvD,cAAA,CAACC,cAAO4K,iBAAiB,EAAA;AAACC,oBAAAA,iBAAAA,EAAmB,CAACtH,WAAAA;AAC5C,oBAAA,QAAA,gBAAAhE,eAAA,CAACC,iBAAAA,EAAAA;wBACCC,SAAAA,EAAU,QAAA;wBACVC,UAAAA,EAAW,SAAA;wBACXoG,GAAAA,EAAK,CAAA;wBACLjG,UAAAA,EAAY,CAAA;wBACZC,aAAAA,EAAe,CAAA;wBACfH,WAAAA,EAAa,CAAA;wBACbC,YAAAA,EAAc,CAAA;;AAEbiK,4BAAAA,cAAAA,CAAeiB,GAAG,CAAC,CAAClC,IAAAA,iBACnB7I,cAAA,CAAC4I,eAAAA,EAAAA;oCAAiCC,IAAAA,EAAMA;AAAlBA,iCAAAA,EAAAA,IAAAA,CAAKmC,KAAK,CAAA,CAAA;AAGjCjB,4BAAAA,WAAAA,CAAYgB,GAAG,CAAC,CAAClC,IAAAA,iBAChB7I,cAAA,CAAC4I,eAAAA,EAAAA;oCAAiCC,IAAAA,EAAMA;AAAlBA,iCAAAA,EAAAA,IAAAA,CAAKmC,KAAK,CAAA,CAAA;4BAGjChB,cAAAA,CAAepF,MAAM,GAAG,CAAA,kBACvB5E,cAAA,CAAC2J,kBAAAA,EAAAA;AACEK,gCAAAA,QAAAA,EAAAA,cAAAA,CAAee,GAAG,CAAC,CAAClC,IAAAA,iBACnB7I,cAAA,CAAC4I,eAAAA,EAAAA;wCAAiCC,IAAAA,EAAMA;AAAlBA,qCAAAA,EAAAA,IAAAA,CAAKmC,KAAK,CAAA;;;;;;;;AASlD;;;;"}
|
|
@@ -6,9 +6,10 @@ import { useIntl } from 'react-intl';
|
|
|
6
6
|
import { styled, keyframes } from 'styled-components';
|
|
7
7
|
import { useRetryCancelledFilesMutation, abortUpload } from '../services/api.mjs';
|
|
8
8
|
import { useTypedDispatch, useTypedSelector } from '../store/hooks.mjs';
|
|
9
|
-
import { closeUploadProgress, selectAggregateProgress, selectMetadataProgress, selectIsGeneratingMetadata, selectMetadataOutcome, cancelUpload, toggleMinimize } from '../store/uploadProgress.mjs';
|
|
9
|
+
import { closeUploadProgress, selectAggregateProgress, selectReportsByteProgress, selectCountBasedProgress, selectMetadataProgress, selectIsGeneratingMetadata, selectMetadataOutcome, cancelUpload, toggleMinimize } from '../store/uploadProgress.mjs';
|
|
10
10
|
import { getTranslationKey } from '../utils/translations.mjs';
|
|
11
11
|
import { Drawer } from './Drawer.mjs';
|
|
12
|
+
import { TruncatedText } from './TruncatedText.mjs';
|
|
12
13
|
|
|
13
14
|
/* -------------------------------------------------------------------------------------------------
|
|
14
15
|
* DialogHeader
|
|
@@ -17,6 +18,9 @@ import { Drawer } from './Drawer.mjs';
|
|
|
17
18
|
direction: "column",
|
|
18
19
|
alignItems: "flex-start",
|
|
19
20
|
paddingLeft: 2,
|
|
21
|
+
paddingRight: 2,
|
|
22
|
+
paddingTop: 1,
|
|
23
|
+
paddingBottom: 1,
|
|
20
24
|
children: [
|
|
21
25
|
/*#__PURE__*/ jsx(Drawer.Title, {
|
|
22
26
|
children: /*#__PURE__*/ jsx(Typography, {
|
|
@@ -40,6 +44,7 @@ import { Drawer } from './Drawer.mjs';
|
|
|
40
44
|
});
|
|
41
45
|
};
|
|
42
46
|
const HeaderStatusIcon = styled(Flex)`
|
|
47
|
+
align-self: stretch;
|
|
43
48
|
padding: ${({ theme })=>theme.spaces[3]};
|
|
44
49
|
border-radius: ${({ theme })=>`${theme.borderRadius} 0 0 ${theme.borderRadius}`};
|
|
45
50
|
|
|
@@ -175,7 +180,19 @@ const HeaderStatus = ({ status, progress, totalFiles, successfulCount, errorCoun
|
|
|
175
180
|
});
|
|
176
181
|
}
|
|
177
182
|
if (status === 'uploading') {
|
|
178
|
-
|
|
183
|
+
// Two separate strings so a locale can position (or omit) the percentage itself.
|
|
184
|
+
const title = progress === null ? formatMessage({
|
|
185
|
+
id: getTranslationKey('upload.progress.uploading.indeterminate'),
|
|
186
|
+
defaultMessage: 'Uploading {total, plural, one {# item} other {# items}}'
|
|
187
|
+
}, {
|
|
188
|
+
total: totalFiles
|
|
189
|
+
}) : formatMessage({
|
|
190
|
+
id: getTranslationKey('upload.progress.uploading.withCount'),
|
|
191
|
+
defaultMessage: 'Uploading {total, plural, one {# item} other {# items}} ({percentage}%)'
|
|
192
|
+
}, {
|
|
193
|
+
total: totalFiles,
|
|
194
|
+
percentage: Math.round(progress)
|
|
195
|
+
});
|
|
179
196
|
return /*#__PURE__*/ jsxs(HeaderStatusWrapper, {
|
|
180
197
|
children: [
|
|
181
198
|
/*#__PURE__*/ jsx(HeaderStatusIcon, {
|
|
@@ -185,13 +202,7 @@ const HeaderStatus = ({ status, progress, totalFiles, successfulCount, errorCoun
|
|
|
185
202
|
})
|
|
186
203
|
}),
|
|
187
204
|
/*#__PURE__*/ jsx(HeaderStatusMessage, {
|
|
188
|
-
title:
|
|
189
|
-
id: getTranslationKey('upload.progress.uploading.withCount'),
|
|
190
|
-
defaultMessage: 'Uploading {total} items ({percentage}%)'
|
|
191
|
-
}, {
|
|
192
|
-
total: totalFiles,
|
|
193
|
-
percentage: progressPercentage
|
|
194
|
-
}),
|
|
205
|
+
title: title,
|
|
195
206
|
metadataSubtitle: metadataSubtitle
|
|
196
207
|
})
|
|
197
208
|
]
|
|
@@ -226,7 +237,12 @@ const HEADER_COLOR_MAP = {
|
|
|
226
237
|
const DialogHeader = ({ handleClose })=>{
|
|
227
238
|
const { formatMessage } = useIntl();
|
|
228
239
|
const { isMinimized, files, uploadId, totalFiles } = useTypedSelector((state)=>state.uploadProgress);
|
|
229
|
-
const
|
|
240
|
+
const aggregateProgress = useTypedSelector(selectAggregateProgress);
|
|
241
|
+
const reportsByteProgress = useTypedSelector(selectReportsByteProgress);
|
|
242
|
+
const countBasedProgress = useTypedSelector(selectCountBasedProgress);
|
|
243
|
+
// Byte-weighted when the flow streams bytes (direct-file), else count-based (settled/total).
|
|
244
|
+
// Both return `null` for an indeterminate header when there's nothing to show yet.
|
|
245
|
+
const progress = reportsByteProgress ? aggregateProgress : countBasedProgress;
|
|
230
246
|
const metadataProgress = useTypedSelector(selectMetadataProgress);
|
|
231
247
|
const isGeneratingMetadata = useTypedSelector(selectIsGeneratingMetadata);
|
|
232
248
|
const metadataOutcome = useTypedSelector(selectMetadataOutcome);
|
|
@@ -395,6 +411,25 @@ const IndeterminateIndicator = styled.div`
|
|
|
395
411
|
children: /*#__PURE__*/ jsx(IndeterminateIndicator, {})
|
|
396
412
|
});
|
|
397
413
|
};
|
|
414
|
+
/**
|
|
415
|
+
* Without a floor of zero the row is as wide as its longest filename, which
|
|
416
|
+
* pushes past the panel and gives the dialog a second, horizontal scrollbar
|
|
417
|
+
* instead of truncating.
|
|
418
|
+
*
|
|
419
|
+
* The floor belongs to the name alone: the icon carries its size in SVG
|
|
420
|
+
* attributes, which flex is free to override, so letting it shrink squashes it
|
|
421
|
+
* against a long name instead of truncating the name.
|
|
422
|
+
*/ const FileRowName = styled(Flex)`
|
|
423
|
+
min-width: 0;
|
|
424
|
+
|
|
425
|
+
> :first-child {
|
|
426
|
+
flex-shrink: 0;
|
|
427
|
+
}
|
|
428
|
+
|
|
429
|
+
> :last-child {
|
|
430
|
+
min-width: 0;
|
|
431
|
+
}
|
|
432
|
+
`;
|
|
398
433
|
const FileRow = ({ icon, fileName, children })=>{
|
|
399
434
|
return /*#__PURE__*/ jsxs(Flex, {
|
|
400
435
|
direction: "column",
|
|
@@ -403,14 +438,13 @@ const FileRow = ({ icon, fileName, children })=>{
|
|
|
403
438
|
gap: 1,
|
|
404
439
|
width: "100%",
|
|
405
440
|
children: [
|
|
406
|
-
/*#__PURE__*/ jsxs(
|
|
441
|
+
/*#__PURE__*/ jsxs(FileRowName, {
|
|
407
442
|
gap: 2,
|
|
408
443
|
children: [
|
|
409
444
|
icon,
|
|
410
|
-
/*#__PURE__*/ jsx(
|
|
445
|
+
/*#__PURE__*/ jsx(TruncatedText, {
|
|
411
446
|
variant: "omega",
|
|
412
447
|
fontWeight: "semiBold",
|
|
413
|
-
ellipsis: true,
|
|
414
448
|
children: fileName
|
|
415
449
|
})
|
|
416
450
|
]
|