@aws-amplify/ui-react-storage 3.15.0 → 3.17.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.
Files changed (101) hide show
  1. package/dist/browser.js +1 -1
  2. package/dist/{createStorageBrowser-CG-6mXiT.js → createStorageBrowser-De4hcP-u.js} +710 -158
  3. package/dist/esm/browser.mjs +1 -0
  4. package/dist/esm/components/StorageBrowser/ErrorBoundary/ErrorBoundary.mjs +1 -4
  5. package/dist/esm/components/StorageBrowser/actions/configs/defaults.mjs +13 -3
  6. package/dist/esm/components/StorageBrowser/actions/handlers/delete.mjs +39 -8
  7. package/dist/esm/components/StorageBrowser/components/ComponentsProvider.mjs +1 -4
  8. package/dist/esm/components/StorageBrowser/components/base/preview/DownloadButton.mjs +1 -4
  9. package/dist/esm/components/StorageBrowser/components/composables/ActionConfirmationModal.mjs +34 -0
  10. package/dist/esm/components/StorageBrowser/components/composables/defaults.mjs +2 -0
  11. package/dist/esm/components/StorageBrowser/components/elements/definitions.mjs +2 -2
  12. package/dist/esm/components/StorageBrowser/configuration/paginationContext.mjs +15 -0
  13. package/dist/esm/components/StorageBrowser/controls/ActionConfirmationModalControl.mjs +12 -0
  14. package/dist/esm/components/StorageBrowser/controls/DataTableControl.mjs +1 -4
  15. package/dist/esm/components/StorageBrowser/controls/hooks/useActionConfirmationModal.mjs +17 -0
  16. package/dist/esm/components/StorageBrowser/createStorageBrowser/StorageBrowserDefault.mjs +9 -4
  17. package/dist/esm/components/StorageBrowser/createStorageBrowser/createProvider.mjs +11 -9
  18. package/dist/esm/components/StorageBrowser/createStorageBrowser/createStorageBrowser.mjs +10 -5
  19. package/dist/esm/components/StorageBrowser/displayText/libraries/en/deleteView.mjs +117 -5
  20. package/dist/esm/components/StorageBrowser/displayText/libraries/en/locationDetailView.mjs +1 -0
  21. package/dist/esm/components/StorageBrowser/displayText/libraries/en/shared.mjs +1 -0
  22. package/dist/esm/components/StorageBrowser/locationItems/context.mjs +17 -14
  23. package/dist/esm/components/StorageBrowser/locationItems/utils.mjs +38 -0
  24. package/dist/esm/components/StorageBrowser/store/validateStoreProps.mjs +1 -1
  25. package/dist/esm/components/StorageBrowser/tasks/useProcessTasks.mjs +7 -4
  26. package/dist/esm/components/StorageBrowser/useAction/useHandler.mjs +1 -0
  27. package/dist/esm/components/StorageBrowser/useAction/useListFolderItems.mjs +1 -0
  28. package/dist/esm/components/StorageBrowser/useAction/useListLocationItems.mjs +1 -0
  29. package/dist/esm/components/StorageBrowser/useAction/utils.mjs +0 -5
  30. package/dist/esm/components/StorageBrowser/utils/validatePageSize.mjs +12 -0
  31. package/dist/esm/components/StorageBrowser/views/LocationActionView/CopyView/CopyView.mjs +1 -4
  32. package/dist/esm/components/StorageBrowser/views/LocationActionView/CopyView/CopyViewProvider.mjs +5 -4
  33. package/dist/esm/components/StorageBrowser/views/LocationActionView/CopyView/FoldersMessageControl.mjs +1 -4
  34. package/dist/esm/components/StorageBrowser/views/LocationActionView/CopyView/useCopyView.mjs +1 -4
  35. package/dist/esm/components/StorageBrowser/views/LocationActionView/CopyView/useFolders.mjs +1 -4
  36. package/dist/esm/components/StorageBrowser/views/LocationActionView/CreateFolderView/CreateFolderView.mjs +1 -4
  37. package/dist/esm/components/StorageBrowser/views/LocationActionView/CreateFolderView/useCreateFolderView.mjs +1 -4
  38. package/dist/esm/components/StorageBrowser/views/LocationActionView/DeleteView/DeleteView.mjs +6 -6
  39. package/dist/esm/components/StorageBrowser/views/LocationActionView/DeleteView/DeleteViewProvider.mjs +7 -6
  40. package/dist/esm/components/StorageBrowser/views/LocationActionView/DeleteView/useDeleteView.mjs +70 -7
  41. package/dist/esm/components/StorageBrowser/views/LocationActionView/DeleteView/utils.mjs +87 -0
  42. package/dist/esm/components/StorageBrowser/views/LocationActionView/DownloadView/DownloadView.mjs +1 -4
  43. package/dist/esm/components/StorageBrowser/views/LocationActionView/DownloadView/DownloadViewProvider.mjs +9 -0
  44. package/dist/esm/components/StorageBrowser/views/LocationActionView/DownloadView/useDownloadView.mjs +1 -4
  45. package/dist/esm/components/StorageBrowser/views/LocationActionView/UploadView/UploadView.mjs +3 -6
  46. package/dist/esm/components/StorageBrowser/views/LocationActionView/UploadView/UploadViewProvider.mjs +3 -0
  47. package/dist/esm/components/StorageBrowser/views/LocationActionView/UploadView/useUploadView.mjs +11 -12
  48. package/dist/esm/components/StorageBrowser/views/LocationDetailView/LocationDetailView.mjs +1 -4
  49. package/dist/esm/components/StorageBrowser/views/LocationDetailView/LocationDetailViewProvider.mjs +2 -1
  50. package/dist/esm/components/StorageBrowser/views/LocationDetailView/getLocationDetailViewTableData/getFolderRowContent.mjs +38 -27
  51. package/dist/esm/components/StorageBrowser/views/LocationDetailView/getLocationDetailViewTableData/getLocationDetailViewTableData.mjs +8 -1
  52. package/dist/esm/components/StorageBrowser/views/LocationDetailView/useLocationDetailView.mjs +24 -20
  53. package/dist/esm/components/StorageBrowser/views/LocationsView/LocationsView.mjs +1 -4
  54. package/dist/esm/components/StorageBrowser/views/LocationsView/LocationsViewProvider.mjs +1 -4
  55. package/dist/esm/components/StorageBrowser/views/LocationsView/useLocationsView.mjs +13 -10
  56. package/dist/esm/components/StorageBrowser/views/context/actionViews.mjs +12 -8
  57. package/dist/esm/components/StorageBrowser/views/context/primaryViews.mjs +9 -4
  58. package/dist/esm/components/StorageBrowser/views/hooks/usePaginate.mjs +18 -7
  59. package/dist/esm/components/StorageBrowser/views/utils/tableResolvers/constants.mjs +10 -1
  60. package/dist/esm/components/StorageBrowser/views/utils/tableResolvers/deleteResolvers.mjs +123 -13
  61. package/dist/esm/components/StorageBrowser/views/utils/tableResolvers/utils.mjs +3 -3
  62. package/dist/esm/version.mjs +1 -1
  63. package/dist/index.js +1 -1
  64. package/dist/styles.css +83 -1
  65. package/dist/types/components/StorageBrowser/StorageBrowserAmplify.d.ts +3 -1
  66. package/dist/types/components/StorageBrowser/actions/handlers/delete.d.ts +5 -3
  67. package/dist/types/components/StorageBrowser/actions/handlers/types.d.ts +15 -1
  68. package/dist/types/components/StorageBrowser/components/composables/ActionConfirmationModal.d.ts +12 -0
  69. package/dist/types/components/StorageBrowser/components/composables/types.d.ts +2 -0
  70. package/dist/types/components/StorageBrowser/configuration/index.d.ts +2 -0
  71. package/dist/types/components/StorageBrowser/configuration/paginationContext.d.ts +12 -0
  72. package/dist/types/components/StorageBrowser/controls/ActionConfirmationModalControl.d.ts +2 -0
  73. package/dist/types/components/StorageBrowser/controls/hooks/useActionConfirmationModal.d.ts +2 -0
  74. package/dist/types/components/StorageBrowser/controls/index.d.ts +1 -0
  75. package/dist/types/components/StorageBrowser/controls/types.d.ts +4 -0
  76. package/dist/types/components/StorageBrowser/createStorageBrowser/types.d.ts +7 -1
  77. package/dist/types/components/StorageBrowser/displayText/types.d.ts +7 -0
  78. package/dist/types/components/StorageBrowser/locationItems/context.d.ts +12 -3
  79. package/dist/types/components/StorageBrowser/locationItems/index.d.ts +1 -0
  80. package/dist/types/components/StorageBrowser/locationItems/utils.d.ts +27 -0
  81. package/dist/types/components/StorageBrowser/store/types.d.ts +7 -0
  82. package/dist/types/components/StorageBrowser/tasks/types.d.ts +7 -2
  83. package/dist/types/components/StorageBrowser/utils/index.d.ts +1 -0
  84. package/dist/types/components/StorageBrowser/utils/validatePageSize.d.ts +1 -0
  85. package/dist/types/components/StorageBrowser/views/LocationActionView/DeleteView/types.d.ts +5 -0
  86. package/dist/types/components/StorageBrowser/views/LocationActionView/DeleteView/utils.d.ts +26 -0
  87. package/dist/types/components/StorageBrowser/views/LocationActionView/UploadView/types.d.ts +7 -0
  88. package/dist/types/components/StorageBrowser/views/LocationDetailView/getLocationDetailViewTableData/getFolderRowContent.d.ts +4 -1
  89. package/dist/types/components/StorageBrowser/views/LocationDetailView/getLocationDetailViewTableData/getLocationDetailViewTableData.d.ts +3 -2
  90. package/dist/types/components/StorageBrowser/views/LocationDetailView/types.d.ts +10 -3
  91. package/dist/types/components/StorageBrowser/views/LocationsView/types.d.ts +2 -2
  92. package/dist/types/components/StorageBrowser/views/hooks/usePaginate.d.ts +1 -1
  93. package/dist/types/components/StorageBrowser/views/types.d.ts +6 -0
  94. package/dist/types/components/StorageBrowser/views/utils/index.d.ts +1 -1
  95. package/dist/types/components/StorageBrowser/views/utils/tableResolvers/constants.d.ts +1 -0
  96. package/dist/types/components/StorageBrowser/views/utils/tableResolvers/deleteResolvers.d.ts +5 -2
  97. package/dist/types/components/StorageBrowser/views/utils/tableResolvers/index.d.ts +1 -1
  98. package/dist/types/components/StorageBrowser/views/utils/tableResolvers/types.d.ts +4 -0
  99. package/dist/types/index.d.ts +1 -1
  100. package/dist/types/version.d.ts +1 -1
  101. package/package.json +7 -7
