petri_flow 0.1.3 → 0.1.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/app/assets/javascripts/wf/application.js +1 -0
- data/app/assets/stylesheets/wf/application.scss +5 -0
- data/app/controllers/wf/guards_controller.rb +1 -1
- data/app/controllers/wf/transitions_controller.rb +5 -3
- data/app/controllers/wf/workitems_controller.rb +13 -9
- data/app/models/wf/case_command/create_entry.rb +38 -0
- data/app/models/wf/entry.rb +2 -1
- data/app/models/wf/field.rb +29 -4
- data/app/models/wf/field_value.rb +30 -13
- data/app/models/wf/form.rb +1 -0
- data/app/models/wf/guard.rb +1 -1
- data/app/models/wf/transition.rb +2 -2
- data/app/models/wf/workflow.rb +67 -20
- data/app/models/wf/workitem.rb +1 -5
- data/app/views/wf/guards/_form.html.erb +1 -1
- data/app/views/wf/transitions/_form.html.erb +2 -2
- data/app/views/wf/workflows/index.html.erb +5 -1
- data/app/views/wf/workflows/show.html.erb +5 -1
- data/app/views/wf/workitems/pre_finish.html.erb +16 -2
- data/db/migrate/20200212120019_remove_targetable_from_workitem.rb +8 -0
- data/db/migrate/20200213085258_add_formable.rb +8 -0
- data/db/migrate/20200213125753_add_form_id_for_entry.rb +7 -0
- data/db/migrate/20200213130900_remove_workflow_id_from_form_related.rb +8 -0
- data/lib/wf/engine.rb +7 -0
- data/lib/wf/version.rb +1 -1
- metadata +49 -2
    
        checksums.yaml
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            ---
         | 
| 2 2 | 
             
            SHA256:
         | 
| 3 | 
            -
              metadata.gz:  | 
| 4 | 
            -
              data.tar.gz:  | 
| 3 | 
            +
              metadata.gz: 2b49ee6a8670d856f4c49892c235385b7d12a2918c7e909380c36cb45770bd8b
         | 
| 4 | 
            +
              data.tar.gz: d0479916f6a0b30c72f6e54e5de57efdf3e88fe4e0e9c36f5077ab223b1a6c5f
         | 
| 5 5 | 
             
            SHA512:
         | 
| 6 | 
            -
              metadata.gz:  | 
| 7 | 
            -
              data.tar.gz:  | 
| 6 | 
            +
              metadata.gz: bc7387ca697d2a67ee0686afa6191a5ade457322861ce5f014b9005fc44c9734c6612159dcab09c09e31b35a55353db3a833fa6c23023f09ca266ddc3d599e10
         | 
| 7 | 
            +
              data.tar.gz: a3a5398ae365be6bd2b49691d8ccba02c444172986f1a8808e7ba00d00b537f13e36361010aae162c48aa37ebef85ac298f4dae8a2e69e5aba4eba446588a04d
         | 
| @@ -14,7 +14,7 @@ module Wf | |
| 14 14 |  | 
| 15 15 | 
             
                def create
         | 
| 16 16 | 
             
                  @arc = Wf::Arc.find(params[:arc_id])
         | 
| 17 | 
            -
                  gp = guard_params.merge(fieldable: GlobalID::Locator.locate(guard_params[:fieldable])) | 
| 17 | 
            +
                  gp = guard_params.merge(fieldable: GlobalID::Locator.locate(guard_params[:fieldable]))
         | 
| 18 18 | 
             
                  @guard = @arc.guards.new(gp.merge(workflow: @arc.workflow))
         | 
| 19 19 | 
             
                  redirect_to workflow_arc_path(@arc.workflow, @arc), notice: "only out direction arc can set guard!" unless @arc.out?
         | 
| 20 20 | 
             
                  if @guard.save
         | 
| @@ -14,7 +14,8 @@ module Wf | |
| 14 14 |  | 
| 15 15 | 
             
                def create
         | 
| 16 16 | 
             
                  @workflow = Wf::Workflow.find(params[:workflow_id])
         | 
| 17 | 
            -
                   | 
| 17 | 
            +
                  tp = transition_params.merge(form: GlobalID::Locator.locate(transition_params[:form]))
         | 
| 18 | 
            +
                  @transition = @workflow.transitions.new(tp)
         | 
| 18 19 | 
             
                  if @transition.save
         | 
| 19 20 | 
             
                    redirect_to workflow_path(@workflow), notice: "transition was successfully created."
         | 
| 20 21 | 
             
                  else
         | 
| @@ -38,7 +39,8 @@ module Wf | |
| 38 39 | 
             
                def update
         | 
| 39 40 | 
             
                  @workflow = Wf::Workflow.find(params[:workflow_id])
         | 
| 40 41 | 
             
                  @transition = @workflow.transitions.find(params[:id])
         | 
| 41 | 
            -
                   | 
| 42 | 
            +
                  tp = transition_params.merge(form: GlobalID::Locator.locate(transition_params[:form]))
         | 
| 43 | 
            +
                  if @transition.update(tp)
         | 
| 42 44 | 
             
                    redirect_to workflow_path(@workflow), notice: "transition was successfully updated."
         | 
| 43 45 | 
             
                  else
         | 
| 44 46 | 
             
                    render :edit
         | 
