diff --git a/app/helpers/events_helper.rb b/app/helpers/events_helper.rb index 9200f84b7..b037c63c4 100644 --- a/app/helpers/events_helper.rb +++ b/app/helpers/events_helper.rb @@ -87,10 +87,6 @@ module EventsHelper "#{h event_creator_name(event) } closed #{h title }".html_safe when "card_reopened" "#{h event_creator_name(event) } reopened #{h title }".html_safe - when "card_staged" - "#{h event_creator_name(event)} moved #{h title } to the #{h event.stage_name} stage".html_safe - when "card_unstaged" - "#{h event_creator_name(event)} moved #{h title } out ofthe #{h event.stage_name} stage".html_safe when "card_due_date_added" "#{h event_creator_name(event)} set the date to #{h event.particulars.dig('particulars', 'due_date').to_date.strftime('%B %-d')} on #{h title }".html_safe when "card_due_date_changed" @@ -110,10 +106,6 @@ module EventsHelper "assigned" when "card_unassigned" "minus" - when "card_staged" - "bolt" - when "card_unstaged" - "bolt" when "comment_created" "comment" when "card_title_changed" diff --git a/app/helpers/webhooks_helper.rb b/app/helpers/webhooks_helper.rb index 7fe91d8c0..dfb61c922 100644 --- a/app/helpers/webhooks_helper.rb +++ b/app/helpers/webhooks_helper.rb @@ -8,7 +8,6 @@ module WebhooksHelper card_due_date_removed: "Card due date removed", card_published: "Card published", card_reopened: "Card reopened", - card_staged: "Card staged", card_title_changed: "Card title changed", card_unassigned: "Card unassigned", card_unstaged: "Card unstaged", diff --git a/app/models/ai/list_cards_tool.rb b/app/models/ai/list_cards_tool.rb index a32456ddf..fd969666e 100644 --- a/app/models/ai/list_cards_tool.rb +++ b/app/models/ai/list_cards_tool.rb @@ -72,7 +72,7 @@ class Ai::ListCardsTool < Ai::Tool .where(collection: user.collections) .published .with_rich_text_description - .includes(:stage, :creator, :assignees, :goldness, :collection) + .includes(:column, :creator, :assignees, :goldness, :collection) cards = Filter.new(scope: cards, filters: params).filter @@ -98,7 +98,7 @@ class Ai::ListCardsTool < Ai::Tool last_active_at: card.last_active_at, collection_id: card.collection_id, golden: card.golden?, - stage: card.stage.as_json(only: [ :id, :name ]), + column: card.column.as_json(only: [ :id, :name ]), creator: card.creator.as_json(only: [ :id, :name ]), assignees: card.assignees.as_json(only: [ :id, :name ]), description: card.description.to_plain_text.truncate(1000), diff --git a/app/models/card.rb b/app/models/card.rb index a40c0ad90..2368d10ed 100644 --- a/app/models/card.rb +++ b/app/models/card.rb @@ -1,7 +1,7 @@ class Card < ApplicationRecord include Assignable, Attachments, Cacheable, Closeable, Colored, Entropic, Eventable, Golden, Mentions, Multistep, Pinnable, Postponable, Promptable, Readable, Searchable, - Staged, Stallable, Statuses, Taggable, Triageable, Watchable + Stallable, Statuses, Taggable, Triageable, Watchable belongs_to :collection, touch: true belongs_to :creator, class_name: "User", default: -> { Current.user } diff --git a/app/models/card/cacheable.rb b/app/models/card/cacheable.rb index 94c6b6d11..c0aac0dd5 100644 --- a/app/models/card/cacheable.rb +++ b/app/models/card/cacheable.rb @@ -17,11 +17,11 @@ module Card::Cacheable end def for_perma(*other) - [ card, Workflow.all, User.all, Tag.all, *other ] + [ card, User.all, Tag.all, *other ] end def for_preview(*other) - [ card, card.workflow, Workflow.all, card.collection.entropy_configuration, card.collection.publication, *other ] + [ card, card.collection.entropy_configuration, card.collection.publication, *other ] end end end diff --git a/app/models/card/eventable/system_commenter.rb b/app/models/card/eventable/system_commenter.rb index b633b45e7..65a6b8a36 100644 --- a/app/models/card/eventable/system_commenter.rb +++ b/app/models/card/eventable/system_commenter.rb @@ -18,8 +18,6 @@ class Card::Eventable::SystemCommenter "#{event.creator.name} assigned this to #{event.assignees.pluck(:name).to_sentence}." when "card_unassigned" "#{event.creator.name} unassigned from #{event.assignees.pluck(:name).to_sentence}." - when "card_staged" - "#{event.creator.name} moved this to ‘#{event.stage_name}’." when "card_closed" "Closed as ‘#{ card.closure.reason }’ by #{ event.creator.name }" when "card_reopened" diff --git a/app/models/card/staged.rb b/app/models/card/staged.rb deleted file mode 100644 index 4cd497abd..000000000 --- a/app/models/card/staged.rb +++ /dev/null @@ -1,28 +0,0 @@ -module Card::Staged - extend ActiveSupport::Concern - - included do - belongs_to :stage, class_name: "Workflow::Stage", optional: true - - before_create :assign_initial_stage - - scope :in_stage, ->(stage) { where stage: stage } - delegate :workflow, to: :collection, allow_nil: true - end - - def staged? - stage.present? - end - - def change_stage_to(new_stage) - transaction do - update! stage: new_stage - track_event :staged, stage_id: new_stage.id, stage_name: new_stage.name - end - end - - private - def assign_initial_stage - self.stage = collection.initial_workflow_stage - end -end diff --git a/app/models/collection.rb b/app/models/collection.rb index bd4d403c7..7ccb34806 100644 --- a/app/models/collection.rb +++ b/app/models/collection.rb @@ -1,5 +1,5 @@ class Collection < ApplicationRecord - include AutoClosing, Accessible, Broadcastable, Entropic, Filterable, Publishable, Triageable, Workflowing + include AutoClosing, Accessible, Broadcastable, Entropic, Filterable, Publishable, Triageable belongs_to :creator, class_name: "User", default: -> { Current.user } diff --git a/app/models/collection/workflowing.rb b/app/models/collection/workflowing.rb deleted file mode 100644 index 0a14cad36..000000000 --- a/app/models/collection/workflowing.rb +++ /dev/null @@ -1,18 +0,0 @@ -module Collection::Workflowing - extend ActiveSupport::Concern - - included do - belongs_to :workflow, optional: true - - after_update_commit :set_all_cards_to_initial_workflow_stage, if: :saved_change_to_workflow_id? - end - - def initial_workflow_stage - workflow&.stages&.first - end - - private - def set_all_cards_to_initial_workflow_stage - cards.update_all(stage_id: initial_workflow_stage&.id, updated_at: Time.current) - end -end diff --git a/app/models/event/particulars.rb b/app/models/event/particulars.rb index dd92fa4da..31ecd66bf 100644 --- a/app/models/event/particulars.rb +++ b/app/models/event/particulars.rb @@ -2,7 +2,7 @@ module Event::Particulars extend ActiveSupport::Concern included do - store_accessor :particulars, :assignee_ids, :stage_id, :stage_name + store_accessor :particulars, :assignee_ids end def assignees diff --git a/app/models/filter/params.rb b/app/models/filter/params.rb index 6992516f5..166436e4b 100644 --- a/app/models/filter/params.rb +++ b/app/models/filter/params.rb @@ -12,7 +12,6 @@ module Filter::Params creator_ids: [], closer_ids: [], collection_ids: [], - stage_ids: [], tag_ids: [], terms: [] ] diff --git a/app/models/user/day_timeline.rb b/app/models/user/day_timeline.rb index 80eb8a95d..cf8d08612 100644 --- a/app/models/user/day_timeline.rb +++ b/app/models/user/day_timeline.rb @@ -46,7 +46,7 @@ class User::DayTimeline end def cache_key - ActiveSupport::Cache.expand_cache_key [ user, filter, day.to_date, events, Workflow.all, weekly_highlights ], "day-timeline" + ActiveSupport::Cache.expand_cache_key [ user, filter, day.to_date, events, weekly_highlights ], "day-timeline" end private diff --git a/app/models/webhook.rb b/app/models/webhook.rb index 1eefb2cb5..a766e68f5 100644 --- a/app/models/webhook.rb +++ b/app/models/webhook.rb @@ -15,7 +15,6 @@ class Webhook < ApplicationRecord card_due_date_removed card_published card_reopened - card_staged card_title_changed card_unassigned card_unstaged diff --git a/app/models/workflow.rb b/app/models/workflow.rb deleted file mode 100644 index 196af1cc3..000000000 --- a/app/models/workflow.rb +++ /dev/null @@ -1,16 +0,0 @@ -class Workflow < ApplicationRecord - DEFAULT_STAGES = [ - { name: "Figuring it out", color: "var(--color-card-5)" }, - { name: "In progress", color: "var(--color-card-3)" } - ] - - has_many :stages, dependent: :destroy - has_many :collections, dependent: :nullify - - after_create_commit :create_default_columns - - private - def create_default_stages - Workflow::Stage.insert_all(DEFAULT_STAGES.map { { name: it[:name], color: it[:color], workflow_id: id } }) - end -end diff --git a/app/models/workflow/stage.rb b/app/models/workflow/stage.rb deleted file mode 100644 index 4eb08828d..000000000 --- a/app/models/workflow/stage.rb +++ /dev/null @@ -1,12 +0,0 @@ -class Workflow::Stage < ApplicationRecord - belongs_to :workflow, touch: true - - has_many :cards, dependent: :nullify - - before_validation :assign_random_color, on: :create - - private - def assign_random_color - self.color ||= Card::Colored::COLORS.sample - end -end diff --git a/app/views/cards/_card.json.jbuilder b/app/views/cards/_card.json.jbuilder index fdb242edd..15926a921 100644 --- a/app/views/cards/_card.json.jbuilder +++ b/app/views/cards/_card.json.jbuilder @@ -12,9 +12,9 @@ json.cache! card do json.partial! "collections/collection", locals: { collection: card.collection } end - json.stage do - if card.stage - json.partial! "workflows/stages/stage", stage: card.stage + json.column do + if card.column + json.partial! "columns/column", column: card.column else nil end diff --git a/app/views/cards/display/public_preview/_columns.html.erb b/app/views/cards/display/public_preview/_columns.html.erb index 670767f24..459893b7f 100644 --- a/app/views/cards/display/public_preview/_columns.html.erb +++ b/app/views/cards/display/public_preview/_columns.html.erb @@ -1,4 +1,4 @@ -
+
<% card.collection.columns.each do |column| %> <%= tag.div column.name, class: ["workflow-stage overflow-ellipsis flex align-center gap-half btn non-clickable no-hover", { "workflow-stage--current": column == card.column }] %> diff --git a/app/views/cards/stagings/_stages.html.erb b/app/views/cards/stagings/_stages.html.erb deleted file mode 100644 index abfe4af08..000000000 --- a/app/views/cards/stagings/_stages.html.erb +++ /dev/null @@ -1,27 +0,0 @@ -<% if workflow = card.collection.workflow %> -
- Choose a column for this card - - <%= button_to "Not now", card_closure_path(card, reason: "Not now"), - class: [ "workflow-stage btn", { "workflow-stage--current": card.closed? } ], - role: "radio", - aria: { checked: card.closed? }, - form_class: "flex align-center gap-half" %> - - <%= button_to "The Stream", card_engagement_path(card), method: :delete, - class: [ "workflow-stage workflow-stage--stream btn", { "workflow-stage--current": card.considering? } ], - role: "radio", - aria: { checked: card.considering? }, - form_class: "flex align-center gap-half" %> - - <% workflow.stages.each do |stage| %> - <%= button_to_set_stage card, stage %> - <% end %> - - <%= button_to "Closed", card_closure_path(card, reason: "Completed"), - class: [ "workflow-stage btn", { "workflow-stage--current": card.closed? } ], - role: "radio", - aria: { checked: card.closed? }, - form_class: "flex align-center gap-half" %> -
-<% end %> diff --git a/app/views/collections/_collection.json.jbuilder b/app/views/collections/_collection.json.jbuilder index 3c42b2fc9..01857786e 100644 --- a/app/views/collections/_collection.json.jbuilder +++ b/app/views/collections/_collection.json.jbuilder @@ -5,12 +5,4 @@ json.cache! collection do json.creator do json.partial! "users/user", user: collection.creator end - - json.workflow do - if collection.workflow - json.partial! "workflows/workflow", workflow: collection.workflow - else - nil - end - end end diff --git a/app/views/columns/_column.json.jbuilder b/app/views/columns/_column.json.jbuilder new file mode 100644 index 000000000..355a62606 --- /dev/null +++ b/app/views/columns/_column.json.jbuilder @@ -0,0 +1,2 @@ +json.(column, :id, :name, :color) +json.created_at column.created_at.utc diff --git a/app/views/events/day_timeline/_columns.html.erb b/app/views/events/day_timeline/_columns.html.erb index 020526e04..5391736e9 100644 --- a/app/views/events/day_timeline/_columns.html.erb +++ b/app/views/events/day_timeline/_columns.html.erb @@ -1,4 +1,4 @@ -<% cache [ day_timeline.events, Workflow.all ] do %> +<% cache [ day_timeline.events ] do %> <% if day_timeline.has_activity? %>
<%= render "events/day_timeline/column", event_type: "added", day_timeline: day_timeline %> diff --git a/db/schema.rb b/db/schema.rb index 136bbc782..d84722ea0 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_10_06_091442) do +ActiveRecord::Schema[8.1].define(version: 2025_10_07_084223) do create_table "accesses", force: :cascade do |t| t.datetime "accessed_at" t.integer "collection_id", null: false @@ -145,14 +145,12 @@ ActiveRecord::Schema[8.1].define(version: 2025_10_06_091442) do t.integer "creator_id", null: false t.date "due_on" t.datetime "last_active_at", null: false - t.integer "stage_id" t.text "status", default: "creating", null: false t.string "title" t.datetime "updated_at", null: false t.index ["collection_id"], name: "index_cards_on_collection_id" t.index ["column_id"], name: "index_cards_on_column_id" t.index ["last_active_at", "status"], name: "index_cards_on_last_active_at_and_status" - t.index ["stage_id"], name: "index_cards_on_stage_id" end create_table "closers_filters", id: false, force: :cascade do |t| @@ -194,9 +192,7 @@ ActiveRecord::Schema[8.1].define(version: 2025_10_06_091442) do t.integer "creator_id", null: false t.string "name", null: false t.datetime "updated_at", null: false - t.integer "workflow_id" t.index ["creator_id"], name: "index_collections_on_creator_id" - t.index ["workflow_id"], name: "index_collections_on_workflow_id" end create_table "collections_filters", id: false, force: :cascade do |t| @@ -288,13 +284,6 @@ ActiveRecord::Schema[8.1].define(version: 2025_10_06_091442) do t.index ["creator_id", "params_digest"], name: "index_filters_on_creator_id_and_params_digest", unique: true end - create_table "filters_stages", id: false, force: :cascade do |t| - t.integer "filter_id", null: false - t.integer "stage_id", null: false - t.index ["filter_id"], name: "index_filters_stages_on_filter_id" - t.index ["stage_id"], name: "index_filters_stages_on_stage_id" - end - create_table "filters_tags", id: false, force: :cascade do |t| t.integer "filter_id", null: false t.integer "tag_id", null: false @@ -513,21 +502,6 @@ ActiveRecord::Schema[8.1].define(version: 2025_10_06_091442) do t.index ["collection_id"], name: "index_webhooks_on_collection_id" end - create_table "workflow_stages", force: :cascade do |t| - t.string "color" - t.datetime "created_at", null: false - t.string "name", null: false - t.datetime "updated_at", null: false - t.integer "workflow_id", null: false - t.index ["workflow_id"], name: "index_workflow_stages_on_workflow_id" - end - - create_table "workflows", force: :cascade do |t| - t.datetime "created_at", null: false - t.string "name", null: false - t.datetime "updated_at", null: false - 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 "ai_quotas", "users" @@ -535,11 +509,9 @@ ActiveRecord::Schema[8.1].define(version: 2025_10_06_091442) do add_foreign_key "card_goldnesses", "cards" add_foreign_key "card_not_nows", "cards" add_foreign_key "cards", "columns" - add_foreign_key "cards", "workflow_stages", column: "stage_id" add_foreign_key "closures", "cards" add_foreign_key "closures", "users" add_foreign_key "collection_publications", "collections" - add_foreign_key "collections", "workflows" add_foreign_key "columns", "collections" add_foreign_key "comments", "cards" add_foreign_key "conversation_messages", "conversations" @@ -567,7 +539,6 @@ ActiveRecord::Schema[8.1].define(version: 2025_10_06_091442) do add_foreign_key "webhook_deliveries", "events" add_foreign_key "webhook_deliveries", "webhooks" add_foreign_key "webhooks", "collections" - add_foreign_key "workflow_stages", "workflows" # 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/db/schema_cache.yml b/db/schema_cache.yml index eb63f2cf9..84068a62f 100644 --- a/db/schema_cache.yml +++ b/db/schema_cache.yml @@ -491,16 +491,6 @@ columns: default_function: collation: comment: - - !ruby/object:ActiveRecord::ConnectionAdapters::SQLite3::Column - auto_increment: - name: stage_id - cast_type: *3 - sql_type_metadata: *4 - 'null': true - default: - default_function: - collation: - comment: - !ruby/object:ActiveRecord::ConnectionAdapters::SQLite3::Column auto_increment: name: status @@ -612,16 +602,6 @@ columns: - *6 - *10 - *9 - - !ruby/object:ActiveRecord::ConnectionAdapters::SQLite3::Column - auto_increment: - name: workflow_id - cast_type: *3 - sql_type_metadata: *4 - 'null': true - default: - default_function: - collation: - comment: collections_filters: - *24 - *20 @@ -882,18 +862,6 @@ columns: collation: comment: - *9 - filters_stages: - - *20 - - !ruby/object:ActiveRecord::ConnectionAdapters::SQLite3::Column - auto_increment: - name: stage_id - cast_type: *3 - sql_type_metadata: *4 - 'null': false - default: - default_function: - collation: - comment: filters_tags: - *20 - &35 !ruby/object:ActiveRecord::ConnectionAdapters::SQLite3::Column @@ -1479,36 +1447,6 @@ columns: default_function: collation: comment: - workflow_stages: - - !ruby/object:ActiveRecord::ConnectionAdapters::SQLite3::Column - auto_increment: - name: color - cast_type: *7 - sql_type_metadata: *8 - 'null': true - default: - default_function: - collation: - comment: - - *5 - - *6 - - *10 - - *9 - - !ruby/object:ActiveRecord::ConnectionAdapters::SQLite3::Column - auto_increment: - name: workflow_id - cast_type: *3 - sql_type_metadata: *4 - 'null': false - default: - default_function: - collation: - comment: - workflows: - - *5 - - *6 - - *10 - - *9 primary_keys: accesses: id accounts: id @@ -1540,7 +1478,6 @@ primary_keys: entropy_configurations: id events: id filters: id - filters_stages: filters_tags: mentions: id notification_bundles: id @@ -1564,8 +1501,6 @@ primary_keys: webhook_delinquency_trackers: id webhook_deliveries: id webhooks: id - workflow_stages: id - workflows: id data_sources: accesses: true accounts: true @@ -1597,7 +1532,6 @@ data_sources: entropy_configurations: true events: true filters: true - filters_stages: true filters_tags: true mentions: true notification_bundles: true @@ -1621,8 +1555,6 @@ data_sources: webhook_delinquency_trackers: true webhook_deliveries: true webhooks: true - workflow_stages: true - workflows: true indexes: accesses: - !ruby/object:ActiveRecord::ConnectionAdapters::IndexDefinition @@ -2081,22 +2013,6 @@ indexes: nulls_not_distinct: comment: valid: true - - !ruby/object:ActiveRecord::ConnectionAdapters::IndexDefinition - table: cards - name: index_cards_on_stage_id - unique: false - columns: - - stage_id - lengths: {} - orders: {} - opclasses: {} - where: - type: - using: - include: - nulls_not_distinct: - comment: - valid: true closers_filters: - !ruby/object:ActiveRecord::ConnectionAdapters::IndexDefinition table: closers_filters @@ -2231,22 +2147,6 @@ indexes: nulls_not_distinct: comment: valid: true - - !ruby/object:ActiveRecord::ConnectionAdapters::IndexDefinition - table: collections - name: index_collections_on_workflow_id - unique: false - columns: - - workflow_id - lengths: {} - orders: {} - opclasses: {} - where: - type: - using: - include: - nulls_not_distinct: - comment: - valid: true collections_filters: - !ruby/object:ActiveRecord::ConnectionAdapters::IndexDefinition table: collections_filters @@ -2501,39 +2401,6 @@ indexes: nulls_not_distinct: comment: valid: true - filters_stages: - - !ruby/object:ActiveRecord::ConnectionAdapters::IndexDefinition - table: filters_stages - name: index_filters_stages_on_filter_id - unique: false - columns: - - filter_id - lengths: {} - orders: {} - opclasses: {} - where: - type: - using: - include: - nulls_not_distinct: - comment: - valid: true - - !ruby/object:ActiveRecord::ConnectionAdapters::IndexDefinition - table: filters_stages - name: index_filters_stages_on_stage_id - unique: false - columns: - - stage_id - lengths: {} - orders: {} - opclasses: {} - where: - type: - using: - include: - nulls_not_distinct: - comment: - valid: true filters_tags: - !ruby/object:ActiveRecord::ConnectionAdapters::IndexDefinition table: filters_tags @@ -3281,22 +3148,4 @@ indexes: nulls_not_distinct: comment: valid: true - workflow_stages: - - !ruby/object:ActiveRecord::ConnectionAdapters::IndexDefinition - table: workflow_stages - name: index_workflow_stages_on_workflow_id - unique: false - columns: - - workflow_id - lengths: {} - orders: {} - opclasses: {} - where: - type: - using: - include: - nulls_not_distinct: - comment: - valid: true - workflows: [] -version: 20251006091442 +version: 20251007084223 diff --git a/db/seeds/37signals.rb b/db/seeds/37signals.rb index e1f3ed145..cbb5ebeab 100644 --- a/db/seeds/37signals.rb +++ b/db/seeds/37signals.rb @@ -12,8 +12,8 @@ create_collection("Fizzy", access_to: [ jason, jz, kevin ]).tap do |fizzy| create_card("Prepare sign-up page", description: "We need to do this before the launch.", collection: fizzy).tap do |card| card.toggle_assignment(kevin) - if stage = card.workflow&.stages&.sample - card.change_stage_to(stage) + if column = card.collection&.columns&.sample + card.triage_into(column) end end diff --git a/db/seeds/honcho.rb b/db/seeds/honcho.rb index 1ad072ba7..80ffab4d6 100644 --- a/db/seeds/honcho.rb +++ b/db/seeds/honcho.rb @@ -75,8 +75,8 @@ collections.each_with_index do |collection_name, index| travel rand(0..20).minutes case rand(3) when 0 - if stage = card.workflow&.stages&.sample - card.change_stage_to(stage) + if column = card.collection&.columns&.sample + card.triage_into(column) end when 1 card.close