From 2752d139c969d96e016fe2941443acefbebee8c8 Mon Sep 17 00:00:00 2001 From: Stas Vilchik Date: Tue, 13 Sep 2016 11:49:17 +0200 Subject: [PATCH] SONAR-7897 Update measures on the Projects page (#1237) --- .../src/main/js/apps/code/actions/index.js | 57 ++++++++----- .../src/main/js/apps/code/components/Code.js | 2 +- .../main/js/apps/code/components/Component.js | 79 ++++++------------- .../apps/code/components/ComponentMeasure.js | 20 +++-- .../apps/code/components/ComponentsHeader.js | 67 +++++++++------- .../tests/apps/code/components-test.js | 9 ++- .../resources/org/sonar/l10n/core.properties | 1 + 7 files changed, 122 insertions(+), 113 deletions(-) diff --git a/server/sonar-web/src/main/js/apps/code/actions/index.js b/server/sonar-web/src/main/js/apps/code/actions/index.js index 2422d993362..c765e9ed755 100644 --- a/server/sonar-web/src/main/js/apps/code/actions/index.js +++ b/server/sonar-web/src/main/js/apps/code/actions/index.js @@ -24,6 +24,15 @@ import { getChildren, getComponent, getTree, getBreadcrumbs } from '../../../api import { translate } from '../../../helpers/l10n'; import { getComponentUrl } from '../../../helpers/urls'; +const VIEW_METRICS = [ + 'releasability_rating', + 'alert_status', + 'reliability_rating', + 'security_rating', + 'sqale_rating', + 'ncloc' +]; + const METRICS = [ 'ncloc', 'code_smells', @@ -120,16 +129,18 @@ function getPath (componentKey) { return '/' + encodeURIComponent(componentKey); } -function expandRootDir ({ children, total, ...other }) { - const rootDir = children.find(component => component.qualifier === 'DIR' && component.name === '/'); - if (rootDir) { - return getChildren(rootDir.key, METRICS_WITH_COVERAGE).then(r => { - const nextChildren = _.without([...children, ...r.components], rootDir); - const nextTotal = total + r.components.length - /* root dir */ 1; - return { children: nextChildren, total: nextTotal, ...other }; - }); - } else { - return { children, total, ...other }; +function expandRootDir (metrics) { + return function ({ children, total, ...other }) { + const rootDir = children.find(component => component.qualifier === 'DIR' && component.name === '/'); + if (rootDir) { + return getChildren(rootDir.key, metrics).then(r => { + const nextChildren = _.without([...children, ...r.components], rootDir); + const nextTotal = total + r.components.length - /* root dir */ 1; + return { children: nextChildren, total: nextTotal, ...other }; + }); + } else { + return { children, total, ...other }; + } } } @@ -143,16 +154,16 @@ function skipRootDir (breadcrumbs) { }); } -function retrieveComponentBase (componentKey, candidate) { +function retrieveComponentBase (componentKey, candidate, metrics) { return candidate ? Promise.resolve(candidate) : - getComponent(componentKey, METRICS_WITH_COVERAGE); + getComponent(componentKey, metrics); } -function retrieveComponentChildren (componentKey, candidate) { +function retrieveComponentChildren (componentKey, candidate, metrics) { return candidate && candidate.children ? Promise.resolve({ children: candidate.children, total: candidate.total }) : - getChildren(componentKey, METRICS_WITH_COVERAGE, { ps: PAGE_SIZE }).then(prepareChildren).then(expandRootDir); + getChildren(componentKey, metrics, { ps: PAGE_SIZE }).then(prepareChildren).then(expandRootDir(metrics)); } function retrieveComponentBreadcrumbs (componentKey, candidate) { @@ -161,11 +172,12 @@ function retrieveComponentBreadcrumbs (componentKey, candidate) { getBreadcrumbs({ key: componentKey }).then(skipRootDir); } -function retrieveComponent (componentKey, bucket) { +function retrieveComponent (componentKey, bucket, isView) { const candidate = _.findWhere(bucket, { key: componentKey }); + const metrics = isView ? VIEW_METRICS : METRICS_WITH_COVERAGE; return Promise.all([ - retrieveComponentBase(componentKey, candidate), - retrieveComponentChildren(componentKey, candidate), + retrieveComponentBase(componentKey, candidate, metrics), + retrieveComponentChildren(componentKey, candidate, metrics), retrieveComponentBreadcrumbs(componentKey, candidate) ]); } @@ -193,10 +205,13 @@ async function getErrorMessage (response) { } } -export function initComponent (componentKey, breadcrumbs) { +export function initComponent (component, breadcrumbs) { return dispatch => { + const componentKey = component.key; + const isView = component.qualifier === 'VW' || component.qualifier === 'SVW'; + const metrics = isView ? VIEW_METRICS : METRICS_WITH_COVERAGE; dispatch(startFetching()); - return getComponent(componentKey, METRICS_WITH_COVERAGE) + return getComponent(componentKey, metrics) .then(component => dispatch(initComponentAction(component, breadcrumbs))) .then(() => dispatch(replacePath(getPath(componentKey)))) .then(() => dispatch(stopFetching())); @@ -205,9 +220,9 @@ export function initComponent (componentKey, breadcrumbs) { export function browse (componentKey) { return (dispatch, getState) => { - const { bucket } = getState(); + const { bucket, current } = getState(); dispatch(startFetching()); - return retrieveComponent(componentKey, bucket) + return retrieveComponent(componentKey, bucket, current.isView) .then(([component, children, breadcrumbs]) => { if (component.refKey) { window.location = getComponentUrl(component.refKey); diff --git a/server/sonar-web/src/main/js/apps/code/components/Code.js b/server/sonar-web/src/main/js/apps/code/components/Code.js index 16ea3bd1767..aec9d8e724c 100644 --- a/server/sonar-web/src/main/js/apps/code/components/Code.js +++ b/server/sonar-web/src/main/js/apps/code/components/Code.js @@ -32,7 +32,7 @@ class Code extends Component { componentDidMount () { const { dispatch, component, routing } = this.props; const selectedKey = (routing.path && decodeURIComponent(routing.path.substr(1))) || component.key; - dispatch(initComponent(component.key, component.breadcrumbs)) + dispatch(initComponent(component, component.breadcrumbs)) .then(() => dispatch(browse(selectedKey))); } 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 47efb73c58c..ffbab8c9d31 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 @@ -76,7 +76,21 @@ 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 ( @@ -85,63 +99,22 @@ class Component extends React.Component { - {isView && ( - - )} - -
- -
- - -
- -
- - -
- -
- - -
- -
- - -
- -
- - -
- -
- + + {columns.map(column => ( + +
+ +
+ + ))} ); } 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 ; + } + return ( - - {measure ? formatMeasure(measure.value, metricType) : ''} - + ); }; 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 bbe0b097494..8b071f136ff 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,45 @@ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ import React from 'react'; - +import { connect } from 'react-redux'; import { translate } from '../../../helpers/l10n'; -const ComponentsHeader = ({ baseComponent }) => ( - - -   -   - - {baseComponent && translate('metric.ncloc.name')} - - - {baseComponent && translate('metric.bugs.name')} - - - {baseComponent && translate('metric.vulnerabilities.name')} - - - {baseComponent && translate('metric.code_smells.name')} - - - {baseComponent && translate('metric.coverage.name')} - - - {baseComponent && translate('metric.duplicated_lines_density.short_name')} - - - -); +const ComponentsHeader = ({ baseComponent, isView }) => { + 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 ( + + +   +   + {columns.map(column => ( + + {baseComponent && column} + + ))} + + + ); +}; + +function mapStateToProps (state) { + return { + isView: state.current.isView + }; +} + +export default connect(mapStateToProps)(ComponentsHeader); -export default ComponentsHeader; diff --git a/server/sonar-web/tests/apps/code/components-test.js b/server/sonar-web/tests/apps/code/components-test.js index 9613032c75f..26192a5b210 100644 --- a/server/sonar-web/tests/apps/code/components-test.js +++ b/server/sonar-web/tests/apps/code/components-test.js @@ -3,7 +3,6 @@ import sinon from 'sinon'; import sinonChai from 'sinon-chai'; import { shallow } from 'enzyme'; import React from 'react'; -import TestUtils from 'react-addons-test-utils'; import Breadcrumb from '../../../src/main/js/apps/code/components/Breadcrumb'; import Breadcrumbs from '../../../src/main/js/apps/code/components/Breadcrumbs'; @@ -104,10 +103,12 @@ describe('Code :: Components', () => { ); + metricType="SHORT_INT"/> + ).find('Measure'); - expect(output.text()) - .to.equal('9.8k'); + expect(output.length).to.equal(1); + expect(output.prop('measure')).to.deep.equal({ metric: 'ncloc', value: 9757 }); + expect(output.prop('metric')).to.deep.equal({ key: 'ncloc', type: 'SHORT_INT' }); }); it('should not render measure', () => { diff --git a/sonar-core/src/main/resources/org/sonar/l10n/core.properties b/sonar-core/src/main/resources/org/sonar/l10n/core.properties index 4a0d83cf6bf..bfdc872a746 100644 --- a/sonar-core/src/main/resources/org/sonar/l10n/core.properties +++ b/sonar-core/src/main/resources/org/sonar/l10n/core.properties @@ -1276,6 +1276,7 @@ metric_domain.General=General metric_domain.Integration Tests=Integration Tests metric_domain.Issues=Issues metric_domain.Maintainability=Maintainability +metric_domain.Releasability=Releasability metric_domain.Reliability=Reliability metric_domain.Rules=Rules metric_domain.SCM=SCM -- 2.39.5