From 862595ce5014412f5c79de66ee33d66d8febaafb Mon Sep 17 00:00:00 2001 From: Jeff Durand Date: Thu, 18 Feb 2021 13:52:39 +0000 Subject: [PATCH 1/5] tech-radar: add description dialog box --- .../src/components/RadarComponent.tsx | 1 + .../RadarDescription.test.tsx | 43 +++++++++++++ .../RadarDescription/RadarDescription.tsx | 62 ++++++++++++++++++ .../src/components/RadarDescription/index.ts | 17 +++++ .../components/RadarEntry/RadarEntry.test.tsx | 36 +++++++++-- .../src/components/RadarEntry/RadarEntry.tsx | 47 +++++++++++++- .../components/RadarLegend/RadarLegend.tsx | 63 ++++++++++++++++++- .../src/components/RadarPlot/RadarPlot.tsx | 2 + plugins/tech-radar/src/utils/types.ts | 2 + 9 files changed, 262 insertions(+), 11 deletions(-) create mode 100644 plugins/tech-radar/src/components/RadarDescription/RadarDescription.test.tsx create mode 100644 plugins/tech-radar/src/components/RadarDescription/RadarDescription.tsx create mode 100644 plugins/tech-radar/src/components/RadarDescription/index.ts diff --git a/plugins/tech-radar/src/components/RadarComponent.tsx b/plugins/tech-radar/src/components/RadarComponent.tsx index 759fec62c3..bed45e63fc 100644 --- a/plugins/tech-radar/src/components/RadarComponent.tsx +++ b/plugins/tech-radar/src/components/RadarComponent.tsx @@ -68,6 +68,7 @@ const RadarComponent = (props: TechRadarComponentProps): JSX.Element => { }; }), moved: entry.timeline[0].moved, + description: entry.timeline[0].description, url: entry.url, }; }); diff --git a/plugins/tech-radar/src/components/RadarDescription/RadarDescription.test.tsx b/plugins/tech-radar/src/components/RadarDescription/RadarDescription.test.tsx new file mode 100644 index 0000000000..54b8ef0892 --- /dev/null +++ b/plugins/tech-radar/src/components/RadarDescription/RadarDescription.test.tsx @@ -0,0 +1,43 @@ +/* + * Copyright 2020 Spotify AB + * + * 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. + */ + +import React from 'react'; +import { render, screen } from '@testing-library/react'; +import { ThemeProvider } from '@material-ui/core'; +import { lightTheme } from '@backstage/theme'; + +import RadarDescription, { Props } from './RadarDescription'; + +const minProps: Props = { + open: true, + title: 'example-title', + description: 'example-description', + onClose: () => {}, +}; + +describe('RadarDescription', () => { + it('should render', () => { + render( + + + , + ); + + const radarDescription = screen.getByTestId('radar-description'); + expect(radarDescription).toBeInTheDocument(); + expect(screen.getByText(String(minProps.description))).toBeInTheDocument(); + }); +}); diff --git a/plugins/tech-radar/src/components/RadarDescription/RadarDescription.tsx b/plugins/tech-radar/src/components/RadarDescription/RadarDescription.tsx new file mode 100644 index 0000000000..ecef4900fb --- /dev/null +++ b/plugins/tech-radar/src/components/RadarDescription/RadarDescription.tsx @@ -0,0 +1,62 @@ +/* + * Copyright 2020 Spotify AB + * + * 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. + */ + +import React from 'react'; +import Dialog from '@material-ui/core/Dialog'; +import DialogTitle from '@material-ui/core/DialogTitle'; +import { Button, DialogActions, DialogContent } from '@material-ui/core'; +import LinkIcon from '@material-ui/icons/Link'; + +export type Props = { + open: boolean; + onClose: () => void; + title: string; + description: string; + url?: string; +}; + +const RadarDescription = (props: Props): JSX.Element => { + // const classes = useStyles(props); + const { open, onClose, title, description, url } = props; + + const handleClick = () => { + onClose(); + if (url) { + window.location.href = url; + } + }; + + return ( + + {title} + {description} + {url && ( + + + + )} + + ); +}; + +export default RadarDescription; diff --git a/plugins/tech-radar/src/components/RadarDescription/index.ts b/plugins/tech-radar/src/components/RadarDescription/index.ts new file mode 100644 index 0000000000..908e97701e --- /dev/null +++ b/plugins/tech-radar/src/components/RadarDescription/index.ts @@ -0,0 +1,17 @@ +/* + * Copyright 2020 Spotify AB + * + * 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 { default } from './RadarDescription'; diff --git a/plugins/tech-radar/src/components/RadarEntry/RadarEntry.test.tsx b/plugins/tech-radar/src/components/RadarEntry/RadarEntry.test.tsx index 2d24f301d1..0424624007 100644 --- a/plugins/tech-radar/src/components/RadarEntry/RadarEntry.test.tsx +++ b/plugins/tech-radar/src/components/RadarEntry/RadarEntry.test.tsx @@ -15,7 +15,8 @@ */ import React from 'react'; -import { render } from '@testing-library/react'; +import { render, screen } from '@testing-library/react'; +import userEvent from '@testing-library/user-event'; import { ThemeProvider } from '@material-ui/core'; import { lightTheme } from '@backstage/theme'; import GetBBoxPolyfill from '../../utils/polyfills/getBBox'; @@ -29,6 +30,12 @@ const minProps: Props = { color: 'red', }; +const optionalProps: Props = { + ...minProps, + title: 'example-title', + description: 'example-description', +}; + describe('RadarEntry', () => { beforeAll(() => { GetBBoxPolyfill.create(0, 0, 1000, 500); @@ -38,8 +45,8 @@ describe('RadarEntry', () => { GetBBoxPolyfill.remove(); }); - it('should render', () => { - const rendered = render( + it('should render link only', () => { + render( @@ -47,10 +54,29 @@ describe('RadarEntry', () => { , ); - const radarEntry = rendered.getByTestId('radar-entry'); + const radarEntry = screen.getByTestId('radar-entry'); const { x, y } = minProps; expect(radarEntry).toBeInTheDocument(); expect(radarEntry.getAttribute('transform')).toBe(`translate(${x}, ${y})`); - expect(rendered.getByText(String(minProps.value))).toBeInTheDocument(); + expect(screen.getByText(String(minProps.value))).toBeInTheDocument(); + }); + + it('should render with description', () => { + render( + + + + + , + ); + + userEvent.click(screen.getByRole('button')); + + const radarEntry = screen.getByTestId('radar-entry'); + expect(radarEntry).toBeInTheDocument(); + + const radarDescription = screen.getByTestId('radar-description'); + expect(radarDescription).toBeInTheDocument(); + expect(screen.getByText(String(minProps.value))).toBeInTheDocument(); }); }); diff --git a/plugins/tech-radar/src/components/RadarEntry/RadarEntry.tsx b/plugins/tech-radar/src/components/RadarEntry/RadarEntry.tsx index 29d35e01e2..f146eb5fa8 100644 --- a/plugins/tech-radar/src/components/RadarEntry/RadarEntry.tsx +++ b/plugins/tech-radar/src/components/RadarEntry/RadarEntry.tsx @@ -17,6 +17,7 @@ import React from 'react'; import { makeStyles, Theme } from '@material-ui/core'; import { WithLink } from '../../utils/components'; +import RadarDescription from '../RadarDescription'; export type Props = { x: number; @@ -25,6 +26,8 @@ export type Props = { color: string; url?: string; moved?: number; + description?: string; + title?: string; onMouseEnter?: (event: React.MouseEvent) => void; onMouseLeave?: (event: React.MouseEvent) => void; onClick?: (event: React.MouseEvent) => void; @@ -59,9 +62,12 @@ const makeBlip = (color: string, moved?: number) => { const RadarEntry = (props: Props): JSX.Element => { const classes = useStyles(props); + const [open, setOpen] = React.useState(false); const { moved, + description, + title, color, url, value, @@ -74,6 +80,18 @@ const RadarEntry = (props: Props): JSX.Element => { const blip = makeBlip(color, moved); + const handleClickOpen = () => { + setOpen(true); + }; + + const handleClose = () => { + setOpen(false); + }; + + const toggle = () => { + setOpen(!open); + }; + return ( { onClick={onClick} data-testid="radar-entry" > - - {blip} - + {' '} + {description ? ( + <> + + {blip} + + + + ) : ( + + {blip} + + )} {value} diff --git a/plugins/tech-radar/src/components/RadarLegend/RadarLegend.tsx b/plugins/tech-radar/src/components/RadarLegend/RadarLegend.tsx index e10993b010..998a3370c1 100644 --- a/plugins/tech-radar/src/components/RadarLegend/RadarLegend.tsx +++ b/plugins/tech-radar/src/components/RadarLegend/RadarLegend.tsx @@ -17,6 +17,7 @@ import React from 'react'; import { makeStyles, Theme } from '@material-ui/core'; import type { Quadrant, Ring, Entry } from '../../utils/types'; import { WithLink } from '../../utils/components'; +import RadarDescription from '../RadarDescription'; type Segments = { [k: number]: { [k: number]: Entry[] }; @@ -105,6 +106,60 @@ const RadarLegend = (props: Props): JSX.Element => { onEntryMouseLeave?: Props['onEntryMouseEnter']; }; + type RadarLegendLinkProps = { + url?: string; + description?: string; + title?: string; + }; + + const RadarLegendLink = ({ + url, + description, + title, + }: RadarLegendLinkProps) => { + const [open, setOpen] = React.useState(false); + + const handleClickOpen = () => { + setOpen(true); + }; + + const handleClose = () => { + setOpen(false); + }; + + const toggle = () => { + setOpen(!open); + }; + + if (description && url) { + return ( + <> + + {title} + + + + ); + } + return ( + + {title} + + ); + }; + const RadarLegendRing = ({ ring, entries, @@ -129,9 +184,11 @@ const RadarLegend = (props: Props): JSX.Element => { onEntryMouseLeave && (() => onEntryMouseLeave(entry)) } > - - {entry.title} - + ))} diff --git a/plugins/tech-radar/src/components/RadarPlot/RadarPlot.tsx b/plugins/tech-radar/src/components/RadarPlot/RadarPlot.tsx index 7f68ffe021..4dd11c6ccf 100644 --- a/plugins/tech-radar/src/components/RadarPlot/RadarPlot.tsx +++ b/plugins/tech-radar/src/components/RadarPlot/RadarPlot.tsx @@ -73,7 +73,9 @@ const RadarPlot = (props: Props): JSX.Element => { color={entry.color || ''} value={(entry?.index || 0) + 1} url={entry.url} + description={entry.description} moved={entry.moved} + title={entry.title} onMouseEnter={onEntryMouseEnter && (() => onEntryMouseEnter(entry))} onMouseLeave={onEntryMouseLeave && (() => onEntryMouseLeave(entry))} /> diff --git a/plugins/tech-radar/src/utils/types.ts b/plugins/tech-radar/src/utils/types.ts index 3322a67dcb..e4b2ef6fbe 100644 --- a/plugins/tech-radar/src/utils/types.ts +++ b/plugins/tech-radar/src/utils/types.ts @@ -68,6 +68,8 @@ export type Entry = { url?: string; // How this entry has recently moved; -1 for "down", +1 for "up", 0 for not moved moved?: MovedState; + // Most recent description to display in the UI + description?: string; active?: boolean; timeline?: Array; }; From 9f2b3a26e9e860aa1042eb83613edc3c99238e8a Mon Sep 17 00:00:00 2001 From: Jeff Durand Date: Thu, 18 Feb 2021 16:47:33 +0000 Subject: [PATCH 2/5] added changeset description --- .changeset/popular-donuts-fetch.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/popular-donuts-fetch.md diff --git a/.changeset/popular-donuts-fetch.md b/.changeset/popular-donuts-fetch.md new file mode 100644 index 0000000000..9681bdb875 --- /dev/null +++ b/.changeset/popular-donuts-fetch.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-tech-radar': patch +--- + +Added a dialog box that will show up when a you click on link on the radar and display the description if provided. From 5f5c98e2ae9d286f8f7bcbd65a7b05119f6f9e3a Mon Sep 17 00:00:00 2001 From: Jeff Durand Date: Thu, 18 Feb 2021 17:54:06 +0000 Subject: [PATCH 3/5] updated button to learn more based on reviewer suggestions --- .../src/components/RadarDescription/RadarDescription.tsx | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/plugins/tech-radar/src/components/RadarDescription/RadarDescription.tsx b/plugins/tech-radar/src/components/RadarDescription/RadarDescription.tsx index ecef4900fb..24e31dd34f 100644 --- a/plugins/tech-radar/src/components/RadarDescription/RadarDescription.tsx +++ b/plugins/tech-radar/src/components/RadarDescription/RadarDescription.tsx @@ -49,9 +49,8 @@ const RadarDescription = (props: Props): JSX.Element => { onClick={handleClick} color="primary" startIcon={} - variant="contained" > - Visit URL + LEARN MORE )} From 6262a5661448af85b44ebb14400e67e3030c3651 Mon Sep 17 00:00:00 2001 From: Jeff Durand Date: Fri, 19 Feb 2021 00:04:34 +0000 Subject: [PATCH 4/5] fixing based on review --- .../RadarDescription.test.tsx | 2 +- .../RadarDescription/RadarDescription.tsx | 8 ++-- .../src/components/RadarDescription/index.ts | 2 +- .../src/components/RadarEntry/RadarEntry.tsx | 40 +++++++++---------- .../components/RadarLegend/RadarLegend.tsx | 20 +++++----- 5 files changed, 38 insertions(+), 34 deletions(-) diff --git a/plugins/tech-radar/src/components/RadarDescription/RadarDescription.test.tsx b/plugins/tech-radar/src/components/RadarDescription/RadarDescription.test.tsx index 54b8ef0892..b19794042e 100644 --- a/plugins/tech-radar/src/components/RadarDescription/RadarDescription.test.tsx +++ b/plugins/tech-radar/src/components/RadarDescription/RadarDescription.test.tsx @@ -19,7 +19,7 @@ import { render, screen } from '@testing-library/react'; import { ThemeProvider } from '@material-ui/core'; import { lightTheme } from '@backstage/theme'; -import RadarDescription, { Props } from './RadarDescription'; +import { Props, RadarDescription } from './RadarDescription'; const minProps: Props = { open: true, diff --git a/plugins/tech-radar/src/components/RadarDescription/RadarDescription.tsx b/plugins/tech-radar/src/components/RadarDescription/RadarDescription.tsx index 24e31dd34f..20c489f630 100644 --- a/plugins/tech-radar/src/components/RadarDescription/RadarDescription.tsx +++ b/plugins/tech-radar/src/components/RadarDescription/RadarDescription.tsx @@ -29,7 +29,6 @@ export type Props = { }; const RadarDescription = (props: Props): JSX.Element => { - // const classes = useStyles(props); const { open, onClose, title, description, url } = props; const handleClick = () => { @@ -41,7 +40,9 @@ const RadarDescription = (props: Props): JSX.Element => { return ( - {title} + + {title} + {description} {url && ( @@ -49,6 +50,7 @@ const RadarDescription = (props: Props): JSX.Element => { onClick={handleClick} color="primary" startIcon={} + href={url} > LEARN MORE @@ -58,4 +60,4 @@ const RadarDescription = (props: Props): JSX.Element => { ); }; -export default RadarDescription; +export { RadarDescription }; diff --git a/plugins/tech-radar/src/components/RadarDescription/index.ts b/plugins/tech-radar/src/components/RadarDescription/index.ts index 908e97701e..748898cf0b 100644 --- a/plugins/tech-radar/src/components/RadarDescription/index.ts +++ b/plugins/tech-radar/src/components/RadarDescription/index.ts @@ -14,4 +14,4 @@ * limitations under the License. */ -export { default } from './RadarDescription'; +export { RadarDescription, Props } from './RadarDescription'; diff --git a/plugins/tech-radar/src/components/RadarEntry/RadarEntry.tsx b/plugins/tech-radar/src/components/RadarEntry/RadarEntry.tsx index f146eb5fa8..fb47a75c71 100644 --- a/plugins/tech-radar/src/components/RadarEntry/RadarEntry.tsx +++ b/plugins/tech-radar/src/components/RadarEntry/RadarEntry.tsx @@ -17,7 +17,7 @@ import React from 'react'; import { makeStyles, Theme } from '@material-ui/core'; import { WithLink } from '../../utils/components'; -import RadarDescription from '../RadarDescription'; +import { RadarDescription } from '../RadarDescription'; export type Props = { x: number; @@ -101,26 +101,26 @@ const RadarEntry = (props: Props): JSX.Element => { data-testid="radar-entry" > {' '} + {open && ( + + )} {description ? ( - <> - - {blip} - - - + + {blip} + ) : ( {blip} diff --git a/plugins/tech-radar/src/components/RadarLegend/RadarLegend.tsx b/plugins/tech-radar/src/components/RadarLegend/RadarLegend.tsx index 998a3370c1..d4ef38d5ee 100644 --- a/plugins/tech-radar/src/components/RadarLegend/RadarLegend.tsx +++ b/plugins/tech-radar/src/components/RadarLegend/RadarLegend.tsx @@ -17,7 +17,7 @@ import React from 'react'; import { makeStyles, Theme } from '@material-ui/core'; import type { Quadrant, Ring, Entry } from '../../utils/types'; import { WithLink } from '../../utils/components'; -import RadarDescription from '../RadarDescription'; +import { RadarDescription } from '../RadarDescription'; type Segments = { [k: number]: { [k: number]: Entry[] }; @@ -131,7 +131,7 @@ const RadarLegend = (props: Props): JSX.Element => { setOpen(!open); }; - if (description && url) { + if (description) { return ( <> { > {title} - + {open && ( + + )} ); } From 9abacc8ebc1425bce1625003462575f0c61c3a98 Mon Sep 17 00:00:00 2001 From: Jeff Durand Date: Fri, 19 Feb 2021 00:10:33 +0000 Subject: [PATCH 5/5] need to export type as type --- plugins/tech-radar/src/components/RadarDescription/index.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/plugins/tech-radar/src/components/RadarDescription/index.ts b/plugins/tech-radar/src/components/RadarDescription/index.ts index 748898cf0b..027407718e 100644 --- a/plugins/tech-radar/src/components/RadarDescription/index.ts +++ b/plugins/tech-radar/src/components/RadarDescription/index.ts @@ -14,4 +14,5 @@ * limitations under the License. */ -export { RadarDescription, Props } from './RadarDescription'; +export { RadarDescription } from './RadarDescription'; +export type { Props } from './RadarDescription';