easy_flow 0.3.0 → 0.4.0

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 8ff52593be51a666b42de7e2b05f7fea31de7b09240a21884d341ee0d7bfc1d2
4
- data.tar.gz: cb2902b162132cdbfa5060b64acc49835fdbfaeacffc83665a8d2ab74a5de722
3
+ metadata.gz: 047aff1880613e32482420c7b478d5000d0c719ba1aa71c16f417b7d452fc439
4
+ data.tar.gz: 0e844849204cd09a8cf19eb589135aff9baa01feb95f5d9df35b30e74b1852e4
5
5
  SHA512:
6
- metadata.gz: 10a1e356dfcddc779ffc9f0ada50195c03a676ff2717ed64f0e6bbbbab1df3e834e6f7be22758a0de79c7ee6e490fe471c1654d4f4af97f1172a9bed69f2749b
7
- data.tar.gz: 4cb65c539b7a12d104e0c12db6cb304267ef966b892ba3cdfe920e0e4e50d703936189ad685a2412761e5f4c4e9bed292048723c8c1c84e9ff43408a83eb193b
6
+ metadata.gz: 1ff1a5d9237fa30f12bf00c0bad7b1d79be71908a2f798b7e90c82c40f3dd95c8c49791619535b8f4db6540721ed91649a11d4370f32f5b5e3ba50d3560f769b
7
+ data.tar.gz: 69e16473303ea08c45ed0027cf9a07a2b75d027d4955e88703fe10d17998ebdfd9477949e4f53b09f42bf78feb41249fcf70ff79151a30faa698845631770cce
@@ -0,0 +1,21 @@
1
+ module EasyFlow
2
+ module Hosted
3
+ extend ActiveSupport::Concern
4
+
5
+ included do
6
+ class_attribute :named_flow_host, instance_accessor: false
7
+ end
8
+
9
+ class_methods do
10
+ def hosted_by(name)
11
+ self.named_flow_host = name.to_s
12
+ end
13
+ end
14
+
15
+ private
16
+
17
+ def flow_host
18
+ @flow_host ||= EasyFlow.host_named(self.class.named_flow_host || request.path_parameters[:easy_flow_host])
19
+ end
20
+ end
21
+ end
@@ -10,9 +10,9 @@ module EasyFlow
10
10
  private
11
11
 
12
12
  def authenticate_admin
13
- return unless EasyFlow.admin_authentication_method
13
+ return unless flow_host.admin_authentication_method
14
14
 
15
- send(EasyFlow.admin_authentication_method)
15
+ send(flow_host.admin_authentication_method)
16
16
  end
17
17
  end
18
18
  end
@@ -1,16 +1,24 @@
1
1
  module EasyFlow
2
2
  class ApplicationController < EasyFlow.base_controller.constantize
3
- layout -> { EasyFlow.layout }
3
+ include Hosted
4
+
5
+ layout -> { flow_host.layout }
4
6
  helper KeystoneUiHelper
5
7
 
6
8
  rescue_from NotPublished, NotPermitted, Withdrawn, with: :refuse
7
9
 
8
- helper_method :flow_start_path
10
+ helper_method :flow_start_path, :flow_routes
9
11
 
10
12
  private
11
13
 
14
+ def flow_routes
15
+ return easy_flow unless request.routes.equal?(EasyFlow::Engine.routes)
16
+
17
+ @flow_routes ||= ActionDispatch::Routing::RoutesProxy.new(_routes, self, _routes.url_helpers)
18
+ end
19
+
12
20
  def flow_start_path(slug)
13
- easy_flow.flow_path(slug)
21
+ flow_routes.flow_path(slug)
14
22
  end
15
23
 
16
24
  def admit(flow)
@@ -18,15 +26,15 @@ module EasyFlow
18
26
  end
19
27
 
20
28
  def permitted?(flow)
21
- return false unless EasyFlow.visitor_authorization_method
29
+ return false unless flow_host.visitor_authorization_method
22
30
 
23
- send(EasyFlow.visitor_authorization_method, flow)
31
+ send(flow_host.visitor_authorization_method, flow)
24
32
  end
25
33
 
26
34
  def refuse(refusal)
27
- return head :not_found unless EasyFlow.refusal_method
35
+ return head :not_found unless flow_host.refusal_method
28
36
 
29
- send(EasyFlow.refusal_method, refusal)
37
+ send(flow_host.refusal_method, refusal)
30
38
  end
31
39
  end
32
40
  end
@@ -34,7 +34,7 @@ module EasyFlow
34
34
  end
