diff --git a/.changeset/late-news-chew.md b/.changeset/late-news-chew.md index 09ae191470..5552caf8fb 100644 --- a/.changeset/late-news-chew.md +++ b/.changeset/late-news-chew.md @@ -1,5 +1,5 @@ --- -'@backstage/plugin-tech-radar': minor +'@backstage/plugin-tech-radar': patch --- -Added SearchBar to allow filtering and a scroll bar to display hidden tech +Added `SearchBar` to allow filtering and a scroll bar to display hidden tech diff --git a/plugins/tech-radar/src/components/RadarComponent.tsx b/plugins/tech-radar/src/components/RadarComponent.tsx index 53748580c0..9abb200792 100644 --- a/plugins/tech-radar/src/components/RadarComponent.tsx +++ b/plugins/tech-radar/src/components/RadarComponent.tsx @@ -14,19 +14,19 @@ * limitations under the License. */ +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 Radar from '../components/Radar'; import { + RadarEntry, techRadarApiRef, TechRadarComponentProps, TechRadarLoaderResponse, } from '../api'; +import Radar from '../components/Radar'; import { Entry } from '../utils/types'; -import { Progress } from '@backstage/core-components'; -import { useApi, errorApiRef } from '@backstage/core-plugin-api'; - const useTechRadarLoader = (id: string | undefined) => { const errorApi = useApi(errorApiRef); const techRadarApi = useApi(techRadarApiRef); @@ -45,37 +45,44 @@ const useTechRadarLoader = (id: string | undefined) => { return { loading, value, error }; }; +function matchFilter(filter?: string): (entry: RadarEntry) => boolean { + const terms = filter + ?.toLocaleLowerCase('en-US') + .split(/\s/) + .map(e => e.trim()) + .filter(Boolean); + + if (!terms?.length) { + return () => true; + } + + return entry => { + const text = `${entry.title} ${ + entry.timeline[0]?.description || '' + }`.toLocaleLowerCase('en-US'); + return terms.every(term => text.includes(term)); + }; +} + const RadarComponent = (props: TechRadarComponentProps): JSX.Element => { const { loading, error, value: data } = useTechRadarLoader(props.id); const mapToEntries = ( - loaderResponse: TechRadarLoaderResponse | undefined, + loaderResponse: TechRadarLoaderResponse, ): Array => { - let filteredArray = loaderResponse!.entries; - if (props.searchText) { - // Compare the name or the description with the search input text - filteredArray = loaderResponse!.entries.filter( - element => - element.title - .toLowerCase() - .includes(props.searchText!.toLowerCase()) || - element.timeline[0].description - ?.toLowerCase() - .includes(props.searchText!.toLowerCase()), - ); - } - return filteredArray.map(entry => { - return { + return loaderResponse.entries + .filter(matchFilter(props.searchText)) + .map(entry => ({ id: entry.key, - quadrant: loaderResponse!.quadrants.find(q => q.id === entry.quadrant)!, + quadrant: loaderResponse.quadrants.find(q => q.id === entry.quadrant)!, title: entry.title, - ring: loaderResponse!.rings.find( + ring: loaderResponse.rings.find( r => r.id === entry.timeline[0].ringId, )!, timeline: entry.timeline.map(e => { return { date: e.date, - ring: loaderResponse!.rings.find(a => a.id === e.ringId)!, + ring: loaderResponse.rings.find(a => a.id === e.ringId)!, description: e.description, moved: e.moved, }; @@ -83,18 +90,17 @@ const RadarComponent = (props: TechRadarComponentProps): JSX.Element => { moved: entry.timeline[0].moved, description: entry.description || entry.timeline[0].description, url: entry.url, - }; - }); + })); }; return ( <> {loading && } - {!loading && !error && ( + {!loading && !error && data && ( )} diff --git a/plugins/tech-radar/src/components/RadarLegend/RadarLegend.tsx b/plugins/tech-radar/src/components/RadarLegend/RadarLegend.tsx index c96b79ee28..d2626a2dc3 100644 --- a/plugins/tech-radar/src/components/RadarLegend/RadarLegend.tsx +++ b/plugins/tech-radar/src/components/RadarLegend/RadarLegend.tsx @@ -13,10 +13,10 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import React from 'react'; import { makeStyles, Theme } from '@material-ui/core'; -import type { Quadrant, Ring, Entry } from '../../utils/types'; +import React from 'react'; import { WithLink } from '../../utils/components'; +import type { Entry, Quadrant, Ring } from '../../utils/types'; import { RadarDescription } from '../RadarDescription'; type Segments = { @@ -41,13 +41,13 @@ const useStyles = makeStyles(theme => ({ width: '100%', overflow: 'scroll', scrollbarWidth: 'thin', - // pointerEvents: 'none', + pointerEvents: 'none', }, quadrantHeading: { pointerEvents: 'none', userSelect: 'none', marginTop: 0, - marginBottom: theme.spacing(8 / (18 * 0.375)), + marginBottom: theme.spacing(2), fontSize: '18px', }, rings: { @@ -58,12 +58,16 @@ const useStyles = makeStyles(theme => ({ pageBreakInside: 'avoid', '-webkit-column-break-inside': 'avoid', fontSize: '12px', + marginBottom: theme.spacing(2), + }, + ringEmpty: { + color: theme.palette.text.secondary, }, ringHeading: { pointerEvents: 'none', userSelect: 'none', marginTop: 0, - marginBottom: theme.spacing(8 / (12 * 0.375)), + marginBottom: theme.spacing(1), fontSize: '12px', fontWeight: 800, }, @@ -177,19 +181,15 @@ const RadarLegend = (props: Props): JSX.Element => {

{ring.name}

{entries.length === 0 ? ( -

(empty)

+

(empty)

) : (
    {entries.map(entry => (
  1. onEntryMouseEnter(entry)) - } - onMouseLeave={ - onEntryMouseLeave && (() => onEntryMouseLeave(entry)) - } + onMouseEnter={() => onEntryMouseEnter?.(entry)} + onMouseLeave={() => onEntryMouseLeave?.(entry)} > ({ overflowXScroll: { @@ -47,24 +47,16 @@ export const RadarPage = ({ const classes = useStyles(); const [searchText, setSearchText] = React.useState(''); - const searchInput = ( - event: React.ChangeEvent, - ) => { - setSearchText(event.target.value); - }; - return (
    - { - searchInput(e); - }} + placeholder="Filter" + onChange={e => setSearchText(e.target.value)} /> This is used for visualizing the official guidelines of different diff --git a/plugins/tech-radar/src/components/RadarPlot/RadarPlot.tsx b/plugins/tech-radar/src/components/RadarPlot/RadarPlot.tsx index d9788be887..a5d7e0442c 100644 --- a/plugins/tech-radar/src/components/RadarPlot/RadarPlot.tsx +++ b/plugins/tech-radar/src/components/RadarPlot/RadarPlot.tsx @@ -55,12 +55,8 @@ const RadarPlot = (props: Props): JSX.Element => { quadrants={quadrants} rings={rings} entries={entries} - onEntryMouseEnter={ - onEntryMouseEnter && (entry => onEntryMouseEnter(entry)) - } - onEntryMouseLeave={ - onEntryMouseLeave && (entry => onEntryMouseLeave(entry)) - } + onEntryMouseEnter={entry => onEntryMouseEnter?.(entry)} + onEntryMouseLeave={entry => onEntryMouseLeave?.(entry)} /> @@ -76,8 +72,8 @@ const RadarPlot = (props: Props): JSX.Element => { description={entry.description} moved={entry.moved} title={entry.title} - onMouseEnter={onEntryMouseEnter && (() => onEntryMouseEnter(entry))} - onMouseLeave={onEntryMouseLeave && (() => onEntryMouseLeave(entry))} + onMouseEnter={() => onEntryMouseEnter?.(entry)} + onMouseLeave={() => onEntryMouseLeave?.(entry)} /> ))}