]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-21586 Provide query for overall and new tabs in branch overview
authorstanislavh <stanislav.honcharov@sonarsource.com>
Wed, 14 Feb 2024 13:10:00 +0000 (14:10 +0100)
committersonartech <sonartech@sonarsource.com>
Thu, 15 Feb 2024 20:02:34 +0000 (20:02 +0000)
server/sonar-web/src/main/js/apps/issues/sidebar/PeriodFilter.tsx
server/sonar-web/src/main/js/apps/overview/branches/BranchOverviewRenderer.tsx
server/sonar-web/src/main/js/apps/overview/branches/MeasuresPanelNoNewCode.tsx
server/sonar-web/src/main/js/apps/overview/branches/NewCodeMeasuresPanel.tsx
server/sonar-web/src/main/js/apps/overview/branches/OverallCodeMeasuresPanel.tsx
server/sonar-web/src/main/js/apps/overview/branches/TabsPanel.tsx
server/sonar-web/src/main/js/apps/overview/utils.tsx

index 4768f867260871975640cbed9fdd0ec209273ebe..6fbd93b38b1cebebe3a459c876a19c1453c03804 100644 (file)
@@ -20,7 +20,7 @@
 import { BasicSeparator, FacetItem } from 'design-system';
 import * as React from 'react';
 import { translate } from '../../../helpers/l10n';
-import { MeasuresTabs } from '../../overview/utils';
+import { CodeScope } from '../../../helpers/urls';
 import { Query } from '../utils';
 import { FacetItemsList } from './FacetItemsList';
 