35
35
 
36
36
  def run_location(run)
37
- easy_flow.run_path(run)
37
+ flow_routes.run_path(run)
38
38
  end
39
39
 
40
40
  def start_run(flow)
@@ -42,11 +42,11 @@ module EasyFlow
42
42
  end
43
43
 
44
44
  def flow_start_path(slug)
45
- easy_flow.flow_path(slug)
45
+ flow_routes.flow_path(slug)
46
46
  end
47
47
 
48
48
  def flow_step_path(slug)
49
- easy_flow.flow_step_path(slug)
49
+ flow_routes.flow_step_path(slug)
50
50
  end
51
51
 
52
52
  def previewing?
@@ -89,13 +89,13 @@ module EasyFlow
89
89
  end
90
90
 
91
91
  def admitted_run
92
- found = Run.find(params[:id])
92
+ found = Run.where(flow: flow_host.flows).find(params[:id])
93
93
 
94
94
  Admission.of_run(found, permitted: permitted?(found.flow))
95
95
  end
96
96
 
97
97
  def flow
98
- @stored_flow ||= admit(Definition.find_by(slug: params[:slug]))
98
+ @stored_flow ||= admit(flow_host.flows.find_by(slug: params[:slug]))
99
99
  end
100
100
 
101
101
  def flowing_definition(flow)
@@ -3,12 +3,22 @@ require "keystone_ui/react/mount_helper"
3
3
  module EasyFlow
4
4
  module Manage
5
5
  class BaseController < EasyFlow.base_controller.constantize
6
+ include Hosted
7
+
8
+ before_action :refuse_a_host_not_set_up
9
+
6
10
  include AuthenticatesAdmin
7
11
 
8
- layout -> { EasyFlow.admin_layout }
12
+ layout -> { flow_host.admin_layout }
9
13
 
10
14
  helper KeystoneUiHelper
11
15
  helper KeystoneUi::React::MountHelper
16
+
17
+ private
18
+
19
+ def refuse_a_host_not_set_up
20
+ head :not_found unless flow_host.set_up?
21
+ end
12
22
  end
13
23
  end
14
24
  end
@@ -83,7 +83,7 @@ module EasyFlow
83
83
  end
84
84
 
85
85
  def flow
86
- @flow ||= Definition.find(params[:flow_id])
86
+ @flow ||= flow_host.flows.find(params[:flow_id])
87
87
  end
88
88
 
89
89
  def document
@@ -2,11 +2,11 @@ module EasyFlow
2
2
  module Manage
3
3
  class DefinitionsController < BaseController
4
4
  def edit
5
- @flow = Definition.find(params[:flow_id])
5
+ @flow = flow_host.flows.find(params[:flow_id])
6
6
  end
7
7
 
8
8
  def update
9
- @flow = Definition.find(params[:flow_id])
9
+ @flow = flow_host.flows.find(params[:flow_id])
10
10
  @flow.edit_history.edit_document(JSON.parse(params.require(:definition)))
11
11
  redirect_to manage_flow_path(@flow), notice: "Definition saved."
12
12
  end
@@ -7,7 +7,7 @@ module EasyFlow
7
7
  end
8
8
 
9
9
  def create
10
- @flow = Definition.new(create_params)
10
+ @flow = flow_host.flows.new(create_params)
11
11
 
12
12
  if @flow.save
13
13
  redirect_to manage_flow_path(@flow), notice: "Flow created."
@@ -18,29 +18,29 @@ module EasyFlow
18
18
  end
19
19
 
20
20
  def show
21
- @flow = Definition.find(params[:id])
21
+ @flow = flow_host.flows.find(params[:id])
22
22
  @canvas = canvas_payload(@flow)
23
23
  end
24
24
 
25
25
  def edit
26
- @flow = Definition.find(params[:id])
26
+ @flow = flow_host.flows.find(params[:id])
27
27
  end
28
28
 
29
29
  def update
30
- @flow = Definition.find(params[:id])
30
+ @flow = flow_host.flows.find(params[:id])
31
31
  @flow.update!(flow_params)
32
32
  redirect_to manage_flow_path(@flow), notice: "Saved."
33
33
  end
34
34
 
35
35
  def destroy
36
- Definition.find(params[:id]).destroy!
36
+ flow_host.flows.find(params[:id]).destroy!
37
37
  redirect_to manage_flows_path, notice: "Flow removed."
38
38
  end
39
39
 
40
40
  private
41
41
 
42
42
  def ordered_flows
43
- Definition.order(:slug)
43
+ flow_host.flows.order(:slug)
44
44
  end
