@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 +1,41 @@
|
|
|
1
|
+
import { useNavigate } from "react-router-dom";
|
|
2
|
+
interface BucketDetailsContextValue {
|
|
3
|
+
bucketName: string;
|
|
4
|
+
navigate: ReturnType<typeof useNavigate>;
|
|
5
|
+
}
|
|
6
|
+
/**
|
|
7
|
+
* Context for BucketDetails component.
|
|
8
|
+
*
|
|
9
|
+
* **Important**: Always use `useBucketDetailsContext()` hook instead of accessing this context directly.
|
|
10
|
+
* The hook provides proper error handling if the context is not available.
|
|
11
|
+
*
|
|
12
|
+
* This context is exported for testing purposes only.
|
|
13
|
+
*/
|
|
14
|
+
export declare const BucketDetailsContext: import("react").Context<BucketDetailsContextValue | null>;
|
|
15
|
+
export declare function useBucketDetailsContext(): BucketDetailsContextValue;
|
|
16
|
+
declare const OverviewTab: React.FC;
|
|
17
|
+
declare const LifecycleTab: React.FC;
|
|
18
|
+
declare const ReplicationTab: React.FC;
|
|
19
|
+
interface CustomTabProps {
|
|
20
|
+
config: {
|
|
21
|
+
id: string;
|
|
22
|
+
title: string;
|
|
23
|
+
path?: string;
|
|
24
|
+
withoutPadding?: boolean;
|
|
25
|
+
render: () => React.ReactNode;
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
declare const CustomTab: React.FC<CustomTabProps>;
|
|
29
|
+
interface BucketDetailsProps {
|
|
30
|
+
children?: React.ReactNode;
|
|
31
|
+
}
|
|
32
|
+
declare const BucketDetailsRoot: React.FC<BucketDetailsProps>;
|
|
1
33
|
export declare function BucketDetails(): import("react/jsx-runtime").JSX.Element;
|
|
34
|
+
type BucketDetailsComponent = typeof BucketDetailsRoot & {
|
|
35
|
+
OverviewTab: typeof OverviewTab;
|
|
36
|
+
LifecycleTab: typeof LifecycleTab;
|
|
37
|
+
ReplicationTab: typeof ReplicationTab;
|
|
38
|
+
CustomTab: typeof CustomTab;
|
|
39
|
+
};
|
|
40
|
+
declare const BucketDetailsCompound: BucketDetailsComponent;
|
|
41
|
+
export { BucketDetailsCompound };
|
|
@@ -1,106 +1,214 @@
|
|
|
1
1
|
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
2
|
-
import {
|
|
2
|
+
import { createContext, memo, useCallback, useContext, useMemo } from "react";
|
|
3
3
|
import { useNavigate, useParams } from "react-router-dom";
|
|
4
4
|
import { Tabs } from "@scality/core-ui/dist/next";
|
|
5
|
-
import {
|
|
6
|
-
import { DeleteBucketButton } from "./DeleteBucketButton.js";
|
|
7
|
-
import { EmptyBucketButton } from "./EmptyBucketButton.js";
|
|
8
|
-
import { BucketLifecycleList } from "./BucketLifecycleList.js";
|
|
9
|
-
import { BucketReplicationList } from "./BucketReplicationList.js";
|
|
5
|
+
import { useDataBrowserUICustomization } from "../../contexts/DataBrowserUICustomizationContext.js";
|
|
10
6
|
import { useGetBucketLifecycle, useGetBucketReplication } from "../../hooks/bucketConfiguration.js";
|
|
7
|
+
import { BUCKET_ROUTES } from "../../utils/constants.js";
|
|
11
8
|
import { isNotFoundError } from "../../utils/errorHandling.js";
|
|
9
|
+
import { BucketLifecycleList } from "./BucketLifecycleList.js";
|
|
10
|
+
import { BucketOverview } from "./BucketOverview.js";
|
|
11
|
+
import { BucketReplicationList } from "./BucketReplicationList.js";
|
|
12
12
|
import { BucketVersioning } from "./BucketVersioning.js";
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
const
|
|
13
|
+
import { DeleteBucketButton } from "./DeleteBucketButton.js";
|
|
14
|
+
import { EmptyBucketButton } from "./EmptyBucketButton.js";
|
|
15
|
+
const BucketDetailsContext = /*#__PURE__*/ createContext(null);
|
|
16
|
+
function useBucketDetailsContext() {
|
|
17
|
+
const context = useContext(BucketDetailsContext);
|
|
18
|
+
if (!context) throw new Error("BucketDetails components must be used within BucketDetails");
|
|
19
|
+
return context;
|
|
20
|
+
}
|
|
21
|
+
const getEffectiveStatus = (status, error)=>{
|
|
22
|
+
if (isNotFoundError(error)) return "success";
|
|
23
|
+
if ("pending" === status) return "loading";
|
|
24
|
+
if ("error" === status) return "error";
|
|
25
|
+
return "success";
|
|
26
|
+
};
|
|
27
|
+
const OverviewTab = /*#__PURE__*/ memo(()=>{
|
|
28
|
+
const { bucketName, navigate } = useBucketDetailsContext();
|
|
29
|
+
const renderDeleteButton = useCallback((name)=>/*#__PURE__*/ jsx(DeleteBucketButton, {
|
|
30
|
+
bucketName: name
|
|
31
|
+
}), []);
|
|
32
|
+
const renderEmptyButton = useCallback((name)=>/*#__PURE__*/ jsx(EmptyBucketButton, {
|
|
33
|
+
bucketName: name
|
|
34
|
+
}), []);
|
|
35
|
+
const renderVersioning = useCallback(()=>/*#__PURE__*/ jsx(BucketVersioning, {}), []);
|
|
36
|
+
const handleEditPolicy = useCallback((name)=>navigate(BUCKET_ROUTES.bucketPolicy(name)), [
|
|
37
|
+
navigate
|
|
38
|
+
]);
|
|
39
|
+
return /*#__PURE__*/ jsxs(BucketOverview, {
|
|
40
|
+
bucketName: bucketName,
|
|
41
|
+
children: [
|
|
42
|
+
/*#__PURE__*/ jsx(BucketOverview.Actions, {
|
|
43
|
+
renderDeleteButton: renderDeleteButton,
|
|
44
|
+
renderEmptyButton: renderEmptyButton
|
|
45
|
+
}),
|
|
46
|
+
/*#__PURE__*/ jsxs(BucketOverview.Sections, {
|
|
47
|
+
children: [
|
|
48
|
+
/*#__PURE__*/ jsx(BucketOverview.GeneralSection, {
|
|
49
|
+
renderVersioning: renderVersioning
|
|
50
|
+
}),
|
|
51
|
+
/*#__PURE__*/ jsx(BucketOverview.DataProtectionSection, {}),
|
|
52
|
+
/*#__PURE__*/ jsx(BucketOverview.PermissionsSection, {
|
|
53
|
+
onEditPolicy: handleEditPolicy
|
|
54
|
+
})
|
|
55
|
+
]
|
|
56
|
+
})
|
|
57
|
+
]
|
|
58
|
+
});
|
|
59
|
+
});
|
|
60
|
+
OverviewTab.displayName = "BucketDetails.OverviewTab";
|
|
61
|
+
const LifecycleTab = /*#__PURE__*/ memo(()=>{
|
|
62
|
+
const { bucketName, navigate } = useBucketDetailsContext();
|
|
18
63
|
const { data: lifecycleData, status: lifecycleStatus, error: lifecycleError } = useGetBucketLifecycle({
|
|
19
64
|
Bucket: bucketName
|
|
20
65
|
});
|
|
66
|
+
const lifecycleRules = lifecycleData?.Rules || [];
|
|
67
|
+
const effectiveStatus = getEffectiveStatus(lifecycleStatus, lifecycleError);
|
|
68
|
+
const handleCreateRule = useCallback(()=>navigate(BUCKET_ROUTES.lifecycleCreate(bucketName)), [
|
|
69
|
+
navigate,
|
|
70
|
+
bucketName
|
|
71
|
+
]);
|
|
72
|
+
const handleEditRule = useCallback((ruleId)=>navigate(BUCKET_ROUTES.lifecycleEdit(bucketName, ruleId)), [
|
|
73
|
+
navigate,
|
|
74
|
+
bucketName
|
|
75
|
+
]);
|
|
76
|
+
return /*#__PURE__*/ jsx(BucketLifecycleList, {
|
|
77
|
+
bucketName: bucketName,
|
|
78
|
+
lifecycleRules: lifecycleRules,
|
|
79
|
+
lifecycleStatus: effectiveStatus,
|
|
80
|
+
onCreateRule: handleCreateRule,
|
|
81
|
+
onEditRule: handleEditRule
|
|
82
|
+
});
|
|
83
|
+
});
|
|
84
|
+
LifecycleTab.displayName = "BucketDetails.LifecycleTab";
|
|
85
|
+
const ReplicationTab = /*#__PURE__*/ memo(()=>{
|
|
86
|
+
const { bucketName, navigate } = useBucketDetailsContext();
|
|
21
87
|
const { data: replicationData, status: replicationStatus, error: replicationError } = useGetBucketReplication({
|
|
22
88
|
Bucket: bucketName
|
|
23
89
|
});
|
|
24
|
-
const lifecycleRules = lifecycleData?.Rules || [];
|
|
25
90
|
const replicationRules = replicationData?.ReplicationConfiguration?.Rules || [];
|
|
26
91
|
const replicationRole = replicationData?.ReplicationConfiguration?.Role || "";
|
|
27
|
-
const
|
|
28
|
-
const
|
|
92
|
+
const effectiveStatus = getEffectiveStatus(replicationStatus, replicationError);
|
|
93
|
+
const handleCreateRule = useCallback(()=>navigate(BUCKET_ROUTES.replicationCreate(bucketName)), [
|
|
94
|
+
navigate,
|
|
95
|
+
bucketName
|
|
96
|
+
]);
|
|
97
|
+
const handleEditRule = useCallback((ruleId)=>navigate(BUCKET_ROUTES.replicationEdit(bucketName, ruleId)), [
|
|
98
|
+
navigate,
|
|
99
|
+
bucketName
|
|
100
|
+
]);
|
|
101
|
+
return /*#__PURE__*/ jsx(BucketReplicationList, {
|
|
102
|
+
bucketName: bucketName,
|
|
103
|
+
replicationRules: replicationRules,
|
|
104
|
+
replicationRole: replicationRole,
|
|
105
|
+
replicationStatus: effectiveStatus,
|
|
106
|
+
onCreateRule: handleCreateRule,
|
|
107
|
+
onEditRule: handleEditRule
|
|
108
|
+
});
|
|
109
|
+
});
|
|
110
|
+
ReplicationTab.displayName = "BucketDetails.ReplicationTab";
|
|
111
|
+
const CustomTab = ({ config })=>/*#__PURE__*/ jsx(Fragment, {
|
|
112
|
+
children: config.render()
|
|
113
|
+
});
|
|
114
|
+
CustomTab.displayName = "BucketDetails.CustomTab";
|
|
115
|
+
const BucketDetailsRoot = ({ children })=>{
|
|
116
|
+
const { bucketName } = useParams();
|
|
117
|
+
const navigate = useNavigate();
|
|
29
118
|
if (!bucketName) return /*#__PURE__*/ jsx("div", {
|
|
30
119
|
children: "No bucket selected"
|
|
31
120
|
});
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
121
|
+
const contextValue = useMemo(()=>({
|
|
122
|
+
bucketName,
|
|
123
|
+
navigate
|
|
124
|
+
}), [
|
|
125
|
+
bucketName,
|
|
126
|
+
navigate
|
|
127
|
+
]);
|
|
128
|
+
return /*#__PURE__*/ jsx(BucketDetailsContext.Provider, {
|
|
129
|
+
value: contextValue,
|
|
130
|
+
children: children || /*#__PURE__*/ jsx(DefaultTabs, {})
|
|
131
|
+
});
|
|
132
|
+
};
|
|
133
|
+
BucketDetailsRoot.displayName = "BucketDetails";
|
|
134
|
+
const DefaultTabs = ()=>{
|
|
135
|
+
const { extraBucketTabs } = useDataBrowserUICustomization();
|
|
136
|
+
const defaultTabsMap = useMemo(()=>({
|
|
137
|
+
overview: {
|
|
138
|
+
id: "overview",
|
|
139
|
+
label: "Overview",
|
|
140
|
+
path: "",
|
|
141
|
+
withoutPadding: false,
|
|
142
|
+
query: {
|
|
143
|
+
tab: ""
|
|
144
|
+
},
|
|
145
|
+
type: "default",
|
|
146
|
+
Component: OverviewTab
|
|
147
|
+
},
|
|
148
|
+
lifecycle: {
|
|
149
|
+
id: "lifecycle",
|
|
150
|
+
label: "Lifecycle",
|
|
151
|
+
path: "",
|
|
152
|
+
withoutPadding: true,
|
|
153
|
+
query: {
|
|
154
|
+
tab: "lifecycle"
|
|
155
|
+
},
|
|
156
|
+
type: "default",
|
|
157
|
+
Component: LifecycleTab
|
|
158
|
+
},
|
|
159
|
+
replication: {
|
|
160
|
+
id: "replication",
|
|
161
|
+
label: "Replication",
|
|
162
|
+
path: "",
|
|
163
|
+
withoutPadding: true,
|
|
164
|
+
query: {
|
|
165
|
+
tab: "replication"
|
|
166
|
+
},
|
|
167
|
+
type: "default",
|
|
168
|
+
Component: ReplicationTab
|
|
169
|
+
}
|
|
170
|
+
}), []);
|
|
171
|
+
const allTabs = useMemo(()=>{
|
|
172
|
+
const customTabConfigs = extraBucketTabs ? extraBucketTabs.map((tabConfig)=>({
|
|
173
|
+
id: tabConfig.id,
|
|
174
|
+
label: tabConfig.title,
|
|
175
|
+
path: tabConfig.path || "",
|
|
176
|
+
query: {
|
|
177
|
+
tab: tabConfig.id
|
|
178
|
+
},
|
|
179
|
+
withoutPadding: tabConfig.withoutPadding || false,
|
|
180
|
+
type: "custom",
|
|
181
|
+
config: tabConfig
|
|
182
|
+
})) : [];
|
|
183
|
+
const overrideIds = new Set(customTabConfigs.filter((t)=>t.id in defaultTabsMap).map((t)=>t.id));
|
|
184
|
+
const defaults = Object.values(defaultTabsMap).filter((tab)=>!overrideIds.has(tab.id));
|
|
185
|
+
return [
|
|
186
|
+
...defaults,
|
|
187
|
+
...customTabConfigs
|
|
188
|
+
];
|
|
189
|
+
}, [
|
|
190
|
+
extraBucketTabs,
|
|
191
|
+
defaultTabsMap
|
|
192
|
+
]);
|
|
193
|
+
return /*#__PURE__*/ jsx(Tabs, {
|
|
194
|
+
children: allTabs.map((tab)=>/*#__PURE__*/ jsx(Tabs.Tab, {
|
|
195
|
+
label: tab.label,
|
|
196
|
+
path: tab.path,
|
|
197
|
+
query: tab.query,
|
|
198
|
+
withoutPadding: tab.withoutPadding,
|
|
199
|
+
children: "default" === tab.type ? /*#__PURE__*/ jsx(tab.Component, {}) : /*#__PURE__*/ jsx(CustomTab, {
|
|
200
|
+
config: tab.config
|
|
101
201
|
})
|
|
102
|
-
|
|
103
|
-
})
|
|
202
|
+
}, tab.id))
|
|
104
203
|
});
|
|
204
|
+
};
|
|
205
|
+
DefaultTabs.displayName = "BucketDetails.DefaultTabs";
|
|
206
|
+
function BucketDetails() {
|
|
207
|
+
return /*#__PURE__*/ jsx(BucketDetailsRoot, {});
|
|
105
208
|
}
|
|
106
|
-
|
|
209
|
+
const BucketDetailsCompound = BucketDetailsRoot;
|
|
210
|
+
BucketDetailsCompound.OverviewTab = OverviewTab;
|
|
211
|
+
BucketDetailsCompound.LifecycleTab = LifecycleTab;
|
|
212
|
+
BucketDetailsCompound.ReplicationTab = ReplicationTab;
|
|
213
|
+
BucketDetailsCompound.CustomTab = CustomTab;
|
|
214
|
+
export { BucketDetails, BucketDetailsCompound, BucketDetailsContext, useBucketDetailsContext };
|
|
@@ -1,15 +1,14 @@
|
|
|
1
1
|
import type { Bucket } from "@aws-sdk/client-s3";
|
|
2
|
-
|
|
3
|
-
interface BucketListProps<TData extends Bucket & Record<string, unknown> = Bucket & Record<string, unknown>> {
|
|
2
|
+
interface BucketListProps {
|
|
4
3
|
buckets: Bucket[];
|
|
5
4
|
bucketStatus?: "idle" | "loading" | "error" | "success";
|
|
6
5
|
selectedBucketName?: string | null;
|
|
7
6
|
onBucketSelect?: (bucketName: string) => void;
|
|
8
7
|
onCreateBucket?: () => void;
|
|
9
8
|
onNavigateToBucket?: (bucketName: string) => void;
|
|
10
|
-
renderBucketLocation?: (bucketName: string) => React.ReactNode;
|
|
11
|
-
additionalColumns?: Column<TData>[];
|
|
12
|
-
transformBucketData?: (bucket: Bucket) => TData;
|
|
13
9
|
}
|
|
14
|
-
export declare function BucketList
|
|
10
|
+
export declare function BucketList({ buckets, bucketStatus, selectedBucketName, onBucketSelect, onCreateBucket, onNavigateToBucket, }: BucketListProps): import("react/jsx-runtime").JSX.Element;
|
|
11
|
+
export declare namespace BucketList {
|
|
12
|
+
var displayName: string;
|
|
13
|
+
}
|
|
15
14
|
export {};
|
|
@@ -1,101 +1,162 @@
|
|
|
1
1
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { Fragment, useCallback, useMemo } from "react";
|
|
2
3
|
import { ConstrainedText, FormattedDateTime, Icon, Link, Wrap, spacing } from "@scality/core-ui";
|
|
3
4
|
import { Box, Button, Table } from "@scality/core-ui/dist/next";
|
|
4
|
-
import {
|
|
5
|
+
import { useDataBrowserUICustomization } from "../../contexts/DataBrowserUICustomizationContext.js";
|
|
6
|
+
import { BucketLocation } from "./BucketLocation.js";
|
|
5
7
|
const SEARCH_QUERY_PARAM = "search";
|
|
6
|
-
|
|
8
|
+
const LOCATION_COLUMN_FLEX = "1.2";
|
|
9
|
+
const createBucketNameColumn = (onNavigateToBucket)=>({
|
|
10
|
+
Header: "Bucket Name",
|
|
11
|
+
accessor: "Name",
|
|
12
|
+
id: "name",
|
|
13
|
+
Cell: ({ value })=>{
|
|
14
|
+
if (!value) return /*#__PURE__*/ jsx("span", {
|
|
15
|
+
children: "-"
|
|
16
|
+
});
|
|
17
|
+
return /*#__PURE__*/ jsx(ConstrainedText, {
|
|
18
|
+
text: /*#__PURE__*/ jsx(Link, {
|
|
19
|
+
onClick: (e)=>{
|
|
20
|
+
e.stopPropagation();
|
|
21
|
+
onNavigateToBucket?.(value);
|
|
22
|
+
},
|
|
23
|
+
children: value
|
|
24
|
+
}),
|
|
25
|
+
lineClamp: 2
|
|
26
|
+
});
|
|
27
|
+
},
|
|
28
|
+
cellStyle: {
|
|
29
|
+
flex: "1",
|
|
30
|
+
width: "unset"
|
|
31
|
+
}
|
|
32
|
+
});
|
|
33
|
+
const createLocationColumn = ()=>({
|
|
34
|
+
Header: "Storage Location",
|
|
35
|
+
accessor: "Name",
|
|
36
|
+
id: "location",
|
|
37
|
+
Cell: ({ value })=>{
|
|
38
|
+
if (!value) return /*#__PURE__*/ jsx("span", {
|
|
39
|
+
children: "-"
|
|
40
|
+
});
|
|
41
|
+
return /*#__PURE__*/ jsx(BucketLocation, {
|
|
42
|
+
bucketName: value
|
|
43
|
+
});
|
|
44
|
+
},
|
|
45
|
+
cellStyle: {
|
|
46
|
+
width: "unset",
|
|
47
|
+
flex: LOCATION_COLUMN_FLEX
|
|
48
|
+
}
|
|
49
|
+
});
|
|
50
|
+
const createDateColumn = ()=>({
|
|
51
|
+
Header: "Created on",
|
|
52
|
+
accessor: "CreationDate",
|
|
53
|
+
id: "date",
|
|
54
|
+
cellStyle: {
|
|
55
|
+
flex: "1",
|
|
56
|
+
textAlign: "right",
|
|
57
|
+
paddingRight: spacing.r16,
|
|
58
|
+
width: "unset"
|
|
59
|
+
},
|
|
60
|
+
Cell: ({ value })=>{
|
|
61
|
+
if (!value) return /*#__PURE__*/ jsx("span", {
|
|
62
|
+
children: "-"
|
|
63
|
+
});
|
|
64
|
+
return /*#__PURE__*/ jsx(FormattedDateTime, {
|
|
65
|
+
format: "date-time-second",
|
|
66
|
+
value: new Date(value)
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
});
|
|
70
|
+
const buildCustomColumn = (columnConfig)=>({
|
|
71
|
+
Header: columnConfig.header,
|
|
72
|
+
id: String(columnConfig.id),
|
|
73
|
+
Cell: ({ row })=>{
|
|
74
|
+
const RenderComponent = columnConfig.render;
|
|
75
|
+
return /*#__PURE__*/ jsx(RenderComponent, {
|
|
76
|
+
data: row.original
|
|
77
|
+
});
|
|
78
|
+
},
|
|
79
|
+
cellStyle: {
|
|
80
|
+
width: columnConfig.width ?? "unset",
|
|
81
|
+
flex: columnConfig.width ? void 0 : "1"
|
|
82
|
+
}
|
|
83
|
+
});
|
|
84
|
+
function createOverrideMap(customItems) {
|
|
85
|
+
return new Map(customItems.filter((item)=>item.id).map((item)=>[
|
|
86
|
+
String(item.id),
|
|
87
|
+
item
|
|
88
|
+
]));
|
|
89
|
+
}
|
|
90
|
+
function BucketList({ buckets, bucketStatus, selectedBucketName, onBucketSelect, onCreateBucket, onNavigateToBucket }) {
|
|
91
|
+
const { extraBucketListColumns, extraBucketListActions } = useDataBrowserUICustomization();
|
|
7
92
|
const columns = useMemo(()=>{
|
|
8
|
-
const
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
onNavigateToBucket?.(name);
|
|
23
|
-
},
|
|
24
|
-
children: name
|
|
25
|
-
}),
|
|
26
|
-
lineClamp: 2
|
|
27
|
-
});
|
|
28
|
-
},
|
|
29
|
-
cellStyle: {
|
|
30
|
-
flex: "1",
|
|
31
|
-
width: "unset"
|
|
32
|
-
}
|
|
33
|
-
},
|
|
34
|
-
{
|
|
35
|
-
Header: "Storage Location",
|
|
36
|
-
accessor: "Name",
|
|
37
|
-
id: "location",
|
|
38
|
-
Cell ({ value }) {
|
|
39
|
-
return renderBucketLocation ? renderBucketLocation(value) : /*#__PURE__*/ jsx("span", {
|
|
40
|
-
children: "-"
|
|
41
|
-
});
|
|
42
|
-
},
|
|
43
|
-
cellStyle: {
|
|
44
|
-
width: "unset",
|
|
45
|
-
flex: "1.2"
|
|
46
|
-
}
|
|
47
|
-
}
|
|
93
|
+
const defaultColumnsMap = {
|
|
94
|
+
name: createBucketNameColumn(onNavigateToBucket),
|
|
95
|
+
location: createLocationColumn(),
|
|
96
|
+
date: createDateColumn()
|
|
97
|
+
};
|
|
98
|
+
const customColumns = (extraBucketListColumns || []).map((config)=>buildCustomColumn(config));
|
|
99
|
+
const customColumnsMap = createOverrideMap(customColumns);
|
|
100
|
+
const getColumn = (id)=>customColumnsMap.get(id) || defaultColumnsMap[id];
|
|
101
|
+
const extraColumns = customColumns.filter((col)=>col.id && !(col.id in defaultColumnsMap));
|
|
102
|
+
return [
|
|
103
|
+
getColumn("name"),
|
|
104
|
+
getColumn("location"),
|
|
105
|
+
...extraColumns,
|
|
106
|
+
getColumn("date")
|
|
48
107
|
];
|
|
49
|
-
if (additionalColumns) baseColumns.push(...additionalColumns);
|
|
50
|
-
baseColumns.push({
|
|
51
|
-
Header: "Created on",
|
|
52
|
-
accessor: "CreationDate",
|
|
53
|
-
id: "date",
|
|
54
|
-
cellStyle: {
|
|
55
|
-
flex: "1",
|
|
56
|
-
textAlign: "right",
|
|
57
|
-
paddingRight: spacing.r16,
|
|
58
|
-
width: "unset"
|
|
59
|
-
},
|
|
60
|
-
Cell: ({ value, row })=>{
|
|
61
|
-
const date = value || row.original?.CreationDate;
|
|
62
|
-
if (!date) return /*#__PURE__*/ jsx("span", {
|
|
63
|
-
children: "-"
|
|
64
|
-
});
|
|
65
|
-
return /*#__PURE__*/ jsx(FormattedDateTime, {
|
|
66
|
-
format: "date-time-second",
|
|
67
|
-
value: new Date(date)
|
|
68
|
-
});
|
|
69
|
-
}
|
|
70
|
-
});
|
|
71
|
-
return baseColumns;
|
|
72
108
|
}, [
|
|
73
109
|
onNavigateToBucket,
|
|
74
|
-
|
|
75
|
-
additionalColumns
|
|
76
|
-
]);
|
|
77
|
-
const tableData = useMemo(()=>buckets.map((bucket)=>{
|
|
78
|
-
if (transformBucketData) return transformBucketData(bucket);
|
|
79
|
-
const { Name, CreationDate, ...rest } = bucket;
|
|
80
|
-
return {
|
|
81
|
-
Name,
|
|
82
|
-
CreationDate,
|
|
83
|
-
...rest
|
|
84
|
-
};
|
|
85
|
-
}), [
|
|
86
|
-
buckets,
|
|
87
|
-
transformBucketData
|
|
110
|
+
extraBucketListColumns
|
|
88
111
|
]);
|
|
89
112
|
const selectedId = useMemo(()=>{
|
|
90
|
-
if (buckets
|
|
91
|
-
|
|
113
|
+
if (!buckets || !selectedBucketName) return;
|
|
114
|
+
const index = buckets.findIndex((bucket)=>bucket.Name === selectedBucketName);
|
|
115
|
+
return index >= 0 ? String(index) : void 0;
|
|
92
116
|
}, [
|
|
93
117
|
selectedBucketName,
|
|
94
118
|
buckets
|
|
95
119
|
]);
|
|
120
|
+
const actions = useMemo(()=>{
|
|
121
|
+
const defaultActionsMap = {
|
|
122
|
+
createBucket: {
|
|
123
|
+
id: "createBucket",
|
|
124
|
+
render: ()=>/*#__PURE__*/ jsx(Button, {
|
|
125
|
+
icon: /*#__PURE__*/ jsx(Icon, {
|
|
126
|
+
name: "Create-add"
|
|
127
|
+
}),
|
|
128
|
+
label: "Create Bucket",
|
|
129
|
+
variant: "primary",
|
|
130
|
+
onClick: onCreateBucket,
|
|
131
|
+
type: "submit"
|
|
132
|
+
})
|
|
133
|
+
}
|
|
134
|
+
};
|
|
135
|
+
const customActions = (extraBucketListActions || []).map((config)=>({
|
|
136
|
+
id: config.id,
|
|
137
|
+
render: config.render
|
|
138
|
+
}));
|
|
139
|
+
const customActionsMap = createOverrideMap(customActions);
|
|
140
|
+
const getAction = (id)=>customActionsMap.get(id) || defaultActionsMap[id];
|
|
141
|
+
const extraActions = customActions.filter((action)=>!(action.id in defaultActionsMap));
|
|
142
|
+
return [
|
|
143
|
+
getAction("createBucket"),
|
|
144
|
+
...extraActions
|
|
145
|
+
];
|
|
146
|
+
}, [
|
|
147
|
+
onCreateBucket,
|
|
148
|
+
extraBucketListActions
|
|
149
|
+
]);
|
|
150
|
+
const handleRowSelected = useCallback((row)=>{
|
|
151
|
+
const isSelected = selectedBucketName === row.original.Name;
|
|
152
|
+
if (!isSelected && row.original.Name) onBucketSelect?.(row.original.Name);
|
|
153
|
+
}, [
|
|
154
|
+
selectedBucketName,
|
|
155
|
+
onBucketSelect
|
|
156
|
+
]);
|
|
96
157
|
return /*#__PURE__*/ jsxs(Table, {
|
|
97
158
|
columns: columns,
|
|
98
|
-
data:
|
|
159
|
+
data: buckets,
|
|
99
160
|
status: bucketStatus,
|
|
100
161
|
defaultSortingKey: "CreationDate",
|
|
101
162
|
entityName: {
|
|
@@ -118,29 +179,23 @@ function BucketList({ buckets, bucketStatus, selectedBucketName, onBucketSelect,
|
|
|
118
179
|
})
|
|
119
180
|
}),
|
|
120
181
|
/*#__PURE__*/ jsx(Box, {
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
variant: "primary",
|
|
128
|
-
onClick: onCreateBucket,
|
|
129
|
-
type: "submit"
|
|
130
|
-
})
|
|
182
|
+
display: "flex",
|
|
183
|
+
gap: spacing.r16,
|
|
184
|
+
alignItems: "center",
|
|
185
|
+
children: actions.map((action)=>/*#__PURE__*/ jsx(Fragment, {
|
|
186
|
+
children: action.render()
|
|
187
|
+
}, action.id))
|
|
131
188
|
})
|
|
132
189
|
]
|
|
133
190
|
}),
|
|
134
191
|
/*#__PURE__*/ jsx(Table.SingleSelectableContent, {
|
|
135
192
|
rowHeight: "h40",
|
|
136
|
-
selectedId: selectedId
|
|
137
|
-
onRowSelected:
|
|
138
|
-
const isSelected = selectedBucketName === row.original.Name;
|
|
139
|
-
if (!isSelected && row.original.Name) onBucketSelect?.(row.original.Name);
|
|
140
|
-
},
|
|
193
|
+
selectedId: selectedId,
|
|
194
|
+
onRowSelected: handleRowSelected,
|
|
141
195
|
separationLineVariant: "backgroundLevel1"
|
|
142
196
|
})
|
|
143
197
|
]
|
|
144
198
|
});
|
|
145
199
|
}
|
|
200
|
+
BucketList.displayName = "BucketList";
|
|
146
201
|
export { BucketList };
|