Merge pull request #6243 from Sainsburys/6180-add-tech-radar-id
Add an optional id prop and pass to load API
This commit is contained in:
@@ -82,7 +82,9 @@ import {
|
||||
} from '@backstage/plugin-tech-radar';
|
||||
|
||||
class MyOwnClient implements TechRadarApi {
|
||||
async load(): Promise<TechRadarLoaderResponse> {
|
||||
async load(id: string | undefined): Promise<TechRadarLoaderResponse> {
|
||||
// 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 `<svg>` 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.
|
||||
|
||||
@@ -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<TechRadarLoaderResponse>;
|
||||
load: (id: string | undefined) => Promise<TechRadarLoaderResponse>;
|
||||
}
|
||||
|
||||
// @public (undocumented)
|
||||
@@ -78,17 +77,19 @@ export const techRadarApiRef: ApiRef<TechRadarApi>;
|
||||
// @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[];
|
||||
|
||||
@@ -23,11 +23,14 @@ export const techRadarApiRef = createApiRef<TechRadarApi>({
|
||||
});
|
||||
|
||||
export interface TechRadarApi {
|
||||
// Loads the TechRadar response data to pass through to the TechRadar component
|
||||
load: () => Promise<TechRadarLoaderResponse>;
|
||||
/**
|
||||
* 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<TechRadarLoaderResponse>;
|
||||
}
|
||||
|
||||
/**
|
||||
/*
|
||||
* 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;
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -85,6 +85,7 @@ describe('RadarPage', () => {
|
||||
height: 800,
|
||||
svgProps: { 'data-testid': 'tech-radar-svg' },
|
||||
};
|
||||
jest.spyOn(mockClient, 'load');
|
||||
|
||||
const { getByText, getByTestId } = await renderInTestApp(
|
||||
<ThemeProvider theme={lightTheme}>
|
||||
@@ -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(
|
||||
<ThemeProvider theme={lightTheme}>
|
||||
<ApiProvider apis={ApiRegistry.from([[techRadarApiRef, mockClient]])}>
|
||||
<RadarPage {...techRadarProps} />
|
||||
</ApiProvider>
|
||||
</ThemeProvider>,
|
||||
);
|
||||
|
||||
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 () => {
|
||||
|
||||
Reference in New Issue
Block a user