aboutsummaryrefslogtreecommitdiffstats
path: root/sonar-server
diff options
context:
space:
mode:
authorFabrice Bellingard <bellingard@gmail.com>2012-01-23 18:03:19 +0100
committerFabrice Bellingard <bellingard@gmail.com>2012-01-23 19:23:18 +0100
commit328abda6157af975f9251c854320f064dafa5a82 (patch)
tree3fedf2925645257438c99e0056ee59008690c632 /sonar-server
parent2044f95a1c1064f2cde28df0c33af633fdd8d8a2 (diff)
downloadsonarqube-328abda6157af975f9251c854320f064dafa5a82.tar.gz
sonarqube-328abda6157af975f9251c854320f064dafa5a82.zip
SONAR-1492 Allow notes per quality rule
Admin page implemented
Diffstat (limited to 'sonar-server')
-rw-r--r--sonar-server/src/main/webapp/WEB-INF/app/controllers/rules_configuration_controller.rb40
-rw-r--r--sonar-server/src/main/webapp/WEB-INF/app/models/active_rule_note.rb9
-rw-r--r--sonar-server/src/main/webapp/WEB-INF/app/models/rule_note.rb8
-rw-r--r--sonar-server/src/main/webapp/WEB-INF/app/views/rules_configuration/_create_rule_note.html.erb48
-rw-r--r--sonar-server/src/main/webapp/WEB-INF/app/views/rules_configuration/_rule.html.erb113
-rw-r--r--sonar-server/src/main/webapp/WEB-INF/app/views/rules_configuration/_rule_note.html.erb36
-rw-r--r--sonar-server/src/main/webapp/WEB-INF/app/views/rules_configuration/_rule_param.html.erb8
-rw-r--r--sonar-server/src/main/webapp/WEB-INF/app/views/rules_configuration/index.html.erb9
-rw-r--r--sonar-server/src/main/webapp/stylesheets/style.css24
9 files changed, 244 insertions, 51 deletions
diff --git a/sonar-server/src/main/webapp/WEB-INF/app/controllers/rules_configuration_controller.rb b/sonar-server/src/main/webapp/WEB-INF/app/controllers/rules_configuration_controller.rb
index 4fb539ecf85..b8563fb4a70 100644
--- a/sonar-server/src/main/webapp/WEB-INF/app/controllers/rules_configuration_controller.rb
+++ b/sonar-server/src/main/webapp/WEB-INF/app/controllers/rules_configuration_controller.rb
@@ -29,7 +29,9 @@ class RulesConfigurationController < ApplicationController
RULE_PRIORITIES = Sonar::RulePriority.as_options.reverse
# GETs should be safe (see http://www.w3.org/2001/tag/doc/whenToUseGet.html)
- verify :method => :post, :only => ['activate_rule', 'update_param', 'bulk_edit', 'create', 'update', 'delete', 'revert_rule'], :redirect_to => { :action => 'index' }
+ verify :method => :post,
+ :only => ['activate_rule', 'update_param', 'bulk_edit', 'create', 'update', 'delete', 'revert_rule', 'update_note', 'delete_note'],
+ :redirect_to => { :action => 'index' }
before_filter :admin_required, :except => [ 'index', 'export' ]
@@ -312,6 +314,42 @@ class RulesConfigurationController < ApplicationController
:locals => {:parameter => rule_param, :active_parameter => active_param, :profile => profile, :active_rule => active_rule, :is_admin => is_admin }
end
+
+ def update_note
+ if params[:is_active_rule]
+ rule = ActiveRule.find(params[:rule_id])
+ else
+ rule = Rule.find(params[:rule_id])
+ end
+ note = rule.note
+ unless note
+ if params[:is_active_rule]
+ note = ActiveRuleNote.new({:rule => rule})
+ else
+ note = RuleNote.new({:rule => rule})
+ end
+ # set the note on the rule to avoid reloading the rule
+ rule.note = note
+ end
+ note.text = params[:text]
+ note.user_login = current_user.login
+ note.save!
+ render :partial => 'rule_note', :locals => {:rule => rule, :is_admin => true, :is_active_rule => params[:is_active_rule] }
+ end
+
+
+ def delete_note
+ if params[:is_active_rule]
+ rule = ActiveRule.find(params[:rule_id])
+ else
+ rule = Rule.find(params[:rule_id])
+ end
+ rule.note.destroy if rule.note
+ render :text => ''
+ end
+
+
+
private
# return the number of newly activated rules
diff --git a/sonar-server/src/main/webapp/WEB-INF/app/models/active_rule_note.rb b/sonar-server/src/main/webapp/WEB-INF/app/models/active_rule_note.rb
index 45bdfb4b8bb..b306bec7393 100644
--- a/sonar-server/src/main/webapp/WEB-INF/app/models/active_rule_note.rb
+++ b/sonar-server/src/main/webapp/WEB-INF/app/models/active_rule_note.rb
@@ -20,8 +20,17 @@
class ActiveRuleNote < ActiveRecord::Base
belongs_to :active_rule
alias_attribute :text, :data
+ alias_attribute :rule, :active_rule
validates_presence_of :active_rule, :message => "can't be empty"
validates_presence_of :user_login, :message => "can't be empty"
+ validates_length_of :data, :minimum => 1
+
+ def user
+ @user ||=
+ begin
+ user_login ? User.find(:first, :conditions => ['login=?', user_login]) : nil
+ end
+ end
end
diff --git a/sonar-server/src/main/webapp/WEB-INF/app/models/rule_note.rb b/sonar-server/src/main/webapp/WEB-INF/app/models/rule_note.rb
index c879875a95f..ca7c805a4f7 100644
--- a/sonar-server/src/main/webapp/WEB-INF/app/models/rule_note.rb
+++ b/sonar-server/src/main/webapp/WEB-INF/app/models/rule_note.rb
@@ -23,5 +23,13 @@ class RuleNote < ActiveRecord::Base
validates_presence_of :rule, :message => "can't be empty"
validates_presence_of :user_login, :message => "can't be empty"
+ validates_length_of :data, :minimum => 1
+
+ def user
+ @user ||=
+ begin
+ user_login ? User.find(:first, :conditions => ['login=?', user_login]) : nil
+ end
+ end
end
diff --git a/sonar-server/src/main/webapp/WEB-INF/app/views/rules_configuration/_create_rule_note.html.erb b/sonar-server/src/main/webapp/WEB-INF/app/views/rules_configuration/_create_rule_note.html.erb
new file mode 100644
index 00000000000..ebc2ddaaa9a
--- /dev/null
+++ b/sonar-server/src/main/webapp/WEB-INF/app/views/rules_configuration/_create_rule_note.html.erb
@@ -0,0 +1,48 @@
+<% #locals = rule, active_rule, is_admin
+ create_buttons_div_id = "cb_" + rule.id.to_s
+ create_rule_note_button_div_id = "cnb_" + rule.id.to_s
+ create_active_rule_note_button_div_id = "canb_" + rule.id.to_s
+ create_rule_note_form_div_id = "crnf_" + rule.id.to_s
+ create_active_rule_note_form_div_id = "carnf_" + rule.id.to_s
+ submit_rule_note_id = "srn_" + rule.id.to_s
+ submit_active_rule_note_id = "sarn_" + rule.id.to_s
+ rule_note_text_id = "rnt_" + rule.id.to_s
+ active_rule_note_text_id = "arnt_" + rule.id.to_s
+%>
+
+<div style="margin-top: 10px;">
+
+<div id="<%= create_buttons_div_id -%>">
+ <input type="button" id="<%= create_rule_note_button_div_id -%>" value="<%= message('rules_configuration.add_note') -%>"
+ onclick="$('<%= create_buttons_div_id -%>').hide();$('<%= create_rule_note_form_div_id -%>').show();$('<%= rule_note_text_id -%>').focus();"
+ <%= 'style="display:none;"' if rule.note -%>>
+ <input type="button" id="<%= create_active_rule_note_button_div_id -%>" value="<%= message('rules_configuration.add_activation_note') -%>"
+ onclick="$('<%= create_buttons_div_id -%>').hide();$('<%= create_active_rule_note_form_div_id -%>').show();$('<%= active_rule_note_text_id -%>').focus();"
+ <%= 'style="display:none;"' if active_rule && active_rule.note -%>>
+</div>
+
+<div id="<%= create_rule_note_form_div_id -%>" style="display: none" class="admin">
+ <%= form_remote_tag :url => {:action => 'update_note', :rule_id => rule.id, :is_active_rule => false},
+ :update => "rule_note_#{rule.id}",
+ :complete => "$('#{create_rule_note_form_div_id}').hide();$('#{create_buttons_div_id}').show();$('#{create_rule_note_button_div_id}').hide();" %>
+ <textarea name="text" id="<%= rule_note_text_id -%>" cols="100" rows="10" onkeyup="if (this.value=='') $('<%= submit_rule_note_id -%>').disabled=true; else $('<%= submit_rule_note_id -%>').disabled=false;"></textarea>
+ <div class="note" style="padding: 5px 0px"><%= message('rules_configuration.adding_note_decsription') -%></div>
+ <input type="submit" value="<%= message('rules_configuration.create_note') -%>" name="commit" id="<%= submit_rule_note_id -%>" disabled/>
+ <a href="#" onclick="$('<%= create_buttons_div_id -%>').show();$('<%= create_rule_note_form_div_id -%>').hide();return false;"><%= message('cancel') %></a>
+ </form>
+</div>
+
+<% if active_rule%>
+<div id="<%= create_active_rule_note_form_div_id -%>" style="display: none" class="admin">
+ <%= form_remote_tag :url => {:action => 'update_note', :rule_id => active_rule.id, :is_active_rule => true},
+ :update => "active_rule_note_#{active_rule.id}",
+ :complete => "$('#{create_active_rule_note_form_div_id}').hide();$('#{create_buttons_div_id}').show();$('#{create_active_rule_note_button_div_id}').hide();" %>
+ <textarea name="text" id="<%= active_rule_note_text_id -%>" cols="100" rows="10" onkeyup="if (this.value=='') $('<%= submit_active_rule_note_id -%>').disabled=true; else $('<%= submit_active_rule_note_id -%>').disabled=false;"></textarea>
+ <div class="note" style="padding: 5px 0px"><%= message('rules_configuration.adding_activation_note_decsription')-%></div>
+ <input type="submit" value="<%= message('rules_configuration.create_activation_note') -%>" name="commit" id="<%= submit_active_rule_note_id -%>" disabled/>
+ <a href="#" onclick="$('<%= create_buttons_div_id -%>').show();$('<%= create_active_rule_note_form_div_id -%>').hide();return false;"><%= message('cancel') %></a>
+ </form>
+</div>
+<% end %>
+
+</div> \ No newline at end of file
diff --git a/sonar-server/src/main/webapp/WEB-INF/app/views/rules_configuration/_rule.html.erb b/sonar-server/src/main/webapp/WEB-INF/app/views/rules_configuration/_rule.html.erb
index 8ca525c5202..da6cad72dd4 100644
--- a/sonar-server/src/main/webapp/WEB-INF/app/views/rules_configuration/_rule.html.erb
+++ b/sonar-server/src/main/webapp/WEB-INF/app/views/rules_configuration/_rule.html.erb
@@ -1,5 +1,8 @@
-<td nowrap valign="top" class="left" x="<%= active_rule.failure_level if active_rule -%>" width="1%">
- <form id="levels_<%= rule.id -%>" action="">
+<% color = cycle('even','odd') %>
+
+<tr id="rule_<%= rule.id -%>" class="<%= color -%>">
+ <td nowrap valign="top" class="left" x="<%= active_rule.failure_level if active_rule -%>" width="1%">
+ <form id="levels_<%= rule.id -%>" action="">
<% enable_modification = is_admin && !profile.provided?
select_box_id = "levels_select_#{rule.id}"
check_box_id = "levels_check_#{rule.id}"
@@ -25,42 +28,76 @@
<img src="<%= ApplicationController.root_context -%>/images/overrides.png" alt="Overrides parent definition" title="<%= message('rules_configuration.overrides_parent_definition') -%>"/>
<% end %>
<% end %>
- </form>
-</td>
-<td valign="top" class="left">
- <%= link_to_function("#{h rule.name}", nil, :class => "") do |page|
+ </form>
+ </td>
+ <td valign="top" class="left">
+ <%= link_to_function("#{h rule.name}", nil, :class => "") do |page|
page.toggle "desc_#{rule.id}"
end
- %>
- <div id="desc_<%= rule.id -%>" class="rule_desc" style="display:none">
- <span class="subtitle"><%= message('key') -%>: <%= rule.plugin_rule_key -%></span>
- <div style="margin:8px 0px"><%= rule.description %></div>
- <table style="margin: 10px 0">
- <% rule.parameters.each do |parameter|
- active_parameter = active_rule.active_param_by_param_id(parameter.id) if active_rule
- %>
- <tbody id="param_<%= parameter.id -%>">
- <%= render :partial => 'rule_param', :object => nil,
- :locals => {:parameter => parameter, :active_parameter => active_parameter, :profile => profile, :active_rule => active_rule, :is_admin => is_admin } %>
- </tbody>
- <% end %>
- </table>
- <% if is_admin %>
- <% if rule.template? %>
- <%= button_to message('rules_configuration.copy_rule'), {:action => 'new', :id => profile.id, :rule_id => rule.id}, :id => "copy-#{u rule.key}" %>
- <% end %>
- <% if rule.editable? %>
- <%= button_to message('rules_configuration.edit_rule'), :action => 'edit', :id => profile.id, :rule_id => rule.id %>
- <% end %>
- <% if active_rule && active_rule.overrides? %>
- <%= button_to message('rules_configuration.revert_to_parent_definition'), :overwrite_params => {:action => 'revert_rule', :id => profile.id, :active_rule_id => active_rule.id} %><br/>
- <% end %>
- <% end %>
- </div>
-</td>
-<td valign="top" class="right rule_plugin">
-<%= rule.plugin_name.capitalize %>
-</td>
-<script type="text/javascript">
+ %>
+ </td>
+ <script type="text/javascript">
Form.reset($('levels_<%= rule.id -%>'));
-</script>
+ </script>
+</tr>
+
+<tr id="desc_<%= rule.id -%>" class="rule_detail <%= color -%>" style="display:none">
+ <td colspan="3">
+ <table width="100%">
+ <tbody>
+ <tr>
+ <td width="50%">
+ <h3><%= message('rules_configuration.rule_description') -%></h3>
+ <p><%= rule.description %></p>
+ <div id="rule_note_<%= rule.id -%>">
+ <%= render :partial => 'rule_note', :locals => {:rule => rule, :is_admin => is_admin, :is_active_rule => false } %>
+ </div>
+ <% if active_rule %>
+ <div id="active_rule_note_<%= active_rule.id -%>">
+ <%= render :partial => 'rule_note', :locals => {:rule => active_rule, :is_admin => is_admin, :is_active_rule => true } %>
+ </div>
+ <% end %>
+ <% if is_admin %>
+ <%= render :partial => 'create_rule_note', :locals => {:rule => rule, :active_rule => active_rule, :is_admin => is_admin } %>
+ <% end %>
+ </td>
+ <td class="separator"></td>
+ <td width="50%">
+ <h3><%= message('rules_configuration.rule_identification') -%></h3>
+ <table style="margin-left:7px">
+ <tbody>
+ <tr><td style="padding-right:10px"><%= message('plugin') -%>:</td><td><%= rule.plugin_name.capitalize %></td></tr>
+ <tr><td style="padding-right:10px"><%= message('key') -%>:</td><td><%= rule.plugin_rule_key %></td></tr>
+ <t/body>
+ </table>
+ <% unless rule.parameters.empty? %>
+ <br/>
+ <h3><%= message('rules_configuration.rule_parameters') -%></h3>
+ <table style="margin-left:7px">
+ <% rule.parameters.each do |parameter|
+ active_parameter = active_rule.active_param_by_param_id(parameter.id) if active_rule
+ %>
+ <tbody id="param_<%= parameter.id -%>">
+ <%= render :partial => 'rule_param', :object => nil,
+ :locals => {:parameter => parameter, :active_parameter => active_parameter, :profile => profile, :active_rule => active_rule, :is_admin => is_admin } %>
+ </tbody>
+ <% end %>
+ </table>
+ <% end %>
+ <% if is_admin %>
+ <% if rule.template? %>
+ <%= button_to message('rules_configuration.copy_rule'), {:action => 'new', :id => profile.id, :rule_id => rule.id}, :id => "copy-#{u rule.key}" %>
+ <% end %>
+ <% if rule.editable? %>
+ <%= button_to message('rules_configuration.edit_rule'), :action => 'edit', :id => profile.id, :rule_id => rule.id %>
+ <% end %>
+ <% if active_rule && active_rule.overrides? %>
+ <%= button_to message('rules_configuration.revert_to_parent_definition'), :overwrite_params => {:action => 'revert_rule', :id => profile.id, :active_rule_id => active_rule.id} %><br/>
+ <% end %>
+ <% end %>
+ </td>
+ </tr>
+ </tbody>
+ </table>
+ </td>
+</tr>
diff --git a/sonar-server/src/main/webapp/WEB-INF/app/views/rules_configuration/_rule_note.html.erb b/sonar-server/src/main/webapp/WEB-INF/app/views/rules_configuration/_rule_note.html.erb
new file mode 100644
index 00000000000..208a1fe98c4
--- /dev/null
+++ b/sonar-server/src/main/webapp/WEB-INF/app/views/rules_configuration/_rule_note.html.erb
@@ -0,0 +1,36 @@
+<% #locals = rule, is_admin, is_active_rule
+ submit_note_update_button_id = (is_active_rule ? 'a' : '') + "snub_" + rule.id.to_s
+%>
+
+<%
+ if rule.note
+ note = rule.note
+%>
+ <h3><%= is_active_rule ? message('rules_configuration.rule_activation_note') : message('rules_configuration.rule_note') -%></h3>
+ <div class="note"><%= note.user.name -%>, <%= l(note.updated_at) -%></div>
+ <div id="note_detail_<%= rule.id -%>">
+ <p><%= sanitize(note.text) -%></p>
+ <% if is_admin %>
+ <div style="margin-bottom: 10px">
+ <input type="button" value="<%= message('update_verb') -%>" onclick="$('note_detail_<%= rule.id -%>').hide();$('note_form_<%= rule.id -%>').show();">
+ <%= button_to_remote message('delete'),
+ {:url => {:action => 'delete_note', :rule_id => rule.id, :is_active_rule => is_active_rule },
+ :update => "#{'active_' if is_active_rule}rule_note_#{rule.id}",
+ :complete => "$('#{is_active_rule ? "canb_"+rule.rule.id.to_s : "cnb_"+rule.id.to_s}').show()",
+ :confirm => message('rules_configuration.confirm_delete_note')},
+ {:class => 'red-button'} -%>
+ </div>
+ <% end %>
+ </div>
+
+ <div id="note_form_<%= rule.id -%>" style="display: none" class="admin">
+ <%= form_remote_tag :url => {:action => 'update_note', :rule_id => rule.id, :is_active_rule => is_active_rule},
+ :update => "#{'active_' if is_active_rule}rule_note_#{rule.id}" %>
+ <textarea name="text" id="update_<%= 'active_' if is_active_rule -%>_rule_note_<%= rule.id -%>" cols="100" rows="10"
+ onkeyup="if (this.value=='') $('<%= submit_note_update_button_id -%>').disabled=true; else $('<%= submit_note_update_button_id -%>').disabled=false;"><%= h(note.text) -%></textarea>
+ <br/>
+ <input type="submit" value="<%= message('update_verb') -%>" name="commit" id="<%= submit_note_update_button_id -%>"/>
+ <a href="#" onclick="$('note_detail_<%= rule.id -%>').show();$('note_form_<%= rule.id -%>').hide();return false;"><%= message('cancel') %></a>
+ </form>
+ </div>
+<% end %> \ No newline at end of file
diff --git a/sonar-server/src/main/webapp/WEB-INF/app/views/rules_configuration/_rule_param.html.erb b/sonar-server/src/main/webapp/WEB-INF/app/views/rules_configuration/_rule_param.html.erb
index 0e011d5322e..0a2ee16ba06 100644
--- a/sonar-server/src/main/webapp/WEB-INF/app/views/rules_configuration/_rule_param.html.erb
+++ b/sonar-server/src/main/webapp/WEB-INF/app/views/rules_configuration/_rule_param.html.erb
@@ -32,7 +32,13 @@
<span class="error"><%= active_parameter.errors.on 'value' %></span>
<% end %>
<% end %>
- <span class="note"><%= h parameter.description -%></span>
+
</form>
</td>
</tr>
+<tr>
+ <td></td>
+ <td style="padding-bottom:5px;">
+ <span class="note" style="white-space: normal"><%= h parameter.description -%></span>
+ </td>
+</tr>
diff --git a/sonar-server/src/main/webapp/WEB-INF/app/views/rules_configuration/index.html.erb b/sonar-server/src/main/webapp/WEB-INF/app/views/rules_configuration/index.html.erb
index 484fce0b348..be2e5c9b50c 100644
--- a/sonar-server/src/main/webapp/WEB-INF/app/views/rules_configuration/index.html.erb
+++ b/sonar-server/src/main/webapp/WEB-INF/app/views/rules_configuration/index.html.erb
@@ -20,7 +20,7 @@
return !localModifications;
}
function toggle_rules(){
- $$('.rule_desc').each(function(element) {
+ $$('.rule_detail').each(function(element) {
element.toggle();
});
}
@@ -106,7 +106,6 @@
<tr>
<th class="left" nowrap><%= message('active') -%>/<%= message('severity') -%></th>
<th class="left"><%= message('name') -%> <span style="font-weight: normal">[<%= link_to_function(message('rules_configuration.expand_collapse'), "toggle_rules()") %>]</span></th>
- <th class="right"><%= message('plugin') -%></th>
</tr>
</thead>
<tbody>
@@ -119,9 +118,9 @@
@rules.each do |rule|
active_rule = @profile.active_by_rule_id(rule.id)
%>
- <tr id="rule_<%= rule.id -%>" class="<%= cycle('even','odd') -%>">
- <%= render :partial => 'rule', :object => rule, :locals => {:profile => @profile, :active_rule => active_rule, :is_admin => is_admin} %>
- </tr>
+
+ <%= render :partial => 'rule', :object => rule, :locals => {:profile => @profile, :active_rule => active_rule, :is_admin => is_admin} %>
+
<% end %>
</tbody>
</table>
diff --git a/sonar-server/src/main/webapp/stylesheets/style.css b/sonar-server/src/main/webapp/stylesheets/style.css
index 4bc8b09f896..b2438ffdec5 100644
--- a/sonar-server/src/main/webapp/stylesheets/style.css
+++ b/sonar-server/src/main/webapp/stylesheets/style.css
@@ -2046,32 +2046,44 @@ ul.bullet li {
width: 100%;
}
-.rule_desc {
+.rule_detail {
color: #444;
- padding: 2px 0;
}
-.rule_desc li {
+.rule_detail > td > table {
+ margin: 4px;
+}
+
+.rule_detail td {
+ vertical-align: text-top;
+}
+
+.rule_detail li {
list-style: disc outside;
padding: 2px;
}
-.rule_desc ul {
+.rule_detail ul {
list-style: none outside;
padding-left: 30px;
}
-.rule_desc pre, .rule_desc p {
+.rule_detail pre, .rule_detail p {
padding: 7px;
}
-.rule_desc pre {
+.rule_detail pre {
margin: 10px 0;
font-family: "Courier New", Courier, monospace;;
border: 1px dashed #aaa;
font-size: 93%;
}
+.rule_detail .separator {
+ background: url('../images/sep12.png') center repeat-y;
+ min-width: 20px;
+}
+
.tip:hover {
background: #FFF;
position: relative;