Approval workflow - log view

This commit is contained in:
Karel Picman 2013-06-03 07:10:32 +02:00
parent a2c0e1f471
commit b2106ad01b
13 changed files with 120 additions and 34 deletions

View File

@ -182,20 +182,22 @@ class DmsfFileRevision < ActiveRecord::Base
unless dmsf_workflow_id.blank?
self.dmsf_workflow_id = dmsf_workflow_id
if commit == 'start'
self.workflow = DmsfWorkflow::STATE_WAITING_FOR_APPROVAL # Waiting for approval
self.workflow = DmsfWorkflow::STATE_WAITING_FOR_APPROVAL
self.dmsf_workflow_started_by = User.current.id if User.current
self.dmsf_workflow_started_at = DateTime.now
else
self.workflow = DmsfWorkflow::STATE_DRAFT # Draft
self.workflow = DmsfWorkflow::STATE_DRAFT
self.dmsf_workflow_assigned_by = User.current.id if User.current
self.dmsf_workflow_assigned_at = DateTime.now
end
end
end
end
def assign_workflow(dmsf_workflow_id)
if User.current.allowed_to?(:file_approval, self.file.project)
#if self.workflow == DmsfWorkflow::STATE_DRAFT # Waiting for approval
wf = DmsfWorkflow.find_by_id(dmsf_workflow_id)
wf.assign(self.id) if wf && self.id
#end
if User.current.allowed_to?(:file_approval, self.file.project)
wf = DmsfWorkflow.find_by_id(dmsf_workflow_id)
wf.assign(self.id) if wf && self.id
end
end

View File

@ -17,17 +17,25 @@
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
class DmsfWorkflowStepAction < ActiveRecord::Base
belongs_to :dmsf_workflow_step_assignment
validates :dmsf_workflow_step_assignment_id, :presence => true
validates :action, :presence => true
validates :note, :presence => true, :unless => lambda { self.action == DmsfWorkflowStepAction::ACTION_APPROVE }
validates :author_id, :presence => true
ACTION_APPROVE = 1
ACTION_REJECT = 2
ACTION_DELEGATE = 3
ACTION_ASSIGN = 4
ACTION_START = 5
def initialize(*args)
super
self.author_id = User.current.id if User.current
end
def self.is_finished?(action)
action == DmsfWorkflowStepAction::ACTION_APPROVE ||
action == DmsfWorkflowStepAction::ACTION_REJECT
@ -36,5 +44,5 @@ class DmsfWorkflowStepAction < ActiveRecord::Base
def is_finished?
DmsfWorkflowStepAction.is_finished? self.action
end
end

View File

