@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.
- package/dist/browser.js +1 -1
- package/dist/{createStorageBrowser-B75dAYRb.js → createStorageBrowser-CVfazB4S.js} +167 -169
- package/dist/esm/components/StorageBrowser/actions/handlers/listLocations.mjs +1 -1
- package/dist/esm/components/StorageBrowser/createStorageBrowser/StorageBrowserDefault.mjs +1 -1
- package/dist/esm/components/StorageBrowser/createStorageBrowser/createProvider.mjs +5 -3
- package/dist/esm/components/StorageBrowser/createStorageBrowser/createStorageBrowser.mjs +1 -1
- package/dist/esm/components/StorageBrowser/displayText/libraries/en/uploadView.mjs +3 -6
- package/dist/esm/components/StorageBrowser/fileItems/constants.mjs +11 -0
- package/dist/esm/components/StorageBrowser/fileItems/context.mjs +42 -0
- package/dist/esm/components/StorageBrowser/fileItems/fileItemsReducer.mjs +33 -0
- package/dist/esm/components/StorageBrowser/fileItems/utils.mjs +55 -0
- package/dist/esm/components/StorageBrowser/views/LocationActionView/CopyView/CopyViewProvider.mjs +3 -2
- package/dist/esm/components/StorageBrowser/views/LocationActionView/CreateFolderView/CreateFolderViewProvider.mjs +0 -1
- package/dist/esm/components/StorageBrowser/views/LocationActionView/DeleteView/DeleteViewProvider.mjs +4 -3
- package/dist/esm/components/StorageBrowser/views/LocationActionView/UploadView/useUploadView.mjs +13 -34
- package/dist/esm/components/StorageBrowser/views/LocationDetailView/LocationDetailViewProvider.mjs +0 -1
- package/dist/esm/components/StorageBrowser/views/LocationDetailView/useLocationDetailView.mjs +3 -3
- package/dist/esm/components/StorageBrowser/views/context/actionViews.mjs +1 -1
- package/dist/esm/components/StorageBrowser/views/context/primaryViews.mjs +1 -1
- package/dist/esm/components/StorageBrowser/views/utils/tableResolvers/constants.mjs +9 -1
- package/dist/esm/components/StorageBrowser/views/utils/tableResolvers/copyResolvers.mjs +4 -42
- package/dist/esm/components/StorageBrowser/views/utils/tableResolvers/deleteResolvers.mjs +4 -42
- package/dist/esm/components/StorageBrowser/views/utils/tableResolvers/utils.mjs +45 -5
- package/dist/esm/version.mjs +1 -1
- package/dist/index.js +1 -1
- package/dist/types/components/StorageBrowser/actions/index.d.ts +1 -1
- package/dist/types/components/StorageBrowser/createStorageBrowser/createProvider.d.ts +1 -1
- package/dist/types/components/StorageBrowser/createStorageBrowser/types.d.ts +21 -3
- package/dist/types/components/StorageBrowser/displayText/types.d.ts +1 -1
- package/dist/types/components/StorageBrowser/fileItems/constants.d.ts +4 -0
- package/dist/types/components/StorageBrowser/fileItems/context.d.ts +6 -0
- package/dist/types/components/StorageBrowser/fileItems/fileItemsReducer.d.ts +6 -0
- package/dist/types/components/StorageBrowser/fileItems/index.d.ts +3 -0
- package/dist/types/components/StorageBrowser/fileItems/types.d.ts +44 -0
- package/dist/types/components/StorageBrowser/fileItems/utils.d.ts +5 -0
- package/dist/types/components/StorageBrowser/validators/index.d.ts +1 -2
- package/dist/types/components/StorageBrowser/views/LocationActionView/UploadView/types.d.ts +1 -1
- package/dist/types/components/StorageBrowser/views/utils/index.d.ts +1 -1
- package/dist/types/components/StorageBrowser/views/utils/tableResolvers/__testUtils__/tasks.d.ts +6 -11
- package/dist/types/components/StorageBrowser/views/utils/tableResolvers/constants.d.ts +1 -0
- package/dist/types/components/StorageBrowser/views/utils/tableResolvers/copyResolvers.d.ts +2 -3
- package/dist/types/components/StorageBrowser/views/utils/tableResolvers/deleteResolvers.d.ts +2 -3
- package/dist/types/components/StorageBrowser/views/utils/tableResolvers/index.d.ts +3 -2
- package/dist/types/components/StorageBrowser/views/utils/tableResolvers/types.d.ts +10 -10
- package/dist/types/components/StorageBrowser/views/utils/tableResolvers/utils.d.ts +15 -7
- package/dist/types/version.d.ts +1 -1
- package/package.json +1 -1
- package/dist/esm/components/StorageBrowser/files/context.mjs +0 -31
- package/dist/esm/components/StorageBrowser/files/utils.mjs +0 -52
- package/dist/esm/components/StorageBrowser/validators/isFileTooBig.mjs +0 -4
- package/dist/types/components/StorageBrowser/files/context.d.ts +0 -6
- package/dist/types/components/StorageBrowser/files/index.d.ts +0 -2
- package/dist/types/components/StorageBrowser/files/types.d.ts +0 -28
- package/dist/types/components/StorageBrowser/files/utils.d.ts +0 -7
- 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 {
|
|
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(
|
|
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 '../
|
|
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
|
|
71
|
-
.filter(({ file }) => isFileTooBig(file))
|
|
68
|
+
const invalidFileNames = data.invalidFiles
|
|
72
69
|
.map(({ file }) => file.name)
|
|
73
70
|
.join(', ');
|
|
74
|
-
if (
|
|
71
|
+
if (invalidFileNames) {
|
|
75
72
|
return {
|
|
76
|
-
content: `Files larger than 160GB cannot be added to the upload queue: ${
|
|
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 };
|
package/dist/esm/components/StorageBrowser/views/LocationActionView/CopyView/CopyViewProvider.mjs
CHANGED
|
@@ -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
|
|
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(
|
|
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
|
|
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(
|
|
16
|
+
const tableData = useResolveTableData(FILE_DATA_ITEM_TABLE_KEYS, DELETE_TABLE_RESOLVERS, {
|
|
16
17
|
items,
|
|
17
18
|
props: { displayText, isProcessing, onTaskRemove },
|
|
18
19
|
});
|
package/dist/esm/components/StorageBrowser/views/LocationActionView/UploadView/useUploadView.mjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import React__default from 'react';
|
|
2
|
-
import {
|
|
3
|
-
import
|
|
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 [
|
|
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
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
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
|
-
|
|
31
|
+
fileItemsDispatch({ type: 'ADD_FILES', files });
|
|
50
32
|
}
|
|
51
33
|
};
|
|
52
34
|
const onSelectFiles = (type) => {
|
|
53
|
-
|
|
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
|
-
|
|
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
|
-
|
|
54
|
+
fileItemsDispatch({ type: 'REMOVE_FILE_ITEM', id: data.id });
|
|
76
55
|
};
|
|
77
56
|
return {
|
|
78
57
|
isProcessing,
|
package/dist/esm/components/StorageBrowser/views/LocationDetailView/LocationDetailViewProvider.mjs
CHANGED
|
@@ -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 }) {
|
package/dist/esm/components/StorageBrowser/views/LocationDetailView/useLocationDetailView.mjs
CHANGED
|
@@ -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 {
|
|
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
|
|
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
|
-
|
|
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 '../../
|
|
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 {
|
|
5
|
-
import {
|
|
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 =
|
|
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 {
|
|
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 {
|
|
5
|
-
import {
|
|
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 =
|
|
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 {
|
|
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
|
-
//
|
|
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
|
|
14
|
-
const
|
|
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
|
|
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,
|
|
89
|
+
export { cancel, folder, getCellName, getFileDataCancelCellContent, getFileDataCellFolder, getFileDataCellKey, getFileSize, getFileType, getUploadCellFolder, getUploadCellProgress, name, size, type };
|
package/dist/esm/version.mjs
CHANGED