diff options
author | Stas Vilchik <vilchiks@gmail.com> | 2016-09-13 17:57:52 +0200 |
---|---|---|
committer | Stas Vilchik <vilchiks@gmail.com> | 2016-09-13 17:58:15 +0200 |
commit | b48a6cd51868eab19a131ef7d43ec8d0e10c90f6 (patch) | |
tree | 84c0f36b280e4bb6bcbb447bba1140cc9c157421 /server/sonar-web/src/main/js/apps/code | |
parent | 9033014604e9d537068485b0c71c685eac34d721 (diff) | |
parent | 0359411125578632c70ccf458625d0163c2b8b16 (diff) | |
download | sonarqube-b48a6cd51868eab19a131ef7d43ec8d0e10c90f6.tar.gz sonarqube-b48a6cd51868eab19a131ef7d43ec8d0e10c90f6.zip |
Merge branch 'branch-5.6'
Diffstat (limited to 'server/sonar-web/src/main/js/apps/code')
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"> </th> - <th> </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"> </th> + <th> </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); |