@ -65,8 +65,9 @@
<th><%= l(:link_title) %></th>
<th><%= l(:link_size) %></th>
<th><%= l(:link_modified) %></th>
<th><%= l(:link_ver) %></th>
<th><%= l(:link_author) %></th>
<th title="<%= l(:label_version) %>"><%= l(:link_ver) %></th>
<th><%= l(:link_workflow) %></th>
<th><%= l(:link_author) %></th>
<th></th>
<th class="hidden"></th>
<th class="hidden"></th>
@ -93,7 +94,8 @@
<%= image_tag("lockedbycurrent.png", :title => l(:title_locked_by_you), :plugin => :redmine_dmsf) %>
<% end %>
</td>
<td class="version"></td>
<td class="version"></td>
<td class="workflow"></td>
<td class="author"><%= h(subfolder.user) %></td>
<td class="actions">
<% if User.current.allowed_to?(:file_approval, @project) %>
@ -171,9 +173,21 @@
<%= image_tag("lockedbycurrent.png", :title => l(:title_locked_by_you), :plugin => :redmine_dmsf) %>
<% end %>
</td>
<td class="version">
<%= "#{file.last_revision.version} #{file.last_revision.workflow_str(false)}" %>
</td>
<td class="version"><%= file.last_revision.version %></td>
<td class="workflow">
<% wf = DmsfWorkflow.find_by_id(file.last_revision.dmsf_workflow_id) %>
<% if wf %>
<%= link_to(
file.last_revision.workflow_str(false),
log_dmsf_workflow_path(
:project_id => @project.id,
:id => wf.id,
#:dmsf_workflow_step_assignment_id => dmsf_workflow_step_assignment_id,
:dmsf_file_revision_id => file.last_revision.id),
#:title => l(:title_waiting_for_approval),
:remote => true) %>
<% end %>
</td>
<td class="author"><%= h(file.last_revision.user) %></td>
<td class="actions">
<% if User.current.allowed_to?(:file_approval, @project) %>
@ -314,9 +328,9 @@ sUrl = "jquery.dataTables/#{I18n.locale.to_s.downcase}.json" if I18n.locale && !
"aaSorting": [[1,'asc']],
"aaSortingFixed": [[7,'asc']],
"aoColumnDefs": [
{ "bSearchable": false, "aTargets": [0, 6, 7, 8] },
{ "bSortable": false, "aTargets": [0, 6, 7] },
{ "iDataSort": 8, "aTargets": [ 2 ] }
{ "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

@ -0,0 +1,49 @@
<h3 class="title"><%= l(:title_dmsf_workflow_log) %></h3>
<p>
<% if params[:dmsf_file_revision_id].present? %>
<% revision = DmsfFileRevision.find_by_id(params[:dmsf_file_revision_id]) %>
<% if revision %>
<%= link_to @workflow.name, edit_dmsf_workflow_path(@workflow) %><%= " - #{revision.workflow_str false}" %>
<div class="tab-content" id="tab-content-members">
<table class="steps">
<thead><tr>
<th><%= l(:label_dmsf_workflow_step) %></th>
<th><%= l(:label_user) %> </th>
<th><%= l(:label_action) %></th>
<th><%= l(:label_note) %></th>
<th><%=l(:label_date)%></th>
</tr></thead>
<tbody>
<tr id="step-0" class="<%= cycle 'odd', 'even' %> step">
<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">Assigned</td>
<td class="note"></td>
<td class="date" align="center"><%= format_time(revision.dmsf_workflow_assigned_at) if revision.dmsf_workflow_assigned_at %></td>
</tr>
<tr id="step-1" class="<%= cycle 'odd', 'even' %> step">
<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">Started</td>
<td class="note"></td>
<td class="date" align="center"><%= 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 JOIN dmsf_workflow_steps s ON s.id = a.dmsf_workflow_step_id WHERE a.dmsf_file_revision_id = #{revision.id} ORDER BY c.created_at" %>
<% result = DmsfWorkflowStep.connection.execute sql %>
<% result.each_with_index do |row, i| %>
<tr id="step-<%= i + 2 %> " class="<%= cycle 'odd', 'even' %> step">
<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"><%= revision.workflow_str false %></td>
<td class="note"><%= row[1] %></td>
<td class="date" align="center"><%= format_time(row[2]) if row[2].present? %></td>
</tr>
<% end; reset_cycle %>
</tbody>
</table>
</div>
<% end %>
<% end %>
</p>

View File

@ -1 +0,0 @@
<h2>WorkflowController#log</h2>

View File

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

View File

@ -1,2 +0,0 @@
$('#ajax-modal').modal('hide').empty();
window.location.reload();

View File

@ -14,8 +14,8 @@ table.entries {
}
table.entries td.modified {
min-width: 140px;
width: 140px;
min-width: 104px;
width: 104px;
}
table.entries td.actions {
@ -24,7 +24,7 @@ table.entries td.actions {
}
table.entries td.title {
width: 50%;
width: 40%;
}
table.entries th.check, table.entries td.check {
@ -136,6 +136,11 @@ td.version img {
vertical-align:text-top;
}
td.workflow {
font-size: 0.8em;
white-space: nowrap;
}
/* DMSF entries list icons */
div.right_icon_box {
@ -251,11 +256,6 @@ div.revision_box .ui-widget-header {
font-weight: normal;
}
td.workflow {
font-size: 0.8em;
white-space: nowrap;
table.steps td.note {
width: 30%;
}
td.workflow img {
vertical-align:text-top;
}

View File

@ -45,7 +45,7 @@ en:
:link_title: "Title"
:link_size: "Size"
:link_modified: "Modified"
:link_ver: "Version"
:link_ver: "Ver."
:link_author: "Author"
:title_check_for_zip_download_or_email: "Check for Zip download or email"
:title_delete: "Delete"
@ -230,4 +230,7 @@ en:
info_revision: "r%{rev}"
link_workflow: Workflow
button_assign: Assign
error_empty_note: "The note can't be empty"
error_empty_note: "The note can't be empty"
title_dmsf_workflow_log: 'Approval workflow log'
label_action: Action
label_note: Note

View File

@ -107,6 +107,7 @@ RedmineApp::Application.routes.draw do
get 'autocomplete_for_user'
get 'action'
get 'assign'
get 'log'
post 'new_action'
post 'start'
post 'assignment'

View File

@ -26,11 +26,19 @@ class CreateDmsfWorkflows < ActiveRecord::Migration
change_table :dmsf_file_revisions do |t|
t.references :dmsf_workflow
t.integer :dmsf_workflow_assigned_by
t.datetime :dmsf_workflow_assigned_at
t.integer :dmsf_workflow_started_by
t.datetime :dmsf_workflow_started_at
end
end
def self.down
remove_column :dmsf_file_revisions, :dmsf_workflow_id
remove_column :dmsf_file_revisions, :dmsf_workflow_assigned_by
remove_column :dmsf_file_revisions, :dmsf_workflow_assigned_at
remove_column :dmsf_file_revisions, :dmsf_workflow_started_by
remove_column :dmsf_file_revisions, :dmsf_workflow_started_at
drop_table :dmsf_workflows
end
end

View File

@ -23,6 +23,7 @@ class CreateDmsfWorkflowStepActions < ActiveRecord::Migration
t.integer :action, :null => false
t.text :note
t.timestamp :created_at
t.integer :author_id, :null => false
end
add_index :dmsf_workflow_step_actions,
:dmsf_workflow_step_assignment_id,

View File

@ -57,7 +57,7 @@ Redmine::Plugin.register :redmine_dmsf do
:dmsf_upload => [:upload_files, :upload_file, :commit_files]}
permission :file_approval, {:dmsf_files => [:delete_revision, :notify_activate, :notify_deactivate],
:dmsf => [:notify_activate, :notify_deactivate],
:dmsf_workflows => [:new, :create, :destroy, :edit, :add_step, :remove_step, :reorder_steps, :update, :start, :assign, :assignment, :action, :new_action]}
:dmsf_workflows => [:new, :create, :destroy, :edit, :add_step, :remove_step, :reorder_steps, :update, :start, :assign, :assignment, :action, :new_action, :log]}
permission :force_file_unlock, {}
end