@@ -99,16 +99,19 @@ function useProcessTasks(handler, options) {
99
99
  const getTask = () => tasksRef.current.get(data.id);
100
100
  const { options } = _input;
101
101
  const { onProgress: _onProgress } = options ?? {};
102
- const onProgress = ({ id }, progress, status = 'PENDING') => {
102
+ const onProgress = ({ id }, progressDetails, status = 'PENDING') => {
103
+ const isNumber = typeof progressDetails === 'number';
103
104
  const task = updateTask(id, {
104
- progress,
105
+ progress: isNumber ? progressDetails : progressDetails.progress,
106
+ failureCount: isNumber ? undefined : progressDetails.failureCount,
107
+ successCount: isNumber ? undefined : progressDetails.successCount,
105
108
  status,
106
109
  });
107
110
  if (task && isFunction(onTaskProgress)) {
108
- onTaskProgress(task, progress);
111
+ onTaskProgress(task, progressDetails);
109
112
  }
110
113
  if (task && isFunction(_onProgress)) {
111
- _onProgress(data, progress, status);
114
+ _onProgress(data, progressDetails, status);
112
115
  }
113
116
  };
114
117
  const input = { ..._input, data, all, options: { ...options, onProgress } };
@@ -3,6 +3,7 @@ import '@aws-amplify/ui-react-core/elements';
3
3
  import '../credentials/context.mjs';
4
4
  import '@aws-amplify/storage/internals';
5
5
  import { useGetActionInput } from '../configuration/context.mjs';
6
+ import '../configuration/paginationContext.mjs';
6
7
  import { DEFAULT_ACTION_CONCURRENCY } from './constants.mjs';
7
8
  import { useProcessTasks } from '../tasks/useProcessTasks.mjs';
8
9
 
@@ -7,6 +7,7 @@ import '@aws-amplify/ui-react-core/elements';
7
7
  import '../credentials/context.mjs';
8
8
  import '@aws-amplify/storage/internals';
9
9
  import { useGetActionInput } from '../configuration/context.mjs';
10
+ import '../configuration/paginationContext.mjs';
10
11
 
11
12
  const useListFolderItems = () => {
12
13
  const { handlers } = useActionHandlers({
@@ -4,6 +4,7 @@ import '@aws-amplify/ui-react-core/elements';
4
4
  import '../credentials/context.mjs';
5
5
  import '@aws-amplify/storage/internals';
6
6
  import { useGetActionInput } from '../configuration/context.mjs';
7
+ import '../configuration/paginationContext.mjs';
7
8
  import { USE_LIST_ERROR_MESSAGE } from './constants.mjs';
8
9
  import { useActionHandlers } from './context.mjs';
9
10
  import { createEnhancedListHandler } from './createEnhancedListHandler.mjs';
@@ -1,9 +1,4 @@
1
1
  import { isFunction } from '@aws-amplify/ui';
2
- import '@aws-amplify/storage/internals';
3
- import 'aws-amplify';
4
- import 'jszip';
5
- import 'aws-amplify/storage';
6
- import '../actions/configs/context.mjs';
7
2
  import { isDefaultActionViewType } from '../actions/configs/defaults.mjs';
8
3
 
9
4
  const resolveHandler = (value) => (isFunction(value) ? value : value.handler);
@@ -0,0 +1,12 @@
1
+ const DEFAULT_PAGE_SIZE = 100;
2
+ const validatePageSize = (pageSize) => {
3
+ if (pageSize === undefined ||
4
+ pageSize === null ||
5
+ !Number.isInteger(pageSize) ||
6
+ pageSize < 1) {
7
+ return DEFAULT_PAGE_SIZE;
8
+ }
9
+ return pageSize;
10
+ };
11
+
12
+ export { validatePageSize };
@@ -11,10 +11,7 @@ import '@aws-amplify/ui-react-core/elements';
11
11
  import '../../../credentials/context.mjs';
12
12
  import '@aws-amplify/storage/internals';
13
13
  import '../../../configuration/context.mjs';
14
- import 'aws-amplify';
15
- import 'jszip';
16
- import 'aws-amplify/storage';
17
- import '../../../actions/configs/context.mjs';
14
+ import '../../../configuration/paginationContext.mjs';
18
15
  import '../../../actions/configs/defaults.mjs';
19
16
  import '../../../displayText/context.mjs';
20
17
  import '../../../filePreview/context.mjs';
@@ -11,16 +11,17 @@ import '@aws-amplify/ui-react-core/elements';
11
11
  import '../../../credentials/context.mjs';
12
12
  import '@aws-amplify/storage/internals';
13
13
  import '../../../configuration/context.mjs';
14
- import 'aws-amplify';
15
- import 'jszip';
16
- import 'aws-amplify/storage';
17
- import '../../../actions/configs/context.mjs';
14
+ import '../../../configuration/paginationContext.mjs';
18
15
  import '../../../actions/configs/defaults.mjs';
19
16
  import { useDisplayText } from '../../../displayText/context.mjs';
20
17
  import '../../../filePreview/context.mjs';
21
18
  import useResolveTableData from '../../hooks/useResolveTableData/useResolveTableData.mjs';
22
19
  import { COPY_TABLE_RESOLVERS } from '../../utils/tableResolvers/copyResolvers.mjs';
23
20
  import { FILE_DATA_ITEM_TABLE_KEYS } from '../../utils/tableResolvers/constants.mjs';
21
+ import 'aws-amplify';
22
+ import 'jszip';
23
+ import 'aws-amplify/storage';
24
+ import '../../../actions/configs/context.mjs';
24
25
  import { FoldersMessageProvider } from './FoldersMessageControl.mjs';
25
26
  import { FoldersPaginationProvider } from './FoldersPaginationControl.mjs';
26
27
  import { FoldersTableProvider } from './FoldersTableControl.mjs';
@@ -13,10 +13,7 @@ import '@aws-amplify/ui-react-core/elements';
13
13
  import '../../../credentials/context.mjs';
14
14
  import '@aws-amplify/storage/internals';
15
15
  import '../../../configuration/context.mjs';
16
- import 'aws-amplify';
17
- import 'jszip';
18
- import 'aws-amplify/storage';
19
- import '../../../actions/configs/context.mjs';
16
+ import '../../../configuration/paginationContext.mjs';
20
17
  import '../../../actions/configs/defaults.mjs';
21
18
  import { useDisplayText } from '../../../displayText/context.mjs';
22
19
  import '../../../filePreview/context.mjs';
@@ -9,10 +9,7 @@ import '@aws-amplify/ui-react-core/elements';
9
9
  import '../../../credentials/context.mjs';
10
10
  import '@aws-amplify/storage/internals';
11
11
  import '../../../configuration/context.mjs';
12
- import 'aws-amplify';
13
- import 'jszip';
14
- import 'aws-amplify/storage';
15
- import '../../../actions/configs/context.mjs';
12
+ import '../../../configuration/paginationContext.mjs';
16
13
  import '../../../actions/configs/defaults.mjs';
17
14
  import { useFolders } from './useFolders.mjs';
18
15
 
@@ -4,12 +4,9 @@ import '@aws-amplify/ui-react-core/elements';
4
4
  import '../../../credentials/context.mjs';
5
5
  import '@aws-amplify/storage/internals';
6
6
  import '../../../configuration/context.mjs';
7
+ import '../../../configuration/paginationContext.mjs';
7
8
  import '@aws-amplify/ui';
8
9
  import { useList } from '../../../useAction/useList.mjs';
9
- import 'aws-amplify';
10
- import 'jszip';
11
- import 'aws-amplify/storage';
12
- import '../../../actions/configs/context.mjs';
13
10
  import '../../../actions/configs/defaults.mjs';
14
11
  import { usePaginate } from '../../hooks/usePaginate.mjs';
15
12
  import { useSearch } from '../../hooks/useSearch.mjs';
@@ -11,10 +11,7 @@ import '@aws-amplify/ui-react-core/elements';
11
11
  import '../../../credentials/context.mjs';
12
12
  import '@aws-amplify/storage/internals';
13
13
  import '../../../configuration/context.mjs';
14
- import 'aws-amplify';
15
- import 'jszip';
16
- import 'aws-amplify/storage';
17
- import '../../../actions/configs/context.mjs';
14
+ import '../../../configuration/paginationContext.mjs';
18
15
  import '../../../actions/configs/defaults.mjs';
19
16
  import '../../../displayText/context.mjs';
20
17
  import '../../../filePreview/context.mjs';
@@ -7,10 +7,7 @@ import '@aws-amplify/ui-react-core/elements';
7
7
  import '../../../credentials/context.mjs';
8
8
  import '@aws-amplify/storage/internals';
9
9
  import '../../../configuration/context.mjs';
10
- import 'aws-amplify';
11
- import 'jszip';
12
- import 'aws-amplify/storage';
13
- import '../../../actions/configs/context.mjs';
10
+ import '../../../configuration/paginationContext.mjs';
14
11
  import '../../../actions/configs/defaults.mjs';
15
12
  import { useStore } from '../../../store/context.mjs';
16
13
 
@@ -1,15 +1,16 @@
1
1
  import React__default from 'react';
2
+ import { classNames } from '@aws-amplify/ui';
2
3
  import '@aws-amplify/ui-react';
3
4
  import { ViewElement } from '../../../components/elements/definitions.mjs';
4
5
  import '../../../components/elements/IconElement.mjs';
5
6
  import { ActionCancelControl } from '../../../controls/ActionCancelControl.mjs';
7
+ import { ActionConfirmationModalControl } from '../../../controls/ActionConfirmationModalControl.mjs';
6
8
  import { ActionExitControl } from '../../../controls/ActionExitControl.mjs';
7
9
  import { ActionStartControl } from '../../../controls/ActionStartControl.mjs';
8
10
  import { DataTableControl } from '../../../controls/DataTableControl.mjs';
9
11
  import { MessageControl } from '../../../controls/MessageControl.mjs';
10
12
  import { StatusDisplayControl } from '../../../controls/StatusDisplayControl.mjs';
11
13
  import { TitleControl } from '../../../controls/TitleControl.mjs';
12
- import { classNames } from '@aws-amplify/ui';
13
14
  import { STORAGE_BROWSER_BLOCK } from '../../../components/base/constants.mjs';
14
15
  import '../../../components/composables/context.mjs';
15
16
  import '@aws-amplify/ui-react-core';
@@ -18,10 +19,7 @@ import '@aws-amplify/ui-react-core/elements';
18
19
  import '../../../credentials/context.mjs';
19
20
  import '@aws-amplify/storage/internals';
20
21
  import '../../../configuration/context.mjs';
21
- import 'aws-amplify';
22
- import 'jszip';
23
- import 'aws-amplify/storage';
24
- import '../../../actions/configs/context.mjs';
22
+ import '../../../configuration/paginationContext.mjs';
25
23
  import '../../../actions/configs/defaults.mjs';
26
24
  import '../../../displayText/context.mjs';
27
25
  import '../../../filePreview/context.mjs';
@@ -43,11 +41,13 @@ const DeleteView = ({ className, ...props }) => {
43
41
  React__default.createElement(MessageControl, null)),
44
42
  React__default.createElement(ViewElement, { className: `${STORAGE_BROWSER_BLOCK}__buttons` },
45
43
  React__default.createElement(ActionCancelControl, null),
46
- React__default.createElement(ActionStartControl, null))))));
44
+ React__default.createElement(ActionStartControl, null))),
45
+ React__default.createElement(ActionConfirmationModalControl, null))));
47
46
  };
