Approval workflow log view tuned

This commit is contained in:
Karel Picman 2013-06-20 09:50:47 +02:00
parent 1f3d04cf9f
commit 1cc5b507ba
15 changed files with 143 additions and 71 deletions

View File

@ -167,12 +167,12 @@ class DmsfFileRevision < ActiveRecord::Base
str + l(:title_waiting_for_approval)
when DmsfWorkflow::STATE_APPROVED
str + l(:title_approved)
when DmsfWorkflow::STATE_DRAFT
str + l(:title_draft)
when DmsfWorkflow::STATE_ASSIGNED
str + l(:title_assigned)
when DmsfWorkflow::STATE_REJECTED
str + l(:title_rejected)
else
str
str + l(:title_none)
end
end
@ -183,7 +183,7 @@ class DmsfFileRevision < ActiveRecord::Base
self.dmsf_workflow_started_by = User.current.id if User.current
self.dmsf_workflow_started_at = DateTime.now
else
self.workflow = DmsfWorkflow::STATE_DRAFT
self.workflow = DmsfWorkflow::STATE_ASSIGNED
self.dmsf_workflow_assigned_by = User.current.id if User.current
self.dmsf_workflow_assigned_at = DateTime.now
end

View File

@ -24,7 +24,7 @@ class DmsfWorkflow < ActiveRecord::Base
validates_length_of :name, :maximum => 255
STATE_NONE = nil
STATE_DRAFT = 3
STATE_ASSIGNED = 3
STATE_WAITING_FOR_APPROVAL = 1
STATE_APPROVED = 2
STATE_REJECTED = 4

View File

@ -24,6 +24,7 @@ class DmsfWorkflowStepAction < ActiveRecord::Base
validates :action, :presence => true
validates :note, :presence => true, :unless => lambda { self.action == DmsfWorkflowStepAction::ACTION_APPROVE }
validates :author_id, :presence => true
validates_uniqueness_of :dmsf_workflow_step_assignment_id, :scope => [:action], :unless => lambda {self.action == DmsfWorkflowStepAction::ACTION_DELEGATE}
ACTION_APPROVE = 1
ACTION_REJECT = 2
@ -49,15 +50,30 @@ class DmsfWorkflowStepAction < ActiveRecord::Base
if action
case action.to_i
when ACTION_APPROVE
l(:title_approved)
l(:title_approval)
when ACTION_REJECT
l(:title_rejection)
when ACTION_DELEGATE
l(:title_delegation)
when ACTION_ASSIGN
l(:title_assignment)
when ACTION_START
l(:title_start)
end
end
end
def self.workflow_str(action)
if action
case action.to_i
when ACTION_REJECT
l(:title_rejected)
when ACTION_DELEGATE
l(:title_delegated)
when ACTION_ASSIGN
l(:title_assigned)
when ACTION_START
l(:title_started)
when ACTION_START, ACTION_DELEGATE, ACTION_APPROVE
l(:title_waiting_for_approval)
else
l(:title_none)
end
end
end

View File

@ -23,6 +23,7 @@ class DmsfWorkflowStepAssignment < ActiveRecord::Base
validates :dmsf_workflow_step_id, :presence => true
validates :dmsf_file_revision_id, :presence => true
validates_uniqueness_of :dmsf_workflow_step_id, :scope => [:dmsf_file_revision_id]
def step
DmsfWorkflowStep.find_by_id self.dmsf_workflow_step_id

View File

