@nospt/backstage-plugin-apigee 1.1.0-rc3 → 1.1.0-rc5
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.
Potentially problematic release.
This version of @nospt/backstage-plugin-apigee might be problematic. Click here for more details.
- package/config.d.ts +0 -10
- package/dist/components/ApiCard.esm.js +61 -47
- package/dist/components/ApiCard.esm.js.map +1 -1
- package/dist/components/ApiCard.module.css.esm.js +2 -2
- package/dist/components/ApiCardGrid.esm.js +6 -34
- package/dist/components/ApiCardGrid.esm.js.map +1 -1
- package/dist/components/ApiDetailsDrawer.esm.js +335 -0
- package/dist/components/ApiDetailsDrawer.esm.js.map +1 -0
- package/dist/components/ApiDetailsDrawer.module.css.esm.js +8 -0
- package/dist/components/ApiDetailsDrawer.module.css.esm.js.map +1 -0
- package/dist/components/ApiTable.esm.js +170 -0
- package/dist/components/ApiTable.esm.js.map +1 -0
- package/dist/components/ApiTable.module.css.esm.js +8 -0
- package/dist/components/ApiTable.module.css.esm.js.map +1 -0
- package/dist/components/ApigeeApiCatalogPage.esm.js +98 -79
- package/dist/components/ApigeeApiCatalogPage.esm.js.map +1 -1
- package/dist/components/CountCards.esm.js +23 -0
- package/dist/components/CountCards.esm.js.map +1 -1
- package/dist/components/FilterToolbar.esm.js +43 -39
- package/dist/components/FilterToolbar.esm.js.map +1 -1
- package/dist/components/FilterToolbar.module.css.esm.js +2 -2
- package/dist/components/apiCardViewModel.esm.js +16 -3
- package/dist/components/apiCardViewModel.esm.js.map +1 -1
- package/dist/components/apiDetailViewModel.esm.js +60 -0
- package/dist/components/apiDetailViewModel.esm.js.map +1 -0
- package/dist/components/apigeeFacetFilters.esm.js +3 -6
- package/dist/components/apigeeFacetFilters.esm.js.map +1 -1
- package/dist/components/apigeeSearchParams.esm.js +0 -1
- package/dist/components/apigeeSearchParams.esm.js.map +1 -1
- package/dist/components/facetModel.esm.js +3 -29
- package/dist/components/facetModel.esm.js.map +1 -1
- package/dist/components/grouping.esm.js +1 -26
- package/dist/components/grouping.esm.js.map +1 -1
- package/dist/components/useApigeeFilters.esm.js +1 -3
- package/dist/components/useApigeeFilters.esm.js.map +1 -1
- package/dist/constants.esm.js +3 -3
- package/dist/constants.esm.js.map +1 -1
- package/dist/index.d.ts +52 -1
- package/dist/index.esm.js +1 -1
- package/dist/plugin.esm.js +17 -7
- package/dist/plugin.esm.js.map +1 -1
- package/dist/routes.esm.js +2 -1
- package/dist/routes.esm.js.map +1 -1
- package/package.json +2 -2
- package/dist/components/ApiCardGrid.module.css.esm.js +0 -8
- package/dist/components/ApiCardGrid.module.css.esm.js.map +0 -1
- package/dist/components/categoryIcons.esm.js +0 -53
- package/dist/components/categoryIcons.esm.js.map +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ApiDetailsDrawer.esm.js","sources":["../../src/components/ApiDetailsDrawer.tsx"],"sourcesContent":["// SPDX-License-Identifier: Apache-2.0\nimport { Link } from '@backstage/core-components';\nimport { useApi } from '@backstage/core-plugin-api';\nimport { useRouteRef } from '@backstage/frontend-plugin-api';\nimport { type Entity, parseEntityRef } from '@backstage/catalog-model';\nimport {\n catalogApiRef,\n entityRouteRef,\n EntityRefLink,\n} from '@backstage/plugin-catalog-react';\nimport {\n Button,\n ButtonIcon,\n Tab,\n TabList,\n TabPanel,\n Tabs,\n Text,\n} from '@backstage/ui';\nimport {\n RiCloseLine,\n RiDownloadLine,\n RiExternalLinkLine,\n RiFileCopyLine,\n} from '@remixicon/react';\nimport { Fragment, type ReactNode, useEffect, useMemo, useState } from 'react';\nimport { useNavigate } from 'react-router-dom';\nimport { LifecycleBadge } from './ApiCard';\nimport {\n specFileName,\n toApiDetailViewModel,\n type ApiDetailViewModel,\n} from './apiDetailViewModel';\nimport styles from './ApiDetailsDrawer.module.css';\n\nexport interface ApiDetailsDrawerProps {\n /** The selected API entity, or undefined when the drawer is closed. */\n entity: Entity | undefined;\n /** Config `apigee.catalog.orgLabels` — friendly names for org values. */\n orgLabels?: Record<string, string>;\n onClose: () => void;\n}\n\n/** One label/value row in the Overview card. */\nfunction MetaRow({\n label,\n value,\n children,\n}: {\n label: string;\n value?: string;\n children?: ReactNode;\n}) {\n return (\n <div className={styles.metaRow}>\n <dt className={styles.metaLabel}>{label}</dt>\n <dd className={styles.metaValue}>{children ?? value}</dd>\n </div>\n );\n}\n\n/** Owner as a catalog link when the ref parses, else plain humanised text. */\nfunction OwnerValue({ vm }: { vm: ApiDetailViewModel }) {\n if (vm.ownerRef) {\n try {\n parseEntityRef(vm.ownerRef, {\n defaultKind: 'group',\n defaultNamespace: 'default',\n });\n return <EntityRefLink entityRef={vm.ownerRef} defaultKind=\"group\" />;\n } catch {\n // Unparseable ref — fall back to the humanised label below.\n }\n }\n return <>{vm.ownerLabel}</>;\n}\n\n/** The Specification card body: OpenAPI/Raw tabs plus Download + Copy actions. */\n/** The Specification card body: an inline Raw spec tab, plus an OpenAPI tab that redirects to\n * the catalog's API definition page (rendered there by @backstage/plugin-api-docs). Download +\n * Copy act on the raw spec. */\nfunction SpecSection({\n definition,\n fileBaseName,\n definitionHref,\n}: {\n definition: string;\n fileBaseName: string;\n definitionHref?: string;\n}) {\n const navigate = useNavigate();\n const [copied, setCopied] = useState(false);\n\n if (!definition.trim()) {\n return (\n <Text variant=\"body-small\" color=\"secondary\" as=\"p\">\n No specification available for preview.\n </Text>\n );\n }\n\n const handleCopy = async () => {\n await navigator.clipboard.writeText(definition);\n setCopied(true);\n setTimeout(() => setCopied(false), 2000);\n };\n\n const handleDownload = () => {\n const blob = new Blob([definition], { type: 'text/plain;charset=utf-8' });\n const url = URL.createObjectURL(blob);\n try {\n const anchor = document.createElement('a');\n anchor.href = url;\n anchor.download = specFileName(fileBaseName, definition);\n anchor.click();\n } finally {\n URL.revokeObjectURL(url);\n }\n };\n\n return (\n <div className={styles.spec}>\n <div className={styles.specActions}>\n <Button\n size=\"small\"\n variant=\"secondary\"\n iconStart={<RiDownloadLine />}\n onPress={handleDownload}\n >\n Download\n </Button>\n <Button\n size=\"small\"\n variant=\"secondary\"\n iconStart={<RiFileCopyLine />}\n onPress={handleCopy}\n >\n {copied ? 'Copied!' : 'Copy'}\n </Button>\n </div>\n <Tabs\n selectedKey=\"raw\"\n onSelectionChange={key => {\n // The OpenAPI tab is a redirect to the catalog's API definition page, not an\n // inline panel — the raw tab stays selected and the browser navigates away.\n if (key === 'openapi' && definitionHref) {\n navigate(definitionHref);\n }\n }}\n >\n <TabList aria-label=\"Specification format\" className={styles.tabList}>\n <Tab id=\"openapi\" isDisabled={!definitionHref}>\n <span className={styles.tabLabel}>\n OpenAPI <RiExternalLinkLine aria-hidden size={12} />\n </span>\n </Tab>\n <Tab id=\"raw\">Raw</Tab>\n </TabList>\n <TabPanel id=\"raw\">\n <pre className={styles.code}>\n <code>{definition}</code>\n </pre>\n </TabPanel>\n </Tabs>\n </div>\n );\n}\n\n/**\n * The drawer body. Split from the exported wrapper so `useApi(catalogApiRef)` and the\n * Component fetch only run while a drawer is actually open — the closed drawer renders\n * nothing and touches no APIs (keeps the catalog page's other tests API-free).\n */\nfunction ApiDetailsDrawerContent({\n entity,\n orgLabels,\n onClose,\n}: {\n entity: Entity;\n orgLabels?: Record<string, string>;\n onClose: () => void;\n}) {\n const catalogApi = useApi(catalogApiRef);\n const entityRoute = useRouteRef(entityRouteRef);\n\n // Runtime env/revision data lives on the sibling Component (same name/namespace),\n // fetched lazily on open. Hub-only APIs have no Component → orgs render without envs.\n const [component, setComponent] = useState<Entity | undefined>();\n const namespace = entity.metadata.namespace ?? 'default';\n const name = entity.metadata.name;\n useEffect(() => {\n let active = true;\n catalogApi\n .getEntityByRef({ kind: 'Component', namespace, name })\n .then(found => {\n if (active) {\n setComponent(found ?? undefined);\n }\n })\n .catch(() => {\n if (active) {\n setComponent(undefined);\n }\n });\n return () => {\n active = false;\n };\n }, [catalogApi, namespace, name]);\n\n const vm = useMemo(\n () => toApiDetailViewModel(entity, component, orgLabels),\n [entity, component, orgLabels],\n );\n\n const catalogHref = entityRoute\n ? entityRoute({\n kind: vm.targetRef.kind.toLowerCase(),\n namespace: vm.targetRef.namespace,\n name: vm.targetRef.name,\n })\n : undefined;\n\n // Mount closed, then flip open on the next frame so the slide-in transition plays.\n const [open, setOpen] = useState(false);\n useEffect(() => {\n const id = requestAnimationFrame(() => setOpen(true));\n return () => cancelAnimationFrame(id);\n }, []);\n\n useEffect(() => {\n const onKey = (event: KeyboardEvent) => {\n if (event.key === 'Escape') {\n onClose();\n }\n };\n document.addEventListener('keydown', onKey);\n return () => document.removeEventListener('keydown', onKey);\n }, [onClose]);\n\n const showDeployments = vm.runtimeOrgs.length > 0;\n\n return (\n <>\n <div\n className={styles.overlay}\n data-open={open}\n onClick={onClose}\n role=\"presentation\"\n aria-hidden={!open}\n />\n <aside\n className={styles.drawer}\n data-open={open}\n role=\"dialog\"\n aria-modal=\"true\"\n aria-label={`${vm.name} API details`}\n >\n <header className={styles.header}>\n <div className={styles.headerText}>\n <Text\n variant=\"title-small\"\n weight=\"bold\"\n as=\"h2\"\n className={styles.title}\n >\n {vm.name}\n </Text>\n <div className={styles.badges}>\n {vm.version ? (\n <span className={`${styles.badge} ${styles.badgeVersion}`}>\n {vm.version}\n </span>\n ) : null}\n <LifecycleBadge kind={vm.badge.kind} label={vm.badge.label} />\n </div>\n </div>\n <ButtonIcon\n icon={<RiCloseLine />}\n variant=\"tertiary\"\n onPress={onClose}\n aria-label=\"Close\"\n />\n </header>\n\n <div className={styles.body}>\n <section className={styles.card} aria-labelledby=\"apigee-overview-title\">\n <Text\n id=\"apigee-overview-title\"\n variant=\"title-x-small\"\n weight=\"bold\"\n as=\"h3\"\n className={styles.cardTitle}\n >\n Overview\n </Text>\n <dl className={styles.metaList}>\n <MetaRow label=\"Title\" value={vm.name} />\n {vm.description ? (\n <MetaRow label=\"Description\" value={vm.description} />\n ) : null}\n <MetaRow label=\"Kind\" value={vm.kind} />\n {vm.type ? <MetaRow label=\"Type\" value={vm.type} /> : null}\n {vm.version ? (\n <MetaRow label=\"Version\" value={vm.version} />\n ) : null}\n <MetaRow label=\"Lifecycle\" value={vm.badge.label} />\n <MetaRow label=\"Owner\">\n <OwnerValue vm={vm} />\n </MetaRow>\n {vm.department ? (\n <MetaRow label=\"Department\" value={vm.department} />\n ) : null}\n {vm.tags.length > 0 ? (\n <MetaRow label=\"Tags\">\n <div className={styles.tags}>\n {vm.tags.map(tag => (\n <span key={tag} className={styles.tag}>\n {tag}\n </span>\n ))}\n </div>\n </MetaRow>\n ) : null}\n </dl>\n\n {showDeployments ? (\n <div className={styles.deployments}>\n <Text\n variant=\"body-small\"\n weight=\"bold\"\n as=\"h4\"\n className={styles.deploymentsTitle}\n >\n Deployments\n </Text>\n <table className={styles.deploymentsTable}>\n <thead>\n <tr>\n <th scope=\"col\">Org</th>\n <th scope=\"col\">Environment</th>\n <th scope=\"col\">Revision</th>\n </tr>\n </thead>\n <tbody>\n {vm.runtimeOrgs.map(org => (\n <Fragment key={org.value}>\n {org.environments.length > 0 ? (\n org.environments.map((env, index) => (\n <tr key={env.name}>\n {index === 0 ? (\n <th\n scope=\"rowgroup\"\n rowSpan={org.environments.length}\n className={styles.orgCell}\n >\n {org.label}\n </th>\n ) : null}\n <td>{env.name}</td>\n <td>{env.revision}</td>\n </tr>\n ))\n ) : (\n <tr>\n <th scope=\"row\" className={styles.orgCell}>\n {org.label}\n </th>\n <td colSpan={2} className={styles.noDeployments}>\n No deployments\n </td>\n </tr>\n )}\n </Fragment>\n ))}\n </tbody>\n </table>\n </div>\n ) : null}\n </section>\n\n <section className={styles.card} aria-labelledby=\"apigee-spec-title\">\n <Text\n id=\"apigee-spec-title\"\n variant=\"title-x-small\"\n weight=\"bold\"\n as=\"h3\"\n className={styles.cardTitle}\n >\n Specification\n </Text>\n <SpecSection\n definition={vm.definition}\n fileBaseName={vm.targetRef.name}\n definitionHref={\n catalogHref ? `${catalogHref}/definition` : undefined\n }\n />\n </section>\n\n {catalogHref || vm.sourceRepo ? (\n <section className={styles.card} aria-labelledby=\"apigee-links-title\">\n <Text\n id=\"apigee-links-title\"\n variant=\"title-x-small\"\n weight=\"bold\"\n as=\"h3\"\n className={styles.cardTitle}\n >\n Links\n </Text>\n {catalogHref ? (\n <Link to={catalogHref} className={styles.catalogLink}>\n <RiExternalLinkLine aria-hidden size={14} /> View in catalog\n </Link>\n ) : null}\n {vm.sourceRepo ? (\n <Link to={vm.sourceRepo.url} className={styles.sourceRepo}>\n <RiExternalLinkLine aria-hidden size={14} /> {vm.sourceRepo.title}\n </Link>\n ) : null}\n </section>\n ) : null}\n </div>\n </aside>\n </>\n );\n}\n\n/**\n * Side drawer with full details for an Apigee API — opened from a card/row instead of\n * navigating to the catalog entity page. Renders nothing when no entity is selected.\n * (Header: title + version/lifecycle badges · Overview · Specification · Links cards.)\n */\nexport function ApiDetailsDrawer({\n entity,\n orgLabels,\n onClose,\n}: ApiDetailsDrawerProps) {\n if (!entity) {\n return null;\n }\n return (\n <ApiDetailsDrawerContent\n entity={entity}\n orgLabels={orgLabels}\n onClose={onClose}\n />\n );\n}\n"],"names":["Fragment"],"mappings":"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"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import styleInject from '../node_modules_dist/style-inject/dist/style-inject.es.esm.js';
|
|
2
|
+
|
|
3
|
+
var css_248z = "/* SPDX-License-Identifier: Apache-2.0 */\n\n.ApiDetailsDrawer_overlay__4d2ff9c469 {\n position: fixed;\n inset: 0;\n background-color: rgba(0, 0, 0, 0.3);\n z-index: 1299;\n opacity: 0;\n pointer-events: none;\n transition: opacity 220ms ease;\n}\n\n.ApiDetailsDrawer_overlay__4d2ff9c469[data-open='true'] {\n opacity: 1;\n pointer-events: auto;\n}\n\n.ApiDetailsDrawer_drawer__4d2ff9c469 {\n position: fixed;\n top: 0;\n right: 0;\n bottom: 0;\n width: 560px;\n max-width: 100vw;\n display: flex;\n flex-direction: column;\n /* An opaque surface token: the drawer floats over the page, so it must bring its own\n background rather than a translucent neutral that assumes a solid layer beneath it. */\n background-color: var(--bui-bg-app);\n border-left: 1px solid var(--bui-border-1);\n box-shadow: -4px 0 24px rgba(0, 0, 0, 0.15);\n z-index: 1300;\n transform: translateX(100%);\n transition: transform 260ms cubic-bezier(0.16, 1, 0.3, 1);\n}\n\n.ApiDetailsDrawer_drawer__4d2ff9c469[data-open='true'] {\n transform: translateX(0);\n}\n\n@media (prefers-reduced-motion: reduce) {\n .ApiDetailsDrawer_overlay__4d2ff9c469,\n .ApiDetailsDrawer_drawer__4d2ff9c469 {\n transition: none;\n }\n}\n\n.ApiDetailsDrawer_header__4d2ff9c469 {\n display: flex;\n align-items: flex-start;\n gap: var(--bui-space-2);\n padding: var(--bui-space-4);\n border-bottom: 1px solid var(--bui-border-1);\n}\n\n.ApiDetailsDrawer_headerText__4d2ff9c469 {\n flex: 1;\n min-width: 0;\n display: flex;\n flex-direction: column;\n gap: var(--bui-space-2);\n}\n\n.ApiDetailsDrawer_title__4d2ff9c469 {\n word-break: break-word;\n}\n\n.ApiDetailsDrawer_badges__4d2ff9c469 {\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n gap: var(--bui-space-1);\n}\n\n.ApiDetailsDrawer_badge__4d2ff9c469 {\n flex-shrink: 0;\n display: inline-flex;\n align-items: center;\n padding: 2px var(--bui-space-2);\n border-radius: var(--bui-radius-full);\n font-size: var(--bui-font-size-1);\n font-weight: var(--bui-font-weight-bold);\n line-height: 1.5;\n white-space: nowrap;\n}\n\n.ApiDetailsDrawer_badgeVersion__4d2ff9c469 {\n background-color: var(--bui-bg-info);\n color: var(--bui-fg-info-on-bg);\n}\n\n.ApiDetailsDrawer_body__4d2ff9c469 {\n flex: 1;\n min-height: 0;\n overflow-y: auto;\n display: flex;\n flex-direction: column;\n gap: var(--bui-space-4);\n padding: var(--bui-space-4);\n}\n\n.ApiDetailsDrawer_card__4d2ff9c469 {\n display: flex;\n flex-direction: column;\n gap: var(--bui-space-3);\n padding: var(--bui-space-4);\n border: 1px solid var(--bui-border-1);\n border-radius: var(--bui-radius-3);\n background-color: var(--bui-bg-neutral-1);\n}\n\n.ApiDetailsDrawer_cardTitle__4d2ff9c469 {\n margin: 0;\n}\n\n.ApiDetailsDrawer_catalogLink__4d2ff9c469,\n.ApiDetailsDrawer_sourceRepo__4d2ff9c469 {\n display: inline-flex;\n align-items: center;\n gap: var(--bui-space-1);\n width: fit-content;\n}\n\n.ApiDetailsDrawer_metaList__4d2ff9c469 {\n display: flex;\n flex-direction: column;\n gap: var(--bui-space-2);\n margin: 0;\n}\n\n.ApiDetailsDrawer_metaRow__4d2ff9c469 {\n display: grid;\n grid-template-columns: 120px 1fr;\n gap: var(--bui-space-2);\n align-items: start;\n}\n\n.ApiDetailsDrawer_metaLabel__4d2ff9c469 {\n margin: 0;\n color: var(--bui-fg-secondary);\n font-size: var(--bui-font-size-2);\n font-weight: var(--bui-font-weight-bold);\n}\n\n.ApiDetailsDrawer_metaValue__4d2ff9c469 {\n margin: 0;\n min-width: 0;\n font-size: var(--bui-font-size-2);\n word-break: break-word;\n}\n\n.ApiDetailsDrawer_tags__4d2ff9c469 {\n display: flex;\n flex-wrap: wrap;\n gap: var(--bui-space-1);\n}\n\n.ApiDetailsDrawer_tag__4d2ff9c469 {\n display: inline-flex;\n align-items: center;\n padding: 1px var(--bui-space-2);\n border-radius: var(--bui-radius-full);\n background-color: var(--bui-bg-neutral-2);\n color: var(--bui-fg-secondary);\n font-size: var(--bui-font-size-1);\n}\n\n.ApiDetailsDrawer_deployments__4d2ff9c469 {\n display: flex;\n flex-direction: column;\n gap: var(--bui-space-2);\n padding-top: var(--bui-space-2);\n border-top: 1px solid var(--bui-border-1);\n}\n\n.ApiDetailsDrawer_deploymentsTitle__4d2ff9c469 {\n margin: 0;\n}\n\n.ApiDetailsDrawer_deploymentsTable__4d2ff9c469 {\n width: 100%;\n border-collapse: collapse;\n font-size: var(--bui-font-size-2);\n}\n\n.ApiDetailsDrawer_deploymentsTable__4d2ff9c469 th,\n.ApiDetailsDrawer_deploymentsTable__4d2ff9c469 td {\n padding: var(--bui-space-1) var(--bui-space-2);\n text-align: left;\n border: 1px solid var(--bui-border-1);\n}\n\n.ApiDetailsDrawer_deploymentsTable__4d2ff9c469 thead th {\n color: var(--bui-fg-secondary);\n font-weight: var(--bui-font-weight-bold);\n background-color: var(--bui-bg-neutral-2);\n}\n\n.ApiDetailsDrawer_orgCell__4d2ff9c469 {\n vertical-align: top;\n font-weight: var(--bui-font-weight-bold);\n white-space: nowrap;\n}\n\n.ApiDetailsDrawer_noDeployments__4d2ff9c469 {\n color: var(--bui-fg-secondary);\n}\n\n.ApiDetailsDrawer_spec__4d2ff9c469 {\n display: flex;\n flex-direction: column;\n gap: var(--bui-space-3);\n}\n\n.ApiDetailsDrawer_specActions__4d2ff9c469 {\n display: flex;\n gap: var(--bui-space-2);\n}\n\n.ApiDetailsDrawer_tabList__4d2ff9c469 {\n margin-bottom: var(--bui-space-2);\n}\n\n.ApiDetailsDrawer_tabLabel__4d2ff9c469 {\n display: inline-flex;\n align-items: center;\n gap: var(--bui-space-1);\n}\n\n.ApiDetailsDrawer_code__4d2ff9c469 {\n margin: 0;\n max-height: 320px;\n overflow: auto;\n padding: var(--bui-space-3);\n border-radius: var(--bui-radius-2);\n background-color: var(--bui-bg-neutral-2);\n font-family: var(--bui-font-family-mono, monospace);\n font-size: var(--bui-font-size-1);\n line-height: 1.5;\n white-space: pre;\n tab-size: 2;\n}\n";
|
|
4
|
+
var styles = {"overlay":"ApiDetailsDrawer_overlay__4d2ff9c469","drawer":"ApiDetailsDrawer_drawer__4d2ff9c469","header":"ApiDetailsDrawer_header__4d2ff9c469","headerText":"ApiDetailsDrawer_headerText__4d2ff9c469","title":"ApiDetailsDrawer_title__4d2ff9c469","badges":"ApiDetailsDrawer_badges__4d2ff9c469","badge":"ApiDetailsDrawer_badge__4d2ff9c469","badgeVersion":"ApiDetailsDrawer_badgeVersion__4d2ff9c469","body":"ApiDetailsDrawer_body__4d2ff9c469","card":"ApiDetailsDrawer_card__4d2ff9c469","cardTitle":"ApiDetailsDrawer_cardTitle__4d2ff9c469","catalogLink":"ApiDetailsDrawer_catalogLink__4d2ff9c469","sourceRepo":"ApiDetailsDrawer_sourceRepo__4d2ff9c469","metaList":"ApiDetailsDrawer_metaList__4d2ff9c469","metaRow":"ApiDetailsDrawer_metaRow__4d2ff9c469","metaLabel":"ApiDetailsDrawer_metaLabel__4d2ff9c469","metaValue":"ApiDetailsDrawer_metaValue__4d2ff9c469","tags":"ApiDetailsDrawer_tags__4d2ff9c469","tag":"ApiDetailsDrawer_tag__4d2ff9c469","deployments":"ApiDetailsDrawer_deployments__4d2ff9c469","deploymentsTitle":"ApiDetailsDrawer_deploymentsTitle__4d2ff9c469","deploymentsTable":"ApiDetailsDrawer_deploymentsTable__4d2ff9c469","orgCell":"ApiDetailsDrawer_orgCell__4d2ff9c469","noDeployments":"ApiDetailsDrawer_noDeployments__4d2ff9c469","spec":"ApiDetailsDrawer_spec__4d2ff9c469","specActions":"ApiDetailsDrawer_specActions__4d2ff9c469","tabList":"ApiDetailsDrawer_tabList__4d2ff9c469","tabLabel":"ApiDetailsDrawer_tabLabel__4d2ff9c469","code":"ApiDetailsDrawer_code__4d2ff9c469"};
|
|
5
|
+
styleInject(css_248z);
|
|
6
|
+
|
|
7
|
+
export { styles as default };
|
|
8
|
+
//# sourceMappingURL=ApiDetailsDrawer.module.css.esm.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ApiDetailsDrawer.module.css.esm.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;"}
|
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
import { jsx, jsxs } from 'react/jsx-runtime';
|
|
2
|
+
import { Link } from '@backstage/core-components';
|
|
3
|
+
import { useRouteRef } from '@backstage/frontend-plugin-api';
|
|
4
|
+
import { entityRouteRef } from '@backstage/plugin-catalog-react';
|
|
5
|
+
import { RiFileTextLine, RiArrowUpSLine, RiArrowDownSLine, RiArrowUpDownLine } from '@remixicon/react';
|
|
6
|
+
import { useState, useMemo } from 'react';
|
|
7
|
+
import { LifecycleBadge, VISIBILITY_ICON } from './ApiCard.esm.js';
|
|
8
|
+
import styles from './ApiTable.module.css.esm.js';
|
|
9
|
+
|
|
10
|
+
function sortValue(vm, key) {
|
|
11
|
+
switch (key) {
|
|
12
|
+
case "name":
|
|
13
|
+
return vm.name;
|
|
14
|
+
case "lifecycle":
|
|
15
|
+
return vm.badge.label;
|
|
16
|
+
case "version":
|
|
17
|
+
return vm.version ?? "";
|
|
18
|
+
case "owner":
|
|
19
|
+
return vm.ownerLabel;
|
|
20
|
+
case "department":
|
|
21
|
+
return vm.department ?? "";
|
|
22
|
+
case "orgs":
|
|
23
|
+
return vm.visibilities.join(", ");
|
|
24
|
+
default:
|
|
25
|
+
return "";
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
function SortableHeader({
|
|
29
|
+
label,
|
|
30
|
+
sortKey,
|
|
31
|
+
sort,
|
|
32
|
+
onSort
|
|
33
|
+
}) {
|
|
34
|
+
const activeSort = sort && sort.key === sortKey ? sort : null;
|
|
35
|
+
const ariaSort = activeSort ? activeSort.dir === "asc" ? "ascending" : "descending" : "none";
|
|
36
|
+
const Icon = activeSort ? activeSort.dir === "asc" ? RiArrowUpSLine : RiArrowDownSLine : RiArrowUpDownLine;
|
|
37
|
+
return /* @__PURE__ */ jsx("th", { scope: "col", "aria-sort": ariaSort, children: /* @__PURE__ */ jsxs(
|
|
38
|
+
"button",
|
|
39
|
+
{
|
|
40
|
+
type: "button",
|
|
41
|
+
className: styles.sortButton,
|
|
42
|
+
onClick: () => onSort(sortKey),
|
|
43
|
+
children: [
|
|
44
|
+
label,
|
|
45
|
+
/* @__PURE__ */ jsx(
|
|
46
|
+
Icon,
|
|
47
|
+
{
|
|
48
|
+
"aria-hidden": true,
|
|
49
|
+
size: 14,
|
|
50
|
+
className: activeSort ? styles.sortIcon : styles.sortIconIdle
|
|
51
|
+
}
|
|
52
|
+
)
|
|
53
|
+
]
|
|
54
|
+
}
|
|
55
|
+
) });
|
|
56
|
+
}
|
|
57
|
+
function ApiTable({ vms, onSelect }) {
|
|
58
|
+
const entityRoute = useRouteRef(entityRouteRef);
|
|
59
|
+
const [sort, setSort] = useState(null);
|
|
60
|
+
const handleSort = (key) => setSort(
|
|
61
|
+
(prev) => prev?.key === key ? { key, dir: prev.dir === "asc" ? "desc" : "asc" } : { key, dir: "asc" }
|
|
62
|
+
);
|
|
63
|
+
const sortedVms = useMemo(() => {
|
|
64
|
+
if (!sort) {
|
|
65
|
+
return vms;
|
|
66
|
+
}
|
|
67
|
+
const dir = sort.dir === "asc" ? 1 : -1;
|
|
68
|
+
return [...vms].sort(
|
|
69
|
+
(a, b) => dir * sortValue(a, sort.key).localeCompare(sortValue(b, sort.key))
|
|
70
|
+
);
|
|
71
|
+
}, [vms, sort]);
|
|
72
|
+
return /* @__PURE__ */ jsx("div", { className: styles.tableWrap, children: /* @__PURE__ */ jsxs("table", { className: styles.table, children: [
|
|
73
|
+
/* @__PURE__ */ jsx("thead", { children: /* @__PURE__ */ jsxs("tr", { children: [
|
|
74
|
+
/* @__PURE__ */ jsx(
|
|
75
|
+
SortableHeader,
|
|
76
|
+
{
|
|
77
|
+
label: "Name",
|
|
78
|
+
sortKey: "name",
|
|
79
|
+
sort,
|
|
80
|
+
onSort: handleSort
|
|
81
|
+
}
|
|
82
|
+
),
|
|
83
|
+
/* @__PURE__ */ jsx(
|
|
84
|
+
SortableHeader,
|
|
85
|
+
{
|
|
86
|
+
label: "Lifecycle",
|
|
87
|
+
sortKey: "lifecycle",
|
|
88
|
+
sort,
|
|
89
|
+
onSort: handleSort
|
|
90
|
+
}
|
|
91
|
+
),
|
|
92
|
+
/* @__PURE__ */ jsx(
|
|
93
|
+
SortableHeader,
|
|
94
|
+
{
|
|
95
|
+
label: "Version",
|
|
96
|
+
sortKey: "version",
|
|
97
|
+
sort,
|
|
98
|
+
onSort: handleSort
|
|
99
|
+
}
|
|
100
|
+
),
|
|
101
|
+
/* @__PURE__ */ jsx(
|
|
102
|
+
SortableHeader,
|
|
103
|
+
{
|
|
104
|
+
label: "Owner",
|
|
105
|
+
sortKey: "owner",
|
|
106
|
+
sort,
|
|
107
|
+
onSort: handleSort
|
|
108
|
+
}
|
|
109
|
+
),
|
|
110
|
+
/* @__PURE__ */ jsx(
|
|
111
|
+
SortableHeader,
|
|
112
|
+
{
|
|
113
|
+
label: "Department",
|
|
114
|
+
sortKey: "department",
|
|
115
|
+
sort,
|
|
116
|
+
onSort: handleSort
|
|
117
|
+
}
|
|
118
|
+
),
|
|
119
|
+
/* @__PURE__ */ jsx(
|
|
120
|
+
SortableHeader,
|
|
121
|
+
{
|
|
122
|
+
label: "Orgs",
|
|
123
|
+
sortKey: "orgs",
|
|
124
|
+
sort,
|
|
125
|
+
onSort: handleSort
|
|
126
|
+
}
|
|
127
|
+
),
|
|
128
|
+
/* @__PURE__ */ jsx("th", { scope: "col", children: "Spec" })
|
|
129
|
+
] }) }),
|
|
130
|
+
/* @__PURE__ */ jsx("tbody", { children: sortedVms.map((vm) => {
|
|
131
|
+
const { kind, namespace, name } = vm.targetRef;
|
|
132
|
+
const href = entityRoute ? entityRoute({ kind: kind.toLowerCase(), namespace, name }) : void 0;
|
|
133
|
+
return /* @__PURE__ */ jsxs("tr", { children: [
|
|
134
|
+
/* @__PURE__ */ jsx("td", { className: styles.nameCell, children: onSelect ? /* @__PURE__ */ jsx(
|
|
135
|
+
"button",
|
|
136
|
+
{
|
|
137
|
+
type: "button",
|
|
138
|
+
className: styles.nameButton,
|
|
139
|
+
onClick: () => onSelect(vm),
|
|
140
|
+
children: vm.name
|
|
141
|
+
}
|
|
142
|
+
) : href ? /* @__PURE__ */ jsx(Link, { to: href, className: styles.nameLink, children: vm.name }) : vm.name }),
|
|
143
|
+
/* @__PURE__ */ jsx("td", { children: /* @__PURE__ */ jsx(LifecycleBadge, { kind: vm.badge.kind, label: vm.badge.label }) }),
|
|
144
|
+
/* @__PURE__ */ jsx("td", { children: vm.version ?? "\u2014" }),
|
|
145
|
+
/* @__PURE__ */ jsx("td", { children: vm.ownerLabel }),
|
|
146
|
+
/* @__PURE__ */ jsx("td", { children: vm.department ?? "\u2014" }),
|
|
147
|
+
/* @__PURE__ */ jsx("td", { children: vm.visibilities.length > 0 ? /* @__PURE__ */ jsx("span", { className: styles.orgs, children: vm.visibilities.map((visibility) => {
|
|
148
|
+
const VisibilityIcon = VISIBILITY_ICON[visibility];
|
|
149
|
+
return /* @__PURE__ */ jsxs("span", { className: styles.org, children: [
|
|
150
|
+
/* @__PURE__ */ jsx(VisibilityIcon, { "aria-hidden": true, size: 14 }),
|
|
151
|
+
visibility
|
|
152
|
+
] }, visibility);
|
|
153
|
+
}) }) : "\u2014" }),
|
|
154
|
+
/* @__PURE__ */ jsx("td", { children: vm.hasSpec ? /* @__PURE__ */ jsx(
|
|
155
|
+
"span",
|
|
156
|
+
{
|
|
157
|
+
role: "img",
|
|
158
|
+
"aria-label": "OpenAPI spec available",
|
|
159
|
+
title: "OpenAPI spec available",
|
|
160
|
+
className: styles.specIcon,
|
|
161
|
+
children: /* @__PURE__ */ jsx(RiFileTextLine, { "aria-hidden": true, size: 16 })
|
|
162
|
+
}
|
|
163
|
+
) : "\u2014" })
|
|
164
|
+
] }, vm.targetRef.name);
|
|
165
|
+
}) })
|
|
166
|
+
] }) });
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
export { ApiTable };
|
|
170
|
+
//# sourceMappingURL=ApiTable.esm.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ApiTable.esm.js","sources":["../../src/components/ApiTable.tsx"],"sourcesContent":["// SPDX-License-Identifier: Apache-2.0\nimport { Link } from '@backstage/core-components';\nimport { useRouteRef } from '@backstage/frontend-plugin-api';\nimport { entityRouteRef } from '@backstage/plugin-catalog-react';\nimport {\n RiArrowDownSLine,\n RiArrowUpDownLine,\n RiArrowUpSLine,\n RiFileTextLine,\n} from '@remixicon/react';\nimport { useMemo, useState } from 'react';\nimport { LifecycleBadge, VISIBILITY_ICON } from './ApiCard';\nimport type { ApiCardViewModel } from './apiCardViewModel';\nimport styles from './ApiTable.module.css';\n\nexport interface ApiTableProps {\n vms: ApiCardViewModel[];\n /** When provided, clicking a row name opens the details drawer instead of\n * navigating to the catalog entity page. */\n onSelect?: (vm: ApiCardViewModel) => void;\n}\n\ntype SortKey = 'name' | 'lifecycle' | 'version' | 'owner' | 'department' | 'orgs';\ntype SortState = { key: SortKey; dir: 'asc' | 'desc' };\n\n/** Alphabetical sort key per column; missing values collapse to '' (sort first asc). */\nfunction sortValue(vm: ApiCardViewModel, key: SortKey): string {\n switch (key) {\n case 'name':\n return vm.name;\n case 'lifecycle':\n return vm.badge.label;\n case 'version':\n return vm.version ?? '';\n case 'owner':\n return vm.ownerLabel;\n case 'department':\n return vm.department ?? '';\n case 'orgs':\n return vm.visibilities.join(', ');\n default:\n return '';\n }\n}\n\n/** Clickable column header that toggles asc/desc alphabetical sort for its column. */\nfunction SortableHeader({\n label,\n sortKey,\n sort,\n onSort,\n}: {\n label: string;\n sortKey: SortKey;\n sort: SortState | null;\n onSort: (key: SortKey) => void;\n}) {\n const activeSort = sort && sort.key === sortKey ? sort : null;\n const ariaSort = activeSort\n ? activeSort.dir === 'asc'\n ? 'ascending'\n : 'descending'\n : 'none';\n const Icon = activeSort\n ? activeSort.dir === 'asc'\n ? RiArrowUpSLine\n : RiArrowDownSLine\n : RiArrowUpDownLine;\n return (\n <th scope=\"col\" aria-sort={ariaSort}>\n <button\n type=\"button\"\n className={styles.sortButton}\n onClick={() => onSort(sortKey)}\n >\n {label}\n <Icon\n aria-hidden\n size={14}\n className={activeSort ? styles.sortIcon : styles.sortIconIdle}\n />\n </button>\n </th>\n );\n}\n\n/**\n * Tabular (\"list\") presentation of the same view-models rendered as tiles by `ApiCard`.\n * Each row's name is the entity link (resolved via `entityRouteRef`, degrading to plain\n * text when the route ref is unbound); one anchor per row keeps the table keyboard\n * accessible. Reuses `ApiCard`'s lifecycle badge and org icons. (UI-01)\n */\nexport function ApiTable({ vms, onSelect }: ApiTableProps) {\n const entityRoute = useRouteRef(entityRouteRef);\n const [sort, setSort] = useState<SortState | null>(null);\n\n const handleSort = (key: SortKey) =>\n setSort(prev =>\n prev?.key === key\n ? { key, dir: prev.dir === 'asc' ? 'desc' : 'asc' }\n : { key, dir: 'asc' },\n );\n\n const sortedVms = useMemo(() => {\n if (!sort) {\n return vms;\n }\n const dir = sort.dir === 'asc' ? 1 : -1;\n return [...vms].sort(\n (a, b) => dir * sortValue(a, sort.key).localeCompare(sortValue(b, sort.key)),\n );\n }, [vms, sort]);\n\n return (\n <div className={styles.tableWrap}>\n <table className={styles.table}>\n <thead>\n <tr>\n <SortableHeader\n label=\"Name\"\n sortKey=\"name\"\n sort={sort}\n onSort={handleSort}\n />\n <SortableHeader\n label=\"Lifecycle\"\n sortKey=\"lifecycle\"\n sort={sort}\n onSort={handleSort}\n />\n <SortableHeader\n label=\"Version\"\n sortKey=\"version\"\n sort={sort}\n onSort={handleSort}\n />\n <SortableHeader\n label=\"Owner\"\n sortKey=\"owner\"\n sort={sort}\n onSort={handleSort}\n />\n <SortableHeader\n label=\"Department\"\n sortKey=\"department\"\n sort={sort}\n onSort={handleSort}\n />\n <SortableHeader\n label=\"Orgs\"\n sortKey=\"orgs\"\n sort={sort}\n onSort={handleSort}\n />\n <th scope=\"col\">Spec</th>\n </tr>\n </thead>\n <tbody>\n {sortedVms.map(vm => {\n const { kind, namespace, name } = vm.targetRef;\n const href = entityRoute\n ? entityRoute({ kind: kind.toLowerCase(), namespace, name })\n : undefined;\n return (\n <tr key={vm.targetRef.name}>\n <td className={styles.nameCell}>\n {onSelect ? (\n <button\n type=\"button\"\n className={styles.nameButton}\n onClick={() => onSelect(vm)}\n >\n {vm.name}\n </button>\n ) : href ? (\n <Link to={href} className={styles.nameLink}>\n {vm.name}\n </Link>\n ) : (\n vm.name\n )}\n </td>\n <td>\n <LifecycleBadge kind={vm.badge.kind} label={vm.badge.label} />\n </td>\n <td>{vm.version ?? '—'}</td>\n <td>{vm.ownerLabel}</td>\n <td>{vm.department ?? '—'}</td>\n <td>\n {vm.visibilities.length > 0 ? (\n <span className={styles.orgs}>\n {vm.visibilities.map(visibility => {\n const VisibilityIcon = VISIBILITY_ICON[visibility];\n return (\n <span key={visibility} className={styles.org}>\n <VisibilityIcon aria-hidden size={14} />\n {visibility}\n </span>\n );\n })}\n </span>\n ) : (\n '—'\n )}\n </td>\n <td>\n {vm.hasSpec ? (\n <span\n role=\"img\"\n aria-label=\"OpenAPI spec available\"\n title=\"OpenAPI spec available\"\n className={styles.specIcon}\n >\n <RiFileTextLine aria-hidden size={16} />\n </span>\n ) : (\n '—'\n )}\n </td>\n </tr>\n );\n })}\n </tbody>\n </table>\n </div>\n );\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import styleInject from '../node_modules_dist/style-inject/dist/style-inject.es.esm.js';
|
|
2
|
+
|
|
3
|
+
var css_248z = ".ApiTable_tableWrap__f2dd7e5fb8 {\n width: 100%;\n overflow-x: auto;\n}\n\n.ApiTable_table__f2dd7e5fb8 {\n width: 100%;\n border-collapse: collapse;\n font-size: var(--bui-font-size-2);\n}\n\n.ApiTable_table__f2dd7e5fb8 th,\n.ApiTable_table__f2dd7e5fb8 td {\n padding: var(--bui-space-2) var(--bui-space-3);\n text-align: left;\n vertical-align: middle;\n white-space: nowrap;\n border-bottom: 1px solid var(--bui-border-1);\n}\n\n.ApiTable_table__f2dd7e5fb8 th {\n color: var(--bui-fg-secondary);\n font-weight: var(--bui-font-weight-bold);\n}\n\n.ApiTable_table__f2dd7e5fb8 td {\n color: var(--bui-fg-secondary);\n}\n\n.ApiTable_table__f2dd7e5fb8 tbody tr:hover {\n background-color: var(--bui-bg-neutral-1);\n}\n\n.ApiTable_sortButton__f2dd7e5fb8 {\n display: inline-flex;\n align-items: center;\n gap: var(--bui-space-1);\n margin: 0;\n padding: 0;\n border: none;\n background: none;\n color: inherit;\n font: inherit;\n font-weight: var(--bui-font-weight-bold);\n cursor: pointer;\n}\n\n.ApiTable_sortButton__f2dd7e5fb8:hover {\n color: var(--bui-fg-primary);\n}\n\n.ApiTable_sortButton__f2dd7e5fb8:focus-visible {\n outline: 2px solid var(--bui-ring);\n outline-offset: 2px;\n border-radius: 2px;\n}\n\n.ApiTable_sortIcon__f2dd7e5fb8 {\n color: var(--bui-fg-primary);\n}\n\n.ApiTable_sortIconIdle__f2dd7e5fb8 {\n opacity: 0.4;\n}\n\n.ApiTable_nameCell__f2dd7e5fb8 {\n color: var(--bui-fg-primary);\n font-weight: var(--bui-font-weight-bold);\n}\n\n.ApiTable_nameLink__f2dd7e5fb8 {\n color: inherit;\n text-decoration: none;\n}\n\n.ApiTable_nameLink__f2dd7e5fb8:hover {\n text-decoration: underline;\n}\n\n.ApiTable_nameButton__f2dd7e5fb8 {\n margin: 0;\n padding: 0;\n border: none;\n background: none;\n color: inherit;\n font: inherit;\n font-weight: inherit;\n cursor: pointer;\n}\n\n.ApiTable_nameButton__f2dd7e5fb8:hover {\n text-decoration: underline;\n}\n\n.ApiTable_nameButton__f2dd7e5fb8:focus-visible {\n outline: 2px solid var(--bui-ring);\n outline-offset: 2px;\n border-radius: 2px;\n}\n\n.ApiTable_orgs__f2dd7e5fb8 {\n display: inline-flex;\n align-items: center;\n gap: var(--bui-space-2);\n}\n\n.ApiTable_org__f2dd7e5fb8 {\n display: inline-flex;\n align-items: center;\n gap: var(--bui-space-1);\n}\n\n.ApiTable_specIcon__f2dd7e5fb8 {\n display: inline-flex;\n color: var(--bui-fg-secondary);\n}\n";
|
|
4
|
+
var styles = {"tableWrap":"ApiTable_tableWrap__f2dd7e5fb8","table":"ApiTable_table__f2dd7e5fb8","sortButton":"ApiTable_sortButton__f2dd7e5fb8","sortIcon":"ApiTable_sortIcon__f2dd7e5fb8","sortIconIdle":"ApiTable_sortIconIdle__f2dd7e5fb8","nameCell":"ApiTable_nameCell__f2dd7e5fb8","nameLink":"ApiTable_nameLink__f2dd7e5fb8","nameButton":"ApiTable_nameButton__f2dd7e5fb8","orgs":"ApiTable_orgs__f2dd7e5fb8","org":"ApiTable_org__f2dd7e5fb8","specIcon":"ApiTable_specIcon__f2dd7e5fb8"};
|
|
5
|
+
styleInject(css_248z);
|
|
6
|
+
|
|
7
|
+
export { styles as default };
|
|
8
|
+
//# sourceMappingURL=ApiTable.module.css.esm.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ApiTable.module.css.esm.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;"}
|
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
|
|
2
|
-
import { Page, Content
|
|
2
|
+
import { Page, Content } from '@backstage/core-components';
|
|
3
3
|
import { useApi, configApiRef } from '@backstage/core-plugin-api';
|
|
4
4
|
import { EntityListProvider, useEntityList } from '@backstage/plugin-catalog-react';
|
|
5
5
|
import { ToggleButton } from '@backstage/ui';
|
|
6
|
-
import { RiLayoutGridLine,
|
|
7
|
-
import { useEffect, useMemo, useState } from 'react';
|
|
6
|
+
import { RiLayoutGridLine, RiListUnordered } from '@remixicon/react';
|
|
7
|
+
import { useEffect, useMemo, useState, useCallback } from 'react';
|
|
8
|
+
import { ANNOTATION_HAS_SPEC } from '../constants.esm.js';
|
|
8
9
|
import { toApiCardViewModel } from './apiCardViewModel.esm.js';
|
|
9
10
|
import { ApiCardGrid } from './ApiCardGrid.esm.js';
|
|
11
|
+
import { ApiDetailsDrawer } from './ApiDetailsDrawer.esm.js';
|
|
10
12
|
import { ApiKindFilter, isApigeeEntity } from './apigeeFacetFilters.esm.js';
|
|
11
13
|
import { ApigeeOrgFilter } from './apigeeOrgFilter.esm.js';
|
|
12
14
|
import { isActive } from './apigeeSearchParams.esm.js';
|
|
@@ -39,20 +41,6 @@ function ApigeeCatalogContent() {
|
|
|
39
41
|
clearAll
|
|
40
42
|
} = useApigeeFilters();
|
|
41
43
|
const configApi = useApi(configApiRef);
|
|
42
|
-
const overrides = useMemo(() => {
|
|
43
|
-
const config = configApi.getOptionalConfig("apigee.catalog.categoryIcons");
|
|
44
|
-
if (!config) {
|
|
45
|
-
return void 0;
|
|
46
|
-
}
|
|
47
|
-
const out = {};
|
|
48
|
-
for (const key of config.keys()) {
|
|
49
|
-
const value = config.getOptionalString(key);
|
|
50
|
-
if (value) {
|
|
51
|
-
out[key] = value;
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
return Object.keys(out).length > 0 ? out : void 0;
|
|
55
|
-
}, [configApi]);
|
|
56
44
|
const orgLabels = useMemo(() => {
|
|
57
45
|
const config = configApi.getOptionalConfig("apigee.catalog.orgLabels");
|
|
58
46
|
if (!config) {
|
|
@@ -73,15 +61,38 @@ function ApigeeCatalogContent() {
|
|
|
73
61
|
);
|
|
74
62
|
const vms = useMemo(() => entities.map(toApiCardViewModel), [entities]);
|
|
75
63
|
const facets = useMemo(
|
|
76
|
-
() => deriveFacets(apigeeEntities,
|
|
77
|
-
[apigeeEntities,
|
|
64
|
+
() => deriveFacets(apigeeEntities, orgLabels),
|
|
65
|
+
[apigeeEntities, orgLabels]
|
|
78
66
|
);
|
|
79
67
|
const counts = useMemo(
|
|
80
68
|
() => deriveCounts(apigeeEntities, ["org", "lifecycle", "department"], orgLabels),
|
|
81
69
|
[apigeeEntities, orgLabels]
|
|
82
70
|
);
|
|
71
|
+
const specCount = useMemo(
|
|
72
|
+
() => apigeeEntities.filter(
|
|
73
|
+
(entity) => entity.metadata.annotations?.[ANNOTATION_HAS_SPEC] === "true"
|
|
74
|
+
).length,
|
|
75
|
+
[apigeeEntities]
|
|
76
|
+
);
|
|
83
77
|
const active = isActive(state);
|
|
84
78
|
const [viewMode, setViewMode] = useState("flat");
|
|
79
|
+
const [selected, setSelected] = useState();
|
|
80
|
+
const entitiesByRef = useMemo(() => {
|
|
81
|
+
const map = /* @__PURE__ */ new Map();
|
|
82
|
+
for (const entity of entities) {
|
|
83
|
+
const namespace = entity.metadata.namespace ?? "default";
|
|
84
|
+
map.set(`${namespace}/${entity.metadata.name}`, entity);
|
|
85
|
+
}
|
|
86
|
+
return map;
|
|
87
|
+
}, [entities]);
|
|
88
|
+
const handleSelect = useCallback(
|
|
89
|
+
(vm) => {
|
|
90
|
+
const { namespace, name } = vm.targetRef;
|
|
91
|
+
setSelected(entitiesByRef.get(`${namespace}/${name}`));
|
|
92
|
+
},
|
|
93
|
+
[entitiesByRef]
|
|
94
|
+
);
|
|
95
|
+
const handleClose = useCallback(() => setSelected(void 0), []);
|
|
85
96
|
const renderBody = () => {
|
|
86
97
|
if (error) {
|
|
87
98
|
return /* @__PURE__ */ jsx(ApiCatalogError, { error });
|
|
@@ -92,69 +103,77 @@ function ApigeeCatalogContent() {
|
|
|
92
103
|
if (vms.length === 0) {
|
|
93
104
|
return active ? /* @__PURE__ */ jsx(NoMatchState, { onClearAll: clearAll }) : /* @__PURE__ */ jsx(ApiCatalogEmptyState, {});
|
|
94
105
|
}
|
|
95
|
-
return /* @__PURE__ */ jsx(ApiCardGrid, { vms, viewMode,
|
|
106
|
+
return /* @__PURE__ */ jsx(ApiCardGrid, { vms, viewMode, onSelect: handleSelect });
|
|
96
107
|
};
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
108
|
+
const viewToggle = /* @__PURE__ */ jsxs(
|
|
109
|
+
"div",
|
|
110
|
+
{
|
|
111
|
+
role: "group",
|
|
112
|
+
"aria-label": "API view mode",
|
|
113
|
+
style: { display: "inline-flex", gap: "var(--bui-space-1)" },
|
|
114
|
+
children: [
|
|
115
|
+
/* @__PURE__ */ jsx(
|
|
116
|
+
ToggleButton,
|
|
117
|
+
{
|
|
118
|
+
"aria-label": "Flat grid view",
|
|
119
|
+
isSelected: viewMode === "flat",
|
|
120
|
+
onChange: () => setViewMode("flat"),
|
|
121
|
+
iconStart: /* @__PURE__ */ jsx(RiLayoutGridLine, {}),
|
|
122
|
+
children: "Flat"
|
|
123
|
+
}
|
|
124
|
+
),
|
|
125
|
+
/* @__PURE__ */ jsx(
|
|
126
|
+
ToggleButton,
|
|
127
|
+
{
|
|
128
|
+
"aria-label": "List view",
|
|
129
|
+
isSelected: viewMode === "list",
|
|
130
|
+
onChange: () => setViewMode("list"),
|
|
131
|
+
iconStart: /* @__PURE__ */ jsx(RiListUnordered, {}),
|
|
132
|
+
children: "List"
|
|
133
|
+
}
|
|
134
|
+
)
|
|
135
|
+
]
|
|
136
|
+
}
|
|
137
|
+
);
|
|
138
|
+
return /* @__PURE__ */ jsxs(Page, { themeId: "apis", children: [
|
|
139
|
+
/* @__PURE__ */ jsxs(Content, { children: [
|
|
140
|
+
!loading && !error && apigeeEntities.length > 0 ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
141
|
+
/* @__PURE__ */ jsx(
|
|
142
|
+
CountCards,
|
|
143
|
+
{
|
|
144
|
+
total: apigeeEntities.length,
|
|
145
|
+
specCount,
|
|
146
|
+
counts,
|
|
147
|
+
selected: state.selected,
|
|
148
|
+
onSelectFacet: selectOnlyFacet
|
|
149
|
+
}
|
|
150
|
+
),
|
|
151
|
+
/* @__PURE__ */ jsx(
|
|
152
|
+
FilterToolbar,
|
|
153
|
+
{
|
|
154
|
+
facets,
|
|
155
|
+
selected: state.selected,
|
|
156
|
+
onToggleFacet: toggleFacet,
|
|
157
|
+
onClearFacet: clearFacet,
|
|
158
|
+
onClearAll: clearAll,
|
|
159
|
+
active,
|
|
160
|
+
resultCount: vms.length,
|
|
161
|
+
searchBar: /* @__PURE__ */ jsx(SearchBar, { value: inputValue, onChange: setInputValue }),
|
|
162
|
+
viewToggle
|
|
163
|
+
}
|
|
164
|
+
)
|
|
165
|
+
] }) : null,
|
|
166
|
+
renderBody()
|
|
167
|
+
] }),
|
|
168
|
+
/* @__PURE__ */ jsx(
|
|
169
|
+
ApiDetailsDrawer,
|
|
100
170
|
{
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
marginLeft: "auto",
|
|
105
|
-
display: "inline-flex",
|
|
106
|
-
gap: "var(--bui-space-1)"
|
|
107
|
-
},
|
|
108
|
-
children: [
|
|
109
|
-
/* @__PURE__ */ jsx(
|
|
110
|
-
ToggleButton,
|
|
111
|
-
{
|
|
112
|
-
"aria-label": "Flat grid view",
|
|
113
|
-
isSelected: viewMode === "flat",
|
|
114
|
-
onChange: () => setViewMode("flat"),
|
|
115
|
-
iconStart: /* @__PURE__ */ jsx(RiLayoutGridLine, {}),
|
|
116
|
-
children: "Flat"
|
|
117
|
-
}
|
|
118
|
-
),
|
|
119
|
-
/* @__PURE__ */ jsx(
|
|
120
|
-
ToggleButton,
|
|
121
|
-
{
|
|
122
|
-
"aria-label": "Group by category",
|
|
123
|
-
isSelected: viewMode === "grouped",
|
|
124
|
-
onChange: () => setViewMode("grouped"),
|
|
125
|
-
iconStart: /* @__PURE__ */ jsx(RiLayoutRowLine, {}),
|
|
126
|
-
children: "Grouped"
|
|
127
|
-
}
|
|
128
|
-
)
|
|
129
|
-
]
|
|
171
|
+
entity: selected,
|
|
172
|
+
orgLabels,
|
|
173
|
+
onClose: handleClose
|
|
130
174
|
}
|
|
131
|
-
)
|
|
132
|
-
|
|
133
|
-
/* @__PURE__ */ jsx(
|
|
134
|
-
CountCards,
|
|
135
|
-
{
|
|
136
|
-
total: apigeeEntities.length,
|
|
137
|
-
counts,
|
|
138
|
-
selected: state.selected,
|
|
139
|
-
onSelectFacet: selectOnlyFacet
|
|
140
|
-
}
|
|
141
|
-
),
|
|
142
|
-
/* @__PURE__ */ jsx(
|
|
143
|
-
FilterToolbar,
|
|
144
|
-
{
|
|
145
|
-
facets,
|
|
146
|
-
selected: state.selected,
|
|
147
|
-
onToggleFacet: toggleFacet,
|
|
148
|
-
onClearFacet: clearFacet,
|
|
149
|
-
onClearAll: clearAll,
|
|
150
|
-
active,
|
|
151
|
-
resultCount: vms.length,
|
|
152
|
-
searchBar: /* @__PURE__ */ jsx(SearchBar, { value: inputValue, onChange: setInputValue })
|
|
153
|
-
}
|
|
154
|
-
)
|
|
155
|
-
] }) : null,
|
|
156
|
-
renderBody()
|
|
157
|
-
] }) });
|
|
175
|
+
)
|
|
176
|
+
] });
|
|
158
177
|
}
|
|
159
178
|
function ApigeeApiCatalogPage() {
|
|
160
179
|
return /* @__PURE__ */ jsxs(EntityListProvider, { children: [
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ApigeeApiCatalogPage.esm.js","sources":["../../src/components/ApigeeApiCatalogPage.tsx"],"sourcesContent":["// SPDX-License-Identifier: Apache-2.0\nimport { Content, ContentHeader, Page } from '@backstage/core-components';\nimport { configApiRef, useApi } from '@backstage/core-plugin-api';\nimport {\n EntityListProvider,\n useEntityList,\n type DefaultEntityFilters,\n} from '@backstage/plugin-catalog-react';\nimport { ToggleButton } from '@backstage/ui';\nimport { RiLayoutGridLine, RiLayoutRowLine } from '@remixicon/react';\nimport { useEffect, useMemo, useState } from 'react';\nimport { toApiCardViewModel } from './apiCardViewModel';\nimport { ApiCardGrid, type ViewMode } from './ApiCardGrid';\nimport {\n ApiKindFilter,\n isApigeeEntity,\n type ApiSearchFilter,\n type FieldFacetFilter,\n} from './apigeeFacetFilters';\nimport { ApigeeOrgFilter } from './apigeeOrgFilter';\nimport { isActive } from './apigeeSearchParams';\nimport { CountCards } from './CountCards';\nimport { deriveCounts, deriveFacets } from './facetModel';\nimport { FilterToolbar } from './FilterToolbar';\nimport { SearchBar } from './SearchBar';\nimport {\n ApiCatalogEmptyState,\n ApiCatalogError,\n NoMatchState,\n SkeletonGrid,\n} from './states';\nimport { useApigeeFilters } from './useApigeeFilters';\n\n/**\n * Entity-list filters registered on the Apigee catalog page. `apigeeKind` (the seam-free\n * `ApiKindFilter`) and `apigeeOrg` (the dual-key is-Apigee gate) are the backend filters applied\n * once by {@link ApplyApigeeFilters}; the facet + search filters\n * (`apigeeLifecycle`/`apigeeOrgFacet`/`apigeeOwner`/`apigeeCategory`/`apigeeDepartment`/`apigeeSearch`)\n * are driven from the URL by `useApigeeFilters`. Exported so the hook can import the filter contract.\n */\nexport type ApigeeFilters = DefaultEntityFilters & {\n apigeeKind?: ApiKindFilter;\n apigeeOrg?: ApigeeOrgFilter;\n apigeeLifecycle?: FieldFacetFilter;\n apigeeOrgFacet?: FieldFacetFilter;\n apigeeOwner?: FieldFacetFilter;\n apigeeCategory?: FieldFacetFilter;\n apigeeDepartment?: FieldFacetFilter;\n apigeeSearch?: ApiSearchFilter;\n};\n\n/**\n * Registers the Apigee backend filters on the shared EntityListProvider ONCE: the seam-free\n * `ApiKindFilter` (kind=api with NO `toQueryValue`, so the provider's URL writer stays a no-op and\n * `useSearchParams` owns a clean URL) plus the dual-key `ApigeeOrgFilter` is-Apigee gate. The facet\n * + search filters are applied separately, URL-driven, by `useApigeeFilters`. Rendered inside the\n * provider; renders nothing itself.\n */\nfunction ApplyApigeeFilters() {\n const { updateFilters } = useEntityList<ApigeeFilters>();\n useEffect(() => {\n updateFilters({\n apigeeKind: new ApiKindFilter(),\n apigeeOrg: new ApigeeOrgFilter(),\n });\n }, [updateFilters]);\n return null;\n}\n\n/**\n * The page body: reads the filtered entity list, maps to view-models, and branches on\n * loading/empty/error. Exposes a Flat/Grouped view toggle (component state only, no view\n * URL param — that is a Phase 6 seam). (UI-01, UI-05, UI-11)\n */\nexport function ApigeeCatalogContent() {\n const { entities, backendEntities, loading, error } =\n useEntityList<ApigeeFilters>();\n const {\n state,\n inputValue,\n setInputValue,\n toggleFacet,\n selectOnlyFacet,\n clearFacet,\n clearAll,\n } = useApigeeFilters();\n const configApi = useApi(configApiRef);\n\n const overrides = useMemo<Record<string, string> | undefined>(() => {\n const config = configApi.getOptionalConfig('apigee.catalog.categoryIcons');\n if (!config) {\n return undefined;\n }\n const out: Record<string, string> = {};\n for (const key of config.keys()) {\n const value = config.getOptionalString(key);\n if (value) {\n out[key] = value;\n }\n }\n return Object.keys(out).length > 0 ? out : undefined;\n }, [configApi]);\n\n const orgLabels = useMemo<Record<string, string> | undefined>(() => {\n const config = configApi.getOptionalConfig('apigee.catalog.orgLabels');\n if (!config) {\n return undefined;\n }\n const out: Record<string, string> = {};\n for (const key of config.keys()) {\n const value = config.getOptionalString(key);\n if (value) {\n out[key] = value;\n }\n }\n return Object.keys(out).length > 0 ? out : undefined;\n }, [configApi]);\n\n const apigeeEntities = useMemo(\n () => backendEntities.filter(isApigeeEntity),\n [backendEntities],\n );\n const vms = useMemo(() => entities.map(toApiCardViewModel), [entities]);\n const facets = useMemo(\n () => deriveFacets(apigeeEntities, overrides, orgLabels),\n [apigeeEntities, overrides, orgLabels],\n );\n // Static full-catalog counts: the cards stay fixed as filters apply; only the grid narrows.\n const counts = useMemo(\n () => deriveCounts(apigeeEntities, ['org', 'lifecycle', 'department'], orgLabels),\n [apigeeEntities, orgLabels],\n );\n const active = isActive(state);\n const [viewMode, setViewMode] = useState<ViewMode>('flat');\n\n const renderBody = () => {\n if (error) {\n return <ApiCatalogError error={error} />;\n }\n if (loading) {\n return <SkeletonGrid />;\n }\n if (vms.length === 0) {\n return active ? (\n <NoMatchState onClearAll={clearAll} />\n ) : (\n <ApiCatalogEmptyState />\n );\n }\n return <ApiCardGrid vms={vms} viewMode={viewMode} overrides={overrides} />;\n };\n\n return (\n <Page themeId=\"apis\">\n <Content>\n <ContentHeader title=\"APIs\">\n <div\n role=\"group\"\n aria-label=\"API view mode\"\n style={{\n marginLeft: 'auto',\n display: 'inline-flex',\n gap: 'var(--bui-space-1)',\n }}\n >\n <ToggleButton\n aria-label=\"Flat grid view\"\n isSelected={viewMode === 'flat'}\n onChange={() => setViewMode('flat')}\n iconStart={<RiLayoutGridLine />}\n >\n Flat\n </ToggleButton>\n <ToggleButton\n aria-label=\"Group by category\"\n isSelected={viewMode === 'grouped'}\n onChange={() => setViewMode('grouped')}\n iconStart={<RiLayoutRowLine />}\n >\n Grouped\n </ToggleButton>\n </div>\n </ContentHeader>\n {!loading && !error && apigeeEntities.length > 0 ? (\n <>\n <CountCards\n total={apigeeEntities.length}\n counts={counts}\n selected={state.selected}\n onSelectFacet={selectOnlyFacet}\n />\n <FilterToolbar\n facets={facets}\n selected={state.selected}\n onToggleFacet={toggleFacet}\n onClearFacet={clearFacet}\n onClearAll={clearAll}\n active={active}\n resultCount={vms.length}\n searchBar={\n <SearchBar value={inputValue} onChange={setInputValue} />\n }\n />\n </>\n ) : null}\n {renderBody()}\n </Content>\n </Page>\n );\n}\n\n/**\n * Route target for `/apigee` (05-06). Wraps the content in an `EntityListProvider` and\n * registers the Apigee filters — the shared filter context Phase 6's facets + search reuse.\n */\nexport function ApigeeApiCatalogPage() {\n return (\n <EntityListProvider>\n <ApplyApigeeFilters />\n <ApigeeCatalogContent />\n </EntityListProvider>\n );\n}\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"ApigeeApiCatalogPage.esm.js","sources":["../../src/components/ApigeeApiCatalogPage.tsx"],"sourcesContent":["// SPDX-License-Identifier: Apache-2.0\nimport type { Entity } from '@backstage/catalog-model';\nimport { Content, Page } from '@backstage/core-components';\nimport { configApiRef, useApi } from '@backstage/core-plugin-api';\nimport {\n EntityListProvider,\n useEntityList,\n type DefaultEntityFilters,\n} from '@backstage/plugin-catalog-react';\nimport { ToggleButton } from '@backstage/ui';\nimport { RiLayoutGridLine, RiListUnordered } from '@remixicon/react';\nimport { useCallback, useEffect, useMemo, useState } from 'react';\nimport { ANNOTATION_HAS_SPEC } from '../constants';\nimport { toApiCardViewModel, type ApiCardViewModel } from './apiCardViewModel';\nimport { ApiCardGrid, type ViewMode } from './ApiCardGrid';\nimport { ApiDetailsDrawer } from './ApiDetailsDrawer';\nimport {\n ApiKindFilter,\n isApigeeEntity,\n type ApiSearchFilter,\n type FieldFacetFilter,\n} from './apigeeFacetFilters';\nimport { ApigeeOrgFilter } from './apigeeOrgFilter';\nimport { isActive } from './apigeeSearchParams';\nimport { CountCards } from './CountCards';\nimport { deriveCounts, deriveFacets } from './facetModel';\nimport { FilterToolbar } from './FilterToolbar';\nimport { SearchBar } from './SearchBar';\nimport {\n ApiCatalogEmptyState,\n ApiCatalogError,\n NoMatchState,\n SkeletonGrid,\n} from './states';\nimport { useApigeeFilters } from './useApigeeFilters';\n\n/**\n * Entity-list filters registered on the Apigee catalog page. `apigeeKind` (the seam-free\n * `ApiKindFilter`) and `apigeeOrg` (the dual-key is-Apigee gate) are the backend filters applied\n * once by {@link ApplyApigeeFilters}; the facet + search filters\n * (`apigeeLifecycle`/`apigeeOrgFacet`/`apigeeOwner`/`apigeeDepartment`/`apigeeSearch`)\n * are driven from the URL by `useApigeeFilters`. Exported so the hook can import the filter contract.\n */\nexport type ApigeeFilters = DefaultEntityFilters & {\n apigeeKind?: ApiKindFilter;\n apigeeOrg?: ApigeeOrgFilter;\n apigeeLifecycle?: FieldFacetFilter;\n apigeeOrgFacet?: FieldFacetFilter;\n apigeeOwner?: FieldFacetFilter;\n apigeeDepartment?: FieldFacetFilter;\n apigeeSearch?: ApiSearchFilter;\n};\n\n/**\n * Registers the Apigee backend filters on the shared EntityListProvider ONCE: the seam-free\n * `ApiKindFilter` (kind=api with NO `toQueryValue`, so the provider's URL writer stays a no-op and\n * `useSearchParams` owns a clean URL) plus the dual-key `ApigeeOrgFilter` is-Apigee gate. The facet\n * + search filters are applied separately, URL-driven, by `useApigeeFilters`. Rendered inside the\n * provider; renders nothing itself.\n */\nfunction ApplyApigeeFilters() {\n const { updateFilters } = useEntityList<ApigeeFilters>();\n useEffect(() => {\n updateFilters({\n apigeeKind: new ApiKindFilter(),\n apigeeOrg: new ApigeeOrgFilter(),\n });\n }, [updateFilters]);\n return null;\n}\n\n/**\n * The page body: reads the filtered entity list, maps to view-models, and branches on\n * loading/empty/error. Exposes a Flat/List view toggle (component state only, no view\n * URL param — that is a Phase 6 seam). (UI-01, UI-05, UI-11)\n */\nexport function ApigeeCatalogContent() {\n const { entities, backendEntities, loading, error } =\n useEntityList<ApigeeFilters>();\n const {\n state,\n inputValue,\n setInputValue,\n toggleFacet,\n selectOnlyFacet,\n clearFacet,\n clearAll,\n } = useApigeeFilters();\n const configApi = useApi(configApiRef);\n\n const orgLabels = useMemo<Record<string, string> | undefined>(() => {\n const config = configApi.getOptionalConfig('apigee.catalog.orgLabels');\n if (!config) {\n return undefined;\n }\n const out: Record<string, string> = {};\n for (const key of config.keys()) {\n const value = config.getOptionalString(key);\n if (value) {\n out[key] = value;\n }\n }\n return Object.keys(out).length > 0 ? out : undefined;\n }, [configApi]);\n\n const apigeeEntities = useMemo(\n () => backendEntities.filter(isApigeeEntity),\n [backendEntities],\n );\n const vms = useMemo(() => entities.map(toApiCardViewModel), [entities]);\n const facets = useMemo(\n () => deriveFacets(apigeeEntities, orgLabels),\n [apigeeEntities, orgLabels],\n );\n // Static full-catalog counts: the cards stay fixed as filters apply; only the grid narrows.\n const counts = useMemo(\n () => deriveCounts(apigeeEntities, ['org', 'lifecycle', 'department'], orgLabels),\n [apigeeEntities, orgLabels],\n );\n const specCount = useMemo(\n () =>\n apigeeEntities.filter(\n entity => entity.metadata.annotations?.[ANNOTATION_HAS_SPEC] === 'true',\n ).length,\n [apigeeEntities],\n );\n const active = isActive(state);\n const [viewMode, setViewMode] = useState<ViewMode>('flat');\n\n // Clicking a card/row opens a details drawer instead of navigating to the catalog\n // entity page. The vm carries only a targetRef, so resolve the full entity by ref.\n const [selected, setSelected] = useState<Entity | undefined>();\n const entitiesByRef = useMemo(() => {\n const map = new Map<string, Entity>();\n for (const entity of entities) {\n const namespace = entity.metadata.namespace ?? 'default';\n map.set(`${namespace}/${entity.metadata.name}`, entity);\n }\n return map;\n }, [entities]);\n const handleSelect = useCallback(\n (vm: ApiCardViewModel) => {\n const { namespace, name } = vm.targetRef;\n setSelected(entitiesByRef.get(`${namespace}/${name}`));\n },\n [entitiesByRef],\n );\n const handleClose = useCallback(() => setSelected(undefined), []);\n\n const renderBody = () => {\n if (error) {\n return <ApiCatalogError error={error} />;\n }\n if (loading) {\n return <SkeletonGrid />;\n }\n if (vms.length === 0) {\n return active ? (\n <NoMatchState onClearAll={clearAll} />\n ) : (\n <ApiCatalogEmptyState />\n );\n }\n return <ApiCardGrid vms={vms} viewMode={viewMode} onSelect={handleSelect} />;\n };\n\n const viewToggle = (\n <div\n role=\"group\"\n aria-label=\"API view mode\"\n style={{ display: 'inline-flex', gap: 'var(--bui-space-1)' }}\n >\n <ToggleButton\n aria-label=\"Flat grid view\"\n isSelected={viewMode === 'flat'}\n onChange={() => setViewMode('flat')}\n iconStart={<RiLayoutGridLine />}\n >\n Flat\n </ToggleButton>\n <ToggleButton\n aria-label=\"List view\"\n isSelected={viewMode === 'list'}\n onChange={() => setViewMode('list')}\n iconStart={<RiListUnordered />}\n >\n List\n </ToggleButton>\n </div>\n );\n\n return (\n <Page themeId=\"apis\">\n <Content>\n {!loading && !error && apigeeEntities.length > 0 ? (\n <>\n <CountCards\n total={apigeeEntities.length}\n specCount={specCount}\n counts={counts}\n selected={state.selected}\n onSelectFacet={selectOnlyFacet}\n />\n <FilterToolbar\n facets={facets}\n selected={state.selected}\n onToggleFacet={toggleFacet}\n onClearFacet={clearFacet}\n onClearAll={clearAll}\n active={active}\n resultCount={vms.length}\n searchBar={\n <SearchBar value={inputValue} onChange={setInputValue} />\n }\n viewToggle={viewToggle}\n />\n </>\n ) : null}\n {renderBody()}\n </Content>\n <ApiDetailsDrawer\n entity={selected}\n orgLabels={orgLabels}\n onClose={handleClose}\n />\n </Page>\n );\n}\n\n/**\n * Route target for `/apigee` (05-06). Wraps the content in an `EntityListProvider` and\n * registers the Apigee filters — the shared filter context Phase 6's facets + search reuse.\n */\nexport function ApigeeApiCatalogPage() {\n return (\n <EntityListProvider>\n <ApplyApigeeFilters />\n <ApigeeCatalogContent />\n </EntityListProvider>\n );\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -4,6 +4,7 @@ import styles from './CountCards.module.css.esm.js';
|
|
|
4
4
|
|
|
5
5
|
function CountCards({
|
|
6
6
|
total,
|
|
7
|
+
specCount,
|
|
7
8
|
counts,
|
|
8
9
|
selected,
|
|
9
10
|
onSelectFacet
|
|
@@ -31,6 +32,28 @@ function CountCards({
|
|
|
31
32
|
}
|
|
32
33
|
)
|
|
33
34
|
] }),
|
|
35
|
+
/* @__PURE__ */ jsxs("div", { role: "group", "aria-label": "With specs", className: styles.card, children: [
|
|
36
|
+
/* @__PURE__ */ jsx(
|
|
37
|
+
Text,
|
|
38
|
+
{
|
|
39
|
+
as: "p",
|
|
40
|
+
variant: "title-large",
|
|
41
|
+
weight: "bold",
|
|
42
|
+
className: styles.total,
|
|
43
|
+
children: specCount
|
|
44
|
+
}
|
|
45
|
+
),
|
|
46
|
+
/* @__PURE__ */ jsx(
|
|
47
|
+
Text,
|
|
48
|
+
{
|
|
49
|
+
as: "h3",
|
|
50
|
+
variant: "body-x-small",
|
|
51
|
+
color: "secondary",
|
|
52
|
+
className: styles.cardTitle,
|
|
53
|
+
children: "With specs"
|
|
54
|
+
}
|
|
55
|
+
)
|
|
56
|
+
] }),
|
|
34
57
|
counts.map((count) => {
|
|
35
58
|
const heading = `By ${count.label.toLowerCase()}`;
|
|
36
59
|
return /* @__PURE__ */ jsxs(
|