alembic 0.1.0 → 0.3.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 +4 -4
- data/README.md +36 -22
- data/app/assets/builds/alembic/page_builder.css +1 -1
- data/app/assets/builds/alembic/page_builder.js +3 -3
- data/app/controllers/alembic/application_controller.rb +1 -16
- data/app/controllers/alembic/flows_controller.rb +6 -90
- data/app/controllers/alembic/manage/base_controller.rb +2 -0
- data/app/controllers/alembic/manage/flows_controller.rb +12 -44
- data/app/controllers/alembic/manage/pages_controller.rb +8 -1
- data/app/controllers/alembic/manage/previews_controller.rb +4 -19
- data/app/controllers/alembic/pages_controller.rb +19 -0
- data/app/controllers/concerns/alembic/summarizes.rb +59 -0
- data/app/helpers/alembic/application_helper.rb +2 -2
- data/app/helpers/alembic/pages_helper.rb +40 -0
- data/app/helpers/alembic/result_blocks_helper.rb +45 -0
- data/app/models/alembic/flow/definition_summary.rb +10 -0
- data/app/models/alembic/flow/run_summary.rb +10 -0
- data/app/models/alembic/flow/summaries.rb +44 -5
- data/app/models/alembic/flow/summary_version.rb +1 -1
- data/app/models/alembic/outputs/band.rb +1 -1
- data/app/models/alembic/outputs/grouped.rb +1 -1
- data/app/models/alembic/outputs/lowest.rb +5 -3
- data/app/models/alembic/outputs/percentage.rb +1 -1
- data/app/models/alembic/outputs/weighted_sum.rb +1 -1
- data/app/models/alembic/page/drawing.rb +17 -0
- data/app/models/alembic/page/options.rb +53 -0
- data/app/models/alembic/page/version.rb +13 -0
- data/app/models/alembic/page.rb +32 -0
- data/app/models/alembic/result_blocks.rb +29 -0
- data/app/models/alembic/summary/report.rb +1 -1
- data/app/models/alembic/summary/result.rb +1 -1
- data/app/views/alembic/blocks/_answers.html.erb +11 -0
- data/app/views/alembic/blocks/_band.html.erb +6 -0
- data/app/views/alembic/blocks/_categories.html.erb +11 -0
- data/app/views/alembic/blocks/_lead.html.erb +15 -0
- data/app/views/alembic/blocks/_score.html.erb +7 -0
- data/app/views/alembic/blocks/_weakest.html.erb +12 -0
- data/app/views/alembic/flows/complete.html.erb +12 -6
- data/app/views/alembic/flows/show.html.erb +6 -6
- data/app/views/alembic/flows/summary_page.html.erb +5 -0
- data/app/views/alembic/manage/flows/edit.html.erb +16 -10
- data/app/views/alembic/manage/pages/_block_content.html.erb +1 -1
- data/app/views/alembic/manage/pages/index.html.erb +4 -1
- data/app/views/alembic/manage/pages/show.html.erb +7 -1
- data/app/views/alembic/pages/show.html.erb +5 -0
- data/config/routes.rb +8 -19
- data/db/migrate/20260825224538_remove_published_version_from_alembic_diagnostics.rb +21 -1
- data/db/migrate/20260922120000_add_slug_to_alembic_pages.rb +6 -0
- data/db/migrate/20260922130000_create_alembic_page_versions.rb +16 -0
- data/db/migrate/20260924220000_move_flows_onto_easy_flow.rb +166 -0
- data/db/migrate/20260930120000_add_summary_page_to_alembic_flow_definition_summaries.rb +6 -0
- data/lib/alembic/engine.rb +6 -11
- data/lib/alembic/version.rb +1 -1
- data/lib/alembic.rb +34 -6
- metadata +45 -71
- data/app/assets/builds/alembic/canvas.js +0 -1
- data/app/controllers/alembic/manage/canvas_controller.rb +0 -183
- data/app/controllers/alembic/manage/definitions_controller.rb +0 -15
- data/app/controllers/alembic/manage/versions_controller.rb +0 -22
- data/app/controllers/concerns/alembic/manage/draws_canvas.rb +0 -35
- data/app/javascript/alembic/canvas/Canvas.jsx +0 -197
- data/app/javascript/alembic/canvas/Connector.jsx +0 -30
- data/app/javascript/alembic/canvas/ConnectorLayer.jsx +0 -31
- data/app/javascript/alembic/canvas/Control.jsx +0 -42
- data/app/javascript/alembic/canvas/Inspector.jsx +0 -44
- data/app/javascript/alembic/canvas/Panel.jsx +0 -67
- data/app/javascript/alembic/canvas/Placeholder.jsx +0 -24
- data/app/javascript/alembic/canvas/Port.jsx +0 -16
- data/app/javascript/alembic/canvas/Records.jsx +0 -34
- data/app/javascript/alembic/canvas/StepCard.jsx +0 -57
- data/app/javascript/alembic/canvas/Toolbar.jsx +0 -19
- data/app/javascript/alembic/canvas/TypePicker.jsx +0 -21
- data/app/javascript/alembic/canvas/changes.js +0 -5
- data/app/javascript/alembic/canvas/choices.js +0 -4
- data/app/javascript/alembic/canvas/flow.js +0 -7
- data/app/javascript/alembic/canvas/flowSender.js +0 -22
- data/app/javascript/alembic/canvas/ids.js +0 -7
- data/app/javascript/alembic/canvas/rows.js +0 -2
- data/app/javascript/alembic/canvas/styles.js +0 -3
- data/app/javascript/alembic/canvas/useConnectors.js +0 -75
- data/app/javascript/alembic/canvas/useFlow.js +0 -17
- data/app/javascript/alembic/canvas.jsx +0 -13
- data/app/models/alembic/asked.rb +0 -3
- data/app/models/alembic/choice.rb +0 -7
- data/app/models/alembic/flow/admission.rb +0 -19
- data/app/models/alembic/flow/canvas.rb +0 -167
- data/app/models/alembic/flow/change.rb +0 -18
- data/app/models/alembic/flow/condition.rb +0 -24
- data/app/models/alembic/flow/definition.rb +0 -132
- data/app/models/alembic/flow/digest.rb +0 -116
- data/app/models/alembic/flow/document.rb +0 -131
- data/app/models/alembic/flow/drawing.rb +0 -15
- data/app/models/alembic/flow/edge.rb +0 -9
- data/app/models/alembic/flow/edit_history.rb +0 -75
- data/app/models/alembic/flow/layout.rb +0 -88
- data/app/models/alembic/flow/name.rb +0 -15
- data/app/models/alembic/flow/node.rb +0 -5
- data/app/models/alembic/flow/output.rb +0 -23
- data/app/models/alembic/flow/progress/kept.rb +0 -38
- data/app/models/alembic/flow/progress/loose.rb +0 -43
- data/app/models/alembic/flow/progress.rb +0 -11
- data/app/models/alembic/flow/registry.rb +0 -25
- data/app/models/alembic/flow/run.rb +0 -54
- data/app/models/alembic/flow/runner.rb +0 -65
- data/app/models/alembic/flow/settings.rb +0 -80
- data/app/models/alembic/flow/start.rb +0 -13
- data/app/models/alembic/flow/step.rb +0 -42
- data/app/models/alembic/flow/step_type/declaration.rb +0 -118
- data/app/models/alembic/flow/step_type.rb +0 -69
- data/app/models/alembic/flow/switch.rb +0 -17
- data/app/models/alembic/flow/terminal.rb +0 -13
- data/app/models/alembic/flow/validator.rb +0 -171
- data/app/models/alembic/flow/version.rb +0 -26
- data/app/models/alembic/flow/violation.rb +0 -9
- data/app/models/alembic/flow.rb +0 -44
- data/app/models/alembic/runner.rb +0 -13
- data/app/models/alembic/steps/question.rb +0 -52
- data/app/views/alembic/flow/steps/_choosing.html.erb +0 -9
- data/app/views/alembic/flows/step.html.erb +0 -27
- data/app/views/alembic/manage/definitions/edit.html.erb +0 -13
- data/app/views/alembic/manage/flows/index.html.erb +0 -32
- data/app/views/alembic/manage/flows/show.html.erb +0 -26
- data/app/views/alembic/manage/versions/index.html.erb +0 -41
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
module Alembic
|
|
2
|
+
class Page < ApplicationRecord
|
|
3
|
+
class Version < ApplicationRecord
|
|
4
|
+
self.table_name = "alembic_page_versions"
|
|
5
|
+
|
|
6
|
+
enum :status, { draft: "draft", live: "live", superseded: "superseded" }
|
|
7
|
+
|
|
8
|
+
belongs_to :page, class_name: "Alembic::Page"
|
|
9
|
+
|
|
10
|
+
validates :number, uniqueness: { scope: :page_id }
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
end
|
data/app/models/alembic/page.rb
CHANGED
|
@@ -6,6 +6,38 @@ module Alembic
|
|
|
6
6
|
|
|
7
7
|
block_layout :blocks, kind: :pages
|
|
8
8
|
|
|
9
|
+
has_many :versions, class_name: "Alembic::Page::Version", dependent: :destroy, inverse_of: :page
|
|
10
|
+
|
|
9
11
|
validates :name, presence: true
|
|
12
|
+
validates :slug, uniqueness: true, allow_nil: true
|
|
13
|
+
|
|
14
|
+
def publish
|
|
15
|
+
transaction do
|
|
16
|
+
live_version&.update!(status: :superseded)
|
|
17
|
+
versions.create!(number: next_number, blocks: blocks, status: :live)
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def live_version
|
|
22
|
+
versions.find_by(status: :live)
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def next_number
|
|
26
|
+
(versions.maximum(:number) || 0) + 1
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def self.block(key, drawn_by: nil, options: {}, body: nil, **block_type)
|
|
30
|
+
refuse_unknown(key, drawn_by)
|
|
31
|
+
Drawing.record(key, drawn_by)
|
|
32
|
+
Options.declare(key, options, body: body)
|
|
33
|
+
KsBlocks.block(key, kind: :pages, **block_type)
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def self.refuse_unknown(key, component)
|
|
37
|
+
return if component.nil? || ApplicationController.helpers.respond_to?(component)
|
|
38
|
+
|
|
39
|
+
raise ArgumentError, "The #{key} page block names #{component}, which nothing draws"
|
|
40
|
+
end
|
|
41
|
+
private_class_method :refuse_unknown
|
|
10
42
|
end
|
|
11
43
|
end
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
module Alembic
|
|
2
|
+
module ResultBlocks
|
|
3
|
+
OUTPUT = { key: :output, label: "Output" }.freeze
|
|
4
|
+
HEADING = { key: :heading, label: "Heading" }.freeze
|
|
5
|
+
|
|
6
|
+
def self.register
|
|
7
|
+
Page.block(:alembic_score, name: "Score", width: 12, height: 3, drawn_by: :alembic_score_block,
|
|
8
|
+
fields: [ OUTPUT, { key: :kicker, label: "Label above" }, { key: :caption, label: "Caption" } ],
|
|
9
|
+
options: { value: { value_of: :output } })
|
|
10
|
+
Page.block(:alembic_band, name: "Band", width: 12, height: 2, drawn_by: :alembic_band_block,
|
|
11
|
+
fields: [ OUTPUT, { key: :score, label: "Score output" } ],
|
|
12
|
+
options: { value: { value_of: :output }, score: { value_of: :score } })
|
|
13
|
+
Page.block(:alembic_categories, name: "Score per category", width: 12, height: 4, drawn_by: :alembic_categories_block,
|
|
14
|
+
fields: [ OUTPUT, HEADING ], options: { value: { value_of: :output } })
|
|
15
|
+
Page.block(:alembic_weakest, name: "Weakest categories", width: 12, height: 4, drawn_by: :alembic_weakest_block,
|
|
16
|
+
fields: [ OUTPUT, HEADING, { key: :cost_label, label: "Cost label" } ], options: { value: { value_of: :output } })
|
|
17
|
+
Page.block(:alembic_answers, name: "Answers given", width: 12, height: 4, drawn_by: :alembic_answers_block,
|
|
18
|
+
fields: [ HEADING ], options: { value: { value: "answers" } })
|
|
19
|
+
register_lead if Alembic.lead_address
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def self.register_lead
|
|
23
|
+
Page.block(:alembic_lead, name: "Lead", width: 12, height: 3, drawn_by: :alembic_lead_block,
|
|
24
|
+
fields: [ HEADING, { key: :blurb, label: "Text" }, { key: :button, label: "Button" }, { key: :placeholder, label: "Placeholder" } ],
|
|
25
|
+
options: { slug: { value: "slug" }, note: { value: "note" } })
|
|
26
|
+
end
|
|
27
|
+
private_class_method :register_lead
|
|
28
|
+
end
|
|
29
|
+
end
|
|
@@ -13,7 +13,7 @@ module Alembic
|
|
|
13
13
|
output_type = @registry.fetch(output["type"])
|
|
14
14
|
produced[output["id"]] = output_type.compute(output, run, produced)
|
|
15
15
|
|
|
16
|
-
Result.new(id: output["id"], label: label_for(output, output_type), value: produced[output["id"]])
|
|
16
|
+
Result.new(id: output["id"], type: output["type"], label: label_for(output, output_type), value: produced[output["id"]])
|
|
17
17
|
end
|
|
18
18
|
end
|
|
19
19
|
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
<div>
|
|
2
|
+
<h2 class="text-xs font-semibold uppercase tracking-wider text-gray-500 mb-4"><%= heading %></h2>
|
|
3
|
+
<ul class="divide-y divide-gray-100 border-y border-gray-100">
|
|
4
|
+
<% answers.each do |question, answer| %>
|
|
5
|
+
<li class="flex items-baseline justify-between gap-6 py-3">
|
|
6
|
+
<span class="text-gray-600"><%= question %></span>
|
|
7
|
+
<span class="shrink-0 font-semibold text-gray-900"><%= answer %></span>
|
|
8
|
+
</li>
|
|
9
|
+
<% end %>
|
|
10
|
+
</ul>
|
|
11
|
+
</div>
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
<div class="text-center">
|
|
2
|
+
<span class="inline-block mt-5 px-4 py-1.5 rounded-full text-sm font-semibold text-white <%= tone %>"><%= band["name"] %></span>
|
|
3
|
+
<% if band["description"].present? %>
|
|
4
|
+
<p class="text-gray-600 leading-relaxed max-w-lg mx-auto mt-4"><%= band["description"] %></p>
|
|
5
|
+
<% end %>
|
|
6
|
+
</div>
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
<div>
|
|
2
|
+
<h2 class="text-xs font-semibold uppercase tracking-wider text-gray-500 mb-4"><%= heading %></h2>
|
|
3
|
+
<% shares.each do |name, share| %>
|
|
4
|
+
<div class="flex items-center gap-3 mb-2.5">
|
|
5
|
+
<span class="text-sm text-gray-600 w-44 shrink-0"><%= name %></span>
|
|
6
|
+
<span class="flex-1 h-2 bg-gray-100 rounded-full overflow-hidden">
|
|
7
|
+
<span class="block h-full rounded-full <%= alembic_tone(share) %>" style="width:<%= [ share.to_i, 4 ].max %>%"></span>
|
|
8
|
+
</span>
|
|
9
|
+
</div>
|
|
10
|
+
<% end %>
|
|
11
|
+
</div>
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
<%= ui_panel(padding: :lg) do %>
|
|
2
|
+
<h2 class="text-xl font-semibold text-gray-900 mb-2"><%= heading %></h2>
|
|
3
|
+
<% if blurb.present? %>
|
|
4
|
+
<p class="text-gray-600 mb-5"><%= blurb %></p>
|
|
5
|
+
<% end %>
|
|
6
|
+
<%= form_with url: address, method: :post, class: "flex flex-col sm:flex-row gap-3" do %>
|
|
7
|
+
<%= render Alembic.lead_fields_partial if Alembic.lead_fields_partial %>
|
|
8
|
+
<%= hidden_field_tag "slug", slug %>
|
|
9
|
+
<%= hidden_field_tag "note", note %>
|
|
10
|
+
<div class="flex-1">
|
|
11
|
+
<%= ui_input(name: "email", type: :email, placeholder: placeholder) %>
|
|
12
|
+
</div>
|
|
13
|
+
<button type="submit" class="inline-flex items-center justify-center font-semibold rounded-lg bg-accent-600 text-white hover:bg-accent-500 px-6 py-3 cursor-pointer whitespace-nowrap"><%= button %></button>
|
|
14
|
+
<% end %>
|
|
15
|
+
<% end %>
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
<div class="text-center">
|
|
2
|
+
<p class="text-xs font-semibold uppercase tracking-widest text-accent-600 mb-4"><%= kicker %></p>
|
|
3
|
+
<div class="text-7xl md:text-8xl font-bold tracking-tight text-gray-900"><%= value.nil? ? "—" : "#{value}%" %></div>
|
|
4
|
+
<% if caption.present? %>
|
|
5
|
+
<p class="text-sm text-gray-500 mt-1"><%= caption %></p>
|
|
6
|
+
<% end %>
|
|
7
|
+
</div>
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
<div>
|
|
2
|
+
<h2 class="text-xs font-semibold uppercase tracking-wider text-gray-500 mb-4"><%= heading %></h2>
|
|
3
|
+
<div class="space-y-4">
|
|
4
|
+
<% categories.each do |category| %>
|
|
5
|
+
<%= ui_panel(padding: :lg) do %>
|
|
6
|
+
<h3 class="text-lg font-semibold text-gray-900 mb-1.5"><%= category["name"] %></h3>
|
|
7
|
+
<p class="text-gray-700 mb-2"><%= category["miss"] %></p>
|
|
8
|
+
<p class="text-sm text-accent-700"><span class="font-semibold"><%= cost_label %></span> <%= category["cost"] %></p>
|
|
9
|
+
<% end %>
|
|
10
|
+
<% end %>
|
|
11
|
+
</div>
|
|
12
|
+
</div>
|
|
@@ -11,22 +11,28 @@
|
|
|
11
11
|
|
|
12
12
|
<% if @outputs.any? %>
|
|
13
13
|
<%= ui_section do %>
|
|
14
|
-
|
|
14
|
+
<div class="space-y-10">
|
|
15
15
|
<% @outputs.each do |output| %>
|
|
16
16
|
<div data-output="<%= output.id %>">
|
|
17
|
-
<%=
|
|
17
|
+
<%= alembic_default_result(output, @outputs) %>
|
|
18
18
|
</div>
|
|
19
19
|
<% end %>
|
|
20
|
-
|
|
20
|
+
</div>
|
|
21
|
+
<% end %>
|
|
22
|
+
<% end %>
|
|
23
|
+
|
|
24
|
+
<% if Alembic.lead_address %>
|
|
25
|
+
<%= ui_section do %>
|
|
26
|
+
<%= alembic_lead_block(slug: summary_values["slug"], note: summary_values["note"]) %>
|
|
21
27
|
<% end %>
|
|
22
28
|
<% end %>
|
|
23
29
|
|
|
24
30
|
<%= ui_section(title: @outputs.any? ? "What you told us" : nil) do %>
|
|
25
|
-
<ul class="divide-y divide-
|
|
31
|
+
<ul class="divide-y divide-(color:--ks-color-divider) border-y border-(color:--ks-color-divider) dark:divide-(color:--ks-color-divider-dark) dark:border-(color:--ks-color-divider-dark)">
|
|
26
32
|
<% @answered.each do |step, value| %>
|
|
27
33
|
<li data-answer="<%= step %>" class="flex items-baseline justify-between gap-6 py-3">
|
|
28
|
-
<span class="
|
|
29
|
-
<span class="shrink-0 font-medium
|
|
34
|
+
<span class="ks-tone-muted"><%= @guide.question_text(step) %></span>
|
|
35
|
+
<span class="shrink-0 font-(weight:--ks-font-weight-medium) ks-tone-neutral"><%= @guide.choice_label(step, value) %></span>
|
|
30
36
|
</li>
|
|
31
37
|
<% end %>
|
|
32
38
|
</ul>
|
|
@@ -1,16 +1,16 @@
|
|
|
1
|
-
<% content_for(:title, @
|
|
1
|
+
<% content_for(:title, @flow.title.presence || @flow.slug) %>
|
|
2
2
|
|
|
3
3
|
<%= ui_page(max_width: :md) do %>
|
|
4
|
-
<%= ui_page_header(title: @
|
|
4
|
+
<%= ui_page_header(title: @flow.title.presence || @flow.slug, subtitle: flow_summary(@flow)) %>
|
|
5
5
|
|
|
6
6
|
<%= ui_section do %>
|
|
7
7
|
<div class="flex flex-wrap items-center gap-3">
|
|
8
|
-
<% if @
|
|
9
|
-
<%= ui_form(action: alembic.flow_runs_path(@
|
|
10
|
-
<%= ui_button(label: @
|
|
8
|
+
<% if @flow.each_step? && @flow.definition.present? && !previewing? %>
|
|
9
|
+
<%= ui_form(action: alembic.flow_runs_path(@flow.slug), method: :post) do %>
|
|
10
|
+
<%= ui_button(label: @flow.start_label.presence || "Start", type: :submit) %>
|
|
11
11
|
<% end %>
|
|
12
12
|
<% else %>
|
|
13
|
-
<%= ui_button(label: @
|
|
13
|
+
<%= ui_button(label: @flow.start_label.presence || "Start", href: first_step_path(@flow.slug)) %>
|
|
14
14
|
<% end %>
|
|
15
15
|
</div>
|
|
16
16
|
<% end %>
|
|
@@ -1,24 +1,30 @@
|
|
|
1
1
|
<%= ui_page(max_width: :lg) do %>
|
|
2
2
|
<p class="mb-4">
|
|
3
|
-
<%= link_to "← Back to the flow",
|
|
3
|
+
<%= link_to "← Back to the flow", easy_flow.manage_flow_path(@flow), class: "text-sm text-(color:--ks-color-link) hover:text-(color:--ks-color-link-hover) dark:text-(color:--ks-color-link-dark) dark:hover:text-(color:--ks-color-link-hover-dark)" %>
|
|
4
4
|
</p>
|
|
5
5
|
|
|
6
|
-
<%= ui_form_page(title: "Edit details", back_url:
|
|
6
|
+
<%= ui_form_page(title: "Edit details", back_url: easy_flow.manage_flow_path(@flow)) %>
|
|
7
7
|
|
|
8
|
-
<%= ui_form(action:
|
|
8
|
+
<%= ui_form(action: easy_flow.manage_flow_path(@flow), method: :patch) do %>
|
|
9
9
|
<%= ui_section(title: "How this is introduced") do %>
|
|
10
|
-
<label class="
|
|
11
|
-
<%= ui_input(name: "flow[title]", value: @
|
|
10
|
+
<label class="ks-label mb-1">Title</label>
|
|
11
|
+
<%= ui_input(name: "flow[title]", value: @flow.title) %>
|
|
12
12
|
|
|
13
|
-
<label class="
|
|
14
|
-
<%= ui_textarea(name: "flow[summary]", value: @
|
|
13
|
+
<label class="ks-label mb-1 mt-4">Summary</label>
|
|
14
|
+
<%= ui_textarea(name: "flow[summary]", value: @summary, rows: 4) %>
|
|
15
15
|
|
|
16
|
-
<label class="
|
|
17
|
-
<%= ui_input(name: "flow[start_label]", value: @
|
|
16
|
+
<label class="ks-label mb-1 mt-4">Start label</label>
|
|
17
|
+
<%= ui_input(name: "flow[start_label]", value: @flow.start_label) %>
|
|
18
|
+
<% end %>
|
|
19
|
+
|
|
20
|
+
<%= ui_section(title: "Where this finishes") do %>
|
|
21
|
+
<%= ui_select(name: "flow[summary_page_id]", selected: @summary_page&.id,
|
|
22
|
+
include_blank: "Alembic's default summary page",
|
|
23
|
+
options: @published_pages.map { |page| [ page.name, page.id ] }) %>
|
|
18
24
|
<% end %>
|
|
19
25
|
|
|
20
26
|
<%= ui_section(title: "What this keeps of a run") do %>
|
|
21
|
-
<%= ui_select(name: "flow[persists]", selected: @
|
|
27
|
+
<%= ui_select(name: "flow[persists]", selected: @flow.persists,
|
|
22
28
|
options: [ [ "Nothing", "unsaved" ],
|
|
23
29
|
[ "Every answer as it is given", "each_step" ],
|
|
24
30
|
[ "The whole run once it finishes", "on_finish" ] ]) %>
|
|
@@ -1 +1 @@
|
|
|
1
|
-
<%=
|
|
1
|
+
<%= shown_block(block) %>
|
|
@@ -11,9 +11,12 @@
|
|
|
11
11
|
|
|
12
12
|
<%= ui_section(title: "Create a page") do %>
|
|
13
13
|
<%= ui_form(action: alembic.manage_pages_path, method: :post) do %>
|
|
14
|
-
<label class="
|
|
14
|
+
<label class="ks-label mb-1">Name</label>
|
|
15
15
|
<%= ui_input(name: "page[name]", placeholder: "e.g. Welcome") %>
|
|
16
16
|
|
|
17
|
+
<label class="ks-label mb-1">Address</label>
|
|
18
|
+
<%= ui_input(name: "page[slug]", placeholder: "e.g. welcome") %>
|
|
19
|
+
|
|
17
20
|
<%= ui_button(label: "Create", type: :submit, variant: :secondary) %>
|
|
18
21
|
<% end %>
|
|
19
22
|
<% end %>
|
|
@@ -4,7 +4,13 @@
|
|
|
4
4
|
<%= javascript_include_tag "alembic/page_builder", defer: true %>
|
|
5
5
|
<% end %>
|
|
6
6
|
|
|
7
|
-
<%=
|
|
7
|
+
<%= ui_form(action: alembic.publish_manage_page_path(@page), method: :post) do %>
|
|
8
|
+
<%= ui_button(label: "Publish", type: :submit, variant: :secondary) %>
|
|
9
|
+
<% end %>
|
|
10
|
+
|
|
11
|
+
<%= ui_panel do %>
|
|
12
|
+
<%= react_ui("alembic/page-builder", @payload.merge(token: form_authenticity_token)) %>
|
|
13
|
+
<% end %>
|
|
8
14
|
|
|
9
15
|
<%= block_contents(@page.blocks) do |block| %>
|
|
10
16
|
<%= render "alembic/manage/pages/block_content", block: block %>
|
data/config/routes.rb
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
Alembic::Engine.routes.draw do
|
|
2
2
|
namespace :manage do
|
|
3
3
|
resources :pages, only: [ :index, :create, :show ] do
|
|
4
|
+
post "publish", on: :member
|
|
4
5
|
get "layout", to: "page_blocks#layout", as: :layout
|
|
5
6
|
post "blocks", to: "page_blocks#add_block", as: :blocks
|
|
6
7
|
patch "blocks", to: "page_blocks#place_blocks"
|
|
@@ -8,35 +9,23 @@ Alembic::Engine.routes.draw do
|
|
|
8
9
|
delete "blocks/:block_id", to: "page_blocks#remove_block", as: :block
|
|
9
10
|
end
|
|
10
11
|
|
|
11
|
-
resources :flows, only: [ :
|
|
12
|
-
resource :definition, only: [ :edit, :update ]
|
|
12
|
+
resources :flows, only: [ :edit, :update ] do
|
|
13
13
|
resource :preview, only: :show, controller: "previews" do
|
|
14
14
|
get :step
|
|
15
15
|
end
|
|
16
|
-
resources :versions, only: :index do
|
|
17
|
-
post :return, on: :member
|
|
18
|
-
end
|
|
19
|
-
|
|
20
|
-
resource :canvas, only: :show, controller: "canvas" do
|
|
21
|
-
post "steps", action: :add_step
|
|
22
|
-
patch "steps/:step", action: :configure_step
|
|
23
|
-
delete "steps/:step", action: :remove_step
|
|
24
|
-
patch "steps/:step/move", action: :move_step
|
|
25
|
-
post "versions", action: :create
|
|
26
|
-
post "publish", action: :publish
|
|
27
|
-
patch "details", action: :details
|
|
28
|
-
post "undo", action: :undo
|
|
29
|
-
post "redo", action: :redo
|
|
30
|
-
post "edges", action: :connect
|
|
31
|
-
delete "edges", action: :disconnect
|
|
32
|
-
end
|
|
33
16
|
end
|
|
34
17
|
end
|
|
35
18
|
|
|
19
|
+
constraints(->(request) { request.path_info.match?(%r{\A/manage/flows(/|\z)}) }) do
|
|
20
|
+
mount EasyFlow::Engine, at: "/", defaults: { easy_flow_host: Alembic::FLOW_HOST.to_s }
|
|
21
|
+
end
|
|
22
|
+
|
|
36
23
|
post ":slug/runs", to: "flows#start", as: :flow_runs
|
|
37
24
|
get "runs/:id", to: "flows#step", as: :run
|
|
38
25
|
patch "runs/:id", to: "flows#update"
|
|
39
26
|
|
|
27
|
+
get "pages/:slug", to: "pages#show", as: :page
|
|
28
|
+
|
|
40
29
|
get ":slug", to: "flows#show", as: :flow
|
|
41
30
|
get ":slug/step", to: "flows#step", as: :flow_step
|
|
42
31
|
end
|
|
@@ -1,5 +1,25 @@
|
|
|
1
1
|
class RemovePublishedVersionFromAlembicDiagnostics < ActiveRecord::Migration[8.1]
|
|
2
|
-
|
|
2
|
+
class Diagnostic < ActiveRecord::Base
|
|
3
|
+
self.table_name = "alembic_diagnostics"
|
|
4
|
+
end
|
|
5
|
+
|
|
6
|
+
class DefinitionVersion < ActiveRecord::Base
|
|
7
|
+
self.table_name = "alembic_definition_versions"
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def up
|
|
11
|
+
[ Diagnostic, DefinitionVersion ].each(&:reset_column_information)
|
|
12
|
+
DefinitionVersion.where(id: Diagnostic.where.not(published_version_id: nil).select(:published_version_id)).update_all(status: "live")
|
|
13
|
+
|
|
3
14
|
remove_reference :alembic_diagnostics, :published_version, foreign_key: { to_table: :alembic_definition_versions }
|
|
4
15
|
end
|
|
16
|
+
|
|
17
|
+
def down
|
|
18
|
+
add_reference :alembic_diagnostics, :published_version, foreign_key: { to_table: :alembic_definition_versions }
|
|
19
|
+
|
|
20
|
+
[ Diagnostic, DefinitionVersion ].each(&:reset_column_information)
|
|
21
|
+
DefinitionVersion.where(status: "live").find_each do |version|
|
|
22
|
+
Diagnostic.where(id: version.diagnostic_id).update_all(published_version_id: version.id)
|
|
23
|
+
end
|
|
24
|
+
end
|
|
5
25
|
end
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
class CreateAlembicPageVersions < ActiveRecord::Migration[8.1]
|
|
2
|
+
def change
|
|
3
|
+
create_table :alembic_page_versions do |t|
|
|
4
|
+
t.references :page, null: false, foreign_key: { to_table: :alembic_pages }
|
|
5
|
+
t.integer :number, null: false
|
|
6
|
+
t.json :blocks, default: [], null: false
|
|
7
|
+
t.string :status, null: false, default: "draft"
|
|
8
|
+
|
|
9
|
+
t.timestamps
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
add_index :alembic_page_versions, [ :page_id, :number ], unique: true
|
|
13
|
+
add_index :alembic_page_versions, :page_id, unique: true, where: "status = 'live'",
|
|
14
|
+
name: "index_alembic_page_versions_on_one_live_per_page"
|
|
15
|
+
end
|
|
16
|
+
end
|
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
class MoveFlowsOntoEasyFlow < ActiveRecord::Migration[8.1]
|
|
2
|
+
HOST = "alembic"
|
|
3
|
+
FLOW_COLUMNS = %w[slug title start_label kind status persists document definition_cursor
|
|
4
|
+
changes_since_version undo_history undone_changes created_at updated_at].freeze
|
|
5
|
+
|
|
6
|
+
class OldFlow < ActiveRecord::Base
|
|
7
|
+
self.table_name = "alembic_flows"
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
class Definition < ActiveRecord::Base
|
|
11
|
+
self.table_name = "easy_flow_definitions"
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
class OldVersion < ActiveRecord::Base
|
|
15
|
+
self.table_name = "alembic_flow_versions"
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
class Version < ActiveRecord::Base
|
|
19
|
+
self.table_name = "easy_flow_versions"
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
class OldRun < ActiveRecord::Base
|
|
23
|
+
self.table_name = "alembic_flow_runs"
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
class Run < ActiveRecord::Base
|
|
27
|
+
self.table_name = "easy_flow_runs"
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
class SummaryVersion < ActiveRecord::Base
|
|
31
|
+
self.table_name = "alembic_flow_summaries"
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
class DefinitionSummary < ActiveRecord::Base
|
|
35
|
+
self.table_name = "alembic_flow_definition_summaries"
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
class RunSummary < ActiveRecord::Base
|
|
39
|
+
self.table_name = "alembic_flow_run_summaries"
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def up
|
|
43
|
+
[ OldFlow, Definition, OldVersion, Version, OldRun, Run, SummaryVersion ].each(&:reset_column_information)
|
|
44
|
+
flows = copy_flows
|
|
45
|
+
versions = copy_versions(flows)
|
|
46
|
+
runs = copy_runs(flows, versions)
|
|
47
|
+
summaries = OldFlow.pluck(:id, :summary, :summary_cursor)
|
|
48
|
+
pins = OldRun.where.not(summary_version_id: nil).pluck(:id, :summary_version_id)
|
|
49
|
+
|
|
50
|
+
drop_table :alembic_flow_runs
|
|
51
|
+
remove_foreign_key :alembic_flow_summaries, column: :flow_id
|
|
52
|
+
repoint_summary_versions(flows)
|
|
53
|
+
drop_table :alembic_flow_versions
|
|
54
|
+
drop_table :alembic_flows
|
|
55
|
+
add_foreign_key :alembic_flow_summaries, :easy_flow_definitions, column: :flow_id, on_delete: :cascade
|
|
56
|
+
|
|
57
|
+
create_table :alembic_flow_definition_summaries do |t|
|
|
58
|
+
t.references :flow, null: false, index: { unique: true },
|
|
59
|
+
foreign_key: { to_table: :easy_flow_definitions, on_delete: :cascade }
|
|
60
|
+
t.text :summary
|
|
61
|
+
t.integer :summary_cursor
|
|
62
|
+
t.timestamps
|
|
63
|
+
end
|
|
64
|
+
restore_summaries(summaries, flows)
|
|
65
|
+
|
|
66
|
+
create_table :alembic_flow_run_summaries do |t|
|
|
67
|
+
t.references :run, null: false, index: { unique: true },
|
|
68
|
+
foreign_key: { to_table: :easy_flow_runs, on_delete: :cascade }
|
|
69
|
+
t.references :summary_version, null: false,
|
|
70
|
+
foreign_key: { to_table: :alembic_flow_summaries, on_delete: :cascade }
|
|
71
|
+
t.timestamps
|
|
72
|
+
end
|
|
73
|
+
restore_pins(pins, runs)
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
def down
|
|
77
|
+
drop_table :alembic_flow_run_summaries
|
|
78
|
+
drop_table :alembic_flow_definition_summaries
|
|
79
|
+
remove_foreign_key :alembic_flow_summaries, column: :flow_id
|
|
80
|
+
execute "DELETE FROM alembic_flow_summaries"
|
|
81
|
+
|
|
82
|
+
create_table :alembic_flows do |t|
|
|
83
|
+
t.string :slug
|
|
84
|
+
t.string :title
|
|
85
|
+
t.text :summary
|
|
86
|
+
t.string :start_label
|
|
87
|
+
t.string :kind
|
|
88
|
+
t.string :status, null: false, default: "active"
|
|
89
|
+
t.string :persists, null: false, default: "unsaved"
|
|
90
|
+
t.json :document
|
|
91
|
+
t.integer :definition_cursor
|
|
92
|
+
t.integer :summary_cursor
|
|
93
|
+
t.json :changes_since_version
|
|
94
|
+
t.json :undo_history
|
|
95
|
+
t.json :undone_changes
|
|
96
|
+
t.timestamps
|
|
97
|
+
end
|
|
98
|
+
add_index :alembic_flows, :slug, unique: true
|
|
99
|
+
|
|
100
|
+
create_table :alembic_flow_versions do |t|
|
|
101
|
+
t.references :flow, null: false, foreign_key: { to_table: :alembic_flows }
|
|
102
|
+
t.integer :number, null: false
|
|
103
|
+
t.json :definition
|
|
104
|
+
t.json :changes_captured
|
|
105
|
+
t.string :status, null: false, default: "draft"
|
|
106
|
+
t.datetime :created_at, null: false
|
|
107
|
+
end
|
|
108
|
+
add_index :alembic_flow_versions, [ :flow_id, :number ], unique: true
|
|
109
|
+
add_index :alembic_flow_versions, :flow_id, unique: true, where: "status = 'live'",
|
|
110
|
+
name: "index_alembic_flow_versions_on_one_live_per_flow"
|
|
111
|
+
|
|
112
|
+
add_foreign_key :alembic_flow_summaries, :alembic_flows, column: :flow_id
|
|
113
|
+
|
|
114
|
+
create_table :alembic_flow_runs do |t|
|
|
115
|
+
t.references :flow, null: false, foreign_key: { to_table: :alembic_flows }
|
|
116
|
+
t.references :definition_version, null: false, foreign_key: { to_table: :alembic_flow_versions }
|
|
117
|
+
t.references :summary_version, foreign_key: { to_table: :alembic_flow_summaries }
|
|
118
|
+
t.references :owner, polymorphic: true
|
|
119
|
+
t.json :recorded
|
|
120
|
+
t.string :label
|
|
121
|
+
t.string :status
|
|
122
|
+
t.timestamps
|
|
123
|
+
end
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
private
|
|
127
|
+
|
|
128
|
+
def copy_flows
|
|
129
|
+
OldFlow.order(:id).to_h do |flow|
|
|
130
|
+
[ flow.id, Definition.create!(flow.attributes.slice(*FLOW_COLUMNS).merge("host" => HOST)).id ]
|
|
131
|
+
end
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
def copy_versions(flows)
|
|
135
|
+
OldVersion.order(:id).to_h do |version|
|
|
136
|
+
copied = version.attributes.slice("number", "definition", "changes_captured", "status", "created_at")
|
|
137
|
+
[ version.id, Version.create!(copied.merge("flow_id" => flows.fetch(version.flow_id))).id ]
|
|
138
|
+
end
|
|
139
|
+
end
|
|
140
|
+
|
|
141
|
+
def copy_runs(flows, versions)
|
|
142
|
+
OldRun.order(:id).to_h do |run|
|
|
143
|
+
copied = run.attributes.slice("owner_type", "owner_id", "recorded", "label", "status", "created_at", "updated_at")
|
|
144
|
+
moved = copied.merge("flow_id" => flows.fetch(run.flow_id), "definition_version_id" => versions.fetch(run.definition_version_id))
|
|
145
|
+
[ run.id, Run.create!(moved).id ]
|
|
146
|
+
end
|
|
147
|
+
end
|
|
148
|
+
|
|
149
|
+
def restore_summaries(summaries, flows)
|
|
150
|
+
DefinitionSummary.reset_column_information
|
|
151
|
+
summaries.each do |flow_id, summary, cursor|
|
|
152
|
+
next if summary.nil? && cursor.nil?
|
|
153
|
+
|
|
154
|
+
DefinitionSummary.create!(flow_id: flows.fetch(flow_id), summary: summary, summary_cursor: cursor)
|
|
155
|
+
end
|
|
156
|
+
end
|
|
157
|
+
|
|
158
|
+
def restore_pins(pins, runs)
|
|
159
|
+
RunSummary.reset_column_information
|
|
160
|
+
pins.each { |run_id, summary_version_id| RunSummary.create!(run_id: runs.fetch(run_id), summary_version_id: summary_version_id) }
|
|
161
|
+
end
|
|
162
|
+
|
|
163
|
+
def repoint_summary_versions(flows)
|
|
164
|
+
SummaryVersion.find_each { |version| version.update_columns(flow_id: flows.fetch(version.flow_id)) }
|
|
165
|
+
end
|
|
166
|
+
end
|
data/lib/alembic/engine.rb
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
require "alembic/leftover_stylesheet"
|
|
2
2
|
require "keystone_ui-blocks"
|
|
3
3
|
require "keystone_ui-react"
|
|
4
|
+
require "easy_flow"
|
|
4
5
|
|
|
5
6
|
module Alembic
|
|
6
7
|
class Engine < ::Rails::Engine
|
|
@@ -19,18 +20,8 @@ module Alembic
|
|
|
19
20
|
KeystoneUi.configuration.tailwind_sources << root.join("app/assets/builds/alembic/*.js").to_s
|
|
20
21
|
end
|
|
21
22
|
|
|
22
|
-
initializer "alembic.
|
|
23
|
+
initializer "alembic.output_types" do |app|
|
|
23
24
|
app.config.to_prepare do
|
|
24
|
-
Alembic::Flow::Start.register
|
|
25
|
-
Alembic::Flow::Terminal.register
|
|
26
|
-
|
|
27
|
-
Alembic::Steps::Question.register
|
|
28
|
-
Alembic::Flow::Condition.register
|
|
29
|
-
Alembic::Flow::Switch.register
|
|
30
|
-
|
|
31
|
-
Alembic::Flow.check(:unrouted_value)
|
|
32
|
-
Alembic::Flow.check(:unfollowed_path)
|
|
33
|
-
Alembic::Flow.check(:dead_end)
|
|
34
25
|
Alembic::Outputs::WeightedSum.register
|
|
35
26
|
Alembic::Outputs::Percentage.register
|
|
36
27
|
Alembic::Outputs::Grouped.register
|
|
@@ -39,5 +30,9 @@ module Alembic
|
|
|
39
30
|
Alembic::Outputs::Band.register
|
|
40
31
|
end
|
|
41
32
|
end
|
|
33
|
+
|
|
34
|
+
initializer "alembic.result_blocks" do |app|
|
|
35
|
+
app.config.to_prepare { Alembic::ResultBlocks.register }
|
|
36
|
+
end
|
|
42
37
|
end
|
|
43
38
|
end
|
data/lib/alembic/version.rb
CHANGED