aboutsummaryrefslogtreecommitdiffstats
path: root/server/sonar-web/src/main/js/apps/code
diff options
context:
space:
mode:
authorStas Vilchik <vilchiks@gmail.com>2016-09-13 17:57:52 +0200
committerStas Vilchik <vilchiks@gmail.com>2016-09-13 17:58:15 +0200
commitb48a6cd51868eab19a131ef7d43ec8d0e10c90f6 (patch)
tree84c0f36b280e4bb6bcbb447bba1140cc9c157421 /server/sonar-web/src/main/js/apps/code
parent9033014604e9d537068485b0c71c685eac34d721 (diff)
parent0359411125578632c70ccf458625d0163c2b8b16 (diff)
downloadsonarqube-b48a6cd51868eab19a131ef7d43ec8d0e10c90f6.tar.gz
sonarqube-b48a6cd51868eab19a131ef7d43ec8d0e10c90f6.zip
Merge branch 'branch-5.6'
Diffstat (limited to 'server/sonar-web/src/main/js/apps/code')
-rw-r--r--server/sonar-web/src/main/js/apps/code/components/App.js9
-rw-r--r--server/sonar-web/src/main/js/apps/code/components/Component.js80
-rw-r--r--server/sonar-web/src/main/js/apps/code/components/ComponentMeasure.js20
-rw-r--r--server/sonar-web/src/main/js/apps/code/components/ComponentQualityGate.js39
-rw-r--r--server/sonar-web/src/main/js/apps/code/components/Components.js2
-rw-r--r--server/sonar-web/src/main/js/apps/code/components/ComponentsHeader.js59
-rw-r--r--server/sonar-web/src/main/js/apps/code/utils.js107
7 files changed, 158 insertions, 158 deletions
diff --git a/server/sonar-web/src/main/js/apps/code/components/App.js b/server/sonar-web/src/main/js/apps/code/components/App.js
index 556bbb8e70c..fda516734ca 100644
--- a/server/sonar-web/src/main/js/apps/code/components/App.js
+++ b/server/sonar-web/src/main/js/apps/code/components/App.js
@@ -67,7 +67,8 @@ export default class App extends React.Component {
addComponentBreadcrumbs(component.key, component.breadcrumbs);
this.setState({ loading: true });
- retrieveComponentBase(component.key).then(component => {
+ const isView = component.qualifier === 'VW' || component.qualifier === 'SVW';
+ retrieveComponentBase(component.key, isView).then(component => {
const prefix = selectCoverageMetric(component.measures);
this.coverageMetric = `${prefix}coverage`;
this.handleUpdate();
@@ -82,7 +83,8 @@ export default class App extends React.Component {
loadComponent (componentKey) {
this.setState({ loading: true });
- retrieveComponent(componentKey).then(r => {
+ const isView = this.props.component.qualifier === 'VW' || this.props.component.qualifier === 'SVW';
+ retrieveComponent(componentKey, isView).then(r => {
if (this.mounted) {
if (['FIL', 'UTS'].includes(r.component.qualifier)) {
this.setState({
@@ -122,7 +124,8 @@ export default class App extends React.Component {
handleLoadMore () {
const { baseComponent, page } = this.state;
- loadMoreChildren(baseComponent.key, page + 1).then(r => {
+ const isView = this.props.component.qualifier === 'VW' || this.props.component.qualifier === 'SVW';
+ loadMoreChildren(baseComponent.key, page + 1, isView).then(r => {
if (this.mounted) {
this.setState({
components: [...this.state.components, ...r.components],
diff --git a/server/sonar-web/src/main/js/apps/code/components/Component.js b/server/sonar-web/src/main/js/apps/code/components/Component.js
index 5134427d03d..11b975c81c2 100644
--- a/server/sonar-web/src/main/js/apps/code/components/Component.js
+++ b/server/sonar-web/src/main/js/apps/code/components/Component.js
@@ -24,7 +24,6 @@ import shallowCompare from 'react-addons-shallow-compare';
import ComponentName from './ComponentName';
import ComponentMeasure from './ComponentMeasure';
-import ComponentQualityGate from './ComponentQualityGate';
import ComponentDetach from './ComponentDetach';
import ComponentPin from './ComponentPin';
@@ -83,7 +82,21 @@ export default class Component extends React.Component {
}
}
- /* eslint object-shorthand: 0 */
+ const columns = isView ? [
+ { metric: 'releasability_rating', type: 'RATING' },
+ { metric: 'reliability_rating', type: 'RATING' },
+ { metric: 'security_rating', type: 'RATING' },
+ { metric: 'sqale_rating', type: 'RATING' },
+ { metric: 'ncloc', type: 'SHORT_INT' },
+ ] : [
+ { metric: 'ncloc', type: 'SHORT_INT' },
+ { metric: 'bugs', type: 'SHORT_INT' },
+ { metric: 'vulnerabilities', type: 'SHORT_INT' },
+ { metric: 'code_smells', type: 'SHORT_INT' },
+ { metric: coverageMetric, type: 'PERCENT' },
+ { metric: 'duplicated_lines_density', type: 'PERCENT' }
+ ];
+
return (
<tr className={classNames({ selected })}>
<td className="thin nowrap">
@@ -92,64 +105,23 @@ export default class Component extends React.Component {
</span>
</td>
<td className="code-name-cell">
- {isView && (
- <ComponentQualityGate
- component={component}/>
- )}
<ComponentName
component={component}
rootComponent={rootComponent}
previous={previous}
canBrowse={canBrowse}/>
</td>
- <td className="thin nowrap text-right">
- <div className="code-components-cell">
- <ComponentMeasure
- component={component}
- metricKey="ncloc"
- metricType="SHORT_INT"/>
- </div>
- </td>
- <td className="thin nowrap text-right">
- <div className="code-components-cell">
- <ComponentMeasure
- component={component}
- metricKey="bugs"
- metricType="SHORT_INT"/>
- </div>
- </td>
- <td className="thin nowrap text-right">
- <div className="code-components-cell">
- <ComponentMeasure
- component={component}
- metricKey="vulnerabilities"
- metricType="SHORT_INT"/>
- </div>
- </td>
- <td className="thin nowrap text-right">
- <div className="code-components-cell">
- <ComponentMeasure
- component={component}
- metricKey="code_smells"
- metricType="SHORT_INT"/>
- </div>
- </td>
- <td className="thin nowrap text-right">
- <div className="code-components-cell">
- <ComponentMeasure
- component={component}
- metricKey={coverageMetric}
- metricType="PERCENT"/>
- </div>
- </td>
- <td className="thin nowrap text-right">
- <div className="code-components-cell">
- <ComponentMeasure
- component={component}
- metricKey="duplicated_lines_density"
- metricType="PERCENT"/>
- </div>
- </td>
+
+ {columns.map(column => (
+ <td key={column.metric} className="thin nowrap text-right">
+ <div className="code-components-cell">
+ <ComponentMeasure
+ component={component}
+ metricKey={column.metric}
+ metricType={column.type}/>
+ </div>
+ </td>
+ ))}
</tr>
);
}
diff --git a/server/sonar-web/src/main/js/apps/code/components/ComponentMeasure.js b/server/sonar-web/src/main/js/apps/code/components/ComponentMeasure.js
index a4a31655b74..4938464a414 100644
--- a/server/sonar-web/src/main/js/apps/code/components/ComponentMeasure.js
+++ b/server/sonar-web/src/main/js/apps/code/components/ComponentMeasure.js
@@ -19,15 +19,23 @@
*/
import _ from 'underscore';
import React from 'react';
-
-import { formatMeasure } from '../../../helpers/measures';
+import Measure from '../../component-measures/components/Measure';
const ComponentMeasure = ({ component, metricKey, metricType }) => {
- const measure = _.findWhere(component.measures, { metric: metricKey });
+ const isProject = component.qualifier === 'TRK';
+ const isReleasability = metricKey === 'releasability_rating';
+
+ const finalMetricKey = (isProject && isReleasability) ? 'alert_status' : metricKey;
+ const finalMetricType = (isProject && isReleasability) ? 'LEVEL' : metricType;
+
+ const measure = _.findWhere(component.measures, { metric: finalMetricKey });
+
+ if (!measure) {
+ return <span/>;
+ }
+
return (
- <span>
- {measure ? formatMeasure(measure.value, metricType) : ''}
- </span>
+ <Measure measure={measure} metric={{ key: finalMetricKey, type: finalMetricType }}/>
);
};
diff --git a/server/sonar-web/src/main/js/apps/code/components/ComponentQualityGate.js b/server/sonar-web/src/main/js/apps/code/components/ComponentQualityGate.js
deleted file mode 100644
index 599515ebefd..00000000000
--- a/server/sonar-web/src/main/js/apps/code/components/ComponentQualityGate.js
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2016 SonarSource SA
- * mailto:contact 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.
- */
-import _ from 'underscore';
-import React from 'react';
-
-import { translate } from '../../../helpers/l10n';
-
-const METRIC = 'alert_status';
-
-const ComponentQualityGate = ({ component }) => {
- const measure = _.findWhere(component.measures, { metric: METRIC });
- return measure ? (
- <span
- className="spacer-right"
- title={translate('metric.level', measure.value)}
- style={{ position: 'relative', top: '-1px' }}>
- <i className={`icon-alert-${measure.value.toLowerCase()}`}/>
- </span>
- ) : <span/>;
-};
-
-export default ComponentQualityGate;
diff --git a/server/sonar-web/src/main/js/apps/code/components/Components.js b/server/sonar-web/src/main/js/apps/code/components/Components.js
index 056e1795cd5..dc5a3da84e8 100644
--- a/server/sonar-web/src/main/js/apps/code/components/Components.js
+++ b/server/sonar-web/src/main/js/apps/code/components/Components.js
@@ -25,7 +25,7 @@ import ComponentsHeader from './ComponentsHeader';
const Components = ({ rootComponent, baseComponent, components, selected, coverageMetric }) => (
<table className="data zebra">
- <ComponentsHeader baseComponent={baseComponent}/>
+ <ComponentsHeader baseComponent={baseComponent} rootComponent={rootComponent}/>
{baseComponent && (
<tbody>
<Component
diff --git a/server/sonar-web/src/main/js/apps/code/components/ComponentsHeader.js b/server/sonar-web/src/main/js/apps/code/components/ComponentsHeader.js
index 0cd9e667a74..2efd63147a6 100644
--- a/server/sonar-web/src/main/js/apps/code/components/ComponentsHeader.js
+++ b/server/sonar-web/src/main/js/apps/code/components/ComponentsHeader.js
@@ -18,34 +18,39 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
import React from 'react';
-
import { translate } from '../../../helpers/l10n';
-const ComponentsHeader = ({ baseComponent }) => (
- <thead>
- <tr className="code-components-header">
- <th className="thin nowrap">&nbsp;</th>
- <th>&nbsp;</th>
- <th className="thin nowrap text-right code-components-cell">
- {baseComponent && translate('metric.ncloc.name')}
- </th>
- <th className="thin nowrap text-right code-components-cell">
- {baseComponent && translate('metric.bugs.name')}
- </th>
- <th className="thin nowrap text-right code-components-cell">
- {baseComponent && translate('metric.vulnerabilities.name')}
- </th>
- <th className="thin nowrap text-right code-components-cell">
- {baseComponent && translate('metric.code_smells.name')}
- </th>
- <th className="thin nowrap text-right code-components-cell">
- {baseComponent && translate('metric.coverage.name')}
- </th>
- <th className="thin nowrap text-right code-components-cell">
- {baseComponent && translate('metric.duplicated_lines_density.short_name')}
- </th>
- </tr>
- </thead>
-);
+const ComponentsHeader = ({ baseComponent, rootComponent }) => {
+ const isView = rootComponent.qualifier === 'VW' || rootComponent.qualifier === 'SVW';
+
+ const columns = isView ? [
+ translate('metric_domain.Releasability'),
+ translate('metric_domain.Reliability'),
+ translate('metric_domain.Security'),
+ translate('metric_domain.Maintainability'),
+ translate('metric', 'ncloc', 'name')
+ ] : [
+ translate('metric', 'ncloc', 'name'),
+ translate('metric', 'bugs', 'name'),
+ translate('metric', 'vulnerabilities', 'name'),
+ translate('metric', 'code_smells', 'name'),
+ translate('metric', 'coverage', 'name'),
+ translate('metric', 'duplicated_lines_density', 'short_name')
+ ];
+
+ return (
+ <thead>
+ <tr className="code-components-header">
+ <th className="thin nowrap">&nbsp;</th>
+ <th>&nbsp;</th>
+ {columns.map(column => (
+ <th key={column} className="thin nowrap text-right code-components-cell">
+ {baseComponent && column}
+ </th>
+ ))}
+ </tr>
+ </thead>
+ );
+};
export default ComponentsHeader;
diff --git a/server/sonar-web/src/main/js/apps/code/utils.js b/server/sonar-web/src/main/js/apps/code/utils.js
index 169f7175ac9..8347f52fe71 100644
--- a/server/sonar-web/src/main/js/apps/code/utils.js
+++ b/server/sonar-web/src/main/js/apps/code/utils.js
@@ -20,12 +20,12 @@
import without from 'lodash/without';
import {
- addComponent,
- getComponent as getComponentFromBucket,
- addComponentChildren,
- getComponentChildren,
- addComponentBreadcrumbs,
- getComponentBreadcrumbs
+ addComponent,
+ getComponent as getComponentFromBucket,
+ addComponentChildren,
+ getComponentChildren,
+ addComponentBreadcrumbs,
+ getComponentBreadcrumbs
} from './bucket';
import { getChildren, getComponent, getBreadcrumbs } from '../../api/components';
import { translate } from '../../helpers/l10n';
@@ -46,19 +46,45 @@ const METRICS_WITH_COVERAGE = [
'overall_coverage'
];
+const VIEW_METRICS = [
+ 'releasability_rating',
+ 'alert_status',
+ 'reliability_rating',
+ 'security_rating',
+ 'sqale_rating',
+ 'ncloc'
+];
+
const PAGE_SIZE = 100;
-function expandRootDir ({ components, total, ...other }) {
- const rootDir = components.find(component => component.qualifier === 'DIR' && component.name === '/');
- if (rootDir) {
- return getChildren(rootDir.key, METRICS_WITH_COVERAGE).then(r => {
- const nextComponents = without([...r.components, ...components], rootDir);
- const nextTotal = total + r.components.length - /* root dir */ 1;
- return { components: nextComponents, total: nextTotal, ...other };
- });
- } else {
- return { components, total, ...other };
- }
+function requestChildren (componentKey, metrics, page) {
+ return getChildren(componentKey, metrics, { p: page, ps: PAGE_SIZE }).then(r => {
+ if (r.paging.total > r.paging.pageSize * r.paging.pageIndex) {
+ return requestChildren(componentKey, metrics, page + 1).then(moreComponents => {
+ return [...r.components, ...moreComponents];
+ })
+ }
+ return r.components;
+ });
+}
+
+function requestAllChildren (componentKey, metrics) {
+ return requestChildren(componentKey, metrics, 1);
+}
+
+function expandRootDir (metrics) {
+ return function ({ components, total, ...other }) {
+ const rootDir = components.find(component => component.qualifier === 'DIR' && component.name === '/');
+ if (rootDir) {
+ return requestAllChildren(rootDir.key, metrics).then(rootDirComponents => {
+ const nextComponents = without([...rootDirComponents, ...components], rootDir);
+ const nextTotal = total + rootDirComponents.length - /* root dir */ 1;
+ return { components: nextComponents, total: nextTotal, ...other };
+ });
+ } else {
+ return { components, total, ...other };
+ }
+ };
}
function prepareChildren (r) {
@@ -89,19 +115,35 @@ function storeChildrenBreadcrumbs (parentComponentKey, children) {
}
}
-export function retrieveComponentBase (componentKey) {
+function getMetrics (isView) {
+ return isView ? VIEW_METRICS : METRICS_WITH_COVERAGE;
+}
+
+/**
+ * @param {string} componentKey
+ * @param {boolean} isView
+ * @returns {Promise}
+ */
+export function retrieveComponentBase (componentKey, isView) {
const existing = getComponentFromBucket(componentKey);
if (existing) {
return Promise.resolve(existing);
}
- return getComponent(componentKey, METRICS_WITH_COVERAGE).then(component => {
+ const metrics = getMetrics(isView);
+
+ return getComponent(componentKey, metrics).then(component => {
addComponent(component);
return component;
});
}
-function retrieveComponentChildren (componentKey) {
+/**
+ * @param {string} componentKey
+ * @param {boolean} isView
+ * @returns {Promise}
+ */
+function retrieveComponentChildren (componentKey, isView) {
const existing = getComponentChildren(componentKey);
if (existing) {
return Promise.resolve({
@@ -110,9 +152,11 @@ function retrieveComponentChildren (componentKey) {
});
}
- return getChildren(componentKey, METRICS_WITH_COVERAGE, { ps: PAGE_SIZE, s: 'name' })
+ const metrics = getMetrics(isView);
+
+ return getChildren(componentKey, metrics, { ps: PAGE_SIZE, s: 'name' })
.then(prepareChildren)
- .then(expandRootDir)
+ .then(expandRootDir(metrics))
.then(r => {
addComponentChildren(componentKey, r.components, r.total);
storeChildrenBase(r.components);
@@ -135,10 +179,15 @@ function retrieveComponentBreadcrumbs (componentKey) {
});
}
-export function retrieveComponent (componentKey) {
+/**
+ * @param {string} componentKey
+ * @param {boolean} isView
+ * @returns {Promise}
+ */
+export function retrieveComponent (componentKey, isView) {
return Promise.all([
- retrieveComponentBase(componentKey),
- retrieveComponentChildren(componentKey),
+ retrieveComponentBase(componentKey, isView),
+ retrieveComponentChildren(componentKey, isView),
retrieveComponentBreadcrumbs(componentKey)
]).then(r => {
return {
@@ -151,10 +200,12 @@ export function retrieveComponent (componentKey) {
});
}
-export function loadMoreChildren (componentKey, page) {
- return getChildren(componentKey, METRICS_WITH_COVERAGE, { ps: PAGE_SIZE, p: page })
+export function loadMoreChildren (componentKey, page, isView) {
+ const metrics = getMetrics(isView);
+
+ return getChildren(componentKey, metrics, { ps: PAGE_SIZE, p: page })
.then(prepareChildren)
- .then(expandRootDir)
+ .then(expandRootDir(metrics))
.then(r => {
addComponentChildren(componentKey, r.components, r.total);
storeChildrenBase(r.components);