feat(techradar-plugin) add techradar blip history backend support (#3191)
* add techradar entry history data structure * updated names and added changeset * fix docs Co-authored-by: Omer Farooq <17722640+o-farooq@users.noreply.github.com>
This commit is contained in:
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/plugin-tech-radar': minor
|
||||
---
|
||||
|
||||
Added tech radar blip history backend support and normalized the data structure
|
||||
@@ -34,11 +34,17 @@ export interface RadarQuadrant {
|
||||
export interface RadarEntry {
|
||||
key: string; // react key
|
||||
id: string;
|
||||
moved: MovedState;
|
||||
quadrant: RadarQuadrant;
|
||||
ring: RadarRing;
|
||||
quadrant: string;
|
||||
title: string;
|
||||
url: string;
|
||||
timeline: Array<RadarEntrySnapshot>;
|
||||
}
|
||||
|
||||
export interface RadarEntrySnapshot {
|
||||
date: Date;
|
||||
ringId: string;
|
||||
description?: string;
|
||||
moved?: MovedState;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -20,6 +20,7 @@ import { useAsync } from 'react-use';
|
||||
import Radar from '../components/Radar';
|
||||
import { TechRadarComponentProps, TechRadarLoaderResponse } from '../api';
|
||||
import getSampleData from '../sampleData';
|
||||
import { Entry } from '../utils/types';
|
||||
|
||||
const useTechRadarLoader = (props: TechRadarComponentProps) => {
|
||||
const errorApi = useApi<ErrorApi>(errorApiRef);
|
||||
@@ -47,6 +48,29 @@ const useTechRadarLoader = (props: TechRadarComponentProps) => {
|
||||
const RadarComponent = (props: TechRadarComponentProps): JSX.Element => {
|
||||
const { loading, error, value: data } = useTechRadarLoader(props);
|
||||
|
||||
const mapToEntries = (
|
||||
loaderResponse: TechRadarLoaderResponse | undefined,
|
||||
): Array<Entry> => {
|
||||
return loaderResponse!.entries.map(entry => {
|
||||
return {
|
||||
id: entry.key,
|
||||
quadrant: loaderResponse!.quadrants.find(q => q.id === entry.quadrant)!,
|
||||
title: entry.title,
|
||||
ring: loaderResponse!.rings.find(
|
||||
r => r.id === entry.timeline[0].ringId,
|
||||
)!,
|
||||
history: entry.timeline.map(e => {
|
||||
return {
|
||||
date: e.date,
|
||||
ring: loaderResponse!.rings.find(a => a.id === e.ringId)!,
|
||||
description: e.description,
|
||||
moved: e.moved,
|
||||
};
|
||||
}),
|
||||
};
|
||||
});
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
{loading && <Progress />}
|
||||
@@ -55,7 +79,7 @@ const RadarComponent = (props: TechRadarComponentProps): JSX.Element => {
|
||||
{...props}
|
||||
rings={data!.rings}
|
||||
quadrants={data!.quadrants}
|
||||
entries={data!.entries}
|
||||
entries={mapToEntries(data)}
|
||||
/>
|
||||
)}
|
||||
</>
|
||||
|
||||
@@ -35,85 +35,132 @@ quadrants.push({ id: 'process', name: 'Process' });
|
||||
|
||||
const entries = new Array<RadarEntry>();
|
||||
entries.push({
|
||||
moved: 0,
|
||||
ring: { id: 'use', name: 'USE', color: '#93c47d' },
|
||||
timeline: [
|
||||
{
|
||||
moved: 0,
|
||||
ringId: 'use',
|
||||
date: new Date('2020-08-06'),
|
||||
description:
|
||||
'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua',
|
||||
},
|
||||
],
|
||||
url: '#',
|
||||
key: 'javascript',
|
||||
id: 'javascript',
|
||||
title: 'JavaScript',
|
||||
quadrant: { id: 'languages', name: 'Languages' },
|
||||
quadrant: 'languages',
|
||||
});
|
||||
entries.push({
|
||||
moved: 0,
|
||||
ring: { id: 'use', name: 'USE', color: '#93c47d' },
|
||||
timeline: [
|
||||
{
|
||||
moved: 0,
|
||||
ringId: 'use',
|
||||
date: new Date('2020-08-06'),
|
||||
description:
|
||||
'Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat',
|
||||
},
|
||||
],
|
||||
url: '#',
|
||||
key: 'typescript',
|
||||
id: 'typescript',
|
||||
title: 'TypeScript',
|
||||
quadrant: { id: 'languages', name: 'Languages' },
|
||||
quadrant: 'languages',
|
||||
});
|
||||
entries.push({
|
||||
moved: 0,
|
||||
ring: { id: 'use', name: 'USE', color: '#93c47d' },
|
||||
timeline: [
|
||||
{
|
||||
moved: 0,
|
||||
ringId: 'use',
|
||||
date: new Date('2020-08-06'),
|
||||
},
|
||||
],
|
||||
url: '#',
|
||||
key: 'webpack',
|
||||
id: 'webpack',
|
||||
title: 'Webpack',
|
||||
quadrant: { id: 'frameworks', name: 'Frameworks' },
|
||||
quadrant: 'frameworks',
|
||||
});
|
||||
entries.push({
|
||||
moved: 0,
|
||||
ring: { id: 'use', name: 'USE', color: '#93c47d' },
|
||||
timeline: [
|
||||
{
|
||||
moved: 0,
|
||||
ringId: 'use',
|
||||
date: new Date('2020-08-06'),
|
||||
},
|
||||
],
|
||||
url: '#',
|
||||
key: 'react',
|
||||
id: 'react',
|
||||
title: 'React',
|
||||
quadrant: { id: 'frameworks', name: 'Frameworks' },
|
||||
quadrant: 'frameworks',
|
||||
});
|
||||
entries.push({
|
||||
moved: 0,
|
||||
ring: { id: 'use', name: 'USE', color: '#93c47d' },
|
||||
timeline: [
|
||||
{
|
||||
moved: 0,
|
||||
ringId: 'use',
|
||||
date: new Date('2020-08-06'),
|
||||
},
|
||||
],
|
||||
url: '#',
|
||||
key: 'code-reviews',
|
||||
id: 'code-reviews',
|
||||
title: 'Code Reviews',
|
||||
quadrant: { id: 'process', name: 'Process' },
|
||||
quadrant: 'process',
|
||||
});
|
||||
entries.push({
|
||||
moved: 0,
|
||||
timeline: [
|
||||
{
|
||||
moved: 0,
|
||||
ringId: 'assess',
|
||||
date: new Date('2020-08-06'),
|
||||
},
|
||||
],
|
||||
url: '#',
|
||||
key: 'mob-programming',
|
||||
id: 'mob-programming',
|
||||
title: 'Mob Programming',
|
||||
quadrant: { id: 'process', name: 'Process' },
|
||||
ring: { id: 'assess', name: 'ASSESS', color: '#fbdb84' },
|
||||
quadrant: 'process',
|
||||
});
|
||||
entries.push({
|
||||
moved: 0,
|
||||
timeline: [
|
||||
{
|
||||
moved: 0,
|
||||
ringId: 'use',
|
||||
date: new Date('2020-08-06'),
|
||||
},
|
||||
],
|
||||
url: '#',
|
||||
key: 'docs-like-code',
|
||||
id: 'docs-like-code',
|
||||
title: 'Docs-like-code',
|
||||
quadrant: { id: 'process', name: 'Process' },
|
||||
ring: { id: 'use', name: 'USE', color: '#93c47d' },
|
||||
quadrant: 'process',
|
||||
});
|
||||
entries.push({
|
||||
moved: 0,
|
||||
timeline: [
|
||||
{
|
||||
ringId: 'hold',
|
||||
date: new Date('2020-08-06'),
|
||||
},
|
||||
],
|
||||
url: '#',
|
||||
key: 'force-push',
|
||||
id: 'force-push',
|
||||
title: 'Force push to master',
|
||||
quadrant: { id: 'process', name: 'Process' },
|
||||
ring: { id: 'hold', name: 'HOLD', color: '#93c47d' },
|
||||
quadrant: 'process',
|
||||
});
|
||||
entries.push({
|
||||
moved: 0,
|
||||
ring: { id: 'use', name: 'USE', color: '#93c47d' },
|
||||
timeline: [
|
||||
{
|
||||
ringId: 'use',
|
||||
date: new Date('2020-08-06'),
|
||||
},
|
||||
],
|
||||
url: '#',
|
||||
key: 'github-actions',
|
||||
id: 'github-actions',
|
||||
title: 'GitHub Actions',
|
||||
quadrant: { id: 'infrastructure', name: 'Infrastructure' },
|
||||
quadrant: 'infrastructure',
|
||||
});
|
||||
|
||||
export default function getSampleData(): Promise<TechRadarLoaderResponse> {
|
||||
|
||||
@@ -69,6 +69,14 @@ export type Entry = {
|
||||
// How this entry has recently moved; -1 for "down", +1 for "up", 0 for not moved
|
||||
moved?: MovedState;
|
||||
active?: boolean;
|
||||
timeline?: Array<EntrySnapshot>;
|
||||
};
|
||||
|
||||
export type EntrySnapshot = {
|
||||
date: Date;
|
||||
ring: Ring;
|
||||
description?: string;
|
||||
moved?: MovedState;
|
||||
};
|
||||
|
||||
// The same as Entry except quadrant/ring are declared by their string ID instead of being the actual objects
|
||||
|
||||
Reference in New Issue
Block a user