-<h3 class="coding-rules-detail-header">
- {{name}}
- <a class="coding-rules-detail-permalink icon-link" target="_blank" href="#rule_key={{key}}"></a>
-</h3>
-<span class="subtitle">{{key}}</span>
-
-<ul class="coding-rules-detail-properties">
- {{#unless isManual}}
- <li class="coding-rules-detail-property">{{severityIcon severity}} {{t "severity" severity}}</li>
- {{/unless}}
- {{#notEq status 'READY'}}
- <li class="coding-rules-detail-property">
- <span class="coding-rules-detail-status coding-rules-detail-not-ready">{{status}}</span>
- </li>
- {{/notEq}}
-
-
- <li class="coding-rules-detail-property coding-rules-detail-tag-list {{#if canWrite}}coding-rules-detail-tags-change{{/if}}">
- <i class="icon-tags"></i>
- <span>{{#if allTags}}{{join allTags ', '}}{{else}}{{t 'coding_rules.no_tags'}}{{/if}}</span>
- </li>
- {{#if canWrite}}<li class="coding-rules-detail-property coding-rules-detail-tag-edit">
- {{#if sysTags}}<i class="icon-tags"></i>
- <span>{{join sysTags ', '}}</span>{{/if}}
- <input class="coding-rules-detail-tag-input" type="text" value="{{#if tags}}{{join tags ','}}{{/if}}">
-
- <div class="button-group">
- <button class="coding-rules-detail-tag-edit-done">{{t 'Done'}}</button>
- </div>
- <a class="coding-rules-details-tag-edit-cancel">{{t 'cancel'}}</a>
- </li>{{/if}}
-
- {{#if subCharacteristic}}
- <li class="coding-rules-detail-property coding-rules-subcharacteristic">{{subCharacteristic}}</li>
- {{/if}}
- <li class="coding-rules-detail-property">{{t 'coding_rules.available_since'}} {{d createdAt}}</li>
- <li class="coding-rules-detail-property">{{repository}}{{#unless isManual}} ({{language}}){{/unless}}</li>
-
- {{#if isTemplate}}
- <li class="coding-rules-detail-property" title="{{t 'coding_rules.rule_template.title'}}">{{t 'coding_rules.rule_template'}}</li>
- {{/if}}
- {{#if templateKey}}
- <li class="coding-rules-detail-property" title="{{t 'coding_rules.custom_rule.title'}}">{{t 'coding_rules.custom_rule'}}
- (<a href="#rule_key={{templateKey}}">{{t 'coding_rules.show_template'}}</a>)
- </li>
- {{/if}}
-</ul>
-
-<div class="coding-rules-detail-description rule-desc markdown">{{{htmlDesc}}}</div>
-
-{{#unless isEditable}}
- {{#unless isManual}}
- <div class="coding-rules-detail-description coding-rules-detail-description-extra">
- <div id="coding-rules-detail-description-extra">
- {{#if htmlNote}}
- <div class="rule-desc marginbottom10 markdown">{{{htmlNote}}}</div>{{/if}}
- {{#if canWrite}}<div class="button-group">
- <button id="coding-rules-detail-extend-description">{{t 'coding_rules.extend_description'}}</button>
- </div>{{/if}}
- </div>
-
- {{#if canWrite}}<div class="coding-rules-detail-extend-description-form">
- <table class="width100">
- <tbody>
- <tr>
- <td class="width100" colspan="2">
- <textarea id="coding-rules-detail-extend-description-text" rows="4"
- style="width: 100%; margin-bottom: 4px;">{{mdNote}}</textarea>
- </td>
- </tr>
- <tr>
- <td>
- <div class="button-group">
- <button id="coding-rules-detail-extend-description-submit">{{t 'save'}}</button>
- {{#if mdNote}}
- <button id="coding-rules-detail-extend-description-remove" class="button-red">{{t 'remove'}}</button>
- {{/if}}
- </div>
- <a id="coding-rules-detail-extend-description-cancel" class="action">{{t 'cancel'}}</a>
- </td>
- <td class="right">
- {{> '_markdown-tips' }}
- </td>
- </tr>
- </tbody>
- </table>
- </div>
-
- <div id="coding-rules-detail-extend-description-spinner">
- <i class="spinner"></i>
- </div>{{/if}}
- </div>
- {{/unless}}
-{{/unless}}
-
-
-{{#if params}}
- <h3 class="coding-rules-detail-title">{{t 'coding_rules.parameters'}}</h3>
- <div class="coding-rules-detail-parameters">
- {{#each params}}
- <dl class="coding-rules-detail-parameter">
- <dt class="coding-rules-detail-parameter-name">{{key}}</dt>
- <dd class="coding-rules-detail-parameter-description" data-key="{{key}}">
- <p>{{{htmlDesc}}}</p>
- {{#if ../../templateKey}}
- <div class="subtitle">
- {{#if defaultValue }}
- <span class="value">{{defaultValue}}</span>
- {{else}}
- {{t 'coding_rules.parameter.empty'}}
- {{/if}}
- </div>
- {{else}}
- {{#if defaultValue}}
- <div class="subtitle">{{t 'coding_rules.parameters.default_value'}} <span class="value">{{defaultValue}}</span></div>
- {{/if}}
- {{/if}}
- </dd>
- </dl>
- {{/each}}
- </div>
-{{/if}}
+<div class="js-rule-meta"></div>
+<div class="js-rule-description"></div>
+<div class="js-rule-parameters"></div>
{{#if isEditable}}
<div class="coding-rules-detail-description">
</div>
{{/if}}
-
{{#if isTemplate}}
<div class="coding-rules-detail-custom-rules-section">
<h3 class="coding-rules-detail-title">{{t 'coding_rules.custom_rules'}}</h3>
- {{#if canWrite}}<div class="button-group coding-rules-detail-quality-profiles-activation">
- <button id="coding-rules-custom-rules-create">{{t 'coding_rules.create'}}</button>
- </div>{{/if}}
+ {{#if canWrite}}
+ <div class="button-group coding-rules-detail-quality-profiles-activation">
+ <button id="coding-rules-custom-rules-create">{{t 'coding_rules.create'}}</button>
+ </div>
+ {{/if}}
<div id="coding-rules-detail-custom-rules"></div>
</div>
{{/if}}
-
-{{#if qualityProfilesVisible}}
- <div class="coding-rules-detail-quality-profiles-section">
- <h3 class="coding-rules-detail-title">{{t 'coding_rules.quality_profiles'}}</h3>
-
- {{#if canWrite}}{{#unless isTemplate}}<div class="button-group coding-rules-detail-quality-profiles-activation">
- <button id="coding-rules-quality-profile-activate">{{t 'coding_rules.activate'}}</button>
- </div>{{/unless}}{{/if}}
- {{#if isTemplate}}
- <div class="coding-rules-detail-quality-profiles-template-caption warning">{{t 'coding_rules.quality_profiles.template_caption'}}</div>
- {{/if}}
- <div id="coding-rules-detail-quality-profiles"></div>
- </div>
-{{/if}}
+<div class="js-rule-profiles"></div>
--- /dev/null
+<form>
+ <div class="modal-head">
+ {{#if change}}
+ <h2>{{t 'coding_rules.change_details'}}</h2>
+ {{else}}
+ <h2>{{t 'coding_rules.activate_in_quality_profile'}}</h2>
+ {{/if}}
+ </div>
+
+ <div class="modal-body modal-body-select2">
+ <div class="modal-error"></div>
+
+ <table>
+ <tr class="property">
+ <th><h3>{{t 'coding_rules.quality_profile'}}</h3></th>
+ <td>
+ {{#if key}}
+ {{name}}
+ {{else}}
+ <select id="coding-rules-quality-profile-activation-select">
+ {{#each qualityProfiles}}
+ <option value="{{key}}">{{name}}</option>
+ {{/each}}
+ </select>
+ {{/if}}
+ </td>
+ </tr>
+ <tr class="property">
+ <th><h3>{{t 'severity'}}</h3></th>
+ <td>
+ <select id="coding-rules-quality-profile-activation-severity">
+ {{#each severities}}
+ <option value="{{this}}">{{t 'severity' this}}</option>
+ {{/each}}
+ </select>
+ </td>
+ </tr>
+ {{#if isCustomRule}}
+ <tr class="property">
+ <td colspan="2" class="note">{{t 'coding_rules.custom_rule.activation_notice'}}</td>
+ {{else}}
+ {{#each params}}
+ <tr class="property">
+ <th><h3>{{key}}</h3></th>
+ <td>
+ {{#eq type 'TEXT'}}
+ <textarea class="width100" rows="3" name="{{key}}" placeholder="{{defaultValue}}">{{value}}</textarea>
+ {{else}}
+ {{#eq type 'BOOLEAN'}}
+ <select name="{{key}}" value="{{value}}">
+ <option value="{{defaultValue}}">{{t 'default'}} ({{t defaultValue}})</option>
+ <option value="true"{{#eq value 'true'}} selected="selected"{{/eq}}>{{t 'true'}}</option>
+ <option value="false"{{#eq value 'false'}} selected="selected"{{/eq}}>{{t 'false'}}</option>
+ </select>
+ {{else}}
+ <input type="text" name="{{key}}" value="{{value}}" placeholder="{{defaultValue}}">
+ {{/eq}}
+ {{/eq}}
+ <div class="note">{{description}}</div>
+ {{#if extra}}
+ <div class="note">{{extra}}</div>
+ {{/if}}
+ </td>
+ </tr>
+ {{/each}}
+ {{/if}}
+ </table>
+ </div>
+
+ <div class="modal-foot">
+ <button id="coding-rules-quality-profile-activation-activate" {{#unless saveEnabled}}disabled="disabled"{{/unless}}>
+ {{#if change}}{{t 'save'}}{{else}}{{t 'coding_rules.activate'}}{{/if}}
+ </button>
+ <a id="coding-rules-quality-profile-activation-cancel" class="js-modal-close">{{t 'cancel'}}</a>
+ </div>
+</form>
--- /dev/null
+<div class="coding-rules-detail-description rule-desc markdown">{{{htmlDesc}}}</div>
+
+{{#unless isEditable}}
+ {{#unless isManual}}
+ <div class="coding-rules-detail-description coding-rules-detail-description-extra">
+ <div id="coding-rules-detail-description-extra">
+ {{#if htmlNote}}
+ <div class="rule-desc marginbottom10 markdown">{{{htmlNote}}}</div>
+ {{/if}}
+ {{#if canWrite}}
+ <div class="button-group">
+ <button id="coding-rules-detail-extend-description">{{t 'coding_rules.extend_description'}}</button>
+ </div>
+ {{/if}}
+ </div>
+
+ {{#if canWrite}}
+ <div class="coding-rules-detail-extend-description-form hidden">
+ <table class="width100">
+ <tbody>
+ <tr>
+ <td class="width100" colspan="2">
+ <textarea id="coding-rules-detail-extend-description-text" rows="4"
+ style="width: 100%; margin-bottom: 4px;">{{mdNote}}</textarea>
+ </td>
+ </tr>
+ <tr>
+ <td>
+ <div class="button-group">
+ <button id="coding-rules-detail-extend-description-submit">{{t 'save'}}</button>
+ {{#if mdNote}}
+ <button id="coding-rules-detail-extend-description-remove"
+ class="button-red">{{t 'remove'}}</button>
+ {{/if}}
+ </div>
+ <a id="coding-rules-detail-extend-description-cancel" class="action">{{t 'cancel'}}</a>
+ </td>
+ <td class="right">
+ {{> '_markdown-tips' }}
+ </td>
+ </tr>
+ </tbody>
+ </table>
+ </div>
+ {{/if}}
+ </div>
+ {{/unless}}
+{{/unless}}
--- /dev/null
+<h3 class="coding-rules-detail-header">
+ {{name}}
+ <a class="coding-rules-detail-permalink icon-link" target="_blank" href="#rule_key={{key}}"></a>
+</h3>
+
+<span class="subtitle">{{key}}</span>
+
+<ul class="coding-rules-detail-properties">
+ {{#unless isManual}}
+ <li class="coding-rules-detail-property">{{severityIcon severity}} {{t "severity" severity}}</li>
+ {{/unless}}
+
+ {{#notEq status 'READY'}}
+ <li class="coding-rules-detail-property">{{status}}</li>
+ {{/notEq}}
+
+ <li class="coding-rules-detail-property coding-rules-detail-tag-list {{#if canWrite}}coding-rules-detail-tags-change{{/if}}">
+ <i class="icon-tags"></i>
+ <span>{{#if allTags}}{{join allTags ', '}}{{else}}{{t 'coding_rules.no_tags'}}{{/if}}</span>
+ </li>
+
+ {{#if canWrite}}
+ <li class="coding-rules-detail-property coding-rules-detail-tag-edit hidden">
+ {{#if sysTags}}<i class="icon-tags"></i>
+ <span>{{join sysTags ', '}}</span>{{/if}}
+ <input class="coding-rules-detail-tag-input" type="text" value="{{#if tags}}{{join tags ','}}{{/if}}">
+
+ <div class="button-group">
+ <button class="coding-rules-detail-tag-edit-done">{{t 'Done'}}</button>
+ </div>
+ <a class="coding-rules-details-tag-edit-cancel">{{t 'cancel'}}</a>
+ </li>
+ {{/if}}
+
+ {{#if subCharacteristic}}
+ <li class="coding-rules-detail-property coding-rules-subcharacteristic">{{subCharacteristic}}</li>
+ {{/if}}
+
+ <li class="coding-rules-detail-property">{{t 'coding_rules.available_since'}} {{d createdAt}}</li>
+
+ <li class="coding-rules-detail-property">{{default repo.name repo}}{{#unless isManual}} ({{langName}}){{/unless}}</li>
+
+ {{#if isTemplate}}
+ <li class="coding-rules-detail-property"
+ title="{{t 'coding_rules.rule_template.title'}}">{{t 'coding_rules.rule_template'}}</li>
+ {{/if}}
+
+ {{#if templateKey}}
+ <li class="coding-rules-detail-property"
+ title="{{t 'coding_rules.custom_rule.title'}}">{{t 'coding_rules.custom_rule'}}
+ (<a href="#rule_key={{templateKey}}">{{t 'coding_rules.show_template'}}</a>)
+ </li>
+ {{/if}}
+</ul>
--- /dev/null
+<h3 class="coding-rules-detail-title">{{t 'coding_rules.parameters'}}</h3>
+<table class="coding-rules-detail-parameters">
+ {{#each params}}
+ <tr class="coding-rules-detail-parameter">
+ <td class="coding-rules-detail-parameter-name">{{key}}</td>
+ <td class="coding-rules-detail-parameter-description" data-key="{{key}}">
+ <p>{{{htmlDesc}}}</p>
+ {{#if ../../templateKey}}
+ <div class="subtitle">
+ {{#if defaultValue }}
+ <span class="value">{{defaultValue}}</span>
+ {{else}}
+ {{t 'coding_rules.parameter.empty'}}
+ {{/if}}
+ </div>
+ {{else}}
+ {{#if defaultValue}}
+ <div class="subtitle">{{t 'coding_rules.parameters.default_value'}} <span
+ class="value">{{defaultValue}}</span></div>
+ {{/if}}
+ {{/if}}
+ </td>
+ </tr>
+ {{/each}}
+</table>
--- /dev/null
+<td class="coding-rules-detail-quality-profile-name">
+ {{name}}
+ {{#if parent}}
+ <div class="coding-rules-detail-quality-profile-inheritance">
+ {{#eq inherit 'OVERRIDES'}}
+ <i class="icon-inheritance" title="{{tp 'coding_rules.overrides' name parent.name}}"></i>
+ {{/eq}}
+ {{#eq inherit 'INHERITED'}}
+ <i class="icon-inheritance" title="{{tp 'coding_rules.inherits' name parent.name}}"></i>
+ {{/eq}}
+ {{parent.name}}
+ </div>
+ {{/if}}
+</td>
+
+{{#if severity}}
+ <td class="coding-rules-detail-quality-profile-severity">
+ {{severityIcon severity}} {{t "severity" severity}}
+ {{#if parent}}{{#notEq severity parent.severity}}
+ <div class="coding-rules-detail-quality-profile-inheritance">
+ {{t 'coding_rules.original'}} {{t 'severity' parent.severity}}
+ </div>
+ {{/notEq}}{{/if}}
+ </td>
+
+ {{#unless templateKey}}
+ <td class="coding-rules-detail-quality-profile-parameters">
+ {{#each parameters}}
+ <div class="coding-rules-detail-quality-profile-parameter">
+ <span class="key">{{key}}</span><span class="sep">: </span><span class="value"
+ title="{{value}}">{{value}}</span>
+ {{#if ../parent}}{{#notEq value original}}
+ <div class="coding-rules-detail-quality-profile-inheritance">
+ {{t 'coding_rules.original'}} <span class="value">{{original}}</span>
+ </div>
+ {{/notEq}}{{/if}}
+ </div>
+ {{/each}}
+
+ </td>
+ {{/unless}}
+
+ {{#if canWrite}}
+ <td class="coding-rules-detail-quality-profile-actions">
+ <div class="button-group">
+ {{#unless isTemplate}}
+ <button class="coding-rules-detail-quality-profile-change">{{t 'change_verb'}}</button>
+ {{/unless}}
+ {{#if parent}}
+ {{#eq inherit 'OVERRIDES'}}
+ <button class="coding-rules-detail-quality-profile-revert button-red">
+ {{t 'coding_rules.revert_to_parent_definition'}}
+ </button>
+ {{/eq}}
+ {{else}}
+ <button class="coding-rules-detail-quality-profile-deactivate button-red">
+ {{t 'coding_rules.deactivate'}}
+ </button>
+ {{/if}}
+ </div>
+ </td>
+ {{/if}}
+
+{{else}}
+ {{#if canWrite}}{{#unless isTemplate}}
+ <td class="coding-rules-detail-quality-profile-actions">
+ <div class="button-group">
+ <button class="coding-rules-detail-quality-profile-activate">{{t 'coding_rules.activate'}}</button>
+ </div>
+ </td>
+ {{/unless}}{{/if}}
+{{/if}}
--- /dev/null
+<div class="coding-rules-detail-quality-profiles-section">
+ <h3 class="coding-rules-detail-title">{{t 'coding_rules.quality_profiles'}}</h3>
+
+ {{#if canWrite}}
+ {{#unless isTemplate}}
+ <div class="button-group coding-rules-detail-quality-profiles-activation">
+ <button id="coding-rules-quality-profile-activate">{{t 'coding_rules.activate'}}</button>
+ </div>
+ {{/unless}}
+ {{/if}}
+
+ {{#if isTemplate}}
+ <div class="coding-rules-detail-quality-profiles-template-caption warning">
+ {{t 'coding_rules.quality_profiles.template_caption'}}
+ </div>
+ {{/if}}
+
+ <table id="coding-rules-detail-quality-profiles" class="coding-rules-detail-quality-profiles width100"></table>
+</div>
that.app.list.add(rules);
}
that.app.list.setIndex();
+ that.app.list.addExtraAttributes(that.app.languages, that.app.repositories);
that.app.facets.reset(that._allFacets());
that.app.facets.add(r.facets, { merge: true });
that.enableFacets(that._enabledFacets());
},
getRuleDetails: function (rule) {
- var url = baseUrl + '/api/rules/show',
+ var that = this,
+ url = baseUrl + '/api/rules/show',
options = {
key: rule.id,
actives: true
};
return $.get(url, options).done(function (data) {
rule.set(data.rule);
+ rule.addExtraAttributes(that.app.languages, that.app.repositories);
});
},
showDetails: function (rule) {
- var that = this;
+ var that = this,
+ ruleModel = typeof rule === 'string' ? new Backbone.Model({ key: rule }) : rule;
this.app.layout.workspaceDetailsRegion.reset();
- this.getRuleDetails(rule).done(function () {
+ this.getRuleDetails(ruleModel).done(function (data) {
key.setScope('details');
that.app.workspaceListView.unbindScrollEvents();
- that.app.state.set({ rule: rule });
+ that.app.state.set({ rule: ruleModel });
that.app.workspaceDetailsView = new RuleDetailsView({
app: that.app,
- model: rule
+ model: ruleModel,
+ actives: data.actives
});
that.app.layout.workspaceDetailsRegion.show(that.app.workspaceDetailsView);
that.app.layout.showDetails();
], function (Backbone) {
return Backbone.Model.extend({
- idAttribute: 'key'
+ idAttribute: 'key',
+
+ addExtraAttributes: function (languages, repositories) {
+ var langName = languages[this.get('lang')] || this.get('lang'),
+ repo = _.findWhere(repositories, { key: this.get('repo') }) || this.get('repo'),
+ isManual = this.get('repo') === 'manual',
+ isCustom = this.has('templateKey');
+ this.set({
+ langName: langName,
+ repo: repo,
+ isManual: isManual,
+ isCustom: isCustom
+ });
+ }
});
});
this.forEach(function (rule, index) {
rule.set({ index: index });
});
+ },
+
+ addExtraAttributes: function (languages, repositories) {
+ this.models.forEach(function (model) {
+ model.addExtraAttributes(languages, repositories);
+ });
}
});
define([
- 'backbone.marionette',
- 'templates/coding-rules'
-], function (Marionette, Templates) {
+ 'backbone',
+ 'backbone.marionette',
+ 'templates/coding-rules',
+ 'coding-rules/rule/rule-meta-view',
+ 'coding-rules/rule/rule-description-view',
+ 'coding-rules/rule/rule-parameters-view',
+ 'coding-rules/rule/rule-profiles-view'
+], function (Backbone, Marionette, Templates, MetaView, DescView, ParamView, ProfilesView) {
- return Marionette.ItemView.extend({
+ return Marionette.Layout.extend({
template: Templates['coding-rules-rule-details'],
- modelEvents: {
- 'change': 'render'
+ regions: {
+ metaRegion: '.js-rule-meta',
+ descRegion: '.js-rule-description',
+ paramRegion: '.js-rule-parameters',
+ profilesRegion: '.js-rule-profiles'
},
initialize: function () {
this.bindShortcuts();
},
+ onRender: function () {
+ this.metaRegion.show(new MetaView({
+ app: this.options.app,
+ model: this.model
+ }));
+ this.descRegion.show(new DescView({
+ app: this.options.app,
+ model: this.model
+ }));
+ this.paramRegion.show(new ParamView({
+ app: this.options.app,
+ model: this.model
+ }));
+ this.profilesRegion.show(new ProfilesView({
+ app: this.options.app,
+ model: this.model,
+ collection: new Backbone.Collection(this.getQualityProfiles())
+ }));
+ },
+
onClose: function () {
this.unbindShortcuts();
},
+ getQualityProfiles: function () {
+ var that = this;
+ return this.options.actives.map(function (profile) {
+ var profileBase = _.findWhere(that.options.app.qualityProfiles, { key: profile.qProfile });
+ if (profileBase != null) {
+ _.extend(profile, profileBase);
+ }
+ return profile;
+ });
+ },
+
bindShortcuts: function () {
var that = this;
key('up', 'details', function () {
},
serializeData: function () {
- var isManual = (this.options.app.manualRepository().key === this.model.get('repo'));
+ var isManual = (this.options.app.manualRepository().key === this.model.get('repo')),
+ isCustom = this.model.has('templateKey'),
+ isEditable = this.options.app.canWrite && (isManual || isCustom),
+ qualityProfilesVisible = !isManual;
+
+ if (qualityProfilesVisible) {
+ if (this.model.get('isTemplate')) {
+ qualityProfilesVisible = !_.isEmpty(this.options.actives);
+ }
+ else {
+ qualityProfilesVisible = (this.options.app.canWrite || !_.isEmpty(this.options.actives));
+ }
+ }
return _.extend(Marionette.ItemView.prototype.serializeData.apply(this, arguments), {
- language: this.options.app.languages[this.model.get('lang')],
- repository: _.findWhere(this.options.app.repositories, { key: this.model.get('repo') }).name,
isManual: isManual,
+ isEditable: isEditable,
+ canWrite: this.options.app.canWrite,
+ qualityProfilesVisible: qualityProfilesVisible,
subCharacteristic: this.options.app.getSubCharacteristicName(this.model.get('debtSubChar')),
allTags: _.union(this.model.get('sysTags'), this.model.get('tags'))
});
--- /dev/null
+define([
+ 'common/modals',
+ 'templates/coding-rules'
+], function (Modal, Templates) {
+
+ var $ = jQuery;
+
+ return Modal.extend({
+ template: Templates['coding-rules-profile-activation'],
+
+ ui: {
+ qualityProfileSelect: '#coding-rules-quality-profile-activation-select',
+ qualityProfileSeverity: '#coding-rules-quality-profile-activation-severity',
+ qualityProfileActivate: '#coding-rules-quality-profile-activation-activate',
+ qualityProfileParameters: '[name]'
+ },
+
+ events: function () {
+ return _.extend(Modal.prototype.events.apply(this, arguments), {
+ 'click @ui.qualityProfileActivate': 'activate'
+ });
+ },
+
+ onRender: function () {
+ Modal.prototype.onRender.apply(this, arguments);
+
+ this.ui.qualityProfileSelect.select2({
+ width: '250px',
+ minimumResultsForSearch: 5
+ });
+
+ var format = function (state) {
+ if (!state.id) {
+ return state.text;
+ } else {
+ return '<i class="icon-severity-' + state.id.toLowerCase() + '"></i> ' + state.text;
+ }
+ },
+ severity = (this.model && this.model.get('severity')) || this.options.rule.get('severity');
+ this.ui.qualityProfileSeverity.val(severity);
+ this.ui.qualityProfileSeverity.select2({
+ width: '250px',
+ minimumResultsForSearch: 999,
+ formatResult: format,
+ formatSelection: format
+ });
+ },
+
+ activate: function () {
+ var that = this,
+ p = window.process.addBackgroundProcess(),
+ profileKey = this.ui.qualityProfileSelect.val(),
+ params = this.ui.qualityProfileParameters.map(function () {
+ return {
+ key: $(this).prop('name'),
+ value: $(this).val() || $(this).prop('placeholder') || ''
+ };
+ }).get(),
+ paramsHash = (params.map(function (param) {
+ return param.key + '=' + window.csvEscape(param.value);
+ })).join(';');
+
+ if (this.model) {
+ profileKey = this.model.get('qProfile');
+ if (!profileKey) {
+ profileKey = this.model.get('key');
+ }
+ }
+
+ var severity = this.ui.qualityProfileSeverity.val(),
+ ruleKey = this.options.rule.get('key');
+
+ this.close();
+
+ return jQuery.ajax({
+ type: 'POST',
+ url: baseUrl + '/api/qualityprofiles/activate_rule',
+ data: {
+ profile_key: profileKey,
+ rule_key: ruleKey,
+ severity: severity,
+ params: paramsHash
+ }
+ }).done(function () {
+ that.options.app.controller.showDetails(that.options.rule);
+ window.process.finishBackgroundProcess(p);
+ }).fail(function () {
+ that.options.app.controller.showDetails(that.options.rule);
+ window.process.failBackgroundProcess(p);
+ });
+ },
+
+ getAvailableQualityProfiles: function (lang) {
+ var activeQualityProfiles = this.collection,
+ inactiveProfiles = _.reject(this.options.app.qualityProfiles, function (profile) {
+ return activeQualityProfiles.findWhere({ key: profile.key });
+ });
+ return _.filter(inactiveProfiles, function (profile) {
+ return profile.lang === lang;
+ });
+ },
+
+ serializeData: function () {
+ var params = this.options.rule.get('params');
+ if (this.model != null) {
+ var modelParams = this.model.get('params');
+ if (_.isArray(modelParams)) {
+ params = params.map(function (p) {
+ var parentParam = _.findWhere(modelParams, { key: p.key });
+ if (parentParam != null) {
+ _.extend(p, { value: parentParam.value });
+ }
+ return p;
+ });
+ }
+ }
+
+ var availableProfiles = this.getAvailableQualityProfiles(this.options.rule.get('lang'));
+
+ return _.extend(Modal.prototype.serializeData.apply(this, arguments), {
+ change: this.model && this.model.has('severity'),
+ params: params,
+ qualityProfiles: availableProfiles,
+ severities: ['BLOCKER', 'CRITICAL', 'MAJOR', 'MINOR', 'INFO'],
+ saveEnabled: !_.isEmpty(availableProfiles) || (this.model && this.model.get('qProfile')),
+ isCustomRule: (this.model && this.model.has('templateKey')) || this.options.rule.has('templateKey')
+ });
+ }
+ });
+
+});
--- /dev/null
+define([
+ 'backbone.marionette',
+ 'templates/coding-rules'
+], function (Marionette, Templates) {
+
+ return Marionette.ItemView.extend({
+ template: Templates['coding-rules-rule-description'],
+
+ modelEvents: {
+ 'change': 'render'
+ },
+
+ ui: {
+ descriptionExtra: '#coding-rules-detail-description-extra',
+ extendDescriptionLink: '#coding-rules-detail-extend-description',
+ extendDescriptionForm: '.coding-rules-detail-extend-description-form',
+ extendDescriptionSubmit: '#coding-rules-detail-extend-description-submit',
+ extendDescriptionRemove: '#coding-rules-detail-extend-description-remove',
+ extendDescriptionText: '#coding-rules-detail-extend-description-text',
+ cancelExtendDescription: '#coding-rules-detail-extend-description-cancel'
+ },
+
+ events: {
+ 'click @ui.extendDescriptionLink': 'showExtendDescriptionForm',
+ 'click @ui.cancelExtendDescription': 'hideExtendDescriptionForm',
+ 'click @ui.extendDescriptionSubmit': 'submitExtendDescription',
+ 'click @ui.extendDescriptionRemove': 'removeExtendedDescription'
+ },
+
+ showExtendDescriptionForm: function () {
+ this.ui.descriptionExtra.addClass('hidden');
+ this.ui.extendDescriptionForm.removeClass('hidden');
+ this.ui.extendDescriptionText.focus();
+ },
+
+ hideExtendDescriptionForm: function () {
+ this.ui.descriptionExtra.removeClass('hidden');
+ this.ui.extendDescriptionForm.addClass('hidden');
+ },
+
+ submitExtendDescription: function () {
+ var that = this,
+ p = window.process.addBackgroundProcess();
+ this.ui.extendDescriptionForm.addClass('hidden');
+ return jQuery.ajax({
+ type: 'POST',
+ url: baseUrl + '/api/rules/update',
+ dataType: 'json',
+ data: {
+ key: this.model.get('key'),
+ markdown_note: this.ui.extendDescriptionText.val()
+ }
+ }).done(function (r) {
+ that.model.set({
+ htmlNote: r.rule.htmlNote,
+ mdNote: r.rule.mdNote
+ });
+ that.render();
+ window.process.finishBackgroundProcess(p);
+ }).fail(function () {
+ that.render();
+ window.process.failBackgroundProcess(p);
+ });
+ },
+
+ removeExtendedDescription: function () {
+ var that = this;
+ window.confirmDialog({
+ html: t('coding_rules.remove_extended_description.confirm'),
+ yesHandler: function () {
+ that.ui.extendDescriptionText.val('');
+ that.submitExtendDescription();
+ }
+ });
+ },
+
+ serializeData: function () {
+ var isEditable = this.options.app.canWrite && (this.model.get('isManual') || this.model.get('isCustom'));
+
+ return _.extend(Marionette.ItemView.prototype.serializeData.apply(this, arguments), {
+ isEditable: isEditable,
+ canWrite: this.options.app.canWrite
+ });
+ }
+ });
+
+});
--- /dev/null
+define([
+ 'backbone.marionette',
+ 'templates/coding-rules'
+], function (Marionette, Templates) {
+
+ return Marionette.ItemView.extend({
+ template: Templates['coding-rules-rule-meta'],
+
+ modelEvents: {
+ 'change': 'render'
+ },
+
+ ui: {
+ tagsChange: '.coding-rules-detail-tags-change',
+ tagInput: '.coding-rules-detail-tag-input',
+ tagsEdit: '.coding-rules-detail-tag-edit',
+ tagsEditDone: '.coding-rules-detail-tag-edit-done',
+ tagsEditCancel: '.coding-rules-details-tag-edit-cancel',
+ tagsList: '.coding-rules-detail-tag-list'
+ },
+
+ events: {
+ 'click @ui.tagsChange': 'changeTags',
+ 'click @ui.tagsEditDone': 'editDone',
+ 'click @ui.tagsEditCancel': 'cancelEdit'
+ },
+
+ requestTags: function () {
+ var url = baseUrl + '/api/rules/tags';
+ return jQuery.get(url);
+ },
+
+ changeTags: function () {
+ var that = this;
+ this.requestTags().done(function (r) {
+ that.ui.tagInput.select2({
+ tags: _.difference(_.difference(r.tags, that.model.get('tags')), that.model.get('sysTags')),
+ width: '300px'
+ });
+
+ that.ui.tagsEdit.removeClass('hidden');
+ that.ui.tagsList.addClass('hidden');
+ that.tagsBuffer = that.ui.tagInput.select2('val');
+ });
+ },
+
+ cancelEdit: function () {
+ this.ui.tagsList.removeClass('hidden');
+ this.ui.tagsEdit.addClass('hidden');
+ if (this.ui.tagInput.select2) {
+ this.ui.tagInput.select2('val', this.tagsBuffer);
+ this.ui.tagInput.select2('close');
+ }
+ },
+
+ editDone: function () {
+ var that = this,
+ p = window.process.addBackgroundProcess(),
+ tags = this.ui.tagInput.val();
+ return jQuery.ajax({
+ type: 'POST',
+ url: baseUrl + '/api/rules/update',
+ data: {
+ key: this.model.get('key'),
+ tags: tags
+ }
+ }).done(function (r) {
+ that.model.set('tags', r.rule.tags);
+ that.cancelEdit();
+ window.process.finishBackgroundProcess(p);
+ }).always(function () {
+ that.cancelEdit();
+ window.process.failBackgroundProcess(p);
+ });
+ },
+
+ serializeData: function () {
+ return _.extend(Marionette.ItemView.prototype.serializeData.apply(this, arguments), {
+ canWrite: this.options.app.canWrite,
+ subCharacteristic: this.options.app.getSubCharacteristicName(this.model.get('debtSubChar')),
+ allTags: _.union(this.model.get('sysTags'), this.model.get('tags'))
+ });
+ }
+ });
+
+});
--- /dev/null
+define([
+ 'backbone.marionette',
+ 'templates/coding-rules'
+], function (Marionette, Templates) {
+
+ return Marionette.ItemView.extend({
+ template: Templates['coding-rules-rule-parameters'],
+
+ modelEvents: {
+ 'change': 'render'
+ },
+
+ onRender: function () {
+ this.$el.toggleClass('hidden', _.isEmpty(this.model.get('params')));
+ },
+
+ serializeData: function () {
+ var isEditable = this.options.app.canWrite && (this.model.get('isManual') || this.model.get('isCustom'));
+
+ return _.extend(Marionette.ItemView.prototype.serializeData.apply(this, arguments), {
+ isEditable: isEditable,
+ canWrite: this.options.app.canWrite
+ });
+ }
+ });
+
+});
--- /dev/null
+define([
+ 'backbone.marionette',
+ 'templates/coding-rules',
+ 'coding-rules/rule/profile-activation-view'
+], function (Marionette, Templates, ProfileActivationView) {
+
+ return Marionette.ItemView.extend({
+ tagName: 'tr',
+ template: Templates['coding-rules-rule-profile'],
+
+ modelEvents: {
+ 'change': 'render'
+ },
+
+ ui: {
+ change: '.coding-rules-detail-quality-profile-change',
+ revert: '.coding-rules-detail-quality-profile-revert',
+ deactivate: '.coding-rules-detail-quality-profile-deactivate'
+ },
+
+ events: {
+ 'click @ui.change': 'change',
+ 'click @ui.revert': 'revert',
+ 'click @ui.deactivate': 'deactivate'
+ },
+
+ change: function () {
+ new ProfileActivationView({
+ model: this.model,
+ collection: this.model.collection,
+ rule: this.options.rule,
+ app: this.options.app
+ }).render();
+ },
+
+ revert: function () {
+ var that = this,
+ ruleKey = this.options.rule.get('key');
+ window.confirmDialog({
+ title: t('coding_rules.revert_to_parent_definition'),
+ html: tp('coding_rules.revert_to_parent_definition.confirm', this.getParent().name),
+ yesHandler: function () {
+ var p = window.process.addBackgroundProcess();
+ return jQuery.ajax({
+ type: 'POST',
+ url: baseUrl + '/api/qualityprofiles/activate_rule',
+ data: {
+ profile_key: that.model.get('qProfile'),
+ rule_key: ruleKey,
+ reset: true
+ }
+ }).done(function () {
+ window.process.finishBackgroundProcess(p);
+ that.options.app.controller.showDetails(that.options.rule);
+ });
+ }
+ });
+ },
+
+ deactivate: function () {
+ var that = this,
+ ruleKey = this.options.rule.get('key'),
+ myProfile = _.findWhere(this.options.app.qualityProfiles, {
+ key: this.model.get('qProfile')
+ });
+ window.confirmDialog({
+ title: t('coding_rules.deactivate'),
+ html: tp('coding_rules.deactivate.confirm', myProfile.name),
+ yesHandler: function () {
+ var p = window.process.addBackgroundProcess();
+ return jQuery.ajax({
+ type: 'POST',
+ url: baseUrl + '/api/qualityprofiles/deactivate_rule',
+ data: {
+ profile_key: that.model.get('qProfile'),
+ rule_key: ruleKey
+ }
+ }).done(function () {
+ window.process.finishBackgroundProcess(p);
+ that.options.app.controller.showDetails(that.options.rule);
+ });
+ }
+ });
+ },
+
+ enableUpdate: function () {
+ return this.ui.update.prop('disabled', false);
+ },
+
+ getParent: function () {
+ if (!(this.model.get('inherit') && this.model.get('inherit') !== 'NONE')) {
+ return null;
+ }
+ var myProfile = _.findWhere(this.options.app.qualityProfiles, {
+ key: this.model.get('qProfile')
+ }),
+ parentKey = myProfile.parentKey,
+ parent = _.extend({}, _.findWhere(this.options.app.qualityProfiles, {
+ key: parentKey
+ })),
+ parentActiveInfo = this.model.collection.findWhere({ qProfile: parentKey }) || new Backbone.Model();
+ _.extend(parent, parentActiveInfo.toJSON());
+ return parent;
+ },
+
+ enhanceParameters: function () {
+ var parent = this.getParent(),
+ params = _.sortBy(this.model.get('params'), 'key');
+ if (!parent) {
+ return params;
+ }
+ return params.map(function (p) {
+ var parentParam = _.findWhere(parent.params, { key: p.key });
+ if (parentParam != null) {
+ return _.extend(p, {
+ original: _.findWhere(parent.params, { key: p.key }).value
+ });
+ } else {
+ return p;
+ }
+ });
+ },
+
+ serializeData: function () {
+ return _.extend(Marionette.ItemView.prototype.serializeData.apply(this, arguments), {
+ canWrite: this.options.app.canWrite,
+ parent: this.getParent(),
+ parameters: this.enhanceParameters(),
+ templateKey: this.options.rule.get('templateKey'),
+ isTemplate: this.options.rule.get('isTemplate')
+ });
+ }
+ });
+
+});
--- /dev/null
+define([
+ 'backbone.marionette',
+ 'templates/coding-rules',
+ 'coding-rules/rule/rule-profile-view',
+ 'coding-rules/rule/profile-activation-view'
+], function (Marionette, Templates, ProfileView, ProfileActivationView) {
+
+ return Marionette.CompositeView.extend({
+ template: Templates['coding-rules-rule-profiles'],
+ itemView: ProfileView,
+ itemViewContainer: '#coding-rules-detail-quality-profiles',
+
+ itemViewOptions: function () {
+ return {
+ app: this.options.app,
+ rule: this.model
+ };
+ },
+
+ modelEvents: {
+ 'change': 'render'
+ },
+
+ events: {
+ 'click #coding-rules-quality-profile-activate': 'activate'
+ },
+
+ activate: function () {
+ new ProfileActivationView({
+ rule: this.model,
+ collection: this.collection,
+ app: this.options.app
+ }).render();
+ },
+
+ serializeData: function () {
+ return _.extend(Marionette.ItemView.prototype.serializeData.apply(this, arguments), {
+ canWrite: this.options.app.canWrite
+ });
+ }
+ });
+
+});
.coding-rules-detail-header,
.coding-rules-detail-title {
position: relative;
- margin-bottom: @navigatorPadding;
+ margin: 1em 0;
line-height: 1.5;
- font-weight: bold;
+ font-size: @bigFontSize;
+ font-weight: 400;
}
.coding-rules-detail-header {
.coding-rules-detail-title {
display: inline-block;
- margin-top: 3 * @navigatorPadding;
- text-transform: uppercase;
+ margin-top: 2em;
}
.coding-rules-detail-permalink {
}
.coding-rules-detail-parameters {
+ width: 100%;
margin: @navigatorPadding 0 @navigatorPadding * 2;
}
.coding-rules-detail-parameter {
- margin: @navigatorPadding 0;
+
}
.coding-rules-detail-parameter-name {
- display: block;
- margin-left: 2 * @navigatorPadding;
+ width: 1px;
+ vertical-align: top;
+ padding: 5px 10px 5px 0;
font-weight: bold;
- cursor: pointer;
}
.coding-rules-detail-parameter-description {
- display: inline-block;
- text-overflow: ellipsis;
vertical-align: top;
- max-width: 75%;
- margin-left: 2 * @navigatorPadding;
- padding: @navigatorPadding;
- .box-sizing(border-box);
+ padding: 5px 5px;
.subtitle {
margin-top: @navigatorPadding;
}
.coding-rules-detail-quality-profiles {
- font-size: 0;
-}
+ line-height: 22px;
-.coding-rules-detail-quality-profile {
- margin-left: 2 * @navigatorPadding;
-}
+ td {
+ border-top: 1px solid @barBorderColor;
+ }
-.coding-rules-detail-quality-profile + .coding-rules-detail-quality-profile {
- margin-top: @navigatorPadding;
- padding-top: @navigatorPadding;
- border-top: 1px solid @navigatorBorderLightColor;
+ tr:first-child td {
+ border-top: none;
+ }
}
.coding-rules-detail-quality-profile-name {
vertical-align: top;
- width: 15%;
+ width: 1px;
+ padding: 8px 5px 8px 0;
font-weight: bold;
white-space: nowrap;
- padding-right: 5px;
}
.coding-rules-detail-quality-profile-severity {
vertical-align: top;
- width: 10%;
+ width: 1px;
+ padding: 8px 5px;
+ white-space: nowrap;
}
.coding-rules-detail-quality-profile-parameters {
vertical-align: top;
-}
-
-.coding-rules-detail-quality-profile-parameter + .coding-rules-detail-quality-profile-parameter {
- margin-top: 8px;
+ padding: 8px 5px;
}
.coding-rules-detail-quality-profile-actions {
vertical-align: top;
- width: 25%;
+ width: 1px;
+ padding: 8px 0 8px 5px;
text-align: right;
+ white-space: nowrap;
}
.coding-rules-detail-quality-profile-inheritance {
.modal {
position: fixed;
- z-index: 9100;
+ z-index: 9000;
top: 15%;
left: 50%;
margin-left: -270px;
.modal-overlay {
position: fixed;
- z-index: 9099;
+ z-index: 8999;
top: 0; bottom: 0; left: 0; right: 0;
background-color: rgba(0, 0, 0, 0.5);
}