@aws-amplify/ui-react-storage 3.4.1 → 3.5.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 (134) hide show
  1. package/dist/browser.js +35 -2
  2. package/dist/{createAmplifyAuthAdapter-BRctUWdR.js → createAmplifyAuthAdapter-BUDNgORg.js} +3045 -2921
  3. package/dist/esm/browser.mjs +2 -0
  4. package/dist/esm/components/StorageBrowser/StorageBrowserAmplify.mjs +2 -7
  5. package/dist/esm/components/StorageBrowser/StorageBrowserDefault.mjs +3 -16
  6. package/dist/esm/components/StorageBrowser/actions/configs/context.mjs +4 -9
  7. package/dist/esm/components/StorageBrowser/actions/configs/defaults.mjs +14 -39
  8. package/dist/esm/components/StorageBrowser/actions/configs/utils.mjs +8 -0
  9. package/dist/esm/components/StorageBrowser/actions/handlers/copy.mjs +13 -13
  10. package/dist/esm/components/StorageBrowser/actions/handlers/createFolder.mjs +9 -6
  11. package/dist/esm/components/StorageBrowser/actions/handlers/delete.mjs +9 -7
  12. package/dist/esm/components/StorageBrowser/actions/handlers/download.mjs +7 -11
  13. package/dist/esm/components/StorageBrowser/actions/handlers/listLocationItems.mjs +3 -3
  14. package/dist/esm/components/StorageBrowser/actions/handlers/upload.mjs +11 -7
  15. package/dist/esm/components/StorageBrowser/actions/handlers/utils.mjs +1 -11
  16. package/dist/esm/components/StorageBrowser/adapters/createManagedAuthAdapter/createManagedAuthAdapter.mjs +1 -3
  17. package/dist/esm/components/StorageBrowser/controls/PaginationControl.mjs +3 -3
  18. package/dist/esm/components/StorageBrowser/controls/SearchFieldControl.mjs +12 -0
  19. package/dist/esm/components/StorageBrowser/controls/hooks/usePagination.mjs +9 -0
  20. package/dist/esm/components/StorageBrowser/controls/hooks/useSearchField.mjs +17 -0
  21. package/dist/esm/components/StorageBrowser/createStorageBrowser.mjs +36 -27
  22. package/dist/esm/components/StorageBrowser/displayText/libraries/en/locationDetailView.mjs +6 -0
  23. package/dist/esm/components/StorageBrowser/displayText/libraries/en/locationsView.mjs +2 -2
  24. package/dist/esm/components/StorageBrowser/providers/configuration/createConfigurationProvider.mjs +4 -10
  25. package/dist/esm/components/StorageBrowser/providers/configuration/useGetActionInputCallback.mjs +7 -7
  26. package/dist/esm/components/StorageBrowser/providers/store/locationItems/context.mjs +1 -1
  27. package/dist/esm/components/StorageBrowser/tasks/useProcessTasks.mjs +27 -6
  28. package/dist/esm/components/StorageBrowser/useAction/constants.mjs +4 -0
  29. package/dist/esm/components/StorageBrowser/useAction/context.mjs +8 -0
  30. package/dist/esm/components/StorageBrowser/useAction/useAction.mjs +18 -0
  31. package/dist/esm/components/StorageBrowser/useAction/useHandler.mjs +40 -0
  32. package/dist/esm/components/StorageBrowser/useAction/useList.mjs +19 -0
  33. package/dist/esm/components/StorageBrowser/useAction/useListFolderItems.mjs +23 -0
  34. package/dist/esm/components/StorageBrowser/useAction/useListLocationItems.mjs +23 -0
  35. package/dist/esm/components/StorageBrowser/{actions/useAction → useAction}/useListLocations.mjs +7 -6
  36. package/dist/esm/components/StorageBrowser/useAction/utils.mjs +26 -0
  37. package/dist/esm/components/StorageBrowser/views/LocationActionView/CopyView/CopyView.mjs +3 -3
  38. package/dist/esm/components/StorageBrowser/views/LocationActionView/CopyView/useCopyView.mjs +32 -17
  39. package/dist/esm/components/StorageBrowser/views/LocationActionView/CopyView/useFolders.mjs +12 -17
  40. package/dist/esm/components/StorageBrowser/views/LocationActionView/CreateFolderView/useCreateFolderView.mjs +18 -15
  41. package/dist/esm/components/StorageBrowser/views/LocationActionView/DeleteView/useDeleteView.mjs +17 -12
  42. package/dist/esm/components/StorageBrowser/views/LocationActionView/LocationActionView.mjs +9 -16
  43. package/dist/esm/components/StorageBrowser/views/LocationActionView/UploadView/useUploadView.mjs +44 -49
  44. package/dist/esm/components/StorageBrowser/views/LocationActionView/getActionViewTableData.mjs +2 -4
  45. package/dist/esm/components/StorageBrowser/views/LocationDetailView/LocationDetailView.mjs +3 -3
  46. package/dist/esm/components/StorageBrowser/views/LocationDetailView/LocationDetailViewProvider.mjs +12 -8
  47. package/dist/esm/components/StorageBrowser/views/LocationDetailView/getLocationDetailViewTableData/getLocationDetailViewTableData.mjs +1 -0
  48. package/dist/esm/components/StorageBrowser/views/LocationDetailView/useLocationDetailView.mjs +50 -69
  49. package/dist/esm/components/StorageBrowser/views/LocationsView/LocationsView.mjs +3 -3
  50. package/dist/esm/components/StorageBrowser/views/LocationsView/LocationsViewProvider.mjs +2 -3
  51. package/dist/esm/components/StorageBrowser/views/LocationsView/useLocationsView.mjs +22 -29
  52. package/dist/esm/components/StorageBrowser/views/context/actionViews.mjs +33 -0
  53. package/dist/esm/components/StorageBrowser/views/context/getViews.mjs +32 -0
  54. package/dist/esm/components/StorageBrowser/views/context/primaryViews.mjs +32 -0
  55. package/dist/esm/components/StorageBrowser/views/context/views.mjs +19 -0
  56. package/dist/esm/components/StorageBrowser/views/{createUseView.mjs → useView.mjs} +19 -28
  57. package/dist/esm/version.mjs +1 -1
  58. package/dist/index.js +3 -6
  59. package/dist/styles.css +6 -2
  60. package/dist/types/components/StorageBrowser/actions/configs/context.d.ts +4 -5
  61. package/dist/types/components/StorageBrowser/actions/configs/defaults.d.ts +6 -7
  62. package/dist/types/components/StorageBrowser/actions/configs/index.d.ts +3 -2
  63. package/dist/types/components/StorageBrowser/actions/configs/types.d.ts +39 -69
  64. package/dist/types/components/StorageBrowser/actions/configs/utils.d.ts +2 -0
  65. package/dist/types/components/StorageBrowser/actions/handlers/copy.d.ts +12 -5
  66. package/dist/types/components/StorageBrowser/actions/handlers/createFolder.d.ts +7 -4
  67. package/dist/types/components/StorageBrowser/actions/handlers/delete.d.ts +6 -3
  68. package/dist/types/components/StorageBrowser/actions/handlers/download.d.ts +6 -3
  69. package/dist/types/components/StorageBrowser/actions/handlers/types.d.ts +11 -2
  70. package/dist/types/components/StorageBrowser/actions/handlers/upload.d.ts +8 -4
  71. package/dist/types/components/StorageBrowser/actions/handlers/utils.d.ts +0 -1
  72. package/dist/types/components/StorageBrowser/actions/index.d.ts +2 -4
  73. package/dist/types/components/StorageBrowser/adapters/permissionParsers.d.ts +1 -1
  74. package/dist/types/components/StorageBrowser/composables/ActionsList.d.ts +2 -2
  75. package/dist/types/components/StorageBrowser/controls/SearchFieldControl.d.ts +2 -0
  76. package/dist/types/components/StorageBrowser/controls/hooks/usePagination.d.ts +2 -0
  77. package/dist/types/components/StorageBrowser/controls/hooks/useSearchField.d.ts +2 -0
  78. package/dist/types/components/StorageBrowser/controls/types.d.ts +3 -3
  79. package/dist/types/components/StorageBrowser/createStorageBrowser.d.ts +3 -7
  80. package/dist/types/components/StorageBrowser/displayText/index.d.ts +1 -1
  81. package/dist/types/components/StorageBrowser/displayText/types.d.ts +1 -1
  82. package/dist/types/components/StorageBrowser/index.d.ts +3 -1
  83. package/dist/types/components/StorageBrowser/providers/configuration/index.d.ts +1 -1
  84. package/dist/types/components/StorageBrowser/providers/configuration/types.d.ts +2 -2
  85. package/dist/types/components/StorageBrowser/providers/store/files/types.d.ts +10 -1
  86. package/dist/types/components/StorageBrowser/providers/store/files/utils.d.ts +1 -2
  87. package/dist/types/components/StorageBrowser/tasks/types.d.ts +16 -13
  88. package/dist/types/components/StorageBrowser/tasks/useProcessTasks.d.ts +2 -3
  89. package/dist/types/components/StorageBrowser/types.d.ts +42 -12
  90. package/dist/types/components/StorageBrowser/useAction/constants.d.ts +3 -0
  91. package/dist/types/components/StorageBrowser/useAction/context.d.ts +5 -0
  92. package/dist/types/components/StorageBrowser/{actions/useAction → useAction}/createEnhancedListHandler.d.ts +3 -3
  93. package/dist/types/components/StorageBrowser/useAction/index.d.ts +6 -0
  94. package/dist/types/components/StorageBrowser/useAction/types.d.ts +76 -0
  95. package/dist/types/components/StorageBrowser/useAction/useAction.d.ts +3 -0
  96. package/dist/types/components/StorageBrowser/useAction/useHandler.d.ts +3 -0
  97. package/dist/types/components/StorageBrowser/useAction/useList.d.ts +9 -0
  98. package/dist/types/components/StorageBrowser/useAction/useListFolderItems.d.ts +13 -0
  99. package/dist/types/components/StorageBrowser/useAction/useListLocationItems.d.ts +10 -0
  100. package/dist/types/components/StorageBrowser/useAction/useListLocations.d.ts +8 -0
  101. package/dist/types/components/StorageBrowser/useAction/utils.d.ts +6 -0
  102. package/dist/types/components/StorageBrowser/views/LocationActionView/CopyView/useFolders.d.ts +1 -4
  103. package/dist/types/components/StorageBrowser/views/LocationActionView/CreateFolderView/types.d.ts +2 -2
  104. package/dist/types/components/StorageBrowser/views/LocationActionView/LocationActionView.d.ts +2 -6
  105. package/dist/types/components/StorageBrowser/views/LocationActionView/getActionViewTableData.d.ts +2 -4
  106. package/dist/types/components/StorageBrowser/views/LocationActionView/index.d.ts +6 -6
  107. package/dist/types/components/StorageBrowser/views/LocationActionView/types.d.ts +4 -8
  108. package/dist/types/components/StorageBrowser/views/LocationDetailView/getLocationDetailViewTableData/getLocationDetailViewTableData.d.ts +1 -3
  109. package/dist/types/components/StorageBrowser/views/LocationDetailView/types.d.ts +16 -17
  110. package/dist/types/components/StorageBrowser/views/LocationsView/types.d.ts +8 -12
  111. package/dist/types/components/StorageBrowser/views/context/actionViews.d.ts +6 -0
  112. package/dist/types/components/StorageBrowser/views/context/getViews.d.ts +4 -0
  113. package/dist/types/components/StorageBrowser/views/context/index.d.ts +1 -0
  114. package/dist/types/components/StorageBrowser/views/context/primaryViews.d.ts +6 -0
  115. package/dist/types/components/StorageBrowser/views/context/types.d.ts +9 -0
  116. package/dist/types/components/StorageBrowser/views/context/views.d.ts +10 -0
  117. package/dist/types/components/StorageBrowser/views/index.d.ts +2 -2
  118. package/dist/types/components/StorageBrowser/views/types.d.ts +22 -0
  119. package/dist/types/components/StorageBrowser/views/useView.d.ts +16 -0
  120. package/dist/types/version.d.ts +1 -1
  121. package/package.json +4 -4
  122. package/dist/esm/components/StorageBrowser/controls/SearchControl.mjs +0 -13
  123. package/dist/esm/components/StorageBrowser/views/LocationActionView/constants.mjs +0 -3
  124. package/dist/esm/components/StorageBrowser/views/LocationActionView/useActionView.mjs +0 -20
  125. package/dist/esm/components/StorageBrowser/views/context.mjs +0 -43
  126. package/dist/types/components/StorageBrowser/actions/createUseAction.d.ts +0 -2
  127. package/dist/types/components/StorageBrowser/actions/types.d.ts +0 -8
  128. package/dist/types/components/StorageBrowser/actions/useAction/index.d.ts +0 -1
  129. package/dist/types/components/StorageBrowser/actions/useAction/useListLocations.d.ts +0 -8
  130. package/dist/types/components/StorageBrowser/controls/SearchControl.d.ts +0 -2
  131. package/dist/types/components/StorageBrowser/views/LocationActionView/constants.d.ts +0 -1
  132. package/dist/types/components/StorageBrowser/views/context.d.ts +0 -16
  133. package/dist/types/components/StorageBrowser/views/createUseView.d.ts +0 -19
  134. /package/dist/esm/components/StorageBrowser/{actions/useAction → useAction}/createEnhancedListHandler.mjs +0 -0
