diff --git a/app/controllers/bubbles/stage_pickers_controller.rb b/app/controllers/bubbles/stage_pickers_controller.rb
new file mode 100644
index 000000000..3e7c0d25d
--- /dev/null
+++ b/app/controllers/bubbles/stage_pickers_controller.rb
@@ -0,0 +1,21 @@
+class Bubbles::StagePickersController < ApplicationController
+ include BubbleScoped, BucketScoped
+
+ before_action :set_workflows, :set_selected_workflow
+
+ def new
+ end
+
+ private
+ def set_workflows
+ @workflows = Current.account.workflows
+ end
+
+ def set_selected_workflow
+ @selected_workflow = if params[:workflow_id]
+ @workflows.find params[:workflow_id]
+ else
+ @bubble.workflow || @workflows.first
+ end
+ end
+end
diff --git a/app/controllers/bubbles/stagings_controller.rb b/app/controllers/bubbles/stagings_controller.rb
new file mode 100644
index 000000000..3a17b169c
--- /dev/null
+++ b/app/controllers/bubbles/stagings_controller.rb
@@ -0,0 +1,8 @@
+class Bubbles::StagingsController < ApplicationController
+ include BubbleScoped, BucketScoped
+
+ def create
+ @bubble.toggle_stage Current.account.stages.find(params[:stage_id])
+ redirect_to new_bucket_bubble_stage_picker_path(@bucket, @bubble)
+ end
+end
diff --git a/app/controllers/concerns/.keep b/app/controllers/concerns/.keep
deleted file mode 100644
index e69de29bb..000000000
diff --git a/app/controllers/concerns/workflow_scoped.rb b/app/controllers/concerns/workflow_scoped.rb
new file mode 100644
index 000000000..ca2e7398c
--- /dev/null
+++ b/app/controllers/concerns/workflow_scoped.rb
@@ -0,0 +1,12 @@
+module WorkflowScoped
+ extend ActiveSupport::Concern
+
+ included do
+ before_action :set_workflow
+ end
+
+ private
+ def set_workflow
+ @workflow = Current.account.workflows.find params[:workflow_id]
+ end
+end
diff --git a/app/controllers/workflows/stages_controller.rb b/app/controllers/workflows/stages_controller.rb
new file mode 100644
index 000000000..d05ae61c4
--- /dev/null
+++ b/app/controllers/workflows/stages_controller.rb
@@ -0,0 +1,36 @@
+class Workflows::StagesController < ApplicationController
+ include WorkflowScoped
+
+ before_action :set_stage, only: %i[ edit update destroy ]
+
+ def new
+ @stage = @workflow.stages.new
+ end
+
+ def create
+ @stage = @workflow.stages.create! stage_params
+ redirect_to account_workflow_path(@workflow)
+ end
+
+ def edit
+ end
+
+ def update
+ @stage.update! stage_params
+ redirect_to account_workflow_path(@workflow)
+ end
+
+ def destroy
+ @stage.destroy
+ redirect_to account_workflow_path(@workflow)
+ end
+
+ private
+ def set_stage
+ @stage = @workflow.stages.find params[:id]
+ end
+
+ def stage_params
+ params.require(:workflow_stage).permit(:name)
+ end
+end
diff --git a/app/controllers/workflows_controller.rb b/app/controllers/workflows_controller.rb
new file mode 100644
index 000000000..95117f9b9
--- /dev/null
+++ b/app/controllers/workflows_controller.rb
@@ -0,0 +1,43 @@
+class WorkflowsController < ApplicationController
+ before_action :set_workflow, only: %i[ show edit update destroy ]
+
+ def index
+ @workflows = Current.account.workflows
+ end
+
+ def new
+ @workflow = Current.account.workflows.new
+ end
+
+ def create
+ @workflow = Current.account.workflows.create! workflow_params
+ # FIXME: this should definitely change.
+ %w[ Triage WIP On-hold ].each { |name| @workflow.stages.create! name: name }
+ redirect_to account_workflows_path
+ end
+
+ def show
+ end
+
+ def edit
+ end
+
+ def update
+ @workflow.update! workflow_params
+ redirect_to account_workflow_path(@workflow)
+ end
+
+ def destroy
+ @workflow.destroy
+ redirect_to account_workflows_path
+ end
+
+ private
+ def set_workflow
+ @workflow = Current.account.workflows.find params[:id]
+ end
+
+ def workflow_params
+ params.require(:workflow).permit(:name)
+ end
+end
diff --git a/app/helpers/workflows_helper.rb b/app/helpers/workflows_helper.rb
new file mode 100644
index 000000000..80297ce12
--- /dev/null
+++ b/app/helpers/workflows_helper.rb
@@ -0,0 +1,10 @@
+module WorkflowsHelper
+ def link_to_stage_picker(bubble, workflow)
+ link_to workflow.name, new_bucket_bubble_stage_picker_path(bubble.bucket, bubble, workflow_id: workflow.id)
+ end
+
+ def button_to_set_stage(bubble, stage)
+ button_to stage.name, bucket_bubble_stagings_path(bubble.bucket, bubble, stage_id: stage.id),
+ method: :post, class: [ "btn btn--small", { "fill-selected": stage == bubble.stage } ]
+ end
+end
diff --git a/app/models/account.rb b/app/models/account.rb
index ec9290b11..101c96210 100644
--- a/app/models/account.rb
+++ b/app/models/account.rb
@@ -6,5 +6,8 @@ class Account < ApplicationRecord
has_many :buckets, dependent: :destroy
has_many :bubbles, through: :buckets
+ has_many :workflows, dependent: :destroy
+ has_many :stages, through: :workflows, class_name: "Workflow::Stage"
+
has_many :tags, dependent: :destroy
end
diff --git a/app/models/bubble.rb b/app/models/bubble.rb
index e2281f617..3f7345469 100644
--- a/app/models/bubble.rb
+++ b/app/models/bubble.rb
@@ -1,5 +1,5 @@
class Bubble < ApplicationRecord
- include Assignable, Boostable, Colored, Commentable, Eventable, Poppable, Searchable, Taggable, Threaded
+ include Assignable, Boostable, Colored, Commentable, Eventable, Poppable, Searchable, Staged, Taggable, Threaded
belongs_to :bucket
belongs_to :creator, class_name: "User", default: -> { Current.user }
diff --git a/app/models/bubble/staged.rb b/app/models/bubble/staged.rb
new file mode 100644
index 000000000..39e94f632
--- /dev/null
+++ b/app/models/bubble/staged.rb
@@ -0,0 +1,21 @@
+module Bubble::Staged
+ extend ActiveSupport::Concern
+
+ included do
+ belongs_to :stage, class_name: "Workflow::Stage", optional: true
+ end
+
+ def workflow
+ stage&.workflow
+ end
+
+ def toggle_stage(stage)
+ if self.stage == stage
+ update! stage: nil
+ track_event :unstaged, stage_id: stage.id
+ else
+ update! stage: stage
+ track_event :staged, stage_id: stage.id
+ end
+ end
+end
diff --git a/app/models/bubble/thread/rollup.rb b/app/models/bubble/thread/rollup.rb
index dd034aa8b..daa25c32b 100644
--- a/app/models/bubble/thread/rollup.rb
+++ b/app/models/bubble/thread/rollup.rb
@@ -25,9 +25,10 @@ class Bubble::Thread::Rollup
def sorted_entries
entries.sort_by do |entry|
case entry.action
- when "created" then [ 1, entry.created_at ]
- when "assigned" then [ 2, entry.created_at ]
- when "boosted" then [ 3, entry.creator, entry.created_at ]
+ when "created" then [ 1, entry.created_at ]
+ when "assigned" then [ 2, entry.created_at ]
+ when "staged", "unstaged" then [ 3, entry.created_at ]
+ when "boosted" then [ 4, entry.creator, entry.created_at ]
end
end
end
@@ -41,9 +42,13 @@ class Bubble::Thread::Rollup
when "created"
"added by #{entry.creator.name} #{time_ago_in_words(entry.created_at)} ago"
when "assigned"
- summary = "assigned to #{entry.assignee_names.to_sentence}"
+ summary = "assigned to #{entry.assignees.map(&:name).to_sentence}"
summary += " #{time_ago_in_words(entry.created_at)} ago" unless first_position?
summary
+ when "staged"
+ "#{entry.creator.name} moved this to '#{entry.stage.name}'"
+ when "unstaged"
+ "#{entry.creator.name} removed this from '#{entry.stage.name}'"
when "boosted"
"#{entry.creator.name} +#{chunk_size}"
end
diff --git a/app/models/event.rb b/app/models/event.rb
index 119d871ac..7946e79fe 100644
--- a/app/models/event.rb
+++ b/app/models/event.rb
@@ -1,7 +1,7 @@
class Event < ApplicationRecord
- THREADABLE_ACTIONS = %w[ assigned boosted created ]
+ THREADABLE_ACTIONS = %w[ assigned boosted created staged unstaged ]
- include Assignments
+ include Assignments, Stages
belongs_to :creator, class_name: "User"
belongs_to :bubble, touch: true
diff --git a/app/models/event/assignments.rb b/app/models/event/assignments.rb
index 1daedbf9f..56a6b9e6e 100644
--- a/app/models/event/assignments.rb
+++ b/app/models/event/assignments.rb
@@ -5,12 +5,7 @@ module Event::Assignments
store_accessor :particulars, :assignee_ids
end
- def assignee_names
- assignees.map &:name
+ def assignees
+ @assignees ||= account.users.where id: assignee_ids
end
-
- private
- def assignees
- @assignees ||= account.users.where id: assignee_ids
- end
end
diff --git a/app/models/event/stages.rb b/app/models/event/stages.rb
new file mode 100644
index 000000000..65b20e3ad
--- /dev/null
+++ b/app/models/event/stages.rb
@@ -0,0 +1,11 @@
+module Event::Stages
+ extend ActiveSupport::Concern
+
+ included do
+ store_accessor :particulars, :stage_id
+ end
+
+ def stage
+ @stage ||= account.stages.find_by_id stage_id
+ end
+end
diff --git a/app/models/workflow.rb b/app/models/workflow.rb
new file mode 100644
index 000000000..164d3eb47
--- /dev/null
+++ b/app/models/workflow.rb
@@ -0,0 +1,4 @@
+class Workflow < ApplicationRecord
+ belongs_to :account
+ has_many :stages, dependent: :delete_all
+end
diff --git a/app/models/workflow/stage.rb b/app/models/workflow/stage.rb
new file mode 100644
index 000000000..9eb7ef1d0
--- /dev/null
+++ b/app/models/workflow/stage.rb
@@ -0,0 +1,3 @@
+class Workflow::Stage < ApplicationRecord
+ belongs_to :workflow
+end
diff --git a/app/views/accounts/users/index.html.erb b/app/views/accounts/users/index.html.erb
index dea54bb15..1c707e96c 100644
--- a/app/views/accounts/users/index.html.erb
+++ b/app/views/accounts/users/index.html.erb
@@ -21,3 +21,8 @@
<%= render partial: "accounts/users/user", collection: @users %>
+
+
+
Workflows
+ <%= turbo_frame_tag :workflows, src: account_workflows_path %>
+
diff --git a/app/views/bubbles/_pop_toggle.html.erb b/app/views/bubbles/_pop_toggle.html.erb
new file mode 100644
index 000000000..146ea5aee
--- /dev/null
+++ b/app/views/bubbles/_pop_toggle.html.erb
@@ -0,0 +1,11 @@
+<% if bubble.popped? %>
+ <%= button_to bucket_bubble_pop_path(bubble.bucket, bubble), method: :delete, class: "btn" do %>
+ <%= image_tag "pop.svg", aria: { hidden: true }, size: 24 %>
+ Un-pop
+ <% end %>
+<% else %>
+ <%= button_to bucket_bubble_pop_path(bubble.bucket, bubble), class: "btn" do %>
+ <%= image_tag "pop.svg", aria: { hidden: true }, size: 24 %>
+ Pop
+ <% end %>
+<% end %>
diff --git a/app/views/bubbles/filters/_bucket_view_form.html.erb b/app/views/bubbles/filters/_bucket_view_form.html.erb
index 56d911e9b..a910a6fb9 100644
--- a/app/views/bubbles/filters/_bucket_view_form.html.erb
+++ b/app/views/bubbles/filters/_bucket_view_form.html.erb
@@ -18,8 +18,8 @@
Update
<% end %>
- <%= button_tag type: :submit, form: dom_id(view, :delete_form), class: "btn", style: "font-size: 0.4em;" do %>
- <%= image_tag "alert.svg", aria: { hidden: true }, size: 24 %>
+ <%= button_tag type: :submit, form: dom_id(view, :delete_form), class: "btn", style: "font-size: 0.4em;", data: { turbo_confirm: "Are you sure you want to delete this filter?" } do %>
+ <%= image_tag "minus.svg", aria: { hidden: true }, size: 24 %>
Delete
<% end %>
<% end %>
diff --git a/app/views/bubbles/show.html.erb b/app/views/bubbles/show.html.erb
index 9d320c4f7..a43755cd0 100644
--- a/app/views/bubbles/show.html.erb
+++ b/app/views/bubbles/show.html.erb
@@ -7,18 +7,11 @@
All Bubbles
<% end %>
- <% if @bubble.popped? %>
- <%= button_to bucket_bubble_pop_path(@bubble.bucket, @bubble), method: :delete, class: "btn" do %>
- <%= image_tag "pop.svg", aria: { hidden: true }, size: 24 %>
- Un-pop
- <% end %>
- <% else %>
- <%= button_to bucket_bubble_pop_path(@bubble.bucket, @bubble), class: "btn" do %>
- <%= image_tag "pop.svg", aria: { hidden: true }, size: 24 %>
- Pop
- <% end %>
- <% end %>
-
+
+ <%= render "bubbles/pop_toggle", bubble: @bubble %>
+ <%= turbo_frame_tag dom_id(@bubble, :stage_picker), src: new_bucket_bubble_stage_picker_path(@bubble.bucket, @bubble) %>
+
+
<% end %>
diff --git a/app/views/bubbles/stage_pickers/new.html.erb b/app/views/bubbles/stage_pickers/new.html.erb
new file mode 100644
index 000000000..a0ee840b1
--- /dev/null
+++ b/app/views/bubbles/stage_pickers/new.html.erb
@@ -0,0 +1,25 @@
+<%= turbo_frame_tag dom_id(@bubble, :stage_picker) do %>
+ <% if @selected_workflow %>
+
+
+
+
+
+
+
+
+
+ <% end %>
+<% end %>
diff --git a/app/views/workflows/_workflow.html.erb b/app/views/workflows/_workflow.html.erb
new file mode 100644
index 000000000..ab7f7272b
--- /dev/null
+++ b/app/views/workflows/_workflow.html.erb
@@ -0,0 +1,26 @@
+<%= turbo_frame_tag workflow do %>
+
+
+ <%= turbo_frame_tag dom_id(workflow, :header) do %>
+
<%= workflow.name %>
+
+
+ <%= link_to edit_account_workflow_path(workflow), class: "btn btn--small" do %>
+ <%= image_tag "pencil.svg", aria: { hidden: true }, size: 24 %>
+ <% end %>
+
+ <%= button_to account_workflow_path(workflow), method: :delete, class: "btn btn--small", data: { turbo_frame: :workflows, turbo_confirm: "Are you sure you want to delete this workflow?" } do %>
+ <%= image_tag "minus.svg", aria: { hidden: true }, size: 24 %>
+ <% end %>
+
+ <% end %>
+
+
+
+ <%= turbo_frame_tag dom_id(workflow, :stages) do %>
+ <%= render partial: "workflows/stages/stage", collection: workflow.stages %>
+ <%= link_to "New stage", new_account_workflow_stage_path(workflow), class: "btn btn--small" %>
+ <% end %>
+
+
+<% end %>
diff --git a/app/views/workflows/edit.html.erb b/app/views/workflows/edit.html.erb
new file mode 100644
index 000000000..292802c5b
--- /dev/null
+++ b/app/views/workflows/edit.html.erb
@@ -0,0 +1,17 @@
+<%= turbo_frame_tag dom_id(@workflow, :header) do %>
+ <%= form_with model: @workflow, url: account_workflow_path(@workflow) do |form| %>
+
+ <%= form.text_field :name, required: true, autofocus: true %>
+
+
+ <%= form.button type: :submit, class: "btn btn--small" do %>
+ <%= image_tag "check.svg", aria: { hidden: true }, size: 24 %>
+ <% end %>
+
+ <%= link_to account_workflow_path(@workflow), class: "btn btn--small", data: { turbo_frame: dom_id(@workflow), turbo_confirm: "Are you sure you want to delete this workflow?" } do %>
+ <%= image_tag "remove.svg", aria: { hidden: true }, size: 24 %>
+ <% end %>
+
+
+ <% end %>
+<% end %>
diff --git a/app/views/workflows/index.html.erb b/app/views/workflows/index.html.erb
new file mode 100644
index 000000000..31be2970c
--- /dev/null
+++ b/app/views/workflows/index.html.erb
@@ -0,0 +1,7 @@
+<%= turbo_frame_tag :workflows do %>
+
+ <%= render partial: "workflows/workflow", collection: @workflows %>
+
+
+ <%= link_to "New workflow", new_account_workflow_path, class: "btn" %>
+<% end %>
diff --git a/app/views/workflows/new.html.erb b/app/views/workflows/new.html.erb
new file mode 100644
index 000000000..7ebe61b49
--- /dev/null
+++ b/app/views/workflows/new.html.erb
@@ -0,0 +1,6 @@
+<%= turbo_frame_tag :workflows do %>
+ <%= form_with model: @workflow, url: account_workflows_path do |form| %>
+ <%= form.text_field :name, required: true, autofocus: true %>
+ <%= form.submit %>
+ <% end %>
+<% end %>
diff --git a/app/views/workflows/show.html.erb b/app/views/workflows/show.html.erb
new file mode 100644
index 000000000..17ccd8193
--- /dev/null
+++ b/app/views/workflows/show.html.erb
@@ -0,0 +1 @@
+<%= render "workflows/workflow", workflow: @workflow %>
diff --git a/app/views/workflows/stages/_stage.html.erb b/app/views/workflows/stages/_stage.html.erb
new file mode 100644
index 000000000..fb8119441
--- /dev/null
+++ b/app/views/workflows/stages/_stage.html.erb
@@ -0,0 +1,17 @@
+
+ <%= turbo_frame_tag stage do %>
+
<%= stage.name %>
+
+
+ <%= link_to edit_account_workflow_stage_path(stage.workflow, stage), class: "btn btn--small" do %>
+ <%= image_tag "pencil.svg", aria: { hidden: true }, size: 24 %>
+ <% end %>
+
+ <% if stage_counter >= 1 %>
+ <%= button_to account_workflow_stage_path(stage.workflow, stage), method: :delete, class: "btn btn--small", data: { turbo_frame: dom_id(stage.workflow), turbo_confirm: "Are you sure you want to delete this stage?" } do %>
+ <%= image_tag "minus.svg", aria: { hidden: true }, size: 24 %>
+ <% end %>
+ <% end %>
+
+ <% end %>
+
diff --git a/app/views/workflows/stages/edit.html.erb b/app/views/workflows/stages/edit.html.erb
new file mode 100644
index 000000000..5b7d7e259
--- /dev/null
+++ b/app/views/workflows/stages/edit.html.erb
@@ -0,0 +1,17 @@
+<%= turbo_frame_tag @stage do %>
+ <%= form_with model: @stage, url: account_workflow_stage_path(@stage.workflow, @stage) do |form| %>
+
+ <%= form.text_field :name, required: true, autofocus: true %>
+
+
+ <%= form.button type: :submit, class: "btn btn--small" do %>
+ <%= image_tag "check.svg", aria: { hidden: true }, size: 24 %>
+ <% end %>
+
+ <%= link_to account_workflow_path(@workflow), class: "btn btn--small", data: { turbo_frame: dom_id(@workflow), turbo_confirm: "Are you sure you want to delete this workflow?" } do %>
+ <%= image_tag "remove.svg", aria: { hidden: true }, size: 24 %>
+ <% end %>
+
+
+ <% end %>
+<% end %>
diff --git a/app/views/workflows/stages/new.html.erb b/app/views/workflows/stages/new.html.erb
new file mode 100644
index 000000000..4a479df4f
--- /dev/null
+++ b/app/views/workflows/stages/new.html.erb
@@ -0,0 +1,6 @@
+<%= turbo_frame_tag dom_id(@stage.workflow, :stages) do %>
+ <%= form_with model: @stage, url: account_workflow_stages_path(@stage.workflow) do |form| %>
+ <%= form.text_field :name, required: true, autofocus: true %>
+ <%= form.submit %>
+ <% end %>
+<% end %>
diff --git a/config/routes.rb b/config/routes.rb
index 4286d0fa8..a29ef9879 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -8,28 +8,30 @@ Rails.application.routes.draw do
end
end
+ resolve "Bubble" do |bubble, options|
+ route_for :bucket_bubble, bubble.bucket, bubble, options
+ end
+
resources :buckets do
- scope module: :buckets do
- resources :views
- end
-
resources :bubbles do
- scope module: :bubbles do
- resource :image
- resource :pop
- end
-
resources :assignments
resources :boosts
resources :comments
resources :tags, shallow: true
+
+ scope module: :bubbles do
+ resource :image
+ resource :pop
+ resource :stage_picker
+ resources :stagings
+ end
end
resources :tags, only: :index
- end
- resolve "Bubble" do |bubble, options|
- route_for :bucket_bubble, bubble.bucket, bubble, options
+ scope module: :buckets do
+ resources :views
+ end
end
resource :first_run
@@ -41,6 +43,10 @@ Rails.application.routes.draw do
end
end
+ resources :workflows do
+ resources :stages, module: :workflows
+ end
+
get "join/:join_code", to: "users#new", as: :join
post "join/:join_code", to: "users#create"
get "up", to: "rails/health#show", as: :rails_health_check
diff --git a/db/migrate/20241018175019_create_workflows.rb b/db/migrate/20241018175019_create_workflows.rb
new file mode 100644
index 000000000..9d57fc8fb
--- /dev/null
+++ b/db/migrate/20241018175019_create_workflows.rb
@@ -0,0 +1,10 @@
+class CreateWorkflows < ActiveRecord::Migration[8.0]
+ def change
+ create_table :workflows do |t|
+ t.references :account, null: false, foreign_key: true
+ t.string :name, null: false
+
+ t.timestamps
+ end
+ end
+end
diff --git a/db/migrate/20241018175057_create_workflow_stages.rb b/db/migrate/20241018175057_create_workflow_stages.rb
new file mode 100644
index 000000000..ff7d3e490
--- /dev/null
+++ b/db/migrate/20241018175057_create_workflow_stages.rb
@@ -0,0 +1,10 @@
+class CreateWorkflowStages < ActiveRecord::Migration[8.0]
+ def change
+ create_table :workflow_stages do |t|
+ t.references :workflow, null: false, foreign_key: true
+ t.string :name, null: false
+
+ t.timestamps
+ end
+ end
+end
diff --git a/db/migrate/20241018223027_add_workflow_stage_to_bubbles.rb b/db/migrate/20241018223027_add_workflow_stage_to_bubbles.rb
new file mode 100644
index 000000000..cb528612a
--- /dev/null
+++ b/db/migrate/20241018223027_add_workflow_stage_to_bubbles.rb
@@ -0,0 +1,5 @@
+class AddWorkflowStageToBubbles < ActiveRecord::Migration[8.0]
+ def change
+ add_reference :bubbles, :stage, null: true, foreign_key: { to_table: :workflow_stages }
+ end
+end
diff --git a/db/schema.rb b/db/schema.rb
index 77284d456..49c2ebde3 100644
--- a/db/schema.rb
+++ b/db/schema.rb
@@ -10,7 +10,7 @@
#
# It's strongly recommended that you check this file into your version control system.
-ActiveRecord::Schema[8.0].define(version: 2024_10_17_202003) do
+ActiveRecord::Schema[8.0].define(version: 2024_10_18_223027) do
create_table "accesses", force: :cascade do |t|
t.integer "bucket_id", null: false
t.integer "user_id", null: false
@@ -77,7 +77,9 @@ ActiveRecord::Schema[8.0].define(version: 2024_10_17_202003) do
t.date "due_on"
t.integer "bucket_id", null: false
t.integer "boost_count", default: 0, null: false
+ t.integer "stage_id"
t.index ["bucket_id"], name: "index_bubbles_on_bucket_id"
+ t.index ["stage_id"], name: "index_bubbles_on_stage_id"
end
create_table "bucket_views", force: :cascade do |t|
@@ -166,14 +168,33 @@ ActiveRecord::Schema[8.0].define(version: 2024_10_17_202003) do
t.index ["email_address"], name: "index_users_on_email_address", unique: true
end
+ create_table "workflow_stages", force: :cascade do |t|
+ t.integer "workflow_id", null: false
+ t.string "name", null: false
+ t.datetime "created_at", null: false
+ t.datetime "updated_at", null: false
+ t.index ["workflow_id"], name: "index_workflow_stages_on_workflow_id"
+ end
+
+ create_table "workflows", force: :cascade do |t|
+ t.integer "account_id", null: false
+ t.string "name", null: false
+ t.datetime "created_at", null: false
+ t.datetime "updated_at", null: false
+ t.index ["account_id"], name: "index_workflows_on_account_id"
+ end
+
add_foreign_key "active_storage_attachments", "active_storage_blobs", column: "blob_id"
add_foreign_key "active_storage_variant_records", "active_storage_blobs", column: "blob_id"
+ add_foreign_key "bubbles", "workflow_stages", column: "stage_id"
add_foreign_key "pops", "bubbles"
add_foreign_key "pops", "users"
add_foreign_key "sessions", "users"
add_foreign_key "taggings", "bubbles"
add_foreign_key "taggings", "tags"
add_foreign_key "users", "accounts"
+ add_foreign_key "workflow_stages", "workflows"
+ add_foreign_key "workflows", "accounts"
# Virtual tables defined in this database.
# Note that virtual tables may not work with other database engines. Be careful if changing database.
diff --git a/test/models/bubble_test.rb b/test/models/bubble_test.rb
index 4ffe9d923..e8c11a9ec 100644
--- a/test/models/bubble_test.rb
+++ b/test/models/bubble_test.rb
@@ -17,7 +17,7 @@ class BubbleTest < ActiveSupport::TestCase
assert_equal users(:kevin, :jz, :david), bubbles(:logo).assignees
assert_equal users(:david, :kevin), bubbles(:logo).assigners.uniq
assert_equal [ users(:david).id ], bubbles(:logo).events.last.assignee_ids
- assert_equal [ "David" ], bubbles(:logo).events.last.assignee_names
+ assert_equal [ "David" ], bubbles(:logo).events.last.assignees.map(&:name)
end
test "searchable by title" do