diff options
Diffstat (limited to 'server/sonar-web/src/main/js/apps/coding-rules')
16 files changed, 78 insertions, 50 deletions
diff --git a/server/sonar-web/src/main/js/apps/coding-rules/components/CodingRulesAppContainer.js b/server/sonar-web/src/main/js/apps/coding-rules/components/CodingRulesAppContainer.js index 91b561597b9..c7bb6c70ed3 100644 --- a/server/sonar-web/src/main/js/apps/coding-rules/components/CodingRulesAppContainer.js +++ b/server/sonar-web/src/main/js/apps/coding-rules/components/CodingRulesAppContainer.js @@ -17,16 +17,26 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ +// @flow import React from 'react'; import init from '../init'; -export default class CodingRulesAppContainer extends React.Component { +export default class CodingRulesAppContainer extends React.PureComponent { + stop: ?() => void; + props: { + params: { + organizationKey?: string + } + }; + componentDidMount() { - this.stop = init(this.refs.container); + this.stop = init(this.refs.container, this.props.params.organizationKey); } componentWillUnmount() { - this.stop(); + if (this.stop) { + this.stop(); + } } render() { diff --git a/server/sonar-web/src/main/js/apps/coding-rules/init.js b/server/sonar-web/src/main/js/apps/coding-rules/init.js index f25d2ad0c10..1a92814b70c 100644 --- a/server/sonar-web/src/main/js/apps/coding-rules/init.js +++ b/server/sonar-web/src/main/js/apps/coding-rules/init.js @@ -17,6 +17,7 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ +// @flow import $ from 'jquery'; import { sortBy } from 'lodash'; import Backbone from 'backbone'; @@ -34,10 +35,14 @@ import FiltersView from './filters-view'; const App = new Marionette.Application(); -App.on('start', function(el) { - $.get(window.baseUrl + '/api/rules/app') +App.on('start', function(options: { el: HTMLElement, organization: ?string }) { + const data = options.organization ? { organization: options.organization } : {}; + $.get(window.baseUrl + '/api/rules/app', data) .done(r => { + App.canCreateCustomRule = r.canCreateCustomRule; + App.canCustomizeRule = r.canCustomizeRule; App.canWrite = r.canWrite; + App.organization = options.organization; App.qualityProfiles = sortBy(r.qualityprofiles, ['name', 'lang']); App.languages = { ...r.languages, none: 'None' }; App.qualityProfiles.forEach(profile => { @@ -47,7 +52,7 @@ App.on('start', function(el) { App.statuses = r.statuses; }) .done(() => { - this.layout = new Layout({ el }); + this.layout = new Layout({ el: options.el }); this.layout.render(); $('#footer').addClass('search-navigator-footer'); @@ -81,7 +86,7 @@ App.on('start', function(el) { }); this.layout.filtersRegion.show(this.filtersView); - key.setScope('list'); + window.key.setScope('list'); this.router = new Router({ app: this }); @@ -89,10 +94,11 @@ App.on('start', function(el) { }); }); -export default function(el) { - App.start(el); +export default function(el: HTMLElement, organization: ?string) { + App.start({ el, organization }); return () => { + // $FlowFixMe Backbone.history.stop(); App.layout.destroy(); $('#footer').removeClass('search-navigator-footer'); diff --git a/server/sonar-web/src/main/js/apps/coding-rules/rule-details-view.js b/server/sonar-web/src/main/js/apps/coding-rules/rule-details-view.js index 2fa5eb3f2f4..11ed2ef6b74 100644 --- a/server/sonar-web/src/main/js/apps/coding-rules/rule-details-view.js +++ b/server/sonar-web/src/main/js/apps/coding-rules/rule-details-view.js @@ -171,7 +171,7 @@ export default Marionette.LayoutView.extend({ serializeData() { const isCustom = this.model.has('templateKey'); - const isEditable = this.options.app.canWrite && isCustom; + const isEditable = this.options.app.canCustomizeRule && isCustom; let qualityProfilesVisible = true; if (this.model.get('isTemplate')) { @@ -182,7 +182,6 @@ export default Marionette.LayoutView.extend({ ...Marionette.ItemView.prototype.serializeData.apply(this, arguments), isEditable, qualityProfilesVisible, - canWrite: this.options.app.canWrite, allTags: union(this.model.get('sysTags'), this.model.get('tags')) }; } diff --git a/server/sonar-web/src/main/js/apps/coding-rules/rule/custom-rule-view.js b/server/sonar-web/src/main/js/apps/coding-rules/rule/custom-rule-view.js index 1a5ff0ccdfe..295590a3bcb 100644 --- a/server/sonar-web/src/main/js/apps/coding-rules/rule/custom-rule-view.js +++ b/server/sonar-web/src/main/js/apps/coding-rules/rule/custom-rule-view.js @@ -47,7 +47,7 @@ export default Marionette.ItemView.extend({ serializeData() { return { ...Marionette.ItemView.prototype.serializeData.apply(this, arguments), - canWrite: this.options.app.canWrite, + canDeleteCustomRule: this.options.app.canCreateCustomRule, templateRule: this.options.templateRule, permalink: window.baseUrl + '/coding_rules/#rule_key=' + encodeURIComponent(this.model.id) }; diff --git a/server/sonar-web/src/main/js/apps/coding-rules/rule/custom-rules-view.js b/server/sonar-web/src/main/js/apps/coding-rules/rule/custom-rules-view.js index e8f9c0752c1..d6ec8a461cd 100644 --- a/server/sonar-web/src/main/js/apps/coding-rules/rule/custom-rules-view.js +++ b/server/sonar-web/src/main/js/apps/coding-rules/rule/custom-rules-view.js @@ -56,7 +56,7 @@ export default Marionette.CompositeView.extend({ serializeData() { return { ...Marionette.ItemView.prototype.serializeData.apply(this, arguments), - canWrite: this.options.app.canWrite + canCreateCustomRule: this.options.app.canCreateCustomRule }; } }); diff --git a/server/sonar-web/src/main/js/apps/coding-rules/rule/rule-description-view.js b/server/sonar-web/src/main/js/apps/coding-rules/rule/rule-description-view.js index 62d516c543d..0e942ef4bfb 100644 --- a/server/sonar-web/src/main/js/apps/coding-rules/rule/rule-description-view.js +++ b/server/sonar-web/src/main/js/apps/coding-rules/rule/rule-description-view.js @@ -94,12 +94,10 @@ export default Marionette.ItemView.extend({ }, serializeData() { - const isEditable = this.options.app.canWrite && this.model.get('isCustom'); - return { ...Marionette.ItemView.prototype.serializeData.apply(this, arguments), - isEditable, - canWrite: this.options.app.canWrite + isCustom: this.model.get('isCustom'), + canCustomizeRule: this.options.app.canCustomizeRule }; } }); diff --git a/server/sonar-web/src/main/js/apps/coding-rules/rule/rule-issues-view.js b/server/sonar-web/src/main/js/apps/coding-rules/rule/rule-issues-view.js index d13deae57e0..384270c2919 100644 --- a/server/sonar-web/src/main/js/apps/coding-rules/rule/rule-issues-view.js +++ b/server/sonar-web/src/main/js/apps/coding-rules/rule/rule-issues-view.js @@ -20,6 +20,7 @@ import $ from 'jquery'; import Marionette from 'backbone.marionette'; import Template from '../templates/rule/coding-rules-rule-issues.hbs'; +import { getComponentIssuesUrl } from '../../../helpers/urls'; export default Marionette.ItemView.extend({ template: Template, @@ -34,7 +35,6 @@ export default Marionette.ItemView.extend({ }, requestIssues() { - const that = this; const url = window.baseUrl + '/api/issues/search'; const options = { rules: this.model.id, @@ -42,6 +42,10 @@ export default Marionette.ItemView.extend({ ps: 1, facets: 'projectUuids' }; + const { organization } = this.options.app; + if (organization) { + Object.assign(options, { organization }); + } return $.get(url, options).done(r => { const projectsFacet = r.facets.find(facet => facet.property === 'projectUuids'); let projects = projectsFacet != null ? projectsFacet.values : []; @@ -49,11 +53,16 @@ export default Marionette.ItemView.extend({ const projectBase = r.components.find(component => component.uuid === project.val); return { ...project, - name: projectBase != null ? projectBase.longName : '' + name: projectBase != null ? projectBase.longName : '', + issuesUrl: projectBase != null && + getComponentIssuesUrl(projectBase.key, { + resolved: 'false', + rules: this.model.id + }) }; }); - that.projects = projects; - that.total = r.total; + this.projects = projects; + this.total = r.total; }); }, @@ -61,10 +70,7 @@ export default Marionette.ItemView.extend({ return { ...Marionette.ItemView.prototype.serializeData.apply(this, arguments), total: this.total, - projects: this.projects, - baseSearchUrl: window.baseUrl + - '/issues/search#resolved=false|rules=' + - encodeURIComponent(this.model.id) + projects: this.projects }; } }); diff --git a/server/sonar-web/src/main/js/apps/coding-rules/rule/rule-meta-view.js b/server/sonar-web/src/main/js/apps/coding-rules/rule/rule-meta-view.js index ba8ed5311ba..0a0b22ade85 100644 --- a/server/sonar-web/src/main/js/apps/coding-rules/rule/rule-meta-view.js +++ b/server/sonar-web/src/main/js/apps/coding-rules/rule/rule-meta-view.js @@ -106,11 +106,15 @@ export default Marionette.ItemView.extend(RuleFilterMixin).extend({ }, serializeData() { + const permalinkPath = this.options.app.organization + ? `/organizations/${this.options.app.organization}/rules` + : '/coding_rules'; + return { ...Marionette.ItemView.prototype.serializeData.apply(this, arguments), - canWrite: this.options.app.canWrite, + canCustomizeRule: this.options.app.canCustomizeRule, allTags: union(this.model.get('sysTags'), this.model.get('tags')), - permalink: window.baseUrl + '/coding_rules#rule_key=' + encodeURIComponent(this.model.id) + permalink: window.baseUrl + permalinkPath + '#rule_key=' + encodeURIComponent(this.model.id) }; } }); diff --git a/server/sonar-web/src/main/js/apps/coding-rules/rule/rule-parameters-view.js b/server/sonar-web/src/main/js/apps/coding-rules/rule/rule-parameters-view.js index 8923b74d374..209860ab4cd 100644 --- a/server/sonar-web/src/main/js/apps/coding-rules/rule/rule-parameters-view.js +++ b/server/sonar-web/src/main/js/apps/coding-rules/rule/rule-parameters-view.js @@ -30,15 +30,5 @@ export default Marionette.ItemView.extend({ onRender() { const params = this.model.get('params'); this.$el.toggleClass('hidden', params == null || params.length === 0); - }, - - serializeData() { - const isEditable = this.options.app.canWrite && this.model.get('isCustom'); - - return { - ...Marionette.ItemView.prototype.serializeData.apply(this, arguments), - isEditable, - canWrite: this.options.app.canWrite - }; } }); diff --git a/server/sonar-web/src/main/js/apps/coding-rules/rule/rule-profile-view.js b/server/sonar-web/src/main/js/apps/coding-rules/rule/rule-profile-view.js index eab8d1be804..8120484ae41 100644 --- a/server/sonar-web/src/main/js/apps/coding-rules/rule/rule-profile-view.js +++ b/server/sonar-web/src/main/js/apps/coding-rules/rule/rule-profile-view.js @@ -123,6 +123,9 @@ export default Marionette.ItemView.extend({ const myProfile = this.options.app.qualityProfiles.find( p => p.key === this.model.get('qProfile') ); + if (!myProfile) { + return null; + } const parentKey = myProfile.parentKey; const parent = { ...this.options.app.qualityProfiles.find(p => p.key === parentKey) }; const parentActiveInfo = this.model.collection.findWhere({ qProfile: parentKey }) || @@ -147,14 +150,26 @@ export default Marionette.ItemView.extend({ }); }, + getProfilePath(profileKey) { + const { organization } = this.options.app; + const encodedKey = encodeURIComponent(profileKey); + return organization + ? `${window.baseUrl}/organizations/${organization}/quality_profiles/show?key=${encodedKey}` + : `${window.baseUrl}/profiles/show?key=${encodedKey}`; + }, + serializeData() { + const parent = this.getParent(); + return { ...Marionette.ItemView.prototype.serializeData.apply(this, arguments), + parent, canWrite: this.options.app.canWrite, - parent: this.getParent(), parameters: this.enhanceParameters(), templateKey: this.options.rule.get('templateKey'), - isTemplate: this.options.rule.get('isTemplate') + isTemplate: this.options.rule.get('isTemplate'), + profilePath: this.getProfilePath(this.model.get('key')), + parentProfilePath: parent && this.getProfilePath(parent.key) }; } }); diff --git a/server/sonar-web/src/main/js/apps/coding-rules/templates/rule/coding-rules-custom-rule.hbs b/server/sonar-web/src/main/js/apps/coding-rules/templates/rule/coding-rules-custom-rule.hbs index b5371ee37f3..eaff503fc17 100644 --- a/server/sonar-web/src/main/js/apps/coding-rules/templates/rule/coding-rules-custom-rule.hbs +++ b/server/sonar-web/src/main/js/apps/coding-rules/templates/rule/coding-rules-custom-rule.hbs @@ -17,7 +17,7 @@ </td> -{{#if canWrite}} +{{#if canDeleteCustomRule}} <td class="coding-rules-detail-list-actions"> <div class="button-group"> <button class="js-delete-custom-rule button-red"> diff --git a/server/sonar-web/src/main/js/apps/coding-rules/templates/rule/coding-rules-custom-rules.hbs b/server/sonar-web/src/main/js/apps/coding-rules/templates/rule/coding-rules-custom-rules.hbs index 36a79d1951a..bd3899109cf 100644 --- a/server/sonar-web/src/main/js/apps/coding-rules/templates/rule/coding-rules-custom-rules.hbs +++ b/server/sonar-web/src/main/js/apps/coding-rules/templates/rule/coding-rules-custom-rules.hbs @@ -3,7 +3,7 @@ <h3 class="coding-rules-detail-title">{{t 'coding_rules.custom_rules'}}</h3> - {{#if canWrite}} + {{#if canCreateCustomRule}} <div class="button-group coding-rules-detail-quality-profiles-activation"> <button class="js-create-custom-rule">{{t 'coding_rules.create'}}</button> </div> diff --git a/server/sonar-web/src/main/js/apps/coding-rules/templates/rule/coding-rules-rule-description.hbs b/server/sonar-web/src/main/js/apps/coding-rules/templates/rule/coding-rules-rule-description.hbs index 3b86bc6d54e..d0ab5457eeb 100644 --- a/server/sonar-web/src/main/js/apps/coding-rules/templates/rule/coding-rules-rule-description.hbs +++ b/server/sonar-web/src/main/js/apps/coding-rules/templates/rule/coding-rules-rule-description.hbs @@ -1,19 +1,19 @@ <div class="coding-rules-detail-description rule-desc markdown">{{{htmlDesc}}}</div> -{{#unless isEditable}} +{{#unless isCustom}} <div class="coding-rules-detail-description coding-rules-detail-description-extra"> <div id="coding-rules-detail-description-extra"> {{#if htmlNote}} <div class="rule-desc spacer-bottom markdown">{{{htmlNote}}}</div> {{/if}} - {{#if canWrite}} + {{#if canCustomizeRule}} <div class="button-group"> <button id="coding-rules-detail-extend-description">{{t 'coding_rules.extend_description'}}</button> </div> {{/if}} </div> - {{#if canWrite}} + {{#if canCustomizeRule}} <div class="coding-rules-detail-extend-description-form hidden"> <table class="width100"> <tbody> diff --git a/server/sonar-web/src/main/js/apps/coding-rules/templates/rule/coding-rules-rule-issues.hbs b/server/sonar-web/src/main/js/apps/coding-rules/templates/rule/coding-rules-rule-issues.hbs index da9a5336d36..f6dc9fe7619 100644 --- a/server/sonar-web/src/main/js/apps/coding-rules/templates/rule/coding-rules-rule-issues.hbs +++ b/server/sonar-web/src/main/js/apps/coding-rules/templates/rule/coding-rules-rule-issues.hbs @@ -1,7 +1,7 @@ <div class="coding-rule-section-separator"></div> <h3 class="coding-rules-detail-title"> - {{t 'coding_rules.issues'}} (<a class="js-rule-issues" href="{{baseSearchUrl}}">{{total}}</a>) + {{t 'coding_rules.issues'}} ({{total}}) </h3> {{#notEmpty projects}} @@ -13,7 +13,7 @@ <tr> <td class="coding-rules-detail-list-name">{{name}}</td> <td class="coding-rules-detail-list-parameters"> - <a href="{{../baseSearchUrl}}|projectUuids={{val}}" target="_blank">{{count}}</a> + <a href="{{issuesUrl}}" target="_blank">{{count}}</a> </td> </tr> {{/each}} diff --git a/server/sonar-web/src/main/js/apps/coding-rules/templates/rule/coding-rules-rule-meta.hbs b/server/sonar-web/src/main/js/apps/coding-rules/templates/rule/coding-rules-rule-meta.hbs index fc38adfff0c..255f97fea08 100644 --- a/server/sonar-web/src/main/js/apps/coding-rules/templates/rule/coding-rules-rule-meta.hbs +++ b/server/sonar-web/src/main/js/apps/coding-rules/templates/rule/coding-rules-rule-meta.hbs @@ -34,14 +34,14 @@ </li> {{/notEq}} - <li class="coding-rules-detail-property coding-rules-detail-tag-list {{#if canWrite}}coding-rules-detail-tags-change{{/if}}" + <li class="coding-rules-detail-property coding-rules-detail-tag-list {{#if canCustomizeRule}}coding-rules-detail-tags-change{{/if}}" data-toggle="tooltip" data-placement="bottom" title="Rule tags"> <i class="icon-tags"></i> <span>{{#if allTags}}{{join allTags ', '}}{{else}}{{t 'coding_rules.no_tags'}}{{/if}}</span> {{#if canWrite}}<i class="icon-dropdown"></i>{{/if}} </li> - {{#if canWrite}} + {{#if canCustomizeRule}} <li class="coding-rules-detail-property coding-rules-detail-tag-edit hidden"> {{#if sysTags}}<i class="icon-tags"></i> <span>{{join sysTags ', '}}</span>{{/if}} diff --git a/server/sonar-web/src/main/js/apps/coding-rules/templates/rule/coding-rules-rule-profile.hbs b/server/sonar-web/src/main/js/apps/coding-rules/templates/rule/coding-rules-rule-profile.hbs index 929a1e6d454..12d1fe950d5 100644 --- a/server/sonar-web/src/main/js/apps/coding-rules/templates/rule/coding-rules-rule-profile.hbs +++ b/server/sonar-web/src/main/js/apps/coding-rules/templates/rule/coding-rules-rule-profile.hbs @@ -1,5 +1,5 @@ <td class="coding-rules-detail-quality-profile-name"> - <a href="{{profileUrl key}}"> + <a href="{{profilePath}}"> {{name}} </a> {{#if parent}} @@ -10,7 +10,7 @@ {{#eq inherit 'INHERITED'}} <i class="icon-inheritance" title="{{tp 'coding_rules.inherits' name parent.name}}"></i> {{/eq}} - <a class="link-base-color" href="{{profileUrl parent.key}}"> + <a class="link-base-color" href="{{parentProfilePath}}"> {{parent.name}} </a> </div> |