@aws-amplify/ui-react-storage 3.15.0 → 3.16.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 (80) hide show
  1. package/dist/browser.js +1 -1
  2. package/dist/{createStorageBrowser-CG-6mXiT.js → createStorageBrowser-B-J76Lyp.js} +624 -105
  3. package/dist/esm/components/StorageBrowser/ErrorBoundary/ErrorBoundary.mjs +0 -4
  4. package/dist/esm/components/StorageBrowser/actions/configs/defaults.mjs +13 -3
  5. package/dist/esm/components/StorageBrowser/actions/handlers/delete.mjs +39 -8
  6. package/dist/esm/components/StorageBrowser/components/ComponentsProvider.mjs +0 -4
  7. package/dist/esm/components/StorageBrowser/components/base/preview/DownloadButton.mjs +0 -4
  8. package/dist/esm/components/StorageBrowser/components/composables/ActionConfirmationModal.mjs +34 -0
  9. package/dist/esm/components/StorageBrowser/components/composables/defaults.mjs +2 -0
  10. package/dist/esm/components/StorageBrowser/components/elements/definitions.mjs +2 -2
  11. package/dist/esm/components/StorageBrowser/controls/ActionConfirmationModalControl.mjs +12 -0
  12. package/dist/esm/components/StorageBrowser/controls/DataTableControl.mjs +0 -4
  13. package/dist/esm/components/StorageBrowser/controls/hooks/useActionConfirmationModal.mjs +17 -0
  14. package/dist/esm/components/StorageBrowser/createStorageBrowser/StorageBrowserDefault.mjs +8 -4
  15. package/dist/esm/components/StorageBrowser/createStorageBrowser/createStorageBrowser.mjs +9 -5
  16. package/dist/esm/components/StorageBrowser/displayText/libraries/en/deleteView.mjs +117 -5
  17. package/dist/esm/components/StorageBrowser/displayText/libraries/en/locationDetailView.mjs +1 -0
  18. package/dist/esm/components/StorageBrowser/displayText/libraries/en/shared.mjs +1 -0
  19. package/dist/esm/components/StorageBrowser/locationItems/context.mjs +17 -14
  20. package/dist/esm/components/StorageBrowser/locationItems/utils.mjs +38 -0
  21. package/dist/esm/components/StorageBrowser/store/validateStoreProps.mjs +1 -1
  22. package/dist/esm/components/StorageBrowser/tasks/useProcessTasks.mjs +7 -4
  23. package/dist/esm/components/StorageBrowser/useAction/utils.mjs +0 -5
  24. package/dist/esm/components/StorageBrowser/views/LocationActionView/CopyView/CopyView.mjs +0 -4
  25. package/dist/esm/components/StorageBrowser/views/LocationActionView/CopyView/CopyViewProvider.mjs +4 -4
  26. package/dist/esm/components/StorageBrowser/views/LocationActionView/CopyView/FoldersMessageControl.mjs +0 -4
  27. package/dist/esm/components/StorageBrowser/views/LocationActionView/CopyView/useCopyView.mjs +0 -4
  28. package/dist/esm/components/StorageBrowser/views/LocationActionView/CopyView/useFolders.mjs +0 -4
  29. package/dist/esm/components/StorageBrowser/views/LocationActionView/CreateFolderView/CreateFolderView.mjs +0 -4
  30. package/dist/esm/components/StorageBrowser/views/LocationActionView/CreateFolderView/useCreateFolderView.mjs +0 -4
  31. package/dist/esm/components/StorageBrowser/views/LocationActionView/DeleteView/DeleteView.mjs +5 -6
  32. package/dist/esm/components/StorageBrowser/views/LocationActionView/DeleteView/DeleteViewProvider.mjs +7 -6
  33. package/dist/esm/components/StorageBrowser/views/LocationActionView/DeleteView/useDeleteView.mjs +69 -7
  34. package/dist/esm/components/StorageBrowser/views/LocationActionView/DeleteView/utils.mjs +87 -0
  35. package/dist/esm/components/StorageBrowser/views/LocationActionView/DownloadView/DownloadView.mjs +0 -4
  36. package/dist/esm/components/StorageBrowser/views/LocationActionView/DownloadView/DownloadViewProvider.mjs +9 -0
  37. package/dist/esm/components/StorageBrowser/views/LocationActionView/DownloadView/useDownloadView.mjs +0 -4
  38. package/dist/esm/components/StorageBrowser/views/LocationActionView/UploadView/UploadView.mjs +1 -5
  39. package/dist/esm/components/StorageBrowser/views/LocationActionView/UploadView/UploadViewProvider.mjs +3 -0
  40. package/dist/esm/components/StorageBrowser/views/LocationActionView/UploadView/useUploadView.mjs +0 -4
  41. package/dist/esm/components/StorageBrowser/views/LocationDetailView/LocationDetailView.mjs +0 -4
  42. package/dist/esm/components/StorageBrowser/views/LocationDetailView/LocationDetailViewProvider.mjs +2 -1
  43. package/dist/esm/components/StorageBrowser/views/LocationDetailView/getLocationDetailViewTableData/getFolderRowContent.mjs +38 -27
  44. package/dist/esm/components/StorageBrowser/views/LocationDetailView/getLocationDetailViewTableData/getLocationDetailViewTableData.mjs +8 -1
  45. package/dist/esm/components/StorageBrowser/views/LocationDetailView/useLocationDetailView.mjs +10 -9
  46. package/dist/esm/components/StorageBrowser/views/LocationsView/LocationsView.mjs +0 -4
  47. package/dist/esm/components/StorageBrowser/views/LocationsView/LocationsViewProvider.mjs +0 -4
  48. package/dist/esm/components/StorageBrowser/views/context/actionViews.mjs +7 -4
  49. package/dist/esm/components/StorageBrowser/views/context/primaryViews.mjs +8 -4
  50. package/dist/esm/components/StorageBrowser/views/utils/tableResolvers/constants.mjs +10 -1
  51. package/dist/esm/components/StorageBrowser/views/utils/tableResolvers/deleteResolvers.mjs +123 -13
  52. package/dist/esm/components/StorageBrowser/views/utils/tableResolvers/utils.mjs +3 -3
  53. package/dist/esm/version.mjs +1 -1
  54. package/dist/index.js +1 -1
  55. package/dist/styles.css +83 -1
  56. package/dist/types/components/StorageBrowser/actions/handlers/delete.d.ts +5 -3
  57. package/dist/types/components/StorageBrowser/actions/handlers/types.d.ts +15 -1
  58. package/dist/types/components/StorageBrowser/components/composables/ActionConfirmationModal.d.ts +12 -0
  59. package/dist/types/components/StorageBrowser/components/composables/types.d.ts +2 -0
  60. package/dist/types/components/StorageBrowser/controls/ActionConfirmationModalControl.d.ts +2 -0
  61. package/dist/types/components/StorageBrowser/controls/hooks/useActionConfirmationModal.d.ts +2 -0
  62. package/dist/types/components/StorageBrowser/controls/index.d.ts +1 -0
  63. package/dist/types/components/StorageBrowser/controls/types.d.ts +4 -0
  64. package/dist/types/components/StorageBrowser/displayText/types.d.ts +7 -0
  65. package/dist/types/components/StorageBrowser/locationItems/context.d.ts +12 -3
  66. package/dist/types/components/StorageBrowser/locationItems/index.d.ts +1 -0
  67. package/dist/types/components/StorageBrowser/locationItems/utils.d.ts +27 -0
  68. package/dist/types/components/StorageBrowser/tasks/types.d.ts +7 -2
  69. package/dist/types/components/StorageBrowser/views/LocationActionView/DeleteView/types.d.ts +5 -0
  70. package/dist/types/components/StorageBrowser/views/LocationActionView/DeleteView/utils.d.ts +26 -0
  71. package/dist/types/components/StorageBrowser/views/LocationDetailView/getLocationDetailViewTableData/getFolderRowContent.d.ts +4 -1
  72. package/dist/types/components/StorageBrowser/views/LocationDetailView/getLocationDetailViewTableData/getLocationDetailViewTableData.d.ts +3 -2
  73. package/dist/types/components/StorageBrowser/views/LocationDetailView/types.d.ts +8 -1
  74. package/dist/types/components/StorageBrowser/views/utils/index.d.ts +1 -1
  75. package/dist/types/components/StorageBrowser/views/utils/tableResolvers/constants.d.ts +1 -0
  76. package/dist/types/components/StorageBrowser/views/utils/tableResolvers/deleteResolvers.d.ts +5 -2
  77. package/dist/types/components/StorageBrowser/views/utils/tableResolvers/index.d.ts +1 -1
  78. package/dist/types/components/StorageBrowser/views/utils/tableResolvers/types.d.ts +4 -0
  79. package/dist/types/version.d.ts +1 -1
  80. package/package.json +7 -7
