From 7fa667d94b3bf5c4b7d74835d91d64caac7469dd Mon Sep 17 00:00:00 2001 From: 7PH Date: Tue, 30 Jan 2024 19:13:25 +0100 Subject: [PATCH] SONAR-21467 Fix clickable software quality breakdown links during reindexing --- .../design-system/src/components/Link.tsx | 15 ++++--- .../branches/OverallCodeMeasuresPanel.tsx | 3 ++ .../SoftwareImpactMeasureBreakdownCard.tsx | 1 + .../branches/SoftwareImpactMeasureCard.tsx | 45 +++++++++++-------- .../branches/__tests__/BranchOverview-it.tsx | 35 +++++++++++++++ .../apps/overview/components/MeasuresCard.tsx | 31 +++++++------ 6 files changed, 93 insertions(+), 37 deletions(-) diff --git a/server/sonar-web/design-system/src/components/Link.tsx b/server/sonar-web/design-system/src/components/Link.tsx index edd9f192a40..d97489785d7 100644 --- a/server/sonar-web/design-system/src/components/Link.tsx +++ b/server/sonar-web/design-system/src/components/Link.tsx @@ -155,11 +155,14 @@ export const NakedLink = styled(BaseLink)` font-weight: 600; color: ${themeColor('linkNaked')}; - &:hover, - &:focus, - &:active { - color: ${themeColor('linkActive')}; - } + ${({ disabled, theme }) => + disabled + ? tw`sw-cursor-default` + : `&:hover, + &:focus, + &:active { + color: ${themeColor('linkActive')({ theme })}; + }`}; `; export const DrilldownLink = styled(StyledBaseLink)` @@ -219,6 +222,8 @@ export const DiscreetLinkBox = styled(StyledBaseLink)` background-color: none; display: block; } + + ${({ disabled }) => (disabled ? tw`sw-cursor-default` : '')}; `; LinkBox.displayName = 'DiscreetLinkBox'; diff --git a/server/sonar-web/src/main/js/apps/overview/branches/OverallCodeMeasuresPanel.tsx b/server/sonar-web/src/main/js/apps/overview/branches/OverallCodeMeasuresPanel.tsx index 4c228520cc7..1d66c017c3e 100644 --- a/server/sonar-web/src/main/js/apps/overview/branches/OverallCodeMeasuresPanel.tsx +++ b/server/sonar-web/src/main/js/apps/overview/branches/OverallCodeMeasuresPanel.tsx @@ -38,6 +38,7 @@ import { QualityGateStatus } from '../../../types/quality-gates'; import { Component, MeasureEnhanced } from '../../../types/types'; import MeasuresCard from '../components/MeasuresCard'; import MeasuresCardNumber from '../components/MeasuresCardNumber'; +import { OverviewDisabledLinkTooltip } from '../components/OverviewDisabledLinkTooltip'; import { MeasuresTabs } from '../utils'; import MeasuresPanelPercentCards from './MeasuresPanelPercentCards'; import SoftwareImpactMeasureCard from './SoftwareImpactMeasureCard'; @@ -99,6 +100,8 @@ export default function OverallCodeMeasuresPanel(props: Readonly } + disabled={component.needIssueSync} + tooltip={component.needIssueSync ? : null} > {intl.formatMessage({ diff --git a/server/sonar-web/src/main/js/apps/overview/branches/SoftwareImpactMeasureBreakdownCard.tsx b/server/sonar-web/src/main/js/apps/overview/branches/SoftwareImpactMeasureBreakdownCard.tsx index d8755ae82ad..fcab9056e65 100644 --- a/server/sonar-web/src/main/js/apps/overview/branches/SoftwareImpactMeasureBreakdownCard.tsx +++ b/server/sonar-web/src/main/js/apps/overview/branches/SoftwareImpactMeasureBreakdownCard.tsx @@ -92,6 +92,7 @@ export function SoftwareImpactMeasureBreakdownCard( }), }, )} + disabled={component.needIssueSync} to={url} > {formatMeasure(value, MetricType.ShortInteger)} diff --git a/server/sonar-web/src/main/js/apps/overview/branches/SoftwareImpactMeasureCard.tsx b/server/sonar-web/src/main/js/apps/overview/branches/SoftwareImpactMeasureCard.tsx index d0ea22018fb..3d7bab789e5 100644 --- a/server/sonar-web/src/main/js/apps/overview/branches/SoftwareImpactMeasureCard.tsx +++ b/server/sonar-web/src/main/js/apps/overview/branches/SoftwareImpactMeasureCard.tsx @@ -29,6 +29,7 @@ import { } from 'design-system'; import * as React from 'react'; import { useIntl } from 'react-intl'; +import Tooltip from '../../../components/controls/Tooltip'; import { DEFAULT_ISSUES_QUERY } from '../../../components/shared/utils'; import { formatMeasure } from '../../../helpers/measures'; import { getComponentIssuesUrl } from '../../../helpers/urls'; @@ -39,6 +40,7 @@ import { } from '../../../types/clean-code-taxonomy'; import { MetricKey, MetricType } from '../../../types/metrics'; import { Component, MeasureEnhanced } from '../../../types/types'; +import { OverviewDisabledLinkTooltip } from '../components/OverviewDisabledLinkTooltip'; import { softwareQualityToMeasure } from '../utils'; import SoftwareImpactMeasureBreakdownCard from './SoftwareImpactMeasureBreakdownCard'; import SoftwareImpactMeasureRating from './SoftwareImpactMeasureRating'; @@ -60,6 +62,8 @@ export function SoftwareImpactMeasureCard(props: Readonly m.metric.key === metricKey); const measure = JSON.parse(measureRaw?.value ?? 'null') as SoftwareImpactMeasureData; + const renderDisabled = !measure || component.needIssueSync; + // Find rating measure const ratingMeasure = measures.find((m) => m.metric.key === ratingMetricKey); @@ -85,28 +89,31 @@ export function SoftwareImpactMeasureCard(props: Readonly
{measure ? ( - - {formatMeasure(measure.total, MetricType.ShortInteger)} - + : null}> + + {formatMeasure(measure.total, MetricType.ShortInteger)} + + ) : ( )} diff --git a/server/sonar-web/src/main/js/apps/overview/branches/__tests__/BranchOverview-it.tsx b/server/sonar-web/src/main/js/apps/overview/branches/__tests__/BranchOverview-it.tsx index a956a8b75e3..e8710eaca52 100644 --- a/server/sonar-web/src/main/js/apps/overview/branches/__tests__/BranchOverview-it.tsx +++ b/server/sonar-web/src/main/js/apps/overview/branches/__tests__/BranchOverview-it.tsx @@ -348,6 +348,41 @@ describe('project overview', () => { false, ]); }); + + it('should disable software impact measure card links during reindexing', async () => { + const { user, ui } = getPageObjects(); + renderBranchOverview({ + component: mockComponent({ + breadcrumbs: [mockComponent({ key: 'foo' })], + key: 'foo', + needIssueSync: true, + }), + }); + + await user.click(await ui.overallCodeButton.find()); + + expect(await ui.softwareImpactMeasureCard(SoftwareQuality.Security).find()).toBeInTheDocument(); + + ui.expectSoftwareImpactMeasureCard( + SoftwareQuality.Security, + 'B', + { + total: 1, + [SoftwareImpactSeverity.High]: 0, + [SoftwareImpactSeverity.Medium]: 1, + [SoftwareImpactSeverity.Low]: 0, + }, + [false, true, false], + ); + + await expect( + byRole('link', { + name: `overview.measures.software_impact.see_list_of_x_open_issues.${1}.software_quality.${ + SoftwareQuality.Security + }`, + }).get(), + ).toHaveATooltipWithContent('indexation.in_progress'); + }); }); describe('application overview', () => { diff --git a/server/sonar-web/src/main/js/apps/overview/components/MeasuresCard.tsx b/server/sonar-web/src/main/js/apps/overview/components/MeasuresCard.tsx index de80ee18c20..68c6174487b 100644 --- a/server/sonar-web/src/main/js/apps/overview/components/MeasuresCard.tsx +++ b/server/sonar-web/src/main/js/apps/overview/components/MeasuresCard.tsx @@ -18,7 +18,7 @@ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ import styled from '@emotion/styled'; -import { Badge, Card, ContentLink, themeBorder, themeColor } from 'design-system'; +import { Badge, Card, ContentLink, Tooltip, themeBorder, themeColor } from 'design-system'; import * as React from 'react'; import { To } from 'react-router-dom'; import { translate, translateWithParameters } from '../../../helpers/l10n'; @@ -32,12 +32,14 @@ export interface MeasuresCardProps { label: string; failed?: boolean; icon?: React.ReactElement; + disabled?: boolean; + tooltip?: React.ReactNode | null; } export default function MeasuresCard( props: React.PropsWithChildren>, ) { - const { failed, children, metric, icon, value, url, label, ...rest } = props; + const { failed, children, metric, icon, value, url, label, disabled, tooltip, ...rest } = props; return ( @@ -49,17 +51,20 @@ export default function MeasuresCard( )}
{value ? ( - - {value} - + + + {value} + + ) : ( — )} -- 2.39.5