@@ -1,21 +1,15 @@
1
1
  import React__default from 'react';
2
2
  import { isComponent } from '@aws-amplify/ui-react-core/elements';
3
- import { ActionConfigsProvider } from '../../actions/configs/context.mjs';
4
- import '@aws-amplify/storage/internals';
5
- import '@aws-amplify/ui';
6
- import 'aws-amplify/storage';
7
- import '@aws-amplify/ui-react-core';
8
3
  import { CredentialsProvider } from './credentials/context.mjs';
9
4
  import { GetActionInputProvider } from './context.mjs';
10
5
 
11
6
  const Passthrough = ({ children }) => (React__default.createElement(React__default.Fragment, null, children));
12
7
  function createConfigurationProvider(input) {
13
- const { accountId, actions, ChildComponent, displayName, region, customEndpoint, ...rest } = input;
8
+ const { accountId, ChildComponent, displayName, region, customEndpoint, ...rest } = input;
14
9
  const Child = isComponent(ChildComponent) ? ChildComponent : Passthrough;
15
- const Provider = (props) => (React__default.createElement(ActionConfigsProvider, { actions: actions },
16
- React__default.createElement(CredentialsProvider, { ...rest },
17
- React__default.createElement(GetActionInputProvider, { accountId: accountId, region: region, customEndpoint: customEndpoint },
18
- React__default.createElement(Child, { ...props })))));
10
+ const Provider = (props) => (React__default.createElement(CredentialsProvider, { ...rest },
11
+ React__default.createElement(GetActionInputProvider, { accountId: accountId, region: region, customEndpoint: customEndpoint },
12
+ React__default.createElement(Child, { ...props }))));
19
13
  Provider.displayName = displayName;
20
14
  return Provider;
21
15
  }
