From 5d0730e2be1a25c186049a3255c50772818ae4c1 Mon Sep 17 00:00:00 2001 From: Stas Vilchik Date: Tue, 10 Jun 2014 16:09:46 +0600 Subject: [PATCH] SONAR-5209 Issues time changes --- .../coffee/component-viewer/header.coffee | 30 +++---- .../header/base-header.coffee | 4 +- .../header/issues-header.coffee | 81 ++++++++++++++--- .../header/tests-header.coffee | 2 +- .../main/coffee/component-viewer/main.coffee | 29 +++---- .../mixins/main-issues.coffee | 24 +++++ .../time-changes-popup.coffee | 2 +- .../src/main/hbs/component-viewer/header.hbs | 87 +++++++++---------- .../component-viewer/header/issues-header.hbs | 42 ++++----- .../main/js/common/handlebars-extensions.js | 14 ++- .../src/main/less/component-viewer.less | 32 ++----- 11 files changed, 206 insertions(+), 141 deletions(-) diff --git a/sonar-server/src/main/coffee/component-viewer/header.coffee b/sonar-server/src/main/coffee/component-viewer/header.coffee index bbe11055e9a..b6f84d4ba0f 100644 --- a/sonar-server/src/main/coffee/component-viewer/header.coffee +++ b/sonar-server/src/main/coffee/component-viewer/header.coffee @@ -8,8 +8,6 @@ define [ 'component-viewer/header/duplications-header' 'component-viewer/header/tests-header' - 'component-viewer/time-changes-popup' - 'common/handlebars-extensions' ], ( Marionette @@ -20,8 +18,6 @@ define [ CoverageHeaderView DuplicationsHeaderView TestsHeaderView - - TimeChangesPopupView ) -> $ = jQuery @@ -61,8 +57,6 @@ define [ 'click .js-toggle-duplications': 'toggleDuplications' 'click .js-toggle-scm': 'toggleSCM' - 'click .component-viewer-header-time-changes a': 'showTimeChangesPopup' - initialize: (options) -> options.main.settings.on 'change', => @changeSettings() @@ -73,6 +67,12 @@ define [ onRender: -> @delegateEvents() + activeHeaderTab = @state.get 'activeHeaderTab' + activeHeaderItem = @state.get 'activeHeaderItem' + if activeHeaderTab + @enableBar(activeHeaderTab).done => + if activeHeaderItem + @enableBarItem activeHeaderItem toggleFavorite: -> @@ -120,10 +120,14 @@ define [ @state.set 'activeHeaderTab', scope bar = _.findWhere BARS, scope: scope @barRegion.show new bar.view - state: @state, component: @component, settings: @settings, source: @model, header: @ + main: @options.main, state: @state, component: @component, settings: @settings, source: @model, header: @ @ui.expandLinks.filter("[data-scope=#{scope}]").addClass 'active' + enableBarItem: (item) -> + @$(item).click() + + showExpandedBar: (e) -> el = $(e.currentTarget) active = el.is '.active' @@ -157,13 +161,8 @@ define [ toggleWorkspace: (e) -> @toggleSetting e, @options.main.showWorkspace, @options.main.hideWorkspace - showTimeChangesPopup: (e) -> - e.stopPropagation() - $('body').click() - popup = new TimeChangesPopupView - triggerEl: $(e.currentTarget) - main: @options.main - popup.render() + showTimeChangesSpinner: -> + @$('.component-viewer-header-time-changes').html '' filterLines: (e, methodName, extra) -> @@ -188,5 +187,4 @@ define [ state: @state.toJSON() showSettings: @showSettings component: component - currentIssue: @options.main.currentIssue - period: @options.main.period?.toJSON() \ No newline at end of file + currentIssue: @options.main.currentIssue \ No newline at end of file diff --git a/sonar-server/src/main/coffee/component-viewer/header/base-header.coffee b/sonar-server/src/main/coffee/component-viewer/header/base-header.coffee index 2d870bf860f..d2ff8730104 100644 --- a/sonar-server/src/main/coffee/component-viewer/header/base-header.coffee +++ b/sonar-server/src/main/coffee/component-viewer/header/base-header.coffee @@ -8,6 +8,7 @@ define [ initialize: (options) -> super + @main = options.main @state = options.state @component = options.component @settings = options.settings @@ -19,4 +20,5 @@ define [ _.extend super, state: @state.toJSON() component: @component.toJSON() - settings: @settings.toJSON() \ No newline at end of file + settings: @settings.toJSON() + periods: @main.periods.toJSON() \ No newline at end of file diff --git a/sonar-server/src/main/coffee/component-viewer/header/issues-header.coffee b/sonar-server/src/main/coffee/component-viewer/header/issues-header.coffee index 56999615526..13989aa78d1 100644 --- a/sonar-server/src/main/coffee/component-viewer/header/issues-header.coffee +++ b/sonar-server/src/main/coffee/component-viewer/header/issues-header.coffee @@ -2,10 +2,12 @@ define [ 'backbone.marionette' 'templates/component-viewer' 'component-viewer/header/base-header' + 'component-viewer/time-changes-popup' ], ( Marionette Templates BaseHeaderView + TimeChangesPopupView ) -> $ = jQuery @@ -17,6 +19,7 @@ define [ events: 'click .js-issues-bulk-change': 'issuesBulkChange' + 'click .js-issues-time-changes': 'issuesTimeChanges' 'click .js-filter-current-issue': 'filterByCurrentIssue' 'click .js-filter-all-issues': 'filterByAllIssues' @@ -38,16 +41,72 @@ define [ openModalWindow url, {} - filterByCurrentIssue: (e) -> @header.filterLines e, 'filterByCurrentIssue' - filterByAllIssues: (e) -> @header.filterLines e, 'filterByAllIssues' - filterByFixedIssues: (e) -> @header.filterLines e, 'filterByFixedIssues' - filterByUnresolvedIssues: (e) -> @header.filterLines e, 'filterByUnresolvedIssues' - filterByFalsePositiveIssues: (e) -> @header.filterLines e, 'filterByFalsePositiveIssues' + issuesTimeChanges: (e) -> + e.stopPropagation() + $('body').click() + popup = new TimeChangesPopupView + triggerEl: $(e.currentTarget) + main: @options.main + bottom: true + popup.render() + popup.on 'change', (period) => @main.enableIssuesPeriod period - filterByRule: (e) -> @header.filterLines e, 'filterByRule', $(e.currentTarget).data 'rule' - filterByBlockerIssues: (e) -> @header.filterLines e, 'filterByBlockerIssues' - filterByCriticalIssues: (e) -> @header.filterLines e, 'filterByCriticalIssues' - filterByMajorIssues: (e) -> @header.filterLines e, 'filterByMajorIssues' - filterByMinorIssues: (e) -> @header.filterLines e, 'filterByMinorIssues' - filterByInfoIssues: (e) -> @header.filterLines e, 'filterByInfoIssues' \ No newline at end of file + filterByCurrentIssue: (e) -> + @header.filterLines e, 'filterByCurrentIssue' + @state.set 'activeHeaderItem', '.js-filter-current-issues' + + + filterByAllIssues: (e) -> + @header.filterLines e, 'filterByAllIssues' + @state.set 'activeHeaderItem', '.js-filter-all-issues' + + + filterByFixedIssues: (e) -> + @header.filterLines e, 'filterByFixedIssues' + @state.set 'activeHeaderItem', '.js-filter-fixed-issues' + + + filterByUnresolvedIssues: (e) -> + @header.filterLines e, 'filterByUnresolvedIssues' + @state.set 'activeHeaderItem', '.js-filter-unresolved-issues' + + + filterByFalsePositiveIssues: (e) -> + @header.filterLines e, 'filterByFalsePositiveIssues' + @state.set 'activeHeaderItem', '.js-filter-false-positive-issues' + + + filterByRule: (e) -> + rule = $(e.currentTarget).data 'rule' + @header.filterLines e, 'filterByRule', rule + @state.set 'activeHeaderItem', ".js-filter-rule[data-rule='#{rule}']" + + + filterByBlockerIssues: (e) -> + @header.filterLines e, 'filterByBlockerIssues' + @state.set 'activeHeaderItem', '.js-filter-BLOCKER-issues' + + + filterByCriticalIssues: (e) -> + @header.filterLines e, 'filterByCriticalIssues' + @state.set 'activeHeaderItem', '.js-filter-CRITICAL-issues' + + + filterByMajorIssues: (e) -> + @header.filterLines e, 'filterByMajorIssues' + @state.set 'activeHeaderItem', '.js-filter-MAJOR-issues' + + + filterByMinorIssues: (e) -> + @header.filterLines e, 'filterByMinorIssues' + @state.set 'activeHeaderItem', '.js-filter-MINOR-issues' + + + filterByInfoIssues: (e) -> + @header.filterLines e, 'filterByInfoIssues' + @state.set 'activeHeaderItem', '.js-filter-INFO-issues' + + + serializeData: -> + _.extend super, period: @state.get('issuesPeriod')?.toJSON() \ No newline at end of file diff --git a/sonar-server/src/main/coffee/component-viewer/header/tests-header.coffee b/sonar-server/src/main/coffee/component-viewer/header/tests-header.coffee index ddcebd2277d..002c4b21dbe 100644 --- a/sonar-server/src/main/coffee/component-viewer/header/tests-header.coffee +++ b/sonar-server/src/main/coffee/component-viewer/header/tests-header.coffee @@ -46,5 +46,5 @@ define [ triggerEl: $(e.currentTarget) collection: new Backbone.Collection data.files test: test - main: @options.main + main: @main popup.render() \ No newline at end of file diff --git a/sonar-server/src/main/coffee/component-viewer/main.coffee b/sonar-server/src/main/coffee/component-viewer/main.coffee index 11f54131d60..ada2780e0a0 100644 --- a/sonar-server/src/main/coffee/component-viewer/main.coffee +++ b/sonar-server/src/main/coffee/component-viewer/main.coffee @@ -98,7 +98,6 @@ define [ model: @source main: @ - @period = null @periods = new Backbone.Collection [], model: Period @@ -123,8 +122,8 @@ define [ @headerRegion.show @headerView - requestComponent: (key, clear = false) -> - STATE_FIELDS = ['canBulkChange', 'canMarkAsFavourite', 'scmAvailable'] + requestComponent: (key, clear = false, full = true) -> + STATE_FIELDS = ['canBulkChange', 'canMarkAsFavourite', 'tabs'] COMPONENT_FIELDS = ['key', 'name', 'path', 'q', 'projectName', 'subProjectName', 'measures', 'fav'] $.get API_COMPONENT, key: key, (data) => @@ -134,6 +133,7 @@ define [ @component.set 'dir', utils.splitLongName(data.path).dir @component.set 'isUnitTest', data.q == 'UTS' + # State stateAttributes = {} STATE_FIELDS.forEach (f) -> stateAttributes[f] = data[f] @@ -141,13 +141,16 @@ define [ stateAttributes.rules = _.sortBy rules, 'name' severities = data.severities.map (r) -> key: r[0], name: r[1], count: r[2] stateAttributes.severities = utils.sortSeverities severities - @state.clear silent: true - @state.set _.defaults stateAttributes, @state.defaults + if full + @state.clear silent: true + @state.set _.defaults stateAttributes, @state.defaults + else + @state.set stateAttributes - # Periods - @periods.reset [{}] - data.periods.forEach (p) => @periods.add key: p[0], label: p[1], sinceDate: new Date p[2] - @period = @periods.at 0 + if full + # Periods + @periods.reset [{}] + data.periods.forEach (p) => @periods.add key: p[0], label: p[1], sinceDate: new Date p[2] requestMeasures: (key) -> @@ -156,7 +159,8 @@ define [ metrics = [SOURCE_METRIC_LIST, COVERAGE_METRIC_LIST, ISSUES_METRIC_LIST, DUPLICATIONS_METRIC_LIST].join ',' else metrics = [ISSUES_METRIC_LIST, TESTS_METRIC_LIST] - $.get API_MEASURES, resource: key, metrics: metrics, (data) => + data = resource: key, metrics: metrics + $.get API_MEASURES, data, (data) => measuresList = data[0].msr || [] measures = @component.get 'measures' measuresList.forEach (m) -> @@ -215,11 +219,6 @@ define [ @render() - enablePeriod: (period) -> - @period = @periods.findWhere key: period - @render() - - showAllLines: -> @sourceView.resetShowBlocks() @sourceView.showBlocks.push from: 0, to: _.size @source.get 'source' diff --git a/sonar-server/src/main/coffee/component-viewer/mixins/main-issues.coffee b/sonar-server/src/main/coffee/component-viewer/mixins/main-issues.coffee index b840a274a5c..d29235bc9ca 100644 --- a/sonar-server/src/main/coffee/component-viewer/mixins/main-issues.coffee +++ b/sonar-server/src/main/coffee/component-viewer/mixins/main-issues.coffee @@ -1,6 +1,7 @@ define [], () -> $ = jQuery + API_COMPONENT = "#{baseUrl}/api/components/app" API_ISSUES = "#{baseUrl}/api/issues/search" LINES_AROUND_ISSUE = 4 @@ -35,6 +36,22 @@ define [], () -> @sourceView.render() + requestIssuesPeriod: (key, period) -> + $.get API_COMPONENT, key: key, period: period, (data) => + rules = data.rules.map (r) -> key: r[0], name: r[1], count: r[2] + severities = data.severities.map (r) -> key: r[0], name: r[1], count: r[2] + @state.set rules: rules, severities: severities + + + enableIssuesPeriod: (periodKey) -> + period = if periodKey == '' then null else @periods.findWhere key: periodKey + @state.set 'issuesPeriod', period + if period? + @requestIssuesPeriod(@key, period.get('key')).done => @headerView.render() + else + @requestComponent(@key, false, false).done => @headerView.render() + + filterLinesByIssues: -> issues = @source.get 'issues' @sourceView.resetShowBlocks() @@ -45,6 +62,12 @@ define [], () -> filterByIssues: (predicate, requestIssues = true) -> + issuesPeriod = @state.get('issuesPeriod') + if issuesPeriod + p = predicate + predicate = (issue) => + (new Date(issue.creationDate) >= issuesPeriod.get('sinceDate')) && p issue + if requestIssues && !@state.get 'hasIssues' @requestIssues(@key).done => @_filterByIssues(predicate) else @@ -68,6 +91,7 @@ define [], () -> # Current Issue filterByCurrentIssue: -> @filterByIssues ((issue) => issue.key == @currentIssue), false + # All Issues filterByAllIssues: -> @filterByIssues -> true diff --git a/sonar-server/src/main/coffee/component-viewer/time-changes-popup.coffee b/sonar-server/src/main/coffee/component-viewer/time-changes-popup.coffee index 26291e3b53a..a677ee7dd5b 100644 --- a/sonar-server/src/main/coffee/component-viewer/time-changes-popup.coffee +++ b/sonar-server/src/main/coffee/component-viewer/time-changes-popup.coffee @@ -21,7 +21,7 @@ define [ enablePeriod: (e) -> period = $(e.currentTarget).data 'period' - @options.main.enablePeriod period + @trigger 'change', period serializeData: -> diff --git a/sonar-server/src/main/hbs/component-viewer/header.hbs b/sonar-server/src/main/hbs/component-viewer/header.hbs index 0adfde9f815..a3733bf8285 100644 --- a/sonar-server/src/main/hbs/component-viewer/header.hbs +++ b/sonar-server/src/main/hbs/component-viewer/header.hbs @@ -42,7 +42,7 @@
- {{component.measures.fNcloc}} + {{default component.measures.fNcloc '–'}} {{t 'metric.ncloc.name'}}
@@ -53,7 +53,7 @@
- {{default component.measures.fDebt 0}} + {{default component.measures.fDebt '–'}} {{t 'component_viewer.header.debt'}}
{{#if component.measures.fIssues}} @@ -84,53 +84,46 @@ class="js-toggle-issues component-viewer-header-measures-toggle-scope {{#if settings.issues}}active{{/if}}">
- {{#unless component.isUnitTest}} - {{#if component.measures.fCoverage}} -
- -
- {{component.measures.fCoverage}} - {{t 'metric.coverage.name'}} -
- -
- -
- {{/if}} - - {{#if component.measures.fDuplicationDensity}} -
- -
- {{component.measures.fDuplicationDensity}} - {{t 'metric.duplicated_lines_density.name'}} -
- -
- -
- {{/if}} - {{/unless}} + {{#inArray state.tabs 'coverage'}} +
+ +
+ {{default component.measures.fCoverage '–'}} + {{t 'metric.coverage.name'}} +
+ +
+ +
+ {{/inArray}} -
- -
- - SCM -
-
- -
- + {{#inArray state.tabs 'duplications'}} +
+ +
+ {{default component.measures.fDuplicationDensity '–'}} + {{t 'metric.duplicated_lines_density.name'}} +
+ +
+ +
+ {{/inArray}} -
- - -
{{#if period.key}}{{period.label}}{{else}}Time
Changes{{/if}}
-
+ {{#inArray state.tabs 'scm'}} +
+ +
+ + SCM +
+
+ +
+ {{/inArray}}
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 d35dbd71140..c4632830440 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,4 +1,4 @@ -{{#if component.measures.fIssues}} +{{#ifNotEmpty state.severities}}
{{t 'component_viewer.measure_section.severities'}} @@ -13,9 +13,9 @@ {{/each}}
-{{/if}} +{{/ifNotEmpty}} -{{#if component.measures.fIssues}} +{{#ifNotEmpty state.rules}}
{{t 'component_viewer.measure_section.rules'}} @@ -30,7 +30,7 @@ {{/each}}
-{{/if}} +{{/ifNotEmpty}}
-{{#if state.canBulkChange}} -{{/if}} \ No newline at end of file diff --git a/sonar-server/src/main/js/common/handlebars-extensions.js b/sonar-server/src/main/js/common/handlebars-extensions.js index 8deac86c643..8d7ada4f526 100644 --- a/sonar-server/src/main/js/common/handlebars-extensions.js +++ b/sonar-server/src/main/js/common/handlebars-extensions.js @@ -79,7 +79,11 @@ define(['handlebars', 'moment'], function (Handlebars, moment) { }); Handlebars.registerHelper('percent', function(value, total) { - return '' + ((value || 0) / total * 100) + '%'; + if (total > 0) { + return '' + ((value || 0) / total * 100) + '%'; + } else { + return '0%'; + } }); Handlebars.registerHelper('eq', function(v1, v2, options) { @@ -303,4 +307,12 @@ define(['handlebars', 'moment'], function (Handlebars, moment) { } }); + Handlebars.registerHelper('ifMeasureShouldBeShown', function(measure, period, options) { + if (measure != null || period != null) { + return options.fn(this); + } else { + return options.inverse(this); + } + }); + }); diff --git a/sonar-server/src/main/less/component-viewer.less b/sonar-server/src/main/less/component-viewer.less index 685a7f6f9c8..98143dca240 100644 --- a/sonar-server/src/main/less/component-viewer.less +++ b/sonar-server/src/main/less/component-viewer.less @@ -433,33 +433,6 @@ & > a { display: block; } } -.component-viewer-header-time-changes { - float: right; - max-width: 180px; - - & > a { - display: block; - padding: 14px 10px; - border-right: 1px solid @barBorderColor; - font-size: @smallFontSize; - .trans; - - &:hover { background-color: @barBorderColor; } - - & > i { - display: block; - float: left; - margin-top: 8px; - margin-right: 4px; - } - - & > div { - padding: 2px 0; - overflow: hidden; - } - } -} - .component-viewer-header-expanded-bar { display: none; .clearfix; @@ -482,6 +455,11 @@ .component-viewer-header-expanded-bar-section-actions { margin-left: 15px; + + .component-viewer-header-expanded-bar-section-list > li { + padding: 4px 0; + line-height: 1.5; + } } .component-viewer-header-expanded-bar-section-title { -- 2.39.5