summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStas Vilchik <vilchiks@gmail.com>2014-12-24 17:18:45 +0100
committerStas Vilchik <vilchiks@gmail.com>2014-12-24 17:18:45 +0100
commitc158c1b03e2fbc205a310e2fc8b20c35ec4ccbad (patch)
tree3e1c46a6870ee424d506f21722580f08c28e020c
parent008a6d3ea04cacebbc2e7b5efdfddcfa024eb48e (diff)
downloadsonarqube-c158c1b03e2fbc205a310e2fc8b20c35ec4ccbad.tar.gz
sonarqube-c158c1b03e2fbc205a310e2fc8b20c35ec4ccbad.zip
SONAR-5820 Provide a permalink on each rule description
-rw-r--r--server/sonar-web/Gruntfile.coffee4
-rw-r--r--server/sonar-web/src/main/coffee/issue/views/rule-overlay.coffee2
-rw-r--r--server/sonar-web/src/main/hbs/coding-rules/rule/coding-rules-rule-meta.hbs2
-rw-r--r--server/sonar-web/src/main/js/coding-rules/rule-details-view.js1
-rw-r--r--server/sonar-web/src/main/js/coding-rules/rule/rule-meta-view.js3
-rw-r--r--server/sonar-web/src/main/js/coding-rules/show-app.js94
-rw-r--r--server/sonar-web/src/main/js/tests/e2e/tests/coding-rules-page-rule-permalink/app.json168
-rw-r--r--server/sonar-web/src/main/js/tests/e2e/tests/coding-rules-page-rule-permalink/search.json171
-rw-r--r--server/sonar-web/src/main/js/tests/e2e/tests/coding-rules-page-rule-permalink/show.json76
-rw-r--r--server/sonar-web/src/main/js/tests/e2e/tests/coding-rules-page-rule-should-have-permalink.js36
-rw-r--r--server/sonar-web/src/main/less/components/rules.less4
-rw-r--r--server/sonar-web/src/main/webapp/WEB-INF/app/controllers/coding_rules_controller.rb5
-rw-r--r--server/sonar-web/src/main/webapp/WEB-INF/app/views/coding_rules/show.html.erb6
13 files changed, 569 insertions, 3 deletions
diff --git a/server/sonar-web/Gruntfile.coffee b/server/sonar-web/Gruntfile.coffee
index 736f83885b8..4e00555ddfa 100644
--- a/server/sonar-web/Gruntfile.coffee
+++ b/server/sonar-web/Gruntfile.coffee
@@ -174,6 +174,10 @@ module.exports = (grunt) ->
name: 'coding-rules/app'
out: '<%= pkg.assets %>build/js/coding-rules/app.js'
+ codingRulesShow: options:
+ name: 'coding-rules/app'
+ out: '<%= pkg.assets %>build/js/coding-rules/show-app.js'
+
codingRulesOld: options:
name: 'coding-rules-old/app'
out: '<%= pkg.assets %>build/js/coding-rules-old/app.js'
diff --git a/server/sonar-web/src/main/coffee/issue/views/rule-overlay.coffee b/server/sonar-web/src/main/coffee/issue/views/rule-overlay.coffee
index 78415e338e0..54d13bd8f0a 100644
--- a/server/sonar-web/src/main/coffee/issue/views/rule-overlay.coffee
+++ b/server/sonar-web/src/main/coffee/issue/views/rule-overlay.coffee
@@ -12,5 +12,5 @@ define [
serializeData: ->
_.extend super,
- permalink: "#{baseUrl}/coding_rules#rule_key=#{@model.get('key')}"
+ permalink: "#{baseUrl}/coding_rules/show?key=#{encodeURIComponent @model.get('key')}"
allTags: _.union @model.get('sysTags'), @model.get('tags')
diff --git a/server/sonar-web/src/main/hbs/coding-rules/rule/coding-rules-rule-meta.hbs b/server/sonar-web/src/main/hbs/coding-rules/rule/coding-rules-rule-meta.hbs
index 44cd94a7adf..383258b9bbb 100644
--- a/server/sonar-web/src/main/hbs/coding-rules/rule/coding-rules-rule-meta.hbs
+++ b/server/sonar-web/src/main/hbs/coding-rules/rule/coding-rules-rule-meta.hbs
@@ -1,6 +1,6 @@
<h3 class="coding-rules-detail-header">
{{name}}
- <a class="coding-rules-detail-permalink icon-link" target="_blank" href="#rule_key={{key}}"></a>
+ <a class="coding-rules-detail-permalink icon-link" target="_blank" href="{{permalink}}"></a>
</h3>
<span class="subtitle">{{key}}</span>
diff --git a/server/sonar-web/src/main/js/coding-rules/rule-details-view.js b/server/sonar-web/src/main/js/coding-rules/rule-details-view.js
index 2e41d7663fa..051413e679f 100644
--- a/server/sonar-web/src/main/js/coding-rules/rule-details-view.js
+++ b/server/sonar-web/src/main/js/coding-rules/rule-details-view.js
@@ -9,6 +9,7 @@ define([
], function (Backbone, Marionette, Templates, MetaView, DescView, ParamView, ProfilesView) {
return Marionette.Layout.extend({
+ className: 'coding-rule-details',
template: Templates['coding-rules-rule-details'],
regions: {
diff --git a/server/sonar-web/src/main/js/coding-rules/rule/rule-meta-view.js b/server/sonar-web/src/main/js/coding-rules/rule/rule-meta-view.js
index 6f3c3c36700..e01fa1d2942 100644
--- a/server/sonar-web/src/main/js/coding-rules/rule/rule-meta-view.js
+++ b/server/sonar-web/src/main/js/coding-rules/rule/rule-meta-view.js
@@ -78,7 +78,8 @@ define([
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'))
+ allTags: _.union(this.model.get('sysTags'), this.model.get('tags')),
+ permalink: baseUrl + '/coding_rules/show?key=' + encodeURIComponent(this.model.id)
});
}
});
diff --git a/server/sonar-web/src/main/js/coding-rules/show-app.js b/server/sonar-web/src/main/js/coding-rules/show-app.js
new file mode 100644
index 00000000000..ee68beb0df4
--- /dev/null
+++ b/server/sonar-web/src/main/js/coding-rules/show-app.js
@@ -0,0 +1,94 @@
+requirejs.config({
+ baseUrl: baseUrl + '/js',
+
+ paths: {
+ 'backbone': 'third-party/backbone',
+ 'backbone.marionette': 'third-party/backbone.marionette',
+ 'handlebars': 'third-party/handlebars'
+ },
+
+ shim: {
+ 'backbone.marionette': {
+ deps: ['backbone'],
+ exports: 'Marionette'
+ },
+ 'backbone': {
+ exports: 'Backbone'
+ },
+ 'handlebars': {
+ exports: 'Handlebars'
+ }
+ }
+});
+
+
+requirejs([
+ 'backbone',
+ 'backbone.marionette',
+
+ 'coding-rules/models/rule',
+ 'coding-rules/rule-details-view',
+
+ 'common/handlebars-extensions'
+],
+ function (Backbone,
+ Marionette,
+ Rule,
+ RuleDetailsView) {
+
+ var $ = jQuery,
+ App = new Marionette.Application(),
+ p = window.process.addBackgroundProcess();
+
+ App.addInitializer(function () {
+ var url = baseUrl + '/api/rules/show',
+ key = decodeURIComponent(window.location.search.substr(5)),
+ options = {
+ key: key,
+ actives: true
+ };
+ $.get(url, options).done(function (data) {
+ this.ruleDetailsView = new RuleDetailsView({
+ app: App,
+ model: new Rule(data.rule),
+ actives: data.actives
+ });
+ this.ruleDetailsView.render().$el.appendTo($('.page'));
+ window.process.finishBackgroundProcess(p);
+ }).fail(function () {
+ window.process.failBackgroundProcess(p);
+ });
+ });
+
+ App.manualRepository = function () {
+ return {
+ key: 'manual',
+ name: t('coding_rules.manual_rules'),
+ language: 'none'
+ };
+ };
+
+ App.getSubCharacteristicName = function (name) {
+ return (App.characteristics[name] || '').replace(': ', ' > ');
+ };
+
+ var appXHR = $.get(baseUrl + '/api/rules/app').done(function(r) {
+ App.canWrite = r.canWrite;
+ App.qualityProfiles = _.sortBy(r.qualityprofiles, ['name', 'lang']);
+ App.languages = _.extend(r.languages, {
+ none: 'None'
+ });
+ _.map(App.qualityProfiles, function(profile) {
+ profile.language = App.languages[profile.lang];
+ });
+ App.repositories = r.repositories;
+ App.repositories.push(App.manualRepository());
+ App.statuses = r.statuses;
+ App.characteristics = r.characteristics;
+ });
+
+ $.when(window.requestMessages(), appXHR).done(function () {
+ App.start();
+ });
+
+ });
diff --git a/server/sonar-web/src/main/js/tests/e2e/tests/coding-rules-page-rule-permalink/app.json b/server/sonar-web/src/main/js/tests/e2e/tests/coding-rules-page-rule-permalink/app.json
new file mode 100644
index 00000000000..4f3319c8707
--- /dev/null
+++ b/server/sonar-web/src/main/js/tests/e2e/tests/coding-rules-page-rule-permalink/app.json
@@ -0,0 +1,168 @@
+{
+ "canWrite": false,
+ "qualityprofiles": [
+ {
+ "key": "java-default-with-mojo-conventions-49307",
+ "name": "Default - Maven Conventions",
+ "lang": "java",
+ "parentKey": "java-top-profile-without-formatting-conventions-50037"
+ },
+ {
+ "key": "java-default-with-sonarsource-conventions-27339",
+ "name": "Default - SonarSource conventions",
+ "lang": "java",
+ "parentKey": "java-top-profile-without-formatting-conventions-50037"
+ },
+ {
+ "key": "java-top-profile-without-formatting-conventions-50037",
+ "name": "Default - Top",
+ "lang": "java"
+ },
+ {
+ "key": "java-findbugs-14954",
+ "name": "FindBugs",
+ "lang": "java"
+ },
+ {
+ "key": "java-for-sq-java-plugin-only-92289",
+ "name": "For SQ Java Plugin Only",
+ "lang": "java",
+ "parentKey": "java-default-with-sonarsource-conventions-27339"
+ },
+ {
+ "key": "java-for-sq-only-95381",
+ "name": "For SQ Only",
+ "lang": "java",
+ "parentKey": "java-default-with-sonarsource-conventions-27339"
+ },
+ {
+ "key": "php-psr-2-06315",
+ "name": "PSR-2",
+ "lang": "php"
+ },
+ {
+ "key": "java-sonar-way-80423",
+ "name": "Sonar way",
+ "lang": "java"
+ },
+ {
+ "key": "js-sonar-way",
+ "name": "Sonar way",
+ "lang": "js"
+ },
+ {
+ "key": "php-sonar-way-05548",
+ "name": "Sonar way",
+ "lang": "php"
+ },
+ {
+ "key": "py-sonar-way-80265",
+ "name": "Sonar way",
+ "lang": "py"
+ },
+ {
+ "key": "java-without-findbugs",
+ "name": "Without Findbugs",
+ "lang": "java"
+ }
+ ],
+ "languages": {
+ "py": "Python",
+ "js": "JavaScript",
+ "php": "PHP",
+ "java": "Java"
+ },
+ "repositories": [
+ {
+ "key": "common-java",
+ "name": "Common SonarQube",
+ "language": "java"
+ },
+ {
+ "key": "common-js",
+ "name": "Common SonarQube",
+ "language": "js"
+ },
+ {
+ "key": "common-php",
+ "name": "Common SonarQube",
+ "language": "php"
+ },
+ {
+ "key": "common-py",
+ "name": "Common SonarQube",
+ "language": "py"
+ },
+ {
+ "key": "Pylint",
+ "name": "Pylint",
+ "language": "py"
+ },
+ {
+ "key": "javascript",
+ "name": "SonarQube",
+ "language": "js"
+ },
+ {
+ "key": "php",
+ "name": "SonarQube",
+ "language": "php"
+ },
+ {
+ "key": "python",
+ "name": "SonarQube",
+ "language": "py"
+ },
+ {
+ "key": "squid",
+ "name": "SonarQube",
+ "language": "java"
+ }
+ ],
+ "statuses": {
+ "BETA": "Beta",
+ "DEPRECATED": "Deprecated",
+ "READY": "Ready"
+ },
+ "characteristics": {
+ "UNDERSTANDABILITY": "Maintainability: Understandability",
+ "MAINTAINABILITY": "Maintainability",
+ "TIME_ZONE_RELATED_PORTABILITY": "Portability: Time zone related portability",
+ "READABILITY": "Maintainability: Readability",
+ "SECURITY_FEATURES": "Security: Security features",
+ "ARCHITECTURE_RELIABILITY": "Reliability: Architecture related reliability",
+ "OS_RELATED_PORTABILITY": "Portability: OS related portability",
+ "EXCEPTION_HANDLING": "Reliability: Exception handling",
+ "LOGIC_CHANGEABILITY": "Changeability: Logic related changeability",
+ "SOFTWARE_RELATED_PORTABILITY": "Portability: Software related portability",
+ "INPUT_VALIDATION_AND_REPRESENTATION": "Security: Input validation and representation",
+ "LANGUAGE_RELATED_PORTABILITY": "Portability: Language related portability",
+ "ERRORS": "Security: Errors",
+ "SECURITY": "Security",
+ "RELIABILITY": "Reliability",
+ "PORTABILITY": "Portability",
+ "HARDWARE_RELATED_PORTABILITY": "Portability: Hardware related portability",
+ "SYNCHRONIZATION_RELIABILITY": "Reliability: Synchronization related reliability",
+ "TRANSPORTABILITY": "Reusability: Transportability",
+ "COMPILER_RELATED_PORTABILITY": "Portability: Compiler related portability",
+ "RESOURCE_RELIABILITY": "Reliability: Resource",
+ "CPU_EFFICIENCY": "Efficiency: Processor use",
+ "EFFICIENCY": "Efficiency",
+ "CHANGEABILITY": "Changeability",
+ "DATA_CHANGEABILITY": "Changeability: Data related changeability",
+ "API_ABUSE": "Security: API abuse",
+ "ARCHITECTURE_CHANGEABILITY": "Changeability: Architecture related changeability",
+ "UNIT_TESTS": "Reliability: Unit tests",
+ "INSTRUCTION_RELIABILITY": "Reliability: Instruction related reliability",
+ "REUSABILITY": "Reusability",
+ "MODULARITY": "Reusability: Modularity",
+ "UNIT_TESTABILITY": "Testability: Unit level testability",
+ "TESTABILITY": "Testability",
+ "INTEGRATION_TESTABILITY": "Testability: Integration level testability",
+ "NETWORK_USE": "Efficiency: Network use",
+ "MEMORY_EFFICIENCY": "Efficiency: Memory use",
+ "DATA_RELIABILITY": "Reliability: Data related reliability",
+ "FAULT_TOLERANCE": "Reliability: Fault tolerance",
+ "LOGIC_RELIABILITY": "Reliability: Logic related reliability"
+ }
+}
diff --git a/server/sonar-web/src/main/js/tests/e2e/tests/coding-rules-page-rule-permalink/search.json b/server/sonar-web/src/main/js/tests/e2e/tests/coding-rules-page-rule-permalink/search.json
new file mode 100644
index 00000000000..b5a6bc269b9
--- /dev/null
+++ b/server/sonar-web/src/main/js/tests/e2e/tests/coding-rules-page-rule-permalink/search.json
@@ -0,0 +1,171 @@
+{
+ "total": 10,
+ "p": 1,
+ "ps": 200,
+ "rules": [
+ {
+ "key": "squid:S1181",
+ "name": "Throwable and Error classes should not be caught",
+ "lang": "java",
+ "langName": "Java",
+ "sysTags": [
+ "error-handling"
+ ],
+ "tags": []
+ },
+ {
+ "key": "squid:S1849",
+ "name": "\"Iterator.hasNext()\" should not call \"Iterator.next()\"",
+ "lang": "java",
+ "langName": "Java",
+ "sysTags": [
+ "bug"
+ ],
+ "tags": []
+ },
+ {
+ "key": "squid:S1844",
+ "name": "\"Object.wait(...)\" should never be called on objects that implement \"java.util.concurrent.locks.Condition\"",
+ "lang": "java",
+ "langName": "Java",
+ "sysTags": [
+ "bug",
+ "pitfall"
+ ],
+ "tags": []
+ },
+ {
+ "key": "squid:S2258",
+ "name": "\"javax.crypto.NullCipher\" should not be used for anything other than testing",
+ "lang": "java",
+ "langName": "Java",
+ "sysTags": [
+ "cwe",
+ "owasp-top10",
+ "security"
+ ],
+ "tags": []
+ },
+ {
+ "key": "squid:S2251",
+ "name": "A \"for\" loop update clause should move the counter in the right direction",
+ "lang": "java",
+ "langName": "Java",
+ "sysTags": [
+ "bug"
+ ],
+ "tags": []
+ },
+ {
+ "key": "squid:ObjectFinalizeOverridenCallsSuperFinalizeCheck",
+ "name": "super.finalize() should be called at the end of Object.finalize() implementations",
+ "lang": "java",
+ "langName": "Java",
+ "sysTags": [
+ "bug"
+ ],
+ "tags": []
+ },
+ {
+ "key": "squid:S1143",
+ "name": "Return statements should not occur in finally blocks",
+ "lang": "java",
+ "langName": "Java",
+ "sysTags": [
+ "bug"
+ ],
+ "tags": []
+ },
+ {
+ "key": "squid:S1206",
+ "name": "\"equals(Object obj)\" and \"hashCode()\" should be overridden in pairs",
+ "lang": "java",
+ "langName": "Java",
+ "sysTags": [
+ "bug"
+ ],
+ "tags": []
+ },
+ {
+ "key": "squid:S1451",
+ "name": "Copyright and license headers should be defined in all source files",
+ "lang": "java",
+ "langName": "Java",
+ "sysTags": [
+ "convention"
+ ],
+ "tags": []
+ },
+ {
+ "key": "squid:S1697",
+ "name": "Short-circuit logic should be used to prevent null pointer dereferences in conditionals",
+ "lang": "java",
+ "langName": "Java",
+ "sysTags": [
+ "bug"
+ ],
+ "tags": []
+ }
+ ],
+ "facets": [
+ {
+ "property": "tags",
+ "values": [
+ {
+ "val": "bug",
+ "count": 7
+ },
+ {
+ "val": "convention",
+ "count": 1
+ },
+ {
+ "val": "cwe",
+ "count": 1
+ },
+ {
+ "val": "error-handling",
+ "count": 1
+ },
+ {
+ "val": "owasp-top10",
+ "count": 1
+ },
+ {
+ "val": "pitfall",
+ "count": 1
+ },
+ {
+ "val": "security",
+ "count": 1
+ }
+ ]
+ },
+ {
+ "property": "languages",
+ "values": [
+ {
+ "val": "java",
+ "count": 10
+ },
+ {
+ "val": "js",
+ "count": 6
+ },
+ {
+ "val": "php",
+ "count": 2
+ }
+ ]
+ },
+ {
+ "property": "repositories",
+ "values": [
+ {
+ "val": "squid",
+ "count": 10
+ }
+ ]
+ }
+ ]
+}
diff --git a/server/sonar-web/src/main/js/tests/e2e/tests/coding-rules-page-rule-permalink/show.json b/server/sonar-web/src/main/js/tests/e2e/tests/coding-rules-page-rule-permalink/show.json
new file mode 100644
index 00000000000..274b587bfb2
--- /dev/null
+++ b/server/sonar-web/src/main/js/tests/e2e/tests/coding-rules-page-rule-permalink/show.json
@@ -0,0 +1,76 @@
+{
+ "rule": {
+ "key": "squid:S1181",
+ "repo": "squid",
+ "name": "Throwable and Error classes should not be caught",
+ "createdAt": "2013-08-09T14:40:54+0200",
+ "severity": "BLOCKER",
+ "status": "READY",
+ "internalKey": "S1181",
+ "isTemplate": false,
+ "tags": [],
+ "sysTags": [
+ "error-handling"
+ ],
+ "lang": "java",
+ "langName": "Java",
+ "htmlDesc": "<p>\n<code>Throwable</code> is the superclass of all errors and exceptions in Java.\n<code>Error</code> is the superclass of all errors which are not meant to be caught by applications.\n</p>\n\n<p>\nCatching either <code>Throwable</code> or <code>Error</code> will also catch <code>OutOfMemoryError</code> or <code>InternalError</code> from which an application should not attempt to recover.\n</p>\n\n<p>Only <code>Exception</code> and its subclasses should be caught.</p>\n\n<h2>Noncompliant Code Example</h2>\n\n<pre>\ntry { /* ... */ } catch (Throwable t) { /* ... */ }\ntry { /* ... */ } catch (Error e) { /* ... */ } \n</pre>\n\n<h2>Compliant Solution</h2>\n\n<pre>\ntry { /* ... */ } catch (Exception e) { /* ... */ } \ntry { /* ... */ } catch (RuntimeException e) { /* ... */ } \ntry { /* ... */ } catch (MyException e) { /* ... */ } \n</pre>",
+ "defaultDebtChar": "RELIABILITY",
+ "defaultDebtSubChar": "EXCEPTION_HANDLING",
+ "debtChar": "RELIABILITY",
+ "debtSubChar": "EXCEPTION_HANDLING",
+ "debtCharName": "Reliability",
+ "debtSubCharName": "Exception handling",
+ "defaultDebtRemFnType": "CONSTANT_ISSUE",
+ "defaultDebtRemFnOffset": "20min",
+ "debtOverloaded": true,
+ "debtRemFnType": "LINEAR",
+ "debtRemFnCoeff": "20min",
+ "params": [
+ {
+ "key": "max",
+ "htmlDesc": "Maximum authorized number of parameters",
+ "type": "INTEGER",
+ "defaultValue": "7"
+ }
+ ]
+ },
+ "actives": [
+ {
+ "qProfile": "java-top-profile-without-formatting-conventions-50037",
+ "inherit": "NONE",
+ "severity": "BLOCKER",
+ "params": []
+ },
+ {
+ "qProfile": "java-default-with-sonarsource-conventions-27339",
+ "inherit": "INHERITED",
+ "severity": "BLOCKER",
+ "params": []
+ },
+ {
+ "qProfile": "java-for-sq-java-plugin-only-92289",
+ "inherit": "INHERITED",
+ "severity": "BLOCKER",
+ "params": []
+ },
+ {
+ "qProfile": "java-for-sq-only-95381",
+ "inherit": "INHERITED",
+ "severity": "BLOCKER",
+ "params": []
+ },
+ {
+ "qProfile": "java-default-with-mojo-conventions-49307",
+ "inherit": "INHERITED",
+ "severity": "BLOCKER",
+ "params": []
+ },
+ {
+ "qProfile": "java-sonar-way-80423",
+ "inherit": "NONE",
+ "severity": "BLOCKER",
+ "params": []
+ }
+ ]
+}
diff --git a/server/sonar-web/src/main/js/tests/e2e/tests/coding-rules-page-rule-should-have-permalink.js b/server/sonar-web/src/main/js/tests/e2e/tests/coding-rules-page-rule-should-have-permalink.js
new file mode 100644
index 00000000000..75898fd15fe
--- /dev/null
+++ b/server/sonar-web/src/main/js/tests/e2e/tests/coding-rules-page-rule-should-have-permalink.js
@@ -0,0 +1,36 @@
+/* global casper:false */
+
+var lib = require('../lib');
+
+lib.initMessages();
+lib.changeWorkingDirectory('coding-rules-page-rule-permalink');
+
+
+casper.test.begin('coding-rules-page-rule-permalink', 1, function (test) {
+ casper
+ .start(lib.buildUrl('coding-rules'), function () {
+ lib.setDefaultViewport();
+
+ lib.mockRequest('/api/l10n/index', '{}');
+ lib.mockRequestFromFile('/api/rules/app', 'app.json');
+ lib.mockRequestFromFile('/api/rules/search', 'search.json');
+ lib.mockRequestFromFile('/api/rules/show', 'show.json');
+ })
+
+ .then(function () {
+ casper.waitForSelector('.coding-rule.selected');
+ })
+
+ .then(function () {
+ casper.click('.coding-rule.selected .js-rule');
+ casper.waitForSelector('.coding-rules-detail-header');
+ })
+
+ .then(function () {
+ test.assertExists('a[href="/coding_rules/show?key=squid%3AS1181"]');
+ })
+
+ .run(function () {
+ test.done();
+ });
+});
diff --git a/server/sonar-web/src/main/less/components/rules.less b/server/sonar-web/src/main/less/components/rules.less
index affe5c40766..41793326f44 100644
--- a/server/sonar-web/src/main/less/components/rules.less
+++ b/server/sonar-web/src/main/less/components/rules.less
@@ -57,3 +57,7 @@
content: "";
}
}
+
+.coding-rule-details {
+ max-width: 1020px;
+}
diff --git a/server/sonar-web/src/main/webapp/WEB-INF/app/controllers/coding_rules_controller.rb b/server/sonar-web/src/main/webapp/WEB-INF/app/controllers/coding_rules_controller.rb
index cc4298b9383..04900e82a39 100644
--- a/server/sonar-web/src/main/webapp/WEB-INF/app/controllers/coding_rules_controller.rb
+++ b/server/sonar-web/src/main/webapp/WEB-INF/app/controllers/coding_rules_controller.rb
@@ -27,4 +27,9 @@ class CodingRulesController < ApplicationController
end
+ # GET /coding_rules/show
+ def show
+
+ end
+
end
diff --git a/server/sonar-web/src/main/webapp/WEB-INF/app/views/coding_rules/show.html.erb b/server/sonar-web/src/main/webapp/WEB-INF/app/views/coding_rules/show.html.erb
new file mode 100644
index 00000000000..629a4a120d0
--- /dev/null
+++ b/server/sonar-web/src/main/webapp/WEB-INF/app/views/coding_rules/show.html.erb
@@ -0,0 +1,6 @@
+<% content_for :script do %>
+ <script data-main="<%= ApplicationController.root_context -%>/js/coding-rules/show-app" src="<%= ApplicationController.root_context -%>/js/require.js"></script>
+<% end %>
+
+
+<div class="page"></div>