diff options
author | Stas Vilchik <vilchiks@gmail.com> | 2015-01-06 14:32:44 +0100 |
---|---|---|
committer | Stas Vilchik <vilchiks@gmail.com> | 2015-01-06 14:32:59 +0100 |
commit | e2d074c326a61db83147840e17eae49bd984a29e (patch) | |
tree | 7a5a42953460be4515cb6d6fd984f1378a0326b1 | |
parent | 94949bfa631d8e88d26becb9a42e9dd6ccb61b6e (diff) | |
download | sonarqube-e2d074c326a61db83147840e17eae49bd984a29e.tar.gz sonarqube-e2d074c326a61db83147840e17eae49bd984a29e.zip |
SONAR-5820 Ability to bulk "Activate In" or "Deactivate In" all rules matching some search criteria
8 files changed, 231 insertions, 11 deletions
diff --git a/server/sonar-web/src/main/hbs/coding-rules/coding-rules-bulk-change-modal.hbs b/server/sonar-web/src/main/hbs/coding-rules/coding-rules-bulk-change-modal.hbs new file mode 100644 index 00000000000..0ad2c90b684 --- /dev/null +++ b/server/sonar-web/src/main/hbs/coding-rules/coding-rules-bulk-change-modal.hbs @@ -0,0 +1,39 @@ +<form> + <div class="modal-head"> + {{#eq action 'activate'}} + <h2>{{t 'coding_rules.activate_in_quality_profile'}} ({{state.total}} {{t 'coding_rules._rules'}})</h2> + {{/eq}} + {{#eq action 'deactivate'}} + <h2>{{t 'coding_rules.deactivate_in_quality_profile'}} ({{state.total}} {{t 'coding_rules._rules'}})</h2> + {{/eq}} + </div> + + <div class="modal-body modal-body-select2"> + <div class="js-modal-messages"></div> + + <div class="modal-field"> + <h3> + <label for="coding-rules-bulk-change-profile"> + {{#eq action 'activate'}}{{t 'coding_rules.activate_in'}}{{/eq}} + {{#eq action 'deactivate'}}{{t 'coding_rules.deactivate_in'}}{{/eq}} + </label> + </h3> + {{#if qualityProfile}} + <h3 class="readonly-field"> + {{qualityProfileName}}{{#notEq action 'change-severity'}} — {{t 'are_you_sure'}}{{/notEq}} + </h3> + {{else}} + <select id="coding-rules-bulk-change-profile"> + {{#each availableQualityProfiles}} + <option value="{{key}}">{{name}} - {{language}}</option> + {{/each}} + </select> + {{/if}} + </div> + </div> + + <div class="modal-foot"> + <button id="coding-rules-submit-bulk-change">{{t 'apply'}}</button> + <a class="js-modal-close">{{t 'close'}}</a> + </div> +</form> diff --git a/server/sonar-web/src/main/hbs/coding-rules/coding-rules-bulk-change-popup.hbs b/server/sonar-web/src/main/hbs/coding-rules/coding-rules-bulk-change-popup.hbs new file mode 100644 index 00000000000..c5a4622e9f6 --- /dev/null +++ b/server/sonar-web/src/main/hbs/coding-rules/coding-rules-bulk-change-popup.hbs @@ -0,0 +1,41 @@ +<div class="bubble-popup-title">{{t 'bulk_change'}}</div> + +<ul class="bubble-popup-list"> + + {{! activation }} + + <li> + <a class="js-bulk-change" data-action="activate"> + {{t 'coding_rules.activate_in'}}… + </a> + </li> + + {{#if allowActivateOnProfile}} + <li> + <a class="js-bulk-change" data-action="activate" data-param="{{qualityProfile}}"> + {{t 'coding_rules.activate_in'}} <strong>{{qualityProfileName}}</strong> + </a> + </li> + {{/if}} + + + + {{! deactivation }} + + <li> + <a class="js-bulk-change" data-action="deactivate"> + {{t 'coding_rules.deactivate_in'}}… + </a> + </li> + + {{#if allowDeactivateOnProfile}} + <li> + <a class="js-bulk-change" data-action="deactivate" data-param="{{qualityProfile}}"> + {{tp 'coding_rules.deactivate_in'}} <strong>{{qualityProfileName}}</strong> + </a> + </li> + {{/if}} +</ul> + + +<div class="bubble-popup-arrow"></div> diff --git a/server/sonar-web/src/main/hbs/coding-rules/coding-rules-workspace-header.hbs b/server/sonar-web/src/main/hbs/coding-rules/coding-rules-workspace-header.hbs index e91dbcd736b..bcf70f5d3ab 100644 --- a/server/sonar-web/src/main/hbs/coding-rules/coding-rules-workspace-header.hbs +++ b/server/sonar-web/src/main/hbs/coding-rules/coding-rules-workspace-header.hbs @@ -12,7 +12,8 @@ <div class="search-navigator-header-pagination"> {{#gt state.total 0}} <a class="js-prev icon-prev" title="{{t 'paging_previous'}}"></a> - <span class="current">{{sum state.selectedIndex 1}} / <span id="coding-rules-total">{{state.total}}</span></span> + <span class="current">{{sum state.selectedIndex 1}} / <span + id="coding-rules-total">{{state.total}}</span></span> <a class="js-next icon-next" title="{{t 'paging_next'}}"></a> {{else}} <span class="current">0 / <span id="coding-rules-total">0</span></span> @@ -20,11 +21,9 @@ </div> {{/notNull}} - - <div class="search-navigator-header-buttons button-group"> - <button class="js-reload">{{t 'reload'}}</button> - {{#if state.canBulkChange}} + {{#if canWrite}} + <div class="search-navigator-header-buttons button-group"> <button class="js-bulk-change">{{t 'bulk_change'}}</button> - {{/if}} - </div> + </div> + {{/if}} </div> diff --git a/server/sonar-web/src/main/hbs/coding-rules/rule/coding-rules-manual-rule-creation.hbs b/server/sonar-web/src/main/hbs/coding-rules/rule/coding-rules-manual-rule-creation.hbs index 5a6e62a6c46..f413905f636 100644 --- a/server/sonar-web/src/main/hbs/coding-rules/rule/coding-rules-manual-rule-creation.hbs +++ b/server/sonar-web/src/main/hbs/coding-rules/rule/coding-rules-manual-rule-creation.hbs @@ -45,6 +45,6 @@ <button id="coding-rules-manual-rule-creation-create"> {{#if change}}{{t 'save'}}{{else}}{{t 'create'}}{{/if}} </button> - <a id="coding-rules-manual-rule-creation-cancel" class="action">{{t 'cancel'}}</a> + <a id="coding-rules-manual-rule-creation-cancel" class="js-modal-close">{{t 'cancel'}}</a> </div> </form> diff --git a/server/sonar-web/src/main/js/coding-rules/bulk-change-modal-view.js b/server/sonar-web/src/main/js/coding-rules/bulk-change-modal-view.js new file mode 100644 index 00000000000..93755794b3a --- /dev/null +++ b/server/sonar-web/src/main/js/coding-rules/bulk-change-modal-view.js @@ -0,0 +1,74 @@ +define([ + 'common/modal-form', + 'templates/coding-rules' +], function (ModalFormView, Templates) { + + var $ = jQuery; + + return ModalFormView.extend({ + template: Templates['coding-rules-bulk-change-modal'], + + ui: function () { + return _.extend(ModalFormView.prototype.ui.apply(this, arguments), { + codingRulesSubmitBulkChange: '#coding-rules-submit-bulk-change' + }); + }, + + showSuccessMessage: function (succeeded) { + var message = tp('coding_rules.bulk_change.success', succeeded); + this.ui.messagesContainer.html('<div class="message-notice">' + message + '</div>'); + }, + + showWarnMessage: function (succeeded, failed) { + var message = tp('coding_rules.bulk_change.warning', succeeded, failed); + this.ui.messagesContainer.html('<div class="message-alert">' + message + '</div>'); + }, + + onRender: function () { + ModalFormView.prototype.onRender.apply(this, arguments); + this.$('#coding-rules-bulk-change-profile').select2({ + width: '250px', + minimumResultsForSearch: 1 + }); + }, + + onFormSubmit: function () { + ModalFormView.prototype.onFormSubmit.apply(this, arguments); + var that = this, + p = window.process.addBackgroundProcess(), + url = baseUrl + '/api/qualityprofiles/' + this.options.action + '_rules', + options = _.extend({}, this.options.app.state.get('query'), { + wsAction: this.options.action, + profile_key: this.$('#coding-rules-bulk-change-profile').val() || this.options.param + }); + $.post(url, options).done(function (r) { + if (r.failed) { + that.showWarnMessage(r.succeeded, r.failed); + } else { + that.showSuccessMessage(r.succeeded, r.failed); + } + that.$(that.ui.codingRulesSubmitBulkChange.selector).hide(); + window.process.finishBackgroundProcess(p); + }).fail(function () { + window.process.failBackgroundProcess(p); + }); + }, + + getAvailableQualityProfiles: function () { + return this.options.app.qualityProfiles; + }, + + serializeData: function () { + var profile = _.findWhere(this.options.app.qualityProfiles, { key: this.options.param }); + return _.extend(ModalFormView.prototype.serializeData.apply(this, arguments), { + action: this.options.action, + state: this.options.app.state.toJSON(), + qualityProfile: this.options.param, + qualityProfileName: profile != null ? profile.name : null, + qualityProfiles: this.options.app.qualityProfiles, + availableQualityProfiles: this.getAvailableQualityProfiles() + }); + } + }); + +}); diff --git a/server/sonar-web/src/main/js/coding-rules/bulk-change-popup-view.js b/server/sonar-web/src/main/js/coding-rules/bulk-change-popup-view.js new file mode 100644 index 00000000000..e373bd04da6 --- /dev/null +++ b/server/sonar-web/src/main/js/coding-rules/bulk-change-popup-view.js @@ -0,0 +1,41 @@ +define([ + 'common/popup', + 'templates/coding-rules', + 'coding-rules/bulk-change-modal-view' +], function (PopupView, Templates, BulkChangeModalView) { + + var $ = jQuery; + + return PopupView.extend({ + template: Templates['coding-rules-bulk-change-popup'], + + events: { + 'click .js-bulk-change': 'doAction' + }, + + doAction: function (e) { + var action = $(e.currentTarget).data('action'), + param = $(e.currentTarget).data('param'); + new BulkChangeModalView({ + app: this.options.app, + action: action, + param: param + }).render(); + }, + + serializeData: function () { + var query = this.options.app.state.get('query'), + profileKey = query.qprofile, + profile = _.findWhere(this.options.app.qualityProfiles, { key: profileKey }), + activation = query.activation; + + return { + qualityProfile: profileKey, + qualityProfileName: profile != null ? profile.name : null, + allowActivateOnProfile: profileKey != null && (activation === 'false' || activation === false), + allowDeactivateOnProfile: profileKey != null && (activation === 'true' || activation === true) + }; + } + }); + +}); diff --git a/server/sonar-web/src/main/js/coding-rules/workspace-header-view.js b/server/sonar-web/src/main/js/coding-rules/workspace-header-view.js index fae2372a8dc..ef19ef289a9 100644 --- a/server/sonar-web/src/main/js/coding-rules/workspace-header-view.js +++ b/server/sonar-web/src/main/js/coding-rules/workspace-header-view.js @@ -1,19 +1,39 @@ define([ 'components/navigator/workspace-header-view', - 'templates/coding-rules' -], function (WorkspaceHeaderView, Templates) { + 'templates/coding-rules', + 'coding-rules/bulk-change-popup-view' +], function (WorkspaceHeaderView, Templates, BulkChangePopup) { + + var $ = jQuery; return WorkspaceHeaderView.extend({ template: Templates['coding-rules-workspace-header'], events: function () { return _.extend(WorkspaceHeaderView.prototype.events.apply(this, arguments), { - 'click .js-back': 'onBackClick' + 'click .js-back': 'onBackClick', + 'click .js-bulk-change': 'onBulkChangeClick' }); }, onBackClick: function () { this.options.app.controller.hideDetails(); + }, + + onBulkChangeClick: function (e) { + e.stopPropagation(); + $('body').click(); + new BulkChangePopup({ + app: this.options.app, + triggerEl: $(e.currentTarget), + bottomRight: true + }).render(); + }, + + serializeData: function () { + return _.extend(WorkspaceHeaderView.prototype.serializeData.apply(this, arguments), { + canWrite: this.options.app.canWrite + }); } }); diff --git a/server/sonar-web/src/main/less/ui.less b/server/sonar-web/src/main/less/ui.less index f12a4f536e7..d0b840b128c 100644 --- a/server/sonar-web/src/main/less/ui.less +++ b/server/sonar-web/src/main/less/ui.less @@ -329,6 +329,12 @@ input[type=button] { } +.message-notice { + display: block; + padding: 5px 8px; + border: 2px solid @blue; +} + .message-alert { display: block; padding: 5px 8px; |