| @@ -54,7 +56,7 @@ module Wf | |
| 54 56 | 
             
                      :trigger_limit,
         | 
| 55 57 | 
             
                      :trigger_type,
         | 
| 56 58 | 
             
                      :sort_order,
         | 
| 57 | 
            -
                      : | 
| 59 | 
            +
                      :form,
         | 
| 58 60 | 
             
                      :enable_callback,
         | 
| 59 61 | 
             
                      :fire_callback,
         | 
| 60 62 | 
             
                      :time_callback,
         | 
| @@ -42,17 +42,21 @@ module Wf | |
| 42 42 |  | 
| 43 43 | 
             
                def finish
         | 
| 44 44 | 
             
                  if @workitem.transition.form && params[:workitem][:entry]
         | 
| 45 | 
            -
                     | 
| 46 | 
            -
                    params[:workitem][:entry].permit | 
| 47 | 
            -
             | 
| 48 | 
            -
             | 
| 49 | 
            -
                       | 
| 50 | 
            -
             | 
| 51 | 
            -
                       | 
| 45 | 
            +
                    form = @workitem.transition.form
         | 
| 46 | 
            +
                    cmd = Wf::CaseCommand::CreateEntry.call(form, @workitem, wf_current_user, params[:workitem][:entry].permit!)
         | 
| 47 | 
            +
                    if cmd.success?
         | 
| 48 | 
            +
                      Wf::CaseCommand::FinishWorkitem.call(@workitem)
         | 
| 49 | 
            +
                      finish_and_redirect
         | 
| 50 | 
            +
                    else
         | 
| 51 | 
            +
                      redirect_to pre_finish_workitem_path(@workitem), notice: "Your input no OK."
         | 
| 52 52 | 
             
                    end
         | 
| 53 | 
            -
             | 
| 53 | 
            +
                  else
         | 
| 54 | 
            +
                    Wf::CaseCommand::FinishWorkitem.call(@workitem)
         | 
| 55 | 
            +
                    finish_and_redirect
         | 
| 54 56 | 
             
                  end
         | 
| 55 | 
            -
             | 
| 57 | 
            +
                end
         | 
| 58 | 
            +
             | 
| 59 | 
            +
                def finish_and_redirect
         | 
| 56 60 | 
             
                  if @workitem.case.finished?
         | 
| 57 61 | 
             
                    redirect_to workflow_case_path(@workitem.workflow, @workitem.case), notice: "workitem is done, and the case is finished."
         | 
| 58 62 | 
             
                  else
         | 
| @@ -0,0 +1,38 @@ | |
| 1 | 
            +
            # frozen_string_literal: true
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            module Wf::CaseCommand
         | 
| 4 | 
            +
              class CreateEntry
         | 
| 5 | 
            +
                prepend SimpleCommand
         | 
| 6 | 
            +
                attr_reader :form, :workitem, :user, :params
         | 
| 7 | 
            +
                def initialize(form, workitem, user, params)
         | 
| 8 | 
            +
                  @form       = form
         | 
| 9 | 
            +
                  @workitem   = workitem
         | 
| 10 | 
            +
                  @params     = params
         | 
| 11 | 
            +
                  @user       = user
         | 
| 12 | 
            +
                end
         | 
| 13 | 
            +
             | 
| 14 | 
            +
                def call
         | 
| 15 | 
            +
                  create_entry
         | 
| 16 | 
            +
                rescue StandardError
         | 
| 17 | 
            +
                  binding.pry
         | 
| 18 | 
            +
                  puts $ERROR_INFO
         | 
| 19 | 
            +
                  # TODO: more detail
         | 
| 20 | 
            +
                  errors.add(:base, :failure)
         | 
| 21 | 
            +
                end
         | 
| 22 | 
            +
             | 
| 23 | 
            +
                def create_entry
         | 
| 24 | 
            +
                  Wf::ApplicationRecord.transaction do
         | 
| 25 | 
            +
                    entry = form.entries.find_or_create_by!(user: user, workitem: workitem)
         | 
| 26 | 
            +
                    params.each do |field_id, field_value|
         | 
| 27 | 
            +
                      if field = entry.field_values.where(form: form, field_id: field_id).first
         | 
| 28 | 
            +
                        field.update!(value: field_value)
         | 
| 29 | 
            +
                      else
         | 
| 30 | 
            +
                        entry.field_values.create!(form: form, field_id: field_id, value: field_value)
         | 
| 31 | 
            +
                      end
         | 
| 32 | 
            +
                    end
         | 
| 33 | 
            +
                    entry.update_payload!
         | 
| 34 | 
            +
                    entry
         | 
| 35 | 
            +
                  end
         | 
| 36 | 
            +
                end
         | 
| 37 | 
            +
              end
         | 
| 38 | 
            +
            end
         | 
    
        data/app/models/wf/entry.rb
    CHANGED
    
    | @@ -1,5 +1,4 @@ | |
| 1 1 | 
             
            # frozen_string_literal: true
         | 
| 2 | 
            -
             | 
| 3 2 | 
             
            # == Schema Information
         | 
| 4 3 | 
             
            #
         | 
| 5 4 | 
             
            # Table name: wf_entries
         | 
| @@ -10,10 +9,12 @@ | |
| 10 9 | 
             
            #  payload     :json             default("{}")
         | 
| 11 10 | 
             
            #  created_at  :datetime         not null
         | 
