]> source.dussan.org Git - sonarqube.git/commitdiff
Feature/pm/hardening 5 6 04 (#119)
authorPascal Mugnier <pascal.mugnier@sonarsource.com>
Wed, 11 Apr 2018 07:27:52 +0000 (09:27 +0200)
committerSonarTech <sonartech@sonarsource.com>
Wed, 11 Apr 2018 18:20:48 +0000 (20:20 +0200)
25 files changed:
server/sonar-web/src/main/js/apps/component-measures/drilldown/BubbleChart.js
server/sonar-web/src/main/js/apps/projects/styles.css
server/sonar-web/src/main/js/apps/projects/visualizations/Coverage.tsx
server/sonar-web/src/main/js/apps/projects/visualizations/Duplications.tsx
server/sonar-web/src/main/js/apps/projects/visualizations/Maintainability.tsx
server/sonar-web/src/main/js/apps/projects/visualizations/Reliability.tsx
server/sonar-web/src/main/js/apps/projects/visualizations/Risk.tsx
server/sonar-web/src/main/js/apps/projects/visualizations/Security.tsx
server/sonar-web/src/main/js/apps/projects/visualizations/SimpleBubbleChart.tsx
server/sonar-web/src/main/js/apps/projects/visualizations/Visualizations.tsx
server/sonar-web/src/main/js/apps/projects/visualizations/__tests__/Coverage-test.tsx
server/sonar-web/src/main/js/apps/projects/visualizations/__tests__/Duplications-test.tsx
server/sonar-web/src/main/js/apps/projects/visualizations/__tests__/Maintainability-test.tsx
server/sonar-web/src/main/js/apps/projects/visualizations/__tests__/Reliability-test.tsx
server/sonar-web/src/main/js/apps/projects/visualizations/__tests__/Risk-test.tsx
server/sonar-web/src/main/js/apps/projects/visualizations/__tests__/Security-test.tsx
server/sonar-web/src/main/js/apps/projects/visualizations/__tests__/SimpleBubbleChart-test.tsx
server/sonar-web/src/main/js/apps/projects/visualizations/__tests__/__snapshots__/Coverage-test.tsx.snap
server/sonar-web/src/main/js/apps/projects/visualizations/__tests__/__snapshots__/Duplications-test.tsx.snap
server/sonar-web/src/main/js/apps/projects/visualizations/__tests__/__snapshots__/Maintainability-test.tsx.snap
server/sonar-web/src/main/js/apps/projects/visualizations/__tests__/__snapshots__/Reliability-test.tsx.snap
server/sonar-web/src/main/js/apps/projects/visualizations/__tests__/__snapshots__/Risk-test.tsx.snap
server/sonar-web/src/main/js/apps/projects/visualizations/__tests__/__snapshots__/Security-test.tsx.snap
server/sonar-web/src/main/js/apps/projects/visualizations/__tests__/__snapshots__/SimpleBubbleChart-test.tsx.snap
server/sonar-web/src/main/js/apps/projects/visualizations/__tests__/__snapshots__/Visualizations-test.tsx.snap

index 4c6ae9e9b4ea461bfb243680ba820f6e0135a82b..082dad7f72d3ba2a8c877b6154a9427b83b60d11 100644 (file)
@@ -22,6 +22,8 @@ import React from 'react';
 import EmptyResult from './EmptyResult';
 import OriginalBubbleChart from '../../../components/charts/BubbleChart';
 import ColorRatingsLegend from '../../../components/charts/ColorRatingsLegend';
+import Tooltip from '../../../components/controls/Tooltip';
+import HelpIcon from '../../../components/icons-components/HelpIcon';
 import { formatMeasure, isDiffMetric } from '../../../helpers/measures';
 import {
   getLocalizedMetricDomain,
@@ -99,6 +101,15 @@ export default class BubbleChart extends React.PureComponent {
   handleBubbleClick = (component /*: ComponentEnhanced */) =>
     this.props.updateSelected(component.refKey || component.key);
 
+  getDescription(domain /*: string */) {
+    const description = `component_measures.overview.${domain}.description`;
+    const translatedDescription = translate(description);
+    if (description === translatedDescription) {
+      return null;
+    }
+    return translatedDescription;
+  }
+
   renderBubbleChart(
     metrics /*: {
       x: Metric ,
@@ -158,7 +169,14 @@ export default class BubbleChart extends React.PureComponent {
         );
     return (
       <div className="measure-overview-bubble-chart-header">
-        <span className="measure-overview-bubble-chart-title">{title}</span>
+        <span className="measure-overview-bubble-chart-title">
+          {title}
+          <Tooltip overlay={this.getDescription(domain)}>
+            <span className="spacer-left text-info">
+              <HelpIcon />
+            </span>
+          </Tooltip>
+        </span>
         <span className="measure-overview-bubble-chart-legend">
           <span className="note">
             {colorsMetric && (
@@ -185,15 +203,6 @@ export default class BubbleChart extends React.PureComponent {
     );
   }
 
-  renderChartFooter(domain /*: string */) {
-    const description = `component_measures.overview.${domain}.description`;
-    const translatedDescription = translate(description);
-    if (description === translatedDescription) {
-      return null;
-    }
-    return <div className="measure-overview-bubble-chart-footer">{translatedDescription}</div>;
-  }
-
   render() {
     if (this.props.components.length <= 0) {
       return <EmptyResult />;
@@ -213,7 +222,6 @@ export default class BubbleChart extends React.PureComponent {
         <div className="measure-overview-bubble-chart-axis y">
           {getLocalizedMetricName(metrics.y)}
         </div>
-        {this.renderChartFooter(domain)}
       </div>
     );
   }
index 8b6ada0cea81090ebd29b53fdda2e1cad50b0c8b..9b741654e9c73afa9e090a4217f2db1d3d3a1995 100644 (file)
   font-style: italic;
 }
 
+.measure-details-bubble-chart-title {
+  position: absolute;
+  left: 20px;
+}
+
 .measure-details-bubble-chart-axis {
   position: absolute;
   color: var(--secondFontColor);
 
 .measure-details-bubble-chart-axis.x {
   left: 50%;
-  bottom: 10px;
+  bottom: 16px;
   width: 500px;
   margin-left: -250px;
   text-align: center;
 }
 
 .measure-details-bubble-chart-axis.size {
-  left: 50%;
-  top: 10px;
-  width: 500px;
-  margin-left: -250px;
-  text-align: center;
+  display: flex;
+  align-items: center;
+  justify-content: space-around;
+  top: 16px;
+  width: 100%;
 }
 
 .projects-empty-list {
index 1a19f1422172538919f094e3cf6ae9952d71d7ff..344ac208b51b91dc4f737166c26f71a5c975e535 100644 (file)
 import * as React from 'react';
 import SimpleBubbleChart from './SimpleBubbleChart';
 import { Project } from '../types';
+import { translate } from '../../../helpers/l10n';
 
 interface Props {
   displayOrganizations: boolean;
+  helpText: string;
   projects: Project[];
 }
 
@@ -30,10 +32,11 @@ export default function Coverage(props: Props) {
   return (
     <SimpleBubbleChart
       {...props}
+      sizeMetric={{ key: 'uncovered_lines', type: 'SHORT_INT' }}
+      title={translate('projects.visualization', 'coverage')}
       xMetric={{ key: 'complexity', type: 'SHORT_INT' }}
-      yMetric={{ key: 'coverage', type: 'PERCENT' }}
       yDomain={[100, 0]}
-      sizeMetric={{ key: 'uncovered_lines', type: 'SHORT_INT' }}
+      yMetric={{ key: 'coverage', type: 'PERCENT' }}
     />
   );
 }
index 974302289469e91da6f4085f8f4e6a32f0b98471..666823d34473c9b81cd856f36db17bb09ee88018 100644 (file)
 import * as React from 'react';
 import SimpleBubbleChart from './SimpleBubbleChart';
 import { Project } from '../types';
+import { translate } from '../../../helpers/l10n';
 
 interface Props {
   displayOrganizations: boolean;
+  helpText: string;
   projects: Project[];
 }
 
@@ -30,9 +32,10 @@ export default function Duplications(props: Props) {
   return (
     <SimpleBubbleChart
       {...props}
+      sizeMetric={{ key: 'duplicated_blocks', type: 'SHORT_INT' }}
+      title={translate('projects.visualization', 'duplications')}
       xMetric={{ key: 'ncloc', type: 'SHORT_INT' }}
       yMetric={{ key: 'duplicated_lines_density', type: 'PERCENT' }}
-      sizeMetric={{ key: 'duplicated_blocks', type: 'SHORT_INT' }}
     />
   );
 }
index 73224f37723a239e0bf02ecedc61115195d420e8..7c61aa51c45184072dbcd62e63a20c121b93c5ec 100644 (file)
 import * as React from 'react';
 import SimpleBubbleChart from './SimpleBubbleChart';
 import { Project } from '../types';
+import { translate } from '../../../helpers/l10n';
 
 interface Props {
   displayOrganizations: boolean;
+  helpText: string;
   projects: Project[];
 }
 
@@ -30,10 +32,11 @@ export default function Maintainability(props: Props) {
   return (
     <SimpleBubbleChart
       {...props}
+      colorMetric="sqale_rating"
+      sizeMetric={{ key: 'code_smells', type: 'SHORT_INT' }}
+      title={translate('projects.visualization', 'maintainability')}
       xMetric={{ key: 'ncloc', type: 'SHORT_INT' }}
       yMetric={{ key: 'sqale_index', type: 'SHORT_WORK_DUR' }}
-      sizeMetric={{ key: 'code_smells', type: 'SHORT_INT' }}
-      colorMetric="sqale_rating"
     />
   );
 }
index 96aa91b4df5f1ec35e4083c429e33b0f5320a987..20e5c12bea24c2485186ee2ec7d4a6a47176d963 100644 (file)
 import * as React from 'react';
 import SimpleBubbleChart from './SimpleBubbleChart';
 import { Project } from '../types';
+import { translate } from '../../../helpers/l10n';
 
 interface Props {
   displayOrganizations: boolean;
+  helpText: string;
   projects: Project[];
 }
 
@@ -30,10 +32,11 @@ export default function Reliability(props: Props) {
   return (
     <SimpleBubbleChart
       {...props}
+      colorMetric="reliability_rating"
+      sizeMetric={{ key: 'bugs', type: 'SHORT_INT' }}
+      title={translate('projects.visualization', 'reliability')}
       xMetric={{ key: 'ncloc', type: 'SHORT_INT' }}
       yMetric={{ key: 'reliability_remediation_effort', type: 'SHORT_WORK_DUR' }}
-      sizeMetric={{ key: 'bugs', type: 'SHORT_INT' }}
-      colorMetric="reliability_rating"
     />
   );
 }
index d7c004af86c5952eddb805ecb576c8996b6e725e..a82b86d69fde6a97cd2f1562f4314b0a9effe0cd 100644 (file)
@@ -25,6 +25,8 @@ import { formatMeasure } from '../../../helpers/measures';
 import { translate, translateWithParameters } from '../../../helpers/l10n';
 import { RATING_COLORS } from '../../../helpers/constants';
 import { getProjectUrl } from '../../../helpers/urls';
+import Tooltip from '../../../components/controls/Tooltip';
+import HelpIcon from '../../../components/icons-components/HelpIcon';
 
 const X_METRIC = 'sqale_index';
 const X_METRIC_TYPE = 'SHORT_WORK_DUR';
@@ -38,6 +40,7 @@ const COLOR_METRIC_TYPE = 'RATING';
 
 interface Props {
   displayOrganizations: boolean;
+  helpText: string;
   projects: Project[];
 }
 
@@ -126,6 +129,7 @@ export default class Risk extends React.PureComponent<Props> {
           padding={[80, 20, 60, 100]}
           yDomain={[100, 0]}
         />
+
         <div className="measure-details-bubble-chart-axis x">
           {translate('metric', X_METRIC, 'name')}
         </div>
@@ -133,17 +137,27 @@ export default class Risk extends React.PureComponent<Props> {
           {translate('metric', Y_METRIC, 'name')}
         </div>
         <div className="measure-details-bubble-chart-axis size">
-          <span className="spacer-right">
+          <span className="measure-details-bubble-chart-title">
+            {translate('projects.visualization.risk')}
+            <Tooltip overlay={this.props.helpText}>
+              <span className="spacer-left text-info">
+                <HelpIcon />
+              </span>
+            </Tooltip>
+          </span>
+          <div>
+            <span className="spacer-right">
+              {translateWithParameters(
+                'component_measures.legend.color_x',
+                translate('projects.worse_of_reliablity_and_security')
+              )}
+            </span>
             {translateWithParameters(
-              'component_measures.legend.color_x',
-              translate('projects.worse_of_reliablity_and_security')
+              'component_measures.legend.size_x',
+              translate('metric', SIZE_METRIC, 'name')
             )}
-          </span>
-          {translateWithParameters(
-            'component_measures.legend.size_x',
-            translate('metric', SIZE_METRIC, 'name')
-          )}
-          <ColorRatingsLegend className="big-spacer-top" />
+            <ColorRatingsLegend className="big-spacer-top" />
+          </div>
         </div>
       </div>
     );
index 1972b302e56aff3904c9694e18bf11ba458d5aac..aecb4d68b3b38757cf5b1393a77305ced11252f1 100644 (file)
 import * as React from 'react';
 import SimpleBubbleChart from './SimpleBubbleChart';
 import { Project } from '../types';
+import { translate } from '../../../helpers/l10n';
 
 interface Props {
   displayOrganizations: boolean;
+  helpText: string;
   projects: Project[];
 }
 
@@ -30,10 +32,11 @@ export default function Security(props: Props) {
   return (
     <SimpleBubbleChart
       {...props}
+      colorMetric="security_rating"
+      sizeMetric={{ key: 'vulnerabilities', type: 'SHORT_INT' }}
+      title={translate('projects.visualization', 'security')}
       xMetric={{ key: 'ncloc', type: 'SHORT_INT' }}
       yMetric={{ key: 'security_remediation_effort', type: 'SHORT_WORK_DUR' }}
-      sizeMetric={{ key: 'vulnerabilities', type: 'SHORT_INT' }}
-      colorMetric="security_rating"
     />
   );
 }
index 9b9d8af06aa31295d20a11d11c103934339a9d71..10c1291f61ff0032457ed1528d153e88b0eda7d8 100644 (file)
@@ -25,6 +25,8 @@ import { translate, translateWithParameters } from '../../../helpers/l10n';
 import { RATING_COLORS } from '../../../helpers/constants';
 import { getProjectUrl } from '../../../helpers/urls';
 import { Project } from '../types';
+import Tooltip from '../../../components/controls/Tooltip';
+import HelpIcon from '../../../components/icons-components/HelpIcon';
 
 export interface Metric {
   key: string;
@@ -34,8 +36,10 @@ export interface Metric {
 interface Props {
   colorMetric?: string;
   displayOrganizations: boolean;
+  helpText: string;
   projects: Project[];
   sizeMetric: Metric;
+  title?: string;
   xMetric: Metric;
   yDomain?: [number, number];
   yMetric: Metric;
@@ -124,19 +128,29 @@ export default class SimpleBubbleChart extends React.PureComponent<Props> {
           {translate('metric', yMetric.key, 'name')}
         </div>
         <div className="measure-details-bubble-chart-axis size">
-          {colorMetric != null && (
-            <span className="spacer-right">
-              {translateWithParameters(
-                'component_measures.legend.color_x',
-                translate('metric', colorMetric, 'name')
-              )}
-            </span>
-          )}
-          {translateWithParameters(
-            'component_measures.legend.size_x',
-            translate('metric', sizeMetric.key, 'name')
-          )}
-          {colorMetric != null && <ColorRatingsLegend className="big-spacer-top" />}
+          <span className="measure-details-bubble-chart-title">
+            {this.props.title}
+            <Tooltip overlay={this.props.helpText}>
+              <span className="spacer-left text-info">
+                <HelpIcon className="text-bottom" />
+              </span>
+            </Tooltip>
+          </span>
+          <div>
+            {colorMetric != null && (
+              <span className="spacer-right">
+                {translateWithParameters(
+                  'component_measures.legend.color_x',
+                  translate('metric', colorMetric, 'name')
+                )}
+              </span>
+            )}
+            {translateWithParameters(
+              'component_measures.legend.size_x',
+              translate('metric', sizeMetric.key, 'name')
+            )}
+            {colorMetric != null && <ColorRatingsLegend className="big-spacer-top" />}
+          </div>
         </div>
       </div>
     );
index 6c93acd4d9e46962959af93b5149cf43ff051788..947b58fddde5757c13522f26ae424549a4b2148f 100644 (file)
@@ -49,7 +49,11 @@ export default class Visualizations extends React.PureComponent<Props> {
     const Component = visualizationToComponent[this.props.visualization];
 
     return Component ? (
-      <Component displayOrganizations={this.props.displayOrganizations} projects={projects} />
+      <Component
+        displayOrganizations={this.props.displayOrganizations}
+        helpText={translate('projects.visualization', this.props.visualization, 'description')}
+        projects={projects}
+      />
     ) : null;
   }
 
@@ -58,20 +62,17 @@ export default class Visualizations extends React.PureComponent<Props> {
 
     const limitReached = projects != null && total != null && projects.length < total;
 
-    return (
+    return limitReached ? (
       <footer className="projects-visualizations-footer">
-        <p>{translate('projects.visualization', this.props.visualization, 'description')}</p>
-        {limitReached && (
-          <p className="note spacer-top">
-            {translateWithParameters(
-              'projects.limited_set_of_projects',
-              projects!.length,
-              localizeSorting(sort)
-            )}
-          </p>
-        )}
+        <p className="note spacer-top">
+          {translateWithParameters(
+            'projects.limited_set_of_projects',
+            projects!.length,
+            localizeSorting(sort)
+          )}
+        </p>
       </footer>
-    );
+    ) : null;
   }
 
   render() {
index 4138d3d98584b8b89efb1658b855352eba972831..aa6e78c656ab463be387ece9f9223b1eb3d0c810 100644 (file)
@@ -22,5 +22,7 @@ import { shallow } from 'enzyme';
 import Coverage from '../Coverage';
 
 it('renders', () => {
-  expect(shallow(<Coverage displayOrganizations={false} projects={[]} />)).toMatchSnapshot();
+  expect(
+    shallow(<Coverage displayOrganizations={false} helpText="foobar" projects={[]} />)
+  ).toMatchSnapshot();
 });
index b7c8ecf236e6b7ff61ba8d3608d4d756f93cf84d..a08e2476e04536996747bcc64c641ca96f0f1c68 100644 (file)
@@ -22,5 +22,7 @@ import { shallow } from 'enzyme';
 import Duplications from '../Duplications';
 
 it('renders', () => {
-  expect(shallow(<Duplications displayOrganizations={false} projects={[]} />)).toMatchSnapshot();
+  expect(
+    shallow(<Duplications displayOrganizations={false} helpText="foobar" projects={[]} />)
+  ).toMatchSnapshot();
 });
index 7b0bdee6e233782b047ee2cdd1cd3fe309dcea31..194ed1ff3f15149a66a66ffd53b4fd07faec182b 100644 (file)
@@ -22,5 +22,7 @@ import { shallow } from 'enzyme';
 import Maintainability from '../Maintainability';
 
 it('renders', () => {
-  expect(shallow(<Maintainability displayOrganizations={false} projects={[]} />)).toMatchSnapshot();
+  expect(
+    shallow(<Maintainability displayOrganizations={false} helpText="foobar" projects={[]} />)
+  ).toMatchSnapshot();
 });
index f26a17fd5dcb627716cc259d54939254f28039d7..bdf50bd8d7921ace8d7af15a02d60f97371728b7 100644 (file)
@@ -22,5 +22,7 @@ import { shallow } from 'enzyme';
 import Reliability from '../Reliability';
 
 it('renders', () => {
-  expect(shallow(<Reliability displayOrganizations={false} projects={[]} />)).toMatchSnapshot();
+  expect(
+    shallow(<Reliability displayOrganizations={false} helpText="foobar" projects={[]} />)
+  ).toMatchSnapshot();
 });
index d10e432091f904817f97f5003b416016b3a15dba..688230948db59137fa70fde115add8ba4a699e88 100644 (file)
@@ -29,5 +29,7 @@ it('renders', () => {
     tags: [],
     visibility: 'public'
   };
-  expect(shallow(<Risk displayOrganizations={false} projects={[project1]} />)).toMatchSnapshot();
+  expect(
+    shallow(<Risk displayOrganizations={false} helpText="foobar" projects={[project1]} />)
+  ).toMatchSnapshot();
 });
index 3ef218698e63a418d5bdfa3605bc1b99d5573ec8..0101947a375dbf9f111b01369f596a1e087674ac 100644 (file)
@@ -22,5 +22,7 @@ import { shallow } from 'enzyme';
 import Security from '../Security';
 
 it('renders', () => {
-  expect(shallow(<Security displayOrganizations={false} projects={[]} />)).toMatchSnapshot();
+  expect(
+    shallow(<Security displayOrganizations={false} helpText="foobar" projects={[]} />)
+  ).toMatchSnapshot();
 });
index e76c73076f0429f9a84b08dd4b4658f3ae158dd4..4224630f25d5f350e46e092af52854a61c079e13 100644 (file)
@@ -35,6 +35,7 @@ it('renders', () => {
       <SimpleBubbleChart
         colorMetric="security_rating"
         displayOrganizations={false}
+        helpText="foobar"
         projects={[project1]}
         sizeMetric={{ key: 'ncloc', type: 'INT' }}
         xMetric={{ key: 'complexity', type: 'INT' }}
index e1207dff93f5908099f95164885b035990524228..01107b14c10b5c1c17e14b29d9bb0694682670e3 100644 (file)
@@ -3,6 +3,7 @@
 exports[`renders 1`] = `
 <SimpleBubbleChart
   displayOrganizations={false}
+  helpText="foobar"
   projects={Array []}
   sizeMetric={
     Object {
@@ -10,6 +11,7 @@ exports[`renders 1`] = `
       "type": "SHORT_INT",
     }
   }
+  title="projects.visualization.coverage"
   xMetric={
     Object {
       "key": "complexity",
index c3920375a20ec2fedb9fee85d1e598d3dd9c53a2..7ec3fbb1ac5af3780a64bb42ee97fc4e52de01e1 100644 (file)
@@ -3,6 +3,7 @@
 exports[`renders 1`] = `
 <SimpleBubbleChart
   displayOrganizations={false}
+  helpText="foobar"
   projects={Array []}
   sizeMetric={
     Object {
@@ -10,6 +11,7 @@ exports[`renders 1`] = `
       "type": "SHORT_INT",
     }
   }
+  title="projects.visualization.duplications"
   xMetric={
     Object {
       "key": "ncloc",
index aa9eb694998060f0acaea2fafc99093853b45338..14f2cea5c44e4501aebc7ded63c16f930a4dedd5 100644 (file)
@@ -4,6 +4,7 @@ exports[`renders 1`] = `
 <SimpleBubbleChart
   colorMetric="sqale_rating"
   displayOrganizations={false}
+  helpText="foobar"
   projects={Array []}
   sizeMetric={
     Object {
@@ -11,6 +12,7 @@ exports[`renders 1`] = `
       "type": "SHORT_INT",
     }
   }
+  title="projects.visualization.maintainability"
   xMetric={
     Object {
       "key": "ncloc",
index 74b8820dcd81017c3756bf856b1a9547b5ca5044..b8a733b6b54ce1107eed77db22483f544ab4efe1 100644 (file)
@@ -4,6 +4,7 @@ exports[`renders 1`] = `
 <SimpleBubbleChart
   colorMetric="reliability_rating"
   displayOrganizations={false}
+  helpText="foobar"
   projects={Array []}
   sizeMetric={
     Object {
@@ -11,6 +12,7 @@ exports[`renders 1`] = `
       "type": "SHORT_INT",
     }
   }
+  title="projects.visualization.reliability"
   xMetric={
     Object {
       "key": "ncloc",
index ecc8cc1fede93fb112e097dc91d508e198318975..ec17ac106b4449ed957001733c48ce573ac5d9bf 100644 (file)
@@ -98,14 +98,30 @@ exports[`renders 1`] = `
     className="measure-details-bubble-chart-axis size"
   >
     <span
-      className="spacer-right"
+      className="measure-details-bubble-chart-title"
     >
-      component_measures.legend.color_x.projects.worse_of_reliablity_and_security
+      projects.visualization.risk
+      <Tooltip
+        overlay="foobar"
+      >
+        <span
+          className="spacer-left text-info"
+        >
+          <HelpIcon />
+        </span>
+      </Tooltip>
     </span>
-    component_measures.legend.size_x.metric.ncloc.name
-    <ColorRatingsLegend
-      className="big-spacer-top"
-    />
+    <div>
+      <span
+        className="spacer-right"
+      >
+        component_measures.legend.color_x.projects.worse_of_reliablity_and_security
+      </span>
+      component_measures.legend.size_x.metric.ncloc.name
+      <ColorRatingsLegend
+        className="big-spacer-top"
+      />
+    </div>
   </div>
 </div>
 `;
index 1ff6a7d08a7aecde3706100fb5d1a287db2b9242..8ab18b4f2562927efd2c32e20534e9c0e01a8f7d 100644 (file)
@@ -4,6 +4,7 @@ exports[`renders 1`] = `
 <SimpleBubbleChart
   colorMetric="security_rating"
   displayOrganizations={false}
+  helpText="foobar"
   projects={Array []}
   sizeMetric={
     Object {
@@ -11,6 +12,7 @@ exports[`renders 1`] = `
       "type": "SHORT_INT",
     }
   }
+  title="projects.visualization.security"
   xMetric={
     Object {
       "key": "ncloc",
index 1c661eb169095ca3de9d24a67859f91fe91aaa4d..020df683ca2cc5f69854fff10ed10976c587dd4f 100644 (file)
@@ -87,14 +87,31 @@ exports[`renders 1`] = `
     className="measure-details-bubble-chart-axis size"
   >
     <span
-      className="spacer-right"
+      className="measure-details-bubble-chart-title"
     >
-      component_measures.legend.color_x.metric.security_rating.name
+      <Tooltip
+        overlay="foobar"
+      >
+        <span
+          className="spacer-left text-info"
+        >
+          <HelpIcon
+            className="text-bottom"
+          />
+        </span>
+      </Tooltip>
     </span>
-    component_measures.legend.size_x.metric.ncloc.name
-    <ColorRatingsLegend
-      className="big-spacer-top"
-    />
+    <div>
+      <span
+        className="spacer-right"
+      >
+        component_measures.legend.color_x.metric.security_rating.name
+      </span>
+      component_measures.legend.size_x.metric.ncloc.name
+      <ColorRatingsLegend
+        className="big-spacer-top"
+      />
+    </div>
   </div>
 </div>
 `;
index 6a28f9d5baa78f59191e9377d11074f46b00f939..ecbdf1bc0e420f7b07272b18cb7650b84495d630 100644 (file)
@@ -9,16 +9,10 @@ exports[`renders 1`] = `
   >
     <Coverage
       displayOrganizations={false}
+      helpText="projects.visualization.coverage.description"
       projects={Array []}
     />
   </div>
-  <footer
-    className="projects-visualizations-footer"
-  >
-    <p>
-      projects.visualization.coverage.description
-    </p>
-  </footer>
 </div>
 `;
 
@@ -31,15 +25,13 @@ exports[`renders when limit is reached 1`] = `
   >
     <Coverage
       displayOrganizations={false}
+      helpText="projects.visualization.coverage.description"
       projects={Array []}
     />
   </div>
   <footer
     className="projects-visualizations-footer"
   >
-    <p>
-      projects.visualization.coverage.description
-    </p>
     <p
       className="note spacer-top"
     >