]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-21455 Fix software quality impact measures in branch overview page
author7PH <benjamin.raymond@sonarsource.com>
Thu, 25 Jan 2024 09:44:08 +0000 (10:44 +0100)
committersonartech <sonartech@sonarsource.com>
Wed, 31 Jan 2024 20:03:36 +0000 (20:03 +0000)
server/sonar-web/design-system/src/components/Card.tsx
server/sonar-web/design-system/src/components/Link.tsx
server/sonar-web/design-system/src/theme/light.ts
server/sonar-web/src/main/js/api/measures.ts
server/sonar-web/src/main/js/apps/overview/branches/SoftwareImpactMeasureCard.tsx
server/sonar-web/src/main/js/apps/overview/branches/SoftwareImpactMeasureRating.tsx
server/sonar-web/src/main/js/apps/overview/branches/SoftwareImpactRatingTooltip.tsx [new file with mode: 0644]

index 43ef238a2e35be1fbabcf6ae74d6d71b7c0a04a9..3093905fa9f279368a7993435190cf831c50361a 100644 (file)
@@ -56,6 +56,10 @@ const CardStyled = styled.div`
   ${tw`sw-rounded-1`};
 `;
 
+const LightGreyCardStyled = styled(CardStyled)`
+  border: ${themeBorder('default')};
+`;
+
 const GreyCardStyled = styled(CardStyled)`
   border: ${themeBorder('default', 'almCardBorder')};
 `;