| 12 11 | 
             
            #  updated_at  :datetime         not null
         | 
| 12 | 
            +
            #  form_id     :integer
         | 
| 13 13 | 
             
            #
         | 
| 14 14 |  | 
| 15 15 | 
             
            module Wf
         | 
| 16 16 | 
             
              class Entry < ApplicationRecord
         | 
| 17 | 
            +
                belongs_to :form
         | 
| 17 18 | 
             
                belongs_to :user, class_name: Wf::Workflow.user_class.to_s
         | 
| 18 19 | 
             
                belongs_to :workitem
         | 
| 19 20 | 
             
                has_many :field_values
         | 
    
        data/app/models/wf/field.rb
    CHANGED
    
    | @@ -40,14 +40,39 @@ module Wf | |
| 40 40 | 
             
                  "text[]": 28
         | 
| 41 41 | 
             
                }
         | 
| 42 42 |  | 
| 43 | 
            +
                # TODO: array type
         | 
| 44 | 
            +
                def field_type_for_view
         | 
| 45 | 
            +
                  case field_type
         | 
| 46 | 
            +
                  when "string"
         | 
| 47 | 
            +
                    "text_field"
         | 
| 48 | 
            +
                  when "integer"
         | 
| 49 | 
            +
                    "number_field"
         | 
| 50 | 
            +
                  when "date"
         | 
| 51 | 
            +
                    "date_field"
         | 
| 52 | 
            +
                  when "datetime"
         | 
| 53 | 
            +
                    "datetime_field"
         | 
| 54 | 
            +
                  when "boolean"
         | 
| 55 | 
            +
                    "radio_button"
         | 
| 56 | 
            +
                  when "text"
         | 
| 57 | 
            +
                    "text_area"
         | 
| 58 | 
            +
                  else
         | 
| 59 | 
            +
                    "text_field"
         | 
| 60 | 
            +
                  end
         | 
| 61 | 
            +
                end
         | 
| 62 | 
            +
             | 
| 63 | 
            +
                def array?
         | 
| 64 | 
            +
                  field_type.to_s.match(/^(\w+)(\[\])?$/)[2] == "[]"
         | 
| 65 | 
            +
                end
         | 
| 66 | 
            +
             | 
| 43 67 | 
             
                def type_for_cast
         | 
| 44 68 | 
             
                  type = field_type.to_s.match(/^(\w+)(\[\])?$/)[1]
         | 
| 45 | 
            -
                   | 
| 46 | 
            -
             | 
| 47 | 
            -
                    ActiveRecord::Type.lookup(type.to_sym, array: true)
         | 
| 69 | 
            +
                  if array?
         | 
| 70 | 
            +
                    ActiveRecord::Type.lookup(type.to_sym, adapter: :postgresql, array: true)
         | 
| 48 71 | 
             
                  else
         | 
| 49 | 
            -
                    ActiveRecord::Type.lookup(type.to_sym)
         | 
| 72 | 
            +
                    ActiveRecord::Type.lookup(type.to_sym, adapter: :postgresql)
         | 
| 50 73 | 
             
                  end
         | 
| 51 74 | 
             
                end
         | 
| 75 | 
            +
             | 
| 76 | 
            +
                delegate :cast, to: :type_for_cast
         | 
| 52 77 | 
             
              end
         | 
| 53 78 | 
             
            end
         | 
| @@ -1,30 +1,47 @@ | |
| 1 1 | 
             
            # frozen_string_literal: true
         | 
| 2 | 
            -
             | 
| 3 2 | 
             
            # == Schema Information
         | 
| 4 3 | 
             
            #
         | 
| 5 4 | 
             
            # Table name: wf_field_values
         | 
| 6 5 | 
             
            #
         | 
| 7 | 
            -
            #  id | 
| 8 | 
            -
            #   | 
| 9 | 
            -
            #   | 
| 10 | 
            -
            #   | 
| 11 | 
            -
            #   | 
| 12 | 
            -
            #   | 
| 13 | 
            -
            #   | 
| 14 | 
            -
            #  updated_at    :datetime         not null
         | 
| 15 | 
            -
            #  entry_id      :integer
         | 
| 6 | 
            +
            #  id         :integer          not null, primary key
         | 
| 7 | 
            +
            #  form_id    :integer
         | 
| 8 | 
            +
            #  field_id   :integer
         | 
| 9 | 
            +
            #  value      :text
         | 
| 10 | 
            +
            #  created_at :datetime         not null
         | 
| 11 | 
            +
            #  updated_at :datetime         not null
         | 
| 12 | 
            +
            #  entry_id   :integer
         | 
| 16 13 | 
             
            #
         | 
| 17 14 |  | 
| 18 15 | 
             
            module Wf
         | 
| 19 16 | 
             
              class FieldValue < ApplicationRecord
         | 
| 20 | 
            -
                belongs_to :workflow, optional: true
         | 
| 21 | 
            -
                belongs_to :transition, optional: true
         | 
| 22 17 | 
             
                belongs_to :form
         | 
| 23 18 | 
             
                belongs_to :field
         | 
| 24 19 | 
             
                belongs_to :entry
         | 
| 25 20 |  | 
| 26 21 | 
             
                def value_after_cast
         | 
| 27 | 
            -
                   | 
| 22 | 
            +
                  ov = self[:value]
         | 