@ -185,6 +185,8 @@
:dmsf_file_revision_id => file.last_revision.id),
:title => DmsfWorkflow.assignments_to_users_str(wf.next_assignments(file.last_revision.id)),
:remote => true) %>
<% else %>
<%= file.last_revision.workflow_str(false) %>
<% end %>
</td>
<td class="author"><%= h(file.last_revision.user) %></td>
@ -221,15 +223,15 @@
<% end %>
<% when DmsfWorkflow::STATE_APPROVED %>
<%= image_tag('approved.png', :title => l(:title_approved), :plugin => :redmine_dmsf) %>
<% when DmsfWorkflow::STATE_DRAFT %>
<% when DmsfWorkflow::STATE_ASSIGNED %>
<% if User.current && (file.last_revision.dmsf_workflow_assigned_by == User.current.id) %>
<%= link_to_function(image_tag('draft.png', :plugin => :redmine_dmsf),
<%= link_to_function(image_tag('assigned.png', :plugin => :redmine_dmsf),
"manipulation_link('#{start_dmsf_workflow_path(
:id => file.last_revision.dmsf_workflow_id,
:dmsf_file_revision_id => file.last_revision.id)}')",
:title => l(:label_dmsf_wokflow_action_start)) %>
<% else %>
<%= image_tag('draft.png', :title => l(:label_dmsf_wokflow_action_start), :plugin => :redmine_dmsf) %>
<%= image_tag('assigned.png', :title => l(:label_dmsf_wokflow_action_start), :plugin => :redmine_dmsf) %>
<% end %>
<% when DmsfWorkflow::STATE_REJECTED %>
<%= image_tag('rejected.png', :title => l(:title_rejected), :plugin => :redmine_dmsf) %>
@ -325,15 +327,15 @@ sUrl = "jquery.dataTables/#{I18n.locale.to_s.downcase}.json" if I18n.locale && !
"oLanguage": {
'sUrl': '<%= plugin_asset_path(:redmine_dmsf, 'javascripts', sUrl) %>'
},
"bAutoWidth": false,
"bPaginate": false,
"aaSorting": [[1,'asc']],
"aaSortingFixed": [[7,'asc']],
"aoColumnDefs": [
{ "bSearchable": false, "aTargets": [0, 7, 8, 9] },
{ "bSortable": false, "aTargets": [0, 7, 8] },
{ "iDataSort": 9, "aTargets": [ 2 ] }
],
"bAutoWidth": false,
"bPaginate": false,
"aaSorting": [[1,'asc']],
"aaSortingFixed": [[8,'asc']],
"aoColumnDefs": [
{ "bSearchable": false, "aTargets": [0, 7, 8, 9] },
{ "bSortable": false, "aTargets": [0, 7, 8] },
{ "iDataSort": 9, "aTargets": [ 2 ] }
],
"fnInitComplete": function() {
jQuery("div.controls").prependTo(jQuery("#browser_wrapper div.fg-toolbar")[0]);
},

View File

