diff --git a/plugins/catalog/src/components/SystemDiagramCard/SystemDiagramCard.test.tsx b/plugins/catalog/src/components/SystemDiagramCard/SystemDiagramCard.test.tsx
index baa8c667d2..34dfcfef56 100644
--- a/plugins/catalog/src/components/SystemDiagramCard/SystemDiagramCard.test.tsx
+++ b/plugins/catalog/src/components/SystemDiagramCard/SystemDiagramCard.test.tsx
@@ -62,9 +62,9 @@ describe('', () => {
);
expect(queryByText(/System Diagram/)).toBeInTheDocument();
- expect(queryByText(/system:my-namespace2\/my-system2/)).toBeInTheDocument();
+ expect(queryByText(/my-namespace2\/my-system2/)).toBeInTheDocument();
expect(
- queryByText(/component:my-namespace\/my-entity/),
+ queryByText(/my-namespace\/my-entity/),
).not.toBeInTheDocument();
});
@@ -118,7 +118,7 @@ describe('', () => {
);
expect(getByText('System Diagram')).toBeInTheDocument();
- expect(getByText('system:my-namespace/my-system')).toBeInTheDocument();
- expect(getByText('component:my-namespace/my-entity')).toBeInTheDocument();
+ expect(getByText('my-namespace/my-system')).toBeInTheDocument();
+ expect(getByText('my-namespace/my-entity')).toBeInTheDocument();
});
});
diff --git a/plugins/catalog/src/components/SystemDiagramCard/SystemDiagramCard.tsx b/plugins/catalog/src/components/SystemDiagramCard/SystemDiagramCard.tsx
index e601b443de..c7a9cfdb01 100644
--- a/plugins/catalog/src/components/SystemDiagramCard/SystemDiagramCard.tsx
+++ b/plugins/catalog/src/components/SystemDiagramCard/SystemDiagramCard.tsx
@@ -19,11 +19,13 @@ import {
RELATION_DEPENDS_ON,
RELATION_PROVIDES_API,
RELATION_PART_OF,
- serializeEntityRef,
+ stringifyEntityRef,
ENTITY_DEFAULT_NAMESPACE,
+ parseEntityRef,
} from '@backstage/catalog-model';
import {
catalogApiRef,
+ entityRoute,
getEntityRelations,
useEntity,
} from '@backstage/plugin-catalog-react';
@@ -34,26 +36,106 @@ import {
Progress,
useApi,
ResponseErrorPanel,
+ Link,
} from '@backstage/core';
-import { Box, Typography } from '@material-ui/core';
+import { Box, makeStyles, Typography } from '@material-ui/core';
import ZoomOutMap from '@material-ui/icons/ZoomOutMap';
import React from 'react';
import { useAsync } from 'react-use';
+import { BackstageTheme } from '@backstage/theme';
+import { generatePath } from 'react-router';
-function simplifiedEntityName(
+const useStyles = makeStyles((theme: BackstageTheme) => ({
+ domainNode: {
+ fill: theme.palette.primary.main,
+ stroke: theme.palette.border,
+ },
+ systemNode: {
+ fill: 'coral',
+ stroke: theme.palette.border,
+ },
+ componentNode: {
+ fill: 'yellowgreen',
+ stroke: theme.palette.border,
+ },
+ apiNode: {
+ fill: theme.palette.gold,
+ stroke: theme.palette.border,
+ },
+ resourceNode: {
+ fill: 'grey',
+ stroke: theme.palette.border,
+ },
+}));
+
+// Simplifies the diagram output by hiding the default namespace and kind
+function readableEntityName(
ref:
| Entity
| {
- kind?: string;
+ kind: string;
namespace?: string;
name: string;
},
): string {
- // Simplify the diagram output by hiding only the default namespace
- return serializeEntityRef(ref)
- .toString()
+ return stringifyEntityRef(ref)
.toLocaleLowerCase('en-US')
- .replace(':default/', ':');
+ .replace(`:${ENTITY_DEFAULT_NAMESPACE}/`, ':')
+ .split(':')[1];
+}
+
+function RenderNode(props: DependencyGraphTypes.RenderNodeProps) {
+ const classes = useStyles();
+ const kind = props.node.kind || 'Component';
+ const ref = parseEntityRef(props.node.id);
+ let nodeClass = classes.componentNode;
+
+ switch (kind) {
+ case 'Domain':
+ nodeClass = classes.domainNode;
+ break;
+ case 'System':
+ nodeClass = classes.systemNode;
+ break;
+ case 'Component':
+ nodeClass = classes.componentNode;
+ break;
+ case 'API':
+ nodeClass = classes.apiNode;
+ break;
+ case 'Resource':
+ nodeClass = classes.resourceNode;
+ break;
+ default:
+ nodeClass = classes.componentNode;
+ }
+
+ return (
+
+
+
+
+ {props.node.name}
+
+
+
+
+ {props.node.kind}
+
+
+ );
}
/**
@@ -63,8 +145,8 @@ function simplifiedEntityName(
export function SystemDiagramCard() {
const { entity } = useEntity();
const currentSystemName = entity.metadata.name;
- const currentSystemNode = simplifiedEntityName(entity);
- const systemNodes = new Array<{ id: string }>();
+ const currentSystemNode = stringifyEntityRef(entity);
+ const systemNodes = new Array<{ id: string; kind: string; name: string }>();
const systemEdges = new Array<{ from: string; to: string; label: string }>();
const catalogApi = useApi(catalogApiRef);
@@ -83,22 +165,26 @@ export function SystemDiagramCard() {
// pick out the system itself
systemNodes.push({
id: currentSystemNode,
+ kind: 'System',
+ name: readableEntityName(entity),
});
// check if the system has an assigned domain
// even if the domain object doesn't exist in the catalog, display it in the map
const catalogItemDomain = getEntityRelations(entity, RELATION_PART_OF, {
- kind: 'domain',
+ kind: 'Domain',
});
catalogItemDomain.forEach(foundDomain =>
systemNodes.push({
- id: simplifiedEntityName(foundDomain),
+ id: stringifyEntityRef(foundDomain),
+ kind: foundDomain.kind,
+ name: readableEntityName(foundDomain),
}),
);
catalogItemDomain.forEach(foundDomain =>
systemEdges.push({
from: currentSystemNode,
- to: simplifiedEntityName(foundDomain),
+ to: stringifyEntityRef(foundDomain),
label: 'part of',
}),
);
@@ -106,7 +192,9 @@ export function SystemDiagramCard() {
if (catalogResponse && catalogResponse.items) {
for (const catalogItem of catalogResponse.items) {
systemNodes.push({
- id: simplifiedEntityName(catalogItem),
+ id: stringifyEntityRef(catalogItem),
+ kind: catalogItem.kind,
+ name: readableEntityName(catalogItem),
});
// Check relations of the entity assigned to this system to see
@@ -119,8 +207,8 @@ export function SystemDiagramCard() {
);
catalogItemRelations_partOf.forEach(foundRelation =>
systemEdges.push({
- from: simplifiedEntityName(catalogItem),
- to: simplifiedEntityName(foundRelation),
+ from: stringifyEntityRef(catalogItem),
+ to: stringifyEntityRef(foundRelation),
label: 'part of',
}),
);
@@ -131,9 +219,9 @@ export function SystemDiagramCard() {
);
catalogItemRelations_providesApi.forEach(foundRelation =>
systemEdges.push({
- from: simplifiedEntityName(catalogItem),
- to: simplifiedEntityName(foundRelation),
- label: 'provides API',
+ from: stringifyEntityRef(catalogItem),
+ to: stringifyEntityRef(foundRelation),
+ label: 'provides',
}),
);
@@ -143,8 +231,8 @@ export function SystemDiagramCard() {
);
catalogItemRelations_dependsOn.forEach(foundRelation =>
systemEdges.push({
- from: simplifiedEntityName(catalogItem),
- to: simplifiedEntityName(foundRelation),
+ from: stringifyEntityRef(catalogItem),
+ to: stringifyEntityRef(foundRelation),
label: 'depends on',
}),
);
@@ -164,6 +252,7 @@ export function SystemDiagramCard() {
edges={systemEdges}
nodeMargin={10}
direction={DependencyGraphTypes.Direction.BOTTOM_TOP}
+ renderNode={RenderNode}
/>