| 23 | 
            +
                  if field.array? && !ov.is_a?(Array)
         | 
| 24 | 
            +
                    v = begin
         | 
| 25 | 
            +
                          JSON.parse(ov)
         | 
| 26 | 
            +
                        rescue StandardError
         | 
| 27 | 
            +
                          []
         | 
| 28 | 
            +
                        end
         | 
| 29 | 
            +
                    field.type_for_cast.cast(v)
         | 
| 30 | 
            +
                  else
         | 
| 31 | 
            +
                    field.type_for_cast.cast(ov)
         | 
| 32 | 
            +
                  end
         | 
| 33 | 
            +
                end
         | 
| 34 | 
            +
             | 
| 35 | 
            +
                def value=(v)
         | 
| 36 | 
            +
                  self[:value] = if field.array?
         | 
| 37 | 
            +
                    Array(v.as_json)
         | 
| 38 | 
            +
                  else
         | 
| 39 | 
            +
                    v
         | 
| 40 | 
            +
                  end
         | 
| 41 | 
            +
                end
         | 
| 42 | 
            +
             | 
| 43 | 
            +
                def value
         | 
| 44 | 
            +
                  value_after_cast
         | 
| 28 45 | 
             
                end
         | 
| 29 46 | 
             
              end
         | 
| 30 47 | 
             
            end
         | 
    
        data/app/models/wf/form.rb
    CHANGED
    
    
    
        data/app/models/wf/guard.rb
    CHANGED
    
    
    
        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
         | 
| @@ -22,6 +21,7 @@ | |
| 22 21 | 
             
            #  hold_timeout_callback :string           default("Wf::Callbacks::HoldTimeoutDefault")
         | 
| 23 22 | 
             
            #  assignment_callback   :string           default("Wf::Callbacks::AssignmentDefault")
         | 
| 24 23 | 
             
            #  unassignment_callback :string           default("Wf::Callbacks::UnassignmentDefault")
         | 
| 24 | 
            +
            #  form_type             :string           default("Wf::Form")
         | 
| 25 25 | 
             
            #
         | 
| 26 26 |  | 
| 27 27 | 
             
            module Wf
         | 
| @@ -31,7 +31,7 @@ module Wf | |
| 31 31 | 
             
                has_many :transition_static_assignments
         | 
| 32 32 | 
             
                has_many :static_parties, through: :transition_static_assignments, source: "party"
         | 
| 33 33 | 
             
                has_many :workitems
         | 
| 34 | 
            -
                belongs_to :form, optional: true
         | 
| 34 | 
            +
                belongs_to :form, optional: true, polymorphic: true
         | 