@ -5,7 +5,7 @@
<% if revision %>
<div class="log_header_box">
<div class="log_header_left">
<%= label_tag 'workflow_name', "#{l(:field_name)}: " %>
<%= label_tag 'workflow_name', "#{l(:link_workflow)} #{l(:field_name).downcase}: " %>
<%= link_to @workflow.name, edit_dmsf_workflow_path(@workflow) %>
</div>
<div>
@ -19,35 +19,55 @@
<th><%= l(:label_dmsf_workflow_step) %></th>
<th><%= l(:label_user) %> </th>
<th><%= l(:label_action) %></th>
<th><%= l(:label_workflow) %></th>
<th><%= l(:label_note) %></th>
<th><%=l(:label_date)%></th>
<th><%= l(:label_date)%></th>
</tr></thead>
<tbody>
<tr id="step-0" class="odd">
<td class="step"></td>
<td class="user"><%= link_to_user User.find_by_id(revision.dmsf_workflow_assigned_by) if revision.dmsf_workflow_assigned_by %></td>
<td class="action"><%= DmsfWorkflowStepAction.action_str(DmsfWorkflowStepAction::ACTION_ASSIGN) %></td>
<tr id="step-0" class="even">
<td class="step"/>
<td/>
<td/>
<td><%= DmsfWorkflowStepAction.workflow_str(0) %></td>
<td class="note"></td>
<td class="date" align="center"><%= format_time(revision.dmsf_workflow_assigned_at) if revision.dmsf_workflow_assigned_at %></td>
<td/>
</tr>
<tr id="step-1" class="even">
<tr id="step-1" class="odd">
<td class="step"></td>
<td class="user"><%= link_to_user User.find_by_id(revision.dmsf_workflow_started_by) if revision.dmsf_workflow_started_by %></td>
<td class="action"><%= DmsfWorkflowStepAction.action_str(DmsfWorkflowStepAction::ACTION_START) %></td>
<td><%= link_to_user User.find_by_id(revision.dmsf_workflow_assigned_by) if revision.dmsf_workflow_assigned_by %></td>
<td><%= DmsfWorkflowStepAction.action_str(DmsfWorkflowStepAction::ACTION_ASSIGN) %></td>
<td><%= DmsfWorkflowStepAction.workflow_str(DmsfWorkflowStepAction::ACTION_ASSIGN) %></td>
<td class="note"></td>
<td class="date" align="center"><%= format_time(revision.dmsf_workflow_started_at) if revision.dmsf_workflow_started_at %></td>
<td><%= format_time(revision.dmsf_workflow_assigned_at) if revision.dmsf_workflow_assigned_at %></td>
</tr>
<% sql = "SELECT c.action, c.note, c.created_at, c.author_id, a.user_id, s.step FROM dmsf_workflow_step_actions c RIGHT JOIN dmsf_workflow_step_assignments a ON a.id = c.dmsf_workflow_step_assignment_id JOIN dmsf_workflow_steps s ON s.id = a.dmsf_workflow_step_id WHERE a.dmsf_file_revision_id = #{revision.id} ORDER BY s.step, c.created_at" %>
<tr id="step-2" class="even">
<td class="step"></td>
<td><%= link_to_user User.find_by_id(revision.dmsf_workflow_started_by) if revision.dmsf_workflow_started_by %></td>
<td><%= DmsfWorkflowStepAction.action_str(DmsfWorkflowStepAction::ACTION_START) %></td>
<td><%= DmsfWorkflowStepAction.workflow_str(DmsfWorkflowStepAction::ACTION_START) if revision.dmsf_workflow_started_by %></td>
<td class="note"></td>
<td><%= format_time(revision.dmsf_workflow_started_at) if revision.dmsf_workflow_started_at %></td>
</tr>
<% sql = "SELECT c.action, c.note, c.created_at, c.author_id, a.user_id, s.step FROM dmsf_workflow_step_actions c RIGHT JOIN dmsf_workflow_step_assignments a ON a.id = c.dmsf_workflow_step_assignment_id RIGHT JOIN dmsf_workflow_steps s ON s.id = a.dmsf_workflow_step_id WHERE a.dmsf_file_revision_id = #{revision.id} ORDER BY s.step, c.action DESC, c.created_at" %>
<% result = DmsfWorkflowStep.connection.execute sql %>
<% result.each_with_index do |row, i| %>
<tr id="step-<%= i + 2 %> " class="<%= cycle 'odd', 'even' %>">
<tr id="step-<%= i + 3 %> " class="<%= cycle 'odd', 'even' %>">
<td class="step"><%= row[5] %></td>
<td class="user"><%= link_to_user User.find_by_id(row[3].present? ? row[3] : row[4]) %></td>
<td class="action"><%= DmsfWorkflowStepAction.action_str(row[0]) %></td>
<td><%= link_to_user User.find_by_id(row[3].present? ? row[3] : row[4]) %></td>
<td><%= DmsfWorkflowStepAction.action_str(row[0]) %></td>
<td>
<% s = @workflow.dmsf_workflow_steps.last.step %>
<% s1 = row[5] %>
<% if((row[5].to_i == @workflow.dmsf_workflow_steps.last.step) && (revision.workflow == DmsfWorkflow::STATE_APPROVED)) %>
<%= l(:title_approved) %>
<% else %>
<%= DmsfWorkflowStepAction.workflow_str(row[0]) %>
<% end %>
</td>
<td class="note"><%= row[1] %></td>
<td class="date" align="center"><%= format_time(row[2]) if row[2].present? %></td>
<td><%= format_time(row[2]) if row[2].present? %></td>
</tr>
<% end; reset_cycle %>
<% end %>
</tbody>
</table>
</div>

View File

@ -1,3 +1,3 @@
$('#ajax-modal').html('<%= escape_javascript(render :partial => 'log', :locals => {:workflow => @workflow}) %>');
showModal('ajax-modal', '640px');
showModal('ajax-modal', '800px');
$('#ajax-modal').addClass('workflow-log');

View File

Before

Width:  |  Height:  |  Size: 459 B

After

Width:  |  Height:  |  Size: 459 B

View File

