*/
export const domains = {
'Reliability': {
+ main: [
+ 'bugs',
+ 'new_bugs',
+ 'reliability_rating'
+ ],
order: [
'bugs',
'new_bugs',
},
'Security': {
+ main: [
+ 'vulnerabilities',
+ 'new_vulnerabilities',
+ 'security_rating'
+ ],
order: [
'vulnerabilities',
'new_vulnerabilities',
},
'Maintainability': {
+ main: [
+ 'code_smells',
+ 'new_code_smells',
+ 'sqale_rating'
+ ],
order: [
'code_smells',
'new_code_smells',
+ 'sqale_rating',
'sqale_index',
'new_technical_debt',
- 'sqale_rating',
'sqale_debt_ratio',
'new_sqale_debt_ratio',
'effort_to_reach_maintainability_rating_a'
},
'Tests': {
+ main: [
+ 'overall_coverage',
+ 'coverage',
+ 'it_coverage',
+ 'new_overall_coverage',
+ 'new_coverage',
+ 'new_it_coverage',
+ 'tests'
+ ],
order: [
'overall_coverage',
'new_overall_coverage',
},
'Duplication': {
+ main: [
+ 'duplicated_lines_density'
+ ],
order: [
'duplicated_lines_density',
'duplicated_blocks',
},
'Size': {
- order: [
+ main: [
'ncloc'
+ ],
+ order: [
+ 'ncloc',
+ 'lines',
+ 'statements',
+ 'functions',
+ 'classes',
+ 'files',
+ 'directories'
+ ]
+ },
+
+ 'Complexity': {
+ main: [
+ 'complexity'
+ ],
+ order: [
+ 'complexity',
+ 'function_complexity',
+ 'file_complexity',
+ 'class_complexity'
+ ]
+ },
+
+ 'Documentation': {
+ main: [
+ 'comment_lines_density'
+ ],
+ order: [
+ 'comment_lines_density'
+ ]
+ },
+
+ 'General': {
+ main: [
+ 'alert_status'
+ ],
+ order: [
+ 'alert_status'
]
},
'Issues': {
+ main: [
+ 'violations',
+ 'new_violations'
+ ],
order: [
'violations',
'new_violations',
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-import sortBy from '../../../../../../node_modules/lodash/sortBy';
-import partition from '../../../../../../node_modules/lodash/partition';
import React from 'react';
-import MeasuresList from './MeasuresList';
-import { domains } from '../config/domains';
-
-const sortMeasures = (measures, order) => {
- const [known, unknown] = partition(measures, measure => order.includes(measure.metric.key));
- return [
- ...sortBy(known, measure => order.indexOf(measure.metric.key)),
- ...sortBy(unknown, measure => measure.metric.name)
- ];
-};
+import HomeMeasuresList from './HomeMeasuresList';
export default class AllMeasuresDomain extends React.Component {
render () {
- const { domain, component, leakPeriodLabel, displayHeader } = this.props;
-
- const hasLeak = !!leakPeriodLabel;
- const { measures } = domain;
- const domainConfig = domains[domain.name] || { order: [] };
- const orderedMeasures = domainConfig.order;
- const sortedMeasures = sortMeasures(measures, orderedMeasures);
+ const { domain, component, displayHeader } = this.props;
return (
<li>
</header>
)}
- <MeasuresList
- measures={sortedMeasures}
- hasLeak={hasLeak}
- component={component}
- spaces={domainConfig.spaces || []}/>
+ <HomeMeasuresList
+ domain={domain}
+ component={component}/>
</li>
);
}
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-import sortBy from '../../../../../../node_modules/lodash/sortBy';
-import partition from '../../../../../../node_modules/lodash/partition';
import React from 'react';
-import MeasuresList from './MeasuresList';
+import HomeMeasuresList from './HomeMeasuresList';
import MeasureBubbleChartContainer from '../components/bubbleChart/MeasureBubbleChartContainer';
-import { getLeakPeriodLabel } from '../../../helpers/periods';
import { hasBubbleChart } from '../utils';
-import { domains as domainsConf } from '../config/domains';
-
-const sortMeasures = (measures, order) => {
- const [known, unknown] = partition(measures, measure => order.includes(measure.metric.key));
- return [
- ...sortBy(known, measure => order.indexOf(measure.metric.key)),
- ...sortBy(unknown, measure => measure.metric.name)
- ];
-};
-
-const filterCoverageMeasures = measures => {
- const hasOverallCoverage = !!measures.find(measure => measure.metric.key === 'overall_coverage');
- const hasUTCoverage = !!measures.find(measure => measure.metric.key === 'coverage');
- const hasITCoverage = !!measures.find(measure => measure.metric.key === 'it_coverage');
-
- // display overall coverage only if all types of coverage exist
- const shouldShowOverallCoverage = hasOverallCoverage && hasUTCoverage && hasITCoverage;
-
- // skip if we should display overall coverage
- if (shouldShowOverallCoverage) {
- return measures;
- }
-
- // otherwise, hide all overall coverage measures
- return measures.filter(measure => {
- return measure.metric.key.indexOf('overall_') !== 0 &&
- measure.metric.key.indexOf('new_overall_') !== 0;
- });
-};
export default class DomainMeasures extends React.Component {
render () {
- const { component, domains, periods } = this.props;
+ const { component, domains } = this.props;
const { domainName } = this.props.params;
const domain = domains.find(d => d.name === domainName);
- const { measures } = domain;
- const leakPeriodLabel = getLeakPeriodLabel(periods);
-
- const filteredMeasures = filterCoverageMeasures(measures);
- const conf = domainsConf[domainName];
- const order = conf ? conf.order : [];
- const spaces = conf && conf.spaces ? conf.spaces : [];
- const sortedMeasures = sortMeasures(filteredMeasures, order);
return (
<section id="component-measures-domain">
- <MeasuresList
- measures={sortedMeasures}
- component={component}
- spaces={spaces}
- hasLeak={leakPeriodLabel != null}/>
+ <HomeMeasuresList
+ domain={domain}
+ component={component}/>
{hasBubbleChart(domainName) && (
<MeasureBubbleChartContainer domainName={domainName}/>
export default class Home extends React.Component {
componentDidMount () {
+ document.querySelector('html').classList.add('dashboard-page');
this.props.onDisplay();
this.props.fetchMeasures();
}
+ componentWillUnmount () {
+ document.querySelector('html').classList.remove('dashboard-page');
+ }
+
render () {
const { component, domains, periods } = this.props;
--- /dev/null
+/*
+ * 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 React from 'react';
+import partition from 'lodash/partition';
+import sortBy from 'lodash/sortBy';
+
+import MeasuresList from './MeasuresList';
+import { domains } from '../config/domains';
+
+function sortMeasures (measures, order) {
+ const [known, unknown] = partition(measures, measure => order.includes(measure.metric.key));
+ return [
+ ...sortBy(known, measure => order.indexOf(measure.metric.key)),
+ ...sortBy(unknown, measure => measure.metric.name)
+ ];
+}
+
+function filterCoverageMeasures (measures) {
+ const hasOverallCoverage = !!measures.find(measure => measure.metric.key === 'overall_coverage');
+ const hasUTCoverage = !!measures.find(measure => measure.metric.key === 'coverage');
+ const hasITCoverage = !!measures.find(measure => measure.metric.key === 'it_coverage');
+
+ // display overall coverage only if all types of coverage exist
+ const shouldShowOverallCoverage = hasOverallCoverage && hasUTCoverage && hasITCoverage;
+
+ // skip if we should display overall coverage
+ if (shouldShowOverallCoverage) {
+ return measures;
+ }
+
+ // otherwise, hide all overall coverage measures
+ return measures.filter(measure => {
+ return measure.metric.key.indexOf('overall_') !== 0 &&
+ measure.metric.key.indexOf('new_overall_') !== 0;
+ });
+}
+
+function filterIssuesMeasures (measures) {
+ const BANNED_MEASURES = [
+ 'blocker_violations',
+ 'new_blocker_violations',
+ 'critical_violations',
+ 'new_critical_violations',
+ 'major_violations',
+ 'new_major_violations',
+ 'minor_violations',
+ 'new_minor_violations',
+ 'info_violations',
+ 'new_info_violations'
+ ];
+ return measures.filter(measure => !BANNED_MEASURES.includes(measure.metric.key));
+}
+
+const HomeMeasuresList = ({ domain, component }) => {
+ const { measures, name } = domain;
+ const config = domains[name] || {};
+
+ const filteredMeasures = filterCoverageMeasures(filterIssuesMeasures(measures));
+
+ const configMain = config.main || [];
+ const [mainMeasures, otherMeasures] = partition(filteredMeasures, measure => configMain.includes(measure.metric.key));
+
+ const configOrder = config.order || [];
+ const sortedMainMeasures = sortMeasures(mainMeasures, configOrder);
+ const sortedOtherMeasures = sortMeasures(otherMeasures, configOrder);
+
+ return (
+ <div className="home-measures-list clearfix">
+ {sortedMainMeasures.length > 0 && (
+ <MeasuresList
+ className="main-domain-measures"
+ measures={sortedMainMeasures}
+ component={component}
+ spaces={[]}/>
+ )}
+
+ {sortedOtherMeasures.length > 0 && (
+ <MeasuresList
+ measures={sortedOtherMeasures}
+ component={component}
+ spaces={[]}/>
+ )}
+ </div>
+ );
+};
+
+export default HomeMeasuresList;
*/
import React from 'react';
import { Link } from 'react-router';
-import classNames from 'classnames';
import MeasureListValue from './MeasureListValue';
-const shouldPutSpace = (spaces, measure, index) => {
- return index !== 0 && spaces.includes(measure.metric.key);
-};
-
-const MeasuresList = ({ measures, component, spaces }) => {
+const MeasuresList = ({ measures, component, className = 'domain-measures' }) => {
return (
- <ul className="domain-measures">
- {measures.map((measure, index) => (
+ <ul className={className}>
+ {measures.map(measure => (
<li
key={measure.metric.key}
- id={`measure-${measure.metric.key}`}
- className={classNames({ 'big-spacer-top': shouldPutSpace(spaces, measure, index) })}>
+ id={`measure-${measure.metric.key}`}>
<Link to={{ pathname: `metric/${measure.metric.key}`, query: { id: component.key } }}>
<div className="domain-measures-name">
<span id={`measure-${measure.metric.key}-name`}>
display: flex;
justify-content: space-between;
align-items: flex-start;
- margin-bottom: 30px;
+ margin-bottom: 20px;
}
.measures-domains {
}
.measures-domains > li {
- padding-bottom: 20px;
+ margin-bottom: 20px;
+}
+
+.measures-domains > li > div {
+ border: 1px solid #e6e6e6;
+ background-color: #fff;
}
.measures-domains-leak-header {
white-space: nowrap;
}
+.main-domain-measures {
+ display: flex;
+ flex-wrap: wrap;
+ justify-content: space-around;
+ float: left;
+ width: 480px;
+ margin-right: 60px;
+}
+
+.main-domain-measures > li {
+ padding: 12px 0;
+}
+
+.main-domain-measures > li > a {
+ display: flex;
+ flex-direction: column-reverse;
+ width: 160px;
+ border: none;
+ text-align: center;
+}
+
+.main-domain-measures .domain-measures-value {
+ height: 40px;
+ box-sizing: border-box;
+ color: #444;
+ font-size: 30px;
+ font-weight: 300;
+}
+
+.main-domain-measures .domain-measures-name {
+ margin-top: 8px;
+}
+
+.main-domain-measures .domain-measures-name > span {
+ border-bottom: 1px solid #cae3f2;
+}
+
+.main-domain-measures .domain-measures-leak {
+ margin: 0 20px;
+ border: 1px solid #eae3c7;
+ background-color: #fbf3d5;
+}
+
.domain-measures {
+ overflow: hidden;
line-height: 1.4;
}
background-color: #ecf6fe !important;
}
-.domain-measures-name,
-.domain-measures-value {
+.domain-measures .domain-measures-name,
+.domain-measures .domain-measures-value {
padding: 7px 10px;
box-sizing: border-box;
}
-.domain-measures-name {
+.domain-measures .domain-measures-name {
width: calc(100% - 160px);
}
-.domain-measures-name > span {
+.domain-measures .domain-measures-name > span {
border-bottom: 1px solid #cae3f2;
}
-.domain-measures-value {
+.domain-measures .domain-measures-value {
width: 80px;
color: #444;
text-align: right;
}
-.domain-measures-leak {
+.domain-measures .domain-measures-leak {
background-color: #fbf3d5;
transition: background-color 0.3s ease;
}
-.domain-measures > li:nth-child(odd) .domain-measures-leak {
+.domain-measures .domain-measures > li:nth-child(odd) .domain-measures-leak {
background-color: #f5eed0;
}
-.domain-main-measures {
- display: flex;
- flex-wrap: wrap;
- padding: 0 10px;
-}
-
-.domain-main-measures > li {
- margin-right: 40px;
- margin-bottom: 30px;
-}
-
-.domain-main-measures-value {
- line-height: 1;
- font-size: 24px;
- font-weight: 300;
-}
-
-.domain-main-measures-leak {
-
-}
-
-.domain-main-measures-label {
- margin-top: 4px;
- white-space: nowrap;
-}
-
.measure-details {
margin-top: 10px;
}
.measure-details-bubble-chart {
position: relative;
- margin: 10px 0;
+ margin: 40px 0 10px;
padding: 30px 0 30px 60px;
+ border: 1px solid #e6e6e6;
+ background-color: #fff;
}
.measure-details-bubble-chart-axis {
.component-measures-breadcrumbs > li:last-child::after {
display: none;
}
+
+.home-measures-list {
+ border: 1px solid #e6e6e6;
+ background-color: #fff;
+}
padding: 3px 10px;
border: 1px solid transparent;
border-radius: 24px;
- background-color: #fff;
color: @darkBlue;
transition: none;