aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStas Vilchik <vilchiks@gmail.com>2014-05-19 10:59:05 +0200
committerStas Vilchik <vilchiks@gmail.com>2014-05-19 10:59:12 +0200
commitb278651d81fe6302181da3a19bff7d9673c72bd0 (patch)
tree120d6078b11faa5637ab276d44f75a89d604c596
parentd4a0a5ac884a5381bc20b0ab12015063704b830f (diff)
downloadsonarqube-b278651d81fe6302181da3a19bff7d9673c72bd0.tar.gz
sonarqube-b278651d81fe6302181da3a19bff7d9673c72bd0.zip
SONAR-5209 Issues filtering
-rw-r--r--sonar-server/src/main/coffee/component-viewer/header.coffee55
-rw-r--r--sonar-server/src/main/coffee/component-viewer/main.coffee65
-rw-r--r--sonar-server/src/main/coffee/component-viewer/source.coffee4
-rw-r--r--sonar-server/src/main/hbs/component-viewer/header.hbs32
-rw-r--r--sonar-server/src/main/hbs/component-viewer/header/_issues-header.hbs109
-rw-r--r--sonar-server/src/main/js/common/handlebars-extensions.js10
-rw-r--r--sonar-server/src/main/js/issues/extra.js2
7 files changed, 183 insertions, 94 deletions
diff --git a/sonar-server/src/main/coffee/component-viewer/header.coffee b/sonar-server/src/main/coffee/component-viewer/header.coffee
index 731268a19dc..d8e0e4b5968 100644
--- a/sonar-server/src/main/coffee/component-viewer/header.coffee
+++ b/sonar-server/src/main/coffee/component-viewer/header.coffee
@@ -27,13 +27,23 @@ define [
'click .js-toggle-duplications': 'toggleDuplications'
'click .js-toggle-scm': 'toggleSCM'
+ 'click .js-filter-current-issue': 'filterByCurrentIssue'
+ 'click .js-filter-all-issues': 'filterByAllIssues'
+ 'click .js-filter-resolved-issues': 'filterByResolvedIssues'
+ 'click .js-filter-unresolved-issues': 'filterByUnresolvedIssues'
+ 'click .js-filter-false-positive-issues': 'filterByFalsePositiveIssues'
+ 'click .js-filter-blocker-issues': 'filterByBlockerIssues'
+ 'click .js-filter-critical-issues': 'filterByCriticalIssues'
+ 'click .js-filter-major-issues': 'filterByMajorIssues'
+ 'click .js-filter-minor-issues': 'filterByMinorIssues'
+ 'click .js-filter-info-issues': 'filterByInfoIssues'
+
'click .js-filter-lines-to-cover': 'filterByLinesToCover'
'click .js-filter-covered-lines': 'filterByCoveredLines'
'click .js-filter-uncovered-lines': 'filterByUncoveredLines'
'click .js-filter-branches-to-cover': 'filterByBranchesToCover'
'click .js-filter-covered-branches': 'filterByCoveredBranches'
'click .js-filter-uncovered-branches': 'filterByUncoveredBranches'
-
'click .js-filter-lines-to-cover-it': 'filterByLinesToCoverIT'
'click .js-filter-covered-lines-it': 'filterByCoveredLinesIT'
'click .js-filter-uncovered-lines-it': 'filterByUncoveredLinesIT'
@@ -90,25 +100,40 @@ define [
toggleWorkspace: (e) -> @toggleSetting e, @options.main.showWorkspace, @options.main.hideWorkspace
- filterByCoverage: (e, method) ->
+ filterLines: (e, method) ->
@$('.component-viewer-header-expanded-bar-section-list .active').removeClass 'active'
$(e.currentTarget).addClass 'active'
_.result @options.main, method
- filterByLinesToCover: (e) -> @filterByCoverage e, 'filterByLinesToCover'
- filterByCoveredLines: (e) -> @filterByCoverage e, 'filterByCoveredLines'
- filterByUncoveredLines: (e) -> @filterByCoverage e, 'filterByUncoveredLines'
- filterByBranchesToCover: (e) -> @filterByCoverage e, 'filterByBranchesToCover'
- filterByCoveredBranches: (e) -> @filterByCoverage e, 'filterByCoveredBranches'
- filterByUncoveredBranches: (e) -> @filterByCoverage e, 'filterByUncoveredBranches'
-
- filterByLinesToCoverIT: (e) -> @filterByCoverage e, 'filterByLinesToCoverIT'
- filterByCoveredLinesIT: (e) -> @filterByCoverage e, 'filterByCoveredLinesIT'
- filterByUncoveredLinesIT: (e) -> @filterByCoverage e, 'filterByUncoveredLinesIT'
- filterByBranchesToCoverIT: (e) -> @filterByCoverage e, 'filterByBranchesToCoverIT'
- filterByCoveredBranchesIT: (e) -> @filterByCoverage e, 'filterByCoveredBranchesIT'
- filterByUncoveredBranchesIT: (e) -> @filterByCoverage e, 'filterByUncoveredBranchesIT'
+ # Issues
+ filterByCurrentIssue: (e) -> @filterLines e, 'filterByCurrentIssue'
+ filterByAllIssues: (e) -> @filterLines e, 'filterByAllIssues'
+ filterByResolvedIssues: (e) -> @filterLines e, 'filterByResolvedIssues'
+ filterByUnresolvedIssues: (e) -> @filterLines e, 'filterByUnresolvedIssues'
+ filterByFalsePositiveIssues: (e) -> @filterLines e, 'filterByFalsePositiveIssues'
+
+ filterByBlockerIssues: (e) -> @filterLines e, 'filterByBlockerIssues'
+ filterByCriticalIssues: (e) -> @filterLines e, 'filterByCriticalIssues'
+ filterByMajorIssues: (e) -> @filterLines e, 'filterByMajorIssues'
+ filterByMinorIssues: (e) -> @filterLines e, 'filterByMinorIssues'
+ filterByInfoIssues: (e) -> @filterLines e, 'filterByInfoIssues'
+
+
+ # Coverage
+ filterByLinesToCover: (e) -> @filterLines e, 'filterByLinesToCover'
+ filterByCoveredLines: (e) -> @filterLines e, 'filterByCoveredLines'
+ filterByUncoveredLines: (e) -> @filterLines e, 'filterByUncoveredLines'
+ filterByBranchesToCover: (e) -> @filterLines e, 'filterByBranchesToCover'
+ filterByCoveredBranches: (e) -> @filterLines e, 'filterByCoveredBranches'
+ filterByUncoveredBranches: (e) -> @filterLines e, 'filterByUncoveredBranches'
+
+ filterByLinesToCoverIT: (e) -> @filterLines e, 'filterByLinesToCoverIT'
+ filterByCoveredLinesIT: (e) -> @filterLines e, 'filterByCoveredLinesIT'
+ filterByUncoveredLinesIT: (e) -> @filterLines e, 'filterByUncoveredLinesIT'
+ filterByBranchesToCoverIT: (e) -> @filterLines e, 'filterByBranchesToCoverIT'
+ filterByCoveredBranchesIT: (e) -> @filterLines e, 'filterByCoveredBranchesIT'
+ filterByUncoveredBranchesIT: (e) -> @filterLines e, 'filterByUncoveredBranchesIT'
serializeData: ->
diff --git a/sonar-server/src/main/coffee/component-viewer/main.coffee b/sonar-server/src/main/coffee/component-viewer/main.coffee
index 1cdde9a823a..7c65a008829 100644
--- a/sonar-server/src/main/coffee/component-viewer/main.coffee
+++ b/sonar-server/src/main/coffee/component-viewer/main.coffee
@@ -20,6 +20,7 @@ define [
API_COMPONENT = "#{baseUrl}/api/components/app"
API_SOURCES = "#{baseUrl}/api/sources/show"
+ API_ISSUES = "#{baseUrl}/api/issues/search"
API_COVERAGE = "#{baseUrl}/api/coverage/show"
API_SCM = "#{baseUrl}/api/sources/scm"
API_MEASURES = "#{baseUrl}/api/resources"
@@ -80,6 +81,8 @@ define [
model: @source
main: @
+ @requestIssuesOnce = false
+
onRender: ->
if @settings.get 'workspace'
@@ -128,6 +131,12 @@ define [
@source.set scm: data.scm
+ requestIssues: (key) ->
+ $.get API_ISSUES, components: key, ps: 10000, (data) =>
+ @requestIssuesOnce = true
+ @source.set issues: data.issues
+
+
requestCoverage: (key, type = 'UT') ->
$.get API_COVERAGE, key: key, type: type, (data) =>
@source.set coverage: data.coverage
@@ -176,11 +185,12 @@ define [
@render()
- showIssues: (issues) ->
+ showIssues: (issue) ->
@settings.set 'issues', true
- if _.isArray(issues) && issues.length > 0
- @source.set 'issues', issues
- @filterLinesByIssues()
+ if issue?
+ @currentIssue = issue.key
+ @source.set 'issues', [issue]
+ @filterByCurrentIssue()
else
@sourceView.render()
@@ -222,6 +232,50 @@ define [
@sourceView.render()
+ filterByIssues: (predicate, requestIssues = true) ->
+ if requestIssues && !@requestIssuesOnce
+ @requestIssues(@key).done => @_filterByIssues(predicate)
+ else
+ @_filterByIssues(predicate)
+
+
+ _filterByIssues: (predicate) ->
+ issues = @source.get 'issues'
+ @settings.set 'issues', true
+ @sourceView.resetShowBlocks()
+ activeIssues = []
+ issues.forEach (issue) =>
+ if predicate issue
+ line = issue.line || 0
+ @sourceView.addShowBlock line - LINES_AROUND_ISSUE, line + LINES_AROUND_ISSUE
+ activeIssues.push issue
+ @source.set 'activeIssues', activeIssues
+ @sourceView.render()
+
+
+ # Current Issue
+ filterByCurrentIssue: -> @filterByIssues ((issue) => issue.key == @currentIssue), false
+
+ # All Issues
+ filterByAllIssues: -> @filterByIssues -> true
+
+ # Resolved Issues
+ filterByResolvedIssues: -> @filterByIssues (issue) -> !!issue.resolution
+
+ # Unresolved Issues
+ filterByUnresolvedIssues: -> @filterByIssues (issue) -> !issue.resolution
+
+ # False Positive
+ filterByFalsePositiveIssues: -> @filterByIssues (issue) -> issue.resolution == 'FALSE-POSITIVE'
+
+ # Severity
+ filterByBlockerIssues: -> @filterByIssues (issue) -> issue.severity == 'BLOCKER' && !issue.resolution
+ filterByCriticalIssues: -> @filterByIssues (issue) -> issue.severity == 'CRITICAL' && !issue.resolution
+ filterByMajorIssues: -> @filterByIssues (issue) -> issue.severity == 'MAJOR' && !issue.resolution
+ filterByMinorIssues: -> @filterByIssues (issue) -> issue.severity == 'MINOR' && !issue.resolution
+ filterByInfoIssues: -> @filterByIssues (issue) -> issue.severity == 'INFO' && !issue.resolution
+
+
filterByCoverage: (predicate) ->
@requestCoverage(@key).done => @_filterByCoverage(predicate)
@@ -258,9 +312,6 @@ define [
filterByUncoveredBranchesIT: -> @filterByCoverageIT (c) -> c[3]? && c[4]? && (c[3] > c[4])
-
-
-
addTransition: (key, transition, optionsForCurrent, options) ->
if optionsForCurrent?
last = @workspace.at(@workspace.length - 1)
diff --git a/sonar-server/src/main/coffee/component-viewer/source.coffee b/sonar-server/src/main/coffee/component-viewer/source.coffee
index b5b01020a8b..fdd1fa9f057 100644
--- a/sonar-server/src/main/coffee/component-viewer/source.coffee
+++ b/sonar-server/src/main/coffee/component-viewer/source.coffee
@@ -59,7 +59,7 @@ define [
@delegateEvents()
@showSettings = false
@renderExpandButtons()
- @renderIssues() if @options.main.settings.get('issues') && @model.has('issues')
+ @renderIssues() if @options.main.settings.get('issues') && @model.has('activeIssues')
renderExpandButtons: ->
@@ -81,7 +81,7 @@ define [
renderIssues: ->
- issues = @model.get 'issues'
+ issues = @model.get 'activeIssues'
issues.forEach (issue) =>
line = issue.line || 0
row = @$("[data-line-number=#{line}]")
diff --git a/sonar-server/src/main/hbs/component-viewer/header.hbs b/sonar-server/src/main/hbs/component-viewer/header.hbs
index b4070fded78..c039f3e2a4b 100644
--- a/sonar-server/src/main/hbs/component-viewer/header.hbs
+++ b/sonar-server/src/main/hbs/component-viewer/header.hbs
@@ -31,32 +31,32 @@
<div class="component-viewer-header-measures-scope">
<a data-scope="issues" class="component-viewer-header-measures-expand">
- {{#if component.measures.fDebt}}
<div class="component-viewer-header-measure">
- <span class="component-viewer-header-measure-value">{{component.measures.fDebt}}</span>
+ <span class="component-viewer-header-measure-value">{{default component.measures.fDebt 0}}</span>
<span class="component-viewer-header-measure-label">Debt</span>
</div>
- {{/if}}
{{#if component.measures.fIssues}}
<div class="component-viewer-header-measure">
<span class="component-viewer-header-measure-value">{{component.measures.fIssues}}</span>
<span class="component-viewer-header-measure-label">{{t 'metric.violations.name'}}</span>
</div>
{{/if}}
- <div class="component-viewer-header-measure">
- <div class="component-viewer-header-measure-issues">
- <div class="component-viewer-header-measure-issue s-blocker"
- style="width: {{percent component.measures.fBlockerIssues component.measures.maxIssues}}%;"></div>
- <div class="component-viewer-header-measure-issue s-critical"
- style="width: {{percent component.measures.fCriticalIssues component.measures.maxIssues}}%;"></div>
- <div class="component-viewer-header-measure-issue s-major"
- style="width: {{percent component.measures.fMajorIssues component.measures.maxIssues}}%;"></div>
- <div class="component-viewer-header-measure-issue s-minor"
- style="width: {{percent component.measures.fMinorIssues component.measures.maxIssues}}%;"></div>
- <div class="component-viewer-header-measure-issue s-info"
- style="width: {{percent component.measures.fInfoIssues component.measures.maxIssues}}%;"></div>
+ {{#if component.measures.fIssues}}
+ <div class="component-viewer-header-measure">
+ <div class="component-viewer-header-measure-issues">
+ <div class="component-viewer-header-measure-issue s-blocker"
+ style="width: {{percent component.measures.fBlockerIssues component.measures.maxIssues}}%;"></div>
+ <div class="component-viewer-header-measure-issue s-critical"
+ style="width: {{percent component.measures.fCriticalIssues component.measures.maxIssues}}%;"></div>
+ <div class="component-viewer-header-measure-issue s-major"
+ style="width: {{percent component.measures.fMajorIssues component.measures.maxIssues}}%;"></div>
+ <div class="component-viewer-header-measure-issue s-minor"
+ style="width: {{percent component.measures.fMinorIssues component.measures.maxIssues}}%;"></div>
+ <div class="component-viewer-header-measure-issue s-info"
+ style="width: {{percent component.measures.fInfoIssues component.measures.maxIssues}}%;"></div>
+ </div>
</div>
- </div>
+ {{/if}}
<i class="icon-dropdown"></i>
</a>
<a data-scope="issues" title="Toggle issues"
diff --git a/sonar-server/src/main/hbs/component-viewer/header/_issues-header.hbs b/sonar-server/src/main/hbs/component-viewer/header/_issues-header.hbs
index 3298f8bbac0..8dacac532ff 100644
--- a/sonar-server/src/main/hbs/component-viewer/header/_issues-header.hbs
+++ b/sonar-server/src/main/hbs/component-viewer/header/_issues-header.hbs
@@ -1,59 +1,70 @@
-<div class="component-viewer-header-expanded-bar-section">
- <div class="component-viewer-header-expanded-bar-section-title">Severities</div>
- <ul class="component-viewer-header-expanded-bar-section-list">
- {{#if component.msr.blocker_violations}}
- <li><a class="item">
- <span><i class="icon-severity-blocker"></i> {{t 'severity.BLOCKER'}}</span>
- <span class="number">{{component.msr.blocker_violations}}</span>
- <i class="icon-chevron-right"></i>
- </a></li>
- {{/if}}
- {{#if component.msr.critical_violations}}
- <li><a class="item">
- <span><i class="icon-severity-critical"></i> {{t 'severity.CRITICAL'}}</span>
- <span class="number">{{component.msr.critical_violations}}</span>
- <i class="icon-chevron-right"></i>
- </a></li>
- {{/if}}
- {{#if component.msr.major_violations}}
- <li><a class="item">
- <span><i class="icon-severity-major"></i> {{t 'severity.MAJOR'}}</span>
- <span class="number">{{component.msr.major_violations}}</span>
- <i class="icon-chevron-right"></i>
- </a></li>
- {{/if}}
- {{#if component.msr.minor_violations}}
- <li><a class="item">
- <span><i class="icon-severity-minor"></i> {{t 'severity.MINOR'}}</span>
- <span class="number">{{component.msr.minor_violations}}</span>
- <i class="icon-chevron-right"></i>
- </a></li>
- {{/if}}
- {{#if component.msr.info_violations}}
- <li><a class="item">
- <span><i class="icon-severity-info"></i> {{t 'severity.INFO'}}</span>
- <span class="number">{{component.msr.info_violations}}</span>
- <i class="icon-chevron-right"></i>
- </a></li>
- {{/if}}
- </ul>
-</div>
+{{#if component.measures.fIssues}}
+ <div class="component-viewer-header-expanded-bar-section">
+ <div class="component-viewer-header-expanded-bar-section-title">Severities</div>
+ <ul class="component-viewer-header-expanded-bar-section-list">
+ {{#if component.msr.blocker_violations}}
+ <li><a class="item js-filter-blocker-issues">
+ <span><i class="icon-severity-blocker"></i> {{t 'severity.BLOCKER'}}</span>
+ <span class="number">{{component.msr.blocker_violations}}</span>
+ <i class="icon-chevron-right"></i>
+ </a></li>
+ {{/if}}
+ {{#if component.msr.critical_violations}}
+ <li><a class="item js-filter-critical-issues">
+ <span><i class="icon-severity-critical"></i> {{t 'severity.CRITICAL'}}</span>
+ <span class="number">{{component.msr.critical_violations}}</span>
+ <i class="icon-chevron-right"></i>
+ </a></li>
+ {{/if}}
+ {{#if component.msr.major_violations}}
+ <li><a class="item js-filter-major-issues">
+ <span><i class="icon-severity-major"></i> {{t 'severity.MAJOR'}}</span>
+ <span class="number">{{component.msr.major_violations}}</span>
+ <i class="icon-chevron-right"></i>
+ </a></li>
+ {{/if}}
+ {{#if component.msr.minor_violations}}
+ <li><a class="item js-filter-minor-issues">
+ <span><i class="icon-severity-minor"></i> {{t 'severity.MINOR'}}</span>
+ <span class="number">{{component.msr.minor_violations}}</span>
+ <i class="icon-chevron-right"></i>
+ </a></li>
+ {{/if}}
+ {{#if component.msr.info_violations}}
+ <li><a class="item js-filter-info-issues">
+ <span><i class="icon-severity-info"></i> {{t 'severity.INFO'}}</span>
+ <span class="number">{{component.msr.info_violations}}</span>
+ <i class="icon-chevron-right"></i>
+ </a></li>
+ {{/if}}
+ </ul>
+ </div>
+{{/if}}
-<div class="component-viewer-header-expanded-bar-section">
- <div class="component-viewer-header-expanded-bar-section-title">Rules</div>
- <ul class="component-viewer-header-expanded-bar-section-list">
- </ul>
-</div>
+{{#if component.measures.fIssues}}
+ <div class="component-viewer-header-expanded-bar-section">
+ <div class="component-viewer-header-expanded-bar-section-title">Rules</div>
+ <ul class="component-viewer-header-expanded-bar-section-list">
+ </ul>
+ </div>
+{{/if}}
<div class="component-viewer-header-expanded-bar-section">
- <div class="component-viewer-header-expanded-bar-section-title">&nbsp;</div>
+ <div class="component-viewer-header-expanded-bar-section-title">Issues</div>
<ul class="component-viewer-header-expanded-bar-section-list">
- <li><a class="item">
- <span>Current issue</span>
+ <li><a class="item js-filter-current-issue">
+ <span>Current Issue</span>
<i class="icon-chevron-right"></i>
</a></li>
+ {{#if component.measures.fIssues}}
+ <li><a class="item js-filter-unresolved-issues">
+ <span>Unresolved Issues</span>
+ <span class="number">{{component.measures.fIssues}}</span>
+ <i class="icon-chevron-right"></i>
+ </a></li>
+ {{/if}}
{{#if component.msr.false_positive_issues}}
- <li><a class="item">
+ <li><a class="item js-filter-false-positive-issues">
<span>False Positive</span>
<span class="number">{{component.msr.false_positive_issues}}</span>
<i class="icon-chevron-right"></i>
diff --git a/sonar-server/src/main/js/common/handlebars-extensions.js b/sonar-server/src/main/js/common/handlebars-extensions.js
index d4e2ffa911b..5ea426ecee7 100644
--- a/sonar-server/src/main/js/common/handlebars-extensions.js
+++ b/sonar-server/src/main/js/common/handlebars-extensions.js
@@ -70,10 +70,12 @@ define(['handlebars'], function (Handlebars) {
});
Handlebars.registerHelper('inArray', function(array, element, options) {
- if (array.indexOf(element) !== -1) {
- return options.fn(this);
- } else {
- return options.inverse(this);
+ if (_.isArray(array)) {
+ if (array.indexOf(element) !== -1) {
+ return options.fn(this);
+ } else {
+ return options.inverse(this);
+ }
}
});
diff --git a/sonar-server/src/main/js/issues/extra.js b/sonar-server/src/main/js/issues/extra.js
index c03cb85fde2..105ef9d16bf 100644
--- a/sonar-server/src/main/js/issues/extra.js
+++ b/sonar-server/src/main/js/issues/extra.js
@@ -156,7 +156,7 @@ define(
jQuery('.navigator-details').removeClass('navigator-fetching');
app.detailsRegion.show(componentViewer);
componentViewer.open(that.model.get('component')).done(function() {
- componentViewer.showIssues([that.model.toJSON()], true);
+ componentViewer.showIssues(that.model.toJSON(), true);
var row = componentViewer.$('.code-issue:first').closest('.row');
if (row.data('line-number') > 0) {