@ -256,12 +256,12 @@ div.revision_box .ui-widget-header {
font-weight: normal;
}
table.list td.note {
width: 30%;
table.list th {
text-align: left;
}
table.list td.date {
text-align: center;
table.list td.note {
width: 20%;
}
table.list td.reorder {

View File

@ -213,7 +213,7 @@ en:
error_cannot_start_workflow: "Workflow can't be started"
error_cannot_renumber_steps: "Steps can't be renumbered"
label_dmsf_workflow_new: 'New approval workflow'
label_dmsf_workflow: 'Approval workflow'
label_dmsf_workflow: 'Approval Workflow'
label_dmsf_workflow_plural: 'Approval workflows'
label_dmsf_workflow_step: Step
label_dmsf_workflow_step_plural: Steps
@ -227,12 +227,15 @@ en:
label_dmsf_wokflow_action_start: 'Start workflow'
label_action: Action
label_note: Note
title_draft: Draft
title_rejected: Rejected
title_delegated: Delegated
title_none: None
title_rejection: Rejection
title_delegation: Delegation
title_assignment: Assignment
title_start: Start
title_dmsf_workflow_log: 'Approval Workflow Log'
title_assigned: Assigned
title_started: Started
title_dmsf_workflow_log: 'Approval workflow log'
title_approval: Approval
title_rejected: Rejected
dmsf_and: AND
dmsf_or: OR
dmsf_new_step: New step

View File

@ -25,6 +25,11 @@ class CreateDmsfWorkflowSteps < ActiveRecord::Migration
t.integer :operator, :null => false
end
add_index :dmsf_workflow_steps, :dmsf_workflow_id
add_index :dmsf_workflow_steps,
[:user_id, :dmsf_workflow_id, :step],
# The default index name exceeds the index name limit
:name => 'index_dmsf_wrkfl_steps_on_usr_id_and_dmsf_wrkfl_id_and_step',
:unique => true
end
def self.down

View File

@ -26,7 +26,8 @@ class CreateDmsfWorkflowStepAssignments < ActiveRecord::Migration
add_index :dmsf_workflow_step_assignments,
[:dmsf_workflow_step_id, :dmsf_file_revision_id],
# The default index name exceeds the index name limit
{:name => 'index_dmsf_wrkfl_step_assigns_on_wrkfl_step_id_and_frev_id'}
:name => 'index_dmsf_wrkfl_step_assigns_on_wrkfl_step_id_and_frev_id',
:unique => true
end
def self.down

View File

@ -7,7 +7,7 @@ wfsa1:
wfsa2:
id: 2
dmsf_workflow_step_id: 1
dmsf_workflow_step_id: 4
user_id: 2
dmsf_file_revision_id: 2
@ -19,7 +19,7 @@ wfsa3:
wfsa4:
id: 4
dmsf_workflow_step_id: 2
dmsf_workflow_step_id: 3
user_id: 2
dmsf_file_revision_id: 2
@ -31,7 +31,7 @@ wfsa5:
wfsa6:
id: 6
dmsf_workflow_step_id: 1
dmsf_workflow_step_id: 4
user_id: 2
dmsf_file_revision_id: 1
@ -43,6 +43,6 @@ wfsa7:
wfsa8:
id: 8
dmsf_workflow_step_id: 2
dmsf_workflow_step_id: 3
user_id: 2
dmsf_file_revision_id: 1

View File

@ -21,8 +21,8 @@ class DmsfWorkflowStepActionTest < RedmineDmsf::Test::UnitTest
def test_create
wfsac = DmsfWorkflowStepAction.new(
:dmsf_workflow_step_assignment_id => 1,
:action => 1,
:note => 'Approvement')
:action => DmsfWorkflowStepAction::ACTION_DELEGATE,
:note => 'Approval')
assert wfsac.save
wfsac.reload
assert wfsac.created_at
@ -30,14 +30,14 @@ class DmsfWorkflowStepActionTest < RedmineDmsf::Test::UnitTest
def test_update
@wfsac1.dmsf_workflow_step_assignment_id = 2
@wfsac1.action = 2
@wfsac1.action = DmsfWorkflowStepAction::ACTION_REJECT
@wfsac1.note = 'Rejection'
assert @wfsac1.save
@wfsac1.reload
assert_equal 2, @wfsac1.dmsf_workflow_step_assignment_id
assert_equal 2, @wfsac1.action
assert_equal DmsfWorkflowStepAction::ACTION_REJECT, @wfsac1.action
assert_equal 'Rejection', @wfsac1.note
end
@ -77,6 +77,22 @@ class DmsfWorkflowStepActionTest < RedmineDmsf::Test::UnitTest
assert_equal 1, @wfsac1.errors.count
end
def test_validate_dmsf_workflow_step_assignment_id_uniqueness
@wfsac2.dmsf_workflow_step_assignment_id = @wfsac1.dmsf_workflow_step_assignment_id;
@wfsac2.action = @wfsac1.action;
assert !@wfsac2.save
assert_equal 1, @wfsac2.errors.count
@wfsac1.action = DmsfWorkflowStepAction::ACTION_REJECT
@wfsac2.action = @wfsac1.action;
assert @wfsac1.save
assert !@wfsac2.save
assert_equal 1, @wfsac2.errors.count
@wfsac1.action = DmsfWorkflowStepAction::ACTION_DELEGATE
assert @wfsac1.save
@wfsac2.action = @wfsac1.action;
assert @wfsac2.save
end
def test_destroy
@wfsac1.destroy
assert_nil DmsfWorkflowStepAction.find_by_id(1)
@ -92,10 +108,10 @@ class DmsfWorkflowStepActionTest < RedmineDmsf::Test::UnitTest
end
def test_action_str
assert_equal DmsfWorkflowStepAction.action_str(DmsfWorkflowStepAction::ACTION_APPROVE), l(:title_approved)
assert_equal DmsfWorkflowStepAction.action_str(DmsfWorkflowStepAction::ACTION_REJECT), l(:title_rejected)
assert_equal DmsfWorkflowStepAction.action_str(DmsfWorkflowStepAction::ACTION_DELEGATE), l(:title_delegated)
assert_equal DmsfWorkflowStepAction.action_str(DmsfWorkflowStepAction::ACTION_ASSIGN), l(:title_assigned)
assert_equal DmsfWorkflowStepAction.action_str(DmsfWorkflowStepAction::ACTION_START), l(:title_started)
assert_equal DmsfWorkflowStepAction.action_str(DmsfWorkflowStepAction::ACTION_APPROVE), l(:title_approval)
assert_equal DmsfWorkflowStepAction.action_str(DmsfWorkflowStepAction::ACTION_REJECT), l(:title_rejection)
assert_equal DmsfWorkflowStepAction.action_str(DmsfWorkflowStepAction::ACTION_DELEGATE), l(:title_delegation)
assert_equal DmsfWorkflowStepAction.action_str(DmsfWorkflowStepAction::ACTION_ASSIGN), l(:title_assignment)
assert_equal DmsfWorkflowStepAction.action_str(DmsfWorkflowStepAction::ACTION_START), l(:title_start)
end
end

View File

@ -6,6 +6,7 @@ class WorkflowStepAssignmentTest < RedmineDmsf::Test::UnitTest
def setup
@wfsa1 = DmsfWorkflowStepAssignment.find(1)
@wfsa2 = DmsfWorkflowStepAssignment.find(2)
end
def test_truth
@ -21,14 +22,14 @@ class WorkflowStepAssignmentTest < RedmineDmsf::Test::UnitTest
end
def test_update
@wfsa1.dmsf_workflow_step_id = 2
@wfsa1.dmsf_workflow_step_id = 5
@wfsa1.user_id = 2
@wfsa1.dmsf_file_revision_id = 2
assert @wfsa1.save
@wfsa1.reload
assert_equal 2, @wfsa1.dmsf_workflow_step_id
assert_equal 5, @wfsa1.dmsf_workflow_step_id
assert_equal 2, @wfsa1.user_id
assert_equal 2, @wfsa1.dmsf_file_revision_id
end
@ -45,6 +46,13 @@ class WorkflowStepAssignmentTest < RedmineDmsf::Test::UnitTest
assert_equal 1, @wfsa1.errors.count
end
def test_validate_dmsf_workflow_step_id_uniqueness
@wfsa1.dmsf_workflow_step_id = @wfsa2.dmsf_workflow_step_id
@wfsa1.dmsf_file_revision_id = @wfsa2.dmsf_file_revision_id
assert !@wfsa1.save
assert_equal 1, @wfsa1.errors.count
end
def test_destroy
@wfsa1.destroy
assert_nil DmsfWorkflowStepAssignment.find_by_id(1)