]> source.dussan.org Git - sonarqube.git/commitdiff
use new WS on code, projects and overview pages
authorStas Vilchik <vilchiks@gmail.com>
Wed, 20 Jan 2016 13:39:06 +0000 (14:39 +0100)
committerStas Vilchik <vilchiks@gmail.com>
Wed, 20 Jan 2016 13:41:39 +0000 (14:41 +0100)
15 files changed:
server/sonar-web/src/main/js/api/components.js
server/sonar-web/src/main/js/apps/code/actions/index.js
server/sonar-web/src/main/js/apps/code/components/Component.js
server/sonar-web/src/main/js/apps/code/components/ComponentDetach.js
server/sonar-web/src/main/js/apps/code/components/ComponentMeasure.js
server/sonar-web/src/main/js/apps/code/components/ComponentName.js
server/sonar-web/src/main/js/apps/code/components/ComponentPin.js
server/sonar-web/src/main/js/apps/code/components/ComponentQualityGate.js
server/sonar-web/src/main/js/apps/code/components/SourceViewer.js
server/sonar-web/src/main/js/apps/code/reducers/index.js
server/sonar-web/src/main/js/apps/overview/components/domain-bubble-chart.js
server/sonar-web/src/main/js/apps/overview/components/domain-treemap.js
server/sonar-web/src/main/js/apps/overview/components/ncloc-distribution.js
server/sonar-web/tests/apps/code/components-test.js
server/sonar-web/tests/apps/code/store-test.js

index 3db794b855e0e0fbb742942e4837288337e3d3ba..89a6e35ffec872ffc5bc118d5a968ae64c388c7c 100644 (file)
@@ -46,27 +46,29 @@ export function createProject (data) {
 }
 
 export function getChildren (componentKey, metrics = []) {
-  const url = baseUrl + '/api/resources/index';
-  const data = { resource: componentKey, metrics: metrics.join(','), depth: 1 };
-  return getJSON(url, data);
+  const url = baseUrl + '/api/measures/component_tree';
+  const data = {
+    baseComponentKey: componentKey,
+    metricKeys: metrics.join(','),
+    strategy: 'children'
+  };
+  return getJSON(url, data).then(r => r.components);
 }
 
