@backstage/plugin-catalog 0.7.9 → 0.7.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +37 -0
- package/dist/esm/index-9e441058.esm.js.map +1 -1
- package/dist/index.d.ts +4 -0
- package/package.json +10 -10
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,42 @@
|
|
|
1
1
|
# @backstage/plugin-catalog
|
|
2
2
|
|
|
3
|
+
## 0.7.11
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- Updated dependencies
|
|
8
|
+
- @backstage/core-components@0.8.7
|
|
9
|
+
- @backstage/plugin-catalog-react@0.6.13
|
|
10
|
+
- @backstage/plugin-catalog-common@0.1.2
|
|
11
|
+
- @backstage/integration-react@0.1.20
|
|
12
|
+
|
|
13
|
+
## 0.7.11-next.1
|
|
14
|
+
|
|
15
|
+
### Patch Changes
|
|
16
|
+
|
|
17
|
+
- Updated dependencies
|
|
18
|
+
- @backstage/core-components@0.8.7-next.1
|
|
19
|
+
- @backstage/plugin-catalog-react@0.6.13-next.1
|
|
20
|
+
- @backstage/plugin-catalog-common@0.1.2-next.0
|
|
21
|
+
|
|
22
|
+
## 0.7.11-next.0
|
|
23
|
+
|
|
24
|
+
### Patch Changes
|
|
25
|
+
|
|
26
|
+
- Updated dependencies
|
|
27
|
+
- @backstage/core-components@0.8.7-next.0
|
|
28
|
+
- @backstage/integration-react@0.1.20-next.0
|
|
29
|
+
- @backstage/plugin-catalog-react@0.6.13-next.0
|
|
30
|
+
|
|
31
|
+
## 0.7.10
|
|
32
|
+
|
|
33
|
+
### Patch Changes
|
|
34
|
+
|
|
35
|
+
- aac316279f: Deprecated `EntitySystemDiagramCard`
|
|
36
|
+
`EntitySystemDiagramCard` is replaced by `EntityCatalogGraphCard` which is imported from `@backstage/plugin-catalog-graph`. This component will be removed in an upcoming release
|
|
37
|
+
- Updated dependencies
|
|
38
|
+
- @backstage/core-components@0.8.6
|
|
39
|
+
|
|
3
40
|
## 0.7.9
|
|
4
41
|
|
|
5
42
|
### Patch Changes
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index-9e441058.esm.js","sources":["../../src/CatalogClientWrapper.ts","../../src/routes.ts","../../src/components/AboutCard/AboutField.tsx","../../src/components/AboutCard/AboutContent.tsx","../../src/components/AboutCard/AboutCard.tsx","../../src/components/CatalogKindHeader/CatalogKindHeader.tsx","../../src/components/CatalogResultListItem/CatalogResultListItem.tsx","../../src/components/CatalogTable/columns.tsx","../../src/components/CatalogTable/CatalogTable.tsx","../../src/components/EntityContextMenu/EntityContextMenu.tsx","../../src/components/EntityLayout/EntityLayout.tsx","../../src/components/EntityOrphanWarning/DeleteEntityDialog.tsx","../../src/components/EntityOrphanWarning/EntityOrphanWarning.tsx","../../src/components/EntityProcessingErrorsPanel/EntityProcessingErrorsPanel.tsx","../../src/components/EntityPageLayout/Tabbed/Tabbed.tsx","../../src/components/EntityPageLayout/EntityPageLayout.tsx","../../src/components/EntitySwitch/EntitySwitch.tsx","../../src/components/EntitySwitch/conditions.ts","../../src/components/FilteredEntityLayout/FilteredEntityLayout.tsx","../../src/components/FilteredEntityLayout/FilterContainer.tsx","../../src/components/FilteredEntityLayout/EntityListContainer.tsx","../../src/components/CatalogPage/DefaultCatalogPage.tsx","../../src/components/CatalogPage/CatalogPage.tsx","../../src/components/EntityNotFound/Illo/Illo.tsx","../../src/components/EntityNotFound/EntityNotFound.tsx","../../src/components/Router.tsx","../../src/plugin.ts"],"sourcesContent":["/*\n * Copyright 2020 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { Entity, EntityName, Location } from '@backstage/catalog-model';\nimport {\n AddLocationRequest,\n AddLocationResponse,\n CatalogApi,\n CatalogClient,\n CatalogEntitiesRequest,\n CatalogListResponse,\n CatalogRequestOptions,\n CatalogEntityAncestorsRequest,\n CatalogEntityAncestorsResponse,\n} from '@backstage/catalog-client';\nimport { IdentityApi } from '@backstage/core-plugin-api';\n\n/**\n * CatalogClient wrapper that injects identity token for all requests\n *\n * @deprecated The default catalog client now uses the `fetchApiRef`\n * implementation, which in turn by default issues tokens just the same as this\n * class used to assist in doing. If you use a custom `fetchApiRef`\n * implementation that does NOT issue tokens, or use a custom `catalogApiRef`\n * implementation which does not use the default `fetchApiRef`, you can wrap\n * your catalog API in this class to get back the old behavior.\n */\nexport class CatalogClientWrapper implements CatalogApi {\n private readonly identityApi: IdentityApi;\n private readonly client: CatalogClient;\n\n constructor(options: { client: CatalogClient; identityApi: IdentityApi }) {\n this.client = options.client;\n this.identityApi = options.identityApi;\n }\n\n async getLocationById(\n id: string,\n options?: CatalogRequestOptions,\n ): Promise<Location | undefined> {\n return await this.client.getLocationById(\n id,\n await this.getCredentials(options),\n );\n }\n\n async getEntities(\n request?: CatalogEntitiesRequest,\n options?: CatalogRequestOptions,\n ): Promise<CatalogListResponse<Entity>> {\n return await this.client.getEntities(\n request,\n await this.getCredentials(options),\n );\n }\n\n async getEntityByName(\n compoundName: EntityName,\n options?: CatalogRequestOptions,\n ): Promise<Entity | undefined> {\n return await this.client.getEntityByName(\n compoundName,\n await this.getCredentials(options),\n );\n }\n\n async addLocation(\n request: AddLocationRequest,\n options?: CatalogRequestOptions,\n ): Promise<AddLocationResponse> {\n return await this.client.addLocation(\n request,\n await this.getCredentials(options),\n );\n }\n\n async getOriginLocationByEntity(\n entity: Entity,\n options?: CatalogRequestOptions,\n ): Promise<Location | undefined> {\n return await this.client.getOriginLocationByEntity(\n entity,\n await this.getCredentials(options),\n );\n }\n\n async getLocationByEntity(\n entity: Entity,\n options?: CatalogRequestOptions,\n ): Promise<Location | undefined> {\n return await this.client.getLocationByEntity(\n entity,\n await this.getCredentials(options),\n );\n }\n\n async removeLocationById(\n id: string,\n options?: CatalogRequestOptions,\n ): Promise<void> {\n return await this.client.removeLocationById(\n id,\n await this.getCredentials(options),\n );\n }\n\n async removeEntityByUid(\n uid: string,\n options?: CatalogRequestOptions,\n ): Promise<void> {\n return await this.client.removeEntityByUid(\n uid,\n await this.getCredentials(options),\n );\n }\n\n async refreshEntity(\n entityRef: string,\n options?: CatalogRequestOptions,\n ): Promise<void> {\n return await this.client.refreshEntity(\n entityRef,\n await this.getCredentials(options),\n );\n }\n\n async getEntityAncestors(\n request: CatalogEntityAncestorsRequest,\n options?: CatalogRequestOptions,\n ): Promise<CatalogEntityAncestorsResponse> {\n return await this.client.getEntityAncestors(\n request,\n await this.getCredentials(options),\n );\n }\n\n private async getCredentials(\n options?: CatalogRequestOptions,\n ): Promise<{ token?: string }> {\n if (options?.token) {\n return { token: options?.token };\n }\n return this.identityApi.getCredentials();\n }\n}\n","/*\n * Copyright 2021 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { createExternalRouteRef } from '@backstage/core-plugin-api';\n\nexport const createComponentRouteRef = createExternalRouteRef({\n id: 'create-component',\n optional: true,\n});\n\nexport const viewTechDocRouteRef = createExternalRouteRef({\n id: 'view-techdoc',\n optional: true,\n params: ['namespace', 'kind', 'name'],\n});\n","/*\n * Copyright 2020 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { useElementFilter } from '@backstage/core-plugin-api';\nimport { Grid, makeStyles, Typography } from '@material-ui/core';\nimport React from 'react';\n\nconst useStyles = makeStyles(theme => ({\n value: {\n fontWeight: 'bold',\n overflow: 'hidden',\n lineHeight: '24px',\n wordBreak: 'break-word',\n },\n label: {\n color: theme.palette.text.secondary,\n textTransform: 'uppercase',\n fontSize: '10px',\n fontWeight: 'bold',\n letterSpacing: 0.5,\n overflow: 'hidden',\n whiteSpace: 'nowrap',\n },\n}));\n\ntype Props = {\n label: string;\n value?: string;\n gridSizes?: Record<string, number>;\n children?: React.ReactNode;\n};\n\nexport const AboutField = ({ label, value, gridSizes, children }: Props) => {\n const classes = useStyles();\n\n const childElements = useElementFilter(children, c => c.getElements());\n\n // Content is either children or a string prop `value`\n const content =\n childElements.length > 0 ? (\n childElements\n ) : (\n <Typography variant=\"body2\" className={classes.value}>\n {value || `unknown`}\n </Typography>\n );\n return (\n <Grid item {...gridSizes}>\n <Typography variant=\"subtitle2\" className={classes.label}>\n {label}\n </Typography>\n {content}\n </Grid>\n );\n};\n","/*\n * Copyright 2020 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n Entity,\n RELATION_OWNED_BY,\n RELATION_PART_OF,\n} from '@backstage/catalog-model';\nimport {\n EntityRefLinks,\n getEntityRelations,\n} from '@backstage/plugin-catalog-react';\nimport { Chip, Grid, makeStyles, Typography } from '@material-ui/core';\nimport React from 'react';\nimport { AboutField } from './AboutField';\n\nconst useStyles = makeStyles({\n description: {\n wordBreak: 'break-word',\n },\n});\n\ntype Props = {\n entity: Entity;\n};\n\nexport const AboutContent = ({ entity }: Props) => {\n const classes = useStyles();\n const isSystem = entity.kind.toLocaleLowerCase('en-US') === 'system';\n const isResource = entity.kind.toLocaleLowerCase('en-US') === 'resource';\n const isComponent = entity.kind.toLocaleLowerCase('en-US') === 'component';\n const isAPI = entity.kind.toLocaleLowerCase('en-US') === 'api';\n const isTemplate = entity.kind.toLocaleLowerCase('en-US') === 'template';\n const isLocation = entity.kind.toLocaleLowerCase('en-US') === 'location';\n const isGroup = entity.kind.toLocaleLowerCase('en-US') === 'group';\n\n const partOfSystemRelations = getEntityRelations(entity, RELATION_PART_OF, {\n kind: 'system',\n });\n const partOfComponentRelations = getEntityRelations(\n entity,\n RELATION_PART_OF,\n {\n kind: 'component',\n },\n );\n const partOfDomainRelations = getEntityRelations(entity, RELATION_PART_OF, {\n kind: 'domain',\n });\n const ownedByRelations = getEntityRelations(entity, RELATION_OWNED_BY);\n\n return (\n <Grid container>\n <AboutField label=\"Description\" gridSizes={{ xs: 12 }}>\n <Typography variant=\"body2\" paragraph className={classes.description}>\n {entity?.metadata?.description || 'No description'}\n </Typography>\n </AboutField>\n <AboutField\n label=\"Owner\"\n value=\"No Owner\"\n gridSizes={{ xs: 12, sm: 6, lg: 4 }}\n >\n {ownedByRelations.length > 0 && (\n <EntityRefLinks entityRefs={ownedByRelations} defaultKind=\"group\" />\n )}\n </AboutField>\n {(isSystem || partOfDomainRelations.length > 0) && (\n <AboutField\n label=\"Domain\"\n value=\"No Domain\"\n gridSizes={{ xs: 12, sm: 6, lg: 4 }}\n >\n {partOfDomainRelations.length > 0 && (\n <EntityRefLinks\n entityRefs={partOfDomainRelations}\n defaultKind=\"domain\"\n />\n )}\n </AboutField>\n )}\n {(isAPI ||\n isComponent ||\n isResource ||\n partOfSystemRelations.length > 0) && (\n <AboutField\n label=\"System\"\n value=\"No System\"\n gridSizes={{ xs: 12, sm: 6, lg: 4 }}\n >\n {partOfSystemRelations.length > 0 && (\n <EntityRefLinks\n entityRefs={partOfSystemRelations}\n defaultKind=\"system\"\n />\n )}\n </AboutField>\n )}\n {isComponent && partOfComponentRelations.length > 0 && (\n <AboutField\n label=\"Parent Component\"\n value=\"No Parent Component\"\n gridSizes={{ xs: 12, sm: 6, lg: 4 }}\n >\n <EntityRefLinks\n entityRefs={partOfComponentRelations}\n defaultKind=\"component\"\n />\n </AboutField>\n )}\n {(isAPI ||\n isComponent ||\n isResource ||\n isTemplate ||\n isGroup ||\n isLocation ||\n typeof entity?.spec?.type === 'string') && (\n <AboutField\n label=\"Type\"\n value={entity?.spec?.type as string}\n gridSizes={{ xs: 12, sm: 6, lg: 4 }}\n />\n )}\n {(isAPI ||\n isComponent ||\n typeof entity?.spec?.lifecycle === 'string') && (\n <AboutField\n label=\"Lifecycle\"\n value={entity?.spec?.lifecycle as string}\n gridSizes={{ xs: 12, sm: 6, lg: 4 }}\n />\n )}\n <AboutField\n label=\"Tags\"\n value=\"No Tags\"\n gridSizes={{ xs: 12, sm: 6, lg: 4 }}\n >\n {(entity?.metadata?.tags || []).map(t => (\n <Chip key={t} size=\"small\" label={t} />\n ))}\n </AboutField>\n </Grid>\n );\n};\n","/*\n * Copyright 2020 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n Entity,\n ENTITY_DEFAULT_NAMESPACE,\n LOCATION_ANNOTATION,\n stringifyEntityRef,\n} from '@backstage/catalog-model';\nimport {\n HeaderIconLinkRow,\n IconLinkVerticalProps,\n InfoCardVariants,\n Link,\n} from '@backstage/core-components';\nimport { alertApiRef, useApi, useRouteRef } from '@backstage/core-plugin-api';\nimport {\n ScmIntegrationIcon,\n scmIntegrationsApiRef,\n} from '@backstage/integration-react';\nimport {\n catalogApiRef,\n getEntityMetadataEditUrl,\n getEntitySourceLocation,\n useEntity,\n} from '@backstage/plugin-catalog-react';\nimport {\n Card,\n CardContent,\n CardHeader,\n Divider,\n IconButton,\n makeStyles,\n} from '@material-ui/core';\nimport CachedIcon from '@material-ui/icons/Cached';\nimport DocsIcon from '@material-ui/icons/Description';\nimport EditIcon from '@material-ui/icons/Edit';\nimport React, { useCallback } from 'react';\nimport { viewTechDocRouteRef } from '../../routes';\nimport { AboutContent } from './AboutContent';\n\nconst useStyles = makeStyles({\n gridItemCard: {\n display: 'flex',\n flexDirection: 'column',\n height: 'calc(100% - 10px)', // for pages without content header\n marginBottom: '10px',\n },\n fullHeightCard: {\n display: 'flex',\n flexDirection: 'column',\n height: '100%',\n },\n gridItemCardContent: {\n flex: 1,\n },\n fullHeightCardContent: {\n flex: 1,\n },\n});\n\ntype AboutCardProps = {\n /** @deprecated The entity is now grabbed from context instead */\n entity?: Entity;\n variant?: InfoCardVariants;\n};\n\nexport function AboutCard({ variant }: AboutCardProps) {\n const classes = useStyles();\n const { entity } = useEntity();\n const scmIntegrationsApi = useApi(scmIntegrationsApiRef);\n const catalogApi = useApi(catalogApiRef);\n const alertApi = useApi(alertApiRef);\n const viewTechdocLink = useRouteRef(viewTechDocRouteRef);\n\n const entitySourceLocation = getEntitySourceLocation(\n entity,\n scmIntegrationsApi,\n );\n const entityMetadataEditUrl = getEntityMetadataEditUrl(entity);\n\n const viewInSource: IconLinkVerticalProps = {\n label: 'View Source',\n disabled: !entitySourceLocation,\n icon: <ScmIntegrationIcon type={entitySourceLocation?.integrationType} />,\n href: entitySourceLocation?.locationTargetUrl,\n };\n const viewInTechDocs: IconLinkVerticalProps = {\n label: 'View TechDocs',\n disabled:\n !entity.metadata.annotations?.['backstage.io/techdocs-ref'] ||\n !viewTechdocLink,\n icon: <DocsIcon />,\n href:\n viewTechdocLink &&\n viewTechdocLink({\n namespace: entity.metadata.namespace || ENTITY_DEFAULT_NAMESPACE,\n kind: entity.kind,\n name: entity.metadata.name,\n }),\n };\n\n let cardClass = '';\n if (variant === 'gridItem') {\n cardClass = classes.gridItemCard;\n } else if (variant === 'fullHeight') {\n cardClass = classes.fullHeightCard;\n }\n\n let cardContentClass = '';\n if (variant === 'gridItem') {\n cardContentClass = classes.gridItemCardContent;\n } else if (variant === 'fullHeight') {\n cardContentClass = classes.fullHeightCardContent;\n }\n\n const entityLocation = entity.metadata.annotations?.[LOCATION_ANNOTATION];\n // Limiting the ability to manually refresh to the less expensive locations\n const allowRefresh =\n entityLocation?.startsWith('url:') || entityLocation?.startsWith('file:');\n const refreshEntity = useCallback(async () => {\n await catalogApi.refreshEntity(stringifyEntityRef(entity));\n alertApi.post({ message: 'Refresh scheduled', severity: 'info' });\n }, [catalogApi, alertApi, entity]);\n\n return (\n <Card className={cardClass}>\n <CardHeader\n title=\"About\"\n action={\n <>\n {allowRefresh && (\n <IconButton\n aria-label=\"Refresh\"\n title=\"Schedule entity refresh\"\n onClick={refreshEntity}\n >\n <CachedIcon />\n </IconButton>\n )}\n <IconButton\n component={Link}\n aria-label=\"Edit\"\n disabled={!entityMetadataEditUrl}\n title=\"Edit Metadata\"\n to={entityMetadataEditUrl ?? '#'}\n >\n <EditIcon />\n </IconButton>\n </>\n }\n subheader={<HeaderIconLinkRow links={[viewInSource, viewInTechDocs]} />}\n />\n <Divider />\n <CardContent className={cardContentClass}>\n <AboutContent entity={entity} />\n </CardContent>\n </Card>\n );\n}\n","/*\n * Copyright 2021 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport React, { useEffect, useState } from 'react';\nimport {\n capitalize,\n createStyles,\n InputBase,\n makeStyles,\n MenuItem,\n Select,\n Theme,\n} from '@material-ui/core';\nimport {\n EntityKindFilter,\n useEntityKinds,\n useEntityListProvider,\n} from '@backstage/plugin-catalog-react';\n\nconst useStyles = makeStyles((theme: Theme) =>\n createStyles({\n root: {\n ...theme.typography.h4,\n },\n }),\n);\n\ntype CatalogKindHeaderProps = {\n initialFilter?: string;\n};\n\nexport const CatalogKindHeader = ({\n initialFilter = 'component',\n}: CatalogKindHeaderProps) => {\n const classes = useStyles();\n const { kinds: allKinds = [] } = useEntityKinds();\n const { updateFilters, queryParameters } = useEntityListProvider();\n\n const [selectedKind, setSelectedKind] = useState(\n ([queryParameters.kind].flat()[0] ?? initialFilter).toLocaleLowerCase(\n 'en-US',\n ),\n );\n\n useEffect(() => {\n updateFilters({\n kind: selectedKind ? new EntityKindFilter(selectedKind) : undefined,\n });\n }, [selectedKind, updateFilters]);\n\n // Before allKinds is loaded, or when a kind is entered manually in the URL, selectedKind may not\n // be present in allKinds. It should still be shown in the dropdown, but may not have the nice\n // enforced casing from the catalog-backend. This makes a key/value record for the Select options,\n // including selectedKind if it's unknown - but allows the selectedKind to get clobbered by the\n // more proper catalog kind if it exists.\n const options = [capitalize(selectedKind)]\n .concat(allKinds)\n .sort()\n .reduce((acc, kind) => {\n acc[kind.toLocaleLowerCase('en-US')] = kind;\n return acc;\n }, {} as Record<string, string>);\n\n return (\n <Select\n input={<InputBase value={selectedKind} />}\n value={selectedKind}\n onChange={e => setSelectedKind(e.target.value as string)}\n classes={classes}\n >\n {Object.keys(options).map(kind => (\n <MenuItem value={kind} key={kind}>\n {`${options[kind]}s`}\n </MenuItem>\n ))}\n </Select>\n );\n};\n","/*\n * Copyright 2021 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport React from 'react';\nimport {\n Box,\n Chip,\n Divider,\n ListItem,\n ListItemText,\n makeStyles,\n} from '@material-ui/core';\nimport { Link } from '@backstage/core-components';\n\nconst useStyles = makeStyles({\n flexContainer: {\n flexWrap: 'wrap',\n },\n itemText: {\n width: '100%',\n wordBreak: 'break-all',\n marginBottom: '1rem',\n },\n});\n\nexport const CatalogResultListItem = ({ result }: any) => {\n const classes = useStyles();\n return (\n <Link to={result.location}>\n <ListItem alignItems=\"flex-start\" className={classes.flexContainer}>\n <ListItemText\n className={classes.itemText}\n primaryTypographyProps={{ variant: 'h6' }}\n primary={result.title}\n secondary={result.text}\n />\n <Box>\n {result.kind && <Chip label={`Kind: ${result.kind}`} size=\"small\" />}\n {result.lifecycle && (\n <Chip label={`Lifecycle: ${result.lifecycle}`} size=\"small\" />\n )}\n </Box>\n </ListItem>\n <Divider component=\"li\" />\n </Link>\n );\n};\n","/*\n * Copyright 2021 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport React from 'react';\nimport {\n formatEntityRefTitle,\n EntityRefLink,\n EntityRefLinks,\n} from '@backstage/plugin-catalog-react';\nimport { Chip } from '@material-ui/core';\nimport { EntityRow } from './types';\nimport { OverflowTooltip, TableColumn } from '@backstage/core-components';\nimport { Entity } from '@backstage/catalog-model';\n\ntype NameColumnProps = {\n defaultKind?: string;\n};\n\nexport function createNameColumn(\n props?: NameColumnProps,\n): TableColumn<EntityRow> {\n function formatContent(entity: Entity): string {\n return (\n entity.metadata?.title ||\n formatEntityRefTitle(entity, {\n defaultKind: props?.defaultKind,\n })\n );\n }\n\n return {\n title: 'Name',\n field: 'resolved.name',\n highlight: true,\n customSort({ entity: entity1 }, { entity: entity2 }) {\n // TODO: We could implement this more efficiently by comparing field by field.\n // This has similar issues as above.\n return formatContent(entity1).localeCompare(formatContent(entity2));\n },\n render: ({ entity }) => (\n <EntityRefLink\n entityRef={entity}\n defaultKind={props?.defaultKind || 'Component'}\n title={entity.metadata?.title}\n />\n ),\n };\n}\n\nexport function createSystemColumn(): TableColumn<EntityRow> {\n return {\n title: 'System',\n field: 'resolved.partOfSystemRelationTitle',\n render: ({ resolved }) => (\n <EntityRefLinks\n entityRefs={resolved.partOfSystemRelations}\n defaultKind=\"system\"\n />\n ),\n };\n}\n\nexport function createOwnerColumn(): TableColumn<EntityRow> {\n return {\n title: 'Owner',\n field: 'resolved.ownedByRelationsTitle',\n render: ({ resolved }) => (\n <EntityRefLinks\n entityRefs={resolved.ownedByRelations}\n defaultKind=\"group\"\n />\n ),\n };\n}\n\nexport function createSpecTypeColumn(): TableColumn<EntityRow> {\n return {\n title: 'Type',\n field: 'entity.spec.type',\n hidden: true,\n };\n}\n\nexport function createSpecLifecycleColumn(): TableColumn<EntityRow> {\n return {\n title: 'Lifecycle',\n field: 'entity.spec.lifecycle',\n };\n}\n\nexport function createMetadataDescriptionColumn(): TableColumn<EntityRow> {\n return {\n title: 'Description',\n field: 'entity.metadata.description',\n render: ({ entity }) => (\n <OverflowTooltip\n text={entity.metadata.description}\n placement=\"bottom-start\"\n />\n ),\n width: 'auto',\n };\n}\n\nexport function createTagsColumn(): TableColumn<EntityRow> {\n return {\n title: 'Tags',\n field: 'entity.metadata.tags',\n cellStyle: {\n padding: '0px 16px 0px 20px',\n },\n render: ({ entity }) => (\n <>\n {entity.metadata.tags &&\n entity.metadata.tags.map(t => (\n <Chip\n key={t}\n label={t}\n size=\"small\"\n variant=\"outlined\"\n style={{ marginBottom: '0px' }}\n />\n ))}\n </>\n ),\n };\n}\n","/*\n * Copyright 2020 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport { RELATION_OWNED_BY, RELATION_PART_OF } from '@backstage/catalog-model';\nimport {\n favoriteEntityIcon,\n favoriteEntityTooltip,\n formatEntityRefTitle,\n getEntityMetadataEditUrl,\n getEntityMetadataViewUrl,\n getEntityRelations,\n useEntityListProvider,\n useStarredEntities,\n} from '@backstage/plugin-catalog-react';\nimport Edit from '@material-ui/icons/Edit';\nimport OpenInNew from '@material-ui/icons/OpenInNew';\nimport { capitalize } from 'lodash';\nimport React, { useMemo } from 'react';\nimport * as columnFactories from './columns';\nimport { EntityRow } from './types';\nimport {\n CodeSnippet,\n Table,\n TableColumn,\n TableProps,\n WarningPanel,\n} from '@backstage/core-components';\n\ntype CatalogTableProps = {\n columns?: TableColumn<EntityRow>[];\n actions?: TableProps<EntityRow>['actions'];\n};\n\nexport const CatalogTable = ({ columns, actions }: CatalogTableProps) => {\n const { isStarredEntity, toggleStarredEntity } = useStarredEntities();\n const { loading, error, entities, filters } = useEntityListProvider();\n\n const defaultColumns: TableColumn<EntityRow>[] = useMemo(\n () => [\n columnFactories.createNameColumn({ defaultKind: filters.kind?.value }),\n columnFactories.createSystemColumn(),\n columnFactories.createOwnerColumn(),\n columnFactories.createSpecTypeColumn(),\n columnFactories.createSpecLifecycleColumn(),\n columnFactories.createMetadataDescriptionColumn(),\n columnFactories.createTagsColumn(),\n ],\n [filters.kind?.value],\n );\n\n const showTypeColumn = filters.type === undefined;\n // TODO(timbonicus): remove the title from the CatalogTable once using EntitySearchBar\n const titlePreamble = capitalize(filters.user?.value ?? 'all');\n\n if (error) {\n return (\n <div>\n <WarningPanel\n severity=\"error\"\n title=\"Could not fetch catalog entities.\"\n >\n <CodeSnippet language=\"text\" text={error.toString()} />\n </WarningPanel>\n </div>\n );\n }\n\n const defaultActions: TableProps<EntityRow>['actions'] = [\n ({ entity }) => {\n const url = getEntityMetadataViewUrl(entity);\n return {\n icon: () => <OpenInNew aria-label=\"View\" fontSize=\"small\" />,\n tooltip: 'View',\n disabled: !url,\n onClick: () => {\n if (!url) return;\n window.open(url, '_blank');\n },\n };\n },\n ({ entity }) => {\n const url = getEntityMetadataEditUrl(entity);\n return {\n icon: () => <Edit aria-label=\"Edit\" fontSize=\"small\" />,\n tooltip: 'Edit',\n disabled: !url,\n onClick: () => {\n if (!url) return;\n window.open(url, '_blank');\n },\n };\n },\n ({ entity }) => {\n const isStarred = isStarredEntity(entity);\n return {\n cellStyle: { paddingLeft: '1em' },\n icon: () => favoriteEntityIcon(isStarred),\n tooltip: favoriteEntityTooltip(isStarred),\n onClick: () => toggleStarredEntity(entity),\n };\n },\n ];\n\n const rows = entities.map(entity => {\n const partOfSystemRelations = getEntityRelations(entity, RELATION_PART_OF, {\n kind: 'system',\n });\n const ownedByRelations = getEntityRelations(entity, RELATION_OWNED_BY);\n\n return {\n entity,\n resolved: {\n name: formatEntityRefTitle(entity, {\n defaultKind: 'Component',\n }),\n ownedByRelationsTitle: ownedByRelations\n .map(r => formatEntityRefTitle(r, { defaultKind: 'group' }))\n .join(', '),\n ownedByRelations,\n partOfSystemRelationTitle: partOfSystemRelations\n .map(r =>\n formatEntityRefTitle(r, {\n defaultKind: 'system',\n }),\n )\n .join(', '),\n partOfSystemRelations,\n },\n };\n });\n\n const typeColumn = (columns || defaultColumns).find(c => c.title === 'Type');\n if (typeColumn) {\n typeColumn.hidden = !showTypeColumn;\n }\n const showPagination = rows.length > 20;\n\n return (\n <Table<EntityRow>\n isLoading={loading}\n columns={columns || defaultColumns}\n options={{\n paging: showPagination,\n pageSize: 20,\n actionsColumnIndex: -1,\n loadingType: 'linear',\n showEmptyDataSourceMessage: !loading,\n padding: 'dense',\n pageSizeOptions: [20, 50, 100],\n }}\n title={`${titlePreamble} (${entities.length})`}\n data={rows}\n actions={actions || defaultActions}\n />\n );\n};\n\nCatalogTable.columns = columnFactories;\n","/*\n * Copyright 2020 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n Divider,\n IconButton,\n ListItemIcon,\n ListItemText,\n MenuItem,\n MenuList,\n Popover,\n} from '@material-ui/core';\nimport { makeStyles } from '@material-ui/core/styles';\nimport Cancel from '@material-ui/icons/Cancel';\nimport MoreVert from '@material-ui/icons/MoreVert';\nimport React, { useState } from 'react';\nimport { IconComponent } from '@backstage/core-plugin-api';\nimport { useEntityPermission } from '@backstage/plugin-catalog-react';\nimport { catalogEntityDeletePermission } from '@backstage/plugin-catalog-common';\n\n// TODO(freben): It should probably instead be the case that Header sets the theme text color to white inside itself unconditionally instead\nconst useStyles = makeStyles({\n button: {\n color: 'white',\n },\n});\n\n// NOTE(freben): Intentionally not exported at this point, since it's part of\n// the unstable extra context menu items concept below\ntype ExtraContextMenuItem = {\n title: string;\n Icon: IconComponent;\n onClick: () => void;\n};\n\n// unstable context menu option, eg: disable the unregister entity menu\ntype contextMenuOptions = {\n disableUnregister: boolean;\n};\n\ntype Props = {\n UNSTABLE_extraContextMenuItems?: ExtraContextMenuItem[];\n UNSTABLE_contextMenuOptions?: contextMenuOptions;\n onUnregisterEntity: () => void;\n};\n\nexport const EntityContextMenu = ({\n UNSTABLE_extraContextMenuItems,\n UNSTABLE_contextMenuOptions,\n onUnregisterEntity,\n}: Props) => {\n const [anchorEl, setAnchorEl] = useState<HTMLButtonElement>();\n const classes = useStyles();\n const unregisterPermission = useEntityPermission(\n catalogEntityDeletePermission,\n );\n\n const onOpen = (event: React.SyntheticEvent<HTMLButtonElement>) => {\n setAnchorEl(event.currentTarget);\n };\n\n const onClose = () => {\n setAnchorEl(undefined);\n };\n\n const extraItems = UNSTABLE_extraContextMenuItems && [\n ...UNSTABLE_extraContextMenuItems.map(item => (\n <MenuItem\n key={item.title}\n onClick={() => {\n onClose();\n item.onClick();\n }}\n >\n <ListItemIcon>\n <item.Icon fontSize=\"small\" />\n </ListItemIcon>\n <ListItemText primary={item.title} />\n </MenuItem>\n )),\n <Divider key=\"the divider is here!\" />,\n ];\n\n const disableUnregister =\n (!unregisterPermission.allowed ||\n UNSTABLE_contextMenuOptions?.disableUnregister) ??\n false;\n\n return (\n <>\n <IconButton\n aria-label=\"more\"\n aria-controls=\"long-menu\"\n aria-haspopup=\"true\"\n onClick={onOpen}\n data-testid=\"menu-button\"\n className={classes.button}\n >\n <MoreVert />\n </IconButton>\n <Popover\n open={Boolean(anchorEl)}\n onClose={onClose}\n anchorEl={anchorEl}\n anchorOrigin={{ vertical: 'bottom', horizontal: 'right' }}\n transformOrigin={{ vertical: 'top', horizontal: 'right' }}\n >\n <MenuList>\n {extraItems}\n <MenuItem\n onClick={() => {\n onClose();\n onUnregisterEntity();\n }}\n disabled={disableUnregister}\n >\n <ListItemIcon>\n <Cancel fontSize=\"small\" />\n </ListItemIcon>\n <ListItemText primary=\"Unregister entity\" />\n </MenuItem>\n </MenuList>\n </Popover>\n </>\n );\n};\n","/*\n * Copyright 2020 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n Entity,\n ENTITY_DEFAULT_NAMESPACE,\n RELATION_OWNED_BY,\n} from '@backstage/catalog-model';\nimport {\n Content,\n Header,\n HeaderLabel,\n Link,\n Page,\n Progress,\n RoutedTabs,\n WarningPanel,\n} from '@backstage/core-components';\nimport {\n attachComponentData,\n IconComponent,\n useElementFilter,\n} from '@backstage/core-plugin-api';\nimport {\n EntityContext,\n EntityRefLinks,\n FavoriteEntity,\n getEntityRelations,\n UnregisterEntityDialog,\n useEntityCompoundName,\n} from '@backstage/plugin-catalog-react';\nimport { Box, TabProps } from '@material-ui/core';\nimport { Alert } from '@material-ui/lab';\nimport React, { useContext, useState } from 'react';\nimport { useNavigate } from 'react-router';\nimport { EntityContextMenu } from '../EntityContextMenu/EntityContextMenu';\n\ntype SubRoute = {\n path: string;\n title: string;\n children: JSX.Element;\n if?: (entity: Entity) => boolean;\n tabProps?: TabProps<React.ElementType, { component?: React.ElementType }>;\n};\n\nconst dataKey = 'plugin.catalog.entityLayoutRoute';\n\nconst Route: (props: SubRoute) => null = () => null;\nattachComponentData(Route, dataKey, true);\n\n// This causes all mount points that are discovered within this route to use the path of the route itself\nattachComponentData(Route, 'core.gatherMountPoints', true);\n\nconst EntityLayoutTitle = ({\n entity,\n title,\n}: {\n title: string;\n entity: Entity | undefined;\n}) => {\n return (\n <Box display=\"inline-flex\" alignItems=\"center\" height=\"1em\" maxWidth=\"100%\">\n <Box\n component=\"span\"\n textOverflow=\"ellipsis\"\n whiteSpace=\"nowrap\"\n overflow=\"hidden\"\n >\n {title}\n </Box>\n {entity && <FavoriteEntity entity={entity} />}\n </Box>\n );\n};\n\nconst headerProps = (\n paramKind: string | undefined,\n paramNamespace: string | undefined,\n paramName: string | undefined,\n entity: Entity | undefined,\n): { headerTitle: string; headerType: string } => {\n const kind = paramKind ?? entity?.kind ?? '';\n const namespace = paramNamespace ?? entity?.metadata.namespace ?? '';\n const name =\n entity?.metadata.title ?? paramName ?? entity?.metadata.name ?? '';\n return {\n headerTitle: `${name}${\n namespace && namespace !== ENTITY_DEFAULT_NAMESPACE\n ? ` in ${namespace}`\n : ''\n }`,\n headerType: (() => {\n let t = kind.toLocaleLowerCase('en-US');\n if (entity && entity.spec && 'type' in entity.spec) {\n t += ' — ';\n t += (entity.spec as { type: string }).type.toLocaleLowerCase('en-US');\n }\n return t;\n })(),\n };\n};\n\nconst EntityLabels = ({ entity }: { entity: Entity }) => {\n const ownedByRelations = getEntityRelations(entity, RELATION_OWNED_BY);\n return (\n <>\n {ownedByRelations.length > 0 && (\n <HeaderLabel\n label=\"Owner\"\n value={\n <EntityRefLinks\n entityRefs={ownedByRelations}\n defaultKind=\"Group\"\n color=\"inherit\"\n />\n }\n />\n )}\n {entity.spec?.lifecycle && (\n <HeaderLabel label=\"Lifecycle\" value={entity.spec.lifecycle} />\n )}\n </>\n );\n};\n\n// NOTE(freben): Intentionally not exported at this point, since it's part of\n// the unstable extra context menu items concept below\ntype ExtraContextMenuItem = {\n title: string;\n Icon: IconComponent;\n onClick: () => void;\n};\n\n// unstable context menu option, eg: disable the unregister entity menu\ntype contextMenuOptions = {\n disableUnregister: boolean;\n};\n\ntype EntityLayoutProps = {\n UNSTABLE_extraContextMenuItems?: ExtraContextMenuItem[];\n UNSTABLE_contextMenuOptions?: contextMenuOptions;\n children?: React.ReactNode;\n};\n\n/**\n * EntityLayout is a compound component, which allows you to define a layout for\n * entities using a sub-navigation mechanism.\n *\n * Consists of two parts: EntityLayout and EntityLayout.Route\n *\n * @example\n * ```jsx\n * <EntityLayout>\n * <EntityLayout.Route path=\"/example\" title=\"Example tab\">\n * <div>This is rendered under /example/anything-here route</div>\n * </EntityLayout.Route>\n * </EntityLayout>\n * ```\n */\nexport const EntityLayout = ({\n UNSTABLE_extraContextMenuItems,\n UNSTABLE_contextMenuOptions,\n children,\n}: EntityLayoutProps) => {\n const { kind, namespace, name } = useEntityCompoundName();\n const { entity, loading, error } = useContext(EntityContext);\n const routes = useElementFilter(\n children,\n elements =>\n elements\n .selectByComponentData({\n key: dataKey,\n withStrictError:\n 'Child of EntityLayout must be an EntityLayout.Route',\n })\n .getElements<SubRoute>() // all nodes, element data, maintain structure or not?\n .flatMap(({ props }) => {\n if (props.if && entity && !props.if(entity)) {\n return [];\n }\n\n return [\n {\n path: props.path,\n title: props.title,\n children: props.children,\n tabProps: props.tabProps,\n },\n ];\n }),\n [entity],\n );\n\n const { headerTitle, headerType } = headerProps(\n kind,\n namespace,\n name,\n entity,\n );\n\n const [confirmationDialogOpen, setConfirmationDialogOpen] = useState(false);\n const navigate = useNavigate();\n const cleanUpAfterRemoval = async () => {\n setConfirmationDialogOpen(false);\n navigate('/');\n };\n\n const showRemovalDialog = () => setConfirmationDialogOpen(true);\n\n return (\n <Page themeId={entity?.spec?.type?.toString() ?? 'home'}>\n <Header\n title={<EntityLayoutTitle title={headerTitle} entity={entity!} />}\n pageTitleOverride={headerTitle}\n type={headerType}\n >\n {entity && (\n <>\n <EntityLabels entity={entity} />\n <EntityContextMenu\n UNSTABLE_extraContextMenuItems={UNSTABLE_extraContextMenuItems}\n UNSTABLE_contextMenuOptions={UNSTABLE_contextMenuOptions}\n onUnregisterEntity={showRemovalDialog}\n />\n </>\n )}\n </Header>\n\n {loading && <Progress />}\n\n {entity && <RoutedTabs routes={routes} />}\n\n {error && (\n <Content>\n <Alert severity=\"error\">{error.toString()}</Alert>\n </Content>\n )}\n\n {!loading && !error && !entity && (\n <Content>\n <WarningPanel title=\"Entity not found\">\n There is no {kind} with the requested{' '}\n <Link to=\"https://backstage.io/docs/features/software-catalog/references\">\n kind, namespace, and name\n </Link>\n .\n </WarningPanel>\n </Content>\n )}\n\n <UnregisterEntityDialog\n open={confirmationDialogOpen}\n entity={entity!}\n onConfirm={cleanUpAfterRemoval}\n onClose={() => setConfirmationDialogOpen(false)}\n />\n </Page>\n );\n};\n\nEntityLayout.Route = Route;\n","/*\n * Copyright 2021 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { Entity } from '@backstage/catalog-model';\nimport { catalogApiRef } from '@backstage/plugin-catalog-react';\nimport { Button, Dialog, DialogActions, DialogTitle } from '@material-ui/core';\nimport React, { useState } from 'react';\nimport { alertApiRef, useApi } from '@backstage/core-plugin-api';\nimport { assertError } from '@backstage/errors';\n\ntype Props = {\n open: boolean;\n onClose: () => any;\n onConfirm: () => any;\n entity: Entity;\n};\n\nexport const DeleteEntityDialog = ({\n open,\n onClose,\n onConfirm,\n entity,\n}: Props) => {\n const [busy, setBusy] = useState(false);\n const catalogApi = useApi(catalogApiRef);\n const alertApi = useApi(alertApiRef);\n\n const onDelete = async () => {\n setBusy(true);\n try {\n const uid = entity.metadata.uid;\n await catalogApi.removeEntityByUid(uid!);\n onConfirm();\n } catch (err) {\n assertError(err);\n alertApi.post({ message: err.message });\n } finally {\n setBusy(false);\n }\n };\n\n return (\n <Dialog open={open} onClose={onClose}>\n <DialogTitle id=\"responsive-dialog-title\">\n Are you sure you want to delete this entity?\n </DialogTitle>\n <DialogActions>\n <Button\n variant=\"contained\"\n color=\"secondary\"\n disabled={busy}\n onClick={onDelete}\n >\n Delete\n </Button>\n <Button onClick={onClose} color=\"primary\">\n Cancel\n </Button>\n </DialogActions>\n </Dialog>\n );\n};\n","/*\n * Copyright 2021 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { Entity } from '@backstage/catalog-model';\nimport { catalogRouteRef, useEntity } from '@backstage/plugin-catalog-react';\nimport { Alert } from '@material-ui/lab';\nimport React, { useState } from 'react';\nimport { useNavigate } from 'react-router';\nimport { DeleteEntityDialog } from './DeleteEntityDialog';\nimport { useRouteRef } from '@backstage/core-plugin-api';\n\nexport const isOrphan = (entity: Entity) =>\n entity?.metadata?.annotations?.['backstage.io/orphan'] === 'true';\n\n/**\n * Displays a warning alert if the entity is marked as orphan with the ability to delete said entity.\n */\nexport const EntityOrphanWarning = () => {\n const navigate = useNavigate();\n const catalogLink = useRouteRef(catalogRouteRef);\n const [confirmationDialogOpen, setConfirmationDialogOpen] = useState(false);\n const { entity } = useEntity();\n\n const cleanUpAfterRemoval = async () => {\n setConfirmationDialogOpen(false);\n navigate(catalogLink());\n };\n\n return (\n <>\n <Alert severity=\"warning\" onClick={() => setConfirmationDialogOpen(true)}>\n This entity is not referenced by any location and is therefore not\n receiving updates. Click here to delete.\n </Alert>\n <DeleteEntityDialog\n open={confirmationDialogOpen}\n entity={entity!}\n onConfirm={cleanUpAfterRemoval}\n onClose={() => setConfirmationDialogOpen(false)}\n />\n </>\n );\n};\n","/*\n * Copyright 2021 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n Entity,\n AlphaEntity,\n stringifyEntityRef,\n EntityStatusItem,\n compareEntityToRef,\n} from '@backstage/catalog-model';\nimport {\n catalogApiRef,\n EntityRefLink,\n useEntity,\n} from '@backstage/plugin-catalog-react';\nimport { Box } from '@material-ui/core';\nimport React from 'react';\nimport { ResponseErrorPanel } from '@backstage/core-components';\nimport {\n CatalogApi,\n ENTITY_STATUS_CATALOG_PROCESSING_TYPE,\n} from '@backstage/catalog-client';\nimport { useApi, ApiHolder } from '@backstage/core-plugin-api';\nimport useAsync from 'react-use/lib/useAsync';\nimport { SerializedError } from '@backstage/errors';\n\nconst errorFilter = (i: EntityStatusItem) =>\n i.error &&\n i.level === 'error' &&\n i.type === ENTITY_STATUS_CATALOG_PROCESSING_TYPE;\n\ntype GetOwnAndAncestorsErrorsResponse = {\n items: {\n errors: SerializedError[];\n entity: Entity;\n }[];\n};\n\nasync function getOwnAndAncestorsErrors(\n entityRef: string,\n catalogApi: CatalogApi,\n): Promise<GetOwnAndAncestorsErrorsResponse> {\n const ancestors = await catalogApi.getEntityAncestors({ entityRef });\n const items = ancestors.items\n .map(item => {\n const statuses = (item.entity as AlphaEntity).status?.items ?? [];\n const errors = statuses\n .filter(errorFilter)\n .map(e => e.error)\n .filter((e): e is SerializedError => Boolean(e));\n return { errors: errors, entity: item.entity };\n })\n .filter(item => item.errors.length > 0);\n return { items };\n}\n\nexport const hasCatalogProcessingErrors = async (\n entity: Entity,\n context: { apis: ApiHolder },\n) => {\n const catalogApi = context.apis.get(catalogApiRef);\n if (!catalogApi) {\n throw new Error(`No implementation available for ${catalogApiRef}`);\n }\n\n const errors = await getOwnAndAncestorsErrors(\n stringifyEntityRef(entity),\n catalogApi,\n );\n return errors.items.length > 0;\n};\n\n/**\n * Displays a list of errors from the ancestors of the current entity.\n */\nexport const EntityProcessingErrorsPanel = () => {\n const { entity } = useEntity();\n const entityRef = stringifyEntityRef(entity);\n const catalogApi = useApi(catalogApiRef);\n const { loading, error, value } = useAsync(async () => {\n return getOwnAndAncestorsErrors(entityRef, catalogApi);\n }, [entityRef, catalogApi]);\n\n if (error) {\n return (\n <Box mb={1}>\n <ResponseErrorPanel error={error} />\n </Box>\n );\n }\n\n if (loading || !value) {\n return null;\n }\n\n return (\n <>\n {value.items.map((ancestorError, index) => (\n <Box key={index} mb={1}>\n {!compareEntityToRef(\n entity,\n stringifyEntityRef(ancestorError.entity),\n ) && (\n <Box p={1}>\n The error below originates from{' '}\n <EntityRefLink entityRef={ancestorError.entity} />\n </Box>\n )}\n {ancestorError.errors.map((e, i) => (\n <ResponseErrorPanel key={i} error={e} />\n ))}\n </Box>\n ))}\n </>\n );\n};\n","/*\n * Copyright 2020 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport React from 'react';\nimport {\n useParams,\n useNavigate,\n PartialRouteObject,\n matchRoutes,\n RouteObject,\n useRoutes,\n Navigate,\n RouteMatch,\n} from 'react-router';\nimport { Helmet } from 'react-helmet';\nimport { Tab, HeaderTabs, Content } from '@backstage/core-components';\n\nconst getSelectedIndexOrDefault = (\n matchedRoute: RouteMatch,\n tabs: Tab[],\n defaultIndex = 0,\n) => {\n if (!matchedRoute) return defaultIndex;\n const tabIndex = tabs.findIndex(t => t.id === matchedRoute.route.path);\n return ~tabIndex ? tabIndex : defaultIndex;\n};\n\n/**\n * Compound component, which allows you to define layout\n * for EntityPage using Tabs as a sub-navigation mechanism\n * Consists of 2 parts: Tabbed.Layout and Tabbed.Content.\n * Takes care of: tabs, routes, document titles, spacing around content\n *\n * @example\n * ```jsx\n * <Tabbed.Layout>\n * <Tabbed.Content\n * title=\"Example tab\"\n * route=\"/example/*\"\n * element={<div>This is rendered under /example/anything-here route</div>}\n * />\n * </TabbedLayout>\n * ```\n */\nexport const Tabbed = {\n Layout: ({ children }: { children: React.ReactNode }) => {\n const routes: PartialRouteObject[] = [];\n const tabs: Tab[] = [];\n const params = useParams();\n const navigate = useNavigate();\n\n React.Children.forEach(children, child => {\n if (!React.isValidElement(child)) {\n // Skip conditionals resolved to falses/nulls/undefineds etc\n return;\n }\n if (child.type !== Tabbed.Content) {\n throw new Error(\n 'This component only accepts Content elements as direct children. Check the code of the EntityPage.',\n );\n }\n const pathAndId = (child as JSX.Element).props.path;\n\n // Child here must be then always a functional component without any wrappers\n tabs.push({\n id: pathAndId,\n label: (child as JSX.Element).props.title,\n });\n\n routes.push({\n path: pathAndId,\n element: child.props.element,\n });\n });\n\n // Add catch-all for incorrect sub-routes\n if ((routes?.[0]?.path ?? '') !== '')\n routes.push({\n path: '/*',\n element: <Navigate to={routes[0].path!} />,\n });\n\n const [matchedRoute] =\n matchRoutes(routes as RouteObject[], `/${params['*']}`) ?? [];\n const selectedIndex = getSelectedIndexOrDefault(matchedRoute, tabs);\n const currentTab = tabs[selectedIndex];\n const title = currentTab?.label;\n\n const onTabChange = (index: number) =>\n // Remove trailing /*\n // And remove leading / for relative navigation\n // Note! route resolves relative to the position in the React tree,\n // not relative to current location\n navigate(tabs[index].id.replace(/\\/\\*$/, '').replace(/^\\//, ''));\n\n const currentRouteElement = useRoutes(routes);\n\n if (!currentTab) return null;\n return (\n <>\n <HeaderTabs\n tabs={tabs}\n selectedIndex={selectedIndex}\n onChange={onTabChange}\n />\n <Content>\n <Helmet title={title} />\n {currentRouteElement}\n </Content>\n </>\n );\n },\n Content: (_props: { path: string; title: string; element: JSX.Element }) =>\n null,\n};\n","/*\n * Copyright 2020 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport {\n Entity,\n ENTITY_DEFAULT_NAMESPACE,\n RELATION_OWNED_BY,\n} from '@backstage/catalog-model';\nimport {\n EntityContext,\n EntityRefLinks,\n FavoriteEntity,\n getEntityRelations,\n UnregisterEntityDialog,\n useEntityCompoundName,\n} from '@backstage/plugin-catalog-react';\nimport { Box } from '@material-ui/core';\nimport React, { useContext, useState } from 'react';\nimport { useNavigate } from 'react-router';\nimport { EntityContextMenu } from '../EntityContextMenu/EntityContextMenu';\nimport { Tabbed } from './Tabbed';\n\nimport {\n Content,\n Header,\n HeaderLabel,\n Link,\n Page,\n Progress,\n ResponseErrorPanel,\n WarningPanel,\n} from '@backstage/core-components';\n\nimport { IconComponent } from '@backstage/core-plugin-api';\n\nconst EntityPageTitle = ({\n entity,\n title,\n}: {\n title: string;\n entity: Entity | undefined;\n}) => (\n <Box display=\"inline-flex\" alignItems=\"center\" height=\"1em\">\n {title}\n {entity && <FavoriteEntity entity={entity} />}\n </Box>\n);\n\nconst EntityLabels = ({ entity }: { entity: Entity }) => {\n const ownedByRelations = getEntityRelations(entity, RELATION_OWNED_BY);\n return (\n <>\n {ownedByRelations.length > 0 && (\n <HeaderLabel\n label=\"Owner\"\n value={\n <EntityRefLinks\n entityRefs={ownedByRelations}\n defaultKind=\"Group\"\n color=\"inherit\"\n />\n }\n />\n )}\n {entity.spec?.lifecycle && (\n <HeaderLabel label=\"Lifecycle\" value={entity.spec.lifecycle} />\n )}\n </>\n );\n};\n\nconst headerProps = (\n kind: string,\n namespace: string | undefined,\n name: string,\n entity: Entity | undefined,\n): { headerTitle: string; headerType: string } => {\n return {\n headerTitle: `${name}${\n namespace && namespace !== ENTITY_DEFAULT_NAMESPACE\n ? ` in ${namespace}`\n : ''\n }`,\n headerType: (() => {\n let t = kind.toLocaleLowerCase('en-US');\n if (entity && entity.spec && 'type' in entity.spec) {\n t += ' — ';\n t += (entity.spec as { type: string }).type.toLocaleLowerCase('en-US');\n }\n return t;\n })(),\n };\n};\n\n// NOTE(freben): Intentionally not exported at this point, since it's part of\n// the unstable extra context menu items concept below\ntype ExtraContextMenuItem = {\n title: string;\n Icon: IconComponent;\n onClick: () => void;\n};\n\n// unstable context menu option, eg: disable the unregister entity menu\ntype contextMenuOptions = {\n disableUnregister: boolean;\n};\n\ntype EntityPageLayoutProps = {\n UNSTABLE_extraContextMenuItems?: ExtraContextMenuItem[];\n UNSTABLE_contextMenuOptions?: contextMenuOptions;\n children?: React.ReactNode;\n};\n\nexport const EntityPageLayout = ({\n children,\n UNSTABLE_extraContextMenuItems,\n UNSTABLE_contextMenuOptions,\n}: EntityPageLayoutProps) => {\n const { kind, namespace, name } = useEntityCompoundName();\n const { entity, loading, error } = useContext(EntityContext);\n const { headerTitle, headerType } = headerProps(\n kind,\n namespace,\n name,\n entity!,\n );\n\n const [confirmationDialogOpen, setConfirmationDialogOpen] = useState(false);\n const navigate = useNavigate();\n const cleanUpAfterRemoval = async () => {\n setConfirmationDialogOpen(false);\n navigate('/');\n };\n\n const showRemovalDialog = () => setConfirmationDialogOpen(true);\n\n return (\n <Page themeId={entity?.spec?.type?.toString() ?? 'home'}>\n <Header\n title={<EntityPageTitle title={headerTitle} entity={entity!} />}\n pageTitleOverride={headerTitle}\n type={headerType}\n >\n {/* TODO: Make entity labels configurable for entity kind / type */}\n {entity && (\n <>\n <EntityLabels entity={entity} />\n <EntityContextMenu\n UNSTABLE_extraContextMenuItems={UNSTABLE_extraContextMenuItems}\n UNSTABLE_contextMenuOptions={UNSTABLE_contextMenuOptions}\n onUnregisterEntity={showRemovalDialog}\n />\n </>\n )}\n </Header>\n\n {loading && (\n <Content>\n <Progress />\n </Content>\n )}\n\n {entity && <Tabbed.Layout>{children}</Tabbed.Layout>}\n\n {error && (\n <Content>\n <ResponseErrorPanel error={error} />\n </Content>\n )}\n\n {!loading && !error && !entity && (\n <Content>\n <WarningPanel title=\"Entity not found\">\n There is no {kind} with the requested{' '}\n <Link to=\"https://backstage.io/docs/features/software-catalog/references\">\n kind, namespace, and name\n </Link>\n .\n </WarningPanel>\n </Content>\n )}\n\n <UnregisterEntityDialog\n open={confirmationDialogOpen}\n entity={entity!}\n onConfirm={cleanUpAfterRemoval}\n onClose={() => setConfirmationDialogOpen(false)}\n />\n </Page>\n );\n};\n\nEntityPageLayout.Content = Tabbed.Content;\n","/*\n * Copyright 2020 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { Entity } from '@backstage/catalog-model';\nimport { useEntity } from '@backstage/plugin-catalog-react';\nimport React, { PropsWithChildren, ReactNode } from 'react';\nimport {\n attachComponentData,\n useApiHolder,\n useElementFilter,\n ApiHolder,\n} from '@backstage/core-plugin-api';\nimport useAsync from 'react-use/lib/useAsync';\n\nconst ENTITY_SWITCH_KEY = 'core.backstage.entitySwitch';\n\nconst EntitySwitchCase = (_: {\n if?: (\n entity: Entity,\n context: { apis: ApiHolder },\n ) => boolean | Promise<boolean>;\n children: ReactNode;\n}) => null;\n\nattachComponentData(EntitySwitchCase, ENTITY_SWITCH_KEY, true);\n\ntype SwitchCase = {\n if?: (\n entity: Entity,\n context: { apis: ApiHolder },\n ) => boolean | Promise<boolean>;\n children: JSX.Element;\n};\n\ntype SwitchCaseResult = {\n if: boolean | Promise<boolean>;\n children: JSX.Element;\n};\n\nexport const EntitySwitch = ({ children }: PropsWithChildren<{}>) => {\n const { entity } = useEntity();\n const apis = useApiHolder();\n const results = useElementFilter(\n children,\n collection =>\n collection\n .selectByComponentData({\n key: ENTITY_SWITCH_KEY,\n withStrictError: 'Child of EntitySwitch is not an EntitySwitch.Case',\n })\n .getElements()\n .flatMap<SwitchCaseResult>((element: React.ReactElement) => {\n const { if: condition, children: elementsChildren } =\n element.props as SwitchCase;\n return [\n {\n if: condition?.(entity, { apis }) ?? true,\n children: elementsChildren,\n },\n ];\n }),\n [apis, entity],\n );\n const hasAsyncCases = results.some(\n r => typeof r.if === 'object' && 'then' in r.if,\n );\n\n if (hasAsyncCases) {\n return <AsyncEntitySwitch results={results} />;\n }\n\n return results.find(r => r.if)?.children ?? null;\n};\n\nfunction AsyncEntitySwitch({ results }: { results: SwitchCaseResult[] }) {\n const { loading, value } = useAsync(async () => {\n const promises = results.map(\n async ({ if: condition, children: output }) => {\n try {\n if (await condition) {\n return output;\n }\n } catch {\n /* ignored */\n }\n\n return null;\n },\n );\n return (await Promise.all(promises)).find(Boolean) ?? null;\n }, [results]);\n\n if (loading || !value) {\n return null;\n }\n\n return value;\n}\n\nEntitySwitch.Case = EntitySwitchCase;\n","/*\n * Copyright 2020 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { Entity, ComponentEntity } from '@backstage/catalog-model';\n\nfunction strCmp(a: string | undefined, b: string | undefined): boolean {\n return Boolean(\n a && a?.toLocaleLowerCase('en-US') === b?.toLocaleLowerCase('en-US'),\n );\n}\n\nexport function isKind(kind: string) {\n return (entity: Entity) => strCmp(entity?.kind, kind);\n}\n\nexport function isComponentType(type: string) {\n return (entity: Entity) => {\n if (!strCmp(entity?.kind, 'component')) {\n return false;\n }\n const componentEntity = entity as ComponentEntity;\n return strCmp(componentEntity.spec.type, type);\n };\n}\n\nexport function isNamespace(namespace: string) {\n return (entity: Entity) => strCmp(entity?.metadata?.namespace, namespace);\n}\n","/*\n * Copyright 2021 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { Grid } from '@material-ui/core';\nimport React, { PropsWithChildren } from 'react';\n\nexport const FilteredEntityLayout = ({ children }: PropsWithChildren<{}>) => (\n <Grid container style={{ position: 'relative' }}>\n {children}\n </Grid>\n);\n","/*\n * Copyright 2021 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { BackstageTheme } from '@backstage/theme';\nimport {\n Box,\n Button,\n Drawer,\n Grid,\n Typography,\n useMediaQuery,\n useTheme,\n} from '@material-ui/core';\nimport FilterListIcon from '@material-ui/icons/FilterList';\nimport React, { useState, PropsWithChildren } from 'react';\n\nexport const FilterContainer = ({ children }: PropsWithChildren<{}>) => {\n const isMidSizeScreen = useMediaQuery<BackstageTheme>(theme =>\n theme.breakpoints.down('md'),\n );\n const theme = useTheme<BackstageTheme>();\n const [filterDrawerOpen, setFilterDrawerOpen] = useState<boolean>(false);\n\n return isMidSizeScreen ? (\n <>\n <Button\n style={{ marginTop: theme.spacing(1), marginLeft: theme.spacing(1) }}\n onClick={() => setFilterDrawerOpen(true)}\n startIcon={<FilterListIcon />}\n >\n Filters\n </Button>\n <Drawer\n open={filterDrawerOpen}\n onClose={() => setFilterDrawerOpen(false)}\n anchor=\"left\"\n disableAutoFocus\n keepMounted\n variant=\"temporary\"\n >\n <Box m={2}>\n <Typography\n variant=\"h6\"\n component=\"h2\"\n style={{ marginBottom: theme.spacing(1) }}\n >\n Filters\n </Typography>\n {children}\n </Box>\n </Drawer>\n </>\n ) : (\n <Grid item lg={2}>\n {children}\n </Grid>\n );\n};\n","/*\n * Copyright 2021 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { Grid } from '@material-ui/core';\nimport React, { PropsWithChildren } from 'react';\n\nexport const EntityListContainer = ({ children }: PropsWithChildren<{}>) => (\n <Grid item xs={12} lg={10}>\n {children}\n </Grid>\n);\n","/*\n * Copyright 2021 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n Content,\n ContentHeader,\n CreateButton,\n PageWithHeader,\n SupportButton,\n TableColumn,\n TableProps,\n} from '@backstage/core-components';\nimport { configApiRef, useApi, useRouteRef } from '@backstage/core-plugin-api';\nimport {\n EntityLifecyclePicker,\n EntityListProvider,\n EntityOwnerPicker,\n EntityTagPicker,\n EntityTypePicker,\n UserListFilterKind,\n UserListPicker,\n} from '@backstage/plugin-catalog-react';\nimport React from 'react';\nimport { createComponentRouteRef } from '../../routes';\nimport { CatalogTable } from '../CatalogTable';\nimport { EntityRow } from '../CatalogTable/types';\nimport {\n FilteredEntityLayout,\n EntityListContainer,\n FilterContainer,\n} from '../FilteredEntityLayout';\nimport { CatalogKindHeader } from '../CatalogKindHeader';\n\n/**\n * DefaultCatalogPageProps\n * @public\n */\nexport type DefaultCatalogPageProps = {\n initiallySelectedFilter?: UserListFilterKind;\n columns?: TableColumn<EntityRow>[];\n actions?: TableProps<EntityRow>['actions'];\n};\n\nexport const DefaultCatalogPage = ({\n columns,\n actions,\n initiallySelectedFilter = 'owned',\n}: DefaultCatalogPageProps) => {\n const orgName =\n useApi(configApiRef).getOptionalString('organization.name') ?? 'Backstage';\n const createComponentLink = useRouteRef(createComponentRouteRef);\n\n return (\n <PageWithHeader title={`${orgName} Catalog`} themeId=\"home\">\n <EntityListProvider>\n <Content>\n <ContentHeader titleComponent={<CatalogKindHeader />}>\n <CreateButton\n title=\"Create Component\"\n to={createComponentLink && createComponentLink()}\n />\n <SupportButton>All your software catalog entities</SupportButton>\n </ContentHeader>\n <FilteredEntityLayout>\n <FilterContainer>\n <EntityTypePicker />\n <UserListPicker initialFilter={initiallySelectedFilter} />\n <EntityOwnerPicker />\n <EntityLifecyclePicker />\n <EntityTagPicker />\n </FilterContainer>\n <EntityListContainer>\n <CatalogTable columns={columns} actions={actions} />\n </EntityListContainer>\n </FilteredEntityLayout>\n </Content>\n </EntityListProvider>\n </PageWithHeader>\n );\n};\n","/*\n * Copyright 2021 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport React from 'react';\nimport { useOutlet } from 'react-router';\nimport {\n DefaultCatalogPage,\n DefaultCatalogPageProps,\n} from './DefaultCatalogPage';\n\nexport const CatalogPage = (props: DefaultCatalogPageProps) => {\n const outlet = useOutlet();\n\n return outlet || <DefaultCatalogPage {...props} />;\n};\n","/*\n * Copyright 2020 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport React from 'react';\nimport { makeStyles } from '@material-ui/core';\nimport IlloSvgUrl from './illo.svg';\n\nconst useStyles = makeStyles(theme => ({\n illo: {\n maxWidth: '60%',\n top: 100,\n right: 20,\n position: 'absolute',\n [theme.breakpoints.down('xs')]: {\n maxWidth: '96%',\n position: 'relative',\n top: 'unset',\n right: 'unset',\n margin: `${theme.spacing(10)}px auto ${theme.spacing(4)}px`,\n },\n },\n}));\n\nexport const Illo = () => {\n const classes = useStyles();\n return (\n <img\n src={IlloSvgUrl}\n className={classes.illo}\n alt=\"Illustration on entity not found page\"\n />\n );\n};\n","/*\n * Copyright 2020 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport React from 'react';\nimport { Grid, Button, Typography } from '@material-ui/core';\nimport { makeStyles } from '@material-ui/core/styles';\nimport { BackstageTheme } from '@backstage/theme';\n\nimport { Illo } from './Illo';\n\nconst useStyles = makeStyles<BackstageTheme>(theme => ({\n container: {\n paddingTop: theme.spacing(24),\n paddingLeft: theme.spacing(8),\n [theme.breakpoints.down('xs')]: {\n padding: theme.spacing(2),\n },\n },\n title: {\n paddingBottom: theme.spacing(2),\n [theme.breakpoints.down('xs')]: {\n fontSize: 32,\n },\n },\n body: {\n paddingBottom: theme.spacing(6),\n [theme.breakpoints.down('xs')]: {\n paddingBottom: theme.spacing(5),\n },\n },\n}));\n\nexport const EntityNotFound = () => {\n const classes = useStyles();\n\n return (\n <Grid container spacing={0} className={classes.container}>\n <Illo />\n <Grid item xs={12} sm={6}>\n <Typography variant=\"h2\" className={classes.title}>\n Entity was not found\n </Typography>\n <Typography variant=\"body1\" className={classes.body}>\n Want to help us build this? Check out our Getting Started\n documentation.\n </Typography>\n <Button\n variant=\"contained\"\n color=\"primary\"\n href=\"https://backstage.io/docs\"\n >\n DOCS\n </Button>\n </Grid>\n </Grid>\n );\n};\n","/*\n * Copyright 2020 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport { ENTITY_DEFAULT_NAMESPACE } from '@backstage/catalog-model';\nimport {\n AsyncEntityProvider,\n useEntity,\n useEntityFromUrl,\n} from '@backstage/plugin-catalog-react';\nimport { Typography } from '@material-ui/core';\nimport React, { ComponentType, ReactNode } from 'react';\nimport { Navigate, Route, Routes, useParams } from 'react-router';\nimport { CatalogPage } from './CatalogPage';\nimport { EntityNotFound } from './EntityNotFound';\nimport { EntityPageLayout } from './EntityPageLayout';\nimport { Content, Link } from '@backstage/core-components';\n\nconst DefaultEntityPage = () => (\n <EntityPageLayout>\n <EntityPageLayout.Content\n path=\"/\"\n title=\"Overview\"\n element={\n <Content>\n <Typography variant=\"h2\">This is the default entity page.</Typography>\n <Typography variant=\"body1\">\n To override this component with your custom implementation, read\n docs on{' '}\n <Link to=\"https://backstage.io/docs\">backstage.io/docs</Link>\n </Typography>\n </Content>\n }\n />\n </EntityPageLayout>\n);\n\nconst EntityPageSwitch = ({ EntityPage }: { EntityPage: ComponentType }) => {\n const { entity, loading, error } = useEntity();\n // Loading and error states\n if (loading) return <EntityPageLayout />;\n if (error || !entity) return <EntityNotFound />;\n\n // Otherwise EntityPage provided from the App\n // Note that EntityPage will include EntityPageLayout already\n return <EntityPage />;\n};\n\nconst OldEntityRouteRedirect = () => {\n const { optionalNamespaceAndName, '*': rest } = useParams() as any;\n const [name, namespace] = optionalNamespaceAndName.split(':').reverse();\n const namespaceLower =\n namespace?.toLocaleLowerCase('en-US') ?? ENTITY_DEFAULT_NAMESPACE;\n const restWithSlash = rest ? `/${rest}` : '';\n return (\n <Navigate\n to={`../../${namespaceLower}/component/${name}${restWithSlash}`}\n />\n );\n};\n\nexport const EntityLoader = (props: { children: ReactNode }) => (\n <AsyncEntityProvider {...useEntityFromUrl()} {...props} />\n);\n\n/**\n * @deprecated Use plugin extensions instead\n * */\nexport const Router = ({\n EntityPage = DefaultEntityPage,\n}: {\n EntityPage?: ComponentType;\n}) => (\n <Routes>\n <Route path=\"/\" element={<CatalogPage />} />\n <Route\n path=\"/:namespace/:kind/:name\"\n element={\n <EntityLoader>\n <EntityPageSwitch EntityPage={EntityPage} />\n </EntityLoader>\n }\n />\n <Route\n path=\"Component/:optionalNamespaceAndName/*\"\n element={<OldEntityRouteRedirect />}\n />\n </Routes>\n);\n","/*\n * Copyright 2020 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { CatalogClient } from '@backstage/catalog-client';\nimport {\n catalogApiRef,\n catalogRouteRef,\n DefaultStarredEntitiesApi,\n entityRouteRef,\n starredEntitiesApiRef,\n} from '@backstage/plugin-catalog-react';\nimport { createComponentRouteRef, viewTechDocRouteRef } from './routes';\nimport {\n createApiFactory,\n createComponentExtension,\n createPlugin,\n createRoutableExtension,\n discoveryApiRef,\n fetchApiRef,\n storageApiRef,\n} from '@backstage/core-plugin-api';\n\nexport const catalogPlugin = createPlugin({\n id: 'catalog',\n apis: [\n createApiFactory({\n api: catalogApiRef,\n deps: {\n discoveryApi: discoveryApiRef,\n fetchApi: fetchApiRef,\n },\n factory: ({ discoveryApi, fetchApi }) =>\n new CatalogClient({ discoveryApi, fetchApi }),\n }),\n createApiFactory({\n api: starredEntitiesApiRef,\n deps: { storageApi: storageApiRef },\n factory: ({ storageApi }) =>\n new DefaultStarredEntitiesApi({ storageApi }),\n }),\n ],\n routes: {\n catalogIndex: catalogRouteRef,\n catalogEntity: entityRouteRef,\n },\n externalRoutes: {\n createComponent: createComponentRouteRef,\n viewTechDoc: viewTechDocRouteRef,\n },\n});\n\nexport const CatalogIndexPage = catalogPlugin.provide(\n createRoutableExtension({\n name: 'CatalogIndexPage',\n component: () =>\n import('./components/CatalogPage').then(m => m.CatalogPage),\n mountPoint: catalogRouteRef,\n }),\n);\n\nexport const CatalogEntityPage = catalogPlugin.provide(\n createRoutableExtension({\n name: 'CatalogEntityPage',\n component: () =>\n import('./components/CatalogEntityPage').then(m => m.CatalogEntityPage),\n mountPoint: entityRouteRef,\n }),\n);\n\nexport const EntityAboutCard = catalogPlugin.provide(\n createComponentExtension({\n name: 'EntityAboutCard',\n component: {\n lazy: () => import('./components/AboutCard').then(m => m.AboutCard),\n },\n }),\n);\n\nexport const EntityLinksCard = catalogPlugin.provide(\n createComponentExtension({\n name: 'EntityLinksCard',\n component: {\n lazy: () =>\n import('./components/EntityLinksCard').then(m => m.EntityLinksCard),\n },\n }),\n);\n\nexport const EntityHasSystemsCard = catalogPlugin.provide(\n createComponentExtension({\n name: 'EntityHasSystemsCard',\n component: {\n lazy: () =>\n import('./components/HasSystemsCard').then(m => m.HasSystemsCard),\n },\n }),\n);\n\nexport const EntityHasComponentsCard = catalogPlugin.provide(\n createComponentExtension({\n name: 'EntityHasComponentsCard',\n component: {\n lazy: () =>\n import('./components/HasComponentsCard').then(m => m.HasComponentsCard),\n },\n }),\n);\n\nexport const EntityHasSubcomponentsCard = catalogPlugin.provide(\n createComponentExtension({\n name: 'EntityHasSubcomponentsCard',\n component: {\n lazy: () =>\n import('./components/HasSubcomponentsCard').then(\n m => m.HasSubcomponentsCard,\n ),\n },\n }),\n);\n\nexport const EntityHasResourcesCard = catalogPlugin.provide(\n createComponentExtension({\n name: 'EntityHasResourcesCard',\n component: {\n lazy: () =>\n import('./components/HasResourcesCard').then(m => m.HasResourcesCard),\n },\n }),\n);\n\nexport const EntityDependsOnComponentsCard = catalogPlugin.provide(\n createComponentExtension({\n name: 'EntityDependsOnComponentsCard',\n component: {\n lazy: () =>\n import('./components/DependsOnComponentsCard').then(\n m => m.DependsOnComponentsCard,\n ),\n },\n }),\n);\n\nexport const EntityDependencyOfComponentsCard = catalogPlugin.provide(\n createComponentExtension({\n name: 'EntityDependencyOfComponentsCard',\n component: {\n lazy: () =>\n import('./components/DependencyOfComponentsCard').then(\n m => m.DependencyOfComponentsCard,\n ),\n },\n }),\n);\n\nexport const EntityDependsOnResourcesCard = catalogPlugin.provide(\n createComponentExtension({\n name: 'EntityDependsOnResourcesCard',\n component: {\n lazy: () =>\n import('./components/DependsOnResourcesCard').then(\n m => m.DependsOnResourcesCard,\n ),\n },\n }),\n);\n\nexport const EntitySystemDiagramCard = catalogPlugin.provide(\n createComponentExtension({\n name: 'EntitySystemDiagramCard',\n component: {\n lazy: () =>\n import('./components/SystemDiagramCard').then(m => m.SystemDiagramCard),\n },\n }),\n);\n\nexport const RelatedEntitiesCard = catalogPlugin.provide(\n createComponentExtension({\n name: 'RelatedEntitiesCard',\n component: {\n lazy: () =>\n import('./components/RelatedEntitiesCard').then(\n m => m.RelatedEntitiesCard,\n ),\n },\n }),\n);\n"],"names":["useStyles","columnFactories.createNameColumn","columnFactories.createSystemColumn","columnFactories.createOwnerColumn","columnFactories.createSpecTypeColumn","columnFactories.createSpecLifecycleColumn","columnFactories.createMetadataDescriptionColumn","columnFactories.createTagsColumn","capitalize","Edit","makeStyles","headerProps","EntityLabels","Route"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index-9e441058.esm.js","sources":["../../src/CatalogClientWrapper.ts","../../src/routes.ts","../../src/components/AboutCard/AboutField.tsx","../../src/components/AboutCard/AboutContent.tsx","../../src/components/AboutCard/AboutCard.tsx","../../src/components/CatalogKindHeader/CatalogKindHeader.tsx","../../src/components/CatalogResultListItem/CatalogResultListItem.tsx","../../src/components/CatalogTable/columns.tsx","../../src/components/CatalogTable/CatalogTable.tsx","../../src/components/EntityContextMenu/EntityContextMenu.tsx","../../src/components/EntityLayout/EntityLayout.tsx","../../src/components/EntityOrphanWarning/DeleteEntityDialog.tsx","../../src/components/EntityOrphanWarning/EntityOrphanWarning.tsx","../../src/components/EntityProcessingErrorsPanel/EntityProcessingErrorsPanel.tsx","../../src/components/EntityPageLayout/Tabbed/Tabbed.tsx","../../src/components/EntityPageLayout/EntityPageLayout.tsx","../../src/components/EntitySwitch/EntitySwitch.tsx","../../src/components/EntitySwitch/conditions.ts","../../src/components/FilteredEntityLayout/FilteredEntityLayout.tsx","../../src/components/FilteredEntityLayout/FilterContainer.tsx","../../src/components/FilteredEntityLayout/EntityListContainer.tsx","../../src/components/CatalogPage/DefaultCatalogPage.tsx","../../src/components/CatalogPage/CatalogPage.tsx","../../src/components/EntityNotFound/Illo/Illo.tsx","../../src/components/EntityNotFound/EntityNotFound.tsx","../../src/components/Router.tsx","../../src/plugin.ts"],"sourcesContent":["/*\n * Copyright 2020 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { Entity, EntityName, Location } from '@backstage/catalog-model';\nimport {\n AddLocationRequest,\n AddLocationResponse,\n CatalogApi,\n CatalogClient,\n CatalogEntitiesRequest,\n CatalogListResponse,\n CatalogRequestOptions,\n CatalogEntityAncestorsRequest,\n CatalogEntityAncestorsResponse,\n} from '@backstage/catalog-client';\nimport { IdentityApi } from '@backstage/core-plugin-api';\n\n/**\n * CatalogClient wrapper that injects identity token for all requests\n *\n * @deprecated The default catalog client now uses the `fetchApiRef`\n * implementation, which in turn by default issues tokens just the same as this\n * class used to assist in doing. If you use a custom `fetchApiRef`\n * implementation that does NOT issue tokens, or use a custom `catalogApiRef`\n * implementation which does not use the default `fetchApiRef`, you can wrap\n * your catalog API in this class to get back the old behavior.\n */\nexport class CatalogClientWrapper implements CatalogApi {\n private readonly identityApi: IdentityApi;\n private readonly client: CatalogClient;\n\n constructor(options: { client: CatalogClient; identityApi: IdentityApi }) {\n this.client = options.client;\n this.identityApi = options.identityApi;\n }\n\n async getLocationById(\n id: string,\n options?: CatalogRequestOptions,\n ): Promise<Location | undefined> {\n return await this.client.getLocationById(\n id,\n await this.getCredentials(options),\n );\n }\n\n async getEntities(\n request?: CatalogEntitiesRequest,\n options?: CatalogRequestOptions,\n ): Promise<CatalogListResponse<Entity>> {\n return await this.client.getEntities(\n request,\n await this.getCredentials(options),\n );\n }\n\n async getEntityByName(\n compoundName: EntityName,\n options?: CatalogRequestOptions,\n ): Promise<Entity | undefined> {\n return await this.client.getEntityByName(\n compoundName,\n await this.getCredentials(options),\n );\n }\n\n async addLocation(\n request: AddLocationRequest,\n options?: CatalogRequestOptions,\n ): Promise<AddLocationResponse> {\n return await this.client.addLocation(\n request,\n await this.getCredentials(options),\n );\n }\n\n async getOriginLocationByEntity(\n entity: Entity,\n options?: CatalogRequestOptions,\n ): Promise<Location | undefined> {\n return await this.client.getOriginLocationByEntity(\n entity,\n await this.getCredentials(options),\n );\n }\n\n async getLocationByEntity(\n entity: Entity,\n options?: CatalogRequestOptions,\n ): Promise<Location | undefined> {\n return await this.client.getLocationByEntity(\n entity,\n await this.getCredentials(options),\n );\n }\n\n async removeLocationById(\n id: string,\n options?: CatalogRequestOptions,\n ): Promise<void> {\n return await this.client.removeLocationById(\n id,\n await this.getCredentials(options),\n );\n }\n\n async removeEntityByUid(\n uid: string,\n options?: CatalogRequestOptions,\n ): Promise<void> {\n return await this.client.removeEntityByUid(\n uid,\n await this.getCredentials(options),\n );\n }\n\n async refreshEntity(\n entityRef: string,\n options?: CatalogRequestOptions,\n ): Promise<void> {\n return await this.client.refreshEntity(\n entityRef,\n await this.getCredentials(options),\n );\n }\n\n async getEntityAncestors(\n request: CatalogEntityAncestorsRequest,\n options?: CatalogRequestOptions,\n ): Promise<CatalogEntityAncestorsResponse> {\n return await this.client.getEntityAncestors(\n request,\n await this.getCredentials(options),\n );\n }\n\n private async getCredentials(\n options?: CatalogRequestOptions,\n ): Promise<{ token?: string }> {\n if (options?.token) {\n return { token: options?.token };\n }\n return this.identityApi.getCredentials();\n }\n}\n","/*\n * Copyright 2021 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { createExternalRouteRef } from '@backstage/core-plugin-api';\n\nexport const createComponentRouteRef = createExternalRouteRef({\n id: 'create-component',\n optional: true,\n});\n\nexport const viewTechDocRouteRef = createExternalRouteRef({\n id: 'view-techdoc',\n optional: true,\n params: ['namespace', 'kind', 'name'],\n});\n","/*\n * Copyright 2020 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { useElementFilter } from '@backstage/core-plugin-api';\nimport { Grid, makeStyles, Typography } from '@material-ui/core';\nimport React from 'react';\n\nconst useStyles = makeStyles(theme => ({\n value: {\n fontWeight: 'bold',\n overflow: 'hidden',\n lineHeight: '24px',\n wordBreak: 'break-word',\n },\n label: {\n color: theme.palette.text.secondary,\n textTransform: 'uppercase',\n fontSize: '10px',\n fontWeight: 'bold',\n letterSpacing: 0.5,\n overflow: 'hidden',\n whiteSpace: 'nowrap',\n },\n}));\n\ntype Props = {\n label: string;\n value?: string;\n gridSizes?: Record<string, number>;\n children?: React.ReactNode;\n};\n\nexport const AboutField = ({ label, value, gridSizes, children }: Props) => {\n const classes = useStyles();\n\n const childElements = useElementFilter(children, c => c.getElements());\n\n // Content is either children or a string prop `value`\n const content =\n childElements.length > 0 ? (\n childElements\n ) : (\n <Typography variant=\"body2\" className={classes.value}>\n {value || `unknown`}\n </Typography>\n );\n return (\n <Grid item {...gridSizes}>\n <Typography variant=\"subtitle2\" className={classes.label}>\n {label}\n </Typography>\n {content}\n </Grid>\n );\n};\n","/*\n * Copyright 2020 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n Entity,\n RELATION_OWNED_BY,\n RELATION_PART_OF,\n} from '@backstage/catalog-model';\nimport {\n EntityRefLinks,\n getEntityRelations,\n} from '@backstage/plugin-catalog-react';\nimport { Chip, Grid, makeStyles, Typography } from '@material-ui/core';\nimport React from 'react';\nimport { AboutField } from './AboutField';\n\nconst useStyles = makeStyles({\n description: {\n wordBreak: 'break-word',\n },\n});\n\ntype Props = {\n entity: Entity;\n};\n\nexport const AboutContent = ({ entity }: Props) => {\n const classes = useStyles();\n const isSystem = entity.kind.toLocaleLowerCase('en-US') === 'system';\n const isResource = entity.kind.toLocaleLowerCase('en-US') === 'resource';\n const isComponent = entity.kind.toLocaleLowerCase('en-US') === 'component';\n const isAPI = entity.kind.toLocaleLowerCase('en-US') === 'api';\n const isTemplate = entity.kind.toLocaleLowerCase('en-US') === 'template';\n const isLocation = entity.kind.toLocaleLowerCase('en-US') === 'location';\n const isGroup = entity.kind.toLocaleLowerCase('en-US') === 'group';\n\n const partOfSystemRelations = getEntityRelations(entity, RELATION_PART_OF, {\n kind: 'system',\n });\n const partOfComponentRelations = getEntityRelations(\n entity,\n RELATION_PART_OF,\n {\n kind: 'component',\n },\n );\n const partOfDomainRelations = getEntityRelations(entity, RELATION_PART_OF, {\n kind: 'domain',\n });\n const ownedByRelations = getEntityRelations(entity, RELATION_OWNED_BY);\n\n return (\n <Grid container>\n <AboutField label=\"Description\" gridSizes={{ xs: 12 }}>\n <Typography variant=\"body2\" paragraph className={classes.description}>\n {entity?.metadata?.description || 'No description'}\n </Typography>\n </AboutField>\n <AboutField\n label=\"Owner\"\n value=\"No Owner\"\n gridSizes={{ xs: 12, sm: 6, lg: 4 }}\n >\n {ownedByRelations.length > 0 && (\n <EntityRefLinks entityRefs={ownedByRelations} defaultKind=\"group\" />\n )}\n </AboutField>\n {(isSystem || partOfDomainRelations.length > 0) && (\n <AboutField\n label=\"Domain\"\n value=\"No Domain\"\n gridSizes={{ xs: 12, sm: 6, lg: 4 }}\n >\n {partOfDomainRelations.length > 0 && (\n <EntityRefLinks\n entityRefs={partOfDomainRelations}\n defaultKind=\"domain\"\n />\n )}\n </AboutField>\n )}\n {(isAPI ||\n isComponent ||\n isResource ||\n partOfSystemRelations.length > 0) && (\n <AboutField\n label=\"System\"\n value=\"No System\"\n gridSizes={{ xs: 12, sm: 6, lg: 4 }}\n >\n {partOfSystemRelations.length > 0 && (\n <EntityRefLinks\n entityRefs={partOfSystemRelations}\n defaultKind=\"system\"\n />\n )}\n </AboutField>\n )}\n {isComponent && partOfComponentRelations.length > 0 && (\n <AboutField\n label=\"Parent Component\"\n value=\"No Parent Component\"\n gridSizes={{ xs: 12, sm: 6, lg: 4 }}\n >\n <EntityRefLinks\n entityRefs={partOfComponentRelations}\n defaultKind=\"component\"\n />\n </AboutField>\n )}\n {(isAPI ||\n isComponent ||\n isResource ||\n isTemplate ||\n isGroup ||\n isLocation ||\n typeof entity?.spec?.type === 'string') && (\n <AboutField\n label=\"Type\"\n value={entity?.spec?.type as string}\n gridSizes={{ xs: 12, sm: 6, lg: 4 }}\n />\n )}\n {(isAPI ||\n isComponent ||\n typeof entity?.spec?.lifecycle === 'string') && (\n <AboutField\n label=\"Lifecycle\"\n value={entity?.spec?.lifecycle as string}\n gridSizes={{ xs: 12, sm: 6, lg: 4 }}\n />\n )}\n <AboutField\n label=\"Tags\"\n value=\"No Tags\"\n gridSizes={{ xs: 12, sm: 6, lg: 4 }}\n >\n {(entity?.metadata?.tags || []).map(t => (\n <Chip key={t} size=\"small\" label={t} />\n ))}\n </AboutField>\n </Grid>\n );\n};\n","/*\n * Copyright 2020 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n Entity,\n ENTITY_DEFAULT_NAMESPACE,\n LOCATION_ANNOTATION,\n stringifyEntityRef,\n} from '@backstage/catalog-model';\nimport {\n HeaderIconLinkRow,\n IconLinkVerticalProps,\n InfoCardVariants,\n Link,\n} from '@backstage/core-components';\nimport { alertApiRef, useApi, useRouteRef } from '@backstage/core-plugin-api';\nimport {\n ScmIntegrationIcon,\n scmIntegrationsApiRef,\n} from '@backstage/integration-react';\nimport {\n catalogApiRef,\n getEntityMetadataEditUrl,\n getEntitySourceLocation,\n useEntity,\n} from '@backstage/plugin-catalog-react';\nimport {\n Card,\n CardContent,\n CardHeader,\n Divider,\n IconButton,\n makeStyles,\n} from '@material-ui/core';\nimport CachedIcon from '@material-ui/icons/Cached';\nimport DocsIcon from '@material-ui/icons/Description';\nimport EditIcon from '@material-ui/icons/Edit';\nimport React, { useCallback } from 'react';\nimport { viewTechDocRouteRef } from '../../routes';\nimport { AboutContent } from './AboutContent';\n\nconst useStyles = makeStyles({\n gridItemCard: {\n display: 'flex',\n flexDirection: 'column',\n height: 'calc(100% - 10px)', // for pages without content header\n marginBottom: '10px',\n },\n fullHeightCard: {\n display: 'flex',\n flexDirection: 'column',\n height: '100%',\n },\n gridItemCardContent: {\n flex: 1,\n },\n fullHeightCardContent: {\n flex: 1,\n },\n});\n\ntype AboutCardProps = {\n /** @deprecated The entity is now grabbed from context instead */\n entity?: Entity;\n variant?: InfoCardVariants;\n};\n\nexport function AboutCard({ variant }: AboutCardProps) {\n const classes = useStyles();\n const { entity } = useEntity();\n const scmIntegrationsApi = useApi(scmIntegrationsApiRef);\n const catalogApi = useApi(catalogApiRef);\n const alertApi = useApi(alertApiRef);\n const viewTechdocLink = useRouteRef(viewTechDocRouteRef);\n\n const entitySourceLocation = getEntitySourceLocation(\n entity,\n scmIntegrationsApi,\n );\n const entityMetadataEditUrl = getEntityMetadataEditUrl(entity);\n\n const viewInSource: IconLinkVerticalProps = {\n label: 'View Source',\n disabled: !entitySourceLocation,\n icon: <ScmIntegrationIcon type={entitySourceLocation?.integrationType} />,\n href: entitySourceLocation?.locationTargetUrl,\n };\n const viewInTechDocs: IconLinkVerticalProps = {\n label: 'View TechDocs',\n disabled:\n !entity.metadata.annotations?.['backstage.io/techdocs-ref'] ||\n !viewTechdocLink,\n icon: <DocsIcon />,\n href:\n viewTechdocLink &&\n viewTechdocLink({\n namespace: entity.metadata.namespace || ENTITY_DEFAULT_NAMESPACE,\n kind: entity.kind,\n name: entity.metadata.name,\n }),\n };\n\n let cardClass = '';\n if (variant === 'gridItem') {\n cardClass = classes.gridItemCard;\n } else if (variant === 'fullHeight') {\n cardClass = classes.fullHeightCard;\n }\n\n let cardContentClass = '';\n if (variant === 'gridItem') {\n cardContentClass = classes.gridItemCardContent;\n } else if (variant === 'fullHeight') {\n cardContentClass = classes.fullHeightCardContent;\n }\n\n const entityLocation = entity.metadata.annotations?.[LOCATION_ANNOTATION];\n // Limiting the ability to manually refresh to the less expensive locations\n const allowRefresh =\n entityLocation?.startsWith('url:') || entityLocation?.startsWith('file:');\n const refreshEntity = useCallback(async () => {\n await catalogApi.refreshEntity(stringifyEntityRef(entity));\n alertApi.post({ message: 'Refresh scheduled', severity: 'info' });\n }, [catalogApi, alertApi, entity]);\n\n return (\n <Card className={cardClass}>\n <CardHeader\n title=\"About\"\n action={\n <>\n {allowRefresh && (\n <IconButton\n aria-label=\"Refresh\"\n title=\"Schedule entity refresh\"\n onClick={refreshEntity}\n >\n <CachedIcon />\n </IconButton>\n )}\n <IconButton\n component={Link}\n aria-label=\"Edit\"\n disabled={!entityMetadataEditUrl}\n title=\"Edit Metadata\"\n to={entityMetadataEditUrl ?? '#'}\n >\n <EditIcon />\n </IconButton>\n </>\n }\n subheader={<HeaderIconLinkRow links={[viewInSource, viewInTechDocs]} />}\n />\n <Divider />\n <CardContent className={cardContentClass}>\n <AboutContent entity={entity} />\n </CardContent>\n </Card>\n );\n}\n","/*\n * Copyright 2021 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport React, { useEffect, useState } from 'react';\nimport {\n capitalize,\n createStyles,\n InputBase,\n makeStyles,\n MenuItem,\n Select,\n Theme,\n} from '@material-ui/core';\nimport {\n EntityKindFilter,\n useEntityKinds,\n useEntityListProvider,\n} from '@backstage/plugin-catalog-react';\n\nconst useStyles = makeStyles((theme: Theme) =>\n createStyles({\n root: {\n ...theme.typography.h4,\n },\n }),\n);\n\ntype CatalogKindHeaderProps = {\n initialFilter?: string;\n};\n\nexport const CatalogKindHeader = ({\n initialFilter = 'component',\n}: CatalogKindHeaderProps) => {\n const classes = useStyles();\n const { kinds: allKinds = [] } = useEntityKinds();\n const { updateFilters, queryParameters } = useEntityListProvider();\n\n const [selectedKind, setSelectedKind] = useState(\n ([queryParameters.kind].flat()[0] ?? initialFilter).toLocaleLowerCase(\n 'en-US',\n ),\n );\n\n useEffect(() => {\n updateFilters({\n kind: selectedKind ? new EntityKindFilter(selectedKind) : undefined,\n });\n }, [selectedKind, updateFilters]);\n\n // Before allKinds is loaded, or when a kind is entered manually in the URL, selectedKind may not\n // be present in allKinds. It should still be shown in the dropdown, but may not have the nice\n // enforced casing from the catalog-backend. This makes a key/value record for the Select options,\n // including selectedKind if it's unknown - but allows the selectedKind to get clobbered by the\n // more proper catalog kind if it exists.\n const options = [capitalize(selectedKind)]\n .concat(allKinds)\n .sort()\n .reduce((acc, kind) => {\n acc[kind.toLocaleLowerCase('en-US')] = kind;\n return acc;\n }, {} as Record<string, string>);\n\n return (\n <Select\n input={<InputBase value={selectedKind} />}\n value={selectedKind}\n onChange={e => setSelectedKind(e.target.value as string)}\n classes={classes}\n >\n {Object.keys(options).map(kind => (\n <MenuItem value={kind} key={kind}>\n {`${options[kind]}s`}\n </MenuItem>\n ))}\n </Select>\n );\n};\n","/*\n * Copyright 2021 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport React from 'react';\nimport {\n Box,\n Chip,\n Divider,\n ListItem,\n ListItemText,\n makeStyles,\n} from '@material-ui/core';\nimport { Link } from '@backstage/core-components';\n\nconst useStyles = makeStyles({\n flexContainer: {\n flexWrap: 'wrap',\n },\n itemText: {\n width: '100%',\n wordBreak: 'break-all',\n marginBottom: '1rem',\n },\n});\n\nexport const CatalogResultListItem = ({ result }: any) => {\n const classes = useStyles();\n return (\n <Link to={result.location}>\n <ListItem alignItems=\"flex-start\" className={classes.flexContainer}>\n <ListItemText\n className={classes.itemText}\n primaryTypographyProps={{ variant: 'h6' }}\n primary={result.title}\n secondary={result.text}\n />\n <Box>\n {result.kind && <Chip label={`Kind: ${result.kind}`} size=\"small\" />}\n {result.lifecycle && (\n <Chip label={`Lifecycle: ${result.lifecycle}`} size=\"small\" />\n )}\n </Box>\n </ListItem>\n <Divider component=\"li\" />\n </Link>\n );\n};\n","/*\n * Copyright 2021 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport React from 'react';\nimport {\n formatEntityRefTitle,\n EntityRefLink,\n EntityRefLinks,\n} from '@backstage/plugin-catalog-react';\nimport { Chip } from '@material-ui/core';\nimport { EntityRow } from './types';\nimport { OverflowTooltip, TableColumn } from '@backstage/core-components';\nimport { Entity } from '@backstage/catalog-model';\n\ntype NameColumnProps = {\n defaultKind?: string;\n};\n\nexport function createNameColumn(\n props?: NameColumnProps,\n): TableColumn<EntityRow> {\n function formatContent(entity: Entity): string {\n return (\n entity.metadata?.title ||\n formatEntityRefTitle(entity, {\n defaultKind: props?.defaultKind,\n })\n );\n }\n\n return {\n title: 'Name',\n field: 'resolved.name',\n highlight: true,\n customSort({ entity: entity1 }, { entity: entity2 }) {\n // TODO: We could implement this more efficiently by comparing field by field.\n // This has similar issues as above.\n return formatContent(entity1).localeCompare(formatContent(entity2));\n },\n render: ({ entity }) => (\n <EntityRefLink\n entityRef={entity}\n defaultKind={props?.defaultKind || 'Component'}\n title={entity.metadata?.title}\n />\n ),\n };\n}\n\nexport function createSystemColumn(): TableColumn<EntityRow> {\n return {\n title: 'System',\n field: 'resolved.partOfSystemRelationTitle',\n render: ({ resolved }) => (\n <EntityRefLinks\n entityRefs={resolved.partOfSystemRelations}\n defaultKind=\"system\"\n />\n ),\n };\n}\n\nexport function createOwnerColumn(): TableColumn<EntityRow> {\n return {\n title: 'Owner',\n field: 'resolved.ownedByRelationsTitle',\n render: ({ resolved }) => (\n <EntityRefLinks\n entityRefs={resolved.ownedByRelations}\n defaultKind=\"group\"\n />\n ),\n };\n}\n\nexport function createSpecTypeColumn(): TableColumn<EntityRow> {\n return {\n title: 'Type',\n field: 'entity.spec.type',\n hidden: true,\n };\n}\n\nexport function createSpecLifecycleColumn(): TableColumn<EntityRow> {\n return {\n title: 'Lifecycle',\n field: 'entity.spec.lifecycle',\n };\n}\n\nexport function createMetadataDescriptionColumn(): TableColumn<EntityRow> {\n return {\n title: 'Description',\n field: 'entity.metadata.description',\n render: ({ entity }) => (\n <OverflowTooltip\n text={entity.metadata.description}\n placement=\"bottom-start\"\n />\n ),\n width: 'auto',\n };\n}\n\nexport function createTagsColumn(): TableColumn<EntityRow> {\n return {\n title: 'Tags',\n field: 'entity.metadata.tags',\n cellStyle: {\n padding: '0px 16px 0px 20px',\n },\n render: ({ entity }) => (\n <>\n {entity.metadata.tags &&\n entity.metadata.tags.map(t => (\n <Chip\n key={t}\n label={t}\n size=\"small\"\n variant=\"outlined\"\n style={{ marginBottom: '0px' }}\n />\n ))}\n </>\n ),\n };\n}\n","/*\n * Copyright 2020 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport { RELATION_OWNED_BY, RELATION_PART_OF } from '@backstage/catalog-model';\nimport {\n favoriteEntityIcon,\n favoriteEntityTooltip,\n formatEntityRefTitle,\n getEntityMetadataEditUrl,\n getEntityMetadataViewUrl,\n getEntityRelations,\n useEntityListProvider,\n useStarredEntities,\n} from '@backstage/plugin-catalog-react';\nimport Edit from '@material-ui/icons/Edit';\nimport OpenInNew from '@material-ui/icons/OpenInNew';\nimport { capitalize } from 'lodash';\nimport React, { useMemo } from 'react';\nimport * as columnFactories from './columns';\nimport { EntityRow } from './types';\nimport {\n CodeSnippet,\n Table,\n TableColumn,\n TableProps,\n WarningPanel,\n} from '@backstage/core-components';\n\ntype CatalogTableProps = {\n columns?: TableColumn<EntityRow>[];\n actions?: TableProps<EntityRow>['actions'];\n};\n\nexport const CatalogTable = ({ columns, actions }: CatalogTableProps) => {\n const { isStarredEntity, toggleStarredEntity } = useStarredEntities();\n const { loading, error, entities, filters } = useEntityListProvider();\n\n const defaultColumns: TableColumn<EntityRow>[] = useMemo(\n () => [\n columnFactories.createNameColumn({ defaultKind: filters.kind?.value }),\n columnFactories.createSystemColumn(),\n columnFactories.createOwnerColumn(),\n columnFactories.createSpecTypeColumn(),\n columnFactories.createSpecLifecycleColumn(),\n columnFactories.createMetadataDescriptionColumn(),\n columnFactories.createTagsColumn(),\n ],\n [filters.kind?.value],\n );\n\n const showTypeColumn = filters.type === undefined;\n // TODO(timbonicus): remove the title from the CatalogTable once using EntitySearchBar\n const titlePreamble = capitalize(filters.user?.value ?? 'all');\n\n if (error) {\n return (\n <div>\n <WarningPanel\n severity=\"error\"\n title=\"Could not fetch catalog entities.\"\n >\n <CodeSnippet language=\"text\" text={error.toString()} />\n </WarningPanel>\n </div>\n );\n }\n\n const defaultActions: TableProps<EntityRow>['actions'] = [\n ({ entity }) => {\n const url = getEntityMetadataViewUrl(entity);\n return {\n icon: () => <OpenInNew aria-label=\"View\" fontSize=\"small\" />,\n tooltip: 'View',\n disabled: !url,\n onClick: () => {\n if (!url) return;\n window.open(url, '_blank');\n },\n };\n },\n ({ entity }) => {\n const url = getEntityMetadataEditUrl(entity);\n return {\n icon: () => <Edit aria-label=\"Edit\" fontSize=\"small\" />,\n tooltip: 'Edit',\n disabled: !url,\n onClick: () => {\n if (!url) return;\n window.open(url, '_blank');\n },\n };\n },\n ({ entity }) => {\n const isStarred = isStarredEntity(entity);\n return {\n cellStyle: { paddingLeft: '1em' },\n icon: () => favoriteEntityIcon(isStarred),\n tooltip: favoriteEntityTooltip(isStarred),\n onClick: () => toggleStarredEntity(entity),\n };\n },\n ];\n\n const rows = entities.map(entity => {\n const partOfSystemRelations = getEntityRelations(entity, RELATION_PART_OF, {\n kind: 'system',\n });\n const ownedByRelations = getEntityRelations(entity, RELATION_OWNED_BY);\n\n return {\n entity,\n resolved: {\n name: formatEntityRefTitle(entity, {\n defaultKind: 'Component',\n }),\n ownedByRelationsTitle: ownedByRelations\n .map(r => formatEntityRefTitle(r, { defaultKind: 'group' }))\n .join(', '),\n ownedByRelations,\n partOfSystemRelationTitle: partOfSystemRelations\n .map(r =>\n formatEntityRefTitle(r, {\n defaultKind: 'system',\n }),\n )\n .join(', '),\n partOfSystemRelations,\n },\n };\n });\n\n const typeColumn = (columns || defaultColumns).find(c => c.title === 'Type');\n if (typeColumn) {\n typeColumn.hidden = !showTypeColumn;\n }\n const showPagination = rows.length > 20;\n\n return (\n <Table<EntityRow>\n isLoading={loading}\n columns={columns || defaultColumns}\n options={{\n paging: showPagination,\n pageSize: 20,\n actionsColumnIndex: -1,\n loadingType: 'linear',\n showEmptyDataSourceMessage: !loading,\n padding: 'dense',\n pageSizeOptions: [20, 50, 100],\n }}\n title={`${titlePreamble} (${entities.length})`}\n data={rows}\n actions={actions || defaultActions}\n />\n );\n};\n\nCatalogTable.columns = columnFactories;\n","/*\n * Copyright 2020 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n Divider,\n IconButton,\n ListItemIcon,\n ListItemText,\n MenuItem,\n MenuList,\n Popover,\n} from '@material-ui/core';\nimport { makeStyles } from '@material-ui/core/styles';\nimport Cancel from '@material-ui/icons/Cancel';\nimport MoreVert from '@material-ui/icons/MoreVert';\nimport React, { useState } from 'react';\nimport { IconComponent } from '@backstage/core-plugin-api';\nimport { useEntityPermission } from '@backstage/plugin-catalog-react';\nimport { catalogEntityDeletePermission } from '@backstage/plugin-catalog-common';\n\n// TODO(freben): It should probably instead be the case that Header sets the theme text color to white inside itself unconditionally instead\nconst useStyles = makeStyles({\n button: {\n color: 'white',\n },\n});\n\n// NOTE(freben): Intentionally not exported at this point, since it's part of\n// the unstable extra context menu items concept below\ntype ExtraContextMenuItem = {\n title: string;\n Icon: IconComponent;\n onClick: () => void;\n};\n\n// unstable context menu option, eg: disable the unregister entity menu\ntype contextMenuOptions = {\n disableUnregister: boolean;\n};\n\ntype Props = {\n UNSTABLE_extraContextMenuItems?: ExtraContextMenuItem[];\n UNSTABLE_contextMenuOptions?: contextMenuOptions;\n onUnregisterEntity: () => void;\n};\n\nexport const EntityContextMenu = ({\n UNSTABLE_extraContextMenuItems,\n UNSTABLE_contextMenuOptions,\n onUnregisterEntity,\n}: Props) => {\n const [anchorEl, setAnchorEl] = useState<HTMLButtonElement>();\n const classes = useStyles();\n const unregisterPermission = useEntityPermission(\n catalogEntityDeletePermission,\n );\n\n const onOpen = (event: React.SyntheticEvent<HTMLButtonElement>) => {\n setAnchorEl(event.currentTarget);\n };\n\n const onClose = () => {\n setAnchorEl(undefined);\n };\n\n const extraItems = UNSTABLE_extraContextMenuItems && [\n ...UNSTABLE_extraContextMenuItems.map(item => (\n <MenuItem\n key={item.title}\n onClick={() => {\n onClose();\n item.onClick();\n }}\n >\n <ListItemIcon>\n <item.Icon fontSize=\"small\" />\n </ListItemIcon>\n <ListItemText primary={item.title} />\n </MenuItem>\n )),\n <Divider key=\"the divider is here!\" />,\n ];\n\n const disableUnregister =\n (!unregisterPermission.allowed ||\n UNSTABLE_contextMenuOptions?.disableUnregister) ??\n false;\n\n return (\n <>\n <IconButton\n aria-label=\"more\"\n aria-controls=\"long-menu\"\n aria-haspopup=\"true\"\n onClick={onOpen}\n data-testid=\"menu-button\"\n className={classes.button}\n >\n <MoreVert />\n </IconButton>\n <Popover\n open={Boolean(anchorEl)}\n onClose={onClose}\n anchorEl={anchorEl}\n anchorOrigin={{ vertical: 'bottom', horizontal: 'right' }}\n transformOrigin={{ vertical: 'top', horizontal: 'right' }}\n >\n <MenuList>\n {extraItems}\n <MenuItem\n onClick={() => {\n onClose();\n onUnregisterEntity();\n }}\n disabled={disableUnregister}\n >\n <ListItemIcon>\n <Cancel fontSize=\"small\" />\n </ListItemIcon>\n <ListItemText primary=\"Unregister entity\" />\n </MenuItem>\n </MenuList>\n </Popover>\n </>\n );\n};\n","/*\n * Copyright 2020 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n Entity,\n ENTITY_DEFAULT_NAMESPACE,\n RELATION_OWNED_BY,\n} from '@backstage/catalog-model';\nimport {\n Content,\n Header,\n HeaderLabel,\n Link,\n Page,\n Progress,\n RoutedTabs,\n WarningPanel,\n} from '@backstage/core-components';\nimport {\n attachComponentData,\n IconComponent,\n useElementFilter,\n} from '@backstage/core-plugin-api';\nimport {\n EntityContext,\n EntityRefLinks,\n FavoriteEntity,\n getEntityRelations,\n UnregisterEntityDialog,\n useEntityCompoundName,\n} from '@backstage/plugin-catalog-react';\nimport { Box, TabProps } from '@material-ui/core';\nimport { Alert } from '@material-ui/lab';\nimport React, { useContext, useState } from 'react';\nimport { useNavigate } from 'react-router';\nimport { EntityContextMenu } from '../EntityContextMenu/EntityContextMenu';\n\ntype SubRoute = {\n path: string;\n title: string;\n children: JSX.Element;\n if?: (entity: Entity) => boolean;\n tabProps?: TabProps<React.ElementType, { component?: React.ElementType }>;\n};\n\nconst dataKey = 'plugin.catalog.entityLayoutRoute';\n\nconst Route: (props: SubRoute) => null = () => null;\nattachComponentData(Route, dataKey, true);\n\n// This causes all mount points that are discovered within this route to use the path of the route itself\nattachComponentData(Route, 'core.gatherMountPoints', true);\n\nconst EntityLayoutTitle = ({\n entity,\n title,\n}: {\n title: string;\n entity: Entity | undefined;\n}) => {\n return (\n <Box display=\"inline-flex\" alignItems=\"center\" height=\"1em\" maxWidth=\"100%\">\n <Box\n component=\"span\"\n textOverflow=\"ellipsis\"\n whiteSpace=\"nowrap\"\n overflow=\"hidden\"\n >\n {title}\n </Box>\n {entity && <FavoriteEntity entity={entity} />}\n </Box>\n );\n};\n\nconst headerProps = (\n paramKind: string | undefined,\n paramNamespace: string | undefined,\n paramName: string | undefined,\n entity: Entity | undefined,\n): { headerTitle: string; headerType: string } => {\n const kind = paramKind ?? entity?.kind ?? '';\n const namespace = paramNamespace ?? entity?.metadata.namespace ?? '';\n const name =\n entity?.metadata.title ?? paramName ?? entity?.metadata.name ?? '';\n return {\n headerTitle: `${name}${\n namespace && namespace !== ENTITY_DEFAULT_NAMESPACE\n ? ` in ${namespace}`\n : ''\n }`,\n headerType: (() => {\n let t = kind.toLocaleLowerCase('en-US');\n if (entity && entity.spec && 'type' in entity.spec) {\n t += ' — ';\n t += (entity.spec as { type: string }).type.toLocaleLowerCase('en-US');\n }\n return t;\n })(),\n };\n};\n\nconst EntityLabels = ({ entity }: { entity: Entity }) => {\n const ownedByRelations = getEntityRelations(entity, RELATION_OWNED_BY);\n return (\n <>\n {ownedByRelations.length > 0 && (\n <HeaderLabel\n label=\"Owner\"\n value={\n <EntityRefLinks\n entityRefs={ownedByRelations}\n defaultKind=\"Group\"\n color=\"inherit\"\n />\n }\n />\n )}\n {entity.spec?.lifecycle && (\n <HeaderLabel label=\"Lifecycle\" value={entity.spec.lifecycle} />\n )}\n </>\n );\n};\n\n// NOTE(freben): Intentionally not exported at this point, since it's part of\n// the unstable extra context menu items concept below\ntype ExtraContextMenuItem = {\n title: string;\n Icon: IconComponent;\n onClick: () => void;\n};\n\n// unstable context menu option, eg: disable the unregister entity menu\ntype contextMenuOptions = {\n disableUnregister: boolean;\n};\n\ntype EntityLayoutProps = {\n UNSTABLE_extraContextMenuItems?: ExtraContextMenuItem[];\n UNSTABLE_contextMenuOptions?: contextMenuOptions;\n children?: React.ReactNode;\n};\n\n/**\n * EntityLayout is a compound component, which allows you to define a layout for\n * entities using a sub-navigation mechanism.\n *\n * Consists of two parts: EntityLayout and EntityLayout.Route\n *\n * @example\n * ```jsx\n * <EntityLayout>\n * <EntityLayout.Route path=\"/example\" title=\"Example tab\">\n * <div>This is rendered under /example/anything-here route</div>\n * </EntityLayout.Route>\n * </EntityLayout>\n * ```\n */\nexport const EntityLayout = ({\n UNSTABLE_extraContextMenuItems,\n UNSTABLE_contextMenuOptions,\n children,\n}: EntityLayoutProps) => {\n const { kind, namespace, name } = useEntityCompoundName();\n const { entity, loading, error } = useContext(EntityContext);\n const routes = useElementFilter(\n children,\n elements =>\n elements\n .selectByComponentData({\n key: dataKey,\n withStrictError:\n 'Child of EntityLayout must be an EntityLayout.Route',\n })\n .getElements<SubRoute>() // all nodes, element data, maintain structure or not?\n .flatMap(({ props }) => {\n if (props.if && entity && !props.if(entity)) {\n return [];\n }\n\n return [\n {\n path: props.path,\n title: props.title,\n children: props.children,\n tabProps: props.tabProps,\n },\n ];\n }),\n [entity],\n );\n\n const { headerTitle, headerType } = headerProps(\n kind,\n namespace,\n name,\n entity,\n );\n\n const [confirmationDialogOpen, setConfirmationDialogOpen] = useState(false);\n const navigate = useNavigate();\n const cleanUpAfterRemoval = async () => {\n setConfirmationDialogOpen(false);\n navigate('/');\n };\n\n const showRemovalDialog = () => setConfirmationDialogOpen(true);\n\n return (\n <Page themeId={entity?.spec?.type?.toString() ?? 'home'}>\n <Header\n title={<EntityLayoutTitle title={headerTitle} entity={entity!} />}\n pageTitleOverride={headerTitle}\n type={headerType}\n >\n {entity && (\n <>\n <EntityLabels entity={entity} />\n <EntityContextMenu\n UNSTABLE_extraContextMenuItems={UNSTABLE_extraContextMenuItems}\n UNSTABLE_contextMenuOptions={UNSTABLE_contextMenuOptions}\n onUnregisterEntity={showRemovalDialog}\n />\n </>\n )}\n </Header>\n\n {loading && <Progress />}\n\n {entity && <RoutedTabs routes={routes} />}\n\n {error && (\n <Content>\n <Alert severity=\"error\">{error.toString()}</Alert>\n </Content>\n )}\n\n {!loading && !error && !entity && (\n <Content>\n <WarningPanel title=\"Entity not found\">\n There is no {kind} with the requested{' '}\n <Link to=\"https://backstage.io/docs/features/software-catalog/references\">\n kind, namespace, and name\n </Link>\n .\n </WarningPanel>\n </Content>\n )}\n\n <UnregisterEntityDialog\n open={confirmationDialogOpen}\n entity={entity!}\n onConfirm={cleanUpAfterRemoval}\n onClose={() => setConfirmationDialogOpen(false)}\n />\n </Page>\n );\n};\n\nEntityLayout.Route = Route;\n","/*\n * Copyright 2021 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { Entity } from '@backstage/catalog-model';\nimport { catalogApiRef } from '@backstage/plugin-catalog-react';\nimport { Button, Dialog, DialogActions, DialogTitle } from '@material-ui/core';\nimport React, { useState } from 'react';\nimport { alertApiRef, useApi } from '@backstage/core-plugin-api';\nimport { assertError } from '@backstage/errors';\n\ntype Props = {\n open: boolean;\n onClose: () => any;\n onConfirm: () => any;\n entity: Entity;\n};\n\nexport const DeleteEntityDialog = ({\n open,\n onClose,\n onConfirm,\n entity,\n}: Props) => {\n const [busy, setBusy] = useState(false);\n const catalogApi = useApi(catalogApiRef);\n const alertApi = useApi(alertApiRef);\n\n const onDelete = async () => {\n setBusy(true);\n try {\n const uid = entity.metadata.uid;\n await catalogApi.removeEntityByUid(uid!);\n onConfirm();\n } catch (err) {\n assertError(err);\n alertApi.post({ message: err.message });\n } finally {\n setBusy(false);\n }\n };\n\n return (\n <Dialog open={open} onClose={onClose}>\n <DialogTitle id=\"responsive-dialog-title\">\n Are you sure you want to delete this entity?\n </DialogTitle>\n <DialogActions>\n <Button\n variant=\"contained\"\n color=\"secondary\"\n disabled={busy}\n onClick={onDelete}\n >\n Delete\n </Button>\n <Button onClick={onClose} color=\"primary\">\n Cancel\n </Button>\n </DialogActions>\n </Dialog>\n );\n};\n","/*\n * Copyright 2021 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { Entity } from '@backstage/catalog-model';\nimport { catalogRouteRef, useEntity } from '@backstage/plugin-catalog-react';\nimport { Alert } from '@material-ui/lab';\nimport React, { useState } from 'react';\nimport { useNavigate } from 'react-router';\nimport { DeleteEntityDialog } from './DeleteEntityDialog';\nimport { useRouteRef } from '@backstage/core-plugin-api';\n\nexport const isOrphan = (entity: Entity) =>\n entity?.metadata?.annotations?.['backstage.io/orphan'] === 'true';\n\n/**\n * Displays a warning alert if the entity is marked as orphan with the ability to delete said entity.\n */\nexport const EntityOrphanWarning = () => {\n const navigate = useNavigate();\n const catalogLink = useRouteRef(catalogRouteRef);\n const [confirmationDialogOpen, setConfirmationDialogOpen] = useState(false);\n const { entity } = useEntity();\n\n const cleanUpAfterRemoval = async () => {\n setConfirmationDialogOpen(false);\n navigate(catalogLink());\n };\n\n return (\n <>\n <Alert severity=\"warning\" onClick={() => setConfirmationDialogOpen(true)}>\n This entity is not referenced by any location and is therefore not\n receiving updates. Click here to delete.\n </Alert>\n <DeleteEntityDialog\n open={confirmationDialogOpen}\n entity={entity!}\n onConfirm={cleanUpAfterRemoval}\n onClose={() => setConfirmationDialogOpen(false)}\n />\n </>\n );\n};\n","/*\n * Copyright 2021 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n Entity,\n AlphaEntity,\n stringifyEntityRef,\n EntityStatusItem,\n compareEntityToRef,\n} from '@backstage/catalog-model';\nimport {\n catalogApiRef,\n EntityRefLink,\n useEntity,\n} from '@backstage/plugin-catalog-react';\nimport { Box } from '@material-ui/core';\nimport React from 'react';\nimport { ResponseErrorPanel } from '@backstage/core-components';\nimport {\n CatalogApi,\n ENTITY_STATUS_CATALOG_PROCESSING_TYPE,\n} from '@backstage/catalog-client';\nimport { useApi, ApiHolder } from '@backstage/core-plugin-api';\nimport useAsync from 'react-use/lib/useAsync';\nimport { SerializedError } from '@backstage/errors';\n\nconst errorFilter = (i: EntityStatusItem) =>\n i.error &&\n i.level === 'error' &&\n i.type === ENTITY_STATUS_CATALOG_PROCESSING_TYPE;\n\ntype GetOwnAndAncestorsErrorsResponse = {\n items: {\n errors: SerializedError[];\n entity: Entity;\n }[];\n};\n\nasync function getOwnAndAncestorsErrors(\n entityRef: string,\n catalogApi: CatalogApi,\n): Promise<GetOwnAndAncestorsErrorsResponse> {\n const ancestors = await catalogApi.getEntityAncestors({ entityRef });\n const items = ancestors.items\n .map(item => {\n const statuses = (item.entity as AlphaEntity).status?.items ?? [];\n const errors = statuses\n .filter(errorFilter)\n .map(e => e.error)\n .filter((e): e is SerializedError => Boolean(e));\n return { errors: errors, entity: item.entity };\n })\n .filter(item => item.errors.length > 0);\n return { items };\n}\n\nexport const hasCatalogProcessingErrors = async (\n entity: Entity,\n context: { apis: ApiHolder },\n) => {\n const catalogApi = context.apis.get(catalogApiRef);\n if (!catalogApi) {\n throw new Error(`No implementation available for ${catalogApiRef}`);\n }\n\n const errors = await getOwnAndAncestorsErrors(\n stringifyEntityRef(entity),\n catalogApi,\n );\n return errors.items.length > 0;\n};\n\n/**\n * Displays a list of errors from the ancestors of the current entity.\n */\nexport const EntityProcessingErrorsPanel = () => {\n const { entity } = useEntity();\n const entityRef = stringifyEntityRef(entity);\n const catalogApi = useApi(catalogApiRef);\n const { loading, error, value } = useAsync(async () => {\n return getOwnAndAncestorsErrors(entityRef, catalogApi);\n }, [entityRef, catalogApi]);\n\n if (error) {\n return (\n <Box mb={1}>\n <ResponseErrorPanel error={error} />\n </Box>\n );\n }\n\n if (loading || !value) {\n return null;\n }\n\n return (\n <>\n {value.items.map((ancestorError, index) => (\n <Box key={index} mb={1}>\n {!compareEntityToRef(\n entity,\n stringifyEntityRef(ancestorError.entity),\n ) && (\n <Box p={1}>\n The error below originates from{' '}\n <EntityRefLink entityRef={ancestorError.entity} />\n </Box>\n )}\n {ancestorError.errors.map((e, i) => (\n <ResponseErrorPanel key={i} error={e} />\n ))}\n </Box>\n ))}\n </>\n );\n};\n","/*\n * Copyright 2020 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport React from 'react';\nimport {\n useParams,\n useNavigate,\n PartialRouteObject,\n matchRoutes,\n RouteObject,\n useRoutes,\n Navigate,\n RouteMatch,\n} from 'react-router';\nimport { Helmet } from 'react-helmet';\nimport { Tab, HeaderTabs, Content } from '@backstage/core-components';\n\nconst getSelectedIndexOrDefault = (\n matchedRoute: RouteMatch,\n tabs: Tab[],\n defaultIndex = 0,\n) => {\n if (!matchedRoute) return defaultIndex;\n const tabIndex = tabs.findIndex(t => t.id === matchedRoute.route.path);\n return ~tabIndex ? tabIndex : defaultIndex;\n};\n\n/**\n * Compound component, which allows you to define layout\n * for EntityPage using Tabs as a sub-navigation mechanism\n * Consists of 2 parts: Tabbed.Layout and Tabbed.Content.\n * Takes care of: tabs, routes, document titles, spacing around content\n *\n * @example\n * ```jsx\n * <Tabbed.Layout>\n * <Tabbed.Content\n * title=\"Example tab\"\n * route=\"/example/*\"\n * element={<div>This is rendered under /example/anything-here route</div>}\n * />\n * </TabbedLayout>\n * ```\n */\nexport const Tabbed = {\n Layout: ({ children }: { children: React.ReactNode }) => {\n const routes: PartialRouteObject[] = [];\n const tabs: Tab[] = [];\n const params = useParams();\n const navigate = useNavigate();\n\n React.Children.forEach(children, child => {\n if (!React.isValidElement(child)) {\n // Skip conditionals resolved to falses/nulls/undefineds etc\n return;\n }\n if (child.type !== Tabbed.Content) {\n throw new Error(\n 'This component only accepts Content elements as direct children. Check the code of the EntityPage.',\n );\n }\n const pathAndId = (child as JSX.Element).props.path;\n\n // Child here must be then always a functional component without any wrappers\n tabs.push({\n id: pathAndId,\n label: (child as JSX.Element).props.title,\n });\n\n routes.push({\n path: pathAndId,\n element: child.props.element,\n });\n });\n\n // Add catch-all for incorrect sub-routes\n if ((routes?.[0]?.path ?? '') !== '')\n routes.push({\n path: '/*',\n element: <Navigate to={routes[0].path!} />,\n });\n\n const [matchedRoute] =\n matchRoutes(routes as RouteObject[], `/${params['*']}`) ?? [];\n const selectedIndex = getSelectedIndexOrDefault(matchedRoute, tabs);\n const currentTab = tabs[selectedIndex];\n const title = currentTab?.label;\n\n const onTabChange = (index: number) =>\n // Remove trailing /*\n // And remove leading / for relative navigation\n // Note! route resolves relative to the position in the React tree,\n // not relative to current location\n navigate(tabs[index].id.replace(/\\/\\*$/, '').replace(/^\\//, ''));\n\n const currentRouteElement = useRoutes(routes);\n\n if (!currentTab) return null;\n return (\n <>\n <HeaderTabs\n tabs={tabs}\n selectedIndex={selectedIndex}\n onChange={onTabChange}\n />\n <Content>\n <Helmet title={title} />\n {currentRouteElement}\n </Content>\n </>\n );\n },\n Content: (_props: { path: string; title: string; element: JSX.Element }) =>\n null,\n};\n","/*\n * Copyright 2020 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport {\n Entity,\n ENTITY_DEFAULT_NAMESPACE,\n RELATION_OWNED_BY,\n} from '@backstage/catalog-model';\nimport {\n EntityContext,\n EntityRefLinks,\n FavoriteEntity,\n getEntityRelations,\n UnregisterEntityDialog,\n useEntityCompoundName,\n} from '@backstage/plugin-catalog-react';\nimport { Box } from '@material-ui/core';\nimport React, { useContext, useState } from 'react';\nimport { useNavigate } from 'react-router';\nimport { EntityContextMenu } from '../EntityContextMenu/EntityContextMenu';\nimport { Tabbed } from './Tabbed';\n\nimport {\n Content,\n Header,\n HeaderLabel,\n Link,\n Page,\n Progress,\n ResponseErrorPanel,\n WarningPanel,\n} from '@backstage/core-components';\n\nimport { IconComponent } from '@backstage/core-plugin-api';\n\nconst EntityPageTitle = ({\n entity,\n title,\n}: {\n title: string;\n entity: Entity | undefined;\n}) => (\n <Box display=\"inline-flex\" alignItems=\"center\" height=\"1em\">\n {title}\n {entity && <FavoriteEntity entity={entity} />}\n </Box>\n);\n\nconst EntityLabels = ({ entity }: { entity: Entity }) => {\n const ownedByRelations = getEntityRelations(entity, RELATION_OWNED_BY);\n return (\n <>\n {ownedByRelations.length > 0 && (\n <HeaderLabel\n label=\"Owner\"\n value={\n <EntityRefLinks\n entityRefs={ownedByRelations}\n defaultKind=\"Group\"\n color=\"inherit\"\n />\n }\n />\n )}\n {entity.spec?.lifecycle && (\n <HeaderLabel label=\"Lifecycle\" value={entity.spec.lifecycle} />\n )}\n </>\n );\n};\n\nconst headerProps = (\n kind: string,\n namespace: string | undefined,\n name: string,\n entity: Entity | undefined,\n): { headerTitle: string; headerType: string } => {\n return {\n headerTitle: `${name}${\n namespace && namespace !== ENTITY_DEFAULT_NAMESPACE\n ? ` in ${namespace}`\n : ''\n }`,\n headerType: (() => {\n let t = kind.toLocaleLowerCase('en-US');\n if (entity && entity.spec && 'type' in entity.spec) {\n t += ' — ';\n t += (entity.spec as { type: string }).type.toLocaleLowerCase('en-US');\n }\n return t;\n })(),\n };\n};\n\n// NOTE(freben): Intentionally not exported at this point, since it's part of\n// the unstable extra context menu items concept below\ntype ExtraContextMenuItem = {\n title: string;\n Icon: IconComponent;\n onClick: () => void;\n};\n\n// unstable context menu option, eg: disable the unregister entity menu\ntype contextMenuOptions = {\n disableUnregister: boolean;\n};\n\ntype EntityPageLayoutProps = {\n UNSTABLE_extraContextMenuItems?: ExtraContextMenuItem[];\n UNSTABLE_contextMenuOptions?: contextMenuOptions;\n children?: React.ReactNode;\n};\n\nexport const EntityPageLayout = ({\n children,\n UNSTABLE_extraContextMenuItems,\n UNSTABLE_contextMenuOptions,\n}: EntityPageLayoutProps) => {\n const { kind, namespace, name } = useEntityCompoundName();\n const { entity, loading, error } = useContext(EntityContext);\n const { headerTitle, headerType } = headerProps(\n kind,\n namespace,\n name,\n entity!,\n );\n\n const [confirmationDialogOpen, setConfirmationDialogOpen] = useState(false);\n const navigate = useNavigate();\n const cleanUpAfterRemoval = async () => {\n setConfirmationDialogOpen(false);\n navigate('/');\n };\n\n const showRemovalDialog = () => setConfirmationDialogOpen(true);\n\n return (\n <Page themeId={entity?.spec?.type?.toString() ?? 'home'}>\n <Header\n title={<EntityPageTitle title={headerTitle} entity={entity!} />}\n pageTitleOverride={headerTitle}\n type={headerType}\n >\n {/* TODO: Make entity labels configurable for entity kind / type */}\n {entity && (\n <>\n <EntityLabels entity={entity} />\n <EntityContextMenu\n UNSTABLE_extraContextMenuItems={UNSTABLE_extraContextMenuItems}\n UNSTABLE_contextMenuOptions={UNSTABLE_contextMenuOptions}\n onUnregisterEntity={showRemovalDialog}\n />\n </>\n )}\n </Header>\n\n {loading && (\n <Content>\n <Progress />\n </Content>\n )}\n\n {entity && <Tabbed.Layout>{children}</Tabbed.Layout>}\n\n {error && (\n <Content>\n <ResponseErrorPanel error={error} />\n </Content>\n )}\n\n {!loading && !error && !entity && (\n <Content>\n <WarningPanel title=\"Entity not found\">\n There is no {kind} with the requested{' '}\n <Link to=\"https://backstage.io/docs/features/software-catalog/references\">\n kind, namespace, and name\n </Link>\n .\n </WarningPanel>\n </Content>\n )}\n\n <UnregisterEntityDialog\n open={confirmationDialogOpen}\n entity={entity!}\n onConfirm={cleanUpAfterRemoval}\n onClose={() => setConfirmationDialogOpen(false)}\n />\n </Page>\n );\n};\n\nEntityPageLayout.Content = Tabbed.Content;\n","/*\n * Copyright 2020 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { Entity } from '@backstage/catalog-model';\nimport { useEntity } from '@backstage/plugin-catalog-react';\nimport React, { PropsWithChildren, ReactNode } from 'react';\nimport {\n attachComponentData,\n useApiHolder,\n useElementFilter,\n ApiHolder,\n} from '@backstage/core-plugin-api';\nimport useAsync from 'react-use/lib/useAsync';\n\nconst ENTITY_SWITCH_KEY = 'core.backstage.entitySwitch';\n\nconst EntitySwitchCase = (_: {\n if?: (\n entity: Entity,\n context: { apis: ApiHolder },\n ) => boolean | Promise<boolean>;\n children: ReactNode;\n}) => null;\n\nattachComponentData(EntitySwitchCase, ENTITY_SWITCH_KEY, true);\n\ntype SwitchCase = {\n if?: (\n entity: Entity,\n context: { apis: ApiHolder },\n ) => boolean | Promise<boolean>;\n children: JSX.Element;\n};\n\ntype SwitchCaseResult = {\n if: boolean | Promise<boolean>;\n children: JSX.Element;\n};\n\nexport const EntitySwitch = ({ children }: PropsWithChildren<{}>) => {\n const { entity } = useEntity();\n const apis = useApiHolder();\n const results = useElementFilter(\n children,\n collection =>\n collection\n .selectByComponentData({\n key: ENTITY_SWITCH_KEY,\n withStrictError: 'Child of EntitySwitch is not an EntitySwitch.Case',\n })\n .getElements()\n .flatMap<SwitchCaseResult>((element: React.ReactElement) => {\n const { if: condition, children: elementsChildren } =\n element.props as SwitchCase;\n return [\n {\n if: condition?.(entity, { apis }) ?? true,\n children: elementsChildren,\n },\n ];\n }),\n [apis, entity],\n );\n const hasAsyncCases = results.some(\n r => typeof r.if === 'object' && 'then' in r.if,\n );\n\n if (hasAsyncCases) {\n return <AsyncEntitySwitch results={results} />;\n }\n\n return results.find(r => r.if)?.children ?? null;\n};\n\nfunction AsyncEntitySwitch({ results }: { results: SwitchCaseResult[] }) {\n const { loading, value } = useAsync(async () => {\n const promises = results.map(\n async ({ if: condition, children: output }) => {\n try {\n if (await condition) {\n return output;\n }\n } catch {\n /* ignored */\n }\n\n return null;\n },\n );\n return (await Promise.all(promises)).find(Boolean) ?? null;\n }, [results]);\n\n if (loading || !value) {\n return null;\n }\n\n return value;\n}\n\nEntitySwitch.Case = EntitySwitchCase;\n","/*\n * Copyright 2020 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { Entity, ComponentEntity } from '@backstage/catalog-model';\n\nfunction strCmp(a: string | undefined, b: string | undefined): boolean {\n return Boolean(\n a && a?.toLocaleLowerCase('en-US') === b?.toLocaleLowerCase('en-US'),\n );\n}\n\nexport function isKind(kind: string) {\n return (entity: Entity) => strCmp(entity?.kind, kind);\n}\n\nexport function isComponentType(type: string) {\n return (entity: Entity) => {\n if (!strCmp(entity?.kind, 'component')) {\n return false;\n }\n const componentEntity = entity as ComponentEntity;\n return strCmp(componentEntity.spec.type, type);\n };\n}\n\nexport function isNamespace(namespace: string) {\n return (entity: Entity) => strCmp(entity?.metadata?.namespace, namespace);\n}\n","/*\n * Copyright 2021 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { Grid } from '@material-ui/core';\nimport React, { PropsWithChildren } from 'react';\n\nexport const FilteredEntityLayout = ({ children }: PropsWithChildren<{}>) => (\n <Grid container style={{ position: 'relative' }}>\n {children}\n </Grid>\n);\n","/*\n * Copyright 2021 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { BackstageTheme } from '@backstage/theme';\nimport {\n Box,\n Button,\n Drawer,\n Grid,\n Typography,\n useMediaQuery,\n useTheme,\n} from '@material-ui/core';\nimport FilterListIcon from '@material-ui/icons/FilterList';\nimport React, { useState, PropsWithChildren } from 'react';\n\nexport const FilterContainer = ({ children }: PropsWithChildren<{}>) => {\n const isMidSizeScreen = useMediaQuery<BackstageTheme>(theme =>\n theme.breakpoints.down('md'),\n );\n const theme = useTheme<BackstageTheme>();\n const [filterDrawerOpen, setFilterDrawerOpen] = useState<boolean>(false);\n\n return isMidSizeScreen ? (\n <>\n <Button\n style={{ marginTop: theme.spacing(1), marginLeft: theme.spacing(1) }}\n onClick={() => setFilterDrawerOpen(true)}\n startIcon={<FilterListIcon />}\n >\n Filters\n </Button>\n <Drawer\n open={filterDrawerOpen}\n onClose={() => setFilterDrawerOpen(false)}\n anchor=\"left\"\n disableAutoFocus\n keepMounted\n variant=\"temporary\"\n >\n <Box m={2}>\n <Typography\n variant=\"h6\"\n component=\"h2\"\n style={{ marginBottom: theme.spacing(1) }}\n >\n Filters\n </Typography>\n {children}\n </Box>\n </Drawer>\n </>\n ) : (\n <Grid item lg={2}>\n {children}\n </Grid>\n );\n};\n","/*\n * Copyright 2021 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { Grid } from '@material-ui/core';\nimport React, { PropsWithChildren } from 'react';\n\nexport const EntityListContainer = ({ children }: PropsWithChildren<{}>) => (\n <Grid item xs={12} lg={10}>\n {children}\n </Grid>\n);\n","/*\n * Copyright 2021 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n Content,\n ContentHeader,\n CreateButton,\n PageWithHeader,\n SupportButton,\n TableColumn,\n TableProps,\n} from '@backstage/core-components';\nimport { configApiRef, useApi, useRouteRef } from '@backstage/core-plugin-api';\nimport {\n EntityLifecyclePicker,\n EntityListProvider,\n EntityOwnerPicker,\n EntityTagPicker,\n EntityTypePicker,\n UserListFilterKind,\n UserListPicker,\n} from '@backstage/plugin-catalog-react';\nimport React from 'react';\nimport { createComponentRouteRef } from '../../routes';\nimport { CatalogTable } from '../CatalogTable';\nimport { EntityRow } from '../CatalogTable/types';\nimport {\n FilteredEntityLayout,\n EntityListContainer,\n FilterContainer,\n} from '../FilteredEntityLayout';\nimport { CatalogKindHeader } from '../CatalogKindHeader';\n\n/**\n * DefaultCatalogPageProps\n * @public\n */\nexport type DefaultCatalogPageProps = {\n initiallySelectedFilter?: UserListFilterKind;\n columns?: TableColumn<EntityRow>[];\n actions?: TableProps<EntityRow>['actions'];\n};\n\nexport const DefaultCatalogPage = ({\n columns,\n actions,\n initiallySelectedFilter = 'owned',\n}: DefaultCatalogPageProps) => {\n const orgName =\n useApi(configApiRef).getOptionalString('organization.name') ?? 'Backstage';\n const createComponentLink = useRouteRef(createComponentRouteRef);\n\n return (\n <PageWithHeader title={`${orgName} Catalog`} themeId=\"home\">\n <EntityListProvider>\n <Content>\n <ContentHeader titleComponent={<CatalogKindHeader />}>\n <CreateButton\n title=\"Create Component\"\n to={createComponentLink && createComponentLink()}\n />\n <SupportButton>All your software catalog entities</SupportButton>\n </ContentHeader>\n <FilteredEntityLayout>\n <FilterContainer>\n <EntityTypePicker />\n <UserListPicker initialFilter={initiallySelectedFilter} />\n <EntityOwnerPicker />\n <EntityLifecyclePicker />\n <EntityTagPicker />\n </FilterContainer>\n <EntityListContainer>\n <CatalogTable columns={columns} actions={actions} />\n </EntityListContainer>\n </FilteredEntityLayout>\n </Content>\n </EntityListProvider>\n </PageWithHeader>\n );\n};\n","/*\n * Copyright 2021 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport React from 'react';\nimport { useOutlet } from 'react-router';\nimport {\n DefaultCatalogPage,\n DefaultCatalogPageProps,\n} from './DefaultCatalogPage';\n\nexport const CatalogPage = (props: DefaultCatalogPageProps) => {\n const outlet = useOutlet();\n\n return outlet || <DefaultCatalogPage {...props} />;\n};\n","/*\n * Copyright 2020 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport React from 'react';\nimport { makeStyles } from '@material-ui/core';\nimport IlloSvgUrl from './illo.svg';\n\nconst useStyles = makeStyles(theme => ({\n illo: {\n maxWidth: '60%',\n top: 100,\n right: 20,\n position: 'absolute',\n [theme.breakpoints.down('xs')]: {\n maxWidth: '96%',\n position: 'relative',\n top: 'unset',\n right: 'unset',\n margin: `${theme.spacing(10)}px auto ${theme.spacing(4)}px`,\n },\n },\n}));\n\nexport const Illo = () => {\n const classes = useStyles();\n return (\n <img\n src={IlloSvgUrl}\n className={classes.illo}\n alt=\"Illustration on entity not found page\"\n />\n );\n};\n","/*\n * Copyright 2020 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport React from 'react';\nimport { Grid, Button, Typography } from '@material-ui/core';\nimport { makeStyles } from '@material-ui/core/styles';\nimport { BackstageTheme } from '@backstage/theme';\n\nimport { Illo } from './Illo';\n\nconst useStyles = makeStyles<BackstageTheme>(theme => ({\n container: {\n paddingTop: theme.spacing(24),\n paddingLeft: theme.spacing(8),\n [theme.breakpoints.down('xs')]: {\n padding: theme.spacing(2),\n },\n },\n title: {\n paddingBottom: theme.spacing(2),\n [theme.breakpoints.down('xs')]: {\n fontSize: 32,\n },\n },\n body: {\n paddingBottom: theme.spacing(6),\n [theme.breakpoints.down('xs')]: {\n paddingBottom: theme.spacing(5),\n },\n },\n}));\n\nexport const EntityNotFound = () => {\n const classes = useStyles();\n\n return (\n <Grid container spacing={0} className={classes.container}>\n <Illo />\n <Grid item xs={12} sm={6}>\n <Typography variant=\"h2\" className={classes.title}>\n Entity was not found\n </Typography>\n <Typography variant=\"body1\" className={classes.body}>\n Want to help us build this? Check out our Getting Started\n documentation.\n </Typography>\n <Button\n variant=\"contained\"\n color=\"primary\"\n href=\"https://backstage.io/docs\"\n >\n DOCS\n </Button>\n </Grid>\n </Grid>\n );\n};\n","/*\n * Copyright 2020 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport { ENTITY_DEFAULT_NAMESPACE } from '@backstage/catalog-model';\nimport {\n AsyncEntityProvider,\n useEntity,\n useEntityFromUrl,\n} from '@backstage/plugin-catalog-react';\nimport { Typography } from '@material-ui/core';\nimport React, { ComponentType, ReactNode } from 'react';\nimport { Navigate, Route, Routes, useParams } from 'react-router';\nimport { CatalogPage } from './CatalogPage';\nimport { EntityNotFound } from './EntityNotFound';\nimport { EntityPageLayout } from './EntityPageLayout';\nimport { Content, Link } from '@backstage/core-components';\n\nconst DefaultEntityPage = () => (\n <EntityPageLayout>\n <EntityPageLayout.Content\n path=\"/\"\n title=\"Overview\"\n element={\n <Content>\n <Typography variant=\"h2\">This is the default entity page.</Typography>\n <Typography variant=\"body1\">\n To override this component with your custom implementation, read\n docs on{' '}\n <Link to=\"https://backstage.io/docs\">backstage.io/docs</Link>\n </Typography>\n </Content>\n }\n />\n </EntityPageLayout>\n);\n\nconst EntityPageSwitch = ({ EntityPage }: { EntityPage: ComponentType }) => {\n const { entity, loading, error } = useEntity();\n // Loading and error states\n if (loading) return <EntityPageLayout />;\n if (error || !entity) return <EntityNotFound />;\n\n // Otherwise EntityPage provided from the App\n // Note that EntityPage will include EntityPageLayout already\n return <EntityPage />;\n};\n\nconst OldEntityRouteRedirect = () => {\n const { optionalNamespaceAndName, '*': rest } = useParams() as any;\n const [name, namespace] = optionalNamespaceAndName.split(':').reverse();\n const namespaceLower =\n namespace?.toLocaleLowerCase('en-US') ?? ENTITY_DEFAULT_NAMESPACE;\n const restWithSlash = rest ? `/${rest}` : '';\n return (\n <Navigate\n to={`../../${namespaceLower}/component/${name}${restWithSlash}`}\n />\n );\n};\n\nexport const EntityLoader = (props: { children: ReactNode }) => (\n <AsyncEntityProvider {...useEntityFromUrl()} {...props} />\n);\n\n/**\n * @deprecated Use plugin extensions instead\n * */\nexport const Router = ({\n EntityPage = DefaultEntityPage,\n}: {\n EntityPage?: ComponentType;\n}) => (\n <Routes>\n <Route path=\"/\" element={<CatalogPage />} />\n <Route\n path=\"/:namespace/:kind/:name\"\n element={\n <EntityLoader>\n <EntityPageSwitch EntityPage={EntityPage} />\n </EntityLoader>\n }\n />\n <Route\n path=\"Component/:optionalNamespaceAndName/*\"\n element={<OldEntityRouteRedirect />}\n />\n </Routes>\n);\n","/*\n * Copyright 2020 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { CatalogClient } from '@backstage/catalog-client';\nimport {\n catalogApiRef,\n catalogRouteRef,\n DefaultStarredEntitiesApi,\n entityRouteRef,\n starredEntitiesApiRef,\n} from '@backstage/plugin-catalog-react';\nimport { createComponentRouteRef, viewTechDocRouteRef } from './routes';\nimport {\n createApiFactory,\n createComponentExtension,\n createPlugin,\n createRoutableExtension,\n discoveryApiRef,\n fetchApiRef,\n storageApiRef,\n} from '@backstage/core-plugin-api';\n\nexport const catalogPlugin = createPlugin({\n id: 'catalog',\n apis: [\n createApiFactory({\n api: catalogApiRef,\n deps: {\n discoveryApi: discoveryApiRef,\n fetchApi: fetchApiRef,\n },\n factory: ({ discoveryApi, fetchApi }) =>\n new CatalogClient({ discoveryApi, fetchApi }),\n }),\n createApiFactory({\n api: starredEntitiesApiRef,\n deps: { storageApi: storageApiRef },\n factory: ({ storageApi }) =>\n new DefaultStarredEntitiesApi({ storageApi }),\n }),\n ],\n routes: {\n catalogIndex: catalogRouteRef,\n catalogEntity: entityRouteRef,\n },\n externalRoutes: {\n createComponent: createComponentRouteRef,\n viewTechDoc: viewTechDocRouteRef,\n },\n});\n\nexport const CatalogIndexPage = catalogPlugin.provide(\n createRoutableExtension({\n name: 'CatalogIndexPage',\n component: () =>\n import('./components/CatalogPage').then(m => m.CatalogPage),\n mountPoint: catalogRouteRef,\n }),\n);\n\nexport const CatalogEntityPage = catalogPlugin.provide(\n createRoutableExtension({\n name: 'CatalogEntityPage',\n component: () =>\n import('./components/CatalogEntityPage').then(m => m.CatalogEntityPage),\n mountPoint: entityRouteRef,\n }),\n);\n\nexport const EntityAboutCard = catalogPlugin.provide(\n createComponentExtension({\n name: 'EntityAboutCard',\n component: {\n lazy: () => import('./components/AboutCard').then(m => m.AboutCard),\n },\n }),\n);\n\nexport const EntityLinksCard = catalogPlugin.provide(\n createComponentExtension({\n name: 'EntityLinksCard',\n component: {\n lazy: () =>\n import('./components/EntityLinksCard').then(m => m.EntityLinksCard),\n },\n }),\n);\n\nexport const EntityHasSystemsCard = catalogPlugin.provide(\n createComponentExtension({\n name: 'EntityHasSystemsCard',\n component: {\n lazy: () =>\n import('./components/HasSystemsCard').then(m => m.HasSystemsCard),\n },\n }),\n);\n\nexport const EntityHasComponentsCard = catalogPlugin.provide(\n createComponentExtension({\n name: 'EntityHasComponentsCard',\n component: {\n lazy: () =>\n import('./components/HasComponentsCard').then(m => m.HasComponentsCard),\n },\n }),\n);\n\nexport const EntityHasSubcomponentsCard = catalogPlugin.provide(\n createComponentExtension({\n name: 'EntityHasSubcomponentsCard',\n component: {\n lazy: () =>\n import('./components/HasSubcomponentsCard').then(\n m => m.HasSubcomponentsCard,\n ),\n },\n }),\n);\n\nexport const EntityHasResourcesCard = catalogPlugin.provide(\n createComponentExtension({\n name: 'EntityHasResourcesCard',\n component: {\n lazy: () =>\n import('./components/HasResourcesCard').then(m => m.HasResourcesCard),\n },\n }),\n);\n\nexport const EntityDependsOnComponentsCard = catalogPlugin.provide(\n createComponentExtension({\n name: 'EntityDependsOnComponentsCard',\n component: {\n lazy: () =>\n import('./components/DependsOnComponentsCard').then(\n m => m.DependsOnComponentsCard,\n ),\n },\n }),\n);\n\nexport const EntityDependencyOfComponentsCard = catalogPlugin.provide(\n createComponentExtension({\n name: 'EntityDependencyOfComponentsCard',\n component: {\n lazy: () =>\n import('./components/DependencyOfComponentsCard').then(\n m => m.DependencyOfComponentsCard,\n ),\n },\n }),\n);\n\nexport const EntityDependsOnResourcesCard = catalogPlugin.provide(\n createComponentExtension({\n name: 'EntityDependsOnResourcesCard',\n component: {\n lazy: () =>\n import('./components/DependsOnResourcesCard').then(\n m => m.DependsOnResourcesCard,\n ),\n },\n }),\n);\n\n/**\n * @deprecated This component is replaced by EntityCatalogGraphCard which is imported from `@backstage/plugin-catalog-graph`. This component will be removed in an\n * upcoming release\n */\nexport const EntitySystemDiagramCard = catalogPlugin.provide(\n createComponentExtension({\n name: 'EntitySystemDiagramCard',\n component: {\n lazy: () =>\n import('./components/SystemDiagramCard').then(m => m.SystemDiagramCard),\n },\n }),\n);\n\nexport const RelatedEntitiesCard = catalogPlugin.provide(\n createComponentExtension({\n name: 'RelatedEntitiesCard',\n component: {\n lazy: () =>\n import('./components/RelatedEntitiesCard').then(\n m => m.RelatedEntitiesCard,\n ),\n },\n }),\n);\n"],"names":["useStyles","columnFactories.createNameColumn","columnFactories.createSystemColumn","columnFactories.createOwnerColumn","columnFactories.createSpecTypeColumn","columnFactories.createSpecLifecycleColumn","columnFactories.createMetadataDescriptionColumn","columnFactories.createTagsColumn","capitalize","Edit","makeStyles","headerProps","EntityLabels","Route"],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -304,6 +304,10 @@ declare const EntityDependencyOfComponentsCard: ({ variant, title, }: {
|
|
|
304
304
|
declare const EntityDependsOnResourcesCard: ({ variant }: {
|
|
305
305
|
variant?: "gridItem" | undefined;
|
|
306
306
|
}) => JSX.Element;
|
|
307
|
+
/**
|
|
308
|
+
* @deprecated This component is replaced by EntityCatalogGraphCard which is imported from `@backstage/plugin-catalog-graph`. This component will be removed in an
|
|
309
|
+
* upcoming release
|
|
310
|
+
*/
|
|
307
311
|
declare const EntitySystemDiagramCard: typeof SystemDiagramCard;
|
|
308
312
|
declare const RelatedEntitiesCard: <T extends _backstage_catalog_model.Entity>(props: {
|
|
309
313
|
variant?: "gridItem" | undefined;
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@backstage/plugin-catalog",
|
|
3
3
|
"description": "The Backstage plugin for browsing the Backstage catalog",
|
|
4
|
-
"version": "0.7.
|
|
4
|
+
"version": "0.7.11",
|
|
5
5
|
"main": "dist/index.esm.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
7
7
|
"license": "Apache-2.0",
|
|
@@ -33,12 +33,12 @@
|
|
|
33
33
|
"dependencies": {
|
|
34
34
|
"@backstage/catalog-client": "^0.5.5",
|
|
35
35
|
"@backstage/catalog-model": "^0.9.10",
|
|
36
|
-
"@backstage/core-components": "^0.8.
|
|
36
|
+
"@backstage/core-components": "^0.8.7",
|
|
37
37
|
"@backstage/core-plugin-api": "^0.6.0",
|
|
38
38
|
"@backstage/errors": "^0.2.0",
|
|
39
|
-
"@backstage/integration-react": "^0.1.
|
|
40
|
-
"@backstage/plugin-catalog-common": "^0.1.
|
|
41
|
-
"@backstage/plugin-catalog-react": "^0.6.
|
|
39
|
+
"@backstage/integration-react": "^0.1.20",
|
|
40
|
+
"@backstage/plugin-catalog-common": "^0.1.2",
|
|
41
|
+
"@backstage/plugin-catalog-react": "^0.6.13",
|
|
42
42
|
"@backstage/theme": "^0.2.14",
|
|
43
43
|
"@material-ui/core": "^4.12.2",
|
|
44
44
|
"@material-ui/icons": "^4.9.1",
|
|
@@ -54,11 +54,11 @@
|
|
|
54
54
|
"react": "^16.13.1 || ^17.0.0"
|
|
55
55
|
},
|
|
56
56
|
"devDependencies": {
|
|
57
|
-
"@backstage/cli": "^0.
|
|
58
|
-
"@backstage/core-app-api": "^0.5.
|
|
59
|
-
"@backstage/dev-utils": "^0.2.
|
|
57
|
+
"@backstage/cli": "^0.13.1",
|
|
58
|
+
"@backstage/core-app-api": "^0.5.2",
|
|
59
|
+
"@backstage/dev-utils": "^0.2.20",
|
|
60
60
|
"@backstage/plugin-permission-react": "^0.3.0",
|
|
61
|
-
"@backstage/test-utils": "^0.2.
|
|
61
|
+
"@backstage/test-utils": "^0.2.4",
|
|
62
62
|
"@testing-library/jest-dom": "^5.10.1",
|
|
63
63
|
"@testing-library/react": "^11.2.5",
|
|
64
64
|
"@testing-library/user-event": "^13.1.8",
|
|
@@ -68,5 +68,5 @@
|
|
|
68
68
|
"files": [
|
|
69
69
|
"dist"
|
|
70
70
|
],
|
|
71
|
-
"gitHead": "
|
|
71
|
+
"gitHead": "f944a625c4a8ec7f6a6237502691da9209ce6b14"
|
|
72
72
|
}
|