From 1cf2e24bcc2ac5ac76675ccd38b910bf33eaa883 Mon Sep 17 00:00:00 2001 From: Jason Zimdars Date: Thu, 27 Mar 2025 14:35:07 -0500 Subject: [PATCH] Set buckets at the workflow level - All bubbles inherit the bucket's set workflow --- app/controllers/buckets_controller.rb | 3 +- app/controllers/workflows_controller.rb | 2 +- app/models/account.rb | 11 +++++ app/models/bubble.rb | 2 +- app/models/bucket.rb | 13 +++++- app/views/buckets/edit.html.erb | 10 ++++- .../20250327191456_add_workflow_to_buckets.rb | 5 +++ db/schema.rb | 6 ++- db/schema_cache.yml | 45 +++++++++++-------- test/fixtures/workflow/stages.yml | 10 +++-- 10 files changed, 79 insertions(+), 28 deletions(-) create mode 100644 db/migrate/20250327191456_add_workflow_to_buckets.rb diff --git a/app/controllers/buckets_controller.rb b/app/controllers/buckets_controller.rb index 63357bb92..32df270e0 100644 --- a/app/controllers/buckets_controller.rb +++ b/app/controllers/buckets_controller.rb @@ -33,7 +33,8 @@ class BucketsController < ApplicationController end def bucket_params - params.expect(bucket: [ :name, :all_access ]).with_defaults(all_access: false) + params.expect(bucket: [ :name, :all_access, :workflow_id ]).with_defaults(all_access: false) + params.require(:bucket).permit(:name, :all_access, :workflow_id) end def grantees diff --git a/app/controllers/workflows_controller.rb b/app/controllers/workflows_controller.rb index edc89a008..390cedcdb 100644 --- a/app/controllers/workflows_controller.rb +++ b/app/controllers/workflows_controller.rb @@ -12,7 +12,7 @@ class WorkflowsController < ApplicationController def create @workflow = Current.account.workflows.create! workflow_params # FIXME: this should definitely change. - [ "Maybe?", "Not now", "Done" ].each { |name| @workflow.stages.create! name: name } + [ "Triage", "In progress", "On Hold", "Review" ].each { |name| @workflow.stages.create! name: name } redirect_to workflows_path end diff --git a/app/models/account.rb b/app/models/account.rb index f8fc136b9..0f5d15fee 100644 --- a/app/models/account.rb +++ b/app/models/account.rb @@ -16,4 +16,15 @@ class Account < ApplicationRecord has_many :tags, dependent: :destroy has_many_attached :uploads + + after_create :create_default_workflow + + private + def create_default_workflow + workflows.create!(name: "Default Workflow").tap do |workflow| + [ "Triage", "In progress", "On Hold", "Review" ].each do |name| + workflow.stages.create!(name: name) + end + end + end end diff --git a/app/models/bubble.rb b/app/models/bubble.rb index 441071f5a..c90ac1075 100644 --- a/app/models/bubble.rb +++ b/app/models/bubble.rb @@ -56,7 +56,7 @@ class Bubble < ApplicationRecord end def assign_initial_stage - if workflow_stage = bucket.account.workflows.first&.stages&.first + if workflow_stage = bucket.workflow&.stages&.first self.stage = workflow_stage save! touch: false track_event :staged, stage_id: workflow_stage.id, stage_name: workflow_stage.name diff --git a/app/models/bucket.rb b/app/models/bucket.rb index 16f1f1d63..d0ce59a73 100644 --- a/app/models/bucket.rb +++ b/app/models/bucket.rb @@ -3,6 +3,7 @@ class Bucket < ApplicationRecord belongs_to :account belongs_to :creator, class_name: "User", default: -> { Current.user } + belongs_to :workflow, optional: true has_many :bubbles, dependent: :destroy has_many :tags, -> { distinct }, through: :bubbles @@ -10,6 +11,7 @@ class Bucket < ApplicationRecord validates_presence_of :name after_create :ensure_workflow_exists + after_save :update_bubbles_workflow, if: :saved_change_to_workflow_id? scope :alphabetically, -> { order(name: :asc) } @@ -17,7 +19,16 @@ class Bucket < ApplicationRecord def ensure_workflow_exists unless account.workflows.exists? workflow = account.workflows.create!(name: "Default Workflow") - [ "Maybe?", "Not now", "Done" ].each { |name| workflow.stages.create!(name: name) } + [ "Triage", "In progress", "Oh Hold", "Review" ].each { |name| workflow.stages.create!(name: name) } + end + end + + def update_bubbles_workflow + if workflow + first_stage = workflow.stages.first + bubbles.update_all(stage_id: first_stage.id) if first_stage + else + bubbles.update_all(stage_id: nil) end end end diff --git a/app/views/buckets/edit.html.erb b/app/views/buckets/edit.html.erb index 2f024c221..e8f16c46e 100644 --- a/app/views/buckets/edit.html.erb +++ b/app/views/buckets/edit.html.erb @@ -67,7 +67,7 @@ <% end %> - @@ -75,3 +75,11 @@ <%= link_to "Cancel and go back", bubbles_path(bucket_ids: [ @bucket ]), data: { form_target: "cancel", turbo_frame: "_top" }, hidden: true %> <% end %> + +
+ Choose a workflow +

