]> source.dussan.org Git - sonarqube.git/commitdiff
Move Measure component to the global components folder
authorGrégoire Aubert <gregoire.aubert@sonarsource.com>
Wed, 26 Jul 2017 10:07:07 +0000 (12:07 +0200)
committerGrégoire Aubert <gregoire.aubert@sonarsource.com>
Mon, 14 Aug 2017 09:44:44 +0000 (11:44 +0200)
server/sonar-web/src/main/js/apps/code/components/ComponentMeasure.js
server/sonar-web/src/main/js/apps/overview/qualityGate/QualityGateCondition.js
server/sonar-web/src/main/js/apps/overview/qualityGate/__tests__/__snapshots__/QualityGateCondition-test.js.snap
server/sonar-web/src/main/js/apps/projects/components/ProjectCardLeakMeasures.js
server/sonar-web/src/main/js/apps/projects/components/ProjectCardOverallMeasures.js
server/sonar-web/src/main/js/apps/projects/components/__tests__/__snapshots__/ProjectCardLeakMeasures-test.js.snap
server/sonar-web/src/main/js/apps/projects/components/__tests__/__snapshots__/ProjectCardOverallMeasures-test.js.snap
server/sonar-web/src/main/js/components/measure/Measure.js [new file with mode: 0644]
server/sonar-web/src/main/js/components/measure/types.js [new file with mode: 0644]
server/sonar-web/src/main/js/components/measure/utils.js [new file with mode: 0644]

index 7ad6e2067c19c13c4c375648723bad495cd79cb0..b0e2db4adc12a37b8b470f7614e3687f0c33ba01 100644 (file)
@@ -18,7 +18,7 @@
  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
  */
 import React from 'react';
-import Measure from '../../component-measures-old/components/Measure';
+import Measure from '../../../components/measure/Measure';
 
 const ComponentMeasure = ({ component, metricKey, metricType }) => {
   const isProject = component.qualifier === 'TRK';
@@ -35,7 +35,9 @@ const ComponentMeasure = ({ component, metricKey, metricType }) => {
     return <span />;
   }
 
-  return <Measure measure={measure} metric={{ key: finalMetricKey, type: finalMetricType }} />;
+  return (
+    <Measure measure={{ ...measure, metric: { key: finalMetricKey, type: finalMetricType } }} />
+  );
 };
 
 export default ComponentMeasure;
index 905f06b0d6834f37cf0ef84848c969d86c927882..e00bb556764571c07da528462775f7183e0ae8c7 100644 (file)
@@ -22,26 +22,20 @@ import React from 'react';
 import classNames from 'classnames';
 import { Link } from 'react-router';
 import { DrilldownLink } from '../../../components/shared/drilldown-link';
-import Measure from '../../component-measures-old/components/Measure';
+import Measure from '../../../components/measure/Measure';
+import IssueTypeIcon from '../../../components/ui/IssueTypeIcon';
 import { getPeriodValue, isDiffMetric, formatMeasure } from '../../../helpers/measures';
 import { translate } from '../../../helpers/l10n';
 import { getComponentIssuesUrl } from '../../../helpers/urls';
-import IssueTypeIcon from '../../../components/ui/IssueTypeIcon';
 import type { Component } from '../types';
