'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'
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: ->
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"
model: @source
main: @
+ @requestIssuesOnce = false
+
onRender: ->
if @settings.get 'workspace'
@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
@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()
@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)
filterByUncoveredBranchesIT: -> @filterByCoverageIT (c) -> c[3]? && c[4]? && (c[3] > c[4])
-
-
-
addTransition: (key, transition, optionsForCurrent, options) ->
if optionsForCurrent?
last = @workspace.at(@workspace.length - 1)
@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: ->
renderIssues: ->
- issues = @model.get 'issues'
+ issues = @model.get 'activeIssues'
issues.forEach (issue) =>
line = issue.line || 0
row = @$("[data-line-number=#{line}]")
<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"
-<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>
});
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);
+ }
}
});
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) {