@@ -56,7 +56,7 @@ export function PeriodFilter(props: PeriodFilterProps) {
         className="it__search-navigator-facet"
         name={translate('issues.new_code')}
         onClick={handleClick}
-        value={newCodeSelected ? MeasuresTabs.New : MeasuresTabs.Overall}
+        value={newCodeSelected ? CodeScope.New : CodeScope.Overall}
       />
 
       <BasicSeparator className="sw-mb-5 sw-mt-4" />
index 1c8eefaafaa70642b9996e72902c502a6df82d07..c56c808d48b57a88526886752cd91a8079ef9d17 100644 (file)
@@ -27,7 +27,7 @@ import {
 import * as React from 'react';
 import { useIntl } from 'react-intl';
 import A11ySkipTarget from '../../../components/a11y/A11ySkipTarget';
-import { useLocation } from '../../../components/hoc/withRouter';
+import { useLocation, useRouter } from '../../../components/hoc/withRouter';
 import { parseDate } from '../../../helpers/dates';
 import { isDiffMetric } from '../../../helpers/measures';
 import { CodeScope } from '../../../helpers/urls';
@@ -39,7 +39,6 @@ import { Analysis, GraphType, MeasureHistory } from '../../../types/project-acti
 import { QualityGateStatus } from '../../../types/quality-gates';
 import { Component, MeasureEnhanced, Metric, Period, QualityGate } from '../../../types/types';
 import { AnalysisStatus } from '../components/AnalysisStatus';
-import { MeasuresTabs } from '../utils';
 import ActivityPanel from './ActivityPanel';
 import BranchMetaTopBar from './BranchMetaTopBar';
 import FirstAnalysisNextStepsNotif from './FirstAnalysisNextStepsNotif';
@@ -93,13 +92,12 @@ export default function BranchOverviewRenderer(props: BranchOverviewRendererProp
   } = props;
 
   const { query } = useLocation();
-  const [tab, selectTab] = React.useState(() => {
-    return query.codeScope === CodeScope.Overall ? MeasuresTabs.Overall : MeasuresTabs.New;
-  });
-  const intl = useIntl();
+  const router = useRouter();
 
+  const intl = useIntl();
+  const tab = query.codeScope === CodeScope.Overall ? CodeScope.Overall : CodeScope.New;
   const leakPeriod = component.qualifier === ComponentQualifier.Application ? appLeak : period;
-  const isNewCodeTab = tab === MeasuresTabs.New;
+  const isNewCodeTab = tab === CodeScope.New;
   const hasNewCodeMeasures = measures.some((m) => isDiffMetric(m.metric.key));
 
   // Check if any potentially missing uncomputed measure is not present
@@ -109,10 +107,14 @@ export default function BranchOverviewRenderer(props: BranchOverviewRendererProp
       : [MetricKey.security_issues, MetricKey.maintainability_issues, MetricKey.reliability_issues]
   ).some((key) => !measures.find((measure) => measure.metric.key === key));
 
+  const selectTab = (tab: CodeScope) => {
+    router.replace({ query: { ...query, codeScope: tab } });
+  };
+
   React.useEffect(() => {
     // Open Overall tab by default if there are no new measures.
     if (loadingStatus === false && !hasNewCodeMeasures && isNewCodeTab) {
-      selectTab(MeasuresTabs.Overall);
+      selectTab(CodeScope.Overall);
     }
     // In this case, we explicitly do NOT want to mark tab as a dependency, as
     // it would prevent the user from selecting it, even if it's empty.
index b2bea1237ad9ba16d1cadf4002a4a10a2de3de7b..17bc57ee8fcf27c37f4044e9b37159676a0b7093 100644 (file)
@@ -25,12 +25,11 @@ import { getTabPanelId } from '../../../components/controls/BoxedTabs';
 import { getBranchLikeQuery } from '../../../helpers/branch-like';
 import { translate } from '../../../helpers/l10n';
 import { getBaseUrl } from '../../../helpers/system';
-import { queryToSearch } from '../../../helpers/urls';
+import { CodeScope, queryToSearch } from '../../../helpers/urls';
 import { Branch } from '../../../types/branch-like';
 import { ComponentQualifier } from '../../../types/component';
 import { NewCodeDefinitionType } from '../../../types/new-code-definition';
 import { Component, Period } from '../../../types/types';
-import { MeasuresTabs } from '../utils';
 
 export interface MeasuresPanelNoNewCodeProps {
   branch?: Branch;
@@ -64,7 +63,7 @@ export default function MeasuresPanelNoNewCode(props: MeasuresPanelNoNewCodeProp
   return (
     <div
       className="display-flex-center display-flex-justify-center"
-      id={getTabPanelId(MeasuresTabs.New)}
+      id={getTabPanelId(CodeScope.New)}
       style={{ height: 500 }}
     >
       <img
index d7918f1f21437efba7314beaade4dfd2947158b5..20c966c44f5e1480b9c52ce56bdaf4ebe7cca509 100644 (file)
@@ -36,7 +36,11 @@ import { getLeakValue } from '../../../components/measure/utils';
 import { DEFAULT_ISSUES_QUERY } from '../../../components/shared/utils';
 import { getBranchLikeQuery } from '../../../helpers/branch-like';
 import { findMeasure, formatMeasure, formatRating } from '../../../helpers/measures';
-import { getComponentIssuesUrl, getComponentSecurityHotspotsUrl } from '../../../helpers/urls';
+import {
+  CodeScope,
+  getComponentIssuesUrl,
+  getComponentSecurityHotspotsUrl,
+} from '../../../helpers/urls';
 import { Branch } from '../../../types/branch-like';
 import { isApplication } from '../../../types/component';
 import { IssueStatus } from '../../../types/issues';
@@ -45,7 +49,7 @@ import { QualityGateStatus } from '../../../types/quality-gates';
 import { Component, MeasureEnhanced } from '../../../types/types';
 import { IssueMeasuresCardInner } from '../components/IssueMeasuresCardInner';
 import MeasuresCardNumber from '../components/MeasuresCardNumber';
-import { MeasuresTabs, Status, getConditionRequiredLabel } from '../utils';
+import { Status, getConditionRequiredLabel } from '../utils';
 import MeasuresPanelPercentCards from './MeasuresPanelPercentCards';
 
 interface Props {
@@ -107,7 +111,7 @@ export default function NewCodeMeasuresPanel(props: Readonly<Props>) {
   }
 
   return (
-    <div className="sw-grid sw-grid-cols-2 sw-gap-4 sw-mt-6" id={getTabPanelId(MeasuresTabs.New)}>
+    <div className="sw-grid sw-grid-cols-2 sw-gap-4 sw-mt-6" id={getTabPanelId(CodeScope.New)}>
       <LightGreyCard className="sw-flex sw-col-span-2 sw-rounded-2 sw-gap-4">
         <IssueMeasuresCardInner
           data-testid="overview__measures-new_issues"
index 52893ab28c9baf3bf00d34f751dbe3ceb33ddf66..5530d595dac33eee9c5383f5fd55b96fa6c3919e 100644 (file)
@@ -28,7 +28,11 @@ import * as React from 'react';
 import { useIntl } from 'react-intl';
 import { getBranchLikeQuery } from '../../../helpers/branch-like';
 import { findMeasure, formatMeasure, formatRating } from '../../../helpers/measures';
-import { getComponentIssuesUrl, getComponentSecurityHotspotsUrl } from '../../../helpers/urls';
+import {
+  CodeScope,
+  getComponentIssuesUrl,
+  getComponentSecurityHotspotsUrl,
+} from '../../../helpers/urls';
 import { Branch } from '../../../types/branch-like';
 import { SoftwareQuality } from '../../../types/clean-code-taxonomy';
 import { isApplication } from '../../../types/component';
@@ -39,7 +43,6 @@ 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';
 
@@ -62,7 +65,7 @@ export default function OverallCodeMeasuresPanel(props: Readonly<OverallCodeMeas
   const securityRating = findMeasure(measures, MetricKey.security_review_rating)?.value;
 
   return (
-    <div id={getTabPanelId(MeasuresTabs.Overall)} className="sw-mt-6">
+    <div id={getTabPanelId(CodeScope.Overall)} className="sw-mt-6">
       <div className="sw-flex sw-gap-4">
         <SoftwareImpactMeasureCard
           branch={branch}
index 9a4fa00083aa0172a099a8c2ce5de950eb51c521..d4f366e35e1aaddc98e0ccee1fbf28fee7da7acd 100644 (file)
@@ -32,6 +32,7 @@ import { FormattedMessage } from 'react-intl';
 import DocLink from '../../../components/common/DocLink';
 import { translate } from '../../../helpers/l10n';
 import { isDiffMetric } from '../../../helpers/measures';
+import { CodeScope } from '../../../helpers/urls';
 import { ApplicationPeriod } from '../../../types/application';
 import { Branch } from '../../../types/branch-like';
 import { ComponentQualifier } from '../../../types/component';
@@ -39,7 +40,6 @@ import { Analysis, ProjectAnalysisEventCategory } from '../../../types/project-a
 import { QualityGateStatus } from '../../../types/quality-gates';
 import { Component, Period } from '../../../types/types';
 import LastAnalysisLabel from '../components/LastAnalysisLabel';
-import { MeasuresTabs } from '../utils';
 import { MAX_ANALYSES_NB } from './ActivityPanel';
 import { LeakPeriodInfo } from './LeakPeriodInfo';
 
@@ -52,7 +52,7 @@ export interface MeasuresPanelProps {
   branch?: Branch;
   qgStatuses?: QualityGateStatus[];
   isNewCode: boolean;
-  onTabSelect: (tab: MeasuresTabs) => void;
+  onTabSelect: (tab: CodeScope) => void;
 }
 
 const SQ_UPGRADE_NOTIFICATION_TIMEOUT = { weeks: 3 };
@@ -118,12 +118,12 @@ export function TabsPanel(props: React.PropsWithChildren<MeasuresPanelProps>) {
 
   const tabs = [
     {
-      value: MeasuresTabs.New,
+      value: CodeScope.New,
       label: translate('overview.new_code'),
       counter: failingConditionsOnNewCode,
     },
     {
-      value: MeasuresTabs.Overall,
+      value: CodeScope.Overall,
       label: translate('overview.overall_code'),
       counter: failingConditionsOnOverallCode,
     },
@@ -165,7 +165,7 @@ export function TabsPanel(props: React.PropsWithChildren<MeasuresPanelProps>) {
             <Tabs
               onChange={props.onTabSelect}
               options={tabs}
-              value={isNewCode ? MeasuresTabs.New : MeasuresTabs.Overall}
+              value={isNewCode ? CodeScope.New : CodeScope.Overall}
             >
               {isNewCode && leakPeriod && (
                 <LightLabel className="sw-body-sm sw-flex sw-items-center sw-mr-6">
index 40c962140d106c14381d8df03a16ac077ccbaac9..bcb1431ffab361a2475cc4886b1dac434daf1d55 100644 (file)
@@ -131,11 +131,6 @@ const MEASURES_VARIATIONS_METRICS = [
   MetricKey.vulnerabilities,
 ];
 
-export enum MeasuresTabs {
-  New = 'new',
-  Overall = 'overall',
-}
-
 export enum MeasurementType {
   Coverage = 'COVERAGE',
   Duplication = 'DUPLICATION',