petri_flow 0.1.8 → 0.2.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/app/assets/stylesheets/wf/static_assignments.css +4 -0
- data/app/controllers/wf/static_assignments_controller.rb +34 -0
- data/app/controllers/wf/transitions_controller.rb +8 -1
- data/app/controllers/wf/workitems_controller.rb +1 -5
- data/app/helpers/wf/static_assignments_helper.rb +6 -0
- data/app/models/wf/case_command/add_workitem_assignment.rb +18 -1
- data/app/models/wf/case_command/finish_workitem.rb +16 -2
- data/app/models/wf/case_command/start_workitem.rb +1 -0
- data/app/models/wf/field.rb +1 -1
- data/app/models/wf/guard.rb +2 -12
- data/app/models/wf/multiple_instances/all_finish.rb +11 -0
- data/app/models/wf/transition.rb +2 -1
- data/app/models/wf/transition_static_assignment.rb +6 -0
- data/app/models/wf/workflow.rb +6 -1
- data/app/models/wf/workitem.rb +64 -17
- data/app/views/wf/guards/_form.html.erb +1 -1
- data/app/views/wf/static_assignments/_form.html.erb +27 -0
- data/app/views/wf/static_assignments/new.html.erb +3 -0
- data/app/views/wf/transitions/_form.html.erb +90 -55
- data/app/views/wf/transitions/show.html.erb +83 -0
- data/config/routes.rb +4 -0
- data/db/migrate/20200222150432_add_multi_instance.rb +12 -0
- data/lib/wf/version.rb +1 -1
- data/lib/wf.rb +3 -0
- metadata +10 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8edfa5f265e495edad2726cb2d812e0dea76978623cc7f9e0c03d2aaa27c7e90
|
4
|
+
data.tar.gz: 8d4b8737d9fb6d4b36977d873a078d57cbba1bbffebe0d357a12e62904de4025
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 36a38a82bc4b3b45b0879c5019e52417589a5868192828854091b9ead9e8f34384c7063325e0d1405e6bcfe18c318f11451630226354e0f966a2277ed5ba4e2f
|
7
|
+
data.tar.gz: 8b7d014f64cfd03d7d794d87f2556c115a4b095e23dbdb4b5e67f73f7e62b4f44924769c73ad66dec1b9362264f64df7e09fe7f92df549a044f8e62c9aa91498
|
@@ -0,0 +1,34 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_dependency "wf/application_controller"
|
4
|
+
|
5
|
+
module Wf
|
6
|
+
class StaticAssignmentsController < ApplicationController
|
7
|
+
def new
|
8
|
+
@transition = Wf::Transition.find(params[:transition_id])
|
9
|
+
@static_assignment = @transition.transition_static_assignments.new
|
10
|
+
end
|
11
|
+
|
12
|
+
def create
|
13
|
+
@transition = Wf::Transition.find(params[:transition_id])
|
14
|
+
@party = Wf::Party.find(permit_params[:party_id])
|
15
|
+
@static_assignment = @transition.transition_static_assignments.new(party: @party)
|
16
|
+
if @static_assignment.save
|
17
|
+
redirect_to workflow_transition_path(@transition.workflow, @transition), notice: "static assignment was successfully created."
|
18
|
+
else
|
19
|
+
render :new
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def destroy
|
24
|
+
@transition = Wf::Transition.find(params[:transition_id])
|
25
|
+
@static_assignment = @transition.transition_static_assignments.find(params[:id])
|
26
|
+
@static_assignment.destroy
|
27
|
+
render js: "window.location.reload()"
|
28
|
+
end
|
29
|
+
|
30
|
+
def permit_params
|
31
|
+
params.fetch(:transition_static_assignment, {}).permit(:party_id)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -12,6 +12,11 @@ module Wf
|
|
12
12
|
breadcrumb @workflow.name, workflow_path(@workflow)
|
13
13
|
end
|
14
14
|
|
15
|
+
def show
|
16
|
+
@workflow = Wf::Workflow.find(params[:workflow_id])
|
17
|
+
@transition = @workflow.transitions.find(params[:id])
|
18
|
+
end
|
19
|
+
|
15
20
|
def create
|
16
21
|
@workflow = Wf::Workflow.find(params[:workflow_id])
|
17
22
|
tp = transition_params.merge(form: GlobalID::Locator.locate(transition_params[:form]))
|
@@ -65,7 +70,9 @@ module Wf
|
|
65
70
|
:unassignment_callback,
|
66
71
|
:notification_callback,
|
67
72
|
:deadline_callback,
|
68
|
-
:sub_workflow_id
|
73
|
+
:sub_workflow_id,
|
74
|
+
:multiple_instance,
|
75
|
+
:finish_condition
|
69
76
|
)
|
70
77
|
end
|
71
78
|
end
|
@@ -11,11 +11,7 @@ module Wf
|
|
11
11
|
breadcrumb "Workflows", :workflows_path
|
12
12
|
|
13
13
|
def index
|
14
|
-
|
15
|
-
wf_current_user,
|
16
|
-
Wf.org_classes.map { |org, _org_class| wf_current_user&.public_send(org) }
|
17
|
-
].flatten.map { |x| x&.party&.id }.compact
|
18
|
-
@workitems = Wf::Workitem.joins(:workitem_assignments).where(Wf::WorkitemAssignment.table_name => { party_id: current_party_ids })
|
14
|
+
@workitems = Wf::Workitem.todo(wf_current_user)
|
19
15
|
@workitems = @workitems.where(state: params[:state].intern) if params[:state]
|
20
16
|
@workitems = @workitems.where(state: params[:state].intern) if params[:state].present?
|
21
17
|
@workitems = @workitems.distinct.order("id desc").page(params[:page])
|
@@ -26,8 +26,25 @@ module Wf::CaseCommand
|
|
26
26
|
workitem.workitem_assignments.create!(party: party)
|
27
27
|
new_users = party.partable.users.to_a
|
28
28
|
to_notify = new_users - notified_users
|
29
|
+
transition = workitem.transition
|
29
30
|
to_notify.each do |user|
|
30
|
-
|
31
|
+
# TODO: multiple instance + sub workflow
|
32
|
+
if transition.multiple_instance? && !workitem.forked?
|
33
|
+
next if workitem.children.where(holding_user: user).exists?
|
34
|
+
|
35
|
+
child = workitem.children.create!(
|
36
|
+
workflow_id: workitem.workflow_id,
|
37
|
+
transition_id: workitem.transition_id,
|
38
|
+
state: :enabled,
|
39
|
+
trigger_time: workitem.trigger_time,
|
40
|
+
forked: true,
|
41
|
+
holding_user: user,
|
42
|
+
case_id: workitem.case_id
|
43
|
+
)
|
44
|
+
workitem.transition.notification_callback.constantize.new(child, user.id).perform_now
|
45
|
+
else
|
46
|
+
workitem.transition.notification_callback.constantize.new(workitem, user.id).perform_now
|
47
|
+
end
|
31
48
|
end
|
32
49
|
end
|
33
50
|
end
|
@@ -10,8 +10,22 @@ module Wf::CaseCommand
|
|
10
10
|
|
11
11
|
def call
|
12
12
|
Wf::ApplicationRecord.transaction do
|
13
|
-
|
14
|
-
|
13
|
+
if workitem.forked?
|
14
|
+
workitem.update!(finished_at: Time.zone.now, state: :finished)
|
15
|
+
Wf::Workitem.increment_counter(:children_finished_count, workitem.parent_id)
|
16
|
+
if parent = workitem.parent
|
17
|
+
if (parent.children_finished_count >= parent.children_count) || workitem.transition.finish_condition.constantize.new.perform(workitem)
|
18
|
+
parent.children.where(state: %i[started enabled]).find_each do |wi|
|
19
|
+
wi.update!(overridden_at: Time.zone.now, state: :overridden)
|
20
|
+
end
|
21
|
+
FireTransitionInternal.call(parent)
|
22
|
+
SweepAutomaticTransitions.call(parent.case)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
else
|
26
|
+
FireTransitionInternal.call(workitem)
|
27
|
+
SweepAutomaticTransitions.call(workitem.case)
|
28
|
+
end
|
15
29
|
end
|
16
30
|
end
|
17
31
|
end
|
data/app/models/wf/field.rb
CHANGED
data/app/models/wf/guard.rb
CHANGED
@@ -50,21 +50,11 @@ module Wf
|
|
50
50
|
end
|
51
51
|
end
|
52
52
|
|
53
|
-
def check_exp(
|
54
|
-
form_hash = if entry
|
55
|
-
entry.for_mini_racer
|
56
|
-
else
|
57
|
-
{}
|
58
|
-
end
|
59
|
-
|
60
|
-
target_hash = workitem&.case&.targetable&.attributes || {}
|
61
|
-
user_hash = workitem&.holding_user&.attributes || {}
|
62
|
-
|
53
|
+
def check_exp(_entry, workitem)
|
63
54
|
# 1000ms, 200mb
|
64
55
|
context = MiniRacer::Context.new(timeout: 1000, max_memory: 200_000_000)
|
65
|
-
context.eval("let form = #{form_hash.to_json};")
|
66
|
-
context.eval("let user = #{user_hash.to_json};")
|
67
56
|
context.eval("let target = #{target_hash.to_json};")
|
57
|
+
context.eval("let workitem = #{workitem.to_json};")
|
68
58
|
exp_value = context.eval(exp)
|
69
59
|
yes_or_no?(exp_value, value)
|
70
60
|
end
|
data/app/models/wf/transition.rb
CHANGED
@@ -1,5 +1,4 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
-
|
3
2
|
# == Schema Information
|
4
3
|
#
|
5
4
|
# Table name: wf_transitions
|
@@ -24,6 +23,8 @@
|
|
24
23
|
# unassignment_callback :string default("Wf::Callbacks::UnassignmentDefault")
|
25
24
|
# form_type :string default("Wf::Form")
|
26
25
|
# sub_workflow_id :integer
|
26
|
+
# multiple_instance :boolean default("false")
|
27
|
+
# finish_condition :string default("Wf::MultipleInstances::AllFinish")
|
27
28
|
#
|
28
29
|
|
29
30
|
module Wf
|
@@ -17,5 +17,11 @@ module Wf
|
|
17
17
|
belongs_to :workflow
|
18
18
|
belongs_to :transition
|
19
19
|
belongs_to :party
|
20
|
+
|
21
|
+
validates :party_id, uniqueness: { scope: %i[workflow_id transition_id] }
|
22
|
+
|
23
|
+
before_validation do
|
24
|
+
self.workflow_id = transition&.workflow_id
|
25
|
+
end
|
20
26
|
end
|
21
27
|
end
|
data/app/models/wf/workflow.rb
CHANGED
@@ -119,8 +119,13 @@ module Wf
|
|
119
119
|
|
120
120
|
tg_mapping = {}
|
121
121
|
transitions.each do |t|
|
122
|
+
peripheries = if t.multiple_instance?
|
123
|
+
3
|
124
|
+
else
|
125
|
+
1
|
126
|
+
end
|
122
127
|
tg = graph.add_nodes(t.graph_id, label: t.name, shape: :box, style: :filled, fillcolor: "#d6ddfa", color: "#d6ddfa",
|
123
|
-
fontcolor: "#2c50ed", fontname: fontfamily,
|
128
|
+
fontcolor: "#2c50ed", fontname: fontfamily, peripheries: peripheries,
|
124
129
|
href: Wf::Engine.routes.url_helpers.edit_workflow_transition_path(self, t))
|
125
130
|
tg_mapping[t] = tg
|
126
131
|
# NOTICE: if sub_workflow is transition's workflow, then graph will loop infinite, this is valid for workflow definition.
|
data/app/models/wf/workitem.rb
CHANGED
@@ -4,21 +4,25 @@
|
|
4
4
|
#
|
5
5
|
# Table name: wf_workitems
|
6
6
|
#
|
7
|
-
# id
|
8
|
-
# case_id
|
9
|
-
# workflow_id
|
10
|
-
# transition_id
|
11
|
-
# state
|
12
|
-
# enabled_at
|
13
|
-
# started_at
|
14
|
-
# canceled_at
|
15
|
-
# finished_at
|
16
|
-
# overridden_at
|
17
|
-
# deadline
|
18
|
-
# created_at
|
19
|
-
# updated_at
|
20
|
-
# trigger_time
|
21
|
-
# holding_user_id
|
7
|
+
# id :integer not null, primary key
|
8
|
+
# case_id :integer
|
9
|
+
# workflow_id :integer
|
10
|
+
# transition_id :integer
|
11
|
+
# state :integer default("0")
|
12
|
+
# enabled_at :datetime
|
13
|
+
# started_at :datetime
|
14
|
+
# canceled_at :datetime
|
15
|
+
# finished_at :datetime
|
16
|
+
# overridden_at :datetime
|
17
|
+
# deadline :datetime
|
18
|
+
# created_at :datetime not null
|
19
|
+
# updated_at :datetime not null
|
20
|
+
# trigger_time :datetime
|
21
|
+
# holding_user_id :string
|
22
|
+
# children_count :integer default("0")
|
23
|
+
# children_finished_count :integer default("0")
|
24
|
+
# forked :boolean default("false")
|
25
|
+
# parent_id :integer
|
22
26
|
#
|
23
27
|
|
24
28
|
module Wf
|
@@ -26,6 +30,7 @@ module Wf
|
|
26
30
|
belongs_to :workflow
|
27
31
|
belongs_to :transition
|
28
32
|
belongs_to :case
|
33
|
+
belongs_to :parent, class_name: "Wf::Workitem", optional: true, counter_cache: :children_count
|
29
34
|
belongs_to :holding_user, foreign_key: :holding_user_id, class_name: Wf.user_class.to_s, optional: true
|
30
35
|
has_many :workitem_assignments
|
31
36
|
has_many :parties, through: :workitem_assignments, source: "party"
|
@@ -33,6 +38,8 @@ module Wf
|
|
33
38
|
has_many :entries, class_name: Wf.entry_class.to_s
|
34
39
|
has_one :started_case, foreign_key: :started_by_workitem_id, class_name: "Wf::Case"
|
35
40
|
|
41
|
+
has_many :children, foreign_key: :parent_id, class_name: "Wf::Workitem"
|
42
|
+
|
36
43
|
enum state: {
|
37
44
|
enabled: 0,
|
38
45
|
started: 1,
|
@@ -41,6 +48,39 @@ module Wf
|
|
41
48
|
overridden: 4
|
42
49
|
}
|
43
50
|
|
51
|
+
def self.todo(wf_current_user)
|
52
|
+
current_party_ids = [
|
53
|
+
wf_current_user,
|
54
|
+
Wf.org_classes.map { |org, _org_class| wf_current_user&.public_send(org) }
|
55
|
+
].flatten.map { |x| x&.party&.id }.compact
|
56
|
+
Wf::Workitem.where(forked: false).joins(:workitem_assignments).where(Wf::WorkitemAssignment.table_name => { party_id: current_party_ids })
|
57
|
+
end
|
58
|
+
|
59
|
+
def self.doing(wf_current_user)
|
60
|
+
where(holding_user: wf_current_user).where(state: %i[started enabled])
|
61
|
+
end
|
62
|
+
|
63
|
+
def self.done(wf_current_user)
|
64
|
+
where(holding_user: wf_current_user).where(state: [:finished])
|
65
|
+
end
|
66
|
+
|
67
|
+
def for_mini_racer
|
68
|
+
attr = attributes
|
69
|
+
attr = attr.merge(holding_user: holding_user&.attributes || {})
|
70
|
+
attr = attr.merge(form: entries.to_a.first&.for_mini_racer || {})
|
71
|
+
children_attrs = if forked?
|
72
|
+
[]
|
73
|
+
else
|
74
|
+
children.includes(:holding_user, entries: :field_values).map(&:for_mini_racer)
|
75
|
+
end
|
76
|
+
attr = attr.merge(children: children_attrs)
|
77
|
+
attr
|
78
|
+
end
|
79
|
+
|
80
|
+
def parent?
|
81
|
+
!forked
|
82
|
+
end
|
83
|
+
|
44
84
|
def name
|
45
85
|
"Workitem -> #{id}"
|
46
86
|
end
|
@@ -54,12 +94,19 @@ module Wf
|
|
54
94
|
end
|
55
95
|
end
|
56
96
|
|
97
|
+
def real?
|
98
|
+
return false if transition.multiple_instance? && parent_id.nil?
|
99
|
+
return false if transition.sub_workflow_id.present?
|
100
|
+
|
101
|
+
true
|
102
|
+
end
|
103
|
+
|
57
104
|
def started_by?(user)
|
58
|
-
enabled? && owned_by?(user)
|
105
|
+
real? && enabled? && owned_by?(user)
|
59
106
|
end
|
60
107
|
|
61
108
|
def finished_by?(user)
|
62
|
-
started? && owned_by?(user) && holding_user == user
|
109
|
+
real? && started? && owned_by?(user) && holding_user == user
|
63
110
|
end
|
64
111
|
|
65
112
|
def owned_by?(user)
|
@@ -22,7 +22,7 @@
|
|
22
22
|
</div>
|
23
23
|
|
24
24
|
<div class="form-group">
|
25
|
-
<%= f.label :exp, class: "label" %> <small>JavaScript with build-in variable <span class="badge badge-danger">
|
25
|
+
<%= f.label :exp, class: "label" %> <small>JavaScript with build-in variable <span class="badge badge-danger">workitem</span>, <span class="badge badge-danger">target</span>.</small>
|
26
26
|
<%= f.text_area :exp, class: "form-control", placeholder: "Exp", rows: 8 %>
|
27
27
|
</div>
|
28
28
|
|
@@ -0,0 +1,27 @@
|
|
1
|
+
<%= form_with(model: static_assignment, url: transition_static_assignments_path(static_assignment.transition), local: true) do |f| %>
|
2
|
+
<% if static_assignment.errors.any? %>
|
3
|
+
<article class="message is-danger">
|
4
|
+
<div class="message-header">
|
5
|
+
<p>
|
6
|
+
<%= pluralize(static_assignment.errors.count, "error") %> prohibited this static_assignment from being saved:
|
7
|
+
</p>
|
8
|
+
</div>
|
9
|
+
<div class="message-body content">
|
10
|
+
<ul>
|
11
|
+
<% static_assignment.errors.full_messages.each do |message| %>
|
12
|
+
<li><%= message %></li>
|
13
|
+
<% end %>
|
14
|
+
</ul>
|
15
|
+
</div>
|
16
|
+
</article>
|
17
|
+
<% end %>
|
18
|
+
|
19
|
+
<div class="form-group">
|
20
|
+
<%= f.label :party, class: "label" %>
|
21
|
+
<%= f.select :party_id, Wf::Party.all.map{|x| [x.party_name, x.id]}, {}, class: "form-control custom-select", placeholder: "fieldable" %>
|
22
|
+
</div>
|
23
|
+
|
24
|
+
<div class="form-group">
|
25
|
+
<%= f.submit class: "btn btn-primary", value: 'Create Static Assignment', data: {disable_with: 'Waiting...'} %>
|
26
|
+
</div>
|
27
|
+
<% end %>
|
@@ -16,79 +16,114 @@
|
|
16
16
|
</article>
|
17
17
|
<% end %>
|
18
18
|
|
19
|
-
<div class="
|
20
|
-
|
21
|
-
|
22
|
-
|
19
|
+
<div class="card">
|
20
|
+
<h5 class="card-header">Basic Information</h5>
|
21
|
+
<div class="card-body">
|
22
|
+
<div class="form-group">
|
23
|
+
<%= f.label :name, class: "label" %>
|
24
|
+
<%= f.text_field :name, class: "form-control", placeholder: "Name" %>
|
25
|
+
</div>
|
23
26
|
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
27
|
+
<div class="form-group">
|
28
|
+
<%= f.label :description, class: "label" %>
|
29
|
+
<%= f.text_area :description, class: "form-control", placeholder: "Description" %>
|
30
|
+
</div>
|
28
31
|
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
32
|
+
<div class="form-group">
|
33
|
+
<%= f.label :trigger_limit, class: "label" %>
|
34
|
+
<%= f.text_field :trigger_limit, class: "form-control", placeholder: "Trigger Limit" %>
|
35
|
+
</div>
|
33
36
|
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
37
|
+
<div class="form-group">
|
38
|
+
<%= f.label :sort_order, class: "label" %>
|
39
|
+
<%= f.text_field :sort_order, class: "form-control", placeholder: "Sort Order" %>
|
40
|
+
</div>
|
38
41
|
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
+
<div class="form-group">
|
43
|
+
<%= f.label :trigger_type, class: "label" %>
|
44
|
+
<%= f.select :trigger_type, Wf::Transition.trigger_types.keys, {}, class: "form-control custom-select", placeholder: "Trigger Type" %>
|
45
|
+
</div>
|
46
|
+
</div>
|
42
47
|
</div>
|
43
48
|
|
44
|
-
<div class="form-group">
|
45
|
-
<%= f.label :sub_workflow, class: "label" %>
|
46
|
-
<%= f.select :sub_workflow_id, options_for_select(Wf::Workflow.valid.all.map{|x| [x.name, x.id]} || []), {include_blank: 'Start a sub workflow?'}, class: "form-control custom-select", placeholder: "Sub Workflow" %>
|
47
|
-
</div>
|
48
49
|
|
49
|
-
<div class="
|
50
|
-
|
51
|
-
|
50
|
+
<div class="card">
|
51
|
+
<h5 class="card-header">Sub Workflow</h5>
|
52
|
+
<div class="card-body">
|
53
|
+
<div class="form-group">
|
54
|
+
<%= f.label :sub_workflow, class: "label" %>
|
55
|
+
<%= f.select :sub_workflow_id, options_for_select(Wf::Workflow.valid.all.map{|x| [x.name, x.id]} || []), {include_blank: 'Start a sub workflow?'}, class: "form-control custom-select", placeholder: "Sub Workflow" %>
|
56
|
+
</div>
|
52
57
|
</div>
|
53
58
|
|
54
|
-
<div class="
|
55
|
-
|
56
|
-
|
59
|
+
<div class="card">
|
60
|
+
<h5 class="card-header">Dynimac Form</h5>
|
61
|
+
<div class="card-body">
|
62
|
+
<div class="form-group">
|
63
|
+
<%= f.label :form, class: "label" %>
|
64
|
+
<%= f.select :form, options_for_select(Wf.form_class.constantize.all.map{|x| [x.name, x.to_global_id]} || [], selected: f.object&.form&.to_global_id), {include_blank: 'user can input from custom form?'}, class: "form-control custom-select", placeholder: "Form" %>
|
65
|
+
</div>
|
66
|
+
</div>
|
57
67
|
</div>
|
58
68
|
|
59
|
-
<div class="
|
60
|
-
|
61
|
-
|
62
|
-
</div>
|
69
|
+
<div class="card">
|
70
|
+
<h5 class="card-header">Callbacks</h5>
|
71
|
+
<div class="card-body">
|
63
72
|
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
73
|
+
<div class="form-group">
|
74
|
+
<%= f.label :enable_callback, class: "label" %>
|
75
|
+
<%= f.select :enable_callback, Wf.enable_callbacks, {}, class: "form-control custom-select", placeholder: "Callback" %>
|
76
|
+
</div>
|
68
77
|
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
78
|
+
<div class="form-group">
|
79
|
+
<%= f.label :fire_callback, class: "label" %>
|
80
|
+
<%= f.select :fire_callback, Wf.fire_callbacks, {}, class: "form-control custom-select", placeholder: "Callback" %>
|
81
|
+
</div>
|
73
82
|
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
83
|
+
<div class="form-group">
|
84
|
+
<%= f.label :deadline_callback, class: "label" %>
|
85
|
+
<%= f.select :deadline_callback, Wf.deadline_callbacks, {}, class: "form-control custom-select", placeholder: "Callback" %>
|
86
|
+
</div>
|
78
87
|
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
88
|
+
<div class="form-group">
|
89
|
+
<%= f.label :time_callback, class: "label" %>
|
90
|
+
<%= f.select :time_callback, Wf.time_callbacks, {}, class: "form-control custom-select", placeholder: "Callback" %>
|
91
|
+
</div>
|
83
92
|
|
84
|
-
|
85
|
-
|
86
|
-
|
93
|
+
<div class="form-group">
|
94
|
+
<%= f.label :hold_timeout_callback, class: "label" %>
|
95
|
+
<%= f.select :hold_timeout_callback, Wf.hold_timeout_callbacks, {}, class: "form-control custom-select", placeholder: "Callback" %>
|
96
|
+
</div>
|
97
|
+
|
98
|
+
<div class="form-group">
|
99
|
+
<%= f.label :assignment_callback, class: "label" %>
|
100
|
+
<%= f.select :assignment_callback, Wf.assignment_callbacks, {}, class: "form-control custom-select", placeholder: "Callback" %>
|
101
|
+
</div>
|
102
|
+
|
103
|
+
<div class="form-group">
|
104
|
+
<%= f.label :unassignment_callback, class: "label" %>
|
105
|
+
<%= f.select :unassignment_callback, Wf.unassignment_callbacks, {}, class: "form-control custom-select", placeholder: "Callback" %>
|
106
|
+
</div>
|
107
|
+
|
108
|
+
<div class="form-group">
|
109
|
+
<%= f.label :notification_callback, class: "label" %>
|
110
|
+
<%= f.select :notification_callback, Wf.notification_callbacks, {}, class: "form-control custom-select", placeholder: "Callback" %>
|
111
|
+
</div>
|
112
|
+
</div>
|
87
113
|
</div>
|
88
114
|
|
89
|
-
<div class="
|
90
|
-
|
91
|
-
|
115
|
+
<div class="card">
|
116
|
+
<h5 class="card-header">Multiple Instances</h5>
|
117
|
+
<div class="card-body">
|
118
|
+
<div class="form-group">
|
119
|
+
<%= f.label :multiple_instance, class: "label" %>
|
120
|
+
<%= f.check_box :multiple_instance %>
|
121
|
+
</div>
|
122
|
+
<div class="form-group">
|
123
|
+
<%= f.label :finish_condition, class: "label" %>
|
124
|
+
<%= f.select :finish_condition, Wf.finish_conditions, {}, class: "form-control custom-select", placeholder: "Finish_condition" %>
|
125
|
+
</div>
|
126
|
+
</div>
|
92
127
|
</div>
|
93
128
|
|
94
129
|
<div class="form-group">
|
@@ -0,0 +1,83 @@
|
|
1
|
+
<div class="card card-body">
|
2
|
+
<div class="float-right">
|
3
|
+
<%= link_to 'Edit Transition', edit_workflow_transition_path(@workflow, @transition), class: 'btn btn-primary' %>
|
4
|
+
<%= link_to 'Create Static Assignments', new_transition_static_assignment_path(@transition), class: 'btn btn-primary' %>
|
5
|
+
</div>
|
6
|
+
<div>
|
7
|
+
<h2>Transition Detail</h2>
|
8
|
+
<table class="table table-view">
|
9
|
+
<tbody>
|
10
|
+
<tr>
|
11
|
+
<th scope="row">ID</th>
|
12
|
+
<td><%= @transition.id %></td>
|
13
|
+
</tr>
|
14
|
+
<tr>
|
15
|
+
<th scope="row">Name</th>
|
16
|
+
<td><%= @transition.name %></td>
|
17
|
+
</tr>
|
18
|
+
<tr>
|
19
|
+
<th scope="row">Trigger Limit</th>
|
20
|
+
<td><%= @transition.trigger_limit %></td>
|
21
|
+
</tr>
|
22
|
+
<tr>
|
23
|
+
<th scope="row">Trigger Type</th>
|
24
|
+
<td><%= @transition.trigger_type %></td>
|
25
|
+
</tr>
|
26
|
+
<tr>
|
27
|
+
<th>Form</th>
|
28
|
+
<td>
|
29
|
+
<% if @transition.form %>
|
30
|
+
<%= link_to @transition.form.name, form_path(@transition.form) %>
|
31
|
+
<% else %>
|
32
|
+
No Form
|
33
|
+
<% end %>
|
34
|
+
</td>
|
35
|
+
</tr>
|
36
|
+
|
37
|
+
<tr>
|
38
|
+
<th>Sub Workflow</th>
|
39
|
+
<td>
|
40
|
+
<% if @transition.sub_workflow %>
|
41
|
+
<%= link_to @transition.sub_workflow.name, workflow_path(@transition.sub_workflow_id) %>
|
42
|
+
<% else %>
|
43
|
+
No
|
44
|
+
<% end %>
|
45
|
+
</td>
|
46
|
+
</tr>
|
47
|
+
|
48
|
+
<tr>
|
49
|
+
<th scope="row">Multiple Instance?</th>
|
50
|
+
<td><%= @transition.multiple_instance %></td>
|
51
|
+
</tr>
|
52
|
+
<tr>
|
53
|
+
<th scope="row">Finish Condition</th>
|
54
|
+
<td><%= @transition.finish_condition %></td>
|
55
|
+
</tr>
|
56
|
+
</tbody>
|
57
|
+
</table>
|
58
|
+
</div>
|
59
|
+
|
60
|
+
<div>
|
61
|
+
<h2>Static Assignments</h2>
|
62
|
+
<table class="table table-view">
|
63
|
+
<thead>
|
64
|
+
<tr>
|
65
|
+
<th scope="col">ID</th>
|
66
|
+
<th scope="col">Party Name</th>
|
67
|
+
<th scope="col">Party Type</th>
|
68
|
+
<th scope="col">Actions</th>
|
69
|
+
</tr>
|
70
|
+
</thead>
|
71
|
+
<tbody>
|
72
|
+
<% @transition.transition_static_assignments.each do |assign| %>
|
73
|
+
<tr>
|
74
|
+
<td><%= assign.id %></td>
|
75
|
+
<td><%= assign.party.party_name %></td>
|
76
|
+
<td><%= assign.party.partable_type %></td>
|
77
|
+
<td><%= link_to 'Delete', transition_static_assignment_path(@transition, assign), remote: true, method: :delete, data: {confirm: 'confirm?'}, class: 'btn btn-sm btn-info' %></td>
|
78
|
+
</tr>
|
79
|
+
<% end %>
|
80
|
+
</tbody>
|
81
|
+
</table>
|
82
|
+
</div>
|
83
|
+
</div>
|
data/config/routes.rb
CHANGED
@@ -16,6 +16,10 @@ Wf::Engine.routes.draw do
|
|
16
16
|
resources :fields
|
17
17
|
end
|
18
18
|
|
19
|
+
resources :transitions do
|
20
|
+
resources :static_assignments
|
21
|
+
end
|
22
|
+
|
19
23
|
resources :workitems do
|
20
24
|
resources :workitem_assignments, only: %i[new create destroy]
|
21
25
|
resources :comments, only: %i[new create destroy]
|
@@ -0,0 +1,12 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class AddMultiInstance < ActiveRecord::Migration[6.0]
|
4
|
+
def change
|
5
|
+
add_column :wf_transitions, :multiple_instance, :boolean, default: false, comment: "multiple instance mode or not"
|
6
|
+
add_column :wf_transitions, :finish_condition, :string, comment: "set finish condition for parent workitem.", default: "Wf::MultipleInstances::AllFinish"
|
7
|
+
add_column :wf_workitems, :children_count, :integer, default: 0
|
8
|
+
add_column :wf_workitems, :children_finished_count, :integer, default: 0
|
9
|
+
add_column :wf_workitems, :forked, :boolean, default: false
|
10
|
+
add_column :wf_workitems, :parent_id, :bigint, comment: "parent workitem id"
|
11
|
+
end
|
12
|
+
end
|
data/lib/wf/version.rb
CHANGED
data/lib/wf.rb
CHANGED
@@ -19,6 +19,8 @@ module Wf
|
|
19
19
|
|
20
20
|
attr_accessor :user_class
|
21
21
|
attr_accessor :org_classes
|
22
|
+
|
23
|
+
attr_accessor :finish_conditions
|
22
24
|
end
|
23
25
|
|
24
26
|
self.enable_callbacks = ["Wf::Callbacks::EnableDefault"]
|
@@ -34,4 +36,5 @@ module Wf
|
|
34
36
|
self.field_class = "::Wf::Field"
|
35
37
|
self.user_class = "::Wf::User"
|
36
38
|
self.org_classes = { group: "::Wf::Group" }
|
39
|
+
self.finish_conditions = ["Wf::MultipleInstances::AllFinish"]
|
37
40
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: petri_flow
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1
|
4
|
+
version: 0.2.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Hooopo Wang
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-02-
|
11
|
+
date: 2020-02-26 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bootstrap
|
@@ -204,6 +204,7 @@ files:
|
|
204
204
|
- app/assets/stylesheets/wf/forms.css
|
205
205
|
- app/assets/stylesheets/wf/guards.css
|
206
206
|
- app/assets/stylesheets/wf/places.css
|
207
|
+
- app/assets/stylesheets/wf/static_assignments.css
|
207
208
|
- app/assets/stylesheets/wf/transitions.css
|
208
209
|
- app/assets/stylesheets/wf/uikit/_colors.scss
|
209
210
|
- app/assets/stylesheets/wf/uikit/_variables.scss
|
@@ -224,6 +225,7 @@ files:
|
|
224
225
|
- app/controllers/wf/forms_controller.rb
|
225
226
|
- app/controllers/wf/guards_controller.rb
|
226
227
|
- app/controllers/wf/places_controller.rb
|
228
|
+
- app/controllers/wf/static_assignments_controller.rb
|
227
229
|
- app/controllers/wf/transitions_controller.rb
|
228
230
|
- app/controllers/wf/workflows_controller.rb
|
229
231
|
- app/controllers/wf/workitem_assignments_controller.rb
|
@@ -236,6 +238,7 @@ files:
|
|
236
238
|
- app/helpers/wf/forms_helper.rb
|
237
239
|
- app/helpers/wf/guards_helper.rb
|
238
240
|
- app/helpers/wf/places_helper.rb
|
241
|
+
- app/helpers/wf/static_assignments_helper.rb
|
239
242
|
- app/helpers/wf/transitions_helper.rb
|
240
243
|
- app/helpers/wf/workflows_helper.rb
|
241
244
|
- app/helpers/wf/workitem_assignments_helper.rb
|
@@ -293,6 +296,7 @@ files:
|
|
293
296
|
- app/models/wf/form.rb
|
294
297
|
- app/models/wf/group.rb
|
295
298
|
- app/models/wf/guard.rb
|
299
|
+
- app/models/wf/multiple_instances/all_finish.rb
|
296
300
|
- app/models/wf/party.rb
|
297
301
|
- app/models/wf/place.rb
|
298
302
|
- app/models/wf/token.rb
|
@@ -330,9 +334,12 @@ files:
|
|
330
334
|
- app/views/wf/places/_form.html.erb
|
331
335
|
- app/views/wf/places/edit.html.erb
|
332
336
|
- app/views/wf/places/new.html.erb
|
337
|
+
- app/views/wf/static_assignments/_form.html.erb
|
338
|
+
- app/views/wf/static_assignments/new.html.erb
|
333
339
|
- app/views/wf/transitions/_form.html.erb
|
334
340
|
- app/views/wf/transitions/edit.html.erb
|
335
341
|
- app/views/wf/transitions/new.html.erb
|
342
|
+
- app/views/wf/transitions/show.html.erb
|
336
343
|
- app/views/wf/workflows/_form.html.erb
|
337
344
|
- app/views/wf/workflows/edit.html.erb
|
338
345
|
- app/views/wf/workflows/index.html.erb
|
@@ -353,6 +360,7 @@ files:
|
|
353
360
|
- db/migrate/20200213130900_remove_workflow_id_from_form_related.rb
|
354
361
|
- db/migrate/20200220070839_remove_unused_column.rb
|
355
362
|
- db/migrate/20200220072512_add_sub_workflow.rb
|
363
|
+
- db/migrate/20200222150432_add_multi_instance.rb
|
356
364
|
- lib/tasks/wf_tasks.rake
|
357
365
|
- lib/wf.rb
|
358
366
|
- lib/wf/engine.rb
|