@scality/data-browser-library 1.0.0-preview.11 → 1.0.0-preview.13
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/components/DataBrowserUI.d.ts +20 -0
- package/dist/components/DataBrowserUI.js +64 -0
- package/dist/components/__tests__/BucketDetails.test.d.ts +1 -0
- package/dist/components/__tests__/BucketDetails.test.js +421 -0
- package/dist/components/__tests__/BucketList.test.js +389 -164
- package/dist/components/__tests__/BucketOverview.test.js +19 -63
- package/dist/components/__tests__/ObjectList.test.js +719 -219
- package/dist/components/buckets/BucketDetails.d.ts +40 -0
- package/dist/components/buckets/BucketDetails.js +194 -86
- package/dist/components/buckets/BucketList.d.ts +5 -6
- package/dist/components/buckets/BucketList.js +152 -97
- package/dist/components/buckets/BucketOverview.d.ts +6 -0
- package/dist/components/buckets/BucketOverview.js +363 -179
- package/dist/components/buckets/BucketPage.js +1 -5
- package/dist/components/buckets/BucketVersioning.js +3 -0
- package/dist/components/buckets/EmptyBucketButton.js +1 -1
- package/dist/components/index.d.ts +2 -1
- package/dist/components/index.js +2 -1
- package/dist/components/layouts/ArrowNavigation.js +20 -8
- package/dist/components/objects/CreateFolderButton.js +1 -1
- package/dist/components/objects/ObjectDetails/ObjectSummary.js +287 -157
- package/dist/components/objects/ObjectDetails/__tests__/ObjectDetails.test.d.ts +1 -0
- package/dist/components/objects/ObjectDetails/__tests__/ObjectDetails.test.js +516 -0
- package/dist/components/objects/ObjectDetails/__tests__/ObjectSummary.test.d.ts +1 -0
- package/dist/components/objects/ObjectDetails/__tests__/ObjectSummary.test.js +813 -0
- package/dist/components/objects/ObjectDetails/index.d.ts +16 -0
- package/dist/components/objects/ObjectDetails/index.js +132 -46
- package/dist/components/objects/ObjectList.d.ts +7 -5
- package/dist/components/objects/ObjectList.js +566 -286
- package/dist/components/objects/UploadButton.js +1 -1
- package/dist/config/types.d.ts +117 -0
- package/dist/contexts/DataBrowserUICustomizationContext.d.ts +27 -0
- package/dist/contexts/DataBrowserUICustomizationContext.js +13 -0
- package/dist/test/testUtils.d.ts +64 -0
- package/dist/test/testUtils.js +100 -1
- package/dist/types/index.d.ts +5 -3
- package/dist/utils/constants.d.ts +7 -0
- package/dist/utils/constants.js +8 -1
- package/dist/utils/useFeatures.js +1 -1
- package/package.json +2 -2
|
@@ -1,8 +1,11 @@
|
|
|
1
1
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
2
|
-
import { ConstrainedText, FormattedDateTime, Icon, Link, PrettyBytes, Text, Toggle, Wrap, spacing } from "@scality/core-ui";
|
|
2
|
+
import { ConstrainedText, FormattedDateTime, Icon, Link, PrettyBytes, Text, Toggle, Wrap, spacing, useToast } from "@scality/core-ui";
|
|
3
3
|
import { Box, Table } from "@scality/core-ui/dist/next";
|
|
4
|
-
import { useCallback, useEffect, useMemo, useState } from "react";
|
|
4
|
+
import { Fragment, useCallback, useEffect, useMemo, useRef, useState } from "react";
|
|
5
|
+
import { useQueryClient } from "@tanstack/react-query";
|
|
6
|
+
import { useDataBrowserUICustomization } from "../../contexts/DataBrowserUICustomizationContext.js";
|
|
5
7
|
import { useSearchObjects, useSearchObjectsVersions } from "../../hooks/index.js";
|
|
8
|
+
import { useGetPresignedDownload } from "../../hooks/presignedOperations.js";
|
|
6
9
|
import { useBatchObjectLegalHold } from "../../hooks/useBatchObjectLegalHold.js";
|
|
7
10
|
import { useQueryParams } from "../../utils/hooks.js";
|
|
8
11
|
import { useFeatures } from "../../utils/useFeatures.js";
|
|
@@ -11,16 +14,305 @@ import MetadataSearch from "../search/MetadataSearch.js";
|
|
|
11
14
|
import UploadButton from "./UploadButton.js";
|
|
12
15
|
import DeleteObjectButton from "./DeleteObjectButton.js";
|
|
13
16
|
const DEFAULT_PAGE_SIZE = 20;
|
|
17
|
+
const SEARCH_QUERY_PARAM = "search";
|
|
18
|
+
const NAME_COLUMN_FLEX = "2";
|
|
19
|
+
const VERSION_ID_COLUMN_FLEX = "1.5";
|
|
20
|
+
const LAST_MODIFIED_COLUMN_FLEX = "1";
|
|
21
|
+
const SIZE_COLUMN_FLEX = "1";
|
|
22
|
+
const STORAGE_CLASS_COLUMN_FLEX = "1";
|
|
23
|
+
const isObjectLike = (item)=>"folder" !== item.type;
|
|
14
24
|
const getVersionTextColor = (row)=>{
|
|
15
25
|
const isLatest = row.original.IsLatest;
|
|
16
26
|
const isVersion = "version" === row.original.type;
|
|
17
27
|
return !isLatest && isVersion ? "infoPrimary" : "textPrimary";
|
|
18
28
|
};
|
|
29
|
+
const removePrefix = (path, prefix)=>{
|
|
30
|
+
if (!prefix) return path;
|
|
31
|
+
if (path.startsWith(prefix)) return path.slice(prefix.length);
|
|
32
|
+
return path;
|
|
33
|
+
};
|
|
34
|
+
const createLegalHoldKey = (key, versionId)=>`${key}:${versionId ?? "null"}`;
|
|
35
|
+
const downloadFile = (url, filename, onCleanup)=>{
|
|
36
|
+
try {
|
|
37
|
+
new URL(url);
|
|
38
|
+
const link = document.createElement("a");
|
|
39
|
+
link.href = url;
|
|
40
|
+
link.download = filename;
|
|
41
|
+
link.style.display = "none";
|
|
42
|
+
link.rel = "noopener noreferrer";
|
|
43
|
+
document.body.appendChild(link);
|
|
44
|
+
link.click();
|
|
45
|
+
const timeoutId = setTimeout(()=>{
|
|
46
|
+
if (document.body.contains(link)) document.body.removeChild(link);
|
|
47
|
+
}, 100);
|
|
48
|
+
onCleanup?.(timeoutId);
|
|
49
|
+
} catch (error) {
|
|
50
|
+
console.error("Invalid download URL:", url, error);
|
|
51
|
+
throw new Error("Failed to initiate download: Invalid URL");
|
|
52
|
+
}
|
|
53
|
+
};
|
|
54
|
+
const createNameColumn = (onPrefixChange, onDownload)=>({
|
|
55
|
+
Header: "Name",
|
|
56
|
+
accessor: "displayName",
|
|
57
|
+
id: "name",
|
|
58
|
+
sortType: (rowA, rowB)=>{
|
|
59
|
+
const aIsFolder = "folder" === rowA.original.type;
|
|
60
|
+
const bIsFolder = "folder" === rowB.original.type;
|
|
61
|
+
if (aIsFolder && !bIsFolder) return -1;
|
|
62
|
+
if (!aIsFolder && bIsFolder) return 1;
|
|
63
|
+
const aName = String(rowA.values.displayName || "");
|
|
64
|
+
const bName = String(rowB.values.displayName || "");
|
|
65
|
+
return aName.localeCompare(bName, "en", {
|
|
66
|
+
sensitivity: "base"
|
|
67
|
+
});
|
|
68
|
+
},
|
|
69
|
+
Cell: ({ value, row })=>{
|
|
70
|
+
const isFolder = "folder" === row.original.type;
|
|
71
|
+
const isVersion = "version" === row.original.type;
|
|
72
|
+
const isDeleteMarker = "deleteMarker" === row.original.type;
|
|
73
|
+
const isLatest = row.original.IsLatest;
|
|
74
|
+
let iconName;
|
|
75
|
+
iconName = isFolder ? "Folder" : isDeleteMarker ? "Deletion-marker" : "File";
|
|
76
|
+
const shouldIndent = isVersion && !isLatest;
|
|
77
|
+
const isLegalHoldEnabled = isObjectLike(row.original) && Boolean(row.original.isLegalHoldEnabled);
|
|
78
|
+
return /*#__PURE__*/ jsx(ConstrainedText, {
|
|
79
|
+
text: /*#__PURE__*/ jsxs(Box, {
|
|
80
|
+
display: "flex",
|
|
81
|
+
alignItems: "center",
|
|
82
|
+
gap: spacing.r8,
|
|
83
|
+
paddingLeft: shouldIndent ? spacing.r24 : 0,
|
|
84
|
+
children: [
|
|
85
|
+
/*#__PURE__*/ jsx(Icon, {
|
|
86
|
+
name: iconName,
|
|
87
|
+
size: "sm",
|
|
88
|
+
color: getVersionTextColor(row)
|
|
89
|
+
}),
|
|
90
|
+
isLegalHoldEnabled && /*#__PURE__*/ jsx(Icon, {
|
|
91
|
+
name: "Rebalance",
|
|
92
|
+
size: "sm",
|
|
93
|
+
color: getVersionTextColor(row)
|
|
94
|
+
}),
|
|
95
|
+
isDeleteMarker ? /*#__PURE__*/ jsx(Text, {
|
|
96
|
+
color: getVersionTextColor(row),
|
|
97
|
+
children: value
|
|
98
|
+
}) : /*#__PURE__*/ jsx(Text, {
|
|
99
|
+
color: getVersionTextColor(row),
|
|
100
|
+
children: /*#__PURE__*/ jsx(Link, {
|
|
101
|
+
onClick: (e)=>{
|
|
102
|
+
e.stopPropagation();
|
|
103
|
+
if (isFolder) onPrefixChange?.(row.original.Key ?? "");
|
|
104
|
+
else onDownload?.(row.original);
|
|
105
|
+
},
|
|
106
|
+
children: value
|
|
107
|
+
})
|
|
108
|
+
})
|
|
109
|
+
]
|
|
110
|
+
}),
|
|
111
|
+
lineClamp: 2
|
|
112
|
+
});
|
|
113
|
+
},
|
|
114
|
+
cellStyle: {
|
|
115
|
+
flex: NAME_COLUMN_FLEX,
|
|
116
|
+
width: "unset"
|
|
117
|
+
}
|
|
118
|
+
});
|
|
119
|
+
const createVersionIdColumn = ()=>({
|
|
120
|
+
Header: "Version ID",
|
|
121
|
+
accessor: "VersionId",
|
|
122
|
+
id: "versionId",
|
|
123
|
+
Cell: ({ row })=>{
|
|
124
|
+
const isFolder = "folder" === row.original.type;
|
|
125
|
+
const isDeleteMarker = "deleteMarker" === row.original.type;
|
|
126
|
+
const isLatest = row.original.IsLatest;
|
|
127
|
+
if (isFolder || isDeleteMarker) return /*#__PURE__*/ jsx(Text, {
|
|
128
|
+
children: "-"
|
|
129
|
+
});
|
|
130
|
+
const versionId = "version" === row.original.type ? row.original.VersionId ?? "-" : "-";
|
|
131
|
+
const textColor = isLatest ? void 0 : "infoPrimary";
|
|
132
|
+
return /*#__PURE__*/ jsx(ConstrainedText, {
|
|
133
|
+
text: versionId,
|
|
134
|
+
lineClamp: 1,
|
|
135
|
+
color: textColor
|
|
136
|
+
});
|
|
137
|
+
},
|
|
138
|
+
cellStyle: {
|
|
139
|
+
flex: VERSION_ID_COLUMN_FLEX,
|
|
140
|
+
textAlign: "left",
|
|
141
|
+
paddingRight: spacing.r16,
|
|
142
|
+
width: "unset",
|
|
143
|
+
maxWidth: "8rem"
|
|
144
|
+
}
|
|
145
|
+
});
|
|
146
|
+
const createLastModifiedColumn = ()=>({
|
|
147
|
+
Header: "Modified on",
|
|
148
|
+
accessor: "LastModified",
|
|
149
|
+
id: "lastModified",
|
|
150
|
+
Cell: ({ value, row })=>{
|
|
151
|
+
if ("folder" === row.original.type || null == value) return /*#__PURE__*/ jsx(Text, {
|
|
152
|
+
children: "-"
|
|
153
|
+
});
|
|
154
|
+
return /*#__PURE__*/ jsx(Text, {
|
|
155
|
+
color: getVersionTextColor(row),
|
|
156
|
+
children: /*#__PURE__*/ jsx(FormattedDateTime, {
|
|
157
|
+
format: "date-time-second",
|
|
158
|
+
value: new Date(value)
|
|
159
|
+
})
|
|
160
|
+
});
|
|
161
|
+
},
|
|
162
|
+
cellStyle: {
|
|
163
|
+
flex: LAST_MODIFIED_COLUMN_FLEX,
|
|
164
|
+
textAlign: "right",
|
|
165
|
+
paddingRight: spacing.r16,
|
|
166
|
+
width: "unset",
|
|
167
|
+
minWidth: "10rem"
|
|
168
|
+
}
|
|
169
|
+
});
|
|
170
|
+
const createSizeColumn = ()=>({
|
|
171
|
+
Header: "Size",
|
|
172
|
+
accessor: "Size",
|
|
173
|
+
id: "size",
|
|
174
|
+
Cell: ({ value, row })=>{
|
|
175
|
+
if ("folder" === row.original.type || null == value) return /*#__PURE__*/ jsx(Text, {
|
|
176
|
+
children: "-"
|
|
177
|
+
});
|
|
178
|
+
return /*#__PURE__*/ jsx(Box, {
|
|
179
|
+
display: "flex",
|
|
180
|
+
justifyContent: "flex-end",
|
|
181
|
+
children: /*#__PURE__*/ jsx(Text, {
|
|
182
|
+
color: getVersionTextColor(row),
|
|
183
|
+
children: /*#__PURE__*/ jsx(PrettyBytes, {
|
|
184
|
+
bytes: value,
|
|
185
|
+
decimals: 2
|
|
186
|
+
})
|
|
187
|
+
})
|
|
188
|
+
});
|
|
189
|
+
},
|
|
190
|
+
cellStyle: {
|
|
191
|
+
flex: SIZE_COLUMN_FLEX,
|
|
192
|
+
textAlign: "right",
|
|
193
|
+
paddingRight: spacing.r16,
|
|
194
|
+
width: "unset"
|
|
195
|
+
}
|
|
196
|
+
});
|
|
197
|
+
const createStorageClassColumn = ()=>({
|
|
198
|
+
Header: "Storage Location",
|
|
199
|
+
accessor: "StorageClass",
|
|
200
|
+
id: "storageClass",
|
|
201
|
+
Cell: ({ value, row })=>{
|
|
202
|
+
if (null == value) return /*#__PURE__*/ jsx(Text, {
|
|
203
|
+
children: "-"
|
|
204
|
+
});
|
|
205
|
+
return /*#__PURE__*/ jsx(Box, {
|
|
206
|
+
display: "flex",
|
|
207
|
+
justifyContent: "flex-end",
|
|
208
|
+
children: /*#__PURE__*/ jsx(Text, {
|
|
209
|
+
color: getVersionTextColor(row),
|
|
210
|
+
children: "STANDARD" === value ? "default" : value
|
|
211
|
+
})
|
|
212
|
+
});
|
|
213
|
+
},
|
|
214
|
+
cellStyle: {
|
|
215
|
+
flex: STORAGE_CLASS_COLUMN_FLEX,
|
|
216
|
+
textAlign: "right",
|
|
217
|
+
paddingRight: spacing.r16,
|
|
218
|
+
width: "unset"
|
|
219
|
+
}
|
|
220
|
+
});
|
|
221
|
+
const buildCustomColumn = (columnConfig)=>({
|
|
222
|
+
Header: columnConfig.header,
|
|
223
|
+
id: String(columnConfig.id),
|
|
224
|
+
Cell: ({ row })=>{
|
|
225
|
+
const RenderComponent = columnConfig.render;
|
|
226
|
+
return /*#__PURE__*/ jsx(RenderComponent, {
|
|
227
|
+
data: row.original
|
|
228
|
+
});
|
|
229
|
+
},
|
|
230
|
+
cellStyle: {
|
|
231
|
+
width: columnConfig.width ?? "unset",
|
|
232
|
+
flex: columnConfig.width ? void 0 : "1"
|
|
233
|
+
}
|
|
234
|
+
});
|
|
235
|
+
function createOverrideMap(customItems) {
|
|
236
|
+
return new Map(customItems.filter((item)=>item.id).map((item)=>[
|
|
237
|
+
String(item.id),
|
|
238
|
+
item
|
|
239
|
+
]));
|
|
240
|
+
}
|
|
19
241
|
const ObjectList = ({ bucketName, prefix, onObjectSelect, onPrefixChange })=>{
|
|
242
|
+
const { extraObjectListColumns, extraObjectListActions } = useDataBrowserUICustomization();
|
|
243
|
+
const queryClient = useQueryClient();
|
|
20
244
|
const [showVersions, setShowVersions] = useState(false);
|
|
21
245
|
const isMetadataSearchEnabled = useFeatures("metadatasearch");
|
|
22
246
|
const metadataSearchQuery = useQueryParams().get("metadatasearch");
|
|
23
247
|
const [selectedObjects, setSelectedObjects] = useState([]);
|
|
248
|
+
const { mutateAsync: getPresignedDownload } = useGetPresignedDownload();
|
|
249
|
+
const downloadingRef = useRef(new Set());
|
|
250
|
+
const downloadTimeoutsRef = useRef(new Map());
|
|
251
|
+
const { showToast } = useToast();
|
|
252
|
+
const onObjectSelectRef = useRef(onObjectSelect);
|
|
253
|
+
const onPrefixChangeRef = useRef(onPrefixChange);
|
|
254
|
+
useEffect(()=>{
|
|
255
|
+
onObjectSelectRef.current = onObjectSelect;
|
|
256
|
+
}, [
|
|
257
|
+
onObjectSelect
|
|
258
|
+
]);
|
|
259
|
+
useEffect(()=>{
|
|
260
|
+
onPrefixChangeRef.current = onPrefixChange;
|
|
261
|
+
}, [
|
|
262
|
+
onPrefixChange
|
|
263
|
+
]);
|
|
264
|
+
useEffect(()=>()=>{
|
|
265
|
+
downloadTimeoutsRef.current.forEach((timeout)=>clearTimeout(timeout));
|
|
266
|
+
downloadTimeoutsRef.current.clear();
|
|
267
|
+
}, []);
|
|
268
|
+
const handleObjectSelect = useCallback((object)=>{
|
|
269
|
+
onObjectSelectRef.current(object);
|
|
270
|
+
}, []);
|
|
271
|
+
const handlePrefixChange = useCallback((newPrefix)=>{
|
|
272
|
+
onPrefixChangeRef.current(newPrefix);
|
|
273
|
+
}, []);
|
|
274
|
+
const handleDownload = useCallback(async (object)=>{
|
|
275
|
+
if (!object.Key) return void console.warn("Cannot download object: missing Key");
|
|
276
|
+
const versionId = isObjectLike(object) ? object.VersionId : void 0;
|
|
277
|
+
const downloadKey = versionId ? `${object.Key}:${versionId}` : object.Key;
|
|
278
|
+
if (downloadingRef.current.has(downloadKey)) return void console.debug(`Download already in progress for: ${object.Key}`);
|
|
279
|
+
downloadingRef.current.add(downloadKey);
|
|
280
|
+
try {
|
|
281
|
+
const rawFilename = object.displayName || object.Key.split("/").pop() || "download";
|
|
282
|
+
const sanitized = rawFilename.replace(/["\r\n\t]/g, "");
|
|
283
|
+
const encoded = encodeURIComponent(sanitized);
|
|
284
|
+
const result = await getPresignedDownload({
|
|
285
|
+
Bucket: bucketName,
|
|
286
|
+
Key: object.Key,
|
|
287
|
+
ResponseContentDisposition: `attachment; filename="${sanitized}"; filename*=UTF-8''${encoded}`,
|
|
288
|
+
...versionId ? {
|
|
289
|
+
VersionId: versionId
|
|
290
|
+
} : {}
|
|
291
|
+
});
|
|
292
|
+
if (!result?.Url) throw new Error("Failed to generate presigned URL: No URL returned");
|
|
293
|
+
downloadFile(result.Url, sanitized, (timeoutId)=>{
|
|
294
|
+
downloadTimeoutsRef.current.set(`${downloadKey}_link`, timeoutId);
|
|
295
|
+
});
|
|
296
|
+
} catch (error) {
|
|
297
|
+
const errorMessage = error instanceof Error ? error.message : "Unknown error";
|
|
298
|
+
showToast({
|
|
299
|
+
open: true,
|
|
300
|
+
message: errorMessage,
|
|
301
|
+
status: "error"
|
|
302
|
+
});
|
|
303
|
+
} finally{
|
|
304
|
+
const timeoutId = setTimeout(()=>{
|
|
305
|
+
downloadingRef.current.delete(downloadKey);
|
|
306
|
+
downloadTimeoutsRef.current.delete(downloadKey);
|
|
307
|
+
downloadTimeoutsRef.current.delete(`${downloadKey}_link`);
|
|
308
|
+
}, 1000);
|
|
309
|
+
downloadTimeoutsRef.current.set(downloadKey, timeoutId);
|
|
310
|
+
}
|
|
311
|
+
}, [
|
|
312
|
+
bucketName,
|
|
313
|
+
getPresignedDownload,
|
|
314
|
+
showToast
|
|
315
|
+
]);
|
|
24
316
|
const searchParams = useMemo(()=>{
|
|
25
317
|
const baseParams = {
|
|
26
318
|
Bucket: bucketName,
|
|
@@ -40,72 +332,121 @@ const ObjectList = ({ bucketName, prefix, onObjectSelect, onPrefixChange })=>{
|
|
|
40
332
|
metadataSearchQuery
|
|
41
333
|
]);
|
|
42
334
|
const listObjectsQuery = useSearchObjects(searchParams, {
|
|
43
|
-
enabled:
|
|
335
|
+
enabled: Boolean(bucketName)
|
|
44
336
|
});
|
|
45
|
-
const
|
|
46
|
-
|
|
337
|
+
const versionSearchParams = useMemo(()=>({
|
|
338
|
+
Bucket: bucketName,
|
|
339
|
+
Prefix: prefix,
|
|
340
|
+
MaxKeys: DEFAULT_PAGE_SIZE
|
|
341
|
+
}), [
|
|
342
|
+
bucketName,
|
|
343
|
+
prefix
|
|
344
|
+
]);
|
|
345
|
+
const listVersionsQuery = useSearchObjectsVersions(versionSearchParams, {
|
|
346
|
+
enabled: showVersions && Boolean(bucketName)
|
|
47
347
|
});
|
|
48
|
-
const activeQuery = showVersions ? listVersionsQuery : listObjectsQuery;
|
|
49
348
|
useEffect(()=>{
|
|
50
349
|
setSelectedObjects([]);
|
|
51
350
|
}, [
|
|
52
351
|
prefix,
|
|
53
352
|
showVersions
|
|
54
353
|
]);
|
|
55
|
-
const
|
|
354
|
+
const data = showVersions ? listVersionsQuery.data : listObjectsQuery.data;
|
|
355
|
+
const error = showVersions ? listVersionsQuery.error : listObjectsQuery.error;
|
|
356
|
+
const hasNextPage = showVersions ? listVersionsQuery.hasNextPage : listObjectsQuery.hasNextPage;
|
|
357
|
+
const fetchNextPage = showVersions ? listVersionsQuery.fetchNextPage : listObjectsQuery.fetchNextPage;
|
|
358
|
+
const isFetchingNextPage = showVersions ? listVersionsQuery.isFetchingNextPage : listObjectsQuery.isFetchingNextPage;
|
|
359
|
+
const isLoading = showVersions ? listVersionsQuery.isLoading : listObjectsQuery.isLoading;
|
|
56
360
|
const objectsForLegalHold = useMemo(()=>{
|
|
57
361
|
const objects = [];
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
362
|
+
const currentData = showVersions ? listVersionsQuery.data : listObjectsQuery.data;
|
|
363
|
+
if (!currentData?.pages) return objects;
|
|
364
|
+
let count = 0;
|
|
365
|
+
if (showVersions) for (const page of currentData.pages){
|
|
366
|
+
if (count >= 100) break;
|
|
367
|
+
if (page.Versions) for (const version of page.Versions){
|
|
368
|
+
if (count >= 100) break;
|
|
369
|
+
if (version.Key) {
|
|
370
|
+
objects.push({
|
|
371
|
+
Key: version.Key,
|
|
372
|
+
VersionId: version.VersionId
|
|
373
|
+
});
|
|
374
|
+
count++;
|
|
375
|
+
}
|
|
376
|
+
}
|
|
377
|
+
}
|
|
378
|
+
else for (const page of currentData.pages){
|
|
379
|
+
if (count >= 100) break;
|
|
380
|
+
if (page.Contents) for (const obj of page.Contents){
|
|
381
|
+
if (count >= 100) break;
|
|
382
|
+
if (obj.Key) {
|
|
383
|
+
objects.push({
|
|
384
|
+
Key: obj.Key
|
|
385
|
+
});
|
|
386
|
+
count++;
|
|
387
|
+
}
|
|
388
|
+
}
|
|
389
|
+
}
|
|
73
390
|
return objects;
|
|
74
391
|
}, [
|
|
75
|
-
data,
|
|
76
392
|
showVersions,
|
|
77
|
-
listVersionsQuery.data
|
|
393
|
+
listVersionsQuery.data,
|
|
394
|
+
listObjectsQuery.data
|
|
78
395
|
]);
|
|
79
|
-
const
|
|
80
|
-
|
|
396
|
+
const shouldFetchLegalHold = useMemo(()=>Boolean(bucketName) && objectsForLegalHold.length > 0, [
|
|
397
|
+
bucketName,
|
|
398
|
+
objectsForLegalHold.length
|
|
399
|
+
]);
|
|
400
|
+
const { data: legalHoldData } = useBatchObjectLegalHold(bucketName, objectsForLegalHold, shouldFetchLegalHold);
|
|
401
|
+
const processFolders = useCallback((pages)=>{
|
|
81
402
|
const folders = [];
|
|
403
|
+
pages.forEach((page)=>{
|
|
404
|
+
if (page.CommonPrefixes) page.CommonPrefixes.forEach((cp)=>{
|
|
405
|
+
if (cp.Prefix) {
|
|
406
|
+
const folderName = removePrefix(cp.Prefix, prefix).replace(/\/$/, "");
|
|
407
|
+
folders.push({
|
|
408
|
+
Key: cp.Prefix,
|
|
409
|
+
displayName: folderName + "/",
|
|
410
|
+
type: "folder"
|
|
411
|
+
});
|
|
412
|
+
}
|
|
413
|
+
});
|
|
414
|
+
});
|
|
415
|
+
return folders;
|
|
416
|
+
}, [
|
|
417
|
+
prefix
|
|
418
|
+
]);
|
|
419
|
+
const createObjectItem = useCallback((obj, legalHoldData)=>{
|
|
420
|
+
const legalHoldKey = createLegalHoldKey(obj.Key, null);
|
|
421
|
+
const isLegalHoldEnabled = legalHoldData?.[legalHoldKey]?.isLegalHoldEnabled ?? false;
|
|
422
|
+
return {
|
|
423
|
+
...obj,
|
|
424
|
+
displayName: removePrefix(obj.Key, prefix),
|
|
425
|
+
type: "object",
|
|
426
|
+
isLegalHoldEnabled
|
|
427
|
+
};
|
|
428
|
+
}, [
|
|
429
|
+
prefix
|
|
430
|
+
]);
|
|
431
|
+
const tableData = useMemo(()=>{
|
|
432
|
+
let folders = [];
|
|
82
433
|
const items = [];
|
|
83
434
|
if (showVersions) {
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
if (cp.Prefix) {
|
|
87
|
-
const folderName = cp.Prefix.replace(prefix, "").replace(/\/$/, "");
|
|
88
|
-
folders.push({
|
|
89
|
-
Key: cp.Prefix,
|
|
90
|
-
displayName: folderName + "/",
|
|
91
|
-
type: "folder",
|
|
92
|
-
LastModified: void 0,
|
|
93
|
-
Size: void 0
|
|
94
|
-
});
|
|
95
|
-
}
|
|
96
|
-
});
|
|
97
|
-
});
|
|
435
|
+
folders = listObjectsQuery.data?.pages ? processFolders(listObjectsQuery.data.pages) : [];
|
|
436
|
+
const objectsWithVersions = new Set();
|
|
98
437
|
if (listVersionsQuery.data?.pages) {
|
|
99
438
|
const itemsByKey = {};
|
|
100
439
|
listVersionsQuery.data.pages.forEach((page)=>{
|
|
101
440
|
if (page.Versions) page.Versions.forEach((version)=>{
|
|
102
|
-
if (version.Key) {
|
|
441
|
+
if (version.Key && !version.Key.endsWith("/")) {
|
|
442
|
+
objectsWithVersions.add(version.Key);
|
|
103
443
|
if (!itemsByKey[version.Key]) itemsByKey[version.Key] = [];
|
|
104
444
|
itemsByKey[version.Key].push(version);
|
|
105
445
|
}
|
|
106
446
|
});
|
|
107
447
|
if (page.DeleteMarkers) page.DeleteMarkers.forEach((marker)=>{
|
|
108
|
-
if (marker.Key) {
|
|
448
|
+
if (marker.Key && !marker.Key.endsWith("/")) {
|
|
449
|
+
objectsWithVersions.add(marker.Key);
|
|
109
450
|
if (!itemsByKey[marker.Key]) itemsByKey[marker.Key] = [];
|
|
110
451
|
itemsByKey[marker.Key].push({
|
|
111
452
|
...marker,
|
|
@@ -114,21 +455,25 @@ const ObjectList = ({ bucketName, prefix, onObjectSelect, onPrefixChange })=>{
|
|
|
114
455
|
}
|
|
115
456
|
});
|
|
116
457
|
});
|
|
117
|
-
Object.keys(itemsByKey).sort().
|
|
458
|
+
Object.keys(itemsByKey).sort((a, b)=>a.localeCompare(b, "en", {
|
|
459
|
+
sensitivity: "base"
|
|
460
|
+
})).forEach((key)=>{
|
|
118
461
|
const allItems = itemsByKey[key];
|
|
119
462
|
allItems.sort((a, b)=>{
|
|
120
463
|
if (a.IsLatest) return -1;
|
|
121
464
|
if (b.IsLatest) return 1;
|
|
122
|
-
const
|
|
123
|
-
const
|
|
124
|
-
return
|
|
465
|
+
const aTime = a.LastModified?.getTime() ?? 0;
|
|
466
|
+
const bTime = b.LastModified?.getTime() ?? 0;
|
|
467
|
+
return bTime - aTime;
|
|
125
468
|
});
|
|
126
469
|
allItems.forEach((item)=>{
|
|
127
|
-
|
|
470
|
+
if (!item.Key) return;
|
|
471
|
+
if (item.Key.endsWith("/")) return;
|
|
472
|
+
const baseName = removePrefix(item.Key, prefix);
|
|
128
473
|
const isLatest = item.IsLatest;
|
|
129
474
|
const isDeleteMarker = "isDeleteMarker" in item && item.isDeleteMarker;
|
|
130
|
-
const legalHoldKey =
|
|
131
|
-
const isLegalHoldEnabled = legalHoldData?.[legalHoldKey]?.isLegalHoldEnabled
|
|
475
|
+
const legalHoldKey = createLegalHoldKey(item.Key, item.VersionId);
|
|
476
|
+
const isLegalHoldEnabled = legalHoldData?.[legalHoldKey]?.isLegalHoldEnabled ?? false;
|
|
132
477
|
if (isDeleteMarker) items.push({
|
|
133
478
|
...item,
|
|
134
479
|
displayName: baseName,
|
|
@@ -147,224 +492,164 @@ const ObjectList = ({ bucketName, prefix, onObjectSelect, onPrefixChange })=>{
|
|
|
147
492
|
});
|
|
148
493
|
});
|
|
149
494
|
}
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
folders.push({
|
|
155
|
-
Key: cp.Prefix,
|
|
156
|
-
displayName: folderName + "/",
|
|
157
|
-
type: "folder",
|
|
158
|
-
LastModified: void 0,
|
|
159
|
-
Size: void 0
|
|
160
|
-
});
|
|
161
|
-
}
|
|
495
|
+
if (listObjectsQuery.data?.pages) listObjectsQuery.data.pages.forEach((page)=>{
|
|
496
|
+
if (page.Contents) page.Contents.forEach((obj)=>{
|
|
497
|
+
if (obj.Key && !obj.Key.endsWith("/") && !objectsWithVersions.has(obj.Key)) items.push(createObjectItem(obj, legalHoldData));
|
|
498
|
+
});
|
|
162
499
|
});
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
items.push(
|
|
168
|
-
|
|
169
|
-
displayName: obj.Key.replace(prefix, ""),
|
|
170
|
-
type: "object",
|
|
171
|
-
isLegalHoldEnabled
|
|
172
|
-
});
|
|
173
|
-
}
|
|
500
|
+
} else {
|
|
501
|
+
folders = data?.pages ? processFolders(data.pages) : [];
|
|
502
|
+
if (data?.pages) data.pages.forEach((page)=>{
|
|
503
|
+
if (page.Contents) page.Contents.forEach((obj)=>{
|
|
504
|
+
if (obj.Key && !obj.Key.endsWith("/")) items.push(createObjectItem(obj, legalHoldData));
|
|
505
|
+
});
|
|
174
506
|
});
|
|
175
|
-
}
|
|
507
|
+
}
|
|
176
508
|
const allItems = [
|
|
177
509
|
...folders,
|
|
178
510
|
...items
|
|
179
511
|
];
|
|
180
512
|
return allItems;
|
|
181
513
|
}, [
|
|
182
|
-
data,
|
|
183
|
-
prefix,
|
|
184
514
|
showVersions,
|
|
185
515
|
listObjectsQuery.data,
|
|
186
516
|
listVersionsQuery.data,
|
|
187
|
-
legalHoldData
|
|
517
|
+
legalHoldData,
|
|
518
|
+
processFolders,
|
|
519
|
+
createObjectItem
|
|
520
|
+
]);
|
|
521
|
+
const versionIdColumn = useMemo(()=>createVersionIdColumn(), []);
|
|
522
|
+
const lastModifiedColumn = useMemo(()=>createLastModifiedColumn(), []);
|
|
523
|
+
const sizeColumn = useMemo(()=>createSizeColumn(), []);
|
|
524
|
+
const storageClassColumn = useMemo(()=>createStorageClassColumn(), []);
|
|
525
|
+
const nameColumn = useMemo(()=>createNameColumn(handlePrefixChange, handleDownload), [
|
|
526
|
+
handlePrefixChange,
|
|
527
|
+
handleDownload
|
|
188
528
|
]);
|
|
189
529
|
const columns = useMemo(()=>{
|
|
190
|
-
const
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
let iconName;
|
|
211
|
-
iconName = isFolder ? "Folder" : isDeleteMarker ? "Deletion-marker" : "File";
|
|
212
|
-
const shouldIndent = isVersion && !isLatest;
|
|
213
|
-
const isLegalHoldEnabled = Boolean(row.original.isLegalHoldEnabled);
|
|
214
|
-
return /*#__PURE__*/ jsx(ConstrainedText, {
|
|
215
|
-
text: /*#__PURE__*/ jsxs("div", {
|
|
216
|
-
style: {
|
|
217
|
-
display: "flex",
|
|
218
|
-
alignItems: "center",
|
|
219
|
-
gap: spacing.r8,
|
|
220
|
-
paddingLeft: shouldIndent ? spacing.r24 : 0
|
|
221
|
-
},
|
|
222
|
-
children: [
|
|
223
|
-
/*#__PURE__*/ jsx(Icon, {
|
|
224
|
-
name: iconName,
|
|
225
|
-
size: "sm",
|
|
226
|
-
color: getVersionTextColor(row)
|
|
227
|
-
}),
|
|
228
|
-
isLegalHoldEnabled && /*#__PURE__*/ jsx(Icon, {
|
|
229
|
-
name: "Rebalance",
|
|
230
|
-
size: "sm",
|
|
231
|
-
color: getVersionTextColor(row)
|
|
232
|
-
}),
|
|
233
|
-
isDeleteMarker ? /*#__PURE__*/ jsx(Text, {
|
|
234
|
-
color: getVersionTextColor(row),
|
|
235
|
-
children: displayValue
|
|
236
|
-
}) : /*#__PURE__*/ jsx(Link, {
|
|
237
|
-
onClick: (e)=>{
|
|
238
|
-
e.stopPropagation();
|
|
239
|
-
if (isFolder) onPrefixChange?.(row.original.Key || "");
|
|
240
|
-
else onObjectSelect(row.original);
|
|
241
|
-
},
|
|
242
|
-
children: /*#__PURE__*/ jsx(Text, {
|
|
243
|
-
color: getVersionTextColor(row),
|
|
244
|
-
children: displayValue
|
|
245
|
-
})
|
|
246
|
-
})
|
|
247
|
-
]
|
|
248
|
-
}),
|
|
249
|
-
lineClamp: 2
|
|
250
|
-
});
|
|
251
|
-
},
|
|
252
|
-
cellStyle: {
|
|
253
|
-
flex: "2",
|
|
254
|
-
width: "unset"
|
|
255
|
-
}
|
|
256
|
-
}
|
|
530
|
+
const defaultColumnsMap = {
|
|
531
|
+
name: nameColumn,
|
|
532
|
+
versionId: versionIdColumn,
|
|
533
|
+
lastModified: lastModifiedColumn,
|
|
534
|
+
size: sizeColumn,
|
|
535
|
+
storageClass: storageClassColumn
|
|
536
|
+
};
|
|
537
|
+
const customColumns = (extraObjectListColumns || []).map((config)=>buildCustomColumn(config));
|
|
538
|
+
const customColumnsMap = createOverrideMap(customColumns);
|
|
539
|
+
const getColumn = (id)=>customColumnsMap.get(id) || defaultColumnsMap[id];
|
|
540
|
+
const extraColumns = customColumns.filter((col)=>col.id && !(col.id in defaultColumnsMap));
|
|
541
|
+
const finalColumns = [
|
|
542
|
+
getColumn("name"),
|
|
543
|
+
...showVersions ? [
|
|
544
|
+
getColumn("versionId")
|
|
545
|
+
] : [],
|
|
546
|
+
...extraColumns,
|
|
547
|
+
getColumn("lastModified"),
|
|
548
|
+
getColumn("size"),
|
|
549
|
+
getColumn("storageClass")
|
|
257
550
|
];
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
lineClamp: 1,
|
|
274
|
-
color: textColor
|
|
275
|
-
});
|
|
276
|
-
},
|
|
277
|
-
cellStyle: {
|
|
278
|
-
flex: "1.5",
|
|
279
|
-
textAlign: "left",
|
|
280
|
-
paddingRight: spacing.r16,
|
|
281
|
-
width: "unset",
|
|
282
|
-
maxWidth: "8rem"
|
|
283
|
-
}
|
|
551
|
+
return finalColumns;
|
|
552
|
+
}, [
|
|
553
|
+
showVersions,
|
|
554
|
+
extraObjectListColumns,
|
|
555
|
+
nameColumn,
|
|
556
|
+
versionIdColumn,
|
|
557
|
+
lastModifiedColumn,
|
|
558
|
+
sizeColumn,
|
|
559
|
+
storageClassColumn
|
|
560
|
+
]);
|
|
561
|
+
const handleUploadSuccess = useCallback(()=>{
|
|
562
|
+
queryClient.invalidateQueries({
|
|
563
|
+
queryKey: [
|
|
564
|
+
"ListObjects"
|
|
565
|
+
]
|
|
284
566
|
});
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
567
|
+
queryClient.invalidateQueries({
|
|
568
|
+
queryKey: [
|
|
569
|
+
"ListObjectVersions"
|
|
570
|
+
]
|
|
571
|
+
});
|
|
572
|
+
}, [
|
|
573
|
+
queryClient
|
|
574
|
+
]);
|
|
575
|
+
const handleFolderSuccess = useCallback(()=>{
|
|
576
|
+
queryClient.invalidateQueries({
|
|
577
|
+
queryKey: [
|
|
578
|
+
"ListObjects"
|
|
579
|
+
]
|
|
580
|
+
});
|
|
581
|
+
queryClient.invalidateQueries({
|
|
582
|
+
queryKey: [
|
|
583
|
+
"ListObjectVersions"
|
|
584
|
+
]
|
|
585
|
+
});
|
|
586
|
+
}, [
|
|
587
|
+
queryClient
|
|
588
|
+
]);
|
|
589
|
+
const handleUploadError = useCallback(()=>{}, []);
|
|
590
|
+
const handleFolderError = useCallback(()=>{}, []);
|
|
591
|
+
const renderUploadAction = useCallback(()=>/*#__PURE__*/ jsx(UploadButton, {
|
|
592
|
+
bucket: bucketName,
|
|
593
|
+
prefix: prefix,
|
|
594
|
+
onUploadSuccess: handleUploadSuccess,
|
|
595
|
+
onUploadError: handleUploadError
|
|
596
|
+
}), [
|
|
597
|
+
bucketName,
|
|
598
|
+
prefix,
|
|
599
|
+
handleUploadSuccess,
|
|
600
|
+
handleUploadError
|
|
601
|
+
]);
|
|
602
|
+
const renderCreateFolderAction = useCallback(()=>/*#__PURE__*/ jsx(CreateFolderButton, {
|
|
603
|
+
bucket: bucketName,
|
|
604
|
+
prefix: prefix,
|
|
605
|
+
onFolderSuccess: handleFolderSuccess,
|
|
606
|
+
onFolderError: handleFolderError
|
|
607
|
+
}), [
|
|
608
|
+
bucketName,
|
|
609
|
+
prefix,
|
|
610
|
+
handleFolderSuccess,
|
|
611
|
+
handleFolderError
|
|
612
|
+
]);
|
|
613
|
+
const renderDeleteAction = useCallback(()=>/*#__PURE__*/ jsx(DeleteObjectButton, {
|
|
614
|
+
objects: selectedObjects,
|
|
615
|
+
bucketName: bucketName
|
|
616
|
+
}), [
|
|
617
|
+
selectedObjects,
|
|
618
|
+
bucketName
|
|
619
|
+
]);
|
|
620
|
+
const actions = useMemo(()=>{
|
|
621
|
+
const defaultActionsMap = {
|
|
622
|
+
upload: {
|
|
623
|
+
id: "upload",
|
|
624
|
+
render: renderUploadAction
|
|
330
625
|
},
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
paddingRight: spacing.r16,
|
|
335
|
-
width: "unset"
|
|
336
|
-
}
|
|
337
|
-
}, {
|
|
338
|
-
Header: "Storage Location",
|
|
339
|
-
accessor: "StorageClass",
|
|
340
|
-
id: "storageClass",
|
|
341
|
-
Cell: ({ value, row })=>{
|
|
342
|
-
if (!value) return /*#__PURE__*/ jsx(Text, {
|
|
343
|
-
children: "-"
|
|
344
|
-
});
|
|
345
|
-
const storageClass = value;
|
|
346
|
-
return /*#__PURE__*/ jsx(Wrap, {
|
|
347
|
-
style: {
|
|
348
|
-
justifyContent: "flex-end"
|
|
349
|
-
},
|
|
350
|
-
children: /*#__PURE__*/ jsx(Text, {
|
|
351
|
-
color: getVersionTextColor(row),
|
|
352
|
-
children: "STANDARD" === storageClass ? "default" : storageClass
|
|
353
|
-
})
|
|
354
|
-
});
|
|
626
|
+
createFolder: {
|
|
627
|
+
id: "createFolder",
|
|
628
|
+
render: renderCreateFolderAction
|
|
355
629
|
},
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
paddingRight: spacing.r16,
|
|
360
|
-
width: "unset"
|
|
630
|
+
delete: {
|
|
631
|
+
id: "delete",
|
|
632
|
+
render: renderDeleteAction
|
|
361
633
|
}
|
|
362
|
-
}
|
|
363
|
-
|
|
634
|
+
};
|
|
635
|
+
const customActions = (extraObjectListActions || []).map((config)=>({
|
|
636
|
+
id: config.id,
|
|
637
|
+
render: config.render
|
|
638
|
+
}));
|
|
639
|
+
const customActionsMap = createOverrideMap(customActions);
|
|
640
|
+
const getAction = (id)=>customActionsMap.get(id) || defaultActionsMap[id];
|
|
641
|
+
const extraActions = customActions.filter((action)=>!(action.id in defaultActionsMap));
|
|
642
|
+
return [
|
|
643
|
+
getAction("upload"),
|
|
644
|
+
getAction("createFolder"),
|
|
645
|
+
getAction("delete"),
|
|
646
|
+
...extraActions
|
|
647
|
+
];
|
|
364
648
|
}, [
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
649
|
+
renderUploadAction,
|
|
650
|
+
renderCreateFolderAction,
|
|
651
|
+
renderDeleteAction,
|
|
652
|
+
extraObjectListActions
|
|
368
653
|
]);
|
|
369
654
|
const handleReachBottom = useCallback(()=>{
|
|
370
655
|
if (hasNextPage && !isFetchingNextPage) fetchNextPage();
|
|
@@ -373,18 +658,33 @@ const ObjectList = ({ bucketName, prefix, onObjectSelect, onPrefixChange })=>{
|
|
|
373
658
|
isFetchingNextPage,
|
|
374
659
|
fetchNextPage
|
|
375
660
|
]);
|
|
661
|
+
const handleMultiSelectionChanged = useCallback((rows)=>{
|
|
662
|
+
const objects = rows.map((row)=>row.original);
|
|
663
|
+
setSelectedObjects(objects);
|
|
664
|
+
}, []);
|
|
665
|
+
const handleSingleRowSelected = useCallback((row)=>{
|
|
666
|
+
handleObjectSelect(row.original);
|
|
667
|
+
}, [
|
|
668
|
+
handleObjectSelect
|
|
669
|
+
]);
|
|
670
|
+
const handleToggleAll = useCallback((selected)=>{
|
|
671
|
+
selected ? setSelectedObjects(tableData) : setSelectedObjects([]);
|
|
672
|
+
}, [
|
|
673
|
+
tableData
|
|
674
|
+
]);
|
|
376
675
|
const tableStatus = isLoading ? "loading" : error ? "error" : "success";
|
|
676
|
+
const entityName = useMemo(()=>({
|
|
677
|
+
en: {
|
|
678
|
+
singular: "object",
|
|
679
|
+
plural: "objects"
|
|
680
|
+
}
|
|
681
|
+
}), []);
|
|
377
682
|
return /*#__PURE__*/ jsxs(Table, {
|
|
378
683
|
columns: columns,
|
|
379
684
|
data: tableData,
|
|
380
685
|
status: tableStatus,
|
|
381
686
|
onBottom: handleReachBottom,
|
|
382
|
-
entityName:
|
|
383
|
-
en: {
|
|
384
|
-
singular: "object",
|
|
385
|
-
plural: "objects"
|
|
386
|
-
}
|
|
387
|
-
},
|
|
687
|
+
entityName: entityName,
|
|
388
688
|
children: [
|
|
389
689
|
/*#__PURE__*/ jsxs(Wrap, {
|
|
390
690
|
padding: spacing.r16,
|
|
@@ -392,7 +692,7 @@ const ObjectList = ({ bucketName, prefix, onObjectSelect, onPrefixChange })=>{
|
|
|
392
692
|
isMetadataSearchEnabled ? /*#__PURE__*/ jsx(MetadataSearch, {
|
|
393
693
|
isError: !!error
|
|
394
694
|
}) : /*#__PURE__*/ jsx(Table.SearchWithQueryParams, {
|
|
395
|
-
queryParams:
|
|
695
|
+
queryParams: SEARCH_QUERY_PARAM
|
|
396
696
|
}),
|
|
397
697
|
/*#__PURE__*/ jsxs(Box, {
|
|
398
698
|
display: "flex",
|
|
@@ -400,33 +700,20 @@ const ObjectList = ({ bucketName, prefix, onObjectSelect, onPrefixChange })=>{
|
|
|
400
700
|
alignItems: "center",
|
|
401
701
|
gap: spacing.r8,
|
|
402
702
|
children: [
|
|
403
|
-
/*#__PURE__*/
|
|
703
|
+
/*#__PURE__*/ jsx(Box, {
|
|
404
704
|
display: "flex",
|
|
405
705
|
alignItems: "center",
|
|
406
706
|
gap: spacing.r8,
|
|
407
|
-
children:
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
prefix: prefix,
|
|
411
|
-
onUploadSuccess: ()=>{},
|
|
412
|
-
onUploadError: ()=>{}
|
|
413
|
-
}),
|
|
414
|
-
/*#__PURE__*/ jsx(CreateFolderButton, {
|
|
415
|
-
bucket: bucketName,
|
|
416
|
-
prefix: prefix,
|
|
417
|
-
onFolderSuccess: ()=>{},
|
|
418
|
-
onFolderError: ()=>{}
|
|
419
|
-
}),
|
|
420
|
-
/*#__PURE__*/ jsx(DeleteObjectButton, {
|
|
421
|
-
objects: selectedObjects,
|
|
422
|
-
bucketName: bucketName
|
|
423
|
-
})
|
|
424
|
-
]
|
|
707
|
+
children: actions.map((action)=>/*#__PURE__*/ jsx(Fragment, {
|
|
708
|
+
children: action.render()
|
|
709
|
+
}, action.id))
|
|
425
710
|
}),
|
|
426
711
|
/*#__PURE__*/ jsx(Toggle, {
|
|
427
712
|
toggle: showVersions,
|
|
428
713
|
onChange: (e)=>setShowVersions(e.target.checked),
|
|
429
|
-
label: "List Versions"
|
|
714
|
+
label: "List Versions",
|
|
715
|
+
"aria-label": showVersions ? "Hide object versions" : "Show object versions",
|
|
716
|
+
"aria-pressed": showVersions
|
|
430
717
|
})
|
|
431
718
|
]
|
|
432
719
|
})
|
|
@@ -434,20 +721,13 @@ const ObjectList = ({ bucketName, prefix, onObjectSelect, onPrefixChange })=>{
|
|
|
434
721
|
}),
|
|
435
722
|
/*#__PURE__*/ jsx(Table.MultiSelectableContent, {
|
|
436
723
|
rowHeight: "h40",
|
|
437
|
-
onMultiSelectionChanged:
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
},
|
|
441
|
-
onSingleRowSelected: (row)=>{
|
|
442
|
-
onObjectSelect(row.original);
|
|
443
|
-
},
|
|
444
|
-
onToggleAll: (selected)=>{
|
|
445
|
-
console.log("Toggle all", selected);
|
|
446
|
-
},
|
|
724
|
+
onMultiSelectionChanged: handleMultiSelectionChanged,
|
|
725
|
+
onSingleRowSelected: handleSingleRowSelected,
|
|
726
|
+
onToggleAll: handleToggleAll,
|
|
447
727
|
separationLineVariant: "backgroundLevel1",
|
|
448
728
|
isLoadingMoreItems: isFetchingNextPage
|
|
449
729
|
})
|
|
450
730
|
]
|
|
451
731
|
});
|
|
452
732
|
};
|
|
453
|
-
export { ObjectList };
|
|
733
|
+
export { ObjectList, isObjectLike };
|