Use a workflow to track progress in this collection.

+ <%= form_with model: @bucket, local: true, data: { controller: "form" } do |form| %> + <%= form.select :workflow_id, Current.account.workflows.map { |w| [w.name, w.id] }, { include_blank: "Choose…" }, class: "input input--select full-width", data: { action: "change->form#submit" } %> + <% end %> +
diff --git a/db/migrate/20250327191456_add_workflow_to_buckets.rb b/db/migrate/20250327191456_add_workflow_to_buckets.rb new file mode 100644 index 000000000..4efe294f2 --- /dev/null +++ b/db/migrate/20250327191456_add_workflow_to_buckets.rb @@ -0,0 +1,5 @@ +class AddWorkflowToBuckets < ActiveRecord::Migration[8.1] + def change + add_reference :buckets, :workflow, null: true, foreign_key: true + end +end diff --git a/db/schema.rb b/db/schema.rb index 6a65a7709..ef0105d28 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.1].define(version: 2025_03_18_005138) do +ActiveRecord::Schema[8.1].define(version: 2025_03_27_191456) do create_table "accesses", force: :cascade do |t| t.integer "bucket_id", null: false t.datetime "created_at", null: false @@ -123,8 +123,10 @@ ActiveRecord::Schema[8.1].define(version: 2025_03_18_005138) do t.integer "creator_id", null: false t.string "name", null: false t.datetime "updated_at", null: false + t.integer "workflow_id" t.index ["account_id"], name: "index_buckets_on_account_id" t.index ["creator_id"], name: "index_buckets_on_creator_id" + t.index ["workflow_id"], name: "index_buckets_on_workflow_id" end create_table "buckets_filters", id: false, force: :cascade do |t| @@ -220,7 +222,6 @@ ActiveRecord::Schema[8.1].define(version: 2025_03_18_005138) do t.datetime "created_at", null: false t.datetime "updated_at", null: false t.integer "user_id", null: false - t.index ["bubble_id", "user_id"], name: "index_pins_on_bubble_id_and_user_id", unique: true t.index ["bubble_id"], name: "index_pins_on_bubble_id" t.index ["user_id"], name: "index_pins_on_user_id" end @@ -324,6 +325,7 @@ ActiveRecord::Schema[8.1].define(version: 2025_03_18_005138) do 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 "buckets", "workflows" add_foreign_key "events", "bubbles" add_foreign_key "events", "event_summaries", column: "summary_id" add_foreign_key "messages", "bubbles" diff --git a/db/schema_cache.yml b/db/schema_cache.yml index f0550d59e..40d083029 100644 --- a/db/schema_cache.yml +++ b/db/schema_cache.yml @@ -519,6 +519,16 @@ columns: default_function: collation: comment: + - !ruby/object:ActiveRecord::ConnectionAdapters::SQLite3::Column + auto_increment: + name: workflow_id + cast_type: *1 + sql_type_metadata: *2 + 'null': true + default: + default_function: + collation: + comment: buckets_filters: - *18 - *21 @@ -1355,6 +1365,22 @@ indexes: comment: valid: true buckets: + - !ruby/object:ActiveRecord::ConnectionAdapters::IndexDefinition + table: buckets + name: index_buckets_on_workflow_id + unique: false + columns: + - workflow_id + lengths: {} + orders: {} + opclasses: {} + where: + type: + using: + include: + nulls_not_distinct: + comment: + valid: true - !ruby/object:ActiveRecord::ConnectionAdapters::IndexDefinition table: buckets name: index_buckets_on_creator_id @@ -1710,23 +1736,6 @@ indexes: comment: valid: true pins: - - !ruby/object:ActiveRecord::ConnectionAdapters::IndexDefinition - table: pins - name: index_pins_on_bubble_id_and_user_id - unique: true - columns: - - bubble_id - - user_id - lengths: {} - orders: {} - opclasses: {} - where: - type: - using: - include: - nulls_not_distinct: - comment: - valid: true - !ruby/object:ActiveRecord::ConnectionAdapters::IndexDefinition table: pins name: index_pins_on_user_id @@ -2062,4 +2071,4 @@ indexes: nulls_not_distinct: comment: valid: true -version: 20250318005138 +version: 20250327191456 diff --git a/test/fixtures/workflow/stages.yml b/test/fixtures/workflow/stages.yml index 1067c0e33..ca76248bf 100644 --- a/test/fixtures/workflow/stages.yml +++ b/test/fixtures/workflow/stages.yml @@ -1,11 +1,15 @@ qa_maybe: - name: Maybe? + name: Triage workflow: qa qa_not_now: - name: Not now + name: In progress workflow: qa qa_done: - name: Done + name: Oh Hold + workflow: qa + +qa_hold: + name: Review workflow: qa