-export function getFiles (componentKey, metrics = []) {
-  // due to the limitation of the WS we can not ask qualifiers=FIL,
-  // in this case the WS does not return measures
-  // so the filtering by a qualifier is done manually
-
-  const url = baseUrl + '/api/resources/index';
-  const data = { resource: componentKey, metrics: metrics.join(','), depth: -1 };
-  return getJSON(url, data).then(r => {
-    return r.filter(component => component.qualifier === 'FIL');
+export function getFiles (componentKey, metrics = [], additional = {}) {
+  const url = baseUrl + '/api/measures/component_tree';
+  const data = Object.assign({}, additional, {
+    baseComponentKey: componentKey,
+    metricKeys: metrics.join(','),
+    strategy: 'leaves'
   });
+  return getJSON(url, data).then(r => r.components);
 }
 
 export function getComponent (componentKey, metrics = []) {
-  const url = baseUrl + '/api/resources/index';
-  const data = { resource: componentKey, metrics: metrics.join(',') };
-  return getJSON(url, data).then(r => r[0]);
+  const url = baseUrl + '/api/measures/component';
+  const data = { componentKey, metricKeys: metrics.join(',') };
+  return getJSON(url, data).then(r => r.component);
 }
 
 export function getTree (baseComponentKey, options = {}) {
index fcf523372635172bd1086de4cbb6b241a4fba19a..e39f46d0327a50c95de61ed23859c4a70b5b5ede 100644 (file)
@@ -22,6 +22,7 @@ import { pushPath } from 'redux-simple-router';
 
 import { getChildren, getComponent, getTree, getBreadcrumbs } from '../../../api/components';
 import { translate } from '../../../helpers/l10n';
+import { getComponentUrl } from '../../../helpers/urls';
 
 
 const METRICS = [
@@ -192,7 +193,12 @@ export function browse (componentKey) {
     dispatch(startFetching());
     return retrieveComponent(componentKey, bucket)
         .then(([component, children, breadcrumbs]) => {
-          dispatch(browseAction(component, children, breadcrumbs));
+          if (component.refKey) {
+            window.location = getComponentUrl(component.refKey);
+            return new Promise();
+          } else {
+            dispatch(browseAction(component, children, breadcrumbs));
+          }
         })
         .then(() => dispatch(pushPath(getPath(componentKey))))
         .then(() => dispatch(stopFetching()))
index ea6e17a23f540fb8a4fb12348fcb37ff629d0aea..ef1b1e561bbc0e6c714c1d2ad5cba9059804a62d 100644 (file)
@@ -67,13 +67,15 @@ class Component extends React.Component {
 
     let componentAction = null;
 
-    switch (component.qualifier) {
-      case 'FIL':
-      case 'UTS':
-        componentAction = <ComponentPin component={component}/>;
-        break;
-      default:
-        componentAction = <ComponentDetach component={component}/>;
+    if (!component.refKey) {
+      switch (component.qualifier) {
+        case 'FIL':
+        case 'UTS':
+          componentAction = <ComponentPin component={component}/>;
+          break;
+        default:
+          componentAction = <ComponentDetach component={component}/>;
+      }
     }
 
     return (
index 9666577ed346b3d14976e0e9766fe9408051373b..c2a18b6defd5b75fd2d13dc327db3557f2412e9b 100644 (file)
@@ -27,7 +27,7 @@ const ComponentDetach = ({ component }) => (
     <a
         className="icon-detach"
         title={translate('code.open_component_page')}
-        href={getComponentUrl(component.copy || component.key)}/>
+        href={getComponentUrl(component.refKey || component.key)}/>
 );
 
 
index df7e1812d321813f55715f14564a0c6103589895..7845e5d1178956c49108776082d332074beb2bd6 100644 (file)
@@ -24,10 +24,10 @@ import { formatMeasure } from '../../../helpers/measures';
 
 
 const ComponentMeasure = ({ component, metricKey, metricType }) => {
-  const measure = _.findWhere(component.msr, { key: metricKey });
+  const measure = _.findWhere(component.measures, { metric: metricKey });
   return (
       <span>
-        {measure ? formatMeasure(measure.val, metricType) : ''}
+        {measure ? formatMeasure(measure.value, metricType) : ''}
       </span>
   );
 };
index 77405448839e4d64539c05fa0a108bd145bb3ca0..dde1849ce4b8b2c0882d0374e285bb27df99afa8 100644 (file)
@@ -62,7 +62,7 @@ const Component = ({ component, previous, onBrowse }) => {
         <span>{component.name.substr(prefix.length)}</span>
       </span>
   ) : component.name;
-  const canBrowse = !!onBrowse && !component.copy;
+  const canBrowse = !!onBrowse;
 
   return (
       <Truncated title={getTooltip(component)}>
index d51a1dd0a187ac979ffbfe86edb749bd3f538bcb..9e3484cdbdc79f36ce775ee06b4706cd149e004c 100644 (file)
@@ -27,7 +27,7 @@ import { translate } from '../../../helpers/l10n';
 const ComponentPin = ({ component }) => {
   const handleClick = (e) => {
     e.preventDefault();
-    Workspace.openComponent({ uuid: component.uuid || component.id });
+    Workspace.openComponent({ uuid: component.id });
   };
 
   return (
index 040e243e74f589cbc3631befd2a9e067db30def4..9fb381e68336dcf4df62ec57b86b77dbc46e6429 100644 (file)
@@ -25,13 +25,13 @@ import { translate } from '../../../helpers/l10n';
 const METRIC = 'alert_status';
 
 const ComponentQualityGate = ({ component }) => {
-  const measure = _.findWhere(component.msr, { key: METRIC });
+  const measure = _.findWhere(component.measures, { metric: METRIC });
   return measure ? (
       <span
           className="spacer-right"
-          title={translate('metric.level', measure.data)}
+          title={translate('metric.level', measure.value)}
           style={{ position: 'relative', top: '-1px' }}>
-        <i className={`icon-alert-${measure.data.toLowerCase()}`}/>
+        <i className={`icon-alert-${measure.value.toLowerCase()}`}/>
       </span>
   ) : <span/>;
 };
index 8645c362148bff5abb749ab17eca1082350bd5a4..ddedbf2617d6f41cf98db7ec6425c7598026d23c 100644 (file)
@@ -28,7 +28,7 @@ export default class SourceViewer extends Component {
   }
 
   shouldComponentUpdate (nextProps) {
-    return nextProps.component.uuid !== this.props.component.uuid;
+    return nextProps.component.id !== this.props.component.id;
   }
 
   componentWillUpdate () {
@@ -46,7 +46,7 @@ export default class SourceViewer extends Component {
   renderSourceViewer () {
     this.sourceViewer = new BaseSourceViewer();
     this.sourceViewer.render().$el.appendTo(this.refs.container);
-    this.sourceViewer.open(this.props.component.uuid);
+    this.sourceViewer.open(this.props.component.id);
   }
 
   destroySourceViewer () {
index 728782c97e7a5f7c3c45581debbe23817cf2f1f2..eb7c09c83011aa4a949d93a0d06f923bb7b28132 100644 (file)
@@ -28,9 +28,9 @@ function hasSourceCode (component) {
 }
 
 function selectCoverageMetric (component) {
-  const coverage = _.findWhere(component.msr, { key: 'coverage' });
-  const itCoverage = _.findWhere(component.msr, { key: 'it_coverage' });
-  const overallCoverage = _.findWhere(component.msr, { key: 'overall_coverage' });
+  const coverage = _.findWhere(component.measures, { metric: 'coverage' });
+  const itCoverage = _.findWhere(component.measures, { metric: 'it_coverage' });
+  const overallCoverage = _.findWhere(component.measures, { metric: 'overall_coverage' });
 
   if (coverage != null && itCoverage != null && overallCoverage != null) {
     return 'overall_coverage';
index e7ae61e7ca8769383c5caa7df695cc6b6289959f..6554987adf68898c60ff4a8806f629e42487feb4 100644 (file)
@@ -32,7 +32,7 @@ const BUBBLES_LIMIT = 500;
 
 
 function getMeasure (component, metric) {
-  return component.measures[metric] || 0;
+  return Number(component.measures[metric]) || 0;
 }
 
 
@@ -53,28 +53,29 @@ export class DomainBubbleChart extends React.Component {
   }
 
   requestFiles () {
-    let metrics = [].concat(this.props.xMetric, this.props.yMetric, this.props.sizeMetrics);
-    return getFiles(this.props.component.key, metrics).then(r => {
+    const metrics = [].concat(this.props.xMetric, this.props.yMetric, this.props.sizeMetrics);
+    const options = {
+      s: 'metric',
+      metricSort: this.props.sizeMetrics,
+      asc: false,
+      ps: BUBBLES_LIMIT
+    };
+    return getFiles(this.props.component.key, metrics, options).then(r => {
       let files = r.map(file => {
         let measures = {};
-        (file.msr || []).forEach(measure => {
-          measures[measure.key] = measure.val;
+        (file.measures || []).forEach(measure => {
+          measures[measure.metric] = measure.value;
         });
         return _.extend(file, { measures });
       });
       this.setState({
         loading: false,
-        files: this.limitFiles(files),
+        files: files,
         total: files.length
       });
     });
   }
 
-  limitFiles (files) {
-    const comparator = file => -1 * this.getSizeMetricsValue(file);
-    return _.sortBy(files, comparator).slice(0, BUBBLES_LIMIT);
-  }
-
   getMetricObject (metrics, metricKey) {
     return _.findWhere(metrics, { key: metricKey });
   }
@@ -96,15 +97,17 @@ export class DomainBubbleChart extends React.Component {
     /* eslint max-len: 0 */
     let inner = [
       component.name,
-      `${this.state.xMetric.name}: ${formatMeasure(getMeasure(component, this.props.xMetric), this.state.xMetric.type)}`,
-      `${this.state.yMetric.name}: ${formatMeasure(getMeasure(component, this.props.yMetric), this.state.yMetric.type)}`,
+      `${this.state.xMetric.name}: ${formatMeasure(getMeasure(component, this.props.xMetric),
+          this.state.xMetric.type)}`,
+      `${this.state.yMetric.name}: ${formatMeasure(getMeasure(component, this.props.yMetric),
+          this.state.yMetric.type)}`,
       `${sizeMetricsTitle}: ${formatMeasure(this.getSizeMetricsValue(component), sizeMetricsType)}`
     ].join('<br>');
     return `<div class="text-left">${inner}</div>`;
   }
 
-  handleBubbleClick (uuid) {
-    Workspace.openComponent({ uuid });
+  handleBubbleClick (id) {
+    Workspace.openComponent({ uuid: id });
   }
 
   renderLoading () {
@@ -123,7 +126,7 @@ export class DomainBubbleChart extends React.Component {
         x: getMeasure(component, this.props.xMetric),
         y: getMeasure(component, this.props.yMetric),
         size: this.getSizeMetricsValue(component),
-        link: component.uuid,
+        link: component.id,
         tooltip: this.getTooltip(component)
       };
     });
@@ -160,7 +163,8 @@ export class DomainBubbleChart extends React.Component {
           {this.state.xMetric.name}
         </div>
         {this.state.total > BUBBLES_LIMIT &&
-        <div className="note text-center">{translateWithParameters('overview.chart.files.limit_message', BUBBLES_LIMIT)}</div>}
+        <div className="note text-center">{translateWithParameters('overview.chart.files.limit_message',
+            BUBBLES_LIMIT)}</div>}
       </div>
     </div>;
   }
index 4ea27a3523a62df7245e9f3ab907106aaad966d1..3ea605187df70204d419cc2b54792d3c78d87a4c 100644 (file)
@@ -51,12 +51,12 @@ export class DomainTreemap extends React.Component {
     return getChildren(componentKey, metrics).then(r => {
       let components = r.map(component => {
         let measures = {};
-        (component.msr || []).forEach(measure => {
-          measures[measure.key] = measure.val;
+        (component.measures || []).forEach(measure => {
+          measures[measure.metric] = measure.value;
         });
         return _.extend(component, {
           measures,
-          key: component.copy ? `${component.copy}` : component.key
+          key: component.refKey || component.key
         });
       });
       this.setState({ loading: false, components });
index d0c6e5f793e08eff06235a9cc3dbc8dc40420b8e..dfe8cff2dbc726d92da0cb342a8432a2f81fc701 100644 (file)
@@ -50,8 +50,8 @@ export const NclocDistribution = React.createClass({
     return getChildren(this.props.component.key, metrics).then(r => {
       let components = r.map(component => {
         let measures = {};
-        (component.msr || []).forEach(measure => {
-          measures[measure.key] = measure.val;
+        (component.measures || []).forEach(measure => {
+          measures[measure.metric] = measure.value;
         });
         return _.extend(component, { measures });
       });
@@ -76,7 +76,7 @@ export const NclocDistribution = React.createClass({
 
     let data = this.state.components.map((component, index) => {
       return {
-        x: parseInt(component.measures[METRIC], 10),
+        x: component.measures[METRIC] ? parseInt(component.measures[METRIC], 10) : 0,
         y: index,
         value: component.name,
         component: component
index a31591cf24ea852d655d092fbd507d7426f3ef7c..9613032c75f01b64b524a35c2dbabd6bb51b0a9a 100644 (file)
@@ -21,14 +21,14 @@ chai.use(sinonChai);
 
 
 const measures = [
-  { key: 'ncloc', val: 9757 }
+  { metric: 'ncloc', value: 9757 }
 ];
 const exampleComponent = {
   uuid: 'A1',
   key: 'A',
   name: 'AA',
   qualifier: 'TRK',
-  msr: measures
+  measures: measures
 };
 const exampleComponent2 = { uuid: 'B2', key: 'B' };
 const exampleComponent3 = { uuid: 'C3', key: 'C' };
index 613eee6517e2827c3c543fa4ea289f8986b71bc6..de5ddbfadf126c06b8a70753b0947b70b5285e98 100644 (file)
@@ -143,8 +143,8 @@ describe('Code :: Store', () => {
         it('should be set to "coverage"', () => {
           const componentWithCoverage = {
             ...exampleComponent,
-            msr: [
-              { key: 'coverage', val: 13 }
+            measures: [
+              { metric: 'coverage', value: 13 }
             ]
           };
 
@@ -155,8 +155,8 @@ describe('Code :: Store', () => {
         it('should be set to "it_coverage"', () => {
           const componentWithCoverage = {
             ...exampleComponent,
-            msr: [
-              { key: 'it_coverage', val: 13 }
+            measures: [
+              { metric: 'it_coverage', value: 13 }
             ]
           };
 
@@ -167,10 +167,10 @@ describe('Code :: Store', () => {
         it('should be set to "overall_coverage"', () => {
           const componentWithCoverage = {
             ...exampleComponent,
-            msr: [
-              { key: 'coverage', val: 11 },
-              { key: 'it_coverage', val: 12 },
-              { key: 'overall_coverage', val: 13 }
+            measures: [
+              { metric: 'coverage', value: 11 },
+              { metric: 'it_coverage', value: 12 },
+              { metric: 'overall_coverage', value: 13 }
             ]
           };
 
@@ -181,7 +181,7 @@ describe('Code :: Store', () => {
         it('should fallback to "it_coverage"', () => {
           const componentWithCoverage = {
             ...exampleComponent,
-            msr: []
+            measures: []
           };
 
           expect(current(initialState, initComponentAction(componentWithCoverage)).coverageMetric)