@kuadrant/kuadrant-backstage-plugin-frontend 0.0.2-dev-61ff3d3 → 0.0.2-dev-5c79230
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/ApiKeyDetailPage/ApiKeyDetailPage.esm.js +319 -0
- package/dist/components/ApiKeyDetailPage/ApiKeyDetailPage.esm.js.map +1 -0
- package/dist/components/ApiKeyDetailPage/index.esm.js +2 -0
- package/dist/components/ApiKeyDetailPage/index.esm.js.map +1 -0
- package/dist/components/ApiKeyManagementTab/ApiKeyManagementTab.esm.js +340 -162
- package/dist/components/ApiKeyManagementTab/ApiKeyManagementTab.esm.js.map +1 -1
- package/dist/components/ApiKeysPage/ApiKeysPage.esm.js +43 -0
- package/dist/components/ApiKeysPage/ApiKeysPage.esm.js.map +1 -0
- package/dist/components/ApiKeysPage/index.esm.js +2 -0
- package/dist/components/ApiKeysPage/index.esm.js.map +1 -0
- package/dist/components/ApiProductInfoCard/ApiProductInfoCard.esm.js +23 -2
- package/dist/components/ApiProductInfoCard/ApiProductInfoCard.esm.js.map +1 -1
- package/dist/components/ApprovalQueueCard/ApprovalQueueCard.esm.js +312 -118
- package/dist/components/ApprovalQueueCard/ApprovalQueueCard.esm.js.map +1 -1
- package/dist/components/ApprovalQueueTable/ApprovalQueueTable.esm.js +645 -0
- package/dist/components/ApprovalQueueTable/ApprovalQueueTable.esm.js.map +1 -0
- package/dist/components/EditAPIKeyDialog/EditAPIKeyDialog.esm.js +14 -2
- package/dist/components/EditAPIKeyDialog/EditAPIKeyDialog.esm.js.map +1 -1
- package/dist/components/EntityApiApprovalTab/EntityApiApprovalTab.esm.js +276 -0
- package/dist/components/EntityApiApprovalTab/EntityApiApprovalTab.esm.js.map +1 -0
- package/dist/components/EntityApiApprovalTab/index.esm.js +2 -0
- package/dist/components/EntityApiApprovalTab/index.esm.js.map +1 -0
- package/dist/components/FilterPanel/FilterPanel.esm.js +127 -0
- package/dist/components/FilterPanel/FilterPanel.esm.js.map +1 -0
- package/dist/components/KuadrantPage/KuadrantPage.esm.js +93 -43
- package/dist/components/KuadrantPage/KuadrantPage.esm.js.map +1 -1
- package/dist/components/KuadrantPage/index.esm.js +1 -1
- package/dist/components/{MyApiKeysCard/MyApiKeysCard.esm.js → MyApiKeysTable/MyApiKeysTable.esm.js} +294 -176
- package/dist/components/MyApiKeysTable/MyApiKeysTable.esm.js.map +1 -0
- package/dist/components/PlanPolicyDetailsCard/PlanPolicyDetails.esm.js.map +1 -1
- package/dist/index.d.ts +8 -4
- package/dist/index.esm.js +1 -1
- package/dist/plugin.esm.js +30 -1
- package/dist/plugin.esm.js.map +1 -1
- package/dist/utils/styles.esm.js +14 -0
- package/dist/utils/styles.esm.js.map +1 -0
- package/dist-scalprum/{internal.plugin-kuadrant.90488643192ec2f36944.js → internal.plugin-kuadrant.a36ec4956222cb0faf61.js} +2 -2
- package/dist-scalprum/internal.plugin-kuadrant.a36ec4956222cb0faf61.js.map +1 -0
- package/dist-scalprum/plugin-manifest.json +2 -2
- package/dist-scalprum/static/2967.c684efaf.chunk.js +2 -0
- package/dist-scalprum/static/2967.c684efaf.chunk.js.map +1 -0
- package/dist-scalprum/static/3097.4bd6b35f.chunk.js +2 -0
- package/dist-scalprum/static/3097.4bd6b35f.chunk.js.map +1 -0
- package/dist-scalprum/static/4306.3a218ff1.chunk.js +2 -0
- package/dist-scalprum/static/4306.3a218ff1.chunk.js.map +1 -0
- package/dist-scalprum/static/5010.acf9a415.chunk.js +3 -0
- package/dist-scalprum/static/5010.acf9a415.chunk.js.map +1 -0
- package/dist-scalprum/static/5453.c1f90bdf.chunk.js +2 -0
- package/dist-scalprum/static/5453.c1f90bdf.chunk.js.map +1 -0
- package/dist-scalprum/static/6800.736d5da3.chunk.js +2 -0
- package/dist-scalprum/static/6800.736d5da3.chunk.js.map +1 -0
- package/dist-scalprum/static/6813.036a322f.chunk.js +2 -0
- package/dist-scalprum/static/6813.036a322f.chunk.js.map +1 -0
- package/dist-scalprum/static/6840.4728fab9.chunk.js +2 -0
- package/dist-scalprum/static/6840.4728fab9.chunk.js.map +1 -0
- package/dist-scalprum/static/6979.9699b350.chunk.js +2 -0
- package/dist-scalprum/static/6979.9699b350.chunk.js.map +1 -0
- package/dist-scalprum/static/7684.3d1fc1a1.chunk.js +2 -0
- package/dist-scalprum/static/7684.3d1fc1a1.chunk.js.map +1 -0
- package/dist-scalprum/static/8365.d3360f18.chunk.js +2 -0
- package/dist-scalprum/static/8365.d3360f18.chunk.js.map +1 -0
- package/dist-scalprum/static/8416.3604a311.chunk.js +2 -0
- package/dist-scalprum/static/8416.3604a311.chunk.js.map +1 -0
- package/dist-scalprum/static/8563.7e068fb0.chunk.js +3 -0
- package/dist-scalprum/static/8563.7e068fb0.chunk.js.map +1 -0
- package/dist-scalprum/static/exposed-PluginRoot.0717f1ce.chunk.js +2 -0
- package/dist-scalprum/static/exposed-PluginRoot.0717f1ce.chunk.js.map +1 -0
- package/package.json +1 -1
- package/dist/components/MyApiKeysCard/MyApiKeysCard.esm.js.map +0 -1
- package/dist-scalprum/internal.plugin-kuadrant.90488643192ec2f36944.js.map +0 -1
- package/dist-scalprum/static/1483.be69af13.chunk.js +0 -2
- package/dist-scalprum/static/1483.be69af13.chunk.js.map +0 -1
- package/dist-scalprum/static/3483.2f14a8ca.chunk.js +0 -3
- package/dist-scalprum/static/3483.2f14a8ca.chunk.js.map +0 -1
- package/dist-scalprum/static/4306.b68910c9.chunk.js +0 -2
- package/dist-scalprum/static/4306.b68910c9.chunk.js.map +0 -1
- package/dist-scalprum/static/4556.c6bedfc4.chunk.js +0 -3
- package/dist-scalprum/static/4556.c6bedfc4.chunk.js.map +0 -1
- package/dist-scalprum/static/5222.796292ca.chunk.js +0 -2
- package/dist-scalprum/static/5222.796292ca.chunk.js.map +0 -1
- package/dist-scalprum/static/532.146b1fd6.chunk.js +0 -2
- package/dist-scalprum/static/532.146b1fd6.chunk.js.map +0 -1
- package/dist-scalprum/static/5453.29118045.chunk.js +0 -2
- package/dist-scalprum/static/5453.29118045.chunk.js.map +0 -1
- package/dist-scalprum/static/6281.eb6e16a2.chunk.js +0 -2
- package/dist-scalprum/static/6281.eb6e16a2.chunk.js.map +0 -1
- package/dist-scalprum/static/8365.75ea3581.chunk.js +0 -2
- package/dist-scalprum/static/8365.75ea3581.chunk.js.map +0 -1
- package/dist-scalprum/static/exposed-PluginRoot.4183ceef.chunk.js +0 -2
- package/dist-scalprum/static/exposed-PluginRoot.4183ceef.chunk.js.map +0 -1
- /package/dist-scalprum/static/{4556.c6bedfc4.chunk.js.LICENSE.txt → 5010.acf9a415.chunk.js.LICENSE.txt} +0 -0
- /package/dist-scalprum/static/{3483.2f14a8ca.chunk.js.LICENSE.txt → 8563.7e068fb0.chunk.js.LICENSE.txt} +0 -0
|
@@ -9,36 +9,97 @@ import CheckCircleIcon from '@material-ui/icons/CheckCircle';
|
|
|
9
9
|
import CancelIcon from '@material-ui/icons/Cancel';
|
|
10
10
|
import ExpandMoreIcon from '@material-ui/icons/ExpandMore';
|
|
11
11
|
|
|
12
|
-
const ApprovalDialog = ({
|
|
12
|
+
const ApprovalDialog = ({
|
|
13
|
+
open,
|
|
14
|
+
request,
|
|
15
|
+
action,
|
|
16
|
+
processing,
|
|
17
|
+
onClose,
|
|
18
|
+
onConfirm
|
|
19
|
+
}) => {
|
|
13
20
|
const actionLabel = action === "approve" ? "Approve" : "Reject";
|
|
14
21
|
const processingLabel = action === "approve" ? "Approving..." : "Rejecting...";
|
|
15
|
-
return /* @__PURE__ */ React.createElement(
|
|
16
|
-
|
|
22
|
+
return /* @__PURE__ */ React.createElement(
|
|
23
|
+
Dialog,
|
|
17
24
|
{
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
startIcon: processing ? /* @__PURE__ */ React.createElement(CircularProgress, { size: 16, color: "inherit" }) : undefined
|
|
25
|
+
open,
|
|
26
|
+
onClose: processing ? undefined : onClose,
|
|
27
|
+
maxWidth: "sm",
|
|
28
|
+
fullWidth: true
|
|
23
29
|
},
|
|
24
|
-
|
|
25
|
-
|
|
30
|
+
/* @__PURE__ */ React.createElement(DialogTitle, null, actionLabel, " API Key"),
|
|
31
|
+
/* @__PURE__ */ React.createElement(DialogContent, null, request && /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement("p", null, /* @__PURE__ */ React.createElement("strong", null, "User:"), " ", request.spec.requestedBy.userId), /* @__PURE__ */ React.createElement("p", null, /* @__PURE__ */ React.createElement("strong", null, "API:"), " ", request.spec.apiProductRef?.name || "unknown"), /* @__PURE__ */ React.createElement("p", null, /* @__PURE__ */ React.createElement("strong", null, "Tier:"), " ", request.spec.planTier), /* @__PURE__ */ React.createElement(Box, { mb: 2 }, /* @__PURE__ */ React.createElement(
|
|
32
|
+
Typography,
|
|
33
|
+
{
|
|
34
|
+
variant: "body2",
|
|
35
|
+
component: "span",
|
|
36
|
+
style: { fontWeight: "bold" }
|
|
37
|
+
},
|
|
38
|
+
"Use Case:"
|
|
39
|
+
), " ", /* @__PURE__ */ React.createElement(
|
|
40
|
+
Typography,
|
|
41
|
+
{
|
|
42
|
+
variant: "body2",
|
|
43
|
+
component: "span",
|
|
44
|
+
style: { whiteSpace: "pre-wrap" }
|
|
45
|
+
},
|
|
46
|
+
request.spec.useCase || "-"
|
|
47
|
+
)))),
|
|
48
|
+
/* @__PURE__ */ React.createElement(DialogActions, null, /* @__PURE__ */ React.createElement(Button, { onClick: onClose, disabled: processing }, "Cancel"), /* @__PURE__ */ React.createElement(
|
|
49
|
+
Button,
|
|
50
|
+
{
|
|
51
|
+
onClick: onConfirm,
|
|
52
|
+
color: action === "approve" ? "primary" : "secondary",
|
|
53
|
+
variant: "contained",
|
|
54
|
+
disabled: processing,
|
|
55
|
+
startIcon: processing ? /* @__PURE__ */ React.createElement(CircularProgress, { size: 16, color: "inherit" }) : undefined
|
|
56
|
+
},
|
|
57
|
+
processing ? processingLabel : actionLabel
|
|
58
|
+
))
|
|
59
|
+
);
|
|
26
60
|
};
|
|
27
|
-
const BulkActionDialog = ({
|
|
61
|
+
const BulkActionDialog = ({
|
|
62
|
+
open,
|
|
63
|
+
requests,
|
|
64
|
+
action,
|
|
65
|
+
processing,
|
|
66
|
+
onClose,
|
|
67
|
+
onConfirm
|
|
68
|
+
}) => {
|
|
28
69
|
const isApprove = action === "approve";
|
|
29
70
|
const actionLabel = isApprove ? "Approve All" : "Reject All";
|
|
30
71
|
const processingLabel = isApprove ? "Approving..." : "Rejecting...";
|
|
31
|
-
return /* @__PURE__ */ React.createElement(
|
|
32
|
-
|
|
72
|
+
return /* @__PURE__ */ React.createElement(
|
|
73
|
+
Dialog,
|
|
33
74
|
{
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
startIcon: processing ? /* @__PURE__ */ React.createElement(CircularProgress, { size: 16, color: "inherit" }) : undefined
|
|
75
|
+
open,
|
|
76
|
+
onClose: processing ? undefined : onClose,
|
|
77
|
+
maxWidth: "md",
|
|
78
|
+
fullWidth: true
|
|
39
79
|
},
|
|
40
|
-
|
|
41
|
-
|
|
80
|
+
/* @__PURE__ */ React.createElement(DialogTitle, null, isApprove ? "Approve" : "Reject", " ", requests.length, " API Keys"),
|
|
81
|
+
/* @__PURE__ */ React.createElement(DialogContent, null, /* @__PURE__ */ React.createElement(Typography, { variant: "body2", paragraph: true }, "You are about to ", isApprove ? "approve" : "reject", " the following API keys:"), /* @__PURE__ */ React.createElement(Box, { mb: 2, maxHeight: 200, overflow: "auto" }, requests.map((request) => /* @__PURE__ */ React.createElement(
|
|
82
|
+
Box,
|
|
83
|
+
{
|
|
84
|
+
key: `${request.metadata.namespace}/${request.metadata.name}`,
|
|
85
|
+
mb: 1,
|
|
86
|
+
p: 1,
|
|
87
|
+
bgcolor: "background.default"
|
|
88
|
+
},
|
|
89
|
+
/* @__PURE__ */ React.createElement(Typography, { variant: "body2" }, /* @__PURE__ */ React.createElement("strong", null, request.spec.requestedBy.userId), " -", " ", request.spec.apiProductRef?.name || "unknown", " (", request.spec.planTier, ")")
|
|
90
|
+
)))),
|
|
91
|
+
/* @__PURE__ */ React.createElement(DialogActions, null, /* @__PURE__ */ React.createElement(Button, { onClick: onClose, disabled: processing }, "Cancel"), /* @__PURE__ */ React.createElement(
|
|
92
|
+
Button,
|
|
93
|
+
{
|
|
94
|
+
onClick: onConfirm,
|
|
95
|
+
color: isApprove ? "primary" : "secondary",
|
|
96
|
+
variant: "contained",
|
|
97
|
+
disabled: processing,
|
|
98
|
+
startIcon: processing ? /* @__PURE__ */ React.createElement(CircularProgress, { size: 16, color: "inherit" }) : undefined
|
|
99
|
+
},
|
|
100
|
+
processing ? processingLabel : actionLabel
|
|
101
|
+
))
|
|
102
|
+
);
|
|
42
103
|
};
|
|
43
104
|
const ApprovalQueueCard = () => {
|
|
44
105
|
const config = useApi(configApiRef);
|
|
@@ -76,14 +137,26 @@ const ApprovalQueueCard = () => {
|
|
|
76
137
|
const { value, loading, error } = useAsync(async () => {
|
|
77
138
|
const identity = await identityApi.getBackstageIdentity();
|
|
78
139
|
const reviewedBy = identity.userEntityRef;
|
|
79
|
-
console.log(
|
|
140
|
+
console.log(
|
|
141
|
+
"ApprovalQueueCard: fetching all requests from",
|
|
142
|
+
`${backendUrl}/api/kuadrant/requests`
|
|
143
|
+
);
|
|
80
144
|
const [requestsResponse, apiProductsResponse] = await Promise.all([
|
|
81
145
|
fetchApi.fetch(`${backendUrl}/api/kuadrant/requests`),
|
|
82
146
|
fetchApi.fetch(`${backendUrl}/api/kuadrant/apiproducts`)
|
|
83
147
|
]);
|
|
84
148
|
if (!requestsResponse.ok) {
|
|
85
|
-
console.log(
|
|
86
|
-
|
|
149
|
+
console.log(
|
|
150
|
+
"ApprovalQueueCard: failed to fetch requests, status:",
|
|
151
|
+
requestsResponse.status
|
|
152
|
+
);
|
|
153
|
+
return {
|
|
154
|
+
pending: [],
|
|
155
|
+
approved: [],
|
|
156
|
+
rejected: [],
|
|
157
|
+
reviewedBy,
|
|
158
|
+
ownedApiProducts: /* @__PURE__ */ new Set()
|
|
159
|
+
};
|
|
87
160
|
}
|
|
88
161
|
const contentType = requestsResponse.headers.get("content-type");
|
|
89
162
|
if (!contentType?.includes("application/json")) {
|
|
@@ -93,7 +166,13 @@ const ApprovalQueueCard = () => {
|
|
|
93
166
|
display: "transient",
|
|
94
167
|
severity: "warning"
|
|
95
168
|
});
|
|
96
|
-
return {
|
|
169
|
+
return {
|
|
170
|
+
pending: [],
|
|
171
|
+
approved: [],
|
|
172
|
+
rejected: [],
|
|
173
|
+
reviewedBy,
|
|
174
|
+
ownedApiProducts: /* @__PURE__ */ new Set()
|
|
175
|
+
};
|
|
97
176
|
}
|
|
98
177
|
const data = await requestsResponse.json();
|
|
99
178
|
const allRequests = data.items || [];
|
|
@@ -103,12 +182,22 @@ const ApprovalQueueCard = () => {
|
|
|
103
182
|
for (const product of apiProductsData.items || []) {
|
|
104
183
|
const owner = product.metadata?.annotations?.["backstage.io/owner"];
|
|
105
184
|
if (owner === reviewedBy) {
|
|
106
|
-
ownedApiProducts.add(
|
|
185
|
+
ownedApiProducts.add(
|
|
186
|
+
`${product.metadata.namespace}/${product.metadata.name}`
|
|
187
|
+
);
|
|
107
188
|
}
|
|
108
189
|
}
|
|
109
190
|
}
|
|
110
|
-
console.log(
|
|
111
|
-
|
|
191
|
+
console.log(
|
|
192
|
+
"ApprovalQueueCard: received",
|
|
193
|
+
allRequests.length,
|
|
194
|
+
"total requests"
|
|
195
|
+
);
|
|
196
|
+
console.log(
|
|
197
|
+
"ApprovalQueueCard: user owns",
|
|
198
|
+
ownedApiProducts.size,
|
|
199
|
+
"api products"
|
|
200
|
+
);
|
|
112
201
|
const pending2 = allRequests.filter((r) => {
|
|
113
202
|
const phase = r.status?.phase || "Pending";
|
|
114
203
|
return phase === "Pending";
|
|
@@ -129,10 +218,20 @@ const ApprovalQueueCard = () => {
|
|
|
129
218
|
return { pending: pending2, approved: approved2, rejected: rejected2, reviewedBy, ownedApiProducts };
|
|
130
219
|
}, [backendUrl, fetchApi, identityApi, refresh]);
|
|
131
220
|
const handleApprove = (request) => {
|
|
132
|
-
setDialogState({
|
|
221
|
+
setDialogState({
|
|
222
|
+
open: true,
|
|
223
|
+
request,
|
|
224
|
+
action: "approve",
|
|
225
|
+
processing: false
|
|
226
|
+
});
|
|
133
227
|
};
|
|
134
228
|
const handleReject = (request) => {
|
|
135
|
-
setDialogState({
|
|
229
|
+
setDialogState({
|
|
230
|
+
open: true,
|
|
231
|
+
request,
|
|
232
|
+
action: "reject",
|
|
233
|
+
processing: false
|
|
234
|
+
});
|
|
136
235
|
};
|
|
137
236
|
const handleConfirm = async () => {
|
|
138
237
|
if (!dialogState.request || !value) return;
|
|
@@ -149,23 +248,46 @@ const ApprovalQueueCard = () => {
|
|
|
149
248
|
if (!response.ok) {
|
|
150
249
|
throw new Error(`failed to ${dialogState.action} request`);
|
|
151
250
|
}
|
|
152
|
-
setDialogState({
|
|
251
|
+
setDialogState({
|
|
252
|
+
open: false,
|
|
253
|
+
request: null,
|
|
254
|
+
action: "approve",
|
|
255
|
+
processing: false
|
|
256
|
+
});
|
|
153
257
|
setRefresh((r) => r + 1);
|
|
154
258
|
const action = dialogState.action === "approve" ? "approved" : "rejected";
|
|
155
|
-
alertApi.post({
|
|
259
|
+
alertApi.post({
|
|
260
|
+
message: `API key ${action}`,
|
|
261
|
+
severity: "success",
|
|
262
|
+
display: "transient"
|
|
263
|
+
});
|
|
156
264
|
} catch (err) {
|
|
157
265
|
console.error(`error ${dialogState.action}ing request:`, err);
|
|
158
266
|
setDialogState((prev) => ({ ...prev, processing: false }));
|
|
159
|
-
alertApi.post({
|
|
267
|
+
alertApi.post({
|
|
268
|
+
message: `Failed to ${dialogState.action} API key`,
|
|
269
|
+
severity: "error",
|
|
270
|
+
display: "transient"
|
|
271
|
+
});
|
|
160
272
|
}
|
|
161
273
|
};
|
|
162
274
|
const handleBulkApprove = () => {
|
|
163
275
|
if (selectedRequests.length === 0) return;
|
|
164
|
-
setBulkDialogState({
|
|
276
|
+
setBulkDialogState({
|
|
277
|
+
open: true,
|
|
278
|
+
requests: selectedRequests,
|
|
279
|
+
action: "approve",
|
|
280
|
+
processing: false
|
|
281
|
+
});
|
|
165
282
|
};
|
|
166
283
|
const handleBulkReject = () => {
|
|
167
284
|
if (selectedRequests.length === 0) return;
|
|
168
|
-
setBulkDialogState({
|
|
285
|
+
setBulkDialogState({
|
|
286
|
+
open: true,
|
|
287
|
+
requests: selectedRequests,
|
|
288
|
+
action: "reject",
|
|
289
|
+
processing: false
|
|
290
|
+
});
|
|
169
291
|
};
|
|
170
292
|
const handleBulkConfirm = async () => {
|
|
171
293
|
if (!value || bulkDialogState.requests.length === 0) return;
|
|
@@ -189,14 +311,27 @@ const ApprovalQueueCard = () => {
|
|
|
189
311
|
}
|
|
190
312
|
const count = bulkDialogState.requests.length;
|
|
191
313
|
const action = isApprove ? "approved" : "rejected";
|
|
192
|
-
setBulkDialogState({
|
|
314
|
+
setBulkDialogState({
|
|
315
|
+
open: false,
|
|
316
|
+
requests: [],
|
|
317
|
+
action: "approve",
|
|
318
|
+
processing: false
|
|
319
|
+
});
|
|
193
320
|
setSelectedRequests([]);
|
|
194
321
|
setRefresh((r) => r + 1);
|
|
195
|
-
alertApi.post({
|
|
322
|
+
alertApi.post({
|
|
323
|
+
message: `${count} API keys ${action}`,
|
|
324
|
+
severity: "success",
|
|
325
|
+
display: "transient"
|
|
326
|
+
});
|
|
196
327
|
} catch (err) {
|
|
197
328
|
console.error(`error bulk ${bulkDialogState.action}ing requests:`, err);
|
|
198
329
|
setBulkDialogState((prev) => ({ ...prev, processing: false }));
|
|
199
|
-
alertApi.post({
|
|
330
|
+
alertApi.post({
|
|
331
|
+
message: `Failed to bulk ${bulkDialogState.action} API keys`,
|
|
332
|
+
severity: "error",
|
|
333
|
+
display: "transient"
|
|
334
|
+
});
|
|
200
335
|
}
|
|
201
336
|
};
|
|
202
337
|
if (loading || updatePermissionLoading) {
|
|
@@ -223,7 +358,7 @@ const ApprovalQueueCard = () => {
|
|
|
223
358
|
};
|
|
224
359
|
const pendingColumns = [
|
|
225
360
|
{
|
|
226
|
-
title: "
|
|
361
|
+
title: "Name",
|
|
227
362
|
field: "metadata.name",
|
|
228
363
|
render: (row) => /* @__PURE__ */ React.createElement(Typography, { variant: "body2" }, row.metadata.name)
|
|
229
364
|
},
|
|
@@ -245,13 +380,7 @@ const ApprovalQueueCard = () => {
|
|
|
245
380
|
{
|
|
246
381
|
title: "Tier",
|
|
247
382
|
field: "spec.planTier",
|
|
248
|
-
render: (row) => /* @__PURE__ */ React.createElement(
|
|
249
|
-
Chip,
|
|
250
|
-
{
|
|
251
|
-
label: row.spec.planTier,
|
|
252
|
-
size: "small"
|
|
253
|
-
}
|
|
254
|
-
)
|
|
383
|
+
render: (row) => /* @__PURE__ */ React.createElement(Chip, { label: row.spec.planTier, size: "small" })
|
|
255
384
|
},
|
|
256
385
|
{
|
|
257
386
|
title: "Use Case",
|
|
@@ -314,7 +443,7 @@ const ApprovalQueueCard = () => {
|
|
|
314
443
|
];
|
|
315
444
|
const approvedColumns = [
|
|
316
445
|
{
|
|
317
|
-
title: "
|
|
446
|
+
title: "Name",
|
|
318
447
|
field: "metadata.name",
|
|
319
448
|
render: (row) => /* @__PURE__ */ React.createElement(Typography, { variant: "body2" }, row.metadata.name)
|
|
320
449
|
},
|
|
@@ -336,13 +465,7 @@ const ApprovalQueueCard = () => {
|
|
|
336
465
|
{
|
|
337
466
|
title: "Tier",
|
|
338
467
|
field: "spec.planTier",
|
|
339
|
-
render: (row) => /* @__PURE__ */ React.createElement(
|
|
340
|
-
Chip,
|
|
341
|
-
{
|
|
342
|
-
label: row.spec.planTier,
|
|
343
|
-
size: "small"
|
|
344
|
-
}
|
|
345
|
-
)
|
|
468
|
+
render: (row) => /* @__PURE__ */ React.createElement(Chip, { label: row.spec.planTier, size: "small" })
|
|
346
469
|
},
|
|
347
470
|
{
|
|
348
471
|
title: "Requested",
|
|
@@ -377,7 +500,7 @@ const ApprovalQueueCard = () => {
|
|
|
377
500
|
];
|
|
378
501
|
const rejectedColumns = [
|
|
379
502
|
{
|
|
380
|
-
title: "
|
|
503
|
+
title: "Name",
|
|
381
504
|
field: "metadata.name",
|
|
382
505
|
render: (row) => /* @__PURE__ */ React.createElement(Typography, { variant: "body2" }, row.metadata.name)
|
|
383
506
|
},
|
|
@@ -399,13 +522,7 @@ const ApprovalQueueCard = () => {
|
|
|
399
522
|
{
|
|
400
523
|
title: "Tier",
|
|
401
524
|
field: "spec.planTier",
|
|
402
|
-
render: (row) => /* @__PURE__ */ React.createElement(
|
|
403
|
-
Chip,
|
|
404
|
-
{
|
|
405
|
-
label: row.spec.planTier,
|
|
406
|
-
size: "small"
|
|
407
|
-
}
|
|
408
|
-
)
|
|
525
|
+
render: (row) => /* @__PURE__ */ React.createElement(Chip, { label: row.spec.planTier, size: "small" })
|
|
409
526
|
},
|
|
410
527
|
{
|
|
411
528
|
title: "Requested",
|
|
@@ -436,13 +553,29 @@ const ApprovalQueueCard = () => {
|
|
|
436
553
|
tableData: { checked: isSelected }
|
|
437
554
|
};
|
|
438
555
|
});
|
|
439
|
-
return {
|
|
556
|
+
return {
|
|
557
|
+
data: pendingWithSelection,
|
|
558
|
+
columns: pendingColumns,
|
|
559
|
+
showSelection: true
|
|
560
|
+
};
|
|
440
561
|
case 1:
|
|
441
|
-
return {
|
|
562
|
+
return {
|
|
563
|
+
data: addIds(approved),
|
|
564
|
+
columns: approvedColumns,
|
|
565
|
+
showSelection: false
|
|
566
|
+
};
|
|
442
567
|
case 2:
|
|
443
|
-
return {
|
|
568
|
+
return {
|
|
569
|
+
data: addIds(rejected),
|
|
570
|
+
columns: rejectedColumns,
|
|
571
|
+
showSelection: false
|
|
572
|
+
};
|
|
444
573
|
default:
|
|
445
|
-
return {
|
|
574
|
+
return {
|
|
575
|
+
data: addIds(pending),
|
|
576
|
+
columns: pendingColumns,
|
|
577
|
+
showSelection: true
|
|
578
|
+
};
|
|
446
579
|
}
|
|
447
580
|
};
|
|
448
581
|
const tabData = getTabData();
|
|
@@ -477,68 +610,119 @@ const ApprovalQueueCard = () => {
|
|
|
477
610
|
textColor: "primary",
|
|
478
611
|
"data-testid": "approval-queue-tabs"
|
|
479
612
|
},
|
|
480
|
-
/* @__PURE__ */ React.createElement(
|
|
481
|
-
|
|
482
|
-
|
|
613
|
+
/* @__PURE__ */ React.createElement(
|
|
614
|
+
Tab,
|
|
615
|
+
{
|
|
616
|
+
label: `Pending (${pending.length})`,
|
|
617
|
+
"data-testid": "approval-queue-pending-tab"
|
|
618
|
+
}
|
|
619
|
+
),
|
|
620
|
+
/* @__PURE__ */ React.createElement(
|
|
621
|
+
Tab,
|
|
622
|
+
{
|
|
623
|
+
label: `Approved (${approved.length})`,
|
|
624
|
+
"data-testid": "approval-queue-approved-tab"
|
|
625
|
+
}
|
|
626
|
+
),
|
|
627
|
+
/* @__PURE__ */ React.createElement(
|
|
628
|
+
Tab,
|
|
629
|
+
{
|
|
630
|
+
label: `Rejected (${rejected.length})`,
|
|
631
|
+
"data-testid": "approval-queue-rejected-tab"
|
|
632
|
+
}
|
|
633
|
+
)
|
|
483
634
|
)),
|
|
484
|
-
selectedTab === 0 && selectedRequests.length > 0 && /* @__PURE__ */ React.createElement(
|
|
485
|
-
|
|
486
|
-
{
|
|
487
|
-
size: "small",
|
|
488
|
-
variant: "contained",
|
|
489
|
-
color: "primary",
|
|
490
|
-
startIcon: /* @__PURE__ */ React.createElement(CheckCircleIcon, null),
|
|
491
|
-
onClick: handleBulkApprove
|
|
492
|
-
},
|
|
493
|
-
"Approve Selected"
|
|
494
|
-
), /* @__PURE__ */ React.createElement(
|
|
495
|
-
Button,
|
|
635
|
+
selectedTab === 0 && selectedRequests.length > 0 && /* @__PURE__ */ React.createElement(
|
|
636
|
+
Box,
|
|
496
637
|
{
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
638
|
+
mb: 2,
|
|
639
|
+
display: "flex",
|
|
640
|
+
alignItems: "center",
|
|
641
|
+
justifyContent: "space-between",
|
|
642
|
+
p: 2,
|
|
643
|
+
bgcolor: "background.default"
|
|
502
644
|
},
|
|
503
|
-
"
|
|
504
|
-
|
|
645
|
+
/* @__PURE__ */ React.createElement(Typography, { variant: "body2" }, selectedRequests.length, " request", selectedRequests.length !== 1 ? "s" : "", " selected"),
|
|
646
|
+
/* @__PURE__ */ React.createElement(Box, { display: "flex", style: { gap: 8 } }, /* @__PURE__ */ React.createElement(
|
|
647
|
+
Button,
|
|
648
|
+
{
|
|
649
|
+
size: "small",
|
|
650
|
+
variant: "contained",
|
|
651
|
+
color: "primary",
|
|
652
|
+
startIcon: /* @__PURE__ */ React.createElement(CheckCircleIcon, null),
|
|
653
|
+
onClick: handleBulkApprove
|
|
654
|
+
},
|
|
655
|
+
"Approve Selected"
|
|
656
|
+
), /* @__PURE__ */ React.createElement(
|
|
657
|
+
Button,
|
|
658
|
+
{
|
|
659
|
+
size: "small",
|
|
660
|
+
variant: "contained",
|
|
661
|
+
color: "secondary",
|
|
662
|
+
startIcon: /* @__PURE__ */ React.createElement(CancelIcon, null),
|
|
663
|
+
onClick: handleBulkReject
|
|
664
|
+
},
|
|
665
|
+
"Reject Selected"
|
|
666
|
+
))
|
|
667
|
+
),
|
|
505
668
|
tabData.data.length === 0 ? /* @__PURE__ */ React.createElement(Box, { p: 3, textAlign: "center" }, /* @__PURE__ */ React.createElement(Typography, { variant: "body1", color: "textSecondary" }, selectedTab === 0 && "No pending requests.", selectedTab === 1 && "No approved requests.", selectedTab === 2 && "No rejected requests.")) : /* @__PURE__ */ React.createElement(Box, null, apiProductKeys.map((apiProductKey) => {
|
|
506
669
|
const requests = groupedData.get(apiProductKey) || [];
|
|
507
670
|
const displayName = requests[0]?.spec.apiProductRef?.name || apiProductKey;
|
|
508
671
|
const ownsThisApiProduct = value?.ownedApiProducts?.has(apiProductKey) ?? false;
|
|
509
672
|
const canSelectRows = canUpdateAllRequests || canUpdateOwnRequests && ownsThisApiProduct;
|
|
510
|
-
return /* @__PURE__ */ React.createElement(
|
|
511
|
-
|
|
673
|
+
return /* @__PURE__ */ React.createElement(
|
|
674
|
+
Accordion,
|
|
512
675
|
{
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
paging: requests.length > 5,
|
|
524
|
-
pageSize: 20,
|
|
525
|
-
search: true,
|
|
526
|
-
filtering: true,
|
|
527
|
-
debounceInterval: 300,
|
|
528
|
-
showTextRowsSelected: false,
|
|
529
|
-
toolbar: true,
|
|
530
|
-
emptyRowsWhenPaging: false
|
|
676
|
+
key: apiProductKey,
|
|
677
|
+
defaultExpanded: apiProductKeys.length === 1
|
|
678
|
+
},
|
|
679
|
+
/* @__PURE__ */ React.createElement(AccordionSummary, { expandIcon: /* @__PURE__ */ React.createElement(ExpandMoreIcon, null) }, /* @__PURE__ */ React.createElement(
|
|
680
|
+
Box,
|
|
681
|
+
{
|
|
682
|
+
display: "flex",
|
|
683
|
+
alignItems: "center",
|
|
684
|
+
justifyContent: "space-between",
|
|
685
|
+
width: "100%"
|
|
531
686
|
},
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
687
|
+
/* @__PURE__ */ React.createElement(Typography, { variant: "h6" }, displayName),
|
|
688
|
+
/* @__PURE__ */ React.createElement(
|
|
689
|
+
Chip,
|
|
690
|
+
{
|
|
691
|
+
label: `${requests.length} request${requests.length !== 1 ? "s" : ""}`,
|
|
692
|
+
size: "small",
|
|
693
|
+
color: "primary",
|
|
694
|
+
style: { marginRight: 16 }
|
|
695
|
+
}
|
|
696
|
+
)
|
|
697
|
+
)),
|
|
698
|
+
/* @__PURE__ */ React.createElement(AccordionDetails, null, /* @__PURE__ */ React.createElement(Box, { width: "100%" }, /* @__PURE__ */ React.createElement(
|
|
699
|
+
Table,
|
|
700
|
+
{
|
|
701
|
+
options: {
|
|
702
|
+
selection: canSelectRows && tabData.showSelection,
|
|
703
|
+
paging: requests.length > 5,
|
|
704
|
+
pageSize: 20,
|
|
705
|
+
search: true,
|
|
706
|
+
filtering: true,
|
|
707
|
+
debounceInterval: 300,
|
|
708
|
+
showTextRowsSelected: false,
|
|
709
|
+
toolbar: true,
|
|
710
|
+
emptyRowsWhenPaging: false
|
|
711
|
+
},
|
|
712
|
+
data: requests,
|
|
713
|
+
columns: tabData.columns,
|
|
714
|
+
onSelectionChange: (rows) => {
|
|
715
|
+
const otherSelections = selectedRequests.filter(
|
|
716
|
+
(r) => `${r.metadata.namespace}/${r.spec.apiProductRef?.name || "unknown"}` !== apiProductKey
|
|
717
|
+
);
|
|
718
|
+
setSelectedRequests([
|
|
719
|
+
...otherSelections,
|
|
720
|
+
...rows
|
|
721
|
+
]);
|
|
722
|
+
}
|
|
539
723
|
}
|
|
540
|
-
|
|
541
|
-
)
|
|
724
|
+
)))
|
|
725
|
+
);
|
|
542
726
|
}))
|
|
543
727
|
), /* @__PURE__ */ React.createElement(
|
|
544
728
|
ApprovalDialog,
|
|
@@ -547,7 +731,12 @@ const ApprovalQueueCard = () => {
|
|
|
547
731
|
request: dialogState.request,
|
|
548
732
|
action: dialogState.action,
|
|
549
733
|
processing: dialogState.processing,
|
|
550
|
-
onClose: () => setDialogState({
|
|
734
|
+
onClose: () => setDialogState({
|
|
735
|
+
open: false,
|
|
736
|
+
request: null,
|
|
737
|
+
action: "approve",
|
|
738
|
+
processing: false
|
|
739
|
+
}),
|
|
551
740
|
onConfirm: handleConfirm
|
|
552
741
|
}
|
|
553
742
|
), /* @__PURE__ */ React.createElement(
|
|
@@ -557,7 +746,12 @@ const ApprovalQueueCard = () => {
|
|
|
557
746
|
requests: bulkDialogState.requests,
|
|
558
747
|
action: bulkDialogState.action,
|
|
559
748
|
processing: bulkDialogState.processing,
|
|
560
|
-
onClose: () => setBulkDialogState({
|
|
749
|
+
onClose: () => setBulkDialogState({
|
|
750
|
+
open: false,
|
|
751
|
+
requests: [],
|
|
752
|
+
action: "approve",
|
|
753
|
+
processing: false
|
|
754
|
+
}),
|
|
561
755
|
onConfirm: handleBulkConfirm
|
|
562
756
|
}
|
|
563
757
|
));
|