Cleanup workflow/stages

This was pending after moving to columns
This commit is contained in:
Jorge Manrubia
2025-10-07 11:10:10 +02:00
parent 6af1b3a40a
commit 1d1a3da9cf
25 changed files with 21 additions and 321 deletions
-8
View File
@@ -87,10 +87,6 @@ module EventsHelper
"#{h event_creator_name(event) } closed <span style='color: var(--card-color)'>#{h title }</span>".html_safe
when "card_reopened"
"#{h event_creator_name(event) } reopened <span style='color: var(--card-color)'>#{h title }</span>".html_safe
when "card_staged"
"#{h event_creator_name(event)} moved <span style='color: var(--card-color)'>#{h title }</span> to the #{h event.stage_name} stage".html_safe
when "card_unstaged"
"#{h event_creator_name(event)} moved <span style='color: var(--card-color)'>#{h title }</span> 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 <span style='color: var(--card-color)'>#{h title }</span>".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"
-1
View File
@@ -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",
+2 -2
View File
@@ -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),
+1 -1
View File
@@ -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 }
+2 -2
View File
@@ -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
@@ -18,8 +18,6 @@ class Card::Eventable::SystemCommenter
"#{event.creator.name} <strong>assigned</strong> this to #{event.assignees.pluck(:name).to_sentence}."
when "card_unassigned"
"#{event.creator.name} <strong>unassigned</strong> from #{event.assignees.pluck(:name).to_sentence}."
when "card_staged"
"#{event.creator.name} <strong>moved</strong> this to #{event.stage_name}."
when "card_closed"
"<strong>Closed</strong> as #{ card.closure.reason } by #{ event.creator.name }"
when "card_reopened"
-28
View File
@@ -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
+1 -1
View File
@@ -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 }
-18
View File
@@ -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
+1 -1
View File
@@ -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
-1
View File
@@ -12,7 +12,6 @@ module Filter::Params
creator_ids: [],
closer_ids: [],
collection_ids: [],
stage_ids: [],
tag_ids: [],
terms: []
]
+1 -1
View File
@@ -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
-1
View File
@@ -15,7 +15,6 @@ class Webhook < ApplicationRecord
card_due_date_removed
card_published
card_reopened
card_staged
card_title_changed
card_unassigned
card_unstaged
-16
View File
@@ -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
-12
View File
@@ -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
+3 -3
View File
@@ -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
@@ -1,4 +1,4 @@
<div id="<%= dom_id(card, :stages) %>" class="card__stages">
<div id="<%= dom_id(card, :columns) %>" class="card__stages">
<% 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 }] %>
-27
View File
@@ -1,27 +0,0 @@
<% if workflow = card.collection.workflow %>
<div id="<%= dom_id(card, :stages) %>" class="card__stages" role="radiogroup">
<legend class="for-screen-reader">Choose a column for this card</legend>
<%= 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" %>
</div>
<% end %>
@@ -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
+2
View File
@@ -0,0 +1,2 @@
json.(column, :id, :name, :color)
json.created_at column.created_at.utc
@@ -1,4 +1,4 @@
<% cache [ day_timeline.events, Workflow.all ] do %>
<% cache [ day_timeline.events ] do %>
<% if day_timeline.has_activity? %>
<div class="events__columns">
<%= render "events/day_timeline/column", event_type: "added", day_timeline: day_timeline %>
Generated
+1 -30
View File
@@ -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.
+1 -152
View File
@@ -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
+2 -2
View File
@@ -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
+2 -2
View File
@@ -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