]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-10291 Show elements without color measure in treemap
authorStas Vilchik <stas.vilchik@sonarsource.com>
Tue, 27 Mar 2018 15:41:26 +0000 (17:41 +0200)
committerSonarTech <sonartech@sonarsource.com>
Wed, 28 Mar 2018 18:20:59 +0000 (20:20 +0200)
server/sonar-web/src/main/js/apps/component-measures/components/MeasureContent.js
server/sonar-web/src/main/js/apps/component-measures/components/MeasureHeader.js
server/sonar-web/src/main/js/apps/component-measures/components/__tests__/MeasureHeader-test.js
server/sonar-web/src/main/js/apps/component-measures/components/__tests__/__snapshots__/MeasureHeader-test.js.snap
server/sonar-web/src/main/js/apps/component-measures/drilldown/TreeMapView.js

index 8feb83e1167ac074082377918566ca1346b191b5..5c5205077cbca90543a0229f05dbeadd7bf08912 100644 (file)
@@ -324,20 +324,21 @@ export default class MeasureContent extends React.PureComponent {
         {metric == null && (
           <MetricNotFound className="layout-page-main-inner measure-details-content" />
         )}
-        {metric != null &&
-          measure != null && (
-            <div className="layout-page-main-inner measure-details-content">
-              <MeasureHeader
-                branchLike={branchLike}
-                component={component}
-                components={this.state.components}
-                leakPeriod={this.props.leakPeriod}
-                measure={measure}
-                secondaryMeasure={this.props.secondaryMeasure}
-              />
-              {isFileType(component) ? this.renderCode() : this.renderMeasure()}
-            </div>
-          )}
+        {metric != null && (
+          <div className="layout-page-main-inner measure-details-content">
+            <MeasureHeader
+              branchLike={branchLike}
+              component={component}
+              components={this.state.components}
+              leakPeriod={this.props.leakPeriod}
+              // fall back to `undefined` to be compatible with typescript files where we compare with `=== undefined`
+              measure={measure || undefined}
+              metric={metric}
+              secondaryMeasure={this.props.secondaryMeasure}
+            />
+            {isFileType(component) ? this.renderCode() : this.renderMeasure()}
+          </div>
+        )}
       </div>
     );
   }
index abff84b4d2cad900cc0fcafff9534c34e8eeff52..9455760a908e4b9f3d532f07bfd028e6845ae5d6 100644 (file)
@@ -31,44 +31,49 @@ import { getMeasureHistoryUrl } from '../../../helpers/urls';
 import { isDiffMetric } from '../../../helpers/measures';
 /*:: import type { Component, Period } from '../types'; */
 /*:: import type { MeasureEnhanced } from '../../../components/measure/types'; */
