@kuadrant/kuadrant-backstage-plugin-frontend 0.0.2-dev-d9a9178 → 0.0.2-dev-b393fa5
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/ApiAccessCard/ApiAccessCard.esm.js +9 -1
- package/dist/components/ApiAccessCard/ApiAccessCard.esm.js.map +1 -1
- package/dist/components/ApiKeyDetailPage/ApiKeyDetailPage.esm.js +2 -1
- package/dist/components/ApiKeyDetailPage/ApiKeyDetailPage.esm.js.map +1 -1
- package/dist/components/ApiKeyManagementTab/ApiKeyManagementTab.esm.js +7 -3
- package/dist/components/ApiKeyManagementTab/ApiKeyManagementTab.esm.js.map +1 -1
- package/dist/components/ApiProductDetailPage/ApiProductDetailPage.esm.js +15 -5
- package/dist/components/ApiProductDetailPage/ApiProductDetailPage.esm.js.map +1 -1
- package/dist/components/ApprovalQueueTable/ApprovalQueueTable.esm.js +9 -4
- package/dist/components/ApprovalQueueTable/ApprovalQueueTable.esm.js.map +1 -1
- package/dist/components/EditAPIKeyDialog/EditAPIKeyDialog.esm.js +3 -4
- package/dist/components/EditAPIKeyDialog/EditAPIKeyDialog.esm.js.map +1 -1
- package/dist/components/EntityApiApprovalTab/EntityApiApprovalTab.esm.js +7 -3
- package/dist/components/EntityApiApprovalTab/EntityApiApprovalTab.esm.js.map +1 -1
- package/dist/components/KuadrantPage/{KuadrantPage.esm.js → ApiProductsPage.esm.js} +32 -22
- package/dist/components/KuadrantPage/ApiProductsPage.esm.js.map +1 -0
- package/dist/components/KuadrantPage/index.esm.js +1 -1
- package/dist/components/MyApiKeysTable/MyApiKeysTable.esm.js +11 -2
- package/dist/components/MyApiKeysTable/MyApiKeysTable.esm.js.map +1 -1
- package/dist/components/RequestAccessDialog/RequestAccessDialog.esm.js +3 -4
- package/dist/components/RequestAccessDialog/RequestAccessDialog.esm.js.map +1 -1
- package/dist/plugin.esm.js +1 -1
- package/dist/plugin.esm.js.map +1 -1
- package/dist-scalprum/{internal.plugin-kuadrant.e195d879e62f0e73cc2f.js → internal.plugin-kuadrant.09545fa30927eb9a66fd.js} +2 -2
- package/dist-scalprum/{internal.plugin-kuadrant.e195d879e62f0e73cc2f.js.map → internal.plugin-kuadrant.09545fa30927eb9a66fd.js.map} +1 -1
- package/dist-scalprum/plugin-manifest.json +2 -2
- package/dist-scalprum/static/2821.972ae33b.chunk.js +2 -0
- package/dist-scalprum/static/2821.972ae33b.chunk.js.map +1 -0
- package/dist-scalprum/static/{2967.6a1db3ad.chunk.js → 2967.65c51af8.chunk.js} +2 -2
- package/dist-scalprum/static/2967.65c51af8.chunk.js.map +1 -0
- package/dist-scalprum/static/3650.ee76eba9.chunk.js +2 -0
- package/dist-scalprum/static/3650.ee76eba9.chunk.js.map +1 -0
- package/dist-scalprum/static/4682.51e5be13.chunk.js +2 -0
- package/dist-scalprum/static/4682.51e5be13.chunk.js.map +1 -0
- package/dist-scalprum/static/5203.b654e8e0.chunk.js +2 -0
- package/dist-scalprum/static/5203.b654e8e0.chunk.js.map +1 -0
- package/dist-scalprum/static/6800.20f46859.chunk.js +2 -0
- package/dist-scalprum/static/6800.20f46859.chunk.js.map +1 -0
- package/dist-scalprum/static/6840.1653e6b0.chunk.js +2 -0
- package/dist-scalprum/static/6840.1653e6b0.chunk.js.map +1 -0
- package/dist-scalprum/static/7791.ac1ac509.chunk.js +2 -0
- package/dist-scalprum/static/7791.ac1ac509.chunk.js.map +1 -0
- package/dist-scalprum/static/exposed-PluginRoot.55777e36.chunk.js +2 -0
- package/dist-scalprum/static/exposed-PluginRoot.55777e36.chunk.js.map +1 -0
- package/package.json +1 -1
- package/dist/components/KuadrantPage/KuadrantPage.esm.js.map +0 -1
- package/dist-scalprum/static/2967.6a1db3ad.chunk.js.map +0 -1
- package/dist-scalprum/static/3459.ac9b9e54.chunk.js +0 -2
- package/dist-scalprum/static/3459.ac9b9e54.chunk.js.map +0 -1
- package/dist-scalprum/static/3650.4f0dc550.chunk.js +0 -2
- package/dist-scalprum/static/3650.4f0dc550.chunk.js.map +0 -1
- package/dist-scalprum/static/4682.bd2dfccd.chunk.js +0 -2
- package/dist-scalprum/static/4682.bd2dfccd.chunk.js.map +0 -1
- package/dist-scalprum/static/5203.539ed3ec.chunk.js +0 -2
- package/dist-scalprum/static/5203.539ed3ec.chunk.js.map +0 -1
- package/dist-scalprum/static/6800.6e2a08fe.chunk.js +0 -2
- package/dist-scalprum/static/6800.6e2a08fe.chunk.js.map +0 -1
- package/dist-scalprum/static/6840.3bd67cf4.chunk.js +0 -2
- package/dist-scalprum/static/6840.3bd67cf4.chunk.js.map +0 -1
- package/dist-scalprum/static/7791.8135d440.chunk.js +0 -2
- package/dist-scalprum/static/7791.8135d440.chunk.js.map +0 -1
- package/dist-scalprum/static/exposed-PluginRoot.c3fd0cc1.chunk.js +0 -2
- package/dist-scalprum/static/exposed-PluginRoot.c3fd0cc1.chunk.js.map +0 -1
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"static/3650.4f0dc550.chunk.js","mappings":"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","sources":["webpack://internal.plugin-kuadrant/./src/components/RequestAccessDialog/RequestAccessDialog.tsx","webpack://internal.plugin-kuadrant/../../node_modules/@material-ui/icons/Add.js","webpack://internal.plugin-kuadrant/./src/utils/codeSnippets.ts","webpack://internal.plugin-kuadrant/./src/components/ApiKeyManagementTab/ApiKeyManagementTab.tsx","webpack://internal.plugin-kuadrant/./node_modules/@backstage/plugin-catalog-react/dist/hooks/useEntity.esm.js","webpack://internal.plugin-kuadrant/../../node_modules/@material-ui/icons/Info.js","webpack://internal.plugin-kuadrant/../../node_modules/@material-ui/icons/MoreVert.js","webpack://internal.plugin-kuadrant/../../node_modules/@material-ui/icons/Warning.js","webpack://internal.plugin-kuadrant/../../node_modules/@material-ui/icons/HourglassEmpty.js"],"sourcesContent":["import React, { useState } from 'react';\nimport {\n Dialog,\n DialogTitle,\n DialogContent,\n DialogActions,\n Button,\n TextField,\n Select,\n MenuItem,\n FormControl,\n InputLabel,\n Box,\n Typography,\n CircularProgress,\n} from '@material-ui/core';\nimport InfoIcon from '@material-ui/icons/Info';\nimport {\n useApi,\n configApiRef,\n fetchApiRef,\n alertApiRef,\n} from '@backstage/core-plugin-api';\n\nexport interface Plan {\n tier: string;\n limits?: Record<string, number>;\n}\n\nexport interface RequestAccessDialogProps {\n open: boolean;\n onClose: () => void;\n onSuccess: () => void;\n apiProductName: string;\n namespace: string;\n userEmail: string;\n plans: Plan[];\n}\n\nexport const RequestAccessDialog = ({\n open,\n onClose,\n onSuccess,\n apiProductName,\n namespace,\n userEmail,\n plans,\n}: RequestAccessDialogProps) => {\n const config = useApi(configApiRef);\n const fetchApi = useApi(fetchApiRef);\n const alertApi = useApi(alertApiRef);\n const backendUrl = config.getString('backend.baseUrl');\n\n const [selectedPlan, setSelectedPlan] = useState('');\n const [useCase, setUseCase] = useState('');\n const [creating, setCreating] = useState(false);\n const [createError, setCreateError] = useState<string | null>(null);\n\n const handleClose = () => {\n setSelectedPlan('');\n setUseCase('');\n setCreateError(null);\n onClose();\n };\n\n const handleRequestAccess = async () => {\n if (!selectedPlan) return;\n\n setCreating(true);\n setCreateError(null);\n try {\n const response = await fetchApi.fetch(\n `${backendUrl}/api/kuadrant/requests`,\n {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify({\n apiProductName,\n namespace,\n planTier: selectedPlan,\n useCase: useCase.trim() || '',\n userEmail,\n }),\n },\n );\n\n if (!response.ok) {\n const errorData = await response.json().catch(() => ({}));\n throw new Error(\n errorData.error || `failed to create request: ${response.status}`,\n );\n }\n\n alertApi.post({\n message: 'API key requested successfully',\n severity: 'success',\n display: 'transient',\n });\n\n setSelectedPlan('');\n setUseCase('');\n onSuccess();\n } catch (err) {\n const errorMessage =\n err instanceof Error ? err.message : 'unknown error occurred';\n alertApi.post({\n message: `Failed to request API key: ${errorMessage}`,\n severity: 'error',\n display: 'transient',\n });\n setCreateError(errorMessage);\n } finally {\n setCreating(false);\n }\n };\n\n return (\n <Dialog open={open} onClose={handleClose} maxWidth=\"sm\" fullWidth>\n <DialogTitle>Request API Access</DialogTitle>\n <DialogContent>\n <Box\n mb={2}\n p={1.5}\n bgcolor=\"info.light\"\n borderRadius={1}\n display=\"flex\"\n alignItems=\"flex-start\"\n style={{ gap: 8 }}\n >\n <InfoIcon\n color=\"primary\"\n fontSize=\"small\"\n style={{ marginTop: 2 }}\n />\n <Typography variant=\"body2\">\n Your request will be reviewed by an API owner before access is\n granted.\n </Typography>\n </Box>\n {createError && (\n <Box\n mb={2}\n p={2}\n bgcolor=\"error.main\"\n color=\"error.contrastText\"\n borderRadius={1}\n >\n <Typography variant=\"body2\">{createError}</Typography>\n </Box>\n )}\n <FormControl\n fullWidth\n margin=\"normal\"\n disabled={creating}\n data-testid=\"tier-select-form\"\n >\n <InputLabel id=\"tier-select-label\">Select Tier</InputLabel>\n <Select\n labelId=\"tier-select-label\"\n data-testid=\"tier-select\"\n value={selectedPlan}\n onChange={(e) => setSelectedPlan(e.target.value as string)}\n disabled={creating}\n >\n {plans.map((plan: Plan) => {\n const limitDesc = Object.entries(plan.limits || {})\n .map(([key, val]) => `${val} per ${key}`)\n .join(', ');\n return (\n <MenuItem\n key={plan.tier}\n value={plan.tier}\n data-testid={`tier-option-${plan.tier}`}\n >\n {plan.tier} {limitDesc ? `(${limitDesc})` : ''}\n </MenuItem>\n );\n })}\n </Select>\n </FormControl>\n <TextField\n label=\"Use Case (optional)\"\n placeholder=\"Describe how you plan to use this API\"\n multiline\n rows={3}\n fullWidth\n margin=\"normal\"\n value={useCase}\n onChange={(e) => setUseCase(e.target.value)}\n helperText=\"Explain your intended use of this API for admin review\"\n disabled={creating}\n />\n </DialogContent>\n <DialogActions>\n <Button onClick={handleClose} disabled={creating}>\n Cancel\n </Button>\n <Button\n onClick={handleRequestAccess}\n color=\"primary\"\n variant=\"contained\"\n disabled={!selectedPlan || creating}\n startIcon={\n creating ? (\n <CircularProgress size={16} color=\"inherit\" />\n ) : undefined\n }\n >\n {creating ? 'Submitting...' : 'Submit Request'}\n </Button>\n </DialogActions>\n </Dialog>\n );\n};\n","\"use strict\";\n\nvar _interopRequireDefault = require(\"@babel/runtime/helpers/interopRequireDefault\");\n\nvar _interopRequireWildcard = require(\"@babel/runtime/helpers/interopRequireWildcard\");\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nexports.default = void 0;\n\nvar React = _interopRequireWildcard(require(\"react\"));\n\nvar _createSvgIcon = _interopRequireDefault(require(\"./utils/createSvgIcon\"));\n\nvar _default = (0, _createSvgIcon.default)( /*#__PURE__*/React.createElement(\"path\", {\n d: \"M19 13h-6v6h-2v-6H5v-2h6V5h2v6h6v2z\"\n}), 'Add');\n\nexports.default = _default;","import { Credentials } from '../types/api-management';\n\nexport interface CodeSnippets {\n curl: string;\n nodejs: string;\n python: string;\n go: string;\n}\n\nexport function generateAuthCodeSnippets(\n credentials: Credentials | undefined,\n hostname: string,\n apiKey: string,\n): CodeSnippets {\n const baseUrl = `https://${hostname}/api/v1/endpoint`;\n\n if (!credentials) {\n return generateAuthorizationHeaderSnippets(baseUrl, apiKey, 'Bearer');\n }\n\n if (credentials.authorizationHeader) {\n const prefix = credentials!.authorizationHeader!.prefix || '';\n return generateAuthorizationHeaderSnippets(baseUrl, apiKey, prefix);\n }\n\n if (credentials.customHeader) {\n const headerName = credentials!.customHeader!.name;\n const prefix = credentials!.customHeader!.prefix || '';\n return generateCustomHeaderSnippets(baseUrl, apiKey, headerName, prefix);\n }\n\n\n if (credentials.queryString) {\n const paramName = credentials!.queryString!.name;\n return generateQueryStringSnippets(baseUrl, apiKey, paramName);\n }\n\n if (credentials.cookie) {\n const cookieName = credentials!.cookie!.name;\n return generateCookieSnippets(baseUrl, apiKey, cookieName);\n }\n // Default to Authorization Bearer if no authScheme specified\n return generateAuthorizationHeaderSnippets(baseUrl, apiKey, 'Bearer');\n}\n\nfunction generateAuthorizationHeaderSnippets(\n baseUrl: string,\n apiKey: string,\n prefix: string,\n): CodeSnippets {\n const authValue = prefix ? `${prefix} ${apiKey}` : apiKey;\n const prefixWithSpace = prefix ? `${prefix} ` : '';\n\n return {\n curl: `curl -X GET ${baseUrl} \\\\\n -H \"Authorization: ${authValue}\"`,\n\n nodejs: `const fetch = require('node-fetch');\n\nconst apiKey = '${apiKey}';\nconst endpoint = '${baseUrl}';\n\nfetch(endpoint, {\n method: 'GET',\n headers: {\n 'Authorization': '${prefixWithSpace}' + apiKey\n }\n})\n .then(response => response.json())\n .then(data => console.log(data))\n .catch(error => console.error('Error:', error));`,\n\n python: `import requests\n\napi_key = '${apiKey}'\nendpoint = '${baseUrl}'\n\nheaders = {\n 'Authorization': '${prefixWithSpace}' + api_key\n}\n\nresponse = requests.get(endpoint, headers=headers)\nprint(response.json())`,\n\n go: `package main\n\nimport (\n \"fmt\"\n \"net/http\"\n \"io\"\n)\n\nfunc main() {\n apiKey := \"${apiKey}\"\n endpoint := \"${baseUrl}\"\n\n client := &http.Client{}\n req, _ := http.NewRequest(\"GET\", endpoint, nil)\n req.Header.Add(\"Authorization\", \"${prefixWithSpace}\" + apiKey)\n\n resp, err := client.Do(req)\n if err != nil {\n fmt.Println(\"Error:\", err)\n return\n }\n defer resp.Body.Close()\n\n body, _ := io.ReadAll(resp.Body)\n fmt.Println(string(body))\n}`,\n };\n}\n\nfunction generateCustomHeaderSnippets(\n baseUrl: string,\n apiKey: string,\n headerName: string,\n prefix: string,\n): CodeSnippets {\n const headerValue = prefix ? `${prefix}${apiKey}` : apiKey;\n\n return {\n curl: `curl -X GET ${baseUrl} \\\\\n -H \"${headerName}: ${headerValue}\"`,\n\n nodejs: `const fetch = require('node-fetch');\n\nconst apiKey = '${apiKey}';\nconst endpoint = '${baseUrl}';\n\nfetch(endpoint, {\n method: 'GET',\n headers: {\n '${headerName}': '${prefix}' + apiKey\n }\n})\n .then(response => response.json())\n .then(data => console.log(data))\n .catch(error => console.error('Error:', error));`,\n\n python: `import requests\n\napi_key = '${apiKey}'\nendpoint = '${baseUrl}'\n\nheaders = {\n '${headerName}': '${prefix}' + api_key\n}\n\nresponse = requests.get(endpoint, headers=headers)\nprint(response.json())`,\n\n go: `package main\n\nimport (\n \"fmt\"\n \"net/http\"\n \"io\"\n)\n\nfunc main() {\n apiKey := \"${apiKey}\"\n endpoint := \"${baseUrl}\"\n\n client := &http.Client{}\n req, _ := http.NewRequest(\"GET\", endpoint, nil)\n req.Header.Add(\"${headerName}\", \"${prefix}\" + apiKey)\n\n resp, err := client.Do(req)\n if err != nil {\n fmt.Println(\"Error:\", err)\n return\n }\n defer resp.Body.Close()\n\n body, _ := io.ReadAll(resp.Body)\n fmt.Println(string(body))\n}`,\n };\n}\n\nfunction generateQueryStringSnippets(\n baseUrl: string,\n apiKey: string,\n paramName: string,\n): CodeSnippets {\n const urlWithParam = `${baseUrl}?${paramName}=${apiKey}`;\n\n return {\n curl: `curl -X GET \"${urlWithParam}\"`,\n\n nodejs: `const fetch = require('node-fetch');\n\nconst apiKey = '${apiKey}';\nconst endpoint = '${baseUrl}?${paramName}=' + apiKey;\n\nfetch(endpoint, {\n method: 'GET'\n})\n .then(response => response.json())\n .then(data => console.log(data))\n .catch(error => console.error('Error:', error));`,\n\n python: `import requests\n\napi_key = '${apiKey}'\nendpoint = '${baseUrl}'\n\nparams = {\n '${paramName}': api_key\n}\n\nresponse = requests.get(endpoint, params=params)\nprint(response.json())`,\n\n go: `package main\n\nimport (\n \"fmt\"\n \"net/http\"\n \"io\"\n)\n\nfunc main() {\n apiKey := \"${apiKey}\"\n endpoint := \"${baseUrl}?${paramName}=\" + apiKey\n\n client := &http.Client{}\n req, _ := http.NewRequest(\"GET\", endpoint, nil)\n\n resp, err := client.Do(req)\n if err != nil {\n fmt.Println(\"Error:\", err)\n return\n }\n defer resp.Body.Close()\n\n body, _ := io.ReadAll(resp.Body)\n fmt.Println(string(body))\n}`,\n };\n}\n\nfunction generateCookieSnippets(\n baseUrl: string,\n apiKey: string,\n cookieName: string,\n): CodeSnippets {\n return {\n curl: `curl -X GET ${baseUrl} \\\\\n --cookie \"${cookieName}=${apiKey}\"`,\n\n nodejs: `const fetch = require('node-fetch');\n\nconst apiKey = '${apiKey}';\nconst endpoint = '${baseUrl}';\n\nfetch(endpoint, {\n method: 'GET',\n headers: {\n 'Cookie': '${cookieName}=' + apiKey\n }\n})\n .then(response => response.json())\n .then(data => console.log(data))\n .catch(error => console.error('Error:', error));`,\n\n python: `import requests\n\napi_key = '${apiKey}'\nendpoint = '${baseUrl}'\n\ncookies = {\n '${cookieName}': api_key\n}\n\nresponse = requests.get(endpoint, cookies=cookies)\nprint(response.json())`,\n\n go: `package main\n\nimport (\n \"fmt\"\n \"net/http\"\n \"io\"\n)\n\nfunc main() {\n apiKey := \"${apiKey}\"\n endpoint := \"${baseUrl}\"\n\n client := &http.Client{}\n req, _ := http.NewRequest(\"GET\", endpoint, nil)\n req.AddCookie(&http.Cookie{\n Name: \"${cookieName}\",\n Value: apiKey,\n })\n\n resp, err := client.Do(req)\n if err != nil {\n fmt.Println(\"Error:\", err)\n return\n }\n defer resp.Body.Close()\n\n body, _ := io.ReadAll(resp.Body)\n fmt.Println(string(body))\n}`,\n };\n}\n","import React, { useState, useMemo } from \"react\";\nimport { useAsync } from \"react-use\";\nimport {\n Table,\n TableColumn,\n Progress,\n ResponseErrorPanel,\n CodeSnippet,\n} from \"@backstage/core-components\";\nimport {\n IconButton,\n Typography,\n Box,\n Chip,\n Grid,\n Button,\n Dialog,\n DialogTitle,\n DialogContent,\n DialogActions,\n Tabs,\n Tab,\n Menu,\n MenuItem,\n Tooltip,\n CircularProgress,\n} from \"@material-ui/core\";\nimport {\n useApi,\n configApiRef,\n identityApiRef,\n fetchApiRef,\n alertApiRef,\n} from \"@backstage/core-plugin-api\";\nimport { useEntity } from \"@backstage/plugin-catalog-react\";\nimport VisibilityIcon from \"@material-ui/icons/Visibility\";\nimport VisibilityOffIcon from \"@material-ui/icons/VisibilityOff\";\nimport HourglassEmptyIcon from \"@material-ui/icons/HourglassEmpty\";\nimport CancelIcon from \"@material-ui/icons/Cancel\";\nimport AddIcon from \"@material-ui/icons/Add\";\nimport MoreVertIcon from \"@material-ui/icons/MoreVert\";\nimport FileCopyIcon from \"@material-ui/icons/FileCopy\";\nimport WarningIcon from \"@material-ui/icons/Warning\";\nimport { APIKey } from \"../../types/api-management\";\nimport {\n kuadrantApiKeyCreatePermission,\n kuadrantApiKeyDeleteOwnPermission,\n kuadrantApiKeyDeleteAllPermission,\n kuadrantApiKeyUpdateOwnPermission,\n} from \"../../permissions\";\nimport {\n useKuadrantPermission,\n canDeleteResource,\n} from \"../../utils/permissions\";\nimport { EditAPIKeyDialog } from \"../EditAPIKeyDialog\";\nimport { ConfirmDeleteDialog } from \"../ConfirmDeleteDialog\";\nimport { generateAuthCodeSnippets } from \"../../utils/codeSnippets\";\nimport { RequestAccessDialog } from \"../RequestAccessDialog\";\n\ninterface APIProduct {\n metadata: {\n name: string;\n namespace: string;\n };\n spec: {\n displayName?: string;\n };\n status?: {\n discoveredPlans?: Array<{\n tier: string;\n description?: string;\n limits?: any;\n }>;\n conditions?: Array<{\n type: string;\n status: \"True\" | \"False\" | \"Unknown\";\n reason?: string;\n message?: string;\n lastTransitionTime?: string;\n }>;\n };\n}\n\ninterface Plan {\n tier: string;\n limits: any;\n}\n\nexport interface ApiKeyManagementTabProps {\n namespace?: string;\n}\n\nexport const ApiKeyManagementTab = ({\n namespace: propNamespace,\n}: ApiKeyManagementTabProps) => {\n const { entity } = useEntity();\n const config = useApi(configApiRef);\n const identityApi = useApi(identityApiRef);\n const fetchApi = useApi(fetchApiRef);\n const alertApi = useApi(alertApiRef);\n const backendUrl = config.getString(\"backend.baseUrl\");\n const [visibleKeys, setVisibleKeys] = useState<Set<string>>(new Set());\n const [refresh, setRefresh] = useState(0);\n const [userId, setUserId] = useState<string>(\"\");\n const [userEmail, setUserEmail] = useState<string>(\"\");\n const [requestDialogOpen, setRequestDialogOpen] = useState(false);\n const [editDialogOpen, setEditDialogOpen] = useState(false);\n const [requestToEdit, setRequestToEdit] = useState<APIKey | null>(null);\n const [menuAnchor, setMenuAnchor] = useState<{\n top: number;\n left: number;\n } | null>(null);\n const [menuRequest, setMenuRequest] = useState<APIKey | null>(null);\n const [deleting, setDeleting] = useState<string | null>(null);\n const [optimisticallyDeleted, setOptimisticallyDeleted] = useState<\n Set<string>\n >(new Set());\n const [deleteDialogState, setDeleteDialogState] = useState<{\n open: boolean;\n request: APIKey | null;\n }>({ open: false, request: null });\n const [apiKeyValues, setApiKeyValues] = useState<Map<string, string>>(\n new Map(),\n );\n const [apiKeyLoading, setApiKeyLoading] = useState<Set<string>>(new Set());\n const [alreadyReadKeys, setAlreadyReadKeys] = useState<Set<string>>(\n new Set(),\n );\n const [showOnceWarningOpen, setShowOnceWarningOpen] = useState(false);\n const [pendingKeyReveal, setPendingKeyReveal] = useState<{\n namespace: string;\n name: string;\n } | null>(null);\n\n // get apiproduct name from entity annotation (set by entity provider)\n const apiProductName =\n entity.metadata.annotations?.[\"kuadrant.io/apiproduct\"] ||\n entity.metadata.name;\n const namespace =\n entity.metadata.annotations?.[\"kuadrant.io/namespace\"] ||\n propNamespace ||\n \"default\";\n\n useAsync(async () => {\n const identity = await identityApi.getBackstageIdentity();\n const profile = await identityApi.getProfileInfo();\n setUserId(identity.userEntityRef);\n setUserEmail(profile.email || \"\");\n }, [identityApi]);\n\n const {\n value: requests,\n loading: requestsLoading,\n error: requestsError,\n } = useAsync(async () => {\n const response = await fetchApi.fetch(\n `${backendUrl}/api/kuadrant/requests/my?namespace=${namespace}`,\n );\n if (!response.ok) {\n throw new Error(\"failed to fetch requests\");\n }\n const data = await response.json();\n // filter by apiproduct name, not httproute name\n return (data.items || []).filter(\n (r: APIKey) =>\n r.spec.apiProductRef.name === apiProductName &&\n r.metadata.namespace === namespace, // APIProducts and APIKeys (and its Secret) will be in the same NS\n );\n }, [apiProductName, namespace, refresh, fetchApi, backendUrl]);\n\n const {\n value: apiProduct,\n loading: plansLoading,\n error: plansError,\n } = useAsync(async () => {\n const response = await fetchApi.fetch(\n `${backendUrl}/api/kuadrant/apiproducts`,\n );\n if (!response.ok) {\n throw new Error(\"failed to fetch api products\");\n }\n const data = await response.json();\n\n const product = data.items?.find(\n (p: APIProduct) =>\n p.metadata.namespace === namespace &&\n p.metadata.name === apiProductName,\n );\n\n return product;\n }, [namespace, apiProductName, fetchApi]);\n\n // check permissions with resource reference once we have the apiproduct\n const resourceRef = apiProduct\n ? `apiproduct:${apiProduct.metadata.namespace}/${apiProduct.metadata.name}`\n : undefined;\n\n const {\n allowed: canCreateRequest,\n loading: createRequestPermissionLoading,\n error: createRequestPermissionError,\n } = useKuadrantPermission(kuadrantApiKeyCreatePermission, resourceRef);\n\n const {\n allowed: canDeleteOwnKey,\n loading: deleteOwnPermissionLoading,\n error: deleteOwnPermissionError,\n } = useKuadrantPermission(kuadrantApiKeyDeleteOwnPermission);\n\n const {\n allowed: canDeleteAllKeys,\n loading: deleteAllPermissionLoading,\n error: deleteAllPermissionError,\n } = useKuadrantPermission(kuadrantApiKeyDeleteAllPermission);\n\n const {\n allowed: canUpdateRequest,\n loading: updateRequestPermissionLoading,\n error: updateRequestPermissionError,\n } = useKuadrantPermission(kuadrantApiKeyUpdateOwnPermission);\n\n const handleDeleteRequest = async (name: string) => {\n // optimistic update - remove from UI immediately\n setOptimisticallyDeleted((prev) => new Set(prev).add(name));\n setDeleting(name);\n try {\n const response = await fetchApi.fetch(\n `${backendUrl}/api/kuadrant/requests/${namespace}/${name}`,\n { method: \"DELETE\" },\n );\n if (!response.ok) {\n throw new Error(\"failed to delete request\");\n }\n alertApi.post({\n message: \"API key deleted successfully\",\n severity: \"success\",\n display: \"transient\",\n });\n setRefresh((r) => r + 1);\n } catch (err) {\n const errorMessage =\n err instanceof Error ? err.message : \"unknown error occurred\";\n // rollback optimistic update on error\n setOptimisticallyDeleted((prev) => {\n const next = new Set(prev);\n next.delete(name);\n return next;\n });\n alertApi.post({\n message: `Failed to delete API key: ${errorMessage}`,\n severity: \"error\",\n display: \"transient\",\n });\n } finally {\n setDeleting(null);\n }\n };\n\n const fetchApiKeyFromSecret = async (\n requestNamespace: string,\n requestName: string,\n ) => {\n const key = `${requestNamespace}/${requestName}`;\n if (apiKeyLoading.has(key)) {\n return;\n }\n\n setApiKeyLoading((prev) => new Set(prev).add(key));\n try {\n const response = await fetchApi.fetch(\n `${backendUrl}/api/kuadrant/apikeys/${requestNamespace}/${requestName}/secret`,\n );\n if (response.ok) {\n const data = await response.json();\n setApiKeyValues((prev) => new Map(prev).set(key, data.apiKey));\n // after successful read, mark as already read (show-once behaviour)\n setAlreadyReadKeys((prev) => new Set(prev).add(key));\n } else if (response.status === 403) {\n // secret has already been read\n setAlreadyReadKeys((prev) => new Set(prev).add(key));\n alertApi.post({\n message:\n \"This API key has already been viewed and cannot be retrieved again.\",\n severity: \"warning\",\n display: \"transient\",\n });\n }\n } catch (err) {\n const errorMessage =\n err instanceof Error ? err.message : \"unknown error occurred\";\n alertApi.post({\n message: `Failed to fetch api key: ${errorMessage}`,\n severity: \"error\",\n display: \"transient\",\n });\n } finally {\n setApiKeyLoading((prev) => {\n const next = new Set(prev);\n next.delete(key);\n return next;\n });\n }\n };\n\n const clearApiKeyValue = (requestNamespace: string, requestName: string) => {\n const key = `${requestNamespace}/${requestName}`;\n setApiKeyValues((prev) => {\n const next = new Map(prev);\n next.delete(key);\n return next;\n });\n };\n\n const handleEditRequest = (request: APIKey) => {\n setRequestToEdit(request);\n setEditDialogOpen(true);\n };\n\n const handleEditSuccess = () => {\n setRefresh((r) => r + 1);\n setEditDialogOpen(false);\n alertApi.post({\n message: \"API key updated\",\n severity: \"success\",\n display: \"transient\",\n });\n setRequestToEdit(null);\n };\n\n const handleMenuClose = () => {\n setMenuAnchor(null);\n setMenuRequest(null);\n };\n\n const handleMenuEdit = () => {\n if (!menuRequest) return;\n handleEditRequest(menuRequest);\n handleMenuClose();\n };\n\n const handleMenuDeleteClick = () => {\n if (!menuRequest) return;\n const request = menuRequest;\n handleMenuClose();\n setDeleteDialogState({ open: true, request });\n };\n\n const handleDeleteConfirm = async () => {\n if (!deleteDialogState.request) return;\n await handleDeleteRequest(deleteDialogState.request.metadata.name);\n setDeleteDialogState({ open: false, request: null });\n };\n\n const handleDeleteCancel = () => {\n setDeleteDialogState({ open: false, request: null });\n };\n\n const toggleVisibility = (keyName: string) => {\n setVisibleKeys((prev) => {\n const newSet = new Set(prev);\n if (newSet.has(keyName)) {\n newSet.delete(keyName);\n } else {\n newSet.add(keyName);\n }\n return newSet;\n });\n };\n\n const detailPanelConfig = useMemo(\n () => [\n {\n render: (data: any) => {\n // backstage Table wraps the data in { rowData: actualData }\n const request = data.rowData as APIKey;\n if (!request?.metadata?.name) {\n return <Box />;\n }\n\n // pass already-revealed key from parent state (don't auto-fetch - that consumes show-once)\n const key = `${request.metadata.namespace}/${request.metadata.name}`;\n const revealedKey = apiKeyValues.get(key);\n return (\n <DetailPanelContent\n request={request}\n apiName={apiProductName}\n revealedApiKey={revealedKey}\n />\n );\n },\n },\n ],\n [apiProductName, apiKeyValues],\n );\n\n // separate component to isolate state\n const DetailPanelContent = ({\n request,\n apiName: api,\n revealedApiKey,\n }: {\n request: APIKey;\n apiName: string;\n revealedApiKey?: string;\n }) => {\n const [selectedLanguage, setSelectedLanguage] = useState(0);\n const hostname = request.status?.apiHostname || `${api}.apps.example.com`;\n\n // use revealed key if available, otherwise show placeholder\n const displayApiKey = revealedApiKey || \"<your-api-key>\";\n\n // Generate code snippets based on authScheme credentials\n const credentials = request.status?.authScheme?.credentials;\n const snippets = generateAuthCodeSnippets(credentials, hostname, displayApiKey);\n\n return (\n <Box\n p={3}\n bgcolor=\"background.default\"\n onClick={(e) => e.stopPropagation()}\n >\n {request.spec.useCase && (\n <Box mb={3}>\n <Typography variant=\"h6\" gutterBottom>\n Use Case\n </Typography>\n <Box\n p={2}\n bgcolor=\"background.paper\"\n borderRadius={1}\n border=\"1px solid rgba(0, 0, 0, 0.12)\"\n >\n <Typography\n variant=\"body2\"\n style={{\n whiteSpace: \"pre-wrap\",\n wordBreak: \"break-word\",\n overflowWrap: \"break-word\",\n }}\n >\n {request.spec.useCase}\n </Typography>\n </Box>\n </Box>\n )}\n <Typography variant=\"h6\" gutterBottom>\n Usage Examples\n </Typography>\n <Typography variant=\"body2\" paragraph>\n Use these code examples to test the API with your{\" \"}\n {request.spec.planTier} tier key.\n </Typography>\n <Box onClick={(e) => e.stopPropagation()}>\n <Tabs\n value={selectedLanguage}\n onChange={(e, newValue) => {\n e.stopPropagation();\n setSelectedLanguage(newValue);\n }}\n indicatorColor=\"primary\"\n >\n <Tab label=\"cURL\" onClick={(e) => e.stopPropagation()} />\n <Tab label=\"Node.js\" onClick={(e) => e.stopPropagation()} />\n <Tab label=\"Python\" onClick={(e) => e.stopPropagation()} />\n <Tab label=\"Go\" onClick={(e) => e.stopPropagation()} />\n </Tabs>\n </Box>\n <Box mt={2}>\n {selectedLanguage === 0 && (\n <CodeSnippet\n text={snippets.curl}\n language=\"bash\"\n showCopyCodeButton\n />\n )}\n {selectedLanguage === 1 && (\n <CodeSnippet\n text={snippets.nodejs}\n language=\"javascript\"\n showCopyCodeButton\n />\n )}\n {selectedLanguage === 2 && (\n <CodeSnippet\n text={snippets.python}\n language=\"python\"\n showCopyCodeButton\n />\n )}\n {selectedLanguage === 3 && (\n <CodeSnippet\n text={snippets.go}\n language=\"go\"\n showCopyCodeButton\n />\n )}\n </Box>\n </Box>\n );\n };\n\n const loading =\n requestsLoading ||\n plansLoading ||\n createRequestPermissionLoading ||\n deleteOwnPermissionLoading ||\n deleteAllPermissionLoading ||\n updateRequestPermissionLoading;\n const error = requestsError || plansError;\n const permissionError =\n createRequestPermissionError ||\n deleteOwnPermissionError ||\n deleteAllPermissionError ||\n updateRequestPermissionError;\n\n if (loading) {\n return <Progress />;\n }\n\n if (error) {\n return <ResponseErrorPanel error={error} />;\n }\n\n if (permissionError) {\n const failedPermission = createRequestPermissionError\n ? \"kuadrant.apikey.create\"\n : deleteOwnPermissionError\n ? \"kuadrant.apikey.delete.own\"\n : deleteAllPermissionError\n ? \"kuadrant.apikey.delete.all\"\n : updateRequestPermissionError\n ? \"kuadrant.apikey.update.own\"\n : \"unknown\";\n return (\n <Box p={2}>\n <Typography color=\"error\">\n Unable to check permissions: {permissionError.message}\n </Typography>\n <Typography variant=\"body2\" color=\"textSecondary\">\n Permission: {failedPermission}\n </Typography>\n <Typography variant=\"body2\" color=\"textSecondary\">\n Please try again or contact your administrator\n </Typography>\n </Box>\n );\n }\n\n const myRequests = ((requests || []) as APIKey[]).filter(\n (r) => !optimisticallyDeleted.has(r.metadata.name),\n );\n const plans = (apiProduct?.status?.discoveredPlans || []) as Plan[];\n\n const pendingRequests = myRequests.filter(\n (r) => !r.status?.phase || r.status.phase === \"Pending\",\n );\n const approvedRequests = myRequests.filter(\n (r) => r.status?.phase === \"Approved\",\n );\n const rejectedRequests = myRequests.filter(\n (r) => r.status?.phase === \"Rejected\",\n );\n\n const approvedColumns: TableColumn<APIKey>[] = [\n {\n title: \"Tier\",\n field: \"spec.planTier\",\n render: (row: APIKey) => (\n <Chip label={row.spec.planTier} color=\"primary\" size=\"small\" />\n ),\n },\n {\n title: \"Approved\",\n field: \"status.reviewedAt\",\n render: (row: APIKey) => (\n <Typography variant=\"body2\">\n {row.status?.reviewedAt\n ? new Date(row.status.reviewedAt).toLocaleDateString()\n : \"-\"}\n </Typography>\n ),\n },\n {\n title: \"API Key\",\n field: \"status.secretRef\",\n searchable: false,\n filtering: false,\n render: (row: APIKey) => {\n const key = `${row.metadata.namespace}/${row.metadata.name}`;\n const isVisible = visibleKeys.has(row.metadata.name);\n const isLoading = apiKeyLoading.has(key);\n const apiKeyValue = apiKeyValues.get(key);\n const hasSecretRef = row.status?.secretRef?.name;\n const canReadSecret = row.status?.canReadSecret !== false;\n const isAlreadyRead = alreadyReadKeys.has(key) || !canReadSecret;\n\n if (!hasSecretRef) {\n return (\n <Typography variant=\"body2\" color=\"textSecondary\">\n Awaiting secret...\n </Typography>\n );\n }\n\n // key has already been viewed and cannot be retrieved again\n if (isAlreadyRead && !apiKeyValue) {\n return (\n <Tooltip title=\"This API key has already been viewed and cannot be retrieved again\">\n <Box display=\"flex\" alignItems=\"center\">\n <Typography\n variant=\"body2\"\n color=\"textSecondary\"\n style={{ fontFamily: \"monospace\", marginRight: 8 }}\n >\n Already viewed\n </Typography>\n <VisibilityOffIcon fontSize=\"small\" color=\"disabled\" />\n </Box>\n </Tooltip>\n );\n }\n\n const handleRevealClick = () => {\n if (isVisible) {\n // hiding - clear the value from memory\n clearApiKeyValue(row.metadata.namespace, row.metadata.name);\n toggleVisibility(row.metadata.name);\n } else if (!isAlreadyRead) {\n // show warning dialog before first reveal\n setPendingKeyReveal({\n namespace: row.metadata.namespace,\n name: row.metadata.name,\n });\n setShowOnceWarningOpen(true);\n }\n };\n\n const handleCopy = async () => {\n if (apiKeyValue) {\n await navigator.clipboard.writeText(apiKeyValue);\n alertApi.post({\n message: \"API key copied to clipboard\",\n severity: \"success\",\n display: \"transient\",\n });\n }\n };\n\n return (\n <Box display=\"flex\" alignItems=\"center\">\n <Typography\n variant=\"body2\"\n style={{\n fontFamily: \"monospace\",\n marginRight: 8,\n }}\n >\n {isLoading\n ? \"Loading...\"\n : isVisible && apiKeyValue\n ? apiKeyValue\n : \"••••••••••••••••\"}\n </Typography>\n {isVisible && apiKeyValue && (\n <Tooltip title=\"Copy to clipboard\">\n <IconButton size=\"small\" onClick={handleCopy}>\n <FileCopyIcon fontSize=\"small\" />\n </IconButton>\n </Tooltip>\n )}\n <Tooltip\n title={\n isVisible ? \"Hide API key\" : \"Reveal API key (one-time only)\"\n }\n >\n <span>\n <IconButton\n size=\"small\"\n onClick={handleRevealClick}\n disabled={isLoading || (isAlreadyRead && !apiKeyValue)}\n >\n {isVisible ? <VisibilityOffIcon /> : <VisibilityIcon />}\n </IconButton>\n </span>\n </Tooltip>\n </Box>\n );\n },\n },\n {\n title: \"\",\n field: \"actions\",\n searchable: false,\n filtering: false,\n render: (row: APIKey) => {\n const isDeleting = deleting === row.metadata.name;\n if (isDeleting) {\n return <CircularProgress size={20} />;\n }\n const ownerId = row.spec.requestedBy.userId;\n const canDelete = canDeleteResource(\n ownerId,\n userId,\n canDeleteOwnKey,\n canDeleteAllKeys,\n );\n if (!canDelete) return null;\n return (\n <IconButton\n size=\"small\"\n onClick={(e) => {\n e.stopPropagation();\n const rect = e.currentTarget.getBoundingClientRect();\n setMenuAnchor({ top: rect.bottom, left: rect.left });\n setMenuRequest(row);\n }}\n title=\"Actions\"\n aria-controls={menuAnchor ? \"actions-menu\" : undefined}\n aria-haspopup=\"true\"\n >\n <MoreVertIcon />\n </IconButton>\n );\n },\n },\n ];\n\n const requestColumns: TableColumn<APIKey>[] = [\n {\n title: \"Status\",\n field: \"status.phase\",\n render: (row: APIKey) => {\n const phase = row.status?.phase || \"Pending\";\n const isPending = phase === \"Pending\";\n return (\n <Chip\n label={phase}\n size=\"small\"\n icon={isPending ? <HourglassEmptyIcon /> : <CancelIcon />}\n color={isPending ? \"default\" : \"secondary\"}\n />\n );\n },\n },\n {\n title: \"Tier\",\n field: \"spec.planTier\",\n render: (row: APIKey) => (\n <Chip label={row.spec.planTier} color=\"primary\" size=\"small\" />\n ),\n },\n {\n title: \"Use Case\",\n field: \"spec.useCase\",\n render: (row: APIKey) => {\n if (!row.spec.useCase) {\n return <Typography variant=\"body2\">-</Typography>;\n }\n return (\n <Tooltip title={row.spec.useCase} placement=\"top\">\n <Typography\n variant=\"body2\"\n style={{\n maxWidth: \"200px\",\n overflow: \"hidden\",\n textOverflow: \"ellipsis\",\n whiteSpace: \"nowrap\",\n }}\n >\n {row.spec.useCase}\n </Typography>\n </Tooltip>\n );\n },\n },\n {\n title: \"Requested\",\n field: \"metadata.creationTimestamp\",\n render: (row: APIKey) => (\n <Typography variant=\"body2\">\n {row.metadata.creationTimestamp\n ? new Date(row.metadata.creationTimestamp).toLocaleDateString()\n : \"-\"}\n </Typography>\n ),\n },\n {\n title: \"Reviewed\",\n field: \"status.reviewedAt\",\n render: (row: APIKey) => {\n if (!row.status?.reviewedAt)\n return <Typography variant=\"body2\">-</Typography>;\n return (\n <Typography variant=\"body2\">\n {new Date(row.status.reviewedAt).toLocaleDateString()}\n </Typography>\n );\n },\n },\n {\n title: \"\",\n field: \"actions\",\n searchable: false,\n filtering: false,\n render: (row: APIKey) => {\n const isDeleting = deleting === row.metadata.name;\n if (isDeleting) {\n return <CircularProgress size={20} />;\n }\n const isPending = !row.status?.phase || row.status.phase === \"Pending\";\n const ownerId = row.spec.requestedBy.userId;\n const canDelete = canDeleteResource(\n ownerId,\n userId,\n canDeleteOwnKey,\n canDeleteAllKeys,\n );\n const canEdit = canUpdateRequest && ownerId === userId;\n if (!isPending || (!canEdit && !canDelete)) return null;\n return (\n <IconButton\n size=\"small\"\n onClick={(e) => {\n e.stopPropagation();\n const rect = e.currentTarget.getBoundingClientRect();\n setMenuAnchor({ top: rect.bottom, left: rect.left });\n setMenuRequest(row);\n }}\n title=\"Actions\"\n aria-controls={menuAnchor ? \"actions-menu\" : undefined}\n aria-haspopup=\"true\"\n >\n <MoreVertIcon />\n </IconButton>\n );\n },\n },\n ];\n\n // Filter columns for pending requests (no Reviewed or Reason)\n const pendingRequestColumns = requestColumns.filter(\n (col) => col.title !== \"Reviewed\" && col.title !== \"Reason\",\n );\n\n return (\n <Box p={2}>\n <Grid container spacing={3} direction=\"column\">\n {canCreateRequest && (\n <Grid item>\n <Box\n display=\"flex\"\n flexDirection=\"column\"\n alignItems=\"flex-end\"\n mb={2}\n >\n <Button\n variant=\"contained\"\n color=\"primary\"\n startIcon={<AddIcon />}\n onClick={() => setRequestDialogOpen(true)}\n disabled={plans.length === 0}\n data-testid=\"request-api-access-button\"\n data-plans-count={plans.length}\n >\n Request API Access\n </Button>\n {plans.length === 0 && (\n <Typography\n variant=\"caption\"\n color=\"textSecondary\"\n style={{ marginTop: 4 }}\n data-testid=\"no-plans-message\"\n >\n {!apiProduct\n ? \"API product not found\"\n : (() => {\n const readyCondition =\n apiProduct.status?.conditions?.find(\n (c: any) => c.type === \"Ready\",\n );\n const planCondition =\n apiProduct.status?.conditions?.find(\n (c: any) => c.type === \"PlanPolicyDiscovered\",\n );\n\n if (readyCondition?.status !== \"True\") {\n return `HTTPRoute not ready: ${readyCondition?.message || \"unknown\"}`;\n }\n if (planCondition?.status !== \"True\") {\n return `No plans discovered: ${planCondition?.message || \"no PlanPolicy found\"}`;\n }\n return \"No plans available\";\n })()}\n </Typography>\n )}\n </Box>\n </Grid>\n )}\n {pendingRequests.length === 0 &&\n rejectedRequests.length === 0 &&\n approvedRequests.length === 0 && (\n <Grid item>\n <Box p={3} textAlign=\"center\">\n <Typography variant=\"body1\" color=\"textSecondary\">\n No API keys yet. Request access to get started.\n </Typography>\n </Box>\n </Grid>\n )}\n {pendingRequests.length > 0 && (\n <Grid item>\n <Table\n title=\"Pending Requests\"\n options={{\n paging: pendingRequests.length > 5,\n pageSize: 20,\n search: true,\n filtering: true,\n debounceInterval: 300,\n toolbar: true,\n emptyRowsWhenPaging: false,\n }}\n columns={pendingRequestColumns}\n data={pendingRequests}\n />\n </Grid>\n )}\n {rejectedRequests.length > 0 && (\n <Grid item>\n <Table\n title=\"Rejected Requests\"\n options={{\n paging: rejectedRequests.length > 5,\n pageSize: 20,\n search: true,\n filtering: true,\n debounceInterval: 300,\n toolbar: true,\n emptyRowsWhenPaging: false,\n }}\n columns={requestColumns}\n data={rejectedRequests}\n />\n </Grid>\n )}\n {approvedRequests.length > 0 && (\n <Grid item>\n <Table\n key=\"api-keys-table\"\n title=\"API Keys\"\n options={{\n paging: approvedRequests.length > 5,\n pageSize: 20,\n search: true,\n filtering: true,\n debounceInterval: 300,\n toolbar: true,\n emptyRowsWhenPaging: false,\n }}\n columns={approvedColumns}\n data={approvedRequests}\n detailPanel={detailPanelConfig}\n />\n </Grid>\n )}\n </Grid>\n\n <RequestAccessDialog\n open={requestDialogOpen}\n onClose={() => setRequestDialogOpen(false)}\n onSuccess={() => {\n setRequestDialogOpen(false);\n setRefresh((r) => r + 1);\n }}\n apiProductName={apiProductName}\n namespace={namespace}\n userEmail={userEmail}\n plans={plans}\n />\n\n <Menu\n id=\"actions-menu\"\n open={Boolean(menuAnchor)}\n onClose={handleMenuClose}\n anchorReference=\"anchorPosition\"\n anchorPosition={menuAnchor || { top: 0, left: 0 }}\n >\n {menuRequest &&\n (() => {\n const isPending =\n !menuRequest.status?.phase ||\n menuRequest.status.phase === \"Pending\";\n const ownerId = menuRequest.spec.requestedBy.userId;\n const canEdit = canUpdateRequest && ownerId === userId && isPending;\n\n const items = [];\n if (canEdit) {\n items.push(\n <MenuItem key=\"edit\" onClick={handleMenuEdit}>\n Edit\n </MenuItem>,\n );\n }\n items.push(\n <MenuItem key=\"delete\" onClick={handleMenuDeleteClick}>\n Delete\n </MenuItem>,\n );\n return items;\n })()}\n </Menu>\n\n {requestToEdit && (\n <EditAPIKeyDialog\n open={editDialogOpen}\n onClose={() => {\n setEditDialogOpen(false);\n setRequestToEdit(null);\n }}\n onSuccess={handleEditSuccess}\n request={requestToEdit}\n availablePlans={plans}\n />\n )}\n\n <ConfirmDeleteDialog\n open={deleteDialogState.open}\n title=\"Delete Request\"\n description={`Are you sure you want to delete this ${deleteDialogState.request?.status?.phase === \"Approved\" ? \"API key\" : \"request\"}?`}\n deleting={deleting !== null}\n onConfirm={handleDeleteConfirm}\n onCancel={handleDeleteCancel}\n />\n\n <Dialog\n open={showOnceWarningOpen}\n onClose={() => {\n setShowOnceWarningOpen(false);\n setPendingKeyReveal(null);\n }}\n maxWidth=\"sm\"\n >\n <DialogTitle>\n <Box display=\"flex\" alignItems=\"center\">\n <WarningIcon color=\"primary\" style={{ marginRight: 8 }} />\n View API Key\n </Box>\n </DialogTitle>\n <DialogContent>\n <Typography variant=\"body1\" paragraph>\n This API key can only be viewed <strong>once</strong>. After you\n reveal it, you will not be able to retrieve it again.\n </Typography>\n <Typography variant=\"body2\" color=\"textSecondary\">\n Make sure to copy and store it securely before closing this view.\n </Typography>\n </DialogContent>\n <DialogActions>\n <Button\n onClick={() => {\n setShowOnceWarningOpen(false);\n setPendingKeyReveal(null);\n }}\n >\n Cancel\n </Button>\n <Button\n variant=\"contained\"\n color=\"primary\"\n onClick={() => {\n if (pendingKeyReveal) {\n fetchApiKeyFromSecret(\n pendingKeyReveal.namespace,\n pendingKeyReveal.name,\n );\n toggleVisibility(pendingKeyReveal.name);\n }\n setShowOnceWarningOpen(false);\n setPendingKeyReveal(null);\n }}\n >\n Reveal API Key\n </Button>\n </DialogActions>\n </Dialog>\n </Box>\n );\n};\n","import { jsx } from 'react/jsx-runtime';\nimport { stringifyEntityRef } from '@backstage/catalog-model';\nimport { AnalyticsContext } from '@backstage/core-plugin-api';\nimport { createVersionedContext, useVersionedContext, createVersionedValueMap } from '@backstage/version-bridge';\n\nconst NewEntityContext = createVersionedContext(\n \"entity-context\"\n);\nconst AsyncEntityProvider = (props) => {\n const { children, entity, loading, error, refresh } = props;\n const value = { entity, loading, error, refresh };\n return /* @__PURE__ */ jsx(NewEntityContext.Provider, { value: createVersionedValueMap({ 1: value }), children: /* @__PURE__ */ jsx(\n AnalyticsContext,\n {\n attributes: {\n ...entity ? { entityRef: stringifyEntityRef(entity) } : void 0\n },\n children\n }\n ) });\n};\nconst EntityProvider = (props) => /* @__PURE__ */ jsx(\n AsyncEntityProvider,\n {\n entity: props.entity,\n loading: !Boolean(props.entity),\n error: void 0,\n refresh: void 0,\n children: props.children\n }\n);\nfunction useEntity() {\n const versionedHolder = useVersionedContext(\n \"entity-context\"\n );\n if (!versionedHolder) {\n throw new Error(\"Entity context is not available\");\n }\n const value = versionedHolder.atVersion(1);\n if (!value) {\n throw new Error(\"EntityContext v1 not available\");\n }\n if (!value.entity) {\n throw new Error(\n \"useEntity hook is being called outside of an EntityLayout where the entity has not been loaded. If this is intentional, please use useAsyncEntity instead.\"\n );\n }\n return { entity: value.entity };\n}\nfunction useAsyncEntity() {\n const versionedHolder = useVersionedContext(\n \"entity-context\"\n );\n if (!versionedHolder) {\n throw new Error(\"Entity context is not available\");\n }\n const value = versionedHolder.atVersion(1);\n if (!value) {\n throw new Error(\"EntityContext v1 not available\");\n }\n const { entity, loading, error, refresh } = value;\n return { entity, loading, error, refresh };\n}\n\nexport { AsyncEntityProvider, EntityProvider, useAsyncEntity, useEntity };\n//# sourceMappingURL=useEntity.esm.js.map\n","\"use strict\";\n\nvar _interopRequireDefault = require(\"@babel/runtime/helpers/interopRequireDefault\");\n\nvar _interopRequireWildcard = require(\"@babel/runtime/helpers/interopRequireWildcard\");\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nexports.default = void 0;\n\nvar React = _interopRequireWildcard(require(\"react\"));\n\nvar _createSvgIcon = _interopRequireDefault(require(\"./utils/createSvgIcon\"));\n\nvar _default = (0, _createSvgIcon.default)( /*#__PURE__*/React.createElement(\"path\", {\n d: \"M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm1 15h-2v-6h2v6zm0-8h-2V7h2v2z\"\n}), 'Info');\n\nexports.default = _default;","\"use strict\";\n\nvar _interopRequireDefault = require(\"@babel/runtime/helpers/interopRequireDefault\");\n\nvar _interopRequireWildcard = require(\"@babel/runtime/helpers/interopRequireWildcard\");\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nexports.default = void 0;\n\nvar React = _interopRequireWildcard(require(\"react\"));\n\nvar _createSvgIcon = _interopRequireDefault(require(\"./utils/createSvgIcon\"));\n\nvar _default = (0, _createSvgIcon.default)( /*#__PURE__*/React.createElement(\"path\", {\n d: \"M12 8c1.1 0 2-.9 2-2s-.9-2-2-2-2 .9-2 2 .9 2 2 2zm0 2c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2zm0 6c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2z\"\n}), 'MoreVert');\n\nexports.default = _default;","\"use strict\";\n\nvar _interopRequireDefault = require(\"@babel/runtime/helpers/interopRequireDefault\");\n\nvar _interopRequireWildcard = require(\"@babel/runtime/helpers/interopRequireWildcard\");\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nexports.default = void 0;\n\nvar React = _interopRequireWildcard(require(\"react\"));\n\nvar _createSvgIcon = _interopRequireDefault(require(\"./utils/createSvgIcon\"));\n\nvar _default = (0, _createSvgIcon.default)( /*#__PURE__*/React.createElement(\"path\", {\n d: \"M1 21h22L12 2 1 21zm12-3h-2v-2h2v2zm0-4h-2v-4h2v4z\"\n}), 'Warning');\n\nexports.default = _default;","\"use strict\";\n\nvar _interopRequireDefault = require(\"@babel/runtime/helpers/interopRequireDefault\");\n\nvar _interopRequireWildcard = require(\"@babel/runtime/helpers/interopRequireWildcard\");\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nexports.default = void 0;\n\nvar React = _interopRequireWildcard(require(\"react\"));\n\nvar _createSvgIcon = _interopRequireDefault(require(\"./utils/createSvgIcon\"));\n\nvar _default = (0, _createSvgIcon.default)( /*#__PURE__*/React.createElement(\"path\", {\n d: \"M6 2v6h.01L6 8.01 10 12l-4 4 .01.01H6V22h12v-5.99h-.01L18 16l-4-4 4-3.99-.01-.01H18V2H6zm10 14.5V20H8v-3.5l4-4 4 4zm-4-5l-4-4V4h8v3.5l-4 4z\"\n}), 'HourglassEmpty');\n\nexports.default = _default;"],"names":["RequestAccessDialog","open","onClose","onSuccess","apiProductName","namespace","userEmail","plans","config","useApi","configApiRef","fetchApi","fetchApiRef","alertApi","alertApiRef","backendUrl","getString","selectedPlan","setSelectedPlan","useState","useCase","setUseCase","creating","setCreating","createError","setCreateError","handleClose","Dialog","maxWidth","fullWidth","DialogTitle","DialogContent","Box","mb","p","bgcolor","borderRadius","display","alignItems","style","gap","InfoIcon","color","fontSize","marginTop","Typography","variant","FormControl","margin","disabled","data-testid","InputLabel","id","Select","labelId","value","onChange","e","target","map","plan","limitDesc","Object","entries","limits","key","val","join","MenuItem","tier","TextField","label","placeholder","multiline","rows","helperText","DialogActions","Button","onClick","async","response","fetch","method","headers","body","JSON","stringify","planTier","trim","ok","errorData","json","catch","Error","error","status","post","message","severity","err","errorMessage","startIcon","CircularProgress","size","undefined","_interopRequireDefault","_interopRequireWildcard","exports","React","_default","default","createElement","d","generateAuthorizationHeaderSnippets","baseUrl","apiKey","prefix","prefixWithSpace","curl","nodejs","python","go","ApiKeyManagementTab","propNamespace","entity","apiProduct","deleteDialogState","useEntity","identityApi","identityApiRef","visibleKeys","setVisibleKeys","Set","refresh","setRefresh","userId","setUserId","setUserEmail","requestDialogOpen","setRequestDialogOpen","editDialogOpen","setEditDialogOpen","requestToEdit","setRequestToEdit","menuAnchor","setMenuAnchor","menuRequest","setMenuRequest","deleting","setDeleting","optimisticallyDeleted","setOptimisticallyDeleted","setDeleteDialogState","request","apiKeyValues","setApiKeyValues","Map","apiKeyLoading","setApiKeyLoading","alreadyReadKeys","setAlreadyReadKeys","showOnceWarningOpen","setShowOnceWarningOpen","pendingKeyReveal","setPendingKeyReveal","metadata","annotations","name","useAsync","identity","getBackstageIdentity","profile","getProfileInfo","userEntityRef","email","requests","loading","requestsLoading","requestsError","items","filter","r","spec","apiProductRef","plansLoading","plansError","data","find","resourceRef","allowed","canCreateRequest","createRequestPermissionLoading","createRequestPermissionError","useKuadrantPermission","kuadrantApiKeyCreatePermission","canDeleteOwnKey","deleteOwnPermissionLoading","deleteOwnPermissionError","kuadrantApiKeyDeleteOwnPermission","canDeleteAllKeys","deleteAllPermissionLoading","deleteAllPermissionError","kuadrantApiKeyDeleteAllPermission","canUpdateRequest","updateRequestPermissionLoading","updateRequestPermissionError","kuadrantApiKeyUpdateOwnPermission","handleMenuClose","handleMenuEdit","handleMenuDeleteClick","toggleVisibility","keyName","prev","newSet","has","delete","add","detailPanelConfig","useMemo","render","rowData","revealedKey","get","DetailPanelContent","apiName","revealedApiKey","api","selectedLanguage","setSelectedLanguage","hostname","apiHostname","displayApiKey","snippets","credentials","authorizationHeader","customHeader","headerName","generateCustomHeaderSnippets","queryString","paramName","generateQueryStringSnippets","cookie","cookieName","generateCookieSnippets","generateAuthCodeSnippets","authScheme","stopPropagation","gutterBottom","border","whiteSpace","wordBreak","overflowWrap","paragraph","Tabs","newValue","indicatorColor","Tab","mt","CodeSnippet","text","language","showCopyCodeButton","permissionError","Progress","ResponseErrorPanel","failedPermission","myRequests","discoveredPlans","pendingRequests","phase","approvedRequests","rejectedRequests","approvedColumns","title","field","row","Chip","reviewedAt","Date","toLocaleDateString","searchable","filtering","isVisible","isLoading","apiKeyValue","hasSecretRef","secretRef","canReadSecret","isAlreadyRead","Tooltip","fontFamily","marginRight","VisibilityOffIcon","IconButton","navigator","clipboard","writeText","FileCopyIcon","span","requestNamespace","requestName","next","clearApiKeyValue","VisibilityIcon","ownerId","requestedBy","canDeleteResource","rect","currentTarget","getBoundingClientRect","top","bottom","left","aria-controls","aria-haspopup","MoreVertIcon","requestColumns","isPending","icon","HourglassEmptyIcon","CancelIcon","placement","overflow","textOverflow","creationTimestamp","canDelete","pendingRequestColumns","col","Grid","container","spacing","direction","item","flexDirection","AddIcon","length","data-plans-count","readyCondition","conditions","c","type","planCondition","textAlign","Table","options","paging","pageSize","search","debounceInterval","toolbar","emptyRowsWhenPaging","columns","detailPanel","Menu","Boolean","anchorReference","anchorPosition","push","EditAPIKeyDialog","availablePlans","ConfirmDeleteDialog","description","onConfirm","handleDeleteRequest","onCancel","WarningIcon","strong","set","fetchApiKeyFromSecret","versionedHolder","useVersionedContext","atVersion","createVersionedContext"],"sourceRoot":""}
|
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
"use strict";(self.webpackChunkinternal_plugin_kuadrant=self.webpackChunkinternal_plugin_kuadrant||[]).push([[4682],{5030:(e,t,n)=>{Object.defineProperty(t,"__esModule",{value:!0});var a=n(85608),s=n(95478),r=a.__importDefault(n(10009));t.default=function(e,t,n){void 0===t&&(t=[]),void 0===n&&(n={loading:!1});var i=s.useRef(0),o=r.default(),l=s.useState(n),c=l[0],d=l[1],u=s.useCallback(function(){for(var t=[],n=0;n<arguments.length;n++)t[n]=arguments[n];var s=++i.current;return c.loading||d(function(e){return a.__assign(a.__assign({},e),{loading:!0})}),e.apply(void 0,t).then(function(e){return o()&&s===i.current&&d({value:e,loading:!1}),e},function(e){return o()&&s===i.current&&d({error:e,loading:!1}),e})},t);return[c,u]}},10009:(e,t,n)=>{Object.defineProperty(t,"__esModule",{value:!0});var a=n(95478);t.default=function(){var e=a.useRef(!1),t=a.useCallback(function(){return e.current},[]);return a.useEffect(function(){return e.current=!0,function(){e.current=!1}},[]),t}},12229:(e,t,n)=>{n.d(t,{Z:()=>A});var a=n(31085),s=n(95478),r=n.n(s),i=n(10394),o=n(72501),l=n(64947),c=n(37197),d=n(69621),u=n(12981),p=n(86901),m=n(69076),h=n(58837),v=n(6924),g=n(23164);const f=(0,h.A)(e=>({root:{width:240,minWidth:240,padding:e.spacing(2),borderRight:`1px solid ${e.palette.divider}`,backgroundColor:e.palette.background.paper,height:"100%",overflowY:"auto"},sectionTitle:{fontWeight:600,fontSize:"0.75rem",textTransform:"uppercase",letterSpacing:"0.05em",color:e.palette.text.secondary,marginBottom:e.spacing(1),display:"flex",alignItems:"center",justifyContent:"space-between",cursor:"pointer",userSelect:"none"},filterSection:{marginBottom:e.spacing(2)},checkbox:{padding:e.spacing(.5)},checkboxLabel:{fontSize:"0.875rem"},clearButton:{marginTop:e.spacing(2)},count:{fontSize:"0.75rem",color:e.palette.text.secondary,marginLeft:e.spacing(1)}})),A=({sections:e,filters:t,onChange:n,onClear:s})=>{const h=f(),[A,x]=r().useState(new Set(e.filter(e=>e.collapsed).map(e=>e.id))),j=Object.values(t).some(e=>e.length>0);return(0,a.jsxs)(i.A,{className:h.root,children:[(0,a.jsxs)(i.A,{display:"flex",justifyContent:"space-between",alignItems:"center",mb:2,children:[(0,a.jsx)(o.A,{variant:"subtitle2",children:"Filters"}),j&&(0,a.jsx)(l.A,{size:"small",color:"primary",onClick:()=>{const t={};e.forEach(e=>{t[e.id]=[]}),n(t),null==s||s()},children:"Clear all"})]}),(0,a.jsx)(c.A,{}),e.map(e=>{const s=A.has(e.id),r=(t[e.id]||[]).length;return(0,a.jsxs)(i.A,{className:h.filterSection,mt:2,children:[(0,a.jsxs)(i.A,{className:h.sectionTitle,onClick:()=>{return t=e.id,void x(e=>{const n=new Set(e);return n.has(t)?n.delete(t):n.add(t),n});var t},children:[(0,a.jsxs)(i.A,{display:"flex",alignItems:"center",children:[(0,a.jsx)("span",{children:e.title}),r>0&&(0,a.jsxs)("span",{className:h.count,children:["(",r,")"]})]}),s?(0,a.jsx)(v.A,{fontSize:"small"}):(0,a.jsx)(g.A,{fontSize:"small"})]}),(0,a.jsx)(d.A,{in:!s,children:(0,a.jsx)(u.A,{children:e.options.map(s=>(0,a.jsx)(p.A,{control:(0,a.jsx)(m.A,{checked:(t[e.id]||[]).includes(s.value),onChange:()=>((e,a)=>{const s=t[e]||[],r=s.includes(a)?s.filter(e=>e!==a):[...s,a];n({...t,[e]:r})})(e.id,s.value),size:"small",className:h.checkbox,color:"primary"}),label:(0,a.jsxs)(i.A,{display:"flex",alignItems:"center",children:[(0,a.jsx)("span",{className:h.checkboxLabel,children:s.label}),void 0!==s.count&&(0,a.jsxs)("span",{className:h.count,children:["(",s.count,")"]})]})},s.value))})})]},e.id)})]})}},14682:(e,t,n)=>{n.r(t),n.d(t,{ApiKeysPage:()=>se});var a=n(31085),s=n(95478),r=n.n(s),i=n(10394),o=n(31653),l=n(38605),c=n(289),d=n(15831),u=n(45210),p=n(46681),m=n(38599),h=n(49634),v=n(37725),g=n(86687),f=n(42367),A=n(25010),x=n(22097),j=n(91638),y=n(58837),b=n(72501),k=n(67720),w=n(71677),P=n(29365),S=n(78467),C=n(37757),q=n(26343),R=n(76891),I=n(61477),$=n(46805),z=n(93453),T=n(64947),B=n(32269),N=n(61524),M=n(99594),E=n(77225),_=n(39590),L=n(16397),F=n(63221),O=n(12229),D=n(46299);const W=(0,y.A)(e=>({container:{display:"flex",height:"100%",minHeight:400},tableContainer:{flex:1,overflow:"auto",padding:10},useCasePanel:{padding:e.spacing(2),backgroundColor:e.palette.background.default},useCaseLabel:{fontWeight:600,marginBottom:e.spacing(1),color:e.palette.text.secondary,textTransform:"uppercase",fontSize:"0.75rem"},rejectedBanner:{backgroundColor:e.palette.error.light,border:`1px solid ${e.palette.error.main}`,borderRadius:e.shape.borderRadius,padding:e.spacing(1.5,2),marginBottom:e.spacing(2),display:"flex",alignItems:"center",gap:e.spacing(1)}})),K=({request:e})=>{var t,n;const s=W(),r="Rejected"===(null===(t=e.status)||void 0===t?void 0:t.phase),o=(null===(n=e.spec.apiProductRef)||void 0===n?void 0:n.name)||"unknown";return(0,a.jsxs)(i.A,{className:s.useCasePanel,onClick:e=>e.stopPropagation(),children:[r&&(0,a.jsxs)(i.A,{className:s.rejectedBanner,children:[(0,a.jsx)(E.A,{color:"error",fontSize:"small"}),(0,a.jsxs)(b.A,{variant:"body2",children:["This API key was rejected."," ",(0,a.jsx)(v.N_,{to:`/catalog/default/api/${o}/api-keys`,children:"Request a new API key"})]})]}),(0,a.jsx)(b.A,{className:s.useCaseLabel,children:"Use Case"}),(0,a.jsx)(b.A,{variant:"body2",children:e.spec.useCase||"No use case provided"})]})},U=()=>{var e,t;const n=W(),r=(0,h.useNavigate)(),o=(0,x.useApi)(x.configApiRef),l=(0,x.useApi)(x.fetchApiRef),c=(0,x.useApi)(x.alertApiRef),d=o.getString("backend.baseUrl"),[u,p]=(0,s.useState)(new Set),[m,y]=(0,s.useState)(null),[U,H]=(0,s.useState)(null),[V,Y]=(0,s.useState)({open:!1,request:null,plans:[]}),[Z,J]=(0,s.useState)(0),[X,G]=(0,s.useState)(null),[Q,ee]=(0,s.useState)({open:!1,request:null}),[te,ne]=(0,s.useState)(new Map),[ae,se]=(0,s.useState)(new Set),[re,ie]=(0,s.useState)(new Set),[oe,le]=(0,s.useState)(!1),[ce,de]=(0,s.useState)(null),[ue,pe]=(0,s.useState)(new Set),[me,he]=(0,s.useState)({status:[],apiProduct:[],tier:[]}),{value:ve,loading:ge,error:fe}=(0,j.A)(async()=>{const[e,t]=await Promise.all([l.fetch(`${d}/api/kuadrant/requests/my`),l.fetch(`${d}/api/kuadrant/apiproducts`)]);if(!e.ok)throw new Error("failed to fetch requests");const n=(await e.json()).items||[];let a=[];t.ok&&(a=(await t.json()).items||[]);const s=new Map;return a.forEach(e=>{var t;const n=`${e.metadata.namespace}/${e.metadata.name}`,a=(null===(t=e.metadata.annotations)||void 0===t?void 0:t["backstage.io/owner"])||"unknown";s.set(n,a)}),{requests:n,products:a,ownerMap:s}},[d,l,Z]),Ae=(0,s.useMemo)(()=>(null==ve?void 0:ve.requests)?ve.requests.filter(e=>!ue.has(e.metadata.name)):[],[null==ve?void 0:ve.requests,ue]),xe=(0,s.useMemo)(()=>{const e={Approved:0,Pending:0,Rejected:0},t=new Map,n=new Map;return Ae.forEach(a=>{var s,r;const i=(null===(s=a.status)||void 0===s?void 0:s.phase)||"Pending";e[i]++;const o=(null===(r=a.spec.apiProductRef)||void 0===r?void 0:r.name)||"unknown";t.set(o,(t.get(o)||0)+1);const l=a.spec.planTier||"unknown";n.set(l,(n.get(l)||0)+1)}),[{id:"status",title:"Status",options:[{value:"Approved",label:"Active",count:e.Approved},{value:"Pending",label:"Pending",count:e.Pending},{value:"Rejected",label:"Rejected",count:e.Rejected}]},{id:"apiProduct",title:"API Product",options:Array.from(t.entries()).map(([e,t])=>({value:e,label:e,count:t})),collapsed:t.size>5},{id:"tier",title:"Tier",options:Array.from(n.entries()).map(([e,t])=>({value:e,label:e.charAt(0).toUpperCase()+e.slice(1),count:t}))}]},[Ae]),je=(0,s.useMemo)(()=>Ae.filter(e=>{if(me.status.length>0){var t;const n=(null===(t=e.status)||void 0===t?void 0:t.phase)||"Pending";if(!me.status.includes(n))return!1}if(me.apiProduct.length>0){var n;const t=(null===(n=e.spec.apiProductRef)||void 0===n?void 0:n.name)||"unknown";if(!me.apiProduct.includes(t))return!1}if(me.tier.length>0){const t=e.spec.planTier||"unknown";if(!me.tier.includes(t))return!1}return!0}),[Ae,me]),ye=e=>{p(t=>{const n=new Set(t);return n.has(e)?n.delete(e):n.add(e),n})},be=()=>{y(null),H(null)},ke=async()=>{if(!U)return;const e=U;be();try{var t;const a=null===(t=e.spec.apiProductRef)||void 0===t?void 0:t.name,s=e.metadata.namespace,r=await l.fetch(`${d}/api/kuadrant/apiproducts/${s}/${a}`);if(r.ok){var n;const t=(null===(n=(await r.json()).spec)||void 0===n?void 0:n.plans)||[];Y({open:!0,request:e,plans:t})}else Y({open:!0,request:e,plans:[]})}catch(t){console.error("Error fetching plans:",t),Y({open:!0,request:e,plans:[]})}},we=()=>{if(!U)return;const e=U;be(),ee({open:!0,request:e})},Pe=[{title:"API Product",field:"spec.apiProductRef.name",render:e=>{var t;const n=(null===(t=e.spec.apiProductRef)||void 0===t?void 0:t.name)||"unknown";return(0,a.jsx)(v.N_,{to:`/catalog/default/api/${n}/api-keys`,children:(0,a.jsx)("strong",{children:n})})}},{title:"Owner",field:"owner",render:e=>{var t,n;const s=`${e.metadata.namespace}/${null===(t=e.spec.apiProductRef)||void 0===t?void 0:t.name}`,r=((null==ve||null===(n=ve.ownerMap)||void 0===n?void 0:n.get(s))||"unknown").replace(/^user:default\//,"");return(0,a.jsx)(b.A,{variant:"body2",children:r})}},{title:"Status",field:"status.phase",render:e=>{var t;const n=(null===(t=e.status)||void 0===t?void 0:t.phase)||"Pending",s="Approved"===n?"Active":n;return(0,a.jsx)(k.A,{label:s,size:"small",style:(0,D.S)(n)})}},{title:"Tier",field:"spec.planTier",render:e=>(0,a.jsx)(k.A,{label:e.spec.planTier,size:"small",variant:"outlined"})},{title:"API Key",field:"status.secretRef",filtering:!1,render:e=>{var t,n,s,r;if("Approved"!==(null===(t=e.status)||void 0===t?void 0:t.phase))return(0,a.jsx)(b.A,{variant:"body2",color:"textSecondary",children:"-"});const o=`${e.metadata.namespace}/${e.metadata.name}`,l=null===(s=e.status)||void 0===s||null===(n=s.secretRef)||void 0===n?void 0:n.name,d=u.has(e.metadata.name),p=ae.has(o),m=te.get(o),h=!1!==(null===(r=e.status)||void 0===r?void 0:r.canReadSecret),v=re.has(o)||!h;return l?v&&!m?(0,a.jsx)(w.Ay,{title:"This API key has already been viewed and cannot be retrieved again",children:(0,a.jsxs)(i.A,{display:"flex",alignItems:"center",children:[(0,a.jsx)(b.A,{variant:"body2",color:"textSecondary",style:{fontFamily:"monospace",marginRight:8},children:"Already viewed"}),(0,a.jsx)(N.A,{fontSize:"small",color:"disabled"})]})}):(0,a.jsxs)(i.A,{display:"flex",alignItems:"center",style:{gap:8},children:[(0,a.jsx)(i.A,{fontFamily:"monospace",fontSize:"0.875rem",children:p?"Loading...":d&&m?m:"•".repeat(20)+"..."}),d&&m&&(0,a.jsx)(w.Ay,{title:"Copy to clipboard",children:(0,a.jsx)(P.A,{size:"small",onClick:async()=>{m&&(await navigator.clipboard.writeText(m),c.post({message:"API key copied to clipboard",severity:"success",display:"transient"}))},children:(0,a.jsx)(M.A,{fontSize:"small"})})}),(0,a.jsx)(w.Ay,{title:d?"Hide API key":"Reveal API key (one-time only)",children:(0,a.jsx)("span",{children:(0,a.jsx)(P.A,{size:"small",onClick:()=>{d?(((e,t)=>{const n=`${e}/${t}`;ne(e=>{const t=new Map(e);return t.delete(n),t})})(e.metadata.namespace,e.metadata.name),ye(e.metadata.name)):v||(de({namespace:e.metadata.namespace,name:e.metadata.name}),le(!0))},disabled:p||v&&!m,children:d?(0,a.jsx)(N.A,{fontSize:"small"}):(0,a.jsx)(B.A,{fontSize:"small"})})})})]}):(0,a.jsx)(b.A,{variant:"body2",color:"textSecondary",children:"Awaiting secret..."})}},{title:"Requested",field:"metadata.creationTimestamp",render:e=>{if(!e.metadata.creationTimestamp)return(0,a.jsx)(b.A,{variant:"body2",children:"-"});const t=new Date(e.metadata.creationTimestamp);return(0,a.jsx)(b.A,{variant:"body2",children:t.toLocaleDateString()})}},{title:"Actions",filtering:!1,width:"100px",render:e=>X===e.metadata.name?(0,a.jsx)(S.A,{size:20}):(0,a.jsxs)(i.A,{display:"flex",style:{gap:4},children:[(0,a.jsx)(w.Ay,{title:"View details",children:(0,a.jsx)(P.A,{size:"small",onClick:t=>{t.stopPropagation(),r(`/kuadrant/api-keys/${e.metadata.namespace}/${e.metadata.name}`)},children:(0,a.jsx)(B.A,{fontSize:"small"})})}),(0,a.jsx)(w.Ay,{title:"Delete",children:(0,a.jsx)(P.A,{size:"small",onClick:t=>{t.stopPropagation(),ee({open:!0,request:e})},children:(0,a.jsx)(_.A,{fontSize:"small"})})})]})}],Se=(0,s.useMemo)(()=>[{render:e=>{var t;const n=e.rowData;return(null==n||null===(t=n.metadata)||void 0===t?void 0:t.name)?(0,a.jsx)(K,{request:n}):(0,a.jsx)(i.A,{})}}],[]);return ge?(0,a.jsx)(g.k,{}):fe?(0,a.jsx)(f._,{error:fe}):(0,a.jsxs)(a.Fragment,{children:[(0,a.jsxs)(i.A,{className:n.container,children:[(0,a.jsx)(O.Z,{sections:xe,filters:me,onChange:he}),(0,a.jsx)(i.A,{className:n.tableContainer,children:0===je.length?(0,a.jsx)(i.A,{p:4,textAlign:"center",children:(0,a.jsx)(b.A,{variant:"body1",color:"textSecondary",children:0===Ae.length?"No API keys found. Request access to an API to get started.":"No API keys match the selected filters."})}):(0,a.jsx)(A.X,{options:{paging:je.length>10,pageSize:20,search:!0,filtering:!1,debounceInterval:300,toolbar:!0,emptyRowsWhenPaging:!1},columns:Pe,data:je.map(e=>({...e,id:e.metadata.name})),detailPanel:Se})})]}),(0,a.jsx)(C.A,{id:"myapikeys-menu",open:Boolean(m),onClose:be,anchorReference:"anchorPosition",anchorPosition:m||{top:0,left:0},children:U&&(()=>{const e=[];var t;return e.push((0,a.jsx)(q.A,{onClick:()=>{r(`/kuadrant/api-keys/${U.metadata.namespace}/${U.metadata.name}`),be()},children:"View Details"},"view")),(t=U).status&&"Pending"!==t.status.phase||e.push((0,a.jsx)(q.A,{onClick:ke,children:"Edit"},"edit")),e.push((0,a.jsx)(q.A,{onClick:we,children:"Delete"},"delete")),e})()}),V.request&&(0,a.jsx)(L.e,{open:V.open,request:V.request,availablePlans:V.plans,onClose:()=>Y({open:!1,request:null,plans:[]}),onSuccess:()=>{Y({open:!1,request:null,plans:[]}),J(e=>e+1)}}),(0,a.jsx)(F.K,{open:Q.open,title:"Delete API Key",description:`Are you sure you want to delete this API key for ${(null===(t=Q.request)||void 0===t||null===(e=t.spec.apiProductRef)||void 0===e?void 0:e.name)||"this API"}?`,deleting:null!==X,onConfirm:async()=>{if(!Q.request)return;const e=Q.request,t=e.metadata.name;pe(e=>new Set(e).add(t)),G(t);try{if(!(await l.fetch(`${d}/api/kuadrant/requests/${e.metadata.namespace}/${e.metadata.name}`,{method:"DELETE"})).ok)throw new Error("Failed to delete request");J(e=>e+1),c.post({message:"API key deleted",severity:"success",display:"transient"}),ee({open:!1,request:null})}catch(e){console.error("Error deleting request:",e),pe(e=>{const n=new Set(e);return n.delete(t),n}),c.post({message:"Failed to delete API key",severity:"error",display:"transient"})}finally{G(null)}},onCancel:()=>{ee({open:!1,request:null})}}),(0,a.jsxs)(R.A,{open:oe,onClose:()=>{le(!1),de(null)},maxWidth:"sm",children:[(0,a.jsx)(I.A,{children:(0,a.jsxs)(i.A,{display:"flex",alignItems:"center",children:[(0,a.jsx)(E.A,{color:"primary",style:{marginRight:8}}),"View API Key"]})}),(0,a.jsxs)($.A,{children:[(0,a.jsxs)(b.A,{variant:"body1",paragraph:!0,children:["This API key can only be viewed ",(0,a.jsx)("strong",{children:"once"}),". After you reveal it, you will not be able to retrieve it again."]}),(0,a.jsx)(b.A,{variant:"body2",color:"textSecondary",children:"Make sure to copy and store it securely before closing this view."})]}),(0,a.jsxs)(z.A,{children:[(0,a.jsx)(T.A,{onClick:()=>{le(!1),de(null)},children:"Cancel"}),(0,a.jsx)(T.A,{variant:"contained",color:"primary",onClick:()=>{ce&&((async(e,t)=>{const n=`${e}/${t}`;if(!ae.has(n)){se(e=>new Set(e).add(n));try{const a=await l.fetch(`${d}/api/kuadrant/apikeys/${e}/${t}/secret`);if(a.ok){const e=await a.json();ne(t=>new Map(t).set(n,e.apiKey)),ie(e=>new Set(e).add(n))}else 403===a.status&&(ie(e=>new Set(e).add(n)),c.post({message:"This API key has already been viewed and cannot be retrieved again.",severity:"warning",display:"transient"}))}catch(e){const t=e instanceof Error?e.message:"unknown error occurred";c.post({message:`Failed to fetch api key: ${t}`,severity:"error",display:"transient"})}finally{se(e=>{const t=new Set(e);return t.delete(n),t})}}})(ce.namespace,ce.name),ye(ce.name)),le(!1),de(null)},children:"Reveal API Key"})]})]})]})};var H=n(35015),V=n(34955),Y=n(46205),Z=n(16249),J=n(55429),X=n(92399);const G=(0,y.A)(e=>({container:{display:"flex",height:"100%",minHeight:400},tableContainer:{flex:1,overflow:"auto",padding:10},useCasePanel:{padding:e.spacing(2),backgroundColor:e.palette.background.default},useCaseLabel:{fontWeight:600,marginBottom:e.spacing(1),color:e.palette.text.secondary,textTransform:"uppercase",fontSize:"0.75rem"},bulkActions:{padding:e.spacing(2),backgroundColor:e.palette.background.default,borderBottom:`1px solid ${e.palette.divider}`,display:"flex",alignItems:"center",justifyContent:"space-between"}})),Q=({open:e,request:t,action:n,processing:s,onClose:o,onConfirm:l})=>{var c,d;const[u,p]=r().useState(""),m="approve"===n?"Approve":"Reject",h="approve"===n?"Approving...":"Rejecting...",v="reject"===n,g=(null==t||null===(c=t.spec.requestedBy)||void 0===c?void 0:c.userId)||"",f=!v||u===g;return r().useEffect(()=>{e||p("")},[e]),(0,a.jsxs)(R.A,{open:e,onClose:s?void 0:o,maxWidth:"sm",fullWidth:!0,children:[(0,a.jsx)(I.A,{children:v?(0,a.jsxs)(i.A,{display:"flex",alignItems:"center",style:{gap:8},children:[(0,a.jsx)(X.A,{color:"error"}),(0,a.jsxs)("span",{children:[m," API Key"]})]}):(0,a.jsxs)("span",{children:[m," API Key"]})}),(0,a.jsx)($.A,{children:t&&(0,a.jsxs)(a.Fragment,{children:[(0,a.jsxs)("p",{children:[(0,a.jsx)("strong",{children:"User:"})," ",t.spec.requestedBy.userId]}),(0,a.jsxs)("p",{children:[(0,a.jsx)("strong",{children:"API:"})," ",(null===(d=t.spec.apiProductRef)||void 0===d?void 0:d.name)||"unknown"]}),(0,a.jsxs)("p",{children:[(0,a.jsx)("strong",{children:"Tier:"})," ",t.spec.planTier]}),(0,a.jsxs)(i.A,{mb:2,children:[(0,a.jsx)(b.A,{variant:"body2",component:"span",style:{fontWeight:"bold"},children:"Use Case:"})," ",(0,a.jsx)(b.A,{variant:"body2",component:"span",style:{whiteSpace:"pre-wrap"},children:t.spec.useCase||"-"})]}),v&&(0,a.jsxs)(i.A,{mt:2,children:[(0,a.jsxs)(b.A,{variant:"body2",color:"textSecondary",gutterBottom:!0,children:["Type ",(0,a.jsx)("strong",{children:g})," to confirm rejection:"]}),(0,a.jsx)(Z.A,{fullWidth:!0,variant:"outlined",size:"small",value:u,onChange:e=>p(e.target.value),disabled:s,autoFocus:!0,placeholder:g})]})]})}),(0,a.jsxs)(z.A,{children:[(0,a.jsx)(T.A,{onClick:o,disabled:s,children:"Cancel"}),(0,a.jsx)(T.A,{onClick:l,color:"approve"===n?"primary":"secondary",variant:"contained",disabled:s||!f,startIcon:s?(0,a.jsx)(S.A,{size:16,color:"inherit"}):void 0,children:s?h:m})]})]})},ee=({open:e,requests:t,action:n,processing:s,onClose:r,onConfirm:o})=>{const l="approve"===n,c=l?"Approve All":"Reject All",d=l?"Approving...":"Rejecting...";return(0,a.jsxs)(R.A,{open:e,onClose:s?void 0:r,maxWidth:"md",fullWidth:!0,children:[(0,a.jsxs)(I.A,{children:[l?"Approve":"Reject"," ",t.length," API Keys"]}),(0,a.jsxs)($.A,{children:[(0,a.jsxs)(b.A,{variant:"body2",paragraph:!0,children:["You are about to ",l?"approve":"reject"," the following API keys:"]}),(0,a.jsx)(i.A,{mb:2,maxHeight:200,overflow:"auto",children:t.map(e=>{var t;return(0,a.jsx)(i.A,{mb:1,p:1,bgcolor:"background.default",children:(0,a.jsxs)(b.A,{variant:"body2",children:[(0,a.jsx)("strong",{children:e.spec.requestedBy.userId})," -"," ",(null===(t=e.spec.apiProductRef)||void 0===t?void 0:t.name)||"unknown"," (",e.spec.planTier,")"]})},`${e.metadata.namespace}/${e.metadata.name}`)})})]}),(0,a.jsxs)(z.A,{children:[(0,a.jsx)(T.A,{onClick:r,disabled:s,children:"Cancel"}),(0,a.jsx)(T.A,{onClick:o,color:l?"primary":"secondary",variant:"contained",disabled:s,startIcon:s?(0,a.jsx)(S.A,{size:16,color:"inherit"}):void 0,children:s?d:c})]})]})},te=({request:e})=>{const t=G();return(0,a.jsxs)(i.A,{className:t.useCasePanel,onClick:e=>e.stopPropagation(),children:[(0,a.jsx)(b.A,{className:t.useCaseLabel,children:"Use Case"}),(0,a.jsx)(b.A,{variant:"body2",children:e.spec.useCase||"No use case provided"})]})},ne=()=>{var e;const t=G(),n=(0,x.useApi)(x.configApiRef),r=(0,x.useApi)(x.fetchApiRef),o=(0,x.useApi)(x.identityApiRef),l=(0,x.useApi)(x.alertApiRef),c=n.getString("backend.baseUrl"),[d,u]=(0,s.useState)(0),[p,m]=(0,s.useState)([]),[h,j]=(0,s.useState)({open:!1,request:null,action:"approve",processing:!1}),[y,w]=(0,s.useState)({open:!1,requests:[],action:"approve",processing:!1}),[P,S]=(0,s.useState)({status:[],apiProduct:[],tier:[]}),{allowed:C,loading:q,error:R}=(0,Y.l)(V.z4),{allowed:I,loading:$,error:z}=(0,Y.l)(V.q0),B=q||$,N=R||z,{value:M,loading:E,error:_}=(0,H.A)(async()=>{const e=(await o.getBackstageIdentity()).userEntityRef,[t,n]=await Promise.all([r.fetch(`${c}/api/kuadrant/requests`),r.fetch(`${c}/api/kuadrant/apiproducts`)]);if(!t.ok)return{allRequests:[],reviewedBy:e,ownedApiProducts:new Set};const a=t.headers.get("content-type");if(!(null==a?void 0:a.includes("application/json")))return l.post({message:"Unexpected content-type from the server response.",display:"transient",severity:"warning"}),{allRequests:[],reviewedBy:e,ownedApiProducts:new Set};const s=(await t.json()).items||[],i=new Set;if(n.ok){const t=await n.json();for(const n of t.items||[]){var d,u;(null===(u=n.metadata)||void 0===u||null===(d=u.annotations)||void 0===d?void 0:d["backstage.io/owner"])===e&&i.add(`${n.metadata.namespace}/${n.metadata.name}`)}}return{allRequests:s,reviewedBy:e,ownedApiProducts:i}},[c,r,o,d]),L=(0,s.useMemo)(()=>{if(!(null==M?void 0:M.allRequests))return[];const e={Approved:0,Pending:0,Rejected:0},t=new Map,n=new Map;return M.allRequests.forEach(a=>{var s,r;const i=(null===(s=a.status)||void 0===s?void 0:s.phase)||"Pending";e[i]++;const o=(null===(r=a.spec.apiProductRef)||void 0===r?void 0:r.name)||"unknown";t.set(o,(t.get(o)||0)+1);const l=a.spec.planTier||"unknown";n.set(l,(n.get(l)||0)+1)}),[{id:"status",title:"Status",options:[{value:"Pending",label:"Pending",count:e.Pending},{value:"Approved",label:"Approved",count:e.Approved},{value:"Rejected",label:"Rejected",count:e.Rejected}]},{id:"apiProduct",title:"API Product",options:Array.from(t.entries()).map(([e,t])=>({value:e,label:e,count:t})),collapsed:t.size>5},{id:"tier",title:"Tier",options:Array.from(n.entries()).map(([e,t])=>({value:e,label:e.charAt(0).toUpperCase()+e.slice(1),count:t}))}]},[null==M?void 0:M.allRequests]),F=(0,s.useMemo)(()=>(null==M?void 0:M.allRequests)?M.allRequests.filter(e=>{if(P.status.length>0){var t;const n=(null===(t=e.status)||void 0===t?void 0:t.phase)||"Pending";if(!P.status.includes(n))return!1}if(P.apiProduct.length>0){var n;const t=(null===(n=e.spec.apiProductRef)||void 0===n?void 0:n.name)||"unknown";if(!P.apiProduct.includes(t))return!1}if(P.tier.length>0){const t=e.spec.planTier||"unknown";if(!P.tier.includes(t))return!1}return!0}):[],[null==M?void 0:M.allRequests,P]),W=e=>new Date(e).toLocaleDateString("en-GB",{year:"numeric",month:"short",day:"numeric"}),K=[{title:"Requester",field:"spec.requestedBy.userId",render:e=>(0,a.jsx)(b.A,{variant:"body2",children:e.spec.requestedBy.userId})},{title:"API Product",field:"spec.apiProductRef.name",render:e=>{var t;const n=(null===(t=e.spec.apiProductRef)||void 0===t?void 0:t.name)||"unknown";return(0,a.jsx)(v.N_,{to:`/catalog/default/api/${n}`,children:(0,a.jsx)("strong",{children:n})})}},{title:"Status",field:"status.phase",render:e=>{var t;const n=(null===(t=e.status)||void 0===t?void 0:t.phase)||"Pending";return(0,a.jsx)(k.A,{label:n,size:"small",style:(0,D.S)(n)})}},{title:"Tier",field:"spec.planTier",render:e=>(0,a.jsx)(k.A,{label:e.spec.planTier,size:"small",variant:"outlined"})},{title:"Requested",field:"metadata.creationTimestamp",render:e=>(0,a.jsx)(b.A,{variant:"body2",children:e.metadata.creationTimestamp?W(e.metadata.creationTimestamp):"-"})},{title:"Reviewed By",field:"status.reviewedBy",render:e=>{var t;if(!(null===(t=e.status)||void 0===t?void 0:t.reviewedBy))return(0,a.jsx)(b.A,{variant:"body2",color:"textSecondary",children:"-"});const n=e.status.reviewedBy.replace(/^user:default\//,""),s="system"===n;return(0,a.jsxs)(i.A,{children:[(0,a.jsx)(b.A,{variant:"body2",children:s?"Automatic":n}),e.status.reviewedAt&&(0,a.jsx)(b.A,{variant:"caption",color:"textSecondary",children:W(e.status.reviewedAt)})]})}},{title:"Actions",filtering:!1,render:e=>{var t,n,s;if("Pending"!==((null===(t=e.status)||void 0===t?void 0:t.phase)||"Pending"))return null;const r=`${e.metadata.namespace}/${(null===(n=e.spec.apiProductRef)||void 0===n?void 0:n.name)||"unknown"}`;var o;const l=null!==(o=null==M||null===(s=M.ownedApiProducts)||void 0===s?void 0:s.has(r))&&void 0!==o&&o;return C||I&&l?(0,a.jsxs)(i.A,{display:"flex",style:{gap:8},children:[(0,a.jsx)(T.A,{size:"small",startIcon:(0,a.jsx)(J.A,{}),onClick:()=>{j({open:!0,request:e,action:"approve",processing:!1})},color:"primary",variant:"outlined",children:"Approve"}),(0,a.jsx)(T.A,{size:"small",startIcon:(0,a.jsx)(X.A,{}),onClick:()=>{j({open:!0,request:e,action:"reject",processing:!1})},color:"secondary",variant:"outlined",children:"Reject"})]}):null}}],U=(0,s.useMemo)(()=>[{render:e=>{var t;const n=e.rowData;return(null==n||null===(t=n.metadata)||void 0===t?void 0:t.name)?(0,a.jsx)(te,{request:n}):(0,a.jsx)(i.A,{})}}],[]);if(E||B)return(0,a.jsx)(g.k,{});if(_)return(0,a.jsx)(f._,{error:_});if(N)return(0,a.jsx)(i.A,{p:2,children:(0,a.jsxs)(b.A,{color:"error",children:["Unable to check permissions: ",N.message]})});const Z=C||I;return(0,a.jsxs)(a.Fragment,{children:[(0,a.jsxs)(i.A,{className:t.container,children:[(0,a.jsx)(O.Z,{sections:L,filters:P,onChange:S}),(0,a.jsxs)(i.A,{className:t.tableContainer,children:[p.length>0&&(0,a.jsxs)(i.A,{className:t.bulkActions,children:[(0,a.jsxs)(b.A,{variant:"body2",children:[p.length," request",1!==p.length?"s":""," selected"]}),(0,a.jsxs)(i.A,{display:"flex",style:{gap:8},children:[(0,a.jsx)(T.A,{size:"small",variant:"contained",color:"primary",startIcon:(0,a.jsx)(J.A,{}),onClick:()=>{0!==p.length&&w({open:!0,requests:p,action:"approve",processing:!1})},children:"Approve Selected"}),(0,a.jsx)(T.A,{size:"small",variant:"contained",color:"secondary",startIcon:(0,a.jsx)(X.A,{}),onClick:()=>{0!==p.length&&w({open:!0,requests:p,action:"reject",processing:!1})},children:"Reject Selected"})]})]}),0===F.length?(0,a.jsx)(i.A,{p:4,textAlign:"center",children:(0,a.jsx)(b.A,{variant:"body1",color:"textSecondary",children:0===(null==M||null===(e=M.allRequests)||void 0===e?void 0:e.length)?"No API keys found.":"No API keys match the selected filters."})}):(0,a.jsx)(A.X,{options:{selection:Z,showSelectAllCheckbox:F.some(e=>{var t;return!(null===(t=e.status)||void 0===t?void 0:t.phase)||"Pending"===e.status.phase}),selectionProps:e=>{var t,n;return{disabled:"Pending"!==(null===(t=e.status)||void 0===t?void 0:t.phase)&&void 0!==(null===(n=e.status)||void 0===n?void 0:n.phase)}},paging:F.length>10,pageSize:20,search:!0,filtering:!1,debounceInterval:300,showTextRowsSelected:!1,toolbar:!0,emptyRowsWhenPaging:!1},columns:K,data:F.map(e=>{const t=p.some(t=>t.metadata.name===e.metadata.name&&t.metadata.namespace===e.metadata.namespace);return{...e,id:e.metadata.name,tableData:{checked:t}}}),onSelectionChange:e=>{const t=e.filter(e=>{var t;return!(null===(t=e.status)||void 0===t?void 0:t.phase)||"Pending"===e.status.phase});m(t)},detailPanel:U})]})]}),(0,a.jsx)(Q,{open:h.open,request:h.request,action:h.action,processing:h.processing,onClose:()=>j({open:!1,request:null,action:"approve",processing:!1}),onConfirm:async()=>{if(!h.request||!M)return;j(e=>({...e,processing:!0}));const e="approve"===h.action?`${c}/api/kuadrant/requests/${h.request.metadata.namespace}/${h.request.metadata.name}/approve`:`${c}/api/kuadrant/requests/${h.request.metadata.namespace}/${h.request.metadata.name}/reject`;try{if(!(await r.fetch(e,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({reviewedBy:M.reviewedBy})})).ok)throw new Error(`failed to ${h.action} request`);j({open:!1,request:null,action:"approve",processing:!1}),m(e=>e.filter(e=>{var t,n;return e.metadata.name!==(null===(t=h.request)||void 0===t?void 0:t.metadata.name)||e.metadata.namespace!==(null===(n=h.request)||void 0===n?void 0:n.metadata.namespace)})),u(e=>e+1);const t="approve"===h.action?"approved":"rejected";l.post({message:`API key ${t}`,severity:"success",display:"transient"})}catch(e){console.error(`error ${h.action}ing request:`,e),j(e=>({...e,processing:!1})),l.post({message:`Failed to ${h.action} API key`,severity:"error",display:"transient"})}}}),(0,a.jsx)(ee,{open:y.open,requests:y.requests,action:y.action,processing:y.processing,onClose:()=>w({open:!1,requests:[],action:"approve",processing:!1}),onConfirm:async()=>{if(!M||0===y.requests.length)return;w(e=>({...e,processing:!0}));const e="approve"===y.action,t=e?`${c}/api/kuadrant/requests/bulk-approve`:`${c}/api/kuadrant/requests/bulk-reject`;try{if(!(await r.fetch(t,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({requests:y.requests.map(e=>({namespace:e.metadata.namespace,name:e.metadata.name})),reviewedBy:M.reviewedBy})})).ok)throw new Error(`failed to bulk ${y.action} requests`);const n=y.requests.length,a=e?"approved":"rejected";w({open:!1,requests:[],action:"approve",processing:!1}),m([]),u(e=>e+1),l.post({message:`${n} API keys ${a}`,severity:"success",display:"transient"})}catch(e){console.error(`error bulk ${y.action}ing requests:`,e),w(e=>({...e,processing:!1})),l.post({message:`Failed to bulk ${y.action} API keys`,severity:"error",display:"transient"})}}})]})},ae=()=>{const[e,t]=(0,s.useState)(0),{allowed:n,loading:r}=(0,Y.l)(V.KV);return(0,a.jsxs)(c.Y,{themeId:"tool",children:[(0,a.jsx)(d.Y,{title:"API Keys",subtitle:"API keys management for Kubernetes",children:(0,a.jsx)(u.Y,{children:"Manage your API keys and access requests"})}),(0,a.jsxs)(p.U,{children:[(0,a.jsx)(i.A,{mb:2,children:(0,a.jsxs)(o.A,{value:e,onChange:(e,n)=>{t(n)},indicatorColor:"primary",textColor:"primary",children:[(0,a.jsx)(l.A,{label:"My API keys","data-testid":"my-api-keys-tab"}),!r&&n&&(0,a.jsx)(l.A,{label:"API keys approval","data-testid":"api-keys-approval-tab"})]})}),0===e&&(0,a.jsx)(U,{}),1===e&&n&&(0,a.jsx)(ne,{})]})]})},se=()=>(0,a.jsx)(m.B,{permission:V.DS,errorMessage:"you don't have permission to view the API Keys page",children:(0,a.jsx)(ae,{})})},23164:(e,t,n)=>{var a=n(4293),s=n(78920);t.A=void 0;var r=s(n(95478)),i=(0,a(n(74044)).default)(r.createElement("path",{d:"M12 8l-6 6 1.41 1.41L12 10.83l4.59 4.58L18 14z"}),"ExpandLess");t.A=i},27799:(e,t,n)=>{var a=n(4293),s=n(78920);t.A=void 0;var r=s(n(95478)),i=(0,a(n(74044)).default)(r.createElement("path",{d:"M21 5v6.59l-3-3.01-4 4.01-4-4-4 4-3-3.01V5c0-1.1.9-2 2-2h14c1.1 0 2 .9 2 2zm-3 6.42l3 3.01V19c0 1.1-.9 2-2 2H5c-1.1 0-2-.9-2-2v-6.58l3 2.99 4-4 4 4 4-3.99z"}),"BrokenImage");t.A=i},38599:(e,t,n)=>{n.d(t,{B:()=>l});var a=n(31085),s=(n(95478),n(10394)),r=n(72501),i=n(86687),o=n(46205);const l=({children:e,permission:t,fallback:n,errorMessage:l})=>{const{allowed:c,loading:d,error:u}=(0,o.l)(t);return d?(0,a.jsx)(i.k,{}):u?(0,a.jsxs)(s.A,{p:4,children:[(0,a.jsxs)(r.A,{color:"error",children:["Unable to check permissions: ",u.message]}),(0,a.jsx)(r.A,{variant:"body2",color:"textSecondary",children:"Please try again or contact your administrator"})]}):c?(0,a.jsx)(a.Fragment,{children:e}):n?(0,a.jsx)(a.Fragment,{children:n}):(0,a.jsxs)(s.A,{p:4,children:[(0,a.jsx)(r.A,{color:"textSecondary",children:l||"You don't have permission to view this page"}),(0,a.jsx)(s.A,{mt:1,children:(0,a.jsxs)(r.A,{variant:"caption",color:"textSecondary",children:["Required permission: ",t.name]})})]})}},39590:(e,t,n)=>{var a=n(4293),s=n(78920);t.A=void 0;var r=s(n(95478)),i=(0,a(n(74044)).default)(r.createElement("path",{d:"M6 19c0 1.1.9 2 2 2h8c1.1 0 2-.9 2-2V7H6v12zM19 4h-3.5l-1-1h-5l-1 1H5v2h14V4z"}),"Delete");t.A=i},45210:(e,t,n)=>{n.d(t,{Y:()=>R});var a=n(31085),s=n(22097),r=n(10394),i=n(64947),o=n(93453),l=n(29365),c=n(46423),d=n(5951),u=n(26343),p=n(28233),m=n(55197),h=n(37976),v=n(72501),g=n(5893),f=n(95478),A=(n(45250),n(49634),n(21006)),x=n(75501);const j=()=>{const{t:e}=(0,x.useTranslationRef)(A.O);return{url:"https://github.com/backstage/backstage/issues",items:[{title:e("supportConfig.default.title"),icon:"warning",links:[{title:e("supportConfig.default.linkTitle"),url:"https://github.com/backstage/backstage/blob/master/app-config.yaml"}]}]}};var y=n(27799);function b(e){const{id:t,Fallback:n=y.A,...r}=e,i=(0,s.useApp)().getSystemIcon(t)??n;return(0,a.jsx)(i,{...r})}function k(e){return(0,a.jsx)(b,{id:"help",...e})}var w=n(37725);const P=(0,h.makeStyles)({popoverList:{minWidth:260,maxWidth:400},menuItem:{whiteSpace:"normal"}},{name:"BackstageSupportButton"}),S=({icon:e})=>{const t=(0,s.useApp)(),n=e?t.getSystemIcon(e)??k:k;return(0,a.jsx)(n,{})},C=({link:e})=>(0,a.jsx)(w.N_,{to:e.url,children:e.title??e.url}),q=({item:e})=>(0,a.jsxs)(u.A,{button:!1,children:[(0,a.jsx)(c.A,{children:(0,a.jsx)(S,{icon:e.icon})}),(0,a.jsx)(d.A,{primary:e.title,secondary:e.links?.reduce((e,t,n)=>[...e,n>0&&(0,a.jsx)("br",{},n),(0,a.jsx)(C,{link:t},t.url)],[])})]});function R(e){const{t}=(0,x.useTranslationRef)(A.O),{title:n,items:c,children:d}=e,{items:h}=function(){const e=(0,s.useApiHolder)().get(s.configApiRef),t=e?.getOptionalConfig("app.support"),n=j();return t?{url:t.getString("url"),items:t.getConfigArray("items").flatMap(e=>({title:e.getString("title"),icon:e.getOptionalString("icon"),links:(e.getOptionalConfigArray("links")??[]).flatMap(e=>({url:e.getString("url"),title:e.getOptionalString("title")??""}))}))}:n}(),[y,b]=(0,f.useState)(!1),[w,S]=(0,f.useState)(null),C=P(),R=(0,s.useApi)(s.configApiRef).getOptionalConfig("app.support"),I=(0,g.A)(e=>e.breakpoints.down("sm")),$=e=>{S(e.currentTarget),b(!0)},z=()=>{b(!1)};return R?(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(r.A,{display:"flex",ml:1,children:I?(0,a.jsx)(l.A,{color:"primary",size:"small",onClick:$,"data-testid":"support-button","aria-label":"Support",children:(0,a.jsx)(k,{})}):(0,a.jsx)(i.A,{"data-testid":"support-button","aria-label":"Support",color:"primary",onClick:$,startIcon:(0,a.jsx)(k,{}),children:t("supportButton.title")})}),(0,a.jsxs)(m.Ay,{"data-testid":"support-button-popover",open:y,anchorEl:w,anchorOrigin:{vertical:"bottom",horizontal:"right"},transformOrigin:{vertical:"top",horizontal:"right"},onClose:z,children:[(0,a.jsxs)(p.A,{className:C.popoverList,autoFocusItem:Boolean(w),children:[n&&(0,a.jsx)(u.A,{button:!1,alignItems:"flex-start",className:C.menuItem,children:(0,a.jsx)(v.A,{variant:"subtitle1",children:n})}),f.Children.map(d,(e,t)=>(0,a.jsx)(u.A,{button:!1,alignItems:"flex-start",className:C.menuItem,children:e},`child-${t}`)),(c??h).map((e,t)=>(0,a.jsx)(q,{item:e},`item-${t}`))]}),(0,a.jsx)(o.A,{children:(0,a.jsx)(i.A,{color:"primary",onClick:z,"aria-label":"Close",children:t("supportButton.close")})})]})]}):null}},46299:(e,t,n)=>{n.d(t,{S:()=>a});const a=e=>{const t={border:"none"};switch(e){case"Approved":return{...t,backgroundColor:"#4caf50",color:"#fff"};case"Rejected":return{...t,backgroundColor:"#f44336",color:"#fff"};default:return{...t,backgroundColor:"#ff9800",color:"#fff"}}}},55429:(e,t,n)=>{var a=n(4293),s=n(78920);t.A=void 0;var r=s(n(95478)),i=(0,a(n(74044)).default)(r.createElement("path",{d:"M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm-2 15l-5-5 1.41-1.41L10 14.17l7.59-7.59L19 8l-9 9z"}),"CheckCircle");t.A=i},91638:(e,t,n)=>{var a=n(85608),s=n(95478),r=a.__importDefault(n(5030));t.A=function(e,t){void 0===t&&(t=[]);var n=r.default(e,t,{loading:!0}),a=n[0],i=n[1];return s.useEffect(function(){i()},[i]),a}}}]);
|
|
2
|
-
//# sourceMappingURL=4682.bd2dfccd.chunk.js.map
|