+import type { MeasureEnhanced } from '../../../components/measure/types';
 
 export default class QualityGateCondition extends React.PureComponent {
   props: {
     component: Component,
     condition: {
       level: string,
-      measure: {
-        metric: {
-          key: string,
-          name: string,
-          type: string
-        },
-        value: string
-      },
+      measure: MeasureEnhanced,
       op: string,
       period: number,
       error: string,
@@ -49,10 +43,10 @@ export default class QualityGateCondition extends React.PureComponent {
     }
   };
 
-  getDecimalsNumber(threshold: number, value: number) {
+  getDecimalsNumber(threshold: number, value: number): ?number {
     const delta = Math.abs(threshold - value);
     if (delta < 0.1 && delta > 0) {
-      //$FlowFixMe The matching result can't null because of the previous check
+      //$FlowFixMe The matching result can't be null because of the previous check
       return delta.toFixed(20).match('[^0.]').index - 1;
     }
   }
@@ -130,7 +124,6 @@ export default class QualityGateCondition extends React.PureComponent {
 
   render() {
     const { condition } = this.props;
-
     const { measure } = condition;
     const { metric } = measure;
 
@@ -151,7 +144,7 @@ export default class QualityGateCondition extends React.PureComponent {
     return this.wrapWithLink(
       <div className="overview-quality-gate-condition-container">
         <div className="overview-quality-gate-condition-value">
-          <Measure measure={{ value: actual, leak: actual }} metric={metric} decimals={decimals} />
+          <Measure measure={{ ...measure, value: actual, leak: actual }} decimals={decimals} />
         </div>
 
         <div>
index f9e6d025176f3b76d52ddbf3179e4fcf2a0ed9ca..cf6049b83cbce3e4d98cc359a79efc37b5f98b57 100644 (file)
@@ -28,16 +28,20 @@ exports[`new_maintainability_rating 1`] = `
         measure={
           Object {
             "leak": "3",
+            "metric": Object {
+              "key": "new_maintainability_rating",
+              "name": "new_maintainability_rating",
+              "type": "RATING",
+            },
+            "periods": Array [
+              Object {
+                "index": 1,
+                "value": "3",
+              },
+            ],
             "value": "3",
           }
         }
-        metric={
-          Object {
-            "key": "new_maintainability_rating",
-            "name": "new_maintainability_rating",
-            "type": "RATING",
-          }
-        }
       />
     </div>
     <div>
@@ -80,16 +84,20 @@ exports[`new_open_issues 1`] = `
         measure={
           Object {
             "leak": "10",
+            "metric": Object {
+              "key": "new_open_issues",
+              "name": "new_open_issues",
+              "type": "INT",
+            },
+            "periods": Array [
+              Object {
+                "index": 1,
+                "value": "10",
+              },
+            ],
             "value": "10",
           }
         }
-        metric={
-          Object {
-            "key": "new_open_issues",
-            "name": "new_open_issues",
-            "type": "INT",
-          }
-        }
       />
     </div>
     <div>
@@ -143,16 +151,20 @@ exports[`new_reliability_rating 1`] = `
         measure={
           Object {
             "leak": "3",
+            "metric": Object {
+              "key": "new_reliability_rating",
+              "name": "new_reliability_rating",
+              "type": "RATING",
+            },
+            "periods": Array [
+              Object {
+                "index": 1,
+                "value": "3",
+              },
+            ],
             "value": "3",
           }
         }
-        metric={
-          Object {
-            "key": "new_reliability_rating",
-            "name": "new_reliability_rating",
-            "type": "RATING",
-          }
-        }
       />
     </div>
     <div>
@@ -206,16 +218,20 @@ exports[`new_security_rating 1`] = `
         measure={
           Object {
             "leak": "3",
+            "metric": Object {
+              "key": "new_security_rating",
+              "name": "new_security_rating",
+              "type": "RATING",
+            },
+            "periods": Array [
+              Object {
+                "index": 1,
+                "value": "3",
+              },
+            ],
             "value": "3",
           }
         }
-        metric={
-          Object {
-            "key": "new_security_rating",
-            "name": "new_security_rating",
-            "type": "RATING",
-          }
-        }
       />
     </div>
     <div>
@@ -258,16 +274,14 @@ exports[`open_issues 1`] = `
         measure={
           Object {
             "leak": "10",
+            "metric": Object {
+              "key": "open_issues",
+              "name": "Open open_issues",
+              "type": "INT",
+            },
             "value": "10",
           }
         }
-        metric={
-          Object {
-            "key": "open_issues",
-            "name": "Open open_issues",
-            "type": "INT",
-          }
-        }
       />
     </div>
     <div>
@@ -320,16 +334,14 @@ exports[`reliability_rating 1`] = `
         measure={
           Object {
             "leak": "3",
+            "metric": Object {
+              "key": "reliability_rating",
+              "name": "reliability_rating",
+              "type": "RATING",
+            },
             "value": "3",
           }
         }
-        metric={
-          Object {
-            "key": "reliability_rating",
-            "name": "reliability_rating",
-            "type": "RATING",
-          }
-        }
       />
     </div>
     <div>
@@ -382,16 +394,14 @@ exports[`security_rating 1`] = `
         measure={
           Object {
             "leak": "3",
+            "metric": Object {
+              "key": "security_rating",
+              "name": "security_rating",
+              "type": "RATING",
+            },
             "value": "3",
           }
         }
-        metric={
-          Object {
-            "key": "security_rating",
-            "name": "security_rating",
-            "type": "RATING",
-          }
-        }
       />
     </div>
     <div>
@@ -443,16 +453,14 @@ exports[`sqale_rating 1`] = `
         measure={
           Object {
             "leak": "3",
+            "metric": Object {
+              "key": "sqale_rating",
+              "name": "sqale_rating",
+              "type": "RATING",
+            },
             "value": "3",
           }
         }
-        metric={
-          Object {
-            "key": "sqale_rating",
-            "name": "sqale_rating",
-            "type": "RATING",
-          }
-        }
       />
     </div>
     <div>
index 4189c2e1a64e7aa3799ca7349528e525e9cacbb0..36de893963f8d0a2e9e70343f1924995c950a9ed 100644 (file)
@@ -19,7 +19,7 @@
  */
 //@flow
 import React from 'react';
-import Measure from '../../component-measures-old/components/Measure';
+import Measure from '../../../components/measure/Measure';
 import BugIcon from '../../../components/icons-components/BugIcon';
 import CodeSmellIcon from '../../../components/icons-components/CodeSmellIcon';
 import Rating from '../../../components/ui/Rating';
@@ -42,8 +42,10 @@ export default function ProjectCardLeakMeasures({ measures }: Props) {
           <div className="project-card-measure-number">
             <Measure
               className="spacer-right"
-              measure={{ leak: measures['new_bugs'] }}
-              metric={{ key: 'new_bugs', type: 'SHORT_INT' }}
+              measure={{
+                metric: { key: 'new_bugs', name: 'new_bugs', type: 'SHORT_INT' },
+                leak: measures['new_bugs']
+              }}
             />
             <Rating value={measures['new_reliability_rating']} />
           </div>
@@ -59,8 +61,14 @@ export default function ProjectCardLeakMeasures({ measures }: Props) {
           <div className="project-card-measure-number">
             <Measure
               className="spacer-right"
-              measure={{ leak: measures['new_vulnerabilities'] }}
-              metric={{ key: 'new_vulnerabilities', type: 'SHORT_INT' }}
+              measure={{
+                metric: {
+                  key: 'new_vulnerabilities',
+                  name: 'new_vulnerabilities',
+                  type: 'SHORT_INT'
+                },
+                leak: measures['new_vulnerabilities']
+              }}
             />
             <Rating value={measures['new_security_rating']} />
           </div>
@@ -76,8 +84,10 @@ export default function ProjectCardLeakMeasures({ measures }: Props) {
           <div className="project-card-measure-number">
             <Measure
               className="spacer-right"
-              measure={{ leak: measures['new_code_smells'] }}
-              metric={{ key: 'new_code_smells', type: 'SHORT_INT' }}
+              measure={{
+                metric: { key: 'new_code_smells', name: 'new_code_smells', type: 'SHORT_INT' },
+                leak: measures['new_code_smells']
+              }}
             />
             <Rating value={measures['new_maintainability_rating']} />
           </div>
@@ -92,8 +102,10 @@ export default function ProjectCardLeakMeasures({ measures }: Props) {
         <div className="project-card-measure-inner">
           <div className="project-card-measure-number">
             <Measure
-              measure={{ leak: measures['new_coverage'] }}
-              metric={{ key: 'new_coverage', type: 'PERCENT' }}
+              measure={{
+                metric: { key: 'new_coverage', name: 'new_coverage', type: 'PERCENT' },
+                leak: measures['new_coverage']
+              }}
             />
           </div>
           <div className="project-card-measure-label">
@@ -106,8 +118,14 @@ export default function ProjectCardLeakMeasures({ measures }: Props) {
         <div className="project-card-measure-inner">
           <div className="project-card-measure-number">
             <Measure
-              measure={{ leak: measures['new_duplicated_lines_density'] }}
-              metric={{ key: 'new_duplicated_lines_density', type: 'PERCENT' }}
+              measure={{
+                metric: {
+                  key: 'new_duplicated_lines_density',
+                  name: 'new_duplicated_lines_density',
+                  type: 'PERCENT'
+                },
+                leak: measures['new_duplicated_lines_density']
+              }}
             />
           </div>
           <div className="project-card-measure-label">
@@ -120,8 +138,10 @@ export default function ProjectCardLeakMeasures({ measures }: Props) {
         <div className="project-card-measure-inner">
           <div className="project-card-measure-number">
             <Measure
-              measure={{ leak: measures['new_lines'] }}
-              metric={{ key: 'new_lines', type: 'SHORT_INT' }}
+              measure={{
+                metric: { key: 'new_lines', name: 'new_lines', type: 'SHORT_INT' },
+                leak: measures['new_lines']
+              }}
             />
           </div>
           <div className="project-card-measure-label">
index 546b511eb0ef01424b0dee4122fcf035abb6d956..701e707657b9f69268e2a79a4720b8219e97964d 100644 (file)
@@ -20,7 +20,7 @@
 //@flow
 import React from 'react';
 import ProjectCardLanguages from './ProjectCardLanguages';
-import Measure from '../../component-measures-old/components/Measure';
+import Measure from '../../../components/measure/Measure';
 import Rating from '../../../components/ui/Rating';
 import CoverageRating from '../../../components/ui/CoverageRating';
 import DuplicationsRating from '../../../components/ui/DuplicationsRating';
@@ -79,8 +79,10 @@ export default function ProjectCardOverallMeasures({ measures }: Props) {
                 <CoverageRating value={measures['coverage']} />
               </span>}
             <Measure
-              measure={{ value: measures['coverage'] }}
-              metric={{ key: 'coverage', type: 'PERCENT' }}
+              measure={{
+                metric: { key: 'coverage', name: 'coverage', type: 'PERCENT' },
+                value: measures['coverage']
+              }}
             />
           </div>
           <div className="project-card-measure-label">
@@ -97,8 +99,14 @@ export default function ProjectCardOverallMeasures({ measures }: Props) {
                 <DuplicationsRating value={Number(measures['duplicated_lines_density'])} />
               </span>}
             <Measure
-              measure={{ value: measures['duplicated_lines_density'] }}
-              metric={{ key: 'duplicated_lines_density', type: 'PERCENT' }}
+              measure={{
+                metric: {
+                  key: 'duplicated_lines_density',
+                  name: 'duplicated_lines_density',
+                  type: 'PERCENT'
+                },
+                value: measures['duplicated_lines_density']
+              }}
             />
           </div>
           <div className="project-card-measure-label">
@@ -115,8 +123,10 @@ export default function ProjectCardOverallMeasures({ measures }: Props) {
                 <SizeRating value={Number(measures['ncloc'])} />
               </span>
               <Measure
-                measure={{ value: measures['ncloc'] }}
-                metric={{ key: 'ncloc', type: 'SHORT_INT' }}
+                measure={{
+                  metric: { key: 'ncloc', name: 'ncloc', type: 'SHORT_INT' },
+                  value: measures['ncloc']
+                }}
               />
             </div>
             <div className="project-card-measure-label">
index ff9b33de649aed80b9be40b6fcc319b1c38bf355..bbce939030e8c7388776b9fc32199c3b7a8f8812 100644 (file)
@@ -19,12 +19,11 @@ exports[`should render correctly with all data 1`] = `
           measure={
             Object {
               "leak": "8",
-            }
-          }
-          metric={
-            Object {
-              "key": "new_bugs",
-              "type": "SHORT_INT",
+              "metric": Object {
+                "key": "new_bugs",
+                "name": "new_bugs",
+                "type": "SHORT_INT",
+              },
             }
           }
         />
@@ -59,12 +58,11 @@ exports[`should render correctly with all data 1`] = `
           measure={
             Object {
               "leak": "2",
-            }
-          }
-          metric={
-            Object {
-              "key": "new_vulnerabilities",
-              "type": "SHORT_INT",
+              "metric": Object {
+                "key": "new_vulnerabilities",
+                "name": "new_vulnerabilities",
+                "type": "SHORT_INT",
+              },
             }
           }
         />
@@ -99,12 +97,11 @@ exports[`should render correctly with all data 1`] = `
           measure={
             Object {
               "leak": "0",
-            }
-          }
-          metric={
-            Object {
-              "key": "new_code_smells",
-              "type": "SHORT_INT",
+              "metric": Object {
+                "key": "new_code_smells",
+                "name": "new_code_smells",
+                "type": "SHORT_INT",
+              },
             }
           }
         />
@@ -138,12 +135,11 @@ exports[`should render correctly with all data 1`] = `
           measure={
             Object {
               "leak": "26.55",
-            }
-          }
-          metric={
-            Object {
-              "key": "new_coverage",
-              "type": "PERCENT",
+              "metric": Object {
+                "key": "new_coverage",
+                "name": "new_coverage",
+                "type": "PERCENT",
+              },
             }
           }
         />
@@ -169,12 +165,11 @@ exports[`should render correctly with all data 1`] = `
           measure={
             Object {
               "leak": "0.55",
-            }
-          }
-          metric={
-            Object {
-              "key": "new_duplicated_lines_density",
-              "type": "PERCENT",
+              "metric": Object {
+                "key": "new_duplicated_lines_density",
+                "name": "new_duplicated_lines_density",
+                "type": "PERCENT",
+              },
             }
           }
         />
@@ -200,12 +195,11 @@ exports[`should render correctly with all data 1`] = `
           measure={
             Object {
               "leak": "87",
-            }
-          }
-          metric={
-            Object {
-              "key": "new_lines",
-              "type": "SHORT_INT",
+              "metric": Object {
+                "key": "new_lines",
+                "name": "new_lines",
+                "type": "SHORT_INT",
+              },
             }
           }
         />
@@ -239,12 +233,11 @@ exports[`should render no data style new coverage, new duplications and new line
           measure={
             Object {
               "leak": "8",
-            }
-          }
-          metric={
-            Object {
-              "key": "new_bugs",
-              "type": "SHORT_INT",
+              "metric": Object {
+                "key": "new_bugs",
+                "name": "new_bugs",
+                "type": "SHORT_INT",
+              },
             }
           }
         />
@@ -279,12 +272,11 @@ exports[`should render no data style new coverage, new duplications and new line
           measure={
             Object {
               "leak": "2",
-            }
-          }
-          metric={
-            Object {
-              "key": "new_vulnerabilities",
-              "type": "SHORT_INT",
+              "metric": Object {
+                "key": "new_vulnerabilities",
+                "name": "new_vulnerabilities",
+                "type": "SHORT_INT",
+              },
             }
           }
         />
@@ -319,12 +311,11 @@ exports[`should render no data style new coverage, new duplications and new line
           measure={
             Object {
               "leak": "0",
-            }
-          }
-          metric={
-            Object {
-              "key": "new_code_smells",
-              "type": "SHORT_INT",
+              "metric": Object {
+                "key": "new_code_smells",
+                "name": "new_code_smells",
+                "type": "SHORT_INT",
+              },
             }
           }
         />
@@ -358,12 +349,11 @@ exports[`should render no data style new coverage, new duplications and new line
           measure={
             Object {
               "leak": undefined,
-            }
-          }
-          metric={
-            Object {
-              "key": "new_coverage",
-              "type": "PERCENT",
+              "metric": Object {
+                "key": "new_coverage",
+                "name": "new_coverage",
+                "type": "PERCENT",
+              },
             }
           }
         />
@@ -389,12 +379,11 @@ exports[`should render no data style new coverage, new duplications and new line
           measure={
             Object {
               "leak": undefined,
-            }
-          }
-          metric={
-            Object {
-              "key": "new_duplicated_lines_density",
-              "type": "PERCENT",
+              "metric": Object {
+                "key": "new_duplicated_lines_density",
+                "name": "new_duplicated_lines_density",
+                "type": "PERCENT",
+              },
             }
           }
         />
@@ -420,12 +409,11 @@ exports[`should render no data style new coverage, new duplications and new line
           measure={
             Object {
               "leak": undefined,
-            }
-          }
-          metric={
-            Object {
-              "key": "new_lines",
-              "type": "SHORT_INT",
+              "metric": Object {
+                "key": "new_lines",
+                "name": "new_lines",
+                "type": "SHORT_INT",
+              },
             }
           }
         />
index 797b56431adec1ba4dcdba2cb8ad8a027fb6ad18..2cf247a1451cf379e42f6d9addc7b6fe1766e6c4 100644 (file)
@@ -14,15 +14,14 @@ exports[`should not render coverage 1`] = `
       <Measure
         measure={
           Object {
+            "metric": Object {
+              "key": "coverage",
+              "name": "coverage",
+              "type": "PERCENT",
+            },
             "value": undefined,
           }
         }
-        metric={
-          Object {
-            "key": "coverage",
-            "type": "PERCENT",
-          }
-        }
       />
     </div>
     <div
@@ -48,15 +47,14 @@ exports[`should not render duplications 1`] = `
       <Measure
         measure={
           Object {
+            "metric": Object {
+              "key": "duplicated_lines_density",
+              "name": "duplicated_lines_density",
+              "type": "PERCENT",
+            },
             "value": undefined,
           }
         }
-        metric={
-          Object {
-            "key": "duplicated_lines_density",
-            "type": "PERCENT",
-          }
-        }
       />
     </div>
     <div
@@ -163,15 +161,14 @@ exports[`should render correctly with all data 1`] = `
         <Measure
           measure={
             Object {
+              "metric": Object {
+                "key": "coverage",
+                "name": "coverage",
+                "type": "PERCENT",
+              },
               "value": "88.3",
             }
           }
-          metric={
-            Object {
-              "key": "coverage",
-              "type": "PERCENT",
-            }
-          }
         />
       </div>
       <div
@@ -203,15 +200,14 @@ exports[`should render correctly with all data 1`] = `
         <Measure
           measure={
             Object {
+              "metric": Object {
+                "key": "duplicated_lines_density",
+                "name": "duplicated_lines_density",
+                "type": "PERCENT",
+              },
               "value": "9.8",
             }
           }
-          metric={
-            Object {
-              "key": "duplicated_lines_density",
-              "type": "PERCENT",
-            }
-          }
         />
       </div>
       <div
@@ -243,15 +239,14 @@ exports[`should render correctly with all data 1`] = `
         <Measure
           measure={
             Object {
+              "metric": Object {
+                "key": "ncloc",
+                "name": "ncloc",
+                "type": "SHORT_INT",
+              },
               "value": "2053",
             }
           }
-          metric={
-            Object {
-              "key": "ncloc",
-              "type": "SHORT_INT",
-            }
-          }
         />
       </div>
       <div
@@ -287,15 +282,14 @@ exports[`should render ncloc correctly 1`] = `
       <Measure
         measure={
           Object {
+            "metric": Object {
+              "key": "ncloc",
+              "name": "ncloc",
+              "type": "SHORT_INT",
+            },
             "value": "16549887",
           }
         }
-        metric={
-          Object {
-            "key": "ncloc",
-            "type": "SHORT_INT",
-          }
-        }
       />
     </div>
     <div
diff --git a/server/sonar-web/src/main/js/components/measure/Measure.js b/server/sonar-web/src/main/js/components/measure/Measure.js
new file mode 100644 (file)
index 0000000..a2b1e4d
--- /dev/null
@@ -0,0 +1,79 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2017 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.
+ */
+// @flow
+import React from 'react';
+import Rating from '../ui/Rating';
+import Level from '../ui/Level';
+import Tooltips from '../controls/Tooltip';
+import { formatMeasure, isDiffMetric } from '../../helpers/measures';
+import { formatLeak, getRatingTooltip } from './utils';
+import type { MeasureEnhanced } from './types';
+
+type Props = {
+  className?: string,
+  measure: MeasureEnhanced,
+  decimals?: ?number
+};
+
+export default class Measure extends React.PureComponent {
+  props: Props;
+
+  renderRating() {
+    const { measure } = this.props;
+    const metric = measure.metric;
+    const value = isDiffMetric(metric.key) ? measure.leak : measure.value;
+    const tooltip = getRatingTooltip(metric.key, value);
+    const rating = <Rating value={value} />;
+
+    if (tooltip) {
+      return (
+        <Tooltips overlay={tooltip}>
+          <span className={this.props.className}>
+            {rating}
+          </span>
+        </Tooltips>
+      );
+    }
+
+    return rating;
+  }
+
+  render() {
+    const { className, decimals, measure } = this.props;
+    const metric = measure.metric;
+
+    if (metric.type === 'RATING') {
+      return this.renderRating();
+    }
+
+    if (metric.type === 'LEVEL') {
+      return <Level className={className} level={measure.value} />;
+    }
+
+    const formattedValue = isDiffMetric(metric.key)
+      ? formatLeak(measure.leak, metric, { decimals })
+      : formatMeasure(measure.value, metric.type, { decimals });
+    return (
+      <span className={className}>
+        {formattedValue != null ? formattedValue : '–'}
+      </span>
+    );
+  }
+}
diff --git a/server/sonar-web/src/main/js/components/measure/types.js b/server/sonar-web/src/main/js/components/measure/types.js
new file mode 100644 (file)
index 0000000..1883833
--- /dev/null
@@ -0,0 +1,33 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2017 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.
+ */
+// @flow
+import type { Metric } from '../../store/metrics/actions';
+
+type MeasureIntern = {
+  value?: string,
+  periods?: Array<{
+    index: number,
+    value: string
+  }>
+};
+
+export type Measure = MeasureIntern & { metric: string };
+
+export type MeasureEnhanced = MeasureIntern & { metric: Metric, leak?: ?string };
diff --git a/server/sonar-web/src/main/js/components/measure/utils.js b/server/sonar-web/src/main/js/components/measure/utils.js
new file mode 100644 (file)
index 0000000..bf98a58
--- /dev/null
@@ -0,0 +1,45 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2017 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.
+ */
+// @flow
+import {
+  formatMeasure,
+  formatMeasureVariation,
+  getRatingTooltip as nextGetRatingTooltip,
+  isDiffMetric
+} from '../../helpers/measures';
+import type { Metric } from '../../store/metrics/actions';
+
+const KNOWN_RATINGS = ['sqale_rating', 'reliability_rating', 'security_rating'];
+
+export function formatLeak(value: ?string, metric: Metric, options: Object) {
+  if (isDiffMetric(metric.key)) {
+    return formatMeasure(value, metric.type, options);
+  } else {
+    return formatMeasureVariation(value, metric.type, options);
+  }
+}
+
+export function getRatingTooltip(metricKey: string, value: ?string) {
+  const finalMetricKey = isDiffMetric(metricKey) ? metricKey.substr(4) : metricKey;
+  if (KNOWN_RATINGS.includes(finalMetricKey)) {
+    return nextGetRatingTooltip(finalMetricKey, value);
+  }
+  return null;
+}