@kuadrant/kuadrant-backstage-plugin-frontend 0.0.2-dev-06b7d4e → 0.0.2-dev-b0a6833

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.
@@ -1 +0,0 @@
1
- {"version":3,"file":"static/7632.3141cc8f.chunk.js","mappings":"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","sources":["webpack://internal.plugin-kuadrant/./src/components/ConfirmDeleteDialog/ConfirmDeleteDialog.tsx","webpack://internal.plugin-kuadrant/./src/components/EditAPIKeyRequestDialog/EditAPIKeyRequestDialog.tsx","webpack://internal.plugin-kuadrant/./src/components/MyApiKeysCard/MyApiKeysCard.tsx","webpack://internal.plugin-kuadrant/./src/components/PermissionGate/PermissionGate.tsx","webpack://internal.plugin-kuadrant/./src/components/PlanPolicyDetailsCard/PlanPolicyDetails.tsx","webpack://internal.plugin-kuadrant/./src/components/CreateAPIProductDialog/CreateAPIProductDialog.tsx","webpack://internal.plugin-kuadrant/./src/components/EditAPIProductDialog/EditAPIProductDialog.tsx","webpack://internal.plugin-kuadrant/./src/components/KuadrantPage/KuadrantPage.tsx"],"sourcesContent":["import React, { useState, useEffect } from 'react';\nimport {\n Dialog,\n DialogTitle,\n DialogContent,\n DialogContentText,\n DialogActions,\n Button,\n TextField,\n Typography,\n Box,\n CircularProgress,\n} from '@material-ui/core';\nimport WarningIcon from '@material-ui/icons/Warning';\n\nexport interface ConfirmDeleteDialogProps {\n open: boolean;\n title: string;\n description: string;\n // for dangerous deletes, require typing this text to confirm\n confirmText?: string;\n // severity affects styling - 'high' shows warning icon and requires text confirmation\n severity?: 'normal' | 'high';\n deleting?: boolean;\n onConfirm: () => void;\n onCancel: () => void;\n}\n\nexport const ConfirmDeleteDialog = ({\n open,\n title,\n description,\n confirmText,\n severity = 'normal',\n deleting = false,\n onConfirm,\n onCancel,\n}: ConfirmDeleteDialogProps) => {\n const [inputValue, setInputValue] = useState('');\n\n // reset input when dialog opens/closes\n useEffect(() => {\n if (!open) {\n setInputValue('');\n }\n }, [open]);\n\n const requiresTextConfirmation = severity === 'high' && confirmText;\n const canConfirm = requiresTextConfirmation ? inputValue === confirmText : true;\n\n const handleConfirm = () => {\n if (canConfirm) {\n onConfirm();\n }\n };\n\n return (\n <Dialog\n open={open}\n onClose={deleting ? undefined : onCancel}\n maxWidth=\"sm\"\n fullWidth\n >\n <DialogTitle>\n {severity === 'high' && (\n <Box display=\"flex\" alignItems=\"center\" style={{ gap: 8 }}>\n <WarningIcon color=\"error\" />\n <span>{title}</span>\n </Box>\n )}\n {severity !== 'high' && title}\n </DialogTitle>\n <DialogContent>\n <DialogContentText style={{ whiteSpace: 'pre-line' }}>\n {description}\n </DialogContentText>\n {requiresTextConfirmation && (\n <Box mt={2}>\n <Typography variant=\"body2\" color=\"textSecondary\" gutterBottom>\n Type <strong>{confirmText}</strong> to confirm:\n </Typography>\n <TextField\n fullWidth\n variant=\"outlined\"\n size=\"small\"\n value={inputValue}\n onChange={e => setInputValue(e.target.value)}\n disabled={deleting}\n autoFocus\n placeholder={confirmText}\n />\n </Box>\n )}\n </DialogContent>\n <DialogActions>\n <Button onClick={onCancel} disabled={deleting}>\n Cancel\n </Button>\n <Button\n onClick={handleConfirm}\n color=\"secondary\"\n variant=\"contained\"\n disabled={deleting || !canConfirm}\n startIcon={deleting ? <CircularProgress size={16} color=\"inherit\" /> : undefined}\n >\n {deleting ? 'Deleting...' : 'Delete'}\n </Button>\n </DialogActions>\n </Dialog>\n );\n};\n","import React, { useState, useEffect } from 'react';\nimport {\n Dialog,\n DialogTitle,\n DialogContent,\n DialogActions,\n Button,\n TextField,\n Box,\n Typography,\n FormControl,\n InputLabel,\n Select,\n MenuItem,\n CircularProgress,\n} from '@material-ui/core';\nimport { useApi, configApiRef, fetchApiRef } from '@backstage/core-plugin-api';\nimport { APIKey } from '../../types/api-management';\n\ninterface EditAPIKeyDialogProps {\n open: boolean;\n onClose: () => void;\n onSuccess: () => void;\n request: APIKey;\n availablePlans: Array<{\n tier: string;\n description?: string;\n limits?: any;\n }>;\n}\n\nexport const EditAPIKeyRequestDialog = ({\n open,\n onClose,\n onSuccess,\n request,\n availablePlans,\n}: EditAPIKeyDialogProps) => {\n const config = useApi(configApiRef);\n const fetchApi = useApi(fetchApiRef);\n const backendUrl = config.getString('backend.baseUrl');\n\n const [planTier, setPlanTier] = useState('');\n const [useCase, setUseCase] = useState('');\n const [saving, setSaving] = useState(false);\n const [error, setError] = useState('');\n\n useEffect(() => {\n if (open && request) {\n setPlanTier(request.spec.planTier || '');\n setUseCase(request.spec.useCase || '');\n setError('');\n }\n }, [open, request]);\n\n const handleSave = async () => {\n if (!planTier) {\n setError('Please select a tier');\n return;\n }\n\n setError('');\n setSaving(true);\n\n try {\n const patch = {\n spec: {\n planTier,\n useCase: useCase.trim(),\n },\n };\n\n const response = await fetchApi.fetch(\n `${backendUrl}/api/kuadrant/requests/${request.metadata.namespace}/${request.metadata.name}`,\n {\n method: 'PATCH',\n headers: {\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify(patch),\n }\n );\n\n if (!response.ok) {\n const errorData = await response.json().catch(() => ({}));\n throw new Error(errorData.error || `Failed to update request: ${response.status}`);\n }\n\n onSuccess();\n onClose();\n } catch (err) {\n console.error('Error updating API key request:', err);\n setError(err instanceof Error ? err.message : 'Unknown error occurred');\n } finally {\n setSaving(false);\n }\n };\n\n const handleClose = () => {\n if (!saving) {\n setError('');\n onClose();\n }\n };\n\n return (\n <Dialog open={open} onClose={handleClose} maxWidth=\"sm\" fullWidth>\n <DialogTitle>Edit API Access Request</DialogTitle>\n <DialogContent>\n {error && (\n <Box mb={2} p={2} bgcolor=\"error.main\" color=\"error.contrastText\" borderRadius={1}>\n <Typography variant=\"body2\">{error}</Typography>\n </Box>\n )}\n\n <FormControl fullWidth margin=\"normal\">\n <InputLabel>Tier</InputLabel>\n <Select\n value={planTier}\n onChange={(e) => setPlanTier(e.target.value as string)}\n disabled={saving}\n >\n {availablePlans.map((plan) => {\n const limitDesc = Object.entries(plan.limits || {})\n .map(([key, val]) => `${val} per ${key}`)\n .join(', ');\n return (\n <MenuItem key={plan.tier} value={plan.tier}>\n {plan.tier} {limitDesc ? `(${limitDesc})` : ''}\n </MenuItem>\n );\n })}\n </Select>\n </FormControl>\n\n <TextField\n label=\"Use Case\"\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 disabled={saving}\n helperText=\"Explain your intended use of this API for admin review\"\n />\n </DialogContent>\n <DialogActions>\n <Button onClick={handleClose} disabled={saving}>\n Cancel\n </Button>\n <Button\n onClick={handleSave}\n color=\"primary\"\n variant=\"contained\"\n disabled={!planTier || saving}\n startIcon={saving ? <CircularProgress size={16} color=\"inherit\" /> : undefined}\n >\n {saving ? 'Saving...' : 'Save Changes'}\n </Button>\n </DialogActions>\n </Dialog>\n );\n};\n","import React, { useState } from 'react';\nimport { InfoCard, Table, TableColumn, Link, Progress } from '@backstage/core-components';\nimport { useApi, configApiRef, fetchApiRef, identityApiRef, alertApiRef } from '@backstage/core-plugin-api';\nimport useAsync from 'react-use/lib/useAsync';\nimport { Box, Chip, Typography, Tabs, Tab, IconButton, Tooltip, Menu, MenuItem, CircularProgress } from '@material-ui/core';\nimport VisibilityIcon from '@material-ui/icons/Visibility';\nimport VisibilityOffIcon from '@material-ui/icons/VisibilityOff';\nimport MoreVertIcon from '@material-ui/icons/MoreVert';\nimport { EditAPIKeyRequestDialog } from '../EditAPIKeyRequestDialog';\nimport { ConfirmDeleteDialog } from '../ConfirmDeleteDialog';\nimport { APIKey } from '../../types/api-management';\n\nexport const MyApiKeysCard = () => {\n const config = useApi(configApiRef);\n const fetchApi = useApi(fetchApiRef);\n const identityApi = useApi(identityApiRef);\n const alertApi = useApi(alertApiRef);\n const backendUrl = config.getString('backend.baseUrl');\n const [selectedTab, setSelectedTab] = useState(0);\n const [, setUserId] = useState<string>('');\n const [visibleKeys, setVisibleKeys] = useState<Set<string>>(new Set());\n const [menuAnchor, setMenuAnchor] = useState<{ top: number; left: number } | null>(null);\n const [menuRequest, setMenuRequest] = useState<APIKey | null>(null);\n const [editDialogState, setEditDialogState] = useState<{ open: boolean; request: APIKey | null; plans: any[] }>({\n open: false,\n request: null,\n plans: [],\n });\n const [refresh, setRefresh] = useState(0);\n const [deleting, setDeleting] = useState<string | null>(null);\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>>(new Map());\n const [apiKeyLoading, setApiKeyLoading] = useState<Set<string>>(new Set());\n\n useAsync(async () => {\n const identity = await identityApi.getBackstageIdentity();\n const extractedUserId = identity.userEntityRef.split('/')[1] || 'guest';\n console.log(`MyApiKeysCard: setting userId from userEntityRef: ${identity.userEntityRef} -> \"${extractedUserId}\"`);\n setUserId(extractedUserId);\n }, [identityApi]);\n\n const [optimisticallyDeleted, setOptimisticallyDeleted] = useState<Set<string>>(new Set());\n\n const { value: requests, loading, error } = useAsync(async () => {\n const response = await fetchApi.fetch(\n `${backendUrl}/api/kuadrant/requests/my`\n );\n if (!response.ok) {\n throw new Error('failed to fetch requests');\n }\n const data = await response.json();\n return data.items || [];\n }, [backendUrl, fetchApi, refresh]);\n\n if (loading) {\n return (\n <InfoCard title=\"My API Keys\">\n <Progress />\n </InfoCard>\n );\n }\n\n if (error) {\n return (\n <InfoCard title=\"My API Keys\">\n <Typography color=\"error\">Error loading API keys: {error.message}</Typography>\n </InfoCard>\n );\n }\n\n const allRequests = (requests || []).filter(\n (r: APIKey) => !optimisticallyDeleted.has(r.metadata.name)\n );\n const approvedRequests = allRequests.filter((r: APIKey) => r.status?.phase === 'Approved');\n const pendingRequests = allRequests.filter((r: APIKey) => !r.status?.phase || r.status.phase === 'Pending');\n const rejectedRequests = allRequests.filter((r: APIKey) => r.status?.phase === 'Rejected');\n\n const toggleKeyVisibility = (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 fetchApiKeyFromSecret = async (requestNamespace: string, requestName: string) => {\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/requests/${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 }\n } catch (err) {\n console.error('failed to fetch api key:', err);\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 handleMenuClose = () => {\n setMenuAnchor(null);\n setMenuRequest(null);\n };\n\n const handleEdit = async () => {\n if (!menuRequest) return;\n\n const request = menuRequest;\n handleMenuClose();\n\n // Fetch available plans for this API\n try {\n const apiProductName = request.spec.apiProductRef?.name;\n const apiProductNamespace = request.metadata.namespace;\n const apiProductResponse = await fetchApi.fetch(\n `${backendUrl}/api/kuadrant/apiproducts/${apiProductNamespace}/${apiProductName}`\n );\n\n if (apiProductResponse.ok) {\n const apiProduct = await apiProductResponse.json();\n const plans = apiProduct.spec?.plans || [];\n setEditDialogState({ open: true, request, plans });\n } else {\n console.error('Failed to fetch API product');\n setEditDialogState({ open: true, request, plans: [] });\n }\n } catch (err) {\n console.error('Error fetching plans:', err);\n setEditDialogState({ open: true, request, plans: [] });\n }\n };\n\n const handleDeleteClick = () => {\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\n const request = deleteDialogState.request;\n const requestName = request.metadata.name;\n\n // optimistic update - remove from UI immediately\n setOptimisticallyDeleted(prev => new Set(prev).add(requestName));\n setDeleting(requestName);\n\n try {\n const response = await fetchApi.fetch(\n `${backendUrl}/api/kuadrant/requests/${request.metadata.namespace}/${request.metadata.name}`,\n { method: 'DELETE' }\n );\n\n if (!response.ok) {\n throw new Error('Failed to delete request');\n }\n\n setRefresh(r => r + 1);\n alertApi.post({ message: 'Request deleted', severity: 'success', display: 'transient' });\n setDeleteDialogState({ open: false, request: null });\n } catch (err) {\n console.error('Error deleting request:', err);\n // rollback optimistic update on error\n setOptimisticallyDeleted(prev => {\n const next = new Set(prev);\n next.delete(requestName);\n return next;\n });\n alertApi.post({ message: 'Failed to delete request', severity: 'error', display: 'transient' });\n } finally {\n setDeleting(null);\n }\n };\n\n const handleDeleteCancel = () => {\n setDeleteDialogState({ open: false, request: null });\n };\n\n const columns: TableColumn<APIKey>[] = [\n {\n title: 'API Product',\n field: 'spec.apiProductRef.name',\n render: (row: APIKey) => {\n const apiProductName = row.spec.apiProductRef?.name || 'unknown';\n return (\n <Link to={`/catalog/default/api/${apiProductName}/api-keys`}>\n <strong>{apiProductName}</strong>\n </Link>\n );\n },\n },\n {\n title: 'Tier',\n field: 'spec.planTier',\n render: (row: APIKey) => {\n const color = row.spec.planTier === 'gold' ? 'primary' :\n row.spec.planTier === 'silver' ? 'default' : 'secondary';\n return <Chip label={row.spec.planTier} color={color} 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: 'Status',\n field: 'status.phase',\n render: (row: APIKey) => {\n const phase = row.status?.phase || 'Pending';\n const color = phase === 'Approved' ? 'primary' :\n phase === 'Rejected' ? 'secondary' : 'default';\n return <Chip label={phase} color={color} size=\"small\" />;\n },\n },\n {\n title: 'Reviewed By',\n field: 'status.reviewedBy',\n render: (row: APIKey) => {\n if ((row.status?.phase === 'Approved' || row.status?.phase === 'Rejected') && row.status.reviewedBy) {\n const reviewedDate = row.status.reviewedAt ? new Date(row.status.reviewedAt).toLocaleDateString() : '';\n return (\n <Box>\n <Typography variant=\"body2\">{row.status.reviewedBy}</Typography>\n {reviewedDate && (\n <Typography variant=\"caption\" color=\"textSecondary\">\n {reviewedDate}\n </Typography>\n )}\n </Box>\n );\n }\n return <Typography variant=\"body2\" color=\"textSecondary\">-</Typography>;\n },\n },\n {\n title: 'API Key',\n field: 'status.secretRef',\n filtering: false,\n render: (row: APIKey) => {\n if (row.status?.phase !== 'Approved') {\n return <Typography variant=\"body2\" color=\"textSecondary\">-</Typography>;\n }\n\n const key = `${row.metadata.namespace}/${row.metadata.name}`;\n const hasSecretRef = row.status?.secretRef?.name;\n const isVisible = visibleKeys.has(row.metadata.name);\n const isLoading = apiKeyLoading.has(key);\n const apiKeyValue = apiKeyValues.get(key);\n\n if (!hasSecretRef) {\n return (\n <Typography variant=\"body2\" color=\"textSecondary\">\n Awaiting secret...\n </Typography>\n );\n }\n\n const handleToggle = () => {\n if (isVisible) {\n // hiding - clear the value from memory\n clearApiKeyValue(row.metadata.namespace, row.metadata.name);\n toggleKeyVisibility(row.metadata.name);\n } else {\n // showing - fetch fresh value\n fetchApiKeyFromSecret(row.metadata.namespace, row.metadata.name);\n toggleKeyVisibility(row.metadata.name);\n }\n };\n\n return (\n <Box display=\"flex\" alignItems=\"center\" style={{ gap: 8 }}>\n <Box fontFamily=\"monospace\" fontSize=\"0.875rem\">\n {isLoading ? 'Loading...' : isVisible && apiKeyValue ? apiKeyValue : '•'.repeat(20) + '...'}\n </Box>\n <Tooltip title={isVisible ? 'hide key' : 'show key'}>\n <IconButton\n size=\"small\"\n onClick={handleToggle}\n disabled={isLoading}\n >\n {isVisible ? <VisibilityOffIcon fontSize=\"small\" /> : <VisibilityIcon fontSize=\"small\" />}\n </IconButton>\n </Tooltip>\n </Box>\n );\n },\n },\n {\n title: 'Requested',\n field: 'metadata.creationTimestamp',\n render: (row: APIKey) => {\n if (!row.metadata.creationTimestamp) {\n return <Typography variant=\"body2\">-</Typography>;\n }\n const date = new Date(row.metadata.creationTimestamp);\n return <Typography variant=\"body2\">{date.toLocaleDateString()}</Typography>;\n },\n },\n {\n title: '',\n filtering: false,\n render: (row: APIKey) => {\n const isDeleting = deleting === row.metadata.name;\n if (isDeleting) {\n return <CircularProgress size={20} />;\n }\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 aria-controls={menuAnchor ? 'myapikeys-menu' : undefined}\n aria-haspopup=\"true\"\n >\n <MoreVertIcon />\n </IconButton>\n );\n },\n },\n ];\n\n const getTabData = () => {\n switch (selectedTab) {\n case 0:\n return approvedRequests;\n case 1:\n return pendingRequests;\n case 2:\n return rejectedRequests;\n default:\n return allRequests;\n }\n };\n\n const getTabColumns = () => {\n switch (selectedTab) {\n case 0: // Active - no Reason\n return columns.filter(col => col.title !== 'Reason');\n case 1: // Pending - no Reason, Reviewed By, API Key\n return columns.filter(col =>\n col.title !== 'Reason' &&\n col.title !== 'Reviewed By' &&\n col.title !== 'API Key'\n );\n case 2: // Rejected - no API Key\n return columns.filter(col => col.title !== 'API Key');\n default:\n return columns;\n }\n };\n\n const tabData = getTabData();\n const tabColumns = getTabColumns();\n const isPending = (row: APIKey) => !row.status || row.status.phase === 'Pending';\n\n return (\n <>\n <InfoCard\n title=\"My API Keys\"\n subheader={`${approvedRequests.length} active, ${pendingRequests.length} pending`}\n >\n <Box mb={2}>\n <Tabs\n value={selectedTab}\n onChange={(_, newValue) => setSelectedTab(newValue)}\n indicatorColor=\"primary\"\n textColor=\"primary\"\n >\n <Tab label={`Active (${approvedRequests.length})`} />\n <Tab label={`Pending (${pendingRequests.length})`} />\n <Tab label={`Rejected (${rejectedRequests.length})`} />\n </Tabs>\n </Box>\n {tabData.length === 0 ? (\n <Box p={3} textAlign=\"center\">\n <Typography variant=\"body1\" color=\"textSecondary\">\n {selectedTab === 0 && 'No active API keys. Request access to an API to get started.'}\n {selectedTab === 1 && 'No pending requests.'}\n {selectedTab === 2 && 'No rejected requests.'}\n </Typography>\n </Box>\n ) : (\n <Table\n options={{\n paging: tabData.length > 5,\n pageSize: 20,\n search: true,\n filtering: true,\n debounceInterval: 300,\n toolbar: true,\n emptyRowsWhenPaging: false,\n }}\n columns={tabColumns}\n data={tabData.map((item: APIKey) => ({\n ...item,\n id: item.metadata.name,\n }))}\n />\n )}\n </InfoCard>\n\n <Menu\n id=\"myapikeys-menu\"\n open={Boolean(menuAnchor)}\n onClose={handleMenuClose}\n anchorReference=\"anchorPosition\"\n anchorPosition={menuAnchor || { top: 0, left: 0 }}\n >\n {menuRequest && (() => {\n const items = [];\n if (isPending(menuRequest)) {\n items.push(<MenuItem key=\"edit\" onClick={handleEdit}>Edit</MenuItem>);\n }\n items.push(<MenuItem key=\"delete\" onClick={handleDeleteClick}>Delete</MenuItem>);\n return items;\n })()}\n </Menu>\n\n {editDialogState.request && (\n <EditAPIKeyRequestDialog\n open={editDialogState.open}\n request={editDialogState.request}\n availablePlans={editDialogState.plans}\n onClose={() => setEditDialogState({ open: false, request: null, plans: [] })}\n onSuccess={() => {\n setEditDialogState({ open: false, request: null, plans: [] });\n setRefresh(r => r + 1);\n }}\n />\n )}\n\n <ConfirmDeleteDialog\n open={deleteDialogState.open}\n title=\"Delete API Key Request\"\n description={`Are you sure you want to delete the API key request for ${deleteDialogState.request?.spec.apiProductRef?.name || 'this API'}?`}\n deleting={deleting !== null}\n onConfirm={handleDeleteConfirm}\n onCancel={handleDeleteCancel}\n />\n </>\n );\n};\n","import React from 'react';\nimport { Typography, Box } from '@material-ui/core';\nimport { Progress } from '@backstage/core-components';\nimport { Permission } from '@backstage/plugin-permission-common';\nimport { useKuadrantPermission } from '../../utils/permissions';\n\ninterface PermissionGateProps {\n children: React.ReactNode;\n permission: Permission;\n fallback?: React.ReactNode;\n errorMessage?: string;\n}\n\nexport const PermissionGate = ({ children, permission, fallback, errorMessage }: PermissionGateProps) => {\n const { allowed, loading, error } = useKuadrantPermission(permission);\n\n if (loading) {\n return <Progress />;\n }\n\n if (error) {\n return (\n <Box p={4}>\n <Typography color=\"error\">\n Unable to check permissions: {error.message}\n </Typography>\n <Typography variant=\"body2\" color=\"textSecondary\">\n Please try again or contact your administrator\n </Typography>\n </Box>\n );\n }\n\n if (!allowed) {\n if (fallback) {\n return <>{fallback}</>;\n }\n return (\n <Box p={4}>\n <Typography color=\"textSecondary\">\n {errorMessage || 'You don\\'t have permission to view this page'}\n </Typography>\n <Box mt={1}>\n <Typography variant=\"caption\" color=\"textSecondary\">\n Required permission: {permission.name}\n </Typography>\n </Box>\n </Box>\n );\n }\n\n return <>{children}</>;\n};\n","import React from 'react';\nimport { Box, Typography, Chip } from '@material-ui/core';\nimport { Alert } from '@material-ui/lab';\n\ninterface PlanPolicyDetailsProps {\n selectedPolicy: {\n metadata: {\n name: string;\n };\n plans?: Array<{\n tier: string;\n description?: string;\n limits?: {\n daily?: number;\n monthly?: number;\n yearly?: number;\n };\n }>;\n } | null;\n alertSeverity?: 'warning' | 'info';\n alertMessage?: string;\n includeTopMargin?: boolean;\n}\n\nexport const PlanPolicyDetails: React.FC<PlanPolicyDetailsProps> = ({\n selectedPolicy,\n alertSeverity = 'warning',\n alertMessage = 'No PlanPolicy found for this HTTPRoute. API keys and rate limiting may not be available.',\n includeTopMargin = true,\n}) => {\n return (\n <Box\n mt={includeTopMargin ? 1 : 0}\n p={2}\n bgcolor=\"#f5f5f5\"\n borderRadius={1}\n border=\"1px solid #e0e0e0\"\n >\n {selectedPolicy ? (\n <>\n <Typography variant=\"subtitle2\" gutterBottom style={{ fontWeight: 600 }}>\n Associated PlanPolicy: <strong>{selectedPolicy.metadata.name}</strong>\n </Typography>\n\n {selectedPolicy.plans && selectedPolicy.plans.length > 0 ? (\n <>\n <Typography\n variant=\"caption\"\n display=\"block\"\n gutterBottom\n color=\"textSecondary\"\n style={{ marginTop: 8 }}\n >\n Available Plans:\n </Typography>\n <Box display=\"flex\" flexWrap=\"wrap\" mt={1} style={{ gap: 8 }}>\n {selectedPolicy.plans.map((plan: any, idx: number) => {\n const limitText = plan.limits?.daily\n ? `${plan.limits.daily}/day`\n : plan.limits?.monthly\n ? `${plan.limits.monthly}/month`\n : plan.limits?.yearly\n ? `${plan.limits.yearly}/year`\n : 'No limit';\n\n return (\n <Chip\n key={idx}\n label={`${plan.tier}: ${limitText}`}\n size=\"small\"\n variant=\"outlined\"\n color=\"primary\"\n />\n );\n })}\n </Box>\n {selectedPolicy.plans.some((p: any) => p.description) && (\n <Box mt={1}>\n {selectedPolicy.plans.filter((p: any) => p.description).map((plan: any, idx: number) => (\n <Typography key={idx} variant=\"caption\" display=\"block\" color=\"textSecondary\">\n • <strong>{plan.tier}:</strong> {plan.description}\n </Typography>\n ))}\n </Box>\n )}\n </>\n ) : (\n <Typography variant=\"caption\" color=\"textSecondary\">\n No plans defined in this PlanPolicy\n </Typography>\n )}\n </>\n ) : (\n <Alert severity={alertSeverity}>{alertMessage}</Alert>\n )}\n </Box>\n );\n};\n\n","import React, { useState } from 'react';\nimport {\n Dialog,\n DialogTitle,\n DialogContent,\n DialogActions,\n Button,\n TextField,\n Box,\n Typography,\n Chip,\n Grid,\n MenuItem,\n CircularProgress,\n makeStyles,\n} from '@material-ui/core';\nimport { useApi, configApiRef, fetchApiRef } from '@backstage/core-plugin-api';\nimport { Alert } from '@material-ui/lab';\nimport useAsync from 'react-use/lib/useAsync';\nimport { PlanPolicyDetails } from '../PlanPolicyDetailsCard';\n\nconst useStyles = makeStyles({\n asterisk: {\n color: '#f44336',\n },\n});\n\ninterface CreateAPIProductDialogProps {\n open: boolean;\n onClose: () => void;\n onSuccess: () => void;\n}\n\nexport const CreateAPIProductDialog = ({ open, onClose, onSuccess }: CreateAPIProductDialogProps) => {\n const classes = useStyles();\n const config = useApi(configApiRef);\n const fetchApi = useApi(fetchApiRef);\n const backendUrl = config.getString('backend.baseUrl');\n\n const [name, setName] = useState('');\n const [displayName, setDisplayName] = useState('');\n const [description, setDescription] = useState('');\n const [version, setVersion] = useState('v1');\n const [approvalMode, setApprovalMode] = useState<'automatic' | 'manual'>('manual');\n const [publishStatus, setPublishStatus] = useState<'Draft' | 'Published'>('Published');\n const [tags, setTags] = useState<string[]>([]);\n const [tagInput, setTagInput] = useState('');\n const [selectedHTTPRoute, setSelectedHTTPRoute] = useState('');\n const [contactEmail, setContactEmail] = useState('');\n const [contactTeam, setContactTeam] = useState('');\n const [docsURL, setDocsURL] = useState('');\n const [openAPISpec, setOpenAPISpec] = useState('');\n const [error, setError] = useState('');\n const [creating, setCreating] = useState(false);\n\n const { value: httpRoutes, loading: httpRoutesLoading } = useAsync(async () => {\n const response = await fetchApi.fetch(`${backendUrl}/api/kuadrant/httproutes`);\n const data = await response.json();\n // filter to only show httproutes annotated for backstage exposure\n return (data.items || []).filter((route: any) =>\n route.metadata.annotations?.['backstage.io/expose'] === 'true'\n );\n }, [backendUrl, fetchApi, open]);\n\n // load planpolicies with full details to show associated plans\n const { value: planPolicies } = useAsync(async () => {\n const response = await fetchApi.fetch(`${backendUrl}/api/kuadrant/planpolicies`);\n return await response.json();\n }, [backendUrl, fetchApi, open]);\n\n // find planpolicy associated with selected httproute\n const getPlanPolicyForRoute = (routeNamespace: string, routeName: string) => {\n if (!planPolicies?.items) return null;\n\n return planPolicies.items.find((pp: any) => {\n const ref = pp.targetRef;\n return (\n ref?.kind === 'HTTPRoute' &&\n ref?.name === routeName &&\n (!ref?.namespace || ref?.namespace === routeNamespace)\n );\n });\n };\n\n const selectedRouteInfo = selectedHTTPRoute ? selectedHTTPRoute.split('/') : null;\n const selectedPolicy = selectedRouteInfo\n ? getPlanPolicyForRoute(selectedRouteInfo[0], selectedRouteInfo[1])\n : null;\n\n const handleAddTag = () => {\n if (tagInput.trim() && !tags.includes(tagInput.trim())) {\n setTags([...tags, tagInput.trim()]);\n setTagInput('');\n }\n };\n\n const handleDeleteTag = (tagToDelete: string) => {\n setTags(tags.filter(tag => tag !== tagToDelete));\n };\n\n const handleCreate = async () => {\n setError('');\n setCreating(true);\n\n try {\n if (!selectedHTTPRoute) {\n throw new Error('Please select an HTTPRoute');\n }\n\n const [selectedRouteNamespace, selectedRouteName] = selectedHTTPRoute.split('/');\n\n // derive namespace from selected httproute\n const namespace = selectedRouteNamespace;\n\n const apiProduct = {\n apiVersion: 'devportal.kuadrant.io/v1alpha1',\n kind: 'APIProduct',\n metadata: {\n name,\n namespace,\n },\n spec: {\n displayName,\n description,\n version,\n approvalMode,\n publishStatus,\n tags,\n targetRef: {\n group: 'gateway.networking.k8s.io',\n kind: 'HTTPRoute',\n name: selectedRouteName,\n namespace: selectedRouteNamespace,\n },\n ...(contactEmail || contactTeam ? {\n contact: {\n ...(contactEmail && { email: contactEmail }),\n ...(contactTeam && { team: contactTeam }),\n },\n } : {}),\n ...(docsURL || openAPISpec ? {\n documentation: {\n ...(docsURL && { docsURL }),\n ...(openAPISpec && { openAPISpec }),\n },\n } : {}),\n },\n };\n\n const response = await fetchApi.fetch(`${backendUrl}/api/kuadrant/apiproducts`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify(apiProduct),\n });\n\n if (!response.ok) {\n const errorData = await response.json();\n throw new Error(errorData.error || 'failed to create apiproduct');\n }\n\n onSuccess();\n handleClose();\n } catch (err) {\n setError(err instanceof Error ? err.message : String(err));\n } finally {\n setCreating(false);\n }\n };\n\n const handleClose = () => {\n setName('');\n setDisplayName('');\n setDescription('');\n setVersion('v1');\n setApprovalMode('manual');\n setPublishStatus('Published');\n setTags([]);\n setTagInput('');\n setSelectedHTTPRoute('');\n setContactEmail('');\n setContactTeam('');\n setDocsURL('');\n setOpenAPISpec('');\n setError('');\n onClose();\n };\n\n return (\n <Dialog open={open} onClose={handleClose} maxWidth=\"md\" fullWidth>\n <DialogTitle>Create API Product</DialogTitle>\n <DialogContent>\n {error && (\n <Alert severity=\"error\" style={{ marginBottom: 16 }}>\n {error}\n </Alert>\n )}\n\n <Grid container spacing={2}>\n <Grid item xs={6}>\n <TextField\n fullWidth\n label=\"Name\"\n value={name}\n onChange={e => setName(e.target.value)}\n placeholder=\"my-api\"\n helperText=\"Kubernetes resource name (lowercase, hyphens)\"\n margin=\"normal\"\n required\n disabled={creating}\n InputLabelProps={{\n classes: {\n asterisk: classes.asterisk,\n },\n }}\n />\n </Grid>\n <Grid item xs={6}>\n <TextField\n fullWidth\n label=\"Display Name\"\n value={displayName}\n onChange={e => setDisplayName(e.target.value)}\n placeholder=\"My API\"\n margin=\"normal\"\n required\n disabled={creating}\n InputLabelProps={{\n classes: {\n asterisk: classes.asterisk,\n },\n }}\n />\n </Grid>\n <Grid item xs={6}>\n <TextField\n fullWidth\n label=\"Version\"\n value={version}\n onChange={e => setVersion(e.target.value)}\n placeholder=\"v1\"\n margin=\"normal\"\n disabled={creating}\n />\n </Grid>\n <Grid item xs={12}>\n <TextField\n fullWidth\n select\n label=\"Approval Mode\"\n value={approvalMode}\n onChange={e => setApprovalMode(e.target.value as 'automatic' | 'manual')}\n margin=\"normal\"\n helperText=\"Automatic: keys are created immediately. Manual: requires approval.\"\n disabled={creating}\n >\n <MenuItem value=\"manual\">Manual</MenuItem>\n <MenuItem value=\"automatic\">Automatic</MenuItem>\n </TextField>\n </Grid>\n <Grid item xs={12}>\n <TextField\n fullWidth\n select\n label=\"Publish Status\"\n value={publishStatus}\n onChange={e => setPublishStatus(e.target.value as 'Draft' | 'Published')}\n margin=\"normal\"\n helperText=\"Draft: hidden from catalog. Published: visible to consumers.\"\n disabled={creating}\n >\n <MenuItem value=\"Draft\">Draft</MenuItem>\n <MenuItem value=\"Published\">Published</MenuItem>\n </TextField>\n </Grid>\n <Grid item xs={12}>\n <TextField\n fullWidth\n label=\"Description\"\n value={description}\n onChange={e => setDescription(e.target.value)}\n placeholder=\"API description\"\n margin=\"normal\"\n multiline\n rows={2}\n required\n disabled={creating}\n InputLabelProps={{\n classes: {\n asterisk: classes.asterisk,\n },\n }}\n />\n </Grid>\n\n <Grid item xs={12}>\n <Typography variant=\"subtitle2\" gutterBottom style={{ marginTop: 16 }}>\n Tags\n </Typography>\n <Box display=\"flex\" flexWrap=\"wrap\" marginBottom={1} style={{ gap: 8 }}>\n {tags.map(tag => (\n <Chip\n key={tag}\n label={tag}\n onDelete={creating ? undefined : () => handleDeleteTag(tag)}\n size=\"small\"\n disabled={creating}\n />\n ))}\n </Box>\n <Box display=\"flex\" style={{ gap: 8 }}>\n <TextField\n fullWidth\n size=\"small\"\n value={tagInput}\n onChange={e => setTagInput(e.target.value)}\n onKeyPress={e => e.key === 'Enter' && handleAddTag()}\n placeholder=\"Add tag\"\n disabled={creating}\n />\n <Button onClick={handleAddTag} variant=\"outlined\" size=\"small\" disabled={creating}>\n Add\n </Button>\n </Box>\n </Grid>\n\n <Grid item xs={12}>\n <TextField\n fullWidth\n select\n label=\"HTTPRoute\"\n value={selectedHTTPRoute}\n onChange={e => setSelectedHTTPRoute(e.target.value)}\n margin=\"normal\"\n required\n helperText=\"Select an HTTPRoute (backstage.io/expose: true). APIProduct will be created in the same namespace.\"\n disabled={httpRoutesLoading || creating}\n InputLabelProps={{\n classes: {\n asterisk: classes.asterisk,\n },\n }}\n >\n {httpRoutesLoading && (\n <MenuItem value=\"\">Loading...</MenuItem>\n )}\n {!httpRoutesLoading && httpRoutes && httpRoutes.length === 0 && (\n <MenuItem value=\"\">No HTTPRoutes available</MenuItem>\n )}\n {!httpRoutesLoading && httpRoutes && httpRoutes.map((route: any) => (\n <MenuItem\n key={`${route.metadata.namespace}/${route.metadata.name}`}\n value={`${route.metadata.namespace}/${route.metadata.name}`}\n >\n {route.metadata.name} ({route.metadata.namespace})\n </MenuItem>\n ))}\n </TextField>\n </Grid>\n {selectedHTTPRoute && (\n <Grid item xs={12}>\n <PlanPolicyDetails\n selectedPolicy={selectedPolicy}\n alertSeverity=\"warning\"\n alertMessage=\"No PlanPolicy found for this HTTPRoute. API keys and rate limiting may not be available.\"\n includeTopMargin={true}\n />\n </Grid>\n )}\n\n <Grid item xs={6}>\n <TextField\n fullWidth\n label=\"Contact Email\"\n value={contactEmail}\n onChange={e => setContactEmail(e.target.value)}\n placeholder=\"api-team@example.com\"\n margin=\"normal\"\n disabled={creating}\n />\n </Grid>\n <Grid item xs={6}>\n <TextField\n fullWidth\n label=\"Contact Team\"\n value={contactTeam}\n onChange={e => setContactTeam(e.target.value)}\n placeholder=\"platform-team\"\n margin=\"normal\"\n disabled={creating}\n />\n </Grid>\n <Grid item xs={6}>\n <TextField\n fullWidth\n label=\"Docs URL\"\n value={docsURL}\n onChange={e => setDocsURL(e.target.value)}\n placeholder=\"https://api.example.com/docs\"\n margin=\"normal\"\n disabled={creating}\n />\n </Grid>\n <Grid item xs={6}>\n <TextField\n fullWidth\n label=\"OpenAPI Spec URL\"\n value={openAPISpec}\n onChange={e => setOpenAPISpec(e.target.value)}\n placeholder=\"https://api.example.com/openapi.json\"\n margin=\"normal\"\n disabled={creating}\n />\n </Grid>\n </Grid>\n </DialogContent>\n <DialogActions>\n <Button onClick={handleClose} disabled={creating}>Cancel</Button>\n <Button\n onClick={handleCreate}\n color=\"primary\"\n variant=\"contained\"\n disabled={creating || !name || !displayName || !description || !selectedHTTPRoute}\n startIcon={creating ? <CircularProgress size={16} color=\"inherit\" /> : undefined}\n >\n {creating ? 'Creating...' : 'Create'}\n </Button>\n </DialogActions>\n </Dialog>\n );\n};\n","import React, { useState, useEffect } from 'react';\nimport {\n Dialog,\n DialogTitle,\n DialogContent,\n DialogActions,\n Button,\n TextField,\n Box,\n Typography,\n Chip,\n Grid,\n MenuItem,\n CircularProgress,\n makeStyles,\n} from '@material-ui/core';\nimport { useApi, configApiRef, fetchApiRef } from '@backstage/core-plugin-api';\nimport { Alert } from '@material-ui/lab';\nimport { Progress } from '@backstage/core-components';\nimport useAsync from 'react-use/lib/useAsync';\nimport { PlanPolicyDetails } from '../PlanPolicyDetailsCard';\n\nconst useStyles = makeStyles({\n asterisk: {\n color: '#f44336',\n },\n});\n\ninterface EditAPIProductDialogProps {\n open: boolean;\n onClose: () => void;\n onSuccess: () => void;\n namespace: string;\n name: string;\n}\n\nexport const EditAPIProductDialog = ({open, onClose, onSuccess, namespace, name}: EditAPIProductDialogProps) => {\n const classes = useStyles();\n const config = useApi(configApiRef);\n const fetchApi = useApi(fetchApiRef);\n const backendUrl = config.getString('backend.baseUrl');\n const [loading, setLoading] = useState(false);\n const [displayName, setDisplayName] = useState('');\n const [description, setDescription] = useState('');\n const [version, setVersion] = useState('v1');\n const [publishStatus, setPublishStatus] = useState<'Draft' | 'Published'>('Draft');\n const [approvalMode, setApprovalMode] = useState<'automatic' | 'manual'>('manual');\n const [tags, setTags] = useState<string[]>([]);\n const [targetRef, setTargetRef] = useState<any>(null);\n const [tagInput, setTagInput] = useState('');\n const [contactEmail, setContactEmail] = useState('');\n const [contactTeam, setContactTeam] = useState('');\n const [docsURL, setDocsURL] = useState('');\n const [openAPISpec, setOpenAPISpec] = useState('');\n const [error, setError] = useState('');\n const [saving, setSaving] = useState(false);\n\n // Load APIProduct data when dialog opens\n useEffect(() => {\n if (open && namespace && name) {\n setLoading(true);\n setError('');\n\n fetchApi.fetch(`${backendUrl}/api/kuadrant/apiproducts/${namespace}/${name}`)\n .then(async res => {\n if (!res.ok) {\n const errorData = await res.json();\n throw new Error(errorData.error || `Failed to fetch API product: ${res.status}`);\n }\n return res.json();\n })\n .then(data => {\n setDisplayName(data.spec.displayName || '');\n setDescription(data.spec.description || '');\n setVersion(data.spec.version || 'v1');\n setPublishStatus(data.spec.publishStatus || 'Draft');\n setApprovalMode(data.spec.approvalMode || 'manual');\n setTags(data.spec.tags || []);\n setTargetRef(data.spec.targetRef || null);\n setContactEmail(data.spec.contact?.email || '');\n setContactTeam(data.spec.contact?.team || '');\n setDocsURL(data.spec.documentation?.docsURL || '');\n setOpenAPISpec(data.spec.documentation?.openAPISpec || '');\n setLoading(false);\n })\n .catch(err => {\n setError(err.message || 'Failed to load API product');\n setLoading(false);\n });\n }\n }, [open, namespace, name, backendUrl, fetchApi]);\n\n // load planpolicies with full details to show associated plans\n const { value: planPolicies } = useAsync(async () => {\n if (!open) return null;\n const response = await fetchApi.fetch(`${backendUrl}/api/kuadrant/planpolicies`);\n return await response.json();\n }, [backendUrl, fetchApi, open]);\n\n // find planpolicy associated with targetRef\n const selectedPolicy = React.useMemo(() => {\n if (!planPolicies?.items || !targetRef) return null;\n\n return planPolicies.items.find((pp: any) => {\n const ref = pp.targetRef;\n return (\n ref?.kind === 'HTTPRoute' &&\n ref?.name === targetRef.name &&\n (!ref?.namespace || ref?.namespace === (targetRef.namespace || namespace))\n );\n });\n }, [planPolicies, targetRef, namespace]);\n\n const handleAddTag = () => {\n if (tagInput.trim() && !tags.includes(tagInput.trim())) {\n setTags([...tags, tagInput.trim()]);\n setTagInput('');\n }\n };\n\n const handleDeleteTag = (tagToDelete: string) => {\n setTags(tags.filter(tag => tag !== tagToDelete));\n };\n\n const handleSave = async () => {\n setError('');\n setSaving(true);\n\n try {\n const patch = {\n spec: {\n displayName,\n description,\n version,\n publishStatus,\n approvalMode,\n tags,\n targetRef,\n ...(contactEmail || contactTeam ? {\n contact: {\n ...(contactEmail && { email: contactEmail }),\n ...(contactTeam && { team: contactTeam }),\n },\n } : {}),\n ...(docsURL || openAPISpec ? {\n documentation: {\n ...(docsURL && { docsURL }),\n ...(openAPISpec && { openAPISpec }),\n },\n } : {}),\n },\n };\n\n const response = await fetchApi.fetch(\n `${backendUrl}/api/kuadrant/apiproducts/${namespace}/${name}`,\n {\n method: 'PATCH',\n headers: {\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify(patch),\n }\n );\n\n if (!response.ok) {\n const errorData = await response.json();\n throw new Error(errorData.error || 'failed to update apiproduct');\n }\n\n onSuccess();\n onClose();\n } catch (err) {\n setError(err instanceof Error ? err.message : String(err));\n } finally {\n setSaving(false);\n }\n };\n\n return (\n <Dialog open={open} onClose={onClose} maxWidth=\"md\" fullWidth>\n <DialogTitle>Edit API Product</DialogTitle>\n <DialogContent>\n {error && (\n <Alert severity=\"error\" style={{ marginBottom: 16 }}>\n {error}\n </Alert>\n )}\n\n {loading ? (\n <Progress />\n ) : (\n <Grid container spacing={2}>\n <Grid item xs={6}>\n <TextField\n fullWidth\n label=\"Name\"\n value={name}\n disabled\n helperText=\"Kubernetes resource name (immutable)\"\n margin=\"normal\"\n />\n </Grid>\n <Grid item xs={6}>\n <TextField\n fullWidth\n label=\"Namespace\"\n value={namespace}\n disabled\n helperText=\"Derived from HTTPRoute (immutable)\"\n margin=\"normal\"\n />\n </Grid>\n <Grid item xs={6}>\n <TextField\n fullWidth\n label=\"Display Name\"\n value={displayName}\n onChange={e => setDisplayName(e.target.value)}\n placeholder=\"My API\"\n margin=\"normal\"\n required\n disabled={saving}\n InputLabelProps={{\n classes: {\n asterisk: classes.asterisk,\n },\n }}\n />\n </Grid>\n <Grid item xs={6}>\n <TextField\n fullWidth\n label=\"Version\"\n value={version}\n onChange={e => setVersion(e.target.value)}\n placeholder=\"v1\"\n margin=\"normal\"\n disabled={saving}\n />\n </Grid>\n <Grid item xs={6}>\n <TextField\n fullWidth\n select\n label=\"Publish Status\"\n value={publishStatus}\n onChange={e => setPublishStatus(e.target.value as 'Draft' | 'Published')}\n margin=\"normal\"\n helperText=\"Draft: Hidden from catalog. Published: Visible in catalog.\"\n disabled={saving}\n >\n <MenuItem value=\"Draft\">Draft (Hidden)</MenuItem>\n <MenuItem value=\"Published\">Published (Visible)</MenuItem>\n </TextField>\n </Grid>\n <Grid item xs={6}>\n <TextField\n fullWidth\n select\n label=\"Approval Mode\"\n value={approvalMode}\n onChange={e => setApprovalMode(e.target.value as 'automatic' | 'manual')}\n margin=\"normal\"\n helperText=\"Automatic: keys created immediately. Manual: requires approval.\"\n disabled={saving}\n >\n <MenuItem value=\"manual\">Manual</MenuItem>\n <MenuItem value=\"automatic\">Automatic</MenuItem>\n </TextField>\n </Grid>\n <Grid item xs={12}>\n <TextField\n fullWidth\n label=\"Description\"\n value={description}\n onChange={e => setDescription(e.target.value)}\n placeholder=\"API description\"\n margin=\"normal\"\n multiline\n rows={2}\n required\n disabled={saving}\n InputLabelProps={{\n classes: {\n asterisk: classes.asterisk,\n },\n }}\n />\n </Grid>\n\n <Grid item xs={12}>\n <Typography variant=\"subtitle2\" gutterBottom style={{ marginTop: 16 }}>\n Tags\n </Typography>\n <Box display=\"flex\" flexWrap=\"wrap\" marginBottom={1} style={{ gap: 8 }}>\n {tags.map(tag => (\n <Chip\n key={tag}\n label={tag}\n onDelete={saving ? undefined : () => handleDeleteTag(tag)}\n size=\"small\"\n disabled={saving}\n />\n ))}\n </Box>\n <Box display=\"flex\" style={{ gap: 8 }}>\n <TextField\n fullWidth\n size=\"small\"\n value={tagInput}\n onChange={e => setTagInput(e.target.value)}\n onKeyPress={e => e.key === 'Enter' && handleAddTag()}\n placeholder=\"Add tag\"\n disabled={saving}\n />\n <Button onClick={handleAddTag} variant=\"outlined\" size=\"small\" disabled={saving}>\n Add\n </Button>\n </Box>\n </Grid>\n {targetRef && (\n <>\n <Grid item xs={12}>\n <TextField\n fullWidth\n label=\"HTTPRoute\"\n value={`${targetRef.namespace || namespace}/${targetRef.name}`}\n disabled\n helperText=\"Target HTTPRoute (immutable)\"\n margin=\"normal\"\n />\n </Grid>\n\n <Grid item xs={12}>\n <PlanPolicyDetails\n selectedPolicy={selectedPolicy}\n alertSeverity=\"info\"\n alertMessage=\"No PlanPolicy found for this HTTPRoute.\"\n includeTopMargin={false}\n />\n </Grid>\n </>\n )}\n\n <Grid item xs={6}>\n <TextField\n fullWidth\n label=\"Contact Email\"\n value={contactEmail}\n onChange={e => setContactEmail(e.target.value)}\n placeholder=\"api-team@example.com\"\n margin=\"normal\"\n disabled={saving}\n />\n </Grid>\n <Grid item xs={6}>\n <TextField\n fullWidth\n label=\"Contact Team\"\n value={contactTeam}\n onChange={e => setContactTeam(e.target.value)}\n placeholder=\"platform-team\"\n margin=\"normal\"\n disabled={saving}\n />\n </Grid>\n <Grid item xs={6}>\n <TextField\n fullWidth\n label=\"Docs URL\"\n value={docsURL}\n onChange={e => setDocsURL(e.target.value)}\n placeholder=\"https://api.example.com/docs\"\n margin=\"normal\"\n disabled={saving}\n />\n </Grid>\n <Grid item xs={6}>\n <TextField\n fullWidth\n label=\"OpenAPI Spec URL\"\n value={openAPISpec}\n onChange={e => setOpenAPISpec(e.target.value)}\n placeholder=\"https://api.example.com/openapi.json\"\n margin=\"normal\"\n disabled={saving}\n />\n </Grid>\n </Grid>\n )}\n </DialogContent>\n <DialogActions>\n <Button onClick={onClose} disabled={saving}>Cancel</Button>\n <Button\n onClick={handleSave}\n color=\"primary\"\n variant=\"contained\"\n disabled={saving || loading || !displayName || !description}\n startIcon={saving ? <CircularProgress size={16} color=\"inherit\" /> : undefined}\n >\n {saving ? 'Saving...' : 'Save'}\n </Button>\n </DialogActions>\n </Dialog>\n );\n};\n","import React, { useState } from 'react';\nimport { Typography, Grid, Box, Chip, Button, IconButton } from '@material-ui/core';\nimport AddIcon from '@material-ui/icons/Add';\nimport DeleteIcon from '@material-ui/icons/Delete';\nimport EditIcon from '@material-ui/icons/Edit';\nimport {\n InfoCard,\n Header,\n Page,\n Content,\n SupportButton,\n Progress,\n ResponseErrorPanel,\n Link,\n Table,\n TableColumn,\n} from '@backstage/core-components';\nimport useAsync from 'react-use/lib/useAsync';\nimport { useApi, configApiRef, fetchApiRef, alertApiRef, identityApiRef } from '@backstage/core-plugin-api';\nimport { ApprovalQueueCard } from '../ApprovalQueueCard';\nimport { MyApiKeysCard } from '../MyApiKeysCard';\nimport { PermissionGate } from '../PermissionGate';\nimport { CreateAPIProductDialog } from '../CreateAPIProductDialog';\nimport {\n kuadrantApiProductCreatePermission,\n kuadrantApiProductDeleteOwnPermission,\n kuadrantApiProductDeleteAllPermission,\n kuadrantApiProductUpdateOwnPermission,\n kuadrantApiProductUpdateAllPermission,\n kuadrantApiProductListPermission,\n kuadrantApiKeyRequestReadAllPermission,\n kuadrantApiKeyRequestReadOwnPermission,\n kuadrantPlanPolicyListPermission,\n} from '../../permissions';\nimport { useKuadrantPermission } from '../../utils/permissions';\nimport { EditAPIProductDialog } from '../EditAPIProductDialog';\nimport { ConfirmDeleteDialog } from '../ConfirmDeleteDialog';\n\ntype KuadrantResource = {\n metadata: {\n name: string;\n namespace: string;\n creationTimestamp: string;\n annotations?: Record<string, string>;\n };\n spec?: any;\n};\n\ntype KuadrantList = {\n items: KuadrantResource[];\n};\n\nexport const ResourceList = () => {\n const config = useApi(configApiRef);\n const fetchApi = useApi(fetchApiRef);\n const alertApi = useApi(alertApiRef);\n const identityApi = useApi(identityApiRef);\n const backendUrl = config.getString('backend.baseUrl');\n const [userEntityRef, setUserEntityRef] = useState<string>('');\n const [createDialogOpen, setCreateDialogOpen] = useState(false);\n const [editDialogOpen, setEditDialogOpen] = useState(false);\n const [refreshTrigger, setRefreshTrigger] = useState(0);\n const [deleteDialogOpen, setDeleteDialogOpen] = useState(false);\n const [apiProductToDelete, setApiProductToDelete] = useState<{ namespace: string; name: string } | null>(null);\n const [apiProductToEdit, setApiProductToEdit] = useState<{ namespace: string; name: string } | null>(null);\n const [deleting, setDeleting] = useState(false);\n const [deleteStats, setDeleteStats] = useState<{requests: number; secrets: number} | null>(null);\n\n const {\n allowed: canCreateApiProduct,\n loading: createPermissionLoading,\n error: createPermissionError,\n } = useKuadrantPermission(kuadrantApiProductCreatePermission);\n\n const {\n allowed: canViewAllRequests,\n loading: approvalQueueAllPermissionLoading,\n } = useKuadrantPermission(kuadrantApiKeyRequestReadAllPermission);\n\n const {\n allowed: canViewOwnRequests,\n loading: approvalQueueOwnPermissionLoading,\n error: approvalQueuePermissionError,\n } = useKuadrantPermission(kuadrantApiKeyRequestReadOwnPermission);\n\n const canViewApprovalQueue = canViewAllRequests || canViewOwnRequests;\n const approvalQueuePermissionLoading = approvalQueueAllPermissionLoading || approvalQueueOwnPermissionLoading;\n\n const {\n allowed: canDeleteOwnApiProduct,\n loading: deleteOwnPermissionLoading,\n } = useKuadrantPermission(kuadrantApiProductDeleteOwnPermission);\n\n const {\n allowed: canDeleteAllApiProducts,\n loading: deleteAllPermissionLoading,\n error: deletePermissionError,\n } = useKuadrantPermission(kuadrantApiProductDeleteAllPermission);\n\n const {\n allowed: canUpdateOwnApiProduct,\n } = useKuadrantPermission(kuadrantApiProductUpdateOwnPermission);\n\n const {\n allowed: canUpdateAllApiProducts,\n } = useKuadrantPermission(kuadrantApiProductUpdateAllPermission);\n\n const deletePermissionLoading = deleteOwnPermissionLoading || deleteAllPermissionLoading;\n\n const {\n allowed: canListPlanPolicies,\n loading: planPolicyPermissionLoading,\n error: planPolicyPermissionError,\n } = useKuadrantPermission(kuadrantPlanPolicyListPermission);\n\n useAsync(async () => {\n const identity = await identityApi.getBackstageIdentity();\n setUserEntityRef(identity.userEntityRef);\n }, [identityApi]);\n\n const { value: apiProducts, loading: apiProductsLoading, error: apiProductsError } = useAsync(async (): Promise<KuadrantList> => {\n const response = await fetchApi.fetch(`${backendUrl}/api/kuadrant/apiproducts`);\n return await response.json();\n }, [backendUrl, fetchApi, refreshTrigger]);\n\n const { value: planPolicies, loading: planPoliciesLoading, error: planPoliciesError } = useAsync(async (): Promise<KuadrantList> => {\n const response = await fetchApi.fetch(`${backendUrl}/api/kuadrant/planpolicies`);\n return await response.json();\n }, [backendUrl, fetchApi, refreshTrigger]);\n\n const loading = apiProductsLoading || planPoliciesLoading || createPermissionLoading || approvalQueuePermissionLoading || deletePermissionLoading || planPolicyPermissionLoading;\n const error = apiProductsError || planPoliciesError;\n const permissionError = createPermissionError || approvalQueuePermissionError || deletePermissionError || planPolicyPermissionError;\n\n const handleCreateSuccess = () => {\n setRefreshTrigger(prev => prev + 1);\n alertApi.post({ message: 'API Product created', severity: 'success', display: 'transient' });\n };\n\n const handleEditClick = (namespace: string, name: string) => {\n setApiProductToEdit({ namespace, name });\n setEditDialogOpen(true);\n };\n\n const handleEditSuccess = () => {\n setRefreshTrigger(prev => prev + 1);\n alertApi.post({ message: 'API Product updated', severity: 'success', display: 'transient' });\n };\n\n const handleDeleteClick = async (namespace: string, name: string) => {\n setApiProductToDelete({ namespace, name });\n setDeleteStats(null);\n\n try {\n const response = await fetchApi.fetch(`${backendUrl}/api/kuadrant/requests?namespace=${namespace}`);\n if (response.ok) {\n const data = await response.json();\n const related = (data.items || []).filter(\n (r: any) => r.spec.apiName === name && r.spec.apiNamespace === namespace\n );\n const approved = related.filter((r: any) => r.status?.phase === 'Approved').length;\n setDeleteStats({ requests: related.length, secrets: approved });\n }\n } catch (err) {\n console.warn('Failed to fetch delete stats:', err);\n }\n\n setDeleteDialogOpen(true);\n };\n\n const handleDeleteConfirm = async () => {\n if (!apiProductToDelete) return;\n\n setDeleting(true);\n try {\n const response = await fetchApi.fetch(\n `${backendUrl}/api/kuadrant/apiproducts/${apiProductToDelete.namespace}/${apiProductToDelete.name}`,\n { method: 'DELETE' }\n );\n\n if (!response.ok) {\n throw new Error('failed to delete apiproduct');\n }\n\n setRefreshTrigger(prev => prev + 1);\n alertApi.post({ message: 'API Product deleted', severity: 'success', display: 'transient' });\n } catch (err) {\n console.error('error deleting apiproduct:', err);\n alertApi.post({ message: 'Failed to delete API Product', severity: 'error', display: 'transient' });\n } finally {\n setDeleting(false);\n setDeleteDialogOpen(false);\n setApiProductToDelete(null);\n }\n };\n\n const handleDeleteCancel = () => {\n setDeleteDialogOpen(false);\n setApiProductToDelete(null);\n };\n\n const formatDate = (dateString: string) => {\n const date = new Date(dateString);\n return date.toLocaleDateString('en-GB', {\n year: 'numeric',\n month: 'short',\n day: 'numeric',\n });\n };\n\n const columns: TableColumn[] = [\n {\n title: 'Name',\n field: 'spec.displayName',\n render: (row: any) => {\n const publishStatus = row.spec?.publishStatus;\n const isPublished = publishStatus === 'Published';\n const displayName = row.spec?.displayName ?? row.metadata.name;\n\n if (isPublished) {\n return (\n <Link to={`/catalog/default/api/${row.metadata.name}/api-product`}>\n <strong>{displayName}</strong>\n </Link>\n );\n }\n\n return (\n <span className=\"text-muted\">\n <strong>{displayName}</strong>\n </span>\n );\n },\n customFilterAndSearch: (term, row: any) => {\n const displayName = row.spec?.displayName || row.metadata.name || '';\n return displayName.toLowerCase().includes(term.toLowerCase());\n },\n },\n {\n title: 'Resource Name',\n field: 'metadata.name',\n },\n {\n title: 'Version',\n field: 'spec.version',\n render: (row: any) => row.spec?.version || '-',\n },\n {\n title: 'HTTPRoute',\n field: 'spec.targetRef.name',\n render: (row: any) => row.spec?.targetRef?.name || '-',\n },\n {\n title: 'Publish Status',\n field: 'spec.publishStatus',\n render: (row: any) => {\n const status = row.spec?.publishStatus || 'Draft';\n return (\n <Chip\n label={status}\n size=\"small\"\n color={status === 'Published' ? 'primary' : 'default'}\n />\n );\n },\n },\n {\n title: 'Approval Mode',\n field: 'spec.approvalMode',\n render: (row: any) => {\n const mode = row.spec?.approvalMode || 'manual';\n return (\n <Chip\n label={mode}\n size=\"small\"\n color={mode === 'automatic' ? 'secondary' : 'default'}\n />\n );\n },\n },\n {\n title: 'Namespace',\n field: 'metadata.namespace',\n },\n {\n title: 'Created',\n field: 'metadata.creationTimestamp',\n render: (row: any) => formatDate(row.metadata.creationTimestamp),\n },\n {\n title: 'Actions',\n field: 'actions',\n filtering: false,\n render: (row: any) => {\n const owner = row.metadata?.annotations?.['backstage.io/owner'];\n const isOwner = owner === userEntityRef;\n const canEdit = canUpdateAllApiProducts || (canUpdateOwnApiProduct && isOwner);\n const canDelete = canDeleteAllApiProducts || (canDeleteOwnApiProduct && isOwner);\n\n if (!canEdit && !canDelete) return null;\n\n return (\n <Box display=\"flex\" style={{ gap: 4 }}>\n {canEdit && (\n <IconButton\n size=\"small\"\n onClick={() => handleEditClick(row.metadata.namespace, row.metadata.name)}\n title=\"Edit API Product\"\n >\n <EditIcon fontSize=\"small\" />\n </IconButton>\n )}\n\n {canDelete && (\n <IconButton\n size=\"small\"\n onClick={() => handleDeleteClick(row.metadata.namespace, row.metadata.name)}\n title=\"Delete API Product\"\n >\n <DeleteIcon fontSize=\"small\" />\n </IconButton>\n )}\n </Box>\n );\n },\n },\n ];\n\n const planPolicyColumns: TableColumn[] = [\n {\n title: 'Name',\n field: 'metadata.name',\n render: (row: any) => (\n <Link to={`/kuadrant/planpolicy/${row.metadata.namespace}/${row.metadata.name}`}>\n <strong>{row.metadata.name}</strong>\n </Link>\n ),\n },\n {\n title: 'Namespace',\n field: 'metadata.namespace',\n },\n ];\n\n const renderResources = (resources: KuadrantResource[] | undefined) => {\n if (!resources || resources.length === 0) {\n return <Typography variant=\"body2\" color=\"textSecondary\">No API products found</Typography>;\n }\n return (\n <Table\n options={{\n paging: resources.length > 5,\n pageSize: 20,\n search: true,\n filtering: true,\n debounceInterval: 300,\n toolbar: true,\n emptyRowsWhenPaging: false,\n }}\n columns={columns}\n data={resources}\n />\n );\n };\n\n const renderPlanPolicies = (resources: KuadrantResource[] | undefined) => {\n if (!resources || resources.length === 0) {\n return <Typography variant=\"body2\" color=\"textSecondary\">No plan policies found</Typography>;\n }\n return (\n <Table\n options={{ paging: false, search: false, toolbar: false }}\n columns={planPolicyColumns}\n data={resources}\n />\n );\n };\n\n return (\n <Page themeId=\"tool\">\n <Header title=\"Kuadrant\" subtitle=\"API management for Kubernetes\">\n <SupportButton>Manage API products and access requests</SupportButton>\n </Header>\n <Content>\n {loading && <Progress />}\n {error && <ResponseErrorPanel error={error} />}\n {permissionError && (\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: {createPermissionError ? 'kuadrant.apiproduct.create' :\n deletePermissionError ? 'kuadrant.apiproduct.delete' :\n approvalQueuePermissionError ? 'kuadrant.apikeyrequest.read.all' :\n planPolicyPermissionError ? 'kuadrant.planpolicy.list' : 'unknown'}\n </Typography>\n <Typography variant=\"body2\" color=\"textSecondary\">\n please try again or contact your administrator\n </Typography>\n </Box>\n )}\n {!loading && !error && !permissionError && (\n <Grid container spacing={3} direction=\"column\">\n <Grid item>\n <MyApiKeysCard />\n </Grid>\n\n <Grid item>\n <InfoCard\n title=\"API Products\"\n action={\n canCreateApiProduct ? (\n <Box display=\"flex\" alignItems=\"center\" height=\"100%\" mt={1}>\n <Button\n variant=\"contained\"\n color=\"primary\"\n size=\"small\"\n startIcon={<AddIcon />}\n onClick={() => setCreateDialogOpen(true)}\n >\n Create API Product\n </Button>\n </Box>\n ) : undefined\n }\n >\n {renderResources(apiProducts?.items)}\n </InfoCard>\n </Grid>\n\n {canListPlanPolicies && (\n <Grid item>\n <InfoCard title=\"Plan Policies\">\n {renderPlanPolicies(planPolicies?.items)}\n </InfoCard>\n </Grid>\n )}\n\n {canViewApprovalQueue && (\n <Grid item>\n <ApprovalQueueCard />\n </Grid>\n )}\n </Grid>\n )}\n <CreateAPIProductDialog\n open={createDialogOpen}\n onClose={() => setCreateDialogOpen(false)}\n onSuccess={handleCreateSuccess}\n />\n <EditAPIProductDialog\n open={editDialogOpen}\n onClose={() => setEditDialogOpen(false)}\n onSuccess={handleEditSuccess}\n namespace={apiProductToEdit?.namespace || ''}\n name={apiProductToEdit?.name || ''}\n />\n <ConfirmDeleteDialog\n open={deleteDialogOpen}\n title=\"Delete API Product\"\n description={\n deleteStats\n ? `Deleting \"${apiProductToDelete?.name}\" will also remove:\n\n• ${deleteStats.requests} API Key Request(s)\n• ${deleteStats.secrets} API Key Secret(s)\n\nThis action cannot be undone.`\n : `Deleting \"${apiProductToDelete?.name}\" will also remove all associated API Key Requests and Secrets.\nThis action cannot be undone.`\n }\n confirmText={apiProductToDelete?.name}\n severity=\"high\"\n deleting={deleting}\n onConfirm={handleDeleteConfirm}\n onCancel={handleDeleteCancel}\n />\n </Content>\n </Page>\n );\n};\n\nexport const KuadrantPage = () => {\n return (\n <PermissionGate\n permission={kuadrantApiProductListPermission}\n errorMessage=\"you don't have permission to view the Kuadrant page\"\n >\n <ResourceList />\n </PermissionGate>\n );\n};\n"],"names":["ConfirmDeleteDialog","open","title","description","confirmText","severity","deleting","onConfirm","onCancel","inputValue","setInputValue","useState","useEffect","requiresTextConfirmation","canConfirm","Dialog","onClose","undefined","maxWidth","fullWidth","DialogTitle","Box","display","alignItems","style","gap","WarningIcon","color","span","DialogContent","DialogContentText","whiteSpace","mt","Typography","variant","gutterBottom","strong","TextField","size","value","onChange","e","target","disabled","autoFocus","placeholder","DialogActions","Button","onClick","startIcon","CircularProgress","EditAPIKeyRequestDialog","onSuccess","request","availablePlans","config","useApi","configApiRef","fetchApi","fetchApiRef","backendUrl","getString","planTier","setPlanTier","useCase","setUseCase","saving","setSaving","error","setError","spec","handleClose","mb","p","bgcolor","borderRadius","FormControl","margin","InputLabel","Select","map","plan","limitDesc","Object","entries","limits","key","val","join","MenuItem","tier","label","multiline","rows","helperText","async","patch","trim","response","fetch","metadata","namespace","name","method","headers","body","JSON","stringify","ok","errorData","json","catch","Error","status","err","console","message","MyApiKeysCard","deleteDialogState","identityApi","identityApiRef","alertApi","alertApiRef","selectedTab","setSelectedTab","setUserId","visibleKeys","setVisibleKeys","Set","menuAnchor","setMenuAnchor","menuRequest","setMenuRequest","editDialogState","setEditDialogState","plans","refresh","setRefresh","setDeleting","setDeleteDialogState","apiKeyValues","setApiKeyValues","Map","apiKeyLoading","setApiKeyLoading","useAsync","identity","getBackstageIdentity","extractedUserId","userEntityRef","split","log","optimisticallyDeleted","setOptimisticallyDeleted","requests","loading","items","InfoCard","Progress","allRequests","filter","r","has","approvedRequests","phase","pendingRequests","rejectedRequests","toggleKeyVisibility","keyName","prev","newSet","delete","add","handleMenuClose","handleEdit","apiProductName","apiProductRef","apiProductNamespace","apiProductResponse","apiProduct","handleDeleteClick","columns","field","render","row","Link","to","Chip","Tooltip","placement","overflow","textOverflow","reviewedBy","reviewedDate","reviewedAt","Date","toLocaleDateString","filtering","hasSecretRef","secretRef","isVisible","isLoading","apiKeyValue","get","fontFamily","fontSize","repeat","IconButton","requestNamespace","requestName","next","clearApiKeyValue","data","set","apiKey","fetchApiKeyFromSecret","VisibilityOffIcon","VisibilityIcon","creationTimestamp","date","stopPropagation","rect","currentTarget","getBoundingClientRect","top","bottom","left","aria-controls","aria-haspopup","MoreVertIcon","tabData","getTabData","tabColumns","col","getTabColumns","subheader","length","Tabs","_","newValue","indicatorColor","textColor","Tab","textAlign","Table","options","paging","pageSize","search","debounceInterval","toolbar","emptyRowsWhenPaging","item","id","Menu","Boolean","anchorReference","anchorPosition","push","post","PermissionGate","children","permission","fallback","errorMessage","allowed","useKuadrantPermission","PlanPolicyDetails","selectedPolicy","alertSeverity","alertMessage","includeTopMargin","border","fontWeight","marginTop","flexWrap","idx","limitText","daily","monthly","yearly","some","Alert","useStyles","makeStyles","asterisk","CreateAPIProductDialog","classes","setName","displayName","setDisplayName","setDescription","version","setVersion","approvalMode","setApprovalMode","publishStatus","setPublishStatus","tags","setTags","tagInput","setTagInput","selectedHTTPRoute","setSelectedHTTPRoute","contactEmail","setContactEmail","contactTeam","setContactTeam","docsURL","setDocsURL","openAPISpec","setOpenAPISpec","creating","setCreating","httpRoutes","httpRoutesLoading","route","annotations","planPolicies","selectedRouteInfo","routeNamespace","routeName","find","pp","ref","targetRef","kind","handleAddTag","includes","marginBottom","Grid","container","spacing","xs","required","InputLabelProps","select","tag","onDelete","handleDeleteTag","tagToDelete","onKeyPress","selectedRouteNamespace","selectedRouteName","apiVersion","group","contact","email","team","documentation","String","EditAPIProductDialog","setLoading","setTargetRef","then","res","React","ResourceList","setUserEntityRef","createDialogOpen","setCreateDialogOpen","editDialogOpen","setEditDialogOpen","refreshTrigger","setRefreshTrigger","deleteDialogOpen","setDeleteDialogOpen","apiProductToDelete","setApiProductToDelete","apiProductToEdit","setApiProductToEdit","deleteStats","setDeleteStats","canCreateApiProduct","createPermissionLoading","createPermissionError","kuadrantApiProductCreatePermission","canViewAllRequests","approvalQueueAllPermissionLoading","kuadrantApiKeyRequestReadAllPermission","canViewOwnRequests","approvalQueueOwnPermissionLoading","approvalQueuePermissionError","kuadrantApiKeyRequestReadOwnPermission","canViewApprovalQueue","approvalQueuePermissionLoading","canDeleteOwnApiProduct","deleteOwnPermissionLoading","kuadrantApiProductDeleteOwnPermission","canDeleteAllApiProducts","deleteAllPermissionLoading","deletePermissionError","kuadrantApiProductDeleteAllPermission","canUpdateOwnApiProduct","kuadrantApiProductUpdateOwnPermission","canUpdateAllApiProducts","kuadrantApiProductUpdateAllPermission","deletePermissionLoading","canListPlanPolicies","planPolicyPermissionLoading","planPolicyPermissionError","kuadrantPlanPolicyListPermission","apiProducts","apiProductsLoading","apiProductsError","planPoliciesLoading","planPoliciesError","permissionError","isPublished","className","customFilterAndSearch","term","toLowerCase","mode","formatDate","dateString","year","month","day","isOwner","canEdit","canDelete","handleEditClick","EditIcon","related","apiName","apiNamespace","approved","secrets","warn","DeleteIcon","planPolicyColumns","Page","themeId","Header","subtitle","SupportButton","Content","ResponseErrorPanel","direction","action","height","AddIcon","resources","renderPlanPolicies","ApprovalQueueCard","KuadrantPage","kuadrantApiProductListPermission"],"sourceRoot":""}
@@ -1,2 +0,0 @@
1
- "use strict";(self.webpackChunkinternal_plugin_kuadrant=self.webpackChunkinternal_plugin_kuadrant||[]).push([[879],{72627:(e,n,a)=>{a.r(n),a.d(n,{EntityKuadrantApiAccessCard:()=>p,EntityKuadrantApiKeyManagementTab:()=>u,EntityKuadrantApiKeysContent:()=>l,EntityKuadrantApiProductInfoContent:()=>m,KuadrantApprovalQueueCard:()=>c,KuadrantPage:()=>d,PlanPolicyDetailPage:()=>s,kuadrantPlugin:()=>i});var t=a(22097);const o=(0,t.createRouteRef)({id:"kuadrant"}),r=(0,t.createSubRouteRef)({id:"kuadrant/resource",parent:o,path:"/:kind/:namespace/:name"}),i=(0,t.createPlugin)({id:"kuadrant",routes:{root:o,resource:r}}),d=i.provide((0,t.createRoutableExtension)({name:"KuadrantPage",component:()=>Promise.all([a.e(5568),a.e(6352),a.e(9288),a.e(2120),a.e(2198),a.e(4556),a.e(3483),a.e(8441),a.e(5478),a.e(2469),a.e(4218),a.e(484),a.e(1942),a.e(7976),a.e(7094),a.e(6281),a.e(7632)]).then(a.bind(a,95251)).then(e=>e.KuadrantPage),mountPoint:o})),p=i.provide((0,t.createComponentExtension)({name:"EntityKuadrantApiAccessCard",component:{lazy:()=>Promise.all([a.e(5568),a.e(6352),a.e(9288),a.e(5478),a.e(2469),a.e(4218),a.e(484),a.e(1942),a.e(7976),a.e(6659),a.e(441)]).then(a.bind(a,60441)).then(e=>e.ApiAccessCard)}})),u=i.provide((0,t.createComponentExtension)({name:"EntityKuadrantApiKeyManagementTab",component:{lazy:()=>Promise.all([a.e(5568),a.e(6352),a.e(9288),a.e(2120),a.e(2198),a.e(4556),a.e(5478),a.e(4218),a.e(484),a.e(1942),a.e(7976),a.e(7094),a.e(6659),a.e(4306)]).then(a.bind(a,54306)).then(e=>e.ApiKeyManagementTab)}})),l=i.provide((0,t.createComponentExtension)({name:"EntityKuadrantApiKeysContent",component:{lazy:()=>Promise.all([a.e(5568),a.e(6352),a.e(9288),a.e(2120),a.e(2198),a.e(4556),a.e(5478),a.e(4218),a.e(484),a.e(1942),a.e(7976),a.e(7094),a.e(6659),a.e(4306)]).then(a.bind(a,54306)).then(e=>e.ApiKeyManagementTab)}})),c=i.provide((0,t.createComponentExtension)({name:"KuadrantApprovalQueueCard",component:{lazy:()=>Promise.all([a.e(5568),a.e(6352),a.e(9288),a.e(2120),a.e(2198),a.e(4556),a.e(5478),a.e(2469),a.e(4218),a.e(484),a.e(1942),a.e(7976),a.e(7094),a.e(6281),a.e(5222)]).then(a.bind(a,95631)).then(e=>e.ApprovalQueueCard)}})),m=i.provide((0,t.createComponentExtension)({name:"EntityKuadrantApiProductInfoContent",component:{lazy:()=>Promise.all([a.e(5568),a.e(6352),a.e(9288),a.e(2120),a.e(5478),a.e(2469),a.e(4218),a.e(484),a.e(1942),a.e(7976),a.e(7094),a.e(6659),a.e(5453)]).then(a.bind(a,75453)).then(e=>e.ApiProductInfoCard)}})),s=i.provide((0,t.createComponentExtension)({name:"PlanPolicyDetailPage",component:{lazy:()=>Promise.all([a.e(5568),a.e(6352),a.e(9288),a.e(2198),a.e(3483),a.e(5478),a.e(2469),a.e(4218),a.e(484),a.e(1942),a.e(7976),a.e(8365)]).then(a.bind(a,58365)).then(e=>e.PlanPolicyDetailPage)}}))}}]);
2
- //# sourceMappingURL=exposed-PluginRoot.0ac7fe4b.chunk.js.map