45
45
 
46
46
  def create_params
@@ -11,11 +11,11 @@ module EasyFlow
11
11
  private
12
12
 
13
13
  def flow_start_path(_slug)
14
- easy_flow.manage_flow_preview_path(previewed)
14
+ manage_flow_preview_path(previewed)
15
15
  end
16
16
 
17
17
  def flow_step_path(_slug)
18
- easy_flow.step_manage_flow_preview_path(previewed)
18
+ step_manage_flow_preview_path(previewed)
19
19
  end
20
20
 
21
21
  def previewing?
@@ -27,7 +27,7 @@ module EasyFlow
27
27
  end
28
28
 
29
29
  def previewed
30
- @previewed ||= Definition.find(params[:flow_id])
30
+ @previewed ||= flow_host.flows.find(params[:flow_id])
31
31
  end
32
32
 
33
33
  def admit(_flow)
@@ -15,7 +15,7 @@ module EasyFlow
15
15
  private
16
16
 
17
17
  def flow
18
- @flow ||= Definition.find(params[:flow_id])
18
+ @flow ||= flow_host.flows.find(params[:flow_id])
19
19
  end
20
20
  end
21
21
  end
@@ -6,7 +6,7 @@ module EasyFlow
6
6
  enum :kind, { scored: "scored", guide: "guide" }
7
7
  enum :persists, { unsaved: "unsaved", each_step: "each_step", on_finish: "on_finish" }
8
8
 
9
- validates :slug, presence: true
9
+ validates :host, :slug, presence: true
10
10
 
11
11
  after_initialize :begin_the_flow, if: :new_record?
12
12
 
@@ -17,8 +17,8 @@ module EasyFlow
17
17
  has_many :runs, class_name: "EasyFlow::Run", foreign_key: :flow_id, dependent: :destroy
18
18
  has_many :definition_versions, class_name: "EasyFlow::Version", foreign_key: :flow_id, dependent: :destroy
19
19
 
20
- def self.upsert_definition(definition)
21
- find_or_initialize_by(slug: definition["slug"]).tap do |flow|
20
+ def self.upsert_definition(definition, host:)
21
+ find_or_initialize_by(host: host, slug: definition["slug"]).tap do |flow|
22
22
  flow.save!
23
23
  flow.record_definition(definition) unless flow.definition == definition
24
24
  end
@@ -6,7 +6,7 @@
6
6
  <%= ui_section do %>
7
7
  <div class="flex flex-wrap items-center gap-3">
8
8
  <% if @flow.each_step? && @flow.definition.present? && !previewing? %>
9
- <%= ui_form(action: easy_flow.flow_runs_path(@flow.slug), method: :post) do %>
9
+ <%= ui_form(action: flow_routes.flow_runs_path(@flow.slug), method: :post) do %>
10
10
  <%= ui_button(label: @flow.start_label.presence || "Start", type: :submit) %>
11
11
  <% end %>
12
12
  <% else %>
@@ -1,11 +1,11 @@
1
1
  <%= ui_page(max_width: :lg) do %>
2
2
  <p class="mb-4">
3
- <%= link_to "← Back to the flow", easy_flow.manage_flow_path(@flow), class: "text-sm text-accent-600 hover:text-accent-700" %>
3
+ <%= link_to "← Back to the flow", manage_flow_path(@flow), class: "text-sm text-accent-600 hover:text-accent-700" %>
4
4
  </p>
5
5
 
6
- <%= ui_form_page(title: "Definition", back_url: easy_flow.manage_flow_path(@flow), subtitle: @flow.slug) %>
6
+ <%= ui_form_page(title: "Definition", back_url: manage_flow_path(@flow), subtitle: @flow.slug) %>
7
7
 
8
- <%= ui_form(action: easy_flow.manage_flow_definition_path(@flow), method: :patch) do %>
8
+ <%= ui_form(action: manage_flow_definition_path(@flow), method: :patch) do %>
9
9
  <%= ui_textarea(name: "definition", value: JSON.pretty_generate(@flow.document), rows: 30) %>
10
10
 
11
11
  <%= ui_button(label: "Save", type: :submit) %>
@@ -1,11 +1,11 @@
1
1
  <%= ui_page(max_width: :lg) do %>
2
2
  <p class="mb-4">
3
- <%= link_to "← Back to the flow", easy_flow.manage_flow_path(@flow), class: "text-sm text-accent-600 hover:text-accent-700" %>
3
+ <%= link_to "← Back to the flow", manage_flow_path(@flow), class: "text-sm text-accent-600 hover:text-accent-700" %>
4
4
  </p>
