--- /dev/null
+#
+# SonarQube, open source software quality management tool.
+# Copyright (C) 2008-2013 SonarSource
+# mailto:contact AT sonarsource DOT com
+#
+# SonarQube is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 3 of the License, or (at your option) any later version.
+#
+# SonarQube is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with this program; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+#
+require 'cgi'
+
+class NewRulesConfigurationController < ApplicationController
+
+ SECTION=Navigation::SECTION_QUALITY_PROFILES
+
+ STATUS_ACTIVE = "ACTIVE"
+ STATUS_INACTIVE = "INACTIVE"
+
+ ANY_SELECTION = []
+ RULE_PRIORITIES = Sonar::RulePriority.as_options.reverse
+
+ def index
+ require_parameters :id
+
+ @profile = Profile.find(params[:id])
+ add_breadcrumbs ProfilesController::root_breadcrumb, Api::Utils.language_name(@profile.language),
+ {:name => @profile.name, :url => {:controller => 'new_rules_configuration', :action => 'index', :id => @profile.id}}
+
+ init_params()
+
+ @select_repositories = ANY_SELECTION + java_facade.getRuleRepositoriesByLanguage(@profile.language).collect { |repo| [repo.getName(true), repo.getKey()] }.sort
+ @select_priority = ANY_SELECTION + RULE_PRIORITIES
+ @select_activation = [[message('any'), 'any'], [message('active'), STATUS_ACTIVE], [message('inactive'), STATUS_INACTIVE]]
+ @select_inheritance = [[message('any'), 'any'], [message('rules_configuration.not_inherited'), 'NOT'], [message('rules_configuration.inherited'), 'INHERITED'],
+ [message('rules_configuration.overrides'), 'OVERRIDES']]
+ @select_status = ANY_SELECTION + [[message('rules.status.beta'), Rule::STATUS_BETA],
+ [message('rules.status.deprecated'), Rule::STATUS_DEPRECATED],
+ [message('rules.status.ready'), Rule::STATUS_READY]]
+ @select_sort_by = [[message('rules_configuration.rule_name'), Rule::SORT_BY_RULE_NAME], [message('rules_configuration.creation_date'), Rule::SORT_BY_CREATION_DATE]]
+
+ begin
+ stop_watch = Internal.profiling.start("rules", "BASIC")
+
+ criteria = {
+ :profile => @profile, :activation => @activation, :priorities => @priorities, :inheritance => @inheritance, :status => @status,
+ :repositories => @repositories, :searchtext => @searchtext, :include_parameters_and_notes => true, :language => @profile.language, :sort_by => @sort_by}
+ @rules = Rule.search(java_facade, criteria)
+
+ unless @searchtext.blank?
+ if @activation==STATUS_ACTIVE
+ @hidden_inactives = Rule.search(java_facade, {
+ :profile => @profile, :activation => STATUS_INACTIVE, :priorities => @priorities, :status => @status,
+ :repositories => @repositories, :language => @profile.language, :searchtext => @searchtext, :include_parameters_and_notes => false}).size
+
+ elsif @activation==STATUS_INACTIVE
+ @hidden_actives = Rule.search(java_facade, {
+ :profile => @profile, :activation => STATUS_ACTIVE, :priorities => @priorities, :status => @status,
+ :repositories => @repositories, :language => @profile.language, :searchtext => @searchtext, :include_parameters_and_notes => false}).size
+ end
+ end
+
+ stop_watch.stop("found #{@rules.size} rules with criteria #{criteria.to_json}")
+ rescue
+ @rules = []
+ end
+ @pagination = Api::Pagination.new(params)
+ @pagination.count = @rules.size
+ @current_rules = @rules[@pagination.offset, @pagination.limit]
+ end
+
+
+ #
+ #
+ # POST /rules_configuration/revert_rule?id=<profile id>&active_rule_id=<active rule id>
+ #
+ #
+ def revert_rule
+ verify_post_request
+ access_denied unless has_role?(:profileadmin)
+ require_parameters :id, :active_rule_id
+ id = params[:id].to_i
+ rule_id = params[:active_rule_id].to_i
+ java_facade.revertRule(id, rule_id, current_user.name)
+ redirect_to request.query_parameters.merge({:action => 'index', :id => params[:id], :commit => nil})
+ end
+
+
+ #
+ #
+ # POST /rules_configuration/activate_rule?id=<profile id>&rule_id=<rule id>&level=<priority>
+ #
+ # If the parameter "level" is blank or null, then the rule is removed from the profile.
+ #
+ #
+ def activate_rule
+ verify_post_request
+ access_denied unless has_role?(:profileadmin)
+ require_parameters :id, :rule_id
+ profile = Profile.find(params[:id].to_i)
+ if profile
+ rule=Rule.first(:conditions => ["id = ? and status <> ?", params[:rule_id].to_i, Rule::STATUS_REMOVED])
+ priority=params[:level]
+
+ active_rule=profile.active_by_rule_id(rule.id)
+ if priority.blank?
+ # deactivate the rule
+ if active_rule
+ java_facade.ruleDeactivated(profile.id, active_rule.id, current_user.name)
+ active_rule.destroy
+ active_rule=nil
+ end
+ else
+ # activate the rule
+ activated = false
+ if active_rule.nil?
+ active_rule = ActiveRule.new(:profile_id => profile.id, :rule => rule)
+ rule.parameters.select { |p| p.default_value.present? }.each do |p|
+ active_rule.active_rule_parameters.build(:rules_parameter => p, :value => p.default_value)
+ end
+ activated = true
+ end
+ old_severity = active_rule.failure_level
+ active_rule.failure_level=Sonar::RulePriority.id(priority)
+ active_rule.save!
+ if activated
+ java_facade.ruleActivated(profile.id, active_rule.id, current_user.name)
+ else
+ java_facade.ruleSeverityChanged(profile.id, active_rule.id, old_severity, active_rule.failure_level, current_user.name)
+ end
+ end
+ if active_rule
+ active_rule.reload
+ end
+
+ render :update do |page|
+ page.replace_html("rule_#{rule.id}", :partial => 'rule', :object => rule, :locals => {:profile => profile, :rule => rule, :active_rule => active_rule})
+ page.assign('localModifications', true)
+ end
+ end
+ end
+
+
+ #
+ #
+ # GET /rules_configuration/new/<profile id>?rule_id=<rule id>
+ #
+ #
+ def new
+ # form to duplicate a rule
+ access_denied unless has_role?(:profileadmin)
+ require_parameters :id, :rule_id
+ @profile = Profile.find(params[:id].to_i)
+ add_breadcrumbs ProfilesController::root_breadcrumb, Api::Utils.language_name(@profile.language), {:name => @profile.name, :url => {:controller => 'new_rules_configuration', :action => 'index', :id => @profile.id}}
+
+ @rule = Rule.find(params[:rule_id])
+ end
+
+ #
+ #
+ # POST /rules_configuration/create/<profile id>?rule_id=<rule id>&rule[name]=<new name>&...
+ #
+ #
+ def create
+ verify_post_request
+ access_denied unless has_role?(:profileadmin)
+ require_parameters :id, :rule_id
+ profile = Profile.find(params[:id].to_i)
+ template=Rule.find(params[:rule_id])
+ # TODO Call Internal.rule.create(...) ?
+ rule=Rule.create(params[:rule].merge(
+ {
+ :priority => Sonar::RulePriority.id(params[:rule][:priority]),
+ :parent_id => template.id,
+ :plugin_name => template.plugin_name,
+ :cardinality => 'SINGLE',
+ :plugin_rule_key => "#{template.plugin_rule_key}_#{Time.now.to_i}",
+ :plugin_config_key => template.plugin_config_key,
+ :status => Rule::STATUS_READY,
+ :language => profile.language
+ }
+ ))
+
+ template.parameters.each do |template_parameter|
+ rule.rules_parameters.build(:name => template_parameter.name, :param_type => template_parameter.param_type, :description => template_parameter.description,
+ :default_value => params[:rule_param][template_parameter.name])
+ end
+
+ if rule.save
+ Internal.rules.saveOrUpdate(rule.id)
+ redirect_to :action => 'index', :id => profile.id, :searchtext => "\"#{rule.name}\"", :rule_activation => 'INACTIVE', "plugins[]" => rule.plugin_name
+
+ else
+ flash[:error]=message('rules_configuration.rule_not_valid_message_x', :params => rule.errors.full_messages.join('<br/>'))
+ redirect_to :action => 'new', :id => profile.id, :rule_id => params[:rule_id]
+ end
+ end
+
+
+ # deprecated since 2.3
+ def export
+ redirect_to request.query_parameters.merge({:controller => 'profiles', :action => 'export'})
+ end
+
+ #
+ #
+ # GET /rules_configuration/new/<profile id>?rule_id=<rule id>
+ #
+ #
+ def edit
+ # form to edit a rule
+ access_denied unless has_role?(:profileadmin)
+ require_parameters :id, :rule_id
+ @profile = Profile.find(params[:id])
+ @rule = Rule.find(params[:rule_id])
+ if !@rule.editable?
+ redirect_to :action => 'index', :id => params[:id]
+ end
+ end
+
+ #
+ #
+ # POST /rules_configuration/update/<profile id>?rule_id=<rule id>&rule[name]=<new name>&...
+ #
+ #
+ def update
+ verify_post_request
+ access_denied unless has_role?(:profileadmin)
+ require_parameters :id, :rule_id
+ rule=Rule.find(params[:rule_id])
+ if rule.editable?
+ rule.name=params[:rule][:name]
+ rule.description=params[:rule][:description]
+ rule.priority=Sonar::RulePriority.id(params[:rule][:priority])
+ rule.parameters.each do |parameter|
+ parameter.default_value=params[:rule_param][parameter.name]
+ parameter.save
+ end
+ if rule.save
+ Internal.rules.saveOrUpdate(rule.id)
+ redirect_to :action => 'index', :id => params[:id], :searchtext => "\"#{rule.name}\"", :rule_activation => '', "plugins[]" => rule.plugin_name
+ else
+ flash[:error]=message('rules_configuration.rule_not_valid_message_x', :params => rule.errors.full_messages.join('<br/>'))
+ redirect_to :action => 'new', :id => params[:id], :rule_id => params[:rule_id]
+ end
+ else
+ flash[:error]='Unknown rule'
+ redirect_to :action => 'index', :id => params[:id]
+ end
+ end
+
+
+ #
+ #
+ # POST /rules_configuration/delete/<profile id>?rule_id=<rule id>
+ #
+ #
+ def delete
+ verify_post_request
+ access_denied unless has_role?(:profileadmin)
+ require_parameters :id, :rule_id
+ rule=Rule.find(params[:rule_id])
+ if rule.editable?
+ rule.status=Rule::STATUS_REMOVED
+ rule.save
+ Internal.rules.saveOrUpdate(rule.id)
+
+ # it's mandatory to execute 'destroy_all' but not 'delete_all' because active_rule_parameters must
+ # also be destroyed in cascade.
+ ActiveRule.destroy_all("rule_id=#{rule.id}")
+ flash[:notice]=message('rules_configuration.rule_deleted')
+ else
+ flash[:error]=message('rules_configuration.unknown_rule')
+ end
+ redirect_to :action => 'index', :id => params[:id]
+ end
+
+ #
+ #
+ # POST /rules_configuration/bulk_edit?id=<profile id>&bulk_rule_ids=<list of rule ids>&bulk_action=<action>
+ #
+ # Values of the parameter 'bulk_action' :
+ # - 'activate' : activate all the selected rules with their default priority
+ # - 'deactivate' : deactivate all the selected rules
+ #
+ #
+ def bulk_edit
+ verify_post_request
+ access_denied unless has_role?(:profileadmin)
+ require_parameters :id, :bulk_rule_ids, :bulk_action
+ profile = Profile.find(params[:id].to_i)
+ rule_ids = params[:bulk_rule_ids].split(',').map { |id| id.to_i }
+ activation=params[:rule_activation] || STATUS_ACTIVE
+
+ case params[:bulk_action]
+ when 'activate'
+ count=activate_rules(profile, rule_ids)
+ flash[:notice]=message('rules_configuration.x_rules_have_been_activated', :params => count)
+ activation=STATUS_ACTIVE if activation==STATUS_INACTIVE
+
+ when 'deactivate'
+ count=deactivate_rules(profile, rule_ids)
+ flash[:notice]=message('rules_configuration.x_rules_have_been_deactivated', :params => count)
+ activation=STATUS_INACTIVE if activation==STATUS_ACTIVE
+ end
+
+ url_parameters=request.query_parameters.merge({:action => 'index', :bulk_action => nil, :bulk_rule_ids => nil, :id => profile.id, :rule_activation => activation})
+ redirect_to url_parameters
+ end
+
+
+ def update_param
+ verify_post_request
+ access_denied unless has_role?(:profileadmin)
+ require_parameters :profile_id, :param_id, :active_rule_id
+ profile = Profile.find(params[:profile_id].to_i)
+ rule_param = RulesParameter.find(params[:param_id].to_i)
+ active_rule = ActiveRule.find(params[:active_rule_id].to_i)
+ # As the active param can be null, we should not raise a RecordNotFound exception when it's not found (as it would be done when using find(:id) function)
+ active_param = ActiveRuleParameter.find_by_id(params[:id].to_i) if params[:id].to_i > 0
+ value = params[:value]
+ if value != ""
+ active_param = ActiveRuleParameter.new(:rules_parameter => rule_param, :active_rule => active_rule) if active_param.nil?
+ old_value = active_param.value
+ active_param.value = value
+ if active_param.save! && active_param.valid?
+ active_param.reload
+ java_facade.ruleParamChanged(profile.id, active_rule.id, rule_param.name, old_value, value, current_user.name)
+ end
+ elsif !active_param.nil?
+ old_value = active_param.value
+ active_param.destroy
+ java_facade.ruleParamChanged(profile.id, active_rule.id, rule_param.name, old_value, nil, current_user.name)
+ end
+ # let's reload the active rule
+ active_rule = ActiveRule.find(active_rule.id)
+ render :partial => 'rule', :locals => {:profile => profile, :rule => active_rule.rule, :active_rule => active_rule}
+ end
+
+
+ def update_rule_note
+ verify_post_request
+ access_denied unless has_role?(:profileadmin)
+ require_parameters :rule_id
+ rule = Rule.find(params[:rule_id])
+ note = rule.note
+ unless note
+ note = RuleNote.new({:rule => rule})
+ # 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}
+ end
+
+
+ def update_active_rule_note
+ verify_post_request
+ access_denied unless has_role?(:profileadmin)
+ require_parameters :active_rule_id, :note
+ active_rule = ActiveRule.find(params[:active_rule_id])
+ note = active_rule.note
+ unless note
+ note = ActiveRuleNote.new({:active_rule => active_rule})
+ # set the note on the rule to avoid reloading the rule
+ active_rule.note = note
+ end
+ note.text = params[:note]
+ note.user_login = current_user.login
+ note.save!
+ render :partial => 'active_rule_note', :locals => {:active_rule => active_rule, :profile => active_rule.rules_profile}
+ end
+
+
+ def delete_active_rule_note
+ verify_post_request
+ access_denied unless has_role?(:profileadmin)
+ require_parameters :active_rule_id
+ active_rule = ActiveRule.find(params[:active_rule_id])
+ active_rule.note.destroy if active_rule.note
+ active_rule.note = nil
+ render :partial => 'active_rule_note', :locals => {:active_rule => active_rule, :profile => active_rule.rules_profile}
+ end
+
+
+ private
+
+ # return the number of newly activated rules
+ def activate_rules(profile, rule_ids)
+ count=0
+ rule_ids_to_activate=(rule_ids - profile.active_rules.map { |ar| ar.rule_id })
+ unless rule_ids_to_activate.empty?
+ rules_to_activate=Rule.all(:conditions => ["status <> ? AND id IN (?)", Rule::STATUS_REMOVED, rule_ids_to_activate])
+ count = rules_to_activate.size
+ rules_to_activate.each do |rule|
+ active_rule = profile.active_rules.create(:rule => rule, :failure_level => rule.priority)
+ java_facade.ruleActivated(profile.id, active_rule.id, current_user.name)
+ end
+ end
+ count
+ end
+
+ def deactivate_rules(profile, rule_ids)
+ count=0
+ profile.active_rules.each do |ar|
+ if rule_ids.include?(ar.rule_id) && !ar.inheritance.present?
+ java_facade.ruleDeactivated(profile.id, ar.id, current_user.name)
+ ar.destroy
+ count+=1
+ end
+ end
+ count
+ end
+
+ def init_params
+ @id = params[:id]
+ @priorities = filter_any(params[:priorities]) || ['']
+ @repositories = filter_any(params[:repositories]) || ['']
+ @activation = params[:rule_activation] || STATUS_ACTIVE
+ @inheritance = params[:inheritance] || 'any'
+ @status = params[:status]
+ @sort_by = !params[:sort_by].blank? ? params[:sort_by] : Rule::SORT_BY_RULE_NAME
+ @searchtext = params[:searchtext]
+ end
+
+ def filter_any(array)
+ if array && array.size>1 && array.include?('')
+ array=[''] #keep only 'any'
+ end
+ array
+ end
+
+end
--- /dev/null
+#
+# SonarQube, open source software quality management tool.
+# Copyright (C) 2008-2013 SonarSource
+# mailto:contact AT sonarsource DOT com
+#
+# SonarQube is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 3 of the License, or (at your option) any later version.
+#
+# SonarQube is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with this program; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+#
+module NewRulesConfigurationHelper
+ include PropertiesHelper
+
+ PARAM_TYPE_STRING_LIST = "s{}"
+ PARAM_TYPE_INTEGER_LIST = "i{}"
+
+ # Kept for compatibility with old rule param type
+ def type_with_compatibility(type)
+ return PropertyType::TYPE_STRING if type == 's'
+ return PropertyType::TYPE_STRING if type == PARAM_TYPE_STRING_LIST
+ return PropertyType::TYPE_INTEGER if type == 'i'
+ return PropertyType::TYPE_INTEGER if type == PARAM_TYPE_INTEGER_LIST
+ return PropertyType::TYPE_BOOLEAN if type == 'b'
+ return PropertyType::TYPE_REGULAR_EXPRESSION if type == 'r'
+ return PropertyType::TYPE_STRING if is_set(type)
+
+ type
+ end
+
+ def readable_type(param_type)
+ type=type_with_compatibility(param_type)
+
+ return "Set of comma delimited strings" if param_type == PARAM_TYPE_STRING_LIST
+ return "Number" if type == PropertyType::TYPE_INTEGER
+ return "Set of comma delimited numbers" if param_type == PARAM_TYPE_INTEGER_LIST
+ return "Regular expression" if type == PropertyType::TYPE_REGULAR_EXPRESSION
+ return "Set of comma delimited values" if is_set(param_type)
+ ""
+ end
+
+ def param_value_input(parameter, value, options = {})
+ type=type_with_compatibility(parameter.param_type)
+ name = options[:name] || 'value'
+ property_input_field name, type, value, 'WIDGET', {:id => parameter.id, :size => options[:size] }.update(options)
+ end
+
+ def is_set(type)
+ type.at(1) == "[" && type.ends_with?("]")
+ end
+
+ def validate_rule_param(attribute, param_type, errors, value)
+ return if attribute.nil? or attribute.length == 0
+
+ type=type_with_compatibility(param_type)
+
+ if is_set_type
+ attribute.split(',').each do |v|
+ if !get_allowed_tokens.include?(v)
+ errors.add("#{value}", "'#{v}' must be one of : " + get_allowed_tokens.join(', '))
+ end
+ end
+ elsif param_type == RulesConfigurationHelper::PARAM_TYPE_INTEGER_LIST
+ attribute.split(',').each do |n|
+ if !Api::Utils.is_integer?(n)
+ errors.add("#{value}", "'#{n}' must be an integer.")
+ end
+ end
+ elsif type == PropertyType::TYPE_REGULAR_EXPRESSION
+ errors.add("#{value}", "'#{attribute}' must be a regular expression") unless Api::Utils.is_regexp?(attribute)
+ elsif type == PropertyType::TYPE_INTEGER
+ errors.add("#{value}", "'#{attribute}' must be an integer.") unless Api::Utils.is_integer?(attribute)
+ elsif type == PropertyType::TYPE_BOOLEAN
+ errors.add("#{value}", "'#{attribute}' must be one of : true,false") unless Api::Utils.is_boolean?(attribute)
+ end
+ end
+end
+
--- /dev/null
+<% #locals = active_rule, profile
+ note = active_rule.note
+ active_note_detail_div_id = "and_" + active_rule.id.to_s
+ add_active_note_button_id = "aanb_" + active_rule.id.to_s
+ edit_active_note_link_id = "eanl_" + active_rule.id.to_s
+ delete_active_note_link_id = "danl_" + active_rule.id.to_s
+ active_note_form_div_id = "anf_" + active_rule.id.to_s
+ active_note_textarea_id = "ant_" + active_rule.id.to_s
+ submit_active_note_update_button_id = "sanub_" + active_rule.id.to_s
+%>
+
+<div id="<%= active_note_detail_div_id -%>">
+ <% if note %>
+ <blockquote class="spacer-bottom">
+ <cite>
+ <b><%= note.user.name -%></b> (<%= distance_of_time_in_words_to_now(note.updated_at) -%>)
+ <% if profiles_administrator? %>
+ |
+ <a href="#" id="<%= edit_active_note_link_id -%>" class="link-action"
+ onclick="$j('#<%= active_note_detail_div_id -%>').hide();$j('#<%= active_note_form_div_id -%>').show();$j('#<%= active_note_textarea_id -%>').focus();return false;"><%= message('edit') %></a>
+
+ <a class="link-action"
+ onclick="if(confirm('<%= escape_javascript(message('rules_configuration.confirm_delete_note')) -%>')){
+ $j.ajax({
+ url: '<%=ApplicationController.root_context-%>/new_rules_configuration/delete_active_rule_note?active_rule_id=<%=active_rule.id-%>',
+ type: 'post',
+ success:function(response){$j('#active_rule_note_<%= active_rule.id -%>').html(response);}
+ });};return false;"
+ href="#!"><%=message('delete')-%></a>
+ <% end %>
+ </cite>
+ <p><%= note.html_text -%></p>
+ </blockquote>
+ <% elsif profiles_administrator? %>
+ <a href="#" onclick="$j('#<%= active_note_form_div_id -%>').show();$j('#<%= active_note_detail_div_id -%>').hide();$j('#<%= active_note_textarea_id -%>').focus(); return false;"
+ class="link-action spacer-right" id="<%= add_active_note_button_id -%>"><%= message('rules_configuration.add_note') -%></a>
+ <% end %>
+</div>
+
+<% if profiles_administrator? %>
+ <form onsubmit="$j.ajax({
+ url:'<%= ApplicationController.root_context -%>/new_rules_configuration/update_active_rule_note?active_rule_id=<%=active_rule.id-%>',
+ data: $j(this).serialize(),
+ type:'post',
+ success:function(response){$j('#active_rule_note_<%= active_rule.id -%>').html(response);}
+ });
+ return false;"
+ method="post"
+ action="<%= ApplicationController.root_context -%>/new_rules_configuration//update_active_rule_note?active_rule_id=<%=active_rule.id-%>">
+ <table id="<%= active_note_form_div_id -%>" style="display: none" class="admin table width100">
+ <tbody>
+ <tr>
+ <td class="width100" colspan="2">
+ <textarea name="note" id="<%= active_note_textarea_id -%>" rows="10" style="width:100%"
+ onkeyup="if (this.value=='') $j('#<%= submit_active_note_update_button_id -%>').prop('disabled', true); else $j('#<%= submit_active_note_update_button_id -%>').prop('disabled', false);"><%= h(note.plain_text) if note -%></textarea>
+ </td>
+ </tr>
+ <tr>
+ <td>
+ <input type="submit" value="<%= note ? message('update_verb') : message('rules_configuration.add_note') -%>" name="submit-active-note" id="<%= submit_active_note_update_button_id -%>" disabled="disabled"/>
+ <a href="#" onclick="$j('#<%= active_note_detail_div_id -%>').show();$j('#<%= active_note_form_div_id -%>').hide();return false;"><%= message('cancel') %></a>
+ </td>
+ <td align="right">
+ <%= render :partial => 'markdown/tips' -%>
+ </td>
+ </tr>
+ </tbody>
+ </table>
+ </form>
+<% end %>
--- /dev/null
+<td nowrap valign="top" class="left" x="<%= active_rule.failure_level if active_rule -%>" width="1%">
+ <form id="levels_<%= rule.id -%>" action="" class="rule-levels-form">
+ <% enable_modification = profiles_administrator?
+ select_box_id = "levels_select_#{rule.id}"
+ check_box_id = "levels_check_#{rule.id}"
+ activate_rule = "$j.ajax({url:'#{ApplicationController.root_context}/new_rules_configuration/activate_rule/#{profile.id}?rule_id=#{rule.id}',type: 'POST',
+ beforeSend: function(request){$j('#levels_#{rule.id}').replaceWith('<img src=\"#{ApplicationController.root_context}/images/loading.gif\"/>');},
+ data: 'level='+ get_level_for_rule($j('#levels_select_#{rule.id} :selected'),$j('#levels_check_#{rule.id}'))});"
+ changel_level = "if($j('#levels_check_#{rule.id}').prop('checked'))
+ {$j.ajax({url:'#{ApplicationController.root_context}/new_rules_configuration/activate_rule/#{profile.id}?rule_id=#{rule.id}',type:'POST',
+ beforeSend:function(request){$j('#levels_#{rule.id}').replaceWith('<img src=\"#{ApplicationController.root_context}/images/loading.gif\"/>');},
+ data:'level='+$j('#levels_select_#{rule.id} :selected').val()})}"
+ %>
+
+ <%= check_box_tag(check_box_id, 'yes', (!active_rule.nil?), :onclick => activate_rule, :disabled => !enable_modification || (active_rule && (active_rule.inherited? || active_rule.overrides?))) %>
+ <%= select_tag(select_box_id, options_for_select(RulesConfigurationController::RULE_PRIORITIES, (active_rule.nil? ? rule.priority_text : active_rule.priority_text)),
+ {:onchange => changel_level, :disabled => (!(enable_modification) || active_rule.nil?)}) %>
+
+ <% if active_rule %>
+ <% if active_rule.inherited? %>
+ <img src="<%= ApplicationController.root_context -%>/images/inherited.png" alt="Inherited from parent" title="<%= message('rules_configuration.inherited_from_parent') -%>"/>
+ <% elsif active_rule.overrides? %>
+ <img src="<%= ApplicationController.root_context -%>/images/overrides.png" alt="Overrides parent definition" title="<%= message('rules_configuration.overrides_parent_definition') -%>"/>
+ <% end %>
+ <% end %>
+ </form>
+</td>
+
+<td class="left" colspan="2">
+ <% unless rule.ready? %>
+ <div class="rule-status">
+ <% if rule.beta? %>
+ <span><%= message('rules.status.beta') %></span>
+ <% elsif rule.deprecated? %>
+ <span><%= message('rules.status.deprecated') %></span>
+ <% end %>
+ </div>
+ <% end %>
+
+ <div class="h3 rule-title"><%= link_to_function("#{h rule.name}", nil, :class => "") do |page|
+ page.toggle "desc_#{rule.id}"
+ end
+ %></div>
+
+ <div id="desc_<%= rule.id -%>" class="rule-desc" style="<%= 'display:none' -%>">
+ <a name="rule<%= rule.id -%>"></a>
+
+ <div id="rule_note_<%= rule.id -%>" class="marginbottom10">
+ <%= render :partial => 'rule_note', :locals => {:rule => rule} %>
+ </div>
+
+ <%
+ ancestor_profile = profile.parent
+ ancestor_active_rule = ancestor_profile.active_by_rule_id(rule.id) if ancestor_profile && active_rule && (active_rule.inherited? || active_rule.overrides?)
+ if ancestor_active_rule || !rule.parameters.empty?
+ %>
+ <table width="100%" class="table spacer-bottom bordered background-gray">
+ <%
+ if ancestor_active_rule
+ ancestor_active_rule_link = link_to ancestor_profile.name, :controller => 'rules_configuration', :action => 'index',
+ :id => ancestor_profile.id, :rule_id => rule.id, :anchor => 'rule' + rule.id.to_s
+ %>
+ <tr>
+ <td colspan="2">
+ <%= message(active_rule.inherited? ? 'rules_configuration.rule_inherited_from_profile_x' : 'rules_configuration.rule_overriding_from_profile_x',
+ :params => ancestor_active_rule_link) -%>
+ <% if ancestor_active_rule.priority != active_rule.priority %>
+ <img src="<%= ApplicationController.root_context -%>/images/overrides.png" alt="Overrides parent definition" title="<%= message('rules_configuration.overrides_parent_definition') -%>" style="vertical-align: middle"/>
+ <span class="form-val-note" style="font-weight: bold"> <%= message('rules_configuration.original_severity') -%>
+ : <%= ancestor_active_rule.priority_text -%></span>
+ <% end %>
+ <% if profiles_administrator? && active_rule.overrides? %>
+ <form action="<%= url_for :overwrite_params => {:action => 'revert_rule', :id => profile.id, :active_rule_id => active_rule.id} -%>" method="post" style="display: inline">
+ <input type="submit" value="<%= message('rules_configuration.revert_to_parent_definition') -%>">
+ </form>
+ <% end %>
+ </td>
+ </tr>
+ <% end %>
+ <% rule.parameters.sort.each do |parameter|
+ active_parameter = active_rule.active_param_by_param_id(parameter.id) if active_rule
+ %>
+ <tr id="param_<%= parameter.id -%>">
+ <%= render :partial => 'rule_param', :object => nil,
+ :locals => {:parameter => parameter, :active_parameter => active_parameter, :profile => profile, :rule => rule,
+ :active_rule => active_rule, :ancestor_active_rule => ancestor_active_rule} %>
+ </tr>
+ <%
+ end
+ %>
+ </table>
+ <% end %>
+
+ <% if active_rule %>
+ <div id="active_rule_note_<%= active_rule.id -%>">
+ <%= render :partial => 'active_rule_note', :locals => {:active_rule => active_rule, :profile => profile} %>
+ </div>
+ <% end %>
+
+ <% if profiles_administrator? %>
+ <% if rule.template? %>
+ <%= link_to message('rules_configuration.copy_rule'), {:action => 'new', :id => profile.id, :rule_id => rule.id}, :id => "copy-#{u rule.key}", :class => 'link-action spacer-right' %>
+ <% end %>
+ <% if rule.editable? %>
+ <%= link_to message('rules_configuration.edit_rule'), {:action => 'edit', :id => profile.id, :rule_id => rule.id}, :class => 'link-action spacer-right' %>
+ <% end %>
+ <% end %>
+
+ <div class="note">
+ <span id="rule_repository_<%= rule.id -%>"><%= message('rules_configuration.repository') %>: <%= rule.repository_key %></span>
+ <%= image_tag 'sep12.png' -%>
+ <span id="rule_key_<%= rule.id -%>"><%= message('key') %>: <%= rule.plugin_rule_key %></span>
+ <%= image_tag 'sep12.png' -%>
+ <% if rule.removed? %>
+ <span id="rule_available_since_<%= rule.id -%>"><%= message('rules_configuration.removed_since') %>: <%= human_short_date(rule.updated_at) %></span>
+ <% else %>
+ <span id="rule_available_since_<%= rule.id -%>"><%= message('rules_configuration.available_since') %> <%= human_short_date(rule.created_at) %></span>
+ <% end %>
+ </div>
+ </div>
+</td>
--- /dev/null
+<% #locals = rule
+ note = rule.note
+ note_detail_div_id = "nd_" + rule.id.to_s
+ note_extend_link_id = "nel_" + rule.id.to_s
+ note_form_div_id = "nf_" + rule.id.to_s
+ note_textarea_id = "nt_" + rule.id.to_s
+ submit_note_update_button_id = "snub_" + rule.id.to_s
+%>
+
+<div id="<%= note_detail_div_id -%>">
+ <div class="marginbottom10">
+ <% if rule.description.strip.start_with?('<p>') %>
+ <%= Internal.text.interpretMacros(rule.description) %>
+ <% else %>
+ <p><%= Internal.text.interpretMacros(rule.description) %></p>
+ <% end %>
+ </div>
+
+ <% if note && !note.text.strip.blank? %>
+ <p><%= note.html_text -%></p>
+ <% end %>
+
+ <% if profiles_administrator? %>
+ <div>
+ <a href="#" id="<%= note_extend_link_id -%>" class="link-action spacer-right"
+ onclick="$j('#<%= note_detail_div_id -%>').hide();$j('#<%= note_form_div_id -%>').show();$j('#<%= note_textarea_id -%>').focus();return false;"><%= message('rules_configuration.extend_description') %></a>
+ </div>
+ <% end %>
+</div>
+
+<% if profiles_administrator? %>
+<div id="<%= note_form_div_id -%>" style="display: none" class="admin">
+
+ <form onsubmit="$j.ajax({
+ url:'<%=ApplicationController.root_context-%>/new_rules_configuration/update_rule_note?rule_id=<%=rule.id-%>',
+ success:function(response){;$j('#rule_note_<%=rule.id-%>').html(response);},
+ data: $j(this).serialize(),
+ type:'post'});
+ return false;"
+ method="post"
+ action="<%=ApplicationController.root_context-%>/new_rules_configuration/update_rule_note?rule_id=<%=rule.id-%>">
+ <table class="width100 table">
+ <tbody>
+ <tr>
+ <td colspan="2"><%= rule.description %></td>
+ </tr>
+ <tr>
+ <td class="width100" colspan="2">
+ <textarea name="text" id="<%= note_textarea_id -%>" rows="10" style="width:100%"><%= h(note.plain_text) if note -%></textarea>
+ </td>
+ </tr>
+ <tr>
+ <td>
+ <input type="submit" value="<%= message('rules_configuration.extend_description') -%>" name="commit" id="<%= submit_note_update_button_id -%>"/>
+ <a href="#" onclick="$j('#<%= note_detail_div_id -%>').show();$j('#<%= note_form_div_id -%>').hide();return false;"><%= message('cancel') %></a>
+ </td>
+ <td align="right">
+ <%= render :partial => 'markdown/tips' -%>
+ </td>
+ </tr>
+ </tbody>
+ </table>
+ </form>
+</div>
+<% end %>
--- /dev/null
+<% param_value = parameter.default_value || ''
+ param_value = active_parameter.value if active_parameter
+ active_param_id = active_parameter.id if active_parameter
+ active_rule_id = active_rule.id if active_rule
+ read_only = !active_rule || !profiles_administrator?
+%>
+
+<td class="form-key-cell"><%= parameter.name -%></td>
+
+<td class="form-val-cell">
+ <form onsubmit="$j.ajax({ url: '<%= ApplicationController.root_context -%>/new_rules_configuration/update_param/<%=active_param_id-%>?active_rule_id=<%=active_rule_id-%>¶m_id=<%=parameter.id-%>&profile_id=<%=profile.id-%>',
+ type:'post',beforeSend: function(request){$j('#param_loading_<%=parameter.id-%>').show();$j('#error_<%=parameter.id-%>').hide();},
+ data: $j(this).serialize(),
+ success: function(response){$j('#rule_<%=rule.id-%>').html(response);},
+ complete: function(request){$j('#desc_<%=rule.id-%>').show();$j('#param_loading_<%=parameter.id-%>').hide();},
+ error: function(request){$j('#error_<%=parameter.id-%>').text(request.responseText);$j('#error_<%=parameter.id-%>').show();}
+ }); return false;"
+ name="form-<%=u parameter.name-%>" method="post"
+ action="<%= ApplicationController.root_context -%>/new_rules_configuration/update_param/<%=active_param_id-%>?active_rule_id=<%=active_rule_id-%>¶m_id=<%=parameter.id-%>&profile_id=<%=profile.id-%>">
+
+ <div id="error_<%= parameter.id -%>" class="error" style="display: none"></div>
+
+ <span id="text_<%= parameter.id -%>"><%= param_value_input(parameter, param_value, :disabled => read_only) -%></span>
+
+ <% unless read_only %>
+ <%= submit_tag(message('update_verb'), :id => 'submit_' + parameter.id.to_s) %>
+ <img src="<%= ApplicationController.root_context -%>/images/loading.gif" style="display:none;" id="param_loading_<%= parameter.id -%>" class="rule-param-loading">
+ <% if active_parameter and active_parameter.errors.size>0 %>
+ <span class="error"><%= active_parameter.errors.on 'value' %></span>
+ <% end %>
+ <% end %>
+
+ <% if active_rule && active_rule.overrides? && ancestor_active_rule
+ ancestor_param = ancestor_active_rule.active_param_by_param_id(parameter.id)
+ ancestor_value = ancestor_param && ancestor_param.value ? ancestor_param.value : ''
+ %>
+ <% if ancestor_value != param_value %>
+ <img src="<%= ApplicationController.root_context -%>/images/overrides.png" alt="Overrides parent definition" title="<%= message('rules_configuration.overrides_parent_definition') -%>" style="vertical-align: middle"/>
+ <span class="form-val-note" style="font-weight: bold; vertical-align: middle;">
+ <%= message('rules_configuration.original_value') -%>
+ : <%= ancestor_value.blank? ? '(' + message('rules_configuration.parent_parameter.empty') + ')' : ancestor_value -%>
+ </span>
+ <% end %>
+ <% end %>
+
+ <div class="form-val-note"><%= h(parameter.description || "") -%> <%= ('(' + readable_type(parameter.param_type) + ')') if !readable_type(parameter.param_type).empty? -%></div>
+
+ </form>
+</td>
--- /dev/null
+<h1 class="marginbottom10"><%= link_to message('quality_profiles.quality_profiles'), :controller => 'profiles', :action => 'index' -%> / <%= h @profile.language -%> / <%= h @profile.name %></h1>
+
+<%= render :partial => 'profiles/tabs', :locals => {:new_tab => 'Edit rule'} %>
+
+<div class="tabs-panel marginbottom10 background-gray">
+
+<form method="POST" id="delete-form" action="<%= url_for :action => 'delete', :id => @profile.id, :rule_id => @rule.id -%>" style="display: none"></form>
+<script>
+ function deleteRule() {
+ var count = <%= ActiveRule.count(:conditions => {:rule_id => @rule.id}) -%>;
+ var message = 'Are you sure?';
+ if (count>0) {
+ message += ' This rule is activated in ' + count + ' profiles.';
+ }
+ if (confirm(message)) {
+ $j('#delete-form').submit();
+ }
+ return false;
+ }
+</script>
+<form method="POST" action="<%= url_for :action => 'update', :id => @profile.id, :rule_id => @rule.id -%>">
+<table width="100%" class="spaced">
+ <tr>
+ <td width="1%" nowrap><%= message('template') -%>:</td>
+ <td class="sep"> </td>
+ <td><%= h @rule.parent.name -%></td>
+ </tr>
+ <tr>
+ <td width="1%" nowrap><%= message('name') -%>:</td>
+ <td class="sep"> </td>
+ <td><input type="text" name="rule[name]" size="80" value="<%= h @rule.name -%>" /></td>
+ </tr>
+ <tr>
+ <td width="1%" nowrap><%= message('default_severity') -%>:</td>
+ <td class="sep"> </td>
+ <td>
+ <select name="rule[priority]">
+ <%= options_for_select(Sonar::RulePriority.as_options, Sonar::RulePriority.to_s(@rule.priority)) %>
+ </select>
+ </td>
+ </tr>
+ <% @rule.parameters.sort{|x,y| x.name <=> y.name}.each do |parameter| %>
+ <tr>
+ <td width="1%" nowrap><%= parameter.name %>:</td>
+ <td class="sep"> </td>
+ <td>
+ <%= param_value_input(parameter, "#{h parameter.default_value}", {:name => "rule_param[#{h parameter.name }]", :size => '80x10'}) -%>
+ <span class="small"><%= h parameter.description %></span>
+ </td>
+ </tr>
+ <% end %>
+ <tr>
+ <td width="1%" nowrap style="vertical-align: top">Description:</td>
+ <td class="sep"> </td>
+ <td valign="top">
+ <textarea name="rule[description]" cols="80" rows="10" style="vertical-align: baseline"><%= @rule.description -%></textarea>
+ <span class="small"><%= message('rules_configuration.html_allowed') -%></span>
+ </td>
+ </tr>
+ <tr>
+ <td colspan="3">
+ <input type="submit" value="<%= message('update_verb') -%>" />
+ <input type="submit" value="<%= message('delete') -%>" onclick="return deleteRule()" class="red-button" />
+ <a href="<%= url_for :action => 'index', :id => @profile.id -%>"><%= message('cancel') -%></a>
+ </td>
+ </tr>
+</table>
+</form>
+</div>
\ No newline at end of file
--- /dev/null
+<div class="page">
+<script>
+ var localModifications=false;
+
+ function get_level_for_rule(rule_select_box,rule_check_box) {
+ return rule_check_box.prop('checked') ? rule_select_box.val() : '';
+ }
+
+ function submitBulkForm() {
+ if (localModifications) {
+ alert("Please refresh the search results before.");
+ $j('#bulk-form').reset();
+ } else {
+ $j('#bulk-form').submit();
+ $j('#select-bulk-change').select2('disable');
+ }
+ return !localModifications;
+ }
+
+ function downloadCsv() {
+ if (localModifications) {
+ alert("Please refresh the search results before.");
+ }
+ return !localModifications;
+ }
+
+ function expand_rules(){
+ $j('.rule-desc').show();
+ }
+
+ function collapse_rules(){
+ $j('.rule-desc').hide();
+ }
+
+ function submitSearch() {
+ $j("#rules-search-form").submit();
+ }
+
+ function submitSortBy(){
+ $j('#sort_by').val($j('#select-rules-sort-by').val());
+ $j("#rules-search-form").submit();
+ }
+</script>
+<%= render :partial => 'profiles/tabs', :locals => {:selected_tab=>'Coding rules reloaded'} %>
+
+<% enable_modification = profiles_administrator? %>
+<div class="tabs-panel marginbottom10 background-gray">
+
+<% form_tag({:action => 'index'}, {:id => 'rules-search-form', :method => 'get'}) do %>
+ <%= hidden_field_tag "sort_by", @sort_by, :id => 'sort_by' %>
+
+ <div class="table" id="search_table">
+ <div class="rule-search top">
+ <span class="note"><%= message('name') -%>/<%= message('key') -%></span><br/>
+ <%= text_field_tag "searchtext", @searchtext, :id => 'searchtext' %>
+ </div>
+ <div class="rule-search top">
+ <span class="note"><%= message('rules_configuration.repository') -%></span><br/>
+ <%= dropdown_tag "repositories", options_for_select(@select_repositories, @repositories), {
+ :show_search_box => true,
+ :width => '120px',
+ :placeholder => message('any')
+ }, {:id => 'search_repository', :multiple => true} -%>
+ </div>
+ <div class="rule-search top">
+ <span class="note"><%= message('severity') -%></span><br/>
+ <%= dropdown_tag "priorities", options_for_select(@select_priority, @priorities), {
+ :show_search_box => true,
+ :width => '90px',
+ :placeholder => message('any')
+ }, {:id => 'search_priority', :multiple => true} -%>
+ </div>
+ <div class="rule-search top">
+ <span class="note"><%= message('activation') -%></span><br/>
+ <%= dropdown_tag "rule_activation", options_for_select(@select_activation, @activation), {
+ :width => '100px'
+ }, {:id => 'search_activation'} -%>
+ </div>
+ <div class="rule-search top">
+ <span class="note"><%= message('rules_configuration.status_filters') -%></span><br/>
+ <%= dropdown_tag "status", options_for_select(@select_status, @status), {
+ :show_search_box => true,
+ :width => '120px',
+ :placeholder => message('any')
+ }, {:id => 'search_status', :multiple => true} -%>
+ </div>
+ <% if @profile.inherited? %>
+ <div class="rule-search top">
+ <span class="note"><%= message('inheritance') -%></span><br/>
+ <%= dropdown_tag "inheritance", options_for_select(@select_inheritance, @inheritance), {
+ :width => '120px'
+ }, {:id => 'search_inheritance'} -%>
+ </div>
+ <% end %>
+ <div class="rule-search">
+ <br/>
+ <%= submit_tag message('search_verb'), :id => 'submit_search', :onclick => 'submitSearch();' %>
+ </div>
+ </div>
+
+<% end %>
+</div>
+<div class="line-block marginbottom10">
+ <ul style="float: right" class="horizontal">
+ <li class="marginleft10">
+ <div class="csv">
+ <a href="<%= url_for(:controller => 'api/rules', :action => 'index', :language => @profile.language, :profile => @profile.name, :plugins => @repositories.join(','),
+ :status => @activation, :inheritance => @inheritance, :searchtext => @searchtext, :priorities => @priorities.join(','), :format => 'csv') -%>"
+ onClick="return downloadCsv()" id="download-link" class=""><%= message('download_verb') -%></a>
+ </div>
+ </li>
+ <% if enable_modification && @rules.size>0 %>
+ <li class="marginleft10">
+ <div class="bulk-edit"><%= message('bulk_change') -%>:
+ <form action="<%= ApplicationController.root_context -%>/new_rules_configuration/bulk_edit" method="POST" id="bulk-form"
+ style="display: inline; vertical-align: middle; padding-right:5px">
+ <input type="hidden" name="id" value="<%= @profile.id -%>"/>
+ <input type="hidden" name="bulk_rule_ids" value="<%= @rules.map{|r| r.id}.join(',') -%>"/>
+ <%= dropdown_tag "bulk_action", options_for_select([ ["", ""], [message('activate_all'), "activate"], [message('deactivate_all'), "deactivate"] ], ''), {
+ :width => '110px'
+ }, {:onChange => 'submitBulkForm()', :id => 'select-bulk-change'} -%>
+ </form>
+ </div>
+ </li>
+ <% end %>
+ </ul>
+ <h2>
+ <% if @hidden_actives && @hidden_actives>0 %>
+ <span class="small"><a href="<%= url_for params.merge({:rule_activation => ''}) -%>"
+ id="active-rules-link">+<%= message('rules_configuration.x_found_in_active_rules', :params => @hidden_actives) -%></a></span><% end %>
+ <% if @hidden_inactives && @hidden_inactives>0 %>
+ <span class="small"><a href="<%= url_for params.merge({:rule_activation => ''}) -%>"
+ id="inactive-rules-link">+<%= message('rules_configuration.x_found_in_inactive_rules', :params => @hidden_inactives) -%></a></span><% end %>
+ </h2>
+</div>
+<table class="table table-bordered width100 spacer-bottom" id="result_table">
+ <thead>
+ <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'), "expand_rules()") %> / <%= link_to_function(message('rules_configuration.collapse'), "collapse_rules()") %>]</span></th>
+ <th class="right" nowrap>
+ <span class="middle"><%= message('rules_configuration.sort_by') -%></span>
+ <% form_tag({:action => 'index'}, :class=> 'middle', :style => 'display:inline-block') do %>
+ <%= dropdown_tag "sort_by", options_for_select(@select_sort_by, @sort_by), {
+ :width => '120px'
+ }, {:id => 'select-rules-sort-by', :onChange => 'submitSortBy()'} -%>
+ <% end %>
+ </th>
+ </tr>
+</thead>
+
+<%= table_pagination(@pagination, :colspan => 2) { |label, page_id| link_to(label, params.merge({:page => page_id}))} -%>
+
+<tbody>
+<% if @current_rules.empty? %>
+<tr><td colspan="3" class="even"><%= message('no_results') -%>.</td></tr>
+<% end %>
+<%
+ @current_rules.each do |rule|
+ active_rule = @profile.active_by_rule_id(rule.id)
+%>
+ <tr id="rule_<%= rule.id -%>">
+ <%= render :partial => 'rule', :object => rule, :locals => {:profile => @profile, :rule => rule, :active_rule => active_rule} %>
+ </tr>
+<% end %>
+</tbody>
+</table>
+</div>
--- /dev/null
+<div class="page">
+<%= render :partial => 'profiles/tabs', :locals => {:new_tab => message('rules_configuration.tab.new_rule')} %>
+
+<div class="tabs-panel marginbottom10 background-gray">
+
+<form method="POST" action="<%= url_for :action => 'create', :id => @profile.id, :rule_id => @rule.id -%>">
+<table width="100%" class="spaced">
+ <tr>
+ <td width="1%" nowrap><%= message('template') -%>:</td>
+ <td class="sep"> </td>
+ <td><%= h @rule.name -%></td>
+ </tr>
+ <tr>
+ <td width="1%" nowrap><%= message('name') -%>:</td>
+ <td class="sep"> </td>
+ <td><input type="text" name="rule[name]" size="80"/></td>
+ </tr>
+ <tr>
+ <td width="1%" nowrap><%= message('default_severity') -%>:</td>
+ <td class="sep"> </td>
+ <td>
+ <select name="rule[priority]">
+ <%= options_for_select(Sonar::RulePriority.as_options) %>
+ </select>
+ </td>
+ </tr>
+ <% @rule.parameters.sort{|x,y| x.name <=> y.name}.each do |parameter| %>
+ <tr>
+ <td width="1%" nowrap><%= parameter.name %>:</td>
+ <td class="sep"> </td>
+ <td>
+ <%= param_value_input(parameter, "", {:name => "rule_param[#{h parameter.name}]", :size => '80x10'}) -%>
+ <span class="small"><%= h parameter.description %></span>
+ </td>
+ </tr>
+ <% end %>
+ <tr>
+ <td width="1%" nowrap style="vertical-align: top"><%= message('description') -%>:</td>
+ <td class="sep"> </td>
+ <td valign="top">
+ <textarea name="rule[description]" cols="80" rows="10" style="vertical-align: baseline"></textarea>
+ <span class="small"><%= message('rules_configuration.html_allowed') -%></span>
+ </td>
+ </tr>
+ <tr>
+ <td colspan="3">
+ <input type="submit" value="<%= message('create') -%>"/> <a href="<%= url_for :action => 'index', :id => @profile.id -%>"><%= message('cancel') -%></a>
+ </td>
+ </tr>
+</table>
+</form>
+</div>
+</div>
<li>
<a href="<%= url_for :controller => 'profiles', :action => 'changelog', :id => @profile.id -%>" <%= "class='selected'" if selected_tab=='changelog' -%> id="tab-changelog"><%= message('changelog') -%></a>
</li>
+ <li>
+ <a href="<%= url_for :controller => 'new_rules_configuration', :action => 'index', :id => @profile.id %>" <%= "class='selected'" if selected_tab=='Coding rules reloaded' -%> id="tab-rules"><%= message('Coding rules reloaded') -%></a>
+ </li>
<% if new_tab %>
<li>
<a href="#" class='selected'><%= new_tab -%></a>