| 35 35 |  | 
| 36 36 | 
             
                enum trigger_type: {
         | 
| 37 37 | 
             
                  user: 0,
         | 
    
        data/app/models/wf/workflow.rb
    CHANGED
    
    | @@ -13,7 +13,6 @@ | |
| 13 13 | 
             
            #  created_at  :datetime         not null
         | 
| 14 14 | 
             
            #  updated_at  :datetime         not null
         | 
| 15 15 | 
             
            #
         | 
| 16 | 
            -
             | 
| 17 16 | 
             
            module Wf
         | 
| 18 17 | 
             
              class Workflow < ApplicationRecord
         | 
| 19 18 | 
             
                has_many :places, dependent: :destroy
         | 
| @@ -59,13 +58,25 @@ module Wf | |
| 59 58 | 
             
                  [Wf::Callbacks::HoldTimeoutDefault]
         | 
| 60 59 | 
             
                end
         | 
| 61 60 |  | 
| 61 | 
            +
                def self.form_class
         | 
| 62 | 
            +
                  "::Wf::Form"
         | 
| 63 | 
            +
                end
         | 
| 64 | 
            +
             | 
| 65 | 
            +
                def self.entry_class
         | 
| 66 | 
            +
                  "::Wf::Entry"
         | 
| 67 | 
            +
                end
         | 
| 68 | 
            +
             | 
| 69 | 
            +
                def self.field_class
         | 
| 70 | 
            +
                  "::Wf::Field"
         | 
| 71 | 
            +
                end
         | 
| 72 | 
            +
             | 
| 62 73 | 
             
                def self.user_class
         | 
| 63 | 
            -
                  ::Wf::User
         | 
| 74 | 
            +
                  "::Wf::User"
         | 
| 64 75 | 
             
                end
         | 
| 65 76 |  | 
| 66 77 | 
             
                def self.org_classes
         | 
| 67 78 | 
             
                  {
         | 
| 68 | 
            -
                    group: ::Wf::Group
         | 
| 79 | 
            +
                    group: "::Wf::Group"
         | 
| 69 80 | 
             
                  }
         | 
| 70 81 | 
             
                end
         | 
| 71 82 |  | 
| @@ -81,10 +92,26 @@ module Wf | |
| 81 92 | 
             
                # todo: remove color hex to const.
         | 
| 82 93 | 
             
                def do_validate!
         | 
| 83 94 | 
             
                  msgs = []
         | 
| 84 | 
            -
                   | 
| 95 | 
            +
                  start_place = places.start.first
         | 
| 96 | 
            +
                  end_place   = places.end.first
         | 
| 97 | 
            +
                  msgs << "must have start place" if start_place.blank?
         | 
| 85 98 | 
             
                  msgs << "must have only one start place" if places.start.count > 1
         | 
| 86 | 
            -
                  msgs << "must have end place" if  | 
| 99 | 
            +
                  msgs << "must have end place" if end_place.blank?
         | 
| 87 100 | 
             
                  msgs << "must have only one end place" if places.end.count > 1
         | 
| 101 | 
            +
                  msgs << "must not have discrete transition" if transitions.any? { |t| !t.arcs.in.exists? }
         | 
| 102 | 
            +
                  if start_place && end_place
         | 
| 103 | 
            +
                    rgl = to_rgl
         | 
| 104 | 
            +
                    places.each do |p|
         | 
| 105 | 
            +
                      msgs << "start place can not reach #{p.name}" unless rgl.path?(start_place.to_gid.to_s, p.to_gid.to_s)
         | 
| 106 | 
            +
                      msgs << "#{p.name} can not reach end_place" unless rgl.path?(p.to_gid.to_s, end_place.to_gid.to_s)
         | 
| 107 | 
            +
                    end
         | 
| 108 | 
            +
             | 
| 109 | 
            +
                    transitions.each do |t|
         | 
| 110 | 
            +
                      msgs << "start place can not reach #{t.name}" unless rgl.path?(start_place.to_gid.to_s, t.to_gid.to_s)
         | 
| 111 | 
            +
                      msgs << "#{t.name} can not reach end_place" unless rgl.path?(t.to_gid.to_s, end_place.to_gid.to_s)
         | 
| 112 | 
            +
                    end
         | 
| 113 | 
            +
                  end
         | 
| 114 | 
            +
             | 
| 88 115 | 
             
                  if msgs.present?
         | 
| 89 116 | 
             
                    update_columns(is_valid: false, error_msg: msgs.join("\n"))
         | 
| 90 117 | 
             
                  else
         | 
| @@ -93,8 +120,8 @@ module Wf | |
| 93 120 | 
             
                end
         | 
| 94 121 |  | 
| 95 122 | 
             
                def to_graph(wf_case = nil)
         | 
| 96 | 
            -
                  fontfamily =  | 
| 97 | 
            -
                  fontfamily_monospace =  | 
| 123 | 
            +
                  fontfamily = "system, -apple-system, BlinkMacSystemFont, Segoe UI, Helvetica, Arial, sans-serif, Apple Color Emoji, Segoe UI Emoji, Noto Color Emoji, Segoe UI Symbol"
         | 
| 124 | 
            +
                  fontfamily_monospace = "SFMono-Regular, Consolas, Liberation Mono, Menlo, Courier, monospace"
         | 
| 98 125 | 
             
                  graph = GraphViz.new(name, type: :digraph, rankdir: "LR", splines: true, ratio: :auto)
         | 
| 99 126 | 
             
                  free_token_places = if wf_case
         | 
| 100 127 | 
             
                    wf_case.tokens.free.map(&:place_id)
         | 
| @@ -104,16 +131,16 @@ module Wf | |
| 104 131 | 
             
                  pg_mapping = {}
         | 
| 105 132 | 
             
                  places.order("place_type ASC").each do |p|
         | 
| 106 133 | 
             
                    if p.start?
         | 
| 107 | 
            -
                      fillcolor =  | 
| 108 | 
            -
                      textcolor =  | 
| 134 | 
            +
                      fillcolor = "#ffe7ba"
         | 
| 135 | 
            +
                      textcolor = "#fa8c16"
         | 
| 109 136 | 
             
                      shape     = :doublecircle
         | 
| 110 137 | 
             
                    elsif p.end?
         | 
| 111 | 
            -
                      fillcolor =  | 
| 112 | 
            -
                      textcolor =  | 
| 138 | 
            +
                      fillcolor = "#dff2ef"
         | 
| 139 | 
            +
                      textcolor = "#29c0b1"
         | 
| 113 140 | 
             
                      shape     = :doublecircle
         | 
| 114 141 | 
             
                    else
         | 
| 115 | 
            -
                      fillcolor =  | 
| 116 | 
            -
                      textcolor =  | 
| 142 | 
            +
                      fillcolor = "#fbdbe1"
         | 
| 143 | 
            +
                      textcolor = "#ff3366"
         | 
| 117 144 | 
             
                      shape     = :circle
         | 
| 118 145 | 
             
                    end
         | 
| 119 146 |  | 
| @@ -144,9 +171,9 @@ module Wf | |
| 144 171 |  | 
| 145 172 | 
             
                  tg_mapping = {}
         | 
| 146 173 | 
             
                  transitions.each do |t|
         | 
| 147 | 
            -
                    tg = graph.add_nodes(t.name, label: t.name, shape: :box, style: :filled, fillcolor: "#d6ddfa", color:  | 
| 148 | 
            -
             | 
| 149 | 
            -
             | 
| 174 | 
            +
                    tg = graph.add_nodes(t.name, label: t.name, shape: :box, style: :filled, fillcolor: "#d6ddfa", color: "#d6ddfa",
         | 
| 175 | 
            +
                                                 fontcolor: "#2c50ed", fontname: fontfamily,
         | 
| 176 | 
            +
                                                 href: Wf::Engine.routes.url_helpers.edit_workflow_transition_path(self, t))
         | 
| 150 177 | 
             
                    tg_mapping[t] = tg
         | 
| 151 178 | 
             
                  end
         | 
| 152 179 |  | 
| @@ -166,8 +193,8 @@ module Wf | |
| 166 193 | 
             
                        labelfontcolor: :red,
         | 
| 167 194 | 
             
                        arrowhead: :vee,
         | 
| 168 195 | 
             
                        fontsize: 10,
         | 
| 169 | 
            -
                        color:  | 
| 170 | 
            -
                        fontcolor:  | 
| 196 | 
            +
                        color: "#53585c",
         | 
| 197 | 
            +
                        fontcolor: "#53585c",
         | 
| 171 198 | 
             
                        fontname: fontfamily_monospace,
         | 
| 172 199 | 
             
                        href: Wf::Engine.routes.url_helpers.edit_workflow_arc_path(self, arc)
         | 
| 173 200 | 
             
                      )
         | 
| @@ -181,8 +208,8 @@ module Wf | |
| 181 208 | 
             
                        labelfontcolor: :red,
         | 
| 182 209 | 
             
                        arrowhead: :vee,
         | 
| 183 210 | 
             
                        fontsize: 10,
         | 
| 184 | 
            -
                        color:  | 
| 185 | 
            -
                        fontcolor:  | 
| 211 | 
            +
                        color: "#53585c",
         | 
| 212 | 
            +
                        fontcolor: "#53585c",
         | 
| 186 213 | 
             
                        fontname: fontfamily_monospace,
         | 
| 187 214 | 
             
                        href: Wf::Engine.routes.url_helpers.edit_workflow_arc_path(self, arc)
         | 
| 188 215 | 
             
                      )
         | 
