From 01451486cfe17aad78132c4a5d9bdf01449d5c8a Mon Sep 17 00:00:00 2001 From: 7PH Date: Thu, 1 Jun 2023 13:32:41 +0200 Subject: [PATCH] SONAR-19391 Measures page's file views should use the new UI --- .../src/components/icons/QualifierIcon.tsx | 44 +++++++++++- .../__tests__/ComponentMeasures-it.tsx | 10 +-- .../drilldown/ComponentCell.tsx | 55 ++++----------- .../drilldown/ComponentsList.tsx | 68 ++++++++++-------- .../drilldown/ComponentsListRow.tsx | 69 ------------------- .../drilldown/FilesView.tsx | 44 ++++++++---- .../drilldown/MeasureCell.tsx | 31 +++++++-- .../main/js/apps/component-measures/style.css | 16 ----- .../resources/org/sonar/l10n/core.properties | 1 + 9 files changed, 158 insertions(+), 180 deletions(-) delete mode 100644 server/sonar-web/src/main/js/apps/component-measures/drilldown/ComponentsListRow.tsx diff --git a/server/sonar-web/design-system/src/components/icons/QualifierIcon.tsx b/server/sonar-web/design-system/src/components/icons/QualifierIcon.tsx index 4f5bbc4d99b..92685c586f9 100644 --- a/server/sonar-web/design-system/src/components/icons/QualifierIcon.tsx +++ b/server/sonar-web/design-system/src/components/icons/QualifierIcon.tsx @@ -21,7 +21,7 @@ import { useTheme } from '@emotion/react'; import { themeColor } from '../../helpers/theme'; import { DirectoryIcon } from './DirectoryIcon'; import { FileIcon } from './FileIcon'; -import { IconProps } from './Icon'; +import { CustomIcon, IconProps } from './Icon'; import { ProjectIcon } from './ProjectIcon'; import { TestFileIcon } from './TestFileIcon'; @@ -41,7 +41,49 @@ export function QualifierIcon({ qualifier, fill, ...iconProps }: Props) { fil: , trk: , uts: , + app: ApplicationIcon({ fill: fill ?? themeColor('iconProject')({ theme }), ...iconProps }), + vw: PortfolioIcon({ fill: fill ?? themeColor('iconProject')({ theme }), ...iconProps }), + svw: SubPortfolioIcon({ fill: fill ?? themeColor('iconProject')({ theme }), ...iconProps }), }[qualifier.toLowerCase()]; return icon ?? null; } + +function PortfolioIcon({ fill = 'currentColor', ...iconProps }: IconProps) { + const theme = useTheme(); + + return ( + + + + ); +} + +function ApplicationIcon({ fill = 'currentColor', ...iconProps }: IconProps) { + const theme = useTheme(); + + return ( + + + + ); +} + +function SubPortfolioIcon({ fill = 'currentColor', ...iconProps }: IconProps) { + const theme = useTheme(); + + return ( + + + + ); +} diff --git a/server/sonar-web/src/main/js/apps/component-measures/__tests__/ComponentMeasures-it.tsx b/server/sonar-web/src/main/js/apps/component-measures/__tests__/ComponentMeasures-it.tsx index be3ab4737bb..6d8679e4a7b 100644 --- a/server/sonar-web/src/main/js/apps/component-measures/__tests__/ComponentMeasures-it.tsx +++ b/server/sonar-web/src/main/js/apps/component-measures/__tests__/ComponentMeasures-it.tsx @@ -255,7 +255,7 @@ describe('navigation', () => { within(ui.measuresRow('test1.js').get()).getByRole('cell', { name: '2' }) ).toBeInTheDocument(); - await user.click(ui.fileLink('foo:folderA').get()); + await user.click(ui.fileLink('folderA').get()); expect( within(ui.measuresRow('out.tsx').get()).getByRole('cell', { name: '1' }) ).toBeInTheDocument(); @@ -263,7 +263,7 @@ describe('navigation', () => { within(ui.measuresRow('in.tsx').get()).getByRole('cell', { name: '2' }) ).toBeInTheDocument(); - await user.click(ui.fileLink('foo:folderA/out.tsx').get()); + await user.click(ui.fileLink('out.tsx').get()); expect((await ui.sourceCode.findAll()).length).toBeGreaterThan(0); // Go back using the breadcrumbs. @@ -288,7 +288,7 @@ describe('navigation', () => { within(ui.measuresRow('test1.js').get()).getByRole('cell', { name: '2' }) ).toBeInTheDocument(); - await user.click(ui.fileLink('foo:folderA/out.tsx').get()); + await user.click(ui.fileLink('out.tsx').get()); expect((await ui.sourceCode.findAll()).length).toBeGreaterThan(0); }); @@ -479,7 +479,9 @@ function getPageObject() { detailsUnavailableText: byText('component_measures.details_are_not_available'), noAccessWarning: byRole('alert'), showingOutOfTxt: (x: string, y: string) => byText(`x_of_y_shown.${x}.${y}`), - showAllBtn: byRole('button', { name: 'show_them' }), + showAllBtn: byRole('button', { + name: 'component_measures.hidden_best_score_metrics_show_label', + }), goToActivityLink: byRole('link', { name: 'component_measures.show_metric_history' }), }; diff --git a/server/sonar-web/src/main/js/apps/component-measures/drilldown/ComponentCell.tsx b/server/sonar-web/src/main/js/apps/component-measures/drilldown/ComponentCell.tsx index 3f43f541f46..4a2c158e82c 100644 --- a/server/sonar-web/src/main/js/apps/component-measures/drilldown/ComponentCell.tsx +++ b/server/sonar-web/src/main/js/apps/component-measures/drilldown/ComponentCell.tsx @@ -17,23 +17,14 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ +import { ContentCell, HoverLink, Note, QualifierIcon } from 'design-system'; import * as React from 'react'; import { To } from 'react-router-dom'; -import Link from '../../../components/common/Link'; -import BranchIcon from '../../../components/icons/BranchIcon'; -import LinkIcon from '../../../components/icons/LinkIcon'; -import QualifierIcon from '../../../components/icons/QualifierIcon'; import { fillBranchLike } from '../../../helpers/branch-like'; -import { translate } from '../../../helpers/l10n'; import { splitPath } from '../../../helpers/path'; import { getComponentDrilldownUrlWithSelection, getProjectUrl } from '../../../helpers/urls'; import { BranchLike } from '../../../types/branch-like'; -import { - ComponentQualifier, - isApplication, - isPortfolioLike, - isProject, -} from '../../../types/component'; +import { ComponentQualifier, isApplication, isProject } from '../../../types/component'; import { MeasurePageView } from '../../../types/measures'; import { MetricKey } from '../../../types/metrics'; import { ComponentMeasure, ComponentMeasureEnhanced, Metric } from '../../../types/types'; @@ -93,34 +84,18 @@ export default function ComponentCell(props: ComponentCellProps) { } return ( - -
- - {component.refKey && ( - - - - )} - - - {head.length > 0 && {head}/} - {tail} - {(isApplication(rootComponent.qualifier) || isPortfolioLike(rootComponent.qualifier)) && - (component.branch ? ( - <> - - {component.branch} - - ) : ( - {translate('branches.main_branch')} - ))} - - -
- + + } + to={path} + title={component.path} + /> + + {head.length > 0 && {head}/} + {tail} + + ); } diff --git a/server/sonar-web/src/main/js/apps/component-measures/drilldown/ComponentsList.tsx b/server/sonar-web/src/main/js/apps/component-measures/drilldown/ComponentsList.tsx index dd7f9ae2593..d67a32ddf3d 100644 --- a/server/sonar-web/src/main/js/apps/component-measures/drilldown/ComponentsList.tsx +++ b/server/sonar-web/src/main/js/apps/component-measures/drilldown/ComponentsList.tsx @@ -17,15 +17,16 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ +import { ContentCell, NumericalCell, Table, TableRow, TableRowInteractive } from 'design-system'; import * as React from 'react'; -import { getComponentMeasureUniqueKey } from '../../../helpers/component'; import { getLocalizedMetricName } from '../../../helpers/l10n'; import { BranchLike } from '../../../types/branch-like'; import { MeasurePageView } from '../../../types/measures'; import { ComponentMeasure, ComponentMeasureEnhanced, Dict, Metric } from '../../../types/types'; import { complementary } from '../config/complementary'; -import ComponentsListRow from './ComponentsListRow'; +import ComponentCell from './ComponentCell'; import EmptyResult from './EmptyResult'; +import MeasureCell from './MeasureCell'; interface Props { branchLike?: BranchLike; @@ -38,44 +39,51 @@ interface Props { } export default function ComponentsList({ components, metric, metrics, ...props }: Props) { + const { branchLike, rootComponent, selectedComponent } = props; + if (!components.length) { return ; } const otherMetrics = (complementary[metric.key] || []).map((key) => metrics[key]); return ( - - {otherMetrics.length > 0 && ( - - - - +
  - {getLocalizedMetricName(metric)} -
0 && ( + + + {getLocalizedMetricName(metric)} {otherMetrics.map((metric) => ( - + + {getLocalizedMetricName(metric)} + ))} - - - )} - - - {components.map((component) => ( - + ) + } + > + {components.map((component) => ( + + - ))} - -
- {getLocalizedMetricName(metric)} -
+ + + + {otherMetrics.map((metric) => ( + + ))} + + ))} + ); } diff --git a/server/sonar-web/src/main/js/apps/component-measures/drilldown/ComponentsListRow.tsx b/server/sonar-web/src/main/js/apps/component-measures/drilldown/ComponentsListRow.tsx deleted file mode 100644 index fb761dafb36..00000000000 --- a/server/sonar-web/src/main/js/apps/component-measures/drilldown/ComponentsListRow.tsx +++ /dev/null @@ -1,69 +0,0 @@ -/* - * 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 classNames from 'classnames'; -import * as React from 'react'; -import { BranchLike } from '../../../types/branch-like'; -import { MeasurePageView } from '../../../types/measures'; -import { ComponentMeasure, ComponentMeasureEnhanced, Metric } from '../../../types/types'; -import ComponentCell from './ComponentCell'; -import MeasureCell from './MeasureCell'; - -interface Props { - branchLike?: BranchLike; - component: ComponentMeasureEnhanced; - isSelected: boolean; - otherMetrics: Metric[]; - metric: Metric; - rootComponent: ComponentMeasure; - view: MeasurePageView; -} - -export default function ComponentsListRow(props: Props) { - const { branchLike, component, rootComponent } = props; - const otherMeasures = props.otherMetrics.map((metric) => { - const measure = component.measures.find((measure) => measure.metric.key === metric.key); - return { ...measure, metric }; - }); - const rowClass = classNames('measure-details-component-row', { - selected: props.isSelected, - }); - return ( - - - - - - {otherMeasures.map((measure) => ( - - ))} - - ); -} diff --git a/server/sonar-web/src/main/js/apps/component-measures/drilldown/FilesView.tsx b/server/sonar-web/src/main/js/apps/component-measures/drilldown/FilesView.tsx index a909faf1575..5c98cb047f4 100644 --- a/server/sonar-web/src/main/js/apps/component-measures/drilldown/FilesView.tsx +++ b/server/sonar-web/src/main/js/apps/component-measures/drilldown/FilesView.tsx @@ -17,17 +17,17 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ +import { ButtonSecondary, FlagMessage } from 'design-system'; import { throttle } from 'lodash'; import * as React from 'react'; import ListFooter from '../../../components/controls/ListFooter'; -import { Button } from '../../../components/controls/buttons'; -import { Alert } from '../../../components/ui/Alert'; import { isInput, isShortcut } from '../../../helpers/keyboardEventHelpers'; import { KeyboardKeys } from '../../../helpers/keycodes'; import { translate, translateWithParameters } from '../../../helpers/l10n'; import { formatMeasure, isDiffMetric, isPeriodBestValue } from '../../../helpers/measures'; import { BranchLike } from '../../../types/branch-like'; import { MeasurePageView } from '../../../types/measures'; +import { MetricType } from '../../../types/metrics'; import { ComponentMeasure, ComponentMeasureEnhanced, @@ -181,18 +181,34 @@ export default class FilesView extends React.PureComponent { view={this.props.view} /> {hidingBestMeasures && this.props.paging && ( - -
- {translateWithParameters( - 'component_measures.hidden_best_score_metrics', - formatMeasure(this.props.paging.total - filteredComponents.length, 'INT'), - formatMeasure(this.props.metric.bestValue, this.props.metric.type) - )} - -
-
+ + {translateWithParameters( + 'component_measures.hidden_best_score_metrics', + formatMeasure( + this.props.paging.total - filteredComponents.length, + MetricType.Integer + ), + formatMeasure(this.props.metric.bestValue, this.props.metric.type) + )} + + {translate('show_them')} + + )} {!hidingBestMeasures && this.props.paging && this.props.components.length > 0 && ( - - - - + + + } + /> + ); } diff --git a/server/sonar-web/src/main/js/apps/component-measures/style.css b/server/sonar-web/src/main/js/apps/component-measures/style.css index e4d8107cab4..218abc31966 100644 --- a/server/sonar-web/src/main/js/apps/component-measures/style.css +++ b/server/sonar-web/src/main/js/apps/component-measures/style.css @@ -78,18 +78,6 @@ button.search-navigator-facet { margin-top: 4px; } -.measure-details-component-row.selected { - background-color: var(--lightBlue) !important; -} - -.measure-details-component-cell { - max-width: 0; -} - -.measure-details-component-cell > div { - max-width: 100%; -} - .domain-measures-value .rating, .measure-details-value .rating { width: 18px; @@ -122,7 +110,3 @@ button.search-navigator-facet { width: calc(60vw - 80px); } } - -.measure-favorite svg { - vertical-align: middle; -} diff --git a/sonar-core/src/main/resources/org/sonar/l10n/core.properties b/sonar-core/src/main/resources/org/sonar/l10n/core.properties index 2af9659f827..f1c615589cd 100644 --- a/sonar-core/src/main/resources/org/sonar/l10n/core.properties +++ b/sonar-core/src/main/resources/org/sonar/l10n/core.properties @@ -3656,6 +3656,7 @@ component_measures.to_select_files=to select files component_measures.to_navigate=to navigate component_measures.to_navigate_files=to next/previous file component_measures.hidden_best_score_metrics=There are {0} hidden components with a score of {1}. +component_measures.hidden_best_score_metrics_show_label=Show hidden components component_measures.navigation=Measures navigation component_measures.skip_to_navigation=Skip to measure navigation -- 2.39.5