@kuadrant/kuadrant-backstage-plugin-frontend 0.0.2-dev-61ff3d3 → 0.0.2-dev-b696169

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.
Files changed (90) hide show
  1. package/dist/components/ApiKeyDetailPage/ApiKeyDetailPage.esm.js +319 -0
  2. package/dist/components/ApiKeyDetailPage/ApiKeyDetailPage.esm.js.map +1 -0
  3. package/dist/components/ApiKeyDetailPage/index.esm.js +2 -0
  4. package/dist/components/ApiKeyDetailPage/index.esm.js.map +1 -0
  5. package/dist/components/ApiKeyManagementTab/ApiKeyManagementTab.esm.js +340 -162
  6. package/dist/components/ApiKeyManagementTab/ApiKeyManagementTab.esm.js.map +1 -1
  7. package/dist/components/ApiKeysPage/ApiKeysPage.esm.js +43 -0
  8. package/dist/components/ApiKeysPage/ApiKeysPage.esm.js.map +1 -0
  9. package/dist/components/ApiKeysPage/index.esm.js +2 -0
  10. package/dist/components/ApiKeysPage/index.esm.js.map +1 -0
  11. package/dist/components/ApprovalQueueCard/ApprovalQueueCard.esm.js +312 -118
  12. package/dist/components/ApprovalQueueCard/ApprovalQueueCard.esm.js.map +1 -1
  13. package/dist/components/ApprovalQueueTable/ApprovalQueueTable.esm.js +645 -0
  14. package/dist/components/ApprovalQueueTable/ApprovalQueueTable.esm.js.map +1 -0
  15. package/dist/components/EditAPIKeyDialog/EditAPIKeyDialog.esm.js +14 -2
  16. package/dist/components/EditAPIKeyDialog/EditAPIKeyDialog.esm.js.map +1 -1
  17. package/dist/components/EntityApiApprovalTab/EntityApiApprovalTab.esm.js +276 -0
  18. package/dist/components/EntityApiApprovalTab/EntityApiApprovalTab.esm.js.map +1 -0
  19. package/dist/components/EntityApiApprovalTab/index.esm.js +2 -0
  20. package/dist/components/EntityApiApprovalTab/index.esm.js.map +1 -0
  21. package/dist/components/FilterPanel/FilterPanel.esm.js +127 -0
  22. package/dist/components/FilterPanel/FilterPanel.esm.js.map +1 -0
  23. package/dist/components/KuadrantPage/KuadrantPage.esm.js +93 -43
  24. package/dist/components/KuadrantPage/KuadrantPage.esm.js.map +1 -1
  25. package/dist/components/KuadrantPage/index.esm.js +1 -1
  26. package/dist/components/{MyApiKeysCard/MyApiKeysCard.esm.js → MyApiKeysTable/MyApiKeysTable.esm.js} +294 -176
  27. package/dist/components/MyApiKeysTable/MyApiKeysTable.esm.js.map +1 -0
  28. package/dist/components/PlanPolicyDetailsCard/PlanPolicyDetails.esm.js.map +1 -1
  29. package/dist/index.d.ts +8 -4
  30. package/dist/index.esm.js +1 -1
  31. package/dist/plugin.esm.js +30 -1
  32. package/dist/plugin.esm.js.map +1 -1
  33. package/dist/utils/styles.esm.js +14 -0
  34. package/dist/utils/styles.esm.js.map +1 -0
  35. package/dist-scalprum/{internal.plugin-kuadrant.90488643192ec2f36944.js → internal.plugin-kuadrant.e37d8046ec4d7ed991e0.js} +2 -2
  36. package/dist-scalprum/internal.plugin-kuadrant.e37d8046ec4d7ed991e0.js.map +1 -0
  37. package/dist-scalprum/plugin-manifest.json +2 -2
  38. package/dist-scalprum/static/2967.c684efaf.chunk.js +2 -0
  39. package/dist-scalprum/static/2967.c684efaf.chunk.js.map +1 -0
  40. package/dist-scalprum/static/3097.4bd6b35f.chunk.js +2 -0
  41. package/dist-scalprum/static/3097.4bd6b35f.chunk.js.map +1 -0
  42. package/dist-scalprum/static/4306.3a218ff1.chunk.js +2 -0
  43. package/dist-scalprum/static/4306.3a218ff1.chunk.js.map +1 -0
  44. package/dist-scalprum/static/5010.acf9a415.chunk.js +3 -0
  45. package/dist-scalprum/static/5010.acf9a415.chunk.js.map +1 -0
  46. package/dist-scalprum/static/5453.ae292ab1.chunk.js +2 -0
  47. package/dist-scalprum/static/5453.ae292ab1.chunk.js.map +1 -0
  48. package/dist-scalprum/static/6800.736d5da3.chunk.js +2 -0
  49. package/dist-scalprum/static/6800.736d5da3.chunk.js.map +1 -0
  50. package/dist-scalprum/static/6813.036a322f.chunk.js +2 -0
  51. package/dist-scalprum/static/6813.036a322f.chunk.js.map +1 -0
  52. package/dist-scalprum/static/6840.4728fab9.chunk.js +2 -0
  53. package/dist-scalprum/static/6840.4728fab9.chunk.js.map +1 -0
  54. package/dist-scalprum/static/6979.9699b350.chunk.js +2 -0
  55. package/dist-scalprum/static/6979.9699b350.chunk.js.map +1 -0
  56. package/dist-scalprum/static/7684.3d1fc1a1.chunk.js +2 -0
  57. package/dist-scalprum/static/7684.3d1fc1a1.chunk.js.map +1 -0
  58. package/dist-scalprum/static/8365.d3360f18.chunk.js +2 -0
  59. package/dist-scalprum/static/8365.d3360f18.chunk.js.map +1 -0
  60. package/dist-scalprum/static/8416.3604a311.chunk.js +2 -0
  61. package/dist-scalprum/static/8416.3604a311.chunk.js.map +1 -0
  62. package/dist-scalprum/static/8563.7e068fb0.chunk.js +3 -0
  63. package/dist-scalprum/static/8563.7e068fb0.chunk.js.map +1 -0
  64. package/dist-scalprum/static/exposed-PluginRoot.0717f1ce.chunk.js +2 -0
  65. package/dist-scalprum/static/exposed-PluginRoot.0717f1ce.chunk.js.map +1 -0
  66. package/package.json +1 -1
  67. package/dist/components/MyApiKeysCard/MyApiKeysCard.esm.js.map +0 -1
  68. package/dist-scalprum/internal.plugin-kuadrant.90488643192ec2f36944.js.map +0 -1
  69. package/dist-scalprum/static/1483.be69af13.chunk.js +0 -2
  70. package/dist-scalprum/static/1483.be69af13.chunk.js.map +0 -1
  71. package/dist-scalprum/static/3483.2f14a8ca.chunk.js +0 -3
  72. package/dist-scalprum/static/3483.2f14a8ca.chunk.js.map +0 -1
  73. package/dist-scalprum/static/4306.b68910c9.chunk.js +0 -2
  74. package/dist-scalprum/static/4306.b68910c9.chunk.js.map +0 -1
  75. package/dist-scalprum/static/4556.c6bedfc4.chunk.js +0 -3
  76. package/dist-scalprum/static/4556.c6bedfc4.chunk.js.map +0 -1
  77. package/dist-scalprum/static/5222.796292ca.chunk.js +0 -2
  78. package/dist-scalprum/static/5222.796292ca.chunk.js.map +0 -1
  79. package/dist-scalprum/static/532.146b1fd6.chunk.js +0 -2
  80. package/dist-scalprum/static/532.146b1fd6.chunk.js.map +0 -1
  81. package/dist-scalprum/static/5453.29118045.chunk.js +0 -2
  82. package/dist-scalprum/static/5453.29118045.chunk.js.map +0 -1
  83. package/dist-scalprum/static/6281.eb6e16a2.chunk.js +0 -2
  84. package/dist-scalprum/static/6281.eb6e16a2.chunk.js.map +0 -1
  85. package/dist-scalprum/static/8365.75ea3581.chunk.js +0 -2
  86. package/dist-scalprum/static/8365.75ea3581.chunk.js.map +0 -1
  87. package/dist-scalprum/static/exposed-PluginRoot.4183ceef.chunk.js +0 -2
  88. package/dist-scalprum/static/exposed-PluginRoot.4183ceef.chunk.js.map +0 -1
  89. /package/dist-scalprum/static/{4556.c6bedfc4.chunk.js.LICENSE.txt → 5010.acf9a415.chunk.js.LICENSE.txt} +0 -0
  90. /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 = ({ open, request, action, processing, onClose, onConfirm }) => {
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(Dialog, { open, onClose: processing ? undefined : onClose, maxWidth: "sm", fullWidth: true }, /* @__PURE__ */ React.createElement(DialogTitle, null, actionLabel, " API Key Request"), /* @__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(Typography, { variant: "body2", component: "span", style: { fontWeight: "bold" } }, "Use Case:"), " ", /* @__PURE__ */ React.createElement(Typography, { variant: "body2", component: "span", style: { whiteSpace: "pre-wrap" } }, request.spec.useCase || "-")))), /* @__PURE__ */ React.createElement(DialogActions, null, /* @__PURE__ */ React.createElement(Button, { onClick: onClose, disabled: processing }, "Cancel"), /* @__PURE__ */ React.createElement(
16
- Button,
22
+ return /* @__PURE__ */ React.createElement(
23
+ Dialog,
17
24
  {
18
- onClick: onConfirm,
19
- color: action === "approve" ? "primary" : "secondary",
20
- variant: "contained",
21
- disabled: processing,
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
- processing ? processingLabel : actionLabel
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 = ({ open, requests, action, processing, onClose, onConfirm }) => {
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(Dialog, { open, onClose: processing ? undefined : onClose, maxWidth: "md", fullWidth: true }, /* @__PURE__ */ React.createElement(DialogTitle, null, isApprove ? "Approve" : "Reject", " ", requests.length, " API Key Requests"), /* @__PURE__ */ React.createElement(DialogContent, null, /* @__PURE__ */ React.createElement(Typography, { variant: "body2", paragraph: true }, "You are about to ", isApprove ? "approve" : "reject", " the following requests:"), /* @__PURE__ */ React.createElement(Box, { mb: 2, maxHeight: 200, overflow: "auto" }, requests.map((request) => /* @__PURE__ */ React.createElement(Box, { key: `${request.metadata.namespace}/${request.metadata.name}`, mb: 1, p: 1, bgcolor: "background.default" }, /* @__PURE__ */ React.createElement(Typography, { variant: "body2" }, /* @__PURE__ */ React.createElement("strong", null, request.spec.requestedBy.userId), " - ", request.spec.apiProductRef?.name || "unknown", " (", request.spec.planTier, ")"))))), /* @__PURE__ */ React.createElement(DialogActions, null, /* @__PURE__ */ React.createElement(Button, { onClick: onClose, disabled: processing }, "Cancel"), /* @__PURE__ */ React.createElement(
32
- Button,
72
+ return /* @__PURE__ */ React.createElement(
73
+ Dialog,
33
74
  {
34
- onClick: onConfirm,
35
- color: isApprove ? "primary" : "secondary",
36
- variant: "contained",
37
- disabled: processing,
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
- processing ? processingLabel : actionLabel
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("ApprovalQueueCard: fetching all requests from", `${backendUrl}/api/kuadrant/requests`);
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("ApprovalQueueCard: failed to fetch requests, status:", requestsResponse.status);
86
- return { pending: [], approved: [], rejected: [], reviewedBy, ownedApiProducts: /* @__PURE__ */ new Set() };
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 { pending: [], approved: [], rejected: [], reviewedBy, ownedApiProducts: /* @__PURE__ */ new Set() };
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(`${product.metadata.namespace}/${product.metadata.name}`);
185
+ ownedApiProducts.add(
186
+ `${product.metadata.namespace}/${product.metadata.name}`
187
+ );
107
188
  }
108
189
  }
109
190
  }
110
- console.log("ApprovalQueueCard: received", allRequests.length, "total requests");
111
- console.log("ApprovalQueueCard: user owns", ownedApiProducts.size, "api products");
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({ open: true, request, action: "approve", processing: false });
221
+ setDialogState({
222
+ open: true,
223
+ request,
224
+ action: "approve",
225
+ processing: false
226
+ });
133
227
  };
134
228
  const handleReject = (request) => {
135
- setDialogState({ open: true, request, action: "reject", processing: false });
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({ open: false, request: null, action: "approve", processing: false });
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({ message: `Request ${action}`, severity: "success", display: "transient" });
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({ message: `Failed to ${dialogState.action} request`, severity: "error", display: "transient" });
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({ open: true, requests: selectedRequests, action: "approve", processing: false });
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({ open: true, requests: selectedRequests, action: "reject", processing: false });
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({ open: false, requests: [], action: "approve", processing: false });
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({ message: `${count} requests ${action}`, severity: "success", display: "transient" });
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({ message: `Failed to bulk ${bulkDialogState.action} requests`, severity: "error", display: "transient" });
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: "Request Name",
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: "Request Name",
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: "Request Name",
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 { data: pendingWithSelection, columns: pendingColumns, showSelection: true };
556
+ return {
557
+ data: pendingWithSelection,
558
+ columns: pendingColumns,
559
+ showSelection: true
560
+ };
440
561
  case 1:
441
- return { data: addIds(approved), columns: approvedColumns, showSelection: false };
562
+ return {
563
+ data: addIds(approved),
564
+ columns: approvedColumns,
565
+ showSelection: false
566
+ };
442
567
  case 2:
443
- return { data: addIds(rejected), columns: rejectedColumns, showSelection: false };
568
+ return {
569
+ data: addIds(rejected),
570
+ columns: rejectedColumns,
571
+ showSelection: false
572
+ };
444
573
  default:
445
- return { data: addIds(pending), columns: pendingColumns, showSelection: true };
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(Tab, { label: `Pending (${pending.length})`, "data-testid": "approval-queue-pending-tab" }),
481
- /* @__PURE__ */ React.createElement(Tab, { label: `Approved (${approved.length})`, "data-testid": "approval-queue-approved-tab" }),
482
- /* @__PURE__ */ React.createElement(Tab, { label: `Rejected (${rejected.length})`, "data-testid": "approval-queue-rejected-tab" })
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(Box, { mb: 2, display: "flex", alignItems: "center", justifyContent: "space-between", p: 2, bgcolor: "background.default" }, /* @__PURE__ */ React.createElement(Typography, { variant: "body2" }, selectedRequests.length, " request", selectedRequests.length !== 1 ? "s" : "", " selected"), /* @__PURE__ */ React.createElement(Box, { display: "flex", style: { gap: 8 } }, /* @__PURE__ */ React.createElement(
485
- Button,
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
- size: "small",
498
- variant: "contained",
499
- color: "secondary",
500
- startIcon: /* @__PURE__ */ React.createElement(CancelIcon, null),
501
- onClick: handleBulkReject
638
+ mb: 2,
639
+ display: "flex",
640
+ alignItems: "center",
641
+ justifyContent: "space-between",
642
+ p: 2,
643
+ bgcolor: "background.default"
502
644
  },
503
- "Reject Selected"
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(Accordion, { key: apiProductKey, defaultExpanded: apiProductKeys.length === 1 }, /* @__PURE__ */ React.createElement(AccordionSummary, { expandIcon: /* @__PURE__ */ React.createElement(ExpandMoreIcon, null) }, /* @__PURE__ */ React.createElement(Box, { display: "flex", alignItems: "center", justifyContent: "space-between", width: "100%" }, /* @__PURE__ */ React.createElement(Typography, { variant: "h6" }, displayName), /* @__PURE__ */ React.createElement(
511
- Chip,
673
+ return /* @__PURE__ */ React.createElement(
674
+ Accordion,
512
675
  {
513
- label: `${requests.length} request${requests.length !== 1 ? "s" : ""}`,
514
- size: "small",
515
- color: "primary",
516
- style: { marginRight: 16 }
517
- }
518
- ))), /* @__PURE__ */ React.createElement(AccordionDetails, null, /* @__PURE__ */ React.createElement(Box, { width: "100%" }, /* @__PURE__ */ React.createElement(
519
- Table,
520
- {
521
- options: {
522
- selection: canSelectRows && tabData.showSelection,
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
- data: requests,
533
- columns: tabData.columns,
534
- onSelectionChange: (rows) => {
535
- const otherSelections = selectedRequests.filter(
536
- (r) => `${r.metadata.namespace}/${r.spec.apiProductRef?.name || "unknown"}` !== apiProductKey
537
- );
538
- setSelectedRequests([...otherSelections, ...rows]);
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({ open: false, request: null, action: "approve", processing: false }),
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({ open: false, requests: [], action: "approve", processing: false }),
749
+ onClose: () => setBulkDialogState({
750
+ open: false,
751
+ requests: [],
752
+ action: "approve",
753
+ processing: false
754
+ }),
561
755
  onConfirm: handleBulkConfirm
562
756
  }
563
757
  ));