aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStas Vilchik <vilchiks@gmail.com>2015-04-08 14:13:10 +0200
committerStas Vilchik <vilchiks@gmail.com>2015-04-08 14:27:22 +0200
commit94532b34aa649733d0a38d3aabe6e23ee7cfceaf (patch)
treec09a3d292faa8655a99879d855e420c88854c264
parent315d615fe166dcae24500983e77ead9ebdb8ea99 (diff)
downloadsonarqube-94532b34aa649733d0a38d3aabe6e23ee7cfceaf.tar.gz
sonarqube-94532b34aa649733d0a38d3aabe6e23ee7cfceaf.zip
SONAR-6331 apply feedback
-rw-r--r--server/sonar-web/src/main/hbs/overview/_overview-gate-condition.hbs15
-rw-r--r--server/sonar-web/src/main/hbs/overview/overview-coverage.hbs25
-rw-r--r--server/sonar-web/src/main/hbs/overview/overview-debt.hbs21
-rw-r--r--server/sonar-web/src/main/hbs/overview/overview-duplications.hbs17
-rw-r--r--server/sonar-web/src/main/hbs/overview/overview-gate.hbs44
-rw-r--r--server/sonar-web/src/main/hbs/overview/overview-issues.hbs25
-rw-r--r--server/sonar-web/src/main/hbs/overview/overview-main-layout.hbs14
-rw-r--r--server/sonar-web/src/main/hbs/overview/overview-size.hbs18
-rw-r--r--server/sonar-web/src/main/js/application.js26
-rw-r--r--server/sonar-web/src/main/js/common/handlebars-extensions.js11
-rw-r--r--server/sonar-web/src/main/js/graphics/sparkline.js85
-rw-r--r--server/sonar-web/src/main/js/overview/app.js1
-rw-r--r--server/sonar-web/src/main/js/overview/controller.js3
-rw-r--r--server/sonar-web/src/main/js/overview/main/coverage-view.js14
-rw-r--r--server/sonar-web/src/main/js/overview/main/debt-view.js50
-rw-r--r--server/sonar-web/src/main/js/overview/main/duplications-view.js14
-rw-r--r--server/sonar-web/src/main/js/overview/main/issues-view.js14
-rw-r--r--server/sonar-web/src/main/js/overview/main/layout.js3
-rw-r--r--server/sonar-web/src/main/js/overview/main/size-view.js14
-rw-r--r--server/sonar-web/src/main/js/overview/models/state.js16
-rw-r--r--server/sonar-web/src/main/js/overview/trend-view.js163
-rw-r--r--server/sonar-web/src/main/less/components/columns.less9
-rw-r--r--server/sonar-web/src/main/less/pages/overview.less48
-rw-r--r--server/sonar-web/src/test/js/overview.js16
-rw-r--r--server/sonar-web/src/test/json/overview/measures.json4
-rw-r--r--server/sonar-web/src/test/json/overview/timemachine.json2
-rw-r--r--server/sonar-web/src/test/views/overview.jade1
-rw-r--r--sonar-core/src/main/resources/org/sonar/l10n/core.properties12
28 files changed, 523 insertions, 162 deletions
diff --git a/server/sonar-web/src/main/hbs/overview/_overview-gate-condition.hbs b/server/sonar-web/src/main/hbs/overview/_overview-gate-condition.hbs
new file mode 100644
index 00000000000..c3c278b9fd9
--- /dev/null
+++ b/server/sonar-web/src/main/hbs/overview/_overview-gate-condition.hbs
@@ -0,0 +1,15 @@
+<li class="overview-gate-condition spacer-bottom text-ellipsis">
+ <i class="{{alertIconClass level}}"></i>
+ {{#canHaveDrilldownUrl metric period}}
+ <a href="{{urlForDrilldown ../../componentKey metric period periodDate}}"
+ class="overview-status overview-status-{{level}}"
+ title="{{#notEq level 'OK'}}{{t 'quality_gates.operator' op 'short'}} {{/notEq}}{{#eq level 'ERROR'}}{{formatMeasure error type}}{{/eq}}{{#eq level 'WARN'}}{{formatMeasure warning type}}{{/eq}}"
+ data-toggle="tooltip" data-placement="bottom">{{formatMeasure actual type}}</a>
+ {{else}}
+ <span class="overview-status overview-status-{{level}}"
+ title="{{#notEq level 'OK'}}{{t 'quality_gates.operator' op 'short'}} {{/notEq}}{{#eq level 'ERROR'}}{{formatMeasure error type}}{{/eq}}{{#eq level 'WARN'}}{{formatMeasure warning type}}{{/eq}}"
+ data-toggle="tooltip" data-placement="bottom">{{formatMeasure actual type}}</span>
+ {{/canHaveDrilldownUrl}}
+ <span class="note text-lowercase" style="padding-top: 4px;">{{t 'metric' metric 'name'}}</span>
+ <span class="note text-lowercase">{{default periodName period}}</span>
+</li>
diff --git a/server/sonar-web/src/main/hbs/overview/overview-coverage.hbs b/server/sonar-web/src/main/hbs/overview/overview-coverage.hbs
index bdca7c4d95b..ce3d7a41109 100644
--- a/server/sonar-web/src/main/hbs/overview/overview-coverage.hbs
+++ b/server/sonar-web/src/main/hbs/overview/overview-coverage.hbs
@@ -1,26 +1,25 @@
+<header class="overview-card-header page-header">
+ <h2 class="page-title">{{t 'overview.testing'}}</h2>
+</header>
+
<div class="overview-highlight">
- <h6 class="note">{{t 'overview.coverage'}}</h6>
+ <h6 class="note">{{t 'metric.coverage.name'}}</h6>
<div class="overview-main-measure">
{{#notNull coverage}}
- <a href="{{urlForDrilldown componentKey 'overall_coverage'}}">{{formatMeasure coverage 'PERCENT'}}</a>
+ <a href="{{urlForDrilldown componentKey 'coverage'}}">{{formatMeasure coverage 'PERCENT'}}</a>
{{else}}
{{/notNull}}
</div>
- {{#notNull coverage3}}
- <div class="spacer-top">
- <span class="overview-measure {{#gt coverage3 0}}text-success{{/gt}}{{#lt coverage3 0}}text-danger{{/lt}}">{{formatMeasureVariation coverage3 'PERCENT'}}</span>
- <span class="note">{{period3Name}}</span>
- </div>
- {{/notNull}}
{{#notNull newCoverage3}}
- <div class="spacer-top">
- <a class="overview-measure spacer-top" href="{{urlForDrilldown componentKey 'new_overall_coverage' 3}}">{{formatMeasure newCoverage3 'PERCENT'}}</a>
- <span class="note">on new code</span>
- </div>
+ <h6 class="note">{{period3Name}}</h6>
+ <a class="overview-measure spacer-top"
+ href="{{urlForDrilldown componentKey 'new_coverage' 3}}">{{formatMeasure newCoverage3 'PERCENT'}}</a>
+ <span class="note">{{t 'overview.on_new_code'}}</span>
{{/notNull}}
</div>
<div class="overview-trend">
- <div class="overview-sparkline" id="overview-coverage-trend" data-width="300" data-height="50" data-color="#f3ca8e" data-type="PERCENT"></div>
+ <div class="overview-sparkline" id="overview-coverage-trend" data-height="120" data-color="#f3ca8e"
+ data-type="PERCENT"></div>
</div>
diff --git a/server/sonar-web/src/main/hbs/overview/overview-debt.hbs b/server/sonar-web/src/main/hbs/overview/overview-debt.hbs
new file mode 100644
index 00000000000..6c4e6445de6
--- /dev/null
+++ b/server/sonar-web/src/main/hbs/overview/overview-debt.hbs
@@ -0,0 +1,21 @@
+<header class="overview-card-header page-header">
+ <h2 class="page-title">{{t 'overview.debt'}}</h2>
+</header>
+
+<div class="overview-highlight">
+ <h6 class="note">{{t 'metric.sqale_index.name'}}</h6>
+ <div class="overview-main-measure">
+ <a href="{{urlForDrilldown componentKey 'sqale_index'}}">{{formatMeasure debt 'WORK_DUR'}}</a>
+ </div>
+ {{#notNull issues3}}
+ <h6 class="note">{{period3Name}}</h6>
+ <a href="{{urlForDrilldown componentKey 'new_technical_debt'}}"
+ class="overview-measure {{#gt newDebt 0}}text-danger{{else}}text-success{{/gt}}">{{formatMeasure newDebt 'WORK_DUR'}}</a>
+ <span class="note">{{t 'overview.new'}}</span>
+ {{/notNull}}
+</div>
+
+<div class="overview-trend">
+ <div class="overview-sparkline" id="overview-debt-trend" data-height="120" data-color="#f3ca8e"
+ data-type="WORK_DUR"></div>
+</div>
diff --git a/server/sonar-web/src/main/hbs/overview/overview-duplications.hbs b/server/sonar-web/src/main/hbs/overview/overview-duplications.hbs
index 68b7ecf1748..6c675595748 100644
--- a/server/sonar-web/src/main/hbs/overview/overview-duplications.hbs
+++ b/server/sonar-web/src/main/hbs/overview/overview-duplications.hbs
@@ -1,19 +1,22 @@
+<header class="overview-card-header page-header">
+ <h2 class="page-title">{{t 'overview.duplications'}}</h2>
+</header>
+
<div class="overview-highlight">
- <h6 class="note">{{t 'overview.duplications'}}</h6>
+ <h6 class="note">{{t 'metric.duplicated_lines_density.short_name'}}</h6>
<div class="overview-main-measure">
<a href="{{urlForDrilldown componentKey 'duplicated_lines_density'}}">
{{formatMeasure duplications 'PERCENT'}}
</a>
</div>
{{#notNull duplications3}}
- <div class="spacer-top">
- <a class="overview-measure {{#gt duplications3 0}}text-danger{{/gt}}{{#lt duplications3 0}}text-success{{/lt}}"
- href="{{urlForDrilldown componentKey 'duplicated_lines_density' 3}}">{{formatMeasureVariation duplications3 'PERCENT'}}</a>
- <span class="note">{{period3Name}}</span>
- </div>
+ <h6 class="note">{{period3Name}}</h6>
+ <a class="overview-measure {{#gt duplications3 0}}text-danger{{/gt}}{{#lt duplications3 0}}text-success{{/lt}}"
+ href="{{urlForDrilldown componentKey 'duplicated_lines_density' 3}}">{{formatMeasureVariation duplications3 'PERCENT'}}</a>
{{/notNull}}
</div>
<div class="overview-trend">
- <div class="overview-sparkline" id="overview-duplications-trend" data-width="300" data-height="50" data-color="#f3ca8e" data-type="PERCENT"></div>
+ <div class="overview-sparkline" id="overview-duplications-trend" data-height="120" data-color="#f3ca8e"
+ data-type="PERCENT"></div>
</div>
diff --git a/server/sonar-web/src/main/hbs/overview/overview-gate.hbs b/server/sonar-web/src/main/hbs/overview/overview-gate.hbs
index a43f972baac..a354e431b1e 100644
--- a/server/sonar-web/src/main/hbs/overview/overview-gate.hbs
+++ b/server/sonar-web/src/main/hbs/overview/overview-gate.hbs
@@ -1,22 +1,22 @@
-<div class="text-center">
- {{#notEmpty gateConditions}}
- <ul class="list-inline spacer-top" style="display: inline-block;">
- {{#each gateConditions}}
- <li>
- {{#canHaveDrilldownUrl metric period}}
- <a href="{{urlForDrilldown ../../componentKey metric period periodDate}}"
- class="overview-status overview-status-{{level}}"
- title="{{#notEq level 'OK'}}{{t 'quality_gates.operator' op 'short'}} {{/notEq}}{{#eq level 'ERROR'}}{{formatMeasure error type}}{{/eq}}{{#eq level 'WARN'}}{{formatMeasure warning type}}{{/eq}}"
- data-toggle="tooltip" data-placement="bottom">{{formatMeasure actual type}}</a>
- {{else}}
- <span class="overview-status overview-status-{{level}}"
- title="{{#notEq level 'OK'}}{{t 'quality_gates.operator' op 'short'}} {{/notEq}}{{#eq level 'ERROR'}}{{formatMeasure error type}}{{/eq}}{{#eq level 'WARN'}}{{formatMeasure warning type}}{{/eq}}"
- data-toggle="tooltip" data-placement="bottom">{{formatMeasure actual type}}</span>
- {{/canHaveDrilldownUrl}}
- <p class="note text-lowercase" style="padding-top: 4px;">{{t 'metric' metric 'name'}}</p>
- <p class="note">{{default periodName period}}</p>
- </li>
- {{/each}}
- </ul>
- {{/notEmpty}}
-</div>
+<header class="overview-card-header page-header">
+ <h2 class="page-title">{{t 'overview.gate'}}</h2>
+</header>
+
+{{#notEmpty gateConditions}}
+ <div class="columns">
+ <div class="column-half">
+ <ul>
+ {{#eachEven gateConditions}}
+ {{> '_overview-gate-condition'}}
+ {{/eachEven}}
+ </ul>
+ </div>
+ <div class="column-half">
+ <ul>
+ {{#eachOdd gateConditions}}
+ {{> '_overview-gate-condition'}}
+ {{/eachOdd}}
+ </ul>
+ </div>
+ </div>
+{{/notEmpty}}
diff --git a/server/sonar-web/src/main/hbs/overview/overview-issues.hbs b/server/sonar-web/src/main/hbs/overview/overview-issues.hbs
index ddc1ebdc350..09940d8cc95 100644
--- a/server/sonar-web/src/main/hbs/overview/overview-issues.hbs
+++ b/server/sonar-web/src/main/hbs/overview/overview-issues.hbs
@@ -1,24 +1,21 @@
+<header class="overview-card-header page-header">
+ <h2 class="page-title">{{t 'overview.issues'}}</h2>
+</header>
+
<div class="overview-highlight">
<h6 class="note">{{t 'overview.issues'}}</h6>
<div class="overview-main-measure">
- <a href="{{urlForIssuesOverview componentKey}}">{{formatMeasure issues 'INT'}}</a>
- </div>
- <div class="spacer-top">
- {{#notNull sqaleRating}}
- <a class="overview-measure" href="{{urlForDrilldown componentKey 'sqale_rating'}}"><span class="rating rating-{{formatMeasure sqaleRating 'RATING'}}">{{formatMeasure sqaleRating 'RATING'}}</span></a>
- {{/notNull}}
- &nbsp;&nbsp;
- <a class="overview-measure" href="{{urlForDrilldown componentKey 'sqale_index'}}">{{formatMeasure debt 'WORK_DUR'}}</a>
+ <a href="{{urlForIssuesOverview componentKey}}">{{formatMeasure issues 'SHORT_INT'}}</a>
</div>
{{#notNull issues3}}
- <div class="spacer-top">
- <a href="{{urlForIssuesOverview componentKey period3Date}}"
- class="overview-measure {{#gt issues3 0}}text-danger{{else}}text-success{{/gt}}">{{formatMeasureVariation issues3 'INT'}}</a>
- <span class="note">new {{period3Name}}</span>
- </div>
+ <h6 class="note">{{period3Name}}</h6>
+ <a href="{{urlForIssuesOverview componentKey period3Date}}"
+ class="overview-measure {{#gt issues3 0}}text-danger{{else}}text-success{{/gt}}">{{formatMeasure issues3 'INT'}}</a>
+ <span class="note">{{t 'overview.new'}}</span>
{{/notNull}}
</div>
<div class="overview-trend">
- <div class="overview-sparkline" id="overview-issues-trend" data-width="300" data-height="50" data-color="#f3ca8e" data-type="INT"></div>
+ <div class="overview-sparkline" id="overview-issues-trend" data-height="120" data-color="#f3ca8e"
+ data-type="SHORT_INT"></div>
</div>
diff --git a/server/sonar-web/src/main/hbs/overview/overview-main-layout.hbs b/server/sonar-web/src/main/hbs/overview/overview-main-layout.hbs
index 8ce2a7d4e4f..827246359f9 100644
--- a/server/sonar-web/src/main/hbs/overview/overview-main-layout.hbs
+++ b/server/sonar-web/src/main/hbs/overview/overview-main-layout.hbs
@@ -1,18 +1,12 @@
-<div class="overview-card overview-gate" id="overview-gate"></div>
-
-<div class="overview-container columns">
- <div class="column-half">
- <div class="overview-card" id="overview-size"></div>
- </div>
+<div class="columns">
<div class="column-half">
+ <div class="overview-card overview-gate" id="overview-gate"></div>
<div class="overview-card" id="overview-issues"></div>
+ <div class="overview-card" id="overview-debt"></div>
</div>
-</div>
-<div class="overview-container columns">
<div class="column-half">
+ <div class="overview-card" id="overview-size"></div>
<div class="overview-card" id="overview-coverage"></div>
- </div>
- <div class="column-half">
<div class="overview-card" id="overview-duplications"></div>
</div>
</div>
diff --git a/server/sonar-web/src/main/hbs/overview/overview-size.hbs b/server/sonar-web/src/main/hbs/overview/overview-size.hbs
index b06b14ed706..907e4727c9f 100644
--- a/server/sonar-web/src/main/hbs/overview/overview-size.hbs
+++ b/server/sonar-web/src/main/hbs/overview/overview-size.hbs
@@ -1,16 +1,24 @@
+<header class="overview-card-header page-header">
+ <h2 class="page-title">{{t 'overview.size'}}</h2>
+</header>
+
<div class="overview-highlight">
- <h6 class="note">{{t 'overview.lines_of_code'}}</h6>
+ <h6 class="note">{{t 'metric.ncloc.name'}}</h6>
<div class="overview-main-measure">
- <a href="{{urlForDrilldown componentKey 'ncloc'}}">{{formatMeasure ncloc 'INT'}}</a>
+ <a href="{{urlForDrilldown componentKey 'ncloc'}}">{{formatMeasure ncloc 'SHORT_INT'}}</a>
</div>
+
{{#notNull ncloc3}}
<div class="spacer-top">
- <span class="overview-measure">{{formatMeasureVariation ncloc3 'INT'}}</span>
- <span class="note">{{period3Name}}</span>
+ <h6 class="note">{{period3Name}}</h6>
+ <span class="overview-measure">{{formatMeasureVariation ncloc3 'SHORT_INT'}}</span>
</div>
{{/notNull}}
</div>
<div class="overview-trend">
- <div class="overview-sparkline" id="overview-size-trend" data-width="300" data-height="50" data-color="#f3ca8e" data-type="INT"></div>
+ <div class="overview-sparkline" id="overview-size-trend" data-height="120" data-color="#f3ca8e"
+ data-type="SHORT_INT"></div>
</div>
+
+
diff --git a/server/sonar-web/src/main/js/application.js b/server/sonar-web/src/main/js/application.js
index 530f2eba504..592c1265493 100644
--- a/server/sonar-web/src/main/js/application.js
+++ b/server/sonar-web/src/main/js/application.js
@@ -288,6 +288,28 @@ function closeModalWindow () {
(function () {
+ function shortIntFormatter (value) {
+ var format = '0,0';
+ if (value >= 1000) {
+ format = '0.[0]a';
+ }
+ if (value >= 10000) {
+ format = '0a';
+ }
+ return numeral(value).format(format);
+ }
+
+ function shortIntVariationFormatter (value) {
+ var format = '+0,0';
+ if (value >= 1000) {
+ format = '+0.[0]a';
+ }
+ if (value >= 10000) {
+ format = '+0a';
+ }
+ return numeral(value).format(format);
+ }
+
/**
* Check if days should be displayed for a work duration
* @param {number} days
@@ -324,7 +346,7 @@ function closeModalWindow () {
* @returns {string}
*/
function addSpaceIfNeeded (value) {
- return value.length > 0 ? value : value + ' ';
+ return value.length > 0 ? value + ' ' : value;
}
/**
@@ -402,6 +424,7 @@ function closeModalWindow () {
'INT': function (value) {
return numeral(value).format('0,0');
},
+ 'SHORT_INT': shortIntFormatter,
'FLOAT': function (value) {
return numeral(value).format('0,0.0');
},
@@ -429,6 +452,7 @@ function closeModalWindow () {
'INT': function (value) {
return value === 0 ? '0' : numeral(value).format('+0,0');
},
+ 'SHORT_INT': shortIntVariationFormatter,
'FLOAT': function (value) {
return value === 0 ? '0' : numeral(value).format('+0,0.0');
},
diff --git a/server/sonar-web/src/main/js/common/handlebars-extensions.js b/server/sonar-web/src/main/js/common/handlebars-extensions.js
index 86b4286efb4..1a8fb87bef3 100644
--- a/server/sonar-web/src/main/js/common/handlebars-extensions.js
+++ b/server/sonar-web/src/main/js/common/handlebars-extensions.js
@@ -370,11 +370,14 @@
});
Handlebars.registerHelper('numberShort', function (number) {
- if (number > 9999) {
- return numeral(number).format('0.[0]a');
- } else {
- return numeral(number).format('0,0');
+ var format = '0,0';
+ if (number >= 10000) {
+ format = '0.[0]a';
+ }
+ if (number >= 100000) {
+ format = '0a';
}
+ return numeral(number).format(format);
});
Handlebars.registerHelper('pluginActions', function (actions, options) {
diff --git a/server/sonar-web/src/main/js/graphics/sparkline.js b/server/sonar-web/src/main/js/graphics/sparkline.js
index 986011c0e58..6d2397f7210 100644
--- a/server/sonar-web/src/main/js/graphics/sparkline.js
+++ b/server/sonar-web/src/main/js/graphics/sparkline.js
@@ -26,7 +26,7 @@
var defaults = {
height: 30,
color: '#1f77b4',
- interpolate: 'bundle',
+ interpolate: 'linear',
tension: 1,
type: 'INT'
};
@@ -57,15 +57,17 @@
xScale = d3.time.scale()
.domain(d3.extent(data, function (d) {
return moment(d.val).toDate();
- })),
+ }))
+ .nice(),
yScale = d3.scale.linear()
.domain(d3.extent(data, function (d) {
return d.count;
- })),
+ }))
+ .nice(),
- minValue = yScale.domain()[0],
- maxValue = yScale.domain()[1],
+ xTicks = xScale.ticks(5),
+ yTicks = yScale.ticks(3),
line = d3.svg.line()
.x(function (d) {
@@ -75,31 +77,13 @@
return yScale(d.count);
})
.interpolate(options.interpolate)
- .tension(options.tension),
-
- minLabel = plot.append('text')
- .text(window.formatMeasure(minValue, options.type))
- .attr('dy', '3px')
- .style('text-anchor', 'end')
- .style('font-size', '10px')
- .style('font-weight', '300')
- .style('fill', '#aaa'),
-
- maxLabel = plot.append('text')
- .text(window.formatMeasure(maxValue, options.type))
- .attr('dy', '5px')
- .style('text-anchor', 'end')
- .style('font-size', '10px')
- .style('font-weight', '300')
- .style('fill', '#aaa'),
-
- maxLabelWidth = Math.max(minLabel.node().getBBox().width, maxLabel.node().getBBox().width) + 3;
+ .tension(options.tension);
_.extend(options, {
- marginLeft: 1,
- marginRight: 1 + maxLabelWidth,
- marginTop: 6,
- marginBottom: 6
+ marginLeft: 20,
+ marginRight: 50,
+ marginTop: 0,
+ marginBottom: 25
});
_.extend(options, {
@@ -111,18 +95,49 @@
xScale.range([0, options.availableWidth]);
yScale.range([options.availableHeight, 0]);
+ xTicks.forEach(function (tick) {
+ plot.append('text')
+ .text(xScale.tickFormat()(tick))
+ .attr('x', xScale(tick))
+ .attr('y', options.availableHeight + 20)
+ .attr('dy', '0')
+ .style('text-anchor', 'middle')
+ .style('font-size', '10px')
+ .style('font-weight', '300')
+ .style('fill', '#aaa');
+ plot.append('line')
+ .attr('x1', xScale(tick))
+ .attr('x2', xScale(tick))
+ .attr('y1', 0)
+ .attr('y2', options.availableHeight)
+ .style('stroke', '#eee')
+ .style('shape-rendering', 'crispedges');
+ });
+
+ yTicks.forEach(function (tick) {
+ plot.append('text')
+ .text(window.formatMeasure(tick, options.type))
+ .attr('x', options.availableWidth + 50)
+ .attr('y', yScale(tick))
+ .attr('dy', '5px')
+ .style('text-anchor', 'end')
+ .style('font-size', '10px')
+ .style('font-weight', '300')
+ .style('fill', '#aaa');
+ plot.append('line')
+ .attr('x1', 0)
+ .attr('x2', options.availableWidth)
+ .attr('y1', yScale(tick))
+ .attr('y2', yScale(tick))
+ .style('stroke', '#eee')
+ .style('shape-rendering', 'crispedges');
+ });
+
plot.append('path')
.datum(data)
.attr('d', line)
.classed('line', true)
.style('stroke', options.color);
-
- minLabel
- .attr('x', options.availableWidth + maxLabelWidth)
- .attr('y', yScale(minValue));
- maxLabel
- .attr('x', options.availableWidth + maxLabelWidth)
- .attr('y', yScale(maxValue));
}
);
};
diff --git a/server/sonar-web/src/main/js/overview/app.js b/server/sonar-web/src/main/js/overview/app.js
index 4bf5db63969..04f885f2683 100644
--- a/server/sonar-web/src/main/js/overview/app.js
+++ b/server/sonar-web/src/main/js/overview/app.js
@@ -35,6 +35,7 @@ requirejs([
// add state model
this.state = new State(window.overviewConf);
+ this.state.set('period3Name', 'During Leak Period');
// create and render layout
this.layout = new Layout({
diff --git a/server/sonar-web/src/main/js/overview/controller.js b/server/sonar-web/src/main/js/overview/controller.js
index f72b99cefdf..69f50d885bd 100644
--- a/server/sonar-web/src/main/js/overview/controller.js
+++ b/server/sonar-web/src/main/js/overview/controller.js
@@ -22,12 +22,14 @@ define([
'overview/main/gate-view',
'overview/main/size-view',
'overview/main/issues-view',
+ 'overview/main/debt-view',
'overview/main/coverage-view',
'overview/main/duplications-view'
], function (MainLayout,
GateView,
SizeView,
IssuesView,
+ DebtView,
CoverageView,
DuplicationsView) {
@@ -45,6 +47,7 @@ define([
mainLayout.gateRegion.show(new GateView(options));
mainLayout.sizeRegion.show(new SizeView(options));
mainLayout.issuesRegion.show(new IssuesView(options));
+ mainLayout.debtRegion.show(new DebtView(options));
mainLayout.coverageRegion.show(new CoverageView(options));
mainLayout.duplicationsRegion.show(new DuplicationsView(options));
this.state.fetch();
diff --git a/server/sonar-web/src/main/js/overview/main/coverage-view.js b/server/sonar-web/src/main/js/overview/main/coverage-view.js
index 8b807e4d6ed..28bb1e5c7a0 100644
--- a/server/sonar-web/src/main/js/overview/main/coverage-view.js
+++ b/server/sonar-web/src/main/js/overview/main/coverage-view.js
@@ -18,8 +18,9 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
define([
+ 'overview/trend-view',
'templates/overview'
-], function () {
+], function (TrendView) {
return Marionette.Layout.extend({
template: Templates['overview-coverage'],
@@ -32,7 +33,16 @@ define([
var trend = this.model.get('coverageTrend'),
hasCoverage = this.model.get('coverage') != null;
if (_.size(trend) > 1 && hasCoverage) {
- this.$('#overview-coverage-trend').sparkline(this.model.get('coverageTrend'));
+ this.trendView = new TrendView({ data: trend, type: 'PERCENT' });
+ this.trendView.render()
+ .$el.appendTo(this.$('#overview-coverage-trend'));
+ this.trendView.update();
+ }
+ },
+
+ onClose: function () {
+ if (this.trendView != null) {
+ this.trendView.detachEvents().remove();
}
}
});
diff --git a/server/sonar-web/src/main/js/overview/main/debt-view.js b/server/sonar-web/src/main/js/overview/main/debt-view.js
new file mode 100644
index 00000000000..80861a82152
--- /dev/null
+++ b/server/sonar-web/src/main/js/overview/main/debt-view.js
@@ -0,0 +1,50 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube 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.
+ *
+ * SonarQube 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.
+ */
+define([
+ 'overview/trend-view',
+ 'templates/overview'
+], function (TrendView) {
+
+ return Marionette.Layout.extend({
+ template: Templates['overview-debt'],
+
+ modelEvents: {
+ 'change': 'render'
+ },
+
+ onRender: function () {
+ var trend = this.model.get('debtTrend'),
+ hasDebt = this.model.get('debt') != null;
+ if (_.size(trend) > 1 && hasDebt) {
+ this.trendView = new TrendView({ data: trend, type: 'WORK_DUR' });
+ this.trendView.render()
+ .$el.appendTo(this.$('#overview-debt-trend'));
+ this.trendView.update();
+ }
+ },
+
+ onClose: function () {
+ if (this.trendView != null) {
+ this.trendView.detachEvents().remove();
+ }
+ }
+ });
+
+});
diff --git a/server/sonar-web/src/main/js/overview/main/duplications-view.js b/server/sonar-web/src/main/js/overview/main/duplications-view.js
index 18e69af549b..a1310587288 100644
--- a/server/sonar-web/src/main/js/overview/main/duplications-view.js
+++ b/server/sonar-web/src/main/js/overview/main/duplications-view.js
@@ -18,8 +18,9 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
define([
+ 'overview/trend-view',
'templates/overview'
-], function () {
+], function (TrendView) {
return Marionette.Layout.extend({
template: Templates['overview-duplications'],
@@ -32,7 +33,16 @@ define([
var trend = this.model.get('duplicationsTrend'),
hasDuplications = this.model.get('duplications') != null;
if (_.size(trend) > 1 && hasDuplications) {
- this.$('#overview-duplications-trend').sparkline(this.model.get('duplicationsTrend'));
+ this.trendView = new TrendView({ data: trend, type: 'PERCENT' });
+ this.trendView.render()
+ .$el.appendTo(this.$('#overview-duplications-trend'));
+ this.trendView.update();
+ }
+ },
+
+ onClose: function () {
+ if (this.trendView != null) {
+ this.trendView.detachEvents().remove();
}
}
});
diff --git a/server/sonar-web/src/main/js/overview/main/issues-view.js b/server/sonar-web/src/main/js/overview/main/issues-view.js
index a17a1d9547a..bfda55b2578 100644
--- a/server/sonar-web/src/main/js/overview/main/issues-view.js
+++ b/server/sonar-web/src/main/js/overview/main/issues-view.js
@@ -18,8 +18,9 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
define([
+ 'overview/trend-view',
'templates/overview'
-], function () {
+], function (TrendView) {
return Marionette.Layout.extend({
template: Templates['overview-issues'],
@@ -32,7 +33,16 @@ define([
var trend = this.model.get('issuesTrend'),
hasIssues = this.model.get('issues') != null;
if (_.size(trend) > 1 && hasIssues) {
- this.$('#overview-issues-trend').sparkline(this.model.get('issuesTrend'));
+ this.trendView = new TrendView({ data: trend, type: 'SHORT_INT' });
+ this.trendView.render()
+ .$el.appendTo(this.$('#overview-issues-trend'));
+ this.trendView.update();
+ }
+ },
+
+ onClose: function () {
+ if (this.trendView != null) {
+ this.trendView.detachEvents().remove();
}
}
});
diff --git a/server/sonar-web/src/main/js/overview/main/layout.js b/server/sonar-web/src/main/js/overview/main/layout.js
index 8db7c1e088d..c0e46deffd5 100644
--- a/server/sonar-web/src/main/js/overview/main/layout.js
+++ b/server/sonar-web/src/main/js/overview/main/layout.js
@@ -28,6 +28,7 @@ define([
gateRegion: '#overview-gate',
sizeRegion: '#overview-size',
issuesRegion: '#overview-issues',
+ debtRegion: '#overview-debt',
coverageRegion: '#overview-coverage',
duplicationsRegion: '#overview-duplications'
},
@@ -39,7 +40,7 @@ define([
toggleRegions: function () {
var conditions = this.model.get('gateConditions'),
hasGate = _.isArray(conditions) && conditions.length > 0;
- this.$(this.gateRegion.el).toggle(hasGate);
+ this.$(this.gateRegion.el).toggleClass('hidden', !hasGate);
}
});
diff --git a/server/sonar-web/src/main/js/overview/main/size-view.js b/server/sonar-web/src/main/js/overview/main/size-view.js
index db1ab7e41a8..07917e89c52 100644
--- a/server/sonar-web/src/main/js/overview/main/size-view.js
+++ b/server/sonar-web/src/main/js/overview/main/size-view.js
@@ -18,8 +18,9 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
define([
+ 'overview/trend-view',
'templates/overview'
-], function () {
+], function (TrendView) {
return Marionette.Layout.extend({
template: Templates['overview-size'],
@@ -32,7 +33,16 @@ define([
var trend = this.model.get('sizeTrend'),
hasSize = this.model.get('ncloc') != null;
if (_.size(trend) > 1 && hasSize) {
- this.$('#overview-size-trend').sparkline(this.model.get('sizeTrend'));
+ this.trendView = new TrendView({ data: trend, type: 'SHORT_INT' });
+ this.trendView.render()
+ .$el.appendTo(this.$('#overview-size-trend'));
+ this.trendView.update();
+ }
+ },
+
+ onClose: function () {
+ if (this.trendView != null) {
+ this.trendView.detachEvents().remove();
}
}
});
diff --git a/server/sonar-web/src/main/js/overview/models/state.js b/server/sonar-web/src/main/js/overview/models/state.js
index 6b19a415287..d3be4446ee1 100644
--- a/server/sonar-web/src/main/js/overview/models/state.js
+++ b/server/sonar-web/src/main/js/overview/models/state.js
@@ -24,9 +24,10 @@ define(function () {
SIZE_METRIC = 'ncloc',
ISSUES_METRIC = 'violations',
DEBT_METRIC = 'sqale_index',
+ NEW_DEBT_METRIC = 'new_technical_debt',
SQALE_RATING_METRIC = 'sqale_rating',
- COVERAGE_METRIC = 'overall_coverage',
- NEW_COVERAGE_METRIC = 'new_overall_coverage',
+ COVERAGE_METRIC = 'coverage',
+ NEW_COVERAGE_METRIC = 'new_coverage',
DUPLICATIONS_METRIC = 'duplicated_lines_density';
return Backbone.Model.extend({
@@ -68,6 +69,7 @@ define(function () {
GATE_METRIC,
SIZE_METRIC,
DEBT_METRIC,
+ NEW_DEBT_METRIC,
SQALE_RATING_METRIC,
COVERAGE_METRIC,
NEW_COVERAGE_METRIC,
@@ -148,10 +150,14 @@ define(function () {
parseDebt: function (msr) {
var debtMeasure = _.findWhere(msr, { key: DEBT_METRIC }),
+ newDebtMeasure = _.findWhere(msr, { key: NEW_DEBT_METRIC }),
sqaleRatingMeasure = _.findWhere(msr, { key: SQALE_RATING_METRIC });
if (debtMeasure != null) {
this.set({ debt: debtMeasure.val });
}
+ if (newDebtMeasure != null) {
+ this.set({ newDebt: newDebtMeasure.var3 });
+ }
if (sqaleRatingMeasure != null) {
this.set({ sqaleRating: sqaleRatingMeasure.val });
}
@@ -191,6 +197,7 @@ define(function () {
metrics: [
SIZE_METRIC,
ISSUES_METRIC,
+ DEBT_METRIC,
COVERAGE_METRIC,
DUPLICATIONS_METRIC
].join(',')
@@ -199,6 +206,7 @@ define(function () {
if (_.isArray(r)) {
that.parseSizeTrend(r[0]);
that.parseIssuesTrend(r[0]);
+ that.parseDebtTrend(r[0]);
that.parseCoverageTrend(r[0]);
that.parseDuplicationsTrend(r[0]);
}
@@ -224,6 +232,10 @@ define(function () {
this.parseTrend(r, 'issuesTrend', ISSUES_METRIC);
},
+ parseDebtTrend: function (r) {
+ this.parseTrend(r, 'debtTrend', DEBT_METRIC);
+ },
+
parseCoverageTrend: function (r) {
this.parseTrend(r, 'coverageTrend', COVERAGE_METRIC);
},
diff --git a/server/sonar-web/src/main/js/overview/trend-view.js b/server/sonar-web/src/main/js/overview/trend-view.js
new file mode 100644
index 00000000000..aeaac5ad697
--- /dev/null
+++ b/server/sonar-web/src/main/js/overview/trend-view.js
@@ -0,0 +1,163 @@
+define(function () {
+
+ function trans (left, top) {
+ return 'translate(' + left + ', ' + top + ')';
+ }
+
+ var $ = jQuery;
+
+
+ return Backbone.View.extend({
+
+ initialize: function (options) {
+ this.data = options.data;
+ this.type = options.type || 'INT';
+ this.width = 0;
+ this.height = 0;
+ },
+
+ attachEvents: function () {
+ this.detachEvents();
+ var event = 'resize.trend-' + this.cid,
+ update = _.throttle(_.bind(this.update, this), 50);
+ $(window).on(event, update);
+ },
+
+ detachEvents: function () {
+ var event = 'resize.trend-' + this.cid;
+ $(window).off(event);
+ return this;
+ },
+
+ render: function () {
+ var that = this,
+ data = this.data;
+ this.container = d3.select(this.el);
+ this.svg = this.container.append('svg')
+ .classed('sonar-d3', true);
+ this.plot = this.svg.append('g')
+ .classed('plot', true);
+
+ this.xScale = d3.time.scale()
+ .domain(d3.extent(data, function (d) {
+ return moment(d.val).toDate();
+ }))
+ .nice();
+ this.yScale = d3.scale.linear()
+ .domain(d3.extent(data, function (d) {
+ return d.count;
+ }))
+ .nice();
+
+ this.line = d3.svg.line()
+ .x(function (d) {
+ return that.xScale(moment(d.val).toDate());
+ })
+ .y(function (d) {
+ return that.yScale(d.count);
+ })
+ .interpolate('linear');
+
+ this.xScaleTicks = this.xScale.ticks(5);
+ this.yScaleTicks = this.yScale.ticks(3);
+
+ this.xTicks = this.xScaleTicks.map(function (tick) {
+ return that.plot.append('text')
+ .datum(tick)
+ .text(that.xScale.tickFormat()(tick))
+ .attr('dy', '0')
+ .style('text-anchor', 'middle')
+ .style('font-size', '10px')
+ .style('font-weight', '300')
+ .style('fill', '#aaa');
+ });
+ this.yTicks = this.yScaleTicks.map(function (tick) {
+ return that.plot.append('text')
+ .datum(tick)
+ .text(window.formatMeasure(tick, that.type))
+ .attr('dy', '5px')
+ .style('text-anchor', 'end')
+ .style('font-size', '10px')
+ .style('font-weight', '300')
+ .style('fill', '#aaa');
+ });
+
+ this.xTickLines = this.xScaleTicks.map(function (tick) {
+ return that.plot.append('line')
+ .datum(tick)
+ .style('stroke', '#eee')
+ .style('shape-rendering', 'crispedges');
+ });
+ this.yTickLines = this.yScaleTicks.map(function (tick) {
+ return that.plot.append('line')
+ .datum(tick)
+ .style('stroke', '#eee')
+ .style('shape-rendering', 'crispedges');
+ });
+
+ this.path = this.plot.append('path')
+ .datum(data)
+ .classed('line', true)
+ .style('stroke', 'rgb(31, 119, 180)');
+
+ this.attachEvents();
+
+ return this;
+ },
+
+ update: function () {
+ var that = this,
+ width = this.$el.closest('.overview-trend').width(),
+ height = 150,
+ marginLeft = 20,
+ marginRight = 50,
+ marginTop = 5,
+ marginBottom = 25,
+ availableWidth = width - marginLeft - marginRight,
+ availableHeight = height - marginTop - marginBottom;
+
+ this.svg
+ .attr('width', width)
+ .attr('height', height);
+
+ this.plot.attr('transform', trans(marginLeft, marginTop));
+ this.xScale.range([0, availableWidth]);
+ this.yScale.range([availableHeight, 0]);
+
+ this.path
+ .attr('d', this.line);
+
+ this.xTicks.forEach(function (tick) {
+ tick
+ .attr('x', that.xScale(tick.datum()))
+ .attr('y', availableHeight + 20);
+ });
+
+ this.yTicks.forEach(function (tick) {
+ tick
+ .attr('x', availableWidth + 50)
+ .attr('y', that.yScale(tick.datum()));
+ });
+
+ this.xTickLines.forEach(function (tick) {
+ tick
+ .attr('x1', that.xScale(tick.datum()))
+ .attr('x2', that.xScale(tick.datum()))
+ .attr('y1', 0)
+ .attr('y2', availableHeight);
+ });
+
+ this.yTickLines.forEach(function (tick) {
+ tick
+ .attr('x1', 0)
+ .attr('x2', availableWidth)
+ .attr('y1', that.yScale(tick.datum()))
+ .attr('y2', that.yScale(tick.datum()));
+ });
+
+ return this;
+ }
+
+ });
+
+});
diff --git a/server/sonar-web/src/main/less/components/columns.less b/server/sonar-web/src/main/less/components/columns.less
index 0e4b489e74b..699573084ee 100644
--- a/server/sonar-web/src/main/less/components/columns.less
+++ b/server/sonar-web/src/main/less/components/columns.less
@@ -37,7 +37,14 @@
.column-third {
float: left;
- width: 33%;
+ width: 33.3333333333%;
+ padding: 0 10px;
+ .box-sizing(border-box);
+}
+
+.column-two-thirds {
+ float: left;
+ width: 66.6666666667%;
padding: 0 10px;
.box-sizing(border-box);
}
diff --git a/server/sonar-web/src/main/less/pages/overview.less b/server/sonar-web/src/main/less/pages/overview.less
index 311e5bb6bc4..4582868d23e 100644
--- a/server/sonar-web/src/main/less/pages/overview.less
+++ b/server/sonar-web/src/main/less/pages/overview.less
@@ -28,13 +28,14 @@
}
.overview-card {
- padding-top: 5px;
- background: @white;
+ .clearfix;
+ padding: 20px;
border: 1px solid @barBorderColor;
+ background: @white;
}
-.overview-gate {
- padding: 10px;
+.overview-card:not(.hidden) + .overview-card {
+ margin-top: 20px;
}
.overview-gate-ok { border: 2px solid @green; }
@@ -43,13 +44,17 @@
.overview-gate-error { border: 2px solid @red; }
+.overview-gate-condition {
+ padding-left: 1px;
+}
+
.overview-container {
margin-top: 20px;
- text-align: center;
}
.overview-card-header {
- padding-bottom: 5px;
+ margin-bottom: 20px;
+ padding-bottom: 20px;
border-bottom: 1px solid @barBorderColor;
}
@@ -57,7 +62,6 @@
margin: 0;
padding: 0 6px;
color: #fff !important;
- font-size: 24px;
font-weight: 300;
a& {
@@ -74,31 +78,29 @@
.overview-status-ERROR { background-color: @red; }
.overview-highlight {
- height: 145px;
-}
-
-.overview-main-measure {
- line-height: 1.3;
- font-size: 36px;
- font-weight: 300;
+ float: left;
+ width: 160px;
+ padding-right: 20px;
+ .box-sizing(border-box);
}
.overview-trend {
- height: 50px;
- margin-top: 15px;
- padding: 5px 10px;
- border-top: 1px solid @barBorderColor;
- background-color: #fdfdfd;
+ padding-left: 160px;
.note { font-size: 10px; }
}
-.overview-sparkline {
- display: inline-block;
- vertical-align: middle;
+.overview-main-measure {
+ line-height: 1.3;
+ margin-bottom: 20px;
+ font-size: 36px;
+ font-weight: 300;
+
+ .rating { font-size: 30px; }
}
.overview-measure {
- font-size: 16px;
+ line-height: 1.5;
+ font-size: 20px;
font-weight: 300;
}
diff --git a/server/sonar-web/src/test/js/overview.js b/server/sonar-web/src/test/js/overview.js
index 0a1cb43e0f1..78c2dcbb23a 100644
--- a/server/sonar-web/src/test/js/overview.js
+++ b/server/sonar-web/src/test/js/overview.js
@@ -26,7 +26,7 @@ lib.changeWorkingDirectory('overview');
lib.configureCasper();
-casper.test.begin(testName(), 23, function (test) {
+casper.test.begin(testName(), 22, function (test) {
casper
.start(lib.buildUrl('overview'), function () {
lib.setDefaultViewport();
@@ -44,7 +44,7 @@ casper.test.begin(testName(), 23, function (test) {
})
.then(function () {
- casper.waitForText('165,077');
+ casper.waitForText('165k');
})
.then(function () {
@@ -58,17 +58,17 @@ casper.test.begin(testName(), 23, function (test) {
test.assertElementCount('#overview-gate .overview-status-WARN', 1);
test.assertElementCount('#overview-gate .overview-status-OK', 5);
- test.assertSelectorContains('#overview-size', '165,077');
- test.assertSelectorContains('#overview-size', '+3,916');
+ test.assertSelectorContains('#overview-size', '165k');
+ test.assertSelectorContains('#overview-size', '+3.9k');
test.assertExists('#overview-size-trend path');
- test.assertSelectorContains('#overview-issues', '1,605');
- test.assertSelectorContains('#overview-issues', 'A');
- test.assertSelectorContains('#overview-issues', '66');
+ test.assertSelectorContains('#overview-issues', '1.6k');
test.assertExists('#overview-issues-trend path');
+ test.assertSelectorContains('#overview-debt', '66');
+ test.assertExists('#overview-debt-trend path');
+
test.assertSelectorContains('#overview-coverage', '83.9%');
- test.assertSelectorContains('#overview-coverage', '+0.6%');
test.assertSelectorContains('#overview-coverage', '90.0%');
test.assertExists('#overview-coverage-trend path');
diff --git a/server/sonar-web/src/test/json/overview/measures.json b/server/sonar-web/src/test/json/overview/measures.json
index 33c235ca575..826a1ab308d 100644
--- a/server/sonar-web/src/test/json/overview/measures.json
+++ b/server/sonar-web/src/test/json/overview/measures.json
@@ -74,7 +74,7 @@
"fvar3": "0"
},
{
- "key": "overall_coverage",
+ "key": "coverage",
"val": 83.9,
"frmt_val": "83.9%",
"trend": 0,
@@ -85,7 +85,7 @@
"fvar3": "0.6%"
},
{
- "key": "new_overall_coverage",
+ "key": "new_coverage",
"var1": 88.2352941176471,
"fvar1": "88.2%",
"var2": 87.9254132585941,
diff --git a/server/sonar-web/src/test/json/overview/timemachine.json b/server/sonar-web/src/test/json/overview/timemachine.json
index a2d4391d1e7..1ac438fc2bb 100644
--- a/server/sonar-web/src/test/json/overview/timemachine.json
+++ b/server/sonar-web/src/test/json/overview/timemachine.json
@@ -11,7 +11,7 @@
"metric": "sqale_index"
},
{
- "metric": "overall_coverage"
+ "metric": "coverage"
},
{
"metric": "duplicated_lines_density"
diff --git a/server/sonar-web/src/test/views/overview.jade b/server/sonar-web/src/test/views/overview.jade
index 7f50024c955..4e381f1ce6d 100644
--- a/server/sonar-web/src/test/views/overview.jade
+++ b/server/sonar-web/src/test/views/overview.jade
@@ -14,4 +14,3 @@ block body
componentKey: 'org.codehaus.sonar:sonar',
componentUuid: '69e57151-be0d-4157-adff-c06741d88879'
};
- require(['overview/app']);
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 16d538afaff..0b1657038ba 100644
--- a/sonar-core/src/main/resources/org/sonar/l10n/core.properties
+++ b/sonar-core/src/main/resources/org/sonar/l10n/core.properties
@@ -2259,7 +2259,7 @@ metric.generated_ncloc.abbreviation=Gen. LOC
metric.lines.name=Lines
metric.lines.description=Lines
-metric.ncloc.name=Lines of code
+metric.ncloc.name=Lines of Code
metric.ncloc.description=Non Commenting Lines of Code
metric.ncloc.abbreviation=LOC
@@ -2533,6 +2533,7 @@ metric.duplicated_files.description=Duplicated files
metric.duplicated_files.abbreviation=Dup. files
metric.duplicated_lines_density.name=Duplicated lines (%)
+metric.duplicated_lines_density.short_name=Duplications
metric.duplicated_lines_density.description=Duplicated lines balanced by statements
metric.duplicated_lines_density.abbreviation=Dup. lines(%)
@@ -2993,8 +2994,11 @@ workspace.close=Remove from the list of pinned files
# OVERVIEW
#
#------------------------------------------------------------------------------
-overview.lines_of_code=Lines of Code
+overview.size=Size
+overview.gate=Quality Gate
overview.issues=Issues
-overview.debt=Debt
-overview.coverage=Coverage
+overview.debt=Technical Debt
+overview.testing=Testing
overview.duplications=Duplications
+overview.new=new
+overview.on_new_code=on new code