| @@ -197,5 +224,25 @@ module Wf | |
| 197 224 | 
             
                  graph.output(svg: path)
         | 
| 198 225 | 
             
                  File.read(path)
         | 
| 199 226 | 
             
                end
         | 
| 227 | 
            +
             | 
| 228 | 
            +
                def to_rgl
         | 
| 229 | 
            +
                  graph = RGL::DirectedAdjacencyGraph.new
         | 
| 230 | 
            +
                  places.order("place_type ASC").each do |p|
         | 
| 231 | 
            +
                    graph.add_vertex(p.to_gid.to_s)
         | 
| 232 | 
            +
                  end
         | 
| 233 | 
            +
             | 
| 234 | 
            +
                  transitions.each do |t|
         | 
| 235 | 
            +
                    graph.add_vertex(t.to_gid.to_s)
         | 
| 236 | 
            +
                  end
         | 
| 237 | 
            +
             | 
| 238 | 
            +
                  arcs.order("direction desc").each do |arc|
         | 
| 239 | 
            +
                    if arc.in?
         | 
| 240 | 
            +
                      graph.add_edge(arc.place.to_gid.to_s, arc.transition.to_gid.to_s)
         | 
| 241 | 
            +
                    else
         | 
| 242 | 
            +
                      graph.add_edge(arc.transition.to_gid.to_s, arc.place.to_gid.to_s)
         | 
| 243 | 
            +
                    end
         | 
| 244 | 
            +
                  end
         | 
| 245 | 
            +
                  graph
         | 
| 246 | 
            +
                end
         | 
| 200 247 | 
             
              end
         | 
| 201 248 | 
             
            end
         | 
    
        data/app/models/wf/workitem.rb
    CHANGED
    
    | @@ -1,5 +1,4 @@ | |
| 1 1 | 
             
            # frozen_string_literal: true
         | 
| 2 | 
            -
             | 
| 3 2 | 
             
            # == Schema Information
         | 
| 4 3 | 
             
            #
         | 
| 5 4 | 
             
            # Table name: wf_workitems
         | 
| @@ -8,8 +7,6 @@ | |
| 8 7 | 
             
            #  case_id         :integer
         | 
| 9 8 | 
             
            #  workflow_id     :integer
         | 
| 10 9 | 
             
            #  transition_id   :integer
         | 
| 11 | 
            -
            #  targetable_type :string
         | 
| 12 | 
            -
            #  targetable_id   :string
         | 
| 13 10 | 
             
            #  state           :integer          default("0")
         | 
| 14 11 | 
             
            #  enabled_at      :datetime
         | 
| 15 12 | 
             
            #  started_at      :datetime
         | 
| @@ -28,12 +25,11 @@ module Wf | |
| 28 25 | 
             
                belongs_to :workflow
         | 
| 29 26 | 
             
                belongs_to :transition
         | 
| 30 27 | 
             
                belongs_to :case
         | 
| 31 | 
            -
                belongs_to :targetable, optional: true
         | 
| 32 28 | 
             
                belongs_to :holding_user, foreign_key: :holding_user_id, class_name: Workflow.user_class.to_s, optional: true
         | 
| 33 29 | 
             
                has_many :workitem_assignments
         | 
| 34 30 | 
             
                has_many :parties, through: :workitem_assignments, source: "party"
         | 
| 35 31 | 
             
                has_many :comments
         | 
| 36 | 
            -
                has_many :entries
         | 
| 32 | 
            +
                has_many :entries, class_name: Wf::Workflow.entry_class.to_s
         | 
