@kuadrant/kuadrant-backstage-plugin-frontend 0.0.2-dev-cd184fc → 0.0.2-dev-d2ba42b

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (119) hide show
  1. package/dist/components/ApiAccessCard/ApiAccessCard.esm.js +2 -1
  2. package/dist/components/ApiAccessCard/ApiAccessCard.esm.js.map +1 -1
  3. package/dist/components/ApiKeyApprovalPage/ApiKeyApprovalPage.esm.js +10 -0
  4. package/dist/components/ApiKeyApprovalPage/ApiKeyApprovalPage.esm.js.map +1 -0
  5. package/dist/components/ApiKeyApprovalPage/index.esm.js +2 -0
  6. package/dist/components/ApiKeyDetailPage/ApiKeyDetailPage.esm.js +4 -4
  7. package/dist/components/ApiKeyDetailPage/ApiKeyDetailPage.esm.js.map +1 -1
  8. package/dist/components/ApiProductDetailPage/ApiProductDetailPage.esm.js +28 -2
  9. package/dist/components/ApiProductDetailPage/ApiProductDetailPage.esm.js.map +1 -1
  10. package/dist/components/ApiProductDetails/ApiProductDetails.esm.js +13 -3
  11. package/dist/components/ApiProductDetails/ApiProductDetails.esm.js.map +1 -1
  12. package/dist/components/ApprovalQueueTable/ApprovalQueueTable.esm.js +2 -2
  13. package/dist/components/ApprovalQueueTable/ApprovalQueueTable.esm.js.map +1 -1
  14. package/dist/components/CreateAPIProductDialog/CreateAPIProductDialog.esm.js +117 -10
  15. package/dist/components/CreateAPIProductDialog/CreateAPIProductDialog.esm.js.map +1 -1
  16. package/dist/components/EditAPIProductDialog/EditAPIProductDialog.esm.js +48 -24
  17. package/dist/components/EditAPIProductDialog/EditAPIProductDialog.esm.js.map +1 -1
  18. package/dist/components/EntityApiApprovalTab/EntityApiApprovalTab.esm.js +2 -2
  19. package/dist/components/EntityApiApprovalTab/EntityApiApprovalTab.esm.js.map +1 -1
  20. package/dist/components/KuadrantPage/ApiProductsPage.esm.js +53 -3
  21. package/dist/components/KuadrantPage/ApiProductsPage.esm.js.map +1 -1
  22. package/dist/components/MyApiKeysPage/MyApiKeysPage.esm.js +10 -0
  23. package/dist/components/MyApiKeysPage/MyApiKeysPage.esm.js.map +1 -0
  24. package/dist/components/MyApiKeysPage/index.esm.js +2 -0
  25. package/dist/components/MyApiKeysPage/index.esm.js.map +1 -0
  26. package/dist/components/MyApiKeysTable/MyApiKeysTable.esm.js +26 -5
  27. package/dist/components/MyApiKeysTable/MyApiKeysTable.esm.js.map +1 -1
  28. package/dist/components/PlanPolicyDetailsCard/PlanPolicyDetails.esm.js +4 -4
  29. package/dist/components/PlanPolicyDetailsCard/PlanPolicyDetails.esm.js.map +1 -1
  30. package/dist/components/SimpleRequestAccessDialog/SimpleRequestAccessDialog.esm.js +206 -0
  31. package/dist/components/SimpleRequestAccessDialog/SimpleRequestAccessDialog.esm.js.map +1 -0
  32. package/dist/index.d.ts +3 -2
  33. package/dist/index.esm.js +1 -1
  34. package/dist/plugin.esm.js +11 -4
  35. package/dist/plugin.esm.js.map +1 -1
  36. package/dist/utils/styles.esm.js +44 -5
  37. package/dist/utils/styles.esm.js.map +1 -1
  38. package/dist-scalprum/internal.plugin-kuadrant.eacc31ca4d6c1340f8a8.js +2 -0
  39. package/dist-scalprum/{internal.plugin-kuadrant.c830fc2d56f9e96a055e.js.map → internal.plugin-kuadrant.eacc31ca4d6c1340f8a8.js.map} +1 -1
  40. package/dist-scalprum/plugin-manifest.json +3 -3
  41. package/dist-scalprum/static/2118.82433765.chunk.js +2 -0
  42. package/dist-scalprum/static/2118.82433765.chunk.js.map +1 -0
  43. package/dist-scalprum/static/2967.5bade048.chunk.js +2 -0
  44. package/dist-scalprum/static/2967.5bade048.chunk.js.map +1 -0
  45. package/dist-scalprum/static/3650.89dfc64c.chunk.js +2 -0
  46. package/dist-scalprum/static/3650.89dfc64c.chunk.js.map +1 -0
  47. package/dist-scalprum/static/369.2374941c.chunk.js +2 -0
  48. package/dist-scalprum/static/369.2374941c.chunk.js.map +1 -0
  49. package/dist-scalprum/static/3947.ff1c25cf.chunk.js +2 -0
  50. package/dist-scalprum/static/3947.ff1c25cf.chunk.js.map +1 -0
  51. package/dist-scalprum/static/3976.4cf18515.chunk.js +2 -0
  52. package/dist-scalprum/static/3976.4cf18515.chunk.js.map +1 -0
  53. package/dist-scalprum/static/4447.adbf663f.chunk.js +2 -0
  54. package/dist-scalprum/static/4447.adbf663f.chunk.js.map +1 -0
  55. package/dist-scalprum/static/5010.4ef96c87.chunk.js +3 -0
  56. package/dist-scalprum/static/5010.4ef96c87.chunk.js.map +1 -0
  57. package/dist-scalprum/static/5203.fce2a28f.chunk.js +2 -0
  58. package/dist-scalprum/static/5203.fce2a28f.chunk.js.map +1 -0
  59. package/dist-scalprum/static/6422.969d9b8c.chunk.js +2 -0
  60. package/dist-scalprum/static/6422.969d9b8c.chunk.js.map +1 -0
  61. package/dist-scalprum/static/6800.cd5c7bcb.chunk.js +2 -0
  62. package/dist-scalprum/static/6800.cd5c7bcb.chunk.js.map +1 -0
  63. package/dist-scalprum/static/7005.72759857.chunk.js +2 -0
  64. package/dist-scalprum/static/7005.72759857.chunk.js.map +1 -0
  65. package/dist-scalprum/static/7270.9473c969.chunk.js +2 -0
  66. package/dist-scalprum/static/7270.9473c969.chunk.js.map +1 -0
  67. package/dist-scalprum/static/7791.01371352.chunk.js +2 -0
  68. package/dist-scalprum/static/7791.01371352.chunk.js.map +1 -0
  69. package/dist-scalprum/static/{6763.d6cd937f.chunk.js → 8563.46f1a3e1.chunk.js} +3 -3
  70. package/dist-scalprum/static/8563.46f1a3e1.chunk.js.map +1 -0
  71. package/dist-scalprum/static/8789.30227526.chunk.js +2 -0
  72. package/dist-scalprum/static/8789.30227526.chunk.js.map +1 -0
  73. package/dist-scalprum/static/8804.63919453.chunk.js +2 -0
  74. package/dist-scalprum/static/8804.63919453.chunk.js.map +1 -0
  75. package/dist-scalprum/static/exposed-PluginRoot.8d8f0b09.chunk.js +2 -0
  76. package/dist-scalprum/static/exposed-PluginRoot.8d8f0b09.chunk.js.map +1 -0
  77. package/package.json +1 -1
  78. package/dist/components/ApiKeysPage/ApiKeysPage.esm.js +0 -43
  79. package/dist/components/ApiKeysPage/ApiKeysPage.esm.js.map +0 -1
  80. package/dist/components/ApiKeysPage/index.esm.js +0 -2
  81. package/dist-scalprum/internal.plugin-kuadrant.c830fc2d56f9e96a055e.js +0 -2
  82. package/dist-scalprum/static/2821.972ae33b.chunk.js +0 -2
  83. package/dist-scalprum/static/2821.972ae33b.chunk.js.map +0 -1
  84. package/dist-scalprum/static/2967.65c51af8.chunk.js +0 -2
  85. package/dist-scalprum/static/2967.65c51af8.chunk.js.map +0 -1
  86. package/dist-scalprum/static/3091.9a74ea5f.chunk.js +0 -2
  87. package/dist-scalprum/static/3091.9a74ea5f.chunk.js.map +0 -1
  88. package/dist-scalprum/static/3650.ee76eba9.chunk.js +0 -2
  89. package/dist-scalprum/static/3650.ee76eba9.chunk.js.map +0 -1
  90. package/dist-scalprum/static/3947.7458971d.chunk.js +0 -2
  91. package/dist-scalprum/static/3947.7458971d.chunk.js.map +0 -1
  92. package/dist-scalprum/static/3984.647ef00c.chunk.js +0 -2
  93. package/dist-scalprum/static/3984.647ef00c.chunk.js.map +0 -1
  94. package/dist-scalprum/static/4651.c85cecc4.chunk.js +0 -2
  95. package/dist-scalprum/static/4651.c85cecc4.chunk.js.map +0 -1
  96. package/dist-scalprum/static/4682.75f17114.chunk.js +0 -2
  97. package/dist-scalprum/static/4682.75f17114.chunk.js.map +0 -1
  98. package/dist-scalprum/static/5010.0cd6c959.chunk.js +0 -3
  99. package/dist-scalprum/static/5010.0cd6c959.chunk.js.map +0 -1
  100. package/dist-scalprum/static/5203.b654e8e0.chunk.js +0 -2
  101. package/dist-scalprum/static/5203.b654e8e0.chunk.js.map +0 -1
  102. package/dist-scalprum/static/5453.ecdee66d.chunk.js +0 -2
  103. package/dist-scalprum/static/5453.ecdee66d.chunk.js.map +0 -1
  104. package/dist-scalprum/static/6763.d6cd937f.chunk.js.map +0 -1
  105. package/dist-scalprum/static/6800.20f46859.chunk.js +0 -2
  106. package/dist-scalprum/static/6800.20f46859.chunk.js.map +0 -1
  107. package/dist-scalprum/static/6840.1653e6b0.chunk.js +0 -2
  108. package/dist-scalprum/static/6840.1653e6b0.chunk.js.map +0 -1
  109. package/dist-scalprum/static/7791.ac1ac509.chunk.js +0 -2
  110. package/dist-scalprum/static/7791.ac1ac509.chunk.js.map +0 -1
  111. package/dist-scalprum/static/8172.cbe1f2c4.chunk.js +0 -2
  112. package/dist-scalprum/static/8172.cbe1f2c4.chunk.js.map +0 -1
  113. package/dist-scalprum/static/8799.52bbeef1.chunk.js +0 -2
  114. package/dist-scalprum/static/8799.52bbeef1.chunk.js.map +0 -1
  115. package/dist-scalprum/static/exposed-PluginRoot.55777e36.chunk.js +0 -2
  116. package/dist-scalprum/static/exposed-PluginRoot.55777e36.chunk.js.map +0 -1
  117. /package/dist/components/{ApiKeysPage → ApiKeyApprovalPage}/index.esm.js.map +0 -0
  118. /package/dist-scalprum/static/{5010.0cd6c959.chunk.js.LICENSE.txt → 5010.4ef96c87.chunk.js.LICENSE.txt} +0 -0
  119. /package/dist-scalprum/static/{6763.d6cd937f.chunk.js.LICENSE.txt → 8563.46f1a3e1.chunk.js.LICENSE.txt} +0 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"static/7005.72759857.chunk.js","mappings":"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","sources":["webpack://internal.plugin-kuadrant/./src/components/FilterPanel/FilterPanel.tsx","webpack://internal.plugin-kuadrant/./src/components/PermissionGate/PermissionGate.tsx","webpack://internal.plugin-kuadrant/./src/components/CreateAPIProductDialog/CreateAPIProductDialog.tsx","webpack://internal.plugin-kuadrant/./src/components/KuadrantPage/ApiProductsPage.tsx"],"sourcesContent":["import React from 'react';\nimport {\n Box,\n Typography,\n Checkbox,\n FormControlLabel,\n FormGroup,\n Divider,\n Button,\n Collapse,\n makeStyles,\n} from '@material-ui/core';\nimport ExpandMoreIcon from '@material-ui/icons/ExpandMore';\nimport ExpandLessIcon from '@material-ui/icons/ExpandLess';\n\nconst useStyles = makeStyles(theme => ({\n root: {\n width: 240,\n minWidth: 240,\n padding: theme.spacing(2),\n borderRight: `1px solid ${theme.palette.divider}`,\n backgroundColor: theme.palette.background.paper,\n height: '100%',\n overflowY: 'auto',\n },\n sectionTitle: {\n fontWeight: 600,\n fontSize: '0.75rem',\n textTransform: 'uppercase',\n letterSpacing: '0.05em',\n color: theme.palette.text.secondary,\n marginBottom: theme.spacing(1),\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'space-between',\n cursor: 'pointer',\n userSelect: 'none',\n },\n filterSection: {\n marginBottom: theme.spacing(2),\n },\n checkbox: {\n padding: theme.spacing(0.5),\n },\n checkboxLabel: {\n fontSize: '0.875rem',\n },\n clearButton: {\n marginTop: theme.spacing(2),\n },\n count: {\n fontSize: '0.75rem',\n color: theme.palette.text.secondary,\n marginLeft: theme.spacing(1),\n },\n}));\n\nexport interface FilterOption {\n value: string;\n label: string;\n count?: number;\n}\n\nexport interface FilterSection {\n id: string;\n title: string;\n options: FilterOption[];\n collapsed?: boolean;\n}\n\nexport interface FilterState {\n [sectionId: string]: string[];\n}\n\ninterface FilterPanelProps {\n sections: FilterSection[];\n filters: FilterState;\n onChange: (filters: FilterState) => void;\n onClear?: () => void;\n}\n\nexport const FilterPanel = ({\n sections,\n filters,\n onChange,\n onClear,\n}: FilterPanelProps) => {\n const classes = useStyles();\n const [collapsedSections, setCollapsedSections] = React.useState<Set<string>>(\n new Set(sections.filter(s => s.collapsed).map(s => s.id)),\n );\n\n const toggleSection = (sectionId: string) => {\n setCollapsedSections(prev => {\n const next = new Set(prev);\n if (next.has(sectionId)) {\n next.delete(sectionId);\n } else {\n next.add(sectionId);\n }\n return next;\n });\n };\n\n const handleCheckboxChange = (sectionId: string, value: string) => {\n const currentValues = filters[sectionId] || [];\n const newValues = currentValues.includes(value)\n ? currentValues.filter(v => v !== value)\n : [...currentValues, value];\n\n onChange({\n ...filters,\n [sectionId]: newValues,\n });\n };\n\n const hasActiveFilters = Object.values(filters).some(\n values => values.length > 0,\n );\n\n const handleClear = () => {\n const clearedFilters: FilterState = {};\n sections.forEach(section => {\n clearedFilters[section.id] = [];\n });\n onChange(clearedFilters);\n onClear?.();\n };\n\n return (\n <Box className={classes.root}>\n <Box display=\"flex\" justifyContent=\"space-between\" alignItems=\"center\" mb={2}>\n <Typography variant=\"subtitle2\">Filters</Typography>\n {hasActiveFilters && (\n <Button\n size=\"small\"\n color=\"primary\"\n onClick={handleClear}\n >\n Clear all\n </Button>\n )}\n </Box>\n\n <Divider />\n\n {sections.map(section => {\n const isCollapsed = collapsedSections.has(section.id);\n const selectedCount = (filters[section.id] || []).length;\n\n return (\n <Box key={section.id} className={classes.filterSection} mt={2}>\n <Box\n className={classes.sectionTitle}\n onClick={() => toggleSection(section.id)}\n >\n <Box display=\"flex\" alignItems=\"center\">\n <span>{section.title}</span>\n {selectedCount > 0 && (\n <span className={classes.count}>({selectedCount})</span>\n )}\n </Box>\n {isCollapsed ? (\n <ExpandMoreIcon fontSize=\"small\" />\n ) : (\n <ExpandLessIcon fontSize=\"small\" />\n )}\n </Box>\n\n <Collapse in={!isCollapsed}>\n <FormGroup>\n {section.options.map(option => (\n <FormControlLabel\n key={option.value}\n control={\n <Checkbox\n checked={(filters[section.id] || []).includes(option.value)}\n onChange={() =>\n handleCheckboxChange(section.id, option.value)\n }\n size=\"small\"\n className={classes.checkbox}\n color=\"primary\"\n />\n }\n label={\n <Box display=\"flex\" alignItems=\"center\">\n <span className={classes.checkboxLabel}>\n {option.label}\n </span>\n {option.count !== undefined && (\n <span className={classes.count}>({option.count})</span>\n )}\n </Box>\n }\n />\n ))}\n </FormGroup>\n </Collapse>\n </Box>\n );\n })}\n </Box>\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, { useEffect, 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 FormControl,\n RadioGroup,\n FormControlLabel,\n Radio,\n Tooltip,\n IconButton,\n InputAdornment,\n} from '@material-ui/core';\nimport InfoOutlinedIcon from '@material-ui/icons/InfoOutlined';\nimport AddIcon from '@material-ui/icons/Add';\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';\nimport { validateKubernetesName, validateURL } from '../../utils/validation';\nimport { handleFetchError } from \"../../utils/errors\";\nimport { Lifecycle } from '../../types/api-management';\n\nconst useStyles = makeStyles((theme) => ({\n asterisk: {\n color: '#f44336',\n },\n sectionHeader: {\n display: 'flex',\n alignItems: 'center',\n gap: theme.spacing(0.5),\n marginTop: theme.spacing(2),\n marginBottom: theme.spacing(1),\n },\n infoIcon: {\n fontSize: 18,\n color: theme.palette.text.secondary,\n },\n tagChip: {\n marginRight: theme.spacing(0.5),\n marginBottom: theme.spacing(0.5),\n },\n}));\n\ninterface CreateAPIProductDialogProps {\n open: boolean;\n onClose: () => void;\n onSuccess: (productInfo: { namespace: string; name: string; displayName: string }) => 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 [lifecycle, setLifecycle] = useState<Lifecycle>('production');\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 const [httpRoutesRetry, setHttpRoutesRetry] = useState(0);\n const [nameError, setNameError] = useState<string | null>(null);\n const [openAPISpecError, setOpenAPISpecError] = useState<string | null>(null);\n const [routeSearchTerm, setRouteSearchTerm] = useState('');\n const [routeSearchField, setRouteSearchField] = useState<'name' | 'namespace' | 'planpolicy'>('name');\n const {\n value: httpRoutes,\n loading: httpRoutesLoading,\n error: httpRoutesError\n } = useAsync(async () => {\n const response = await fetchApi.fetch(`${backendUrl}/api/kuadrant/httproutes`);\n\n if (!response.ok) {\n const error = await handleFetchError(response);\n throw new Error(`failed to fetch routes. ${error}`);\n }\n\n const data = await response.json();\n return data.items || [];\n }, [backendUrl, fetchApi, open, httpRoutesRetry]);\n\n // load planpolicies with full details to show associated plans\n const {\n value: planPolicies,\n error: planPoliciesError\n } = useAsync(async () => {\n const response = await fetchApi.fetch(`${backendUrl}/api/kuadrant/planpolicies`);\n\n if (!response.ok) {\n const error = await handleFetchError(response);\n throw new Error(`failed to fetch PlanPolicies. ${error}`);\n }\n\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 // format tier info for dropdown display\n const formatTierInfo = (policy: any): string => {\n if (!policy?.spec?.plans) return '';\n const tiers = Object.entries(policy.spec.plans)\n .map(([name, plan]: [string, any]) => {\n const limit = plan?.limits?.requests;\n if (!limit) return name;\n return `${name}: ${limit.count}/${limit.period}`;\n })\n .join('; ');\n return tiers ? ` (${tiers})` : '';\n };\n\n // get policy info for a route (for dropdown display)\n const getPolicyInfoForRoute = (routeNamespace: string, routeName: string): string => {\n const policy = getPlanPolicyForRoute(routeNamespace, routeName);\n if (!policy) return 'N/A';\n return `${policy.metadata.name}${formatTierInfo(policy)}`;\n };\n\n useEffect(() => {\n if (open) {\n setNameError(null);\n setOpenAPISpecError(null);\n }\n }, [open]);\n\n // validate handlers\n const handleNameChange = (value: string) => {\n setName(value);\n setNameError(validateKubernetesName(value));\n };\n\n const handleDisplayNameChange = (value: string) => {\n setDisplayName(value);\n // Auto-generate Kubernetes resource name from display name with random hex suffix\n if (!name || name.match(/-[a-f0-9]{6}$/)) {\n const baseName = value.toLowerCase().replace(/[^a-z0-9-]/g, '-').replace(/-+/g, '-').replace(/^-|-$/g, '');\n const randomHex = Math.floor(Math.random() * 16777215).toString(16).padStart(6, '0');\n const autoName = `${baseName}-${randomHex}`;\n setName(autoName);\n setNameError(validateKubernetesName(autoName));\n }\n };\n\n const handleOpenAPISpecChange = (value: string) => {\n setOpenAPISpec(value);\n setOpenAPISpecError(validateURL(value));\n };\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 labels: {\n lifecycle,\n },\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 && { openAPISpecURL: 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 error = await handleFetchError(response);\n throw new Error(`failed to create APIProduct. ${error}`);\n }\n\n onSuccess({ namespace, name, displayName });\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 setLifecycle('production');\n setTags([]);\n setTagInput('');\n setSelectedHTTPRoute('');\n setContactEmail('');\n setContactTeam('');\n setDocsURL('');\n setOpenAPISpec('');\n setError('');\n setNameError(null);\n setOpenAPISpecError(null);\n onClose();\n };\n\n const hasValidationErrors = !!nameError || !!openAPISpecError;\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 {httpRoutesError && (\n <Alert severity=\"error\" style={{ marginBottom: 16 }}>\n <strong>Failed to load HTTPRoutes:</strong> {httpRoutesError.message}\n <Box mt={1}>\n <Button\n size=\"small\"\n variant=\"outlined\"\n onClick={() => setHttpRoutesRetry(prev => prev + 1)}\n >\n Retry\n </Button>\n </Box>\n </Alert>\n )}\n\n {planPoliciesError && (\n <Alert severity=\"warning\" style={{ marginBottom: 16 }}>\n <strong>Failed to load PlanPolicies:</strong> {planPoliciesError.message}\n <Typography variant=\"body2\" style={{ marginTop: 8 }}>\n You can still create the API Product, but plan information may be incomplete.\n </Typography>\n </Alert>\n )}\n {/* API product info section */}\n <Box className={classes.sectionHeader}>\n <Typography variant=\"subtitle1\"><strong>API product info</strong></Typography>\n </Box>\n <Grid container spacing={2}>\n <Grid item xs={6}>\n <TextField\n fullWidth\n label=\"API product name\"\n value={displayName}\n onChange={e => handleDisplayNameChange(e.target.value)}\n placeholder=\"My API\"\n helperText=\"Display name for your API product (shown to users)\"\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=\"Kubernetes resource name\"\n value={name}\n onChange={e => handleNameChange(e.target.value)}\n placeholder=\"my-api\"\n helperText={nameError || \"Auto-generated from product name. Only lowercase, numbers, and hyphens allowed.\"}\n error={!!nameError}\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 helperText=\"Give a version to your API product\"\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=\"Tag\"\n value={tagInput}\n onChange={e => setTagInput(e.target.value)}\n onKeyPress={e => {\n if (e.key === 'Enter') {\n e.preventDefault();\n handleAddTag();\n }\n }}\n placeholder=\"Add tag\"\n helperText=\"Add a tag to your API product\"\n margin=\"normal\"\n disabled={creating}\n InputProps={{\n endAdornment: tagInput ? (\n <InputAdornment position=\"end\">\n <IconButton size=\"small\" onClick={handleAddTag} disabled={creating}>\n <AddIcon fontSize=\"small\" />\n </IconButton>\n </InputAdornment>\n ) : undefined,\n }}\n />\n </Grid>\n {tags.length > 0 && (\n <Grid item xs={12}>\n <Box display=\"flex\" flexWrap=\"wrap\">\n {tags.map(tag => (\n <Chip\n key={tag}\n label={tag}\n onDelete={creating ? undefined : () => handleDeleteTag(tag)}\n size=\"small\"\n className={classes.tagChip}\n disabled={creating}\n />\n ))}\n </Box>\n </Grid>\n )}\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 </Grid>\n\n {/* Add API and Associate route section */}\n <Box className={classes.sectionHeader}>\n <Typography variant=\"subtitle1\"><strong>Add API and Associate route</strong></Typography>\n <Tooltip title=\"Register an existing API and associate HTTPRoute for your API product\">\n <InfoOutlinedIcon className={classes.infoIcon} />\n </Tooltip>\n </Box>\n <Grid container spacing={2}>\n <Grid item xs={12}>\n <TextField\n fullWidth\n label=\"OpenAPI Spec URL\"\n value={openAPISpec}\n onChange={e => handleOpenAPISpecChange(e.target.value)}\n placeholder=\"https://api.example.com/openapi.json\"\n helperText={openAPISpecError || \"Enter the full path to your API spec file\"}\n error={!!openAPISpecError}\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={12}>\n <TextField\n fullWidth\n label=\"Documentation URL\"\n value={docsURL}\n onChange={e => setDocsURL(e.target.value)}\n placeholder=\"https://docs.example.com/api\"\n helperText=\"Link to external documentation for this API\"\n margin=\"normal\"\n disabled={creating}\n />\n </Grid>\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={\n httpRoutesError\n ? \"Unable to load HTTPRoutes. Please retry.\"\n : \"Select an HTTPRoute. APIProduct will be created in the same namespace.\"\n }\n error={!!httpRoutesError}\n disabled={httpRoutesLoading || creating || !!httpRoutesError}\n InputLabelProps={{\n classes: {\n asterisk: classes.asterisk,\n },\n }}\n SelectProps={{\n 'data-testid': 'httproute-select',\n MenuProps: {\n PaperProps: {\n style: { maxHeight: 400 },\n },\n anchorOrigin: {\n vertical: 'bottom',\n horizontal: 'left',\n },\n transformOrigin: {\n vertical: 'top',\n horizontal: 'left',\n },\n getContentAnchorEl: null,\n },\n } as any}\n >\n {/* Search bar inside dropdown */}\n <Box px={2} pt={1} pb={1} style={{ position: 'sticky', top: 0, zIndex: 1 }}>\n <TextField\n fullWidth\n size=\"small\"\n placeholder=\"Search...\"\n value={routeSearchTerm}\n onChange={e => setRouteSearchTerm(e.target.value)}\n onKeyDown={e => e.stopPropagation()}\n onClick={e => e.stopPropagation()}\n InputProps={{\n endAdornment: (\n <InputAdornment position=\"end\">\n <TextField\n select\n size=\"small\"\n value={routeSearchField}\n onChange={e => setRouteSearchField(e.target.value as 'name' | 'namespace' | 'planpolicy')}\n onKeyDown={e => e.stopPropagation()}\n onClick={e => e.stopPropagation()}\n style={{ minWidth: 120 }}\n variant=\"standard\"\n >\n <MenuItem value=\"name\">Name</MenuItem>\n <MenuItem value=\"namespace\">Namespace</MenuItem>\n <MenuItem value=\"planpolicy\">PlanPolicy</MenuItem>\n </TextField>\n </InputAdornment>\n ),\n }}\n />\n </Box>\n {httpRoutesLoading && (\n <MenuItem value=\"\">Loading...</MenuItem>\n )}\n {httpRoutesError && (\n <MenuItem value=\"\">Error loading routes</MenuItem>\n )}\n {!httpRoutesLoading && !httpRoutesError && httpRoutes && httpRoutes.length === 0 && (\n <MenuItem value=\"\">No HTTPRoutes available</MenuItem>\n )}\n {!httpRoutesLoading && !httpRoutesError && httpRoutes && httpRoutes\n .filter((route: any) => {\n if (!routeSearchTerm) return true;\n const routeNs = route.metadata.namespace;\n const routeName = route.metadata.name;\n const policyInfo = getPolicyInfoForRoute(routeNs, routeName);\n const searchLower = routeSearchTerm.toLowerCase();\n\n switch (routeSearchField) {\n case 'name':\n return routeName.toLowerCase().includes(searchLower);\n case 'namespace':\n return routeNs.toLowerCase().includes(searchLower);\n case 'planpolicy':\n return policyInfo.toLowerCase().includes(searchLower);\n default:\n return true;\n }\n })\n .map((route: any) => {\n const routeNs = route.metadata.namespace;\n const routeName = route.metadata.name;\n const policyInfo = getPolicyInfoForRoute(routeNs, routeName);\n return (\n <MenuItem\n key={`${routeNs}/${routeName}`}\n value={`${routeNs}/${routeName}`}\n >\n <Box>\n <Typography variant=\"body1\">{routeName}</Typography>\n <Typography variant=\"caption\" color=\"textSecondary\">\n Associated PlanPolicy: {policyInfo}\n </Typography>\n </Box>\n </MenuItem>\n );\n })}\n </TextField>\n </Grid>\n </Grid>\n\n {/* HTTPRoute policies section */}\n {selectedHTTPRoute && selectedPolicy && (\n <>\n <Box className={classes.sectionHeader}>\n <Typography variant=\"subtitle1\"><strong>HTTPRoute policies</strong></Typography>\n <Tooltip title=\"Shows the associated policies and rate limit tiers for the selected HTTPRoute\">\n <InfoOutlinedIcon className={classes.infoIcon} />\n </Tooltip>\n </Box>\n <PlanPolicyDetails\n discoveredPlans={selectedPolicy.plans}\n alertSeverity=\"warning\"\n alertMessage=\"No PlanPolicy found for this HTTPRoute. API keys and rate limiting may not be available.\"\n includeTopMargin={false}\n />\n </>\n )}\n\n <Box className={classes.sectionHeader}>\n <Typography variant=\"subtitle1\"><strong>Lifecycle and Visibility</strong></Typography>\n <Tooltip title=\"Control the lifecycle state and catalog visibility of this API product\">\n <InfoOutlinedIcon className={classes.infoIcon} />\n </Tooltip>\n </Box>\n <Grid container spacing={2}>\n <Grid item xs={6}>\n <TextField\n fullWidth\n select\n label=\"Lifecycle\"\n value={lifecycle}\n onChange={e => setLifecycle(e.target.value as Lifecycle)}\n margin=\"normal\"\n helperText=\"API lifecycle state\"\n disabled={creating}\n >\n <MenuItem value=\"experimental\">Experimental</MenuItem>\n <MenuItem value=\"production\">Production</MenuItem>\n <MenuItem value=\"deprecated\">Deprecated</MenuItem>\n <MenuItem value=\"retired\">Retired</MenuItem>\n </TextField>\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=\"Controls catalog visibility (Draft = hidden from consumers)\"\n disabled={creating}\n >\n <MenuItem value=\"Draft\">Draft</MenuItem>\n <MenuItem value=\"Published\">Published</MenuItem>\n </TextField>\n </Grid>\n </Grid>\n\n {/* API Key approval section */}\n <Box className={classes.sectionHeader}>\n <Typography variant=\"subtitle1\"><strong>API Key approval</strong></Typography>\n <Tooltip title=\"Choose how API key requests are handled for this product\">\n <InfoOutlinedIcon className={classes.infoIcon} />\n </Tooltip>\n </Box>\n <FormControl component=\"fieldset\" disabled={creating}>\n <RadioGroup\n row\n value={approvalMode}\n onChange={e => setApprovalMode(e.target.value as 'automatic' | 'manual')}\n >\n <FormControlLabel\n value=\"manual\"\n control={<Radio color=\"primary\" />}\n label={\n <Box>\n <Typography variant=\"body2\">Need manual approval</Typography>\n <Typography variant=\"caption\" color=\"textSecondary\">\n Requires approval for requesting this API\n </Typography>\n </Box>\n }\n />\n <FormControlLabel\n value=\"automatic\"\n control={<Radio color=\"primary\" />}\n label={\n <Box>\n <Typography variant=\"body2\">Automatic</Typography>\n <Typography variant=\"caption\" color=\"textSecondary\">\n Keys are created without need to be approved\n </Typography>\n </Box>\n }\n />\n </RadioGroup>\n </FormControl>\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 || hasValidationErrors}\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, useMemo, useCallback } from \"react\";\nimport {\n Typography,\n Box,\n Chip,\n Button,\n IconButton,\n CircularProgress,\n makeStyles,\n} 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 VpnKeyIcon from \"@material-ui/icons/VpnKey\";\nimport LockIcon from \"@material-ui/icons/Lock\";\nimport { FilterPanel, FilterSection, FilterState } from \"../FilterPanel\";\nimport {\n Header,\n Page,\n Content,\n SupportButton,\n ResponseErrorPanel,\n Link,\n Table,\n TableColumn,\n} from \"@backstage/core-components\";\nimport useAsync from \"react-use/lib/useAsync\";\nimport {\n useApi,\n configApiRef,\n fetchApiRef,\n alertApiRef,\n identityApiRef,\n} from \"@backstage/core-plugin-api\";\nimport { PermissionGate } from \"../PermissionGate\";\nimport { CreateAPIProductDialog } from \"../CreateAPIProductDialog\";\nimport {\n kuadrantApiProductCreatePermission,\n kuadrantApiProductDeleteOwnPermission,\n kuadrantApiProductDeleteAllPermission,\n kuadrantApiProductUpdateOwnPermission,\n kuadrantApiProductUpdateAllPermission,\n kuadrantApiProductListPermission,\n kuadrantPlanPolicyListPermission,\n} from \"../../permissions\";\nimport { useKuadrantPermission } from \"../../utils/permissions\";\nimport { handleFetchError } from \"../../utils/errors\";\nimport { EditAPIProductDialog } from \"../EditAPIProductDialog\";\nimport { ConfirmDeleteDialog } from \"../ConfirmDeleteDialog\";\nimport emptyStateIllustration from \"../../assets/empty-state-illustration.png\";\nimport { getLifecycleChipStyle } from \"../../utils/styles\";\n\ntype KuadrantResource = {\n metadata: {\n name: string;\n namespace: string;\n creationTimestamp: string;\n annotations?: Record<string, string>;\n labels?: Record<string, string>;\n };\n spec?: any;\n status?: any;\n};\n\ntype KuadrantList = {\n items: KuadrantResource[];\n};\n\nconst useStyles = makeStyles((theme) => ({\n container: {\n display: \"flex\",\n height: \"100%\",\n minHeight: 400,\n },\n tableContainer: {\n flex: 1,\n overflow: \"auto\",\n padding: 10,\n },\n emptyState: {\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n padding: theme.spacing(6),\n minHeight: 400,\n },\n emptyStateContent: {\n display: \"flex\",\n alignItems: \"center\",\n gap: theme.spacing(6),\n maxWidth: 900,\n },\n emptyStateText: {\n flex: 1,\n },\n emptyStateTitle: {\n marginBottom: theme.spacing(2),\n },\n emptyStateDescription: {\n marginBottom: theme.spacing(3),\n color: theme.palette.text.secondary,\n },\n emptyStateImage: {\n maxWidth: 400,\n height: \"auto\",\n },\n}));\n\nconst ResourceList = () => {\n const classes = useStyles();\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<{\n namespace: string;\n name: string;\n } | null>(null);\n const [apiProductToEdit, setApiProductToEdit] = useState<{\n namespace: string;\n name: string;\n } | null>(null);\n const [deleting, setDeleting] = useState(false);\n const [deleteStats, setDeleteStats] = useState<{\n requests: number;\n secrets: number;\n } | null>(null);\n const [filters, setFilters] = useState<FilterState>({\n status: [],\n lifecycle: [],\n policy: [],\n route: [],\n namespace: [],\n tags: [],\n authentication: [],\n });\n\n const {\n allowed: canCreateApiProduct,\n loading: createPermissionLoading,\n error: createPermissionError,\n } = useKuadrantPermission(kuadrantApiProductCreatePermission);\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 { allowed: canUpdateOwnApiProduct } = useKuadrantPermission(\n kuadrantApiProductUpdateOwnPermission,\n );\n\n const { allowed: canUpdateAllApiProducts } = useKuadrantPermission(\n kuadrantApiProductUpdateAllPermission,\n );\n\n const deletePermissionLoading =\n 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 {\n value: apiProducts,\n loading: apiProductsLoading,\n error: apiProductsError,\n } = useAsync(async (): Promise<KuadrantList> => {\n const response = await fetchApi.fetch(\n `${backendUrl}/api/kuadrant/apiproducts`,\n );\n if (!response.ok) {\n const error = await handleFetchError(response);\n throw new Error(`failed to fetch APIProducts. ${error}`);\n }\n return await response.json();\n }, [backendUrl, fetchApi, refreshTrigger]);\n\n const {\n value: planPolicies,\n loading: planPoliciesLoading,\n error: planPoliciesError,\n } = useAsync(async (): Promise<KuadrantList> => {\n // skip fetch if user doesn't have permission\n if (!canListPlanPolicies) {\n return { items: [] };\n }\n const response = await fetchApi.fetch(\n `${backendUrl}/api/kuadrant/planpolicies`,\n );\n if (!response.ok) {\n const error = await handleFetchError(response);\n throw new Error(`failed to fetch PlanPolicies: ${error}`);\n }\n return await response.json();\n }, [backendUrl, fetchApi, refreshTrigger, canListPlanPolicies]);\n\n // helper to find policy for a given route\n const getPolicyForProduct = useCallback((product: KuadrantResource): string | null => {\n if (!planPolicies?.items) return null;\n const targetRef = product.spec?.targetRef;\n if (!targetRef) return null;\n\n const policy = planPolicies.items.find((pp: KuadrantResource) => {\n const ref = (pp as any).targetRef;\n return (\n ref?.kind === \"HTTPRoute\" &&\n ref?.name === targetRef.name &&\n (!ref?.namespace || ref?.namespace === (targetRef.namespace || product.metadata.namespace))\n );\n });\n return policy?.metadata.name || null;\n }, [planPolicies]);\n\n // helper to get auth schemes for a product\n const getAuthSchemes = useCallback((product: KuadrantResource): string[] => {\n const authSchemes = product.status?.discoveredAuthScheme?.authentication || {};\n const schemeObjects = Object.values(authSchemes);\n const schemes: string[] = [];\n\n if (schemeObjects.some((scheme: any) => scheme.hasOwnProperty(\"apiKey\"))) {\n schemes.push(\"API Key\");\n }\n if (schemeObjects.some((scheme: any) => scheme.hasOwnProperty(\"jwt\"))) {\n schemes.push(\"OIDC\");\n }\n if (schemes.length === 0) {\n schemes.push(\"Unknown\");\n }\n return schemes;\n }, []);\n\n const loading =\n apiProductsLoading ||\n planPoliciesLoading ||\n createPermissionLoading ||\n deletePermissionLoading ||\n planPolicyPermissionLoading;\n const error = apiProductsError || planPoliciesError;\n const permissionError =\n createPermissionError || deletePermissionError || planPolicyPermissionError;\n\n const allProducts = useMemo(() => {\n const products = apiProducts?.items || [];\n\n // API consumers (users without create/update permissions) should only see Published products\n // API owners can see all products (Draft and Published)\n if (!canCreateApiProduct && !canUpdateOwnApiProduct && !canUpdateAllApiProducts) {\n return products.filter((p: KuadrantResource) => {\n const publishStatus = p.spec?.publishStatus || 'Draft';\n return publishStatus === 'Published';\n });\n }\n\n return products;\n }, [apiProducts, canCreateApiProduct, canUpdateOwnApiProduct, canUpdateAllApiProducts]);\n\n const filterSections: FilterSection[] = useMemo(() => {\n const statusCounts = { Draft: 0, Published: 0 };\n const lifecycleCounts = new Map<string, number>();\n const policyCounts = new Map<string, number>();\n const routeCounts = new Map<string, number>();\n const namespaceCounts = new Map<string, number>();\n const tagCounts = new Map<string, number>();\n const authCounts = new Map<string, number>();\n\n allProducts.forEach((p: KuadrantResource) => {\n const status = p.spec?.publishStatus || \"Draft\";\n statusCounts[status as keyof typeof statusCounts]++;\n\n const lifecycle = p.metadata.labels?.lifecycle || \"production\";\n lifecycleCounts.set(lifecycle, (lifecycleCounts.get(lifecycle) || 0) + 1);\n\n const policy = getPolicyForProduct(p) || \"N/A\";\n policyCounts.set(policy, (policyCounts.get(policy) || 0) + 1);\n\n const route = p.spec?.targetRef?.name || \"unknown\";\n routeCounts.set(route, (routeCounts.get(route) || 0) + 1);\n\n const ns = p.metadata.namespace;\n namespaceCounts.set(ns, (namespaceCounts.get(ns) || 0) + 1);\n\n const tags = p.spec?.tags || [];\n tags.forEach((tag: string) => {\n tagCounts.set(tag, (tagCounts.get(tag) || 0) + 1);\n });\n\n const authSchemes = getAuthSchemes(p);\n authSchemes.forEach((scheme: string) => {\n authCounts.set(scheme, (authCounts.get(scheme) || 0) + 1);\n });\n });\n\n const sections: FilterSection[] = [\n {\n id: \"status\",\n title: \"Publish Status\",\n options: [\n { value: \"Draft\", label: \"Draft\", count: statusCounts.Draft },\n { value: \"Published\", label: \"Published\", count: statusCounts.Published },\n ],\n },\n {\n id: \"lifecycle\",\n title: \"Lifecycle\",\n options: Array.from(lifecycleCounts.entries()).map(([state, count]) => ({\n value: state,\n label: state.charAt(0).toUpperCase() + state.slice(1),\n count,\n })),\n },\n {\n id: \"authentication\",\n title: \"Authentication\",\n options: Array.from(authCounts.entries()).map(([scheme, count]) => ({\n value: scheme,\n label: scheme,\n count,\n })),\n },\n {\n id: \"route\",\n title: \"Route\",\n options: Array.from(routeCounts.entries()).map(([name, count]) => ({\n value: name,\n label: name,\n count,\n })),\n collapsed: routeCounts.size > 5,\n },\n {\n id: \"namespace\",\n title: \"Namespace\",\n options: Array.from(namespaceCounts.entries()).map(([ns, count]) => ({\n value: ns,\n label: ns,\n count,\n })),\n collapsed: namespaceCounts.size > 5,\n },\n {\n id: \"tags\",\n title: \"Tags\",\n options: Array.from(tagCounts.entries()).map(([tag, count]) => ({\n value: tag,\n label: tag,\n count,\n })),\n collapsed: tagCounts.size > 5,\n },\n ];\n\n // only show policy filter if user can list planpolicies\n if (canListPlanPolicies) {\n sections.splice(2, 0, {\n id: \"policy\",\n title: \"Policy\",\n options: Array.from(policyCounts.entries()).map(([name, count]) => ({\n value: name,\n label: name,\n count,\n })),\n collapsed: policyCounts.size > 5,\n });\n }\n\n return sections;\n }, [allProducts, getPolicyForProduct, getAuthSchemes, canListPlanPolicies]);\n\n const filteredProducts = useMemo(() => {\n return allProducts.filter((p: KuadrantResource) => {\n if (filters.status.length > 0) {\n const status = p.spec?.publishStatus || \"Draft\";\n if (!filters.status.includes(status)) return false;\n }\n\n if (filters.lifecycle && filters.lifecycle.length > 0) {\n const lifecycle = p.metadata.labels?.lifecycle || \"production\";\n if (!filters.lifecycle.includes(lifecycle)) return false;\n }\n\n if (filters.authentication.length > 0) {\n const authSchemes = getAuthSchemes(p);\n if (!filters.authentication.some((a: string) => authSchemes.includes(a))) return false;\n }\n\n if (filters.policy.length > 0) {\n const policy = getPolicyForProduct(p) || \"N/A\";\n if (!filters.policy.includes(policy)) return false;\n }\n\n if (filters.route.length > 0) {\n const route = p.spec?.targetRef?.name || \"unknown\";\n if (!filters.route.includes(route)) return false;\n }\n\n if (filters.namespace.length > 0) {\n if (!filters.namespace.includes(p.metadata.namespace)) return false;\n }\n\n if (filters.tags.length > 0) {\n const tags = p.spec?.tags || [];\n if (!filters.tags.some((t: string) => tags.includes(t))) return false;\n }\n\n return true;\n });\n }, [allProducts, filters, getPolicyForProduct, getAuthSchemes]);\n\n const handleCreateSuccess = (productInfo: { namespace: string; name: string; displayName: string }) => {\n setRefreshTrigger((prev) => prev + 1);\n alertApi.post({\n message: `\"${productInfo.displayName}\" created successfully`,\n severity: \"success\",\n display: \"transient\",\n });\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 const productName = apiProductToEdit?.name || \"API Product\";\n alertApi.post({\n message: `\"${productName}\" updated successfully`,\n severity: \"success\",\n display: \"transient\",\n });\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(\n `${backendUrl}/api/kuadrant/requests?namespace=${namespace}`,\n );\n\n if (!response.ok) {\n const error = await handleFetchError(response);\n throw new Error(error);\n }\n\n const data = await response.json();\n const related = (data.items || []).filter(\n (r: any) =>\n r.spec.apiName === name && r.spec.apiNamespace === namespace,\n );\n const approved = related.filter(\n (r: any) => r.status?.phase === \"Approved\",\n ).length;\n setDeleteStats({ requests: related.length, secrets: approved });\n } catch (err) {\n const errorMessage =\n err instanceof Error ? err.message : \"unknown error occurred\";\n alertApi.post({\n message: `Failed to delete access request: ${errorMessage}`,\n severity: \"error\",\n display: \"transient\",\n });\n } finally {\n setDeleteDialogOpen(true);\n }\n\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 const error = await handleFetchError(response);\n throw new Error(error);\n }\n\n const deletedName = apiProductToDelete?.name || \"API Product\";\n setRefreshTrigger((prev) => prev + 1);\n alertApi.post({\n message: `\"${deletedName}\" deleted successfully`,\n severity: \"success\",\n display: \"transient\",\n });\n } catch (err) {\n const errorMessage =\n err instanceof Error ? err.message : \"unknown error occurred\";\n alertApi.post({\n message: `Failed to delete API Product: ${errorMessage}`,\n severity: \"error\",\n display: \"transient\",\n });\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 handlePublishToggle = async (row: any) => {\n const namespace = row.metadata.namespace;\n const name = row.metadata.name;\n const displayName = row.spec?.displayName || name;\n const currentStatus = row.spec?.publishStatus || \"Draft\";\n const newStatus = currentStatus === \"Published\" ? \"Draft\" : \"Published\";\n const lifecycle = row.metadata.labels?.lifecycle;\n\n // prevent publishing retired APIs\n if (newStatus === \"Published\" && lifecycle === \"retired\") {\n alertApi.post({\n message: `Cannot publish a retired API product. Please change the lifecycle status first.`,\n severity: \"error\",\n display: \"transient\",\n });\n return;\n }\n\n try {\n const response = await fetchApi.fetch(\n `${backendUrl}/api/kuadrant/apiproducts/${namespace}/${name}`,\n {\n method: \"PATCH\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({\n spec: { publishStatus: newStatus },\n }),\n },\n );\n\n if (!response.ok) {\n const error = await handleFetchError(response);\n throw new Error(error);\n }\n\n setRefreshTrigger((prev) => prev + 1);\n alertApi.post({\n message: `\"${displayName}\" ${newStatus === \"Published\" ? \"published\" : \"unpublished\"} successfully`,\n severity: \"success\",\n display: \"transient\",\n });\n } catch (err) {\n const errorMessage =\n err instanceof Error ? err.message : \"unknown error occurred\";\n alertApi.post({\n message: `Failed to update publish status: ${errorMessage}`,\n severity: \"error\",\n display: \"transient\",\n });\n }\n };\n\n const columns: TableColumn[] = [\n {\n title: \"Name\",\n field: \"spec.displayName\",\n render: (row: any) => {\n const displayName = row.spec?.displayName ?? row.metadata.name;\n return (\n <Link to={`/kuadrant/api-products/${row.metadata.namespace}/${row.metadata.name}`}>\n <strong>{displayName}</strong>\n </Link>\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: \"Version\",\n field: \"spec.version\",\n render: (row: any) => row.spec?.version || \"-\",\n },\n {\n title: \"Route\",\n field: \"spec.targetRef.name\",\n render: (row: any) => row.spec?.targetRef?.name || \"-\",\n },\n // only show policy column if user can list planpolicies\n ...(canListPlanPolicies\n ? [\n {\n title: \"Policy\",\n field: \"policy\",\n render: (row: any) => getPolicyForProduct(row) || \"N/A\",\n },\n ]\n : []),\n {\n title: \"Tags\",\n field: \"spec.tags\",\n render: (row: any) => {\n const tags = row.spec?.tags || [];\n if (tags.length === 0) return \"-\";\n return (\n <Box display=\"flex\" style={{ gap: 4, flexWrap: \"wrap\" }}>\n {tags.map((tag: string) => (\n <Chip key={tag} label={tag} size=\"small\" variant=\"outlined\" />\n ))}\n </Box>\n );\n },\n },\n {\n title: \"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: \"Lifecycle\",\n field: \"metadata.labels.lifecycle\",\n render: (row: any) => {\n const lifecycle = row.metadata.labels?.lifecycle;\n if (!lifecycle) return \"-\";\n return (\n <Chip\n label={lifecycle.charAt(0).toUpperCase() + lifecycle.slice(1)}\n size=\"small\"\n style={getLifecycleChipStyle(lifecycle)}\n />\n );\n },\n },\n {\n title: \"Authentication\",\n field: \"status.discoveredAuthScheme\",\n render: (row: any) => {\n const authSchemes =\n row.status?.discoveredAuthScheme?.authentication || {};\n const schemeObjects = Object.values(authSchemes);\n\n const hasApiKey = schemeObjects.some((scheme: any) =>\n scheme.hasOwnProperty(\"apiKey\"),\n );\n const hasJwt = schemeObjects.some((scheme: any) =>\n scheme.hasOwnProperty(\"jwt\"),\n );\n\n if (!hasApiKey && !hasJwt) {\n return (\n <Typography variant=\"body2\" style={{ fontStyle: \"italic\" }}>\n unknown\n </Typography>\n );\n }\n\n return (\n <Box display=\"flex\" style={{ gap: 4 }}>\n {hasApiKey && (\n <Chip\n icon={<VpnKeyIcon />}\n label=\"API Key\"\n size=\"small\"\n color=\"primary\"\n />\n )}\n {hasJwt && (\n <Chip\n icon={<LockIcon />}\n label=\"OIDC\"\n size=\"small\"\n color=\"secondary\"\n />\n )}\n </Box>\n );\n },\n },\n {\n title: \"Namespace\",\n field: \"metadata.namespace\",\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 =\n canUpdateAllApiProducts || (canUpdateOwnApiProduct && isOwner);\n const canDelete =\n canDeleteAllApiProducts || (canDeleteOwnApiProduct && isOwner);\n const isPublished = row.spec?.publishStatus === \"Published\";\n\n return (\n <Box display=\"flex\" alignItems=\"center\" style={{ gap: 4 }}>\n {canEdit && (\n <Button\n size=\"small\"\n color=\"primary\"\n onClick={() => handlePublishToggle(row)}\n style={{ marginRight: 4, textTransform: \"none\" }}\n >\n {isPublished ? \"Unpublish\" : \"Publish\"}\n </Button>\n )}\n {canEdit && (\n <IconButton\n size=\"small\"\n onClick={() =>\n handleEditClick(row.metadata.namespace, row.metadata.name)\n }\n title=\"Edit API Product\"\n >\n <EditIcon fontSize=\"small\" />\n </IconButton>\n )}\n {canDelete && (\n <IconButton\n size=\"small\"\n onClick={() =>\n handleDeleteClick(row.metadata.namespace, row.metadata.name)\n }\n title=\"Delete API Product\"\n >\n <DeleteIcon fontSize=\"small\" />\n </IconButton>\n )}\n </Box>\n );\n },\n },\n ];\n\n return (\n <Page themeId=\"tool\">\n <Header\n title=\"API Products\"\n subtitle=\"Manage API products for Kubernetes\"\n >\n <SupportButton>Manage API products and plan policies</SupportButton>\n </Header>\n <Content>\n {loading && (\n <Box\n display=\"flex\"\n flexDirection=\"column\"\n alignItems=\"center\"\n justifyContent=\"center\"\n minHeight={300}\n >\n <CircularProgress />\n <Typography variant=\"h6\" style={{ marginTop: 16 }}>\n Loading data...\n </Typography>\n <Typography variant=\"body2\" color=\"textSecondary\">\n Preparing your data... This should only take a moment.\n </Typography>\n </Box>\n )}\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:{\" \"}\n {createPermissionError\n ? \"kuadrant.apiproduct.create\"\n : deletePermissionError\n ? \"kuadrant.apiproduct.delete\"\n : planPolicyPermissionError\n ? \"kuadrant.planpolicy.list\"\n : \"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 && allProducts.length === 0 && (\n <Box className={classes.emptyState}>\n <Box className={classes.emptyStateContent}>\n <Box className={classes.emptyStateText}>\n <Typography variant=\"h4\" className={classes.emptyStateTitle}>\n API Product\n </Typography>\n <Typography\n variant=\"body1\"\n className={classes.emptyStateDescription}\n >\n Create API product by registering existing API, associate\n route and policy\n </Typography>\n {canCreateApiProduct && (\n <Button\n variant=\"contained\"\n color=\"primary\"\n startIcon={<AddIcon />}\n onClick={() => setCreateDialogOpen(true)}\n >\n Create API Product\n </Button>\n )}\n </Box>\n <img\n src={emptyStateIllustration}\n alt=\"API Product illustration\"\n className={classes.emptyStateImage}\n />\n </Box>\n </Box>\n )}\n {!loading && !error && !permissionError && allProducts.length > 0 && (\n <Box className={classes.container}>\n <FilterPanel\n sections={filterSections}\n filters={filters}\n onChange={setFilters}\n />\n <Box className={classes.tableContainer}>\n <Box display=\"flex\" justifyContent=\"flex-end\" mb={2}>\n {canCreateApiProduct && (\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 )}\n </Box>\n {filteredProducts.length === 0 ? (\n <Box p={4} textAlign=\"center\">\n <Typography variant=\"body1\" color=\"textSecondary\">\n No API products match the selected filters.\n </Typography>\n </Box>\n ) : (\n <Table\n options={{\n paging: filteredProducts.length > 10,\n pageSize: 20,\n search: true,\n filtering: false,\n debounceInterval: 300,\n toolbar: true,\n emptyRowsWhenPaging: false,\n }}\n columns={columns}\n data={filteredProducts}\n />\n )}\n </Box>\n </Box>\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(s)\n• ${deleteStats.secrets} API Key Secret(s)\n\nThis action cannot be undone.`\n : `Deleting \"${apiProductToDelete?.name}\" will also remove all associated API Keys 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 ApiProductsPage = () => {\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":["useStyles","makeStyles","theme","root","width","minWidth","padding","spacing","borderRight","palette","divider","backgroundColor","background","paper","height","overflowY","sectionTitle","fontWeight","fontSize","textTransform","letterSpacing","color","text","secondary","marginBottom","display","alignItems","justifyContent","cursor","userSelect","filterSection","checkbox","checkboxLabel","clearButton","marginTop","count","marginLeft","FilterPanel","sections","filters","onChange","onClear","classes","collapsedSections","setCollapsedSections","React","Set","filter","s","collapsed","map","id","hasActiveFilters","Object","values","some","length","Box","className","mb","Typography","variant","Button","size","onClick","clearedFilters","forEach","section","Divider","isCollapsed","has","selectedCount","mt","toggleSection","sectionId","prev","next","delete","add","span","title","ExpandMoreIcon","ExpandLessIcon","Collapse","in","FormGroup","options","option","FormControlLabel","control","Checkbox","checked","includes","value","currentValues","newValues","v","handleCheckboxChange","label","undefined","PermissionGate","children","permission","fallback","errorMessage","allowed","loading","error","useKuadrantPermission","Progress","p","message","name","asterisk","sectionHeader","gap","infoIcon","tagChip","marginRight","CreateAPIProductDialog","open","onClose","onSuccess","config","useApi","configApiRef","fetchApi","fetchApiRef","backendUrl","getString","setName","useState","displayName","setDisplayName","description","setDescription","version","setVersion","approvalMode","setApprovalMode","publishStatus","setPublishStatus","lifecycle","setLifecycle","tags","setTags","tagInput","setTagInput","selectedHTTPRoute","setSelectedHTTPRoute","contactEmail","setContactEmail","contactTeam","setContactTeam","docsURL","setDocsURL","openAPISpec","setOpenAPISpec","setError","creating","setCreating","httpRoutesRetry","setHttpRoutesRetry","nameError","setNameError","openAPISpecError","setOpenAPISpecError","routeSearchTerm","setRouteSearchTerm","routeSearchField","setRouteSearchField","httpRoutes","httpRoutesLoading","httpRoutesError","useAsync","async","response","fetch","ok","handleFetchError","Error","json","items","planPolicies","planPoliciesError","getPlanPolicyForRoute","routeNamespace","routeName","find","pp","ref","targetRef","kind","namespace","selectedRouteInfo","split","selectedPolicy","getPolicyInfoForRoute","policy","metadata","spec","plans","tiers","entries","plan","limit","limits","requests","period","join","formatTierInfo","useEffect","handleAddTag","trim","handleClose","hasValidationErrors","Dialog","maxWidth","fullWidth","DialogTitle","DialogContent","Alert","severity","style","strong","Grid","container","item","xs","TextField","e","match","autoName","toLowerCase","replace","Math","floor","random","toString","padStart","validateKubernetesName","handleDisplayNameChange","target","placeholder","helperText","margin","required","disabled","InputLabelProps","handleNameChange","onKeyPress","key","preventDefault","InputProps","endAdornment","InputAdornment","position","IconButton","AddIcon","flexWrap","tag","Chip","onDelete","handleDeleteTag","tagToDelete","multiline","rows","Tooltip","InfoOutlinedIcon","handleOpenAPISpecChange","validateURL","select","SelectProps","MenuProps","PaperProps","maxHeight","anchorOrigin","vertical","horizontal","transformOrigin","getContentAnchorEl","px","pt","pb","top","zIndex","onKeyDown","stopPropagation","MenuItem","route","routeNs","policyInfo","searchLower","PlanPolicyDetails","discoveredPlans","alertSeverity","alertMessage","includeTopMargin","FormControl","component","RadioGroup","row","Radio","DialogActions","selectedRouteNamespace","selectedRouteName","apiProduct","apiVersion","labels","group","contact","email","team","documentation","openAPISpecURL","method","headers","body","JSON","stringify","err","String","startIcon","CircularProgress","minHeight","tableContainer","flex","overflow","emptyState","emptyStateContent","emptyStateText","emptyStateTitle","emptyStateDescription","emptyStateImage","ResourceList","alertApi","alertApiRef","identityApi","identityApiRef","userEntityRef","setUserEntityRef","createDialogOpen","setCreateDialogOpen","editDialogOpen","setEditDialogOpen","refreshTrigger","setRefreshTrigger","deleteDialogOpen","setDeleteDialogOpen","apiProductToDelete","setApiProductToDelete","apiProductToEdit","setApiProductToEdit","deleting","setDeleting","deleteStats","setDeleteStats","setFilters","status","authentication","canCreateApiProduct","createPermissionLoading","createPermissionError","kuadrantApiProductCreatePermission","canDeleteOwnApiProduct","deleteOwnPermissionLoading","kuadrantApiProductDeleteOwnPermission","canDeleteAllApiProducts","deleteAllPermissionLoading","deletePermissionError","kuadrantApiProductDeleteAllPermission","canUpdateOwnApiProduct","kuadrantApiProductUpdateOwnPermission","canUpdateAllApiProducts","kuadrantApiProductUpdateAllPermission","deletePermissionLoading","canListPlanPolicies","planPolicyPermissionLoading","planPolicyPermissionError","kuadrantPlanPolicyListPermission","identity","getBackstageIdentity","apiProducts","apiProductsLoading","apiProductsError","planPoliciesLoading","getPolicyForProduct","useCallback","product","getAuthSchemes","authSchemes","discoveredAuthScheme","schemeObjects","schemes","scheme","hasOwnProperty","push","permissionError","allProducts","useMemo","products","filterSections","statusCounts","Draft","Published","lifecycleCounts","Map","policyCounts","routeCounts","namespaceCounts","tagCounts","authCounts","set","get","ns","Array","from","state","charAt","toUpperCase","slice","splice","filteredProducts","a","t","columns","field","render","Link","to","customFilterAndSearch","term","getLifecycleChipStyle","hasApiKey","hasJwt","icon","VpnKeyIcon","LockIcon","fontStyle","filtering","isOwner","annotations","canEdit","canDelete","isPublished","newStatus","post","handlePublishToggle","handleEditClick","EditIcon","related","r","apiName","apiNamespace","approved","phase","secrets","handleDeleteClick","DeleteIcon","Page","themeId","Header","subtitle","SupportButton","Content","flexDirection","ResponseErrorPanel","img","src","emptyStateIllustration","alt","textAlign","Table","paging","pageSize","search","debounceInterval","toolbar","emptyRowsWhenPaging","data","productInfo","EditAPIProductDialog","productName","ConfirmDeleteDialog","confirmText","onConfirm","deletedName","onCancel","ApiProductsPage","kuadrantApiProductListPermission"],"sourceRoot":""}
