@aws-amplify/ui-react-storage 3.9.0 → 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-BcuxpEzi.js → createAmplifyAuthAdapter-BJjOYxQA.js} +541 -394
- 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 +8 -10
- 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 -8
- package/dist/esm/components/StorageBrowser/views/LocationActionView/DeleteView/useDeleteView.mjs +6 -9
- package/dist/esm/components/StorageBrowser/views/LocationActionView/UploadView/UploadViewProvider.mjs +14 -10
- 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/getActionIcon.mjs +0 -25
- package/dist/esm/components/StorageBrowser/views/LocationActionView/getActionViewTableData.mjs +0 -155
- 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/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,207 +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, isProcessing, locationKey, 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
|
-
if (locationKey) {
|
|
2575
|
-
return { key, type: 'text', content: { text: locationKey } };
|
|
2576
|
-
}
|
|
2577
|
-
if (isFileItem(data)) {
|
|
2578
|
-
const { webkitRelativePath } = data.file;
|
|
2579
|
-
return {
|
|
2580
|
-
key,
|
|
2581
|
-
type: 'text',
|
|
2582
|
-
content: {
|
|
2583
|
-
text: webkitRelativePath
|
|
2584
|
-
? webkitRelativePath.slice(0, webkitRelativePath.lastIndexOf('/') + 1)
|
|
2585
|
-
: '-',
|
|
2586
|
-
},
|
|
2587
|
-
};
|
|
2588
|
-
}
|
|
2589
|
-
return { key, type: 'text', content: { text: '/' } };
|
|
2590
|
-
}
|
|
2591
|
-
case 'type': {
|
|
2592
|
-
return {
|
|
2593
|
-
key,
|
|
2594
|
-
type: 'text',
|
|
2595
|
-
content: { text: getFileTypeDisplayValue(displayKey) },
|
|
2596
|
-
};
|
|
2597
|
-
}
|
|
2598
|
-
case 'size': {
|
|
2599
|
-
const value = isFileItem(data)
|
|
2600
|
-
? data.file.size
|
|
2601
|
-
: isFileDataItem(data)
|
|
2602
|
-
? data.size
|
|
2603
|
-
: undefined;
|
|
2604
|
-
return {
|
|
2605
|
-
key,
|
|
2606
|
-
type: 'number',
|
|
2607
|
-
content: {
|
|
2608
|
-
value,
|
|
2609
|
-
displayValue: value ? ui.humanFileSize(value, true) : '-',
|
|
2610
|
-
},
|
|
2611
|
-
};
|
|
2612
|
-
}
|
|
2613
|
-
case 'status': {
|
|
2614
|
-
return {
|
|
2615
|
-
key,
|
|
2616
|
-
type: 'text',
|
|
2617
|
-
content: {
|
|
2618
|
-
text: getTaskStatusDisplayLabel({ status, displayText }),
|
|
2619
|
-
},
|
|
2620
|
-
};
|
|
2621
|
-
}
|
|
2622
|
-
case 'progress': {
|
|
2623
|
-
return {
|
|
2624
|
-
key,
|
|
2625
|
-
type: 'number',
|
|
2626
|
-
content: {
|
|
2627
|
-
value: progress,
|
|
2628
|
-
displayValue: `${getPercentValue(
|
|
2629
|
-
// Default progress to 100% if progress value is unavailable but status is recognized as complete
|
|
2630
|
-
progress ?? (status === 'COMPLETE' ? 1 : 0))}%`,
|
|
2631
|
-
},
|
|
2632
|
-
};
|
|
2633
|
-
}
|
|
2634
|
-
case 'cancel': {
|
|
2635
|
-
const isPending = status === 'PENDING';
|
|
2636
|
-
const isQueued = status === 'QUEUED';
|
|
2637
|
-
const isDisabled = (!isPending && !isQueued) || !cancel || progress === 1;
|
|
2638
|
-
const ariaLabel = `${isProcessing ? 'Cancel' : 'Remove'} item: ${displayKey}`;
|
|
2639
|
-
return {
|
|
2640
|
-
key,
|
|
2641
|
-
type: 'button',
|
|
2642
|
-
content: {
|
|
2643
|
-
isDisabled,
|
|
2644
|
-
onClick: () => {
|
|
2645
|
-
if (!isProcessing) {
|
|
2646
|
-
onTaskRemove?.(task);
|
|
2647
|
-
}
|
|
2648
|
-
cancel?.();
|
|
2649
|
-
},
|
|
2650
|
-
ariaLabel,
|
|
2651
|
-
icon: 'cancel',
|
|
2652
|
-
},
|
|
2653
|
-
};
|
|
2654
|
-
}
|
|
2655
|
-
default:
|
|
2656
|
-
return { key, type: 'text', content: {} };
|
|
2657
|
-
}
|
|
2658
|
-
}),
|
|
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();
|
|
2659
2720
|
};
|
|
2660
|
-
}
|
|
2661
|
-
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,
|
|
2743
|
+
};
|
|
2744
|
+
|
|
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,
|
|
2662
2818
|
};
|
|
2663
2819
|
|
|
2664
2820
|
function UploadViewProvider({ children, ...props }) {
|
|
2665
2821
|
const { UploadView: displayText } = useDisplayText();
|
|
2666
2822
|
const { actionCancelLabel, actionDestinationLabel, actionExitLabel, actionStartLabel, addFilesLabel, addFolderLabel, statusDisplayCanceledLabel, statusDisplayCompletedLabel, statusDisplayFailedLabel, statusDisplayQueuedLabel, overwriteToggleLabel, title, getActionCompleteMessage, getFilesValidationMessage, } = displayText;
|
|
2667
|
-
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;
|
|
2668
2824
|
const isActionStartDisabled = isProcessing || isProcessingComplete || statusCounts.TOTAL === 0;
|
|
2669
2825
|
const isActionCancelDisabled = !isProcessing || isProcessingComplete;
|
|
2670
2826
|
const isAddFilesDisabled = isProcessing || isProcessingComplete;
|
|
@@ -2678,6 +2834,10 @@ function UploadViewProvider({ children, ...props }) {
|
|
|
2678
2834
|
const filesValidationMessage = invalidFiles && !isProcessing
|
|
2679
2835
|
? getFilesValidationMessage({ invalidFiles })
|
|
2680
2836
|
: undefined;
|
|
2837
|
+
const tableData = useResolveDataTable(UPLOAD_TABLE_KEYS, UPLOAD_TABLE_RESOLVERS, {
|
|
2838
|
+
items,
|
|
2839
|
+
props: { displayText, isProcessing, isMultipartUpload, onTaskRemove },
|
|
2840
|
+
});
|
|
2681
2841
|
return (React__namespace["default"].createElement(ControlsContextProvider, { data: {
|
|
2682
2842
|
actionCancelLabel,
|
|
2683
2843
|
actionDestinationLabel,
|
|
@@ -2701,13 +2861,7 @@ function UploadViewProvider({ children, ...props }) {
|
|
|
2701
2861
|
statusDisplayCompletedLabel,
|
|
2702
2862
|
statusDisplayFailedLabel,
|
|
2703
2863
|
statusDisplayQueuedLabel,
|
|
2704
|
-
tableData
|
|
2705
|
-
tasks,
|
|
2706
|
-
shouldDisplayProgress: true,
|
|
2707
|
-
displayText,
|
|
2708
|
-
isProcessing,
|
|
2709
|
-
onTaskRemove,
|
|
2710
|
-
}),
|
|
2864
|
+
tableData,
|
|
2711
2865
|
title,
|
|
2712
2866
|
}, onActionCancel: onActionCancel, onActionExit: onActionExit, onActionStart: onActionStart, onAddFiles: () => {
|
|
2713
2867
|
onSelectFiles('FILE');
|
|
@@ -2843,6 +2997,9 @@ const createEnhancedListHandler = (action) => {
|
|
|
2843
2997
|
};
|
|
2844
2998
|
};
|
|
2845
2999
|
|
|
3000
|
+
const DEFAULT_ACTION_CONCURRENCY = 4;
|
|
3001
|
+
const USE_LIST_ERROR_MESSAGE = '`useList` must be called from within `StorageBrowser.Provider`';
|
|
3002
|
+
|
|
2846
3003
|
const INITIAL_STATUS_COUNTS = {
|
|
2847
3004
|
CANCELED: 0,
|
|
2848
3005
|
COMPLETE: 0,
|
|
@@ -2873,8 +3030,8 @@ const QUEUED_TASK_BASE = {
|
|
|
2873
3030
|
status: 'QUEUED',
|
|
2874
3031
|
};
|
|
2875
3032
|
const isTaskHandlerInput = (input) => !!input.data;
|
|
2876
|
-
|
|
2877
|
-
const { concurrency, ...callbacks } = options ?? {};
|
|
3033
|
+
function useProcessTasks(handler, options) {
|
|
3034
|
+
const { concurrency, items, ...callbacks } = options ?? {};
|
|
2878
3035
|
const callbacksRef = React__namespace["default"].useRef(callbacks);
|
|
2879
3036
|
if (callbacks) {
|
|
2880
3037
|
callbacksRef.current = callbacks;
|
|
@@ -2900,6 +3057,7 @@ const useProcessTasks = (handler, items, options) => {
|
|
|
2900
3057
|
tasksRef.current.set(id, { ...task, ...next });
|
|
2901
3058
|
}
|
|
2902
3059
|
flush();
|
|
3060
|
+
return !next ? undefined : tasksRef.current.get(id);
|
|
2903
3061
|
}, [flush]);
|
|
2904
3062
|
const createTask = React__namespace["default"].useCallback((data) => {
|
|
2905
3063
|
const getTask = () => tasksRef.current.get(data.id);
|
|
@@ -2908,9 +3066,12 @@ const useProcessTasks = (handler, items, options) => {
|
|
|
2908
3066
|
const task = getTask();
|
|
2909
3067
|
if (!task || task?.status !== 'QUEUED')
|
|
2910
3068
|
return;
|
|
2911
|
-
|
|
2912
|
-
|
|
2913
|
-
|
|
3069
|
+
const canceledTask = updateTask(data.id, {
|
|
3070
|
+
cancel: undefined,
|
|
3071
|
+
status: 'CANCELED',
|
|
3072
|
+
});
|
|
3073
|
+
if (canceledTask && ui.isFunction(onTaskCancel))
|
|
3074
|
+
onTaskCancel(canceledTask);
|
|
2914
3075
|
}
|
|
2915
3076
|
const task = { ...QUEUED_TASK_BASE, cancel, data };
|
|
2916
3077
|
tasksRef.current.set(data.id, task);
|
|
@@ -2955,16 +3116,15 @@ const useProcessTasks = (handler, items, options) => {
|
|
|
2955
3116
|
const { onTaskCancel, onTaskComplete, onTaskError, onTaskProgress, onTaskSuccess, } = callbacksRef.current;
|
|
2956
3117
|
const getTask = () => tasksRef.current.get(data.id);
|
|
2957
3118
|
const { options } = _input;
|
|
2958
|
-
const { onProgress: _onProgress
|
|
3119
|
+
const { onProgress: _onProgress } = options ?? {};
|
|
2959
3120
|
const onProgress = ({ id }, progress) => {
|
|
2960
|
-
const task =
|
|
3121
|
+
const task = updateTask(id, { progress });
|
|
2961
3122
|
if (task && ui.isFunction(onTaskProgress)) {
|
|
2962
3123
|
onTaskProgress(task, progress);
|
|
2963
3124
|
}
|
|
2964
3125
|
if (task && ui.isFunction(_onProgress)) {
|
|
2965
3126
|
_onProgress(data, progress);
|
|
2966
3127
|
}
|
|
2967
|
-
updateTask(id, { progress });
|
|
2968
3128
|
};
|
|
2969
3129
|
const input = { ..._input, data, options: { ...options, onProgress } };
|
|
2970
3130
|
const { cancel: _cancel, result } = handler(input);
|
|
@@ -2978,21 +3138,16 @@ const useProcessTasks = (handler, items, options) => {
|
|
|
2978
3138
|
};
|
|
2979
3139
|
result
|
|
2980
3140
|
.then((output) => {
|
|
2981
|
-
const task =
|
|
2982
|
-
|
|
2983
|
-
|
|
2984
|
-
|
|
2985
|
-
if (task && ui.isFunction(onSuccess))
|
|
2986
|
-
onSuccess(data, output?.value);
|
|
2987
|
-
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);
|
|
2988
3145
|
})
|
|
2989
|
-
.catch((
|
|
2990
|
-
const
|
|
3146
|
+
.catch((error) => {
|
|
3147
|
+
const { message } = error;
|
|
3148
|
+
const task = updateTask(data.id, { message, status: 'FAILED' });
|
|
2991
3149
|
if (task && ui.isFunction(onTaskError))
|
|
2992
|
-
onTaskError(task,
|
|
2993
|
-
if (task && ui.isFunction(onError))
|
|
2994
|
-
onError(data, e?.message);
|
|
2995
|
-
updateTask(data.id, { message: e.message, status: 'FAILED' });
|
|
3150
|
+
onTaskError(task, error);
|
|
2996
3151
|
})
|
|
2997
3152
|
.finally(() => {
|
|
2998
3153
|
const task = getTask();
|
|
@@ -3030,52 +3185,54 @@ const useProcessTasks = (handler, items, options) => {
|
|
|
3030
3185
|
{ isProcessing, isProcessingComplete, reset, statusCounts, tasks },
|
|
3031
3186
|
handleProcessTasks,
|
|
3032
3187
|
];
|
|
3033
|
-
}
|
|
3034
|
-
|
|
3035
|
-
const DEFAULT_ACTION_CONCURRENCY = 4;
|
|
3036
|
-
const USE_LIST_ERROR_MESSAGE = '`useList` must be called from within `StorageBrowser.Provider`';
|
|
3188
|
+
}
|
|
3037
3189
|
|
|
3038
|
-
const
|
|
3039
|
-
const
|
|
3040
|
-
|
|
3041
|
-
const
|
|
3042
|
-
|
|
3043
|
-
|
|
3044
|
-
const [state, processTask] = useProcessTasks(action, items, {
|
|
3045
|
-
onTaskSuccess,
|
|
3046
|
-
...(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,
|
|
3047
3196
|
});
|
|
3048
|
-
const
|
|
3049
|
-
const
|
|
3050
|
-
|
|
3051
|
-
const config = getConfig(location
|
|
3052
|
-
|
|
3053
|
-
|
|
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)
|
|
3054
3204
|
reset();
|
|
3055
|
-
|
|
3056
|
-
|
|
3057
|
-
|
|
3058
|
-
|
|
3059
|
-
}, [
|
|
3060
|
-
|
|
3061
|
-
|
|
3062
|
-
|
|
3063
|
-
];
|
|
3064
|
-
}
|
|
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
|
+
}
|
|
3065
3215
|
|
|
3066
3216
|
const ERROR_MESSAGE = '`useAction` must be called from within `StorageBrowser.Provider`';
|
|
3067
|
-
|
|
3068
|
-
if (key === 'listLocations' ||
|
|
3069
|
-
key === 'listLocationItems') {
|
|
3217
|
+
function assertActionHandlerKey(key) {
|
|
3218
|
+
if (key === 'listLocations' || key === 'listLocationItems') {
|
|
3070
3219
|
throw new Error(`Value of \`${key}\` cannot be provided to \`useAction\``);
|
|
3071
3220
|
}
|
|
3072
|
-
|
|
3073
|
-
|
|
3074
|
-
if (
|
|
3221
|
+
}
|
|
3222
|
+
function assertActionHandler(handler, key) {
|
|
3223
|
+
if (typeof handler !== 'function') {
|
|
3075
3224
|
throw new Error(`No handler found for value of \`${key}\` provided to \`useAction\``);
|
|
3076
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);
|
|
3077
3232
|
return useHandler(handler, options);
|
|
3078
|
-
|
|
3233
|
+
// casting to allow usage of `UseAction` interface which ensures that
|
|
3234
|
+
// the `options` param receives the correct typing
|
|
3235
|
+
});
|
|
3079
3236
|
|
|
3080
3237
|
const useListLocations = () => {
|
|
3081
3238
|
const { handlers } = useActionHandlers({
|
|
@@ -3121,7 +3278,6 @@ const LIST_ACTION_HOOKS = {
|
|
|
3121
3278
|
locations: useListLocations,
|
|
3122
3279
|
};
|
|
3123
3280
|
const isListActionViewType = (value) => Object.keys(LIST_ACTION_HOOKS).includes(value);
|
|
3124
|
-
// @ts-expect-error
|
|
3125
3281
|
const useList = (type) => {
|
|
3126
3282
|
if (!isListActionViewType(type)) {
|
|
3127
3283
|
throw new Error(`Value of \`${type}\` cannot be used to index \`useList\``);
|
|
@@ -3487,16 +3643,12 @@ FoldersTableControl.displayName = 'FoldersTable';
|
|
|
3487
3643
|
|
|
3488
3644
|
function CopyViewProvider({ children, ...props }) {
|
|
3489
3645
|
const { CopyView: displayText } = useDisplayText();
|
|
3490
|
-
const { actionCancelLabel, actionDestinationLabel, actionExitLabel, actionStartLabel, getActionCompleteMessage, overwriteWarningMessage, searchPlaceholder, searchSubmitLabel, searchClearLabel, statusDisplayCanceledLabel, statusDisplayCompletedLabel, statusDisplayFailedLabel, statusDisplayQueuedLabel, } = displayText;
|
|
3491
|
-
const { destination, folders, isProcessing, isProcessingComplete,
|
|
3646
|
+
const { actionCancelLabel, actionDestinationLabel, actionExitLabel, actionStartLabel, getActionCompleteMessage, overwriteWarningMessage, searchPlaceholder, searchSubmitLabel, searchClearLabel, statusDisplayCanceledLabel, statusDisplayCompletedLabel, statusDisplayFailedLabel, statusDisplayQueuedLabel, title, } = displayText;
|
|
3647
|
+
const { destination, folders, isProcessing, isProcessingComplete, statusCounts, tasks: items, onActionCancel, onActionExit, onActionStart, onSelectDestination, onTaskRemove, } = props;
|
|
3492
3648
|
const { hasNextPage, highestPageVisited, hasError: hasFoldersError, message: foldersErrorMessage, query, hasExhaustedSearch, isLoading, page, pageItems, onPaginate, onQuery, onSearchClear, onSearch, onSelectFolder, } = folders;
|
|
3493
|
-
const
|
|
3494
|
-
|
|
3495
|
-
|
|
3496
|
-
locationKey,
|
|
3497
|
-
isProcessing,
|
|
3498
|
-
displayText,
|
|
3499
|
-
onTaskRemove,
|
|
3649
|
+
const tableData = useResolveDataTable(COPY_TABLE_KEYS, COPY_TABLE_RESOLVERS, {
|
|
3650
|
+
items,
|
|
3651
|
+
props: { displayText, isProcessing, onTaskRemove },
|
|
3500
3652
|
});
|
|
3501
3653
|
const isActionStartDisabled = isProcessing || isProcessingComplete || !destination?.current;
|
|
3502
3654
|
const isActionCancelDisabled = !isProcessing || isProcessingComplete;
|
|
@@ -3528,46 +3680,45 @@ function CopyViewProvider({ children, ...props }) {
|
|
|
3528
3680
|
statusDisplayFailedLabel,
|
|
3529
3681
|
statusDisplayQueuedLabel,
|
|
3530
3682
|
tableData,
|
|
3683
|
+
title,
|
|
3531
3684
|
}, onActionCancel: onActionCancel, onActionExit: onActionExit, onActionStart: onActionStart, onSearch: onSearch, onSearchClear: onSearchClear, onSearchQueryChange: onQuery, onSelectDestination: onSelectDestination },
|
|
3532
3685
|
React__namespace["default"].createElement(FoldersPaginationProvider, { hasNextPage: hasNextPage, highestPageVisited: highestPageVisited, page: page, onPaginate: onPaginate },
|
|
3533
3686
|
React__namespace["default"].createElement(FoldersTableProvider, { destination: destination, folders: pageItems, onSelectFolder: onSelectFolder },
|
|
3534
3687
|
React__namespace["default"].createElement(FoldersMessageProvider, { folders: folders.pageItems, hasError: hasFoldersError, message: foldersErrorMessage, query: query, hasExhaustedSearch: hasExhaustedSearch }, children)))));
|
|
3535
3688
|
}
|
|
3536
3689
|
|
|
3537
|
-
const
|
|
3538
|
-
|
|
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);
|
|
3539
3694
|
const handleReset = React__namespace["default"].useRef(() => {
|
|
3540
|
-
setCurrentPage(
|
|
3695
|
+
setCurrentPage(page);
|
|
3696
|
+
// set `visitedRef` to initially provided `page`
|
|
3697
|
+
visitedRef.current = page;
|
|
3541
3698
|
}).current;
|
|
3542
3699
|
return React__namespace["default"].useMemo(() => {
|
|
3543
|
-
const
|
|
3544
|
-
const highestPageVisited =
|
|
3700
|
+
const hasItems = Array.isArray(items);
|
|
3701
|
+
const highestPageVisited = visitedRef.current;
|
|
3545
3702
|
const isFirstPage = currentPage === 1;
|
|
3546
3703
|
const start = isFirstPage ? 0 : (currentPage - 1) * pageSize;
|
|
3547
3704
|
const end = isFirstPage ? pageSize : currentPage * pageSize;
|
|
3548
|
-
const pageItems =
|
|
3705
|
+
const pageItems = hasItems ? items.slice(start, end) : [];
|
|
3549
3706
|
return {
|
|
3550
3707
|
currentPage,
|
|
3551
|
-
|
|
3552
|
-
|
|
3553
|
-
|
|
3554
|
-
|
|
3555
|
-
|
|
3556
|
-
|
|
3557
|
-
|
|
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);
|
|
3558
3716
|
},
|
|
3559
3717
|
handleReset,
|
|
3560
3718
|
highestPageVisited,
|
|
3561
3719
|
pageItems,
|
|
3562
3720
|
};
|
|
3563
|
-
}, [
|
|
3564
|
-
currentPage,
|
|
3565
|
-
handleReset,
|
|
3566
|
-
hasNextToken,
|
|
3567
|
-
items,
|
|
3568
|
-
paginateCallback,
|
|
3569
|
-
pageSize,
|
|
3570
|
-
]);
|
|
3721
|
+
}, [currentPage, handleReset, items, onPaginate, pageSize]);
|
|
3571
3722
|
};
|
|
3572
3723
|
|
|
3573
3724
|
function useSearch(props) {
|
|
@@ -3612,20 +3763,19 @@ const useFolders = ({ destination, setDestination, }) => {
|
|
|
3612
3763
|
options: { ...DEFAULT_REFRESH_OPTIONS },
|
|
3613
3764
|
});
|
|
3614
3765
|
}, [handleList, key]);
|
|
3615
|
-
const
|
|
3616
|
-
const
|
|
3617
|
-
if (!
|
|
3766
|
+
const hasNextPage = !!nextToken;
|
|
3767
|
+
const onPaginate = () => {
|
|
3768
|
+
if (!hasNextPage)
|
|
3618
3769
|
return;
|
|
3619
3770
|
handleList({
|
|
3620
3771
|
prefix: key,
|
|
3621
3772
|
options: { ...DEFAULT_LIST_OPTIONS$2, nextToken },
|
|
3622
3773
|
});
|
|
3623
3774
|
};
|
|
3624
|
-
const { currentPage: page,
|
|
3775
|
+
const { currentPage: page, handlePaginate, highestPageVisited, pageItems, handleReset, } = usePaginate({
|
|
3625
3776
|
items,
|
|
3626
|
-
|
|
3777
|
+
onPaginate,
|
|
3627
3778
|
pageSize: DEFAULT_PAGE_SIZE$2,
|
|
3628
|
-
hasNextToken,
|
|
3629
3779
|
});
|
|
3630
3780
|
const onSearch = (query) => {
|
|
3631
3781
|
handleReset();
|
|
@@ -3651,7 +3801,7 @@ const useFolders = ({ destination, setDestination, }) => {
|
|
|
3651
3801
|
};
|
|
3652
3802
|
return {
|
|
3653
3803
|
hasError,
|
|
3654
|
-
hasNextPage
|
|
3804
|
+
hasNextPage,
|
|
3655
3805
|
highestPageVisited,
|
|
3656
3806
|
isLoading,
|
|
3657
3807
|
message,
|
|
@@ -3660,7 +3810,7 @@ const useFolders = ({ destination, setDestination, }) => {
|
|
|
3660
3810
|
pageItems,
|
|
3661
3811
|
query,
|
|
3662
3812
|
hasExhaustedSearch,
|
|
3663
|
-
onPaginate,
|
|
3813
|
+
onPaginate: handlePaginate,
|
|
3664
3814
|
onQuery,
|
|
3665
3815
|
onSearch: onSearchSubmit,
|
|
3666
3816
|
onSearchClear: () => {
|
|
@@ -3796,16 +3946,13 @@ CopyView.Title = TitleControl;
|
|
|
3796
3946
|
function DeleteViewProvider({ children, ...props }) {
|
|
3797
3947
|
const { DeleteView: displayText } = useDisplayText();
|
|
3798
3948
|
const { actionCancelLabel, actionExitLabel, actionStartLabel, title, statusDisplayCanceledLabel, statusDisplayCompletedLabel, statusDisplayFailedLabel, statusDisplayQueuedLabel, getActionCompleteMessage, } = displayText;
|
|
3799
|
-
const { isProcessing, isProcessingComplete,
|
|
3949
|
+
const { isProcessing, isProcessingComplete, statusCounts, tasks: items, onActionCancel, onActionStart, onActionExit, onTaskRemove, } = props;
|
|
3800
3950
|
const message = isProcessingComplete
|
|
3801
3951
|
? getActionCompleteMessage({ counts: statusCounts })
|
|
3802
3952
|
: undefined;
|
|
3803
|
-
const tableData =
|
|
3804
|
-
|
|
3805
|
-
|
|
3806
|
-
isProcessing,
|
|
3807
|
-
displayText,
|
|
3808
|
-
onTaskRemove,
|
|
3953
|
+
const tableData = useResolveDataTable(DELETE_TABLE_KEYS, DELETE_TABLE_RESOLVERS, {
|
|
3954
|
+
items,
|
|
3955
|
+
props: { displayText, isProcessing, onTaskRemove },
|
|
3809
3956
|
});
|
|
3810
3957
|
return (React__namespace["default"].createElement(ControlsContextProvider, { data: {
|
|
3811
3958
|
actionCancelLabel,
|
|
@@ -3825,18 +3972,14 @@ function DeleteViewProvider({ children, ...props }) {
|
|
|
3825
3972
|
}, onActionStart: onActionStart, onActionExit: onActionExit, onActionCancel: onActionCancel }, children));
|
|
3826
3973
|
}
|
|
3827
3974
|
|
|
3975
|
+
// assign to constant to ensure referential equality
|
|
3976
|
+
const EMPTY_ITEMS = [];
|
|
3828
3977
|
const useDeleteView = (options) => {
|
|
3829
3978
|
const { onExit: _onExit } = options ?? {};
|
|
3830
3979
|
const [{ location, locationItems }, dispatchStoreAction] = useStore();
|
|
3831
|
-
const {
|
|
3832
|
-
const {
|
|
3833
|
-
const
|
|
3834
|
-
? []
|
|
3835
|
-
: fileDataItems.map((item) => ({
|
|
3836
|
-
...item,
|
|
3837
|
-
key: `${key}${item.fileKey}`,
|
|
3838
|
-
})), [fileDataItems, key]);
|
|
3839
|
-
const [processState, handleProcess] = useAction('delete', { items: data });
|
|
3980
|
+
const { current } = location;
|
|
3981
|
+
const { fileDataItems: items = EMPTY_ITEMS } = locationItems;
|
|
3982
|
+
const [processState, handleProcess] = useAction('delete', { items });
|
|
3840
3983
|
const { isProcessing, isProcessingComplete, statusCounts, tasks } = processState;
|
|
3841
3984
|
const onActionStart = () => {
|
|
3842
3985
|
if (!current)
|
|
@@ -4034,8 +4177,7 @@ const useLocationDetailView = (options) => {
|
|
|
4034
4177
|
// set up pagination
|
|
4035
4178
|
const { items, nextToken, search } = data;
|
|
4036
4179
|
const { hasExhaustedSearch = false } = search ?? {};
|
|
4037
|
-
const
|
|
4038
|
-
const paginateCallback = () => {
|
|
4180
|
+
const onPaginate = () => {
|
|
4039
4181
|
if (hasInvalidPrefix || !nextToken)
|
|
4040
4182
|
return;
|
|
4041
4183
|
dispatchStoreAction({ type: 'RESET_LOCATION_ITEMS' });
|
|
@@ -4044,11 +4186,10 @@ const useLocationDetailView = (options) => {
|
|
|
4044
4186
|
options: { ...listOptions, nextToken },
|
|
4045
4187
|
});
|
|
4046
4188
|
};
|
|
4047
|
-
const { currentPage,
|
|
4189
|
+
const { currentPage, handlePaginate, handleReset, highestPageVisited, pageItems, } = usePaginate({
|
|
4048
4190
|
items,
|
|
4049
|
-
|
|
4191
|
+
onPaginate,
|
|
4050
4192
|
pageSize: listOptions.pageSize,
|
|
4051
|
-
hasNextToken,
|
|
4052
4193
|
});
|
|
4053
4194
|
const onSearch = (query, includeSubfolders) => {
|
|
4054
4195
|
if (hasInvalidPrefix)
|
|
@@ -4116,13 +4257,13 @@ const useLocationDetailView = (options) => {
|
|
|
4116
4257
|
fileDataItems,
|
|
4117
4258
|
hasError,
|
|
4118
4259
|
hasDownloadError: task?.status === 'FAILED',
|
|
4119
|
-
hasNextPage:
|
|
4260
|
+
hasNextPage: !!nextToken,
|
|
4120
4261
|
highestPageVisited,
|
|
4121
4262
|
message,
|
|
4122
4263
|
downloadErrorMessage: getDownloadErrorMessageFromFailedDownloadTask(task),
|
|
4123
4264
|
isLoading,
|
|
4124
4265
|
isSearchSubfoldersEnabled,
|
|
4125
|
-
onPaginate,
|
|
4266
|
+
onPaginate: handlePaginate,
|
|
4126
4267
|
searchQuery,
|
|
4127
4268
|
hasExhaustedSearch,
|
|
4128
4269
|
onRefresh,
|
|
@@ -4178,10 +4319,7 @@ const useLocationDetailView = (options) => {
|
|
|
4178
4319
|
resetSearch();
|
|
4179
4320
|
if (hasInvalidPrefix)
|
|
4180
4321
|
return;
|
|
4181
|
-
handleList({
|
|
4182
|
-
prefix: key,
|
|
4183
|
-
options: { ...listOptions, refresh: true },
|
|
4184
|
-
});
|
|
4322
|
+
handleList({ prefix: key, options: { ...listOptions, refresh: true } });
|
|
4185
4323
|
handleReset();
|
|
4186
4324
|
},
|
|
4187
4325
|
onSearchQueryChange,
|
|
@@ -4688,16 +4826,15 @@ const useLocationsView = (options) => {
|
|
|
4688
4826
|
handleList({ options: { ...listOptions, refresh: true } });
|
|
4689
4827
|
}, [handleList, listOptions]);
|
|
4690
4828
|
// set up pagination
|
|
4691
|
-
const
|
|
4829
|
+
const onPaginate = () => {
|
|
4692
4830
|
if (!nextToken)
|
|
4693
4831
|
return;
|
|
4694
4832
|
handleList({ options: { ...listOptions, nextToken } });
|
|
4695
4833
|
};
|
|
4696
|
-
const { currentPage,
|
|
4834
|
+
const { currentPage, handlePaginate, handleReset, highestPageVisited, pageItems, } = usePaginate({
|
|
4697
4835
|
items,
|
|
4698
|
-
|
|
4836
|
+
onPaginate,
|
|
4699
4837
|
pageSize: listOptions.pageSize,
|
|
4700
|
-
hasNextToken,
|
|
4701
4838
|
});
|
|
4702
4839
|
const onSearch = (query) => {
|
|
4703
4840
|
handleReset();
|
|
@@ -4744,7 +4881,7 @@ const useLocationsView = (options) => {
|
|
|
4744
4881
|
handleReset();
|
|
4745
4882
|
handleList({ options: { ...listOptions, refresh: true } });
|
|
4746
4883
|
},
|
|
4747
|
-
onPaginate,
|
|
4884
|
+
onPaginate: handlePaginate,
|
|
4748
4885
|
onSearch: onSearchSubmit,
|
|
4749
4886
|
onSearchQueryChange,
|
|
4750
4887
|
onSearchClear: () => {
|
|
@@ -4808,7 +4945,10 @@ const getViews = (views, customConfigs) => {
|
|
|
4808
4945
|
// ignore custom actions that are only handlers
|
|
4809
4946
|
return !ui.isObject(config) || ui.isFunction(config)
|
|
4810
4947
|
? acc
|
|
4811
|
-
: {
|
|
4948
|
+
: {
|
|
4949
|
+
...acc,
|
|
4950
|
+
[key]: views?.[config.viewName],
|
|
4951
|
+
};
|
|
4812
4952
|
}, {});
|
|
4813
4953
|
return {
|
|
4814
4954
|
action: { ...resolvedDefaultActionViews, ...customActionViews },
|
|
@@ -4833,7 +4973,7 @@ function useViews() {
|
|
|
4833
4973
|
};
|
|
4834
4974
|
}
|
|
4835
4975
|
|
|
4836
|
-
const
|
|
4976
|
+
const USE_VIEW_HOOKS = {
|
|
4837
4977
|
Copy: useCopyView,
|
|
4838
4978
|
CreateFolder: useCreateFolderView,
|
|
4839
4979
|
Delete: useDeleteView,
|
|
@@ -4841,13 +4981,12 @@ const DEFAULT_VIEW_HOOKS = {
|
|
|
4841
4981
|
Locations: useLocationsView,
|
|
4842
4982
|
Upload: useUploadView,
|
|
4843
4983
|
};
|
|
4844
|
-
const isUseViewType = (value) => !!
|
|
4845
|
-
// @ts-expect-error
|
|
4984
|
+
const isUseViewType = (value) => !!USE_VIEW_HOOKS?.[value];
|
|
4846
4985
|
const useView = (type) => {
|
|
4847
4986
|
if (!isUseViewType(type)) {
|
|
4848
4987
|
throw new Error(`Value of \`${type}\` cannot be used to index \`useView\``);
|
|
4849
4988
|
}
|
|
4850
|
-
return
|
|
4989
|
+
return USE_VIEW_HOOKS[type]();
|
|
4851
4990
|
};
|
|
4852
4991
|
|
|
4853
4992
|
/**
|
|
@@ -4870,6 +5009,12 @@ function StorageBrowserDefault() {
|
|
|
4870
5009
|
return React__namespace["default"].createElement(LocationsView, null);
|
|
4871
5010
|
}
|
|
4872
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
|
+
*/
|
|
4873
5018
|
function createStorageBrowser(input) {
|
|
4874
5019
|
assertRegisterAuthListener(input.config.registerAuthListener);
|
|
4875
5020
|
const { accountId, customEndpoint, registerAuthListener, getLocationCredentials, region, } = input.config;
|
|
@@ -5071,5 +5216,7 @@ exports.VERSION = VERSION;
|
|
|
5071
5216
|
exports.componentsDefault = componentsDefault;
|
|
5072
5217
|
exports.createAmplifyAuthAdapter = createAmplifyAuthAdapter;
|
|
5073
5218
|
exports.createStorageBrowser = createStorageBrowser;
|
|
5219
|
+
exports.defaultActionConfigs = defaultActionConfigs;
|
|
5220
|
+
exports.defaultHandlers = defaultHandlers;
|
|
5074
5221
|
exports.getFilteredLocations = getFilteredLocations;
|
|
5075
5222
|
exports.toAccessGrantPermission = toAccessGrantPermission;
|