5
5
 
6
- <%= ui_form_page(title: "Edit details", back_url: easy_flow.manage_flow_path(@flow)) %>
6
+ <%= ui_form_page(title: "Edit details", back_url: manage_flow_path(@flow)) %>
7
7
 
8
- <%= ui_form(action: easy_flow.manage_flow_path(@flow), method: :patch) do %>
8
+ <%= ui_form(action: manage_flow_path(@flow), method: :patch) do %>
9
9
  <%= ui_section(title: "How this is introduced") do %>
10
10
  <label class="block text-sm font-medium mb-1">Title</label>
11
11
  <%= ui_input(name: "flow[title]", value: @flow.title) %>
@@ -6,9 +6,9 @@
6
6
  columns: [ { title: "Title" }, { slug: "Slug" }, { kind: "Kind" }, { status: "Status" } ],
7
7
  empty_message: "No flows yet."
8
8
  ) do |table| %>
9
- <% table.link(:title) { |flow| easy_flow.manage_flow_path(flow) } %>
9
+ <% table.link(:title) { |flow| manage_flow_path(flow) } %>
10
10
  <% table.actions do |flow| %>
11
- <%= ui_form(action: easy_flow.manage_flow_path(flow), method: :delete) do %>
11
+ <%= ui_form(action: manage_flow_path(flow), method: :delete) do %>
12
12
  <%= ui_button(label: "Remove", type: :submit, variant: :secondary) %>
13
13
  <% end %>
14
14
  <% end %>
@@ -19,7 +19,7 @@
19
19
  <%= ui_alert(message: @flow.errors.full_messages.to_sentence, type: :error) %>
20
20
  <% end %>
21
21
 
22
- <%= ui_form(action: easy_flow.manage_flows_path, method: :post) do %>
22
+ <%= ui_form(action: manage_flows_path, method: :post) do %>
23
23
  <label class="block text-sm font-medium mb-1">Slug</label>
24
24
  <%= ui_input(name: "flow[slug]", placeholder: "e.g. business-scorecard") %>
25
25
 
@@ -14,13 +14,13 @@
14
14
  onclick="document.dispatchEvent(new CustomEvent('easy_flow:open-flow'))"
15
15
  class="inline-flex items-center justify-center font-semibold rounded-lg border-0 cursor-pointer bg-accent-600 text-white hover:bg-accent-700 text-base px-4 py-2">This flow</button>
16
16
 
17
- <%= ui_button(label: "Try it", href: easy_flow.manage_flow_preview_path(@flow), variant: :secondary) %>
17
+ <%= ui_button(label: "Try it", href: manage_flow_preview_path(@flow), variant: :secondary) %>
18
18
 
19
- <%= ui_button(label: "All flows", href: easy_flow.manage_flows_path, variant: :secondary) %>
19
+ <%= ui_button(label: "All flows", href: manage_flows_path, variant: :secondary) %>
20
20
  </div>
21
21
  </header>
22
22
 