@@ -0,0 +1,2 @@
1
+ "use strict";(self.webpackChunkinternal_plugin_kuadrant=self.webpackChunkinternal_plugin_kuadrant||[]).push([[7270],{5030:(e,t,a)=>{Object.defineProperty(t,"__esModule",{value:!0});var n=a(85608),s=a(95478),r=n.__importDefault(a(10009));t.default=function(e,t,a){void 0===t&&(t=[]),void 0===a&&(a={loading:!1});var i=s.useRef(0),l=r.default(),o=s.useState(a),c=o[0],d=o[1],u=s.useCallback(function(){for(var t=[],a=0;a<arguments.length;a++)t[a]=arguments[a];var s=++i.current;return c.loading||d(function(e){return n.__assign(n.__assign({},e),{loading:!0})}),e.apply(void 0,t).then(function(e){return l()&&s===i.current&&d({value:e,loading:!1}),e},function(e){return l()&&s===i.current&&d({error:e,loading:!1}),e})},t);return[c,u]}},10009:(e,t,a)=>{Object.defineProperty(t,"__esModule",{value:!0});var n=a(95478);t.default=function(){var e=n.useRef(!1),t=n.useCallback(function(){return e.current},[]);return n.useEffect(function(){return e.current=!0,function(){e.current=!1}},[]),t}},12229:(e,t,a)=>{a.d(t,{Z:()=>v});var n=a(31085),s=a(95478),r=a.n(s),i=a(10394),l=a(72501),o=a(64947),c=a(37197),d=a(69621),u=a(12981),p=a(86901),m=a(69076),h=a(58837),f=a(6924),A=a(23164);const g=(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)}})),v=({sections:e,filters:t,onChange:a,onClear:s})=>{const h=g(),[v,x]=r().useState(new Set(e.filter(e=>e.collapsed).map(e=>e.id))),y=Object.values(t).some(e=>e.length>0);return(0,n.jsxs)(i.A,{className:h.root,children:[(0,n.jsxs)(i.A,{display:"flex",justifyContent:"space-between",alignItems:"center",mb:2,children:[(0,n.jsx)(l.A,{variant:"subtitle2",children:"Filters"}),y&&(0,n.jsx)(o.A,{size:"small",color:"primary",onClick:()=>{const t={};e.forEach(e=>{t[e.id]=[]}),a(t),null==s||s()},children:"Clear all"})]}),(0,n.jsx)(c.A,{}),e.map(e=>{const s=v.has(e.id),r=(t[e.id]||[]).length;return(0,n.jsxs)(i.A,{className:h.filterSection,mt:2,children:[(0,n.jsxs)(i.A,{className:h.sectionTitle,onClick:()=>{return t=e.id,void x(e=>{const a=new Set(e);return a.has(t)?a.delete(t):a.add(t),a});var t},children:[(0,n.jsxs)(i.A,{display:"flex",alignItems:"center",children:[(0,n.jsx)("span",{children:e.title}),r>0&&(0,n.jsxs)("span",{className:h.count,children:["(",r,")"]})]}),s?(0,n.jsx)(f.A,{fontSize:"small"}):(0,n.jsx)(A.A,{fontSize:"small"})]}),(0,n.jsx)(d.A,{in:!s,children:(0,n.jsx)(u.A,{children:e.options.map(s=>(0,n.jsx)(p.A,{control:(0,n.jsx)(m.A,{checked:(t[e.id]||[]).includes(s.value),onChange:()=>((e,n)=>{const s=t[e]||[],r=s.includes(n)?s.filter(e=>e!==n):[...s,n];a({...t,[e]:r})})(e.id,s.value),size:"small",className:h.checkbox,color:"primary"}),label:(0,n.jsxs)(i.A,{display:"flex",alignItems:"center",children:[(0,n.jsx)("span",{className:h.checkboxLabel,children:s.label}),void 0!==s.count&&(0,n.jsxs)("span",{className:h.count,children:["(",s.count,")"]})]})},s.value))})})]},e.id)})]})}},16397:(e,t,a)=>{a.d(t,{e:()=>y});var n=a(31085),s=a(95478),r=a(76891),i=a(61477),l=a(46805),o=a(10394),c=a(72501),d=a(95061),u=a(48543),p=a(81215),m=a(26343),h=a(16249),f=a(93453),A=a(64947),g=a(78467),v=a(22097),x=a(77318);const y=({open:e,onClose:t,onSuccess:a,request:y,availablePlans:j})=>{const b=(0,v.useApi)(v.configApiRef),k=(0,v.useApi)(v.fetchApiRef),w=b.getString("backend.baseUrl"),[S,C]=(0,s.useState)(""),[P,I]=(0,s.useState)(""),[$,q]=(0,s.useState)(!1),[R,z]=(0,s.useState)("");(0,s.useEffect)(()=>{e&&y&&(C(y.spec.planTier||""),I(y.spec.useCase||""),z(""))},[e,y]);const T=()=>{$||(z(""),t())};return(0,n.jsxs)(r.A,{open:e,onClose:T,maxWidth:"sm",fullWidth:!0,children:[(0,n.jsx)(i.A,{children:"Edit API Key"}),(0,n.jsxs)(l.A,{children:[R&&(0,n.jsx)(o.A,{mb:2,p:2,bgcolor:"error.main",color:"error.contrastText",borderRadius:1,children:(0,n.jsx)(c.A,{variant:"body2",children:R})}),(0,n.jsxs)(d.A,{fullWidth:!0,margin:"normal",children:[(0,n.jsx)(u.A,{children:"Tier"}),(0,n.jsx)(p.A,{value:S,onChange:e=>C(e.target.value),disabled:$,children:j.map(e=>{const t=Object.entries(e.limits||{}).map(([e,t])=>`${t} per ${e}`).join(", ");return(0,n.jsxs)(m.A,{value:e.tier,children:[e.tier," ",t?`(${t})`:""]},e.tier)})})]}),(0,n.jsx)(h.A,{label:"Use Case",placeholder:"Describe how you plan to use this API",multiline:!0,rows:3,fullWidth:!0,margin:"normal",value:P,onChange:e=>I(e.target.value),disabled:$,helperText:"Explain your intended use of this API for admin review"})]}),(0,n.jsxs)(f.A,{children:[(0,n.jsx)(A.A,{onClick:T,disabled:$,children:"Cancel"}),(0,n.jsx)(A.A,{onClick:async()=>{if(S){z(""),q(!0);try{const e={spec:{planTier:S,useCase:P.trim()}},n=await k.fetch(`${w}/api/kuadrant/requests/${y.metadata.namespace}/${y.metadata.name}`,{method:"PATCH",headers:{"Content-Type":"application/json"},body:JSON.stringify(e)});if(!n.ok){const e=await(0,x.T)(n);throw new Error(`Failed to update request: ${n.status}. ${e}`)}a(),t()}catch(e){console.error("Error updating API key request:",e),z(e instanceof Error?e.message:"Unknown error occurred")}finally{q(!1)}}else z("Please select a tier")},color:"primary",variant:"contained",disabled:!S||$,startIcon:$?(0,n.jsx)(g.A,{size:16,color:"inherit"}):void 0,children:$?"Saving...":"Save Changes"})]})]})}},23164:(e,t,a)=>{var n=a(4293),s=a(78920);t.A=void 0;var r=s(a(95478)),i=(0,n(a(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,a)=>{var n=a(4293),s=a(78920);t.A=void 0;var r=s(a(95478)),i=(0,n(a(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},32269:(e,t,a)=>{var n=a(4293),s=a(78920);t.A=void 0;var r=s(a(95478)),i=(0,n(a(74044)).default)(r.createElement("path",{d:"M12 4.5C7 4.5 2.73 7.61 1 12c1.73 4.39 6 7.5 11 7.5s9.27-3.11 11-7.5c-1.73-4.39-6-7.5-11-7.5zM12 17c-2.76 0-5-2.24-5-5s2.24-5 5-5 5 2.24 5 5-2.24 5-5 5zm0-8c-1.66 0-3 1.34-3 3s1.34 3 3 3 3-1.34 3-3-1.34-3-3-3z"}),"Visibility");t.A=i},37270:(e,t,a)=>{a.r(t),a.d(t,{MyApiKeysPage:()=>J});var n=a(31085),s=a(95478),r=a(289),i=a(15831),l=a(45210),o=a(46681),c=a(49634),d=a(37725),u=a(86687),p=a(42367),m=a(25010),h=a(22097),f=a(91638),A=a(58837),g=a(10394),v=a(72501),x=a(67720),y=a(71677),j=a(29365),b=a(78467),k=a(64947),w=a(37757),S=a(26343),C=a(76891),P=a(61477),I=a(46805),$=a(93453),q=a(95061),R=a(48543),z=a(81215),T=a(51253),E=a(16249);const M=({open:e,onClose:t,onSuccess:a})=>{var r;const i=(0,h.useApi)(h.configApiRef),l=(0,h.useApi)(h.fetchApiRef),o=(0,h.useApi)(h.alertApiRef),c=(0,h.useApi)(h.identityApiRef),d=i.getString("backend.baseUrl"),[u,p]=(0,s.useState)(""),[m,A]=(0,s.useState)(""),[g,x]=(0,s.useState)(""),[y,j]=(0,s.useState)(!1),{value:w,loading:M}=(0,f.A)(async()=>{if(!e)return[];const t=await l.fetch(`${d}/api/kuadrant/apiproducts`);if(!t.ok)throw new Error("Failed to fetch API products");return((await t.json()).items||[]).filter(e=>{var t;return"Published"===(null===(t=e.spec)||void 0===t?void 0:t.publishStatus)})},[d,l,e]),{value:N}=(0,f.A)(async()=>`${(await c.getBackstageIdentity()).userEntityRef.split("/")[1]||"unknown"}@example.com`,[c]),B=null==w?void 0:w.find(e=>`${e.metadata.namespace}/${e.metadata.name}`===u),W=(null==B||null===(r=B.status)||void 0===r?void 0:r.discoveredPlans)||[],_=()=>{p(""),A(""),x(""),t()};return(0,n.jsxs)(C.A,{open:e,onClose:_,maxWidth:"sm",fullWidth:!0,children:[(0,n.jsx)(P.A,{children:"Request API key"}),(0,n.jsxs)(I.A,{children:[(0,n.jsx)(v.A,{variant:"body2",color:"textSecondary",children:"Submit your request to generate an API key."}),(0,n.jsxs)(q.A,{fullWidth:!0,margin:"normal",disabled:y||M,children:[(0,n.jsx)(R.A,{id:"api-select-label",required:!0,children:"API"}),(0,n.jsx)(z.A,{labelId:"api-select-label",value:u,onChange:e=>{p(e.target.value),A("")},disabled:y||M,"data-testid":"api-select",children:M?(0,n.jsx)(S.A,{disabled:!0,children:"Loading..."}):null==w?void 0:w.map(e=>(0,n.jsx)(S.A,{value:`${e.metadata.namespace}/${e.metadata.name}`,children:e.metadata.name},`${e.metadata.namespace}/${e.metadata.name}`))}),(0,n.jsx)(T.A,{children:"Select one API. Please submit separate requests for multiple APIs."})]}),(0,n.jsxs)(q.A,{fullWidth:!0,margin:"normal",disabled:y||!u,required:!0,children:[(0,n.jsx)(R.A,{id:"tier-select-label",children:"Tiers"}),(0,n.jsx)(z.A,{labelId:"tier-select-label",value:m,onChange:e=>A(e.target.value),disabled:y||!u,"data-testid":"tier-select",children:u?0===W.length?(0,n.jsx)(S.A,{disabled:!0,children:"No tiers available"}):W.map(e=>{const t=Object.entries(e.limits||{}).map(([e,t])=>`${t} per ${e}`).join(", ");return(0,n.jsxs)(S.A,{value:e.tier,children:[e.tier," ",t?`(${t})`:""]},e.tier)}):(0,n.jsx)(S.A,{disabled:!0,children:"Select an API first"})}),(0,n.jsx)(T.A,{children:"Select an API to view available tiers."})]}),(0,n.jsx)(E.A,{label:"Use case",placeholder:"Briefly describe your specific use case of using this API key",multiline:!0,rows:2,fullWidth:!0,margin:"normal",value:g,onChange:e=>x(e.target.value),disabled:y,inputProps:{"data-testid":"usecase-input"}})]}),(0,n.jsxs)($.A,{children:[(0,n.jsx)(k.A,{onClick:_,disabled:y,"data-testid":"cancel-button",children:"Cancel"}),(0,n.jsx)(k.A,{onClick:async()=>{if(!u||!m)return;const[e,t]=u.split("/");j(!0);try{const n=await l.fetch(`${d}/api/kuadrant/requests`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({apiProductName:t,namespace:e,planTier:m,useCase:g.trim()||"",userEmail:N||"unknown"})});if(!n.ok){let a;try{a=await n.json()}catch{a={error:`Server returned ${n.status} ${n.statusText}`}}console.error("Backend error response:",{status:n.status,statusText:n.statusText,errorData:a,requestBody:{apiProductName:t,namespace:e,planTier:m,useCase:g.trim()||"",userEmail:N||"unknown"}});const s=a.error||a.message||`Server returned ${n.status}`;let r=s;if(s.includes("spec.requestedBy.email"))r="Invalid email format. Please contact your administrator to update your profile email.";else if(s.includes("is invalid:")){const e=s.match(/is invalid: (.+?)(?:\s+\(|$)/);e&&(r=`Validation error: ${e[1]}`)}else 403===n.status?r="You do not have permission to request access to this API.":404===n.status?r="The selected API or tier was not found.":n.status>=500&&(r=`Server error: ${s}`);throw new Error(r)}o.post({message:"API key requested successfully",severity:"success",display:"transient"}),_(),a()}catch(e){const t=e instanceof Error?e.message:"unknown error occurred";console.error("Failed to create API key request:",{error:e,selectedApi:u,selectedTier:m,userEmail:N}),o.post({message:`Failed to request API key: ${t}`,severity:"error",display:"permanent"})}finally{j(!1)}},color:"primary",variant:"contained",disabled:!u||!m||y,startIcon:y?(0,n.jsx)(b.A,{size:16,color:"inherit"}):void 0,"data-testid":"submit-button",children:y?"Submitting...":"Request"})]})]})};var N=a(32269),B=a(61524),W=a(99594),_=a(77225),O=a(39590),F=a(16397),L=a(63221),D=a(12229),K=a(46299),V=a(77318);const U=(0,A.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)}})),H=({request:e})=>{var t,a;const s=U(),r="Rejected"===(null===(t=e.status)||void 0===t?void 0:t.phase),i=(null===(a=e.spec.apiProductRef)||void 0===a?void 0:a.name)||"unknown";return(0,n.jsxs)(g.A,{className:s.useCasePanel,onClick:e=>e.stopPropagation(),children:[r&&(0,n.jsxs)(g.A,{className:s.rejectedBanner,children:[(0,n.jsx)(_.A,{color:"error",fontSize:"small"}),(0,n.jsxs)(v.A,{variant:"body2",children:["This API key was rejected."," ",(0,n.jsx)(d.N_,{to:`/catalog/default/api/${i}/api-keys`,children:"Request a new API key"})]})]}),(0,n.jsx)(v.A,{className:s.useCaseLabel,children:"Use Case"}),(0,n.jsx)(v.A,{variant:"body2",children:e.spec.useCase||"No use case provided"})]})},Y=()=>{var e,t;const a=U(),r=(0,c.useNavigate)(),i=(0,h.useApi)(h.configApiRef),l=(0,h.useApi)(h.fetchApiRef),o=(0,h.useApi)(h.alertApiRef),A=i.getString("backend.baseUrl"),[q,R]=(0,s.useState)(!1),[z,T]=(0,s.useState)(new Set),[E,Y]=(0,s.useState)(null),[J,Z]=(0,s.useState)(null),[X,G]=(0,s.useState)({open:!1,request:null,plans:[]}),[Q,ee]=(0,s.useState)(0),[te,ae]=(0,s.useState)(null),[ne,se]=(0,s.useState)({open:!1,request:null}),[re,ie]=(0,s.useState)(new Map),[le,oe]=(0,s.useState)(new Set),[ce,de]=(0,s.useState)(new Set),[ue,pe]=(0,s.useState)(!1),[me,he]=(0,s.useState)(null),[fe,Ae]=(0,s.useState)(new Set),[ge,ve]=(0,s.useState)({status:[],apiProduct:[],tier:[]}),{value:xe,loading:ye,error:je}=(0,f.A)(async()=>{const[e,t]=await Promise.all([l.fetch(`${A}/api/kuadrant/requests/my`),l.fetch(`${A}/api/kuadrant/apiproducts`)]);if(!e.ok)throw new Error("failed to fetch requests");const a=(await e.json()).items||[];let n=[];t.ok&&(n=(await t.json()).items||[]);const s=new Map;return n.forEach(e=>{var t;const a=`${e.metadata.namespace}/${e.metadata.name}`,n=(null===(t=e.metadata.annotations)||void 0===t?void 0:t["backstage.io/owner"])||"unknown";s.set(a,n)}),{requests:a,products:n,ownerMap:s}},[A,l,Q]),be=(0,s.useMemo)(()=>(null==xe?void 0:xe.requests)?xe.requests.filter(e=>!fe.has(e.metadata.name)):[],[null==xe?void 0:xe.requests,fe]),ke=(0,s.useMemo)(()=>{const e={Approved:0,Pending:0,Rejected:0},t=new Map,a=new Map;return be.forEach(n=>{var s,r;const i=(null===(s=n.status)||void 0===s?void 0:s.phase)||"Pending";e[i]++;const l=(null===(r=n.spec.apiProductRef)||void 0===r?void 0:r.name)||"unknown";t.set(l,(t.get(l)||0)+1);const o=n.spec.planTier||"unknown";a.set(o,(a.get(o)||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(a.entries()).map(([e,t])=>({value:e,label:e.charAt(0).toUpperCase()+e.slice(1),count:t}))}]},[be]),we=(0,s.useMemo)(()=>be.filter(e=>{if(ge.status.length>0){var t;const a=(null===(t=e.status)||void 0===t?void 0:t.phase)||"Pending";if(!ge.status.includes(a))return!1}if(ge.apiProduct.length>0){var a;const t=(null===(a=e.spec.apiProductRef)||void 0===a?void 0:a.name)||"unknown";if(!ge.apiProduct.includes(t))return!1}if(ge.tier.length>0){const t=e.spec.planTier||"unknown";if(!ge.tier.includes(t))return!1}return!0}),[be,ge]),Se=e=>{T(t=>{const a=new Set(t);return a.has(e)?a.delete(e):a.add(e),a})},Ce=()=>{Y(null),Z(null)},Pe=async()=>{if(!J)return;const e=J;Ce();try{var t;const n=null===(t=e.spec.apiProductRef)||void 0===t?void 0:t.name,s=e.metadata.namespace,r=await l.fetch(`${A}/api/kuadrant/apiproducts/${s}/${n}`);if(r.ok){var a;const t=(null===(a=(await r.json()).spec)||void 0===a?void 0:a.plans)||[];G({open:!0,request:e,plans:t})}else G({open:!0,request:e,plans:[]})}catch(t){console.error("Error fetching plans:",t),G({open:!0,request:e,plans:[]});const a=t instanceof Error?t.message:"unknown error occurred";o.post({message:`Failed to fetch Plans. ${a}`,severity:"error",display:"transient"})}},Ie=()=>{if(!J)return;const e=J;Ce(),se({open:!0,request:e})},$e=[{title:"API Product",field:"spec.apiProductRef.name",render:e=>{var t;const a=(null===(t=e.spec.apiProductRef)||void 0===t?void 0:t.name)||"unknown";return(0,n.jsx)(d.N_,{to:`/catalog/default/api/${a}/api-keys`,children:(0,n.jsx)("strong",{children:a})})}},{title:"Owner",field:"owner",render:e=>{var t,a;const s=`${e.metadata.namespace}/${null===(t=e.spec.apiProductRef)||void 0===t?void 0:t.name}`,r=((null==xe||null===(a=xe.ownerMap)||void 0===a?void 0:a.get(s))||"unknown").replace(/^user:default\//,"");return(0,n.jsx)(v.A,{variant:"body2",children:r})}},{title:"Status",field:"status.phase",render:e=>{var t;const a=(null===(t=e.status)||void 0===t?void 0:t.phase)||"Pending",s="Approved"===a?"Active":a;return(0,n.jsx)(x.A,{label:s,size:"small",style:(0,K.g9)(a)})}},{title:"Tier",field:"spec.planTier",render:e=>(0,n.jsx)(x.A,{label:e.spec.planTier,size:"small",variant:"outlined"})},{title:"API Key",field:"status.secretRef",filtering:!1,render:e=>{var t,a,s,r;if("Approved"!==(null===(t=e.status)||void 0===t?void 0:t.phase))return(0,n.jsx)(v.A,{variant:"body2",color:"textSecondary",children:"-"});const i=`${e.metadata.namespace}/${e.metadata.name}`,l=null===(s=e.status)||void 0===s||null===(a=s.secretRef)||void 0===a?void 0:a.name,c=z.has(e.metadata.name),d=le.has(i),u=re.get(i),p=!1!==(null===(r=e.status)||void 0===r?void 0:r.canReadSecret),m=ce.has(i)||!p;return l?m&&!u?(0,n.jsx)(y.Ay,{title:"This API key has already been viewed and cannot be retrieved again",children:(0,n.jsxs)(g.A,{display:"flex",alignItems:"center",children:[(0,n.jsx)(v.A,{variant:"body2",color:"textSecondary",style:{fontFamily:"monospace",marginRight:8},children:"Already viewed"}),(0,n.jsx)(B.A,{fontSize:"small",color:"disabled"})]})}):(0,n.jsxs)(g.A,{display:"flex",alignItems:"center",style:{gap:8},children:[(0,n.jsx)(g.A,{fontFamily:"monospace",fontSize:"0.875rem",children:d?"Loading...":c&&u?u:"•".repeat(20)+"..."}),c&&u&&(0,n.jsx)(y.Ay,{title:"Copy to clipboard",children:(0,n.jsx)(j.A,{size:"small",onClick:async()=>{u&&(await navigator.clipboard.writeText(u),o.post({message:"API key copied to clipboard",severity:"success",display:"transient"}))},children:(0,n.jsx)(W.A,{fontSize:"small"})})}),(0,n.jsx)(y.Ay,{title:c?"Hide API key":"Reveal API key (one-time only)",children:(0,n.jsx)("span",{children:(0,n.jsx)(j.A,{size:"small",onClick:()=>{c?(((e,t)=>{const a=`${e}/${t}`;ie(e=>{const t=new Map(e);return t.delete(a),t})})(e.metadata.namespace,e.metadata.name),Se(e.metadata.name)):m||(he({namespace:e.metadata.namespace,name:e.metadata.name}),pe(!0))},disabled:d||m&&!u,children:c?(0,n.jsx)(B.A,{fontSize:"small"}):(0,n.jsx)(N.A,{fontSize:"small"})})})})]}):(0,n.jsx)(v.A,{variant:"body2",color:"textSecondary",children:"Awaiting secret..."})}},{title:"Requested",field:"metadata.creationTimestamp",render:e=>{if(!e.metadata.creationTimestamp)return(0,n.jsx)(v.A,{variant:"body2",children:"-"});const t=new Date(e.metadata.creationTimestamp);return(0,n.jsx)(v.A,{variant:"body2",children:t.toLocaleDateString()})}},{title:"Actions",filtering:!1,width:"100px",render:e=>te===e.metadata.name?(0,n.jsx)(b.A,{size:20}):(0,n.jsxs)(g.A,{display:"flex",style:{gap:4},children:[(0,n.jsx)(y.Ay,{title:"View details",children:(0,n.jsx)(j.A,{size:"small",onClick:t=>{t.stopPropagation(),r(`/kuadrant/api-keys/${e.metadata.namespace}/${e.metadata.name}`)},children:(0,n.jsx)(N.A,{fontSize:"small"})})}),(0,n.jsx)(y.Ay,{title:"Delete",children:(0,n.jsx)(j.A,{size:"small",onClick:t=>{t.stopPropagation(),se({open:!0,request:e})},children:(0,n.jsx)(O.A,{fontSize:"small"})})})]})}],qe=(0,s.useMemo)(()=>[{render:e=>{var t;const a=e.rowData;return(null==a||null===(t=a.metadata)||void 0===t?void 0:t.name)?(0,n.jsx)(H,{request:a}):(0,n.jsx)(g.A,{})}}],[]);return ye?(0,n.jsx)(u.k,{}):je?(0,n.jsx)(p._,{error:je}):(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(g.A,{display:"flex",justifyContent:"flex-end",mb:2,px:2,children:(0,n.jsx)(k.A,{variant:"contained",color:"primary",onClick:()=>R(!0),"data-testid":"request-access-button",children:"Request Access"})}),(0,n.jsxs)(g.A,{className:a.container,children:[(0,n.jsx)(D.Z,{sections:ke,filters:ge,onChange:ve}),(0,n.jsx)(g.A,{className:a.tableContainer,children:0===be.length?(0,n.jsx)(g.A,{p:4,textAlign:"center",children:(0,n.jsx)(v.A,{variant:"body1",color:"textSecondary",gutterBottom:!0,children:"No API keys found. Request access to an API to get started."})}):0===we.length?(0,n.jsx)(g.A,{p:4,textAlign:"center",children:(0,n.jsx)(v.A,{variant:"body1",color:"textSecondary",children:"No API keys match the selected filters."})}):(0,n.jsx)(m.X,{options:{paging:we.length>10,pageSize:20,search:!0,filtering:!1,debounceInterval:300,toolbar:!0,emptyRowsWhenPaging:!1},columns:$e,data:we.map(e=>({...e,id:e.metadata.name})),detailPanel:qe})})]}),(0,n.jsx)(w.A,{id:"myapikeys-menu",open:Boolean(E),onClose:Ce,anchorReference:"anchorPosition",anchorPosition:E||{top:0,left:0},children:J&&(()=>{const e=[];var t;return e.push((0,n.jsx)(S.A,{onClick:()=>{r(`/kuadrant/api-keys/${J.metadata.namespace}/${J.metadata.name}`),Ce()},children:"View Details"},"view")),(t=J).status&&"Pending"!==t.status.phase||e.push((0,n.jsx)(S.A,{onClick:Pe,children:"Edit"},"edit")),e.push((0,n.jsx)(S.A,{onClick:Ie,children:"Delete"},"delete")),e})()}),X.request&&(0,n.jsx)(F.e,{open:X.open,request:X.request,availablePlans:X.plans,onClose:()=>G({open:!1,request:null,plans:[]}),onSuccess:()=>{G({open:!1,request:null,plans:[]}),ee(e=>e+1)}}),(0,n.jsx)(L.K,{open:ne.open,title:"Delete API Key",description:`Are you sure you want to delete this API key for ${(null===(t=ne.request)||void 0===t||null===(e=t.spec.apiProductRef)||void 0===e?void 0:e.name)||"this API"}?`,deleting:null!==te,onConfirm:async()=>{if(!ne.request)return;const e=ne.request,t=e.metadata.name;Ae(e=>new Set(e).add(t)),ae(t);try{const t=await l.fetch(`${A}/api/kuadrant/requests/${e.metadata.namespace}/${e.metadata.name}`,{method:"DELETE"});if(!t.ok){const e=await(0,V.T)(t);throw new Error(`Failed to delete request. ${e}`)}ee(e=>e+1),o.post({message:"API key deleted",severity:"success",display:"transient"}),se({open:!1,request:null})}catch(e){console.error("Error deleting request:",e),Ae(e=>{const a=new Set(e);return a.delete(t),a});const a=e instanceof Error?e.message:"unknown error occurred";o.post({message:`Failed to delete APIKey. ${a}`,severity:"error",display:"transient"})}finally{ae(null)}},onCancel:()=>{se({open:!1,request:null})}}),(0,n.jsxs)(C.A,{open:ue,onClose:()=>{pe(!1),he(null)},maxWidth:"sm",children:[(0,n.jsx)(P.A,{children:(0,n.jsxs)(g.A,{display:"flex",alignItems:"center",children:[(0,n.jsx)(_.A,{color:"primary",style:{marginRight:8}}),"View API Key"]})}),(0,n.jsxs)(I.A,{children:[(0,n.jsxs)(v.A,{variant:"body1",paragraph:!0,children:["This API key can only be viewed ",(0,n.jsx)("strong",{children:"once"}),". After you reveal it, you will not be able to retrieve it again."]}),(0,n.jsx)(v.A,{variant:"body2",color:"textSecondary",children:"Make sure to copy and store it securely before closing this view."})]}),(0,n.jsxs)($.A,{children:[(0,n.jsx)(k.A,{onClick:()=>{pe(!1),he(null)},children:"Cancel"}),(0,n.jsx)(k.A,{variant:"contained",color:"primary",onClick:()=>{me&&((async(e,t)=>{const a=`${e}/${t}`;if(!le.has(a)){oe(e=>new Set(e).add(a));try{const n=await l.fetch(`${A}/api/kuadrant/apikeys/${e}/${t}/secret`);if(n.ok){const e=await n.json();ie(t=>new Map(t).set(a,e.apiKey)),de(e=>new Set(e).add(a))}else 403===n.status&&(de(e=>new Set(e).add(a)),o.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";o.post({message:`Failed to fetch api key: ${t}`,severity:"error",display:"transient"})}finally{oe(e=>{const t=new Set(e);return t.delete(a),t})}}})(me.namespace,me.name),Se(me.name)),pe(!1),he(null)},children:"Reveal API Key"})]})]}),(0,n.jsx)(M,{open:q,onClose:()=>R(!1),onSuccess:()=>{R(!1),ee(e=>e+1)}})]})},J=()=>(0,n.jsxs)(r.Y,{themeId:"tool",children:[(0,n.jsx)(i.Y,{title:"My API Keys",subtitle:"View and manage your API keys",children:(0,n.jsx)(l.Y,{children:"Manage your API keys and access requests"})}),(0,n.jsx)(o.U,{children:(0,n.jsx)(Y,{})})]})},39590:(e,t,a)=>{var n=a(4293),s=a(78920);t.A=void 0;var r=s(a(95478)),i=(0,n(a(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,a)=>{a.d(t,{Y:()=>$});var n=a(31085),s=a(22097),r=a(10394),i=a(64947),l=a(93453),o=a(29365),c=a(46423),d=a(5951),u=a(26343),p=a(28233),m=a(55197),h=a(37976),f=a(72501),A=a(5893),g=a(95478),v=(a(45250),a(49634),a(21006)),x=a(75501);const y=()=>{const{t:e}=(0,x.useTranslationRef)(v.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 j=a(27799);function b(e){const{id:t,Fallback:a=j.A,...r}=e,i=(0,s.useApp)().getSystemIcon(t)??a;return(0,n.jsx)(i,{...r})}function k(e){return(0,n.jsx)(b,{id:"help",...e})}var w=a(37725);const S=(0,h.makeStyles)({popoverList:{minWidth:260,maxWidth:400},menuItem:{whiteSpace:"normal"}},{name:"BackstageSupportButton"}),C=({icon:e})=>{const t=(0,s.useApp)(),a=e?t.getSystemIcon(e)??k:k;return(0,n.jsx)(a,{})},P=({link:e})=>(0,n.jsx)(w.N_,{to:e.url,children:e.title??e.url}),I=({item:e})=>(0,n.jsxs)(u.A,{button:!1,children:[(0,n.jsx)(c.A,{children:(0,n.jsx)(C,{icon:e.icon})}),(0,n.jsx)(d.A,{primary:e.title,secondary:e.links?.reduce((e,t,a)=>[...e,a>0&&(0,n.jsx)("br",{},a),(0,n.jsx)(P,{link:t},t.url)],[])})]});function $(e){const{t}=(0,x.useTranslationRef)(v.O),{title:a,items:c,children:d}=e,{items:h}=function(){const e=(0,s.useApiHolder)().get(s.configApiRef),t=e?.getOptionalConfig("app.support"),a=y();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")??""}))}))}:a}(),[j,b]=(0,g.useState)(!1),[w,C]=(0,g.useState)(null),P=S(),$=(0,s.useApi)(s.configApiRef).getOptionalConfig("app.support"),q=(0,A.A)(e=>e.breakpoints.down("sm")),R=e=>{C(e.currentTarget),b(!0)},z=()=>{b(!1)};return $?(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(r.A,{display:"flex",ml:1,children:q?(0,n.jsx)(o.A,{color:"primary",size:"small",onClick:R,"data-testid":"support-button","aria-label":"Support",children:(0,n.jsx)(k,{})}):(0,n.jsx)(i.A,{"data-testid":"support-button","aria-label":"Support",color:"primary",onClick:R,startIcon:(0,n.jsx)(k,{}),children:t("supportButton.title")})}),(0,n.jsxs)(m.Ay,{"data-testid":"support-button-popover",open:j,anchorEl:w,anchorOrigin:{vertical:"bottom",horizontal:"right"},transformOrigin:{vertical:"top",horizontal:"right"},onClose:z,children:[(0,n.jsxs)(p.A,{className:P.popoverList,autoFocusItem:Boolean(w),children:[a&&(0,n.jsx)(u.A,{button:!1,alignItems:"flex-start",className:P.menuItem,children:(0,n.jsx)(f.A,{variant:"subtitle1",children:a})}),g.Children.map(d,(e,t)=>(0,n.jsx)(u.A,{button:!1,alignItems:"flex-start",className:P.menuItem,children:e},`child-${t}`)),(c??h).map((e,t)=>(0,n.jsx)(I,{item:e},`item-${t}`))]}),(0,n.jsx)(l.A,{children:(0,n.jsx)(i.A,{color:"primary",onClick:z,"aria-label":"Close",children:t("supportButton.close")})})]})]}):null}},46299:(e,t,a)=>{a.d(t,{ee:()=>r,g9:()=>n,uU:()=>s});const n=e=>{const t={border:"none"};switch(e){case"Approved":return{...t,backgroundColor:"#1976d2",color:"#fff"};case"Rejected":return{...t,backgroundColor:"#d32f2f",color:"#fff"};default:return{...t,backgroundColor:"#9c27b0",color:"#fff"}}},s=e=>{const t={border:"none"};switch(e){case"Approved":return{...t,backgroundColor:"#2e7d32",color:"#fff"};case"Rejected":return{...t,backgroundColor:"#d32f2f",color:"#fff"};default:return{...t,backgroundColor:"#ed6c02",color:"#fff"}}},r=e=>{switch(e){case"production":return{backgroundColor:"#1976d2",color:"#fff"};case"experimental":return{backgroundColor:"#9c27b0",color:"#fff"};case"deprecated":return{backgroundColor:"#ff9800",color:"#fff"};case"retired":return{backgroundColor:"#d32f2f",color:"#fff"};default:return{}}}},61524:(e,t,a)=>{var n=a(4293),s=a(78920);t.A=void 0;var r=s(a(95478)),i=(0,n(a(74044)).default)(r.createElement("path",{d:"M12 7c2.76 0 5 2.24 5 5 0 .65-.13 1.26-.36 1.83l2.92 2.92c1.51-1.26 2.7-2.89 3.43-4.75-1.73-4.39-6-7.5-11-7.5-1.4 0-2.74.25-3.98.7l2.16 2.16C10.74 7.13 11.35 7 12 7zM2 4.27l2.28 2.28.46.46C3.08 8.3 1.78 10.02 1 12c1.73 4.39 6 7.5 11 7.5 1.55 0 3.03-.3 4.38-.84l.42.42L19.73 22 21 20.73 3.27 3 2 4.27zM7.53 9.8l1.55 1.55c-.05.21-.08.43-.08.65 0 1.66 1.34 3 3 3 .22 0 .44-.03.65-.08l1.55 1.55c-.67.33-1.41.53-2.2.53-2.76 0-5-2.24-5-5 0-.79.2-1.53.53-2.2zm4.31-.78l3.15 3.15.02-.16c0-1.66-1.34-3-3-3l-.17.01z"}),"VisibilityOff");t.A=i},63221:(e,t,a)=>{a.d(t,{K:()=>A});var n=a(31085),s=a(95478),r=a(76891),i=a(61477),l=a(10394),o=a(46805),c=a(59461),d=a(72501),u=a(16249),p=a(93453),m=a(64947),h=a(78467),f=a(77225);const A=({open:e,title:t,description:a,confirmText:A,severity:g="normal",deleting:v=!1,onConfirm:x,onCancel:y})=>{const[j,b]=(0,s.useState)("");(0,s.useEffect)(()=>{e||b("")},[e]);const k="high"===g&&A,w=!k||j===A;return(0,n.jsxs)(r.A,{open:e,onClose:v?void 0:y,maxWidth:"sm",fullWidth:!0,children:[(0,n.jsxs)(i.A,{children:["high"===g&&(0,n.jsxs)(l.A,{display:"flex",alignItems:"center",style:{gap:8},children:[(0,n.jsx)(f.A,{color:"error"}),(0,n.jsx)("span",{children:t})]}),"high"!==g&&t]}),(0,n.jsxs)(o.A,{children:[(0,n.jsx)(c.A,{style:{whiteSpace:"pre-line"},children:a}),k&&(0,n.jsxs)(l.A,{mt:2,children:[(0,n.jsxs)(d.A,{variant:"body2",color:"textSecondary",gutterBottom:!0,children:["Type ",(0,n.jsx)("strong",{children:A})," to confirm:"]}),(0,n.jsx)(u.A,{fullWidth:!0,variant:"outlined",size:"small",value:j,onChange:e=>b(e.target.value),disabled:v,autoFocus:!0,placeholder:A})]})]}),(0,n.jsxs)(p.A,{children:[(0,n.jsx)(m.A,{onClick:y,disabled:v,children:"Cancel"}),(0,n.jsx)(m.A,{onClick:()=>{w&&x()},color:"secondary",variant:"contained",disabled:v||!w,startIcon:v?(0,n.jsx)(h.A,{size:16,color:"inherit"}):void 0,children:v?"Deleting...":"Delete"})]})]})}},77225:(e,t,a)=>{var n=a(4293),s=a(78920);t.A=void 0;var r=s(a(95478)),i=(0,n(a(74044)).default)(r.createElement("path",{d:"M1 21h22L12 2 1 21zm12-3h-2v-2h2v2zm0-4h-2v-4h2v4z"}),"Warning");t.A=i},77318:(e,t,a)=>{async function n(e){const t=await e.json().catch(()=>({}));switch(e.status){case 400:return t.error||"Invalid request. Please check your input.";case 403:return"Permission denied. Contact your administrator.";case 404:return"Resource not found. It may have been deleted.";case 409:return"Resource already exists or conflicts with existing data.";case 500:return"Server error. Please try again or contact support.";default:return t.error||`Request failed (${e.status})`}}a.d(t,{T:()=>n})},91638:(e,t,a)=>{var n=a(85608),s=a(95478),r=n.__importDefault(a(5030));t.A=function(e,t){void 0===t&&(t=[]);var a=r.default(e,t,{loading:!0}),n=a[0],i=a[1];return s.useEffect(function(){i()},[i]),n}}}]);
2
+ //# sourceMappingURL=7270.9473c969.chunk.js.map