48
47
  DeleteView.displayName = 'DeleteView';
49
48
  DeleteView.Provider = DeleteViewProvider;
50
49
  DeleteView.Cancel = ActionCancelControl;
50
+ DeleteView.ConfirmationModal = ActionConfirmationModalControl;
51
51
  DeleteView.Exit = ActionExitControl;
52
52
  DeleteView.Message = MessageControl;
53
53
  DeleteView.Start = ActionStartControl;
@@ -3,18 +3,18 @@ import { ControlsContextProvider } from '../../../controls/context.mjs';
3
3
  import { useDisplayText } from '../../../displayText/context.mjs';
4
4
  import useResolveTableData from '../../hooks/useResolveTableData/useResolveTableData.mjs';
5
5
  import '@aws-amplify/ui';
6
- import { FILE_DATA_ITEM_TABLE_KEYS } from '../../utils/tableResolvers/constants.mjs';
6
+ import { DELETE_TABLE_KEYS } from '../../utils/tableResolvers/constants.mjs';
7
7
  import { DELETE_TABLE_RESOLVERS } from '../../utils/tableResolvers/deleteResolvers.mjs';
8
8
 
9
9
  function DeleteViewProvider({ children, ...props }) {
10
10
  const { DeleteView: displayText } = useDisplayText();
11
11
  const { actionCancelLabel, actionExitLabel, actionStartLabel, title, statusDisplayCanceledLabel, statusDisplayCompletedLabel, statusDisplayFailedLabel, statusDisplayQueuedLabel, getActionCompleteMessage, } = displayText;
12
- const { isProcessing, isProcessingComplete, statusCounts, tasks: items, onActionCancel, onActionStart, onActionExit, onTaskRemove, } = props;
12
+ const { isProcessing, isProcessingComplete, statusCounts, tasks, confirmationModal, onActionCancel, onActionStart, onActionExit, onTaskRemove, onConfirmDelete, onCancelConfirmation, } = props;
13
13
  const message = isProcessingComplete
14
- ? getActionCompleteMessage({ counts: statusCounts })
14
+ ? getActionCompleteMessage({ counts: statusCounts, tasks })
15
15
  : undefined;
16
- const tableData = useResolveTableData(FILE_DATA_ITEM_TABLE_KEYS, DELETE_TABLE_RESOLVERS, {
17
- items,
16
+ const tableData = useResolveTableData(DELETE_TABLE_KEYS, DELETE_TABLE_RESOLVERS, {
17
+ items: tasks,
18
18
  props: { displayText, isProcessing, onTaskRemove },
19
19
  });
20
20
  return (React__default.createElement(ControlsContextProvider, { data: {
@@ -32,7 +32,8 @@ function DeleteViewProvider({ children, ...props }) {
32
32
  tableData,
33
33
  title,
34
34
  message,
35
- }, onActionStart: onActionStart, onActionExit: onActionExit, onActionCancel: onActionCancel }, children));
35
+ confirmationModal,
36
+ }, onActionStart: onActionStart, onActionExit: onActionExit, onActionCancel: onActionCancel, onConfirmationModalConfirm: onConfirmDelete, onConfirmationModalCancel: onCancelConfirmation }, children));
36
37
  }
37
38
 
38
39
  export { DeleteViewProvider };
@@ -1,6 +1,7 @@
1
1
  import React__default from 'react';
2
2
  import { isFunction } from '@aws-amplify/ui';
3
3
  import { useLocationItems } from '../../../locationItems/context.mjs';
4
+ import { getSelectionSummary } from '../../../locationItems/utils.mjs';
4
5
  import { useStore } from '../../../store/context.mjs';
5
6
  import '../../../useAction/context.mjs';
6
7
  import { useAction } from '../../../useAction/useAction.mjs';
@@ -8,28 +9,82 @@ import '@aws-amplify/ui-react-core';
8
9
  import '@aws-amplify/ui-react-core/elements';
9
10
  import '../../../credentials/context.mjs';
10
11
  import '@aws-amplify/storage/internals';
11
- import '../../../configuration/context.mjs';
12
- import 'aws-amplify';
13
- import 'jszip';
14
- import 'aws-amplify/storage';
15
- import '../../../actions/configs/context.mjs';
12
+ import { useGetActionInput } from '../../../configuration/context.mjs';
13
+ import '../../../configuration/paginationContext.mjs';
16
14
  import '../../../actions/configs/defaults.mjs';
15
+ import { useDisplayText } from '../../../displayText/context.mjs';
16
+ import { createDeleteConfirmationModalProps, countFilesInFolder } from './utils.mjs';
17
17
 
