diff options
author | Stas Vilchik <vilchiks@gmail.com> | 2014-05-19 10:59:05 +0200 |
---|---|---|
committer | Stas Vilchik <vilchiks@gmail.com> | 2014-05-19 10:59:12 +0200 |
commit | b278651d81fe6302181da3a19bff7d9673c72bd0 (patch) | |
tree | 120d6078b11faa5637ab276d44f75a89d604c596 | |
parent | d4a0a5ac884a5381bc20b0ab12015063704b830f (diff) | |
download | sonarqube-b278651d81fe6302181da3a19bff7d9673c72bd0.tar.gz sonarqube-b278651d81fe6302181da3a19bff7d9673c72bd0.zip |
SONAR-5209 Issues filtering
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"> </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) { |