@backstage/plugin-catalog 0.8.0 → 0.9.0
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 +26 -0
- package/dist/esm/{index-5c367aca.esm.js → index-0518ad02.esm.js} +3 -3
- package/dist/esm/{index-5c367aca.esm.js.map → index-0518ad02.esm.js.map} +1 -1
- package/dist/esm/{index-36e4660a.esm.js → index-31a771c4.esm.js} +3 -3
- package/dist/esm/index-31a771c4.esm.js.map +1 -0
- package/dist/esm/index-52271589.esm.js.map +1 -1
- package/dist/esm/{index-de01f9dd.esm.js → index-6ca877bd.esm.js} +21 -14
- package/dist/esm/index-6ca877bd.esm.js.map +1 -0
- package/dist/esm/index-7f3caf38.esm.js +34 -0
- package/dist/esm/index-7f3caf38.esm.js.map +1 -0
- package/dist/index.d.ts +25 -27
- package/dist/index.esm.js +2 -2
- package/package.json +16 -16
- package/dist/esm/index-3467aa13.esm.js +0 -12
- package/dist/esm/index-3467aa13.esm.js.map +0 -1
- package/dist/esm/index-36e4660a.esm.js.map +0 -1
- package/dist/esm/index-de01f9dd.esm.js.map +0 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,31 @@
|
|
|
1
1
|
# @backstage/plugin-catalog
|
|
2
2
|
|
|
3
|
+
## 0.9.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- e7b9c3d713: Removed `columnFactories`, which was accidentally exported on the previous release.
|
|
8
|
+
- 2262fe19c9: **BREAKING**: Removed support for passing in an explicit `entity` prop to entity page extensions, which has been deprecated for a long time. This is only a breaking change at the TypeScript level, as this property was already ignored.
|
|
9
|
+
- 3c4376e5e7: **BREAKING**: Removed the old `plugin` export, use `catalogPlugin` instead.
|
|
10
|
+
|
|
11
|
+
### Patch Changes
|
|
12
|
+
|
|
13
|
+
- 2d339b5f2c: Internalize deprecated `useEntityFromUrl` hook
|
|
14
|
+
- a686702dbe: Renamed `CatalogResultListItem` to `CatalogSearchResultListItem` along with its prop type, leaving the old names in place as a deprecations.
|
|
15
|
+
- 852d5ff758: Added `EntitySwitchProps` type for `EntitySwitch`.
|
|
16
|
+
- a8331830f1: Remove use of deprecated `useEntityKinds` hook.
|
|
17
|
+
- 6e1cbc12a6: Updated according to the new `getEntityFacets` catalog API method
|
|
18
|
+
- b776ce5aab: Replaced use of deprecated `useEntityListProvider` hook with `useEntityList`.
|
|
19
|
+
- 3334ad47d4: Removed usage of `EntityContext`.
|
|
20
|
+
- 919cf2f836: Minor updates to match the new `targetRef` field of relations, and to stop consuming the `target` field
|
|
21
|
+
- Updated dependencies
|
|
22
|
+
- @backstage/core-components@0.8.10
|
|
23
|
+
- @backstage/plugin-catalog-react@0.7.0
|
|
24
|
+
- @backstage/catalog-model@0.11.0
|
|
25
|
+
- @backstage/catalog-client@0.7.2
|
|
26
|
+
- @backstage/core-plugin-api@0.7.0
|
|
27
|
+
- @backstage/integration-react@0.1.23
|
|
28
|
+
|
|
3
29
|
## 0.8.0
|
|
4
30
|
|
|
5
31
|
### Minor Changes
|
|
@@ -3,13 +3,14 @@ import { useOutlet } from 'react-router';
|
|
|
3
3
|
import { PageWithHeader, Content, ContentHeader, CreateButton, SupportButton } from '@backstage/core-components';
|
|
4
4
|
import { useApi, configApiRef, useRouteRef } from '@backstage/core-plugin-api';
|
|
5
5
|
import { EntityListProvider, EntityTypePicker, UserListPicker, EntityOwnerPicker, EntityLifecyclePicker, EntityTagPicker } from '@backstage/plugin-catalog-react';
|
|
6
|
-
import { c as createComponentRouteRef, C as CatalogKindHeader, F as FilteredEntityLayout, a as FilterContainer, E as EntityListContainer, b as CatalogTable } from './index-
|
|
6
|
+
import { c as createComponentRouteRef, C as CatalogKindHeader, F as FilteredEntityLayout, a as FilterContainer, E as EntityListContainer, b as CatalogTable } from './index-6ca877bd.esm.js';
|
|
7
7
|
import '@backstage/catalog-model';
|
|
8
8
|
import '@backstage/integration-react';
|
|
9
9
|
import '@material-ui/core';
|
|
10
10
|
import '@material-ui/icons/Cached';
|
|
11
11
|
import '@material-ui/icons/Description';
|
|
12
12
|
import '@material-ui/icons/Edit';
|
|
13
|
+
import 'react-use/lib/useAsync';
|
|
13
14
|
import '@material-ui/icons/OpenInNew';
|
|
14
15
|
import 'lodash';
|
|
15
16
|
import '@material-ui/lab';
|
|
@@ -20,7 +21,6 @@ import '@material-ui/icons/MoreVert';
|
|
|
20
21
|
import '@backstage/plugin-catalog-common';
|
|
21
22
|
import '@backstage/errors';
|
|
22
23
|
import '@backstage/catalog-client';
|
|
23
|
-
import 'react-use/lib/useAsync';
|
|
24
24
|
import '@material-ui/icons/FilterList';
|
|
25
25
|
|
|
26
26
|
function DefaultCatalogPage(props) {
|
|
@@ -52,4 +52,4 @@ function CatalogPage(props) {
|
|
|
52
52
|
}
|
|
53
53
|
|
|
54
54
|
export { CatalogPage, DefaultCatalogPage };
|
|
55
|
-
//# sourceMappingURL=index-
|
|
55
|
+
//# sourceMappingURL=index-0518ad02.esm.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index-
|
|
1
|
+
{"version":3,"file":"index-0518ad02.esm.js","sources":["../../src/components/CatalogPage/DefaultCatalogPage.tsx","../../src/components/CatalogPage/CatalogPage.tsx"],"sourcesContent":["/*\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, CatalogTableRow } from '../CatalogTable';\nimport {\n FilteredEntityLayout,\n EntityListContainer,\n FilterContainer,\n} from '../FilteredEntityLayout';\nimport { CatalogKindHeader } from '../CatalogKindHeader';\n\n/**\n * Props for root catalog pages.\n *\n * @public\n */\nexport interface DefaultCatalogPageProps {\n initiallySelectedFilter?: UserListFilterKind;\n columns?: TableColumn<CatalogTableRow>[];\n actions?: TableProps<CatalogTableRow>['actions'];\n}\n\nexport function DefaultCatalogPage(props: DefaultCatalogPageProps) {\n const { columns, actions, initiallySelectedFilter = 'owned' } = props;\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 function CatalogPage(props: DefaultCatalogPageProps) {\n const outlet = useOutlet();\n\n return outlet || <DefaultCatalogPage {...props} />;\n}\n"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;4BAwDmC,OAAgC;AAxDnE;AAyDE,QAAM,EAAE,SAAS,SAAS,0BAA0B,YAAY;AAChE,QAAM,UACJ,aAAO,cAAc,kBAAkB,yBAAvC,YAA+D;AACjE,QAAM,sBAAsB,YAAY;AAExC,6CACG,gBAAD;AAAA,IAAgB,OAAO,GAAG;AAAA,IAAmB,SAAQ;AAAA,yCAClD,oBAAD,0CACG,SAAD,0CACG,eAAD;AAAA,IAAe,oDAAiB,mBAAD;AAAA,yCAC5B,cAAD;AAAA,IACE,OAAM;AAAA,IACN,IAAI,uBAAuB;AAAA,0CAE5B,eAAD,MAAe,4EAEhB,sBAAD,0CACG,iBAAD,0CACG,kBAAD,2CACC,gBAAD;AAAA,IAAgB,eAAe;AAAA,0CAC9B,mBAAD,2CACC,uBAAD,2CACC,iBAAD,4CAED,qBAAD,0CACG,cAAD;AAAA,IAAc;AAAA,IAAkB;AAAA;AAAA;;qBC3DlB,OAAgC;AAC1D,QAAM,SAAS;AAEf,SAAO,8CAAW,oBAAD;AAAA,OAAwB;AAAA;AAAA;;;;"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { A as AboutCard, d as AboutContent, e as AboutField } from './index-
|
|
1
|
+
export { A as AboutCard, d as AboutContent, e as AboutField } from './index-6ca877bd.esm.js';
|
|
2
2
|
import '@backstage/catalog-model';
|
|
3
3
|
import '@backstage/core-components';
|
|
4
4
|
import '@backstage/core-plugin-api';
|
|
@@ -9,6 +9,7 @@ import '@material-ui/icons/Cached';
|
|
|
9
9
|
import '@material-ui/icons/Description';
|
|
10
10
|
import '@material-ui/icons/Edit';
|
|
11
11
|
import 'react';
|
|
12
|
+
import 'react-use/lib/useAsync';
|
|
12
13
|
import '@material-ui/icons/OpenInNew';
|
|
13
14
|
import 'lodash';
|
|
14
15
|
import '@material-ui/lab';
|
|
@@ -20,6 +21,5 @@ import '@material-ui/icons/MoreVert';
|
|
|
20
21
|
import '@backstage/plugin-catalog-common';
|
|
21
22
|
import '@backstage/errors';
|
|
22
23
|
import '@backstage/catalog-client';
|
|
23
|
-
import 'react-use/lib/useAsync';
|
|
24
24
|
import '@material-ui/icons/FilterList';
|
|
25
|
-
//# sourceMappingURL=index-
|
|
25
|
+
//# sourceMappingURL=index-31a771c4.esm.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index-31a771c4.esm.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index-52271589.esm.js","sources":["../../src/components/EntityLinksCard/EntityLinksEmptyState.tsx","../../src/components/EntityLinksCard/IconLink.tsx","../../src/components/EntityLinksCard/useDynamicColumns.tsx","../../src/components/EntityLinksCard/LinksGridList.tsx","../../src/components/EntityLinksCard/EntityLinksCard.tsx"],"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 { BackstageTheme } from '@backstage/theme';\nimport { Button, makeStyles, Typography } from '@material-ui/core';\nimport React from 'react';\nimport { CodeSnippet } from '@backstage/core-components';\n\nconst ENTITY_YAML = `metadata:\n name: example\n links:\n - url: https://dashboard.example.com\n title: My Dashboard\n icon: dashboard`;\n\n/** @public */\nexport type EntityLinksEmptyStateClassKey = 'code';\n\nconst useStyles = makeStyles<BackstageTheme>(\n theme => ({\n code: {\n borderRadius: 6,\n margin: `${theme.spacing(2)}px 0px`,\n background: theme.palette.type === 'dark' ? '#444' : '#fff',\n },\n }),\n { name: 'PluginCatalogEntityLinksEmptyState' },\n);\n\nexport function EntityLinksEmptyState() {\n const classes = useStyles();\n\n return (\n <>\n <Typography variant=\"body1\">\n No links defined for this entity. You can add links to your entity YAML\n as shown in the highlighted example below:\n </Typography>\n <div className={classes.code}>\n <CodeSnippet\n text={ENTITY_YAML}\n language=\"yaml\"\n showLineNumbers\n highlightedNumbers={[3, 4, 5, 6]}\n customStyle={{ background: 'inherit', fontSize: '115%' }}\n />\n </div>\n <Button\n variant=\"contained\"\n color=\"primary\"\n target=\"_blank\"\n href=\"https://backstage.io/docs/features/software-catalog/descriptor-format#links-optional\"\n >\n Read more\n </Button>\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 { makeStyles, Box, Typography } from '@material-ui/core';\nimport LanguageIcon from '@material-ui/icons/Language';\nimport React from 'react';\nimport { Link } from '@backstage/core-components';\nimport { IconComponent } from '@backstage/core-plugin-api';\n\nconst useStyles = makeStyles({\n svgIcon: {\n display: 'inline-block',\n '& svg': {\n display: 'inline-block',\n fontSize: 'inherit',\n verticalAlign: 'baseline',\n },\n },\n});\n\nexport function IconLink(props: {\n href: string;\n text?: string;\n Icon?: IconComponent;\n}) {\n const { href, text, Icon } = props;\n const classes = useStyles();\n\n return (\n <Box display=\"flex\">\n <Box mr={1} className={classes.svgIcon}>\n <Typography component=\"div\">\n {Icon ? <Icon /> : <LanguageIcon />}\n </Typography>\n </Box>\n <Box flexGrow=\"1\">\n <Link to={href} target=\"_blank\" rel=\"noopener\">\n {text || href}\n </Link>\n </Box>\n </Box>\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 { Theme, useMediaQuery } from '@material-ui/core';\nimport { Breakpoint, ColumnBreakpoints } from './types';\n\nconst colDefaults: ColumnBreakpoints = {\n xs: 1,\n sm: 1,\n md: 1,\n lg: 2,\n xl: 3,\n};\n\nexport function useDynamicColumns(\n cols: ColumnBreakpoints | number | undefined,\n): number {\n const matches: (Breakpoint | null)[] = [\n useMediaQuery((theme: Theme) => theme.breakpoints.up('xl')) ? 'xl' : null,\n useMediaQuery((theme: Theme) => theme.breakpoints.up('lg')) ? 'lg' : null,\n useMediaQuery((theme: Theme) => theme.breakpoints.up('md')) ? 'md' : null,\n useMediaQuery((theme: Theme) => theme.breakpoints.up('sm')) ? 'sm' : null,\n useMediaQuery((theme: Theme) => theme.breakpoints.up('xs')) ? 'xs' : null,\n ];\n\n let numOfCols = 1;\n\n if (typeof cols === 'number') {\n numOfCols = cols;\n } else {\n const breakpoint = matches.find(k => k !== null) ?? 'xs';\n numOfCols = cols?.[breakpoint] ?? colDefaults[breakpoint];\n }\n\n return numOfCols;\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 { ImageList, ImageListItem } from '@material-ui/core';\nimport React from 'react';\nimport { IconLink } from './IconLink';\nimport { ColumnBreakpoints } from './types';\nimport { useDynamicColumns } from './useDynamicColumns';\nimport { IconComponent } from '@backstage/core-plugin-api';\n\nexport interface LinksGridListItem {\n href: string;\n text?: string;\n Icon?: IconComponent;\n}\n\ninterface LinksGridListProps {\n items: LinksGridListItem[];\n cols?: ColumnBreakpoints | number;\n}\n\nexport function LinksGridList(props: LinksGridListProps) {\n const { items, cols = undefined } = props;\n const numOfCols = useDynamicColumns(cols);\n\n return (\n <ImageList rowHeight=\"auto\" cols={numOfCols}>\n {items.map(({ text, href, Icon }, i) => (\n <ImageListItem key={i}>\n <IconLink href={href} text={text ?? href} Icon={Icon} />\n </ImageListItem>\n ))}\n </ImageList>\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 { Entity } from '@backstage/catalog-model';\nimport { useEntity } from '@backstage/plugin-catalog-react';\nimport LanguageIcon from '@material-ui/icons/Language';\nimport React from 'react';\nimport { EntityLinksEmptyState } from './EntityLinksEmptyState';\nimport { LinksGridList } from './LinksGridList';\nimport { ColumnBreakpoints } from './types';\nimport { IconComponent, useApp } from '@backstage/core-plugin-api';\nimport { InfoCard } from '@backstage/core-components';\n\n/** @public */\nexport interface EntityLinksCardProps {\n /** @deprecated The entity is now grabbed from context instead */\n entity?: Entity;\n cols?: ColumnBreakpoints | number;\n variant?: 'gridItem';\n}\n\nexport function EntityLinksCard(props: EntityLinksCardProps) {\n const { cols = undefined, variant } = props;\n const { entity } = useEntity();\n const app = useApp();\n\n const iconResolver = (key?: string): IconComponent =>\n key ? app.getSystemIcon(key) ?? LanguageIcon : LanguageIcon;\n\n const links = entity?.metadata?.links;\n\n return (\n <InfoCard title=\"Links\" variant={variant}>\n {!links || links.length === 0 ? (\n <EntityLinksEmptyState />\n ) : (\n <LinksGridList\n cols={cols}\n items={links.map(({ url, title, icon }) => ({\n text: title ?? url,\n href: url,\n Icon: iconResolver(icon),\n }))}\n />\n )}\n </InfoCard>\n );\n}\n"],"names":["useStyles"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index-52271589.esm.js","sources":["../../src/components/EntityLinksCard/EntityLinksEmptyState.tsx","../../src/components/EntityLinksCard/IconLink.tsx","../../src/components/EntityLinksCard/useDynamicColumns.tsx","../../src/components/EntityLinksCard/LinksGridList.tsx","../../src/components/EntityLinksCard/EntityLinksCard.tsx"],"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 { BackstageTheme } from '@backstage/theme';\nimport { Button, makeStyles, Typography } from '@material-ui/core';\nimport React from 'react';\nimport { CodeSnippet } from '@backstage/core-components';\n\nconst ENTITY_YAML = `metadata:\n name: example\n links:\n - url: https://dashboard.example.com\n title: My Dashboard\n icon: dashboard`;\n\n/** @public */\nexport type EntityLinksEmptyStateClassKey = 'code';\n\nconst useStyles = makeStyles<BackstageTheme>(\n theme => ({\n code: {\n borderRadius: 6,\n margin: `${theme.spacing(2)}px 0px`,\n background: theme.palette.type === 'dark' ? '#444' : '#fff',\n },\n }),\n { name: 'PluginCatalogEntityLinksEmptyState' },\n);\n\nexport function EntityLinksEmptyState() {\n const classes = useStyles();\n\n return (\n <>\n <Typography variant=\"body1\">\n No links defined for this entity. You can add links to your entity YAML\n as shown in the highlighted example below:\n </Typography>\n <div className={classes.code}>\n <CodeSnippet\n text={ENTITY_YAML}\n language=\"yaml\"\n showLineNumbers\n highlightedNumbers={[3, 4, 5, 6]}\n customStyle={{ background: 'inherit', fontSize: '115%' }}\n />\n </div>\n <Button\n variant=\"contained\"\n color=\"primary\"\n target=\"_blank\"\n href=\"https://backstage.io/docs/features/software-catalog/descriptor-format#links-optional\"\n >\n Read more\n </Button>\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 { makeStyles, Box, Typography } from '@material-ui/core';\nimport LanguageIcon from '@material-ui/icons/Language';\nimport React from 'react';\nimport { Link } from '@backstage/core-components';\nimport { IconComponent } from '@backstage/core-plugin-api';\n\nconst useStyles = makeStyles({\n svgIcon: {\n display: 'inline-block',\n '& svg': {\n display: 'inline-block',\n fontSize: 'inherit',\n verticalAlign: 'baseline',\n },\n },\n});\n\nexport function IconLink(props: {\n href: string;\n text?: string;\n Icon?: IconComponent;\n}) {\n const { href, text, Icon } = props;\n const classes = useStyles();\n\n return (\n <Box display=\"flex\">\n <Box mr={1} className={classes.svgIcon}>\n <Typography component=\"div\">\n {Icon ? <Icon /> : <LanguageIcon />}\n </Typography>\n </Box>\n <Box flexGrow=\"1\">\n <Link to={href} target=\"_blank\" rel=\"noopener\">\n {text || href}\n </Link>\n </Box>\n </Box>\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 { Theme, useMediaQuery } from '@material-ui/core';\nimport { Breakpoint, ColumnBreakpoints } from './types';\n\nconst colDefaults: ColumnBreakpoints = {\n xs: 1,\n sm: 1,\n md: 1,\n lg: 2,\n xl: 3,\n};\n\nexport function useDynamicColumns(\n cols: ColumnBreakpoints | number | undefined,\n): number {\n const matches: (Breakpoint | null)[] = [\n useMediaQuery((theme: Theme) => theme.breakpoints.up('xl')) ? 'xl' : null,\n useMediaQuery((theme: Theme) => theme.breakpoints.up('lg')) ? 'lg' : null,\n useMediaQuery((theme: Theme) => theme.breakpoints.up('md')) ? 'md' : null,\n useMediaQuery((theme: Theme) => theme.breakpoints.up('sm')) ? 'sm' : null,\n useMediaQuery((theme: Theme) => theme.breakpoints.up('xs')) ? 'xs' : null,\n ];\n\n let numOfCols = 1;\n\n if (typeof cols === 'number') {\n numOfCols = cols;\n } else {\n const breakpoint = matches.find(k => k !== null) ?? 'xs';\n numOfCols = cols?.[breakpoint] ?? colDefaults[breakpoint];\n }\n\n return numOfCols;\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 { ImageList, ImageListItem } from '@material-ui/core';\nimport React from 'react';\nimport { IconLink } from './IconLink';\nimport { ColumnBreakpoints } from './types';\nimport { useDynamicColumns } from './useDynamicColumns';\nimport { IconComponent } from '@backstage/core-plugin-api';\n\nexport interface LinksGridListItem {\n href: string;\n text?: string;\n Icon?: IconComponent;\n}\n\ninterface LinksGridListProps {\n items: LinksGridListItem[];\n cols?: ColumnBreakpoints | number;\n}\n\nexport function LinksGridList(props: LinksGridListProps) {\n const { items, cols = undefined } = props;\n const numOfCols = useDynamicColumns(cols);\n\n return (\n <ImageList rowHeight=\"auto\" cols={numOfCols}>\n {items.map(({ text, href, Icon }, i) => (\n <ImageListItem key={i}>\n <IconLink href={href} text={text ?? href} Icon={Icon} />\n </ImageListItem>\n ))}\n </ImageList>\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 { useEntity } from '@backstage/plugin-catalog-react';\nimport LanguageIcon from '@material-ui/icons/Language';\nimport React from 'react';\nimport { EntityLinksEmptyState } from './EntityLinksEmptyState';\nimport { LinksGridList } from './LinksGridList';\nimport { ColumnBreakpoints } from './types';\nimport { IconComponent, useApp } from '@backstage/core-plugin-api';\nimport { InfoCard } from '@backstage/core-components';\n\n/** @public */\nexport interface EntityLinksCardProps {\n cols?: ColumnBreakpoints | number;\n variant?: 'gridItem';\n}\n\nexport function EntityLinksCard(props: EntityLinksCardProps) {\n const { cols = undefined, variant } = props;\n const { entity } = useEntity();\n const app = useApp();\n\n const iconResolver = (key?: string): IconComponent =>\n key ? app.getSystemIcon(key) ?? LanguageIcon : LanguageIcon;\n\n const links = entity?.metadata?.links;\n\n return (\n <InfoCard title=\"Links\" variant={variant}>\n {!links || links.length === 0 ? (\n <EntityLinksEmptyState />\n ) : (\n <LinksGridList\n cols={cols}\n items={links.map(({ url, title, icon }) => ({\n text: title ?? url,\n href: url,\n Icon: iconResolver(icon),\n }))}\n />\n )}\n </InfoCard>\n );\n}\n"],"names":["useStyles"],"mappings":"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"}
|
|
@@ -2,12 +2,13 @@ import { RELATION_PART_OF, RELATION_OWNED_BY, DEFAULT_NAMESPACE, ANNOTATION_LOCA
|
|
|
2
2
|
import { Link, HeaderIconLinkRow, OverflowTooltip, WarningPanel, CodeSnippet, Table, Page, Header, Progress, RoutedTabs, Content, HeaderLabel, ResponseErrorPanel } from '@backstage/core-components';
|
|
3
3
|
import { createExternalRouteRef, useElementFilter, useApi, alertApiRef, useRouteRef, attachComponentData, useApiHolder, createPlugin, createApiFactory, discoveryApiRef, fetchApiRef, storageApiRef, createRoutableExtension, createComponentExtension } from '@backstage/core-plugin-api';
|
|
4
4
|
import { scmIntegrationsApiRef, ScmIntegrationIcon } from '@backstage/integration-react';
|
|
5
|
-
import { getEntityRelations, EntityRefLinks, useEntity, catalogApiRef, getEntitySourceLocation, getEntityMetadataEditUrl,
|
|
5
|
+
import { getEntityRelations, EntityRefLinks, useEntity, catalogApiRef, getEntitySourceLocation, getEntityMetadataEditUrl, useEntityList, EntityKindFilter, formatEntityRefTitle, EntityRefLink, useStarredEntities, getEntityMetadataViewUrl, favoriteEntityIcon, favoriteEntityTooltip, useEntityPermission, useEntityCompoundName, UnregisterEntityDialog, InspectEntityDialog, FavoriteEntity, catalogRouteRef, starredEntitiesApiRef, DefaultStarredEntitiesApi, entityRouteRef } from '@backstage/plugin-catalog-react';
|
|
6
6
|
import { makeStyles, Typography, Grid, Chip, Card, CardHeader, IconButton, Divider, CardContent, createStyles, capitalize, Select, InputBase, MenuItem, ListItem, ListItemText, Box, ListItemIcon, Popover, MenuList, Dialog, DialogTitle, DialogActions, Button, useMediaQuery, useTheme, Drawer } from '@material-ui/core';
|
|
7
7
|
import CachedIcon from '@material-ui/icons/Cached';
|
|
8
8
|
import DocsIcon from '@material-ui/icons/Description';
|
|
9
9
|
import EditIcon from '@material-ui/icons/Edit';
|
|
10
|
-
import React, { useCallback, useState, useEffect, useMemo
|
|
10
|
+
import React, { useCallback, useState, useEffect, useMemo } from 'react';
|
|
11
|
+
import useAsync from 'react-use/lib/useAsync';
|
|
11
12
|
import OpenInNew from '@material-ui/icons/OpenInNew';
|
|
12
13
|
import { capitalize as capitalize$1 } from 'lodash';
|
|
13
14
|
import { Alert } from '@material-ui/lab';
|
|
@@ -19,7 +20,6 @@ import MoreVert from '@material-ui/icons/MoreVert';
|
|
|
19
20
|
import { catalogEntityDeletePermission } from '@backstage/plugin-catalog-common';
|
|
20
21
|
import { assertError } from '@backstage/errors';
|
|
21
22
|
import { ENTITY_STATUS_CATALOG_PROCESSING_TYPE, CatalogClient } from '@backstage/catalog-client';
|
|
22
|
-
import useAsync from 'react-use/lib/useAsync';
|
|
23
23
|
import FilterListIcon from '@material-ui/icons/FilterList';
|
|
24
24
|
|
|
25
25
|
const createComponentRouteRef = createExternalRouteRef({
|
|
@@ -248,15 +248,21 @@ function CatalogKindHeader(props) {
|
|
|
248
248
|
var _a;
|
|
249
249
|
const { initialFilter = "component" } = props;
|
|
250
250
|
const classes = useStyles$2();
|
|
251
|
-
const
|
|
252
|
-
const {
|
|
251
|
+
const catalogApi = useApi(catalogApiRef);
|
|
252
|
+
const { value: allKinds } = useAsync(async () => {
|
|
253
|
+
return await catalogApi.getEntityFacets({ facets: ["kind"] }).then((response) => {
|
|
254
|
+
var _a2;
|
|
255
|
+
return ((_a2 = response.facets.kind) == null ? void 0 : _a2.map((f) => f.value).sort()) || [];
|
|
256
|
+
});
|
|
257
|
+
});
|
|
258
|
+
const { updateFilters, queryParameters } = useEntityList();
|
|
253
259
|
const [selectedKind, setSelectedKind] = useState(((_a = [queryParameters.kind].flat()[0]) != null ? _a : initialFilter).toLocaleLowerCase("en-US"));
|
|
254
260
|
useEffect(() => {
|
|
255
261
|
updateFilters({
|
|
256
262
|
kind: selectedKind ? new EntityKindFilter(selectedKind) : void 0
|
|
257
263
|
});
|
|
258
264
|
}, [selectedKind, updateFilters]);
|
|
259
|
-
const options = [capitalize(selectedKind)].concat(allKinds).sort().reduce((acc, kind) => {
|
|
265
|
+
const options = [capitalize(selectedKind)].concat(allKinds != null ? allKinds : []).sort().reduce((acc, kind) => {
|
|
260
266
|
acc[kind.toLocaleLowerCase("en-US")] = kind;
|
|
261
267
|
return acc;
|
|
262
268
|
}, {});
|
|
@@ -283,7 +289,7 @@ const useStyles$1 = makeStyles({
|
|
|
283
289
|
marginBottom: "1rem"
|
|
284
290
|
}
|
|
285
291
|
});
|
|
286
|
-
function
|
|
292
|
+
function CatalogSearchResultListItem(props) {
|
|
287
293
|
const result = props.result;
|
|
288
294
|
const classes = useStyles$1();
|
|
289
295
|
return /* @__PURE__ */ React.createElement(Link, {
|
|
@@ -306,6 +312,7 @@ function CatalogResultListItem(props) {
|
|
|
306
312
|
component: "li"
|
|
307
313
|
}));
|
|
308
314
|
}
|
|
315
|
+
const CatalogResultListItem = CatalogSearchResultListItem;
|
|
309
316
|
|
|
310
317
|
const columnFactories = Object.freeze({
|
|
311
318
|
createNameColumn(options) {
|
|
@@ -398,7 +405,7 @@ const CatalogTable = (props) => {
|
|
|
398
405
|
var _a, _b, _c;
|
|
399
406
|
const { columns, actions } = props;
|
|
400
407
|
const { isStarredEntity, toggleStarredEntity } = useStarredEntities();
|
|
401
|
-
const { loading, error, entities, filters } =
|
|
408
|
+
const { loading, error, entities, filters } = useEntityList();
|
|
402
409
|
const defaultColumns = useMemo(() => {
|
|
403
410
|
var _a2;
|
|
404
411
|
return [
|
|
@@ -644,7 +651,7 @@ const EntityLayout = (props) => {
|
|
|
644
651
|
children
|
|
645
652
|
} = props;
|
|
646
653
|
const { kind, namespace, name } = useEntityCompoundName();
|
|
647
|
-
const { entity, loading, error } =
|
|
654
|
+
const { entity, loading, error } = useEntity();
|
|
648
655
|
const location = useLocation();
|
|
649
656
|
const routes = useElementFilter(children, (elements) => elements.selectByComponentData({
|
|
650
657
|
key: dataKey,
|
|
@@ -960,18 +967,18 @@ const catalogPlugin = createPlugin({
|
|
|
960
967
|
});
|
|
961
968
|
const CatalogIndexPage = catalogPlugin.provide(createRoutableExtension({
|
|
962
969
|
name: "CatalogIndexPage",
|
|
963
|
-
component: () => import('./index-
|
|
970
|
+
component: () => import('./index-0518ad02.esm.js').then((m) => m.CatalogPage),
|
|
964
971
|
mountPoint: catalogRouteRef
|
|
965
972
|
}));
|
|
966
973
|
const CatalogEntityPage = catalogPlugin.provide(createRoutableExtension({
|
|
967
974
|
name: "CatalogEntityPage",
|
|
968
|
-
component: () => import('./index-
|
|
975
|
+
component: () => import('./index-7f3caf38.esm.js').then((m) => m.CatalogEntityPage),
|
|
969
976
|
mountPoint: entityRouteRef
|
|
970
977
|
}));
|
|
971
978
|
const EntityAboutCard = catalogPlugin.provide(createComponentExtension({
|
|
972
979
|
name: "EntityAboutCard",
|
|
973
980
|
component: {
|
|
974
|
-
lazy: () => import('./index-
|
|
981
|
+
lazy: () => import('./index-31a771c4.esm.js').then((m) => m.AboutCard)
|
|
975
982
|
}
|
|
976
983
|
}));
|
|
977
984
|
const EntityLinksCard = catalogPlugin.provide(createComponentExtension({
|
|
@@ -1029,5 +1036,5 @@ const RelatedEntitiesCard = catalogPlugin.provide(createComponentExtension({
|
|
|
1029
1036
|
}
|
|
1030
1037
|
}));
|
|
1031
1038
|
|
|
1032
|
-
export { AboutCard as A, isNamespace as B, CatalogKindHeader as C, isComponentType as D, EntityListContainer as E, FilteredEntityLayout as F, RelatedEntitiesCard as R, FilterContainer as a, CatalogTable as b, createComponentRouteRef as c, AboutContent as d, AboutField as e, CatalogEntityPage as f, CatalogIndexPage as g, catalogPlugin as h, EntityAboutCard as i, EntityDependencyOfComponentsCard as j, EntityDependsOnComponentsCard as k, EntityDependsOnResourcesCard as l, EntityHasComponentsCard as m, EntityHasResourcesCard as n, EntityHasSubcomponentsCard as o, EntityHasSystemsCard as p, EntityLinksCard as q,
|
|
1033
|
-
//# sourceMappingURL=index-
|
|
1039
|
+
export { AboutCard as A, isNamespace as B, CatalogKindHeader as C, isComponentType as D, EntityListContainer as E, FilteredEntityLayout as F, RelatedEntitiesCard as R, FilterContainer as a, CatalogTable as b, createComponentRouteRef as c, AboutContent as d, AboutField as e, CatalogEntityPage as f, CatalogIndexPage as g, catalogPlugin as h, EntityAboutCard as i, EntityDependencyOfComponentsCard as j, EntityDependsOnComponentsCard as k, EntityDependsOnResourcesCard as l, EntityHasComponentsCard as m, EntityHasResourcesCard as n, EntityHasSubcomponentsCard as o, EntityHasSystemsCard as p, EntityLinksCard as q, CatalogSearchResultListItem as r, CatalogResultListItem as s, EntityLayout as t, EntityOrphanWarning as u, isOrphan as v, EntityProcessingErrorsPanel as w, hasCatalogProcessingErrors as x, EntitySwitch as y, isKind as z };
|
|
1040
|
+
//# sourceMappingURL=index-6ca877bd.esm.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index-6ca877bd.esm.js","sources":["../../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/CatalogSearchResultListItem/CatalogSearchResultListItem.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/EntitySwitch/EntitySwitch.tsx","../../src/components/EntitySwitch/conditions.ts","../../src/components/FilteredEntityLayout/FilteredEntityLayout.tsx","../../src/components/FilteredEntityLayout/FilterContainer.tsx","../../src/components/FilteredEntityLayout/EntityListContainer.tsx","../../src/plugin.ts"],"sourcesContent":["/*\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\n/**\n * Props for {@link AboutField}.\n *\n * @public\n */\nexport interface AboutFieldProps {\n label: string;\n value?: string;\n gridSizes?: Record<string, number>;\n children?: React.ReactNode;\n}\n\n/** @public */\nexport function AboutField(props: AboutFieldProps) {\n const { 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\n/**\n * Props for {@link AboutContent}.\n *\n * @public\n */\nexport interface AboutContentProps {\n entity: Entity;\n}\n\n/** @public */\nexport function AboutContent(props: AboutContentProps) {\n const { 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 ANNOTATION_LOCATION,\n DEFAULT_NAMESPACE,\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\n/**\n * Props for {@link AboutCard}.\n *\n * @public\n */\nexport interface AboutCardProps {\n variant?: InfoCardVariants;\n}\n\n/**\n * @public\n * @deprecated Please use EntityAboutCard instead\n */\nexport function AboutCard(props: AboutCardProps) {\n const { variant } = props;\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 || 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?.[ANNOTATION_LOCATION];\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 catalogApiRef,\n EntityKindFilter,\n useEntityList,\n} from '@backstage/plugin-catalog-react';\nimport useAsync from 'react-use/lib/useAsync';\nimport { useApi } from '@backstage/core-plugin-api';\n\nconst useStyles = makeStyles((theme: Theme) =>\n createStyles({\n root: {\n ...theme.typography.h4,\n },\n }),\n);\n\n/**\n * Props for {@link CatalogKindHeader}.\n *\n * @public\n */\nexport interface CatalogKindHeaderProps {\n initialFilter?: string;\n}\n\n/** @public */\nexport function CatalogKindHeader(props: CatalogKindHeaderProps) {\n const { initialFilter = 'component' } = props;\n const classes = useStyles();\n const catalogApi = useApi(catalogApiRef);\n const { value: allKinds } = useAsync(async () => {\n return await catalogApi\n .getEntityFacets({ facets: ['kind'] })\n .then(response => response.facets.kind?.map(f => f.value).sort() || []);\n });\n const { updateFilters, queryParameters } = useEntityList();\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';\nimport { IndexableDocument } from '@backstage/search-common';\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\n/**\n * Props for {@link CatalogSearchResultListItem}.\n *\n * @public\n */\nexport interface CatalogSearchResultListItemProps {\n result: IndexableDocument;\n}\n\n/** @public */\nexport function CatalogSearchResultListItem(\n props: CatalogSearchResultListItemProps,\n) {\n const result = props.result as any;\n\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/**\n * @public\n * @deprecated use {@link CatalogSearchResultListItemProps} instead\n */\nexport type CatalogResultListItemProps = CatalogSearchResultListItemProps;\n\n/**\n * @public\n * @deprecated use {@link CatalogSearchResultListItem} instead\n */\nexport const CatalogResultListItem = CatalogSearchResultListItem;\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 { CatalogTableRow } from './types';\nimport { OverflowTooltip, TableColumn } from '@backstage/core-components';\nimport { Entity } from '@backstage/catalog-model';\n\n// The columnFactories symbol is not directly exported, but through the\n// CatalogTable.columns field.\n/** @public */\nexport const columnFactories = Object.freeze({\n createNameColumn(options?: {\n defaultKind?: string;\n }): TableColumn<CatalogTableRow> {\n function formatContent(entity: Entity): string {\n return (\n entity.metadata?.title ||\n formatEntityRefTitle(entity, {\n defaultKind: options?.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={options?.defaultKind || 'Component'}\n title={entity.metadata?.title}\n />\n ),\n };\n },\n createSystemColumn(): TableColumn<CatalogTableRow> {\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 createOwnerColumn(): TableColumn<CatalogTableRow> {\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 createSpecTypeColumn(): TableColumn<CatalogTableRow> {\n return {\n title: 'Type',\n field: 'entity.spec.type',\n hidden: true,\n };\n },\n createSpecLifecycleColumn(): TableColumn<CatalogTableRow> {\n return {\n title: 'Lifecycle',\n field: 'entity.spec.lifecycle',\n };\n },\n createMetadataDescriptionColumn(): TableColumn<CatalogTableRow> {\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 createTagsColumn(): TableColumn<CatalogTableRow> {\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","/*\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 useEntityList,\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 { columnFactories } from './columns';\nimport { CatalogTableRow } from './types';\nimport {\n CodeSnippet,\n Table,\n TableColumn,\n TableProps,\n WarningPanel,\n} from '@backstage/core-components';\n\n/**\n * Props for {@link CatalogTable}.\n *\n * @public\n */\nexport interface CatalogTableProps {\n columns?: TableColumn<CatalogTableRow>[];\n actions?: TableProps<CatalogTableRow>['actions'];\n}\n\n/** @public */\nexport const CatalogTable = (props: CatalogTableProps) => {\n const { columns, actions } = props;\n const { isStarredEntity, toggleStarredEntity } = useStarredEntities();\n const { loading, error, entities, filters } = useEntityList();\n\n const defaultColumns: TableColumn<CatalogTableRow>[] = 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<CatalogTableRow>['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<CatalogTableRow>\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 CancelIcon from '@material-ui/icons/Cancel';\nimport BugReportIcon from '@material-ui/icons/BugReport';\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\ninterface ExtraContextMenuItem {\n title: string;\n Icon: IconComponent;\n onClick: () => void;\n}\n\n// unstable context menu option, eg: disable the unregister entity menu\ninterface contextMenuOptions {\n disableUnregister: boolean;\n}\n\ninterface EntityContextMenuProps {\n UNSTABLE_extraContextMenuItems?: ExtraContextMenuItem[];\n UNSTABLE_contextMenuOptions?: contextMenuOptions;\n onUnregisterEntity: () => void;\n onInspectEntity: () => void;\n}\n\nexport function EntityContextMenu(props: EntityContextMenuProps) {\n const {\n UNSTABLE_extraContextMenuItems,\n UNSTABLE_contextMenuOptions,\n onUnregisterEntity,\n onInspectEntity,\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 <CancelIcon fontSize=\"small\" />\n </ListItemIcon>\n <ListItemText primary=\"Unregister entity\" />\n </MenuItem>\n <MenuItem\n onClick={() => {\n onClose();\n onInspectEntity();\n }}\n >\n <ListItemIcon>\n <BugReportIcon fontSize=\"small\" />\n </ListItemIcon>\n <ListItemText primary=\"Inspect 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 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 EntityRefLinks,\n FavoriteEntity,\n getEntityRelations,\n InspectEntityDialog,\n UnregisterEntityDialog,\n useEntity,\n useEntityCompoundName,\n} from '@backstage/plugin-catalog-react';\nimport { Box, TabProps } from '@material-ui/core';\nimport { Alert } from '@material-ui/lab';\nimport React, { useEffect, useState } from 'react';\nimport { useLocation, useNavigate } from 'react-router';\nimport { EntityContextMenu } from '../EntityContextMenu/EntityContextMenu';\n\n/** @public */\nexport type EntityLayoutRouteProps = {\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: EntityLayoutRouteProps) => null = () => null;\nattachComponentData(Route, dataKey, true);\nattachComponentData(Route, 'core.gatherMountPoints', true); // This causes all mount points that are discovered within this route to use the path of the route itself\n\nfunction EntityLayoutTitle(props: {\n title: string;\n entity: Entity | undefined;\n}) {\n const { entity, title } = props;\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\nfunction 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 !== DEFAULT_NAMESPACE ? ` in ${namespace}` : ''\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\nfunction EntityLabels(props: { entity: Entity }) {\n const { entity } = props;\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\ninterface ExtraContextMenuItem {\n title: string;\n Icon: IconComponent;\n onClick: () => void;\n}\n\n// unstable context menu option, eg: disable the unregister entity menu\ninterface contextMenuOptions {\n disableUnregister: boolean;\n}\n\n/** @public */\nexport interface 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 *\n * @public\n */\nexport const EntityLayout = (props: EntityLayoutProps) => {\n const {\n UNSTABLE_extraContextMenuItems,\n UNSTABLE_contextMenuOptions,\n children,\n } = props;\n const { kind, namespace, name } = useEntityCompoundName();\n const { entity, loading, error } = useEntity();\n const location = useLocation();\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<EntityLayoutRouteProps>() // all nodes, element data, maintain structure or not?\n .flatMap(({ props: elementProps }) => {\n if (elementProps.if && entity && !elementProps.if(entity)) {\n return [];\n }\n\n return [\n {\n path: elementProps.path,\n title: elementProps.title,\n children: elementProps.children,\n tabProps: elementProps.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 [inspectionDialogOpen, setInspectionDialogOpen] = useState(false);\n const navigate = useNavigate();\n const cleanUpAfterRemoval = async () => {\n setConfirmationDialogOpen(false);\n setInspectionDialogOpen(false);\n navigate('/');\n };\n\n // Make sure to close the dialog if the user clicks links in it that navigate\n // to another entity.\n useEffect(() => {\n setConfirmationDialogOpen(false);\n setInspectionDialogOpen(false);\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [location.pathname]);\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={() => setConfirmationDialogOpen(true)}\n onInspectEntity={() => setInspectionDialogOpen(true)}\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 <InspectEntityDialog\n open={inspectionDialogOpen}\n entity={entity!}\n onClose={() => setInspectionDialogOpen(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\ninterface DeleteEntityDialogProps {\n open: boolean;\n onClose: () => any;\n onConfirm: () => any;\n entity: Entity;\n}\n\nexport function DeleteEntityDialog(props: DeleteEntityDialogProps) {\n const { open, onClose, onConfirm, entity } = 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\n/**\n * Returns true if the given entity has the orphan annotation given by the\n * catalog.\n *\n * @public\n */\nexport function isOrphan(entity: Entity): boolean {\n return entity?.metadata?.annotations?.['backstage.io/orphan'] === 'true';\n}\n\n/**\n * Displays a warning alert if the entity is marked as orphan with the ability\n * to delete said entity.\n *\n * @public\n */\nexport function 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} 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\ninterface 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\n/**\n * Returns true if the given entity has any processing errors on it.\n *\n * @public\n */\nexport async function hasCatalogProcessingErrors(\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 *\n * @public\n */\nexport function 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 {stringifyEntityRef(entity) !==\n stringifyEntityRef(ancestorError.entity) && (\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 */\n\nimport { Entity } from '@backstage/catalog-model';\nimport { useEntity } from '@backstage/plugin-catalog-react';\nimport React, { ReactNode, ReactElement } 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\n/** @public */\nexport interface EntitySwitchCaseProps {\n if?: (\n entity: Entity,\n context: { apis: ApiHolder },\n ) => boolean | Promise<boolean>;\n children: ReactNode;\n}\n\nconst EntitySwitchCaseComponent = (_props: EntitySwitchCaseProps) => null;\n\nattachComponentData(EntitySwitchCaseComponent, ENTITY_SWITCH_KEY, true);\n\ninterface EntitySwitchCase {\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\n/**\n * Props for the {@link EntitySwitch} component.\n * @public\n */\nexport interface EntitySwitchProps {\n children: ReactNode;\n}\n\n/** @public */\nexport const EntitySwitch = (props: EntitySwitchProps) => {\n const { entity } = useEntity();\n const apis = useApiHolder();\n const results = useElementFilter(\n props.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: ReactElement) => {\n const { if: condition, children: elementsChildren } =\n element.props as EntitySwitchCase;\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 = EntitySwitchCaseComponent;\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\n/**\n * For use in EntitySwitch.Case. Matches if the entity is of a given kind.\n * @public\n */\nexport function isKind(kind: string) {\n return (entity: Entity) => strCmp(entity?.kind, kind);\n}\n\n/**\n * For use in EntitySwitch.Case. Matches if the entity is a Component of a given spec.type.\n * @public\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\n/**\n * For use in EntitySwitch.Case. Matches if the entity is in a given namespace.\n * @public\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 from 'react';\n\n/** @public */\nexport function FilteredEntityLayout(props: { children: React.ReactNode }) {\n return (\n <Grid container style={{ position: 'relative' }}>\n {props.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 { 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 } from 'react';\n\n/** @public */\nexport function FilterContainer(props: { children: React.ReactNode }) {\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 {props.children}\n </Box>\n </Drawer>\n </>\n ) : (\n <Grid item lg={2}>\n {props.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 from 'react';\n\n/** @public */\nexport function EntityListContainer(props: { children: React.ReactNode }) {\n return (\n <Grid item xs={12} lg={10}>\n {props.children}\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 { CatalogClient } from '@backstage/catalog-client';\nimport { Entity } from '@backstage/catalog-model';\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';\nimport { AboutCardProps } from './components/AboutCard';\nimport { DefaultCatalogPageProps } from './components/CatalogPage';\nimport { DependencyOfComponentsCardProps } from './components/DependencyOfComponentsCard';\nimport { DependsOnComponentsCardProps } from './components/DependsOnComponentsCard';\nimport { DependsOnResourcesCardProps } from './components/DependsOnResourcesCard';\nimport { HasComponentsCardProps } from './components/HasComponentsCard';\nimport { HasResourcesCardProps } from './components/HasResourcesCard';\nimport { HasSubcomponentsCardProps } from './components/HasSubcomponentsCard';\nimport { HasSystemsCardProps } from './components/HasSystemsCard';\nimport { RelatedEntitiesCardProps } from './components/RelatedEntitiesCard';\n\n/** @public */\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\n/** @public */\nexport const CatalogIndexPage: (props: DefaultCatalogPageProps) => JSX.Element =\n catalogPlugin.provide(\n createRoutableExtension({\n name: 'CatalogIndexPage',\n component: () =>\n import('./components/CatalogPage').then(m => m.CatalogPage),\n mountPoint: catalogRouteRef,\n }),\n );\n\n/** @public */\nexport const CatalogEntityPage: () => JSX.Element = catalogPlugin.provide(\n createRoutableExtension({\n name: 'CatalogEntityPage',\n component: () =>\n import('./components/CatalogEntityPage').then(m => m.CatalogEntityPage),\n mountPoint: entityRouteRef,\n }),\n);\n\n/** @public */\nexport const EntityAboutCard: (props: AboutCardProps) => JSX.Element =\n catalogPlugin.provide(\n createComponentExtension({\n name: 'EntityAboutCard',\n component: {\n lazy: () => import('./components/AboutCard').then(m => m.AboutCard),\n },\n }),\n );\n\n/** @public */\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\n/** @public */\nexport const EntityHasSystemsCard: (props: HasSystemsCardProps) => JSX.Element =\n catalogPlugin.provide(\n createComponentExtension({\n name: 'EntityHasSystemsCard',\n component: {\n lazy: () =>\n import('./components/HasSystemsCard').then(m => m.HasSystemsCard),\n },\n }),\n );\n\n/** @public */\nexport const EntityHasComponentsCard: (\n props: HasComponentsCardProps,\n) => JSX.Element = catalogPlugin.provide(\n createComponentExtension({\n name: 'EntityHasComponentsCard',\n component: {\n lazy: () =>\n import('./components/HasComponentsCard').then(m => m.HasComponentsCard),\n },\n }),\n);\n\n/** @public */\nexport const EntityHasSubcomponentsCard: (\n props: HasSubcomponentsCardProps,\n) => JSX.Element = 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\n/** @public */\nexport const EntityHasResourcesCard: (\n props: HasResourcesCardProps,\n) => JSX.Element = catalogPlugin.provide(\n createComponentExtension({\n name: 'EntityHasResourcesCard',\n component: {\n lazy: () =>\n import('./components/HasResourcesCard').then(m => m.HasResourcesCard),\n },\n }),\n);\n\n/** @public */\nexport const EntityDependsOnComponentsCard: (\n props: DependsOnComponentsCardProps,\n) => JSX.Element = 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\n/** @public */\nexport const EntityDependencyOfComponentsCard: (\n props: DependencyOfComponentsCardProps,\n) => JSX.Element = 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\n/** @public */\nexport const EntityDependsOnResourcesCard: (\n props: DependsOnResourcesCardProps,\n) => JSX.Element = 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/** @public */\nexport const RelatedEntitiesCard: <T extends Entity>(\n props: RelatedEntitiesCardProps<T>,\n) => JSX.Element = 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","capitalize","Edit","makeStyles"],"mappings":"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"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import React, { useEffect } from 'react';
|
|
2
|
+
import { useNavigate, Outlet } from 'react-router';
|
|
3
|
+
import { entityRouteRef, catalogApiRef, AsyncEntityProvider } from '@backstage/plugin-catalog-react';
|
|
4
|
+
import { useRouteRefParams, useApi, errorApiRef } from '@backstage/core-plugin-api';
|
|
5
|
+
import useAsyncRetry from 'react-use/lib/useAsyncRetry';
|
|
6
|
+
|
|
7
|
+
const useEntityFromUrl = () => {
|
|
8
|
+
const { kind, namespace, name } = useRouteRefParams(entityRouteRef);
|
|
9
|
+
const navigate = useNavigate();
|
|
10
|
+
const errorApi = useApi(errorApiRef);
|
|
11
|
+
const catalogApi = useApi(catalogApiRef);
|
|
12
|
+
const {
|
|
13
|
+
value: entity,
|
|
14
|
+
error,
|
|
15
|
+
loading,
|
|
16
|
+
retry: refresh
|
|
17
|
+
} = useAsyncRetry(() => catalogApi.getEntityByName({ kind, namespace, name }), [catalogApi, kind, namespace, name]);
|
|
18
|
+
useEffect(() => {
|
|
19
|
+
if (!name) {
|
|
20
|
+
errorApi.post(new Error("No name provided!"));
|
|
21
|
+
navigate("/");
|
|
22
|
+
}
|
|
23
|
+
}, [errorApi, navigate, error, loading, entity, name]);
|
|
24
|
+
return { entity, loading, error, refresh };
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
function CatalogEntityPage() {
|
|
28
|
+
return /* @__PURE__ */ React.createElement(AsyncEntityProvider, {
|
|
29
|
+
...useEntityFromUrl()
|
|
30
|
+
}, /* @__PURE__ */ React.createElement(Outlet, null));
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export { CatalogEntityPage };
|
|
34
|
+
//# sourceMappingURL=index-7f3caf38.esm.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index-7f3caf38.esm.js","sources":["../../src/components/CatalogEntityPage/useEntityFromUrl.ts","../../src/components/CatalogEntityPage/CatalogEntityPage.tsx"],"sourcesContent":["/*\n * Copyright 2022 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 errorApiRef,\n useApi,\n useRouteRefParams,\n} from '@backstage/core-plugin-api';\nimport {\n catalogApiRef,\n EntityLoadingStatus,\n entityRouteRef,\n} from '@backstage/plugin-catalog-react';\nimport { useEffect } from 'react';\nimport { useNavigate } from 'react-router';\nimport useAsyncRetry from 'react-use/lib/useAsyncRetry';\n\nexport const useEntityFromUrl = (): EntityLoadingStatus => {\n const { kind, namespace, name } = useRouteRefParams(entityRouteRef);\n const navigate = useNavigate();\n const errorApi = useApi(errorApiRef);\n const catalogApi = useApi(catalogApiRef);\n\n const {\n value: entity,\n error,\n loading,\n retry: refresh,\n } = useAsyncRetry(\n () => catalogApi.getEntityByName({ kind, namespace, name }),\n [catalogApi, kind, namespace, name],\n );\n\n useEffect(() => {\n if (!name) {\n errorApi.post(new Error('No name provided!'));\n navigate('/');\n }\n }, [errorApi, navigate, error, loading, entity, name]);\n\n return { entity, loading, error, refresh };\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 { Outlet } from 'react-router';\nimport { AsyncEntityProvider } from '@backstage/plugin-catalog-react';\nimport { useEntityFromUrl } from './useEntityFromUrl';\n\n/** @public */\nexport function CatalogEntityPage() {\n return (\n <AsyncEntityProvider {...useEntityFromUrl()}>\n <Outlet />\n </AsyncEntityProvider>\n );\n}\n"],"names":[],"mappings":";;;;;;MA8Ba,mBAAmB,MAA2B;AACzD,QAAM,EAAE,MAAM,WAAW,SAAS,kBAAkB;AACpD,QAAM,WAAW;AACjB,QAAM,WAAW,OAAO;AACxB,QAAM,aAAa,OAAO;AAE1B,QAAM;AAAA,IACJ,OAAO;AAAA,IACP;AAAA,IACA;AAAA,IACA,OAAO;AAAA,MACL,cACF,MAAM,WAAW,gBAAgB,EAAE,MAAM,WAAW,SACpD,CAAC,YAAY,MAAM,WAAW;AAGhC,YAAU,MAAM;AACd,QAAI,CAAC,MAAM;AACT,eAAS,KAAK,IAAI,MAAM;AACxB,eAAS;AAAA;AAAA,KAEV,CAAC,UAAU,UAAU,OAAO,SAAS,QAAQ;AAEhD,SAAO,EAAE,QAAQ,SAAS,OAAO;AAAA;;6BC/BC;AAClC,6CACG,qBAAD;AAAA,OAAyB;AAAA,yCACtB,QAAD;AAAA;;;;"}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/// <reference types="react" />
|
|
2
|
-
import { Entity, EntityName } from '@backstage/catalog-model';
|
|
3
2
|
import { InfoCardVariants, TableColumn, TableProps } from '@backstage/core-components';
|
|
4
|
-
import
|
|
3
|
+
import { Entity, EntityName } from '@backstage/catalog-model';
|
|
4
|
+
import React, { ReactNode } from 'react';
|
|
5
5
|
import { IndexableDocument } from '@backstage/search-common';
|
|
6
6
|
import * as _backstage_core_plugin_api from '@backstage/core-plugin-api';
|
|
7
7
|
import { IconComponent, ApiHolder } from '@backstage/core-plugin-api';
|
|
@@ -16,8 +16,6 @@ import { UserListFilterKind } from '@backstage/plugin-catalog-react';
|
|
|
16
16
|
* @public
|
|
17
17
|
*/
|
|
18
18
|
interface AboutCardProps {
|
|
19
|
-
/** @deprecated The entity is now grabbed from context instead */
|
|
20
|
-
entity?: Entity;
|
|
21
19
|
variant?: InfoCardVariants;
|
|
22
20
|
}
|
|
23
21
|
/**
|
|
@@ -63,15 +61,25 @@ interface CatalogKindHeaderProps {
|
|
|
63
61
|
declare function CatalogKindHeader(props: CatalogKindHeaderProps): JSX.Element;
|
|
64
62
|
|
|
65
63
|
/**
|
|
66
|
-
* Props for {@link
|
|
64
|
+
* Props for {@link CatalogSearchResultListItem}.
|
|
67
65
|
*
|
|
68
66
|
* @public
|
|
69
67
|
*/
|
|
70
|
-
interface
|
|
68
|
+
interface CatalogSearchResultListItemProps {
|
|
71
69
|
result: IndexableDocument;
|
|
72
70
|
}
|
|
73
71
|
/** @public */
|
|
74
|
-
declare function
|
|
72
|
+
declare function CatalogSearchResultListItem(props: CatalogSearchResultListItemProps): JSX.Element;
|
|
73
|
+
/**
|
|
74
|
+
* @public
|
|
75
|
+
* @deprecated use {@link CatalogSearchResultListItemProps} instead
|
|
76
|
+
*/
|
|
77
|
+
declare type CatalogResultListItemProps = CatalogSearchResultListItemProps;
|
|
78
|
+
/**
|
|
79
|
+
* @public
|
|
80
|
+
* @deprecated use {@link CatalogSearchResultListItem} instead
|
|
81
|
+
*/
|
|
82
|
+
declare const CatalogResultListItem: typeof CatalogSearchResultListItem;
|
|
75
83
|
|
|
76
84
|
/** @public */
|
|
77
85
|
interface CatalogTableRow {
|
|
@@ -110,19 +118,6 @@ declare const CatalogTable: {
|
|
|
110
118
|
}>;
|
|
111
119
|
};
|
|
112
120
|
|
|
113
|
-
/** @public */
|
|
114
|
-
declare const columnFactories: Readonly<{
|
|
115
|
-
createNameColumn(options?: {
|
|
116
|
-
defaultKind?: string | undefined;
|
|
117
|
-
} | undefined): TableColumn<CatalogTableRow>;
|
|
118
|
-
createSystemColumn(): TableColumn<CatalogTableRow>;
|
|
119
|
-
createOwnerColumn(): TableColumn<CatalogTableRow>;
|
|
120
|
-
createSpecTypeColumn(): TableColumn<CatalogTableRow>;
|
|
121
|
-
createSpecLifecycleColumn(): TableColumn<CatalogTableRow>;
|
|
122
|
-
createMetadataDescriptionColumn(): TableColumn<CatalogTableRow>;
|
|
123
|
-
createTagsColumn(): TableColumn<CatalogTableRow>;
|
|
124
|
-
}>;
|
|
125
|
-
|
|
126
121
|
/** @public */
|
|
127
122
|
declare type EntityLayoutRouteProps = {
|
|
128
123
|
path: string;
|
|
@@ -204,13 +199,18 @@ interface EntitySwitchCaseProps {
|
|
|
204
199
|
if?: (entity: Entity, context: {
|
|
205
200
|
apis: ApiHolder;
|
|
206
201
|
}) => boolean | Promise<boolean>;
|
|
207
|
-
children:
|
|
202
|
+
children: ReactNode;
|
|
203
|
+
}
|
|
204
|
+
/**
|
|
205
|
+
* Props for the {@link EntitySwitch} component.
|
|
206
|
+
* @public
|
|
207
|
+
*/
|
|
208
|
+
interface EntitySwitchProps {
|
|
209
|
+
children: ReactNode;
|
|
208
210
|
}
|
|
209
211
|
/** @public */
|
|
210
212
|
declare const EntitySwitch: {
|
|
211
|
-
(props:
|
|
212
|
-
children: React.ReactNode;
|
|
213
|
-
}): JSX.Element | null;
|
|
213
|
+
(props: EntitySwitchProps): JSX.Element | null;
|
|
214
214
|
Case: (_props: EntitySwitchCaseProps) => null;
|
|
215
215
|
};
|
|
216
216
|
|
|
@@ -250,8 +250,6 @@ declare type ColumnBreakpoints = Record<Breakpoint, number>;
|
|
|
250
250
|
|
|
251
251
|
/** @public */
|
|
252
252
|
interface EntityLinksCardProps {
|
|
253
|
-
/** @deprecated The entity is now grabbed from context instead */
|
|
254
|
-
entity?: Entity;
|
|
255
253
|
cols?: ColumnBreakpoints | number;
|
|
256
254
|
variant?: 'gridItem';
|
|
257
255
|
}
|
|
@@ -374,4 +372,4 @@ declare const EntityDependsOnResourcesCard: (props: DependsOnResourcesCardProps)
|
|
|
374
372
|
/** @public */
|
|
375
373
|
declare const RelatedEntitiesCard: <T extends Entity>(props: RelatedEntitiesCardProps<T>) => JSX.Element;
|
|
376
374
|
|
|
377
|
-
export { AboutCard, AboutCardProps, AboutContent, AboutContentProps, AboutField, AboutFieldProps, BackstageOverrides, CatalogEntityPage, CatalogIndexPage, CatalogKindHeader, CatalogKindHeaderProps, CatalogResultListItem, CatalogResultListItemProps, CatalogTable, CatalogTableProps, CatalogTableRow, DefaultCatalogPageProps, DependencyOfComponentsCardProps, DependsOnComponentsCardProps, DependsOnResourcesCardProps, EntityAboutCard, EntityDependencyOfComponentsCard, EntityDependsOnComponentsCard, EntityDependsOnResourcesCard, EntityHasComponentsCard, EntityHasResourcesCard, EntityHasSubcomponentsCard, EntityHasSystemsCard, EntityLayout, EntityLayoutProps, EntityLayoutRouteProps, EntityLinksCard, EntityLinksCardProps, EntityLinksEmptyStateClassKey, EntityListContainer, EntityOrphanWarning, EntityProcessingErrorsPanel, EntitySwitch, EntitySwitchCaseProps, FilterContainer, FilteredEntityLayout, HasComponentsCardProps, HasResourcesCardProps, HasSubcomponentsCardProps, HasSystemsCardProps, PluginCatalogComponentsNameToClassKey, RelatedEntitiesCard, RelatedEntitiesCardProps, SystemDiagramCardClassKey, catalogPlugin,
|
|
375
|
+
export { AboutCard, AboutCardProps, AboutContent, AboutContentProps, AboutField, AboutFieldProps, BackstageOverrides, CatalogEntityPage, CatalogIndexPage, CatalogKindHeader, CatalogKindHeaderProps, CatalogResultListItem, CatalogResultListItemProps, CatalogSearchResultListItem, CatalogSearchResultListItemProps, CatalogTable, CatalogTableProps, CatalogTableRow, DefaultCatalogPageProps, DependencyOfComponentsCardProps, DependsOnComponentsCardProps, DependsOnResourcesCardProps, EntityAboutCard, EntityDependencyOfComponentsCard, EntityDependsOnComponentsCard, EntityDependsOnResourcesCard, EntityHasComponentsCard, EntityHasResourcesCard, EntityHasSubcomponentsCard, EntityHasSystemsCard, EntityLayout, EntityLayoutProps, EntityLayoutRouteProps, EntityLinksCard, EntityLinksCardProps, EntityLinksEmptyStateClassKey, EntityListContainer, EntityOrphanWarning, EntityProcessingErrorsPanel, EntitySwitch, EntitySwitchCaseProps, EntitySwitchProps, FilterContainer, FilteredEntityLayout, HasComponentsCardProps, HasResourcesCardProps, HasSubcomponentsCardProps, HasSystemsCardProps, PluginCatalogComponentsNameToClassKey, RelatedEntitiesCard, RelatedEntitiesCardProps, SystemDiagramCardClassKey, catalogPlugin, hasCatalogProcessingErrors, isComponentType, isKind, isNamespace, isOrphan };
|
package/dist/index.esm.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { A as AboutCard, d as AboutContent, e as AboutField, f as CatalogEntityPage, g as CatalogIndexPage, C as CatalogKindHeader,
|
|
1
|
+
export { A as AboutCard, d as AboutContent, e as AboutField, f as CatalogEntityPage, g as CatalogIndexPage, C as CatalogKindHeader, s as CatalogResultListItem, r as CatalogSearchResultListItem, b as CatalogTable, i as EntityAboutCard, j as EntityDependencyOfComponentsCard, k as EntityDependsOnComponentsCard, l as EntityDependsOnResourcesCard, m as EntityHasComponentsCard, n as EntityHasResourcesCard, o as EntityHasSubcomponentsCard, p as EntityHasSystemsCard, t as EntityLayout, q as EntityLinksCard, E as EntityListContainer, u as EntityOrphanWarning, w as EntityProcessingErrorsPanel, y as EntitySwitch, a as FilterContainer, F as FilteredEntityLayout, R as RelatedEntitiesCard, h as catalogPlugin, x as hasCatalogProcessingErrors, D as isComponentType, z as isKind, B as isNamespace, v as isOrphan } from './esm/index-6ca877bd.esm.js';
|
|
2
2
|
import '@backstage/catalog-model';
|
|
3
3
|
import '@backstage/core-components';
|
|
4
4
|
import '@backstage/core-plugin-api';
|
|
@@ -9,6 +9,7 @@ import '@material-ui/icons/Cached';
|
|
|
9
9
|
import '@material-ui/icons/Description';
|
|
10
10
|
import '@material-ui/icons/Edit';
|
|
11
11
|
import 'react';
|
|
12
|
+
import 'react-use/lib/useAsync';
|
|
12
13
|
import '@material-ui/icons/OpenInNew';
|
|
13
14
|
import 'lodash';
|
|
14
15
|
import '@material-ui/lab';
|
|
@@ -20,6 +21,5 @@ import '@material-ui/icons/MoreVert';
|
|
|
20
21
|
import '@backstage/plugin-catalog-common';
|
|
21
22
|
import '@backstage/errors';
|
|
22
23
|
import '@backstage/catalog-client';
|
|
23
|
-
import 'react-use/lib/useAsync';
|
|
24
24
|
import '@material-ui/icons/FilterList';
|
|
25
25
|
//# sourceMappingURL=index.esm.js.map
|
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.
|
|
4
|
+
"version": "0.9.0",
|
|
5
5
|
"main": "dist/index.esm.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
7
7
|
"license": "Apache-2.0",
|
|
@@ -34,15 +34,15 @@
|
|
|
34
34
|
"clean": "backstage-cli package clean"
|
|
35
35
|
},
|
|
36
36
|
"dependencies": {
|
|
37
|
-
"@backstage/catalog-client": "^0.7.
|
|
38
|
-
"@backstage/catalog-model": "^0.
|
|
39
|
-
"@backstage/core-components": "^0.8.
|
|
40
|
-
"@backstage/core-plugin-api": "^0.
|
|
41
|
-
"@backstage/errors": "^0.2.
|
|
42
|
-
"@backstage/integration-react": "^0.1.
|
|
43
|
-
"@backstage/plugin-catalog-common": "^0.1.
|
|
44
|
-
"@backstage/plugin-catalog-react": "^0.
|
|
45
|
-
"@backstage/search-common": "^0.2.
|
|
37
|
+
"@backstage/catalog-client": "^0.7.2",
|
|
38
|
+
"@backstage/catalog-model": "^0.11.0",
|
|
39
|
+
"@backstage/core-components": "^0.8.10",
|
|
40
|
+
"@backstage/core-plugin-api": "^0.7.0",
|
|
41
|
+
"@backstage/errors": "^0.2.2",
|
|
42
|
+
"@backstage/integration-react": "^0.1.23",
|
|
43
|
+
"@backstage/plugin-catalog-common": "^0.1.4",
|
|
44
|
+
"@backstage/plugin-catalog-react": "^0.7.0",
|
|
45
|
+
"@backstage/search-common": "^0.2.4",
|
|
46
46
|
"@backstage/theme": "^0.2.15",
|
|
47
47
|
"@material-ui/core": "^4.12.2",
|
|
48
48
|
"@material-ui/icons": "^4.9.1",
|
|
@@ -58,11 +58,11 @@
|
|
|
58
58
|
"react": "^16.13.1 || ^17.0.0"
|
|
59
59
|
},
|
|
60
60
|
"devDependencies": {
|
|
61
|
-
"@backstage/cli": "^0.14.
|
|
62
|
-
"@backstage/core-app-api": "^0.5.
|
|
63
|
-
"@backstage/dev-utils": "^0.2.
|
|
64
|
-
"@backstage/plugin-permission-react": "^0.3.
|
|
65
|
-
"@backstage/test-utils": "^0.2.
|
|
61
|
+
"@backstage/cli": "^0.14.1",
|
|
62
|
+
"@backstage/core-app-api": "^0.5.4",
|
|
63
|
+
"@backstage/dev-utils": "^0.2.23",
|
|
64
|
+
"@backstage/plugin-permission-react": "^0.3.2",
|
|
65
|
+
"@backstage/test-utils": "^0.2.6",
|
|
66
66
|
"@testing-library/jest-dom": "^5.10.1",
|
|
67
67
|
"@testing-library/react": "^11.2.5",
|
|
68
68
|
"@testing-library/user-event": "^13.1.8",
|
|
@@ -72,5 +72,5 @@
|
|
|
72
72
|
"files": [
|
|
73
73
|
"dist"
|
|
74
74
|
],
|
|
75
|
-
"gitHead": "
|
|
75
|
+
"gitHead": "a15da6ea1e3e8adc37be98be064071c8b5279b4a"
|
|
76
76
|
}
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
|
-
import { Outlet } from 'react-router';
|
|
3
|
-
import { AsyncEntityProvider, useEntityFromUrl } from '@backstage/plugin-catalog-react';
|
|
4
|
-
|
|
5
|
-
function CatalogEntityPage() {
|
|
6
|
-
return /* @__PURE__ */ React.createElement(AsyncEntityProvider, {
|
|
7
|
-
...useEntityFromUrl()
|
|
8
|
-
}, /* @__PURE__ */ React.createElement(Outlet, null));
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
export { CatalogEntityPage };
|
|
12
|
-
//# sourceMappingURL=index-3467aa13.esm.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index-3467aa13.esm.js","sources":["../../src/components/CatalogEntityPage/CatalogEntityPage.tsx"],"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 React from 'react';\nimport { Outlet } from 'react-router';\nimport {\n useEntityFromUrl,\n AsyncEntityProvider,\n} from '@backstage/plugin-catalog-react';\n\n/** @public */\nexport function CatalogEntityPage() {\n return (\n <AsyncEntityProvider {...useEntityFromUrl()}>\n <Outlet />\n </AsyncEntityProvider>\n );\n}\n"],"names":[],"mappings":";;;;6BAwBoC;AAClC,6CACG,qBAAD;AAAA,OAAyB;AAAA,yCACtB,QAAD;AAAA;;;;"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index-36e4660a.esm.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index-de01f9dd.esm.js","sources":["../../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/EntitySwitch/EntitySwitch.tsx","../../src/components/EntitySwitch/conditions.ts","../../src/components/FilteredEntityLayout/FilteredEntityLayout.tsx","../../src/components/FilteredEntityLayout/FilterContainer.tsx","../../src/components/FilteredEntityLayout/EntityListContainer.tsx","../../src/plugin.ts"],"sourcesContent":["/*\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\n/**\n * Props for {@link AboutField}.\n *\n * @public\n */\nexport interface AboutFieldProps {\n label: string;\n value?: string;\n gridSizes?: Record<string, number>;\n children?: React.ReactNode;\n}\n\n/** @public */\nexport function AboutField(props: AboutFieldProps) {\n const { 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\n/**\n * Props for {@link AboutContent}.\n *\n * @public\n */\nexport interface AboutContentProps {\n entity: Entity;\n}\n\n/** @public */\nexport function AboutContent(props: AboutContentProps) {\n const { 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 ANNOTATION_LOCATION,\n DEFAULT_NAMESPACE,\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\n/**\n * Props for {@link AboutCard}.\n *\n * @public\n */\nexport interface AboutCardProps {\n /** @deprecated The entity is now grabbed from context instead */\n entity?: Entity;\n variant?: InfoCardVariants;\n}\n\n/**\n * @public\n * @deprecated Please use EntityAboutCard instead\n */\nexport function AboutCard(props: AboutCardProps) {\n const { variant } = props;\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 || 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?.[ANNOTATION_LOCATION];\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\n/**\n * Props for {@link CatalogKindHeader}.\n *\n * @public\n */\nexport interface CatalogKindHeaderProps {\n initialFilter?: string;\n}\n\n/** @public */\nexport function CatalogKindHeader(props: CatalogKindHeaderProps) {\n const { initialFilter = 'component' } = props;\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';\nimport { IndexableDocument } from '@backstage/search-common';\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\n/**\n * Props for {@link CatalogResultListItem}.\n *\n * @public\n */\nexport interface CatalogResultListItemProps {\n result: IndexableDocument;\n}\n\n/** @public */\nexport function CatalogResultListItem(props: CatalogResultListItemProps) {\n const result = props.result as any;\n\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 { CatalogTableRow } from './types';\nimport { OverflowTooltip, TableColumn } from '@backstage/core-components';\nimport { Entity } from '@backstage/catalog-model';\n\n// The columnFactories symbol is not directly exported, but through the\n// CatalogTable.columns field.\n/** @public */\nexport const columnFactories = Object.freeze({\n createNameColumn(options?: {\n defaultKind?: string;\n }): TableColumn<CatalogTableRow> {\n function formatContent(entity: Entity): string {\n return (\n entity.metadata?.title ||\n formatEntityRefTitle(entity, {\n defaultKind: options?.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={options?.defaultKind || 'Component'}\n title={entity.metadata?.title}\n />\n ),\n };\n },\n createSystemColumn(): TableColumn<CatalogTableRow> {\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 createOwnerColumn(): TableColumn<CatalogTableRow> {\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 createSpecTypeColumn(): TableColumn<CatalogTableRow> {\n return {\n title: 'Type',\n field: 'entity.spec.type',\n hidden: true,\n };\n },\n createSpecLifecycleColumn(): TableColumn<CatalogTableRow> {\n return {\n title: 'Lifecycle',\n field: 'entity.spec.lifecycle',\n };\n },\n createMetadataDescriptionColumn(): TableColumn<CatalogTableRow> {\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 createTagsColumn(): TableColumn<CatalogTableRow> {\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","/*\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 { columnFactories } from './columns';\nimport { CatalogTableRow } from './types';\nimport {\n CodeSnippet,\n Table,\n TableColumn,\n TableProps,\n WarningPanel,\n} from '@backstage/core-components';\n\n/**\n * Props for {@link CatalogTable}.\n *\n * @public\n */\nexport interface CatalogTableProps {\n columns?: TableColumn<CatalogTableRow>[];\n actions?: TableProps<CatalogTableRow>['actions'];\n}\n\n/** @public */\nexport const CatalogTable = (props: CatalogTableProps) => {\n const { columns, actions } = props;\n const { isStarredEntity, toggleStarredEntity } = useStarredEntities();\n const { loading, error, entities, filters } = useEntityListProvider();\n\n const defaultColumns: TableColumn<CatalogTableRow>[] = 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<CatalogTableRow>['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<CatalogTableRow>\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 CancelIcon from '@material-ui/icons/Cancel';\nimport BugReportIcon from '@material-ui/icons/BugReport';\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\ninterface ExtraContextMenuItem {\n title: string;\n Icon: IconComponent;\n onClick: () => void;\n}\n\n// unstable context menu option, eg: disable the unregister entity menu\ninterface contextMenuOptions {\n disableUnregister: boolean;\n}\n\ninterface EntityContextMenuProps {\n UNSTABLE_extraContextMenuItems?: ExtraContextMenuItem[];\n UNSTABLE_contextMenuOptions?: contextMenuOptions;\n onUnregisterEntity: () => void;\n onInspectEntity: () => void;\n}\n\nexport function EntityContextMenu(props: EntityContextMenuProps) {\n const {\n UNSTABLE_extraContextMenuItems,\n UNSTABLE_contextMenuOptions,\n onUnregisterEntity,\n onInspectEntity,\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 <CancelIcon fontSize=\"small\" />\n </ListItemIcon>\n <ListItemText primary=\"Unregister entity\" />\n </MenuItem>\n <MenuItem\n onClick={() => {\n onClose();\n onInspectEntity();\n }}\n >\n <ListItemIcon>\n <BugReportIcon fontSize=\"small\" />\n </ListItemIcon>\n <ListItemText primary=\"Inspect 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 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 InspectEntityDialog,\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, useEffect, useState } from 'react';\nimport { useLocation, useNavigate } from 'react-router';\nimport { EntityContextMenu } from '../EntityContextMenu/EntityContextMenu';\n\n/** @public */\nexport type EntityLayoutRouteProps = {\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: EntityLayoutRouteProps) => null = () => null;\nattachComponentData(Route, dataKey, true);\nattachComponentData(Route, 'core.gatherMountPoints', true); // This causes all mount points that are discovered within this route to use the path of the route itself\n\nfunction EntityLayoutTitle(props: {\n title: string;\n entity: Entity | undefined;\n}) {\n const { entity, title } = props;\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\nfunction 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 !== DEFAULT_NAMESPACE ? ` in ${namespace}` : ''\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\nfunction EntityLabels(props: { entity: Entity }) {\n const { entity } = props;\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\ninterface ExtraContextMenuItem {\n title: string;\n Icon: IconComponent;\n onClick: () => void;\n}\n\n// unstable context menu option, eg: disable the unregister entity menu\ninterface contextMenuOptions {\n disableUnregister: boolean;\n}\n\n/** @public */\nexport interface 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 *\n * @public\n */\nexport const EntityLayout = (props: EntityLayoutProps) => {\n const {\n UNSTABLE_extraContextMenuItems,\n UNSTABLE_contextMenuOptions,\n children,\n } = props;\n const { kind, namespace, name } = useEntityCompoundName();\n const { entity, loading, error } = useContext(EntityContext);\n const location = useLocation();\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<EntityLayoutRouteProps>() // all nodes, element data, maintain structure or not?\n .flatMap(({ props: elementProps }) => {\n if (elementProps.if && entity && !elementProps.if(entity)) {\n return [];\n }\n\n return [\n {\n path: elementProps.path,\n title: elementProps.title,\n children: elementProps.children,\n tabProps: elementProps.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 [inspectionDialogOpen, setInspectionDialogOpen] = useState(false);\n const navigate = useNavigate();\n const cleanUpAfterRemoval = async () => {\n setConfirmationDialogOpen(false);\n setInspectionDialogOpen(false);\n navigate('/');\n };\n\n // Make sure to close the dialog if the user clicks links in it that navigate\n // to another entity.\n useEffect(() => {\n setConfirmationDialogOpen(false);\n setInspectionDialogOpen(false);\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [location.pathname]);\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={() => setConfirmationDialogOpen(true)}\n onInspectEntity={() => setInspectionDialogOpen(true)}\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 <InspectEntityDialog\n open={inspectionDialogOpen}\n entity={entity!}\n onClose={() => setInspectionDialogOpen(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\ninterface DeleteEntityDialogProps {\n open: boolean;\n onClose: () => any;\n onConfirm: () => any;\n entity: Entity;\n}\n\nexport function DeleteEntityDialog(props: DeleteEntityDialogProps) {\n const { open, onClose, onConfirm, entity } = 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\n/**\n * Returns true if the given entity has the orphan annotation given by the\n * catalog.\n *\n * @public\n */\nexport function isOrphan(entity: Entity): boolean {\n return entity?.metadata?.annotations?.['backstage.io/orphan'] === 'true';\n}\n\n/**\n * Displays a warning alert if the entity is marked as orphan with the ability\n * to delete said entity.\n *\n * @public\n */\nexport function 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} 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\ninterface 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\n/**\n * Returns true if the given entity has any processing errors on it.\n *\n * @public\n */\nexport async function hasCatalogProcessingErrors(\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 *\n * @public\n */\nexport function 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 {stringifyEntityRef(entity) !==\n stringifyEntityRef(ancestorError.entity) && (\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 */\n\nimport { Entity } from '@backstage/catalog-model';\nimport { useEntity } from '@backstage/plugin-catalog-react';\nimport React 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\n/** @public */\nexport interface EntitySwitchCaseProps {\n if?: (\n entity: Entity,\n context: { apis: ApiHolder },\n ) => boolean | Promise<boolean>;\n children: React.ReactNode;\n}\n\nconst EntitySwitchCaseComponent = (_props: EntitySwitchCaseProps) => null;\n\nattachComponentData(EntitySwitchCaseComponent, ENTITY_SWITCH_KEY, true);\n\ninterface EntitySwitchCase {\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\n/** @public */\nexport const EntitySwitch = (props: { children: React.ReactNode }) => {\n const { entity } = useEntity();\n const apis = useApiHolder();\n const results = useElementFilter(\n props.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 EntitySwitchCase;\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 = EntitySwitchCaseComponent;\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\n/**\n * For use in EntitySwitch.Case. Matches if the entity is of a given kind.\n * @public\n */\nexport function isKind(kind: string) {\n return (entity: Entity) => strCmp(entity?.kind, kind);\n}\n\n/**\n * For use in EntitySwitch.Case. Matches if the entity is a Component of a given spec.type.\n * @public\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\n/**\n * For use in EntitySwitch.Case. Matches if the entity is in a given namespace.\n * @public\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 from 'react';\n\n/** @public */\nexport function FilteredEntityLayout(props: { children: React.ReactNode }) {\n return (\n <Grid container style={{ position: 'relative' }}>\n {props.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 { 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 } from 'react';\n\n/** @public */\nexport function FilterContainer(props: { children: React.ReactNode }) {\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 {props.children}\n </Box>\n </Drawer>\n </>\n ) : (\n <Grid item lg={2}>\n {props.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 from 'react';\n\n/** @public */\nexport function EntityListContainer(props: { children: React.ReactNode }) {\n return (\n <Grid item xs={12} lg={10}>\n {props.children}\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 { CatalogClient } from '@backstage/catalog-client';\nimport { Entity } from '@backstage/catalog-model';\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';\nimport { AboutCardProps } from './components/AboutCard';\nimport { DefaultCatalogPageProps } from './components/CatalogPage';\nimport { DependencyOfComponentsCardProps } from './components/DependencyOfComponentsCard';\nimport { DependsOnComponentsCardProps } from './components/DependsOnComponentsCard';\nimport { DependsOnResourcesCardProps } from './components/DependsOnResourcesCard';\nimport { HasComponentsCardProps } from './components/HasComponentsCard';\nimport { HasResourcesCardProps } from './components/HasResourcesCard';\nimport { HasSubcomponentsCardProps } from './components/HasSubcomponentsCard';\nimport { HasSystemsCardProps } from './components/HasSystemsCard';\nimport { RelatedEntitiesCardProps } from './components/RelatedEntitiesCard';\n\n/** @public */\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\n/** @public */\nexport const CatalogIndexPage: (props: DefaultCatalogPageProps) => JSX.Element =\n catalogPlugin.provide(\n createRoutableExtension({\n name: 'CatalogIndexPage',\n component: () =>\n import('./components/CatalogPage').then(m => m.CatalogPage),\n mountPoint: catalogRouteRef,\n }),\n );\n\n/** @public */\nexport const CatalogEntityPage: () => JSX.Element = catalogPlugin.provide(\n createRoutableExtension({\n name: 'CatalogEntityPage',\n component: () =>\n import('./components/CatalogEntityPage').then(m => m.CatalogEntityPage),\n mountPoint: entityRouteRef,\n }),\n);\n\n/** @public */\nexport const EntityAboutCard: (props: AboutCardProps) => JSX.Element =\n catalogPlugin.provide(\n createComponentExtension({\n name: 'EntityAboutCard',\n component: {\n lazy: () => import('./components/AboutCard').then(m => m.AboutCard),\n },\n }),\n );\n\n/** @public */\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\n/** @public */\nexport const EntityHasSystemsCard: (props: HasSystemsCardProps) => JSX.Element =\n catalogPlugin.provide(\n createComponentExtension({\n name: 'EntityHasSystemsCard',\n component: {\n lazy: () =>\n import('./components/HasSystemsCard').then(m => m.HasSystemsCard),\n },\n }),\n );\n\n/** @public */\nexport const EntityHasComponentsCard: (\n props: HasComponentsCardProps,\n) => JSX.Element = catalogPlugin.provide(\n createComponentExtension({\n name: 'EntityHasComponentsCard',\n component: {\n lazy: () =>\n import('./components/HasComponentsCard').then(m => m.HasComponentsCard),\n },\n }),\n);\n\n/** @public */\nexport const EntityHasSubcomponentsCard: (\n props: HasSubcomponentsCardProps,\n) => JSX.Element = 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\n/** @public */\nexport const EntityHasResourcesCard: (\n props: HasResourcesCardProps,\n) => JSX.Element = catalogPlugin.provide(\n createComponentExtension({\n name: 'EntityHasResourcesCard',\n component: {\n lazy: () =>\n import('./components/HasResourcesCard').then(m => m.HasResourcesCard),\n },\n }),\n);\n\n/** @public */\nexport const EntityDependsOnComponentsCard: (\n props: DependsOnComponentsCardProps,\n) => JSX.Element = 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\n/** @public */\nexport const EntityDependencyOfComponentsCard: (\n props: DependencyOfComponentsCardProps,\n) => JSX.Element = 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\n/** @public */\nexport const EntityDependsOnResourcesCard: (\n props: DependsOnResourcesCardProps,\n) => JSX.Element = 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/** @public */\nexport const RelatedEntitiesCard: <T extends Entity>(\n props: RelatedEntitiesCardProps<T>,\n) => JSX.Element = 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","capitalize","Edit","makeStyles"],"mappings":"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"}
|