@aws-amplify/ui-react-storage 3.9.1 → 3.9.2
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 +3 -1
- package/dist/{createAmplifyAuthAdapter-Cf4yJo1e.js → createAmplifyAuthAdapter-BJjOYxQA.js} +533 -377
- package/dist/esm/browser.mjs +6 -0
- package/dist/esm/components/StorageBrowser/StorageBrowserAmplify.mjs +1 -0
- package/dist/esm/components/StorageBrowser/StorageBrowserDefault.mjs +3 -2
- package/dist/esm/components/StorageBrowser/actions/configs/defaults.mjs +10 -12
- package/dist/esm/components/StorageBrowser/actions/handlers/constants.mjs +4 -1
- package/dist/esm/components/StorageBrowser/actions/handlers/copy.mjs +4 -1
- package/dist/esm/components/StorageBrowser/actions/handlers/createFolder.mjs +4 -3
- package/dist/esm/components/StorageBrowser/actions/handlers/defaults.mjs +17 -0
- package/dist/esm/components/StorageBrowser/actions/handlers/delete.mjs +4 -1
- package/dist/esm/components/StorageBrowser/actions/handlers/download.mjs +4 -1
- package/dist/esm/components/StorageBrowser/actions/handlers/upload.mjs +6 -11
- package/dist/esm/components/StorageBrowser/actions/handlers/utils.mjs +4 -3
- package/dist/esm/components/StorageBrowser/adapters/createManagedAuthAdapter/createManagedAuthAdapter.mjs +2 -1
- package/dist/esm/components/StorageBrowser/componentsDefault.mjs +4 -4
- package/dist/esm/components/StorageBrowser/createStorageBrowser.mjs +7 -1
- package/dist/esm/components/StorageBrowser/displayText/libraries/en/shared.mjs +0 -1
- package/dist/esm/components/StorageBrowser/displayText/libraries/en/uploadView.mjs +3 -2
- package/dist/esm/components/StorageBrowser/displayText/utils.mjs +7 -0
- package/dist/esm/components/StorageBrowser/providers/store/locationItems/context.mjs +1 -0
- package/dist/esm/components/StorageBrowser/tasks/useProcessTasks.mjs +20 -22
- package/dist/esm/components/StorageBrowser/useAction/useAction.mjs +14 -7
- package/dist/esm/components/StorageBrowser/useAction/useHandler.mjs +26 -32
- package/dist/esm/components/StorageBrowser/useAction/useList.mjs +0 -1
- package/dist/esm/components/StorageBrowser/views/LocationActionView/CopyView/CopyViewProvider.mjs +6 -9
- package/dist/esm/components/StorageBrowser/views/LocationActionView/CopyView/useCopyView.mjs +1 -0
- package/dist/esm/components/StorageBrowser/views/LocationActionView/CopyView/useFolders.mjs +11 -13
- package/dist/esm/components/StorageBrowser/views/LocationActionView/CreateFolderView/useCreateFolderView.mjs +1 -0
- package/dist/esm/components/StorageBrowser/views/LocationActionView/DeleteView/DeleteViewProvider.mjs +6 -9
- package/dist/esm/components/StorageBrowser/views/LocationActionView/DeleteView/useDeleteView.mjs +1 -0
- package/dist/esm/components/StorageBrowser/views/LocationActionView/UploadView/UploadViewProvider.mjs +14 -12
- package/dist/esm/components/StorageBrowser/views/LocationActionView/UploadView/useUploadView.mjs +2 -1
- package/dist/esm/components/StorageBrowser/views/LocationDetailView/getLocationDetailViewTableData/getLocationDetailViewTableData.mjs +1 -0
- package/dist/esm/components/StorageBrowser/views/LocationDetailView/useLocationDetailView.mjs +7 -11
- package/dist/esm/components/StorageBrowser/views/LocationsView/useLocationsView.mjs +5 -5
- package/dist/esm/components/StorageBrowser/views/context/actionViews.mjs +3 -2
- package/dist/esm/components/StorageBrowser/views/context/getViews.mjs +4 -1
- package/dist/esm/components/StorageBrowser/views/context/primaryViews.mjs +3 -2
- package/dist/esm/components/StorageBrowser/views/hooks/usePaginate.mjs +19 -21
- package/dist/esm/components/StorageBrowser/views/hooks/useResolveTableData/useResolveTableData.mjs +15 -0
- package/dist/esm/components/StorageBrowser/views/useView.mjs +6 -7
- package/dist/esm/components/StorageBrowser/views/utils/tableResolvers/constants.mjs +18 -0
- package/dist/esm/components/StorageBrowser/views/utils/tableResolvers/copyResolvers.mjs +82 -0
- package/dist/esm/components/StorageBrowser/views/utils/tableResolvers/deleteResolvers.mjs +82 -0
- package/dist/esm/components/StorageBrowser/views/utils/tableResolvers/uploadResolvers.mjs +112 -0
- package/dist/esm/components/StorageBrowser/views/utils/tableResolvers/utils.mjs +49 -0
- package/dist/esm/version.mjs +1 -1
- package/dist/index.js +1 -1
- package/dist/types/components/StorageBrowser/ComponentsProvider.d.ts +4 -1
- package/dist/types/components/StorageBrowser/actions/configs/types.d.ts +41 -2
- package/dist/types/components/StorageBrowser/actions/handlers/constants.d.ts +1 -0
- package/dist/types/components/StorageBrowser/actions/handlers/copy.d.ts +4 -7
- package/dist/types/components/StorageBrowser/actions/handlers/createFolder.d.ts +1 -3
- package/dist/types/components/StorageBrowser/actions/handlers/defaults.d.ts +15 -0
- package/dist/types/components/StorageBrowser/actions/handlers/delete.d.ts +2 -2
- package/dist/types/components/StorageBrowser/actions/handlers/index.d.ts +1 -0
- package/dist/types/components/StorageBrowser/actions/handlers/listLocations.d.ts +4 -12
- package/dist/types/components/StorageBrowser/actions/handlers/types.d.ts +26 -17
- package/dist/types/components/StorageBrowser/actions/handlers/upload.d.ts +1 -4
- package/dist/types/components/StorageBrowser/actions/handlers/utils.d.ts +2 -2
- package/dist/types/components/StorageBrowser/actions/index.d.ts +1 -1
- package/dist/types/components/StorageBrowser/componentsDefault.d.ts +2 -2
- package/dist/types/components/StorageBrowser/createStorageBrowser.d.ts +6 -0
- package/dist/types/components/StorageBrowser/displayText/index.d.ts +1 -0
- package/dist/types/components/StorageBrowser/displayText/types.d.ts +16 -5
- package/dist/types/components/StorageBrowser/displayText/utils.d.ts +3 -0
- package/dist/types/components/StorageBrowser/index.d.ts +4 -3
- package/dist/types/components/StorageBrowser/providers/configuration/createConfigurationProvider.d.ts +1 -1
- package/dist/types/components/StorageBrowser/providers/configuration/types.d.ts +3 -3
- package/dist/types/components/StorageBrowser/providers/index.d.ts +1 -1
- package/dist/types/components/StorageBrowser/providers/store/actionType/types.d.ts +4 -0
- package/dist/types/components/StorageBrowser/providers/store/files/types.d.ts +1 -4
- package/dist/types/components/StorageBrowser/providers/store/index.d.ts +1 -1
- package/dist/types/components/StorageBrowser/providers/store/location/context.d.ts +6 -0
- package/dist/types/components/StorageBrowser/storage-internal.d.ts +1 -1
- package/dist/types/components/StorageBrowser/tasks/index.d.ts +1 -1
- package/dist/types/components/StorageBrowser/tasks/types.d.ts +41 -23
- package/dist/types/components/StorageBrowser/tasks/useProcessTasks.d.ts +3 -3
- package/dist/types/components/StorageBrowser/types.d.ts +191 -15
- package/dist/types/components/StorageBrowser/useAction/types.d.ts +60 -32
- package/dist/types/components/StorageBrowser/useAction/useHandler.d.ts +4 -3
- package/dist/types/components/StorageBrowser/useAction/useList.d.ts +10 -7
- package/dist/types/components/StorageBrowser/views/LocationActionView/CopyView/types.d.ts +5 -0
- package/dist/types/components/StorageBrowser/views/LocationActionView/UploadView/types.d.ts +2 -2
- package/dist/types/components/StorageBrowser/views/LocationActionView/types.d.ts +4 -4
- package/dist/types/components/StorageBrowser/views/LocationDetailView/index.d.ts +1 -1
- package/dist/types/components/StorageBrowser/views/LocationsView/index.d.ts +1 -1
- package/dist/types/components/StorageBrowser/views/context/getViews.d.ts +2 -2
- package/dist/types/components/StorageBrowser/views/context/views.d.ts +2 -2
- package/dist/types/components/StorageBrowser/views/hooks/usePaginate.d.ts +8 -8
- package/dist/types/components/StorageBrowser/views/hooks/useResolveTableData/index.d.ts +2 -0
- package/dist/types/components/StorageBrowser/views/hooks/useResolveTableData/types.d.ts +26 -0
- package/dist/types/components/StorageBrowser/views/hooks/useResolveTableData/useResolveTableData.d.ts +6 -0
- package/dist/types/components/StorageBrowser/views/types.d.ts +1 -1
- package/dist/types/components/StorageBrowser/views/useView.d.ts +16 -13
- package/dist/types/components/StorageBrowser/views/utils/index.d.ts +1 -0
- package/dist/types/components/StorageBrowser/views/utils/tableResolvers/__testUtils__/tasks.d.ts +23 -0
- package/dist/types/components/StorageBrowser/views/utils/tableResolvers/constants.d.ts +16 -0
- package/dist/types/components/StorageBrowser/views/utils/tableResolvers/copyResolvers.d.ts +3 -0
- package/dist/types/components/StorageBrowser/views/utils/tableResolvers/deleteResolvers.d.ts +3 -0
- package/dist/types/components/StorageBrowser/views/utils/tableResolvers/index.d.ts +3 -0
- package/dist/types/components/StorageBrowser/views/utils/tableResolvers/types.d.ts +36 -0
- package/dist/types/components/StorageBrowser/views/utils/tableResolvers/uploadResolvers.d.ts +3 -0
- package/dist/types/components/StorageBrowser/views/utils/tableResolvers/utils.d.ts +12 -0
- package/dist/types/version.d.ts +1 -1
- package/package.json +5 -5
- package/dist/esm/components/StorageBrowser/views/LocationActionView/CopyView/utils.mjs +0 -3
- package/dist/esm/components/StorageBrowser/views/LocationActionView/DeleteView/utils.mjs +0 -3
- package/dist/esm/components/StorageBrowser/views/LocationActionView/UploadView/utils.mjs +0 -5
- package/dist/esm/components/StorageBrowser/views/LocationActionView/getActionIcon.mjs +0 -25
- package/dist/esm/components/StorageBrowser/views/LocationActionView/getActionViewTableData.mjs +0 -141
- package/dist/esm/components/StorageBrowser/views/LocationActionView/getDefaultActionViewHeaders.mjs +0 -24
- package/dist/esm/components/StorageBrowser/views/LocationActionView/getFileTypeDisplayValue.mjs +0 -5
- package/dist/esm/components/StorageBrowser/views/LocationActionView/getPercentValue.mjs +0 -3
- package/dist/types/components/StorageBrowser/displayText/en.d.ts +0 -9
- package/dist/types/components/StorageBrowser/views/LocationActionView/CopyView/utils.d.ts +0 -3
- package/dist/types/components/StorageBrowser/views/LocationActionView/DeleteView/utils.d.ts +0 -3
- package/dist/types/components/StorageBrowser/views/LocationActionView/UploadView/utils.d.ts +0 -3
- package/dist/types/components/StorageBrowser/views/LocationActionView/getActionIcon.d.ts +0 -3
- package/dist/types/components/StorageBrowser/views/LocationActionView/getActionViewTableData.d.ts +0 -14
- package/dist/types/components/StorageBrowser/views/LocationActionView/getDefaultActionViewHeaders.d.ts +0 -5
- package/dist/types/components/StorageBrowser/views/LocationActionView/getFileTypeDisplayValue.d.ts +0 -1
- package/dist/types/components/StorageBrowser/views/LocationActionView/getPercentValue.d.ts +0 -1
|
@@ -32,7 +32,12 @@ function _interopNamespace(e) {
|
|
|
32
32
|
|
|
33
33
|
var React__namespace = /*#__PURE__*/_interopNamespace(React);
|
|
34
34
|
|
|
35
|
-
const VERSION = '3.9.
|
|
35
|
+
const VERSION = '3.9.2';
|
|
36
|
+
|
|
37
|
+
const DEFAULT_CHECKSUM_ALGORITHM = 'crc-32';
|
|
38
|
+
// 5MiB for multipart upload
|
|
39
|
+
// https://github.com/aws-amplify/amplify-js/blob/1a5366d113c9af4ce994168653df3aadb142c581/packages/storage/src/providers/s3/utils/constants.ts#L16
|
|
40
|
+
const MULTIPART_UPLOAD_THRESHOLD_BYTES = 5 * 1024 * 1024;
|
|
36
41
|
|
|
37
42
|
const constructBucket = ({ bucket: bucketName, region, }) => ({ bucketName, region });
|
|
38
43
|
const parseAccessGrantLocation = (location) => {
|
|
@@ -118,9 +123,8 @@ const createFileDataItem = (data) => ({
|
|
|
118
123
|
...data,
|
|
119
124
|
fileKey: getFileKey(data.key),
|
|
120
125
|
});
|
|
121
|
-
const isFileItem = (value) => !!value.file;
|
|
122
|
-
const isFileDataItem = (item) => !!item.fileKey;
|
|
123
126
|
const getProgress = ({ totalBytes, transferredBytes, }) => totalBytes ? transferredBytes / totalBytes : undefined;
|
|
127
|
+
const isMultipartUpload = (file) => file.size > MULTIPART_UPLOAD_THRESHOLD_BYTES;
|
|
124
128
|
|
|
125
129
|
const copyHandler = (input) => {
|
|
126
130
|
const { config, data } = input;
|
|
@@ -155,12 +159,13 @@ const copyHandler = (input) => {
|
|
|
155
159
|
status: 'COMPLETE',
|
|
156
160
|
value: { key: path },
|
|
157
161
|
}))
|
|
158
|
-
.catch((
|
|
162
|
+
.catch((error) => {
|
|
163
|
+
const { message } = error;
|
|
164
|
+
return { error, message, status: 'FAILED' };
|
|
165
|
+
}),
|
|
159
166
|
};
|
|
160
167
|
};
|
|
161
168
|
|
|
162
|
-
const DEFAULT_CHECKSUM_ALGORITHM = 'crc-32';
|
|
163
|
-
|
|
164
169
|
const createFolderHandler = (input) => {
|
|
165
170
|
const { config, data, options } = input;
|
|
166
171
|
const { accountId, credentials, customEndpoint } = config;
|
|
@@ -189,11 +194,12 @@ const createFolderHandler = (input) => {
|
|
|
189
194
|
status: 'COMPLETE',
|
|
190
195
|
value: { key: path },
|
|
191
196
|
}))
|
|
192
|
-
.catch((
|
|
197
|
+
.catch((error) => {
|
|
198
|
+
const { message, name } = error;
|
|
193
199
|
if (name === 'PreconditionFailed') {
|
|
194
|
-
return { message, status: 'OVERWRITE_PREVENTED' };
|
|
200
|
+
return { error, message, status: 'OVERWRITE_PREVENTED' };
|
|
195
201
|
}
|
|
196
|
-
return { message, status: 'FAILED' };
|
|
202
|
+
return { error, message, status: 'FAILED' };
|
|
197
203
|
}),
|
|
198
204
|
};
|
|
199
205
|
};
|
|
@@ -214,7 +220,10 @@ const deleteHandler = ({ config, data, }) => {
|
|
|
214
220
|
status: 'COMPLETE',
|
|
215
221
|
value: { key: path },
|
|
216
222
|
}))
|
|
217
|
-
.catch((
|
|
223
|
+
.catch((error) => {
|
|
224
|
+
const { message } = error;
|
|
225
|
+
return { error, message, status: 'FAILED' };
|
|
226
|
+
});
|
|
218
227
|
return { result };
|
|
219
228
|
};
|
|
220
229
|
|
|
@@ -244,11 +253,14 @@ const downloadHandler = ({ config, data: { key }, }) => {
|
|
|
244
253
|
downloadFromUrl(key, url.toString());
|
|
245
254
|
return { status: 'COMPLETE', value: { url } };
|
|
246
255
|
})
|
|
247
|
-
.catch((
|
|
256
|
+
.catch((error) => {
|
|
257
|
+
const { message } = error;
|
|
258
|
+
return { error, message, status: 'FAILED' };
|
|
259
|
+
});
|
|
248
260
|
return { result };
|
|
249
261
|
};
|
|
250
262
|
|
|
251
|
-
const DEFAULT_PAGE_SIZE$
|
|
263
|
+
const DEFAULT_PAGE_SIZE$4 = 1000;
|
|
252
264
|
const parseItems = (items, excludedPath) => items
|
|
253
265
|
// remove root `key` from results
|
|
254
266
|
.filter(({ path }) => path !== excludedPath)
|
|
@@ -281,7 +293,7 @@ const parseResult = ({ excludedSubpaths, items }, prefix) => filterDotItems([...
|
|
|
281
293
|
const listLocationItemsHandler = async (input) => {
|
|
282
294
|
const { config, prefix, options } = input;
|
|
283
295
|
const { bucket: _bucket, credentials, customEndpoint, region, accountId, } = config;
|
|
284
|
-
const { exclude, delimiter, nextToken, pageSize: _pageSize = DEFAULT_PAGE_SIZE$
|
|
296
|
+
const { exclude, delimiter, nextToken, pageSize: _pageSize = DEFAULT_PAGE_SIZE$4, ..._options } = options ?? {};
|
|
285
297
|
const bucket = { bucketName: _bucket, region };
|
|
286
298
|
const subpathStrategy = {
|
|
287
299
|
delimiter,
|
|
@@ -318,39 +330,6 @@ const listLocationItemsHandler = async (input) => {
|
|
|
318
330
|
return { items: result, nextToken: nextNextToken };
|
|
319
331
|
};
|
|
320
332
|
|
|
321
|
-
function assertLocationPermissions(value, message) {
|
|
322
|
-
if (!Array.isArray(value) ||
|
|
323
|
-
value.some((inputPermissionEntry) => typeof inputPermissionEntry !== 'string' ||
|
|
324
|
-
!['list', 'get', 'write', 'delete'].includes(inputPermissionEntry))) {
|
|
325
|
-
throw new Error(message);
|
|
326
|
-
}
|
|
327
|
-
}
|
|
328
|
-
function assertLocationData(value, message = 'Invalid value provided as `location`.') {
|
|
329
|
-
const locationStringDataKeys = ['bucket', 'id', 'prefix', 'type'];
|
|
330
|
-
if (!ui.isObject(value) ||
|
|
331
|
-
locationStringDataKeys.some((key) => !ui.isString(value[key]))) {
|
|
332
|
-
throw new Error(message);
|
|
333
|
-
}
|
|
334
|
-
assertLocationPermissions(value?.permissions, message);
|
|
335
|
-
}
|
|
336
|
-
function assertPrefix(value, message) {
|
|
337
|
-
if (!ui.isString(value)) {
|
|
338
|
-
throw new Error(message ?? 'Invalid value provided as `prefix`.');
|
|
339
|
-
}
|
|
340
|
-
}
|
|
341
|
-
|
|
342
|
-
function assertRegisterAuthListener(value) {
|
|
343
|
-
if (!ui.isFunction(value)) {
|
|
344
|
-
throw new Error('StorageBrowser: `registerAuthListener` must be a function.');
|
|
345
|
-
}
|
|
346
|
-
}
|
|
347
|
-
|
|
348
|
-
const UPLOAD_FILE_SIZE_LIMIT = 160 * 1000 * 1000 * 1000;
|
|
349
|
-
const isFileTooBig = (file) => file.size > UPLOAD_FILE_SIZE_LIMIT;
|
|
350
|
-
|
|
351
|
-
// 5MB for multipart upload
|
|
352
|
-
// https://github.com/aws-amplify/amplify-js/blob/1a5366d113c9af4ce994168653df3aadb142c581/packages/storage/src/providers/s3/utils/constants.ts#L16
|
|
353
|
-
const MULTIPART_UPLOAD_THRESHOLD_BYTES = 5 * 1024 * 1024;
|
|
354
333
|
const UNDEFINED_CALLBACKS = {
|
|
355
334
|
cancel: undefined,
|
|
356
335
|
pause: undefined,
|
|
@@ -378,7 +357,7 @@ const uploadHandler = ({ config, data, options }) => {
|
|
|
378
357
|
};
|
|
379
358
|
const { cancel, pause, resume, result } = internals.uploadData(input);
|
|
380
359
|
return {
|
|
381
|
-
...(file
|
|
360
|
+
...(isMultipartUpload(file)
|
|
382
361
|
? { cancel, pause, resume }
|
|
383
362
|
: UNDEFINED_CALLBACKS),
|
|
384
363
|
result: result
|
|
@@ -389,16 +368,53 @@ const uploadHandler = ({ config, data, options }) => {
|
|
|
389
368
|
.catch((error) => {
|
|
390
369
|
const { message } = error;
|
|
391
370
|
if (error.name === 'PreconditionFailed') {
|
|
392
|
-
return { message, status: 'OVERWRITE_PREVENTED' };
|
|
371
|
+
return { error, message, status: 'OVERWRITE_PREVENTED' };
|
|
393
372
|
}
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
status: storage.isCancelError(error) ? 'CANCELED' : 'FAILED',
|
|
397
|
-
};
|
|
373
|
+
const status = storage.isCancelError(error) ? 'CANCELED' : 'FAILED';
|
|
374
|
+
return { error, message, status };
|
|
398
375
|
}),
|
|
399
376
|
};
|
|
400
377
|
};
|
|
401
378
|
|
|
379
|
+
const defaultHandlers = {
|
|
380
|
+
copy: copyHandler,
|
|
381
|
+
createFolder: createFolderHandler,
|
|
382
|
+
delete: deleteHandler,
|
|
383
|
+
download: downloadHandler,
|
|
384
|
+
listLocationItems: listLocationItemsHandler,
|
|
385
|
+
upload: uploadHandler,
|
|
386
|
+
};
|
|
387
|
+
|
|
388
|
+
function assertLocationPermissions(value, message) {
|
|
389
|
+
if (!Array.isArray(value) ||
|
|
390
|
+
value.some((inputPermissionEntry) => typeof inputPermissionEntry !== 'string' ||
|
|
391
|
+
!['list', 'get', 'write', 'delete'].includes(inputPermissionEntry))) {
|
|
392
|
+
throw new Error(message);
|
|
393
|
+
}
|
|
394
|
+
}
|
|
395
|
+
function assertLocationData(value, message = 'Invalid value provided as `location`.') {
|
|
396
|
+
const locationStringDataKeys = ['bucket', 'id', 'prefix', 'type'];
|
|
397
|
+
if (!ui.isObject(value) ||
|
|
398
|
+
locationStringDataKeys.some((key) => !ui.isString(value[key]))) {
|
|
399
|
+
throw new Error(message);
|
|
400
|
+
}
|
|
401
|
+
assertLocationPermissions(value?.permissions, message);
|
|
402
|
+
}
|
|
403
|
+
function assertPrefix(value, message) {
|
|
404
|
+
if (!ui.isString(value)) {
|
|
405
|
+
throw new Error(message ?? 'Invalid value provided as `prefix`.');
|
|
406
|
+
}
|
|
407
|
+
}
|
|
408
|
+
|
|
409
|
+
function assertRegisterAuthListener(value) {
|
|
410
|
+
if (!ui.isFunction(value)) {
|
|
411
|
+
throw new Error('StorageBrowser: `registerAuthListener` must be a function.');
|
|
412
|
+
}
|
|
413
|
+
}
|
|
414
|
+
|
|
415
|
+
const UPLOAD_FILE_SIZE_LIMIT = 160 * 1000 * 1000 * 1000;
|
|
416
|
+
const isFileTooBig = (file) => file.size > UPLOAD_FILE_SIZE_LIMIT;
|
|
417
|
+
|
|
402
418
|
const defaultValue$9 = {
|
|
403
419
|
actionConfigs: undefined,
|
|
404
420
|
};
|
|
@@ -412,7 +428,7 @@ const copyActionConfig = {
|
|
|
412
428
|
icon: 'copy-file',
|
|
413
429
|
label: 'Copy',
|
|
414
430
|
},
|
|
415
|
-
handler:
|
|
431
|
+
handler: defaultHandlers.copy,
|
|
416
432
|
};
|
|
417
433
|
const deleteActionConfig = {
|
|
418
434
|
viewName: 'DeleteView',
|
|
@@ -422,7 +438,7 @@ const deleteActionConfig = {
|
|
|
422
438
|
icon: 'delete-file',
|
|
423
439
|
label: 'Delete',
|
|
424
440
|
},
|
|
425
|
-
handler:
|
|
441
|
+
handler: defaultHandlers.delete,
|
|
426
442
|
};
|
|
427
443
|
const createFolderActionConfig = {
|
|
428
444
|
viewName: 'CreateFolderView',
|
|
@@ -431,7 +447,7 @@ const createFolderActionConfig = {
|
|
|
431
447
|
icon: 'create-folder',
|
|
432
448
|
label: 'Create folder',
|
|
433
449
|
},
|
|
434
|
-
handler:
|
|
450
|
+
handler: defaultHandlers.createFolder,
|
|
435
451
|
};
|
|
436
452
|
const uploadActionConfig = {
|
|
437
453
|
viewName: 'UploadView',
|
|
@@ -440,12 +456,14 @@ const uploadActionConfig = {
|
|
|
440
456
|
icon: 'upload-file',
|
|
441
457
|
label: 'Upload',
|
|
442
458
|
},
|
|
443
|
-
handler:
|
|
459
|
+
handler: defaultHandlers.upload,
|
|
444
460
|
};
|
|
461
|
+
// Action view configs only, does not include `listLocationItems`
|
|
445
462
|
const defaultActionViewConfigs = {
|
|
446
463
|
copy: copyActionConfig,
|
|
447
464
|
createFolder: createFolderActionConfig,
|
|
448
|
-
download
|
|
465
|
+
// provide `download` handler only; `download` does not have a dedicated view/config
|
|
466
|
+
download: defaultHandlers.download,
|
|
449
467
|
delete: deleteActionConfig,
|
|
450
468
|
upload: uploadActionConfig,
|
|
451
469
|
};
|
|
@@ -453,7 +471,7 @@ const DEFAULT_ACTION_VIEW_TYPES = Object.keys(defaultActionViewConfigs);
|
|
|
453
471
|
const isDefaultActionViewType = (value) => DEFAULT_ACTION_VIEW_TYPES.some((type) => type === value);
|
|
454
472
|
const defaultActionConfigs = {
|
|
455
473
|
...defaultActionViewConfigs,
|
|
456
|
-
listLocationItems:
|
|
474
|
+
listLocationItems: defaultHandlers.listLocationItems,
|
|
457
475
|
};
|
|
458
476
|
|
|
459
477
|
const isActionConfig = (value) => ui.isObject(value);
|
|
@@ -1084,7 +1102,7 @@ const OverwriteToggle = ({ isDisabled, isOverwritingEnabled, label = '', onToggl
|
|
|
1084
1102
|
onToggle?.();
|
|
1085
1103
|
} }));
|
|
1086
1104
|
};
|
|
1087
|
-
const SearchSubfoldersToggle = ({ isSearchingSubfolders, label = '', onToggle
|
|
1105
|
+
const SearchSubfoldersToggle = ({ isSearchingSubfolders, label = '', onToggle }) => {
|
|
1088
1106
|
return (React__namespace.createElement(uiReact.CheckboxField, { name: label, label: label, labelPosition: "end", checked: isSearchingSubfolders, onChange: () => {
|
|
1089
1107
|
onToggle?.();
|
|
1090
1108
|
} }));
|
|
@@ -1114,7 +1132,7 @@ const Navigation = ({ items }) => {
|
|
|
1114
1132
|
item.isCurrent ? null : React__namespace.createElement(uiReact.Breadcrumbs.Separator, null)));
|
|
1115
1133
|
})));
|
|
1116
1134
|
};
|
|
1117
|
-
const LoadingIndicator = ({ isLoading }) => {
|
|
1135
|
+
const LoadingIndicator = ({ isLoading, }) => {
|
|
1118
1136
|
if (isLoading) {
|
|
1119
1137
|
return (React__namespace.createElement(uiReact.Loader, { className: "amplify-storage-browser__loader", variation: "linear", size: "small" }));
|
|
1120
1138
|
}
|
|
@@ -1129,7 +1147,7 @@ const FolderNameField = ({ onChange, label, placeholder, validationMessage, onVa
|
|
|
1129
1147
|
onChange?.(value);
|
|
1130
1148
|
} }));
|
|
1131
1149
|
};
|
|
1132
|
-
const DataRefresh = ({ onRefresh }) => {
|
|
1150
|
+
const DataRefresh = ({ onRefresh, }) => {
|
|
1133
1151
|
return (React__namespace.createElement(uiReact.Button, { onClick: () => {
|
|
1134
1152
|
onRefresh?.();
|
|
1135
1153
|
}, "aria-label": "Refresh data" },
|
|
@@ -1147,7 +1165,7 @@ const ActionsList = ({ items, onActionSelect, isDisabled, }) => {
|
|
|
1147
1165
|
label));
|
|
1148
1166
|
})));
|
|
1149
1167
|
};
|
|
1150
|
-
const StatusDisplay = ({ statuses, total }) => {
|
|
1168
|
+
const StatusDisplay = ({ statuses, total, }) => {
|
|
1151
1169
|
if (!statuses?.length) {
|
|
1152
1170
|
return null;
|
|
1153
1171
|
}
|
|
@@ -1203,7 +1221,6 @@ const DEFAULT_ACTION_VIEW_DISPLAY_TEXT = {
|
|
|
1203
1221
|
tableColumnNameHeader: 'Name',
|
|
1204
1222
|
tableColumnTypeHeader: 'Type',
|
|
1205
1223
|
tableColumnSizeHeader: 'Size',
|
|
1206
|
-
tableColumnProgressHeader: 'Progress',
|
|
1207
1224
|
};
|
|
1208
1225
|
const DEFAULT_LIST_VIEW_DISPLAY_TEXT = {
|
|
1209
1226
|
loadingIndicatorLabel: 'Loading',
|
|
@@ -1433,7 +1450,6 @@ const DEFAULT_LOCATIONS_VIEW_DISPLAY_TEXT = {
|
|
|
1433
1450
|
|
|
1434
1451
|
const DEFAULT_UPLOAD_VIEW_DISPLAY_TEXT = {
|
|
1435
1452
|
...DEFAULT_ACTION_VIEW_DISPLAY_TEXT,
|
|
1436
|
-
title: 'Upload',
|
|
1437
1453
|
actionStartLabel: 'Upload',
|
|
1438
1454
|
addFilesLabel: 'Add files',
|
|
1439
1455
|
addFolderLabel: 'Add folder',
|
|
@@ -1509,8 +1525,10 @@ const DEFAULT_UPLOAD_VIEW_DISPLAY_TEXT = {
|
|
|
1509
1525
|
}
|
|
1510
1526
|
return undefined;
|
|
1511
1527
|
},
|
|
1512
|
-
statusDisplayOverwritePreventedLabel: 'Overwrite prevented',
|
|
1513
1528
|
overwriteToggleLabel: 'Overwrite existing files',
|
|
1529
|
+
statusDisplayOverwritePreventedLabel: 'Overwrite prevented',
|
|
1530
|
+
tableColumnProgressHeader: 'Progress',
|
|
1531
|
+
title: 'Upload',
|
|
1514
1532
|
};
|
|
1515
1533
|
|
|
1516
1534
|
const DEFAULT_STORAGE_BROWSER_DISPLAY_TEXT = {
|
|
@@ -1561,6 +1579,9 @@ function DisplayTextProvider({ children, displayText: _override, }) {
|
|
|
1561
1579
|
return (React__namespace["default"].createElement(DisplayTextContext.Provider, { value: resolvedDisplayText }, children));
|
|
1562
1580
|
}
|
|
1563
1581
|
|
|
1582
|
+
const isCopyViewDisplayTextKey = (value) => !!DEFAULT_COPY_VIEW_DISPLAY_TEXT[value];
|
|
1583
|
+
const isDeleteViewDisplayTextKey = (value) => !!DEFAULT_DELETE_VIEW_DISPLAY_TEXT[value];
|
|
1584
|
+
|
|
1564
1585
|
const Fallback = () => (React__namespace["default"].createElement("div", { className: STORAGE_BROWSER_BLOCK_TO_BE_UPDATED },
|
|
1565
1586
|
React__namespace["default"].createElement("div", { className: `${STORAGE_BROWSER_BLOCK_TO_BE_UPDATED}__error-boundary` }, "Something went wrong.")));
|
|
1566
1587
|
class ErrorBoundary extends React__namespace["default"].Component {
|
|
@@ -2464,197 +2485,342 @@ const TitleControl = () => {
|
|
|
2464
2485
|
return React__namespace["default"].createElement(Resolved, { ...props });
|
|
2465
2486
|
};
|
|
2466
2487
|
|
|
2467
|
-
|
|
2468
|
-
|
|
2469
|
-
|
|
2470
|
-
|
|
2471
|
-
|
|
2472
|
-
|
|
2473
|
-
|
|
2474
|
-
|
|
2475
|
-
|
|
2476
|
-
|
|
2477
|
-
|
|
2478
|
-
case 'OVERWRITE_PREVENTED': {
|
|
2479
|
-
return 'action-info';
|
|
2480
|
-
}
|
|
2481
|
-
case 'CANCELED': {
|
|
2482
|
-
return 'action-canceled';
|
|
2483
|
-
}
|
|
2484
|
-
case 'QUEUED':
|
|
2485
|
-
default: {
|
|
2486
|
-
return 'action-queued';
|
|
2487
|
-
}
|
|
2488
|
-
}
|
|
2489
|
-
};
|
|
2490
|
-
|
|
2491
|
-
const getFileTypeDisplayValue = (fileName) => fileName.lastIndexOf('.') !== -1
|
|
2492
|
-
? fileName.slice(fileName.lastIndexOf('.') + 1)
|
|
2493
|
-
: '';
|
|
2488
|
+
function useResolveDataTable(keys, { getCell, getHeader, getRowKey }, { items, props }) {
|
|
2489
|
+
return React__namespace["default"].useMemo(() => {
|
|
2490
|
+
const getRow = (item) => ({
|
|
2491
|
+
key: getRowKey({ item, props }),
|
|
2492
|
+
content: keys.map((key) => getCell({ key, item, props })),
|
|
2493
|
+
});
|
|
2494
|
+
const headers = keys.map((key) => getHeader({ key, props }));
|
|
2495
|
+
const rows = (items ?? []).map(getRow);
|
|
2496
|
+
return { headers, rows };
|
|
2497
|
+
}, [getCell, getHeader, getRowKey, keys, items, props]);
|
|
2498
|
+
}
|
|
2494
2499
|
|
|
2495
|
-
const
|
|
2500
|
+
const STATUS_LABELS = {
|
|
2501
|
+
PENDING: 'statusDisplayInProgressLabel',
|
|
2502
|
+
CANCELED: 'statusDisplayCanceledLabel',
|
|
2503
|
+
COMPLETE: 'statusDisplayCompletedLabel',
|
|
2504
|
+
FAILED: 'statusDisplayFailedLabel',
|
|
2505
|
+
QUEUED: 'statusDisplayQueuedLabel',
|
|
2506
|
+
OVERWRITE_PREVENTED: 'statusDisplayOverwritePreventedLabel',
|
|
2507
|
+
};
|
|
2508
|
+
const STATUS_ICONS = {
|
|
2509
|
+
PENDING: 'action-progress',
|
|
2510
|
+
COMPLETE: 'action-success',
|
|
2511
|
+
FAILED: 'action-error',
|
|
2512
|
+
OVERWRITE_PREVENTED: 'action-info',
|
|
2513
|
+
CANCELED: 'action-canceled',
|
|
2514
|
+
QUEUED: 'action-queued',
|
|
2515
|
+
};
|
|
2516
|
+
|
|
2517
|
+
const getFileType = (value, fallback = '') => value.lastIndexOf('.') !== -1
|
|
2518
|
+
? value.slice(value.lastIndexOf('.') + 1)
|
|
2519
|
+
: fallback;
|
|
2520
|
+
const getCellName = (value) =>
|
|
2521
|
+
// `value.split` always returns an array with at least one entry
|
|
2522
|
+
// ensruing `.pop()` will always return a string
|
|
2523
|
+
value.split('/').pop();
|
|
2524
|
+
const getUploadCellFolder = ({ data: { file: { webkitRelativePath }, }, }, fallback = '-') => webkitRelativePath
|
|
2525
|
+
? webkitRelativePath.slice(0, webkitRelativePath.lastIndexOf('/') + 1)
|
|
2526
|
+
: fallback;
|
|
2527
|
+
const getCopyCellFolder = ({ data: { fileKey, sourceKey }, }) => sourceKey.slice(0, -fileKey.length);
|
|
2528
|
+
const getDeleteCellFolder = ({ data: { fileKey, key }, }) => key.slice(0, -fileKey.length);
|
|
2529
|
+
const getUploadCellProgress = ({ progress, status, }) => {
|
|
2530
|
+
// prefer `progress` if available, 1 if status is complete, default 0
|
|
2531
|
+
const value = progress ?? (status === 'COMPLETE' ? 1 : 0);
|
|
2532
|
+
const displayValue = `${Math.round(value * 100)}%`;
|
|
2533
|
+
return { displayValue, value };
|
|
2534
|
+
};
|
|
2535
|
+
const getFileSize = (value, fallback = '-') => (!value ? fallback : ui.humanFileSize(value, true));
|
|
2536
|
+
const getCopyOrDeleteCancelCellContent = (data) => {
|
|
2537
|
+
const { item, props } = data;
|
|
2538
|
+
const { cancel, status } = item;
|
|
2539
|
+
const { isProcessing, onTaskRemove } = props;
|
|
2540
|
+
const isQueued = status === 'QUEUED';
|
|
2541
|
+
// a task is removable prior to processing start. Including `isQueued` ensures
|
|
2542
|
+
// that `isRemovable` is `false` on all tasks processing complete
|
|
2543
|
+
const isRemovable = isQueued && !isProcessing;
|
|
2544
|
+
// a task is cancelable while processing is true, and the task has a cancel handler
|
|
2545
|
+
const isCancelable = isProcessing && !!cancel;
|
|
2546
|
+
const ariaLabel = `${isRemovable ? 'Remove' : 'Cancel'} item: ${getCellName(item.data.fileKey)}`;
|
|
2547
|
+
const isDisabled = !isRemovable && !isCancelable;
|
|
2548
|
+
// resolve to `undefined` if not cancelable or removable
|
|
2549
|
+
const onClick = !isCancelable && !isRemovable
|
|
2550
|
+
? undefined
|
|
2551
|
+
: () => {
|
|
2552
|
+
if (isRemovable) {
|
|
2553
|
+
onTaskRemove?.(item);
|
|
2554
|
+
// do not run cancel handler on remove
|
|
2555
|
+
return;
|
|
2556
|
+
}
|
|
2557
|
+
if (isCancelable)
|
|
2558
|
+
cancel();
|
|
2559
|
+
};
|
|
2560
|
+
return { ariaLabel, isDisabled, onClick, icon: 'cancel' };
|
|
2561
|
+
};
|
|
2496
2562
|
|
|
2497
|
-
const
|
|
2498
|
-
|
|
2499
|
-
|
|
2500
|
-
|
|
2501
|
-
|
|
2502
|
-
|
|
2503
|
-
|
|
2504
|
-
|
|
2505
|
-
|
|
2506
|
-
|
|
2507
|
-
|
|
2508
|
-
|
|
2509
|
-
|
|
2510
|
-
|
|
2511
|
-
|
|
2512
|
-
|
|
2513
|
-
|
|
2514
|
-
|
|
2515
|
-
|
|
2516
|
-
|
|
2517
|
-
|
|
2563
|
+
const COPY_TABLE_KEYS = [
|
|
2564
|
+
'name',
|
|
2565
|
+
'folder',
|
|
2566
|
+
'type',
|
|
2567
|
+
'size',
|
|
2568
|
+
'status',
|
|
2569
|
+
'cancel',
|
|
2570
|
+
];
|
|
2571
|
+
const getCopyCellKey = ({ key, item, }) => `${key}-${item.data.id}`;
|
|
2572
|
+
const name$2 = (data) => {
|
|
2573
|
+
const key = getCopyCellKey(data);
|
|
2574
|
+
const { item } = data;
|
|
2575
|
+
const text = item.data.fileKey;
|
|
2576
|
+
const icon = STATUS_ICONS[item.status];
|
|
2577
|
+
return { key, type: 'text', content: { icon, text } };
|
|
2578
|
+
};
|
|
2579
|
+
const folder$2 = (data) => {
|
|
2580
|
+
const key = getCopyCellKey(data);
|
|
2581
|
+
const text = getCopyCellFolder(data.item);
|
|
2582
|
+
return { key, type: 'text', content: { text } };
|
|
2583
|
+
};
|
|
2584
|
+
const type$2 = (data) => {
|
|
2585
|
+
const key = getCopyCellKey(data);
|
|
2586
|
+
const { fileKey } = data.item.data;
|
|
2587
|
+
const text = getFileType(fileKey);
|
|
2588
|
+
return { key, type: 'text', content: { text } };
|
|
2589
|
+
};
|
|
2590
|
+
const size$2 = (data) => {
|
|
2591
|
+
const key = getCopyCellKey(data);
|
|
2592
|
+
const { size: value } = data.item.data;
|
|
2593
|
+
const displayValue = getFileSize(value);
|
|
2594
|
+
return { key, type: 'number', content: { value, displayValue } };
|
|
2595
|
+
};
|
|
2596
|
+
const status$2 = (data) => {
|
|
2597
|
+
const key = getCopyCellKey(data);
|
|
2598
|
+
const { item: { status }, props: { displayText }, } = data;
|
|
2599
|
+
const statusLabelKey = STATUS_LABELS[status];
|
|
2600
|
+
const text = isCopyViewDisplayTextKey(statusLabelKey)
|
|
2601
|
+
? displayText[statusLabelKey]
|
|
2602
|
+
: '';
|
|
2603
|
+
return { key, type: 'text', content: { text } };
|
|
2604
|
+
};
|
|
2605
|
+
const cancel$2 = (data) => {
|
|
2606
|
+
const key = getCopyCellKey(data);
|
|
2607
|
+
const content = getCopyOrDeleteCancelCellContent(data);
|
|
2608
|
+
return { key, type: 'button', content };
|
|
2609
|
+
};
|
|
2610
|
+
const COPY_CELL_RESOLVERS = {
|
|
2611
|
+
name: name$2,
|
|
2612
|
+
folder: folder$2,
|
|
2613
|
+
type: type$2,
|
|
2614
|
+
size: size$2,
|
|
2615
|
+
status: status$2,
|
|
2616
|
+
cancel: cancel$2,
|
|
2617
|
+
/**
|
|
2618
|
+
* @deprecated
|
|
2619
|
+
*
|
|
2620
|
+
* non-upload view tables do not include "progress" headers but include here to
|
|
2621
|
+
* keep TS happy as "progress" headers were included in display text interfaces
|
|
2622
|
+
* and cannot be removed from the tables without a breaking change
|
|
2623
|
+
*/
|
|
2624
|
+
progress: ui.noop,
|
|
2625
|
+
};
|
|
2626
|
+
const COPY_TABLE_RESOLVERS = {
|
|
2627
|
+
getCell: (data) => COPY_CELL_RESOLVERS[data.key](data),
|
|
2628
|
+
getHeader: ({ key, props: { displayText } }) => {
|
|
2629
|
+
const text = displayText[`tableColumn${ui.capitalize(key)}Header`];
|
|
2630
|
+
if (key === 'cancel') {
|
|
2631
|
+
return { key, type: 'text', content: { text } };
|
|
2632
|
+
}
|
|
2633
|
+
return { key, type: 'sort', content: { label: text } };
|
|
2634
|
+
},
|
|
2635
|
+
getRowKey: ({ item }) => item.data.id,
|
|
2518
2636
|
};
|
|
2519
2637
|
|
|
2520
|
-
const
|
|
2521
|
-
|
|
2522
|
-
|
|
2523
|
-
|
|
2524
|
-
|
|
2525
|
-
|
|
2526
|
-
|
|
2527
|
-
|
|
2528
|
-
|
|
2529
|
-
|
|
2530
|
-
|
|
2531
|
-
|
|
2532
|
-
|
|
2533
|
-
|
|
2534
|
-
|
|
2535
|
-
|
|
2638
|
+
const UPLOAD_TABLE_KEYS = [
|
|
2639
|
+
'name',
|
|
2640
|
+
'folder',
|
|
2641
|
+
'type',
|
|
2642
|
+
'size',
|
|
2643
|
+
'status',
|
|
2644
|
+
'progress',
|
|
2645
|
+
'cancel',
|
|
2646
|
+
];
|
|
2647
|
+
const getUploadCellKey = ({ key, item, }) => `${key}-${item.data.id}`;
|
|
2648
|
+
const name$1 = (data) => {
|
|
2649
|
+
const key = getUploadCellKey(data);
|
|
2650
|
+
const { item } = data;
|
|
2651
|
+
const icon = STATUS_ICONS[item.status];
|
|
2652
|
+
const text = getCellName(item.data.key);
|
|
2653
|
+
return { key, type: 'text', content: { icon, text } };
|
|
2654
|
+
};
|
|
2655
|
+
const folder$1 = (data) => {
|
|
2656
|
+
const key = getUploadCellKey(data);
|
|
2657
|
+
const text = getUploadCellFolder(data.item);
|
|
2658
|
+
return { key, type: 'text', content: { text } };
|
|
2659
|
+
};
|
|
2660
|
+
const type$1 = (data) => {
|
|
2661
|
+
const key = getUploadCellKey(data);
|
|
2662
|
+
const { item } = data;
|
|
2663
|
+
const text = getFileType(getCellName(item.data.key));
|
|
2664
|
+
return { key, type: 'text', content: { text } };
|
|
2665
|
+
};
|
|
2666
|
+
const size$1 = (data) => {
|
|
2667
|
+
const key = getUploadCellKey(data);
|
|
2668
|
+
const { size: value } = data.item.data.file;
|
|
2669
|
+
const displayValue = getFileSize(value);
|
|
2670
|
+
return { key, type: 'number', content: { value, displayValue } };
|
|
2671
|
+
};
|
|
2672
|
+
const status$1 = (data) => {
|
|
2673
|
+
const key = getUploadCellKey(data);
|
|
2674
|
+
const { item: { status }, props: { displayText }, } = data;
|
|
2675
|
+
const text = displayText[STATUS_LABELS[status]];
|
|
2676
|
+
return { key, type: 'text', content: { text } };
|
|
2677
|
+
};
|
|
2678
|
+
const progress = (data) => {
|
|
2679
|
+
const key = getUploadCellKey(data);
|
|
2680
|
+
const content = getUploadCellProgress(data.item);
|
|
2681
|
+
return { key, type: 'number', content };
|
|
2682
|
+
};
|
|
2683
|
+
const cancel$1 = (data) => {
|
|
2684
|
+
const key = getUploadCellKey(data);
|
|
2685
|
+
const { item, props } = data;
|
|
2686
|
+
const { cancel, data: taskData, status, progress } = item;
|
|
2687
|
+
const { isMultipartUpload, isProcessing, onTaskRemove } = props;
|
|
2688
|
+
const isQueued = status === 'QUEUED';
|
|
2689
|
+
const isPending = status === 'PENDING';
|
|
2690
|
+
// cancelability is dependent on differing conditions for multipart and single part uploads
|
|
2691
|
+
let isCancelable;
|
|
2692
|
+
if (isMultipartUpload(taskData.file)) {
|
|
2693
|
+
// signals MPU complete has been reached
|
|
2694
|
+
const hasUploadedAllBytes = progress === 1;
|
|
2695
|
+
// MPU allows cancel when tasks processing has begun and task is queued or
|
|
2696
|
+
// pending but not yet reached MPU complete
|
|
2697
|
+
isCancelable =
|
|
2698
|
+
isProcessing && (isQueued || isPending) && !hasUploadedAllBytes;
|
|
2536
2699
|
}
|
|
2537
|
-
|
|
2538
|
-
|
|
2539
|
-
|
|
2540
|
-
type: 'sort',
|
|
2541
|
-
content: { label },
|
|
2542
|
-
});
|
|
2543
|
-
const getActionViewTableData = ({ tasks, displayText, getFolderText, isProcessing, shouldDisplayProgress = false, onTaskRemove, }) => {
|
|
2544
|
-
const headers = [
|
|
2545
|
-
...getDefaultActionViewHeaders({
|
|
2546
|
-
displayText,
|
|
2547
|
-
}),
|
|
2548
|
-
];
|
|
2549
|
-
if (shouldDisplayProgress) {
|
|
2550
|
-
headers.splice(-1, 0, getProgressHeader(displayText.tableColumnProgressHeader));
|
|
2700
|
+
else {
|
|
2701
|
+
// single part upload allows cancel when processing has begun and task is queued
|
|
2702
|
+
isCancelable = isProcessing && isQueued;
|
|
2551
2703
|
}
|
|
2552
|
-
|
|
2553
|
-
|
|
2554
|
-
|
|
2555
|
-
|
|
2556
|
-
|
|
2557
|
-
|
|
2558
|
-
|
|
2559
|
-
|
|
2560
|
-
|
|
2561
|
-
|
|
2562
|
-
|
|
2563
|
-
|
|
2564
|
-
|
|
2565
|
-
|
|
2566
|
-
|
|
2567
|
-
|
|
2568
|
-
icon: getActionIcon(status),
|
|
2569
|
-
text: displayKey,
|
|
2570
|
-
},
|
|
2571
|
-
};
|
|
2572
|
-
}
|
|
2573
|
-
case 'folder': {
|
|
2574
|
-
const text = getFolderText?.(task) ?? '/';
|
|
2575
|
-
return { key, type: 'text', content: { text } };
|
|
2576
|
-
}
|
|
2577
|
-
case 'type': {
|
|
2578
|
-
return {
|
|
2579
|
-
key,
|
|
2580
|
-
type: 'text',
|
|
2581
|
-
content: { text: getFileTypeDisplayValue(displayKey) },
|
|
2582
|
-
};
|
|
2583
|
-
}
|
|
2584
|
-
case 'size': {
|
|
2585
|
-
const value = isFileItem(data)
|
|
2586
|
-
? data.file.size
|
|
2587
|
-
: isFileDataItem(data)
|
|
2588
|
-
? data.size
|
|
2589
|
-
: undefined;
|
|
2590
|
-
return {
|
|
2591
|
-
key,
|
|
2592
|
-
type: 'number',
|
|
2593
|
-
content: {
|
|
2594
|
-
value,
|
|
2595
|
-
displayValue: value ? ui.humanFileSize(value, true) : '-',
|
|
2596
|
-
},
|
|
2597
|
-
};
|
|
2598
|
-
}
|
|
2599
|
-
case 'status': {
|
|
2600
|
-
return {
|
|
2601
|
-
key,
|
|
2602
|
-
type: 'text',
|
|
2603
|
-
content: {
|
|
2604
|
-
text: getTaskStatusDisplayLabel({ status, displayText }),
|
|
2605
|
-
},
|
|
2606
|
-
};
|
|
2607
|
-
}
|
|
2608
|
-
case 'progress': {
|
|
2609
|
-
return {
|
|
2610
|
-
key,
|
|
2611
|
-
type: 'number',
|
|
2612
|
-
content: {
|
|
2613
|
-
value: progress,
|
|
2614
|
-
displayValue: `${getPercentValue(
|
|
2615
|
-
// Default progress to 100% if progress value is unavailable but status is recognized as complete
|
|
2616
|
-
progress ?? (status === 'COMPLETE' ? 1 : 0))}%`,
|
|
2617
|
-
},
|
|
2618
|
-
};
|
|
2619
|
-
}
|
|
2620
|
-
case 'cancel': {
|
|
2621
|
-
const isPending = status === 'PENDING';
|
|
2622
|
-
const isQueued = status === 'QUEUED';
|
|
2623
|
-
const isDisabled = (!isPending && !isQueued) || !cancel || progress === 1;
|
|
2624
|
-
const ariaLabel = `${isProcessing ? 'Cancel' : 'Remove'} item: ${displayKey}`;
|
|
2625
|
-
return {
|
|
2626
|
-
key,
|
|
2627
|
-
type: 'button',
|
|
2628
|
-
content: {
|
|
2629
|
-
isDisabled,
|
|
2630
|
-
onClick: () => {
|
|
2631
|
-
if (!isProcessing) {
|
|
2632
|
-
onTaskRemove?.(task);
|
|
2633
|
-
}
|
|
2634
|
-
cancel?.();
|
|
2635
|
-
},
|
|
2636
|
-
ariaLabel,
|
|
2637
|
-
icon: 'cancel',
|
|
2638
|
-
},
|
|
2639
|
-
};
|
|
2640
|
-
}
|
|
2641
|
-
default:
|
|
2642
|
-
return { key, type: 'text', content: {} };
|
|
2643
|
-
}
|
|
2644
|
-
}),
|
|
2704
|
+
// all uploads are removable prior to processing start. Including `isQueued`
|
|
2705
|
+
// ensures that `isRemovable` is `false` on all tasks processing complete
|
|
2706
|
+
const isRemovable = !isProcessing && isQueued;
|
|
2707
|
+
const isDisabled = !isRemovable && !isCancelable;
|
|
2708
|
+
const ariaLabel = `${isRemovable ? 'Remove' : 'Cancel'} item: ${getCellName(item.data.key)}`;
|
|
2709
|
+
// resolve to `undefined` if not cancelable or removable
|
|
2710
|
+
const onClick = !isCancelable && !isRemovable
|
|
2711
|
+
? undefined
|
|
2712
|
+
: () => {
|
|
2713
|
+
if (isRemovable) {
|
|
2714
|
+
onTaskRemove?.(item);
|
|
2715
|
+
// do not run cancel handler on remove
|
|
2716
|
+
return;
|
|
2717
|
+
}
|
|
2718
|
+
if (!!cancel && isCancelable)
|
|
2719
|
+
cancel();
|
|
2645
2720
|
};
|
|
2646
|
-
}
|
|
2647
|
-
return {
|
|
2721
|
+
const content = { ariaLabel, isDisabled, onClick, icon: 'cancel' };
|
|
2722
|
+
return { key, type: 'button', content };
|
|
2723
|
+
};
|
|
2724
|
+
const UPLOAD_CELL_RESOLVERS = {
|
|
2725
|
+
cancel: cancel$1,
|
|
2726
|
+
folder: folder$1,
|
|
2727
|
+
name: name$1,
|
|
2728
|
+
progress,
|
|
2729
|
+
size: size$1,
|
|
2730
|
+
status: status$1,
|
|
2731
|
+
type: type$1,
|
|
2732
|
+
};
|
|
2733
|
+
const UPLOAD_TABLE_RESOLVERS = {
|
|
2734
|
+
getCell: (data) => UPLOAD_CELL_RESOLVERS[data.key](data),
|
|
2735
|
+
getHeader: ({ key, props: { displayText } }) => {
|
|
2736
|
+
const text = displayText[`tableColumn${ui.capitalize(key)}Header`];
|
|
2737
|
+
if (key === 'cancel') {
|
|
2738
|
+
return { key, type: 'text', content: { text } };
|
|
2739
|
+
}
|
|
2740
|
+
return { key, type: 'sort', content: { label: text } };
|
|
2741
|
+
},
|
|
2742
|
+
getRowKey: ({ item }) => item.data.id,
|
|
2648
2743
|
};
|
|
2649
2744
|
|
|
2650
|
-
const
|
|
2651
|
-
|
|
2652
|
-
|
|
2745
|
+
const DELETE_TABLE_KEYS = [
|
|
2746
|
+
'name',
|
|
2747
|
+
'folder',
|
|
2748
|
+
'type',
|
|
2749
|
+
'size',
|
|
2750
|
+
'status',
|
|
2751
|
+
'cancel',
|
|
2752
|
+
];
|
|
2753
|
+
const getDeleteCellKey = ({ key, item, }) => `${key}-${item.data.id}`;
|
|
2754
|
+
const name = (data) => {
|
|
2755
|
+
const key = getDeleteCellKey(data);
|
|
2756
|
+
const { item } = data;
|
|
2757
|
+
const text = item.data.fileKey;
|
|
2758
|
+
const icon = STATUS_ICONS[item.status];
|
|
2759
|
+
return { key, type: 'text', content: { icon, text } };
|
|
2760
|
+
};
|
|
2761
|
+
const folder = (data) => {
|
|
2762
|
+
const key = getDeleteCellKey(data);
|
|
2763
|
+
const text = getDeleteCellFolder(data.item);
|
|
2764
|
+
return { key, type: 'text', content: { text } };
|
|
2765
|
+
};
|
|
2766
|
+
const type = (data) => {
|
|
2767
|
+
const key = getDeleteCellKey(data);
|
|
2768
|
+
const { fileKey } = data.item.data;
|
|
2769
|
+
const text = getFileType(fileKey);
|
|
2770
|
+
return { key, type: 'text', content: { text } };
|
|
2771
|
+
};
|
|
2772
|
+
const size = (data) => {
|
|
2773
|
+
const key = getDeleteCellKey(data);
|
|
2774
|
+
const { size: value } = data.item.data;
|
|
2775
|
+
const displayValue = getFileSize(value);
|
|
2776
|
+
return { key, type: 'number', content: { value, displayValue } };
|
|
2777
|
+
};
|
|
2778
|
+
const status = (data) => {
|
|
2779
|
+
const key = getDeleteCellKey(data);
|
|
2780
|
+
const { item: { status }, props: { displayText }, } = data;
|
|
2781
|
+
const statusLabelKey = STATUS_LABELS[status];
|
|
2782
|
+
const text = isDeleteViewDisplayTextKey(statusLabelKey)
|
|
2783
|
+
? displayText[statusLabelKey]
|
|
2784
|
+
: '';
|
|
2785
|
+
return { key, type: 'text', content: { text } };
|
|
2786
|
+
};
|
|
2787
|
+
const cancel = (data) => {
|
|
2788
|
+
const key = getDeleteCellKey(data);
|
|
2789
|
+
const content = getCopyOrDeleteCancelCellContent(data);
|
|
2790
|
+
return { key, type: 'button', content };
|
|
2791
|
+
};
|
|
2792
|
+
const DELETE_CELL_RESOLVERS = {
|
|
2793
|
+
name,
|
|
2794
|
+
folder,
|
|
2795
|
+
type,
|
|
2796
|
+
size,
|
|
2797
|
+
status,
|
|
2798
|
+
cancel,
|
|
2799
|
+
/**
|
|
2800
|
+
* @deprecated
|
|
2801
|
+
*
|
|
2802
|
+
* non-upload view tables do not include "progress" headers but include here to
|
|
2803
|
+
* keep TS happy as "progress" headers were included in display text interfaces
|
|
2804
|
+
* and cannot be removed from the tables without a breaking change
|
|
2805
|
+
*/
|
|
2806
|
+
progress: ui.noop,
|
|
2807
|
+
};
|
|
2808
|
+
const DELETE_TABLE_RESOLVERS = {
|
|
2809
|
+
getCell: (data) => DELETE_CELL_RESOLVERS[data.key](data),
|
|
2810
|
+
getHeader: ({ key, props: { displayText } }) => {
|
|
2811
|
+
const text = displayText[`tableColumn${ui.capitalize(key)}Header`];
|
|
2812
|
+
if (key === 'cancel') {
|
|
2813
|
+
return { key, type: 'text', content: { text } };
|
|
2814
|
+
}
|
|
2815
|
+
return { key, type: 'sort', content: { label: text } };
|
|
2816
|
+
},
|
|
2817
|
+
getRowKey: ({ item }) => item.data.id,
|
|
2818
|
+
};
|
|
2653
2819
|
|
|
2654
2820
|
function UploadViewProvider({ children, ...props }) {
|
|
2655
2821
|
const { UploadView: displayText } = useDisplayText();
|
|
2656
2822
|
const { actionCancelLabel, actionDestinationLabel, actionExitLabel, actionStartLabel, addFilesLabel, addFolderLabel, statusDisplayCanceledLabel, statusDisplayCompletedLabel, statusDisplayFailedLabel, statusDisplayQueuedLabel, overwriteToggleLabel, title, getActionCompleteMessage, getFilesValidationMessage, } = displayText;
|
|
2657
|
-
const { isOverwritingEnabled, isProcessing, isProcessingComplete, location, tasks, statusCounts, invalidFiles, onActionStart, onActionCancel, onDropFiles, onActionExit, onTaskRemove, onSelectFiles, onToggleOverwrite, } = props;
|
|
2823
|
+
const { isOverwritingEnabled, isProcessing, isProcessingComplete, location, tasks: items, statusCounts, invalidFiles, onActionStart, onActionCancel, onDropFiles, onActionExit, onTaskRemove, onSelectFiles, onToggleOverwrite, } = props;
|
|
2658
2824
|
const isActionStartDisabled = isProcessing || isProcessingComplete || statusCounts.TOTAL === 0;
|
|
2659
2825
|
const isActionCancelDisabled = !isProcessing || isProcessingComplete;
|
|
2660
2826
|
const isAddFilesDisabled = isProcessing || isProcessingComplete;
|
|
@@ -2668,6 +2834,10 @@ function UploadViewProvider({ children, ...props }) {
|
|
|
2668
2834
|
const filesValidationMessage = invalidFiles && !isProcessing
|
|
2669
2835
|
? getFilesValidationMessage({ invalidFiles })
|
|
2670
2836
|
: undefined;
|
|
2837
|
+
const tableData = useResolveDataTable(UPLOAD_TABLE_KEYS, UPLOAD_TABLE_RESOLVERS, {
|
|
2838
|
+
items,
|
|
2839
|
+
props: { displayText, isProcessing, isMultipartUpload, onTaskRemove },
|
|
2840
|
+
});
|
|
2671
2841
|
return (React__namespace["default"].createElement(ControlsContextProvider, { data: {
|
|
2672
2842
|
actionCancelLabel,
|
|
2673
2843
|
actionDestinationLabel,
|
|
@@ -2691,14 +2861,7 @@ function UploadViewProvider({ children, ...props }) {
|
|
|
2691
2861
|
statusDisplayCompletedLabel,
|
|
2692
2862
|
statusDisplayFailedLabel,
|
|
2693
2863
|
statusDisplayQueuedLabel,
|
|
2694
|
-
tableData
|
|
2695
|
-
getFolderText: getFolderText$2,
|
|
2696
|
-
tasks,
|
|
2697
|
-
shouldDisplayProgress: true,
|
|
2698
|
-
displayText,
|
|
2699
|
-
isProcessing,
|
|
2700
|
-
onTaskRemove,
|
|
2701
|
-
}),
|
|
2864
|
+
tableData,
|
|
2702
2865
|
title,
|
|
2703
2866
|
}, onActionCancel: onActionCancel, onActionExit: onActionExit, onActionStart: onActionStart, onAddFiles: () => {
|
|
2704
2867
|
onSelectFiles('FILE');
|
|
@@ -2834,6 +2997,9 @@ const createEnhancedListHandler = (action) => {
|
|
|
2834
2997
|
};
|
|
2835
2998
|
};
|
|
2836
2999
|
|
|
3000
|
+
const DEFAULT_ACTION_CONCURRENCY = 4;
|
|
3001
|
+
const USE_LIST_ERROR_MESSAGE = '`useList` must be called from within `StorageBrowser.Provider`';
|
|
3002
|
+
|
|
2837
3003
|
const INITIAL_STATUS_COUNTS = {
|
|
2838
3004
|
CANCELED: 0,
|
|
2839
3005
|
COMPLETE: 0,
|
|
@@ -2864,8 +3030,8 @@ const QUEUED_TASK_BASE = {
|
|
|
2864
3030
|
status: 'QUEUED',
|
|
2865
3031
|
};
|
|
2866
3032
|
const isTaskHandlerInput = (input) => !!input.data;
|
|
2867
|
-
|
|
2868
|
-
const { concurrency, ...callbacks } = options ?? {};
|
|
3033
|
+
function useProcessTasks(handler, options) {
|
|
3034
|
+
const { concurrency, items, ...callbacks } = options ?? {};
|
|
2869
3035
|
const callbacksRef = React__namespace["default"].useRef(callbacks);
|
|
2870
3036
|
if (callbacks) {
|
|
2871
3037
|
callbacksRef.current = callbacks;
|
|
@@ -2891,6 +3057,7 @@ const useProcessTasks = (handler, items, options) => {
|
|
|
2891
3057
|
tasksRef.current.set(id, { ...task, ...next });
|
|
2892
3058
|
}
|
|
2893
3059
|
flush();
|
|
3060
|
+
return !next ? undefined : tasksRef.current.get(id);
|
|
2894
3061
|
}, [flush]);
|
|
2895
3062
|
const createTask = React__namespace["default"].useCallback((data) => {
|
|
2896
3063
|
const getTask = () => tasksRef.current.get(data.id);
|
|
@@ -2899,9 +3066,12 @@ const useProcessTasks = (handler, items, options) => {
|
|
|
2899
3066
|
const task = getTask();
|
|
2900
3067
|
if (!task || task?.status !== 'QUEUED')
|
|
2901
3068
|
return;
|
|
2902
|
-
|
|
2903
|
-
|
|
2904
|
-
|
|
3069
|
+
const canceledTask = updateTask(data.id, {
|
|
3070
|
+
cancel: undefined,
|
|
3071
|
+
status: 'CANCELED',
|
|
3072
|
+
});
|
|
3073
|
+
if (canceledTask && ui.isFunction(onTaskCancel))
|
|
3074
|
+
onTaskCancel(canceledTask);
|
|
2905
3075
|
}
|
|
2906
3076
|
const task = { ...QUEUED_TASK_BASE, cancel, data };
|
|
2907
3077
|
tasksRef.current.set(data.id, task);
|
|
@@ -2946,16 +3116,15 @@ const useProcessTasks = (handler, items, options) => {
|
|
|
2946
3116
|
const { onTaskCancel, onTaskComplete, onTaskError, onTaskProgress, onTaskSuccess, } = callbacksRef.current;
|
|
2947
3117
|
const getTask = () => tasksRef.current.get(data.id);
|
|
2948
3118
|
const { options } = _input;
|
|
2949
|
-
const { onProgress: _onProgress
|
|
3119
|
+
const { onProgress: _onProgress } = options ?? {};
|
|
2950
3120
|
const onProgress = ({ id }, progress) => {
|
|
2951
|
-
const task =
|
|
3121
|
+
const task = updateTask(id, { progress });
|
|
2952
3122
|
if (task && ui.isFunction(onTaskProgress)) {
|
|
2953
3123
|
onTaskProgress(task, progress);
|
|
2954
3124
|
}
|
|
2955
3125
|
if (task && ui.isFunction(_onProgress)) {
|
|
2956
3126
|
_onProgress(data, progress);
|
|
2957
3127
|
}
|
|
2958
|
-
updateTask(id, { progress });
|
|
2959
3128
|
};
|
|
2960
3129
|
const input = { ..._input, data, options: { ...options, onProgress } };
|
|
2961
3130
|
const { cancel: _cancel, result } = handler(input);
|
|
@@ -2969,21 +3138,16 @@ const useProcessTasks = (handler, items, options) => {
|
|
|
2969
3138
|
};
|
|
2970
3139
|
result
|
|
2971
3140
|
.then((output) => {
|
|
2972
|
-
const task =
|
|
2973
|
-
|
|
2974
|
-
|
|
2975
|
-
|
|
2976
|
-
if (task && ui.isFunction(onSuccess))
|
|
2977
|
-
onSuccess(data, output?.value);
|
|
2978
|
-
updateTask(data.id, output);
|
|
3141
|
+
const task = updateTask(data.id, output);
|
|
3142
|
+
const { value } = output;
|
|
3143
|
+
if (task && ui.isFunction(onTaskSuccess))
|
|
3144
|
+
onTaskSuccess(task, value);
|
|
2979
3145
|
})
|
|
2980
|
-
.catch((
|
|
2981
|
-
const
|
|
3146
|
+
.catch((error) => {
|
|
3147
|
+
const { message } = error;
|
|
3148
|
+
const task = updateTask(data.id, { message, status: 'FAILED' });
|
|
2982
3149
|
if (task && ui.isFunction(onTaskError))
|
|
2983
|
-
onTaskError(task,
|
|
2984
|
-
if (task && ui.isFunction(onError))
|
|
2985
|
-
onError(data, e?.message);
|
|
2986
|
-
updateTask(data.id, { message: e.message, status: 'FAILED' });
|
|
3150
|
+
onTaskError(task, error);
|
|
2987
3151
|
})
|
|
2988
3152
|
.finally(() => {
|
|
2989
3153
|
const task = getTask();
|
|
@@ -3021,52 +3185,54 @@ const useProcessTasks = (handler, items, options) => {
|
|
|
3021
3185
|
{ isProcessing, isProcessingComplete, reset, statusCounts, tasks },
|
|
3022
3186
|
handleProcessTasks,
|
|
3023
3187
|
];
|
|
3024
|
-
}
|
|
3025
|
-
|
|
3026
|
-
const DEFAULT_ACTION_CONCURRENCY = 4;
|
|
3027
|
-
const USE_LIST_ERROR_MESSAGE = '`useList` must be called from within `StorageBrowser.Provider`';
|
|
3188
|
+
}
|
|
3028
3189
|
|
|
3029
|
-
const
|
|
3030
|
-
const
|
|
3031
|
-
|
|
3032
|
-
const
|
|
3033
|
-
|
|
3034
|
-
|
|
3035
|
-
const [state, processTask] = useProcessTasks(action, items, {
|
|
3036
|
-
onTaskSuccess,
|
|
3037
|
-
...(items ? { concurrency: DEFAULT_ACTION_CONCURRENCY } : undefined),
|
|
3190
|
+
const isOptionsWithItems = (options) => !!options?.items;
|
|
3191
|
+
const isHandleTaskInput = (value) => !!value?.data;
|
|
3192
|
+
function useHandler(handler, options) {
|
|
3193
|
+
const [state, handleProcessing] = useProcessTasks(handler, {
|
|
3194
|
+
...options,
|
|
3195
|
+
concurrency: DEFAULT_ACTION_CONCURRENCY,
|
|
3038
3196
|
});
|
|
3039
|
-
const
|
|
3040
|
-
const
|
|
3041
|
-
|
|
3042
|
-
const config = getConfig(location
|
|
3043
|
-
|
|
3044
|
-
|
|
3197
|
+
const getConfig = useGetActionInput();
|
|
3198
|
+
const { reset, isProcessing, tasks, ...rest } = state;
|
|
3199
|
+
const handleDispatch = React__namespace["default"].useCallback((input) => {
|
|
3200
|
+
const config = getConfig(input?.location);
|
|
3201
|
+
const hasData = isHandleTaskInput(input);
|
|
3202
|
+
// clean up previous state for atomic handler
|
|
3203
|
+
if (hasData)
|
|
3045
3204
|
reset();
|
|
3046
|
-
|
|
3047
|
-
|
|
3048
|
-
|
|
3049
|
-
|
|
3050
|
-
}, [
|
|
3051
|
-
|
|
3052
|
-
|
|
3053
|
-
|
|
3054
|
-
];
|
|
3055
|
-
}
|
|
3205
|
+
handleProcessing({
|
|
3206
|
+
config,
|
|
3207
|
+
...(hasData ? { data: input.data } : undefined),
|
|
3208
|
+
});
|
|
3209
|
+
}, [getConfig, handleProcessing, reset]);
|
|
3210
|
+
if (isOptionsWithItems(options)) {
|
|
3211
|
+
return [{ ...rest, isProcessing, reset, tasks }, handleDispatch];
|
|
3212
|
+
}
|
|
3213
|
+
return [{ isProcessing, task: tasks?.[0] }, handleDispatch];
|
|
3214
|
+
}
|
|
3056
3215
|
|
|
3057
3216
|
const ERROR_MESSAGE = '`useAction` must be called from within `StorageBrowser.Provider`';
|
|
3058
|
-
|
|
3059
|
-
if (key === 'listLocations' ||
|
|
3060
|
-
key === 'listLocationItems') {
|
|
3217
|
+
function assertActionHandlerKey(key) {
|
|
3218
|
+
if (key === 'listLocations' || key === 'listLocationItems') {
|
|
3061
3219
|
throw new Error(`Value of \`${key}\` cannot be provided to \`useAction\``);
|
|
3062
3220
|
}
|
|
3063
|
-
|
|
3064
|
-
|
|
3065
|
-
if (
|
|
3221
|
+
}
|
|
3222
|
+
function assertActionHandler(handler, key) {
|
|
3223
|
+
if (typeof handler !== 'function') {
|
|
3066
3224
|
throw new Error(`No handler found for value of \`${key}\` provided to \`useAction\``);
|
|
3067
3225
|
}
|
|
3226
|
+
}
|
|
3227
|
+
const useAction = ((key, options) => {
|
|
3228
|
+
assertActionHandlerKey(key);
|
|
3229
|
+
const { handlers } = useActionHandlers({ errorMessage: ERROR_MESSAGE });
|
|
3230
|
+
const handler = handlers?.[key];
|
|
3231
|
+
assertActionHandler(handler, key);
|
|
3068
3232
|
return useHandler(handler, options);
|
|
3069
|
-
|
|
3233
|
+
// casting to allow usage of `UseAction` interface which ensures that
|
|
3234
|
+
// the `options` param receives the correct typing
|
|
3235
|
+
});
|
|
3070
3236
|
|
|
3071
3237
|
const useListLocations = () => {
|
|
3072
3238
|
const { handlers } = useActionHandlers({
|
|
@@ -3112,7 +3278,6 @@ const LIST_ACTION_HOOKS = {
|
|
|
3112
3278
|
locations: useListLocations,
|
|
3113
3279
|
};
|
|
3114
3280
|
const isListActionViewType = (value) => Object.keys(LIST_ACTION_HOOKS).includes(value);
|
|
3115
|
-
// @ts-expect-error
|
|
3116
3281
|
const useList = (type) => {
|
|
3117
3282
|
if (!isListActionViewType(type)) {
|
|
3118
3283
|
throw new Error(`Value of \`${type}\` cannot be used to index \`useList\``);
|
|
@@ -3476,19 +3641,14 @@ const FoldersTableControl = () => {
|
|
|
3476
3641
|
};
|
|
3477
3642
|
FoldersTableControl.displayName = 'FoldersTable';
|
|
3478
3643
|
|
|
3479
|
-
const getFolderText$1 = ({ data: { fileKey, sourceKey }, }) => sourceKey.slice(0, -fileKey.length);
|
|
3480
|
-
|
|
3481
3644
|
function CopyViewProvider({ children, ...props }) {
|
|
3482
3645
|
const { CopyView: displayText } = useDisplayText();
|
|
3483
3646
|
const { actionCancelLabel, actionDestinationLabel, actionExitLabel, actionStartLabel, getActionCompleteMessage, overwriteWarningMessage, searchPlaceholder, searchSubmitLabel, searchClearLabel, statusDisplayCanceledLabel, statusDisplayCompletedLabel, statusDisplayFailedLabel, statusDisplayQueuedLabel, title, } = displayText;
|
|
3484
|
-
const { destination, folders, isProcessing, isProcessingComplete, statusCounts, tasks, onActionCancel, onActionExit, onActionStart, onSelectDestination, onTaskRemove, } = props;
|
|
3647
|
+
const { destination, folders, isProcessing, isProcessingComplete, statusCounts, tasks: items, onActionCancel, onActionExit, onActionStart, onSelectDestination, onTaskRemove, } = props;
|
|
3485
3648
|
const { hasNextPage, highestPageVisited, hasError: hasFoldersError, message: foldersErrorMessage, query, hasExhaustedSearch, isLoading, page, pageItems, onPaginate, onQuery, onSearchClear, onSearch, onSelectFolder, } = folders;
|
|
3486
|
-
const tableData =
|
|
3487
|
-
|
|
3488
|
-
|
|
3489
|
-
isProcessing,
|
|
3490
|
-
displayText,
|
|
3491
|
-
onTaskRemove,
|
|
3649
|
+
const tableData = useResolveDataTable(COPY_TABLE_KEYS, COPY_TABLE_RESOLVERS, {
|
|
3650
|
+
items,
|
|
3651
|
+
props: { displayText, isProcessing, onTaskRemove },
|
|
3492
3652
|
});
|
|
3493
3653
|
const isActionStartDisabled = isProcessing || isProcessingComplete || !destination?.current;
|
|
3494
3654
|
const isActionCancelDisabled = !isProcessing || isProcessingComplete;
|
|
@@ -3527,40 +3687,38 @@ function CopyViewProvider({ children, ...props }) {
|
|
|
3527
3687
|
React__namespace["default"].createElement(FoldersMessageProvider, { folders: folders.pageItems, hasError: hasFoldersError, message: foldersErrorMessage, query: query, hasExhaustedSearch: hasExhaustedSearch }, children)))));
|
|
3528
3688
|
}
|
|
3529
3689
|
|
|
3530
|
-
const
|
|
3531
|
-
|
|
3690
|
+
const DEFAULT_PAGE_SIZE$3 = 100;
|
|
3691
|
+
const usePaginate = ({ items, onPaginate, page = 1, pageSize = DEFAULT_PAGE_SIZE$3, }) => {
|
|
3692
|
+
const [currentPage, setCurrentPage] = React__namespace["default"].useState(page);
|
|
3693
|
+
const visitedRef = React__namespace["default"].useRef(page);
|
|
3532
3694
|
const handleReset = React__namespace["default"].useRef(() => {
|
|
3533
|
-
setCurrentPage(
|
|
3695
|
+
setCurrentPage(page);
|
|
3696
|
+
// set `visitedRef` to initially provided `page`
|
|
3697
|
+
visitedRef.current = page;
|
|
3534
3698
|
}).current;
|
|
3535
3699
|
return React__namespace["default"].useMemo(() => {
|
|
3536
|
-
const
|
|
3537
|
-
const highestPageVisited =
|
|
3700
|
+
const hasItems = Array.isArray(items);
|
|
3701
|
+
const highestPageVisited = visitedRef.current;
|
|
3538
3702
|
const isFirstPage = currentPage === 1;
|
|
3539
3703
|
const start = isFirstPage ? 0 : (currentPage - 1) * pageSize;
|
|
3540
3704
|
const end = isFirstPage ? pageSize : currentPage * pageSize;
|
|
3541
|
-
const pageItems =
|
|
3705
|
+
const pageItems = hasItems ? items.slice(start, end) : [];
|
|
3542
3706
|
return {
|
|
3543
3707
|
currentPage,
|
|
3544
|
-
|
|
3545
|
-
|
|
3546
|
-
|
|
3547
|
-
|
|
3548
|
-
|
|
3549
|
-
|
|
3550
|
-
|
|
3708
|
+
handlePaginate: (page) => {
|
|
3709
|
+
if (page < 1)
|
|
3710
|
+
return;
|
|
3711
|
+
if (ui.isFunction(onPaginate))
|
|
3712
|
+
onPaginate(page);
|
|
3713
|
+
if (page > currentPage)
|
|
3714
|
+
visitedRef.current = page;
|
|
3715
|
+
setCurrentPage(page);
|
|
3551
3716
|
},
|
|
3552
3717
|
handleReset,
|
|
3553
3718
|
highestPageVisited,
|
|
3554
3719
|
pageItems,
|
|
3555
3720
|
};
|
|
3556
|
-
}, [
|
|
3557
|
-
currentPage,
|
|
3558
|
-
handleReset,
|
|
3559
|
-
hasNextToken,
|
|
3560
|
-
items,
|
|
3561
|
-
paginateCallback,
|
|
3562
|
-
pageSize,
|
|
3563
|
-
]);
|
|
3721
|
+
}, [currentPage, handleReset, items, onPaginate, pageSize]);
|
|
3564
3722
|
};
|
|
3565
3723
|
|
|
3566
3724
|
function useSearch(props) {
|
|
@@ -3605,20 +3763,19 @@ const useFolders = ({ destination, setDestination, }) => {
|
|
|
3605
3763
|
options: { ...DEFAULT_REFRESH_OPTIONS },
|
|
3606
3764
|
});
|
|
3607
3765
|
}, [handleList, key]);
|
|
3608
|
-
const
|
|
3609
|
-
const
|
|
3610
|
-
if (!
|
|
3766
|
+
const hasNextPage = !!nextToken;
|
|
3767
|
+
const onPaginate = () => {
|
|
3768
|
+
if (!hasNextPage)
|
|
3611
3769
|
return;
|
|
3612
3770
|
handleList({
|
|
3613
3771
|
prefix: key,
|
|
3614
3772
|
options: { ...DEFAULT_LIST_OPTIONS$2, nextToken },
|
|
3615
3773
|
});
|
|
3616
3774
|
};
|
|
3617
|
-
const { currentPage: page,
|
|
3775
|
+
const { currentPage: page, handlePaginate, highestPageVisited, pageItems, handleReset, } = usePaginate({
|
|
3618
3776
|
items,
|
|
3619
|
-
|
|
3777
|
+
onPaginate,
|
|
3620
3778
|
pageSize: DEFAULT_PAGE_SIZE$2,
|
|
3621
|
-
hasNextToken,
|
|
3622
3779
|
});
|
|
3623
3780
|
const onSearch = (query) => {
|
|
3624
3781
|
handleReset();
|
|
@@ -3644,7 +3801,7 @@ const useFolders = ({ destination, setDestination, }) => {
|
|
|
3644
3801
|
};
|
|
3645
3802
|
return {
|
|
3646
3803
|
hasError,
|
|
3647
|
-
hasNextPage
|
|
3804
|
+
hasNextPage,
|
|
3648
3805
|
highestPageVisited,
|
|
3649
3806
|
isLoading,
|
|
3650
3807
|
message,
|
|
@@ -3653,7 +3810,7 @@ const useFolders = ({ destination, setDestination, }) => {
|
|
|
3653
3810
|
pageItems,
|
|
3654
3811
|
query,
|
|
3655
3812
|
hasExhaustedSearch,
|
|
3656
|
-
onPaginate,
|
|
3813
|
+
onPaginate: handlePaginate,
|
|
3657
3814
|
onQuery,
|
|
3658
3815
|
onSearch: onSearchSubmit,
|
|
3659
3816
|
onSearchClear: () => {
|
|
@@ -3786,21 +3943,16 @@ CopyView.Statuses = StatusDisplayControl;
|
|
|
3786
3943
|
CopyView.TasksTable = DataTableControl;
|
|
3787
3944
|
CopyView.Title = TitleControl;
|
|
3788
3945
|
|
|
3789
|
-
const getFolderText = ({ data: { fileKey, key }, }) => key.slice(0, -fileKey.length);
|
|
3790
|
-
|
|
3791
3946
|
function DeleteViewProvider({ children, ...props }) {
|
|
3792
3947
|
const { DeleteView: displayText } = useDisplayText();
|
|
3793
3948
|
const { actionCancelLabel, actionExitLabel, actionStartLabel, title, statusDisplayCanceledLabel, statusDisplayCompletedLabel, statusDisplayFailedLabel, statusDisplayQueuedLabel, getActionCompleteMessage, } = displayText;
|
|
3794
|
-
const { isProcessing, isProcessingComplete, statusCounts, tasks, onActionCancel, onActionStart, onActionExit, onTaskRemove, } = props;
|
|
3949
|
+
const { isProcessing, isProcessingComplete, statusCounts, tasks: items, onActionCancel, onActionStart, onActionExit, onTaskRemove, } = props;
|
|
3795
3950
|
const message = isProcessingComplete
|
|
3796
3951
|
? getActionCompleteMessage({ counts: statusCounts })
|
|
3797
3952
|
: undefined;
|
|
3798
|
-
const tableData =
|
|
3799
|
-
|
|
3800
|
-
isProcessing,
|
|
3801
|
-
displayText,
|
|
3802
|
-
getFolderText,
|
|
3803
|
-
onTaskRemove,
|
|
3953
|
+
const tableData = useResolveDataTable(DELETE_TABLE_KEYS, DELETE_TABLE_RESOLVERS, {
|
|
3954
|
+
items,
|
|
3955
|
+
props: { displayText, isProcessing, onTaskRemove },
|
|
3804
3956
|
});
|
|
3805
3957
|
return (React__namespace["default"].createElement(ControlsContextProvider, { data: {
|
|
3806
3958
|
actionCancelLabel,
|
|
@@ -4025,8 +4177,7 @@ const useLocationDetailView = (options) => {
|
|
|
4025
4177
|
// set up pagination
|
|
4026
4178
|
const { items, nextToken, search } = data;
|
|
4027
4179
|
const { hasExhaustedSearch = false } = search ?? {};
|
|
4028
|
-
const
|
|
4029
|
-
const paginateCallback = () => {
|
|
4180
|
+
const onPaginate = () => {
|
|
4030
4181
|
if (hasInvalidPrefix || !nextToken)
|
|
4031
4182
|
return;
|
|
4032
4183
|
dispatchStoreAction({ type: 'RESET_LOCATION_ITEMS' });
|
|
@@ -4035,11 +4186,10 @@ const useLocationDetailView = (options) => {
|
|
|
4035
4186
|
options: { ...listOptions, nextToken },
|
|
4036
4187
|
});
|
|
4037
4188
|
};
|
|
4038
|
-
const { currentPage,
|
|
4189
|
+
const { currentPage, handlePaginate, handleReset, highestPageVisited, pageItems, } = usePaginate({
|
|
4039
4190
|
items,
|
|
4040
|
-
|
|
4191
|
+
onPaginate,
|
|
4041
4192
|
pageSize: listOptions.pageSize,
|
|
4042
|
-
hasNextToken,
|
|
4043
4193
|
});
|
|
4044
4194
|
const onSearch = (query, includeSubfolders) => {
|
|
4045
4195
|
if (hasInvalidPrefix)
|
|
@@ -4107,13 +4257,13 @@ const useLocationDetailView = (options) => {
|
|
|
4107
4257
|
fileDataItems,
|
|
4108
4258
|
hasError,
|
|
4109
4259
|
hasDownloadError: task?.status === 'FAILED',
|
|
4110
|
-
hasNextPage:
|
|
4260
|
+
hasNextPage: !!nextToken,
|
|
4111
4261
|
highestPageVisited,
|
|
4112
4262
|
message,
|
|
4113
4263
|
downloadErrorMessage: getDownloadErrorMessageFromFailedDownloadTask(task),
|
|
4114
4264
|
isLoading,
|
|
4115
4265
|
isSearchSubfoldersEnabled,
|
|
4116
|
-
onPaginate,
|
|
4266
|
+
onPaginate: handlePaginate,
|
|
4117
4267
|
searchQuery,
|
|
4118
4268
|
hasExhaustedSearch,
|
|
4119
4269
|
onRefresh,
|
|
@@ -4169,10 +4319,7 @@ const useLocationDetailView = (options) => {
|
|
|
4169
4319
|
resetSearch();
|
|
4170
4320
|
if (hasInvalidPrefix)
|
|
4171
4321
|
return;
|
|
4172
|
-
handleList({
|
|
4173
|
-
prefix: key,
|
|
4174
|
-
options: { ...listOptions, refresh: true },
|
|
4175
|
-
});
|
|
4322
|
+
handleList({ prefix: key, options: { ...listOptions, refresh: true } });
|
|
4176
4323
|
handleReset();
|
|
4177
4324
|
},
|
|
4178
4325
|
onSearchQueryChange,
|
|
@@ -4679,16 +4826,15 @@ const useLocationsView = (options) => {
|
|
|
4679
4826
|
handleList({ options: { ...listOptions, refresh: true } });
|
|
4680
4827
|
}, [handleList, listOptions]);
|
|
4681
4828
|
// set up pagination
|
|
4682
|
-
const
|
|
4829
|
+
const onPaginate = () => {
|
|
4683
4830
|
if (!nextToken)
|
|
4684
4831
|
return;
|
|
4685
4832
|
handleList({ options: { ...listOptions, nextToken } });
|
|
4686
4833
|
};
|
|
4687
|
-
const { currentPage,
|
|
4834
|
+
const { currentPage, handlePaginate, handleReset, highestPageVisited, pageItems, } = usePaginate({
|
|
4688
4835
|
items,
|
|
4689
|
-
|
|
4836
|
+
onPaginate,
|
|
4690
4837
|
pageSize: listOptions.pageSize,
|
|
4691
|
-
hasNextToken,
|
|
4692
4838
|
});
|
|
4693
4839
|
const onSearch = (query) => {
|
|
4694
4840
|
handleReset();
|
|
@@ -4735,7 +4881,7 @@ const useLocationsView = (options) => {
|
|
|
4735
4881
|
handleReset();
|
|
4736
4882
|
handleList({ options: { ...listOptions, refresh: true } });
|
|
4737
4883
|
},
|
|
4738
|
-
onPaginate,
|
|
4884
|
+
onPaginate: handlePaginate,
|
|
4739
4885
|
onSearch: onSearchSubmit,
|
|
4740
4886
|
onSearchQueryChange,
|
|
4741
4887
|
onSearchClear: () => {
|
|
@@ -4799,7 +4945,10 @@ const getViews = (views, customConfigs) => {
|
|
|
4799
4945
|
// ignore custom actions that are only handlers
|
|
4800
4946
|
return !ui.isObject(config) || ui.isFunction(config)
|
|
4801
4947
|
? acc
|
|
4802
|
-
: {
|
|
4948
|
+
: {
|
|
4949
|
+
...acc,
|
|
4950
|
+
[key]: views?.[config.viewName],
|
|
4951
|
+
};
|
|
4803
4952
|
}, {});
|
|
4804
4953
|
return {
|
|
4805
4954
|
action: { ...resolvedDefaultActionViews, ...customActionViews },
|
|
@@ -4824,7 +4973,7 @@ function useViews() {
|
|
|
4824
4973
|
};
|
|
4825
4974
|
}
|
|
4826
4975
|
|
|
4827
|
-
const
|
|
4976
|
+
const USE_VIEW_HOOKS = {
|
|
4828
4977
|
Copy: useCopyView,
|
|
4829
4978
|
CreateFolder: useCreateFolderView,
|
|
4830
4979
|
Delete: useDeleteView,
|
|
@@ -4832,13 +4981,12 @@ const DEFAULT_VIEW_HOOKS = {
|
|
|
4832
4981
|
Locations: useLocationsView,
|
|
4833
4982
|
Upload: useUploadView,
|
|
4834
4983
|
};
|
|
4835
|
-
const isUseViewType = (value) => !!
|
|
4836
|
-
// @ts-expect-error
|
|
4984
|
+
const isUseViewType = (value) => !!USE_VIEW_HOOKS?.[value];
|
|
4837
4985
|
const useView = (type) => {
|
|
4838
4986
|
if (!isUseViewType(type)) {
|
|
4839
4987
|
throw new Error(`Value of \`${type}\` cannot be used to index \`useView\``);
|
|
4840
4988
|
}
|
|
4841
|
-
return
|
|
4989
|
+
return USE_VIEW_HOOKS[type]();
|
|
4842
4990
|
};
|
|
4843
4991
|
|
|
4844
4992
|
/**
|
|
@@ -4861,6 +5009,12 @@ function StorageBrowserDefault() {
|
|
|
4861
5009
|
return React__namespace["default"].createElement(LocationsView, null);
|
|
4862
5010
|
}
|
|
4863
5011
|
|
|
5012
|
+
/**
|
|
5013
|
+
* Creates a `StorageBrowser` component and utility hooks from provided configuration `input`.
|
|
5014
|
+
*
|
|
5015
|
+
* @param input - `StorageBrowser` auth, actions and ui configuration values
|
|
5016
|
+
* @returns `StorageBrowser` component, `useAction` and `useView` hooks
|
|
5017
|
+
*/
|
|
4864
5018
|
function createStorageBrowser(input) {
|
|
4865
5019
|
assertRegisterAuthListener(input.config.registerAuthListener);
|
|
4866
5020
|
const { accountId, customEndpoint, registerAuthListener, getLocationCredentials, region, } = input.config;
|
|
@@ -5062,5 +5216,7 @@ exports.VERSION = VERSION;
|
|
|
5062
5216
|
exports.componentsDefault = componentsDefault;
|
|
5063
5217
|
exports.createAmplifyAuthAdapter = createAmplifyAuthAdapter;
|
|
5064
5218
|
exports.createStorageBrowser = createStorageBrowser;
|
|
5219
|
+
exports.defaultActionConfigs = defaultActionConfigs;
|
|
5220
|
+
exports.defaultHandlers = defaultHandlers;
|
|
5065
5221
|
exports.getFilteredLocations = getFilteredLocations;
|
|
5066
5222
|
exports.toAccessGrantPermission = toAccessGrantPermission;
|