aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStas Vilchik <vilchiks@gmail.com>2015-06-29 13:21:37 +0200
committerStas Vilchik <vilchiks@gmail.com>2015-06-29 14:49:35 +0200
commit390aa827d11c7a50c6916c3e80919873fc2266c2 (patch)
treed5627e685144c1189136bf8290532733a03a8617
parentda0c64602b7f8e8b09a7b11a6b9687e7fbfefb69 (diff)
downloadsonarqube-390aa827d11c7a50c6916c3e80919873fc2266c2.tar.gz
sonarqube-390aa827d11c7a50c6916c3e80919873fc2266c2.zip
SONAR-6668 update issue filters widgets to display the technical debt
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/dashboard/widget/IssueFilterWidget.java4
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/dashboard/widget/ProjectIssueFilterWidget.java4
-rw-r--r--server/sonar-server/src/main/resources/org/sonar/server/dashboard/widget/issue_filter.html.erb4
-rw-r--r--server/sonar-server/src/main/resources/org/sonar/server/dashboard/widget/project_issue_filter.html.erb2
-rw-r--r--server/sonar-web/src/main/js/widgets/issue-filter/templates/_widget-issue-filter-total.hbs6
-rw-r--r--server/sonar-web/src/main/js/widgets/issue-filter/templates/widget-issue-filter-action-plans.hbs6
-rw-r--r--server/sonar-web/src/main/js/widgets/issue-filter/templates/widget-issue-filter-assignees.hbs6
-rw-r--r--server/sonar-web/src/main/js/widgets/issue-filter/templates/widget-issue-filter-resolutions.hbs6
-rw-r--r--server/sonar-web/src/main/js/widgets/issue-filter/templates/widget-issue-filter-severities.hbs8
-rw-r--r--server/sonar-web/src/main/js/widgets/issue-filter/templates/widget-issue-filter-statuses.hbs4
-rw-r--r--server/sonar-web/src/main/js/widgets/issue-filter/templates/widget-issue-filter.hbs2
-rw-r--r--server/sonar-web/src/main/js/widgets/issue-filter/widget.js38
-rw-r--r--server/sonar-web/src/test/js/global-issue-filter-widget.js194
-rw-r--r--server/sonar-web/src/test/js/project-issue-filter-widget.js14
-rw-r--r--server/sonar-web/src/test/json/global-issues-filter-widget/messages.json6
-rw-r--r--server/sonar-web/src/test/json/global-issues-filter-widget/unresolved-issues-by-date-debt.json33
-rw-r--r--server/sonar-web/src/test/json/global-issues-filter-widget/unresolved-issues-by-severity-debt.json33
-rw-r--r--sonar-core/src/main/resources/org/sonar/l10n/core.properties6
18 files changed, 305 insertions, 71 deletions
diff --git a/server/sonar-server/src/main/java/org/sonar/server/dashboard/widget/IssueFilterWidget.java b/server/sonar-server/src/main/java/org/sonar/server/dashboard/widget/IssueFilterWidget.java
index d3bc92a44a5..f8042223c79 100644
--- a/server/sonar-server/src/main/java/org/sonar/server/dashboard/widget/IssueFilterWidget.java
+++ b/server/sonar-server/src/main/java/org/sonar/server/dashboard/widget/IssueFilterWidget.java
@@ -34,13 +34,15 @@ import static org.sonar.api.web.WidgetScope.GLOBAL;
@WidgetProperty(key = IssueFilterWidget.DISTRIBUTION_AXIS_PROPERTY, type = WidgetPropertyType.SINGLE_SELECT_LIST, defaultValue = "severities",
options = {"severities", "resolutions", "statuses", "rules", "tags", "projectUuids", "assignees", "reporters",
"authors", "languages", "actionPlans", "createdAt"}),
- @WidgetProperty(key = IssueFilterWidget.DISPLAY_FILTER_DESCRIPTION, type = WidgetPropertyType.BOOLEAN, defaultValue = "false")
+ @WidgetProperty(key = IssueFilterWidget.DISPLAY_FILTER_DESCRIPTION, type = WidgetPropertyType.BOOLEAN, defaultValue = "false"),
+ @WidgetProperty(key = IssueFilterWidget.DISPLAY_MODE, type = WidgetPropertyType.SINGLE_SELECT_LIST, defaultValue = "count", options = {"count", "debt"})
})
public class IssueFilterWidget extends CoreWidget {
public static final String FILTER_PROPERTY = "filter";
public static final String DISTRIBUTION_AXIS_PROPERTY = "distributionAxis";
public static final String DISPLAY_FILTER_DESCRIPTION = "displayFilterDescription";
+ public static final String DISPLAY_MODE = "displayMode";
public static final String ID = "issue_filter";
public IssueFilterWidget() {
diff --git a/server/sonar-server/src/main/java/org/sonar/server/dashboard/widget/ProjectIssueFilterWidget.java b/server/sonar-server/src/main/java/org/sonar/server/dashboard/widget/ProjectIssueFilterWidget.java
index 3f4f1ff9275..6ac66e77d0a 100644
--- a/server/sonar-server/src/main/java/org/sonar/server/dashboard/widget/ProjectIssueFilterWidget.java
+++ b/server/sonar-server/src/main/java/org/sonar/server/dashboard/widget/ProjectIssueFilterWidget.java
@@ -34,13 +34,15 @@ import static org.sonar.api.web.WidgetScope.PROJECT;
@WidgetProperty(key = ProjectIssueFilterWidget.DISTRIBUTION_AXIS_PROPERTY, type = WidgetPropertyType.SINGLE_SELECT_LIST, defaultValue = "severities",
options = {"severities", "resolutions", "statuses", "rules", "tags", "assignees", "reporters", "authors",
"languages", "actionPlans", "createdAt"}),
- @WidgetProperty(key = ProjectIssueFilterWidget.DISPLAY_FILTER_DESCRIPTION, type = WidgetPropertyType.BOOLEAN, defaultValue = "false")
+ @WidgetProperty(key = ProjectIssueFilterWidget.DISPLAY_FILTER_DESCRIPTION, type = WidgetPropertyType.BOOLEAN, defaultValue = "false"),
+ @WidgetProperty(key = ProjectIssueFilterWidget.DISPLAY_MODE, type = WidgetPropertyType.SINGLE_SELECT_LIST, defaultValue = "count", options = {"count", "debt"})
})
public class ProjectIssueFilterWidget extends CoreWidget {
public static final String FILTER_PROPERTY = "filter";
public static final String DISTRIBUTION_AXIS_PROPERTY = "distributionAxis";
public static final String DISPLAY_FILTER_DESCRIPTION = "displayFilterDescription";
+ public static final String DISPLAY_MODE = "displayMode";
public static final String ID = "project_issue_filter";
public ProjectIssueFilterWidget() {
diff --git a/server/sonar-server/src/main/resources/org/sonar/server/dashboard/widget/issue_filter.html.erb b/server/sonar-server/src/main/resources/org/sonar/server/dashboard/widget/issue_filter.html.erb
index f70e79ec85b..5523fbfd11e 100644
--- a/server/sonar-server/src/main/resources/org/sonar/server/dashboard/widget/issue_filter.html.erb
+++ b/server/sonar-server/src/main/resources/org/sonar/server/dashboard/widget/issue_filter.html.erb
@@ -3,6 +3,7 @@
filter_id = widget_properties['filter']
filter = Internal.issues.findIssueFilterById(filter_id.to_i)
distribution_axis = widget_properties['distributionAxis']
+ display_mode = widget_properties['displayMode']
is_enough_permissions = filter.shared || (current_user && filter.userLogin == current_user.login)
%>
@@ -32,7 +33,8 @@
new IssueFilter({
el: '#<%= container_id -%>',
query: query,
- distributionAxis: '<%= distribution_axis -%>'
+ distributionAxis: '<%= distribution_axis -%>',
+ displayMode: '<%= display_mode -%>'
});
});
});
diff --git a/server/sonar-server/src/main/resources/org/sonar/server/dashboard/widget/project_issue_filter.html.erb b/server/sonar-server/src/main/resources/org/sonar/server/dashboard/widget/project_issue_filter.html.erb
index 16edb8192d1..0815b95e88e 100644
--- a/server/sonar-server/src/main/resources/org/sonar/server/dashboard/widget/project_issue_filter.html.erb
+++ b/server/sonar-server/src/main/resources/org/sonar/server/dashboard/widget/project_issue_filter.html.erb
@@ -3,6 +3,7 @@
filter_id = widget_properties['filter']
filter = Internal.issues.findIssueFilterById(filter_id.to_i)
distribution_axis = widget_properties['distributionAxis']
+ display_mode = widget_properties['displayMode']
is_enough_permissions = filter.shared || (current_user && filter.userLogin == current_user.login)
if @dashboard_configuration.selected_period?
@@ -39,6 +40,7 @@
el: '#<%= container_id -%>',
query: query,
distributionAxis: '<%= distribution_axis -%>',
+ displayMode: '<%= display_mode -%>',
<% if period_date %>
periodDate: '<%= period_date -%>',
<% end %>
diff --git a/server/sonar-web/src/main/js/widgets/issue-filter/templates/_widget-issue-filter-total.hbs b/server/sonar-web/src/main/js/widgets/issue-filter/templates/_widget-issue-filter-total.hbs
index 03fb4134f4a..376ea5611de 100644
--- a/server/sonar-web/src/main/js/widgets/issue-filter/templates/_widget-issue-filter-total.hbs
+++ b/server/sonar-web/src/main/js/widgets/issue-filter/templates/_widget-issue-filter-total.hbs
@@ -1,8 +1,10 @@
<tr>
<td>
- <a href="{{issueFilterTotalLink parsedQuery}}"><strong>{{t 'total'}}</strong></a>
+ <a href="{{issueFilterTotalLink parsedQuery displayMode}}"><strong>{{t 'total'}}</strong></a>
+ </td>
+ <td class="text-right nowrap">
+ <strong>{{#notNull periodDate}}+{{/notNull}}{{issueFilterValue total displayMode}}</strong>
</td>
- <td class="text-right"><strong>{{#notNull periodDate}}+{{/notNull}}{{numberShort total}}</strong></td>
<td class="barchart">
<div class="barchart" style="width: 100%;">
<div style="width: 100%;"></div>
diff --git a/server/sonar-web/src/main/js/widgets/issue-filter/templates/widget-issue-filter-action-plans.hbs b/server/sonar-web/src/main/js/widgets/issue-filter/templates/widget-issue-filter-action-plans.hbs
index 07c9b17f40c..b5c93283194 100644
--- a/server/sonar-web/src/main/js/widgets/issue-filter/templates/widget-issue-filter-action-plans.hbs
+++ b/server/sonar-web/src/main/js/widgets/issue-filter/templates/widget-issue-filter-action-plans.hbs
@@ -4,13 +4,13 @@
<tr>
<td>
{{#eq val ''}}
- <a href="{{issueFilterItemLink ../../parsedQuery 'planned' 'false'}}">{{t 'issue.unplanned'}}</a>
+ <a href="{{issueFilterItemLink ../../parsedQuery 'planned' 'false' ../../displayMode}}">{{t 'issue.unplanned'}}</a>
{{else}}
- <a href="{{issueFilterItemLink ../../parsedQuery 'actionPlans' val}}">{{default label val}}</a>
+ <a href="{{issueFilterItemLink ../../parsedQuery 'actionPlans' val ../../displayMode}}">{{default label val}}</a>
{{/eq}}
</td>
<td class="text-right nowrap">
- {{#notNull ../periodDate}}+{{/notNull}}{{numberShort count}}
+ {{#notNull ../periodDate}}+{{/notNull}}{{issueFilterValue count ../displayMode}}
</td>
<td class="barchart">
<div class="barchart" style="width: 100%;">
diff --git a/server/sonar-web/src/main/js/widgets/issue-filter/templates/widget-issue-filter-assignees.hbs b/server/sonar-web/src/main/js/widgets/issue-filter/templates/widget-issue-filter-assignees.hbs
index 494104f3ee9..aef7f8fc9f6 100644
--- a/server/sonar-web/src/main/js/widgets/issue-filter/templates/widget-issue-filter-assignees.hbs
+++ b/server/sonar-web/src/main/js/widgets/issue-filter/templates/widget-issue-filter-assignees.hbs
@@ -4,13 +4,13 @@
<tr>
<td>
{{#eq val ''}}
- <a href="{{issueFilterItemLink ../../parsedQuery 'assigned' 'false'}}">{{t 'unassigned'}}</a>
+ <a href="{{issueFilterItemLink ../../parsedQuery 'assigned' 'false' ../../displayMode}}">{{t 'unassigned'}}</a>
{{else}}
- <a href="{{issueFilterItemLink ../../parsedQuery 'assignees' val}}">{{default label val}}</a>
+ <a href="{{issueFilterItemLink ../../parsedQuery 'assignees' val ../../displayMode}}">{{default label val}}</a>
{{/eq}}
</td>
<td class="text-right nowrap">
- {{#notNull ../periodDate}}+{{/notNull}}{{numberShort count}}
+ {{#notNull ../periodDate}}+{{/notNull}}{{issueFilterValue count ../displayMode}}
</td>
<td class="barchart">
<div class="barchart" style="width: 100%;">
diff --git a/server/sonar-web/src/main/js/widgets/issue-filter/templates/widget-issue-filter-resolutions.hbs b/server/sonar-web/src/main/js/widgets/issue-filter/templates/widget-issue-filter-resolutions.hbs
index 50827ba41bb..5d8d6c2554d 100644
--- a/server/sonar-web/src/main/js/widgets/issue-filter/templates/widget-issue-filter-resolutions.hbs
+++ b/server/sonar-web/src/main/js/widgets/issue-filter/templates/widget-issue-filter-resolutions.hbs
@@ -4,13 +4,13 @@
<tr>
<td>
{{#eq val ''}}
- <a href="{{issueFilterItemLink ../../parsedQuery 'resolved' 'false'}}">{{t 'unresolved'}}</a>
+ <a href="{{issueFilterItemLink ../../parsedQuery 'resolved' 'false' ../../displayMode}}">{{t 'unresolved'}}</a>
{{else}}
- <a href="{{issueFilterItemLink ../../parsedQuery 'resolutions' val}}">{{t 'issue.resolution' val}}</a>
+ <a href="{{issueFilterItemLink ../../parsedQuery 'resolutions' val ../../displayMode}}">{{t 'issue.resolution' val}}</a>
{{/eq}}
</td>
<td class="text-right nowrap">
- {{#notNull ../periodDate}}+{{/notNull}}{{numberShort count}}
+ {{#notNull ../periodDate}}+{{/notNull}}{{issueFilterValue count ../displayMode}}
</td>
<td class="barchart">
<div class="barchart" style="width: 100%;">
diff --git a/server/sonar-web/src/main/js/widgets/issue-filter/templates/widget-issue-filter-severities.hbs b/server/sonar-web/src/main/js/widgets/issue-filter/templates/widget-issue-filter-severities.hbs
index 3ca50c03da5..a292b57e2b9 100644
--- a/server/sonar-web/src/main/js/widgets/issue-filter/templates/widget-issue-filter-severities.hbs
+++ b/server/sonar-web/src/main/js/widgets/issue-filter/templates/widget-issue-filter-severities.hbs
@@ -1,18 +1,18 @@
<table class="data zebra">
<tr>
<td>
- <a href="{{issueFilterTotalLink parsedQuery}}"><strong>{{t 'total'}}</strong></a>
+ <a href="{{issueFilterTotalLink parsedQuery displayMode}}"><strong>{{t 'total'}}</strong></a>
</td>
- <td class="text-right"><strong>{{#notNull periodDate}}+{{/notNull}}{{numberShort total}}</strong></td>
+ <td class="text-right"><strong>{{#notNull periodDate}}+{{/notNull}}{{issueFilterValue total displayMode}}</strong></td>
</tr>
{{#each items}}
<tr>
<td>
{{severityIcon val}}
- <a href="{{issueFilterItemLink ../parsedQuery ../property val}}">{{t 'severity' val}}</a>
+ <a href="{{issueFilterItemLink ../parsedQuery ../property val ../displayMode}}">{{t 'severity' val}}</a>
</td>
<td class="text-right nowrap">
- {{#notNull ../periodDate}}+{{/notNull}}{{numberShort count}}
+ {{#notNull ../periodDate}}+{{/notNull}}{{issueFilterValue count ../displayMode}}
</td>
</tr>
{{/each}}
diff --git a/server/sonar-web/src/main/js/widgets/issue-filter/templates/widget-issue-filter-statuses.hbs b/server/sonar-web/src/main/js/widgets/issue-filter/templates/widget-issue-filter-statuses.hbs
index 70d5a57c765..a661cd7ff3d 100644
--- a/server/sonar-web/src/main/js/widgets/issue-filter/templates/widget-issue-filter-statuses.hbs
+++ b/server/sonar-web/src/main/js/widgets/issue-filter/templates/widget-issue-filter-statuses.hbs
@@ -4,10 +4,10 @@
<tr>
<td>
{{statusIcon val}}
- <a href="{{issueFilterItemLink ../parsedQuery ../property val}}">{{t 'issue.status' val}}</a>
+ <a href="{{issueFilterItemLink ../parsedQuery ../property val ../displayMode}}">{{t 'issue.status' val}}</a>
</td>
<td class="text-right nowrap">
- {{#notNull ../periodDate}}+{{/notNull}}{{numberShort count}}
+ {{#notNull ../periodDate}}+{{/notNull}}{{issueFilterValue count ../displayMode}}
</td>
<td class="barchart">
<div class="barchart" style="width: 100%;">
diff --git a/server/sonar-web/src/main/js/widgets/issue-filter/templates/widget-issue-filter.hbs b/server/sonar-web/src/main/js/widgets/issue-filter/templates/widget-issue-filter.hbs
index dc78bba0232..b92cf91f995 100644
--- a/server/sonar-web/src/main/js/widgets/issue-filter/templates/widget-issue-filter.hbs
+++ b/server/sonar-web/src/main/js/widgets/issue-filter/templates/widget-issue-filter.hbs
@@ -6,7 +6,7 @@
<a href="{{searchLink}}">{{default label val}}</a>
</td>
<td class="text-right nowrap">
- {{#notNull ../periodDate}}+{{/notNull}}{{numberShort count}}
+ {{#notNull ../periodDate}}+{{/notNull}}{{issueFilterValue count ../displayMode}}
</td>
<td class="barchart">
<div class="barchart" style="width: 100%;">
diff --git a/server/sonar-web/src/main/js/widgets/issue-filter/widget.js b/server/sonar-web/src/main/js/widgets/issue-filter/widget.js
index 2fb96c7d2e7..97c72ca75a1 100644
--- a/server/sonar-web/src/main/js/widgets/issue-filter/widget.js
+++ b/server/sonar-web/src/main/js/widgets/issue-filter/widget.js
@@ -32,10 +32,13 @@ define(['./templates'], function () {
defaultLabel = function (item) {
return item.val;
},
- defaultLink = function (item, property, query) {
+ defaultLink = function (item, property, query, index, items, mode) {
var criterion = {};
criterion[property] = item.val;
var r = _.extend({}, query, criterion);
+ if (mode === 'debt') {
+ r.facetMode = 'debt';
+ }
if (r.componentKey != null) {
return baseUrl + '/component_issues/index?id=' + encodeURIComponent(r.componentKey) +
'#' + getQuery(_.omit(r, 'componentKey'));
@@ -164,7 +167,7 @@ define(['./templates'], function () {
isSameDay = ending.diff(beginning, 'days') <= 1;
return beginning.format('LL') + (isSameDay ? '' : (' – ' + ending.format('LL')));
},
- link: function (item, property, query, index, items) {
+ link: function (item, property, query, index, items, mode) {
var createdAfter = moment(item.val),
endDate = query.createdBefore != null ? moment(query.createdBefore) : moment(),
createdBefore = index < items.length - 1 ? moment(items[index + 1].val).subtract(1, 'days') : endDate,
@@ -176,6 +179,9 @@ define(['./templates'], function () {
createdAfter: createdAfter.format('YYYY-MM-DD'),
createdBefore: createdBefore.format('YYYY-MM-DD')
});
+ if (mode === 'debt') {
+ r.facetMode = 'debt';
+ }
if (r.componentKey != null) {
return baseUrl + '/component_issues/index?id=' + encodeURIComponent(r.componentKey) +
'#' + getQuery(_.omit(r, 'componentKey'));
@@ -195,10 +201,13 @@ define(['./templates'], function () {
return route.join(separator);
}
- Handlebars.registerHelper('issueFilterItemLink', function (query, property, value) {
+ Handlebars.registerHelper('issueFilterItemLink', function (query, property, value, mode) {
var criterion = {};
criterion[property] = value;
var r = _.extend({}, query, criterion);
+ if (mode === 'debt') {
+ r.facetMode = 'debt';
+ }
if (r.componentKey != null) {
return baseUrl + '/component_issues/index?id=' + encodeURIComponent(r.componentKey) +
'#' + getQuery(_.omit(r, 'componentKey'));
@@ -207,8 +216,11 @@ define(['./templates'], function () {
}
});
- Handlebars.registerHelper('issueFilterTotalLink', function (query) {
+ Handlebars.registerHelper('issueFilterTotalLink', function (query, mode) {
var r = _.extend({}, query);
+ if (mode === 'debt') {
+ r.facetMode = 'debt';
+ }
if (r.componentKey != null) {
return baseUrl + '/component_issues/index?id=' + encodeURIComponent(r.componentKey) +
'#' + getQuery(_.omit(r, 'componentKey'));
@@ -217,6 +229,11 @@ define(['./templates'], function () {
}
});
+ Handlebars.registerHelper('issueFilterValue', function (value, mode) {
+ var formatter = mode === 'debt' ? 'SHORT_WORK_DUR' : 'SHORT_INT';
+ return window.formatMeasure(value, formatter);
+ });
+
return Marionette.ItemView.extend({
getTemplate: function () {
@@ -284,9 +301,10 @@ define(['./templates'], function () {
withLink: function (items) {
var link = this.conf != null && this.conf.link != null ? this.conf.link : defaultLink,
property = this.options.distributionAxis,
+ mode = this.options.displayMode,
query = this.model.get('parsedQuery');
return items.map(function (item, index) {
- return _.extend(item, { searchLink: link(item, property, query, index, items) });
+ return _.extend(item, { searchLink: link(item, property, query, index, items, mode) });
});
},
@@ -301,10 +319,12 @@ define(['./templates'], function () {
requestIssues: function () {
var that = this,
+ facetMode = this.options.displayMode,
url = baseUrl + '/api/issues/search',
options = _.extend({}, this.query, {
ps: 1,
- facets: this.options.distributionAxis
+ facets: this.options.distributionAxis,
+ facetMode: facetMode
});
if (this.options.componentUuid != null) {
_.extend(options, { componentUuids: this.options.componentUuid });
@@ -321,10 +341,14 @@ define(['./templates'], function () {
items: items,
maxResultsReached: items.length >= FACET_LIMIT,
maxResults: items.length,
- total: r.total
+ total: facetMode === 'debt' ? r.debtTotal : r.total
});
}
});
+ },
+
+ serializeData: function () {
+ return _.extend(this._super(), { displayMode: this.options.displayMode });
}
});
diff --git a/server/sonar-web/src/test/js/global-issue-filter-widget.js b/server/sonar-web/src/test/js/global-issue-filter-widget.js
index 5cf3863ccdb..eedd5f275fc 100644
--- a/server/sonar-web/src/test/js/global-issue-filter-widget.js
+++ b/server/sonar-web/src/test/js/global-issue-filter-widget.js
@@ -61,12 +61,12 @@ casper.test.begin(testName('Unresolved Issues By Severity'), 13, function (test)
test.assertElementCount('tr', 6);
// check order and values
- test.assertSelectorContains('tr:nth-child(1)', '6,851');
+ test.assertSelectorContains('tr:nth-child(1)', '6.9k');
test.assertSelectorContains('tr:nth-child(2)', '1');
test.assertSelectorContains('tr:nth-child(3)', '105');
- test.assertSelectorContains('tr:nth-child(4)', '5,027');
+ test.assertSelectorContains('tr:nth-child(4)', '5k');
test.assertSelectorContains('tr:nth-child(5)', '540');
- test.assertSelectorContains('tr:nth-child(6)', '1,178');
+ test.assertSelectorContains('tr:nth-child(6)', '1.2k');
// check links
test.assertExists('tr:nth-child(1) a[href="/issues/search#resolved=false"]');
@@ -120,10 +120,10 @@ casper.test.begin(testName('Red Issues By Severity'), 9, function (test) {
test.assertElementCount('tr', 4);
// check order and values
- test.assertSelectorContains('tr:nth-child(1)', '6,851');
+ test.assertSelectorContains('tr:nth-child(1)', '6.9k');
test.assertSelectorContains('tr:nth-child(2)', '1');
test.assertSelectorContains('tr:nth-child(3)', '105');
- test.assertSelectorContains('tr:nth-child(4)', '5,027');
+ test.assertSelectorContains('tr:nth-child(4)', '5k');
// check links
test.assertExists('tr:nth-child(1) a[href="/issues/search#resolved=false|severities=BLOCKER%2CCRITICAL%2CMAJOR"]');
@@ -174,12 +174,12 @@ casper.test.begin(testName('All Issues By Status'), 9, function (test) {
test.assertElementCount('tr', 6);
// check order and values
- test.assertSelectorContains('tr:nth-child(1)', '71.6k');
+ test.assertSelectorContains('tr:nth-child(1)', '72k');
test.assertSelectorContains('tr:nth-child(2)', '238');
test.assertSelectorContains('tr:nth-child(3)', '4');
- test.assertSelectorContains('tr:nth-child(4)', '6,609');
- test.assertSelectorContains('tr:nth-child(5)', '1,307');
- test.assertSelectorContains('tr:nth-child(6)', '63.4k');
+ test.assertSelectorContains('tr:nth-child(4)', '6.6k');
+ test.assertSelectorContains('tr:nth-child(5)', '1.3k');
+ test.assertSelectorContains('tr:nth-child(6)', '63k');
// check links
test.assertExists('tr:nth-child(1) a[href="/issues/search#"]');
@@ -229,10 +229,10 @@ casper.test.begin(testName('Unresolved Issues By Status'), 9, function (test) {
test.assertElementCount('tr', 4);
// check order and values
- test.assertSelectorContains('tr:nth-child(1)', '71.6k');
+ test.assertSelectorContains('tr:nth-child(1)', '72k');
test.assertSelectorContains('tr:nth-child(2)', '238');
test.assertSelectorContains('tr:nth-child(3)', '4');
- test.assertSelectorContains('tr:nth-child(4)', '6,609');
+ test.assertSelectorContains('tr:nth-child(4)', '6.6k');
// check links
test.assertExists('tr:nth-child(1) a[href="/issues/search#resolved=false"]');
@@ -283,12 +283,12 @@ casper.test.begin(testName('All Issues By Resolution'), 10, function (test) {
test.assertElementCount('tr', 6);
// check order and values
- test.assertSelectorContains('tr:nth-child(1)', '71.6k');
- test.assertSelectorContains('tr:nth-child(2)', '6,851');
+ test.assertSelectorContains('tr:nth-child(1)', '72k');
+ test.assertSelectorContains('tr:nth-child(2)', '6.9k');
test.assertSelectorContains('tr:nth-child(3)', '752');
test.assertSelectorContains('tr:nth-child(4)', '550');
- test.assertSelectorContains('tr:nth-child(5)', '47.1k');
- test.assertSelectorContains('tr:nth-child(6)', '16.3k');
+ test.assertSelectorContains('tr:nth-child(5)', '47k');
+ test.assertSelectorContains('tr:nth-child(6)', '16k');
// check links
test.assertExists('tr:nth-child(1) a[href="/issues/search#"]');
@@ -339,8 +339,8 @@ casper.test.begin(testName('Unresolved Issues By Resolution'), 5, function (test
test.assertElementCount('tr', 2);
// check order and values
- test.assertSelectorContains('tr:nth-child(1)', '6,851');
- test.assertSelectorContains('tr:nth-child(2)', '6,851');
+ test.assertSelectorContains('tr:nth-child(1)', '6.9k');
+ test.assertSelectorContains('tr:nth-child(2)', '6.9k');
// check links
test.assertExists('tr:nth-child(1) a[href="/issues/search#resolved=false"]');
@@ -390,7 +390,7 @@ casper.test.begin(testName('Unresolved Issues By Rule'), 15, function (test) {
test.assertElementCount('tr', 16);
// check order and values
- test.assertSelectorContains('tr:nth-child(1)', '6,851');
+ test.assertSelectorContains('tr:nth-child(1)', '6.9k');
test.assertSelectorContains('tr:nth-child(2)', '879');
test.assertSelectorContains('tr:nth-child(3)', '571');
test.assertSelectorContains('tr:nth-child(15)', '113');
@@ -453,8 +453,8 @@ casper.test.begin(testName('Unresolved Issues By Project'), 15, function (test)
test.assertElementCount('tr', 5);
// check order and values
- test.assertSelectorContains('tr:nth-child(1)', '2,598');
- test.assertSelectorContains('tr:nth-child(2)', '1,766');
+ test.assertSelectorContains('tr:nth-child(1)', '2.6k');
+ test.assertSelectorContains('tr:nth-child(2)', '1.8k');
test.assertSelectorContains('tr:nth-child(3)', '442');
test.assertSelectorContains('tr:nth-child(4)', '283');
test.assertSelectorContains('tr:nth-child(5)', '107');
@@ -516,8 +516,8 @@ casper.test.begin(testName('Unresolved Issues By Assignee'), 15, function (test)
test.assertElementCount('tr', 5);
// check order and values
- test.assertSelectorContains('tr:nth-child(1)', '6,851');
- test.assertSelectorContains('tr:nth-child(2)', '4,134');
+ test.assertSelectorContains('tr:nth-child(1)', '6.9k');
+ test.assertSelectorContains('tr:nth-child(2)', '4.1k');
test.assertSelectorContains('tr:nth-child(3)', '698');
test.assertSelectorContains('tr:nth-child(4)', '504');
test.assertSelectorContains('tr:nth-child(5)', '426');
@@ -579,8 +579,8 @@ casper.test.begin(testName('Unresolved Unassigned Issues By Assignee'), 6, funct
test.assertElementCount('tr', 2);
// check order and values
- test.assertSelectorContains('tr:nth-child(1)', '4,134');
- test.assertSelectorContains('tr:nth-child(2)', '4,134');
+ test.assertSelectorContains('tr:nth-child(1)', '4.1k');
+ test.assertSelectorContains('tr:nth-child(2)', '4.1k');
// check links
test.assertExists('tr:nth-child(1) a[href="/issues/search#resolved=false|assigned=false"]');
@@ -633,7 +633,7 @@ casper.test.begin(testName('Unresolved Issues By Reporter'), 12, function (test)
test.assertElementCount('tr', 4);
// check order and values
- test.assertSelectorContains('tr:nth-child(1)', '6,851');
+ test.assertSelectorContains('tr:nth-child(1)', '6.9k');
test.assertSelectorContains('tr:nth-child(2)', '698');
test.assertSelectorContains('tr:nth-child(3)', '504');
test.assertSelectorContains('tr:nth-child(4)', '426');
@@ -693,8 +693,8 @@ casper.test.begin(testName('Unresolved Issues By Language'), 15, function (test)
test.assertElementCount('tr', 5);
// check order and values
- test.assertSelectorContains('tr:nth-child(1)', '6,851');
- test.assertSelectorContains('tr:nth-child(2)', '6,336');
+ test.assertSelectorContains('tr:nth-child(1)', '6.9k');
+ test.assertSelectorContains('tr:nth-child(2)', '6.3k');
test.assertSelectorContains('tr:nth-child(3)', '444');
test.assertSelectorContains('tr:nth-child(4)', '22');
test.assertSelectorContains('tr:nth-child(5)', '15');
@@ -756,8 +756,8 @@ casper.test.begin(testName('Unresolved Issues By Action Plan'), 15, function (te
test.assertElementCount('tr', 5);
// check order and values
- test.assertSelectorContains('tr:nth-child(1)', '6,851');
- test.assertSelectorContains('tr:nth-child(2)', '5,877');
+ test.assertSelectorContains('tr:nth-child(1)', '6.9k');
+ test.assertSelectorContains('tr:nth-child(2)', '5.9k');
test.assertSelectorContains('tr:nth-child(3)', '532');
test.assertSelectorContains('tr:nth-child(4)', '56');
test.assertSelectorContains('tr:nth-child(5)', '52');
@@ -819,8 +819,8 @@ casper.test.begin(testName('Unresolved Unplanned Issues By Action Plan'), 6, fun
test.assertElementCount('tr', 2);
// check order and values
- test.assertSelectorContains('tr:nth-child(1)', '5,877');
- test.assertSelectorContains('tr:nth-child(2)', '5,877');
+ test.assertSelectorContains('tr:nth-child(1)', '5.9k');
+ test.assertSelectorContains('tr:nth-child(2)', '5.9k');
// check links
test.assertExists('tr:nth-child(1) a[href="/issues/search#resolved=false|planned=false"]');
@@ -873,10 +873,10 @@ casper.test.begin(testName('Unresolved Issues By Date'), 18, function (test) {
test.assertElementCount('tr', 6);
// check order and values
- test.assertSelectorContains('tr:nth-child(1)', '6,851');
- test.assertSelectorContains('tr:nth-child(2)', '1,724');
- test.assertSelectorContains('tr:nth-child(3)', '3,729');
- test.assertSelectorContains('tr:nth-child(4)', '1,262');
+ test.assertSelectorContains('tr:nth-child(1)', '6.9k');
+ test.assertSelectorContains('tr:nth-child(2)', '1.7k');
+ test.assertSelectorContains('tr:nth-child(3)', '3.7k');
+ test.assertSelectorContains('tr:nth-child(4)', '1.3k');
test.assertSelectorContains('tr:nth-child(5)', '64');
test.assertSelectorContains('tr:nth-child(6)', '72');
@@ -941,7 +941,7 @@ casper.test.begin(testName('Unresolved Issues on a Limited Period By Date'), 12,
test.assertElementCount('tr', 4);
// check order and values
- test.assertSelectorContains('tr:nth-child(1)', '6,851');
+ test.assertSelectorContains('tr:nth-child(1)', '6.9k');
test.assertSelectorContains('tr:nth-child(2)', '47');
test.assertSelectorContains('tr:nth-child(3)', '48');
test.assertSelectorContains('tr:nth-child(4)', '49');
@@ -966,3 +966,125 @@ casper.test.begin(testName('Unresolved Issues on a Limited Period By Date'), 12,
test.done();
});
});
+
+
+casper.test.begin(testName('Unresolved Issues By Severity Displaying Debt'), 13, function (test) {
+ casper
+ .start(lib.buildUrl('base'), function () {
+ lib.setDefaultViewport();
+
+ lib.mockRequestFromFile('/api/l10n/index', 'messages.json');
+ lib.mockRequestFromFile('/api/issues/search', 'unresolved-issues-by-severity-debt.json',
+ { data: { resolved: 'false' } });
+ })
+
+ .then(function () {
+ casper.evaluate(function () {
+ require(['widgets/issue-filter/widget'], function (IssueFilter) {
+ window.requestMessages().done(function () {
+ new IssueFilter({
+ el: '#content',
+ query: 'resolved=false',
+ distributionAxis: 'severities',
+ displayMode: 'debt'
+ });
+ });
+ });
+ });
+ })
+
+ .then(function () {
+ casper.waitForSelector('#content > table');
+ })
+
+ .then(function () {
+ // check count
+ test.assertElementCount('tr', 6);
+
+ // check order and values
+ test.assertSelectorContains('tr:nth-child(1)', '~ 14d');
+ test.assertSelectorContains('tr:nth-child(2)', '1min');
+ test.assertSelectorContains('tr:nth-child(3)', '~ 1h');
+ test.assertSelectorContains('tr:nth-child(4)', '~ 10d');
+ test.assertSelectorContains('tr:nth-child(5)', '~ 1d');
+ test.assertSelectorContains('tr:nth-child(6)', '~ 2d');
+
+ // check links
+ test.assertExists('tr:nth-child(1) a[href="/issues/search#resolved=false|facetMode=debt"]');
+ test.assertExists('tr:nth-child(2) a[href="/issues/search#resolved=false|severities=BLOCKER|facetMode=debt"]');
+ test.assertExists('tr:nth-child(3) a[href="/issues/search#resolved=false|severities=CRITICAL|facetMode=debt"]');
+ test.assertExists('tr:nth-child(4) a[href="/issues/search#resolved=false|severities=MAJOR|facetMode=debt"]');
+ test.assertExists('tr:nth-child(5) a[href="/issues/search#resolved=false|severities=MINOR|facetMode=debt"]');
+ test.assertExists('tr:nth-child(6) a[href="/issues/search#resolved=false|severities=INFO|facetMode=debt"]');
+ })
+
+ .then(function () {
+ lib.sendCoverage();
+ })
+
+ .run(function () {
+ test.done();
+ });
+});
+
+
+casper.test.begin(testName('Unresolved Issues By Date Displaying Debt'), 13, function (test) {
+ casper
+ .start(lib.buildUrl('base'), function () {
+ lib.setDefaultViewport();
+
+ lib.mockRequestFromFile('/api/l10n/index', 'messages.json');
+ lib.mockRequestFromFile('/api/issues/search', 'unresolved-issues-by-date-debt.json',
+ { data: { resolved: 'false' } });
+ })
+
+ .then(function () {
+ casper.evaluate(function () {
+ require(['widgets/issue-filter/widget'], function (IssueFilter) {
+ window.requestMessages().done(function () {
+ new IssueFilter({
+ el: '#content',
+ query: 'resolved=false',
+ distributionAxis: 'createdAt',
+ displayMode: 'debt'
+ });
+ });
+ });
+ });
+ })
+
+ .then(function () {
+ casper.waitForSelector('#content > table');
+ })
+
+ .then(function () {
+ // check count
+ test.assertElementCount('tr', 6);
+
+ // check order and values
+ lib.capture();
+ test.assertSelectorContains('tr:nth-child(1)', '~ 14d');
+ test.assertSelectorContains('tr:nth-child(2)', '1min');
+ test.assertSelectorContains('tr:nth-child(3)', '~ 1h');
+ test.assertSelectorContains('tr:nth-child(4)', '~ 1d');
+ test.assertSelectorContains('tr:nth-child(5)', '~ 2d');
+ test.assertSelectorContains('tr:nth-child(6)', '~ 10d');
+
+ // check links
+ test.assertExists('tr:nth-child(1) a[href="/issues/search#resolved=false|facetMode=debt"]');
+ // do not check createdBefore value, because it is set dynamically to *now*
+ test.assertExists('tr:nth-child(2) a[href^="/issues/search#resolved=false|createdAfter=2015-01-01|createdBefore="]');
+ test.assertExists('tr:nth-child(3) a[href="/issues/search#resolved=false|createdAfter=2014-01-01|createdBefore=2014-12-31|facetMode=debt"]');
+ test.assertExists('tr:nth-child(4) a[href="/issues/search#resolved=false|createdAfter=2013-01-01|createdBefore=2013-12-31|facetMode=debt"]');
+ test.assertExists('tr:nth-child(5) a[href="/issues/search#resolved=false|createdAfter=2012-01-01|createdBefore=2012-12-31|facetMode=debt"]');
+ test.assertExists('tr:nth-child(6) a[href="/issues/search#resolved=false|createdAfter=2011-01-01|createdBefore=2011-12-31|facetMode=debt"]');
+ })
+
+ .then(function () {
+ lib.sendCoverage();
+ })
+
+ .run(function () {
+ test.done();
+ });
+});
diff --git a/server/sonar-web/src/test/js/project-issue-filter-widget.js b/server/sonar-web/src/test/js/project-issue-filter-widget.js
index 8ec0127a1ad..2637edad29b 100644
--- a/server/sonar-web/src/test/js/project-issue-filter-widget.js
+++ b/server/sonar-web/src/test/js/project-issue-filter-widget.js
@@ -63,12 +63,12 @@ casper.test.begin(testName('Unresolved Issues By Severity'), 13, function (test)
test.assertElementCount('tr', 6);
// check order and values
- test.assertSelectorContains('tr:nth-child(1)', '6,851');
+ test.assertSelectorContains('tr:nth-child(1)', '6.9k');
test.assertSelectorContains('tr:nth-child(2)', '1');
test.assertSelectorContains('tr:nth-child(3)', '105');
- test.assertSelectorContains('tr:nth-child(4)', '5,027');
+ test.assertSelectorContains('tr:nth-child(4)', '5k');
test.assertSelectorContains('tr:nth-child(5)', '540');
- test.assertSelectorContains('tr:nth-child(6)', '1,178');
+ test.assertSelectorContains('tr:nth-child(6)', '1.2k');
// check links
test.assertExists('tr:nth-child(1) a[href="/component_issues/index?id=org.codehaus.sonar%3Asonar#resolved=false"]');
@@ -124,10 +124,10 @@ casper.test.begin(testName('Unresolved Issues By Date'), 18, function (test) {
test.assertElementCount('tr', 6);
// check order and values
- test.assertSelectorContains('tr:nth-child(1)', '6,851');
- test.assertSelectorContains('tr:nth-child(2)', '1,724');
- test.assertSelectorContains('tr:nth-child(3)', '3,729');
- test.assertSelectorContains('tr:nth-child(4)', '1,262');
+ test.assertSelectorContains('tr:nth-child(1)', '6.9k');
+ test.assertSelectorContains('tr:nth-child(2)', '1.7k');
+ test.assertSelectorContains('tr:nth-child(3)', '3.7k');
+ test.assertSelectorContains('tr:nth-child(4)', '1.3k');
test.assertSelectorContains('tr:nth-child(5)', '64');
test.assertSelectorContains('tr:nth-child(6)', '72');
diff --git a/server/sonar-web/src/test/json/global-issues-filter-widget/messages.json b/server/sonar-web/src/test/json/global-issues-filter-widget/messages.json
new file mode 100644
index 00000000000..4b2848cc625
--- /dev/null
+++ b/server/sonar-web/src/test/json/global-issues-filter-widget/messages.json
@@ -0,0 +1,6 @@
+{
+ "work_duration.x_days": "{0}d",
+ "work_duration.x_hours": "{0}h",
+ "work_duration.x_minutes": "{0}min",
+ "work_duration.about": "~ {0}"
+}
diff --git a/server/sonar-web/src/test/json/global-issues-filter-widget/unresolved-issues-by-date-debt.json b/server/sonar-web/src/test/json/global-issues-filter-widget/unresolved-issues-by-date-debt.json
new file mode 100644
index 00000000000..c1eb80cb144
--- /dev/null
+++ b/server/sonar-web/src/test/json/global-issues-filter-widget/unresolved-issues-by-date-debt.json
@@ -0,0 +1,33 @@
+{
+ "total": 6851,
+ "debtTotal": 6851,
+ "p": 1,
+ "ps": 1,
+ "facets": [
+ {
+ "property": "createdAt",
+ "values": [
+ {
+ "val": "2011-01-01T01:00:00+0000",
+ "count": 5027
+ },
+ {
+ "val": "2012-01-01T01:00:00+0000",
+ "count": 1178
+ },
+ {
+ "val": "2013-01-01T01:00:00+0000",
+ "count": 540
+ },
+ {
+ "val": "2014-01-01T01:00:00+0000",
+ "count": 105
+ },
+ {
+ "val": "2015-01-01T01:00:00+0000",
+ "count": 1
+ }
+ ]
+ }
+ ]
+}
diff --git a/server/sonar-web/src/test/json/global-issues-filter-widget/unresolved-issues-by-severity-debt.json b/server/sonar-web/src/test/json/global-issues-filter-widget/unresolved-issues-by-severity-debt.json
new file mode 100644
index 00000000000..15a51ee3033
--- /dev/null
+++ b/server/sonar-web/src/test/json/global-issues-filter-widget/unresolved-issues-by-severity-debt.json
@@ -0,0 +1,33 @@
+{
+ "total": 6851,
+ "debtTotal": 6851,
+ "p": 1,
+ "ps": 1,
+ "facets": [
+ {
+ "property": "severities",
+ "values": [
+ {
+ "val": "MAJOR",
+ "count": 5027
+ },
+ {
+ "val": "INFO",
+ "count": 1178
+ },
+ {
+ "val": "MINOR",
+ "count": 540
+ },
+ {
+ "val": "CRITICAL",
+ "count": 105
+ },
+ {
+ "val": "BLOCKER",
+ "count": 1
+ }
+ ]
+ }
+ ]
+}
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 0e762b376cc..4a98a79471e 100644
--- a/sonar-core/src/main/resources/org/sonar/l10n/core.properties
+++ b/sonar-core/src/main/resources/org/sonar/l10n/core.properties
@@ -1338,6 +1338,7 @@ widget.issue_filter.description=Displays the result of a pre-configured issue fi
widget.issue_filter.property.filter.name=Filter
widget.issue_filter.property.distributionAxis.name=Distribution Axis
widget.issue_filter.property.displayFilterDescription.name=Display Filter Description
+widget.issue_filter.property.displayMode.name=Display Mode
widget.issue_filter.unknown_filter_warning=This widget is configured to display an issue filter that doesn't exist anymore.
widget.issue_filter.insufficient_privileges_warning=Widget cannot be displayed: insufficient privileges.
widget.issue_filter.property.distributionAxis.option.severities.name=By Severity
@@ -1352,12 +1353,15 @@ widget.issue_filter.property.distributionAxis.option.resolutions.name=By Resolut
widget.issue_filter.property.distributionAxis.option.languages.name=By Language
widget.issue_filter.property.distributionAxis.option.reporters.name=By Reporter
widget.issue_filter.property.distributionAxis.option.authors.name=By Author
+widget.issue_filter.property.displayMode.option.count.name=Issues
+widget.issue_filter.property.displayMode.option.debt.name=Technical Debt
widget.project_issue_filter.name=Project Issue Filter
widget.project_issue_filter.description=Displays the result of a pre-configured issue filter applied to the project.
widget.project_issue_filter.property.filter.name=Filter
widget.project_issue_filter.property.distributionAxis.name=Distribution Axis
widget.project_issue_filter.property.displayFilterDescription.name=Display Filter Description
+widget.project_issue_filter.property.displayMode.name=Display Mode
widget.project_issue_filter.unknown_filter_warning=This widget is configured to display an issue filter that doesn't exist anymore.
widget.project_issue_filter.insufficient_privileges_warning=Widget cannot be displayed: insufficient privileges.
widget.project_issue_filter.property.distributionAxis.option.severities.name=By Severity
@@ -1371,6 +1375,8 @@ widget.project_issue_filter.property.distributionAxis.option.resolutions.name=By
widget.project_issue_filter.property.distributionAxis.option.languages.name=By Language
widget.project_issue_filter.property.distributionAxis.option.reporters.name=By Reporter
widget.project_issue_filter.property.distributionAxis.option.authors.name=By Author
+widget.project_issue_filter.property.displayMode.option.count.name=Issues
+widget.project_issue_filter.property.displayMode.option.debt.name=Technical Debt
widget.issue_tag_cloud.name=Project Issue Tag Cloud
widget.issue_tag_cloud.title=Issue Tag Cloud