@aws-amplify/ui-react-storage 3.10.3 → 3.11.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 (55) hide show
  1. package/dist/browser.js +1 -1
  2. package/dist/{createStorageBrowser-B75dAYRb.js → createStorageBrowser-CVfazB4S.js} +167 -169
  3. package/dist/esm/components/StorageBrowser/actions/handlers/listLocations.mjs +1 -1
  4. package/dist/esm/components/StorageBrowser/createStorageBrowser/StorageBrowserDefault.mjs +1 -1
  5. package/dist/esm/components/StorageBrowser/createStorageBrowser/createProvider.mjs +5 -3
  6. package/dist/esm/components/StorageBrowser/createStorageBrowser/createStorageBrowser.mjs +1 -1
  7. package/dist/esm/components/StorageBrowser/displayText/libraries/en/uploadView.mjs +3 -6
  8. package/dist/esm/components/StorageBrowser/fileItems/constants.mjs +11 -0
  9. package/dist/esm/components/StorageBrowser/fileItems/context.mjs +42 -0
  10. package/dist/esm/components/StorageBrowser/fileItems/fileItemsReducer.mjs +33 -0
  11. package/dist/esm/components/StorageBrowser/fileItems/utils.mjs +55 -0
  12. package/dist/esm/components/StorageBrowser/views/LocationActionView/CopyView/CopyViewProvider.mjs +3 -2
  13. package/dist/esm/components/StorageBrowser/views/LocationActionView/CreateFolderView/CreateFolderViewProvider.mjs +0 -1
  14. package/dist/esm/components/StorageBrowser/views/LocationActionView/DeleteView/DeleteViewProvider.mjs +4 -3
  15. package/dist/esm/components/StorageBrowser/views/LocationActionView/UploadView/useUploadView.mjs +13 -34
  16. package/dist/esm/components/StorageBrowser/views/LocationDetailView/LocationDetailViewProvider.mjs +0 -1
  17. package/dist/esm/components/StorageBrowser/views/LocationDetailView/useLocationDetailView.mjs +3 -3
  18. package/dist/esm/components/StorageBrowser/views/context/actionViews.mjs +1 -1
  19. package/dist/esm/components/StorageBrowser/views/context/primaryViews.mjs +1 -1
  20. package/dist/esm/components/StorageBrowser/views/utils/tableResolvers/constants.mjs +9 -1
  21. package/dist/esm/components/StorageBrowser/views/utils/tableResolvers/copyResolvers.mjs +4 -42
  22. package/dist/esm/components/StorageBrowser/views/utils/tableResolvers/deleteResolvers.mjs +4 -42
  23. package/dist/esm/components/StorageBrowser/views/utils/tableResolvers/utils.mjs +45 -5
  24. package/dist/esm/version.mjs +1 -1
  25. package/dist/index.js +1 -1
  26. package/dist/types/components/StorageBrowser/actions/index.d.ts +1 -1
  27. package/dist/types/components/StorageBrowser/createStorageBrowser/createProvider.d.ts +1 -1
  28. package/dist/types/components/StorageBrowser/createStorageBrowser/types.d.ts +21 -3
  29. package/dist/types/components/StorageBrowser/displayText/types.d.ts +1 -1
  30. package/dist/types/components/StorageBrowser/fileItems/constants.d.ts +4 -0
  31. package/dist/types/components/StorageBrowser/fileItems/context.d.ts +6 -0
  32. package/dist/types/components/StorageBrowser/fileItems/fileItemsReducer.d.ts +6 -0
  33. package/dist/types/components/StorageBrowser/fileItems/index.d.ts +3 -0
  34. package/dist/types/components/StorageBrowser/fileItems/types.d.ts +44 -0
  35. package/dist/types/components/StorageBrowser/fileItems/utils.d.ts +5 -0
  36. package/dist/types/components/StorageBrowser/validators/index.d.ts +1 -2
  37. package/dist/types/components/StorageBrowser/views/LocationActionView/UploadView/types.d.ts +1 -1
  38. package/dist/types/components/StorageBrowser/views/utils/index.d.ts +1 -1
  39. package/dist/types/components/StorageBrowser/views/utils/tableResolvers/__testUtils__/tasks.d.ts +6 -11
  40. package/dist/types/components/StorageBrowser/views/utils/tableResolvers/constants.d.ts +1 -0
  41. package/dist/types/components/StorageBrowser/views/utils/tableResolvers/copyResolvers.d.ts +2 -3
  42. package/dist/types/components/StorageBrowser/views/utils/tableResolvers/deleteResolvers.d.ts +2 -3
  43. package/dist/types/components/StorageBrowser/views/utils/tableResolvers/index.d.ts +3 -2
  44. package/dist/types/components/StorageBrowser/views/utils/tableResolvers/types.d.ts +10 -10
  45. package/dist/types/components/StorageBrowser/views/utils/tableResolvers/utils.d.ts +15 -7
  46. package/dist/types/version.d.ts +1 -1
  47. package/package.json +1 -1
  48. package/dist/esm/components/StorageBrowser/files/context.mjs +0 -31
  49. package/dist/esm/components/StorageBrowser/files/utils.mjs +0 -52
  50. package/dist/esm/components/StorageBrowser/validators/isFileTooBig.mjs +0 -4
  51. package/dist/types/components/StorageBrowser/files/context.d.ts +0 -6
  52. package/dist/types/components/StorageBrowser/files/index.d.ts +0 -2
  53. package/dist/types/components/StorageBrowser/files/types.d.ts +0 -28
  54. package/dist/types/components/StorageBrowser/files/utils.d.ts +0 -7
  55. package/dist/types/components/StorageBrowser/validators/isFileTooBig.d.ts +0 -2