@@ -13,18 +13,18 @@ function useGetActionInputCallback({ accountId, customEndpoint, region, }) {
13
13
  const { getCredentials } = useCredentials();
14
14
  const [{ location }] = useStore();
15
15
  const { current, key } = location;
16
- return React__default.useCallback((location) => {
16
+ return React__default.useCallback((_location) => {
17
17
  // prefer passed in location / prefix over current location in state
18
- const _location = location ?? current;
18
+ const location = _location ?? current;
19
19
  // when `location` has been provided as a param, resolve `_prefix` to `location.prefix`.
20
20
  // in the default scenario where `current` is the target `location` use the fully qualified `key`
21
21
  // that includes the default `prefix` and any additional prefixes from navigation
22
- const _prefix = location ? location.prefix : key;
23
- assertLocationData(_location, getErrorMessage('locationData'));
24
- assertPrefix(_prefix, getErrorMessage('prefix'));
25
- const { bucket, permissions, type } = _location;
22
+ const prefix = _location ? _location.prefix : key;
23
+ assertLocationData(location, getErrorMessage('locationData'));
24
+ assertPrefix(prefix, getErrorMessage('prefix'));
25
+ const { bucket, permissions, type } = location;
26
26
  // BUCKET/PREFIX grants end with `*`, but object grants do not.
27
- const scope = `s3://${bucket}/${_prefix}${type === 'OBJECT' ? '' : '*'}`;
27
+ const scope = `s3://${bucket}/${prefix}${type === 'OBJECT' ? '' : '*'}`;
28
28
  return {
29
29
  accountId,
30
30
  bucket,
@@ -1,10 +1,10 @@
1
1
  import React__default from 'react';
2
2
  import { createContextUtilities } from '@aws-amplify/ui-react-core';
3
3
  import { noop } from '@aws-amplify/ui';
4
- import '../../../actions/configs/context.mjs';
5
4
  import '@aws-amplify/storage/internals';
6
5
  import { createFileDataItem } from '../../../actions/handlers/utils.mjs';
7
6
  import 'aws-amplify/storage';
7
+ import '../../../actions/configs/context.mjs';
8
8
 
9
9
  const DEFAULT_STATE = {
10
10
  fileDataItems: undefined,
@@ -1,6 +1,6 @@
1
1
  import React__default from 'react';
2
- import { getStatusCounts, isProcessingTasks, hasCompletedProcessingTasks } from './utils.mjs';
3
2
  import { isFunction } from '@aws-amplify/ui';
3
+ import { getStatusCounts, isProcessingTasks, hasCompletedProcessingTasks } from './utils.mjs';
4
4
 
5
5
  const QUEUED_TASK_BASE = {
6
6
  cancel: undefined,
@@ -17,6 +17,12 @@ const useProcessTasks = (handler, items, options) => {
17
17
  }
18
18
  const tasksRef = React__default.useRef(new Map());
19
19
  const flush = React__default.useReducer(() => ({}), {})[1];
20
+ const refreshTaskData = React__default.useCallback((id, data) => {
21
+ const task = tasksRef.current.get(id);
22
+ if (!task || task.data.id !== data.id)
23
+ return;
24
+ tasksRef.current.set(id, { ...task, data });
25
+ }, []);
20
26
  const updateTask = React__default.useCallback((id, next) => {
21
27
  const { onTaskRemove } = callbacksRef.current;
22
28
  const task = tasksRef.current.get(id);
@@ -56,6 +62,9 @@ const useProcessTasks = (handler, items, options) => {
56
62
  // If an item doesn't yet have a task created for it, create one
57
63
  createTask(item);
58
64
  }
65
+ else {
66
+ refreshTaskData(item.id, item);
67
+ }
59
68
  // Remove the item from the lookup to mark it as "synced"
60
69
  delete taskLookup[item.id];
61
70
  });
@@ -67,7 +76,7 @@ const useProcessTasks = (handler, items, options) => {
67
76
  updateTask(taskId);
68
77
  });
69
78
  flush();
70
- }, [createTask, flush, updateTask, items]);
79
+ }, [createTask, flush, updateTask, items, refreshTaskData]);
71
80
  const processNextTask = (_input) => {
72
81
  const hasInputData = isTaskHandlerInput(_input);
73
82
  if (hasInputData) {
@@ -81,14 +90,18 @@ const useProcessTasks = (handler, items, options) => {
81
90
  return;
82
91
  const { onTaskCancel, onTaskComplete, onTaskError, onTaskProgress, onTaskSuccess, } = callbacksRef.current;
83
92
  const getTask = () => tasksRef.current.get(data.id);
93
+ const { options } = _input;
94
+ const { onProgress: _onProgress, onSuccess, onError } = options ?? {};
84
95
  const onProgress = ({ id }, progress) => {
85
96
  const task = getTask();
86
97
  if (task && isFunction(onTaskProgress)) {
87
98
  onTaskProgress(task, progress);
88
99
  }
100
+ if (task && isFunction(_onProgress)) {
101
+ _onProgress(data, progress);
102
+ }
89
103
  updateTask(id, { progress });
90
104
  };
91
- const { options } = _input;
92
105
  const input = { ..._input, data, options: { ...options, onProgress } };
93
106
  const { cancel: _cancel, result } = handler(input);
94
107
  const cancel = !_cancel
@@ -102,14 +115,19 @@ const useProcessTasks = (handler, items, options) => {
102
115
  result
103
116
  .then((output) => {
104
117
  const task = getTask();
105
- if (task && isFunction(onTaskSuccess))
106
- onTaskSuccess(task);
118
+ if (task && isFunction(onTaskSuccess)) {
119
+ onTaskSuccess(task, output?.value);
120
+ }
121
+ if (task && isFunction(onSuccess))
122
+ onSuccess(data, output?.value);
107
123
  updateTask(data.id, output);
108
124
  })
109
125
  .catch((e) => {
110
126
  const task = getTask();
111
127
  if (task && isFunction(onTaskError))
112
128
  onTaskError(task, e);
129
+ if (task && isFunction(onError))
130
+ onError(data, e?.message);
113
131
  updateTask(data.id, { message: e.message, status: 'FAILED' });
114
132
  })
115
133
  .finally(() => {
@@ -141,8 +159,11 @@ const useProcessTasks = (handler, items, options) => {
141
159
  count++;
142
160
  }
143
161
  };
162
+ const reset = () => {
163
+ tasks.forEach(({ data }) => updateTask(data.id));
164
+ };
144
165
  return [
145
- { isProcessing, isProcessingComplete, statusCounts, tasks },
166
+ { isProcessing, isProcessingComplete, reset, statusCounts, tasks },
146
167
  handleProcessTasks,
147
168
  ];
148
169
  };
@@ -0,0 +1,4 @@
1
+ const DEFAULT_ACTION_CONCURRENCY = 4;
2
+ const USE_LIST_ERROR_MESSAGE = '`useList` must be called from within `StorageBrowser.Provider`';
3
+
4
+ export { DEFAULT_ACTION_CONCURRENCY, USE_LIST_ERROR_MESSAGE };
@@ -0,0 +1,8 @@
1
+ import { createContextUtilities } from '@aws-amplify/ui-react-core';
2
+
3
+ const { ActionHandlersProvider, useActionHandlers } = createContextUtilities({
4
+ contextName: 'ActionHandlers',
5
+ errorMessage: '`useActionHandlers` must be called from within an `ActionHandlersProvider',
6
+ });
7
+
8
+ export { ActionHandlersProvider, useActionHandlers };
@@ -0,0 +1,18 @@
1
+ import { useActionHandlers } from './context.mjs';
2
+ import { useHandler } from './useHandler.mjs';
3
+
4
+ const ERROR_MESSAGE = '`useAction` must be called from within `StorageBrowser.Provider`';
5
+ const useAction = (key, options) => {
6
+ if (key === 'listLocations' ||
7
+ key === 'listLocationItems') {
8
+ throw new Error(`Value of \`${key}\` cannot be used to index \`useAction\``);
9
+ }
10
+ const { handlers } = useActionHandlers({ errorMessage: ERROR_MESSAGE });
11
+ const handler = handlers[key];
12
+ if (!handler) {
13
+ throw new Error(`No handler found for value of \`${key}\` provided to \`useAction\``);
14
+ }
15
+ return useHandler(handler, options);
16
+ };
17
+
18
+ export { ERROR_MESSAGE, useAction };
@@ -0,0 +1,40 @@
1
+ import React__default from 'react';
2
+ import { isObject } from '@aws-amplify/ui';
3
+ import { useGetActionInput } from '../providers/configuration/context.mjs';
4
+ import '../providers/store/location/context.mjs';
5
+ import '../providers/store/files/context.mjs';
6
+ import '../providers/store/actionType/context.mjs';
7
+ import '../providers/store/locationItems/context.mjs';
8
+ import { useStore } from '../providers/store/useStore.mjs';
9
+ import { useProcessTasks } from '../tasks/useProcessTasks.mjs';
10
+ import { DEFAULT_ACTION_CONCURRENCY } from './constants.mjs';
11
+
12
+ const isTasksOptions = (value) => isObject(value);
13
+ const useHandler = (action, options) => {
14
+ const hasOptions = isTasksOptions(options);
15
+ const { items, onTaskSuccess } = options ?? {};
16
+ const getConfig = useGetActionInput();
17
+ const { location: { current }, } = useStore()[0];
18
+ const [state, processTask] = useProcessTasks(action, items, {
19
+ onTaskSuccess,
20
+ ...(items ? { concurrency: DEFAULT_ACTION_CONCURRENCY } : undefined),
21
+ });
22
+ const { reset, isProcessing, tasks } = state;
23
+ const handler = React__default.useCallback((input) => {
24
+ const { location } = input ?? {};
25
+ const config = getConfig(location ?? current);
26
+ if (!hasOptions) {
27
+ // clean up previous state
28
+ reset();
29
+ processTask({ ...input, config });
30
+ return;
31
+ }
32
+ processTask({ config });
33
+ }, [current, getConfig, hasOptions, processTask, reset]);
34
+ return [
35
+ hasOptions ? state : { isProcessing, task: tasks?.[0] },
36
+ handler,
37
+ ];
38
+ };
39
+
40
+ export { useHandler };
@@ -0,0 +1,19 @@
1
+ import { useListLocations } from './useListLocations.mjs';
2
+ import { useListLocationItems } from './useListLocationItems.mjs';
3
+ import { useListFolderItems } from './useListFolderItems.mjs';
4
+
5
+ const LIST_ACTION_HOOKS = {
6
+ folderItems: useListFolderItems,
7
+ locationItems: useListLocationItems,
8
+ locations: useListLocations,
9
+ };
10
+ const isListActionViewType = (value) => Object.keys(LIST_ACTION_HOOKS).includes(value);
11
+ // @ts-expect-error
12
+ const useList = (type) => {
13
+ if (!isListActionViewType(type)) {
14
+ throw new Error(`Value of \`${type}\` cannot be used to index \`useList\``);
15
+ }
16
+ return LIST_ACTION_HOOKS[type]();
17
+ };
18
+
19
+ export { useList };
@@ -0,0 +1,23 @@
1
+ import React__default from 'react';
2
+ import { useDataState } from '@aws-amplify/ui-react-core';
3
+ import { USE_LIST_ERROR_MESSAGE } from './constants.mjs';
4
+ import { useActionHandlers } from './context.mjs';
5
+ import { createEnhancedListHandler } from './createEnhancedListHandler.mjs';
6
+ import '@aws-amplify/ui-react-core/elements';
7
+ import '../providers/configuration/credentials/context.mjs';
8
+ import { useGetActionInput } from '../providers/configuration/context.mjs';
9
+
10
+ const useListFolderItems = () => {
11
+ const { handlers } = useActionHandlers({
12
+ errorMessage: USE_LIST_ERROR_MESSAGE,
13
+ });
14
+ const getConfig = useGetActionInput();
15
+ const { listLocationItems } = handlers;
16
+ const enhancedHandler = React__default.useMemo(() => createEnhancedListHandler((input) => listLocationItems({ ...input, config: getConfig() })), [getConfig, listLocationItems]);
17
+ return useDataState(enhancedHandler, {
18
+ items: [],
19
+ nextToken: undefined,
20
+ });
21
+ };
22
+
23
+ export { useListFolderItems };
@@ -0,0 +1,23 @@
1
+ import React__default from 'react';
2
+ import { useDataState } from '@aws-amplify/ui-react-core';
3
+ import '@aws-amplify/ui-react-core/elements';
4
+ import '../providers/configuration/credentials/context.mjs';
5
+ import { useGetActionInput } from '../providers/configuration/context.mjs';
6
+ import { USE_LIST_ERROR_MESSAGE } from './constants.mjs';
7
+ import { useActionHandlers } from './context.mjs';
8
+ import { createEnhancedListHandler } from './createEnhancedListHandler.mjs';
9
+
10
+ const useListLocationItems = () => {
11
+ const { handlers } = useActionHandlers({
12
+ errorMessage: USE_LIST_ERROR_MESSAGE,
13
+ });
14
+ const getConfig = useGetActionInput();
15
+ const { listLocationItems } = handlers;
16
+ const enhancedHandler = React__default.useMemo(() => createEnhancedListHandler((input) => listLocationItems({ ...input, config: getConfig() })), [getConfig, listLocationItems]);
17
+ return useDataState(enhancedHandler, {
18
+ items: [],
19
+ nextToken: undefined,
20
+ });
21
+ };
22
+
23
+ export { useListLocationItems };
@@ -1,14 +1,15 @@
1
1
  import React__default from 'react';
2
2
  import { useDataState } from '@aws-amplify/ui-react-core';
3
- import { useActionConfig } from '../configs/context.mjs';
4
- import '@aws-amplify/storage/internals';
5
- import '@aws-amplify/ui';
6
- import 'aws-amplify/storage';
3
+ import { USE_LIST_ERROR_MESSAGE } from './constants.mjs';
4
+ import { useActionHandlers } from './context.mjs';
7
5
  import { createEnhancedListHandler } from './createEnhancedListHandler.mjs';
8
6
 
9
7
  const useListLocations = () => {
10
- const { handler } = useActionConfig('listLocations');
11
- const enhancedHandler = React__default.useMemo(() => createEnhancedListHandler(handler), [handler]);
8
+ const { handlers } = useActionHandlers({
9
+ errorMessage: USE_LIST_ERROR_MESSAGE,
10
+ });
11
+ const { listLocations } = handlers;
12
+ const enhancedHandler = React__default.useMemo(() => createEnhancedListHandler(listLocations), [listLocations]);
12
13
  return useDataState(enhancedHandler, {
13
14
  items: [],
14
15
  nextToken: undefined,
@@ -0,0 +1,26 @@
1
+ import { isFunction } from '@aws-amplify/ui';
2
+ import '@aws-amplify/storage/internals';
3
+ import 'aws-amplify/storage';
4
+ import '../actions/configs/context.mjs';
5
+ import { isDefaultActionViewType } from '../actions/configs/defaults.mjs';
6
+
7
+ const resolveHandler = (value) => (isFunction(value) ? value : value.handler);
8
+ const getActionHandlers = (configs) => {
9
+ const { copy: copyConfig, createFolder: createFolderConfig, delete: deleteConfig, download, upload: uploadConfig, listLocationItems, listLocations, } = configs.default;
10
+ const defaultHandlers = {
11
+ copy: copyConfig.handler,
12
+ createFolder: createFolderConfig.handler,
13
+ delete: deleteConfig.handler,
14
+ download,
15
+ listLocationItems,
16
+ listLocations,
17
+ upload: uploadConfig.handler,
18
+ };
19
+ return !configs.custom
20
+ ? defaultHandlers
21
+ : Object.entries(configs.custom).reduce((handlers, [key, config]) => isDefaultActionViewType(key)
22
+ ? handlers
23
+ : { ...handlers, [key]: resolveHandler(config) }, defaultHandlers);
24
+ };
25
+
26
+ export { getActionHandlers };
@@ -9,7 +9,7 @@ import { ActionStartControl } from '../../../controls/ActionStartControl.mjs';
9
9
  import { DataTableControl } from '../../../controls/DataTableControl.mjs';
10
10
  import { LoadingIndicatorControl } from '../../../controls/LoadingIndicatorControl.mjs';
11
11
  import { MessageControl } from '../../../controls/MessageControl.mjs';
12
- import { SearchControl } from '../../../controls/SearchControl.mjs';
12
+ import { SearchFieldControl } from '../../../controls/SearchFieldControl.mjs';
13
13
  import { StatusDisplayControl } from '../../../controls/StatusDisplayControl.mjs';
14
14
  import { TitleControl } from '../../../controls/TitleControl.mjs';
15
15
  import { CopyViewProvider } from './CopyViewProvider.mjs';
@@ -32,7 +32,7 @@ const CopyView = ({ className, ...props }) => {
32
32
  isProcessing || isProcessingComplete ? null : (React__default.createElement(React__default.Fragment, null,
33
33
  React__default.createElement(ViewElement, { className: `${STORAGE_BROWSER_BLOCK}__controls` },
34
34
  React__default.createElement(ViewElement, { className: `${STORAGE_BROWSER_BLOCK}__search` },
35
- React__default.createElement(SearchControl, null)),
35
+ React__default.createElement(SearchFieldControl, null)),
36
36
  React__default.createElement(FoldersPaginationControl, null)),
37
37
  React__default.createElement(ViewElement, { className: `${STORAGE_BROWSER_BLOCK}__data-table` },
38
38
  React__default.createElement(LoadingIndicatorControl, null),
@@ -55,7 +55,7 @@ CopyView.Exit = ActionExitControl;
55
55
  CopyView.FoldersLoadingIndicator = LoadingIndicatorControl;
56
56
  CopyView.FoldersMessage = FoldersMessageControl;
57
57
  CopyView.FoldersPagination = FoldersPaginationControl;
58
- CopyView.FoldersSearch = SearchControl;
58
+ CopyView.FoldersSearch = SearchFieldControl;
59
59
  CopyView.FoldersTable = FoldersTableControl;
60
60
  CopyView.Message = MessageControl;
61
61
  CopyView.Start = ActionStartControl;
@@ -1,28 +1,43 @@
1
- import React__default, { useState } from 'react';
1
+ import React__default, { useRef, useState } from 'react';
2
2
  import { isFunction } from '@aws-amplify/ui';
3
- import { copyHandler } from '../../../actions/handlers/copy.mjs';
4
- import '@aws-amplify/storage/internals';
5
- import 'aws-amplify/storage';
6
- import { useProcessTasks } from '../../../tasks/useProcessTasks.mjs';
7
- import { useGetActionInput } from '../../../providers/configuration/context.mjs';
8
- import '@aws-amplify/ui-react-core/elements';
9
- import '../../../actions/configs/context.mjs';
10
- import '@aws-amplify/ui-react-core';
11
- import '../../../providers/configuration/credentials/context.mjs';
12
3
  import '../../../providers/store/location/context.mjs';
13
4
  import '../../../providers/store/files/context.mjs';
14
5
  import '../../../providers/store/actionType/context.mjs';
15
6
  import '../../../providers/store/locationItems/context.mjs';
16
7
  import { useStore } from '../../../providers/store/useStore.mjs';
8
+ import '../../../useAction/context.mjs';
9
+ import { useAction } from '../../../useAction/useAction.mjs';
10
+ import '@aws-amplify/ui-react-core';
11
+ import '@aws-amplify/ui-react-core/elements';
12
+ import '../../../providers/configuration/credentials/context.mjs';
13
+ import '../../../providers/configuration/context.mjs';
14
+ import '@aws-amplify/storage/internals';
15
+ import 'aws-amplify/storage';
16
+ import '../../../actions/configs/context.mjs';
17
17
  import { useFolders } from './useFolders.mjs';
18
18
 
19
19
  const useCopyView = (options) => {
20
20
  const { onExit } = options ?? {};
21
21
  const [{ location, locationItems: { fileDataItems }, }, dispatchStoreAction,] = useStore();
22
- const getInput = useGetActionInput();
23
- const [processState, handleProcess] = useProcessTasks(copyHandler, fileDataItems, { concurrency: 4 });
22
+ const idLookup = useRef({});
24
23
  const [destination, setDestination] = useState(location);
24
+ const data = React__default.useMemo(() => {
25
+ idLookup.current = {};
26
+ return fileDataItems?.map((item) => {
27
+ // generate new `id` on each `destination.key` change to refresh
28
+ // task data provided to `useActon`
29
+ const id = crypto.randomUUID();
30
+ idLookup.current[id] = item.id;
31
+ return {
32
+ ...item,
33
+ id,
34
+ key: `${destination.key}${item.fileKey}`,
35
+ sourceKey: item.key,
36
+ };
37
+ });
38
+ }, [destination.key, fileDataItems]);
25
39
  const folders = useFolders({ destination, setDestination });
40
+ const [processState, handleProcess] = useAction('copy', { items: data });
26
41
  const { isProcessing, isProcessingComplete, statusCounts, tasks } = processState;
27
42
  const { current } = location;
28
43
  const { onInitialize } = folders;
@@ -31,10 +46,7 @@ const useCopyView = (options) => {
31
46
  onInitialize();
32
47
  }, [onInitialize]);
33
48
  const onActionStart = () => {
34
- handleProcess({
35
- config: getInput(),
36
- destinationPrefix: destination.key,
37
- });
49
+ handleProcess();
38
50
  };
39
51
  const onActionCancel = () => {
40
52
  tasks.forEach((task) => {
@@ -51,7 +63,10 @@ const useCopyView = (options) => {
51
63
  onExit(current);
52
64
  };
53
65
  const onTaskRemove = React__default.useCallback(({ data }) => {
54
- dispatchStoreAction({ type: 'REMOVE_LOCATION_ITEM', id: data.id });
66
+ dispatchStoreAction({
67
+ type: 'REMOVE_LOCATION_ITEM',
68
+ id: idLookup.current[data.id],
69
+ });
55
70
  }, [dispatchStoreAction]);
56
71
  const onSelectDestination = (selectedDestination, path) => {
57
72
  setDestination({
@@ -1,15 +1,16 @@
1
1
  import React__default from 'react';
2
- import { useDataState } from '@aws-amplify/ui-react-core';
3
- import { usePaginate } from '../../hooks/usePaginate.mjs';
4
- import '../../../actions/configs/context.mjs';
5
- import '@aws-amplify/storage/internals';
2
+ import '../../../useAction/context.mjs';
6
3
  import '@aws-amplify/ui';
7
- import { listLocationItemsHandler } from '../../../actions/handlers/listLocationItems.mjs';
4
+ import '../../../providers/configuration/context.mjs';
5
+ import '../../../providers/store/location/context.mjs';
6
+ import '../../../providers/store/files/context.mjs';
7
+ import '../../../providers/store/actionType/context.mjs';
8
+ import '../../../providers/store/locationItems/context.mjs';
9
+ import { useList } from '../../../useAction/useList.mjs';
10
+ import '@aws-amplify/storage/internals';
8
11
  import 'aws-amplify/storage';
9
- import { createEnhancedListHandler } from '../../../actions/useAction/createEnhancedListHandler.mjs';
10
- import { useGetActionInput } from '../../../providers/configuration/context.mjs';
11
- import '@aws-amplify/ui-react-core/elements';
12
- import '../../../providers/configuration/credentials/context.mjs';
12
+ import '../../../actions/configs/context.mjs';
13
+ import { usePaginate } from '../../hooks/usePaginate.mjs';
13
14
  import { useSearch } from '../../hooks/useSearch.mjs';
14
15
 
15
16
  const DEFAULT_PAGE_SIZE = 100;
@@ -19,26 +20,22 @@ const DEFAULT_LIST_OPTIONS = {
19
20
  exclude: 'FILE',
20
21
  };
21
22
  const DEFAULT_REFRESH_OPTIONS = { ...DEFAULT_LIST_OPTIONS, refresh: true };
22
- const listLocationItemsAction = createEnhancedListHandler(listLocationItemsHandler);
23
23
  const useFolders = ({ destination, setDestination, }) => {
24
24
  const { current, key } = destination;
25
- const [{ data, hasError, isLoading, message }, handleList] = useDataState(listLocationItemsAction, { items: [], nextToken: undefined });
26
- const getInput = useGetActionInput();
25
+ const [{ data, hasError, isLoading, message }, handleList] = useList('folderItems');
27
26
  const { items, nextToken, search } = data;
28
27
  const { hasExhaustedSearch = false } = search ?? {};
29
28
  const onInitialize = React__default.useCallback(() => {
30
29
  handleList({
31
- config: getInput(),
32
30
  prefix: key,
33
31
  options: { ...DEFAULT_REFRESH_OPTIONS },
34
32
  });
35
- }, [getInput, handleList, key]);
33
+ }, [handleList, key]);
36
34
  const hasNextToken = !!nextToken;
37
35
  const paginateCallback = () => {
38
36
  if (!nextToken)
39
37
  return;
40
38
  handleList({
41
- config: getInput(),
42
39
  prefix: key,
43
40
  options: { ...DEFAULT_LIST_OPTIONS, nextToken },
44
41
  });
@@ -52,7 +49,6 @@ const useFolders = ({ destination, setDestination, }) => {
52
49
  const onSearch = (query) => {
53
50
  handleReset();
54
51
  handleList({
55
- config: getInput(),
56
52
  prefix: key,
57
53
  options: {
58
54
  ...DEFAULT_LIST_OPTIONS,
@@ -90,7 +86,6 @@ const useFolders = ({ destination, setDestination, }) => {
90
86
  handleReset();
91
87
  resetSearch();
92
88
  handleList({
93
- config: getInput(),
94
89
  prefix: key,
95
90
  options: { ...DEFAULT_REFRESH_OPTIONS },
96
91
  });
@@ -1,28 +1,36 @@
1
1
  import React__default from 'react';
2
2
  import { isFunction } from '@aws-amplify/ui';
3
- import '../../../actions/configs/context.mjs';
4
- import '@aws-amplify/storage/internals';
5
- import { createFolderHandler } from '../../../actions/handlers/createFolder.mjs';
6
- import 'aws-amplify/storage';
3
+ import '../../../useAction/context.mjs';
4
+ import { useAction } from '../../../useAction/useAction.mjs';
7
5
  import '@aws-amplify/ui-react-core';
8
- import { useGetActionInput } from '../../../providers/configuration/context.mjs';
9
6
  import '@aws-amplify/ui-react-core/elements';
10
7
  import '../../../providers/configuration/credentials/context.mjs';
8
+ import '../../../providers/configuration/context.mjs';
9
+ import '@aws-amplify/storage/internals';
10
+ import 'aws-amplify/storage';
11
+ import '../../../actions/configs/context.mjs';
11
12
  import '../../../providers/store/location/context.mjs';
12
13
  import '../../../providers/store/files/context.mjs';
13
14
  import '../../../providers/store/actionType/context.mjs';
14
15
  import '../../../providers/store/locationItems/context.mjs';
15
16
  import { useStore } from '../../../providers/store/useStore.mjs';
16
- import { useProcessTasks } from '../../../tasks/useProcessTasks.mjs';
17
17
 
18
18
  const useCreateFolderView = (options) => {
19
19
  const { onExit } = options ?? {};
20
20
  const [folderName, setFolderName] = React__default.useState('');
21
21
  const folderNameId = React__default.useRef(crypto.randomUUID()).current;
22
- const getConfig = useGetActionInput();
23
- const [{ tasks, isProcessing, isProcessingComplete, statusCounts }, handleCreateFolder,] = useProcessTasks(createFolderHandler);
24
22
  const [{ location }, dispatchStoreAction] = useStore();
25
- const { current, key: destinationPrefix } = location;
23
+ const { current, key } = location;
24
+ const data = React__default.useMemo(() => [
25
+ {
26
+ // generate new `id` on each `folderName` change to refresh task
27
+ // data provided to `useAction`
28
+ id: crypto.randomUUID(),
29
+ key: `${key}${folderName}/`,
30
+ preventOverwrite: true,
31
+ },
32
+ ], [key, folderName]);
33
+ const [{ tasks, isProcessing, isProcessingComplete, statusCounts }, handleCreateFolder,] = useAction('createFolder', { items: data });
26
34
  return {
27
35
  folderName,
28
36
  folderNameId,
@@ -30,12 +38,7 @@ const useCreateFolderView = (options) => {
30
38
  isProcessingComplete,
31
39
  location,
32
40
  onActionStart: () => {
33
- handleCreateFolder({
34
- config: getConfig(),
35
- data: { id: folderNameId, key: `${folderName}/` },
36
- destinationPrefix,
37
- options: { preventOverwrite: true },
38
- });
41
+ handleCreateFolder();
39
42
  },
40
43
  onActionExit: () => {
41
44
  if (isFunction(onExit))
@@ -1,32 +1,37 @@
1
- import { isFunction } from '@aws-amplify/ui';
2
- import '@aws-amplify/storage/internals';
3
- import { deleteHandler } from '../../../actions/handlers/delete.mjs';
4
- import 'aws-amplify/storage';
5
1
  import React__default from 'react';
2
+ import { isFunction } from '@aws-amplify/ui';
6
3
  import '../../../providers/store/location/context.mjs';
7
4
  import '../../../providers/store/files/context.mjs';
8
5
  import '../../../providers/store/actionType/context.mjs';
9
6
  import '../../../providers/store/locationItems/context.mjs';
10
7
  import { useStore } from '../../../providers/store/useStore.mjs';
11
- import { useGetActionInput } from '../../../providers/configuration/context.mjs';
12
- import '@aws-amplify/ui-react-core/elements';
13
- import '../../../actions/configs/context.mjs';
8
+ import '../../../useAction/context.mjs';
9
+ import { useAction } from '../../../useAction/useAction.mjs';
14
10
  import '@aws-amplify/ui-react-core';
11
+ import '@aws-amplify/ui-react-core/elements';
15
12
  import '../../../providers/configuration/credentials/context.mjs';
16
- import { useProcessTasks } from '../../../tasks/useProcessTasks.mjs';
13
+ import '../../../providers/configuration/context.mjs';
14
+ import '@aws-amplify/storage/internals';
15
+ import 'aws-amplify/storage';
16
+ import '../../../actions/configs/context.mjs';
17
17
 
18
18
  const useDeleteView = (options) => {
19
19
  const { onExit: _onExit } = options ?? {};
20
20
  const [{ location, locationItems }, dispatchStoreAction] = useStore();
21
21
  const { fileDataItems } = locationItems;
22
- const { current } = location;
23
- const getInput = useGetActionInput();
24
- const [processState, handleProcess] = useProcessTasks(deleteHandler, fileDataItems, { concurrency: 4 });
22
+ const { current, key } = location;
23
+ const data = React__default.useMemo(() => !fileDataItems
24
+ ? []
25
+ : fileDataItems.map((item) => ({
26
+ ...item,
27
+ key: `${key}${item.fileKey}`,
28
+ })), [fileDataItems, key]);
29
+ const [processState, handleProcess] = useAction('delete', { items: data });
25
30
  const { isProcessing, isProcessingComplete, statusCounts, tasks } = processState;
26
31
  const onActionStart = () => {
27
32
  if (!current)
28
33
  return;
29
- handleProcess({ config: getInput() });
34
+ handleProcess();
30
35
  };
31
36
  const onActionCancel = () => {
32
37
  tasks.forEach((task) => {