index 38ad2a351abe236b81aa1000ab68a5c8299cec95..edd9f192a4086b61eaff3021f4335b241ced736f 100644 (file)
@@ -154,6 +154,12 @@ export const NakedLink = styled(BaseLink)`
   border-bottom: none;
   font-weight: 600;
   color: ${themeColor('linkNaked')};
+
+  &:hover,
+  &:focus,
+  &:active {
+    color: ${themeColor('linkActive')};
+  }
 `;
 
 export const DrilldownLink = styled(StyledBaseLink)`
index 79a6cab6ea98be6f845a8e9686391142942e8e0f..e20f3b914cf659d453ee64f6bbf59f3af7aac4f4 100644 (file)
@@ -522,6 +522,7 @@ export const lightTheme = {
     // project
     projectCardBackground: COLORS.white,
     projectCardBorder: COLORS.blueGrey[100],
+    projectLightGreyCardBorder: COLORS.grey[50],
 
     // overview
     overviewCardDefaultIcon: secondary.light,
@@ -531,7 +532,7 @@ export const lightTheme = {
     overviewCardSuccessIcon: COLORS.green[200],
 
     // overview software impact breakdown
-    overviewSoftwareImpactSeverityNeutral: COLORS.blueGrey[50],
+    overviewSoftwareImpactSeverityNeutral: [247, 249, 252],
     overviewSoftwareImpactSeverityHigh: COLORS.red[100],
     overviewSoftwareImpactSeverityMedium: COLORS.yellow[100],
     overviewSoftwareImpactSeverityLow: COLORS.blue[100],
index b701d1cbe65791954be7443914fcdbccc7dfa739..68c784baabe48d7557b5acab534e2eb3a41793fa 100644 (file)
@@ -96,15 +96,12 @@ export async function getMeasuresWithPeriodAndMetrics(
     });
     result.component.measures?.push({
       metric: MetricKey.maintainability_issues,
-      period: {
-        index: 0,
-        value: JSON.stringify({
-          total: 3,
-          high: 1,
-          medium: 1,
-          low: 1,
-        }),
-      },
+      value: JSON.stringify({
+        total: 3,
+        high: 1,
+        medium: 1,
+        low: 1,
+      }),
     });
   }
   if (metrics.includes(MetricKey.reliability_issues)) {
@@ -121,15 +118,12 @@ export async function getMeasuresWithPeriodAndMetrics(
     });
     result.component.measures?.push({
       metric: MetricKey.reliability_issues,
-      period: {
-        index: 0,
-        value: JSON.stringify({
-          total: 2,
-          high: 0,
-          medium: 1,
-          low: 1,
-        }),
-      },
+      value: JSON.stringify({
+        total: 2,
+        high: 0,
+        medium: 1,
+        low: 1,
+      }),
     });
   }
   if (metrics.includes(MetricKey.security_issues)) {
@@ -146,15 +140,12 @@ export async function getMeasuresWithPeriodAndMetrics(
     });
     result.component.measures?.push({
       metric: MetricKey.security_issues,
-      period: {
-        index: 0,
-        value: JSON.stringify({
-          total: 1,
-          high: 0,
-          medium: 0,
-          low: 1,
-        }),
-      },
+      value: JSON.stringify({
+        total: 1,
+        high: 0,
+        medium: 0,
+        low: 1,
+      }),
     });
   }
   return result;
index c7a5de8085c778f91ad7f1e733f9c4fdf2e3283d..e9a199446748109e6e1a351cd232f649c34c5762 100644 (file)
@@ -17,8 +17,7 @@
  * 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 { Card, CardSeparator, NakedLink, TextBold, TextSubdued, themeBorder } from 'design-system';
+import { BasicSeparator, LightGreyCard, NakedLink, TextBold, TextSubdued } from 'design-system';
 import * as React from 'react';
 import { useIntl } from 'react-intl';
 import { DEFAULT_ISSUES_QUERY } from '../../../components/shared/utils';
@@ -78,9 +77,9 @@ export function SoftwareImpactMeasureCard(props: Readonly<SoftwareImpactBreakdow
     : null;
 
   return (
-    <StyledCard className="sw-w-1/3 sw-rounded-2 sw-p-4 sw-flex-col">
+    <LightGreyCard className="sw-w-1/3 sw-rounded-2 sw-p-4 sw-flex-col">
       <TextBold name={intl.formatMessage({ id: `software_quality.${softwareQuality}` })} />
-      <CardSeparator className="sw--mx-4" />
+      <BasicSeparator className="sw--mx-4" />
       <div className="sw-flex sw-flex-col sw-gap-3">
         <div className="sw-flex sw-gap-1 sw-items-end">
           <NakedLink
@@ -127,12 +126,8 @@ export function SoftwareImpactMeasureCard(props: Readonly<SoftwareImpactBreakdow
           ))}
         </div>
       </div>
-    </StyledCard>
+    </LightGreyCard>
   );
 }
 
-const StyledCard = styled(Card)`
-  border: ${themeBorder('default')};
-`;
-
 export default SoftwareImpactMeasureCard;
index 7099e26e030dc5f47a3c6627bea73f11dd4e58e8..f1e436b702e67a6601320d526c4929ce626df748 100644 (file)
  * 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 { BasicSeparator, MetricsRatingBadge, Tooltip, themeColor } from 'design-system';
+import { MetricsRatingBadge, Tooltip } from 'design-system';
 import * as React from 'react';
 import { useIntl } from 'react-intl';
 import { formatRating } from '../../../helpers/measures';
-import { SoftwareImpactSeverity, SoftwareQuality } from '../../../types/clean-code-taxonomy';
+import { SoftwareQuality } from '../../../types/clean-code-taxonomy';
+import SoftwareImpactRatingTooltip from './SoftwareImpactRatingTooltip';
 
 export interface SoftwareImpactMeasureRatingProps {
   softwareQuality: SoftwareQuality;
@@ -36,66 +36,13 @@ export function SoftwareImpactMeasureRating(props: Readonly<SoftwareImpactMeasur
 
   const rating = formatRating(value);
 
-  function ratingToWorseSeverity(rating: string): SoftwareImpactSeverity {
-    switch (rating) {
-      case 'B':
-        return SoftwareImpactSeverity.Low;
-      case 'C':
-        return SoftwareImpactSeverity.Medium;
-      case 'D':
-      case 'E':
-        return SoftwareImpactSeverity.High;
-      default:
-        return SoftwareImpactSeverity.Low;
-    }
-  }
-
-  function getTooltipContent() {
-    if (!rating || rating === 'A') {
-      return null;
-    }
-
-    const softwareQualityLabel = intl.formatMessage({
-      id: `software_quality.${softwareQuality}`,
-    });
-    const severityLabel = intl.formatMessage({
-      id: `overview.measures.software_impact.severity.${ratingToWorseSeverity(
-        rating,
-      )}.improve_tooltip`,
-    });
-
-    return (
-      <div className="sw-flex sw-flex-col sw-gap-1">
-        <span className="sw-font-semibold">
-          {intl.formatMessage({
-            id: 'overview.measures.software_impact.improve_rating_tooltip.title',
-          })}
-        </span>
-
-        <span>
-          {intl.formatMessage(
-            {
-              id: 'overview.measures.software_impact.improve_rating_tooltip.content.1',
-            },
-            {
-              softwareQuality: softwareQualityLabel,
-              ratingLabel: rating,
-              severity: severityLabel,
-            },
-          )}
-        </span>
-
-        <span className="sw-mt-4">
-          {intl.formatMessage({
-            id: 'overview.measures.software_impact.improve_rating_tooltip.content.2',
-          })}
-        </span>
-      </div>
-    );
-  }
-
   return (
-    <Tooltip overlay={getTooltipContent()}>
+    <Tooltip
+      overlay={SoftwareImpactRatingTooltip({
+        rating,
+        softwareQuality,
+      })}
+    >
       <MetricsRatingBadge
         size="lg"
         className="sw-text-sm"
@@ -111,8 +58,4 @@ export function SoftwareImpactMeasureRating(props: Readonly<SoftwareImpactMeasur
   );
 }
 
-export const StyledSeparator = styled(BasicSeparator)`
-  background-color: ${themeColor('projectCardBorder')};
-`;
-
 export default SoftwareImpactMeasureRating;
diff --git a/server/sonar-web/src/main/js/apps/overview/branches/SoftwareImpactRatingTooltip.tsx b/server/sonar-web/src/main/js/apps/overview/branches/SoftwareImpactRatingTooltip.tsx
new file mode 100644 (file)
index 0000000..17d63ec
--- /dev/null
@@ -0,0 +1,88 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2024 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 * as React from 'react';
+import { useIntl } from 'react-intl';
+import { SoftwareImpactSeverity, SoftwareQuality } from '../../../types/clean-code-taxonomy';
+
+export interface SoftwareImpactRatingTooltipProps {
+  rating?: string;
+  softwareQuality: SoftwareQuality;
+}
+
+export function SoftwareImpactRatingTooltip(props: Readonly<SoftwareImpactRatingTooltipProps>) {
+  const { rating, softwareQuality } = props;
+
+  const intl = useIntl();
+
+  if (!rating || rating === 'A') {
+    return null;
+  }
+
+  function ratingToWorseSeverity(rating: string): SoftwareImpactSeverity {
+    return (
+      {
+        B: SoftwareImpactSeverity.Low,
+        C: SoftwareImpactSeverity.Medium,
+        D: SoftwareImpactSeverity.High,
+        E: SoftwareImpactSeverity.High,
+      }[rating] ?? SoftwareImpactSeverity.Low
+    );
+  }
+
+  const softwareQualityLabel = intl.formatMessage({
+    id: `software_quality.${softwareQuality}`,
+  });
+  const severityLabel = intl.formatMessage({
+    id: `overview.measures.software_impact.severity.${ratingToWorseSeverity(
+      rating,
+    )}.improve_tooltip`,
+  });
+
+  return (
+    <div className="sw-flex sw-flex-col sw-gap-1">
+      <span className="sw-font-semibold">
+        {intl.formatMessage({
+          id: 'overview.measures.software_impact.improve_rating_tooltip.title',
+        })}
+      </span>
+
+      <span>
+        {intl.formatMessage(
+          {
+            id: 'overview.measures.software_impact.improve_rating_tooltip.content.1',
+          },
+          {
+            softwareQuality: softwareQualityLabel,
+            ratingLabel: rating,
+            severity: severityLabel,
+          },
+        )}
+      </span>
+
+      <span className="sw-mt-4">
+        {intl.formatMessage({
+          id: 'overview.measures.software_impact.improve_rating_tooltip.content.2',
+        })}
+      </span>
+    </div>
+  );
+}
+
+export default SoftwareImpactRatingTooltip;