diff --git a/.changeset/catalog-graph-nfs-page.md b/.changeset/catalog-graph-nfs-page.md new file mode 100644 index 0000000000..ff43ffaf25 --- /dev/null +++ b/.changeset/catalog-graph-nfs-page.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-catalog-graph': patch +--- + +The new frontend plugin entry now exposes a display title and icon for navigation, and the catalog graph page uses the Backstage UI header when rendered in the new frontend system. A new `NfsCatalogGraphPage` export is available for the same layout without the legacy `Page` shell. diff --git a/plugins/catalog-graph/src/alpha.tsx b/plugins/catalog-graph/src/alpha.tsx index a0f16cda2a..e1e60f77a0 100644 --- a/plugins/catalog-graph/src/alpha.tsx +++ b/plugins/catalog-graph/src/alpha.tsx @@ -19,6 +19,7 @@ import { createFrontendPlugin, PageBlueprint, } from '@backstage/frontend-plugin-api'; +import { RiMindMap } from '@remixicon/react'; import { EntityCardBlueprint } from '@backstage/plugin-catalog-react/alpha'; import { catalogGraphRouteRef, catalogEntityRouteRef } from './routes'; import { @@ -80,7 +81,7 @@ const CatalogGraphPage = PageBlueprint.makeWithOverrides({ routeRef: catalogGraphRouteRef, loader: () => import('./components/CatalogGraphPage').then(m => ( - + )), }); }, @@ -97,6 +98,8 @@ const CatalogGraphApi = ApiBlueprint.make({ export default createFrontendPlugin({ pluginId: 'catalog-graph', + title: 'Catalog Graph', + icon: , info: { packageJson: () => import('../package.json') }, routes: { catalogGraph: catalogGraphRouteRef, diff --git a/plugins/catalog-graph/src/components/CatalogGraphPage/CatalogGraphPage.tsx b/plugins/catalog-graph/src/components/CatalogGraphPage/CatalogGraphPage.tsx index 7e6420da1f..5fb913d8d7 100644 --- a/plugins/catalog-graph/src/components/CatalogGraphPage/CatalogGraphPage.tsx +++ b/plugins/catalog-graph/src/components/CatalogGraphPage/CatalogGraphPage.tsx @@ -27,6 +27,7 @@ import { entityRouteRef, humanizeEntityRef, } from '@backstage/plugin-catalog-react'; +import { Header as BuiHeader } from '@backstage/ui'; import Grid from '@material-ui/core/Grid'; import Paper from '@material-ui/core/Paper'; import Typography from '@material-ui/core/Typography'; @@ -116,22 +117,27 @@ const useStyles = makeStyles( { name: 'PluginCatalogGraphCatalogGraphPage' }, ); -export const CatalogGraphPage = ( - props: { - initialState?: { - selectedRelations?: string[]; - selectedKinds?: string[]; - rootEntityRefs?: string[]; - maxDepth?: number; - unidirectional?: boolean; - mergeRelations?: boolean; - direction?: Direction; - showFilters?: boolean; - curve?: 'curveStepBefore' | 'curveMonotoneX'; - }; - } & Partial, -) => { - const { relationPairs, initialState, entityFilter } = props; +type CatalogGraphPageProps = { + initialState?: { + selectedRelations?: string[]; + selectedKinds?: string[]; + rootEntityRefs?: string[]; + maxDepth?: number; + unidirectional?: boolean; + mergeRelations?: boolean; + direction?: Direction; + showFilters?: boolean; + curve?: 'curveStepBefore' | 'curveMonotoneX'; + }; +} & Partial; + +type CatalogGraphPageContentProps = CatalogGraphPageProps & { + headerVariant: 'legacy' | 'bui'; +}; + +function CatalogGraphPageContent(props: CatalogGraphPageContentProps) { + const { headerVariant, ...graphPageProps } = props; + const { relationPairs, initialState, entityFilter } = graphPageProps; const { t } = useTranslationRef(catalogGraphTranslationRef); const navigate = useNavigate(); const classes = useStyles(); @@ -185,93 +191,127 @@ export const CatalogGraphPage = ( [catalogEntityRoute, navigate, setRootEntityNames, analytics], ); + const subtitle = rootEntityNames.map(e => humanizeEntityRef(e)).join(', '); + + const filterToggle = ( + toggleShowFilters()} + > + {t('catalogGraphPage.filterToggleButtonTitle')} + + ); + + const supportButton = ( + + {t('catalogGraphPage.supportButtonDescription')} + + ); + + const graphBody = ( + + {showFilters && ( + + + + + + + + + + )} + + + + {' '} + {t('catalogGraphPage.zoomOutDescription')} + + 0 + ? selectedKinds + : undefined + } + relations={ + selectedRelations && selectedRelations.length > 0 + ? selectedRelations + : undefined + } + mergeRelations={mergeRelations} + unidirectional={unidirectional} + onNodeClick={onNodeClick} + direction={direction} + relationPairs={relationPairs} + entityFilter={entityFilter} + className={classes.graph} + zoom="enabled" + curve={curve} + /> + + + + ); + + if (headerVariant === 'legacy') { + return ( + +
+ + + {supportButton} + + {graphBody} + + + ); + } + return ( - -
humanizeEntityRef(e)).join(', ')} + <> + + {filterToggle} + {supportButton} + + } /> - toggleShowFilters()} - > - {t('catalogGraphPage.filterToggleButtonTitle')} - - } - > - - {t('catalogGraphPage.supportButtonDescription')} - - - - {showFilters && ( - - - - - - - - - - )} - - - - {' '} - {t('catalogGraphPage.zoomOutDescription')} - - 0 - ? selectedKinds - : undefined - } - relations={ - selectedRelations && selectedRelations.length > 0 - ? selectedRelations - : undefined - } - mergeRelations={mergeRelations} - unidirectional={unidirectional} - onNodeClick={onNodeClick} - direction={direction} - relationPairs={relationPairs} - entityFilter={entityFilter} - className={classes.graph} - zoom="enabled" - curve={curve} - /> - - - + {graphBody} - + ); +} + +export const CatalogGraphPage = (props: CatalogGraphPageProps) => { + return ; +}; + +export const NfsCatalogGraphPage = (props: CatalogGraphPageProps) => { + return ; }; diff --git a/plugins/catalog-graph/src/components/CatalogGraphPage/index.ts b/plugins/catalog-graph/src/components/CatalogGraphPage/index.ts index 496e79aab4..cdf8bc9430 100644 --- a/plugins/catalog-graph/src/components/CatalogGraphPage/index.ts +++ b/plugins/catalog-graph/src/components/CatalogGraphPage/index.ts @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -export { CatalogGraphPage } from './CatalogGraphPage'; +export { CatalogGraphPage, NfsCatalogGraphPage } from './CatalogGraphPage'; export type { CatalogGraphPageClassKey } from './CatalogGraphPage'; export type { MaxDepthFilterClassKey } from './MaxDepthFilter'; export type { SelectedKindsFilterClassKey } from './SelectedKindsFilter';