From 4e767e0f8f19a19a20a4f9faa8190201c8ea3eae Mon Sep 17 00:00:00 2001 From: Kevin Silva Date: Fri, 14 Apr 2023 17:49:21 +0200 Subject: [PATCH] SONAR-19020 Create indicator-type components for the new UI --- .../config/jest/SetupReactTestingLibrary.ts | 2 + server/sonar-web/design-system/package.json | 1 + .../src/components/CoverageIndicator.tsx | 70 +++++++ .../src/components/DonutChart.tsx | 87 +++++++++ .../src/components/DuplicationsIndicator.tsx | 152 +++++++++++++++ .../src/components/MetricsRatingBadge.tsx | 69 +++++++ .../src/components/SizeIndicator.tsx | 55 ++++++ .../__tests__/CoverageIndicator-test.tsx | 39 ++++ .../__tests__/DuplicationsIndicator-test.tsx | 43 +++++ .../__tests__/MetricsRatingBadge-test.tsx | 39 ++++ .../__tests__/SizeIndicator-test.tsx | 38 ++++ .../CoverageIndicator-test.tsx.snap | 49 +++++ .../DuplicationsIndicator-test.tsx.snap | 181 ++++++++++++++++++ .../src/components/icons/Icon.tsx | 2 + .../src/components/icons/NoDataIcon.tsx | 34 ++++ .../src/components/icons/index.ts | 1 + .../design-system/src/components/index.ts | 4 + .../design-system/src/theme/light.ts | 13 +- .../design-system/src/types/measures.ts | 49 +++++ server/sonar-web/yarn.lock | 1 + 20 files changed, 923 insertions(+), 6 deletions(-) create mode 100644 server/sonar-web/design-system/src/components/CoverageIndicator.tsx create mode 100644 server/sonar-web/design-system/src/components/DonutChart.tsx create mode 100644 server/sonar-web/design-system/src/components/DuplicationsIndicator.tsx create mode 100644 server/sonar-web/design-system/src/components/MetricsRatingBadge.tsx create mode 100644 server/sonar-web/design-system/src/components/SizeIndicator.tsx create mode 100644 server/sonar-web/design-system/src/components/__tests__/CoverageIndicator-test.tsx create mode 100644 server/sonar-web/design-system/src/components/__tests__/DuplicationsIndicator-test.tsx create mode 100644 server/sonar-web/design-system/src/components/__tests__/MetricsRatingBadge-test.tsx create mode 100644 server/sonar-web/design-system/src/components/__tests__/SizeIndicator-test.tsx create mode 100644 server/sonar-web/design-system/src/components/__tests__/__snapshots__/CoverageIndicator-test.tsx.snap create mode 100644 server/sonar-web/design-system/src/components/__tests__/__snapshots__/DuplicationsIndicator-test.tsx.snap create mode 100644 server/sonar-web/design-system/src/components/icons/NoDataIcon.tsx create mode 100644 server/sonar-web/design-system/src/types/measures.ts diff --git a/server/sonar-web/design-system/config/jest/SetupReactTestingLibrary.ts b/server/sonar-web/design-system/config/jest/SetupReactTestingLibrary.ts index afaa0a4fcfb..a8e15b082c5 100644 --- a/server/sonar-web/design-system/config/jest/SetupReactTestingLibrary.ts +++ b/server/sonar-web/design-system/config/jest/SetupReactTestingLibrary.ts @@ -19,7 +19,9 @@ */ import '@testing-library/jest-dom'; import { configure } from '@testing-library/react'; +import React from 'react'; configure({ asyncUtilTimeout: 3000, }); +global.React = React; diff --git a/server/sonar-web/design-system/package.json b/server/sonar-web/design-system/package.json index 610c32ffd8a..397174a46a8 100644 --- a/server/sonar-web/design-system/package.json +++ b/server/sonar-web/design-system/package.json @@ -50,6 +50,7 @@ "@primer/octicons-react": "18.3.0", "classnames": "2.3.2", "clipboard": "2.0.11", + "d3-shape": "3.2.0", "lodash": "4.17.21", "react": "17.0.2", "react-dom": "17.0.2", diff --git a/server/sonar-web/design-system/src/components/CoverageIndicator.tsx b/server/sonar-web/design-system/src/components/CoverageIndicator.tsx new file mode 100644 index 00000000000..83489d29d1b --- /dev/null +++ b/server/sonar-web/design-system/src/components/CoverageIndicator.tsx @@ -0,0 +1,70 @@ +/* + * SonarQube + * Copyright (C) 2009-2023 SonarSource SA + * mailto:info AT sonarsource DOT com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +import { useTheme } from '@emotion/react'; +import { themeColor } from '../helpers/theme'; +import { DonutChart } from './DonutChart'; +import { NoDataIcon } from './icons'; + +const SIZE_TO_WIDTH_MAPPING = { xs: 16, sm: 24, md: 36 }; +const SIZE_TO_THICKNESS_MAPPING = { xs: 2, sm: 3, md: 4 }; +const FULL_PERCENT = 100; +const PAD_ANGLE = 0.1; + +export interface CoverageIndicatorProps { + size?: 'xs' | 'sm' | 'md'; + value?: number | string; +} + +export function CoverageIndicator({ size = 'sm', value }: CoverageIndicatorProps) { + const theme = useTheme(); + const width = SIZE_TO_WIDTH_MAPPING[size]; + const thickness = SIZE_TO_THICKNESS_MAPPING[size]; + + if (value === undefined) { + return ; + } + + const themeRed = themeColor('coverageRed')({ theme }); + const themeGreen = themeColor('coverageGreen')({ theme }); + + let padAngle = 0; + const numberValue = Number(value || 0); + const data = [ + { value: numberValue, fill: themeGreen }, + { + value: FULL_PERCENT - numberValue, + fill: themeRed, + }, + ]; + if (numberValue !== 0 && numberValue < FULL_PERCENT) { + padAngle = PAD_ANGLE; // Same for all sizes, because it scales automatically + } + + return ( + + ); +} diff --git a/server/sonar-web/design-system/src/components/DonutChart.tsx b/server/sonar-web/design-system/src/components/DonutChart.tsx new file mode 100644 index 00000000000..883b258c714 --- /dev/null +++ b/server/sonar-web/design-system/src/components/DonutChart.tsx @@ -0,0 +1,87 @@ +/* + * SonarQube + * Copyright (C) 2009-2023 SonarSource SA + * mailto:info AT sonarsource DOT com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +import { arc as d3Arc, pie as d3Pie, PieArcDatum } from 'd3-shape'; + +interface DataPoint { + fill: string; + value: number; +} + +export interface DonutChartProps { + data: DataPoint[]; + height: number; + padAngle?: number; + padding?: [number, number, number, number]; + thickness: number; + width: number; +} + +export function DonutChart(props: DonutChartProps) { + const { height, padding = [0, 0, 0, 0], width } = props; + + const availableWidth = width - padding[1] - padding[3]; + const availableHeight = height - padding[0] - padding[2]; + + const size = Math.min(availableWidth, availableHeight); + const radius = Math.floor(size / 2); + + const pie = d3Pie() + .sort(null) + .value((d) => d.value); + + if (props.padAngle !== undefined) { + pie.padAngle(props.padAngle); + } + + const sectors = pie(props.data).map((d, i) => { + return ( + + ); + }); + + return ( + + + {sectors} + + + ); +} + +interface SectorProps { + data: PieArcDatum; + fill: string; + radius: number; + thickness: number; +} + +function Sector(props: SectorProps) { + const arc = d3Arc>() + .outerRadius(props.radius) + .innerRadius(props.radius - props.thickness); + const d = arc(props.data) as string; + return ; +} diff --git a/server/sonar-web/design-system/src/components/DuplicationsIndicator.tsx b/server/sonar-web/design-system/src/components/DuplicationsIndicator.tsx new file mode 100644 index 00000000000..2286c89b211 --- /dev/null +++ b/server/sonar-web/design-system/src/components/DuplicationsIndicator.tsx @@ -0,0 +1,152 @@ +/* + * SonarQube + * Copyright (C) 2009-2023 SonarSource SA + * mailto:info AT sonarsource DOT com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +import { useTheme } from '@emotion/react'; +import { themeColor } from '../helpers/theme'; +import { isDefined } from '../helpers/types'; +import { DuplicationEnum, DuplicationLabel } from '../types/measures'; +import { NoDataIcon } from './icons'; + +interface Props { + rating?: DuplicationLabel; + size?: 'xs' | 'sm' | 'md'; +} + +const SIZE_TO_PX_MAPPING = { xs: 16, sm: 24, md: 36 }; + +export function DuplicationsIndicator({ size = 'sm', rating }: Props) { + const theme = useTheme(); + const sizePX = SIZE_TO_PX_MAPPING[size]; + + if (rating === undefined) { + return ; + } + + const primaryColor = themeColor(`duplicationsIndicator.${rating}`)({ theme }); + const secondaryColor = themeColor('duplicationsIndicatorSecondary')({ theme }); + + return ( + + ); +} + +interface SVGProps { + primaryColor: string; + rating: DuplicationLabel; + secondaryColor: string; + size: number; +} + +function RatingSVG({ primaryColor, rating, secondaryColor, size }: SVGProps) { + return ( + + + {isDefined(rating) && + { + [DuplicationEnum.A]: ( + <> + + + + ), + [DuplicationEnum.B]: ( + <> + + + + ), + [DuplicationEnum.C]: ( + <> + + + + ), + [DuplicationEnum.D]: ( + <> + + + + ), + [DuplicationEnum.E]: ( + <> + + + + ), + [DuplicationEnum.F]: ( + <> + + + + ), + }[rating]} + + ); +} diff --git a/server/sonar-web/design-system/src/components/MetricsRatingBadge.tsx b/server/sonar-web/design-system/src/components/MetricsRatingBadge.tsx new file mode 100644 index 00000000000..f91758932d7 --- /dev/null +++ b/server/sonar-web/design-system/src/components/MetricsRatingBadge.tsx @@ -0,0 +1,69 @@ +/* + * SonarQube + * Copyright (C) 2009-2023 SonarSource SA + * mailto:info AT sonarsource DOT com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +import styled from '@emotion/styled'; +import tw from 'twin.macro'; +import { getProp, themeColor, themeContrast } from '../helpers/theme'; +import { MetricsLabel } from '../types/measures'; + +interface Props extends React.AriaAttributes { + className?: string; + label: string; + rating?: MetricsLabel; + size?: 'xs' | 'sm' | 'md'; +} + +const SIZE_MAPPING = { + xs: '1rem', + sm: '1.5rem', + md: '2rem', +}; + +export function MetricsRatingBadge({ className, size = 'sm', label, rating, ...ariaAttrs }: Props) { + if (!rating) { + return ( + + – + + ); + } + return ( + + {rating} + + ); +} + +const MetricsRatingBadgeStyled = styled.div<{ rating: MetricsLabel; size: string }>` + width: ${getProp('size')}; + height: ${getProp('size')}; + color: ${({ rating }) => themeContrast(`rating.${rating}`)}; + font-size: ${({ size }) => (size === '2rem' ? '0.875rem' : '0.75rem')}; + background-color: ${({ rating }) => themeColor(`rating.${rating}`)}; + + ${tw`sw-inline-flex sw-items-center sw-justify-center`}; + ${tw`sw-rounded-pill`}; + ${tw`sw-font-semibold`}; +`; diff --git a/server/sonar-web/design-system/src/components/SizeIndicator.tsx b/server/sonar-web/design-system/src/components/SizeIndicator.tsx new file mode 100644 index 00000000000..62cc685c2e7 --- /dev/null +++ b/server/sonar-web/design-system/src/components/SizeIndicator.tsx @@ -0,0 +1,55 @@ +/* + * SonarQube + * Copyright (C) 2009-2023 SonarSource SA + * mailto:info AT sonarsource DOT com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +import styled from '@emotion/styled'; +import tw from 'twin.macro'; +import { getProp, themeColor, themeContrast } from '../helpers/theme'; +import { SizeLabel } from '../types/measures'; + +export interface Props { + size?: 'xs' | 'sm' | 'md'; + value: SizeLabel; +} + +const SIZE_MAPPING = { + xs: '1rem', + sm: '1.5rem', + md: '2rem', +}; + +export function SizeIndicator({ size = 'sm', value }: Props) { + return ( + + ); +} + +const StyledContainer = styled.div<{ size: string }>` + width: ${getProp('size')}; + height: ${getProp('size')}; + font-size: ${({ size }) => (size === '2rem' ? '0.875rem' : '0.75rem')}; + color: ${themeContrast('sizeIndicator')}; + background-color: ${themeColor('sizeIndicator')}; + + ${tw`sw-inline-flex sw-items-center sw-justify-center`}; + ${tw`sw-leading-4`}; + ${tw`sw-rounded-pill`}; + ${tw`sw-font-semibold`}; +`; diff --git a/server/sonar-web/design-system/src/components/__tests__/CoverageIndicator-test.tsx b/server/sonar-web/design-system/src/components/__tests__/CoverageIndicator-test.tsx new file mode 100644 index 00000000000..1b14752eac6 --- /dev/null +++ b/server/sonar-web/design-system/src/components/__tests__/CoverageIndicator-test.tsx @@ -0,0 +1,39 @@ +/* + * SonarQube + * Copyright (C) 2009-2023 SonarSource SA + * mailto:info AT sonarsource DOT com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +import { screen } from '@testing-library/react'; +import { render } from '../../helpers/testUtils'; +import { FCProps } from '../../types/misc'; + +import { CoverageIndicator } from '../CoverageIndicator'; + +it('should display CoverageIndicator', () => { + setupWithProps({ value: 10 }); + expect(screen.getByRole('img', { hidden: true })).toMatchSnapshot(); +}); + +it('should display CoverageIndicator without value', () => { + setupWithProps(); + expect(screen.getByRole('img', { hidden: true })).toMatchSnapshot(); +}); + +function setupWithProps(props: Partial> = {}) { + return render(); +} diff --git a/server/sonar-web/design-system/src/components/__tests__/DuplicationsIndicator-test.tsx b/server/sonar-web/design-system/src/components/__tests__/DuplicationsIndicator-test.tsx new file mode 100644 index 00000000000..c491f942829 --- /dev/null +++ b/server/sonar-web/design-system/src/components/__tests__/DuplicationsIndicator-test.tsx @@ -0,0 +1,43 @@ +/* + * SonarQube + * Copyright (C) 2009-2023 SonarSource SA + * mailto:info AT sonarsource DOT com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +import { screen } from '@testing-library/react'; +import { render } from '../../helpers/testUtils'; +import { FCProps } from '../../types/misc'; + +import { DuplicationLabel } from '../../types/measures'; +import { DuplicationsIndicator } from '../DuplicationsIndicator'; + +it('should display DuplicationsIndicator without rating', () => { + setupWithProps(); + expect(screen.getByRole('img', { hidden: true })).toMatchSnapshot(); +}); + +it.each(['A', 'B', 'C', 'D', 'E', 'F'])( + 'should display DuplicationsIndicator with rating', + (variant: DuplicationLabel) => { + setupWithProps({ rating: variant }); + expect(screen.getByRole('img', { hidden: true })).toMatchSnapshot(); + } +); + +function setupWithProps(props: Partial> = {}) { + return render(); +} diff --git a/server/sonar-web/design-system/src/components/__tests__/MetricsRatingBadge-test.tsx b/server/sonar-web/design-system/src/components/__tests__/MetricsRatingBadge-test.tsx new file mode 100644 index 00000000000..8055a3b7ef3 --- /dev/null +++ b/server/sonar-web/design-system/src/components/__tests__/MetricsRatingBadge-test.tsx @@ -0,0 +1,39 @@ +/* + * SonarQube + * Copyright (C) 2009-2023 SonarSource SA + * mailto:info AT sonarsource DOT com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +import { screen } from '@testing-library/react'; +import { render } from '../../helpers/testUtils'; +import { FCProps } from '../../types/misc'; + +import { MetricsRatingBadge } from '../MetricsRatingBadge'; + +it('should display RatingIndicator', () => { + setupWithProps(); + expect(screen.getByLabelText('New label')).toBeInTheDocument(); +}); + +it('should display RatingIndicator with value', () => { + setupWithProps({ rating: 'A' }); + expect(screen.getByText('A')).toBeInTheDocument(); +}); + +function setupWithProps(props: Partial> = {}) { + return render(); +} diff --git a/server/sonar-web/design-system/src/components/__tests__/SizeIndicator-test.tsx b/server/sonar-web/design-system/src/components/__tests__/SizeIndicator-test.tsx new file mode 100644 index 00000000000..bdd8b8c6d85 --- /dev/null +++ b/server/sonar-web/design-system/src/components/__tests__/SizeIndicator-test.tsx @@ -0,0 +1,38 @@ +/* + * SonarQube + * Copyright (C) 2009-2023 SonarSource SA + * mailto:info AT sonarsource DOT com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +import { screen } from '@testing-library/react'; +import { render } from '../../helpers/testUtils'; +import { FCProps } from '../../types/misc'; + +import { SizeLabel } from '../../types/measures'; +import { SizeIndicator } from '../SizeIndicator'; + +it.each(['XS', 'S', 'M', 'L', 'XL'])( + 'should display SizeIndicator with size', + (value: SizeLabel) => { + setupWithProps({ value }); + expect(screen.getByText(value)).toBeInTheDocument(); + } +); + +function setupWithProps(props: Partial> = {}) { + return render(); +} diff --git a/server/sonar-web/design-system/src/components/__tests__/__snapshots__/CoverageIndicator-test.tsx.snap b/server/sonar-web/design-system/src/components/__tests__/__snapshots__/CoverageIndicator-test.tsx.snap new file mode 100644 index 00000000000..8a49b54ab50 --- /dev/null +++ b/server/sonar-web/design-system/src/components/__tests__/__snapshots__/CoverageIndicator-test.tsx.snap @@ -0,0 +1,49 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`should display CoverageIndicator 1`] = ` + + + + + + + + +`; + +exports[`should display CoverageIndicator without value 1`] = ` + +`; diff --git a/server/sonar-web/design-system/src/components/__tests__/__snapshots__/DuplicationsIndicator-test.tsx.snap b/server/sonar-web/design-system/src/components/__tests__/__snapshots__/DuplicationsIndicator-test.tsx.snap new file mode 100644 index 00000000000..21ac97b1eea --- /dev/null +++ b/server/sonar-web/design-system/src/components/__tests__/__snapshots__/DuplicationsIndicator-test.tsx.snap @@ -0,0 +1,181 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`should display DuplicationsIndicator with rating 1`] = ` + + + + + +`; + +exports[`should display DuplicationsIndicator with rating 2`] = ` + + + + + +`; + +exports[`should display DuplicationsIndicator with rating 3`] = ` + + + + + +`; + +exports[`should display DuplicationsIndicator with rating 4`] = ` + + + + + +`; + +exports[`should display DuplicationsIndicator with rating 5`] = ` + + + + + +`; + +exports[`should display DuplicationsIndicator with rating 6`] = ` + + + + + +`; + +exports[`should display DuplicationsIndicator without rating 1`] = ` + +`; diff --git a/server/sonar-web/design-system/src/components/icons/Icon.tsx b/server/sonar-web/design-system/src/components/icons/Icon.tsx index a9a246a0c21..3a90211b525 100644 --- a/server/sonar-web/design-system/src/components/icons/Icon.tsx +++ b/server/sonar-web/design-system/src/components/icons/Icon.tsx @@ -33,6 +33,8 @@ interface Props { export interface IconProps extends Omit { fill?: ThemeColors | CSSColor; + height?: number; + width?: number; } export function CustomIcon(props: Props) { diff --git a/server/sonar-web/design-system/src/components/icons/NoDataIcon.tsx b/server/sonar-web/design-system/src/components/icons/NoDataIcon.tsx new file mode 100644 index 00000000000..7b357c56449 --- /dev/null +++ b/server/sonar-web/design-system/src/components/icons/NoDataIcon.tsx @@ -0,0 +1,34 @@ +/* + * SonarQube + * Copyright (C) 2009-2023 SonarSource SA + * mailto:info AT sonarsource DOT com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +import { CustomIcon, IconProps } from './Icon'; + +export function NoDataIcon({ fill = 'currentColor', ...iconProps }: IconProps) { + return ( + + + + ); +} diff --git a/server/sonar-web/design-system/src/components/icons/index.ts b/server/sonar-web/design-system/src/components/icons/index.ts index fd76e9c1719..343b0605464 100644 --- a/server/sonar-web/design-system/src/components/icons/index.ts +++ b/server/sonar-web/design-system/src/components/icons/index.ts @@ -34,6 +34,7 @@ export { HomeIcon } from './HomeIcon'; export { MainBranchIcon } from './MainBranchIcon'; export { MenuHelpIcon } from './MenuHelpIcon'; export { MenuSearchIcon } from './MenuSearchIcon'; +export { NoDataIcon } from './NoDataIcon'; export { OpenCloseIndicator } from './OpenCloseIndicator'; export { OpenNewTabIcon } from './OpenNewTabIcon'; export { OverviewQGNotComputedIcon } from './OverviewQGNotComputedIcon'; diff --git a/server/sonar-web/design-system/src/components/index.ts b/server/sonar-web/design-system/src/components/index.ts index 31a1c322c40..93058100cf3 100644 --- a/server/sonar-web/design-system/src/components/index.ts +++ b/server/sonar-web/design-system/src/components/index.ts @@ -22,10 +22,12 @@ export * from './Accordion'; export * from './Avatar'; export { Badge } from './Badge'; export * from './Card'; +export * from './CoverageIndicator'; export { DeferredSpinner } from './DeferredSpinner'; export { Dropdown } from './Dropdown'; export * from './DropdownMenu'; export { DropdownToggler } from './DropdownToggler'; +export * from './DuplicationsIndicator'; export { FailedQGConditionLink } from './FailedQGConditionLink'; export { FlagMessage } from './FlagMessage'; export * from './GenericAvatar'; @@ -36,8 +38,10 @@ export { StandoutLink as Link } from './Link'; export * from './MainAppBar'; export * from './MainMenu'; export * from './MainMenuItem'; +export * from './MetricsRatingBadge'; export * from './NavBarTabs'; export { QualityGateIndicator } from './QualityGateIndicator'; +export * from './SizeIndicator'; export * from './SonarQubeLogo'; export * from './Text'; export { ToggleButton } from './ToggleButton'; diff --git a/server/sonar-web/design-system/src/theme/light.ts b/server/sonar-web/design-system/src/theme/light.ts index ea031787166..df8bb271834 100644 --- a/server/sonar-web/design-system/src/theme/light.ts +++ b/server/sonar-web/design-system/src/theme/light.ts @@ -296,12 +296,13 @@ const lightTheme = { coverageRed: danger.dark, // duplications indicators - 'duplicationsRating.A': COLORS.green[500], - 'duplicationsRating.B': COLORS.yellowGreen[500], - 'duplicationsRating.C': COLORS.yellow[500], - 'duplicationsRating.D': COLORS.orange[500], - 'duplicationsRating.E': COLORS.red[500], - duplicationsRatingSecondary: secondary.light, + 'duplicationsIndicator.A': COLORS.green[500], + 'duplicationsIndicator.B': COLORS.green[500], + 'duplicationsIndicator.C': COLORS.yellowGreen[500], + 'duplicationsIndicator.D': COLORS.yellow[500], + 'duplicationsIndicator.E': COLORS.orange[500], + 'duplicationsIndicator.F': COLORS.red[500], + duplicationsIndicatorSecondary: secondary.light, // size indicators sizeIndicator: COLORS.blue[500], diff --git a/server/sonar-web/design-system/src/types/measures.ts b/server/sonar-web/design-system/src/types/measures.ts new file mode 100644 index 00000000000..807118abe94 --- /dev/null +++ b/server/sonar-web/design-system/src/types/measures.ts @@ -0,0 +1,49 @@ +/* + * SonarQube + * Copyright (C) 2009-2023 SonarSource SA + * mailto:info AT sonarsource DOT com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +export enum DuplicationEnum { + A = 'A', + B = 'B', + C = 'C', + D = 'D', + E = 'E', + F = 'F', +} + +export type DuplicationLabel = keyof typeof DuplicationEnum; + +export enum MetricsEnum { + A = 'A', + B = 'B', + C = 'C', + D = 'D', + E = 'E', +} + +export type MetricsLabel = keyof typeof MetricsEnum; + +export enum SizeEnum { + XS = 'XS', + S = 'S', + M = 'M', + L = 'L', + XL = 'XL', +} +export type SizeLabel = keyof typeof SizeEnum; diff --git a/server/sonar-web/yarn.lock b/server/sonar-web/yarn.lock index 2e4be312cf8..921ef8e55b6 100644 --- a/server/sonar-web/yarn.lock +++ b/server/sonar-web/yarn.lock @@ -6150,6 +6150,7 @@ __metadata: "@primer/octicons-react": 18.3.0 classnames: 2.3.2 clipboard: 2.0.11 + d3-shape: 3.2.0 lodash: 4.17.21 react: 17.0.2 react-dom: 17.0.2 -- 2.39.5