From 8469a03c2fd92304ed93ab9c09009806ebcfeeab Mon Sep 17 00:00:00 2001 From: Ben Keil Date: Tue, 7 Nov 2023 20:40:32 +0100 Subject: [PATCH] fix: revert deleting of fields and deprecate them instead Signed-off-by: Ben Keil --- .changeset/long-sheep-exercise.md | 13 ++++- plugins/catalog-graph/README.md | 49 +++++++++++++++++++ plugins/catalog-graph/api-report.md | 6 +++ .../DefaultRenderNode.test.tsx | 17 +++++++ .../components/EntityRelationsGraph/types.ts | 28 +++++++++++ .../useEntityRelationNodesAndEdges.test.ts | 38 ++++++++++++++ .../useEntityRelationNodesAndEdges.ts | 7 +++ 7 files changed, 157 insertions(+), 1 deletion(-) diff --git a/.changeset/long-sheep-exercise.md b/.changeset/long-sheep-exercise.md index 5cea2f8e32..f5e692f55e 100644 --- a/.changeset/long-sheep-exercise.md +++ b/.changeset/long-sheep-exercise.md @@ -2,4 +2,15 @@ '@backstage/plugin-catalog-graph': minor --- -Add the entire `Entity` to `EntityNodeData` +Add the entire `Entity` to `EntityNodeData` and deprecate `name`, `kind`, `title`, `namespace` and `spec`. + +To get the deprecated properties in your custom component you can use: + +```typescript +import { DEFAULT_NAMESPACE } from '@backstage/catalog-model'; + +const { + kind, + metadata: { name, namespace = DEFAULT_NAMESPACE, title }, +} = entity; +``` diff --git a/plugins/catalog-graph/README.md b/plugins/catalog-graph/README.md index f723523716..010a129b0f 100644 --- a/plugins/catalog-graph/README.md +++ b/plugins/catalog-graph/README.md @@ -85,6 +85,55 @@ To use the catalog graph plugin, you have to add some things to your Backstage a ``` +### Customization + +Copy the default implementation `DefaultRenderNode.tsx` and add more classes to the styles: + +```typescript +const useStyles = makeStyles( + theme => ({ + node: { + … + '&.system': { + fill: '#F5DC70', + stroke: '#F2CE34', + }, + '&.domain': { + fill: '#F5DC70', + stroke: '#F2CE34', + }, + … +); +``` + +Now you can use the new classes in your component with `className={classNames(classes.node, kind?.toLowerCase(), type?.toLowerCase())}` + +```tsx +return ( + + + + {displayTitle} + + +); +``` + ## Development Run `yarn` in the root of this plugin to install all dependencies and then `yarn start` to run a [development version](./dev/index.tsx) of this plugin. diff --git a/plugins/catalog-graph/api-report.md b/plugins/catalog-graph/api-report.md index c9a9bd4d9a..ba75943843 100644 --- a/plugins/catalog-graph/api-report.md +++ b/plugins/catalog-graph/api-report.md @@ -11,6 +11,7 @@ import { DependencyGraphTypes } from '@backstage/core-components'; import { Entity } from '@backstage/catalog-model'; import { ExternalRouteRef } from '@backstage/core-plugin-api'; import { InfoCardVariants } from '@backstage/core-components'; +import { JsonObject } from '@backstage/types'; import { JSX as JSX_2 } from 'react'; import { MouseEvent as MouseEvent_2 } from 'react'; import { MouseEventHandler } from 'react'; @@ -94,6 +95,11 @@ export type EntityNodeData = { focused?: boolean; color?: 'primary' | 'secondary' | 'default'; onClick?: MouseEventHandler; + name: string; + kind?: string; + title?: string; + namespace: string; + spec?: JsonObject; }; // @public diff --git a/plugins/catalog-graph/src/components/EntityRelationsGraph/DefaultRenderNode.test.tsx b/plugins/catalog-graph/src/components/EntityRelationsGraph/DefaultRenderNode.test.tsx index c8a2422a4f..1f3d77e1ae 100644 --- a/plugins/catalog-graph/src/components/EntityRelationsGraph/DefaultRenderNode.test.tsx +++ b/plugins/catalog-graph/src/components/EntityRelationsGraph/DefaultRenderNode.test.tsx @@ -37,6 +37,10 @@ describe('', () => { }, focused: false, color: 'primary', + // @deprecated + kind: 'kind', + name: 'name', + namespace: 'namespace', }} /> , @@ -60,6 +64,10 @@ describe('', () => { }, }, focused: false, + // @deprecated + kind: 'kind', + name: 'name', + namespace: 'default', }} /> , @@ -85,6 +93,10 @@ describe('', () => { }, focused: false, onClick, + // @deprecated + kind: 'kind', + name: 'name', + namespace: 'namespace', }} /> , @@ -111,6 +123,11 @@ describe('', () => { }, }, focused: false, + // @deprecated + kind: 'kind', + name: 'name', + namespace: 'namespace', + title: 'Custom Title', }} /> , diff --git a/plugins/catalog-graph/src/components/EntityRelationsGraph/types.ts b/plugins/catalog-graph/src/components/EntityRelationsGraph/types.ts index 98eacf4d01..6b6061caaf 100644 --- a/plugins/catalog-graph/src/components/EntityRelationsGraph/types.ts +++ b/plugins/catalog-graph/src/components/EntityRelationsGraph/types.ts @@ -17,6 +17,7 @@ import { DependencyGraphTypes } from '@backstage/core-components'; import { MouseEventHandler } from 'react'; import { Entity } from '@backstage/catalog-model'; +import { JsonObject } from '@backstage/types'; /** * Additional Data for entities. @@ -65,6 +66,33 @@ export type EntityNodeData = { * Optional click handler. */ onClick?: MouseEventHandler; + + /** + * Name of the entity. + * @deprecated use {@link EntityNodeData#entity} instead + */ + name: string; + /** + * Optional kind of the entity. + * @deprecated use {@link EntityNodeData#entity} instead + */ + kind?: string; + /** + * Optional title of the entity. + * @deprecated use {@link EntityNodeData#entity} instead + */ + title?: string; + /** + * Namespace of the entity. + * @deprecated use {@link EntityNodeData#entity} instead + * The Entity + */ + namespace: string; + /** + * Optional spec of the entity. + * @deprecated use {@link EntityNodeData#entity} instead + */ + spec?: JsonObject; }; /** diff --git a/plugins/catalog-graph/src/components/EntityRelationsGraph/useEntityRelationNodesAndEdges.test.ts b/plugins/catalog-graph/src/components/EntityRelationsGraph/useEntityRelationNodesAndEdges.test.ts index ab6de43be3..8c7b59b9c4 100644 --- a/plugins/catalog-graph/src/components/EntityRelationsGraph/useEntityRelationNodesAndEdges.test.ts +++ b/plugins/catalog-graph/src/components/EntityRelationsGraph/useEntityRelationNodesAndEdges.test.ts @@ -14,6 +14,7 @@ * limitations under the License. */ import { + DEFAULT_NAMESPACE, Entity, RELATION_HAS_PART, RELATION_OWNED_BY, @@ -25,6 +26,7 @@ import { renderHook, waitFor } from '@testing-library/react'; import { filter, keyBy } from 'lodash'; import { useEntityRelationGraph as useEntityRelationGraphMocked } from './useEntityRelationGraph'; import { useEntityRelationNodesAndEdges } from './useEntityRelationNodesAndEdges'; +import { EntityNode } from './types'; jest.mock('./useEntityRelationGraph'); @@ -107,6 +109,15 @@ const entities: { [ref: string]: Entity } = { }, }; +function deprecatedProperties(entity: Entity): Partial { + return { + kind: entity.kind, + name: entity.metadata.name, + namespace: entity.metadata.namespace || DEFAULT_NAMESPACE, + title: entity.metadata.title, + }; +} + describe('useEntityRelationNodesAndEdges', () => { beforeEach(() => { useEntityRelationGraph.mockImplementation(({ filter: { kinds } }) => ({ @@ -185,24 +196,28 @@ describe('useEntityRelationNodesAndEdges', () => { focused: true, id: 'b:d/c', entity: entities['b:d/c'], + ...deprecatedProperties(entities['b:d/c']), }, { color: 'primary', focused: false, id: 'k:d/a1', entity: entities['k:d/a1'], + ...deprecatedProperties(entities['k:d/a1']), }, { color: 'primary', focused: false, id: 'b:d/c1', entity: entities['b:d/c1'], + ...deprecatedProperties(entities['b:d/c1']), }, { color: 'primary', focused: false, id: 'b:d/c2', entity: entities['b:d/c2'], + ...deprecatedProperties(entities['b:d/c2']), }, ]); expect(edges).toEqual([ @@ -250,24 +265,28 @@ describe('useEntityRelationNodesAndEdges', () => { focused: true, id: 'b:d/c', entity: entities['b:d/c'], + ...deprecatedProperties(entities['b:d/c']), }, { color: 'primary', focused: false, id: 'k:d/a1', entity: entities['k:d/a1'], + ...deprecatedProperties(entities['k:d/a1']), }, { color: 'primary', focused: false, id: 'b:d/c1', entity: entities['b:d/c1'], + ...deprecatedProperties(entities['b:d/c1']), }, { color: 'primary', focused: false, id: 'b:d/c2', entity: entities['b:d/c2'], + ...deprecatedProperties(entities['b:d/c2']), }, ]); expect(edges).toEqual([ @@ -315,24 +334,28 @@ describe('useEntityRelationNodesAndEdges', () => { focused: true, id: 'b:d/c', entity: entities['b:d/c'], + ...deprecatedProperties(entities['b:d/c']), }, { color: 'primary', focused: false, id: 'k:d/a1', entity: entities['k:d/a1'], + ...deprecatedProperties(entities['k:d/a1']), }, { color: 'primary', focused: false, id: 'b:d/c1', entity: entities['b:d/c1'], + ...deprecatedProperties(entities['b:d/c1']), }, { color: 'primary', focused: false, id: 'b:d/c2', entity: entities['b:d/c2'], + ...deprecatedProperties(entities['b:d/c2']), }, ]); expect(edges).toEqual([ @@ -410,24 +433,28 @@ describe('useEntityRelationNodesAndEdges', () => { focused: true, id: 'b:d/c', entity: entities['b:d/c'], + ...deprecatedProperties(entities['b:d/c']), }, { color: 'primary', focused: false, id: 'k:d/a1', entity: entities['k:d/a1'], + ...deprecatedProperties(entities['k:d/a1']), }, { color: 'primary', focused: false, id: 'b:d/c1', entity: entities['b:d/c1'], + ...deprecatedProperties(entities['b:d/c1']), }, { color: 'primary', focused: false, id: 'b:d/c2', entity: entities['b:d/c2'], + ...deprecatedProperties(entities['b:d/c2']), }, ]); expect(edges).toEqual([ @@ -503,24 +530,28 @@ describe('useEntityRelationNodesAndEdges', () => { focused: true, id: 'b:d/c', entity: entities['b:d/c'], + ...deprecatedProperties(entities['b:d/c']), }, { color: 'primary', focused: false, id: 'k:d/a1', entity: entities['k:d/a1'], + ...deprecatedProperties(entities['k:d/a1']), }, { color: 'primary', focused: false, id: 'b:d/c1', entity: entities['b:d/c1'], + ...deprecatedProperties(entities['b:d/c1']), }, { color: 'secondary', focused: true, id: 'b:d/c2', entity: entities['b:d/c2'], + ...deprecatedProperties(entities['b:d/c2']), }, ]); expect(edges).toEqual([ @@ -567,24 +598,28 @@ describe('useEntityRelationNodesAndEdges', () => { focused: true, id: 'b:d/c', entity: entities['b:d/c'], + ...deprecatedProperties(entities['b:d/c']), }, { color: 'primary', focused: false, id: 'k:d/a1', entity: entities['k:d/a1'], + ...deprecatedProperties(entities['k:d/a1']), }, { color: 'primary', focused: false, id: 'b:d/c1', entity: entities['b:d/c1'], + ...deprecatedProperties(entities['b:d/c1']), }, { color: 'primary', focused: false, id: 'b:d/c2', entity: entities['b:d/c2'], + ...deprecatedProperties(entities['b:d/c2']), }, ]); expect(edges).toEqual([ @@ -620,18 +655,21 @@ describe('useEntityRelationNodesAndEdges', () => { focused: true, id: 'b:d/c', entity: entities['b:d/c'], + ...deprecatedProperties(entities['b:d/c']), }, { color: 'primary', focused: false, id: 'b:d/c1', entity: entities['b:d/c1'], + ...deprecatedProperties(entities['b:d/c1']), }, { color: 'primary', focused: false, id: 'b:d/c2', entity: entities['b:d/c2'], + ...deprecatedProperties(entities['b:d/c2']), }, ]); expect(edges).toEqual([ diff --git a/plugins/catalog-graph/src/components/EntityRelationsGraph/useEntityRelationNodesAndEdges.ts b/plugins/catalog-graph/src/components/EntityRelationsGraph/useEntityRelationNodesAndEdges.ts index 49356469a9..4302957d5b 100644 --- a/plugins/catalog-graph/src/components/EntityRelationsGraph/useEntityRelationNodesAndEdges.ts +++ b/plugins/catalog-graph/src/components/EntityRelationsGraph/useEntityRelationNodesAndEdges.ts @@ -18,6 +18,7 @@ import useDebounce from 'react-use/lib/useDebounce'; import { RelationPairs, ALL_RELATION_PAIRS } from './relations'; import { EntityEdge, EntityNode } from './types'; import { useEntityRelationGraph } from './useEntityRelationGraph'; +import { DEFAULT_NAMESPACE } from '@backstage/catalog-model'; /** * Generate nodes and edges to render the entity graph. @@ -73,6 +74,12 @@ export function useEntityRelationNodesAndEdges({ entity, focused, color: focused ? 'secondary' : 'primary', + // @deprecated + kind: entity.kind, + name: entity.metadata.name, + namespace: entity.metadata.namespace || DEFAULT_NAMESPACE, + title: entity.metadata.title, + spec: entity.spec, }; if (onNodeClick) {