Added autoassign issue feature

This commit is contained in:
Alexander Meindl
2016-07-03 15:56:13 +02:00
parent a85b9e10de
commit 3fc334ac6b
11 changed files with 73 additions and 33 deletions

View File

@ -17,6 +17,7 @@ Changelog
- remove garfield support (because there is no image source server available)
- slideshare wiki macro has been added
- issue wiki macro has been added
- autoassign issue if no assignee is selected
0.5.7
+++++

View File

@ -1,8 +1,8 @@
<% tweak_tabs = [ {:name => 'general', :partial => 'settings/redmine_tweaks_general', :label => :label_settings_general},
{:name => 'content', :partial => 'settings/redmine_tweaks_content', :label => :label_settings_content},
{:name => 'rules', :partial => 'settings/redmine_tweaks_rules', :label => :label_settings_rules},
{:name => 'menu', :partial => 'settings/redmine_tweaks_menu', :label => :label_settings_menu},
{:name => 'macros', :partial => 'settings/redmine_tweaks_macros', :label => :label_settings_macros}
<% tweak_tabs = [ { name: 'general', partial: 'settings/redmine_tweaks_general', label: :label_settings_general},
{ name: 'content', partial: 'settings/redmine_tweaks_content', label: :label_settings_content},
{ name: 'rules', partial: 'settings/redmine_tweaks_rules', label: :label_settings_rules},
{ name: 'menu', partial: 'settings/redmine_tweaks_menu', label: :label_settings_menu},
{ name: 'macros', partial: 'settings/redmine_tweaks_macros', label: :label_settings_macros}
] %>
<%= render_tabs tweak_tabs %>

View File

@ -3,66 +3,66 @@
<p>
<%= content_tag(:label, l(:label_account_login)) %>
<%= text_area_tag 'settings[account_login_bottom]', @settings[:account_login_bottom], :class => 'wiki-edit', :rows => 10 %>
<%= text_area_tag 'settings[account_login_bottom]', @settings[:account_login_bottom], class: 'wiki-edit', rows: 10 %>
<em class="info"><%= l(:account_login_info) %></em>
</p>
<p>
<%= content_tag(:label, l(:label_new_ticket_message)) %>
<%= text_area_tag 'settings[new_ticket_message]', @settings[:new_ticket_message], :class => 'wiki-edit', :rows => 10 %>
<%= text_area_tag 'settings[new_ticket_message]', @settings[:new_ticket_message], class: 'wiki-edit', rows: 10 %>
<em class="info"><%= l(:new_ticket_message_info) %></em>
</p>
<p>
<%= content_tag(:label, l(:label_overview_right)) %>
<%= text_area_tag 'settings[overview_right]', @settings[:overview_right], :class => 'wiki-edit', :rows => 10 %>
<%= text_area_tag 'settings[overview_right]', @settings[:overview_right], class: 'wiki-edit', rows: 10 %>
<em class="info"><%= l(:overview_right_info) %></em>
</p>
<p>
<%= content_tag(:label, l(:label_overview_top)) %>
<%= text_area_tag 'settings[overview_top]', @settings[:overview_top], :class => 'wiki-edit', :rows => 10 %>
<%= text_area_tag 'settings[overview_top]', @settings[:overview_top], class: 'wiki-edit', rows: 10 %>
<em class="info"><%= l(:overview_top_info) %></em>
</p>
<p>
<%= content_tag(:label, l(:label_overview_bottom)) %>
<%= text_area_tag 'settings[overview_bottom]', @settings[:overview_bottom], :class => 'wiki-edit', :rows => 10 %>
<%= text_area_tag 'settings[overview_bottom]', @settings[:overview_bottom], class: 'wiki-edit', rows: 10 %>
<em class="info"><%= l(:overview_bottom_info) %></em>
</p>
<p>
<%= content_tag(:label, l(:label_project_overview_content)) %>
<%= text_area_tag 'settings[project_overview_content]', @settings[:project_overview_content], :class => 'wiki-edit', :rows => 10 %>
<%= text_area_tag 'settings[project_overview_content]', @settings[:project_overview_content], class: 'wiki-edit', rows: 10 %>
<em class="info"><%= l(:project_overview_content_info) %></em>
</p>
<p>
<%= content_tag(:label, l(:label_global_sidebar)) %>
<%= text_area_tag 'settings[global_sidebar]', @settings[:global_sidebar], :class => 'wiki-edit', :rows => 10 %>
<%= text_area_tag 'settings[global_sidebar]', @settings[:global_sidebar], class: 'wiki-edit', rows: 10 %>
<em class="info"><%= l(:global_sidebar_info) %></em>
</p>
<p>
<%= content_tag(:label, l(:label_global_wiki_sidebar)) %>
<%= text_area_tag 'settings[global_wiki_sidebar]', @settings[:global_wiki_sidebar], :class => 'wiki-edit', :rows => 10 %>
<%= text_area_tag 'settings[global_wiki_sidebar]', @settings[:global_wiki_sidebar], class: 'wiki-edit', rows: 10 %>
<em class="info"><%= l(:global_wiki_sidebar_info) %></em>
</p>
<p>
<%= content_tag(:label, l(:label_global_wiki_header)) %>
<%= text_area_tag 'settings[global_wiki_header]', @settings[:global_wiki_header], :class => 'wiki-edit', :rows => 5 %>
<%= text_area_tag 'settings[global_wiki_header]', @settings[:global_wiki_header], class: 'wiki-edit', rows: 5 %>
<em class="info"><%= l(:global_wiki_header_info) %></em>
</p>
<p>
<%= content_tag(:label, l(:label_global_wiki_footer)) %>
<%= text_area_tag 'settings[global_wiki_footer]', @settings[:global_wiki_footer], :class => 'wiki-edit', :rows => 5 %>
<%= text_area_tag 'settings[global_wiki_footer]', @settings[:global_wiki_footer], class: 'wiki-edit', rows: 5 %>
<em class="info"><%= l(:global_wiki_footer_info) %></em>
</p>
<p>
<%= content_tag(:label, l(:label_global_footer)) %>
<%= text_area_tag 'settings[global_footer]', @settings[:global_footer], :class => 'wiki-edit', :rows => 5 %>
<%= text_area_tag 'settings[global_footer]', @settings[:global_footer], class: 'wiki-edit', rows: 5 %>
<em class="info"><%= l(:global_footer_info) %></em>
</p>

View File

@ -1,16 +1,16 @@
<p>
<%= content_tag(:label, l(:label_external_urls)) %>
<%= select_tag 'settings[external_urls]', options_for_select({
l(:external_url_default) => "0",
l(:external_url_new_window) => "1",
l(:external_url_noreferrer) => "2"
l(:external_url_default) => '0',
l(:external_url_new_window) => '1',
l(:external_url_noreferrer) => '2'
}, @settings['external_urls']) %>
<em class="info"><%= t(:external_urls_info_html) %></em>
</p>
<p>
<%= content_tag(:label, l(:label_custom_help_url)) %>
<%= text_field_tag('settings[custom_help_url]', @settings[:custom_help_url], :size => 60) %>
<%= text_field_tag('settings[custom_help_url]', @settings[:custom_help_url], size: 60) %>
<em class="info"><%= t(:custom_help_url_info_html) %></em>
</p>
@ -47,6 +47,6 @@
<p>
<% disabled_modules = Struct.new(:id, :name) %>
<%= content_tag(:label, l(:label_disabled_modules)) %>
<%= select_tag("settings[disabled_modules]", options_from_collection_for_select(Redmine::AccessControl.available_project_modules.collect {|m| disabled_modules.new(m, l_or_humanize(m, :prefix => "project_module_").to_s) }, :id, :name, @settings[:disabled_modules]), { :multiple=> true, :style => "height: 300px;" }) %>
<%= select_tag("settings[disabled_modules]", options_from_collection_for_select(Redmine::AccessControl.available_project_modules.collect {|m| disabled_modules.new(m, l_or_humanize(m, prefix: 'project_module_').to_s) }, :id, :name, @settings[:disabled_modules]), { multiple: true, style: 'height: 300px;' }) %>
<em class="info"><%= l(:disabled_modules_info) %></em>
</p>

View File

@ -5,17 +5,17 @@
<fieldset>
<legend><b><%=h l(:label_menu_entry) %> #<%= i+1 %></b></legend>
<div>
<p><label><%=h l(:field_name)%></label><%= text_field_tag('settings[custom_menu'+i.to_s+'_name]', @settings['custom_menu'+i.to_s+'_name'], :size => 40) %></p>
<p><label><%=h l(:field_url)%></label><%= text_field_tag('settings[custom_menu'+i.to_s+'_url]', @settings['custom_menu'+i.to_s+'_url'], :size => 80) %></p>
<p><label><%=h l(:field_title)%></label><%= text_field_tag('settings[custom_menu'+i.to_s+'_title]', @settings['custom_menu'+i.to_s+'_title'], :size => 80) %> <i>(<%=l(:label_optional)%>)</i></p>
<p><label><%=h l(:field_name)%></label><%= text_field_tag('settings[custom_menu'+i.to_s+'_name]', @settings['custom_menu'+i.to_s+'_name'], size: 40) %></p>
<p><label><%=h l(:field_url)%></label><%= text_field_tag('settings[custom_menu'+i.to_s+'_url]', @settings['custom_menu'+i.to_s+'_url'], size: 80) %></p>
<p><label><%=h l(:field_title)%></label><%= text_field_tag('settings[custom_menu'+i.to_s+'_title]', @settings['custom_menu'+i.to_s+'_title'], size: 80) %> <i>(<%=l(:label_optional)%>)</i></p>
<p><label><%=h l(:label_permissions)%></label>
<% permission_field = 'custom_menu'+i.to_s+'_roles' %>
<% menu_roles = Struct.new(:id, :name) %>
<%= select_tag('settings['+permission_field+']', options_from_collection_for_select(Role.sorted.collect {|m| menu_roles.new(m.id, m.name) }, :id, :name, @settings[permission_field]), { :multiple=> true, :style => "height: 100px;" }) %>
<%= select_tag('settings['+permission_field+']', options_from_collection_for_select(Role.sorted.collect {|m| menu_roles.new(m.id, m.name) }, :id, :name, @settings[permission_field]), { multiple: true, style: 'height: 100px;' }) %>
<em class="info"><%= l(:menu_roles_info) %></em>
</p>
</p>
</div>
</fieldset>
<% end %>
<% end %>

View File

@ -12,8 +12,8 @@
<%= content_tag(:label, l(:label_rule_issue_status_change)) %>
<%= check_box_tag 'settings[issue_status_change]', 1, @settings[:issue_status_change] %>
<span style="vertical-align: top; margin-left: 15px;">
<%= l(:field_status) %> x: <%= select_tag 'settings[issue_status_x]', options_for_select(rule_status.collect{|column| [column.name, column.id]}, @settings[:issue_status_x]), :multiple => true, :size => 6, :style => "width:150px" %>
<%= l(:field_status) %> y: <%= select_tag 'settings[issue_status_y]', options_for_select(rule_status.collect{|column| [column.name, column.id]}, @settings[:issue_status_y]), :multiple => false, :style => "width:150px; vertical-align: top" %>
<%= l(:field_status) %> x: <%= select_tag 'settings[issue_status_x]', options_for_select(rule_status.collect{|column| [column.name, column.id]}, @settings[:issue_status_x]), multiple: true, size: 6, style: 'width:150px' %>
<%= l(:field_status) %> y: <%= select_tag 'settings[issue_status_y]', options_for_select(rule_status.collect{|column| [column.name, column.id]}, @settings[:issue_status_y]), multiple: false, style: 'width:150px; vertical-align: top' %>
</span>
</p>
<em class="info"><%= t(:rule_issue_status_change_info) %></em>
@ -24,7 +24,19 @@
<%= content_tag(:label, l(:label_rule_issue_current_user_status)) %>
<%= check_box_tag 'settings[issue_current_user_status]', 1, @settings[:issue_current_user_status] %>
<span style="vertical-align: top; margin-left: 15px;">
<%= l(:field_status) %> x: <%= select_tag 'settings[issue_assign_to_x]', options_for_select(rule_status.collect{|column| [column.name, column.id]}, @settings[:issue_assign_to_x]), :multiple => true, :size => 6, :style => "width:150px" %>
<%= l(:field_status) %> x: <%= select_tag 'settings[issue_assign_to_x]', options_for_select(rule_status.collect{|column| [column.name, column.id]}, @settings[:issue_assign_to_x]), multiple: true, size: 6, style: 'width:150px' %>
</span>
</p>
<em class="info"><%= t(:rule_issue_current_user_status_info) %></em>
<br /><br />
<p>
<%= content_tag(:label, l(:label_rule_issue_auto_assign)) %>
<%= check_box_tag 'settings[issue_auto_assign]', 1, @settings[:issue_auto_assign] %>
<span style="vertical-align: top; margin-left: 15px;">
<%= l(:field_status) %> x: <%= select_tag 'settings[issue_auto_assign_status]', options_for_select(rule_status.collect{|column| [column.name, column.id]}, @settings[:issue_auto_assign_status]), multiple: true, size: 6, style: 'width:150px' %>
<%= l(:label_role) %>: <%= select_tag 'settings[issue_auto_assign_role]', options_from_collection_for_select(Role.givable.sorted, :id, :name, @settings[:issue_auto_assign_role]), multiple: false, style: 'width:150px; vertical-align: top' %>
</span>
</p>
<em class="info"><%= t(:rule_issue_auto_assign_info) %></em>

View File

@ -81,3 +81,5 @@ de:
issue_cannot_close_with_open_children: "Das Ticket kann nicht geschlossen werden, bevor nicht alle Untertickets geschlossen wurden."
issue_current_user_status: "Der ausgewählte Status erfordert, dass \"Zugewiesen an\" Dir selbst zugeordnet wird."
label_tweaks: Tweaks
label_rule_issue_auto_assign: Wird "Zugewiesen an" nicht zugewiesen und der neue Ticketstatus ist x, dann wird dem erste Benutzer mit der festgelegten Rolle das Ticket zugewiesen.
rule_issue_auto_assign_info: 'Use Case: Der Ticketersteller weiss nicht, wem er das Ticket zurordnen soll bzw. wer Zuständig für das Ticket ist. Das neue Ticket mit dem Status "To Do" wird automatisch einem der Benutzer mit der Rolle Projektmanager zugewiesen.'

View File

@ -81,3 +81,5 @@ en:
issue_cannot_close_with_open_children: "This issue can only be closed, if all sub-issues are closed, too."
issue_current_user_status: "The selected status requires that the \"Assignee\" is yourself."
label_tweaks: Tweaks
label_rule_issue_auto_assign: Wird "Zugewiesen an" nicht zugewiesen und der neue Ticketstatus ist x, dann wird dem erste Benutzer mit der festgelegten Rolle das Ticket zugewiesen.
rule_issue_auto_assign_info: 'Use Case: Der Ticketersteller weiss nicht, wem er das Ticket zurordnen soll bzw. wer Zuständig für das Ticket ist. Das neue Ticket mit dem Status "To Do" wird automatisch einem der Benutzer mit der Rolle Projektmanager zugewiesen.'

View File

@ -21,6 +21,9 @@ Redmine::Plugin.register :redmine_tweaks do
'add_go_to_top' => false,
'remove_mypage' => false,
'disabled_modules' => nil,
'issue_auto_assign' => false,
'issue_auto_assign_status' => '',
'issue_auto_assign_role' => '',
'account_login_bottom' => '',
'new_ticket_message' => 'Don\'t forget to define acceptance criteria!',
'overview_right' => '',

View File

@ -13,6 +13,26 @@ module RedmineTweaks
render_on(:view_issues_sidebar_queries_bottom, partial: 'global_sidebar')
render_on(:view_projects_show_right, partial: 'project_overview')
render_on(:view_projects_show_sidebar_bottom, partial: 'global_sidebar')
def controller_issues_new_before_save(context)
issue_auto_assign(context)
end
def controller_issues_edit_before_save(context)
issue_auto_assign(context)
end
def issue_auto_assign(context)
return if RedmineTweaks.settings[:issue_auto_assign].blank? ||
RedmineTweaks.settings[:issue_auto_assign_status].nil? ||
RedmineTweaks.settings[:issue_auto_assign_role].nil?
if context[:params][:issue][:assigned_to_id].blank? &&
RedmineTweaks.settings[:issue_auto_assign_status].include?(context[:params][:issue][:status_id].to_s)
users_list = context[:issue].project.users_by_role
manager_role = Role.builtin.find(RedmineTweaks.settings[:issue_auto_assign_role].to_i)
context[:issue].assigned_to_id = users_list[manager_role].first.id unless users_list[manager_role].blank?
end
end
end
def self.settings

View File

@ -33,9 +33,9 @@ module RedmineTweaks
def validate_open_sub_issues
return true unless RedmineTweaks.settings[:issue_close_with_open_children]
if subject.present? && closing? && descendants.find { |d| !d.closed? }
errors.add :base, :issue_cannot_close_with_open_children
end
errors.add :base, :issue_cannot_close_with_open_children if subject.present? &&
closing? &&
descendants.find { |d| !d.closed? }
end
def validate_current_user_status