Patch #33337 » cleanup_workflows_controller.diff
| app/controllers/workflows_controller.rb | ||
|---|---|---|
| 22 | 22 |
self.main_menu = false |
| 23 | 23 | |
| 24 | 24 |
before_action :require_admin |
| 25 |
before_action :find_trackers_roles_and_statuses_for_edit, only: [:edit, :update, :permissions, :update_permissions] |
|
| 25 | 26 | |
| 26 | 27 |
def index |
| 27 | 28 |
@roles = Role.sorted.select(&:consider_workflow?) |
| ... | ... | |
| 30 | 31 |
end |
| 31 | 32 | |
| 32 | 33 |
def edit |
| 33 |
find_trackers_roles_and_statuses_for_edit |
|
| 34 |
if @trackers && @roles && @statuses.any? |
|
| 35 |
workflows = WorkflowTransition. |
|
| 36 |
where(:role_id => @roles.map(&:id), :tracker_id => @trackers.map(&:id)). |
|
| 37 |
preload(:old_status, :new_status) |
|
| 38 |
@workflows = {}
|
|
| 39 |
@workflows['always'] = workflows.select {|w| !w.author && !w.assignee}
|
|
| 40 |
@workflows['author'] = workflows.select {|w| w.author}
|
|
| 41 |
@workflows['assignee'] = workflows.select {|w| w.assignee}
|
|
| 42 |
end |
|
| 43 |
end |
|
| 34 | 44 | |
| 35 |
if request.post? && @roles && @trackers && params[:transitions] |
|
| 45 |
def update |
|
| 46 |
if @roles && @trackers && params[:transitions] |
|
| 36 | 47 |
transitions = params[:transitions].deep_dup |
| 37 | 48 |
transitions.each do |old_status_id, transitions_by_new_status| |
| 38 | 49 |
transitions_by_new_status.each do |new_status_id, transition_by_rule| |
| ... | ... | |
| 41 | 52 |
end |
| 42 | 53 |
WorkflowTransition.replace_transitions(@trackers, @roles, transitions) |
| 43 | 54 |
flash[:notice] = l(:notice_successful_update) |
| 44 |
redirect_to_referer_or workflows_edit_path |
|
| 45 |
return |
|
| 46 |
end |
|
| 47 | ||
| 48 |
if @trackers && @roles && @statuses.any? |
|
| 49 |
workflows = WorkflowTransition. |
|
| 50 |
where(:role_id => @roles.map(&:id), :tracker_id => @trackers.map(&:id)). |
|
| 51 |
preload(:old_status, :new_status) |
|
| 52 |
@workflows = {}
|
|
| 53 |
@workflows['always'] = workflows.select {|w| !w.author && !w.assignee}
|
|
| 54 |
@workflows['author'] = workflows.select {|w| w.author}
|
|
| 55 |
@workflows['assignee'] = workflows.select {|w| w.assignee}
|
|
| 56 | 55 |
end |
| 56 |
redirect_to_referer_or edit_workflows_path |
|
| 57 | 57 |
end |
| 58 | 58 | |
| 59 | 59 |
def permissions |
| 60 |
find_trackers_roles_and_statuses_for_edit |
|
| 60 |
if @roles && @trackers |
|
| 61 |
@fields = (Tracker::CORE_FIELDS_ALL - @trackers.map(&:disabled_core_fields).reduce(:&)).map {|field| [field, l("field_"+field.sub(/_id$/, ''))]}
|
|
| 62 |
@custom_fields = @trackers.map(&:custom_fields).flatten.uniq.sort |
|
| 63 |
@permissions = WorkflowPermission.rules_by_status_id(@trackers, @roles) |
|
| 64 |
@statuses.each {|status| @permissions[status.id] ||= {}}
|
|
| 65 |
end |
|
| 66 |
end |
|
| 61 | 67 | |
| 62 |
if request.post? && @roles && @trackers && params[:permissions] |
|
| 68 |
def update_permissions |
|
| 69 |
if @roles && @trackers && params[:permissions] |
|
| 63 | 70 |
permissions = params[:permissions].deep_dup |
| 64 | 71 |
permissions.each { |field, rule_by_status_id|
|
| 65 | 72 |
rule_by_status_id.reject! {|status_id, rule| rule == 'no_change'}
|
| 66 | 73 |
} |
| 67 | 74 |
WorkflowPermission.replace_permissions(@trackers, @roles, permissions) |
| 68 | 75 |
flash[:notice] = l(:notice_successful_update) |
| 69 |
redirect_to_referer_or workflows_permissions_path |
|
| 70 |
return |
|
| 71 | 76 |
end |
| 77 |
redirect_to_referer_or permissions_workflows_path |
|
| 78 |
end |
|
| 72 | 79 | |
| 73 |
if @roles && @trackers |
|
| 74 |
@fields = (Tracker::CORE_FIELDS_ALL - @trackers.map(&:disabled_core_fields).reduce(:&)).map {|field| [field, l("field_"+field.sub(/_id$/, ''))]}
|
|
| 75 |
@custom_fields = @trackers.map(&:custom_fields).flatten.uniq.sort |
|
| 76 |
@permissions = WorkflowPermission.rules_by_status_id(@trackers, @roles) |
|
| 77 |
@statuses.each {|status| @permissions[status.id] ||= {}}
|
|
| 80 |
def copy |
|
| 81 |
find_sources_and_targets |
|
| 82 |
end |
|
| 83 | ||
| 84 |
def duplicate |
|
| 85 |
find_sources_and_targets |
|
| 86 |
if params[:source_tracker_id].blank? || params[:source_role_id].blank? || |
|
| 87 |
(@source_tracker.nil? && @source_role.nil?) |
|
| 88 |
flash.now[:error] = l(:error_workflow_copy_source) |
|
| 89 |
render :copy |
|
| 90 |
elsif @target_trackers.blank? || @target_roles.blank? |
|
| 91 |
flash.now[:error] = l(:error_workflow_copy_target) |
|
| 92 |
render :copy |
|
| 93 |
else |
|
| 94 |
WorkflowRule.copy(@source_tracker, @source_role, @target_trackers, @target_roles) |
|
| 95 |
flash[:notice] = l(:notice_successful_update) |
|
| 96 |
redirect_to copy_workflows_path( |
|
| 97 |
:source_tracker_id => @source_tracker, |
|
| 98 |
:source_role_id => @source_role |
|
| 99 |
) |
|
| 78 | 100 |
end |
| 79 | 101 |
end |
| 80 | 102 | |
| 81 |
def copy |
|
| 103 |
private |
|
| 104 | ||
| 105 |
def find_sources_and_targets |
|
| 82 | 106 |
@roles = Role.sorted.select(&:consider_workflow?) |
| 83 | 107 |
@trackers = Tracker.sorted |
| 84 | ||
| 85 | 108 |
if params[:source_tracker_id].blank? || params[:source_tracker_id] == 'any' |
| 86 | 109 |
@source_tracker = nil |
| 87 | 110 |
else |
| ... | ... | |
| 93 | 116 |
@source_role = Role.find_by_id(params[:source_role_id].to_i) |
| 94 | 117 |
end |
| 95 | 118 |
@target_trackers = params[:target_tracker_ids].blank? ? |
| 96 |
nil : Tracker.where(:id => params[:target_tracker_ids]).to_a |
|
| 119 |
nil : Tracker.where(:id => params[:target_tracker_ids]).to_a
|
|
| 97 | 120 |
@target_roles = params[:target_role_ids].blank? ? |
| 98 |
nil : Role.where(:id => params[:target_role_ids]).to_a |
|
| 99 |
if request.post? |
|
| 100 |
if params[:source_tracker_id].blank? || params[:source_role_id].blank? || |
|
| 101 |
(@source_tracker.nil? && @source_role.nil?) |
|
| 102 |
flash.now[:error] = l(:error_workflow_copy_source) |
|
| 103 |
elsif @target_trackers.blank? || @target_roles.blank? |
|
| 104 |
flash.now[:error] = l(:error_workflow_copy_target) |
|
| 105 |
else |
|
| 106 |
WorkflowRule.copy(@source_tracker, @source_role, @target_trackers, @target_roles) |
|
| 107 |
flash[:notice] = l(:notice_successful_update) |
|
| 108 |
redirect_to( |
|
| 109 |
workflows_copy_path(:source_tracker_id => @source_tracker, |
|
| 110 |
:source_role_id => @source_role) |
|
| 111 |
) |
|
| 112 |
end |
|
| 113 |
end |
|
| 121 |
nil : Role.where(:id => params[:target_role_ids]).to_a |
|
| 114 | 122 |
end |
| 115 | 123 | |
| 116 |
private |
|
| 117 | ||
| 118 | 124 |
def find_trackers_roles_and_statuses_for_edit |
| 119 | 125 |
find_roles |
| 120 | 126 |
find_trackers |
| app/views/issue_statuses/index.html.erb | ||
|---|---|---|
| 26 | 26 |
<td> |
| 27 | 27 |
<% unless WorkflowTransition.where('old_status_id = ? OR new_status_id = ?', status.id, status.id).exists? %>
|
| 28 | 28 |
<span class="icon icon-warning"> |
| 29 |
<%= l(:text_status_no_workflow) %> (<%= link_to l(:button_edit), workflows_edit_path(:used_statuses_only => 0) %>)
|
|
| 29 |
<%= l(:text_status_no_workflow) %> (<%= link_to l(:button_edit), edit_workflows_path(:used_statuses_only => 0) %>)
|
|
| 30 | 30 |
</span> |
| 31 | 31 |
<% end %> |
| 32 | 32 |
</td> |
| app/views/roles/index.html.erb | ||
|---|---|---|
| 18 | 18 |
<td> |
| 19 | 19 |
<% unless role.builtin? || role.workflow_rules.exists? %> |
| 20 | 20 |
<span class="icon icon-warning"> |
| 21 |
<%= l(:text_role_no_workflow) %> (<%= link_to l(:button_edit), workflows_edit_path(:role_id => role) %>)
|
|
| 21 |
<%= l(:text_role_no_workflow) %> (<%= link_to l(:button_edit), edit_workflows_path(:role_id => role) %>)
|
|
| 22 | 22 |
</span> |
| 23 | 23 |
<% end %> |
| 24 | 24 |
</td> |
| ... | ... | |
| 36 | 36 | |
| 37 | 37 |
<%= javascript_tag do %> |
| 38 | 38 |
$(function() { $("table.roles tbody").positionedItems({items: ".givable"}); });
|
| 39 |
<% end %> |
|
| 39 |
<% end %> |
|
| app/views/trackers/index.html.erb | ||
|---|---|---|
| 22 | 22 |
<td> |
| 23 | 23 |
<% unless tracker.workflow_rules.exists? %> |
| 24 | 24 |
<span class="icon icon-warning"> |
| 25 |
<%= l(:text_tracker_no_workflow) %> (<%= link_to l(:button_edit), workflows_edit_path(:tracker_id => tracker) %>)
|
|
| 25 |
<%= l(:text_tracker_no_workflow) %> (<%= link_to l(:button_edit), edit_workflows_path(:tracker_id => tracker) %>)
|
|
| 26 | 26 |
</span> |
| 27 | 27 |
<% end %> |
| 28 | 28 |
</td> |
| app/views/workflows/copy.html.erb | ||
|---|---|---|
| 1 |
<%= title [l(:label_workflow), workflows_edit_path], l(:button_copy) %>
|
|
| 1 |
<%= title [l(:label_workflow), edit_workflows_path], l(:button_copy) %>
|
|
| 2 | 2 | |
| 3 |
<%= form_tag({}, :id => 'workflow_copy_form') do %>
|
|
| 3 |
<%= form_tag duplicate_workflows_path, method: :post, id: 'workflow_copy_form' do %>
|
|
| 4 | 4 |
<fieldset class="tabular box"> |
| 5 | 5 |
<legend><%= l(:label_copy_source) %></legend> |
| 6 | 6 |
<p> |
| app/views/workflows/edit.html.erb | ||
|---|---|---|
| 4 | 4 | |
| 5 | 5 |
<div class="tabs"> |
| 6 | 6 |
<ul> |
| 7 |
<li><%= link_to l(:label_status_transitions), workflows_edit_path(:role_id => @roles, :tracker_id => @trackers), :class => 'selected' %></li>
|
|
| 8 |
<li><%= link_to l(:label_fields_permissions), workflows_permissions_path(:role_id => @roles, :tracker_id => @trackers) %></li>
|
|
| 7 |
<li><%= link_to l(:label_status_transitions), edit_workflows_path(:role_id => @roles, :tracker_id => @trackers), :class => 'selected' %></li>
|
|
| 8 |
<li><%= link_to l(:label_fields_permissions), permissions_workflows_path(:role_id => @roles, :tracker_id => @trackers) %></li>
|
|
| 9 | 9 |
</ul> |
| 10 | 10 |
</div> |
| 11 | 11 | |
| ... | ... | |
| 32 | 32 |
<% end %> |
| 33 | 33 | |
| 34 | 34 |
<% if @trackers && @roles && @statuses.any? %> |
| 35 |
<%= form_tag({}, :id => 'workflow_form' ) do %>
|
|
| 35 |
<%= form_tag workflows_path, method: :patch, id: 'workflow_form' do %>
|
|
| 36 | 36 |
<%= @trackers.map {|tracker| hidden_field_tag 'tracker_id[]', tracker.id, :id => nil}.join.html_safe %>
|
| 37 | 37 |
<%= @roles.map {|role| hidden_field_tag 'role_id[]', role.id, :id => nil}.join.html_safe %>
|
| 38 | 38 |
<%= hidden_field_tag 'used_statuses_only', params[:used_statuses_only], :id => nil %> |
| app/views/workflows/index.html.erb | ||
|---|---|---|
| 1 |
<%= title [l(:label_workflow), workflows_edit_path], l(:field_summary) %>
|
|
| 1 |
<%= title [l(:label_workflow), edit_workflows_path], l(:field_summary) %>
|
|
| 2 | 2 | |
| 3 | 3 |
<% if @roles.empty? || @trackers.empty? %> |
| 4 | 4 |
<p class="nodata"><%= l(:label_no_data) %></p> |
| app/views/workflows/permissions.html.erb | ||
|---|---|---|
| 4 | 4 | |
| 5 | 5 |
<div class="tabs"> |
| 6 | 6 |
<ul> |
| 7 |
<li><%= link_to l(:label_status_transitions), workflows_edit_path(:role_id => @roles, :tracker_id => @trackers) %></li>
|
|
| 8 |
<li><%= link_to l(:label_fields_permissions), workflows_permissions_path(:role_id => @roles, :tracker_id => @trackers), :class => 'selected' %></li>
|
|
| 7 |
<li><%= link_to l(:label_status_transitions), edit_workflows_path(:role_id => @roles, :tracker_id => @trackers) %></li>
|
|
| 8 |
<li><%= link_to l(:label_fields_permissions), permissions_workflows_path(:role_id => @roles, :tracker_id => @trackers), :class => 'selected' %></li>
|
|
| 9 | 9 |
</ul> |
| 10 | 10 |
</div> |
| 11 | 11 | |
| ... | ... | |
| 30 | 30 |
<% end %> |
| 31 | 31 | |
| 32 | 32 |
<% if @trackers && @roles && @statuses.any? %> |
| 33 |
<%= form_tag({}, :id => 'workflow_form' ) do %>
|
|
| 33 |
<%= form_tag update_permissions_workflows_path, method: :patch, id: 'workflow_form' do %>
|
|
| 34 | 34 |
<%= @trackers.map {|tracker| hidden_field_tag 'tracker_id[]', tracker.id, :id => nil}.join.html_safe %>
|
| 35 | 35 |
<%= @roles.map {|role| hidden_field_tag 'role_id[]', role.id, :id => nil}.join.html_safe %>
|
| 36 | 36 |
<%= hidden_field_tag 'used_statuses_only', params[:used_statuses_only], :id => nil %> |
| config/routes.rb | ||
|---|---|---|
| 348 | 348 |
end |
| 349 | 349 |
end |
| 350 | 350 | |
| 351 |
match 'workflows', :controller => 'workflows', :action => 'index', :via => :get |
|
| 352 |
match 'workflows/edit', :controller => 'workflows', :action => 'edit', :via => [:get, :post] |
|
| 353 |
match 'workflows/permissions', :controller => 'workflows', :action => 'permissions', :via => [:get, :post] |
|
| 354 |
match 'workflows/copy', :controller => 'workflows', :action => 'copy', :via => [:get, :post] |
|
| 351 |
resources :workflows, only: [:index] do |
|
| 352 |
collection do |
|
| 353 |
get 'edit' |
|
| 354 |
patch 'update' |
|
| 355 |
get 'permissions' |
|
| 356 |
patch 'update_permissions' |
|
| 357 |
get 'copy' |
|
| 358 |
post 'duplicate' |
|
| 359 |
end |
|
| 360 |
end |
|
| 361 | ||
| 355 | 362 |
match 'settings', :controller => 'settings', :action => 'index', :via => :get |
| 356 | 363 |
match 'settings/edit', :controller => 'settings', :action => 'edit', :via => [:get, :post] |
| 357 | 364 |
match 'settings/plugin/:id', :controller => 'settings', :action => 'plugin', :via => [:get, :post], :as => 'plugin_settings' |
| test/functional/workflows_controller_test.rb | ||
|---|---|---|
| 134 | 134 |
def test_post_edit |
| 135 | 135 |
WorkflowTransition.delete_all |
| 136 | 136 | |
| 137 |
post :edit, :params => {
|
|
| 137 |
patch :update, :params => {
|
|
| 138 | 138 |
:role_id => 2, |
| 139 | 139 |
:tracker_id => 1, |
| 140 | 140 |
:transitions => {
|
| ... | ... | |
| 152 | 152 |
def test_post_edit_with_allowed_statuses_for_new_issues |
| 153 | 153 |
WorkflowTransition.delete_all |
| 154 | 154 | |
| 155 |
post :edit, :params => {
|
|
| 155 |
patch :update, :params => {
|
|
| 156 | 156 |
:role_id => 2, |
| 157 | 157 |
:tracker_id => 1, |
| 158 | 158 |
:transitions => {
|
| ... | ... | |
| 169 | 169 |
def test_post_edit_with_additional_transitions |
| 170 | 170 |
WorkflowTransition.delete_all |
| 171 | 171 | |
| 172 |
post :edit, :params => {
|
|
| 172 |
patch :update, :params => {
|
|
| 173 | 173 |
:role_id => 2, |
| 174 | 174 |
:tracker_id => 1, |
| 175 | 175 |
:transitions => {
|
| ... | ... | |
| 346 | 346 |
def test_post_permissions |
| 347 | 347 |
WorkflowPermission.delete_all |
| 348 | 348 | |
| 349 |
post :permissions, :params => {
|
|
| 349 |
patch :update_permissions, :params => {
|
|
| 350 | 350 |
:role_id => 1, |
| 351 | 351 |
:tracker_id => 2, |
| 352 | 352 |
:permissions => {
|
| ... | ... | |
| 389 | 389 |
def test_post_copy_one_to_one |
| 390 | 390 |
source_transitions = status_transitions(:tracker_id => 1, :role_id => 2) |
| 391 | 391 | |
| 392 |
post :copy, :params => {
|
|
| 392 |
post :duplicate, :params => {
|
|
| 393 | 393 |
:source_tracker_id => '1', :source_role_id => '2', |
| 394 | 394 |
:target_tracker_ids => ['3'], :target_role_ids => ['1'] |
| 395 | 395 |
} |
| ... | ... | |
| 400 | 400 |
def test_post_copy_one_to_many |
| 401 | 401 |
source_transitions = status_transitions(:tracker_id => 1, :role_id => 2) |
| 402 | 402 | |
| 403 |
post :copy, :params => {
|
|
| 403 |
post :duplicate, :params => {
|
|
| 404 | 404 |
:source_tracker_id => '1', :source_role_id => '2', |
| 405 | 405 |
:target_tracker_ids => ['2', '3'], :target_role_ids => ['1', '3'] |
| 406 | 406 |
} |
| ... | ... | |
| 415 | 415 |
source_t2 = status_transitions(:tracker_id => 2, :role_id => 2) |
| 416 | 416 |
source_t3 = status_transitions(:tracker_id => 3, :role_id => 2) |
| 417 | 417 | |
| 418 |
post :copy, :params => {
|
|
| 418 |
post :duplicate, :params => {
|
|
| 419 | 419 |
:source_tracker_id => 'any', :source_role_id => '2', |
| 420 | 420 |
:target_tracker_ids => ['2', '3'], :target_role_ids => ['1', '3'] |
| 421 | 421 |
} |
| ... | ... | |
| 428 | 428 | |
| 429 | 429 |
def test_post_copy_with_incomplete_source_specification_should_fail |
| 430 | 430 |
assert_no_difference 'WorkflowRule.count' do |
| 431 |
post :copy, :params => {
|
|
| 431 |
post :duplicate, :params => {
|
|
| 432 | 432 |
:source_tracker_id => '', :source_role_id => '2', |
| 433 | 433 |
:target_tracker_ids => ['2', '3'], :target_role_ids => ['1', '3'] |
| 434 | 434 |
} |
| ... | ... | |
| 439 | 439 | |
| 440 | 440 |
def test_post_copy_with_incomplete_target_specification_should_fail |
| 441 | 441 |
assert_no_difference 'WorkflowRule.count' do |
| 442 |
post :copy, :params => {
|
|
| 442 |
post :duplicate, :params => {
|
|
| 443 | 443 |
:source_tracker_id => '1', :source_role_id => '2', |
| 444 | 444 |
:target_tracker_ids => ['2', '3'] |
| 445 | 445 |
} |
| test/integration/routing/workflows_test.rb | ||
|---|---|---|
| 23 | 23 |
def test_workflows |
| 24 | 24 |
should_route 'GET /workflows' => 'workflows#index' |
| 25 | 25 |
should_route 'GET /workflows/edit' => 'workflows#edit' |
| 26 |
should_route 'POST /workflows/edit' => 'workflows#edit'
|
|
| 26 |
should_route 'PATCH /workflows/update' => 'workflows#update'
|
|
| 27 | 27 | |
| 28 | 28 |
should_route 'GET /workflows/permissions' => 'workflows#permissions' |
| 29 |
should_route 'POST /workflows/permissions' => 'workflows#permissions'
|
|
| 29 |
should_route 'PATCH /workflows/update_permissions' => 'workflows#update_permissions'
|
|
| 30 | 30 | |
| 31 | 31 |
should_route 'GET /workflows/copy' => 'workflows#copy' |
| 32 |
should_route 'POST /workflows/copy' => 'workflows#copy'
|
|
| 32 |
should_route 'POST /workflows/duplicate' => 'workflows#duplicate'
|
|
| 33 | 33 |
end |
| 34 | 34 |
end |