Adds a workflow overview screen.
Workflow setup moved to a dedicated controller. git-svn-id: http://redmine.rubyforge.org/svn/trunk@1914 e93f8b46-1217-0410-a6f0-8f06a7374b81
This commit is contained in:
parent
85711f1d54
commit
a37af7a226
|
@ -79,27 +79,6 @@ class RolesController < ApplicationController
|
||||||
redirect_to :action => 'list'
|
redirect_to :action => 'list'
|
||||||
end
|
end
|
||||||
|
|
||||||
def workflow
|
|
||||||
@role = Role.find_by_id(params[:role_id])
|
|
||||||
@tracker = Tracker.find_by_id(params[:tracker_id])
|
|
||||||
|
|
||||||
if request.post?
|
|
||||||
Workflow.destroy_all( ["role_id=? and tracker_id=?", @role.id, @tracker.id])
|
|
||||||
(params[:issue_status] || []).each { |old, news|
|
|
||||||
news.each { |new|
|
|
||||||
@role.workflows.build(:tracker_id => @tracker.id, :old_status_id => old, :new_status_id => new)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if @role.save
|
|
||||||
flash[:notice] = l(:notice_successful_update)
|
|
||||||
redirect_to :action => 'workflow', :role_id => @role, :tracker_id => @tracker
|
|
||||||
end
|
|
||||||
end
|
|
||||||
@roles = Role.find(:all, :order => 'builtin, position')
|
|
||||||
@trackers = Tracker.find(:all, :order => 'position')
|
|
||||||
@statuses = IssueStatus.find(:all, :order => 'position')
|
|
||||||
end
|
|
||||||
|
|
||||||
def report
|
def report
|
||||||
@roles = Role.find(:all, :order => 'builtin, position')
|
@roles = Role.find(:all, :order => 'builtin, position')
|
||||||
@permissions = Redmine::AccessControl.permissions.select { |p| !p.public? }
|
@permissions = Redmine::AccessControl.permissions.select { |p| !p.public? }
|
||||||
|
|
|
@ -0,0 +1,45 @@
|
||||||
|
# Redmine - project management software
|
||||||
|
# Copyright (C) 2006-2008 Jean-Philippe Lang
|
||||||
|
#
|
||||||
|
# This program is free software; you can redistribute it and/or
|
||||||
|
# modify it under the terms of the GNU General Public License
|
||||||
|
# as published by the Free Software Foundation; either version 2
|
||||||
|
# of the License, or (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program 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 General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU 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.
|
||||||
|
|
||||||
|
class WorkflowsController < ApplicationController
|
||||||
|
before_filter :require_admin
|
||||||
|
|
||||||
|
def index
|
||||||
|
@workflow_counts = Workflow.count_by_tracker_and_role
|
||||||
|
end
|
||||||
|
|
||||||
|
def edit
|
||||||
|
@role = Role.find_by_id(params[:role_id])
|
||||||
|
@tracker = Tracker.find_by_id(params[:tracker_id])
|
||||||
|
|
||||||
|
if request.post?
|
||||||
|
Workflow.destroy_all( ["role_id=? and tracker_id=?", @role.id, @tracker.id])
|
||||||
|
(params[:issue_status] || []).each { |old, news|
|
||||||
|
news.each { |new|
|
||||||
|
@role.workflows.build(:tracker_id => @tracker.id, :old_status_id => old, :new_status_id => new)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if @role.save
|
||||||
|
flash[:notice] = l(:notice_successful_update)
|
||||||
|
redirect_to :action => 'edit', :role_id => @role, :tracker_id => @tracker
|
||||||
|
end
|
||||||
|
end
|
||||||
|
@roles = Role.find(:all, :order => 'builtin, position')
|
||||||
|
@trackers = Tracker.find(:all, :order => 'position')
|
||||||
|
@statuses = IssueStatus.find(:all, :order => 'position')
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,19 @@
|
||||||
|
# Redmine - project management software
|
||||||
|
# Copyright (C) 2006-2008 Jean-Philippe Lang
|
||||||
|
#
|
||||||
|
# This program is free software; you can redistribute it and/or
|
||||||
|
# modify it under the terms of the GNU General Public License
|
||||||
|
# as published by the Free Software Foundation; either version 2
|
||||||
|
# of the License, or (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program 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 General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU 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 WorkflowsHelper
|
||||||
|
end
|
|
@ -21,4 +21,23 @@ class Workflow < ActiveRecord::Base
|
||||||
belongs_to :new_status, :class_name => 'IssueStatus', :foreign_key => 'new_status_id'
|
belongs_to :new_status, :class_name => 'IssueStatus', :foreign_key => 'new_status_id'
|
||||||
|
|
||||||
validates_presence_of :role, :old_status, :new_status
|
validates_presence_of :role, :old_status, :new_status
|
||||||
|
|
||||||
|
# Returns workflow transitions count by tracker and role
|
||||||
|
def self.count_by_tracker_and_role
|
||||||
|
counts = connection.select_all("SELECT role_id, tracker_id, count(id) AS c FROM #{Workflow.table_name} GROUP BY role_id, tracker_id")
|
||||||
|
roles = Role.find(:all, :order => 'builtin, position')
|
||||||
|
trackers = Tracker.find(:all, :order => 'position')
|
||||||
|
|
||||||
|
result = []
|
||||||
|
trackers.each do |tracker|
|
||||||
|
t = []
|
||||||
|
roles.each do |role|
|
||||||
|
row = counts.detect {|c| c['role_id'] == role.id.to_s && c['tracker_id'] = tracker.id.to_s}
|
||||||
|
t << [role, (row.nil? ? 0 : row['c'].to_i)]
|
||||||
|
end
|
||||||
|
result << [tracker, t]
|
||||||
|
end
|
||||||
|
|
||||||
|
result
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -19,7 +19,7 @@
|
||||||
<p class="icon22 icon22-tracker">
|
<p class="icon22 icon22-tracker">
|
||||||
<%= link_to l(:label_tracker_plural), :controller => 'trackers' %> |
|
<%= link_to l(:label_tracker_plural), :controller => 'trackers' %> |
|
||||||
<%= link_to l(:label_issue_status_plural), :controller => 'issue_statuses' %> |
|
<%= link_to l(:label_issue_status_plural), :controller => 'issue_statuses' %> |
|
||||||
<%= link_to l(:label_workflow), :controller => 'roles', :action => 'workflow' %>
|
<%= link_to l(:label_workflow), :controller => 'workflows', :action => 'edit' %>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<p class="icon22 icon22-workflow">
|
<p class="icon22 icon22-workflow">
|
||||||
|
|
|
@ -1,8 +1,12 @@
|
||||||
|
<div class="contextual">
|
||||||
|
<%= link_to l(:field_summary), :action => 'index' %>
|
||||||
|
</div>
|
||||||
|
|
||||||
<h2><%=l(:label_workflow)%></h2>
|
<h2><%=l(:label_workflow)%></h2>
|
||||||
|
|
||||||
<p><%=l(:text_workflow_edit)%>:</p>
|
<p><%=l(:text_workflow_edit)%>:</p>
|
||||||
|
|
||||||
<% form_tag({:action => 'workflow'}, :method => 'get') do %>
|
<% form_tag({}, :method => 'get') do %>
|
||||||
<p><label for="role_id"><%=l(:label_role)%>:</label>
|
<p><label for="role_id"><%=l(:label_role)%>:</label>
|
||||||
<select id="role_id" name="role_id">
|
<select id="role_id" name="role_id">
|
||||||
<%= options_from_collection_for_select @roles, "id", "name", (@role.id unless @role.nil?) %>
|
<%= options_from_collection_for_select @roles, "id", "name", (@role.id unless @role.nil?) %>
|
||||||
|
@ -12,14 +16,16 @@
|
||||||
<select id="tracker_id" name="tracker_id">
|
<select id="tracker_id" name="tracker_id">
|
||||||
<%= options_from_collection_for_select @trackers, "id", "name", (@tracker.id unless @tracker.nil?) %>
|
<%= options_from_collection_for_select @trackers, "id", "name", (@tracker.id unless @tracker.nil?) %>
|
||||||
</select>
|
</select>
|
||||||
<%= submit_tag l(:button_edit) %>
|
<%= submit_tag l(:button_edit), :name => nil %>
|
||||||
</p>
|
</p>
|
||||||
<% end %>
|
<% end %>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<% unless @tracker.nil? or @role.nil? %>
|
<% unless @tracker.nil? or @role.nil? %>
|
||||||
<% form_tag({:action => 'workflow', :role_id => @role, :tracker_id => @tracker }, :id => 'workflow_form' ) do %>
|
<% form_tag({}, :id => 'workflow_form' ) do %>
|
||||||
|
<%= hidden_field_tag 'tracker_id', @tracker.id %>
|
||||||
|
<%= hidden_field_tag 'role_id', @role.id %>
|
||||||
<div class="box">
|
<div class="box">
|
||||||
<table>
|
<table>
|
||||||
<tr>
|
<tr>
|
|
@ -0,0 +1,31 @@
|
||||||
|
<h2><%=l(:label_workflow)%></h2>
|
||||||
|
|
||||||
|
<% if @workflow_counts.empty? %>
|
||||||
|
<p class="nodata"><%= l(:label_no_data) %></p>
|
||||||
|
<% else %>
|
||||||
|
<table class="list">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th></th>
|
||||||
|
<% @workflow_counts.first.last.each do |role, count| %>
|
||||||
|
<th>
|
||||||
|
<%= content_tag(role.builtin? ? 'em' : 'span', h(role.name)) %>
|
||||||
|
</th>
|
||||||
|
|
||||||
|
<% end %>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<% @workflow_counts.each do |tracker, roles| -%>
|
||||||
|
<tr class="<%= cycle('odd', 'even') %>">
|
||||||
|
<td><%= h tracker %></td>
|
||||||
|
<% roles.each do |role, count| -%>
|
||||||
|
<td align="center">
|
||||||
|
<%= link_to((count > 1 ? count : image_tag('false.png')), {:action => 'edit', :role_id => role, :tracker_id => tracker}, :title => l(:button_edit)) %>
|
||||||
|
</td>
|
||||||
|
<% end -%>
|
||||||
|
</tr>
|
||||||
|
<% end -%>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
<% end %>
|
|
@ -118,46 +118,6 @@ class RolesControllerTest < Test::Unit::TestCase
|
||||||
assert_not_nil Role.find_by_id(1)
|
assert_not_nil Role.find_by_id(1)
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_get_workflow
|
|
||||||
get :workflow
|
|
||||||
assert_response :success
|
|
||||||
assert_template 'workflow'
|
|
||||||
assert_not_nil assigns(:roles)
|
|
||||||
assert_not_nil assigns(:trackers)
|
|
||||||
end
|
|
||||||
|
|
||||||
def test_get_workflow_with_role_and_tracker
|
|
||||||
get :workflow, :role_id => 2, :tracker_id => 1
|
|
||||||
assert_response :success
|
|
||||||
assert_template 'workflow'
|
|
||||||
# allowed transitions
|
|
||||||
assert_tag :tag => 'input', :attributes => { :type => 'checkbox',
|
|
||||||
:name => 'issue_status[2][]',
|
|
||||||
:value => '1',
|
|
||||||
:checked => 'checked' }
|
|
||||||
# not allowed
|
|
||||||
assert_tag :tag => 'input', :attributes => { :type => 'checkbox',
|
|
||||||
:name => 'issue_status[2][]',
|
|
||||||
:value => '3',
|
|
||||||
:checked => nil }
|
|
||||||
end
|
|
||||||
|
|
||||||
def test_post_workflow
|
|
||||||
post :workflow, :role_id => 2, :tracker_id => 1, :issue_status => {'4' => ['5'], '3' => ['1', '2']}
|
|
||||||
assert_redirected_to 'roles/workflow'
|
|
||||||
|
|
||||||
assert_equal 3, Workflow.count(:conditions => {:tracker_id => 1, :role_id => 2})
|
|
||||||
assert_not_nil Workflow.find(:first, :conditions => {:role_id => 2, :tracker_id => 1, :old_status_id => 3, :new_status_id => 2})
|
|
||||||
assert_nil Workflow.find(:first, :conditions => {:role_id => 2, :tracker_id => 1, :old_status_id => 5, :new_status_id => 4})
|
|
||||||
end
|
|
||||||
|
|
||||||
def test_clear_workflow
|
|
||||||
assert Workflow.count(:conditions => {:tracker_id => 1, :role_id => 2}) > 0
|
|
||||||
|
|
||||||
post :workflow, :role_id => 2, :tracker_id => 1
|
|
||||||
assert_equal 0, Workflow.count(:conditions => {:tracker_id => 1, :role_id => 2})
|
|
||||||
end
|
|
||||||
|
|
||||||
def test_get_report
|
def test_get_report
|
||||||
get :report
|
get :report
|
||||||
assert_response :success
|
assert_response :success
|
||||||
|
|
|
@ -0,0 +1,84 @@
|
||||||
|
# Redmine - project management software
|
||||||
|
# Copyright (C) 2006-2008 Jean-Philippe Lang
|
||||||
|
#
|
||||||
|
# This program is free software; you can redistribute it and/or
|
||||||
|
# modify it under the terms of the GNU General Public License
|
||||||
|
# as published by the Free Software Foundation; either version 2
|
||||||
|
# of the License, or (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program 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 General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU 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 File.dirname(__FILE__) + '/../test_helper'
|
||||||
|
require 'workflows_controller'
|
||||||
|
|
||||||
|
# Re-raise errors caught by the controller.
|
||||||
|
class WorkflowsController; def rescue_action(e) raise e end; end
|
||||||
|
|
||||||
|
class WorkflowsControllerTest < Test::Unit::TestCase
|
||||||
|
fixtures :roles, :trackers, :workflows
|
||||||
|
|
||||||
|
def setup
|
||||||
|
@controller = WorkflowsController.new
|
||||||
|
@request = ActionController::TestRequest.new
|
||||||
|
@response = ActionController::TestResponse.new
|
||||||
|
User.current = nil
|
||||||
|
@request.session[:user_id] = 1 # admin
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_index
|
||||||
|
get :index
|
||||||
|
assert_response :success
|
||||||
|
assert_template 'index'
|
||||||
|
|
||||||
|
count = Workflow.count(:all, :conditions => 'role_id = 1 AND tracker_id = 2')
|
||||||
|
assert_tag :tag => 'a', :content => count.to_s,
|
||||||
|
:attributes => { :href => '/workflows/edit?role_id=1&tracker_id=2' }
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_get_edit
|
||||||
|
get :edit
|
||||||
|
assert_response :success
|
||||||
|
assert_template 'edit'
|
||||||
|
assert_not_nil assigns(:roles)
|
||||||
|
assert_not_nil assigns(:trackers)
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_get_edit_with_role_and_tracker
|
||||||
|
get :edit, :role_id => 2, :tracker_id => 1
|
||||||
|
assert_response :success
|
||||||
|
assert_template 'edit'
|
||||||
|
# allowed transitions
|
||||||
|
assert_tag :tag => 'input', :attributes => { :type => 'checkbox',
|
||||||
|
:name => 'issue_status[2][]',
|
||||||
|
:value => '1',
|
||||||
|
:checked => 'checked' }
|
||||||
|
# not allowed
|
||||||
|
assert_tag :tag => 'input', :attributes => { :type => 'checkbox',
|
||||||
|
:name => 'issue_status[2][]',
|
||||||
|
:value => '3',
|
||||||
|
:checked => nil }
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_post_edit
|
||||||
|
post :edit, :role_id => 2, :tracker_id => 1, :issue_status => {'4' => ['5'], '3' => ['1', '2']}
|
||||||
|
assert_redirected_to 'workflows/edit'
|
||||||
|
|
||||||
|
assert_equal 3, Workflow.count(:conditions => {:tracker_id => 1, :role_id => 2})
|
||||||
|
assert_not_nil Workflow.find(:first, :conditions => {:role_id => 2, :tracker_id => 1, :old_status_id => 3, :new_status_id => 2})
|
||||||
|
assert_nil Workflow.find(:first, :conditions => {:role_id => 2, :tracker_id => 1, :old_status_id => 5, :new_status_id => 4})
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_clear_workflow
|
||||||
|
assert Workflow.count(:conditions => {:tracker_id => 1, :role_id => 2}) > 0
|
||||||
|
|
||||||
|
post :edit, :role_id => 2, :tracker_id => 1
|
||||||
|
assert_equal 0, Workflow.count(:conditions => {:tracker_id => 1, :role_id => 2})
|
||||||
|
end
|
||||||
|
end
|
Loading…
Reference in New Issue