@@ -15,7 +15,8 @@ import { componentsDefault } from '../components/defaults.mjs';
15
15
  import { createConfigurationProvider } from '../configuration/createConfigurationProvider.mjs';
16
16
  import '../configuration/context.mjs';
17
17
  import { DisplayTextProvider } from '../displayText/context.mjs';
18
- import { FilesProvider } from '../files/context.mjs';
18
+ import { FileItemsProvider } from '../fileItems/context.mjs';
19
+ import { defaultValidateFile } from '../fileItems/utils.mjs';
19
20
  import { LocationItemsProvider } from '../locationItems/context.mjs';
20
21
  import { StoreProvider } from '../store/context.mjs';
21
22
  import { ActionHandlersProvider } from '../useAction/context.mjs';
@@ -30,7 +31,7 @@ import '../views/LocationActionView/UploadView/UploadView.mjs';
30
31
  import '../views/LocationDetailView/LocationDetailView.mjs';
31
32
  import '../views/LocationsView/LocationsView.mjs';
32
33
 
33
- function createProvider({ actions, components, config, }) {
34
+ function createProvider({ actions, components, config, options, }) {
34
35
  const { accountId, customEndpoint, registerAuthListener, getLocationCredentials, region, listLocations, } = config;
35
36
  const resolvedActions = {
36
37
  default: {
@@ -59,6 +60,7 @@ function createProvider({ actions, components, config, }) {
59
60
  // override components
60
61
  ...components,
61
62
  };
63
+ const { validateFile = defaultValidateFile } = options ?? {};
62
64
  /**
63
65
  * Provides state, configuration and action values that are shared between
64
66
  * the primary View components
@@ -72,7 +74,7 @@ function createProvider({ actions, components, config, }) {
72
74
  React__default.createElement(ViewsProvider, { actions: resolvedActions, views: views },
73
75
  React__default.createElement(ComponentsProvider, { composables: composables },
74
76
  React__default.createElement(LocationItemsProvider, null,
75
- React__default.createElement(FilesProvider, null, children))))))))));
77
+ React__default.createElement(FileItemsProvider, { validateFile: validateFile }, children))))))))));
76
78
  }
77
79
  return Provider;
78
80
  }
@@ -22,7 +22,7 @@ import { CreateFolderView } from '../views/LocationActionView/CreateFolderView/C
22
22
  import { DeleteView } from '../views/LocationActionView/DeleteView/DeleteView.mjs';
23
23
  import { LocationActionView } from '../views/LocationActionView/LocationActionView.mjs';
24
24
  import { UploadView } from '../views/LocationActionView/UploadView/UploadView.mjs';
25
- import '../files/context.mjs';
25
+ import '../fileItems/context.mjs';
26
26
  import { LocationDetailView } from '../views/LocationDetailView/LocationDetailView.mjs';
27
27
  import { LocationsView } from '../views/LocationsView/LocationsView.mjs';
28
28
  import { useView } from '../views/useView.mjs';
@@ -1,6 +1,4 @@
1
1
  import { DEFAULT_ACTION_VIEW_DISPLAY_TEXT } from './shared.mjs';
2
- import '@aws-amplify/ui';
3
- import { isFileTooBig } from '../../../validators/isFileTooBig.mjs';
4
2
 
5
3
  const DEFAULT_UPLOAD_VIEW_DISPLAY_TEXT = {
6
4
  ...DEFAULT_ACTION_VIEW_DISPLAY_TEXT,
@@ -67,13 +65,12 @@ const DEFAULT_UPLOAD_VIEW_DISPLAY_TEXT = {
67
65
  if (!data?.invalidFiles) {
68
66
  return undefined;
69
67
  }
70
- const tooBigFileNames = data.invalidFiles
71
- .filter(({ file }) => isFileTooBig(file))
68
+ const invalidFileNames = data.invalidFiles
72
69
  .map(({ file }) => file.name)
73
70
  .join(', ');
74
- if (tooBigFileNames) {
71
+ if (invalidFileNames) {
75
72
  return {
76
- content: `Files larger than 160GB cannot be added to the upload queue: ${tooBigFileNames}`,
73
+ content: `Files larger than 160GB cannot be added to the upload queue: ${invalidFileNames}`,
77
74
  type: 'warning',
78
75
  };
79
76
  }
@@ -0,0 +1,11 @@
1
+ const DEFAULT_STATE = {
2
+ validItems: undefined,
3
+ invalidItems: undefined,
4
+ };
5
+ const DEFAULT_RESOLVED_FILES = {
6
+ validFiles: undefined,
7
+ invalidFiles: undefined,
8
+ };
9
+ const UPLOAD_FILE_SIZE_LIMIT = 160 * 1000 * 1000 * 1000;
10
+
11
+ export { DEFAULT_RESOLVED_FILES, DEFAULT_STATE, UPLOAD_FILE_SIZE_LIMIT };
@@ -0,0 +1,42 @@
1
+ import React__default from 'react';
2
+ import { noop } from '@aws-amplify/ui';
3
+ import { createContextUtilities } from '@aws-amplify/ui-react-core';
4
+ import { useFileSelect } from '@aws-amplify/ui-react/internal';
5
+ import { DEFAULT_STATE } from './constants.mjs';
6
+ import { fileItemsReducer } from './fileItemsReducer.mjs';
7
+ import { resolveFiles, parseFileSelectParams } from './utils.mjs';
8
+
9
+ const defaultValue = [DEFAULT_STATE, noop];
10
+ const { FileItemsContext, useFileItems } = createContextUtilities({
11
+ contextName: 'FileItems',
12
+ defaultValue,
13
+ });
14
+ function FileItemsProvider({ children, validateFile, }) {
15
+ const [state, dispatch] = React__default.useReducer(fileItemsReducer, DEFAULT_STATE);
16
+ const [fileInput, handleFileSelect] = useFileSelect((nextFiles) => {
17
+ dispatch({
18
+ type: 'ADD_FILE_ITEMS',
19
+ ...resolveFiles(nextFiles, validateFile),
20
+ });
21
+ });
22
+ const handleFilesAction = React__default.useCallback((action) => {
23
+ if (action.type === 'SELECT_FILES') {
24
+ handleFileSelect(...parseFileSelectParams(action.selectionType));
25
+ }
26
+ else if (action.type === 'ADD_FILES') {
27
+ dispatch({
28
+ type: 'ADD_FILE_ITEMS',
29
+ ...resolveFiles(action.files, validateFile),
30
+ });
31
+ }
32
+ else {
33
+ dispatch(action);
34
+ }
35
+ }, [handleFileSelect, validateFile]);
36
+ const value = React__default.useMemo(() => [state, handleFilesAction], [state, handleFilesAction]);
37
+ return (React__default.createElement(FileItemsContext.Provider, { value: value },
38
+ fileInput,
39
+ children));
40
+ }
41
+
42
+ export { FileItemsContext, FileItemsProvider, useFileItems };
@@ -0,0 +1,33 @@
1
+ import { DEFAULT_STATE } from './constants.mjs';
2
+ import { processFileItems } from './utils.mjs';
3
+
4
+ const fileItemsReducer = (state, action) => {
5
+ switch (action.type) {
6
+ case 'ADD_FILE_ITEMS': {
7
+ if (!action.validFiles?.length && !action.invalidFiles?.length) {
8
+ return state;
9
+ }
10
+ const validItems = processFileItems(state.validItems, action.validFiles);
11
+ // `invalidItems` should only track invalid items from latest action taken
12
+ const invalidItems = processFileItems(undefined, action.invalidFiles);
13
+ return { validItems, invalidItems };
14
+ }
15
+ case 'REMOVE_FILE_ITEM': {
16
+ const { validItems: prevItems } = state;
17
+ if (!prevItems?.length)
18
+ return state;
19
+ const nextItems = prevItems.filter(({ id }) => id !== action.id);
20
+ if (nextItems.length === prevItems.length)
21
+ return state;
22
+ // `validItems` is strictly undefined if it has 0 file items
23
+ // otherwise, `validItems` is guaranteed to have at least 1+ file items
24
+ const validItems = nextItems.length ? nextItems : undefined;
25
+ return { ...state, validItems };
26
+ }
27
+ case 'RESET_FILE_ITEMS': {
28
+ return DEFAULT_STATE;
29
+ }
30
+ }
31
+ };
32
+
33
+ export { fileItemsReducer };
@@ -0,0 +1,55 @@
1
+ import { isUndefined, isString, isEmpty } from '@aws-amplify/ui';
2
+ import { UPLOAD_FILE_SIZE_LIMIT, DEFAULT_RESOLVED_FILES } from './constants.mjs';
3
+
4
+ const compareFileItems = (prev, next) => prev.key.localeCompare(next.key);
5
+ const constructFiles = (files, file) => isUndefined(files) ? [file] : files.concat(file);
6
+ const defaultValidateFile = (file) => file.size <= UPLOAD_FILE_SIZE_LIMIT;
7
+ const resolveFiles = (files, validateFile) => {
8
+ if (!files?.length)
9
+ return DEFAULT_RESOLVED_FILES;
10
+ if (!validateFile)
11
+ return { validFiles: files, invalidFiles: undefined };
12
+ return files.reduce((acc, file) => {
13
+ if (validateFile(file)) {
14
+ acc.validFiles = constructFiles(acc.validFiles, file);
15
+ }
16
+ else {
17
+ acc.invalidFiles = constructFiles(acc.invalidFiles, file);
18
+ }
19
+ return acc;
20
+ },
21
+ // create new copy of default to be modified
22
+ { ...DEFAULT_RESOLVED_FILES });
23
+ };
24
+ const processFileItems = (prevItems, files) => {
25
+ if (!files?.length)
26
+ return prevItems;
27
+ // construct `nextItems` and filter out existing `file` entries
28
+ const nextItems = files.reduce((items, file) => {
29
+ const { name, webkitRelativePath } = file;
30
+ return prevItems?.some(({ file: existing }) => existing.name === name &&
31
+ existing.webkitRelativePath === webkitRelativePath)
32
+ ? items
33
+ : items.concat({
34
+ key: isEmpty(webkitRelativePath) ? name : webkitRelativePath,
35
+ id: crypto.randomUUID(),
36
+ file,
37
+ });
38
+ }, []);
39
+ if (!nextItems.length)
40
+ return prevItems;
41
+ if (!prevItems?.length) {
42
+ return nextItems.sort(compareFileItems);
43
+ }
44
+ return prevItems?.concat(nextItems).sort(compareFileItems);
45
+ };
46
+ const parseFileSelectParams = (value) => {
47
+ if (isUndefined(value))
48
+ return ['FILE', undefined];
49
+ if (isString(value))
50
+ return [value, undefined];
51
+ const [selectType, ...rest] = value;
52
+ return [selectType, !rest?.length ? undefined : { accept: rest.join() }];
53
+ };
54
+
55
+ export { defaultValidateFile, parseFileSelectParams, processFileItems, resolveFiles };
@@ -9,7 +9,8 @@ import '@aws-amplify/ui-react-core';
9
9
  import '@aws-amplify/ui-react-core/elements';
10
10
  import { useDisplayText } from '../../../displayText/context.mjs';
11
11
  import useResolveTableData from '../../hooks/useResolveTableData/useResolveTableData.mjs';
12
- import { COPY_TABLE_RESOLVERS, COPY_TABLE_KEYS } from '../../utils/tableResolvers/copyResolvers.mjs';
12
+ import { COPY_TABLE_RESOLVERS } from '../../utils/tableResolvers/copyResolvers.mjs';
13
+ import { FILE_DATA_ITEM_TABLE_KEYS } from '../../utils/tableResolvers/constants.mjs';
13
14
  import { FoldersMessageProvider } from './FoldersMessageControl.mjs';
14
15
  import { FoldersPaginationProvider } from './FoldersPaginationControl.mjs';
15
16
  import { FoldersTableProvider } from './FoldersTableControl.mjs';
@@ -19,7 +20,7 @@ function CopyViewProvider({ children, ...props }) {
19
20
  const { actionCancelLabel, actionDestinationLabel, actionExitLabel, actionStartLabel, getActionCompleteMessage, overwriteWarningMessage, searchPlaceholder, searchSubmitLabel, searchClearLabel, statusDisplayCanceledLabel, statusDisplayCompletedLabel, statusDisplayFailedLabel, statusDisplayQueuedLabel, title, } = displayText;
20
21
  const { destination, folders, isProcessing, isProcessingComplete, statusCounts, tasks: items, onActionCancel, onActionExit, onActionStart, onSelectDestination, onTaskRemove, } = props;
21
22
  const { hasNextPage, highestPageVisited, hasError: hasFoldersError, message: foldersErrorMessage, query, hasExhaustedSearch, isLoading, page, pageItems, onPaginate, onQuery, onSearchClear, onSearch, onSelectFolder, } = folders;
22
- const tableData = useResolveTableData(COPY_TABLE_KEYS, COPY_TABLE_RESOLVERS, {
23
+ const tableData = useResolveTableData(FILE_DATA_ITEM_TABLE_KEYS, COPY_TABLE_RESOLVERS, {
23
24
  items,
24
25
  props: { displayText, isProcessing, onTaskRemove },
25
26
  });
@@ -1,7 +1,6 @@
1
1
  import React__default from 'react';
2
2
  import { ControlsContextProvider } from '../../../controls/context.mjs';
3
3
  import { useDisplayText } from '../../../displayText/context.mjs';
4
- import '@aws-amplify/ui';
5
4
  import { isValidFolderName } from './utils.mjs';
6
5
 
7
6
  function CreateFolderViewProvider({ children, ...props }) {
@@ -1,9 +1,10 @@
1
1
  import React__default from 'react';
2
2
  import { ControlsContextProvider } from '../../../controls/context.mjs';
3
3
  import { useDisplayText } from '../../../displayText/context.mjs';
4
- import '@aws-amplify/ui';
5
4
  import useResolveTableData from '../../hooks/useResolveTableData/useResolveTableData.mjs';
6
- import { DELETE_TABLE_RESOLVERS, DELETE_TABLE_KEYS } from '../../utils/tableResolvers/deleteResolvers.mjs';
5
+ import '@aws-amplify/ui';
6
+ import { FILE_DATA_ITEM_TABLE_KEYS } from '../../utils/tableResolvers/constants.mjs';
7
+ import { DELETE_TABLE_RESOLVERS } from '../../utils/tableResolvers/deleteResolvers.mjs';
7
8
 
8
9
  function DeleteViewProvider({ children, ...props }) {
9
10
  const { DeleteView: displayText } = useDisplayText();
@@ -12,7 +13,7 @@ function DeleteViewProvider({ children, ...props }) {
12
13
  const message = isProcessingComplete
13
14
  ? getActionCompleteMessage({ counts: statusCounts })
14
15
  : undefined;
15
- const tableData = useResolveTableData(DELETE_TABLE_KEYS, DELETE_TABLE_RESOLVERS, {
16
+ const tableData = useResolveTableData(FILE_DATA_ITEM_TABLE_KEYS, DELETE_TABLE_RESOLVERS, {
16
17
  items,
17
18
  props: { displayText, isProcessing, onTaskRemove },
18
19
  });
@@ -1,6 +1,6 @@
1
1
  import React__default from 'react';
2
- import { isUndefined } from '@aws-amplify/ui';
3
- import { useFiles } from '../../../files/context.mjs';
2
+ import { useFileItems } from '../../../fileItems/context.mjs';
3
+ import '@aws-amplify/ui';
4
4
  import { useStore } from '../../../store/context.mjs';
5
5
  import '../../../useAction/context.mjs';
6
6
  import { useAction } from '../../../useAction/useAction.mjs';
@@ -10,7 +10,6 @@ import '../../../credentials/context.mjs';
10
10
  import '@aws-amplify/storage/internals';
11
11
  import '../../../configuration/context.mjs';
12
12
  import 'aws-amplify/storage';
13
- import { isFileTooBig } from '../../../validators/isFileTooBig.mjs';
14
13
  import '../../../actions/configs/context.mjs';
15
14
  import '../../../actions/configs/defaults.mjs';
16
15
  import { DEFAULT_OVERWRITE_ENABLED } from './constants.mjs';
@@ -18,44 +17,24 @@ import { DEFAULT_OVERWRITE_ENABLED } from './constants.mjs';
18
17
  const useUploadView = (options) => {
19
18
  const { onExit: _onExit } = options ?? {};
20
19
  const [{ location }, storeDispatch] = useStore();
21
- const [files, filesDispatch] = useFiles();
20
+ const [{ validItems, invalidItems: invalidFiles }, fileItemsDispatch] = useFileItems();
22
21
  const { current } = location;
23
22
  const [isOverwritingEnabled, setIsOverwritingEnabled] = React__default.useState(DEFAULT_OVERWRITE_ENABLED);
24
- const filesData = React__default.useMemo(() => (files ?? [])?.reduce((curr, item) => {
25
- if (isFileTooBig(item.file)) {
26
- curr.invalidFiles = isUndefined(curr.invalidFiles)
27
- ? [item]
28
- : curr.invalidFiles.concat(item);
29
- }
30
- else {
31
- curr.validFiles = isUndefined(curr.validFiles)
32
- ? [item]
33
- : curr.validFiles.concat(item);
34
- const parsedFileItem = {
35
- ...item,
36
- key: `${location.key}${item.key}`,
37
- };
38
- curr.data = curr.data.concat({
39
- ...parsedFileItem,
40
- preventOverwrite: !isOverwritingEnabled,
41
- });
42
- }
43
- return curr;
44
- }, { invalidFiles: undefined, validFiles: undefined, data: [] }), [files, isOverwritingEnabled, location.key]);
45
- const { data, invalidFiles } = filesData;
46
- const [{ isProcessing, isProcessingComplete, statusCounts, tasks }, handleUploads,] = useAction('upload', { items: data });
23
+ const items = React__default.useMemo(() => (validItems ?? []).map((item) => ({
24
+ ...item,
25
+ key: `${location.key}${item.key}`,
26
+ preventOverwrite: !isOverwritingEnabled,
27
+ })), [validItems, isOverwritingEnabled, location.key]);
28
+ const [{ isProcessing, isProcessingComplete, statusCounts, tasks }, handleUploads,] = useAction('upload', { items });
47
29
  const onDropFiles = (files) => {
48
30
  if (files) {
49
- filesDispatch({ type: 'ADD_FILE_ITEMS', files });
31
+ fileItemsDispatch({ type: 'ADD_FILES', files });
50
32
  }
51
33
  };
52
34
  const onSelectFiles = (type) => {
53
- filesDispatch({ type: 'SELECT_FILES', selectionType: type });
35
+ fileItemsDispatch({ type: 'SELECT_FILES', selectionType: type });
54
36
  };
55
37
  const onActionStart = () => {
56
- invalidFiles?.forEach((file) => {
57
- filesDispatch({ type: 'REMOVE_FILE_ITEM', id: file.id });
58
- });
59
38
  handleUploads();
60
39
  };
61
40
  const onActionCancel = () => {
@@ -63,7 +42,7 @@ const useUploadView = (options) => {
63
42
  };
64
43
  const onActionExit = () => {
65
44
  // clear files state
66
- filesDispatch({ type: 'RESET_FILE_ITEMS' });
45
+ fileItemsDispatch({ type: 'RESET_FILE_ITEMS' });
67
46
  // clear selected action
68
47
  storeDispatch({ type: 'RESET_ACTION_TYPE' });
69
48
  _onExit?.(current);
@@ -72,7 +51,7 @@ const useUploadView = (options) => {
72
51
  setIsOverwritingEnabled((prev) => !prev);
73
52
  };
74
53
  const onTaskRemove = ({ data }) => {
75
- filesDispatch({ type: 'REMOVE_FILE_ITEM', id: data.id });
54
+ fileItemsDispatch({ type: 'REMOVE_FILE_ITEM', id: data.id });
76
55
  };
77
56
  return {
78
57
  isProcessing,
@@ -1,7 +1,6 @@
1
1
  import React__default from 'react';
2
2
  import { ControlsContextProvider } from '../../controls/context.mjs';
3
3
  import { useDisplayText } from '../../displayText/context.mjs';
4
- import '@aws-amplify/ui';
5
4
  import { getLocationDetailViewTableData } from './getLocationDetailViewTableData/getLocationDetailViewTableData.mjs';
6
5
 
7
6
  function LocationDetailViewProvider({ children, ...props }) {
@@ -5,7 +5,7 @@ import '@aws-amplify/storage/internals';
5
5
  import 'aws-amplify/storage';
6
6
  import { useActionConfigs } from '../../actions/configs/context.mjs';
7
7
  import '../../actions/configs/defaults.mjs';
8
- import { useFiles } from '../../files/context.mjs';
8
+ import { useFileItems } from '../../fileItems/context.mjs';
9
9
  import { useLocationItems } from '../../locationItems/context.mjs';
10
10
  import { useStore } from '../../store/context.mjs';
11
11
  import '../../useAction/context.mjs';
@@ -32,7 +32,7 @@ const useLocationDetailView = (options) => {
32
32
  const listOptions = listOptionsRef.current;
33
33
  const [{ location, actionType }, storeDispatch] = useStore();
34
34
  const [locationItems, locationItemsDispatch] = useLocationItems();
35
- const filesDispatch = useFiles()[1];
35
+ const fileItemsDispatch = useFileItems()[1];
36
36
  const { current, key } = location;
37
37
  const { permissions, prefix } = current ?? {};
38
38
  const { fileDataItems } = locationItems;
@@ -148,7 +148,7 @@ const useLocationDetailView = (options) => {
148
148
  locationItemsDispatch({ type: 'RESET_LOCATION_ITEMS' });
149
149
  },
150
150
  onDropFiles: (files) => {
151
- filesDispatch({ type: 'ADD_FILE_ITEMS', files });
151
+ fileItemsDispatch({ type: 'ADD_FILES', files });
152
152
  const actionType = 'upload';
153
153
  storeDispatch({ type: 'CHANGE_ACTION_TYPE', actionType });
154
154
  options?.onActionSelect?.(actionType);
@@ -1,7 +1,7 @@
1
1
  import React__default from 'react';
2
2
  import { UploadView } from '../LocationActionView/UploadView/UploadView.mjs';
3
+ import '../../fileItems/context.mjs';
3
4
  import '@aws-amplify/ui';
4
- import '../../files/context.mjs';
5
5
  import '../../store/context.mjs';
6
6
  import '../../useAction/context.mjs';
7
7
  import '@aws-amplify/ui-react-core/elements';
@@ -16,7 +16,7 @@ import '../LocationActionView/CreateFolderView/CreateFolderView.mjs';
16
16
  import '../LocationActionView/DeleteView/DeleteView.mjs';
17
17
  import { LocationActionView } from '../LocationActionView/LocationActionView.mjs';
18
18
  import '../LocationActionView/UploadView/UploadView.mjs';
19
- import '../../files/context.mjs';
19
+ import '../../fileItems/context.mjs';
20
20
  import { LocationDetailView } from '../LocationDetailView/LocationDetailView.mjs';
21
21
  import { LocationsView } from '../LocationsView/LocationsView.mjs';
22
22
 
@@ -14,5 +14,13 @@ const STATUS_ICONS = {
14
14
  CANCELED: 'action-canceled',
15
15
  QUEUED: 'action-queued',
16
16
  };
17
+ const FILE_DATA_ITEM_TABLE_KEYS = [
18
+ 'name',
19
+ 'folder',
20
+ 'type',
21
+ 'size',
22
+ 'status',
23
+ 'cancel',
24
+ ];
17
25
 
18
- export { STATUS_ICONS, STATUS_LABELS };
26
+ export { FILE_DATA_ITEM_TABLE_KEYS, STATUS_ICONS, STATUS_LABELS };
@@ -1,44 +1,11 @@
1
1
  import { noop, capitalize } from '@aws-amplify/ui';
2
2
  import '../../../displayText/context.mjs';
3
3
  import { isCopyViewDisplayTextKey } from '../../../displayText/utils.mjs';
4
- import { STATUS_ICONS, STATUS_LABELS } from './constants.mjs';
5
- import { getCopyOrDeleteCancelCellContent, getFileSize, getFileType, getCopyCellFolder } from './utils.mjs';
4
+ import { STATUS_LABELS } from './constants.mjs';
5
+ import { cancel, size, type, folder, name, getFileDataCellKey } from './utils.mjs';
6
6
 
7
- const COPY_TABLE_KEYS = [
8
- 'name',
9
- 'folder',
10
- 'type',
11
- 'size',
12
- 'status',
13
- 'cancel',
14
- ];
15
- const getCopyCellKey = ({ key, item, }) => `${key}-${item.data.id}`;
16
- const name = (data) => {
17
- const key = getCopyCellKey(data);
18
- const { item } = data;
19
- const text = item.data.fileKey;
20
- const icon = STATUS_ICONS[item.status];
21
- return { key, type: 'text', content: { icon, text } };
22
- };
23
- const folder = (data) => {
24
- const key = getCopyCellKey(data);
25
- const text = getCopyCellFolder(data.item);
26
- return { key, type: 'text', content: { text } };
27
- };
28
- const type = (data) => {
29
- const key = getCopyCellKey(data);
30
- const { fileKey } = data.item.data;
31
- const text = getFileType(fileKey);
32
- return { key, type: 'text', content: { text } };
33
- };
34
- const size = (data) => {
35
- const key = getCopyCellKey(data);
36
- const { size: value } = data.item.data;
37
- const displayValue = getFileSize(value);
38
- return { key, type: 'number', content: { value, displayValue } };
39
- };
40
7
  const status = (data) => {
41
- const key = getCopyCellKey(data);
8
+ const key = getFileDataCellKey(data);
42
9
  const { item: { status }, props: { displayText }, } = data;
43
10
  const statusLabelKey = STATUS_LABELS[status];
44
11
  const text = isCopyViewDisplayTextKey(statusLabelKey)
@@ -46,11 +13,6 @@ const status = (data) => {
46
13
  : '';
47
14
  return { key, type: 'text', content: { text } };
48
15
  };
49
- const cancel = (data) => {
50
- const key = getCopyCellKey(data);
51
- const content = getCopyOrDeleteCancelCellContent(data);
52
- return { key, type: 'button', content };
53
- };
54
16
  const COPY_CELL_RESOLVERS = {
55
17
  name,
56
18
  folder,
@@ -79,4 +41,4 @@ const COPY_TABLE_RESOLVERS = {
79
41
  getRowKey: ({ item }) => item.data.id,
80
42
  };
81
43
 
82
- export { COPY_TABLE_KEYS, COPY_TABLE_RESOLVERS };
44
+ export { COPY_TABLE_RESOLVERS };
@@ -1,44 +1,11 @@
1
1
  import { noop, capitalize } from '@aws-amplify/ui';
2
2
  import '../../../displayText/context.mjs';
3
3
  import { isDeleteViewDisplayTextKey } from '../../../displayText/utils.mjs';
4
- import { STATUS_ICONS, STATUS_LABELS } from './constants.mjs';
5
- import { getCopyOrDeleteCancelCellContent, getFileSize, getFileType, getDeleteCellFolder } from './utils.mjs';
4
+ import { STATUS_LABELS } from './constants.mjs';
5
+ import { cancel, size, type, folder, name, getFileDataCellKey } from './utils.mjs';
6
6
 
7
- const DELETE_TABLE_KEYS = [
8
- 'name',
9
- 'folder',
10
- 'type',
11
- 'size',
12
- 'status',
13
- 'cancel',
14
- ];
15
- const getDeleteCellKey = ({ key, item, }) => `${key}-${item.data.id}`;
16
- const name = (data) => {
17
- const key = getDeleteCellKey(data);
18
- const { item } = data;
19
- const text = item.data.fileKey;
20
- const icon = STATUS_ICONS[item.status];
21
- return { key, type: 'text', content: { icon, text } };
22
- };
23
- const folder = (data) => {
24
- const key = getDeleteCellKey(data);
25
- const text = getDeleteCellFolder(data.item);
26
- return { key, type: 'text', content: { text } };
27
- };
28
- const type = (data) => {
29
- const key = getDeleteCellKey(data);
30
- const { fileKey } = data.item.data;
31
- const text = getFileType(fileKey);
32
- return { key, type: 'text', content: { text } };
33
- };
34
- const size = (data) => {
35
- const key = getDeleteCellKey(data);
36
- const { size: value } = data.item.data;
37
- const displayValue = getFileSize(value);
38
- return { key, type: 'number', content: { value, displayValue } };
39
- };
40
7
  const status = (data) => {
41
- const key = getDeleteCellKey(data);
8
+ const key = getFileDataCellKey(data);
42
9
  const { item: { status }, props: { displayText }, } = data;
43
10
  const statusLabelKey = STATUS_LABELS[status];
44
11
  const text = isDeleteViewDisplayTextKey(statusLabelKey)
@@ -46,11 +13,6 @@ const status = (data) => {
46
13
  : '';
47
14
  return { key, type: 'text', content: { text } };
48
15
  };
49
- const cancel = (data) => {
50
- const key = getDeleteCellKey(data);
51
- const content = getCopyOrDeleteCancelCellContent(data);
52
- return { key, type: 'button', content };
53
- };
54
16
  const DELETE_CELL_RESOLVERS = {
55
17
  name,
56
18
  folder,
@@ -79,4 +41,4 @@ const DELETE_TABLE_RESOLVERS = {
79
41
  getRowKey: ({ item }) => item.data.id,
80
42
  };
81
43
 
82
- export { DELETE_TABLE_KEYS, DELETE_TABLE_RESOLVERS };
44
+ export { DELETE_TABLE_RESOLVERS };
@@ -1,17 +1,24 @@
1
1
  import { humanFileSize } from '@aws-amplify/ui';
2
+ import { STATUS_ICONS } from './constants.mjs';
2
3
 
3
4
  const getFileType = (value, fallback = '') => value.lastIndexOf('.') !== -1
4
5
  ? value.slice(value.lastIndexOf('.') + 1)
5
6
  : fallback;
6
7
  const getCellName = (value) =>
7
8
  // `value.split` always returns an array with at least one entry
8
- // ensruing `.pop()` will always return a string
9
+ // ensuring `.pop()` will always return a string
9
10
  value.split('/').pop();
10
11
  const getUploadCellFolder = ({ data: { file: { webkitRelativePath }, }, }, fallback = '-') => webkitRelativePath
11
12
  ? webkitRelativePath.slice(0, webkitRelativePath.lastIndexOf('/') + 1)
12
13
  : fallback;
13
- const getCopyCellFolder = ({ data: { fileKey, sourceKey }, }) => sourceKey.slice(0, -fileKey.length);
14
- const getDeleteCellFolder = ({ data: { fileKey, key }, }) => key.slice(0, -fileKey.length);
14
+ const isCopyActionTask = (task) => 'sourceKey' in task.data;
15
+ const getFileDataCellFolder = (task) => {
16
+ const targetKey = isCopyActionTask(task)
17
+ ? task.data.sourceKey
18
+ : task.data.key;
19
+ const { fileKey } = task.data;
20
+ return targetKey.slice(0, -fileKey.length);
21
+ };
15
22
  const getUploadCellProgress = ({ progress, status, }) => {
16
23
  // prefer `progress` if available, 1 if status is complete, default 0
17
24
  const value = progress ?? (status === 'COMPLETE' ? 1 : 0);
@@ -19,7 +26,7 @@ const getUploadCellProgress = ({ progress, status, }) => {
19
26
  return { displayValue, value };
20
27
  };
21
28
  const getFileSize = (value, fallback = '-') => (!value ? fallback : humanFileSize(value, true));
22
- const getCopyOrDeleteCancelCellContent = (data) => {
29
+ const getFileDataCancelCellContent = (data) => {
23
30
  const { item, props } = data;
24
31
  const { cancel, status } = item;
25
32
  const { isProcessing, onTaskRemove } = props;
@@ -45,5 +52,38 @@ const getCopyOrDeleteCancelCellContent = (data) => {
45
52
  };
46
53
  return { ariaLabel, isDisabled, onClick, icon: 'cancel' };
47
54
  };
55
+ /**
56
+ * Generates a unique key for a table cell based on the key and item id
57
+ */
58
+ const getFileDataCellKey = ({ key, item, }) => `${key}-${item.data.id}`;
59
+ const name = (data) => {
60
+ const key = getFileDataCellKey(data);
61
+ const { item } = data;
62
+ const text = item.data.fileKey;
63
+ const icon = STATUS_ICONS[item.status];
64
+ return { key, type: 'text', content: { icon, text } };
65
+ };
66
+ const folder = (data) => {
67
+ const key = getFileDataCellKey(data);
68
+ const text = getFileDataCellFolder(data.item);
69
+ return { key, type: 'text', content: { text } };
70
+ };
71
+ const type = (data) => {
72
+ const key = getFileDataCellKey(data);
73
+ const { fileKey } = data.item.data;
74
+ const text = getFileType(fileKey);
75
+ return { key, type: 'text', content: { text } };
76
+ };
77
+ const size = (data) => {
78
+ const key = getFileDataCellKey(data);
79
+ const { size: value } = data.item.data;
80
+ const displayValue = getFileSize(value);
81
+ return { key, type: 'number', content: { value, displayValue } };
82
+ };
83
+ const cancel = (data) => {
84
+ const key = getFileDataCellKey(data);
85
+ const content = getFileDataCancelCellContent(data);
86
+ return { key, type: 'button', content };
87
+ };
48
88
 
49
- export { getCellName, getCopyCellFolder, getCopyOrDeleteCancelCellContent, getDeleteCellFolder, getFileSize, getFileType, getUploadCellFolder, getUploadCellProgress };
89
+ export { cancel, folder, getCellName, getFileDataCancelCellContent, getFileDataCellFolder, getFileDataCellKey, getFileSize, getFileType, getUploadCellFolder, getUploadCellProgress, name, size, type };
@@ -1,3 +1,3 @@
1
- const VERSION = '3.10.3';
1
+ const VERSION = '3.11.0';
2
2
 
3
3
  export { VERSION };