From 846168da2cfbc5a224f35493fdfebe097e64392b Mon Sep 17 00:00:00 2001 From: Andrew Shirley Date: Mon, 28 Jun 2021 13:51:33 +0100 Subject: [PATCH] Add an optional id prop and pass to load API Signed-off-by: Andrew Shirley --- .changeset/many-melons-hang.md | 5 ++++ plugins/tech-radar/README.md | 8 +++++- plugins/tech-radar/api-report.md | 11 ++++---- plugins/tech-radar/src/api.ts | 14 +++++++---- .../src/components/RadarComponent.tsx | 11 ++++---- .../src/components/RadarPage.test.tsx | 25 +++++++++++++++++++ 6 files changed, 58 insertions(+), 16 deletions(-) create mode 100644 .changeset/many-melons-hang.md diff --git a/.changeset/many-melons-hang.md b/.changeset/many-melons-hang.md new file mode 100644 index 0000000000..02fb8316b7 --- /dev/null +++ b/.changeset/many-melons-hang.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-tech-radar': patch +--- + +Add optional id prop passing it to the load API diff --git a/plugins/tech-radar/README.md b/plugins/tech-radar/README.md index 35c510ddd3..469a12e8e4 100644 --- a/plugins/tech-radar/README.md +++ b/plugins/tech-radar/README.md @@ -82,7 +82,9 @@ import { } from '@backstage/plugin-tech-radar'; class MyOwnClient implements TechRadarApi { - async load(): Promise { + async load(id: string | undefined): Promise { + // if needed id prop can be used to fetch the correct data + const data = await fetch('https://mydata.json').then(res => res.json()); // maybe you'll need to do some data transformation here to make it look like TechRadarLoaderResponse @@ -120,3 +122,7 @@ You can use the `svgProps` option to pass custom React props to the `` elem // const { getByTestId } = render(...); // expect(getByTestId('tech-radar-svg')).toBeInTheDocument(); ``` + +### How do I support multiple radars + +The `TechRadarPage` and `TechRadarComponent` components both take an optional `id` prop which is subsequently passed to the `load` method of the API to distinguish which radar's data to load. diff --git a/plugins/tech-radar/api-report.md b/plugins/tech-radar/api-report.md index f8bcc84d3a..8b98f1e494 100644 --- a/plugins/tech-radar/api-report.md +++ b/plugins/tech-radar/api-report.md @@ -46,7 +46,7 @@ export interface RadarQuadrant { name: string; } -// @public +// @public (undocumented) export interface RadarRing { // (undocumented) color: string; @@ -68,8 +68,7 @@ export const Router: { // @public (undocumented) export interface TechRadarApi { - // (undocumented) - load: () => Promise; + load: (id: string | undefined) => Promise; } // @public (undocumented) @@ -78,17 +77,19 @@ export const techRadarApiRef: ApiRef; // @public (undocumented) export const TechRadarComponent: (props: TechRadarComponentProps) => JSX.Element; -// @public +// @public (undocumented) export interface TechRadarComponentProps { // (undocumented) height: number; // (undocumented) + id?: string; + // (undocumented) svgProps?: object; // (undocumented) width: number; } -// @public +// @public (undocumented) export interface TechRadarLoaderResponse { // (undocumented) entries: RadarEntry[]; diff --git a/plugins/tech-radar/src/api.ts b/plugins/tech-radar/src/api.ts index fe574fcfd1..34307a1697 100644 --- a/plugins/tech-radar/src/api.ts +++ b/plugins/tech-radar/src/api.ts @@ -23,11 +23,14 @@ export const techRadarApiRef = createApiRef({ }); export interface TechRadarApi { - // Loads the TechRadar response data to pass through to the TechRadar component - load: () => Promise; + /** + * Loads the TechRadar response data to pass through to the TechRadar component. + * Takes the id prop of the TechRadarComponent or TechRadarPage to distinguish between multiple radars if needed + */ + load: (id: string | undefined) => Promise; } -/** +/* * Types related to the Radar's visualization. */ @@ -59,7 +62,7 @@ export interface RadarEntrySnapshot { moved?: MovedState; } -/** +/* * Types related to data collection for the Radar. */ @@ -69,11 +72,12 @@ export interface TechRadarLoaderResponse { entries: RadarEntry[]; } -/** +/* * Set up the Radar as a Backstage component. */ export interface TechRadarComponentProps { + id?: string; width: number; height: number; svgProps?: object; diff --git a/plugins/tech-radar/src/components/RadarComponent.tsx b/plugins/tech-radar/src/components/RadarComponent.tsx index fe42ad8e78..faa2763f17 100644 --- a/plugins/tech-radar/src/components/RadarComponent.tsx +++ b/plugins/tech-radar/src/components/RadarComponent.tsx @@ -27,13 +27,14 @@ import { Entry } from '../utils/types'; import { Progress } from '@backstage/core-components'; import { useApi, errorApiRef } from '@backstage/core-plugin-api'; -const useTechRadarLoader = () => { +const useTechRadarLoader = (id: string | undefined) => { const errorApi = useApi(errorApiRef); const techRadarApi = useApi(techRadarApiRef); - const { error, value, loading } = useAsync(async () => techRadarApi.load(), [ - techRadarApi, - ]); + const { error, value, loading } = useAsync( + async () => techRadarApi.load(id), + [techRadarApi], + ); useEffect(() => { if (error) { @@ -45,7 +46,7 @@ const useTechRadarLoader = () => { }; const RadarComponent = (props: TechRadarComponentProps): JSX.Element => { - const { loading, error, value: data } = useTechRadarLoader(); + const { loading, error, value: data } = useTechRadarLoader(props.id); const mapToEntries = ( loaderResponse: TechRadarLoaderResponse | undefined, diff --git a/plugins/tech-radar/src/components/RadarPage.test.tsx b/plugins/tech-radar/src/components/RadarPage.test.tsx index f4b768d369..7215fc40df 100644 --- a/plugins/tech-radar/src/components/RadarPage.test.tsx +++ b/plugins/tech-radar/src/components/RadarPage.test.tsx @@ -85,6 +85,7 @@ describe('RadarPage', () => { height: 800, svgProps: { 'data-testid': 'tech-radar-svg' }, }; + jest.spyOn(mockClient, 'load'); const { getByText, getByTestId } = await renderInTestApp( @@ -100,6 +101,30 @@ describe('RadarPage', () => { getByText('Pick the recommended technologies for your projects'), ).toBeInTheDocument(); expect(getByTestId('tech-radar-svg')).toBeInTheDocument(); + expect(mockClient.load).toBeCalledWith(undefined); + }); + + it('should call load with id', async () => { + const techRadarProps = { + width: 1200, + height: 800, + svgProps: { 'data-testid': 'tech-radar-svg' }, + id: 'myId', + }; + jest.spyOn(mockClient, 'load'); + + const { getByTestId } = await renderInTestApp( + + + + + , + ); + + await waitForElement(() => getByTestId('tech-radar-svg')); + + expect(getByTestId('tech-radar-svg')).toBeInTheDocument(); + expect(mockClient.load).toBeCalledWith('myId'); }); it('should call the errorApi if load fails', async () => {