@@ -9,15 +9,18 @@ import '../../credentials/context.mjs';
9
9
  import '@aws-amplify/storage/internals';
10
10
  import '../../configuration/context.mjs';
11
11
  import '@aws-amplify/ui-react-core';
12
- import 'aws-amplify';
13
- import 'jszip';
14
- import 'aws-amplify/storage';
15
- import '../../actions/configs/context.mjs';
16
12
  import '../../actions/configs/defaults.mjs';
17
13
  import { CreateFolderView } from '../LocationActionView/CreateFolderView/CreateFolderView.mjs';
18
14
  import { CopyView } from '../LocationActionView/CopyView/CopyView.mjs';
19
15
  import '../../locationItems/context.mjs';
20
16
  import { DeleteView } from '../LocationActionView/DeleteView/DeleteView.mjs';
17
+ import '../../displayText/context.mjs';
18
+ import '@aws-amplify/ui-react';
19
+ import '../../components/elements/definitions.mjs';
20
+ import '../../components/elements/IconElement.mjs';
21
+ import 'aws-amplify';
22
+ import 'jszip';
23
+ import 'aws-amplify/storage';
21
24
  import { DownloadView } from '../LocationActionView/DownloadView/DownloadView.mjs';
22
25
 
23
26
  const DEFAULT_ACTION_VIEWS = {
@@ -9,18 +9,22 @@ import '../../credentials/context.mjs';
9
9
  import '@aws-amplify/storage/internals';
10
10
  import '../../configuration/context.mjs';
11
11
  import '@aws-amplify/ui-react-core';
12
- import 'aws-amplify';
13
- import 'jszip';
14
- import 'aws-amplify/storage';
15
- import '../../actions/configs/context.mjs';
16
12
  import '../../actions/configs/defaults.mjs';
17
13
  import '../LocationActionView/CreateFolderView/CreateFolderView.mjs';
18
14
  import '../LocationActionView/DeleteView/DeleteView.mjs';
15
+ import '../../displayText/context.mjs';
16
+ import '@aws-amplify/ui-react';
17
+ import '../../components/elements/definitions.mjs';
18
+ import '../../components/elements/IconElement.mjs';
19
+ import 'aws-amplify';
20
+ import 'jszip';
21
+ import 'aws-amplify/storage';
19
22
  import '../LocationActionView/DownloadView/DownloadView.mjs';
20
23
  import { LocationActionView } from '../LocationActionView/LocationActionView.mjs';
21
24
  import '../LocationActionView/UploadView/UploadView.mjs';
22
25
  import '../../fileItems/context.mjs';
23
26
  import { LocationDetailView } from '../LocationDetailView/LocationDetailView.mjs';
27
+ import '../../actions/configs/context.mjs';
24
28
  import '../../filePreview/context.mjs';
25
29
  import { LocationsView } from '../LocationsView/LocationsView.mjs';
26
30
 
@@ -26,5 +26,14 @@ const FILE_DATA_ITEM_TABLE_KEYS = [
26
26
  'status',
27
27
  'cancel',
28
28
  ];
29
+ const DELETE_TABLE_KEYS = [
30
+ 'name',
31
+ 'folder',
32
+ 'type',
33
+ 'size',
34
+ 'status',
35
+ 'progress',
36
+ 'cancel',
37
+ ];
29
38
 
30
- export { FILE_DATA_ITEM_TABLE_KEYS, STATUS_ICONS, STATUS_LABELS };
39
+ export { DELETE_TABLE_KEYS, FILE_DATA_ITEM_TABLE_KEYS, STATUS_ICONS, STATUS_LABELS };
@@ -1,11 +1,95 @@
1
- import { noop, capitalize } from '@aws-amplify/ui';
1
+ import { capitalize } from '@aws-amplify/ui';
2
2
  import '../../../displayText/context.mjs';
3
3
  import { isDeleteViewDisplayTextKey } from '../../../displayText/utils.mjs';
4
- import { STATUS_LABELS } from './constants.mjs';
5
- import { cancel, size, type, folder, name, getFileDataCellKey } from './utils.mjs';
4
+ import { STATUS_ICONS, STATUS_LABELS } from './constants.mjs';
5
+ import { getFileSize, getFileType, getCellName } from './utils.mjs';
6
+ import '@aws-amplify/storage/internals';
7
+ import { getFileKey } from '../../../actions/handlers/utils.mjs';
8
+ import 'jszip';
9
+ import 'aws-amplify/storage';
10
+ import '../../../actions/configs/context.mjs';
11
+ import '../../../actions/configs/defaults.mjs';
12
+ import { getFolderName } from '../../LocationActionView/DeleteView/utils.mjs';
6
13
 
14
+ const getDeleteCellKey = (data) => `${data.key}-${data.item.data.id}`;
15
+ const getCellDataFolder = (data) => {
16
+ const { type, key } = data;
17
+ const fileKey = getFileKey(key);
18
+ const targetKey = data.key;
19
+ if (type === 'FOLDER') {
20
+ const pathWithoutTrailingSlash = targetKey.replace(/\/$/, '');
21
+ const lastSlashIndex = pathWithoutTrailingSlash.lastIndexOf('/');
22
+ return lastSlashIndex >= 0
23
+ ? pathWithoutTrailingSlash.slice(0, lastSlashIndex + 1)
24
+ : '';
25
+ }
26
+ return targetKey.slice(0, -fileKey?.length);
27
+ };
28
+ const name = (data) => {
29
+ const key = getDeleteCellKey(data);
30
+ const { item } = data;
31
+ let text;
32
+ if (item.data.type === 'FOLDER') {
33
+ text = `${getFolderName(item.data.key)}/`;
34
+ }
35
+ else {
36
+ text = item.data.fileKey ?? getCellName(item.data.key);
37
+ }
38
+ const icon = STATUS_ICONS[item.status];
39
+ return { key, type: 'text', content: { icon, text } };
40
+ };
41
+ const folder = (data) => {
42
+ const key = getDeleteCellKey(data);
43
+ const text = getCellDataFolder(data.item.data);
44
+ return { key, type: 'text', content: { text } };
45
+ };
46
+ const type = (data) => {
47
+ const key = getDeleteCellKey(data);
48
+ if (data.item.data.type === 'FOLDER') {
49
+ return { key, type: 'text', content: { text: 'Folder' } };
50
+ }
51
+ const text = getFileType(data.item.data.key);
52
+ return { key, type: 'text', content: { text } };
53
+ };
54
+ const size = (data) => {
55
+ const key = getDeleteCellKey(data);
56
+ const itemData = data.item.data;
57
+ if (data.item.data.type === 'FOLDER') {
58
+ return { key, type: 'text', content: { text: '-' } };
59
+ }
60
+ const value = 'size' in itemData ? itemData.size : 0;
61
+ const displayValue = getFileSize(value);
62
+ return { key, type: 'number', content: { value, displayValue } };
63
+ };
64
+ const getCancelCellContent = (data) => {
65
+ const { item, props } = data;
66
+ const { cancel, status } = item;
67
+ const { isProcessing, onTaskRemove } = props;
68
+ const isQueued = status === 'QUEUED';
69
+ const isRemovable = isQueued && !isProcessing;
70
+ const isCancelable = isProcessing && !!cancel;
71
+ const itemAriaValue = getCellName(item.data.fileKey ?? item.data.key);
72
+ const ariaLabel = `${isRemovable ? 'Remove' : 'Cancel'} item: ${itemAriaValue}`;
73
+ const isDisabled = !isRemovable && !isCancelable;
74
+ const onClick = !isCancelable && !isRemovable
75
+ ? undefined
76
+ : () => {
77
+ if (isRemovable) {
78
+ onTaskRemove?.(item);
79
+ return;
80
+ }
81
+ if (isCancelable)
82
+ cancel();
83
+ };
84
+ return { ariaLabel, isDisabled, onClick, icon: 'cancel' };
85
+ };
86
+ const cancel = (data) => {
87
+ const key = getDeleteCellKey(data);
88
+ const content = getCancelCellContent(data);
89
+ return { key, type: 'button', content };
90
+ };
7
91
  const status = (data) => {
8
- const key = getFileDataCellKey(data);
92
+ const key = getDeleteCellKey(data);
9
93
  const { item: { status }, props: { displayText }, } = data;
10
94
  const statusLabelKey = STATUS_LABELS[status];
11
95
  const text = isDeleteViewDisplayTextKey(statusLabelKey)
@@ -13,21 +97,47 @@ const status = (data) => {
13
97
  : '';
14
98
  return { key, type: 'text', content: { text } };
15
99
  };
100
+ const progress = (data) => {
101
+ const key = getDeleteCellKey(data);
102
+ const { item } = data;
103
+ const itemIsFile = item.data.type === 'FILE';
104
+ if (itemIsFile) {
105
+ const text = item.status === 'COMPLETE' ? 'Deleted' : '-';
106
+ return { key, type: 'text', content: { text } };
107
+ }
108
+ if ((item.status === 'PENDING' ||
109
+ item.status === 'FAILED' ||
110
+ item.status === 'CANCELED') &&
111
+ item.data.totalCount !== undefined) {
112
+ const countDisplay = item.data.totalCount ?? '?';
113
+ const text = `${item.successCount ?? 0}/${countDisplay} files`;
114
+ return { key, type: 'text', content: { text } };
115
+ }
116
+ else if (item.status === 'COMPLETE') {
117
+ if (item.data.totalCount === null) {
118
+ const text = `${item.successCount ?? 0} files deleted`;
119
+ return { key, type: 'text', content: { text } };
120
+ }
121
+ const text = `${item.data.totalCount} files deleted`;
122
+ return { key, type: 'text', content: { text } };
123
+ }
124
+ else {
125
+ const text = item.data.totalCount === null
126
+ ? 'Count failed'
127
+ : item.data.totalCount !== undefined
128
+ ? `${item.data.totalCount} files`
129
+ : 'Calculating...';
130
+ return { key, type: 'text', content: { text } };
131
+ }
132
+ };
16
133
  const DELETE_CELL_RESOLVERS = {
17
134
  name,
18
135
  folder,
19
136
  type,
20
137
  size,
21
138
  status,
139
+ progress,
22
140
  cancel,
23
- /**
24
- * @deprecated
25
- *
26
- * non-upload view tables do not include "progress" headers but include here to
27
- * keep TS happy as "progress" headers were included in display text interfaces
28
- * and cannot be removed from the tables without a breaking change
29
- */
30
- progress: noop,
31
141
  };
32
142
  const DELETE_TABLE_RESOLVERS = {
33
143
  getCell: (data) => DELETE_CELL_RESOLVERS[data.key](data),
@@ -41,4 +151,4 @@ const DELETE_TABLE_RESOLVERS = {
41
151
  getRowKey: ({ item }) => item.data.id,
42
152
  };
43
153
 
44
- export { DELETE_TABLE_RESOLVERS };
154
+ export { DELETE_TABLE_RESOLVERS, getCancelCellContent };
@@ -1,8 +1,8 @@
1
1
  import { humanFileSize } from '@aws-amplify/ui';
2
2
  import { STATUS_ICONS } from './constants.mjs';
3
3
 
4
- const getFileType = (value, fallback = '') => value.lastIndexOf('.') !== -1
5
- ? value.slice(value.lastIndexOf('.') + 1)
4
+ const getFileType = (value, fallback = '') => value?.lastIndexOf?.('.') !== -1
5
+ ? value?.slice(value?.lastIndexOf?.('.') + 1)
6
6
  : fallback;
7
7
  const getCellName = (value) =>
8
8
  // `value.split` always returns an array with at least one entry
@@ -17,7 +17,7 @@ const getFileDataCellFolder = (task) => {
17
17
  ? task.data.sourceKey
18
18
  : task.data.key;
19
19
  const { fileKey } = task.data;
20
- return targetKey.slice(0, -fileKey.length);
20
+ return targetKey.slice(0, -fileKey?.length);
21
21
  };
22
22
  const getUploadCellProgress = ({ progress, status, }) => {
23
23
  // prefer `progress` if available, 1 if status is complete, default 0
@@ -1,3 +1,3 @@
1
- const VERSION = '3.15.0';
1
+ const VERSION = '3.16.0';
2
2
 
3
3
  export { VERSION };
package/dist/index.js CHANGED
@@ -9,7 +9,7 @@ var uiReactCore = require('@aws-amplify/ui-react-core');
9
9
  var auth = require('aws-amplify/auth');
10
10
  var storage = require('aws-amplify/storage');
11
11
  var internal = require('@aws-amplify/ui-react/internal');
12
- var createStorageBrowser = require('./createStorageBrowser-CG-6mXiT.js');
12
+ var createStorageBrowser = require('./createStorageBrowser-B-J76Lyp.js');
13
13
  require('@aws-amplify/storage/internals');
14
14
  require('aws-amplify');
15
15
  require('jszip');
package/dist/styles.css CHANGED
@@ -4816,6 +4816,88 @@ html[dir=rtl] .amplify-field-group__inner-start {
4816
4816
  gap: var(--amplify-components-message-dismiss-gap);
4817
4817
  }
4818
4818
 
4819
+ /* Modal component with highest specificity to override global resets */
4820
+ .amplify-modal__overlay.amplify-modal__overlay {
4821
+ position: fixed;
4822
+ top: 0;
4823
+ left: 0;
4824
+ right: 0;
4825
+ bottom: 0;
4826
+ background-color: rgba(0, 0, 0, 0.5);
4827
+ z-index: 1000;
4828
+ display: flex;
4829
+ align-items: center;
4830
+ justify-content: center;
4831
+ box-sizing: border-box;
4832
+ }
4833
+
4834
+ .amplify-modal__content.amplify-modal__content {
4835
+ background-color: var(--amplify-colors-background-primary);
4836
+ padding: var(--amplify-space-large);
4837
+ border-radius: var(--amplify-radii-medium);
4838
+ box-shadow: var(--amplify-shadows-large);
4839
+ max-width: 500px;
4840
+ width: 90%;
4841
+ box-sizing: border-box;
4842
+ }
4843
+
4844
+ .amplify-modal__header.amplify-modal__header {
4845
+ margin-bottom: var(--amplify-space-medium);
4846
+ display: flex;
4847
+ justify-content: space-between;
4848
+ align-items: center;
4849
+ }
4850
+
4851
+ .amplify-modal__title.amplify-modal__title {
4852
+ font-weight: var(--amplify-font-weights-bold);
4853
+ font-size: var(--amplify-font-sizes-large);
4854
+ margin: 0;
4855
+ }
4856
+
4857
+ .amplify-modal__close-button.amplify-modal__close-button {
4858
+ background: none;
4859
+ border: none;
4860
+ font-size: var(--amplify-font-sizes-large);
4861
+ cursor: pointer;
4862
+ padding: var(--amplify-space-xs);
4863
+ color: var(--amplify-colors-font-secondary);
4864
+ }
4865
+
4866
+ .amplify-modal__close-button.amplify-modal__close-button:hover {
4867
+ color: var(--amplify-colors-font-primary);
4868
+ }
4869
+
4870
+ .amplify-modal__body.amplify-modal__body {
4871
+ margin-bottom: var(--amplify-space-medium);
4872
+ color: var(--amplify-colors-font-primary);
4873
+ }
4874
+
4875
+ .amplify-modal__footer.amplify-modal__footer {
4876
+ display: flex;
4877
+ gap: var(--amplify-space-xs);
4878
+ justify-content: flex-end;
4879
+ }
4880
+
4881
+ .amplify-modal__list-title.amplify-modal__list-title {
4882
+ margin-bottom: var(--amplify-space-xs);
4883
+ font-weight: var(--amplify-font-weights-bold);
4884
+ box-sizing: border-box;
4885
+ }
4886
+
4887
+ .amplify-modal__list.amplify-modal__list {
4888
+ margin: var(--amplify-space-xs) 0;
4889
+ padding-left: var(--amplify-space-medium);
4890
+ max-height: 250px;
4891
+ overflow-y: auto;
4892
+ box-sizing: border-box;
4893
+ list-style: disc;
4894
+ }
4895
+
4896
+ .amplify-modal__list-item.amplify-modal__list-item {
4897
+ margin-bottom: var(--amplify-space-xxs);
4898
+ box-sizing: border-box;
4899
+ }
4900
+
4819
4901
  .amplify-pagination {
4820
4902
  list-style-type: none;
4821
4903
  }
@@ -7024,7 +7106,6 @@ html[dir=rtl] .amplify-field-group__inner-start {
7024
7106
  animation-timing-function: linear;
7025
7107
  animation-name: spin;
7026
7108
  }
7027
-
7028
7109
  @keyframes spin {
7029
7110
  0% {
7030
7111
  transform: rotate(0deg);
@@ -7036,6 +7117,7 @@ html[dir=rtl] .amplify-field-group__inner-start {
7036
7117
  transform: rotate(360deg);
7037
7118
  }
7038
7119
  }
7120
+
7039
7121
  .amplify-ai-conversation {
7040
7122
  display: flex;
7041
7123
  flex-direction: column;
@@ -1,8 +1,10 @@
1
- import type { OptionalFileData, TaskHandler, TaskHandlerOptions, TaskHandlerInput, TaskHandlerOutput, TaskData } from './types';
1
+ import type { TaskHandler, TaskHandlerOptions, TaskHandlerInput, TaskHandlerOutput, TaskData, OptionalFileData } from './types';
2
2
  export interface DeleteHandlerOptions extends TaskHandlerOptions {
3
3
  }
4
- export interface DeleteHandlerData extends OptionalFileData, TaskData {
5
- fileKey: string;
4
+ export interface DeleteHandlerData extends Omit<OptionalFileData, 'type'>, TaskData {
5
+ fileKey?: string;
6
+ type?: 'FILE' | 'FOLDER';
7
+ totalCount?: number | null;
6
8
  }
7
9
  export interface DeleteHandlerInput extends TaskHandlerInput<DeleteHandlerData, DeleteHandlerOptions> {
8
10
  }
@@ -79,7 +79,11 @@ export interface TaskHandlerOptions {
79
79
  onProgress?: (data: {
80
80
  key: string;
81
81
  id: string;
82
- }, progress: number | undefined, state?: TaskStatus) => void;
82
+ }, progressDetails: number | undefined | {
83
+ progress?: number;
84
+ successCount?: number;
85
+ failureCount?: number;
86
+ }, state?: TaskStatus) => void;
83
87
  }
84
88
  export interface TaskHandlerInput<TData extends TaskData = TaskData, TOptions extends TaskHandlerOptions = TaskHandlerOptions> {
85
89
  config: ActionInputConfig;
@@ -105,6 +109,16 @@ export interface TaskResult<TStatus, TValue> {
105
109
  * task result value (if any)
106
110
  */
107
111
  value?: TValue;
112
+ /**
113
+ * Number of items successfully processed during the operation
114
+ * @example 150 // out of 200 total items
115
+ */
116
+ successCount?: number;
117
+ /**
118
+ * Number of items that failed during the operation
119
+ * @example 5 // out of 200 total items
120
+ */
121
+ failureCount?: number;
108
122
  }
109
123
  export interface TaskHandlerOutput<K = any> {
110
124
  cancel?: () => void;
@@ -0,0 +1,12 @@
1
+ import React from 'react';
2
+ export interface ActionConfirmationModalProps {
3
+ isOpen: boolean;
4
+ title: string;
5
+ message: string;
6
+ content?: React.ReactNode;
7
+ onConfirm: () => void;
8
+ onCancel: () => void;
9
+ confirmLabel: string;
10
+ cancelLabel: string;
11
+ }
12
+ export declare const ActionConfirmationModal: ({ isOpen, title, message, content, onConfirm, onCancel, confirmLabel, cancelLabel, }: ActionConfirmationModalProps) => React.JSX.Element | null;
@@ -1,4 +1,5 @@
1
1
  import type { ActionCancelProps } from './ActionCancel';
2
+ import type { ActionConfirmationModalProps } from './ActionConfirmationModal';
2
3
  import type { ActionDestinationProps } from './ActionDestination';
3
4
  import type { ActionExitProps } from './ActionExit';
4
5
  import type { ActionStartProps } from './ActionStart';
@@ -21,6 +22,7 @@ import type { TitleProps } from './Title';
21
22
  import type { FilePreviewProps } from './FilePreview';
22
23
  export interface Composables {
23
24
  ActionCancel: React.ComponentType<ActionCancelProps>;
25
+ ActionConfirmationModal: React.ComponentType<ActionConfirmationModalProps>;
24
26
  ActionDestination: React.ComponentType<ActionDestinationProps>;
25
27
  ActionExit: React.ComponentType<ActionExitProps>;
26
28
  ActionStart: React.ComponentType<ActionStartProps>;
@@ -0,0 +1,2 @@
1
+ import React from 'react';
2
+ export declare const ActionConfirmationModalControl: () => React.JSX.Element;
@@ -0,0 +1,2 @@
1
+ import type { ActionConfirmationModalProps } from '../../components/composables/ActionConfirmationModal';
2
+ export declare const useActionConfirmationModal: () => ActionConfirmationModalProps;
@@ -1,4 +1,5 @@
1
1
  export { ActionCancelControl } from './ActionCancelControl';
2
+ export { ActionConfirmationModalControl } from './ActionConfirmationModalControl';
2
3
  export { ActionDestinationControl } from './ActionDestinationControl';
3
4
  export { ActionExitControl } from './ActionExitControl';
4
5
  export { ActionsListControl } from './ActionsListControl';
@@ -1,5 +1,6 @@
1
1
  import type { FileData, LocationData } from '../actions';
2
2
  import type { ActionListItem, Composables, DataTableProps, DataTableSortHeader, MessageProps } from '../components';
3
+ import type { ActionConfirmationModalProps } from '../components/composables/ActionConfirmationModal';
3
4
  import type { LocationState } from '../store';
4
5
  import type { StatusCounts } from '../tasks';
5
6
  import type { FilePreviewState } from '../views/hooks/useFilePreview';
@@ -53,6 +54,7 @@ export interface ControlsContext {
53
54
  location?: LocationState;
54
55
  overwriteToggleLabel?: string;
55
56
  message?: MessageProps;
57
+ confirmationModal?: Omit<ActionConfirmationModalProps, 'onConfirm' | 'onCancel'>;
56
58
  paginationData?: PaginationData;
57
59
  searchPlaceholder?: string;
58
60
  searchQuery?: string;
@@ -91,5 +93,7 @@ export interface ControlsContext {
91
93
  onToggleOverwrite?: () => void;
92
94
  onToggleSearchSubfolders?: () => void;
93
95
  onValidateFolderName?: (value: string) => void;
96
+ onConfirmationModalConfirm?: () => void;
97
+ onConfirmationModalCancel?: () => void;
94
98
  }
95
99
  export {};
@@ -73,6 +73,7 @@ export interface DefaultLocationDetailViewDisplayText extends DefaultListViewDis
73
73
  } | undefined;
74
74
  searchSubfoldersToggleLabel: string;
75
75
  selectFileLabel: string;
76
+ selectFolderLabel: string;
76
77
  selectAllFilesLabel: string;
77
78
  tableColumnLastModifiedHeader: string;
78
79
  tableColumnNameHeader: string;
@@ -115,6 +116,7 @@ export interface DefaultActionViewDisplayText<T extends TaskData = TaskData> {
115
116
  tableColumnNameHeader: string;
116
117
  tableColumnTypeHeader: string;
117
118
  tableColumnSizeHeader: string;
119
+ tableColumnProgressHeader?: string;
118
120
  }
119
121
  export interface DefaultCreateFolderViewDisplayText extends Omit<DefaultActionViewDisplayText<CreateFolderHandlerData>, `${'tableColumn' | 'statusDisplay'}${string}`> {
120
122
  folderNameLabel: string;
@@ -144,6 +146,11 @@ export interface DefaultDeleteViewDisplayText extends DefaultActionViewDisplayTe
144
146
  * @deprecated `DeleteView` does not render a "progress" header
145
147
  */
146
148
  tableColumnProgressHeader?: string;
149
+ confirmationModalTitle: string;
150
+ confirmationModalConfirmLabel: string;
151
+ confirmationModalCancelLabel: string;
152
+ confirmationModalMessage: string;
153
+ confirmationModalFolderListTitle: string;
147
154
  }
148
155
  export interface DefaultDownloadViewDisplayText extends DefaultActionViewDisplayText<DownloadHandlerData> {
149
156
  tableColumnProgressHeader: string;
@@ -1,9 +1,9 @@
1
1
  import React from 'react';
2
- import type { FileData, FileDataItem } from '../actions';
2
+ import type { FileDataItem, LocationItemData } from '../actions';
3
3
  export declare const DEFAULT_STATE: LocationItemsState;
4
4
  export type LocationItemsAction = {
5
5
  type: 'SET_LOCATION_ITEMS';
6
- items?: FileData[];
6
+ items?: LocationItemData[];
7
7
  } | {
8
8
  type: 'REMOVE_LOCATION_ITEM';
9
9
  id: string;
@@ -11,7 +11,16 @@ export type LocationItemsAction = {
11
11
  type: 'RESET_LOCATION_ITEMS';
12
12
  };
13
13
  export interface LocationItemsState {
14
- fileDataItems: FileDataItem[] | undefined;
14
+ /**
15
+ * Selected items (files and folders)
16
+ * Replaces fileDataItems to support mixed selections
17
+ */
18
+ dataItems?: LocationItemData[];
19
+ /**
20
+ * @deprecated Use dataItems instead
21
+ * Will be removed in v4.0.0
22
+ */
23
+ fileDataItems?: FileDataItem[];
15
24
  }
16
25
  export type HandleLocationItemsAction = (event: LocationItemsAction) => void;
17
26
  export type LocationItemStateContext = [
@@ -1,2 +1,3 @@
1
1
  export type { LocationItemsAction, LocationItemsProviderProps, LocationItemsState, } from './context';
2
2
  export { LocationItemsProvider, useLocationItems } from './context';
3
+ export { getSelectedFiles, getSelectedFolders, hasSelectedFolders, getSelectionSummary, } from './utils';
@@ -0,0 +1,27 @@
1
+ import type { LocationItemData } from '../actions';
2
+ /**
3
+ * Selection utility functions for LocationItems
4
+ */
5
+ /**
6
+ * Get selected files from dataItems
7
+ */
8
+ export declare const getSelectedFiles: (dataItems?: LocationItemData[]) => LocationItemData[];
9
+ /**
10
+ * Get selected folders from dataItems
11
+ */
12
+ export declare const getSelectedFolders: (dataItems?: LocationItemData[]) => LocationItemData[];
13
+ /**
14
+ * Check if selection contains folders
15
+ */
16
+ export declare const hasSelectedFolders: (dataItems?: LocationItemData[]) => boolean;
17
+ /**
18
+ * Get selection summary
19
+ */
20
+ export declare const getSelectionSummary: (dataItems?: LocationItemData[]) => {
21
+ total: number;
22
+ files: number;
23
+ folders: number;
24
+ hasFiles: boolean;
25
+ hasFolders: boolean;
26
+ isMixed: boolean;
27
+ };
@@ -13,7 +13,11 @@ export interface ProcessTasksOptions<TTask extends Task, TItems = []> {
13
13
  onTaskCancel?: (task: TTask) => void;
14
14
  onTaskComplete?: (task: TTask) => void;
15
15
  onTaskError?: (task: TTask, error: unknown) => void;
16
- onTaskProgress?: (task: TTask, progress: number | undefined) => void;
16
+ onTaskProgress?: (task: TTask, progressDetails: number | {
17
+ progress?: number;
18
+ successCount?: number;
19
+ failureCount?: number;
20
+ }) => void;
17
21
  onTaskSuccess?: (task: TTask, value: TTask['value'] | undefined) => void;
18
22
  onTaskRemove?: (task: TTask) => void;
19
23
  }
@@ -27,7 +31,8 @@ export interface Task<TData = unknown, TValue = any> extends TaskResult<TaskStat
27
31
  */
28
32
  data: TData & TaskData;
29
33
  /**
30
- * task progress
34
+ * task progress (0-1 representing completion percentage)
35
+ * @example 0.75 // 75% complete
31
36
  */
32
37
  progress?: number;
33
38
  /**
@@ -1,6 +1,10 @@
1
1
  import type { DeleteHandlerData, LocationData } from '../../../actions';
2
+ import type { ActionConfirmationModalProps } from '../../../components/composables/ActionConfirmationModal';
2
3
  import type { ActionViewType, ActionViewProps, ActionViewState } from '../types';
3
4
  export interface DeleteViewState extends ActionViewState<DeleteHandlerData> {
5
+ onConfirmDelete: () => void;
6
+ onCancelConfirmation: () => void;
7
+ confirmationModal: Omit<ActionConfirmationModalProps, 'onConfirm' | 'onCancel'>;
4
8
  }
5
9
  export interface DeleteViewProps extends ActionViewProps {
6
10
  }
@@ -10,6 +14,7 @@ export interface DeleteViewProviderProps extends DeleteViewState {
10
14
  export interface DeleteViewType extends ActionViewType<DeleteHandlerData, DeleteViewProps> {
11
15
  Provider: (props: DeleteViewProviderProps) => React.JSX.Element;
12
16
  Cancel: () => React.JSX.Element | null;
17
+ ConfirmationModal: (props: ActionConfirmationModalProps) => React.JSX.Element;
13
18
  Exit: () => React.JSX.Element | null;
14
19
  Message: () => React.JSX.Element | null;
15
20
  Start: () => React.JSX.Element | null;
@@ -0,0 +1,26 @@
1
+ import React from 'react';
2
+ import type { ActionInputConfig, LocationItemData } from '../../../actions';
3
+ import type { ActionConfirmationModalProps } from '../../../components/composables/ActionConfirmationModal';
4
+ export declare const getFolderName: (folderKey: string) => string;
5
+ /**
6
+ * Creates JSX content showing a list of folders to be deleted
7
+ */
8
+ export declare const createFolderListContent: (folders: LocationItemData[], folderListTitle: string) => React.JSX.Element;
9
+ export declare const createDeleteConfirmationModalProps: ({ items, showConfirmation, displayText, }: {
10
+ items: LocationItemData[];
11
+ showConfirmation: boolean;
12
+ displayText: {
13
+ confirmationModalTitle: string;
14
+ confirmationModalConfirmLabel: string;
15
+ confirmationModalCancelLabel: string;
16
+ confirmationModalMessage: string;
17
+ confirmationModalFolderListTitle: string;
18
+ };
19
+ }) => Omit<ActionConfirmationModalProps, 'onConfirm' | 'onCancel'>;
20
+ /**
21
+ * Count the total number of files in a folder with pagination and limits
22
+ * @param folderKey - The folder path to count files in
23
+ * @param config - Storage configuration
24
+ * @returns Promise<number | string> - File count or "5000+" if exceeds limit
25
+ */
26
+ export declare const countFilesInFolder: (folderKey: string, config: ActionInputConfig) => Promise<number | string>;
@@ -1,6 +1,9 @@
1
1
  import type { DataTableProps } from '../../../components';
2
- export declare const getFolderRowContent: ({ itemSubPath, rowId, onNavigate, }: {
2
+ export declare const getFolderRowContent: ({ itemSubPath, rowId, isSelected, selectFolderLabel, onNavigate, onSelect, }: {
3
3
  itemSubPath: string;
4
4
  rowId: string;
5
+ isSelected: boolean;
6
+ selectFolderLabel: string;
5
7
  onNavigate: () => void;
8
+ onSelect: () => void;
6
9
  }) => DataTableProps['rows'][number]['content'];