Merge pull request #7375 from szubster/tech-radar-api-reference

Improve API Reference in Tech Radar Plugin
This commit is contained in:
Patrik Oldsberg
2021-09-29 13:33:45 +02:00
committed by GitHub
9 changed files with 276 additions and 119 deletions
+39 -62
View File
@@ -9,138 +9,119 @@ import { ApiRef } from '@backstage/core-plugin-api';
import { BackstagePlugin } from '@backstage/core-plugin-api';
import { RouteRef } from '@backstage/core-plugin-api';
// Warning: (ae-missing-release-tag) "MovedState" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
//
// @public
export enum MovedState {
Down = -1,
NoChange = 0,
Up = 1,
}
// Warning: (ae-missing-release-tag) "RadarEntry" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
//
// @public (undocumented)
// @public
export interface RadarEntry {
// (undocumented)
description?: string;
// (undocumented)
id: string;
// (undocumented)
key: string;
// (undocumented)
quadrant: string;
// (undocumented)
timeline: Array<RadarEntrySnapshot>;
// (undocumented)
title: string;
// (undocumented)
url: string;
}
// Warning: (ae-missing-release-tag) "RadarEntrySnapshot" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
//
// @public (undocumented)
// @public
export interface RadarEntrySnapshot {
// (undocumented)
date: Date;
// (undocumented)
description?: string;
// Warning: (ae-forgotten-export) The symbol "MovedState" needs to be exported by the entry point index.d.ts
//
// (undocumented)
moved?: MovedState;
// (undocumented)
ringId: string;
}
// Warning: (ae-missing-release-tag) "RadarPage" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
//
// @public
export function RadarPage(props: TechRadarPageProps): JSX.Element;
// Warning: (ae-missing-release-tag) "RadarQuadrant" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
//
// @public (undocumented)
// @public
export interface RadarQuadrant {
// (undocumented)
id: string;
// (undocumented)
name: string;
}
// Warning: (ae-missing-release-tag) "RadarRing" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
//
// @public (undocumented)
// @public
export interface RadarRing {
// (undocumented)
color: string;
// (undocumented)
id: string;
// (undocumented)
name: string;
}
// Warning: (ae-missing-release-tag) "RadarPage" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
// Warning: (ae-missing-release-tag) "Router" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
//
// @public (undocumented)
export const Router: {
({ title, subtitle, pageTitle, ...props }: TechRadarPageProps): JSX.Element;
defaultProps: {
title: string;
subtitle: string;
pageTitle: string;
};
};
// @public @deprecated (undocumented)
export const Router: typeof RadarPage;
// Warning: (ae-missing-release-tag) "TechRadarApi" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
//
// @public (undocumented)
// @public
export interface TechRadarApi {
load: (id: string | undefined) => Promise<TechRadarLoaderResponse>;
}
// Warning: (ae-missing-release-tag) "techRadarApiRef" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
//
// @public (undocumented)
// @public
export const techRadarApiRef: ApiRef<TechRadarApi>;
// Warning: (ae-missing-release-tag) "RadarComponent" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
//
// @public (undocumented)
export const TechRadarComponent: (
props: TechRadarComponentProps,
) => JSX.Element;
// @public
export function TechRadarComponent(props: TechRadarComponentProps): JSX.Element;
// Warning: (ae-missing-release-tag) "TechRadarComponentProps" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
//
// @public (undocumented)
// @public
export interface TechRadarComponentProps {
// (undocumented)
height: number;
// (undocumented)
id?: string;
// (undocumented)
searchText?: string;
// (undocumented)
svgProps?: object;
// (undocumented)
width: number;
}
// Warning: (ae-missing-release-tag) "TechRadarLoaderResponse" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
//
// @public (undocumented)
// @public
export interface TechRadarLoaderResponse {
// (undocumented)
entries: RadarEntry[];
// (undocumented)
quadrants: RadarQuadrant[];
// (undocumented)
rings: RadarRing[];
}
// Warning: (ae-missing-release-tag) "TechRadarPage" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
//
// @public (undocumented)
export const TechRadarPage: {
({ title, subtitle, pageTitle, ...props }: TechRadarPageProps): JSX.Element;
defaultProps: {
title: string;
subtitle: string;
pageTitle: string;
};
};
// @public
export const TechRadarPage: RadarPage;
// Warning: (ae-missing-release-tag) "TechRadarPageProps" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
//
// @public
export interface TechRadarPageProps extends TechRadarComponentProps {
pageTitle?: string;
subtitle?: string;
title?: string;
}
// Warning: (ae-missing-release-tag) "techRadarPlugin" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
//
// @public (undocumented)
// @public
const techRadarPlugin: BackstagePlugin<
{
root: RouteRef<undefined>;
@@ -149,8 +130,4 @@ const techRadarPlugin: BackstagePlugin<
>;
export { techRadarPlugin as plugin };
export { techRadarPlugin };
// Warnings were encountered during analysis:
//
// src/components/RadarPage.d.ts:9:5 - (ae-forgotten-export) The symbol "TechRadarPageProps" needs to be exported by the entry point index.d.ts
```
+117 -16
View File
@@ -13,15 +13,26 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { ApiRef, createApiRef } from '@backstage/core-plugin-api';
import { MovedState } from './utils/types';
import { createApiRef } from '@backstage/core-plugin-api';
export const techRadarApiRef = createApiRef<TechRadarApi>({
id: 'plugin.techradar.service',
description: 'Used to populate data in the TechRadar plugin',
});
/**
* {@link @backstage/core-plugin-api#ApiRef} for the {@link TechRadarApi}
*/
export const techRadarApiRef: ApiRef<TechRadarApi> = createApiRef<TechRadarApi>(
{
id: 'plugin.techradar.service',
description: 'Used to populate data in the TechRadar plugin',
},
);
/**
* Tech Radar API responsible for loading data for the plugin
*
* @remarks
*
* This should be implemented by user, as {@link https://github.com/backstage/backstage/blob/master/plugins/tech-radar/src/sample.ts | default}
* serves only some static data for example purposes
*/
export interface TechRadarApi {
/**
* Loads the TechRadar response data to pass through to the TechRadar component.
@@ -34,52 +45,142 @@ export interface TechRadarApi {
* Types related to the Radar's visualization.
*/
/**
* Tech Radar Ring which indicates stage of {@link RadarEntry}
*/
export interface RadarRing {
/**
* ID of the Ring
*/
id: string;
/**
* Display name of the Ring
*/
name: string;
/**
* Color used for entries in particular Ring
*
* @remarks
*
* Supports any value parseable by {@link https://www.npmjs.com/package/color-string | color-string}
*/
color: string;
}
/**
* Tech Radar Quadrant which represent area/topic of {@link RadarEntry}
*/
export interface RadarQuadrant {
/**
* ID of the Quadrant
*/
id: string;
/**
* Display name of the Quadrant
*/
name: string;
}
/**
* Single Entry in Tech Radar
*/
export interface RadarEntry {
key: string; // react key
/**
* React key to use for this Entry
*/
key: string;
/**
* ID of this Radar Entry
*/
id: string;
/**
* ID of {@link RadarQuadrant} this Entry belongs to
*/
quadrant: string;
/**
* Display name of the Entry
*/
title: string;
/**
* User-clickable URL when rendered in Radar
*
* @remarks
*
* You can use `#` if you don't want to provide any other url
*/
url: string;
/**
* History of the Entry moving through {@link RadarRing}
*/
timeline: Array<RadarEntrySnapshot>;
/**
* Description of the Entry
*/
description?: string;
}
/**
* State of {@link RadarEntry} at given point in time
*/
export interface RadarEntrySnapshot {
/**
* Point in time when change happened
*/
date: Date;
/**
* ID of {@link RadarRing}
*/
ringId: string;
/**
* Description of change
*/
description?: string;
/**
* Indicates trend compared to previous snapshot
*/
moved?: MovedState;
}
/**
* Indicates how {@link RadarEntry} moved though {@link RadarRing} on {@link RadarEntry.timeline}
*/
export enum MovedState {
/**
* Moved down
*/
Down = -1,
/**
* Didn't move
*/
NoChange = 0,
/**
* Move up
*/
Up = 1,
}
/*
* Types related to data collection for the Radar.
*/
/**
* Response from {@link TechRadarApi}
*/
export interface TechRadarLoaderResponse {
/**
* Quadrant of Tech Radar. Should be 4
*/
quadrants: RadarQuadrant[];
/**
* Rings of Tech Radar
*/
rings: RadarRing[];
/**
* Entries visualised in Tech Radar
*/
entries: RadarEntry[];
}
/*
* Set up the Radar as a Backstage component.
*/
export interface TechRadarComponentProps {
id?: string;
width: number;
height: number;
svgProps?: object;
searchText?: string;
}
@@ -22,7 +22,7 @@ import { act } from 'react-dom/test-utils';
import { withLogCollector } from '@backstage/test-utils';
import GetBBoxPolyfill from '../utils/polyfills/getBBox';
import RadarComponent from './RadarComponent';
import { RadarComponent } from './RadarComponent';
import { TechRadarLoaderResponse, techRadarApiRef, TechRadarApi } from '../api';
import { ApiRegistry, ApiProvider } from '@backstage/core-app-api';
@@ -18,12 +18,7 @@ import { Progress } from '@backstage/core-components';
import { errorApiRef, useApi } from '@backstage/core-plugin-api';
import React, { useEffect } from 'react';
import { useAsync } from 'react-use';
import {
RadarEntry,
techRadarApiRef,
TechRadarComponentProps,
TechRadarLoaderResponse,
} from '../api';
import { RadarEntry, techRadarApiRef, TechRadarLoaderResponse } from '../api';
import Radar from '../components/Radar';
import { Entry } from '../utils/types';
@@ -64,7 +59,44 @@ function matchFilter(filter?: string): (entry: RadarEntry) => boolean {
};
}
const RadarComponent = (props: TechRadarComponentProps): JSX.Element => {
/**
* Properties of {@link TechRadarComponent}
*/
export interface TechRadarComponentProps {
/**
* ID of this Tech Radar
*
* @remarks
*
* Used when there are multiple Tech Radars and passed to {@link TechRadarApi.load}
*/
id?: string;
/**
* Width of Tech Radar
*/
width: number;
/**
* Height of Tech Radar
*/
height: number;
/**
* Custom React props to the `<svg>` element created for Tech Radar
*/
svgProps?: object;
/**
* Text to filter {@link RadarEntry} inside Tech Radar
*/
searchText?: string;
}
/**
* Main React component of Tech Radar
*
* @remarks
*
* For advanced use cases. Typically, you want to use {@link TechRadarPage}
*/
export function RadarComponent(props: TechRadarComponentProps) {
const { loading, error, value: data } = useTechRadarLoader(props.id);
const mapToEntries = (
@@ -106,6 +138,4 @@ const RadarComponent = (props: TechRadarComponentProps): JSX.Element => {
)}
</>
);
};
export default RadarComponent;
}
+27 -18
View File
@@ -23,8 +23,7 @@ import {
} from '@backstage/core-components';
import { Grid, Input, makeStyles } from '@material-ui/core';
import React from 'react';
import { TechRadarComponentProps } from '../api';
import RadarComponent from '../components/RadarComponent';
import { RadarComponent, TechRadarComponentProps } from './RadarComponent';
const useStyles = makeStyles(() => ({
overflowXScroll: {
@@ -32,18 +31,34 @@ const useStyles = makeStyles(() => ({
},
}));
export type TechRadarPageProps = TechRadarComponentProps & {
/**
* Properties for {@link TechRadarPage}
*/
export interface TechRadarPageProps extends TechRadarComponentProps {
/**
* Title
*/
title?: string;
/**
* Subtitle
*/
subtitle?: string;
/**
* Page Title
*/
pageTitle?: string;
};
}
export const RadarPage = ({
title,
subtitle,
pageTitle,
...props
}: TechRadarPageProps): JSX.Element => {
/**
* Main Page of Tech Radar
*/
export function RadarPage(props: TechRadarPageProps) {
const {
title = 'Tech Radar',
subtitle = 'Pick the recommended technologies for your projects',
pageTitle = 'Company Radar',
...componentProps
} = props;
const classes = useStyles();
const [searchText, setSearchText] = React.useState('');
@@ -66,16 +81,10 @@ export const RadarPage = ({
</ContentHeader>
<Grid container spacing={3} direction="row">
<Grid item xs={12} sm={6} md={4}>
<RadarComponent searchText={searchText} {...props} />
<RadarComponent searchText={searchText} {...componentProps} />
</Grid>
</Grid>
</Content>
</Page>
);
};
RadarPage.defaultProps = {
title: 'Tech Radar',
subtitle: 'Pick the recommended technologies for your projects',
pageTitle: 'Company Radar',
};
}
@@ -0,0 +1,33 @@
/*
* Copyright 2021 The Backstage Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
export { RadarComponent as TechRadarComponent } from './RadarComponent';
export type { TechRadarComponentProps } from './RadarComponent';
export * from './RadarPage';
/*
* Copyright 2021 The Backstage Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+8 -6
View File
@@ -20,20 +20,22 @@
* @packageDocumentation
*/
import { RadarPage } from './components';
export {
techRadarPlugin,
techRadarPlugin as plugin,
TechRadarPage,
} from './plugin';
export { RadarPage as Router } from './components/RadarPage';
export * from './components';
/**
* @deprecated Use plugin extensions instead
*/
export const Router = RadarPage;
/**
* The TypeScript API for configuring Tech Radar.
*/
export * from './api';
/**
* The React component for more advanced use cases.
*/
export { default as TechRadarComponent } from './components/RadarComponent';
+10
View File
@@ -28,6 +28,9 @@ const rootRouteRef = createRouteRef({
title: 'Tech Radar',
});
/**
* Tech Radar plugin instance
*/
export const techRadarPlugin = createPlugin({
id: 'tech-radar',
routes: {
@@ -36,6 +39,13 @@ export const techRadarPlugin = createPlugin({
apis: [createApiFactory(techRadarApiRef, new SampleTechRadarApi())],
});
/**
* Main Tech Radar Page
*
* @remarks
*
* Uses {@link TechRadarPageProps} as props
*/
export const TechRadarPage = techRadarPlugin.provide(
createRoutableExtension({
component: () => import('./components/RadarPage').then(m => m.RadarPage),
+1 -6
View File
@@ -13,6 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { MovedState } from '../api';
// Parameters for a ring; its index in an array determines how close to the center this ring is.
export type Ring = {
@@ -45,12 +46,6 @@ export type Segment = {
random: Function;
};
export enum MovedState {
Down = -1,
NoChange = 0,
Up = 1,
}
export type Entry = {
id: string;
index?: number;