@backstage/plugin-catalog 1.29.0-next.1 → 1.29.0-next.2
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 +69 -0
- package/README.md +1 -1
- package/dist/alpha/DefaultEntityContentLayout.esm.js +14 -3
- package/dist/alpha/DefaultEntityContentLayout.esm.js.map +1 -1
- package/dist/alpha/components/EntityHeader/EntityHeader.esm.js +57 -42
- package/dist/alpha/components/EntityHeader/EntityHeader.esm.js.map +1 -1
- package/dist/alpha/components/EntityLabels/EntityLabels.esm.js +25 -22
- package/dist/alpha/components/EntityLabels/EntityLabels.esm.js.map +1 -1
- package/dist/alpha/components/EntityLayout/EntityLayout.esm.js +24 -9
- package/dist/alpha/components/EntityLayout/EntityLayout.esm.js.map +1 -1
- package/dist/alpha/components/EntityTabs/EntityTabs.esm.js +9 -2
- package/dist/alpha/components/EntityTabs/EntityTabs.esm.js.map +1 -1
- package/dist/alpha/components/EntityTabs/EntityTabsGroup.esm.js +69 -53
- package/dist/alpha/components/EntityTabs/EntityTabsGroup.esm.js.map +1 -1
- package/dist/alpha/components/EntityTabs/EntityTabsList.esm.js +31 -30
- package/dist/alpha/components/EntityTabs/EntityTabsList.esm.js.map +1 -1
- package/dist/alpha/components/EntityTabs/EntityTabsPanel.esm.js +5 -5
- package/dist/alpha/components/EntityTabs/EntityTabsPanel.esm.js.map +1 -1
- package/dist/alpha/contextMenuItems.esm.js +106 -0
- package/dist/alpha/contextMenuItems.esm.js.map +1 -0
- package/dist/alpha/entityCards.esm.js +11 -11
- package/dist/alpha/entityCards.esm.js.map +1 -1
- package/dist/alpha/entityContents.esm.js +5 -4
- package/dist/alpha/entityContents.esm.js.map +1 -1
- package/dist/alpha/filter/FilterWrapper.esm.js +1 -0
- package/dist/alpha/filter/FilterWrapper.esm.js.map +1 -1
- package/dist/alpha/filters.esm.js +10 -10
- package/dist/alpha/filters.esm.js.map +1 -1
- package/dist/alpha/pages.esm.js +15 -11
- package/dist/alpha/pages.esm.js.map +1 -1
- package/dist/alpha/plugin.esm.js +2 -0
- package/dist/alpha/plugin.esm.js.map +1 -1
- package/dist/alpha/searchResultItems.esm.js.map +1 -1
- package/dist/alpha.d.ts +58 -44
- package/dist/alpha.esm.js +0 -1
- package/dist/alpha.esm.js.map +1 -1
- package/dist/components/AboutCard/AboutCard.esm.js +50 -41
- package/dist/components/AboutCard/AboutCard.esm.js.map +1 -1
- package/dist/components/AboutCard/AboutContent.esm.js +106 -96
- package/dist/components/AboutCard/AboutContent.esm.js.map +1 -1
- package/dist/components/AboutCard/AboutField.esm.js +6 -3
- package/dist/components/AboutCard/AboutField.esm.js.map +1 -1
- package/dist/components/CatalogEntityPage/CatalogEntityPage.esm.js +2 -2
- package/dist/components/CatalogEntityPage/CatalogEntityPage.esm.js.map +1 -1
- package/dist/components/CatalogKindHeader/CatalogKindHeader.esm.js +7 -6
- package/dist/components/CatalogKindHeader/CatalogKindHeader.esm.js.map +1 -1
- package/dist/components/CatalogPage/CatalogPage.esm.js +2 -2
- package/dist/components/CatalogPage/CatalogPage.esm.js.map +1 -1
- package/dist/components/CatalogPage/DefaultCatalogPage.esm.js +21 -12
- package/dist/components/CatalogPage/DefaultCatalogPage.esm.js.map +1 -1
- package/dist/components/CatalogSearchResultListItem/CatalogSearchResultListItem.esm.js +57 -46
- package/dist/components/CatalogSearchResultListItem/CatalogSearchResultListItem.esm.js.map +1 -1
- package/dist/components/CatalogTable/CatalogTable.esm.js +19 -12
- package/dist/components/CatalogTable/CatalogTable.esm.js.map +1 -1
- package/dist/components/CatalogTable/CatalogTableToolbar.esm.js +5 -2
- package/dist/components/CatalogTable/CatalogTableToolbar.esm.js.map +1 -1
- package/dist/components/CatalogTable/CursorPaginatedCatalogTable.esm.js +2 -2
- package/dist/components/CatalogTable/CursorPaginatedCatalogTable.esm.js.map +1 -1
- package/dist/components/CatalogTable/OffsetPaginatedCatalogTable.esm.js +4 -3
- package/dist/components/CatalogTable/OffsetPaginatedCatalogTable.esm.js.map +1 -1
- package/dist/components/CatalogTable/columns.esm.js +15 -15
- package/dist/components/CatalogTable/columns.esm.js.map +1 -1
- package/dist/components/DependencyOfComponentsCard/DependencyOfComponentsCard.esm.js +2 -2
- package/dist/components/DependencyOfComponentsCard/DependencyOfComponentsCard.esm.js.map +1 -1
- package/dist/components/DependsOnComponentsCard/DependsOnComponentsCard.esm.js +2 -2
- package/dist/components/DependsOnComponentsCard/DependsOnComponentsCard.esm.js.map +1 -1
- package/dist/components/DependsOnResourcesCard/DependsOnResourcesCard.esm.js +2 -2
- package/dist/components/DependsOnResourcesCard/DependsOnResourcesCard.esm.js.map +1 -1
- package/dist/components/EntityContextMenu/EntityContextMenu.esm.js +91 -59
- package/dist/components/EntityContextMenu/EntityContextMenu.esm.js.map +1 -1
- package/dist/components/EntityContextMenu/UnregisterEntity.esm.js +10 -8
- package/dist/components/EntityContextMenu/UnregisterEntity.esm.js.map +1 -1
- package/dist/components/EntityLabelsCard/EntityLabelsCard.esm.js +4 -4
- package/dist/components/EntityLabelsCard/EntityLabelsCard.esm.js.map +1 -1
- package/dist/components/EntityLabelsCard/EntityLabelsEmptyState.esm.js +24 -20
- package/dist/components/EntityLabelsCard/EntityLabelsEmptyState.esm.js.map +1 -1
- package/dist/components/EntityLayout/EntityLayout.esm.js +106 -77
- package/dist/components/EntityLayout/EntityLayout.esm.js.map +1 -1
- package/dist/components/EntityLinksCard/EntityLinksCard.esm.js +3 -3
- package/dist/components/EntityLinksCard/EntityLinksCard.esm.js.map +1 -1
- package/dist/components/EntityLinksCard/EntityLinksEmptyState.esm.js +24 -20
- package/dist/components/EntityLinksCard/EntityLinksEmptyState.esm.js.map +1 -1
- package/dist/components/EntityLinksCard/IconLink.esm.js +5 -2
- package/dist/components/EntityLinksCard/IconLink.esm.js.map +1 -1
- package/dist/components/EntityLinksCard/LinksGridList.esm.js +2 -2
- package/dist/components/EntityLinksCard/LinksGridList.esm.js.map +1 -1
- package/dist/components/EntityOrphanWarning/DeleteEntityDialog.esm.js +18 -11
- package/dist/components/EntityOrphanWarning/DeleteEntityDialog.esm.js.map +1 -1
- package/dist/components/EntityOrphanWarning/EntityOrphanWarning.esm.js +14 -10
- package/dist/components/EntityOrphanWarning/EntityOrphanWarning.esm.js.map +1 -1
- package/dist/components/EntityProcessingErrorsPanel/EntityProcessingErrorsPanel.esm.js +10 -3
- package/dist/components/EntityProcessingErrorsPanel/EntityProcessingErrorsPanel.esm.js.map +1 -1
- package/dist/components/EntityRelationWarning/EntityRelationWarning.esm.js +7 -3
- package/dist/components/EntityRelationWarning/EntityRelationWarning.esm.js.map +1 -1
- package/dist/components/EntitySwitch/EntitySwitch.esm.js +4 -4
- package/dist/components/EntitySwitch/EntitySwitch.esm.js.map +1 -1
- package/dist/components/HasComponentsCard/HasComponentsCard.esm.js +2 -2
- package/dist/components/HasComponentsCard/HasComponentsCard.esm.js.map +1 -1
- package/dist/components/HasResourcesCard/HasResourcesCard.esm.js +2 -2
- package/dist/components/HasResourcesCard/HasResourcesCard.esm.js.map +1 -1
- package/dist/components/HasSubcomponentsCard/HasSubcomponentsCard.esm.js +2 -2
- package/dist/components/HasSubcomponentsCard/HasSubcomponentsCard.esm.js.map +1 -1
- package/dist/components/HasSubdomainsCard/HasSubdomainsCard.esm.js +2 -2
- package/dist/components/HasSubdomainsCard/HasSubdomainsCard.esm.js.map +1 -1
- package/dist/components/HasSystemsCard/HasSystemsCard.esm.js +2 -2
- package/dist/components/HasSystemsCard/HasSystemsCard.esm.js.map +1 -1
- package/dist/components/RelatedEntitiesCard/RelatedEntitiesCard.esm.js +8 -5
- package/dist/components/RelatedEntitiesCard/RelatedEntitiesCard.esm.js.map +1 -1
- package/dist/context/EntityContextMenuContext.esm.js +18 -0
- package/dist/context/EntityContextMenuContext.esm.js.map +1 -0
- package/dist/index.d.ts +23 -22
- package/package.json +18 -17
- package/dist/alpha/blueprints/CatalogFilterBlueprint.esm.js +0 -17
- package/dist/alpha/blueprints/CatalogFilterBlueprint.esm.js.map +0 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,74 @@
|
|
|
1
1
|
# @backstage/plugin-catalog
|
|
2
2
|
|
|
3
|
+
## 1.29.0-next.2
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- 61d350f: **BREAKING ALPHA**: `CatalogFilterBlueprint`, used in the new frontend system, is now exported under plugin-catalog-react instead of plugin-catalog.
|
|
8
|
+
|
|
9
|
+
```diff
|
|
10
|
+
+ import { CatalogFilterBlueprint } from '@backstage/plugin-catalog-react/alpha';
|
|
11
|
+
- import { CatalogFilterBlueprint } from '@backstage/plugin-catalog/alpha';
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
- 09afd67: Adds `EntityContextMenuItemBlueprint` to enable extending the entity page's context menu with user defined items.
|
|
15
|
+
|
|
16
|
+
For example:
|
|
17
|
+
|
|
18
|
+
```ts
|
|
19
|
+
import { EntityContextMenuItemBlueprint } from '@backstage/plugin-catalog-react/alpha';
|
|
20
|
+
|
|
21
|
+
const myCustomHref = EntityContextMenuItemBlueprint.make({
|
|
22
|
+
name: 'test-href',
|
|
23
|
+
params: {
|
|
24
|
+
icon: <span>Example Icon</span>,
|
|
25
|
+
useProps: () => ({
|
|
26
|
+
title: 'Example Href',
|
|
27
|
+
href: '/example-path',
|
|
28
|
+
disabled: false,
|
|
29
|
+
component: 'a',
|
|
30
|
+
}),
|
|
31
|
+
},
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
const myCustomOnClick = EntityContextMenuItemBlueprint.make({
|
|
35
|
+
name: 'test-click',
|
|
36
|
+
params: {
|
|
37
|
+
icon: <span>Test Icon</span>,
|
|
38
|
+
useProps: () => ({
|
|
39
|
+
title: 'Example onClick',
|
|
40
|
+
onClick: () => window.alert('Hello world!'),
|
|
41
|
+
disabled: false,
|
|
42
|
+
}),
|
|
43
|
+
},
|
|
44
|
+
});
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
### Patch Changes
|
|
48
|
+
|
|
49
|
+
- e655f62: Updated `README.md` to use `yarn start` instead of `yarn dev`.
|
|
50
|
+
- a47fd39: Removes instances of default React imports, a necessary update for the upcoming React 19 migration.
|
|
51
|
+
|
|
52
|
+
<https://legacy.reactjs.org/blog/2020/09/22/introducing-the-new-jsx-transform.html>
|
|
53
|
+
|
|
54
|
+
- Updated dependencies
|
|
55
|
+
- @backstage/frontend-plugin-api@0.10.1-next.1
|
|
56
|
+
- @backstage/integration-react@1.2.6-next.1
|
|
57
|
+
- @backstage/core-compat-api@0.4.1-next.2
|
|
58
|
+
- @backstage/core-components@0.17.1-next.1
|
|
59
|
+
- @backstage/core-plugin-api@1.10.6-next.0
|
|
60
|
+
- @backstage/plugin-permission-react@0.4.33-next.0
|
|
61
|
+
- @backstage/plugin-catalog-react@1.17.0-next.2
|
|
62
|
+
- @backstage/plugin-search-react@1.8.8-next.1
|
|
63
|
+
- @backstage/catalog-client@1.9.1
|
|
64
|
+
- @backstage/catalog-model@1.7.3
|
|
65
|
+
- @backstage/errors@1.2.7
|
|
66
|
+
- @backstage/types@1.2.1
|
|
67
|
+
- @backstage/version-bridge@1.0.11
|
|
68
|
+
- @backstage/plugin-catalog-common@1.1.3
|
|
69
|
+
- @backstage/plugin-scaffolder-common@1.5.10
|
|
70
|
+
- @backstage/plugin-search-common@1.2.17
|
|
71
|
+
|
|
3
72
|
## 1.29.0-next.1
|
|
4
73
|
|
|
5
74
|
### Patch Changes
|
package/README.md
CHANGED
|
@@ -93,7 +93,7 @@ To evaluate the catalog and have a greater amount of functionality available,
|
|
|
93
93
|
run the entire Backstage example application from the root folder:
|
|
94
94
|
|
|
95
95
|
```bash
|
|
96
|
-
yarn
|
|
96
|
+
yarn start
|
|
97
97
|
```
|
|
98
98
|
|
|
99
99
|
This will launch both frontend and backend in the same window, populated with
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { jsxs, Fragment, jsx } from 'react/jsx-runtime';
|
|
2
2
|
import Grid from '@material-ui/core/Grid';
|
|
3
3
|
import { makeStyles } from '@material-ui/core/styles';
|
|
4
4
|
import { EntitySwitch } from '../components/EntitySwitch/EntitySwitch.esm.js';
|
|
@@ -63,7 +63,11 @@ const useStyles = makeStyles((theme) => ({
|
|
|
63
63
|
}
|
|
64
64
|
}
|
|
65
65
|
}));
|
|
66
|
-
const entityWarningContent = /* @__PURE__ */
|
|
66
|
+
const entityWarningContent = /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
67
|
+
/* @__PURE__ */ jsx(EntitySwitch, { children: /* @__PURE__ */ jsx(EntitySwitch.Case, { if: isOrphan, children: /* @__PURE__ */ jsx(Grid, { item: true, xs: 12, children: /* @__PURE__ */ jsx(EntityOrphanWarning, {}) }) }) }),
|
|
68
|
+
/* @__PURE__ */ jsx(EntitySwitch, { children: /* @__PURE__ */ jsx(EntitySwitch.Case, { if: hasRelationWarnings, children: /* @__PURE__ */ jsx(Grid, { item: true, xs: 12, children: /* @__PURE__ */ jsx(EntityRelationWarning, {}) }) }) }),
|
|
69
|
+
/* @__PURE__ */ jsx(EntitySwitch, { children: /* @__PURE__ */ jsx(EntitySwitch.Case, { if: hasCatalogProcessingErrors, children: /* @__PURE__ */ jsx(Grid, { item: true, xs: 12, children: /* @__PURE__ */ jsx(EntityProcessingErrorsPanel, {}) }) }) })
|
|
70
|
+
] });
|
|
67
71
|
function DefaultEntityContentLayout(props) {
|
|
68
72
|
const { cards } = props;
|
|
69
73
|
const infoCards = cards.filter((card) => card.type === "info");
|
|
@@ -76,7 +80,14 @@ function DefaultEntityContentLayout(props) {
|
|
|
76
80
|
summaryCards: !!summaryCards.length,
|
|
77
81
|
contentCards: !!contentCards.length
|
|
78
82
|
});
|
|
79
|
-
return /* @__PURE__ */
|
|
83
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
84
|
+
entityWarningContent,
|
|
85
|
+
/* @__PURE__ */ jsxs("div", { className: classes.root, children: [
|
|
86
|
+
infoCards.length > 0 ? /* @__PURE__ */ jsx("div", { className: classes.infoArea, children: infoCards.map((card) => card.element) }) : null,
|
|
87
|
+
summaryCards.length > 0 ? /* @__PURE__ */ jsx("div", { className: classes.summaryArea, children: /* @__PURE__ */ jsx(HorizontalScrollGrid, { children: summaryCards.map((card) => /* @__PURE__ */ jsx("div", { className: classes.summaryCard, children: card.element })) }) }) : null,
|
|
88
|
+
contentCards.length > 0 ? /* @__PURE__ */ jsx("div", { className: classes.contentArea, children: contentCards.map((card) => card.element) }) : null
|
|
89
|
+
] })
|
|
90
|
+
] });
|
|
80
91
|
}
|
|
81
92
|
|
|
82
93
|
export { DefaultEntityContentLayout };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DefaultEntityContentLayout.esm.js","sources":["../../src/alpha/DefaultEntityContentLayout.tsx"],"sourcesContent":["/*\n * Copyright 2023 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
|
|
1
|
+
{"version":3,"file":"DefaultEntityContentLayout.esm.js","sources":["../../src/alpha/DefaultEntityContentLayout.tsx"],"sourcesContent":["/*\n * Copyright 2023 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/Grid';\nimport { makeStyles, Theme } from '@material-ui/core/styles';\nimport { EntityContentLayoutProps } from '@backstage/plugin-catalog-react/alpha';\nimport { EntitySwitch } from '../components/EntitySwitch';\nimport {\n EntityOrphanWarning,\n isOrphan,\n} from '../components/EntityOrphanWarning';\nimport {\n EntityRelationWarning,\n hasRelationWarnings,\n} from '../components/EntityRelationWarning';\nimport {\n EntityProcessingErrorsPanel,\n hasCatalogProcessingErrors,\n} from '../components/EntityProcessingErrorsPanel';\nimport { HorizontalScrollGrid } from '@backstage/core-components';\n\nconst useStyles = makeStyles<\n Theme,\n { infoCards: boolean; summaryCards: boolean; contentCards: boolean }\n>(theme => ({\n root: {\n display: 'flex',\n flexFlow: 'column nowrap',\n gap: theme.spacing(3),\n },\n contentArea: {\n display: 'flex',\n flexFlow: 'column',\n gap: theme.spacing(3),\n alignItems: 'stretch',\n minWidth: 0,\n },\n infoArea: {\n display: 'flex',\n flexFlow: 'column nowrap',\n alignItems: 'stretch',\n gap: theme.spacing(3),\n minWidth: 0,\n },\n summaryArea: {\n margin: theme.spacing(1.5), // To counteract MUI negative grid margin\n },\n summaryCard: {\n flex: '0 0 auto',\n '& + &': {\n marginLeft: theme.spacing(3),\n },\n },\n [theme.breakpoints.up('md')]: {\n root: {\n display: 'grid',\n gap: 0,\n gridTemplateAreas: ({ summaryCards }) => `\n \"${summaryCards ? 'summary' : 'content'} info\"\n \"content info\"\n `,\n gridTemplateColumns: ({ infoCards }) => (infoCards ? '2fr 1fr' : '1fr'),\n alignItems: 'start',\n },\n infoArea: {\n gridArea: 'info',\n position: 'sticky',\n top: theme.spacing(3),\n marginLeft: theme.spacing(3),\n },\n contentArea: {\n gridArea: 'content',\n },\n summaryArea: {\n gridArea: 'summary',\n marginBottom: theme.spacing(3),\n },\n },\n}));\n\nconst entityWarningContent = (\n <>\n <EntitySwitch>\n <EntitySwitch.Case if={isOrphan}>\n <Grid item xs={12}>\n <EntityOrphanWarning />\n </Grid>\n </EntitySwitch.Case>\n </EntitySwitch>\n\n <EntitySwitch>\n <EntitySwitch.Case if={hasRelationWarnings}>\n <Grid item xs={12}>\n <EntityRelationWarning />\n </Grid>\n </EntitySwitch.Case>\n </EntitySwitch>\n\n <EntitySwitch>\n <EntitySwitch.Case if={hasCatalogProcessingErrors}>\n <Grid item xs={12}>\n <EntityProcessingErrorsPanel />\n </Grid>\n </EntitySwitch.Case>\n </EntitySwitch>\n </>\n);\n\nexport function DefaultEntityContentLayout(props: EntityContentLayoutProps) {\n const { cards } = props;\n\n const infoCards = cards.filter(card => card.type === 'info');\n const summaryCards = cards.filter(card => card.type === 'summary');\n const contentCards = cards.filter(\n card => !card.type || card.type === 'content',\n );\n\n const classes = useStyles({\n infoCards: !!infoCards.length,\n summaryCards: !!summaryCards.length,\n contentCards: !!contentCards.length,\n });\n\n return (\n <>\n {entityWarningContent}\n <div className={classes.root}>\n {infoCards.length > 0 ? (\n <div className={classes.infoArea}>\n {infoCards.map(card => card.element)}\n </div>\n ) : null}\n {summaryCards.length > 0 ? (\n <div className={classes.summaryArea}>\n <HorizontalScrollGrid>\n {summaryCards.map(card => (\n <div className={classes.summaryCard}>{card.element}</div>\n ))}\n </HorizontalScrollGrid>\n </div>\n ) : null}\n {contentCards.length > 0 ? (\n <div className={classes.contentArea}>\n {contentCards.map(card => card.element)}\n </div>\n ) : null}\n </div>\n </>\n );\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
2
|
+
import { useState, useCallback, useEffect } from 'react';
|
|
2
3
|
import { useLocation, useNavigate, useSearchParams } from 'react-router-dom';
|
|
3
4
|
import useAsync from 'react-use/esm/useAsync';
|
|
4
5
|
import { makeStyles } from '@material-ui/core/styles';
|
|
@@ -56,16 +57,19 @@ function EntityHeaderTitle() {
|
|
|
56
57
|
const { entity } = useAsyncEntity();
|
|
57
58
|
const { kind, namespace, name } = useRouteRefParams(entityRouteRef);
|
|
58
59
|
const { headerTitle: title } = headerProps(kind, namespace, name, entity);
|
|
59
|
-
return /* @__PURE__ */
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
60
|
+
return /* @__PURE__ */ jsxs(Box, { display: "inline-flex", alignItems: "center", height: "1em", maxWidth: "100%", children: [
|
|
61
|
+
/* @__PURE__ */ jsx(
|
|
62
|
+
Box,
|
|
63
|
+
{
|
|
64
|
+
component: "span",
|
|
65
|
+
textOverflow: "ellipsis",
|
|
66
|
+
whiteSpace: "nowrap",
|
|
67
|
+
overflow: "hidden",
|
|
68
|
+
children: entity ? /* @__PURE__ */ jsx(EntityDisplayName, { entityRef: entity, hideIcon: true }) : title
|
|
69
|
+
}
|
|
70
|
+
),
|
|
71
|
+
entity && /* @__PURE__ */ jsx(FavoriteEntity, { entity })
|
|
72
|
+
] });
|
|
69
73
|
}
|
|
70
74
|
function EntityHeaderSubtitle(props) {
|
|
71
75
|
const { parentEntityRelations } = props;
|
|
@@ -86,12 +90,17 @@ function EntityHeaderSubtitle(props) {
|
|
|
86
90
|
}
|
|
87
91
|
return null;
|
|
88
92
|
}, [parentEntity, catalogApi]);
|
|
89
|
-
return parentEntity ? /* @__PURE__ */
|
|
93
|
+
return parentEntity ? /* @__PURE__ */ jsxs(Breadcrumbs, { separator: ">", className: classes.breadcrumbs, children: [
|
|
94
|
+
ancestorEntity && /* @__PURE__ */ jsx(EntityRefLink, { entityRef: ancestorEntity.targetRef, disableTooltip: true }),
|
|
95
|
+
/* @__PURE__ */ jsx(EntityRefLink, { entityRef: parentEntity.targetRef, disableTooltip: true }),
|
|
96
|
+
name
|
|
97
|
+
] }) : null;
|
|
90
98
|
}
|
|
91
99
|
function EntityHeader(props) {
|
|
92
100
|
const {
|
|
93
101
|
UNSTABLE_extraContextMenuItems,
|
|
94
102
|
UNSTABLE_contextMenuOptions,
|
|
103
|
+
contextMenuItems,
|
|
95
104
|
parentEntityRelations,
|
|
96
105
|
title,
|
|
97
106
|
subtitle
|
|
@@ -146,40 +155,46 @@ function EntityHeader(props) {
|
|
|
146
155
|
[setSearchParams]
|
|
147
156
|
);
|
|
148
157
|
const inspectDialogOpen = typeof selectedInspectEntityDialogTab === "string";
|
|
149
|
-
return /* @__PURE__ */
|
|
158
|
+
return /* @__PURE__ */ jsx(
|
|
150
159
|
Header,
|
|
151
160
|
{
|
|
152
161
|
pageTitleOverride: entityFallbackText,
|
|
153
162
|
type,
|
|
154
|
-
title: title ?? /* @__PURE__ */
|
|
155
|
-
subtitle: subtitle ?? /* @__PURE__ */
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
163
|
+
title: title ?? /* @__PURE__ */ jsx(EntityHeaderTitle, {}),
|
|
164
|
+
subtitle: subtitle ?? /* @__PURE__ */ jsx(EntityHeaderSubtitle, { parentEntityRelations }),
|
|
165
|
+
children: entity && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
166
|
+
/* @__PURE__ */ jsx(EntityLabels, { entity }),
|
|
167
|
+
/* @__PURE__ */ jsx(
|
|
168
|
+
EntityContextMenu,
|
|
169
|
+
{
|
|
170
|
+
UNSTABLE_extraContextMenuItems,
|
|
171
|
+
UNSTABLE_contextMenuOptions,
|
|
172
|
+
contextMenuItems,
|
|
173
|
+
onInspectEntity: openInspectEntityDialog,
|
|
174
|
+
onUnregisterEntity: openUnregisterEntityDialog
|
|
175
|
+
}
|
|
176
|
+
),
|
|
177
|
+
/* @__PURE__ */ jsx(
|
|
178
|
+
InspectEntityDialog,
|
|
179
|
+
{
|
|
180
|
+
entity,
|
|
181
|
+
initialTab: selectedInspectEntityDialogTab || void 0,
|
|
182
|
+
open: inspectDialogOpen,
|
|
183
|
+
onClose: closeInspectEntityDialog,
|
|
184
|
+
onSelect: setInspectEntityDialogTab
|
|
185
|
+
}
|
|
186
|
+
),
|
|
187
|
+
/* @__PURE__ */ jsx(
|
|
188
|
+
UnregisterEntityDialog,
|
|
189
|
+
{
|
|
190
|
+
entity,
|
|
191
|
+
open: confirmationDialogOpen,
|
|
192
|
+
onClose: closeUnregisterEntityDialog,
|
|
193
|
+
onConfirm: cleanUpAfterUnregisterConfirmation
|
|
194
|
+
}
|
|
195
|
+
)
|
|
196
|
+
] })
|
|
197
|
+
}
|
|
183
198
|
);
|
|
184
199
|
}
|
|
185
200
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"EntityHeader.esm.js","sources":["../../../../src/alpha/components/EntityHeader/EntityHeader.tsx"],"sourcesContent":["/*\n * Copyright 2025 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, {\n useState,\n useCallback,\n useEffect,\n ComponentProps,\n ReactNode,\n} from 'react';\nimport { useNavigate, useLocation, useSearchParams } from 'react-router-dom';\nimport useAsync from 'react-use/esm/useAsync';\n\nimport { makeStyles } from '@material-ui/core/styles';\nimport Box from '@material-ui/core/Box';\n\nimport { Header, Breadcrumbs } from '@backstage/core-components';\nimport {\n useApi,\n useRouteRef,\n useRouteRefParams,\n} from '@backstage/core-plugin-api';\nimport { IconComponent } from '@backstage/frontend-plugin-api';\n\nimport {\n Entity,\n EntityRelation,\n DEFAULT_NAMESPACE,\n} from '@backstage/catalog-model';\n\nimport {\n useAsyncEntity,\n entityRouteRef,\n catalogApiRef,\n EntityRefLink,\n InspectEntityDialog,\n UnregisterEntityDialog,\n EntityDisplayName,\n FavoriteEntity,\n} from '@backstage/plugin-catalog-react';\n\nimport { EntityLabels } from '../EntityLabels';\nimport { EntityContextMenu } from '../../../components/EntityContextMenu';\nimport { rootRouteRef, unregisterRedirectRouteRef } from '../../../routes';\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\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 findParentRelation(\n entityRelations: EntityRelation[] = [],\n relationTypes: string[] = [],\n) {\n for (const type of relationTypes) {\n const foundRelation = entityRelations.find(\n relation => relation.type === type,\n );\n if (foundRelation) {\n return foundRelation; // Return the first found relation and stop\n }\n }\n return null;\n}\n\nconst useStyles = makeStyles(theme => ({\n breadcrumbs: {\n color: theme.page.fontColor,\n fontSize: theme.typography.caption.fontSize,\n textTransform: 'uppercase',\n marginTop: theme.spacing(1),\n opacity: 0.8,\n '& span ': {\n color: theme.page.fontColor,\n textDecoration: 'underline',\n textUnderlineOffset: '3px',\n },\n },\n}));\n\nfunction EntityHeaderTitle() {\n const { entity } = useAsyncEntity();\n const { kind, namespace, name } = useRouteRefParams(entityRouteRef);\n const { headerTitle: title } = headerProps(kind, namespace, name, entity);\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 {entity ? <EntityDisplayName entityRef={entity} hideIcon /> : title}\n </Box>\n {entity && <FavoriteEntity entity={entity} />}\n </Box>\n );\n}\n\nfunction EntityHeaderSubtitle(props: { parentEntityRelations?: string[] }) {\n const { parentEntityRelations } = props;\n const classes = useStyles();\n const { entity } = useAsyncEntity();\n const { name } = useRouteRefParams(entityRouteRef);\n const parentEntity = findParentRelation(\n entity?.relations ?? [],\n parentEntityRelations ?? [],\n );\n\n const catalogApi = useApi(catalogApiRef);\n\n const { value: ancestorEntity } = useAsync(async () => {\n if (parentEntity) {\n return findParentRelation(\n (await catalogApi.getEntityByRef(parentEntity?.targetRef))?.relations,\n parentEntityRelations,\n );\n }\n return null;\n }, [parentEntity, catalogApi]);\n\n return parentEntity ? (\n <Breadcrumbs separator=\">\" className={classes.breadcrumbs}>\n {ancestorEntity && (\n <EntityRefLink entityRef={ancestorEntity.targetRef} disableTooltip />\n )}\n <EntityRefLink entityRef={parentEntity.targetRef} disableTooltip />\n {name}\n </Breadcrumbs>\n ) : null;\n}\n\n/** @alpha */\nexport function EntityHeader(props: {\n // NOTE(freben): Intentionally not exported at this point, since it's part of\n // the unstable extra context menu items concept below\n UNSTABLE_extraContextMenuItems?: {\n title: string;\n Icon: IconComponent;\n onClick: () => void;\n }[];\n // NOTE(blam): Intentionally not exported at this point, since it's part of\n // unstable context menu option, eg: disable the unregister entity menu\n UNSTABLE_contextMenuOptions?: {\n disableUnregister: boolean | 'visible' | 'hidden' | 'disable';\n };\n /**\n * An array of relation types used to determine the parent entities in the hierarchy.\n * These relations are prioritized in the order provided, allowing for flexible\n * navigation through entity relationships.\n *\n * For example, use relation types like `[\"partOf\", \"memberOf\", \"ownedBy\"]` to define how the entity is related to\n * its parents in the Entity Catalog.\n *\n * It adds breadcrumbs in the Entity page to enhance user navigation and context awareness.\n */\n parentEntityRelations?: string[];\n title?: ReactNode;\n subtitle?: ReactNode;\n}) {\n const {\n UNSTABLE_extraContextMenuItems,\n UNSTABLE_contextMenuOptions,\n parentEntityRelations,\n title,\n subtitle,\n } = props;\n const { entity } = useAsyncEntity();\n const { kind, namespace, name } = useRouteRefParams(entityRouteRef);\n const { headerTitle: entityFallbackText, headerType: type } = headerProps(\n kind,\n namespace,\n name,\n entity,\n );\n\n const location = useLocation();\n const navigate = useNavigate();\n const catalogRoute = useRouteRef(rootRouteRef);\n const unregisterRedirectRoute = useRouteRef(unregisterRedirectRouteRef);\n\n const [confirmationDialogOpen, setConfirmationDialogOpen] = useState(false);\n\n const openUnregisterEntityDialog = useCallback(\n () => setConfirmationDialogOpen(true),\n [setConfirmationDialogOpen],\n );\n\n const closeUnregisterEntityDialog = useCallback(\n () => setConfirmationDialogOpen(false),\n [setConfirmationDialogOpen],\n );\n\n const cleanUpAfterUnregisterConfirmation = useCallback(async () => {\n setConfirmationDialogOpen(false);\n navigate(\n unregisterRedirectRoute ? unregisterRedirectRoute() : catalogRoute(),\n );\n }, [\n navigate,\n catalogRoute,\n unregisterRedirectRoute,\n setConfirmationDialogOpen,\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 // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [location.pathname]);\n\n const [searchParams, setSearchParams] = useSearchParams();\n const selectedInspectEntityDialogTab = searchParams.get('inspect');\n\n const setInspectEntityDialogTab = useCallback(\n (newTab: string) => setSearchParams(`inspect=${newTab}`),\n [setSearchParams],\n );\n\n const openInspectEntityDialog = useCallback(\n () => setSearchParams('inspect'),\n [setSearchParams],\n );\n\n const closeInspectEntityDialog = useCallback(\n () => setSearchParams(),\n [setSearchParams],\n );\n\n const inspectDialogOpen = typeof selectedInspectEntityDialogTab === 'string';\n\n return (\n <Header\n pageTitleOverride={entityFallbackText}\n type={type}\n title={title ?? <EntityHeaderTitle />}\n subtitle={\n subtitle ?? (\n <EntityHeaderSubtitle parentEntityRelations={parentEntityRelations} />\n )\n }\n >\n {entity && (\n <>\n <EntityLabels entity={entity} />\n <EntityContextMenu\n UNSTABLE_extraContextMenuItems={UNSTABLE_extraContextMenuItems}\n UNSTABLE_contextMenuOptions={UNSTABLE_contextMenuOptions}\n onInspectEntity={openInspectEntityDialog}\n onUnregisterEntity={openUnregisterEntityDialog}\n />\n <InspectEntityDialog\n entity={entity!}\n initialTab={\n (selectedInspectEntityDialogTab as ComponentProps<\n typeof InspectEntityDialog\n >['initialTab']) || undefined\n }\n open={inspectDialogOpen}\n onClose={closeInspectEntityDialog}\n onSelect={setInspectEntityDialogTab}\n />\n <UnregisterEntityDialog\n entity={entity!}\n open={confirmationDialogOpen}\n onClose={closeUnregisterEntityDialog}\n onConfirm={cleanUpAfterUnregisterConfirmation}\n />\n </>\n )}\n </Header>\n );\n}\n"],"names":[],"mappings":";;;;;;;;;;;;;AA0DA,SAAS,WACP,CAAA,SAAA,EACA,cACA,EAAA,SAAA,EACA,MAC6C,EAAA;AAC7C,EAAM,MAAA,IAAA,GAAO,SAAa,IAAA,MAAA,EAAQ,IAAQ,IAAA,EAAA;AAC1C,EAAA,MAAM,SAAY,GAAA,cAAA,IAAkB,MAAQ,EAAA,QAAA,CAAS,SAAa,IAAA,EAAA;AAClE,EAAA,MAAM,OACJ,MAAQ,EAAA,QAAA,CAAS,SAAS,SAAa,IAAA,MAAA,EAAQ,SAAS,IAAQ,IAAA,EAAA;AAElE,EAAO,OAAA;AAAA,IACL,WAAA,EAAa,CAAG,EAAA,IAAI,CAClB,EAAA,SAAA,IAAa,cAAc,iBAAoB,GAAA,CAAA,IAAA,EAAO,SAAS,CAAA,CAAA,GAAK,EACtE,CAAA,CAAA;AAAA,IACA,aAAa,MAAM;AACjB,MAAI,IAAA,CAAA,GAAI,IAAK,CAAA,iBAAA,CAAkB,OAAO,CAAA;AACtC,MAAA,IAAI,MAAU,IAAA,MAAA,CAAO,IAAQ,IAAA,MAAA,IAAU,OAAO,IAAM,EAAA;AAClD,QAAK,CAAA,IAAA,UAAA;AACL,QAAA,CAAA,IAAM,MAAO,CAAA,IAAA,CAA0B,IAAK,CAAA,iBAAA,CAAkB,OAAO,CAAA;AAAA;AAEvE,MAAO,OAAA,CAAA;AAAA,KACN;AAAA,GACL;AACF;AAEA,SAAS,mBACP,eAAoC,GAAA,EACpC,EAAA,aAAA,GAA0B,EAC1B,EAAA;AACA,EAAA,KAAA,MAAW,QAAQ,aAAe,EAAA;AAChC,IAAA,MAAM,gBAAgB,eAAgB,CAAA,IAAA;AAAA,MACpC,CAAA,QAAA,KAAY,SAAS,IAAS,KAAA;AAAA,KAChC;AACA,IAAA,IAAI,aAAe,EAAA;AACjB,MAAO,OAAA,aAAA;AAAA;AACT;AAEF,EAAO,OAAA,IAAA;AACT;AAEA,MAAM,SAAA,GAAY,WAAW,CAAU,KAAA,MAAA;AAAA,EACrC,WAAa,EAAA;AAAA,IACX,KAAA,EAAO,MAAM,IAAK,CAAA,SAAA;AAAA,IAClB,QAAA,EAAU,KAAM,CAAA,UAAA,CAAW,OAAQ,CAAA,QAAA;AAAA,IACnC,aAAe,EAAA,WAAA;AAAA,IACf,SAAA,EAAW,KAAM,CAAA,OAAA,CAAQ,CAAC,CAAA;AAAA,IAC1B,OAAS,EAAA,GAAA;AAAA,IACT,SAAW,EAAA;AAAA,MACT,KAAA,EAAO,MAAM,IAAK,CAAA,SAAA;AAAA,MAClB,cAAgB,EAAA,WAAA;AAAA,MAChB,mBAAqB,EAAA;AAAA;AACvB;AAEJ,CAAE,CAAA,CAAA;AAEF,SAAS,iBAAoB,GAAA;AAC3B,EAAM,MAAA,EAAE,MAAO,EAAA,GAAI,cAAe,EAAA;AAClC,EAAA,MAAM,EAAE,IAAM,EAAA,SAAA,EAAW,IAAK,EAAA,GAAI,kBAAkB,cAAc,CAAA;AAClE,EAAM,MAAA,EAAE,aAAa,KAAM,EAAA,GAAI,YAAY,IAAM,EAAA,SAAA,EAAW,MAAM,MAAM,CAAA;AACxE,EACE,uBAAA,KAAA,CAAA,aAAA,CAAC,OAAI,OAAQ,EAAA,aAAA,EAAc,YAAW,QAAS,EAAA,MAAA,EAAO,KAAM,EAAA,QAAA,EAAS,MACnE,EAAA,kBAAA,KAAA,CAAA,aAAA;AAAA,IAAC,GAAA;AAAA,IAAA;AAAA,MACC,SAAU,EAAA,MAAA;AAAA,MACV,YAAa,EAAA,UAAA;AAAA,MACb,UAAW,EAAA,QAAA;AAAA,MACX,QAAS,EAAA;AAAA,KAAA;AAAA,IAER,yBAAU,KAAA,CAAA,aAAA,CAAA,iBAAA,EAAA,EAAkB,WAAW,MAAQ,EAAA,QAAA,EAAQ,MAAC,CAAK,GAAA;AAAA,GAE/D,EAAA,MAAA,oBAAW,KAAA,CAAA,aAAA,CAAA,cAAA,EAAA,EAAe,QAAgB,CAC7C,CAAA;AAEJ;AAEA,SAAS,qBAAqB,KAA6C,EAAA;AACzE,EAAM,MAAA,EAAE,uBAA0B,GAAA,KAAA;AAClC,EAAA,MAAM,UAAU,SAAU,EAAA;AAC1B,EAAM,MAAA,EAAE,MAAO,EAAA,GAAI,cAAe,EAAA;AAClC,EAAA,MAAM,EAAE,IAAA,EAAS,GAAA,iBAAA,CAAkB,cAAc,CAAA;AACjD,EAAA,MAAM,YAAe,GAAA,kBAAA;AAAA,IACnB,MAAA,EAAQ,aAAa,EAAC;AAAA,IACtB,yBAAyB;AAAC,GAC5B;AAEA,EAAM,MAAA,UAAA,GAAa,OAAO,aAAa,CAAA;AAEvC,EAAA,MAAM,EAAE,KAAA,EAAO,cAAe,EAAA,GAAI,SAAS,YAAY;AACrD,IAAA,IAAI,YAAc,EAAA;AAChB,MAAO,OAAA,kBAAA;AAAA,QAAA,CACJ,MAAM,UAAA,CAAW,cAAe,CAAA,YAAA,EAAc,SAAS,CAAI,GAAA,SAAA;AAAA,QAC5D;AAAA,OACF;AAAA;AAEF,IAAO,OAAA,IAAA;AAAA,GACN,EAAA,CAAC,YAAc,EAAA,UAAU,CAAC,CAAA;AAE7B,EAAO,OAAA,YAAA,mBACJ,KAAA,CAAA,aAAA,CAAA,WAAA,EAAA,EAAY,SAAU,EAAA,GAAA,EAAI,SAAW,EAAA,OAAA,CAAQ,WAC3C,EAAA,EAAA,cAAA,oBACE,KAAA,CAAA,aAAA,CAAA,aAAA,EAAA,EAAc,SAAW,EAAA,cAAA,CAAe,WAAW,cAAc,EAAA,IAAA,EAAC,CAErE,kBAAA,KAAA,CAAA,aAAA,CAAC,aAAc,EAAA,EAAA,SAAA,EAAW,YAAa,CAAA,SAAA,EAAW,cAAc,EAAA,IAAA,EAAC,CAChE,EAAA,IACH,CACE,GAAA,IAAA;AACN;AAGO,SAAS,aAAa,KA0B1B,EAAA;AACD,EAAM,MAAA;AAAA,IACJ,8BAAA;AAAA,IACA,2BAAA;AAAA,IACA,qBAAA;AAAA,IACA,KAAA;AAAA,IACA;AAAA,GACE,GAAA,KAAA;AACJ,EAAM,MAAA,EAAE,MAAO,EAAA,GAAI,cAAe,EAAA;AAClC,EAAA,MAAM,EAAE,IAAM,EAAA,SAAA,EAAW,IAAK,EAAA,GAAI,kBAAkB,cAAc,CAAA;AAClE,EAAA,MAAM,EAAE,WAAA,EAAa,kBAAoB,EAAA,UAAA,EAAY,MAAS,GAAA,WAAA;AAAA,IAC5D,IAAA;AAAA,IACA,SAAA;AAAA,IACA,IAAA;AAAA,IACA;AAAA,GACF;AAEA,EAAA,MAAM,WAAW,WAAY,EAAA;AAC7B,EAAA,MAAM,WAAW,WAAY,EAAA;AAC7B,EAAM,MAAA,YAAA,GAAe,YAAY,YAAY,CAAA;AAC7C,EAAM,MAAA,uBAAA,GAA0B,YAAY,0BAA0B,CAAA;AAEtE,EAAA,MAAM,CAAC,sBAAA,EAAwB,yBAAyB,CAAA,GAAI,SAAS,KAAK,CAAA;AAE1E,EAAA,MAAM,0BAA6B,GAAA,WAAA;AAAA,IACjC,MAAM,0BAA0B,IAAI,CAAA;AAAA,IACpC,CAAC,yBAAyB;AAAA,GAC5B;AAEA,EAAA,MAAM,2BAA8B,GAAA,WAAA;AAAA,IAClC,MAAM,0BAA0B,KAAK,CAAA;AAAA,IACrC,CAAC,yBAAyB;AAAA,GAC5B;AAEA,EAAM,MAAA,kCAAA,GAAqC,YAAY,YAAY;AACjE,IAAA,yBAAA,CAA0B,KAAK,CAAA;AAC/B,IAAA,QAAA;AAAA,MACE,uBAAA,GAA0B,uBAAwB,EAAA,GAAI,YAAa;AAAA,KACrE;AAAA,GACC,EAAA;AAAA,IACD,QAAA;AAAA,IACA,YAAA;AAAA,IACA,uBAAA;AAAA,IACA;AAAA,GACD,CAAA;AAID,EAAA,SAAA,CAAU,MAAM;AACd,IAAA,yBAAA,CAA0B,KAAK,CAAA;AAAA,GAE9B,EAAA,CAAC,QAAS,CAAA,QAAQ,CAAC,CAAA;AAEtB,EAAA,MAAM,CAAC,YAAA,EAAc,eAAe,CAAA,GAAI,eAAgB,EAAA;AACxD,EAAM,MAAA,8BAAA,GAAiC,YAAa,CAAA,GAAA,CAAI,SAAS,CAAA;AAEjE,EAAA,MAAM,yBAA4B,GAAA,WAAA;AAAA,IAChC,CAAC,MAAA,KAAmB,eAAgB,CAAA,CAAA,QAAA,EAAW,MAAM,CAAE,CAAA,CAAA;AAAA,IACvD,CAAC,eAAe;AAAA,GAClB;AAEA,EAAA,MAAM,uBAA0B,GAAA,WAAA;AAAA,IAC9B,MAAM,gBAAgB,SAAS,CAAA;AAAA,IAC/B,CAAC,eAAe;AAAA,GAClB;AAEA,EAAA,MAAM,wBAA2B,GAAA,WAAA;AAAA,IAC/B,MAAM,eAAgB,EAAA;AAAA,IACtB,CAAC,eAAe;AAAA,GAClB;AAEA,EAAM,MAAA,iBAAA,GAAoB,OAAO,8BAAmC,KAAA,QAAA;AAEpE,EACE,uBAAA,KAAA,CAAA,aAAA;AAAA,IAAC,MAAA;AAAA,IAAA;AAAA,MACC,iBAAmB,EAAA,kBAAA;AAAA,MACnB,IAAA;AAAA,MACA,KAAA,EAAO,KAAS,oBAAA,KAAA,CAAA,aAAA,CAAC,iBAAkB,EAAA,IAAA,CAAA;AAAA,MACnC,QACE,EAAA,QAAA,oBACG,KAAA,CAAA,aAAA,CAAA,oBAAA,EAAA,EAAqB,qBAA8C,EAAA;AAAA,KAAA;AAAA,IAIvE,MACC,oBAAA,KAAA,CAAA,aAAA,CAAA,KAAA,CAAA,QAAA,EAAA,IAAA,kBACG,KAAA,CAAA,aAAA,CAAA,YAAA,EAAA,EAAa,QAAgB,CAC9B,kBAAA,KAAA,CAAA,aAAA;AAAA,MAAC,iBAAA;AAAA,MAAA;AAAA,QACC,8BAAA;AAAA,QACA,2BAAA;AAAA,QACA,eAAiB,EAAA,uBAAA;AAAA,QACjB,kBAAoB,EAAA;AAAA;AAAA,KAEtB,kBAAA,KAAA,CAAA,aAAA;AAAA,MAAC,mBAAA;AAAA,MAAA;AAAA,QACC,MAAA;AAAA,QACA,YACG,8BAEmB,IAAA,KAAA,CAAA;AAAA,QAEtB,IAAM,EAAA,iBAAA;AAAA,QACN,OAAS,EAAA,wBAAA;AAAA,QACT,QAAU,EAAA;AAAA;AAAA,KAEZ,kBAAA,KAAA,CAAA,aAAA;AAAA,MAAC,sBAAA;AAAA,MAAA;AAAA,QACC,MAAA;AAAA,QACA,IAAM,EAAA,sBAAA;AAAA,QACN,OAAS,EAAA,2BAAA;AAAA,QACT,SAAW,EAAA;AAAA;AAAA,KAEf;AAAA,GAEJ;AAEJ;;;;"}
|
|
1
|
+
{"version":3,"file":"EntityHeader.esm.js","sources":["../../../../src/alpha/components/EntityHeader/EntityHeader.tsx"],"sourcesContent":["/*\n * Copyright 2025 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 useState,\n useCallback,\n useEffect,\n ComponentProps,\n ReactNode,\n} from 'react';\nimport { useNavigate, useLocation, useSearchParams } from 'react-router-dom';\nimport useAsync from 'react-use/esm/useAsync';\n\nimport { makeStyles } from '@material-ui/core/styles';\nimport Box from '@material-ui/core/Box';\n\nimport { Header, Breadcrumbs } from '@backstage/core-components';\nimport {\n useApi,\n useRouteRef,\n useRouteRefParams,\n} from '@backstage/core-plugin-api';\nimport { IconComponent } from '@backstage/frontend-plugin-api';\n\nimport {\n Entity,\n EntityRelation,\n DEFAULT_NAMESPACE,\n} from '@backstage/catalog-model';\n\nimport {\n useAsyncEntity,\n entityRouteRef,\n catalogApiRef,\n EntityRefLink,\n InspectEntityDialog,\n UnregisterEntityDialog,\n EntityDisplayName,\n FavoriteEntity,\n} from '@backstage/plugin-catalog-react';\n\nimport { EntityLabels } from '../EntityLabels';\nimport { EntityContextMenu } from '../../../components/EntityContextMenu';\nimport { rootRouteRef, unregisterRedirectRouteRef } from '../../../routes';\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\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 findParentRelation(\n entityRelations: EntityRelation[] = [],\n relationTypes: string[] = [],\n) {\n for (const type of relationTypes) {\n const foundRelation = entityRelations.find(\n relation => relation.type === type,\n );\n if (foundRelation) {\n return foundRelation; // Return the first found relation and stop\n }\n }\n return null;\n}\n\nconst useStyles = makeStyles(theme => ({\n breadcrumbs: {\n color: theme.page.fontColor,\n fontSize: theme.typography.caption.fontSize,\n textTransform: 'uppercase',\n marginTop: theme.spacing(1),\n opacity: 0.8,\n '& span ': {\n color: theme.page.fontColor,\n textDecoration: 'underline',\n textUnderlineOffset: '3px',\n },\n },\n}));\n\nfunction EntityHeaderTitle() {\n const { entity } = useAsyncEntity();\n const { kind, namespace, name } = useRouteRefParams(entityRouteRef);\n const { headerTitle: title } = headerProps(kind, namespace, name, entity);\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 {entity ? <EntityDisplayName entityRef={entity} hideIcon /> : title}\n </Box>\n {entity && <FavoriteEntity entity={entity} />}\n </Box>\n );\n}\n\nfunction EntityHeaderSubtitle(props: { parentEntityRelations?: string[] }) {\n const { parentEntityRelations } = props;\n const classes = useStyles();\n const { entity } = useAsyncEntity();\n const { name } = useRouteRefParams(entityRouteRef);\n const parentEntity = findParentRelation(\n entity?.relations ?? [],\n parentEntityRelations ?? [],\n );\n\n const catalogApi = useApi(catalogApiRef);\n\n const { value: ancestorEntity } = useAsync(async () => {\n if (parentEntity) {\n return findParentRelation(\n (await catalogApi.getEntityByRef(parentEntity?.targetRef))?.relations,\n parentEntityRelations,\n );\n }\n return null;\n }, [parentEntity, catalogApi]);\n\n return parentEntity ? (\n <Breadcrumbs separator=\">\" className={classes.breadcrumbs}>\n {ancestorEntity && (\n <EntityRefLink entityRef={ancestorEntity.targetRef} disableTooltip />\n )}\n <EntityRefLink entityRef={parentEntity.targetRef} disableTooltip />\n {name}\n </Breadcrumbs>\n ) : null;\n}\n\n/** @alpha */\nexport function EntityHeader(props: {\n // NOTE(freben): Intentionally not exported at this point, since it's part of\n // the unstable extra context menu items concept below\n UNSTABLE_extraContextMenuItems?: {\n title: string;\n Icon: IconComponent;\n onClick: () => void;\n }[];\n // NOTE(blam): Intentionally not exported at this point, since it's part of\n // unstable context menu option, eg: disable the unregister entity menu\n UNSTABLE_contextMenuOptions?: {\n disableUnregister: boolean | 'visible' | 'hidden' | 'disable';\n };\n contextMenuItems?: React.JSX.Element[];\n /**\n * An array of relation types used to determine the parent entities in the hierarchy.\n * These relations are prioritized in the order provided, allowing for flexible\n * navigation through entity relationships.\n *\n * For example, use relation types like `[\"partOf\", \"memberOf\", \"ownedBy\"]` to define how the entity is related to\n * its parents in the Entity Catalog.\n *\n * It adds breadcrumbs in the Entity page to enhance user navigation and context awareness.\n */\n parentEntityRelations?: string[];\n title?: ReactNode;\n subtitle?: ReactNode;\n}) {\n const {\n UNSTABLE_extraContextMenuItems,\n UNSTABLE_contextMenuOptions,\n contextMenuItems,\n parentEntityRelations,\n title,\n subtitle,\n } = props;\n const { entity } = useAsyncEntity();\n const { kind, namespace, name } = useRouteRefParams(entityRouteRef);\n const { headerTitle: entityFallbackText, headerType: type } = headerProps(\n kind,\n namespace,\n name,\n entity,\n );\n\n const location = useLocation();\n const navigate = useNavigate();\n const catalogRoute = useRouteRef(rootRouteRef);\n const unregisterRedirectRoute = useRouteRef(unregisterRedirectRouteRef);\n\n const [confirmationDialogOpen, setConfirmationDialogOpen] = useState(false);\n\n const openUnregisterEntityDialog = useCallback(\n () => setConfirmationDialogOpen(true),\n [setConfirmationDialogOpen],\n );\n\n const closeUnregisterEntityDialog = useCallback(\n () => setConfirmationDialogOpen(false),\n [setConfirmationDialogOpen],\n );\n\n const cleanUpAfterUnregisterConfirmation = useCallback(async () => {\n setConfirmationDialogOpen(false);\n navigate(\n unregisterRedirectRoute ? unregisterRedirectRoute() : catalogRoute(),\n );\n }, [\n navigate,\n catalogRoute,\n unregisterRedirectRoute,\n setConfirmationDialogOpen,\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 // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [location.pathname]);\n\n const [searchParams, setSearchParams] = useSearchParams();\n const selectedInspectEntityDialogTab = searchParams.get('inspect');\n\n const setInspectEntityDialogTab = useCallback(\n (newTab: string) => setSearchParams(`inspect=${newTab}`),\n [setSearchParams],\n );\n\n const openInspectEntityDialog = useCallback(\n () => setSearchParams('inspect'),\n [setSearchParams],\n );\n\n const closeInspectEntityDialog = useCallback(\n () => setSearchParams(),\n [setSearchParams],\n );\n\n const inspectDialogOpen = typeof selectedInspectEntityDialogTab === 'string';\n\n return (\n <Header\n pageTitleOverride={entityFallbackText}\n type={type}\n title={title ?? <EntityHeaderTitle />}\n subtitle={\n subtitle ?? (\n <EntityHeaderSubtitle parentEntityRelations={parentEntityRelations} />\n )\n }\n >\n {entity && (\n <>\n <EntityLabels entity={entity} />\n <EntityContextMenu\n UNSTABLE_extraContextMenuItems={UNSTABLE_extraContextMenuItems}\n UNSTABLE_contextMenuOptions={UNSTABLE_contextMenuOptions}\n contextMenuItems={contextMenuItems}\n onInspectEntity={openInspectEntityDialog}\n onUnregisterEntity={openUnregisterEntityDialog}\n />\n <InspectEntityDialog\n entity={entity!}\n initialTab={\n (selectedInspectEntityDialogTab as ComponentProps<\n typeof InspectEntityDialog\n >['initialTab']) || undefined\n }\n open={inspectDialogOpen}\n onClose={closeInspectEntityDialog}\n onSelect={setInspectEntityDialogTab}\n />\n <UnregisterEntityDialog\n entity={entity!}\n open={confirmationDialogOpen}\n onClose={closeUnregisterEntityDialog}\n onConfirm={cleanUpAfterUnregisterConfirmation}\n />\n </>\n )}\n </Header>\n );\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { jsxs, Fragment, jsx } from 'react/jsx-runtime';
|
|
2
2
|
import { HeaderLabel } from '@backstage/core-components';
|
|
3
3
|
import { RELATION_OWNED_BY } from '@backstage/catalog-model';
|
|
4
4
|
import { getEntityRelations, EntityRefLinks } from '@backstage/plugin-catalog-react';
|
|
@@ -9,27 +9,30 @@ function EntityLabels(props) {
|
|
|
9
9
|
const { entity } = props;
|
|
10
10
|
const ownedByRelations = getEntityRelations(entity, RELATION_OWNED_BY);
|
|
11
11
|
const { t } = useTranslationRef(catalogTranslationRef);
|
|
12
|
-
return /* @__PURE__ */
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
12
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
13
|
+
ownedByRelations.length > 0 && /* @__PURE__ */ jsx(
|
|
14
|
+
HeaderLabel,
|
|
15
|
+
{
|
|
16
|
+
label: t("entityLabels.ownerLabel"),
|
|
17
|
+
contentTypograpyRootComponent: "p",
|
|
18
|
+
value: /* @__PURE__ */ jsx(
|
|
19
|
+
EntityRefLinks,
|
|
20
|
+
{
|
|
21
|
+
entityRefs: ownedByRelations,
|
|
22
|
+
defaultKind: "Group",
|
|
23
|
+
color: "inherit"
|
|
24
|
+
}
|
|
25
|
+
)
|
|
26
|
+
}
|
|
27
|
+
),
|
|
28
|
+
entity.spec?.lifecycle && /* @__PURE__ */ jsx(
|
|
29
|
+
HeaderLabel,
|
|
30
|
+
{
|
|
31
|
+
label: t("entityLabels.lifecycleLabel"),
|
|
32
|
+
value: entity.spec.lifecycle?.toString()
|
|
33
|
+
}
|
|
34
|
+
)
|
|
35
|
+
] });
|
|
33
36
|
}
|
|
34
37
|
|
|
35
38
|
export { EntityLabels };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"EntityLabels.esm.js","sources":["../../../../src/alpha/components/EntityLabels/EntityLabels.tsx"],"sourcesContent":["/*\n * Copyright 2025 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
|
|
1
|
+
{"version":3,"file":"EntityLabels.esm.js","sources":["../../../../src/alpha/components/EntityLabels/EntityLabels.tsx"],"sourcesContent":["/*\n * Copyright 2025 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 { HeaderLabel } from '@backstage/core-components';\nimport { Entity, RELATION_OWNED_BY } from '@backstage/catalog-model';\nimport {\n EntityRefLinks,\n getEntityRelations,\n} from '@backstage/plugin-catalog-react';\nimport { useTranslationRef } from '@backstage/core-plugin-api/alpha';\nimport { catalogTranslationRef } from '../../translation';\n\ntype EntityLabelsProps = {\n entity: Entity;\n};\n\nexport function EntityLabels(props: EntityLabelsProps) {\n const { entity } = props;\n const ownedByRelations = getEntityRelations(entity, RELATION_OWNED_BY);\n const { t } = useTranslationRef(catalogTranslationRef);\n return (\n <>\n {ownedByRelations.length > 0 && (\n <HeaderLabel\n label={t('entityLabels.ownerLabel')}\n contentTypograpyRootComponent=\"p\"\n value={\n <EntityRefLinks\n entityRefs={ownedByRelations}\n defaultKind=\"Group\"\n color=\"inherit\"\n />\n }\n />\n )}\n {entity.spec?.lifecycle && (\n <HeaderLabel\n label={t('entityLabels.lifecycleLabel')}\n value={entity.spec.lifecycle?.toString()}\n />\n )}\n </>\n );\n}\n"],"names":[],"mappings":";;;;;;;AA6BO,SAAS,aAAa,KAA0B,EAAA;AACrD,EAAM,MAAA,EAAE,QAAW,GAAA,KAAA;AACnB,EAAM,MAAA,gBAAA,GAAmB,kBAAmB,CAAA,MAAA,EAAQ,iBAAiB,CAAA;AACrE,EAAA,MAAM,EAAE,CAAA,EAAM,GAAA,iBAAA,CAAkB,qBAAqB,CAAA;AACrD,EAAA,uBAEK,IAAA,CAAA,QAAA,EAAA,EAAA,QAAA,EAAA;AAAA,IAAA,gBAAA,CAAiB,SAAS,CACzB,oBAAA,GAAA;AAAA,MAAC,WAAA;AAAA,MAAA;AAAA,QACC,KAAA,EAAO,EAAE,yBAAyB,CAAA;AAAA,QAClC,6BAA8B,EAAA,GAAA;AAAA,QAC9B,KACE,kBAAA,GAAA;AAAA,UAAC,cAAA;AAAA,UAAA;AAAA,YACC,UAAY,EAAA,gBAAA;AAAA,YACZ,WAAY,EAAA,OAAA;AAAA,YACZ,KAAM,EAAA;AAAA;AAAA;AACR;AAAA,KAEJ;AAAA,IAED,MAAA,CAAO,MAAM,SACZ,oBAAA,GAAA;AAAA,MAAC,WAAA;AAAA,MAAA;AAAA,QACC,KAAA,EAAO,EAAE,6BAA6B,CAAA;AAAA,QACtC,KAAO,EAAA,MAAA,CAAO,IAAK,CAAA,SAAA,EAAW,QAAS;AAAA;AAAA;AACzC,GAEJ,EAAA,CAAA;AAEJ;;;;"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
2
2
|
import Alert from '@material-ui/lab/Alert';
|
|
3
3
|
import { attachComponentData, useRouteRefParams, useElementFilter } from '@backstage/core-plugin-api';
|
|
4
4
|
import { useTranslationRef } from '@backstage/core-plugin-api/alpha';
|
|
@@ -16,6 +16,7 @@ const EntityLayout = (props) => {
|
|
|
16
16
|
const {
|
|
17
17
|
UNSTABLE_extraContextMenuItems,
|
|
18
18
|
UNSTABLE_contextMenuOptions,
|
|
19
|
+
contextMenuItems,
|
|
19
20
|
children,
|
|
20
21
|
header,
|
|
21
22
|
NotFoundComponent,
|
|
@@ -47,14 +48,28 @@ const EntityLayout = (props) => {
|
|
|
47
48
|
[entity]
|
|
48
49
|
);
|
|
49
50
|
const { t } = useTranslationRef(catalogTranslationRef);
|
|
50
|
-
return /* @__PURE__ */
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
51
|
+
return /* @__PURE__ */ jsxs(Page, { themeId: entity?.spec?.type?.toString() ?? "home", children: [
|
|
52
|
+
header ?? /* @__PURE__ */ jsx(
|
|
53
|
+
EntityHeader,
|
|
54
|
+
{
|
|
55
|
+
parentEntityRelations,
|
|
56
|
+
UNSTABLE_contextMenuOptions,
|
|
57
|
+
UNSTABLE_extraContextMenuItems,
|
|
58
|
+
contextMenuItems
|
|
59
|
+
}
|
|
60
|
+
),
|
|
61
|
+
loading && /* @__PURE__ */ jsx(Progress, {}),
|
|
62
|
+
entity && /* @__PURE__ */ jsx(EntityTabs, { routes }),
|
|
63
|
+
error && /* @__PURE__ */ jsx(Content, { children: /* @__PURE__ */ jsx(Alert, { severity: "error", children: error.toString() }) }),
|
|
64
|
+
!loading && !error && !entity && /* @__PURE__ */ jsx(Content, { children: NotFoundComponent ? NotFoundComponent : /* @__PURE__ */ jsxs(WarningPanel, { title: t("entityLabels.warningPanelTitle"), children: [
|
|
65
|
+
"There is no ",
|
|
66
|
+
kind,
|
|
67
|
+
" with the requested",
|
|
68
|
+
" ",
|
|
69
|
+
/* @__PURE__ */ jsx(Link, { to: "https://backstage.io/docs/features/software-catalog/references", children: "kind, namespace, and name" }),
|
|
70
|
+
"."
|
|
71
|
+
] }) })
|
|
72
|
+
] });
|
|
58
73
|
};
|
|
59
74
|
EntityLayout.Route = Route;
|
|
60
75
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"EntityLayout.esm.js","sources":["../../../../src/alpha/components/EntityLayout/EntityLayout.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
|
|
1
|
+
{"version":3,"file":"EntityLayout.esm.js","sources":["../../../../src/alpha/components/EntityLayout/EntityLayout.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 { ComponentProps, ReactNode } from 'react';\n\nimport Alert from '@material-ui/lab/Alert';\n\nimport {\n attachComponentData,\n useElementFilter,\n useRouteRefParams,\n} from '@backstage/core-plugin-api';\nimport { useTranslationRef } from '@backstage/core-plugin-api/alpha';\nimport {\n Content,\n Link,\n Page,\n Progress,\n WarningPanel,\n} from '@backstage/core-components';\nimport { Entity } from '@backstage/catalog-model';\nimport {\n entityRouteRef,\n useAsyncEntity,\n} from '@backstage/plugin-catalog-react';\n\nimport { catalogTranslationRef } from '../../translation';\nimport { EntityHeader } from '../EntityHeader';\nimport { EntityTabs } from '../EntityTabs';\n\nexport type EntityLayoutRouteProps = {\n path: string;\n title: string;\n group: string;\n children: JSX.Element;\n if?: (entity: Entity) => boolean;\n};\n\nconst dataKey = 'plugin.catalog.entityLayoutRoute';\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\n/** @public */\nexport interface EntityLayoutProps {\n UNSTABLE_contextMenuOptions?: ComponentProps<\n typeof EntityHeader\n >['UNSTABLE_contextMenuOptions'];\n UNSTABLE_extraContextMenuItems?: ComponentProps<\n typeof EntityHeader\n >['UNSTABLE_extraContextMenuItems'];\n contextMenuItems?: ComponentProps<typeof EntityHeader>['contextMenuItems'];\n children?: ReactNode;\n header?: JSX.Element;\n NotFoundComponent?: ReactNode;\n /**\n * An array of relation types used to determine the parent entities in the hierarchy.\n * These relations are prioritized in the order provided, allowing for flexible\n * navigation through entity relationships.\n *\n * For example, use relation types like `[\"partOf\", \"memberOf\", \"ownedBy\"]` to define how the entity is related to\n * its parents in the Entity Catalog.\n *\n * It adds breadcrumbs in the Entity page to enhance user navigation and context awareness.\n */\n parentEntityRelations?: string[];\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 contextMenuItems,\n children,\n header,\n NotFoundComponent,\n parentEntityRelations,\n } = props;\n const { kind } = useRouteRefParams(entityRouteRef);\n const { entity, loading, error } = useAsyncEntity();\n\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 (!entity) {\n return [];\n }\n if (elementProps.if && !elementProps.if(entity)) {\n return [];\n }\n return [\n {\n path: elementProps.path,\n title: elementProps.title,\n group: elementProps.group,\n children: elementProps.children,\n },\n ];\n }),\n [entity],\n );\n\n const { t } = useTranslationRef(catalogTranslationRef);\n\n return (\n <Page themeId={entity?.spec?.type?.toString() ?? 'home'}>\n {header ?? (\n <EntityHeader\n parentEntityRelations={parentEntityRelations}\n UNSTABLE_contextMenuOptions={UNSTABLE_contextMenuOptions}\n UNSTABLE_extraContextMenuItems={UNSTABLE_extraContextMenuItems}\n contextMenuItems={contextMenuItems}\n />\n )}\n\n {loading && <Progress />}\n\n {entity && <EntityTabs 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 {NotFoundComponent ? (\n NotFoundComponent\n ) : (\n <WarningPanel title={t('entityLabels.warningPanelTitle')}>\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 )}\n </Content>\n )}\n </Page>\n );\n};\n\nEntityLayout.Route = Route;\n"],"names":[],"mappings":";;;;;;;;;;AAmDA,MAAM,OAAU,GAAA,kCAAA;AAChB,MAAM,QAAiD,MAAM,IAAA;AAC7D,mBAAoB,CAAA,KAAA,EAAO,SAAS,IAAI,CAAA;AACxC,mBAAoB,CAAA,KAAA,EAAO,0BAA0B,IAAI,CAAA;AA4C5C,MAAA,YAAA,GAAe,CAAC,KAA6B,KAAA;AACxD,EAAM,MAAA;AAAA,IACJ,8BAAA;AAAA,IACA,2BAAA;AAAA,IACA,gBAAA;AAAA,IACA,QAAA;AAAA,IACA,MAAA;AAAA,IACA,iBAAA;AAAA,IACA;AAAA,GACE,GAAA,KAAA;AACJ,EAAA,MAAM,EAAE,IAAA,EAAS,GAAA,iBAAA,CAAkB,cAAc,CAAA;AACjD,EAAA,MAAM,EAAE,MAAA,EAAQ,OAAS,EAAA,KAAA,KAAU,cAAe,EAAA;AAElD,EAAA,MAAM,MAAS,GAAA,gBAAA;AAAA,IACb,QAAA;AAAA,IACA,CAAA,QAAA,KACE,SACG,qBAAsB,CAAA;AAAA,MACrB,GAAK,EAAA,OAAA;AAAA,MACL,eACE,EAAA;AAAA,KACH,EACA,WAAoC,EAAA,CACpC,QAAQ,CAAC,EAAE,KAAO,EAAA,YAAA,EAAmB,KAAA;AACpC,MAAA,IAAI,CAAC,MAAQ,EAAA;AACX,QAAA,OAAO,EAAC;AAAA;AAEV,MAAA,IAAI,aAAa,EAAM,IAAA,CAAC,YAAa,CAAA,EAAA,CAAG,MAAM,CAAG,EAAA;AAC/C,QAAA,OAAO,EAAC;AAAA;AAEV,MAAO,OAAA;AAAA,QACL;AAAA,UACE,MAAM,YAAa,CAAA,IAAA;AAAA,UACnB,OAAO,YAAa,CAAA,KAAA;AAAA,UACpB,OAAO,YAAa,CAAA,KAAA;AAAA,UACpB,UAAU,YAAa,CAAA;AAAA;AACzB,OACF;AAAA,KACD,CAAA;AAAA,IACL,CAAC,MAAM;AAAA,GACT;AAEA,EAAA,MAAM,EAAE,CAAA,EAAM,GAAA,iBAAA,CAAkB,qBAAqB,CAAA;AAErD,EACE,uBAAA,IAAA,CAAC,QAAK,OAAS,EAAA,MAAA,EAAQ,MAAM,IAAM,EAAA,QAAA,MAAc,MAC9C,EAAA,QAAA,EAAA;AAAA,IACC,MAAA,oBAAA,GAAA;AAAA,MAAC,YAAA;AAAA,MAAA;AAAA,QACC,qBAAA;AAAA,QACA,2BAAA;AAAA,QACA,8BAAA;AAAA,QACA;AAAA;AAAA,KACF;AAAA,IAGD,OAAA,wBAAY,QAAS,EAAA,EAAA,CAAA;AAAA,IAErB,MAAA,oBAAW,GAAA,CAAA,UAAA,EAAA,EAAW,MAAgB,EAAA,CAAA;AAAA,IAEtC,KAAA,oBACE,GAAA,CAAA,OAAA,EAAA,EACC,QAAC,kBAAA,GAAA,CAAA,KAAA,EAAA,EAAM,UAAS,OAAS,EAAA,QAAA,EAAA,KAAA,CAAM,QAAS,EAAA,EAAE,CAC5C,EAAA,CAAA;AAAA,IAGD,CAAC,OAAA,IAAW,CAAC,KAAA,IAAS,CAAC,MACtB,oBAAA,GAAA,CAAC,OACE,EAAA,EAAA,QAAA,EAAA,iBAAA,GACC,oCAEC,IAAA,CAAA,YAAA,EAAA,EAAa,KAAO,EAAA,CAAA,CAAE,gCAAgC,CAAG,EAAA,QAAA,EAAA;AAAA,MAAA,cAAA;AAAA,MAC3C,IAAA;AAAA,MAAK,qBAAA;AAAA,MAAoB,GAAA;AAAA,sBACrC,GAAA,CAAA,IAAA,EAAA,EAAK,EAAG,EAAA,gEAAA,EAAiE,QAE1E,EAAA,2BAAA,EAAA,CAAA;AAAA,MAAO;AAAA,KAAA,EAET,CAEJ,EAAA;AAAA,GAEJ,EAAA,CAAA;AAEJ;AAEA,YAAA,CAAa,KAAQ,GAAA,KAAA;;;;"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { jsxs, Fragment, jsx } from 'react/jsx-runtime';
|
|
2
|
+
import { useMemo } from 'react';
|
|
2
3
|
import { Helmet } from 'react-helmet';
|
|
3
4
|
import { useParams, useRoutes, matchRoutes } from 'react-router-dom';
|
|
4
5
|
import { EntityTabsPanel } from './EntityTabsPanel.esm.js';
|
|
@@ -48,7 +49,13 @@ function EntityTabs(props) {
|
|
|
48
49
|
}),
|
|
49
50
|
[routes]
|
|
50
51
|
);
|
|
51
|
-
return /* @__PURE__ */
|
|
52
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
53
|
+
/* @__PURE__ */ jsx(EntityTabsList, { tabs, selectedIndex: index }),
|
|
54
|
+
/* @__PURE__ */ jsxs(EntityTabsPanel, { children: [
|
|
55
|
+
/* @__PURE__ */ jsx(Helmet, { title: route?.title }),
|
|
56
|
+
element
|
|
57
|
+
] })
|
|
58
|
+
] });
|
|
52
59
|
}
|
|
53
60
|
|
|
54
61
|
export { EntityTabs, useSelectedSubRoute };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"EntityTabs.esm.js","sources":["../../../../src/alpha/components/EntityTabs/EntityTabs.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 */\nimport
|
|
1
|
+
{"version":3,"file":"EntityTabs.esm.js","sources":["../../../../src/alpha/components/EntityTabs/EntityTabs.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 */\nimport { useMemo } from 'react';\nimport { Helmet } from 'react-helmet';\nimport { matchRoutes, useParams, useRoutes } from 'react-router-dom';\nimport { EntityTabsPanel } from './EntityTabsPanel';\nimport { EntityTabsList } from './EntityTabsList';\n\ntype SubRoute = {\n group: string;\n path: string;\n title: string;\n children: JSX.Element;\n};\n\nexport function useSelectedSubRoute(subRoutes: SubRoute[]): {\n index: number;\n route?: SubRoute;\n element?: JSX.Element;\n} {\n const params = useParams();\n\n const routes = subRoutes.map(({ path, children }) => ({\n caseSensitive: false,\n path: `${path}/*`,\n element: children,\n }));\n\n // TODO: remove once react-router updated\n const sortedRoutes = routes.sort((a, b) =>\n // remove \"/*\" symbols from path end before comparing\n b.path.replace(/\\/\\*$/, '').localeCompare(a.path.replace(/\\/\\*$/, '')),\n );\n\n const element = useRoutes(sortedRoutes) ?? subRoutes[0]?.children;\n\n // TODO(Rugvip): Once we only support v6 stable we can always prefix\n // This avoids having a double / prefix for react-router v6 beta, which in turn breaks\n // the tab highlighting when using relative paths for the tabs.\n let currentRoute = params['*'] ?? '';\n if (!currentRoute.startsWith('/')) {\n currentRoute = `/${currentRoute}`;\n }\n\n const [matchedRoute] = matchRoutes(sortedRoutes, currentRoute) ?? [];\n const foundIndex = matchedRoute\n ? subRoutes.findIndex(t => `${t.path}/*` === matchedRoute.route.path)\n : 0;\n\n return {\n index: foundIndex === -1 ? 0 : foundIndex,\n element,\n route: subRoutes[foundIndex] ?? subRoutes[0],\n };\n}\n\ntype EntityTabsProps = {\n routes: SubRoute[];\n};\n\nexport function EntityTabs(props: EntityTabsProps) {\n const { routes } = props;\n\n const { index, route, element } = useSelectedSubRoute(routes);\n\n const tabs = useMemo(\n () =>\n routes.map(t => {\n const { path, title, group } = t;\n let to = path;\n // Remove trailing /*\n to = to.replace(/\\/\\*$/, '');\n // And remove leading / for relative navigation\n to = to.replace(/^\\//, '');\n return {\n group,\n id: path,\n path: to,\n label: title,\n };\n }),\n [routes],\n );\n\n return (\n <>\n <EntityTabsList tabs={tabs} selectedIndex={index} />\n <EntityTabsPanel>\n <Helmet title={route?.title} />\n {element}\n </EntityTabsPanel>\n </>\n );\n}\n"],"names":[],"mappings":";;;;;;;AA4BO,SAAS,oBAAoB,SAIlC,EAAA;AACA,EAAA,MAAM,SAAS,SAAU,EAAA;AAEzB,EAAA,MAAM,SAAS,SAAU,CAAA,GAAA,CAAI,CAAC,EAAE,IAAA,EAAM,UAAgB,MAAA;AAAA,IACpD,aAAe,EAAA,KAAA;AAAA,IACf,IAAA,EAAM,GAAG,IAAI,CAAA,EAAA,CAAA;AAAA,IACb,OAAS,EAAA;AAAA,GACT,CAAA,CAAA;AAGF,EAAA,MAAM,eAAe,MAAO,CAAA,IAAA;AAAA,IAAK,CAAC,CAAG,EAAA,CAAA;AAAA;AAAA,MAEnC,CAAE,CAAA,IAAA,CAAK,OAAQ,CAAA,OAAA,EAAS,EAAE,CAAA,CAAE,aAAc,CAAA,CAAA,CAAE,IAAK,CAAA,OAAA,CAAQ,OAAS,EAAA,EAAE,CAAC;AAAA;AAAA,GACvE;AAEA,EAAA,MAAM,UAAU,SAAU,CAAA,YAAY,CAAK,IAAA,SAAA,CAAU,CAAC,CAAG,EAAA,QAAA;AAKzD,EAAI,IAAA,YAAA,GAAe,MAAO,CAAA,GAAG,CAAK,IAAA,EAAA;AAClC,EAAA,IAAI,CAAC,YAAA,CAAa,UAAW,CAAA,GAAG,CAAG,EAAA;AACjC,IAAA,YAAA,GAAe,IAAI,YAAY,CAAA,CAAA;AAAA;AAGjC,EAAA,MAAM,CAAC,YAAY,CAAA,GAAI,YAAY,YAAc,EAAA,YAAY,KAAK,EAAC;AACnE,EAAA,MAAM,UAAa,GAAA,YAAA,GACf,SAAU,CAAA,SAAA,CAAU,CAAK,CAAA,KAAA,CAAA,EAAG,CAAE,CAAA,IAAI,CAAS,EAAA,CAAA,KAAA,YAAA,CAAa,KAAM,CAAA,IAAI,CAClE,GAAA,CAAA;AAEJ,EAAO,OAAA;AAAA,IACL,KAAA,EAAO,UAAe,KAAA,CAAA,CAAA,GAAK,CAAI,GAAA,UAAA;AAAA,IAC/B,OAAA;AAAA,IACA,KAAO,EAAA,SAAA,CAAU,UAAU,CAAA,IAAK,UAAU,CAAC;AAAA,GAC7C;AACF;AAMO,SAAS,WAAW,KAAwB,EAAA;AACjD,EAAM,MAAA,EAAE,QAAW,GAAA,KAAA;AAEnB,EAAA,MAAM,EAAE,KAAO,EAAA,KAAA,EAAO,OAAQ,EAAA,GAAI,oBAAoB,MAAM,CAAA;AAE5D,EAAA,MAAM,IAAO,GAAA,OAAA;AAAA,IACX,MACE,MAAO,CAAA,GAAA,CAAI,CAAK,CAAA,KAAA;AACd,MAAA,MAAM,EAAE,IAAA,EAAM,KAAO,EAAA,KAAA,EAAU,GAAA,CAAA;AAC/B,MAAA,IAAI,EAAK,GAAA,IAAA;AAET,MAAK,EAAA,GAAA,EAAA,CAAG,OAAQ,CAAA,OAAA,EAAS,EAAE,CAAA;AAE3B,MAAK,EAAA,GAAA,EAAA,CAAG,OAAQ,CAAA,KAAA,EAAO,EAAE,CAAA;AACzB,MAAO,OAAA;AAAA,QACL,KAAA;AAAA,QACA,EAAI,EAAA,IAAA;AAAA,QACJ,IAAM,EAAA,EAAA;AAAA,QACN,KAAO,EAAA;AAAA,OACT;AAAA,KACD,CAAA;AAAA,IACH,CAAC,MAAM;AAAA,GACT;AAEA,EAAA,uBAEI,IAAA,CAAA,QAAA,EAAA,EAAA,QAAA,EAAA;AAAA,oBAAC,GAAA,CAAA,cAAA,EAAA,EAAe,IAAY,EAAA,aAAA,EAAe,KAAO,EAAA,CAAA;AAAA,yBACjD,eACC,EAAA,EAAA,QAAA,EAAA;AAAA,sBAAC,GAAA,CAAA,MAAA,EAAA,EAAO,KAAO,EAAA,KAAA,EAAO,KAAO,EAAA,CAAA;AAAA,MAC5B;AAAA,KACH,EAAA;AAAA,GACF,EAAA,CAAA;AAEJ;;;;"}
|