| 37 33 |  | 
| 38 34 | 
             
                enum state: {
         | 
| 39 35 | 
             
                  enabled: 0,
         | 
| @@ -18,7 +18,7 @@ | |
| 18 18 |  | 
| 19 19 | 
             
              <div class="form-group">
         | 
| 20 20 | 
             
                <%= f.label :fieldable, class: "label" %>
         | 
| 21 | 
            -
                <%= f.select :fieldable, options_for_select(@arc.transition.form&.fields&.map {|x| [x.name, x.to_global_id]} || []), {}, class: "form-control custom-select", placeholder: "fieldable" %>
         | 
| 21 | 
            +
                <%= f.select :fieldable, options_for_select(@arc.transition.form&.fields&.map {|x| [x.name, x.to_global_id]} || [], selected: f.object&.fieldable&.to_global_id), {}, class: "form-control custom-select", placeholder: "fieldable" %>
         | 
| 22 22 | 
             
              </div>
         | 
| 23 23 |  | 
| 24 24 | 
             
              <div class="form-group">
         | 
| @@ -42,8 +42,8 @@ | |
| 42 42 | 
             
              </div>
         | 
| 43 43 |  | 
| 44 44 | 
             
              <div class="form-group">
         | 
| 45 | 
            -
                <%= f.label : | 
| 46 | 
            -
                <%= f.select : | 
| 45 | 
            +
                <%= f.label :form, class: "label" %>
         | 
| 46 | 
            +
                <%= f.select :form, options_for_select(Wf::Workflow.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" %>
         | 
| 47 47 | 
             
              </div>
         | 
| 48 48 |  | 
| 49 49 | 
             
              <div class="form-group">
         | 
| @@ -25,7 +25,11 @@ | |
| 25 25 | 
             
                      <td><%= link_to workflow.name, workflow_path(workflow) %></td>
         | 
| 26 26 | 
             
                      <td><%= workflow.description %></td>
         | 
| 27 27 | 
             
                      <td><%= workflow.is_valid? %></td>
         | 
| 28 | 
            -
                      <td | 
| 28 | 
            +
                      <td>
         | 
| 29 | 
            +
                        <pre>
         | 
| 30 | 
            +
                          <%= workflow.error_msg %>
         | 
| 31 | 
            +
                        </pre>
         | 
| 32 | 
            +
                      </td>
         | 
| 29 33 | 
             
                      <td class="text-right">
         | 
| 30 34 | 
             
                        <%= link_to 'Delete Workflow', workflow_path(workflow), remote: true, method: :delete, data: {confirm: 'confirm?'}, class: 'btn btn-link btn-sm text-danger' %>
         | 
| 31 35 | 
             
                        <%= link_to 'Create Transition', new_workflow_transition_path(workflow), class: 'btn btn-link btn-sm' %>
         | 
| @@ -21,7 +21,11 @@ | |
| 21 21 | 
             
                  <% @workitem.transition.form.fields.each do |field| %>
         | 
| 22 22 | 
             
                   <div class="form-group">
         | 
| 23 23 | 
             
                    <%= ff.label field.name, class: "label" %>
         | 
| 24 | 
            -
                     | 
| 24 | 
            +
                    <% if field.array?  %>
         | 
| 25 | 
            +
                      <%= ff.select field.id, {}, {}, multiple: true, class: "form-control select2" %>
         | 
| 26 | 
            +
                    <% else %>
         | 
| 27 | 
            +
                      <%= ff.send(field.field_type_for_view, field.id, class: "form-control") %>
         | 
| 28 | 
            +
                    <% end %>
         | 
| 25 29 | 
             
                    </div>
         | 
| 26 30 | 
             
                  <% end %>
         | 
| 27 31 | 
             
                <% end %>
         | 
| @@ -30,4 +34,14 @@ | |
| 30 34 | 
             
              <div class="form-group">
         | 
| 31 35 | 
             
                <%= f.submit class: "btn btn-primary", value: "Done", data: {disable_with: 'Waiting...'} %>
         | 
| 32 36 | 
             
              </div>
         | 
| 33 | 
            -
            <% end %>
         | 
| 37 | 
            +
            <% end %>
         | 
| 38 | 
            +
             | 
| 39 | 
            +
            <script>
         | 
| 40 | 
            +
              $(function() {
         | 
| 41 | 
            +
                $(".select2").select2({
         | 
| 42 | 
            +
                  tags: [],
         | 
| 43 | 
            +
                  theme: "bootstrap4",
         | 
| 44 | 
            +
                  tokenSeparators: [',', ' ']
         | 
| 45 | 
            +
                });
         | 
| 46 | 
            +
              });
         | 
| 47 | 
            +
            </script>
         | 
    
        data/lib/wf/engine.rb
    CHANGED
    
    | @@ -22,3 +22,10 @@ require "kaminari" | |
| 22 22 | 
             
            require "simple_command"
         | 
| 23 23 | 
             
            require "loaf"
         | 
| 24 24 | 
             
            require "graphviz"
         | 
| 25 | 
            +
            require "rgl/adjacency"
         | 
| 26 | 
            +
            require "rgl/dijkstra"
         | 
| 27 | 
            +
            require "rgl/topsort"
         | 
| 28 | 
            +
            require "rgl/traversal"
         | 
| 29 | 
            +
            require "rgl/path"
         | 
| 30 | 
            +
            require "active_record/connection_adapters/postgresql_adapter.rb"
         | 
| 31 | 
            +
            require "select2-rails"
         | 
    
        data/lib/wf/version.rb
    CHANGED
    
    
    
        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.1.4
         | 
| 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-14 00:00:00.000000000 Z
         | 
| 12 12 | 
             
            dependencies:
         | 
| 13 13 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 14 14 | 
             
              name: bootstrap
         | 
| @@ -80,6 +80,20 @@ dependencies: | |
| 80 80 | 
             
                - - ">="
         | 
| 81 81 | 
             
                  - !ruby/object:Gem::Version
         | 
| 82 82 | 
             
                    version: '0'
         | 
| 83 | 
            +
            - !ruby/object:Gem::Dependency
         | 
| 84 | 
            +
              name: pg
         | 
| 85 | 
            +
              requirement: !ruby/object:Gem::Requirement
         | 
| 86 | 
            +
                requirements:
         | 
| 87 | 
            +
                - - ">="
         | 
| 88 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 89 | 
            +
                    version: '0'
         | 
| 90 | 
            +
              type: :runtime
         | 
| 91 | 
            +
              prerelease: false
         | 
| 92 | 
            +
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 93 | 
            +
                requirements:
         | 
| 94 | 
            +
                - - ">="
         | 
| 95 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 96 | 
            +
                    version: '0'
         | 
| 83 97 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 84 98 | 
             
              name: rails
         | 
| 85 99 | 
             
              requirement: !ruby/object:Gem::Requirement
         | 
| @@ -100,6 +114,20 @@ dependencies: | |
| 100 114 | 
             
                - - ">="
         | 
| 101 115 | 
             
                  - !ruby/object:Gem::Version
         | 
| 102 116 | 
             
                    version: 6.0.2.1
         | 
| 117 | 
            +
            - !ruby/object:Gem::Dependency
         | 
| 118 | 
            +
              name: rgl
         | 
| 119 | 
            +
              requirement: !ruby/object:Gem::Requirement
         | 
| 120 | 
            +
                requirements:
         | 
| 121 | 
            +
                - - ">="
         | 
| 122 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 123 | 
            +
                    version: '0'
         | 
| 124 | 
            +
              type: :runtime
         | 
| 125 | 
            +
              prerelease: false
         | 
| 126 | 
            +
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 127 | 
            +
                requirements:
         | 
| 128 | 
            +
                - - ">="
         | 
| 129 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 130 | 
            +
                    version: '0'
         | 
| 103 131 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 104 132 | 
             
              name: ruby-graphviz
         | 
| 105 133 | 
             
              requirement: !ruby/object:Gem::Requirement
         | 
| @@ -114,6 +142,20 @@ dependencies: | |
| 114 142 | 
             
                - - ">="
         | 
| 115 143 | 
             
                  - !ruby/object:Gem::Version
         | 
| 116 144 | 
             
                    version: '0'
         | 
| 145 | 
            +
            - !ruby/object:Gem::Dependency
         | 
| 146 | 
            +
              name: select2-rails-2020
         | 
| 147 | 
            +
              requirement: !ruby/object:Gem::Requirement
         | 
| 148 | 
            +
                requirements:
         | 
| 149 | 
            +
                - - ">="
         | 
| 150 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 151 | 
            +
                    version: '0'
         | 
| 152 | 
            +
              type: :runtime
         | 
| 153 | 
            +
              prerelease: false
         | 
| 154 | 
            +
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 155 | 
            +
                requirements:
         | 
| 156 | 
            +
                - - ">="
         | 
| 157 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 158 | 
            +
                    version: '0'
         | 
| 117 159 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 118 160 | 
             
              name: simple_command
         | 
| 119 161 | 
             
              requirement: !ruby/object:Gem::Requirement
         | 
| @@ -209,6 +251,7 @@ files: | |
| 209 251 | 
             
            - app/models/wf/case_command/clear_manual_assignments.rb
         | 
| 210 252 | 
             
            - app/models/wf/case_command/clear_workitem_assignments.rb
         | 
| 211 253 | 
             
            - app/models/wf/case_command/consume_token.rb
         | 
| 254 | 
            +
            - app/models/wf/case_command/create_entry.rb
         | 
| 212 255 | 
             
            - app/models/wf/case_command/enable_transitions.rb
         | 
| 213 256 | 
             
            - app/models/wf/case_command/end_workitem_action.rb
         | 
| 214 257 | 
             
            - app/models/wf/case_command/finish_workitem.rb
         | 
| @@ -290,6 +333,10 @@ files: | |
| 290 333 | 
             
            - db/migrate/20200130201641_init_some_data.rb
         | 
| 291 334 | 
             
            - db/migrate/20200131200455_create_wf_entries.rb
         | 
| 292 335 | 
             
            - db/migrate/20200201001543_add_target_field_name_for_guard.rb
         | 
| 336 | 
            +
            - db/migrate/20200212120019_remove_targetable_from_workitem.rb
         | 
| 337 | 
            +
            - db/migrate/20200213085258_add_formable.rb
         | 
| 338 | 
            +
            - db/migrate/20200213125753_add_form_id_for_entry.rb
         | 
| 339 | 
            +
            - db/migrate/20200213130900_remove_workflow_id_from_form_related.rb
         | 
| 293 340 | 
             
            - lib/tasks/wf_tasks.rake
         | 
| 294 341 | 
             
            - lib/wf.rb
         | 
| 295 342 | 
             
            - lib/wf/engine.rb
         |