+/*:: import type { Metric } from '../../../store/metrics/actions'; */
 
 /*:: type Props = {|
   branchLike?: { id?: string; name: string },
   component: Component,
   components: Array<Component>,
   leakPeriod?: Period,
-  measure: MeasureEnhanced,
+  measure?: MeasureEnhanced,
+  metric: Metric,
   secondaryMeasure: ?MeasureEnhanced
 |}; */
 
 export default function MeasureHeader(props /*: Props*/) {
-  const { branchLike, component, leakPeriod, measure, secondaryMeasure } = props;
-  const { metric } = measure;
+  const { branchLike, component, leakPeriod, measure, metric, secondaryMeasure } = props;
   const isDiff = isDiffMetric(metric.key);
   return (
     <div className="measure-details-header big-spacer-bottom">
       <div className="measure-details-primary">
         <div className="measure-details-metric">
-          <IssueTypeIcon query={metric.key} className="little-spacer-right text-text-bottom" />
+          <IssueTypeIcon className="little-spacer-right text-text-bottom" query={metric.key} />
           {getLocalizedMetricName(metric)}
           <span className="measure-details-value spacer-left">
             <strong>
               {isDiff ? (
                 <Measure
                   className="domain-measures-leak"
-                  value={measure.leak}
                   metricKey={metric.key}
                   metricType={metric.type}
+                  value={measure && measure.leak}
                 />
               ) : (
-                <Measure value={measure.value} metricKey={metric.key} metricType={metric.type} />
+                <Measure
+                  metricKey={metric.key}
+                  metricType={metric.type}
+                  value={measure && measure.value}
+                />
               )}
             </strong>
           </span>
           {!isDiff && (
             <Tooltip
-              placement="right"
-              overlay={translate('component_measures.show_metric_history')}>
+              overlay={translate('component_measures.show_metric_history')}
+              placement="right">
               <Link
                 className="js-show-history spacer-left button button-small"
                 to={getMeasureHistoryUrl(component.key, metric.key, branchLike)}>
index 5b02e3d87fb12f9e0f9770666146a086a1617573..8e177e736dfd76c4809afe7ea35c56dac8252730 100644 (file)
@@ -21,24 +21,28 @@ import React from 'react';
 import { shallow } from 'enzyme';
 import MeasureHeader from '../MeasureHeader';
 
+const METRIC = {
+  key: 'reliability_rating',
+  type: 'RATING',
+  name: 'Reliability Rating'
+};
+
 const MEASURE = {
   value: '3.0',
   periods: [{ index: 1, value: '0.0' }],
-  metric: {
-    key: 'reliability_rating',
-    type: 'RATING',
-    name: 'Reliability Rating'
-  },
+  metric: METRIC,
   leak: '0.0'
 };
 
+const LEAK_METRIC = {
+  key: 'new_reliability_rating',
+  type: 'RATING',
+  name: 'Reliability Rating on New Code'
+};
+
 const LEAK_MEASURE = {
   periods: [{ index: 1, value: '3.0' }],
-  metric: {
-    key: 'new_reliability_rating',
-    type: 'RATING',
-    name: 'Reliability Rating on New Code'
-  },
+  metric: LEAK_METRIC,
   leak: '3.0'
 };
 
@@ -63,6 +67,7 @@ const PROPS = {
     parameter: '6,4'
   },
   measure: MEASURE,
+  metric: METRIC,
   paging: null,
   secondaryMeasure: null,
   selectedIdx: null
@@ -73,7 +78,9 @@ it('should render correctly', () => {
 });
 
 it('should render correctly for leak', () => {
-  expect(shallow(<MeasureHeader {...PROPS} measure={LEAK_MEASURE} />)).toMatchSnapshot();
+  expect(
+    shallow(<MeasureHeader {...PROPS} measure={LEAK_MEASURE} metric={LEAK_METRIC} />)
+  ).toMatchSnapshot();
 });
 
 it('should render with branch', () => {
@@ -101,3 +108,7 @@ it('should display correctly for open file', () => {
   wrapper.setProps({ components: [{ key: 'foo' }, { key: 'bar' }] });
   expect(wrapper.find('.measure-details-primary-actions')).toMatchSnapshot();
 });
+
+it('should work with measure without value', () => {
+  expect(shallow(<MeasureHeader {...PROPS} measure={undefined} />)).toMatchSnapshot();
+});
index 8da497107c3d159b6546de6a68d83910bb9f7a80..9ca440a270acb2a3091f2ad8076c615bb06fd62f 100644 (file)
@@ -195,3 +195,76 @@ exports[`should render with branch 1`] = `
   <IconHistory />
 </Link>
 `;
+
+exports[`should work with measure without value 1`] = `
+<div
+  className="measure-details-header big-spacer-bottom"
+>
+  <div
+    className="measure-details-primary"
+  >
+    <div
+      className="measure-details-metric"
+    >
+      <IssueTypeIcon
+        className="little-spacer-right text-text-bottom"
+        query="reliability_rating"
+      />
+      Reliability Rating
+      <span
+        className="measure-details-value spacer-left"
+      >
+        <strong>
+          <Measure
+            metricKey="reliability_rating"
+            metricType="RATING"
+          />
+        </strong>
+      </span>
+      <Tooltip
+        overlay="component_measures.show_metric_history"
+        placement="right"
+      >
+        <Link
+          className="js-show-history spacer-left button button-small"
+          onlyActiveOnIndex={false}
+          style={Object {}}
+          to={
+            Object {
+              "pathname": "/project/activity",
+              "query": Object {
+                "custom_metrics": "reliability_rating",
+                "graph": "custom",
+                "id": "foo",
+              },
+            }
+          }
+        >
+          <IconHistory />
+        </Link>
+      </Tooltip>
+    </div>
+    <div
+      className="measure-details-primary-actions"
+    >
+      <LeakPeriodLegend
+        className="spacer-left"
+        component={
+          Object {
+            "key": "foo",
+            "qualifier": "TRK",
+          }
+        }
+        period={
+          Object {
+            "date": "2017-05-16T13:50:02+0200",
+            "index": 1,
+            "mode": "previous_version",
+            "parameter": "6,4",
+          }
+        }
+      />
+    </div>
+  </div>
+</div>
+`;
index 1dd3fd68f26cc1fe0bb49015798053a89f6edc5e..5dac90f6fc747a6c7873b606b57b35c7efbe616d 100644 (file)
@@ -70,12 +70,11 @@ export default class TreeMapView extends React.PureComponent {
       .map(component => {
         const colorMeasure = component.measures.find(measure => measure.metric.key === metric.key);
         const sizeMeasure = component.measures.find(measure => measure.metric.key !== metric.key);
-        if (colorMeasure == null || sizeMeasure == null) {
+        if (sizeMeasure == null) {
           return null;
         }
-        const colorValue = isDiffMetric(colorMeasure.metric.key)
-          ? colorMeasure.leak
-          : colorMeasure.value;
+        const colorValue =
+          colorMeasure && (isDiffMetric(metric.key) ? colorMeasure.leak : colorMeasure.value);
         const sizeValue = isDiffMetric(sizeMeasure.metric.key)
           ? sizeMeasure.leak
           : sizeMeasure.value;
@@ -89,7 +88,7 @@ export default class TreeMapView extends React.PureComponent {
           icon: <QualifierIcon color={theme.baseFontColor} qualifier={component.qualifier} />,
           tooltip: this.getTooltip(
             component.name,
-            colorMeasure.metric,
+            metric,
             sizeMeasure.metric,
             colorValue,
             sizeValue