18
18
  // assign to constant to ensure referential equality
19
19
  const EMPTY_ITEMS = [];
20
20
  const useDeleteView = (options) => {
21
21
  const { onExit: _onExit } = options ?? {};
22
+ const { DeleteView: displayText } = useDisplayText();
22
23
  const [{ location }, storeDispatch] = useStore();
23
24
  const [locationItems, locationItemsDispatch] = useLocationItems();
24
25
  const { current } = location;
25
- const { fileDataItems: items = EMPTY_ITEMS } = locationItems;
26
- const [processState, handleProcess] = useAction('delete', { items });
26
+ const { dataItems = EMPTY_ITEMS } = locationItems;
27
+ const getConfig = useGetActionInput();
28
+ const [itemsWithCount, setItemsWithCount] = React__default.useState(dataItems);
29
+ const folderCountsRef = React__default.useRef(new Map());
30
+ // Sync itemsWithCount with dataItems when dataItems changes (e.g., item removal)
31
+ React__default.useEffect(() => {
32
+ const itemsWithAppliedCounts = dataItems.map((item) => ({
33
+ ...item,
34
+ totalCount: folderCountsRef.current.get(item.id),
35
+ }));
36
+ setItemsWithCount(itemsWithAppliedCounts);
37
+ }, [dataItems]);
38
+ const [processState, handleProcess] = useAction('delete', {
39
+ items: itemsWithCount,
40
+ });
41
+ const [showConfirmation, setShowConfirmation] = React__default.useState(false);
27
42
  const { isProcessing, isProcessingComplete, statusCounts, tasks } = processState;
43
+ const selectionSummary = getSelectionSummary(dataItems);
44
+ const { hasFolders } = selectionSummary;
45
+ React__default.useEffect(() => {
46
+ const initializeFolderCounts = async () => {
47
+ if (!selectionSummary.hasFolders || !current) {
48
+ return;
49
+ }
50
+ const config = getConfig(current);
51
+ const foldersToCount = dataItems.filter((item) => item.type === 'FOLDER' && !folderCountsRef.current.has(item.id));
52
+ if (foldersToCount.length === 0) {
53
+ return;
54
+ }
55
+ await Promise.all(foldersToCount.map(async (folder) => {
56
+ try {
57
+ const totalCount = await countFilesInFolder(folder.key, config);
58
+ folderCountsRef.current.set(folder.id, totalCount);
59
+ }
60
+ catch (error) {
61
+ folderCountsRef.current.set(folder.id, null);
62
+ }
63
+ }));
64
+ setItemsWithCount((currentItems) => currentItems.map((item) => ({
65
+ ...item,
66
+ totalCount: folderCountsRef.current.get(item.id),
67
+ })));
68
+ };
69
+ initializeFolderCounts();
70
+ }, [current, getConfig, selectionSummary.hasFolders, dataItems]);
28
71
  const onActionStart = () => {
29
72
  if (!current)
30
73
  return;
74
+ if (hasFolders) {
75
+ setShowConfirmation(true);
76
+ }
77
+ else {
78
+ handleProcess();
79
+ }
80
+ };
81
+ const onConfirmDelete = () => {
82
+ setShowConfirmation(false);
31
83
  handleProcess();
32
84
  };
85
+ const onCancelConfirmation = () => {
86
+ setShowConfirmation(false);
87
+ };
33
88
  const onActionCancel = () => {
34
89
  tasks.forEach((task) => {
35
90
  // @TODO Fixme, calling cancel on task doesn't currently work
@@ -48,6 +103,11 @@ const useDeleteView = (options) => {
48
103
  const onTaskRemove = React__default.useCallback(({ data }) => {
49
104
  locationItemsDispatch({ type: 'REMOVE_LOCATION_ITEM', id: data.id });
50
105
  }, [locationItemsDispatch]);
106
+ const confirmationModal = React__default.useMemo(() => createDeleteConfirmationModalProps({
107
+ items: dataItems,
108
+ showConfirmation,
109
+ displayText,
110
+ }), [dataItems, showConfirmation, displayText]);
51
111
  return {
52
112
  isProcessing,
53
113
  isProcessingComplete,
@@ -58,6 +118,9 @@ const useDeleteView = (options) => {
58
118
  onActionExit,
59
119
  onActionStart,
60
120
  onTaskRemove,
121
+ onConfirmDelete,
122
+ onCancelConfirmation,
123
+ confirmationModal,
61
124
  };
62
125
  };
63
126
 
@@ -0,0 +1,87 @@
1
+ import React__default from 'react';
2
+ import { getSelectedFolders } from '../../../locationItems/utils.mjs';
3
+ import '@aws-amplify/ui-react';
4
+ import { TextElement, UnorderedListElement, ListItemElement } from '../../../components/elements/definitions.mjs';
5
+ import '../../../components/elements/IconElement.mjs';
6
+ import { list } from '@aws-amplify/storage/internals';
7
+ import { constructBucket } from '../../../actions/handlers/utils.mjs';
8
+ import '@aws-amplify/ui';
9
+ import 'jszip';
10
+ import 'aws-amplify/storage';
11
+
12
+ const getFolderName = (folderKey) => {
13
+ return folderKey.replace(/\/$/, '').split('/').pop() ?? folderKey;
14
+ };
15
+ /**
16
+ * Creates JSX content showing a list of folders to be deleted
17
+ */
18
+ const createFolderListContent = (folders, folderListTitle) => {
19
+ return (React__default.createElement(React__default.Fragment, null,
20
+ React__default.createElement(TextElement, { className: "amplify-modal__list-title" },
21
+ React__default.createElement("strong", null, folderListTitle)),
22
+ React__default.createElement(UnorderedListElement, { className: "amplify-modal__list" }, folders.map((folder) => (React__default.createElement(ListItemElement, { key: folder.id, className: "amplify-modal__list-item" }, getFolderName(folder.key)))))));
23
+ };
24
+ const createDeleteConfirmationModalProps = ({ items, showConfirmation, displayText, }) => {
25
+ const folders = getSelectedFolders(items);
26
+ const folderCount = folders.length;
27
+ return {
28
+ isOpen: showConfirmation,
29
+ title: displayText.confirmationModalTitle,
30
+ message: displayText.confirmationModalMessage
31
+ .replace('{count}', folderCount.toString())
32
+ .replace('{plural}', folderCount !== 1 ? 's' : ''),
33
+ confirmLabel: displayText.confirmationModalConfirmLabel,
34
+ cancelLabel: displayText.confirmationModalCancelLabel,
35
+ content: createFolderListContent(folders, displayText.confirmationModalFolderListTitle),
36
+ };
37
+ };
38
+ /**
39
+ * Maximum number of files to count before showing "+" notation
40
+ * This prevents expensive operations on very large folders
41
+ */
42
+ const MAX_FILE_COUNT_LIMIT = 5000;
43
+ const LIST_PAGE_SIZE = 1000;
44
+ /**
45
+ * Count the total number of files in a folder with pagination and limits
46
+ * @param folderKey - The folder path to count files in
47
+ * @param config - Storage configuration
48
+ * @returns Promise<number | string> - File count or "5000+" if exceeds limit
49
+ */
50
+ const countFilesInFolder = async (folderKey, config) => {
51
+ try {
52
+ const { accountId, credentials, customEndpoint } = config;
53
+ const bucket = constructBucket(config);
54
+ let fileCount = 0;
55
+ let nextToken;
56
+ let hasMoreItems = true;
57
+ while (hasMoreItems && fileCount < MAX_FILE_COUNT_LIMIT) {
58
+ const { items, nextToken: listNextToken } = await list({
59
+ path: folderKey,
60
+ options: {
61
+ bucket,
62
+ locationCredentialsProvider: credentials,
63
+ expectedBucketOwner: accountId,
64
+ customEndpoint,
65
+ pageSize: LIST_PAGE_SIZE,
66
+ nextToken,
67
+ },
68
+ });
69
+ const batchFileCount = items.filter((item) => !item.path.endsWith('/')).length;
70
+ fileCount += batchFileCount;
71
+ nextToken = listNextToken;
72
+ hasMoreItems = !!nextToken;
73
+ if (fileCount >= MAX_FILE_COUNT_LIMIT) {
74
+ return `${MAX_FILE_COUNT_LIMIT}+`;
75
+ }
76
+ }
77
+ if (hasMoreItems) {
78
+ return `${fileCount}+`;
79
+ }
80
+ return fileCount;
81
+ }
82
+ catch (error) {
83
+ return 0;
84
+ }
85
+ };
86
+
87
+ export { countFilesInFolder, createDeleteConfirmationModalProps, createFolderListContent, getFolderName };
@@ -18,10 +18,7 @@ import '@aws-amplify/ui-react-core/elements';
18
18
  import '../../../credentials/context.mjs';
19
19
  import '@aws-amplify/storage/internals';
20
20
  import '../../../configuration/context.mjs';
21
- import 'aws-amplify';
22
- import 'jszip';
23
- import 'aws-amplify/storage';
24
- import '../../../actions/configs/context.mjs';
21
+ import '../../../configuration/paginationContext.mjs';
25
22
  import '../../../actions/configs/defaults.mjs';
26
23
  import '../../../displayText/context.mjs';
27
24
  import '../../../filePreview/context.mjs';
@@ -3,6 +3,15 @@ import { ControlsContextProvider } from '../../../controls/context.mjs';
3
3
  import { useDisplayText } from '../../../displayText/context.mjs';
4
4
  import useResolveTableData from '../../hooks/useResolveTableData/useResolveTableData.mjs';
5
5
  import '@aws-amplify/ui';
6
+ import '@aws-amplify/storage/internals';
7
+ import 'aws-amplify';
8
+ import 'jszip';
9
+ import 'aws-amplify/storage';
10
+ import '../../../actions/configs/context.mjs';
11
+ import '../../../actions/configs/defaults.mjs';
12
+ import '@aws-amplify/ui-react';
13
+ import '../../../components/elements/definitions.mjs';
14
+ import '../../../components/elements/IconElement.mjs';
6
15
  import { DOWNLOAD_TABLE_RESOLVERS, DOWNLOAD_TABLE_KEYS } from '../../utils/tableResolvers/downloadResolvers.mjs';
7
16
 
8
17
  function DownloadViewProvider({ children, ...props }) {
@@ -9,10 +9,7 @@ import '@aws-amplify/ui-react-core/elements';
9
9
  import '../../../credentials/context.mjs';
10
10
  import '@aws-amplify/storage/internals';
11
11
  import '../../../configuration/context.mjs';
12
- import 'aws-amplify';
13
- import 'jszip';
14
- import 'aws-amplify/storage';
15
- import '../../../actions/configs/context.mjs';
12
+ import '../../../configuration/paginationContext.mjs';
16
13
  import '../../../actions/configs/defaults.mjs';
17
14
 
18
15
  // assign to constant to ensure referential equality
@@ -11,17 +11,14 @@ import '@aws-amplify/ui-react-core/elements';
11
11
  import '../../../credentials/context.mjs';
12
12
  import '@aws-amplify/storage/internals';
13
13
  import '../../../configuration/context.mjs';
14
- import 'aws-amplify';
15
- import 'jszip';
16
- import 'aws-amplify/storage';
17
- import '../../../actions/configs/context.mjs';
14
+ import '../../../configuration/paginationContext.mjs';
18
15
  import '../../../actions/configs/defaults.mjs';
19
16
  import '../../../displayText/context.mjs';
20
17
  import '../../../filePreview/context.mjs';
21
18
  import { ActionCancelControl } from '../../../controls/ActionCancelControl.mjs';
19
+ import '../../../controls/context.mjs';
22
20
  import { ActionDestinationControl } from '../../../controls/ActionDestinationControl.mjs';
23
21
  import { ActionExitControl } from '../../../controls/ActionExitControl.mjs';
24
- import '../../../controls/context.mjs';
25
22
  import { ActionStartControl } from '../../../controls/ActionStartControl.mjs';
26
23
  import { AddFilesControl } from '../../../controls/AddFilesControl.mjs';
27
24
  import { AddFolderControl } from '../../../controls/AddFolderControl.mjs';
@@ -37,7 +34,7 @@ import { useUploadView } from './useUploadView.mjs';
37
34
 
38
35
  const UploadView = ({ className, ...props }) => {
39
36
  const state = useUploadView(props);
40
- return (React__default.createElement(ViewElement, { className: classNames(STORAGE_BROWSER_BLOCK, className) },
37
+ return (React__default.createElement(ViewElement, { className: classNames(STORAGE_BROWSER_BLOCK, className), "data-testid": "UPLOAD_VIEW" },
41
38
  React__default.createElement(UploadViewProvider, { ...state },
42
39
  React__default.createElement(ActionExitControl, null),
43
40
  React__default.createElement(TitleControl, null),
@@ -9,6 +9,9 @@ import '../../../actions/configs/defaults.mjs';
9
9
  import { ControlsContextProvider } from '../../../controls/context.mjs';
10
10
  import { useDisplayText } from '../../../displayText/context.mjs';
11
11
  import useResolveTableData from '../../hooks/useResolveTableData/useResolveTableData.mjs';
12
+ import '@aws-amplify/ui-react';
13
+ import '../../../components/elements/definitions.mjs';
14
+ import '../../../components/elements/IconElement.mjs';
12
15
  import { UPLOAD_TABLE_RESOLVERS, UPLOAD_TABLE_KEYS } from '../../utils/tableResolvers/uploadResolvers.mjs';
13
16
 
14
17
  function UploadViewProvider({ children, ...props }) {
@@ -1,25 +1,23 @@
1
1
  import React__default from 'react';
2
+ import '@aws-amplify/ui-react-core/elements';
3
+ import '../../../credentials/context.mjs';
4
+ import '@aws-amplify/storage/internals';
5
+ import '../../../configuration/context.mjs';
6
+ import { usePaginationConfig } from '../../../configuration/paginationContext.mjs';
2
7
  import { useFileItems } from '../../../fileItems/context.mjs';
3
8
  import '@aws-amplify/ui';
4
9
  import { useStore } from '../../../store/context.mjs';
5
10
  import '../../../useAction/context.mjs';
6
11
  import { useAction } from '../../../useAction/useAction.mjs';
7
12
  import '@aws-amplify/ui-react-core';
8
- import '@aws-amplify/ui-react-core/elements';
9
- import '../../../credentials/context.mjs';
10
- import '@aws-amplify/storage/internals';
11
- import '../../../configuration/context.mjs';
12
- import 'aws-amplify';
13
- import 'jszip';
14
- import 'aws-amplify/storage';
15
- import '../../../actions/configs/context.mjs';
16
13
  import '../../../actions/configs/defaults.mjs';
17
14
  import { DEFAULT_OVERWRITE_ENABLED } from './constants.mjs';
18
15
  import { usePaginate } from '../../hooks/usePaginate.mjs';
19
16
 
20
- const DEFAULT_PAGE_SIZE = 100;
21
17
  const useUploadView = (options) => {
22
- const { onExit: _onExit } = options ?? {};
18
+ const { pageSize: configPageSize } = usePaginationConfig();
19
+ const { onExit: _onExit, pageSize: propPageSize } = options ?? {};
20
+ const pageSize = propPageSize ?? configPageSize;
23
21
  const [{ location }, storeDispatch] = useStore();
24
22
  const [{ validItems, invalidItems: invalidFiles }, fileItemsDispatch] = useFileItems();
25
23
  const { current } = location;
@@ -32,6 +30,7 @@ const useUploadView = (options) => {
32
30
  const [{ isProcessing, isProcessingComplete, statusCounts, tasks }, handleUploads,] = useAction('upload', { items });
33
31
  const { currentPage, handlePaginate, pageItems: pageTasks, } = usePaginate({
34
32
  items: tasks,
33
+ pageSize,
35
34
  });
36
35
  const onDropFiles = (files) => {
37
36
  if (files) {
@@ -69,8 +68,8 @@ const useUploadView = (options) => {
69
68
  statusCounts,
70
69
  tasks: pageTasks,
71
70
  page: currentPage,
72
- hasNextPage: currentPage * DEFAULT_PAGE_SIZE < items.length,
73
- highestPageVisited: Math.ceil(items.length / DEFAULT_PAGE_SIZE),
71
+ hasNextPage: currentPage * pageSize < items.length,
72
+ highestPageVisited: Math.ceil(items.length / pageSize),
74
73
  onActionCancel,
75
74
  onActionExit,
76
75
  onActionStart,
@@ -11,10 +11,7 @@ import '@aws-amplify/ui-react-core/elements';
11
11
  import '../../credentials/context.mjs';
12
12
  import '@aws-amplify/storage/internals';
13
13
  import '../../configuration/context.mjs';
14
- import 'aws-amplify';
15
- import 'jszip';
16
- import 'aws-amplify/storage';
17
- import '../../actions/configs/context.mjs';
14
+ import '../../configuration/paginationContext.mjs';
18
15
  import '../../actions/configs/defaults.mjs';
19
16
  import '../../displayText/context.mjs';
20
17
  import '../../filePreview/context.mjs';
@@ -6,7 +6,7 @@ import { getLocationDetailViewTableData } from './getLocationDetailViewTableData
6
6
  function LocationDetailViewProvider({ children, ...props }) {
7
7
  const { LocationDetailView: displayText } = useDisplayText();
8
8
  const { LocationDetailView: { loadingIndicatorLabel, searchSubfoldersToggleLabel, selectFileLabel, selectAllFilesLabel, searchPlaceholder, searchSubmitLabel, searchClearLabel, getActionListItemLabel, getDateDisplayValue, getTitle, getListItemsResultMessage, }, } = useDisplayText();
9
- const { actionItems, activeFile, activeFileHasNext, activeFileHasPrev, page, pageItems, hasNextPage, highestPageVisited, isLoading, isSearchSubfoldersEnabled, location, fileDataItems, hasError, hasDownloadError, message, downloadErrorMessage, searchQuery, hasExhaustedSearch, onActionSelect, onDropFiles, onRefresh, onPaginate, onDownload, onNavigate, onNavigateHome, onSelect, onSelectActiveFile, onToggleSelectAll, onSearch, onSearchQueryChange, onSearchClear, onToggleSearchSubfolders, filePreviewState, filePreviewEnabled, onRetryFilePreview, } = props;
9
+ const { actionItems, activeFile, activeFileHasNext, activeFileHasPrev, page, pageItems, hasNextPage, highestPageVisited, isLoading, isSearchSubfoldersEnabled, location, fileDataItems, hasError, hasDownloadError, message, downloadErrorMessage, searchQuery, hasExhaustedSearch, onActionSelect, onDropFiles, onRefresh, onPaginate, onDownload, onNavigate, onNavigateHome, onSelect, onSelectActiveFile, onToggleSelectAll, onSearch, onSearchQueryChange, onSearchClear, onToggleSearchSubfolders, filePreviewState, filePreviewEnabled, onRetryFilePreview, dataItems, } = props;
10
10
  const actionsWithDisplayText = actionItems.map((item) => ({
11
11
  ...item,
12
12
  label: getActionListItemLabel(item.label),
@@ -63,6 +63,7 @@ function LocationDetailViewProvider({ children, ...props }) {
63
63
  onNavigate,
64
64
  onSelect,
65
65
  onSelectAll: onToggleSelectAll,
66
+ dataItems,
66
67
  }),
67
68
  title: getTitle(location),
68
69
  message: messageControlContent,