23
- <%= react_ui("easy_flow/flow-editor", { base: easy_flow.manage_flow_canvas_path(@flow), token: form_authenticity_token, initial: @canvas },
23
+ <%= react_ui("easy_flow/flow-editor", { base: manage_flow_canvas_path(@flow), token: form_authenticity_token, initial: @canvas },
24
24
  class: "min-h-0 flex-1",
25
25
  data: { flow_canvas: true }) %>
26
26
  </div>
@@ -1,6 +1,6 @@
1
1
  <%= ui_page(max_width: :lg) do %>
2
2
  <p class="mb-4">
3
- <%= link_to "← Back to the flow", easy_flow.manage_flow_path(@flow), class: "text-sm text-accent-600 hover:text-accent-700" %>
3
+ <%= link_to "← Back to the flow", manage_flow_path(@flow), class: "text-sm text-accent-600 hover:text-accent-700" %>
4
4
  </p>
5
5
 
6
6
  <%= ui_page_header(title: "History", subtitle: @flow.title.presence || @flow.slug) %>
@@ -30,7 +30,7 @@
30
30
 
31
31
  <% unless version == @versions.first %>
32
32
  <%= button_to "Return the flow to this version",
33
- easy_flow.return_manage_flow_version_path(@flow, version),
33
+ return_manage_flow_version_path(@flow, version),
34
34
  form: { data: { turbo: false } }, data: { return: true },
35
35
  class: "mt-3 inline-flex items-center rounded-lg border border-gray-300 bg-white px-3 py-1.5 text-sm text-gray-900 hover:bg-gray-50 cursor-pointer" %>
36
36
  <% end %>
@@ -0,0 +1,9 @@
1
+ class AddHostToEasyFlowDefinitions < ActiveRecord::Migration[8.1]
2
+ def change
3
+ add_column :easy_flow_definitions, :host, :string, null: false, default: ""
4
+ change_column_default :easy_flow_definitions, :host, from: "", to: nil
5
+
6
+ remove_index :easy_flow_definitions, :slug, unique: true
7
+ add_index :easy_flow_definitions, [ :host, :slug ], unique: true
8
+ end
9
+ end
@@ -0,0 +1,27 @@
1
+ module EasyFlow
2
+ class Host
3
+ attr_reader :name
4
+ attr_writer :layout, :admin_layout
5
+ attr_accessor :admin_authentication_method, :visitor_authorization_method, :refusal_method
6
+
7
+ def initialize(name)
8
+ @name = name.to_s
9
+ end
10
+
11
+ def layout
12
+ @layout || "easy_flow/application"
13
+ end
14
+
15
+ def admin_layout
16
+ @admin_layout || "application"
17
+ end
18
+
19
+ def flows
20
+ Definition.where(host: name)
21
+ end
22
+
23
+ def set_up?
24
+ true
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,15 @@
1
+ module EasyFlow
2
+ class UnsetHost < Host
3
+ def initialize
4
+ super(nil)
5
+ end
6
+
7
+ def flows
8
+ Definition.none
9
+ end
10
+
11
+ def set_up?
12
+ false
13
+ end
14
+ end
15
+ end
@@ -1,3 +1,3 @@
1
1
  module EasyFlow
2
- VERSION = "0.3.0"
2
+ VERSION = "0.4.0"
3
3
  end
data/lib/easy_flow.rb CHANGED
@@ -1,5 +1,7 @@
1
1
  require "json"
2
2
  require "easy_flow/version"
3
+ require "easy_flow/host"
4
+ require "easy_flow/unset_host"
3
5
  require "easy_flow/engine"
4
6
 
5
7
  module EasyFlow
@@ -21,19 +23,24 @@ module EasyFlow
21
23
  DRAWING = "easy_flow/steps/choosing".freeze
22
24
 
23
25
  class << self
24
- attr_writer :layout, :base_controller, :admin_layout
25
- attr_accessor :visitor_authorization_method, :refusal_method, :admin_authentication_method
26
-
27
- def layout
28
- @layout || "easy_flow/application"
29
- end
26
+ attr_writer :base_controller
30
27
 
31
28
  def base_controller
32
29
  @base_controller || "ActionController::Base"
33
30
  end
34
31
 
35
- def admin_layout
36
- @admin_layout || "application"
32
+ def host(name)
33
+ raise ArgumentError, "a host needs a name" if name.blank?
34
+
35
+ hosts[name.to_s] = Host.new(name).tap { |host| yield host if block_given? }
36
+ end
37
+
38
+ def hosts
39
+ @hosts ||= {}
40
+ end
41
+
42
+ def host_named(name)
43
+ hosts.fetch(name.to_s) { UnsetHost.new }
37
44
  end
38
45
 
39
46
  def draws_with(template)
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: easy_flow
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.0
4
+ version: 0.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - tylercschneider
@@ -50,6 +50,7 @@ files:
50
50
  - README.md
51
51
  - Rakefile
52
52
  - app/assets/builds/easy_flow/canvas.js
53
+ - app/controllers/concerns/easy_flow/hosted.rb
53
54
  - app/controllers/concerns/easy_flow/manage/authenticates_admin.rb
54
55
  - app/controllers/concerns/easy_flow/manage/draws_canvas.rb
55
56
  - app/controllers/easy_flow/application_controller.rb
@@ -131,8 +132,11 @@ files:
131
132
  - db/migrate/20260924120000_create_easy_flow_definitions.rb
132
133
  - db/migrate/20260924120100_create_easy_flow_versions.rb
133
134
  - db/migrate/20260924120200_create_easy_flow_runs.rb
135
+ - db/migrate/20260924130000_add_host_to_easy_flow_definitions.rb
134
136
  - lib/easy_flow.rb
135
137
  - lib/easy_flow/engine.rb
138
+ - lib/easy_flow/host.rb
139
+ - lib/easy_flow/unset_host.rb
136
140
  - lib/easy_flow/version.rb
137
141
  homepage: https://github.com/DYB-Development/easy_flow
138
142
  licenses: