]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-12749 DRYer SourceViewerHeader
authorJeremy Davis <jeremy.davis@sonarsource.com>
Wed, 12 Aug 2020 07:59:44 +0000 (09:59 +0200)
committersonartech <sonartech@sonarsource.com>
Wed, 26 Aug 2020 20:06:43 +0000 (20:06 +0000)
14 files changed:
server/sonar-web/src/main/js/apps/overview/branches/MeasuresPanel.tsx
server/sonar-web/src/main/js/apps/overview/branches/MeasuresPanelIssueMeasureRow.tsx
server/sonar-web/src/main/js/apps/overview/branches/__tests__/MeasuresPanelIssueMeasureRow-test.tsx
server/sonar-web/src/main/js/apps/overview/components/IssueLabel.tsx
server/sonar-web/src/main/js/apps/overview/components/IssueRating.tsx
server/sonar-web/src/main/js/apps/overview/components/__tests__/IssueLabel-test.tsx
server/sonar-web/src/main/js/apps/overview/components/__tests__/IssueRating-test.tsx
server/sonar-web/src/main/js/apps/overview/pullRequests/PullRequestOverview.tsx
server/sonar-web/src/main/js/apps/overview/utils.ts
server/sonar-web/src/main/js/components/SourceViewer/SourceViewerHeader.tsx
server/sonar-web/src/main/js/components/SourceViewer/__tests__/SourceViewerHeader-test.tsx
server/sonar-web/src/main/js/helpers/constants.ts
server/sonar-web/src/main/js/helpers/issues.ts
server/sonar-web/src/main/js/types/issues.ts [new file with mode: 0644]

index 0dddf9776bb6b3552d328caf75441a5deff2d574..977153b70ae7005fdb5bf74c37e0663d11b92d83 100644 (file)
@@ -27,9 +27,10 @@ import { findMeasure } from '../../../helpers/measures';
 import { ApplicationPeriod } from '../../../types/application';
 import { BranchLike } from '../../../types/branch-like';
 import { ComponentQualifier } from '../../../types/component';
+import { IssueType } from '../../../types/issues';
 import { MetricKey } from '../../../types/metrics';
 import MeasurementLabel from '../components/MeasurementLabel';
-import { IssueType, MeasurementType } from '../utils';
+import { MeasurementType } from '../utils';
 import { DrilldownMeasureValue } from './DrilldownMeasureValue';
 import { LeakPeriodInfo } from './LeakPeriodInfo';
 import MeasuresPanelIssueMeasureRow from './MeasuresPanelIssueMeasureRow';
index dfe8795ce2c34d51df31b1084167f000054f3f7e..a1c1d291cd188d1c429ede6687604c8ddcb74837 100644 (file)
@@ -20,9 +20,9 @@
 import * as React from 'react';
 import { BranchLike } from '../../../types/branch-like';
 import { ComponentQualifier } from '../../../types/component';
+import { IssueType } from '../../../types/issues';
 import IssueLabel from '../components/IssueLabel';
 import IssueRating from '../components/IssueRating';
-import { IssueType } from '../utils';
 import DebtValue from './DebtValue';
 import SecurityHotspotsReviewed from './SecurityHotspotsReviewed';
 
index 2503108b0a02cf115d5274b3f15818ce611173f3..1efc4349978b1cff45cb35dbe6bddb31806a1121 100644 (file)
@@ -22,8 +22,8 @@ import * as React from 'react';
 import { mockMainBranch } from '../../../../helpers/mocks/branch-like';
 import { mockComponent, mockMeasureEnhanced, mockMetric } from '../../../../helpers/testMocks';
 import { ComponentQualifier } from '../../../../types/component';
+import { IssueType } from '../../../../types/issues';
 import { MetricKey } from '../../../../types/metrics';
-import { IssueType } from '../../utils';
 import MeasuresPanelIssueMeasureRow, {
   MeasuresPanelIssueMeasureRowProps
 } from '../MeasuresPanelIssueMeasureRow';
index 89c2405c569e4819d50d1bad13d194bebf36ae78..f2c86205aa633db17c64d129947b01a4bbc51c1a 100644 (file)
@@ -27,7 +27,8 @@ import { getBranchLikeQuery } from '../../../helpers/branch-like';
 import { findMeasure } from '../../../helpers/measures';
 import { getComponentIssuesUrl, getComponentSecurityHotspotsUrl } from '../../../helpers/urls';
 import { BranchLike } from '../../../types/branch-like';
-import { getIssueIconClass, getIssueMetricKey, IssueType } from '../utils';
+import { IssueType } from '../../../types/issues';
+import { getIssueIconClass, getIssueMetricKey } from '../utils';
 
 export interface IssueLabelProps {
   branchLike?: BranchLike;
index 05279460952f565bcbc2a697341e1eadb5e3bf91..830c0a531e510b05221063f591e862b019af9415 100644 (file)
@@ -24,7 +24,8 @@ import { getLeakValue, getRatingTooltip } from '../../../components/measure/util
 import DrilldownLink from '../../../components/shared/DrilldownLink';
 import { findMeasure } from '../../../helpers/measures';
 import { BranchLike } from '../../../types/branch-like';
-import { getIssueRatingMetricKey, getIssueRatingName, IssueType } from '../utils';
+import { IssueType } from '../../../types/issues';
+import { getIssueRatingMetricKey, getIssueRatingName } from '../utils';
 
 export interface IssueRatingProps {
   branchLike?: BranchLike;
index 17b9f42fcb768446445bbf5ef507c0ebe453f317..40f07a5621c086eed2d36345ea9c21a60fc2efd9 100644 (file)
@@ -21,8 +21,8 @@ import { shallow } from 'enzyme';
 import * as React from 'react';
 import { mockPullRequest } from '../../../../helpers/mocks/branch-like';
 import { mockComponent, mockMeasureEnhanced, mockMetric } from '../../../../helpers/testMocks';
+import { IssueType } from '../../../../types/issues';
 import { MetricKey } from '../../../../types/metrics';
-import { IssueType } from '../../utils';
 import { IssueLabel, IssueLabelProps } from '../IssueLabel';
 
 it('should render correctly for bugs', () => {
index 1b660f3c1242e5e174a228bf23dc3c1f9ecd225b..d85efbd06c55d6d51f8a39e46a259e4cce565ffc 100644 (file)
@@ -21,8 +21,8 @@ import { shallow } from 'enzyme';
 import * as React from 'react';
 import { mockPullRequest } from '../../../../helpers/mocks/branch-like';
 import { mockComponent, mockMeasureEnhanced, mockMetric } from '../../../../helpers/testMocks';
+import { IssueType } from '../../../../types/issues';
 import { MetricKey } from '../../../../types/metrics';
-import { IssueType } from '../../utils';
 import { IssueRating, IssueRatingProps } from '../IssueRating';
 
 it('should render correctly for bugs', () => {
index 176ede6361f2af7bc92940ec9903cc4913053a76..df49eb324173a81e693cdc4fd3b148add8fc8077 100644 (file)
@@ -32,13 +32,14 @@ import { enhanceConditionWithMeasure, enhanceMeasuresWithMetrics } from '../../.
 import { fetchBranchStatus } from '../../../store/rootActions';
 import { getBranchStatusByBranchLike, Store } from '../../../store/rootReducer';
 import { BranchLike, PullRequest } from '../../../types/branch-like';
+import { IssueType } from '../../../types/issues';
 import { QualityGateStatusCondition } from '../../../types/quality-gates';
 import IssueLabel from '../components/IssueLabel';
 import IssueRating from '../components/IssueRating';
 import MeasurementLabel from '../components/MeasurementLabel';
 import QualityGateConditions from '../components/QualityGateConditions';
 import '../styles.css';
-import { IssueType, MeasurementType, PR_METRICS } from '../utils';
+import { MeasurementType, PR_METRICS } from '../utils';
 import AfterMergeEstimate from './AfterMergeEstimate';
 import LargeQualityGateBadge from './LargeQualityGateBadge';
 
index 39e122d0a0d99b477e38115873e6369b1a46da94..eadd034a43782356db4477b27446e0233060f080 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 BugIcon from 'sonar-ui-common/components/icons/BugIcon';
-import CodeSmellIcon from 'sonar-ui-common/components/icons/CodeSmellIcon';
-import SecurityHotspotIcon from 'sonar-ui-common/components/icons/SecurityHotspotIcon';
-import VulnerabilityIcon from 'sonar-ui-common/components/icons/VulnerabilityIcon';
 import DuplicationsRating from 'sonar-ui-common/components/ui/DuplicationsRating';
 import { translate } from 'sonar-ui-common/helpers/l10n';
 import CoverageRating from '../../components/ui/CoverageRating';
+import { ISSUETYPE_METRIC_KEYS_MAP } from '../../helpers/issues';
+import { IssueType } from '../../types/issues';
 import { MetricKey } from '../../types/metrics';
 
 export const METRICS: string[] = [
@@ -136,62 +134,24 @@ const MEASUREMENTS_MAP = {
   }
 };
 
-export enum IssueType {
-  CodeSmell = 'CODE_SMELL',
-  Vulnerability = 'VULNERABILITY',
-  Bug = 'BUG',
-  SecurityHotspot = 'SECURITY_HOTSPOT'
-}
-
-const ISSUETYPE_MAP = {
-  [IssueType.CodeSmell]: {
-    metric: MetricKey.code_smells,
-    newMetric: MetricKey.new_code_smells,
-    rating: MetricKey.sqale_rating,
-    newRating: MetricKey.new_maintainability_rating,
-    ratingName: 'Maintainability',
-    iconClass: CodeSmellIcon
-  },
-  [IssueType.Vulnerability]: {
-    metric: MetricKey.vulnerabilities,
-    newMetric: MetricKey.new_vulnerabilities,
-    rating: MetricKey.security_rating,
-    newRating: MetricKey.new_security_rating,
-    ratingName: 'Security',
-    iconClass: VulnerabilityIcon
-  },
-  [IssueType.Bug]: {
-    metric: MetricKey.bugs,
-    newMetric: MetricKey.new_bugs,
-    rating: MetricKey.reliability_rating,
-    newRating: MetricKey.new_reliability_rating,
-    ratingName: 'Reliability',
-    iconClass: BugIcon
-  },
-  [IssueType.SecurityHotspot]: {
-    metric: MetricKey.security_hotspots,
-    newMetric: MetricKey.new_security_hotspots,
-    rating: MetricKey.security_review_rating,
-    newRating: MetricKey.new_security_review_rating,
-    ratingName: 'SecurityReview',
-    iconClass: SecurityHotspotIcon
-  }
-};
-
 export function getIssueRatingName(type: IssueType) {
-  return translate('metric_domain', ISSUETYPE_MAP[type].ratingName);
+  return translate('metric_domain', ISSUETYPE_METRIC_KEYS_MAP[type].ratingName);
 }
 
 export function getIssueIconClass(type: IssueType) {
-  return ISSUETYPE_MAP[type].iconClass;
+  return ISSUETYPE_METRIC_KEYS_MAP[type].iconClass;
 }
 
 export function getIssueMetricKey(type: IssueType, useDiffMetric: boolean) {
-  return useDiffMetric ? ISSUETYPE_MAP[type].newMetric : ISSUETYPE_MAP[type].metric;
+  return useDiffMetric
+    ? ISSUETYPE_METRIC_KEYS_MAP[type].newMetric
+    : ISSUETYPE_METRIC_KEYS_MAP[type].metric;
 }
 
 export function getIssueRatingMetricKey(type: IssueType, useDiffMetric: boolean) {
-  return useDiffMetric ? ISSUETYPE_MAP[type].newRating : ISSUETYPE_MAP[type].rating;
+  return useDiffMetric
+    ? ISSUETYPE_METRIC_KEYS_MAP[type].newRating
+    : ISSUETYPE_METRIC_KEYS_MAP[type].rating;
 }
 
 export function getMeasurementIconClass(type: MeasurementType) {
index 9c4be2d5a84b19e037483cc4311b90d446f41829..63f01ef746ce97acfc7e03a4a0fa2cfaa7cad70c 100644 (file)
@@ -32,6 +32,8 @@ import { collapsedDirFromPath, fileFromPath } from 'sonar-ui-common/helpers/path
 import { omitNil } from 'sonar-ui-common/helpers/request';
 import { getBaseUrl, getPathUrlAsString } from 'sonar-ui-common/helpers/urls';
 import { getBranchLikeQuery } from '../../helpers/branch-like';
+import { ISSUE_TYPES } from '../../helpers/constants';
+import { ISSUETYPE_METRIC_KEYS_MAP } from '../../helpers/issues';
 import { getBranchLikeUrl, getCodeUrl, getComponentIssuesUrl } from '../../helpers/urls';
 import { BranchLike } from '../../types/branch-like';
 import { ComponentQualifier } from '../../types/component';
@@ -50,13 +52,6 @@ interface State {
   measuresOverlay: boolean;
 }
 
-const METRIC_KEY_FOR_ISSUE_TYPE: { [type in T.IssueType]: string } = {
-  BUG: 'bugs',
-  VULNERABILITY: 'vulnerabilities',
-  CODE_SMELL: 'code_smells',
-  SECURITY_HOTSPOT: 'security_hotspots'
-};
-
 export default class SourceViewerHeader extends React.PureComponent<Props, State> {
   state: State = { measuresOverlay: false };
 
@@ -83,7 +78,7 @@ export default class SourceViewerHeader extends React.PureComponent<Props, State
         <>
           <div className="source-viewer-header-measure-separator" />
 
-          {['BUG', 'VULNERABILITY', 'CODE_SMELL', 'SECURITY_HOTSPOT'].map((type: T.IssueType) => {
+          {ISSUE_TYPES.map((type: T.IssueType) => {
             const params = {
               ...getBranchLikeQuery(branchLike),
               fileUuids: sourceViewerFile.uuid,
@@ -92,7 +87,7 @@ export default class SourceViewerHeader extends React.PureComponent<Props, State
             };
 
             const measure = componentMeasures.find(
-              m => m.metric === METRIC_KEY_FOR_ISSUE_TYPE[type]
+              m => m.metric === ISSUETYPE_METRIC_KEYS_MAP[type].metric
             );
             return (
               <div className="source-viewer-header-measure" key={type}>
index 00f10dee620b0b9022d37fdac5e4679dddf46556..5b50fd23e8656e98c0d9c935ece0f34fc52c4936 100644 (file)
@@ -21,6 +21,7 @@ import { shallow } from 'enzyme';
 import * as React from 'react';
 import { mockMainBranch } from '../../../helpers/mocks/branch-like';
 import { mockSourceViewerFile } from '../../../helpers/testMocks';
+import { MetricKey } from '../../../types/metrics';
 import SourceViewerHeader from '../SourceViewerHeader';
 
 it('should render correctly for a regular file', () => {
@@ -38,10 +39,10 @@ it('should render correctly for a unit test', () => {
 
 it('should render correctly if issue details are passed', () => {
   const componentMeasures: T.Measure[] = [
-    { metric: 'code_smells', value: '1' },
-    { metric: 'unused_metric_to_be_ignored', value: '42' },
-    { metric: 'security_hotspots', value: '2' },
-    { metric: 'vulnerabilities', value: '2' }
+    { metric: MetricKey.code_smells, value: '1' },
+    { metric: MetricKey.file_complexity_distribution, value: '42' }, // unused, should be ignored
+    { metric: MetricKey.security_hotspots, value: '2' },
+    { metric: MetricKey.vulnerabilities, value: '2' }
   ];
 
   expect(
index f0d60622137f3a6020cb9dcea0aa54f80d03f9fd..2e101a490d0f6d56982d0c56d7bf2feec46539f7 100644 (file)
  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
  */
 import { colors } from '../app/theme';
+import { IssueType } from '../types/issues';
 
 export const SEVERITIES = ['BLOCKER', 'CRITICAL', 'MAJOR', 'MINOR', 'INFO'];
 export const STATUSES = ['OPEN', 'REOPENED', 'CONFIRMED', 'RESOLVED', 'CLOSED'];
 export const ISSUE_TYPES: T.IssueType[] = [
-  'BUG',
-  'VULNERABILITY',
-  'CODE_SMELL',
-  'SECURITY_HOTSPOT'
+  IssueType.Bug,
+  IssueType.Vulnerability,
+  IssueType.CodeSmell,
+  IssueType.SecurityHotspot
 ];
 export const RULE_TYPES: T.RuleType[] = ['BUG', 'VULNERABILITY', 'CODE_SMELL', 'SECURITY_HOTSPOT'];
 export const RULE_STATUSES = ['READY', 'BETA', 'DEPRECATED'];
index dc84f8d64fb9124f50382fed63e2de8a0ab35bec..68a5d9ee2f0ac565516fa930deae6b5ae0effef8 100644 (file)
  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
  */
 import { flatten, sortBy } from 'lodash';
+import BugIcon from 'sonar-ui-common/components/icons/BugIcon';
+import CodeSmellIcon from 'sonar-ui-common/components/icons/CodeSmellIcon';
+import SecurityHotspotIcon from 'sonar-ui-common/components/icons/SecurityHotspotIcon';
+import VulnerabilityIcon from 'sonar-ui-common/components/icons/VulnerabilityIcon';
+import { IssueType } from '../types/issues';
+import { MetricKey } from '../types/metrics';
 import { ISSUE_TYPES } from './constants';
 
 interface Comment {
@@ -170,3 +176,38 @@ export function parseIssueFromResponse(
     ...ensureTextRange(issue)
   } as T.Issue;
 }
+
+export const ISSUETYPE_METRIC_KEYS_MAP = {
+  [IssueType.CodeSmell]: {
+    metric: MetricKey.code_smells,
+    newMetric: MetricKey.new_code_smells,
+    rating: MetricKey.sqale_rating,
+    newRating: MetricKey.new_maintainability_rating,
+    ratingName: 'Maintainability',
+    iconClass: CodeSmellIcon
+  },
+  [IssueType.Vulnerability]: {
+    metric: MetricKey.vulnerabilities,
+    newMetric: MetricKey.new_vulnerabilities,
+    rating: MetricKey.security_rating,
+    newRating: MetricKey.new_security_rating,
+    ratingName: 'Security',
+    iconClass: VulnerabilityIcon
+  },
+  [IssueType.Bug]: {
+    metric: MetricKey.bugs,
+    newMetric: MetricKey.new_bugs,
+    rating: MetricKey.reliability_rating,
+    newRating: MetricKey.new_reliability_rating,
+    ratingName: 'Reliability',
+    iconClass: BugIcon
+  },
+  [IssueType.SecurityHotspot]: {
+    metric: MetricKey.security_hotspots,
+    newMetric: MetricKey.new_security_hotspots,
+    rating: MetricKey.security_review_rating,
+    newRating: MetricKey.new_security_review_rating,
+    ratingName: 'SecurityReview',
+    iconClass: SecurityHotspotIcon
+  }
+};
diff --git a/server/sonar-web/src/main/js/types/issues.ts b/server/sonar-web/src/main/js/types/issues.ts
new file mode 100644 (file)
index 0000000..a9d2ae5
--- /dev/null
@@ -0,0 +1,26 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2020 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 IssueType {
+  CodeSmell = 'CODE_SMELL',
+  Vulnerability = 'VULNERABILITY',
+  Bug = 'BUG',
+  SecurityHotspot = 'SECURITY_HOTSPOT'
+}