From 7406a1039f5d4d3ee9ff7ac6fb3ffb7c54f8123f Mon Sep 17 00:00:00 2001 From: Jorge Manrubia Date: Thu, 10 Apr 2025 16:48:12 +0200 Subject: [PATCH 01/31] Add models to track gold cards and implement basic toggle behavior --- app/assets/stylesheets/cards.css | 4 + .../cards/goldenesses_controller.rb | 13 + app/models/card.rb | 5 +- app/models/card/golden.rb | 22 ++ app/models/card/goldness.rb | 3 + app/views/cards/_golden_toggle.html.erb | 11 + app/views/cards/display/_perma.html.erb | 2 +- app/views/cards/show.html.erb | 6 +- config/routes.rb | 1 + .../20250410141409_create_card_goldnesses.rb | 9 + db/schema.rb | 10 +- db/schema_cache.yml | 288 ++++++++++-------- 12 files changed, 233 insertions(+), 141 deletions(-) create mode 100644 app/controllers/cards/goldenesses_controller.rb create mode 100644 app/models/card/golden.rb create mode 100644 app/models/card/goldness.rb create mode 100644 app/views/cards/_golden_toggle.html.erb create mode 100644 db/migrate/20250410141409_create_card_goldnesses.rb diff --git a/app/assets/stylesheets/cards.css b/app/assets/stylesheets/cards.css index 4a5e318d7..1ffc3f740 100644 --- a/app/assets/stylesheets/cards.css +++ b/app/assets/stylesheets/cards.css @@ -97,6 +97,10 @@ } } + .card--golden { + outline: 5px solid orange; + } + .card__actions { position: absolute; inset: var(--actions-block-inset) auto auto calc(var(--actions-inline-inset) * -1); diff --git a/app/controllers/cards/goldenesses_controller.rb b/app/controllers/cards/goldenesses_controller.rb new file mode 100644 index 000000000..974610569 --- /dev/null +++ b/app/controllers/cards/goldenesses_controller.rb @@ -0,0 +1,13 @@ +class Cards::GoldenessesController < ApplicationController + include CardScoped + + def create + @card.promote_to_golden + redirect_to @card + end + + def destroy + @card.demote_from_golden + redirect_to @card + end +end diff --git a/app/models/card.rb b/app/models/card.rb index c58507125..46907bf3d 100644 --- a/app/models/card.rb +++ b/app/models/card.rb @@ -1,6 +1,7 @@ class Card < ApplicationRecord - include Assignable, Boostable, Colored, Commentable, Engageable, Eventable, - Messages, Notifiable, Pinnable, Closeable, Scorable, Searchable, Staged, Statuses, Taggable, Watchable + include Assignable, Boostable, Colored, Commentable, Engageable, Eventable, Golden, + Messages, Notifiable, Pinnable, Closeable, Scorable, Searchable, Staged, + Statuses, Taggable, Watchable belongs_to :collection, touch: true belongs_to :creator, class_name: "User", default: -> { Current.user } diff --git a/app/models/card/golden.rb b/app/models/card/golden.rb new file mode 100644 index 000000000..339b8cab6 --- /dev/null +++ b/app/models/card/golden.rb @@ -0,0 +1,22 @@ +module Card::Golden + extend ActiveSupport::Concern + + included do + scope :golden, -> { joins(:goldness) } + scope :non_golden, -> { where.missing(:goldness) } + + has_one :goldness, dependent: :destroy, class_name: "Card::Goldness" + end + + def golden? + goldness.present? + end + + def promote_to_golden + create_goldness! unless golden? + end + + def demote_from_golden + goldness&.destroy + end +end diff --git a/app/models/card/goldness.rb b/app/models/card/goldness.rb new file mode 100644 index 000000000..5ef88fc0b --- /dev/null +++ b/app/models/card/goldness.rb @@ -0,0 +1,3 @@ +class Card::Goldness < ApplicationRecord + belongs_to :card +end diff --git a/app/views/cards/_golden_toggle.html.erb b/app/views/cards/_golden_toggle.html.erb new file mode 100644 index 000000000..e1c475484 --- /dev/null +++ b/app/views/cards/_golden_toggle.html.erb @@ -0,0 +1,11 @@ +<% if @card.golden? %> + <%= button_to card_goldeness_path(@card), method: :delete, class: "btn btn--reversed" do %> + <%= icon_tag "star" %> + Demote to normal + <% end %> +<% else %> + <%= button_to card_goldeness_path(@card), class: "btn" do %> + <%= icon_tag "star" %> + Promote to golden + <% end %> +<% end %> diff --git a/app/views/cards/display/_perma.html.erb b/app/views/cards/display/_perma.html.erb index 4b205e33b..309a6dd86 100644 --- a/app/views/cards/display/_perma.html.erb +++ b/app/views/cards/display/_perma.html.erb @@ -1,5 +1,5 @@ <% cache card do %> -
diff --git a/app/views/cards/show.html.erb b/app/views/cards/show.html.erb index 753c2e464..d7a122b37 100644 --- a/app/views/cards/show.html.erb +++ b/app/views/cards/show.html.erb @@ -55,11 +55,7 @@ <%= render "cards/display/perma", card: @card %>
- + <%= render "cards/golden_toggle" %> <%= render "cards/image", card: @card %> <%= button_to collection_card_path(@card.collection, @card), diff --git a/config/routes.rb b/config/routes.rb index cf2b5fe76..25e6a0f62 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -22,6 +22,7 @@ Rails.application.routes.draw do resource :reading resource :recover resource :watch + resource :goldeness resources :assignments resources :boosts diff --git a/db/migrate/20250410141409_create_card_goldnesses.rb b/db/migrate/20250410141409_create_card_goldnesses.rb new file mode 100644 index 000000000..f8268c243 --- /dev/null +++ b/db/migrate/20250410141409_create_card_goldnesses.rb @@ -0,0 +1,9 @@ +class CreateCardGoldnesses < ActiveRecord::Migration[8.1] + def change + create_table :card_goldnesses do |t| + t.references :card, null: false, foreign_key: true, index: { unique: true } + + t.timestamps + end + end +end diff --git a/db/schema.rb b/db/schema.rb index b7e50d935..4fa6fa273 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_04_09_201424) do +ActiveRecord::Schema[8.1].define(version: 2025_04_10_141409) do create_table "accesses", force: :cascade do |t| t.integer "collection_id", null: false t.datetime "created_at", null: false @@ -102,6 +102,13 @@ ActiveRecord::Schema[8.1].define(version: 2025_04_09_201424) do t.index ["card_id"], name: "index_card_engagements_on_card_id" end + create_table "card_goldnesses", force: :cascade do |t| + t.integer "card_id", null: false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.index ["card_id"], name: "index_card_goldnesses_on_card_id", unique: true + end + create_table "cards", force: :cascade do |t| t.float "activity_score", default: 0.0, null: false t.datetime "activity_score_at" @@ -333,6 +340,7 @@ ActiveRecord::Schema[8.1].define(version: 2025_04_09_201424) 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 "card_goldnesses", "cards" add_foreign_key "cards", "workflow_stages", column: "stage_id" add_foreign_key "closures", "cards" add_foreign_key "closures", "users" diff --git a/db/schema_cache.yml b/db/schema_cache.yml index 592648228..3233fb2f6 100644 --- a/db/schema_cache.yml +++ b/db/schema_cache.yml @@ -21,7 +21,7 @@ columns: default_function: collation: comment: - - &23 !ruby/object:ActiveRecord::ConnectionAdapters::SQLite3::Column + - &24 !ruby/object:ActiveRecord::ConnectionAdapters::SQLite3::Column auto_increment: name: collection_id cast_type: *1 @@ -341,7 +341,7 @@ columns: - *5 - *19 - *20 - - &24 !ruby/object:ActiveRecord::ConnectionAdapters::SQLite3::Column + - &21 !ruby/object:ActiveRecord::ConnectionAdapters::SQLite3::Column auto_increment: name: card_id cast_type: *1 @@ -367,16 +367,21 @@ columns: comment: - *6 - *9 + card_goldnesses: + - *5 + - *21 + - *6 + - *9 cards: - *5 - !ruby/object:ActiveRecord::ConnectionAdapters::SQLite3::Column auto_increment: name: activity_score - cast_type: &21 !ruby/object:ActiveModel::Type::Float + cast_type: &22 !ruby/object:ActiveModel::Type::Float precision: scale: limit: - sql_type_metadata: &22 !ruby/object:ActiveRecord::ConnectionAdapters::SqlTypeMetadata + sql_type_metadata: &23 !ruby/object:ActiveRecord::ConnectionAdapters::SqlTypeMetadata sql_type: float type: :float limit: @@ -400,8 +405,8 @@ columns: - !ruby/object:ActiveRecord::ConnectionAdapters::SQLite3::Column auto_increment: name: activity_score_order - cast_type: *21 - sql_type_metadata: *22 + cast_type: *22 + sql_type_metadata: *23 'null': false default: 0.0 default_function: @@ -417,7 +422,7 @@ columns: default_function: collation: comment: - - *23 + - *24 - !ruby/object:ActiveRecord::ConnectionAdapters::SQLite3::Column auto_increment: name: comments_count @@ -525,7 +530,7 @@ columns: - *9 closures: - *5 - - *24 + - *21 - *6 - !ruby/object:ActiveRecord::ConnectionAdapters::SQLite3::Column auto_increment: @@ -593,7 +598,7 @@ columns: collation: comment: collections_filters: - - *23 + - *24 - *18 comments: - *5 @@ -619,7 +624,7 @@ columns: default_function: collation: comment: - - *24 + - *21 - *6 - *25 - !ruby/object:ActiveRecord::ConnectionAdapters::SQLite3::Column @@ -712,7 +717,7 @@ columns: comment: messages: - *5 - - *24 + - *21 - *6 - !ruby/object:ActiveRecord::ConnectionAdapters::SQLite3::Column auto_increment: @@ -737,7 +742,7 @@ columns: - *9 notifications: - *5 - - *24 + - *21 - *6 - !ruby/object:ActiveRecord::ConnectionAdapters::SQLite3::Column auto_increment: @@ -783,7 +788,7 @@ columns: - *30 pins: - *5 - - *24 + - *21 - *6 - *9 - *30 @@ -869,7 +874,7 @@ columns: - *30 taggings: - *5 - - *24 + - *21 - *6 - *31 - *9 @@ -927,7 +932,7 @@ columns: - *9 watches: - *5 - - *24 + - *21 - *6 - *9 - *30 @@ -984,6 +989,7 @@ primary_keys: assigners_filters: assignments: id card_engagements: id + card_goldnesses: id cards: id closure_reasons: id closures: id @@ -1020,6 +1026,7 @@ data_sources: assigners_filters: true assignments: true card_engagements: true + card_goldnesses: true cards: true closure_reasons: true closures: true @@ -1048,10 +1055,9 @@ indexes: accesses: - !ruby/object:ActiveRecord::ConnectionAdapters::IndexDefinition table: accesses - name: index_accesses_on_collection_id_and_user_id - unique: true + name: index_accesses_on_user_id + unique: false columns: - - collection_id - user_id lengths: {} orders: {} @@ -1081,9 +1087,10 @@ indexes: valid: true - !ruby/object:ActiveRecord::ConnectionAdapters::IndexDefinition table: accesses - name: index_accesses_on_user_id - unique: false + name: index_accesses_on_collection_id_and_user_id + unique: true columns: + - collection_id - user_id lengths: {} orders: {} @@ -1303,10 +1310,9 @@ indexes: assignments: - !ruby/object:ActiveRecord::ConnectionAdapters::IndexDefinition table: assignments - name: index_assignments_on_assignee_id_and_card_id - unique: true + name: index_assignments_on_card_id + unique: false columns: - - assignee_id - card_id lengths: {} orders: {} @@ -1320,9 +1326,10 @@ indexes: valid: true - !ruby/object:ActiveRecord::ConnectionAdapters::IndexDefinition table: assignments - name: index_assignments_on_card_id - unique: false + name: index_assignments_on_assignee_id_and_card_id + unique: true columns: + - assignee_id - card_id lengths: {} orders: {} @@ -1351,7 +1358,57 @@ indexes: nulls_not_distinct: comment: valid: true + card_goldnesses: + - !ruby/object:ActiveRecord::ConnectionAdapters::IndexDefinition + table: card_goldnesses + name: index_card_goldnesses_on_card_id + unique: true + columns: + - card_id + lengths: {} + orders: {} + opclasses: {} + where: + type: + using: + include: + nulls_not_distinct: + comment: + valid: true cards: + - !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 + - !ruby/object:ActiveRecord::ConnectionAdapters::IndexDefinition + table: cards + name: index_cards_on_last_active_at_and_status + unique: false + columns: + - last_active_at + - status + lengths: {} + orders: {} + opclasses: {} + where: + type: + using: + include: + nulls_not_distinct: + comment: + valid: true - !ruby/object:ActiveRecord::ConnectionAdapters::IndexDefinition table: cards name: index_cards_on_collection_id @@ -1384,39 +1441,6 @@ indexes: nulls_not_distinct: comment: valid: true - - !ruby/object:ActiveRecord::ConnectionAdapters::IndexDefinition - table: cards - name: index_cards_on_last_active_at_and_status - unique: false - columns: - - last_active_at - - status - lengths: {} - orders: {} - opclasses: {} - where: - type: - using: - include: - 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 closure_reasons: - !ruby/object:ActiveRecord::ConnectionAdapters::IndexDefinition table: closure_reasons @@ -1435,6 +1459,22 @@ indexes: comment: valid: true closures: + - !ruby/object:ActiveRecord::ConnectionAdapters::IndexDefinition + table: closures + name: index_closures_on_user_id + unique: false + columns: + - user_id + lengths: {} + orders: {} + opclasses: {} + where: + type: + using: + include: + nulls_not_distinct: + comment: + valid: true - !ruby/object:ActiveRecord::ConnectionAdapters::IndexDefinition table: closures name: index_closures_on_card_id @@ -1468,29 +1508,13 @@ indexes: nulls_not_distinct: comment: valid: true - - !ruby/object:ActiveRecord::ConnectionAdapters::IndexDefinition - table: closures - name: index_closures_on_user_id - unique: false - columns: - - user_id - lengths: {} - orders: {} - opclasses: {} - where: - type: - using: - include: - nulls_not_distinct: - comment: - valid: true collections: - !ruby/object:ActiveRecord::ConnectionAdapters::IndexDefinition table: collections - name: index_collections_on_account_id + name: index_collections_on_workflow_id unique: false columns: - - account_id + - workflow_id lengths: {} orders: {} opclasses: {} @@ -1519,10 +1543,10 @@ indexes: valid: true - !ruby/object:ActiveRecord::ConnectionAdapters::IndexDefinition table: collections - name: index_collections_on_workflow_id + name: index_collections_on_account_id unique: false columns: - - workflow_id + - account_id lengths: {} orders: {} opclasses: {} @@ -1536,10 +1560,10 @@ indexes: collections_filters: - !ruby/object:ActiveRecord::ConnectionAdapters::IndexDefinition table: collections_filters - name: index_collections_filters_on_collection_id + name: index_collections_filters_on_filter_id unique: false columns: - - collection_id + - filter_id lengths: {} orders: {} opclasses: {} @@ -1552,10 +1576,10 @@ indexes: valid: true - !ruby/object:ActiveRecord::ConnectionAdapters::IndexDefinition table: collections_filters - name: index_collections_filters_on_filter_id + name: index_collections_filters_on_collection_id unique: false columns: - - filter_id + - collection_id lengths: {} orders: {} opclasses: {} @@ -1602,22 +1626,6 @@ indexes: valid: true event_summaries: [] events: - - !ruby/object:ActiveRecord::ConnectionAdapters::IndexDefinition - table: events - name: index_events_on_card_id - unique: false - columns: - - card_id - lengths: {} - orders: {} - opclasses: {} - where: - type: - using: - include: - nulls_not_distinct: - comment: - valid: true - !ruby/object:ActiveRecord::ConnectionAdapters::IndexDefinition table: events name: index_events_on_summary_id_and_action @@ -1651,6 +1659,22 @@ indexes: nulls_not_distinct: comment: valid: true + - !ruby/object:ActiveRecord::ConnectionAdapters::IndexDefinition + table: events + name: index_events_on_card_id + unique: false + columns: + - card_id + lengths: {} + orders: {} + opclasses: {} + where: + type: + using: + include: + nulls_not_distinct: + comment: + valid: true filters: - !ruby/object:ActiveRecord::ConnectionAdapters::IndexDefinition table: filters @@ -1736,22 +1760,6 @@ indexes: comment: valid: true messages: - - !ruby/object:ActiveRecord::ConnectionAdapters::IndexDefinition - table: messages - name: index_messages_on_card_id - unique: false - columns: - - card_id - lengths: {} - orders: {} - opclasses: {} - where: - type: - using: - include: - nulls_not_distinct: - comment: - valid: true - !ruby/object:ActiveRecord::ConnectionAdapters::IndexDefinition table: messages name: index_messages_on_messageable @@ -1769,10 +1777,9 @@ indexes: nulls_not_distinct: comment: valid: true - notifications: - !ruby/object:ActiveRecord::ConnectionAdapters::IndexDefinition - table: notifications - name: index_notifications_on_card_id + table: messages + name: index_messages_on_card_id unique: false columns: - card_id @@ -1786,6 +1793,7 @@ indexes: nulls_not_distinct: comment: valid: true + notifications: - !ruby/object:ActiveRecord::ConnectionAdapters::IndexDefinition table: notifications name: index_notifications_on_user_id @@ -1855,13 +1863,28 @@ indexes: nulls_not_distinct: comment: valid: true + - !ruby/object:ActiveRecord::ConnectionAdapters::IndexDefinition + table: notifications + name: index_notifications_on_card_id + unique: false + columns: + - card_id + lengths: {} + orders: {} + opclasses: {} + where: + type: + using: + include: + nulls_not_distinct: + comment: + valid: true pins: - !ruby/object:ActiveRecord::ConnectionAdapters::IndexDefinition table: pins - name: index_pins_on_card_id_and_user_id - unique: true + name: index_pins_on_user_id + unique: false columns: - - card_id - user_id lengths: {} orders: {} @@ -1891,9 +1914,10 @@ indexes: valid: true - !ruby/object:ActiveRecord::ConnectionAdapters::IndexDefinition table: pins - name: index_pins_on_user_id - unique: false + name: index_pins_on_card_id_and_user_id + unique: true columns: + - card_id - user_id lengths: {} orders: {} @@ -1959,10 +1983,9 @@ indexes: taggings: - !ruby/object:ActiveRecord::ConnectionAdapters::IndexDefinition table: taggings - name: index_taggings_on_card_id_and_tag_id - unique: true + name: index_taggings_on_tag_id + unique: false columns: - - card_id - tag_id lengths: {} orders: {} @@ -1976,9 +1999,10 @@ indexes: valid: true - !ruby/object:ActiveRecord::ConnectionAdapters::IndexDefinition table: taggings - name: index_taggings_on_tag_id - unique: false + name: index_taggings_on_card_id_and_tag_id + unique: true columns: + - card_id - tag_id lengths: {} orders: {} @@ -2076,10 +2100,10 @@ indexes: watches: - !ruby/object:ActiveRecord::ConnectionAdapters::IndexDefinition table: watches - name: index_watches_on_card_id + name: index_watches_on_user_id unique: false columns: - - card_id + - user_id lengths: {} orders: {} opclasses: {} @@ -2092,10 +2116,10 @@ indexes: valid: true - !ruby/object:ActiveRecord::ConnectionAdapters::IndexDefinition table: watches - name: index_watches_on_user_id + name: index_watches_on_card_id unique: false columns: - - user_id + - card_id lengths: {} orders: {} opclasses: {} @@ -2140,4 +2164,4 @@ indexes: nulls_not_distinct: comment: valid: true -version: 20250409201424 +version: 20250410141409 From 2e5b25a30c14f07afd5b23233b293931c2fe1596 Mon Sep 17 00:00:00 2001 From: Jorge Manrubia Date: Thu, 10 Apr 2025 17:05:30 +0200 Subject: [PATCH 02/31] Always place golden cards first --- app/controllers/cards_controller.rb | 6 +++--- app/models/card/golden.rb | 6 ++++++ app/views/cards/display/_preview.html.erb | 2 +- 3 files changed, 10 insertions(+), 4 deletions(-) diff --git a/app/controllers/cards_controller.rb b/app/controllers/cards_controller.rb index d0b751613..bdb40be8c 100644 --- a/app/controllers/cards_controller.rb +++ b/app/controllers/cards_controller.rb @@ -10,7 +10,7 @@ class CardsController < ApplicationController def index @considering = page_and_filter_for @filter.with(engagement_status: "considering"), per_page: PAGE_SIZE - @doing = page_and_filter_for @filter.with(engagement_status: "doing"), per_page: PAGE_SIZE + @doing = page_and_filter_for @filter.with(engagement_status: "doing"), cards: @filter.cards.golden_first, per_page: PAGE_SIZE @closed = page_and_filter_for @filter.with(indexed_by: "closed"), per_page: PAGE_SIZE end @@ -39,9 +39,9 @@ class CardsController < ApplicationController @card = @collection.cards.find params[:id] end - def page_and_filter_for(filter, per_page: nil) + def page_and_filter_for(filter, per_page: nil, cards: filter.cards) OpenStruct.new \ - page: GearedPagination::Recordset.new(filter.cards, per_page:).page(1), + page: GearedPagination::Recordset.new(cards, per_page:).page(1), filter: filter end diff --git a/app/models/card/golden.rb b/app/models/card/golden.rb index 339b8cab6..bc912431c 100644 --- a/app/models/card/golden.rb +++ b/app/models/card/golden.rb @@ -6,6 +6,12 @@ module Card::Golden scope :non_golden, -> { where.missing(:goldness) } has_one :goldness, dependent: :destroy, class_name: "Card::Goldness" + + scope :golden_first, -> do + left_outer_joins(:goldness).tap do |relation| + relation.order_values.unshift("card_goldnesses.id IS NULL") + end + end end def golden? diff --git a/app/views/cards/display/_preview.html.erb b/app/views/cards/display/_preview.html.erb index 035c72e58..e7a723a1b 100644 --- a/app/views/cards/display/_preview.html.erb +++ b/app/views/cards/display/_preview.html.erb @@ -1,5 +1,5 @@ <% cache [ card ] do %> -
From 9029853bdfe31a91165b68d0cd465ccf6f76c503 Mon Sep 17 00:00:00 2001 From: Jorge Manrubia Date: Thu, 10 Apr 2025 17:11:00 +0200 Subject: [PATCH 03/31] Only show the button when card is in "doing" --- app/views/cards/_golden_toggle.html.erb | 6 +++--- app/views/cards/show.html.erb | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/app/views/cards/_golden_toggle.html.erb b/app/views/cards/_golden_toggle.html.erb index e1c475484..f04e14355 100644 --- a/app/views/cards/_golden_toggle.html.erb +++ b/app/views/cards/_golden_toggle.html.erb @@ -1,10 +1,10 @@ -<% if @card.golden? %> - <%= button_to card_goldeness_path(@card), method: :delete, class: "btn btn--reversed" do %> +<% if card.golden? %> + <%= button_to card_goldeness_path(card), method: :delete, class: "btn btn--reversed" do %> <%= icon_tag "star" %> Demote to normal <% end %> <% else %> - <%= button_to card_goldeness_path(@card), class: "btn" do %> + <%= button_to card_goldeness_path(card), class: "btn" do %> <%= icon_tag "star" %> Promote to golden <% end %> diff --git a/app/views/cards/show.html.erb b/app/views/cards/show.html.erb index d7a122b37..2ee0d121e 100644 --- a/app/views/cards/show.html.erb +++ b/app/views/cards/show.html.erb @@ -55,7 +55,7 @@ <%= render "cards/display/perma", card: @card %>
- <%= render "cards/golden_toggle" %> + <%= render "cards/golden_toggle", card: @card if @card.doing? %> <%= render "cards/image", card: @card %> <%= button_to collection_card_path(@card.collection, @card), From 9747d590eae0fd0d4eb34598cdbbac92318c48af Mon Sep 17 00:00:00 2001 From: Jorge Manrubia Date: Thu, 10 Apr 2025 17:16:36 +0200 Subject: [PATCH 04/31] Not used --- app/models/card/golden.rb | 1 - 1 file changed, 1 deletion(-) diff --git a/app/models/card/golden.rb b/app/models/card/golden.rb index bc912431c..b3206e248 100644 --- a/app/models/card/golden.rb +++ b/app/models/card/golden.rb @@ -3,7 +3,6 @@ module Card::Golden included do scope :golden, -> { joins(:goldness) } - scope :non_golden, -> { where.missing(:goldness) } has_one :goldness, dependent: :destroy, class_name: "Card::Goldness" From fac2fce3d551bbc0618771e24027776dff786f09 Mon Sep 17 00:00:00 2001 From: Jorge Manrubia Date: Thu, 10 Apr 2025 17:18:02 +0200 Subject: [PATCH 05/31] Rename scope --- app/controllers/cards_controller.rb | 2 +- app/models/card/golden.rb | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/controllers/cards_controller.rb b/app/controllers/cards_controller.rb index bdb40be8c..21b6f0dbd 100644 --- a/app/controllers/cards_controller.rb +++ b/app/controllers/cards_controller.rb @@ -10,7 +10,7 @@ class CardsController < ApplicationController def index @considering = page_and_filter_for @filter.with(engagement_status: "considering"), per_page: PAGE_SIZE - @doing = page_and_filter_for @filter.with(engagement_status: "doing"), cards: @filter.cards.golden_first, per_page: PAGE_SIZE + @doing = page_and_filter_for @filter.with(engagement_status: "doing"), cards: @filter.cards.with_golden_first, per_page: PAGE_SIZE @closed = page_and_filter_for @filter.with(indexed_by: "closed"), per_page: PAGE_SIZE end diff --git a/app/models/card/golden.rb b/app/models/card/golden.rb index b3206e248..c8553f6be 100644 --- a/app/models/card/golden.rb +++ b/app/models/card/golden.rb @@ -6,7 +6,7 @@ module Card::Golden has_one :goldness, dependent: :destroy, class_name: "Card::Goldness" - scope :golden_first, -> do + scope :with_golden_first, -> do left_outer_joins(:goldness).tap do |relation| relation.order_values.unshift("card_goldnesses.id IS NULL") end From 81ee2ab64d21b9912a24d66a0a685f78344c364a Mon Sep 17 00:00:00 2001 From: Jason Zimdars Date: Thu, 10 Apr 2025 16:06:35 -0500 Subject: [PATCH 06/31] Try a segmented toggle for engagement --- app/assets/stylesheets/buttons.css | 30 +++++++++++++++++++++- app/assets/stylesheets/cards.css | 40 ++++++++++++++---------------- app/views/cards/show.html.erb | 32 +++++++++++------------- 3 files changed, 62 insertions(+), 40 deletions(-) diff --git a/app/assets/stylesheets/buttons.css b/app/assets/stylesheets/buttons.css index 75c8baf10..a6e1e1139 100644 --- a/app/assets/stylesheets/buttons.css +++ b/app/assets/stylesheets/buttons.css @@ -109,7 +109,7 @@ display: none; } } - + &:has(input:checked) { --btn-background: var(--color-ink); --btn-color: var(--color-ink-reversed); @@ -188,5 +188,33 @@ animation: zoom-fade 300ms ease-out; } } + + .btn__group { + .btn { + --btn-border-radius: 0; + inline-size: 100%; + justify-content: center; + } + + form { + flex: 1 1 0%; + } + + :first-of-type .btn { + border-top-left-radius: 2em; + border-bottom-left-radius: 2em; + flex: 1 0 50%; + } + + :last-of-type .btn { + border-top-right-radius: 2em; + border-bottom-right-radius: 2em; + flex: 1 0 50%; + } + + span { + inline-size: 100%; + } + } } diff --git a/app/assets/stylesheets/cards.css b/app/assets/stylesheets/cards.css index 55f3d88d6..1431180c3 100644 --- a/app/assets/stylesheets/cards.css +++ b/app/assets/stylesheets/cards.css @@ -112,12 +112,12 @@ } .card__actions-container { - --border-radius: 1em; + --border-radius: 6em; background-color: var(--color-bg); color: color-mix(in srgb, var(--card-color) 40%, var(--color-ink)); margin-block: calc(var(--block-space) * -1.66) calc(var(--block-space) * 1.66); - padding: calc(var(--block-space) * 0.66) calc(var(--inline-space) * 1.5); + padding: calc(var(--block-space) * 0.75) calc(var(--block-space) * 0.66); position: relative; z-index: 0; @@ -125,7 +125,7 @@ z-index: 1; } - .btn:not(.popup__item, .btn--plain) { + .btn:not(.popup__item, .btn--plain, :has(input[type="radio"])) { --btn-background: var(--card-color); --btn-color: var(--color-ink-reversed); } @@ -139,28 +139,26 @@ .card__closure-message { color: var(--card-color); } - } - .card__actions-container--top { - min-inline-size: 36ch; - margin: calc(var(--block-space) * 1) auto calc(var(--block-space) * -0.33); - padding: 0.5em 0.75em; + &.card__actions-container--top { + margin: calc(var(--block-space) * 1) auto calc(var(--block-space) * -0.66); + min-inline-size: 30ch; + + #header:has(&) { + position: relative; + z-index: 1; + } - #header:has(&) { - position: relative; - z-index: 1; - } + .btn { + --btn-border-color: var(--card-color); + --btn-color: var(--card-color); - .switch__input:checked + .switch__btn { - background-color: var(--card-color) !important; - } + text-align: center; - strong { - flex: 1 0 42%; - text-align: end; - - &:last-of-type { - text-align: start; + &:has(input:checked) { + --btn-background: var(--card-color); + --btn-color: var(--color-ink-reversed); + } } } } diff --git a/app/views/cards/show.html.erb b/app/views/cards/show.html.erb index 753c2e464..7e8188186 100644 --- a/app/views/cards/show.html.erb +++ b/app/views/cards/show.html.erb @@ -23,26 +23,22 @@ <%= link_to_home %> <%= link_to_back fallback_path: cards_path(collection_id: @card.collection) %> -
- Considering - <% if @card.doing? %> - <%= form_with url: card_engagement_path(@card), method: :delete, data: { controller: "form" }, class: "flex" do %> - +
+
+ <%= form_with url: card_engagement_path(@card), method: :delete, data: { controller: "form" } do |form| %> + <%= form.label :engagement, value: "considering", class: "btn", aria: { label: "Move to Doing"} do %> + <%= form.radio_button :engagement, "considering", checked: @card.considering?, class: "for-screen-reader", data: { action: "change->form#submit" } %> + Considering + <% end %> <% end %> - <% else %> - <%= form_with url: card_engagement_path(@card), method: :post, data: { controller: "form" }, class: "flex" do %> - + + <%= form_with url: card_engagement_path(@card), method: :post, data: { controller: "form" } do |form| %> + <%= form.label :engagement, value: "doing", class: "btn", aria: { label: "Move back to Considering"} do %> + <%= form.radio_button :engagement, "doing", checked: @card.doing?, class: "for-screen-reader", data: { action: "change->form#submit" } %> + Doing + <% end %> <% end %> - <% end %> - Doing +
From 0c107c5894a6f074ba261d4c8c21ff7c25d62dd0 Mon Sep 17 00:00:00 2001 From: Jason Zimdars Date: Thu, 10 Apr 2025 16:42:40 -0500 Subject: [PATCH 07/31] Fix that cards which were Drafted or in Considering were also being displayed in Doing CC: @jorgemanrubia --- app/controllers/cards_controller.rb | 2 +- app/models/card.rb | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/controllers/cards_controller.rb b/app/controllers/cards_controller.rb index 21b6f0dbd..1402d5943 100644 --- a/app/controllers/cards_controller.rb +++ b/app/controllers/cards_controller.rb @@ -10,7 +10,7 @@ class CardsController < ApplicationController def index @considering = page_and_filter_for @filter.with(engagement_status: "considering"), per_page: PAGE_SIZE - @doing = page_and_filter_for @filter.with(engagement_status: "doing"), cards: @filter.cards.with_golden_first, per_page: PAGE_SIZE + @doing = page_and_filter_for @filter.with(engagement_status: "doing"), per_page: PAGE_SIZE @closed = page_and_filter_for @filter.with(indexed_by: "closed"), per_page: PAGE_SIZE end diff --git a/app/models/card.rb b/app/models/card.rb index 46907bf3d..bf1007743 100644 --- a/app/models/card.rb +++ b/app/models/card.rb @@ -33,7 +33,7 @@ class Card < ApplicationRecord scope :by_engagement_status, ->(status) do case status.to_s when "considering" then considering - when "doing" then doing + when "doing" then doing.with_golden_first end end From da7a30203cc6f851fccbde82c50748ffb7ff4ff5 Mon Sep 17 00:00:00 2001 From: Jason Zimdars Date: Thu, 10 Apr 2025 17:14:04 -0500 Subject: [PATCH 08/31] Style golden cards --- app/assets/images/golden-ticket.svg | 1 + app/assets/images/star.svg | 1 - app/assets/stylesheets/_global.css | 2 ++ app/assets/stylesheets/cards.css | 15 ++++++++------- app/assets/stylesheets/icons.css | 2 +- app/views/cards/_golden_toggle.html.erb | 4 ++-- 6 files changed, 14 insertions(+), 11 deletions(-) create mode 100644 app/assets/images/golden-ticket.svg delete mode 100644 app/assets/images/star.svg diff --git a/app/assets/images/golden-ticket.svg b/app/assets/images/golden-ticket.svg new file mode 100644 index 000000000..99d44fdf8 --- /dev/null +++ b/app/assets/images/golden-ticket.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/app/assets/images/star.svg b/app/assets/images/star.svg deleted file mode 100644 index 281a18051..000000000 --- a/app/assets/images/star.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/app/assets/stylesheets/_global.css b/app/assets/stylesheets/_global.css index 8dc17b990..4711ea25d 100644 --- a/app/assets/stylesheets/_global.css +++ b/app/assets/stylesheets/_global.css @@ -31,6 +31,7 @@ --lch-blue: 54% 0.15 255; --lch-blue-light: 95% 0.03 255; --lch-blue-dark: 80% 0.08 255; + --lch-golden: 83% 0.1128 72.43; --lch-orange: 70% 0.2 44; --lch-red: 51% 0.2 31; --lch-green: 65.59% 0.234 142.49; @@ -58,6 +59,7 @@ --color-always-black: oklch(var(--lch-always-black)); --color-always-white: oklch(var(--lch-always-white)); --color-container: oklch(var(--lch-light-blue)); + --color-golden: oklch(var(--lch-golden)); @media (prefers-color-scheme: dark) { --lch-black: 100% 0 0; diff --git a/app/assets/stylesheets/cards.css b/app/assets/stylesheets/cards.css index b8f36e67c..1a8325e45 100644 --- a/app/assets/stylesheets/cards.css +++ b/app/assets/stylesheets/cards.css @@ -98,7 +98,14 @@ } .card--golden { - outline: 5px solid orange; + --border-color: var(--color-bg) !important; + + background-color: var(--color-bg); + background-image: linear-gradient(90deg, oklch(var(--lch-golden) / 0.5) 0%, oklch(var(--lch-golden) / 0.1) 50%, oklch(var(--lch-golden) / 0.75) 100%); + box-shadow: + 0 0 0.5em 0.2em var(--color-golden), + 0 0 1em 0.4em var(--color-golden) !important; + outline: 1px solid var(--color-golden); } .card__actions { @@ -251,12 +258,6 @@ display: inline-flex; margin-block: calc(var(--block-space) * -1) calc(var(--block-space) * -0.33); padding: var(--padding-block) var(--padding-inline); - - &:has(.card__star-input:checked) { - .card { - outline: 4px solid var(--color-negative); - } - } } .card__container--pointing { diff --git a/app/assets/stylesheets/icons.css b/app/assets/stylesheets/icons.css index 1f3d193dc..987210def 100644 --- a/app/assets/stylesheets/icons.css +++ b/app/assets/stylesheets/icons.css @@ -38,6 +38,7 @@ .icon--everyone { --svg: url("everyone.svg "); } .icon--filter { --svg: url("filter.svg "); } .icon--globe { --svg: url("globe.svg "); } + .icon--golden-ticket { --svg: url("golden-ticket.svg "); } .icon--home { --svg: url("home.svg "); } .icon--logout { --svg: url("logout.svg "); } .icon--menu { --svg: url("menu.svg "); } @@ -61,7 +62,6 @@ .icon--rename { --svg: url("rename.svg "); } .icon--settings { --svg: url("settings.svg "); } .icon--share { --svg: url("share.svg "); } - .icon--star { --svg: url("star.svg "); } .icon--tag { --svg: url("tag.svg "); } .icon--thumb-up { --svg: url("thumb-up.svg "); } .icon--trash { --svg: url("trash.svg "); } diff --git a/app/views/cards/_golden_toggle.html.erb b/app/views/cards/_golden_toggle.html.erb index f04e14355..3456bea4b 100644 --- a/app/views/cards/_golden_toggle.html.erb +++ b/app/views/cards/_golden_toggle.html.erb @@ -1,11 +1,11 @@ <% if card.golden? %> <%= button_to card_goldeness_path(card), method: :delete, class: "btn btn--reversed" do %> - <%= icon_tag "star" %> + <%= icon_tag "golden-ticket" %> Demote to normal <% end %> <% else %> <%= button_to card_goldeness_path(card), class: "btn" do %> - <%= icon_tag "star" %> + <%= icon_tag "golden-ticket" %> Promote to golden <% end %> <% end %> From 1bac0b84b32eee1017889451026289458b8dccac Mon Sep 17 00:00:00 2001 From: Jorge Manrubia Date: Fri, 11 Apr 2025 09:36:24 +0200 Subject: [PATCH 09/31] Add tests --- .../cards/goldenesses_controller_test.rb | 27 +++++++++++++++++ test/fixtures/card/engagements.yml | 2 +- test/fixtures/card/goldnesses.yml | 2 ++ test/models/card/golden_test.rb | 30 +++++++++++++++++++ 4 files changed, 60 insertions(+), 1 deletion(-) create mode 100644 test/controllers/cards/goldenesses_controller_test.rb create mode 100644 test/fixtures/card/goldnesses.yml create mode 100644 test/models/card/golden_test.rb diff --git a/test/controllers/cards/goldenesses_controller_test.rb b/test/controllers/cards/goldenesses_controller_test.rb new file mode 100644 index 000000000..245ccc180 --- /dev/null +++ b/test/controllers/cards/goldenesses_controller_test.rb @@ -0,0 +1,27 @@ +require "test_helper" + +class Cards::GoldenessesControllerTest < ActionDispatch::IntegrationTest + setup do + sign_in_as :kevin + end + + test "create" do + card = cards(:text) + + assert_changes -> { card.reload.golden? }, from: false, to: true do + post card_goldeness_url(card) + end + + assert_redirected_to collection_card_url(card.collection, card) + end + + test "destroy" do + card = cards(:logo) + + assert_changes -> { card.reload.golden? }, from: true, to: false do + delete card_goldeness_url(card) + end + + assert_redirected_to collection_card_url(card.collection, card) + end +end diff --git a/test/fixtures/card/engagements.yml b/test/fixtures/card/engagements.yml index f15900c8b..77657385b 100644 --- a/test/fixtures/card/engagements.yml +++ b/test/fixtures/card/engagements.yml @@ -1,2 +1,2 @@ -logo_engagement: +logo: card: logo diff --git a/test/fixtures/card/goldnesses.yml b/test/fixtures/card/goldnesses.yml new file mode 100644 index 000000000..77657385b --- /dev/null +++ b/test/fixtures/card/goldnesses.yml @@ -0,0 +1,2 @@ +logo: + card: logo diff --git a/test/models/card/golden_test.rb b/test/models/card/golden_test.rb new file mode 100644 index 000000000..b20b16e9f --- /dev/null +++ b/test/models/card/golden_test.rb @@ -0,0 +1,30 @@ +require "test_helper" + +class Card::GoldenTest < ActiveSupport::TestCase + setup do + Current.session = sessions(:david) + end + + test "check whether a card is golden" do + assert cards(:logo).golden? + assert_not cards(:text).golden? + end + + test "promote and demote from golden" do + assert_changes -> { cards(:text).reload.golden? }, to: true do + cards(:text).promote_to_golden + end + + assert_changes -> { cards(:logo).reload.golden? }, to: false do + cards(:logo).demote_from_golden + end + end + + test "scopes" do + assert_includes Card.doing, cards(:logo) + assert_not_includes Card.doing, cards(:text) + + assert_includes Card.considering, cards(:text) + assert_not_includes Card.considering, cards(:logo) + end +end From 5360b4ccb4f2af29b3fa1110845351b2fa2e0766 Mon Sep 17 00:00:00 2001 From: Jorge Manrubia Date: Fri, 11 Apr 2025 09:49:34 +0200 Subject: [PATCH 10/31] Add comment --- app/models/card/golden.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/app/models/card/golden.rb b/app/models/card/golden.rb index c8553f6be..340997fd7 100644 --- a/app/models/card/golden.rb +++ b/app/models/card/golden.rb @@ -8,6 +8,7 @@ module Card::Golden scope :with_golden_first, -> do left_outer_joins(:goldness).tap do |relation| + # Make sure it can be layered in with other orderings taking precedence. relation.order_values.unshift("card_goldnesses.id IS NULL") end end From 492a42ba92bda931ff71c553e844358ab1e11aaf Mon Sep 17 00:00:00 2001 From: Jorge Manrubia Date: Fri, 11 Apr 2025 09:50:47 +0200 Subject: [PATCH 11/31] Not needed anymore --- app/controllers/cards_controller.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/controllers/cards_controller.rb b/app/controllers/cards_controller.rb index 07bb6e50f..103c05e99 100644 --- a/app/controllers/cards_controller.rb +++ b/app/controllers/cards_controller.rb @@ -39,9 +39,9 @@ class CardsController < ApplicationController @card = @collection.cards.find params[:id] end - def page_and_filter_for(filter, per_page: nil, cards: filter.cards) + def page_and_filter_for(filter, per_page: nil) OpenStruct.new \ - page: GearedPagination::Recordset.new(cards, per_page:).page(1), + page: GearedPagination::Recordset.new(filter.cards, per_page:).page(1), filter: filter end From f4b2bec5ce954dad8eee432fe9eab86c0ca5df17 Mon Sep 17 00:00:00 2001 From: Jorge Manrubia Date: Fri, 11 Apr 2025 09:54:34 +0200 Subject: [PATCH 12/31] Fix test --- test/models/card/golden_test.rb | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/test/models/card/golden_test.rb b/test/models/card/golden_test.rb index b20b16e9f..2d26101d3 100644 --- a/test/models/card/golden_test.rb +++ b/test/models/card/golden_test.rb @@ -21,10 +21,7 @@ class Card::GoldenTest < ActiveSupport::TestCase end test "scopes" do - assert_includes Card.doing, cards(:logo) - assert_not_includes Card.doing, cards(:text) - - assert_includes Card.considering, cards(:text) - assert_not_includes Card.considering, cards(:logo) + assert_includes Card.golden, cards(:logo) + assert_not_includes Card.golden, cards(:text) end end From b4297ab852cc51e0567eb8c0adb27f87baa86026 Mon Sep 17 00:00:00 2001 From: Jorge Manrubia Date: Fri, 11 Apr 2025 09:55:40 +0200 Subject: [PATCH 13/31] Format --- app/models/card.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/models/card.rb b/app/models/card.rb index fdbf46cb7..8d4411cf4 100644 --- a/app/models/card.rb +++ b/app/models/card.rb @@ -35,7 +35,7 @@ class Card < ApplicationRecord scope :by_engagement_status, ->(status) do case status.to_s when "considering" then considering - when "doing" then doing.with_golden_first + when "doing" then doing.with_golden_first end end From 806609e77b53a1887e450f6a53f3072a0e2603f6 Mon Sep 17 00:00:00 2001 From: Jorge Manrubia Date: Fri, 11 Apr 2025 10:20:06 +0200 Subject: [PATCH 14/31] Use gild/ungild --- app/controllers/cards/goldenesses_controller.rb | 4 ++-- app/models/card/golden.rb | 4 ++-- test/models/card/golden_test.rb | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/app/controllers/cards/goldenesses_controller.rb b/app/controllers/cards/goldenesses_controller.rb index 974610569..2d1045402 100644 --- a/app/controllers/cards/goldenesses_controller.rb +++ b/app/controllers/cards/goldenesses_controller.rb @@ -2,12 +2,12 @@ class Cards::GoldenessesController < ApplicationController include CardScoped def create - @card.promote_to_golden + @card.gild redirect_to @card end def destroy - @card.demote_from_golden + @card.ungild redirect_to @card end end diff --git a/app/models/card/golden.rb b/app/models/card/golden.rb index 340997fd7..92fd3a199 100644 --- a/app/models/card/golden.rb +++ b/app/models/card/golden.rb @@ -18,11 +18,11 @@ module Card::Golden goldness.present? end - def promote_to_golden + def gild create_goldness! unless golden? end - def demote_from_golden + def ungild goldness&.destroy end end diff --git a/test/models/card/golden_test.rb b/test/models/card/golden_test.rb index 2d26101d3..be501c754 100644 --- a/test/models/card/golden_test.rb +++ b/test/models/card/golden_test.rb @@ -12,11 +12,11 @@ class Card::GoldenTest < ActiveSupport::TestCase test "promote and demote from golden" do assert_changes -> { cards(:text).reload.golden? }, to: true do - cards(:text).promote_to_golden + cards(:text).gild end assert_changes -> { cards(:logo).reload.golden? }, to: false do - cards(:logo).demote_from_golden + cards(:logo).ungild end end From eae1669ac30300fbdf7255176fb98e9cf2eeeae1 Mon Sep 17 00:00:00 2001 From: Jorge Manrubia Date: Fri, 11 Apr 2025 10:20:30 +0200 Subject: [PATCH 15/31] Touch --- app/models/card/goldness.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/models/card/goldness.rb b/app/models/card/goldness.rb index 5ef88fc0b..fc2697328 100644 --- a/app/models/card/goldness.rb +++ b/app/models/card/goldness.rb @@ -1,3 +1,3 @@ class Card::Goldness < ApplicationRecord - belongs_to :card + belongs_to :card, touch: true end From 4f3f32252871f6fdd3622d1142ce778e853d2915 Mon Sep 17 00:00:00 2001 From: Jorge Manrubia Date: Fri, 11 Apr 2025 10:22:18 +0200 Subject: [PATCH 16/31] Rename inconsistency: go with goldness --- .../{goldenesses_controller.rb => goldnesses_controller.rb} | 2 +- app/views/cards/_golden_toggle.html.erb | 4 ++-- config/routes.rb | 2 +- ...ses_controller_test.rb => goldnesses_controller_test.rb} | 6 +++--- 4 files changed, 7 insertions(+), 7 deletions(-) rename app/controllers/cards/{goldenesses_controller.rb => goldnesses_controller.rb} (70%) rename test/controllers/cards/{goldenesses_controller_test.rb => goldnesses_controller_test.rb} (76%) diff --git a/app/controllers/cards/goldenesses_controller.rb b/app/controllers/cards/goldnesses_controller.rb similarity index 70% rename from app/controllers/cards/goldenesses_controller.rb rename to app/controllers/cards/goldnesses_controller.rb index 2d1045402..4be611d14 100644 --- a/app/controllers/cards/goldenesses_controller.rb +++ b/app/controllers/cards/goldnesses_controller.rb @@ -1,4 +1,4 @@ -class Cards::GoldenessesController < ApplicationController +class Cards::GoldnessesController < ApplicationController include CardScoped def create diff --git a/app/views/cards/_golden_toggle.html.erb b/app/views/cards/_golden_toggle.html.erb index 3456bea4b..b3525f351 100644 --- a/app/views/cards/_golden_toggle.html.erb +++ b/app/views/cards/_golden_toggle.html.erb @@ -1,10 +1,10 @@ <% if card.golden? %> - <%= button_to card_goldeness_path(card), method: :delete, class: "btn btn--reversed" do %> + <%= button_to card_goldness_path(card), method: :delete, class: "btn btn--reversed" do %> <%= icon_tag "golden-ticket" %> Demote to normal <% end %> <% else %> - <%= button_to card_goldeness_path(card), class: "btn" do %> + <%= button_to card_goldness_path(card), class: "btn" do %> <%= icon_tag "golden-ticket" %> Promote to golden <% end %> diff --git a/config/routes.rb b/config/routes.rb index 25e6a0f62..70de37a31 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -22,7 +22,7 @@ Rails.application.routes.draw do resource :reading resource :recover resource :watch - resource :goldeness + resource :goldness resources :assignments resources :boosts diff --git a/test/controllers/cards/goldenesses_controller_test.rb b/test/controllers/cards/goldnesses_controller_test.rb similarity index 76% rename from test/controllers/cards/goldenesses_controller_test.rb rename to test/controllers/cards/goldnesses_controller_test.rb index 245ccc180..081a6ec61 100644 --- a/test/controllers/cards/goldenesses_controller_test.rb +++ b/test/controllers/cards/goldnesses_controller_test.rb @@ -1,6 +1,6 @@ require "test_helper" -class Cards::GoldenessesControllerTest < ActionDispatch::IntegrationTest +class Cards::GoldnessesControllerTest < ActionDispatch::IntegrationTest setup do sign_in_as :kevin end @@ -9,7 +9,7 @@ class Cards::GoldenessesControllerTest < ActionDispatch::IntegrationTest card = cards(:text) assert_changes -> { card.reload.golden? }, from: false, to: true do - post card_goldeness_url(card) + post card_goldness_url(card) end assert_redirected_to collection_card_url(card.collection, card) @@ -19,7 +19,7 @@ class Cards::GoldenessesControllerTest < ActionDispatch::IntegrationTest card = cards(:logo) assert_changes -> { card.reload.golden? }, from: true, to: false do - delete card_goldeness_url(card) + delete card_goldness_url(card) end assert_redirected_to collection_card_url(card.collection, card) From 17aa9b97e9496db031e87e2e8563a4b565c2cd4e Mon Sep 17 00:00:00 2001 From: Jorge Manrubia Date: Fri, 11 Apr 2025 10:28:12 +0200 Subject: [PATCH 17/31] Monkey patch a prepend_order method --- app/models/card/golden.rb | 7 +------ lib/rails_ext/prepend_order.rb | 16 ++++++++++++++++ 2 files changed, 17 insertions(+), 6 deletions(-) create mode 100644 lib/rails_ext/prepend_order.rb diff --git a/app/models/card/golden.rb b/app/models/card/golden.rb index 92fd3a199..759179415 100644 --- a/app/models/card/golden.rb +++ b/app/models/card/golden.rb @@ -6,12 +6,7 @@ module Card::Golden has_one :goldness, dependent: :destroy, class_name: "Card::Goldness" - scope :with_golden_first, -> do - left_outer_joins(:goldness).tap do |relation| - # Make sure it can be layered in with other orderings taking precedence. - relation.order_values.unshift("card_goldnesses.id IS NULL") - end - end + scope :with_golden_first, -> { left_outer_joins(:goldness).prepend_order("card_goldnesses.id IS NULL") } end def golden? diff --git a/lib/rails_ext/prepend_order.rb b/lib/rails_ext/prepend_order.rb new file mode 100644 index 000000000..b7eb995fa --- /dev/null +++ b/lib/rails_ext/prepend_order.rb @@ -0,0 +1,16 @@ +module ActiveRecordRelationPrependOrder + extend ActiveSupport::Concern + + included do + def prepend_order(*args) + new_orders = args.flatten.map { |arg| arg.is_a?(String) ? arg : arg.to_sql } + + spawn.tap do |relation| + relation.order_values = new_orders + order_values + end + end + end +end + +ActiveRecord::Relation.include(ActiveRecordRelationPrependOrder) +ActiveRecord::AssociationRelation.include(ActiveRecordRelationPrependOrder) From 66b5732264355bdae1c5261995fd76b5df0cc1a9 Mon Sep 17 00:00:00 2001 From: Jorge Manrubia Date: Fri, 11 Apr 2025 11:27:38 +0200 Subject: [PATCH 18/31] Place recently closed cards first --- app/controllers/cards_controller.rb | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/app/controllers/cards_controller.rb b/app/controllers/cards_controller.rb index 103c05e99..0b2a5fdf4 100644 --- a/app/controllers/cards_controller.rb +++ b/app/controllers/cards_controller.rb @@ -11,7 +11,7 @@ class CardsController < ApplicationController def index @considering = page_and_filter_for @filter.with(engagement_status: "considering", indexed_by: "latest"), per_page: PAGE_SIZE @doing = page_and_filter_for @filter.with(engagement_status: "doing", indexed_by: "latest"), per_page: PAGE_SIZE - @closed = page_and_filter_for @filter.with(indexed_by: "closed"), per_page: PAGE_SIZE + @closed = page_and_filter_for @filter.with(indexed_by: "closed") { |cards| cards.recently_closed_first }, per_page: PAGE_SIZE end def create @@ -40,8 +40,10 @@ class CardsController < ApplicationController end def page_and_filter_for(filter, per_page: nil) + cards = block_given? ? yield(filter.cards) : filter.cards + OpenStruct.new \ - page: GearedPagination::Recordset.new(filter.cards, per_page:).page(1), + page: GearedPagination::Recordset.new(cards, per_page:).page(1), filter: filter end From 1275abd99ea580e4c6c404ea4098803813b13304 Mon Sep 17 00:00:00 2001 From: Jorge Manrubia Date: Fri, 11 Apr 2025 11:37:02 +0200 Subject: [PATCH 19/31] Fix recently completed order for good! --- app/controllers/cards_controller.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/controllers/cards_controller.rb b/app/controllers/cards_controller.rb index 0b2a5fdf4..558f13d69 100644 --- a/app/controllers/cards_controller.rb +++ b/app/controllers/cards_controller.rb @@ -11,7 +11,7 @@ class CardsController < ApplicationController def index @considering = page_and_filter_for @filter.with(engagement_status: "considering", indexed_by: "latest"), per_page: PAGE_SIZE @doing = page_and_filter_for @filter.with(engagement_status: "doing", indexed_by: "latest"), per_page: PAGE_SIZE - @closed = page_and_filter_for @filter.with(indexed_by: "closed") { |cards| cards.recently_closed_first }, per_page: PAGE_SIZE + @closed = page_and_filter_for(@filter.with(indexed_by: "closed"), per_page: PAGE_SIZE) { |cards| cards.recently_closed_first } end def create From aef75feead9a1c0fae3e47bcf6fea2d9cc8263a2 Mon Sep 17 00:00:00 2001 From: Jorge Manrubia Date: Fri, 11 Apr 2025 11:45:06 +0200 Subject: [PATCH 20/31] Only consider golden those cards in "doing" --- app/helpers/cards_helper.rb | 4 ++++ app/views/cards/display/_perma.html.erb | 2 +- app/views/cards/display/_preview.html.erb | 2 +- 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/app/helpers/cards_helper.rb b/app/helpers/cards_helper.rb index ba75a6d4a..8c9cc0498 100644 --- a/app/helpers/cards_helper.rb +++ b/app/helpers/cards_helper.rb @@ -26,4 +26,8 @@ module CardsHelper class: "btn txt-small", **options end + + def golden_class_for(card) + "card--golden" if card.doing? && card.golden? + end end diff --git a/app/views/cards/display/_perma.html.erb b/app/views/cards/display/_perma.html.erb index bdc1a3c4d..adba7fb7f 100644 --- a/app/views/cards/display/_perma.html.erb +++ b/app/views/cards/display/_perma.html.erb @@ -1,5 +1,5 @@ <% cache card do %> -
diff --git a/app/views/cards/display/_preview.html.erb b/app/views/cards/display/_preview.html.erb index c8fcbe8c5..3d59c8fb7 100644 --- a/app/views/cards/display/_preview.html.erb +++ b/app/views/cards/display/_preview.html.erb @@ -1,5 +1,5 @@ <% cache [ card ] do %> -
From 825bbf808ef0cdbc95fe49db0220644cc25ee4cc Mon Sep 17 00:00:00 2001 From: Jorge Manrubia Date: Fri, 11 Apr 2025 12:01:52 +0200 Subject: [PATCH 21/31] Extract helper for card articles, use classes to determine when to show golden status --- app/assets/stylesheets/cards.css | 6 +++--- app/helpers/cards_helper.rb | 15 +++++++++++++-- app/views/cards/display/_perma.html.erb | 6 ++---- app/views/cards/display/_preview.html.erb | 6 ++---- 4 files changed, 20 insertions(+), 13 deletions(-) diff --git a/app/assets/stylesheets/cards.css b/app/assets/stylesheets/cards.css index 1a8325e45..61beab9b2 100644 --- a/app/assets/stylesheets/cards.css +++ b/app/assets/stylesheets/cards.css @@ -97,12 +97,12 @@ } } - .card--golden { + .card--golden.card--doing { --border-color: var(--color-bg) !important; background-color: var(--color-bg); background-image: linear-gradient(90deg, oklch(var(--lch-golden) / 0.5) 0%, oklch(var(--lch-golden) / 0.1) 50%, oklch(var(--lch-golden) / 0.75) 100%); - box-shadow: + box-shadow: 0 0 0.5em 0.2em var(--color-golden), 0 0 1em 0.4em var(--color-golden) !important; outline: 1px solid var(--color-golden); @@ -154,7 +154,7 @@ &.card__actions-container--top { margin: calc(var(--block-space) * 1) auto calc(var(--block-space) * -0.66); min-inline-size: 30ch; - + #header:has(&) { position: relative; z-index: 1; diff --git a/app/helpers/cards_helper.rb b/app/helpers/cards_helper.rb index 8c9cc0498..1546efd8e 100644 --- a/app/helpers/cards_helper.rb +++ b/app/helpers/cards_helper.rb @@ -27,7 +27,18 @@ module CardsHelper **options end - def golden_class_for(card) - "card--golden" if card.doing? && card.golden? + def card_article_tag(card, id: dom_id(card, :ticket), **options, &block) + classes = [ + options.delete(:class), + ("card--golden" if card.golden?), + ("card--doing" if card.doing?) + ].compact.join(" ") + + tag.article \ + id: id, + style: "--card-color: #{card.color}; view-transition-name: #{id}", + class: classes, + **options, + &block end end diff --git a/app/views/cards/display/_perma.html.erb b/app/views/cards/display/_perma.html.erb index adba7fb7f..c4c89046c 100644 --- a/app/views/cards/display/_perma.html.erb +++ b/app/views/cards/display/_perma.html.erb @@ -1,7 +1,5 @@ <% cache card do %> -
+ <%= card_article_tag card, class: "card shadow border flex flex-column position-relative txt-align-start border-radius" do %>
<%= link_to card.collection.name, cards_path(collection_ids: [card.collection]), class: "card__collection txt-uppercase overflow-ellipsis txt-reversed" %> @@ -39,5 +37,5 @@ <%= render "cards/display/common/background", card: card %> -
+ <% end %> <% end %> diff --git a/app/views/cards/display/_preview.html.erb b/app/views/cards/display/_preview.html.erb index 3d59c8fb7..ceffc0867 100644 --- a/app/views/cards/display/_preview.html.erb +++ b/app/views/cards/display/_preview.html.erb @@ -1,7 +1,5 @@ <% cache [ card ] do %> -
+ <%= card_article_tag card, class: "card shadow border flex flex-column position-relative txt-align-start full-width border-radius" do %>
<%= card.collection.name %> <%= render "cards/display/preview/tags", card: card %> @@ -26,5 +24,5 @@ <%= render "cards/display/common/background", card: card %> -
+ <% end %> <% end %> From ba6eab509cf49e63dc5974faa75d46eb9d19eec7 Mon Sep 17 00:00:00 2001 From: Jorge Manrubia Date: Fri, 11 Apr 2025 13:05:56 +0200 Subject: [PATCH 22/31] Refresh timers when morphing happens --- app/javascript/controllers/local_time_controller.js | 8 ++++++++ app/views/layouts/application.html.erb | 2 +- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/app/javascript/controllers/local_time_controller.js b/app/javascript/controllers/local_time_controller.js index bdfbe677a..3bc77b769 100644 --- a/app/javascript/controllers/local_time_controller.js +++ b/app/javascript/controllers/local_time_controller.js @@ -24,6 +24,14 @@ export default class extends Controller { clearInterval(this.#timer) } + refreshAll() { + this.constructor.targets.forEach(targetName => { + this.targets.findAll(targetName).forEach(target => { + this.#formatTime(this[`${targetName}Formatter`], target) + }) + }) + } + timeTargetConnected(target) { this.#formatTime(this.timeFormatter, target) } diff --git a/app/views/layouts/application.html.erb b/app/views/layouts/application.html.erb index 1e6afa890..e886c519f 100644 --- a/app/views/layouts/application.html.erb +++ b/app/views/layouts/application.html.erb @@ -25,7 +25,7 @@ - +
<% end %> <% end %> diff --git a/app/views/comments/_comment.html.erb b/app/views/cards/comments/_comment.html.erb similarity index 77% rename from app/views/comments/_comment.html.erb rename to app/views/cards/comments/_comment.html.erb index f90ed8ee6..c866f30f0 100644 --- a/app/views/comments/_comment.html.erb +++ b/app/views/cards/comments/_comment.html.erb @@ -3,5 +3,5 @@ <%= avatar_tag comment.creator, hidden_for_screen_reader: true %> - <%= render "comments/body", comment: comment %> + <%= render "cards/comments/body", comment: comment %> <% end %> diff --git a/app/views/comments/_new.html.erb b/app/views/cards/comments/_new.html.erb similarity index 89% rename from app/views/comments/_new.html.erb rename to app/views/cards/comments/_new.html.erb index 8c75edcf1..2352d1797 100644 --- a/app/views/comments/_new.html.erb +++ b/app/views/cards/comments/_new.html.erb @@ -5,7 +5,7 @@
- <%= form_with model: Comment.new, url: collection_card_comments_path(card.collection, card), class: "flex flex-column gap full-width", + <%= form_with model: Comment.new, url: card_comments_path(card), class: "flex flex-column gap full-width", data: { controller: "form paste local-save", local_save_key_value: "comment-#{card.id}", action: "turbo:submit-end->local-save#submit keydown.ctrl+enter->form#submit:prevent keydown.meta+enter->form#submit:prevent keydown.esc->form#cancel:stop paste->paste#pasteFiles" } do |form| %> diff --git a/app/views/comments/create.html.erb b/app/views/cards/comments/create.html.erb similarity index 100% rename from app/views/comments/create.html.erb rename to app/views/cards/comments/create.html.erb diff --git a/app/views/comments/edit.html.erb b/app/views/cards/comments/edit.html.erb similarity index 73% rename from app/views/comments/edit.html.erb rename to app/views/cards/comments/edit.html.erb index 795a79d71..e3a2e783d 100644 --- a/app/views/comments/edit.html.erb +++ b/app/views/cards/comments/edit.html.erb @@ -1,14 +1,14 @@ <%= turbo_frame_tag dom_id(@comment) do %>
- <%= form_with model: [@card.collection, @card, @comment], class: "flex flex-column gap full-width", + <%= form_with model: [ @card, @comment ], class: "flex flex-column gap full-width", data: { controller: "form paste", action: "keydown.ctrl+enter->form#submit:prevent keydown.meta+enter->form#submit:prevent keydown.esc->form#cancel:stop paste->paste#pasteFiles" } do |form| %> <%= form.markdown_area :body, class: "input comment__input", required: true, autofocus: true, placeholder: new_comment_placeholder(@card) %>
<%= form.button class: "btn btn--reversed", type: :submit do %> Save changes <% end %> - <%= link_to collection_card_comment_path(@card.collection, @card, @comment), class: "btn", data: { form_target: "cancel" } do %> + <%= link_to card_comment_path(@card, @comment), class: "btn", data: { form_target: "cancel" } do %> Cancel <% end %> @@ -20,7 +20,7 @@
<% end %> - <%= form_with url: collection_card_comment_path(@card.collection, @card, @comment), method: :delete, id: dom_id(@comment, :delete_form), data: { turbo_frame: "_top" } %> + <%= form_with url: card_comment_path(@card, @comment), method: :delete, id: dom_id(@comment, :delete_form), data: { turbo_frame: "_top" } %>
<% end %> diff --git a/app/views/comments/reactions/_reaction.html.erb b/app/views/cards/comments/reactions/_reaction.html.erb similarity index 92% rename from app/views/comments/reactions/_reaction.html.erb rename to app/views/cards/comments/reactions/_reaction.html.erb index c5790204d..d88ed4fae 100644 --- a/app/views/comments/reactions/_reaction.html.erb +++ b/app/views/cards/comments/reactions/_reaction.html.erb @@ -13,7 +13,7 @@ class: [ "txt-small", { "txt-medium": reaction.all_emoji? } ], data: { action: "click->reaction-delete#reveal keydown.enter->reaction-delete#reveal:prevent", reaction_delete_target: "content" } %> - <%= button_to collection_card_comment_reaction_path(comment.card.collection, comment.card, comment, reaction), + <%= button_to card_comment_reaction_path(comment.card, comment, reaction), method: :delete, class: "btn btn--negative flex-item-justify-end reaction__delete", data: { action: "reaction-delete#perform", reaction_delete_target: "button" } do %> diff --git a/app/views/comments/reactions/_reactions.html.erb b/app/views/cards/comments/reactions/_reactions.html.erb similarity index 70% rename from app/views/comments/reactions/_reactions.html.erb rename to app/views/cards/comments/reactions/_reactions.html.erb index 0106deefe..5c9b9f846 100644 --- a/app/views/comments/reactions/_reactions.html.erb +++ b/app/views/cards/comments/reactions/_reactions.html.erb @@ -2,12 +2,12 @@ <%= turbo_stream_from comment, :comments %>
- <%= render partial: "comments/reactions/reaction", collection: comment.reactions.ordered, locals: { comment: comment }, cached: true %> + <%= render partial: "cards/comments/reactions/reaction", collection: comment.reactions.ordered, locals: { comment: comment }, cached: true %>
<%= turbo_frame_tag comment, :new_reaction do %>
- <%= link_to new_collection_card_comment_reaction_path(comment.card.collection, comment.card, comment), role: "button", + <%= link_to new_card_comment_reaction_path(comment.card, comment), role: "button", class: "btn reaction__action", action: "soft-keyboard#open" do %> <%= icon_tag "reaction" %> Add a reaction diff --git a/app/views/cards/comments/reactions/index.html.erb b/app/views/cards/comments/reactions/index.html.erb new file mode 100644 index 000000000..74863a9f1 --- /dev/null +++ b/app/views/cards/comments/reactions/index.html.erb @@ -0,0 +1 @@ +<%= render "cards/comments/reactions/reactions", comment: @comment %> diff --git a/app/views/comments/reactions/new.html.erb b/app/views/cards/comments/reactions/new.html.erb similarity index 84% rename from app/views/comments/reactions/new.html.erb rename to app/views/cards/comments/reactions/new.html.erb index fc3983949..a7945c112 100644 --- a/app/views/comments/reactions/new.html.erb +++ b/app/views/cards/comments/reactions/new.html.erb @@ -1,5 +1,5 @@ <%= turbo_frame_tag dom_id(@comment, :new_reaction) do %> - <%= form_with url: collection_card_comment_reactions_path(@comment.card.collection, @comment.card, @comment), + <%= form_with url: card_comment_reactions_path(@comment.card, @comment), class: "reaction reaction__form flex-inline postion--relative max-width align-center fill-white gap expanded", html: { aria: { label: "New reaction" } }, data: { controller: "form", turbo_frame: dom_id(@comment, :reacting), action: "keydown.esc->form#cancel" } do |form| %> @@ -17,7 +17,7 @@ Submit <% end %> - <%= link_to collection_card_comment_reactions_path(@comment.card.collection, @comment.card, @comment), role: "button", + <%= link_to card_comment_reactions_path(@comment.card, @comment), role: "button", data: { turbo_frame: dom_id(@comment, :reactions), form_target: "cancel" }, class: "btn btn--negative" do %> <%= icon_tag "minus" %> Cancel diff --git a/app/views/cards/comments/show.html.erb b/app/views/cards/comments/show.html.erb new file mode 100644 index 000000000..a17046280 --- /dev/null +++ b/app/views/cards/comments/show.html.erb @@ -0,0 +1 @@ +<%= render "cards/comments/body", comment: @comment %> diff --git a/app/views/cards/comments/update.html.erb b/app/views/cards/comments/update.html.erb new file mode 100644 index 000000000..a17046280 --- /dev/null +++ b/app/views/cards/comments/update.html.erb @@ -0,0 +1 @@ +<%= render "cards/comments/body", comment: @comment %> diff --git a/app/views/comments/reactions/index.html.erb b/app/views/comments/reactions/index.html.erb deleted file mode 100644 index 7228b8718..000000000 --- a/app/views/comments/reactions/index.html.erb +++ /dev/null @@ -1 +0,0 @@ -<%= render "comments/reactions/reactions", comment: @comment %> \ No newline at end of file diff --git a/app/views/comments/show.html.erb b/app/views/comments/show.html.erb deleted file mode 100644 index 815881610..000000000 --- a/app/views/comments/show.html.erb +++ /dev/null @@ -1 +0,0 @@ -<%= render "comments/body", comment: @comment %> diff --git a/app/views/comments/update.html.erb b/app/views/comments/update.html.erb deleted file mode 100644 index 815881610..000000000 --- a/app/views/comments/update.html.erb +++ /dev/null @@ -1 +0,0 @@ -<%= render "comments/body", comment: @comment %> diff --git a/app/views/messages/_message.html.erb b/app/views/messages/_message.html.erb index 1a3b8e401..54fa127cc 100644 --- a/app/views/messages/_message.html.erb +++ b/app/views/messages/_message.html.erb @@ -1,5 +1,5 @@ <% cache message do %> - <%# Template Dependency: comments/comment %> + <%# Template Dependency: cards/comments/comment %> <%# Template Dependency: event_summaries/event_summary %> <%= render partial: message.messageable.to_partial_path, object: message.messageable %> <% end %> diff --git a/config/routes.rb b/config/routes.rb index 70de37a31..a0a3f5ffa 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -28,6 +28,10 @@ Rails.application.routes.draw do resources :boosts resources :stagings resources :taggings + + resources :comments do + resources :reactions, module: :comments + end end end @@ -52,11 +56,7 @@ Rails.application.routes.draw do resource :involvement end - resources :cards do - resources :comments do - resources :reactions, module: :comments - end - end + resources :cards end resources :events, only: :index diff --git a/test/controllers/cards/comments/reactions_controller_test.rb b/test/controllers/cards/comments/reactions_controller_test.rb new file mode 100644 index 000000000..83f556992 --- /dev/null +++ b/test/controllers/cards/comments/reactions_controller_test.rb @@ -0,0 +1,26 @@ +require "test_helper" + +class Cards::Comments::ReactionsControllerTest < ActionDispatch::IntegrationTest + setup do + sign_in_as :jz + @comment = comments(:logo_agreement_jz) + end + + test "create" do + assert_turbo_stream_broadcasts [ @comment, :comments ], count: 1 do + assert_difference -> { @comment.reactions.count }, 1 do + post card_comment_reactions_url(@comment.card, @comment, format: :turbo_stream), params: { reaction: { content: "Great work!" } } + assert_redirected_to card_comment_reactions_url(@comment.card, @comment) + end + end + end + + test "destroy" do + assert_turbo_stream_broadcasts [ @comment, :comments ], count: 1 do + assert_difference -> { @comment.reactions.count }, -1 do + delete card_comment_reaction_url(@comment.card, @comment, reactions(:kevin), format: :turbo_stream) + assert_response :success + end + end + end +end diff --git a/test/controllers/cards/comments_controller_test.rb b/test/controllers/cards/comments_controller_test.rb new file mode 100644 index 000000000..a9e45f838 --- /dev/null +++ b/test/controllers/cards/comments_controller_test.rb @@ -0,0 +1,30 @@ +require "test_helper" + +class Cards::CommentsControllerTest < ActionDispatch::IntegrationTest + setup do + sign_in_as :kevin + end + + test "create" do + assert_difference "cards(:logo).messages.comments.count", +1 do + post card_comments_url(cards(:logo), params: { comment: { body: "Agreed." } }) + end + + assert_response :success + end + + test "update" do + put card_comment_url(cards(:logo), comments(:logo_agreement_kevin)), params: { comment: { body: "I've changed my mind" } } + + assert_response :success + assert_equal "I've changed my mind", comments(:logo_agreement_kevin).reload.body.content + end + + test "update another user's comment" do + assert_no_changes "comments(:logo_agreement_jz).body.content" do + put card_comment_url(cards(:logo), comments(:logo_agreement_jz)), params: { comment: { body: "I've changed my mind" } } + end + + assert_response :forbidden + end +end diff --git a/test/controllers/comments_controller_test.rb b/test/controllers/comments_controller_test.rb deleted file mode 100644 index 78d4987ae..000000000 --- a/test/controllers/comments_controller_test.rb +++ /dev/null @@ -1,30 +0,0 @@ -require "test_helper" - -class CommentsControllerTest < ActionDispatch::IntegrationTest - setup do - sign_in_as :kevin - end - - test "create" do - assert_difference "cards(:logo).messages.comments.count", +1 do - post collection_card_comments_url(collections(:writebook), cards(:logo), params: { comment: { body: "Agreed." } }) - end - - assert_response :success - end - - test "update" do - put collection_card_comment_url(collections(:writebook), cards(:logo), comments(:logo_agreement_kevin)), params: { comment: { body: "I've changed my mind" } } - - assert_response :success - assert_equal "I've changed my mind", comments(:logo_agreement_kevin).reload.body.content - end - - test "update another user's comment" do - assert_no_changes "comments(:logo_agreement_jz).body.content" do - put collection_card_comment_url(collections(:writebook), cards(:logo), comments(:logo_agreement_jz)), params: { comment: { body: "I've changed my mind" } } - end - - assert_response :forbidden - end -end diff --git a/test/controllers/reactions_controller_test.rb b/test/controllers/reactions_controller_test.rb deleted file mode 100644 index e46c9ac30..000000000 --- a/test/controllers/reactions_controller_test.rb +++ /dev/null @@ -1,26 +0,0 @@ -require "test_helper" - -class Comments::ReactionsControllerTest < ActionDispatch::IntegrationTest - setup do - sign_in_as :jz - @comment = comments(:logo_agreement_jz) - end - - test "create" do - assert_turbo_stream_broadcasts [ @comment, :comments ], count: 1 do - assert_difference -> { @comment.reactions.count }, 1 do - post collection_card_comment_reactions_url(@comment.card.collection, @comment.card, @comment, format: :turbo_stream), params: { reaction: { content: "Great work!" } } - assert_redirected_to collection_card_comment_reactions_url(@comment.card.collection, @comment.card, @comment) - end - end - end - - test "destroy" do - assert_turbo_stream_broadcasts [ @comment, :comments ], count: 1 do - assert_difference -> { @comment.reactions.count }, -1 do - delete collection_card_comment_reaction_url(@comment.card.collection, @comment.card, @comment, reactions(:kevin), format: :turbo_stream) - assert_response :success - end - end - end -end From cbdb9aa11363fef056aca2ccb1e67d9461d751f3 Mon Sep 17 00:00:00 2001 From: David Heinemeier Hansson Date: Fri, 11 Apr 2025 16:24:38 +0200 Subject: [PATCH 25/31] Schema movement -- is this because the dumper doesnt sort deterministically? cc @flavorjones --- db/schema_cache.yml | 322 ++++++++++++++++++++++---------------------- 1 file changed, 161 insertions(+), 161 deletions(-) diff --git a/db/schema_cache.yml b/db/schema_cache.yml index 3233fb2f6..1a83eece7 100644 --- a/db/schema_cache.yml +++ b/db/schema_cache.yml @@ -50,26 +50,6 @@ columns: default_function: collation: comment: - - !ruby/object:ActiveRecord::ConnectionAdapters::SQLite3::Column - auto_increment: - name: involvement - cast_type: &7 !ruby/object:ActiveModel::Type::String - true: t - false: f - precision: - scale: - limit: - sql_type_metadata: &8 !ruby/object:ActiveRecord::ConnectionAdapters::SqlTypeMetadata - sql_type: varchar - type: :string - limit: - precision: - scale: - 'null': false - default: watching - default_function: - collation: - comment: - &9 !ruby/object:ActiveRecord::ConnectionAdapters::SQLite3::Column auto_increment: name: updated_at @@ -90,6 +70,26 @@ columns: default_function: collation: comment: + - !ruby/object:ActiveRecord::ConnectionAdapters::SQLite3::Column + auto_increment: + name: involvement + cast_type: &7 !ruby/object:ActiveModel::Type::String + true: t + false: f + precision: + scale: + limit: + sql_type_metadata: &8 !ruby/object:ActiveRecord::ConnectionAdapters::SqlTypeMetadata + sql_type: varchar + type: :string + limit: + precision: + scale: + 'null': false + default: watching + default_function: + collation: + comment: accounts: - *5 - *6 @@ -463,16 +463,6 @@ columns: default_function: collation: comment: - - !ruby/object:ActiveRecord::ConnectionAdapters::SQLite3::Column - auto_increment: - name: last_active_at - cast_type: *3 - sql_type_metadata: *4 - 'null': false - default: - default_function: - collation: - comment: - !ruby/object:ActiveRecord::ConnectionAdapters::SQLite3::Column auto_increment: name: stage_id @@ -504,6 +494,16 @@ columns: collation: comment: - *9 + - !ruby/object:ActiveRecord::ConnectionAdapters::SQLite3::Column + auto_increment: + name: last_active_at + cast_type: *3 + sql_type_metadata: *4 + 'null': false + default: + default_function: + collation: + comment: closure_reasons: - *5 - !ruby/object:ActiveRecord::ConnectionAdapters::SQLite3::Column @@ -516,7 +516,6 @@ columns: default_function: collation: comment: - - *6 - !ruby/object:ActiveRecord::ConnectionAdapters::SQLite3::Column auto_increment: name: label @@ -527,21 +526,12 @@ columns: default_function: collation: comment: + - *6 - *9 closures: - *5 - *21 - *6 - - !ruby/object:ActiveRecord::ConnectionAdapters::SQLite3::Column - auto_increment: - name: reason - cast_type: *7 - sql_type_metadata: *8 - 'null': false - default: - default_function: - collation: - comment: - *9 - !ruby/object:ActiveRecord::ConnectionAdapters::SQLite3::Column auto_increment: @@ -553,6 +543,16 @@ columns: default_function: collation: comment: + - !ruby/object:ActiveRecord::ConnectionAdapters::SQLite3::Column + auto_increment: + name: reason + cast_type: *7 + sql_type_metadata: *8 + 'null': false + default: + default_function: + collation: + comment: collections: - *5 - &32 !ruby/object:ActiveRecord::ConnectionAdapters::SQLite3::Column @@ -1055,9 +1055,10 @@ indexes: accesses: - !ruby/object:ActiveRecord::ConnectionAdapters::IndexDefinition table: accesses - name: index_accesses_on_user_id - unique: false + name: index_accesses_on_collection_id_and_user_id + unique: true columns: + - collection_id - user_id lengths: {} orders: {} @@ -1087,10 +1088,9 @@ indexes: valid: true - !ruby/object:ActiveRecord::ConnectionAdapters::IndexDefinition table: accesses - name: index_accesses_on_collection_id_and_user_id - unique: true + name: index_accesses_on_user_id + unique: false columns: - - collection_id - user_id lengths: {} orders: {} @@ -1310,9 +1310,10 @@ indexes: assignments: - !ruby/object:ActiveRecord::ConnectionAdapters::IndexDefinition table: assignments - name: index_assignments_on_card_id - unique: false + name: index_assignments_on_assignee_id_and_card_id + unique: true columns: + - assignee_id - card_id lengths: {} orders: {} @@ -1326,10 +1327,9 @@ indexes: valid: true - !ruby/object:ActiveRecord::ConnectionAdapters::IndexDefinition table: assignments - name: index_assignments_on_assignee_id_and_card_id - unique: true + name: index_assignments_on_card_id + unique: false columns: - - assignee_id - card_id lengths: {} orders: {} @@ -1376,6 +1376,38 @@ indexes: comment: valid: true cards: + - !ruby/object:ActiveRecord::ConnectionAdapters::IndexDefinition + table: cards + name: index_cards_on_collection_id + unique: false + columns: + - collection_id + lengths: {} + orders: {} + opclasses: {} + where: + type: + using: + include: + nulls_not_distinct: + comment: + valid: true + - !ruby/object:ActiveRecord::ConnectionAdapters::IndexDefinition + table: cards + name: index_cards_on_activity_score_order + unique: false + columns: + - activity_score_order + lengths: {} + orders: {} + opclasses: {} + where: + type: + using: + include: + nulls_not_distinct: + comment: + valid: true - !ruby/object:ActiveRecord::ConnectionAdapters::IndexDefinition table: cards name: index_cards_on_stage_id @@ -1409,38 +1441,6 @@ indexes: nulls_not_distinct: comment: valid: true - - !ruby/object:ActiveRecord::ConnectionAdapters::IndexDefinition - table: cards - name: index_cards_on_collection_id - unique: false - columns: - - collection_id - lengths: {} - orders: {} - opclasses: {} - where: - type: - using: - include: - nulls_not_distinct: - comment: - valid: true - - !ruby/object:ActiveRecord::ConnectionAdapters::IndexDefinition - table: cards - name: index_cards_on_activity_score_order - unique: false - columns: - - activity_score_order - lengths: {} - orders: {} - opclasses: {} - where: - type: - using: - include: - nulls_not_distinct: - comment: - valid: true closure_reasons: - !ruby/object:ActiveRecord::ConnectionAdapters::IndexDefinition table: closure_reasons @@ -1461,10 +1461,11 @@ indexes: closures: - !ruby/object:ActiveRecord::ConnectionAdapters::IndexDefinition table: closures - name: index_closures_on_user_id + name: index_closures_on_card_id_and_created_at unique: false columns: - - user_id + - card_id + - created_at lengths: {} orders: {} opclasses: {} @@ -1493,11 +1494,10 @@ indexes: valid: true - !ruby/object:ActiveRecord::ConnectionAdapters::IndexDefinition table: closures - name: index_closures_on_card_id_and_created_at + name: index_closures_on_user_id unique: false columns: - - card_id - - created_at + - user_id lengths: {} orders: {} opclasses: {} @@ -1511,10 +1511,10 @@ indexes: collections: - !ruby/object:ActiveRecord::ConnectionAdapters::IndexDefinition table: collections - name: index_collections_on_workflow_id + name: index_collections_on_account_id unique: false columns: - - workflow_id + - account_id lengths: {} orders: {} opclasses: {} @@ -1543,10 +1543,10 @@ indexes: valid: true - !ruby/object:ActiveRecord::ConnectionAdapters::IndexDefinition table: collections - name: index_collections_on_account_id + name: index_collections_on_workflow_id unique: false columns: - - account_id + - workflow_id lengths: {} orders: {} opclasses: {} @@ -1560,10 +1560,10 @@ indexes: collections_filters: - !ruby/object:ActiveRecord::ConnectionAdapters::IndexDefinition table: collections_filters - name: index_collections_filters_on_filter_id + name: index_collections_filters_on_collection_id unique: false columns: - - filter_id + - collection_id lengths: {} orders: {} opclasses: {} @@ -1576,10 +1576,10 @@ indexes: valid: true - !ruby/object:ActiveRecord::ConnectionAdapters::IndexDefinition table: collections_filters - name: index_collections_filters_on_collection_id + name: index_collections_filters_on_filter_id unique: false columns: - - collection_id + - filter_id lengths: {} orders: {} opclasses: {} @@ -1626,6 +1626,22 @@ indexes: valid: true event_summaries: [] events: + - !ruby/object:ActiveRecord::ConnectionAdapters::IndexDefinition + table: events + name: index_events_on_card_id + unique: false + columns: + - card_id + lengths: {} + orders: {} + opclasses: {} + where: + type: + using: + include: + nulls_not_distinct: + comment: + valid: true - !ruby/object:ActiveRecord::ConnectionAdapters::IndexDefinition table: events name: index_events_on_summary_id_and_action @@ -1659,22 +1675,6 @@ indexes: nulls_not_distinct: comment: valid: true - - !ruby/object:ActiveRecord::ConnectionAdapters::IndexDefinition - table: events - name: index_events_on_card_id - unique: false - columns: - - card_id - lengths: {} - orders: {} - opclasses: {} - where: - type: - using: - include: - nulls_not_distinct: - comment: - valid: true filters: - !ruby/object:ActiveRecord::ConnectionAdapters::IndexDefinition table: filters @@ -1760,6 +1760,22 @@ indexes: comment: valid: true messages: + - !ruby/object:ActiveRecord::ConnectionAdapters::IndexDefinition + table: messages + name: index_messages_on_card_id + unique: false + columns: + - card_id + lengths: {} + orders: {} + opclasses: {} + where: + type: + using: + include: + nulls_not_distinct: + comment: + valid: true - !ruby/object:ActiveRecord::ConnectionAdapters::IndexDefinition table: messages name: index_messages_on_messageable @@ -1777,9 +1793,10 @@ indexes: nulls_not_distinct: comment: valid: true + notifications: - !ruby/object:ActiveRecord::ConnectionAdapters::IndexDefinition - table: messages - name: index_messages_on_card_id + table: notifications + name: index_notifications_on_card_id unique: false columns: - card_id @@ -1793,7 +1810,6 @@ indexes: nulls_not_distinct: comment: valid: true - notifications: - !ruby/object:ActiveRecord::ConnectionAdapters::IndexDefinition table: notifications name: index_notifications_on_user_id @@ -1863,28 +1879,13 @@ indexes: nulls_not_distinct: comment: valid: true - - !ruby/object:ActiveRecord::ConnectionAdapters::IndexDefinition - table: notifications - name: index_notifications_on_card_id - unique: false - columns: - - card_id - lengths: {} - orders: {} - opclasses: {} - where: - type: - using: - include: - nulls_not_distinct: - comment: - valid: true pins: - !ruby/object:ActiveRecord::ConnectionAdapters::IndexDefinition table: pins - name: index_pins_on_user_id - unique: false + name: index_pins_on_card_id_and_user_id + unique: true columns: + - card_id - user_id lengths: {} orders: {} @@ -1914,10 +1915,9 @@ indexes: valid: true - !ruby/object:ActiveRecord::ConnectionAdapters::IndexDefinition table: pins - name: index_pins_on_card_id_and_user_id - unique: true + name: index_pins_on_user_id + unique: false columns: - - card_id - user_id lengths: {} orders: {} @@ -1981,22 +1981,6 @@ indexes: comment: valid: true taggings: - - !ruby/object:ActiveRecord::ConnectionAdapters::IndexDefinition - table: taggings - name: index_taggings_on_tag_id - unique: false - columns: - - tag_id - lengths: {} - orders: {} - opclasses: {} - where: - type: - using: - include: - nulls_not_distinct: - comment: - valid: true - !ruby/object:ActiveRecord::ConnectionAdapters::IndexDefinition table: taggings name: index_taggings_on_card_id_and_tag_id @@ -2014,13 +1998,30 @@ indexes: nulls_not_distinct: comment: valid: true + - !ruby/object:ActiveRecord::ConnectionAdapters::IndexDefinition + table: taggings + name: index_taggings_on_tag_id + unique: false + columns: + - tag_id + lengths: {} + orders: {} + opclasses: {} + where: + type: + using: + include: + nulls_not_distinct: + comment: + valid: true tags: - !ruby/object:ActiveRecord::ConnectionAdapters::IndexDefinition table: tags - name: index_tags_on_account_id - unique: false + name: index_tags_on_account_id_and_title + unique: true columns: - account_id + - title lengths: {} orders: {} opclasses: {} @@ -2033,11 +2034,10 @@ indexes: valid: true - !ruby/object:ActiveRecord::ConnectionAdapters::IndexDefinition table: tags - name: index_tags_on_account_id_and_title - unique: true + name: index_tags_on_account_id + unique: false columns: - account_id - - title lengths: {} orders: {} opclasses: {} @@ -2100,10 +2100,10 @@ indexes: watches: - !ruby/object:ActiveRecord::ConnectionAdapters::IndexDefinition table: watches - name: index_watches_on_user_id + name: index_watches_on_card_id unique: false columns: - - user_id + - card_id lengths: {} orders: {} opclasses: {} @@ -2116,10 +2116,10 @@ indexes: valid: true - !ruby/object:ActiveRecord::ConnectionAdapters::IndexDefinition table: watches - name: index_watches_on_card_id + name: index_watches_on_user_id unique: false columns: - - card_id + - user_id lengths: {} orders: {} opclasses: {} From adabfba6365d97d543992921b843916abcfd267d Mon Sep 17 00:00:00 2001 From: David Heinemeier Hansson Date: Fri, 11 Apr 2025 16:31:01 +0200 Subject: [PATCH 26/31] In order of appearance --- config/routes.rb | 49 ++++++++++++++++++++++++++---------------------- 1 file changed, 27 insertions(+), 22 deletions(-) diff --git a/config/routes.rb b/config/routes.rb index a0a3f5ffa..22235c491 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -8,8 +8,14 @@ Rails.application.routes.draw do end end - namespace :cards do - resources :previews + resources :collections do + scope module: :collections do + resource :subscriptions + resource :workflow, only: :update + resource :involvement + end + + resources :cards end resources :cards do @@ -35,6 +41,11 @@ Rails.application.routes.draw do end end + namespace :cards do + resources :previews + end + + resources :notifications, only: :index namespace :notifications do resource :tray, only: :show @@ -49,15 +60,7 @@ Rails.application.routes.draw do end end - resources :collections do - scope module: :collections do - resource :subscriptions - resource :workflow, only: :update - resource :involvement - end - - resources :cards - end + resources :filters resources :events, only: :index namespace :events do @@ -68,12 +71,15 @@ Rails.application.routes.draw do resources :stages, module: :workflows end - resources :filters - resources :qr_codes + resources :uploads, only: :create + get "/u/*slug" => "uploads#show", as: :upload - namespace :my do - resources :pins - end + resource :terminal, only: [ :show, :edit ] + + + resources :qr_codes + get "join/:join_code", to: "users#new", as: :join + post "join/:join_code", to: "users#create" resource :session do scope module: "sessions" do @@ -87,8 +93,10 @@ Rails.application.routes.draw do end end - get "join/:join_code", to: "users#new", as: :join - post "join/:join_code", to: "users#create" + namespace :my do + resources :pins + end + resolve "Card" do |card, options| route_for :collection_card, card.collection, card, options @@ -99,13 +107,10 @@ Rails.application.routes.draw do route_for :collection_card, comment.card.collection, comment.card, options end + get "up", to: "rails/health#show", as: :rails_health_check get "manifest" => "rails/pwa#manifest", as: :pwa_manifest - resources :uploads, only: :create - get "/u/*slug" => "uploads#show", as: :upload - - resource :terminal, only: [ :show, :edit ] root "events#index" end From f2811803d3dd9daf5ac4b2bea72ae584869b2dfb Mon Sep 17 00:00:00 2001 From: David Heinemeier Hansson Date: Fri, 11 Apr 2025 16:32:06 +0200 Subject: [PATCH 27/31] Needed to come first --- config/routes.rb | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/config/routes.rb b/config/routes.rb index 22235c491..b7b2615c6 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -18,6 +18,10 @@ Rails.application.routes.draw do resources :cards end + namespace :cards do + resources :previews + end + resources :cards do scope module: :cards do resource :engagement @@ -41,10 +45,6 @@ Rails.application.routes.draw do end end - namespace :cards do - resources :previews - end - resources :notifications, only: :index namespace :notifications do From ee8559343ae0c58b35d831281f4bfbb51d2575d4 Mon Sep 17 00:00:00 2001 From: Jason Zimdars Date: Fri, 11 Apr 2025 11:50:09 -0500 Subject: [PATCH 28/31] Tighten engagement switch design, only display it for published cards --- app/assets/stylesheets/buttons.css | 8 ++++++-- app/assets/stylesheets/cards.css | 3 ++- app/views/cards/show.html.erb | 28 +++++++++++++++------------- 3 files changed, 23 insertions(+), 16 deletions(-) diff --git a/app/assets/stylesheets/buttons.css b/app/assets/stylesheets/buttons.css index a6e1e1139..693ba2429 100644 --- a/app/assets/stylesheets/buttons.css +++ b/app/assets/stylesheets/buttons.css @@ -201,15 +201,19 @@ } :first-of-type .btn { - border-top-left-radius: 2em; border-bottom-left-radius: 2em; + border-inline-end: 0; + border-top-left-radius: 2em; flex: 1 0 50%; + padding-inline-end: 0.8em; } :last-of-type .btn { - border-top-right-radius: 2em; border-bottom-right-radius: 2em; + border-inline-start: 0; + border-top-right-radius: 2em; flex: 1 0 50%; + padding-inline-start: 0.8em; } span { diff --git a/app/assets/stylesheets/cards.css b/app/assets/stylesheets/cards.css index 61beab9b2..8a30732ed 100644 --- a/app/assets/stylesheets/cards.css +++ b/app/assets/stylesheets/cards.css @@ -153,7 +153,8 @@ &.card__actions-container--top { margin: calc(var(--block-space) * 1) auto calc(var(--block-space) * -0.66); - min-inline-size: 30ch; + min-inline-size: 28ch; + padding: 0; #header:has(&) { position: relative; diff --git a/app/views/cards/show.html.erb b/app/views/cards/show.html.erb index 93f338f8a..c4a621a00 100644 --- a/app/views/cards/show.html.erb +++ b/app/views/cards/show.html.erb @@ -23,23 +23,25 @@ <%= link_to_home %> <%= link_to_back fallback_path: cards_path(collection_id: @card.collection) %> -
-
- <%= form_with url: card_engagement_path(@card), method: :delete, data: { controller: "form" } do |form| %> - <%= form.label :engagement, value: "considering", class: "btn", aria: { label: "Move to Doing"} do %> - <%= form.radio_button :engagement, "considering", checked: @card.considering?, class: "for-screen-reader", data: { action: "change->form#submit" } %> - Considering + <% if @card.published? %> +
+
+ <%= form_with url: card_engagement_path(@card), method: :delete, data: { controller: "form" } do |form| %> + <%= form.label :engagement, value: "considering", class: "btn", aria: { label: "Move to Doing"} do %> + <%= form.radio_button :engagement, "considering", checked: @card.considering?, class: "for-screen-reader", data: { action: "change->form#submit" } %> + Considering + <% end %> <% end %> - <% end %> - <%= form_with url: card_engagement_path(@card), method: :post, data: { controller: "form" } do |form| %> - <%= form.label :engagement, value: "doing", class: "btn", aria: { label: "Move back to Considering"} do %> - <%= form.radio_button :engagement, "doing", checked: @card.doing?, class: "for-screen-reader", data: { action: "change->form#submit" } %> - Doing + <%= form_with url: card_engagement_path(@card), method: :post, data: { controller: "form" } do |form| %> + <%= form.label :engagement, value: "doing", class: "btn", aria: { label: "Move back to Considering"} do %> + <%= form.radio_button :engagement, "doing", checked: @card.doing?, class: "for-screen-reader", data: { action: "change->form#submit" } %> + Doing + <% end %> <% end %> - <% end %> +
-
+ <% end %>
From 76336a52d60bc4ac3fad6e46eae2ae1fb2041db9 Mon Sep 17 00:00:00 2001 From: Jason Zimdars Date: Fri, 11 Apr 2025 11:56:26 -0500 Subject: [PATCH 29/31] This item makes no sense until it's saved --- app/views/cards/display/common/_meta.html.erb | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/app/views/cards/display/common/_meta.html.erb b/app/views/cards/display/common/_meta.html.erb index e90348331..d27ff3485 100644 --- a/app/views/cards/display/common/_meta.html.erb +++ b/app/views/cards/display/common/_meta.html.erb @@ -16,8 +16,13 @@
- <%= card.creating? ? "Created" : "Updated" %> - <%= local_datetime_tag(card.updated_at, style: :daysago) %> + + <% if card.creating? %> +   + <% else %> + Updated + <%= local_datetime_tag(card.updated_at, style: :daysago) %> + <% end %>
From 5997ef2c709af16a6ffd59ea75429cc31c0aacb5 Mon Sep 17 00:00:00 2001 From: Jason Zimdars Date: Fri, 11 Apr 2025 12:08:05 -0500 Subject: [PATCH 30/31] Considering needs to include drafted cards or you'll never be able to see them --- app/models/card/engageable.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/models/card/engageable.rb b/app/models/card/engageable.rb index aac48232c..f811b639a 100644 --- a/app/models/card/engageable.rb +++ b/app/models/card/engageable.rb @@ -7,7 +7,7 @@ module Card::Engageable has_one :engagement, dependent: :destroy, class_name: "Card::Engagement" scope :doing, -> { published.active.joins(:engagement) } - scope :considering, -> { published.active.where.missing(:engagement) } + scope :considering, -> { published_or_drafted_by(Current.user).active.where.missing(:engagement) } scope :stagnated, -> { doing.where(last_active_at: ..STAGNATED_AFTER.ago) } end From df96ee80fa5d6b60c2a77159a8333732992bda3d Mon Sep 17 00:00:00 2001 From: Jason Zimdars Date: Fri, 11 Apr 2025 12:21:14 -0500 Subject: [PATCH 31/31] Style drafted cards --- app/assets/stylesheets/cards.css | 7 +++++++ app/views/cards/display/_mini.html.erb | 5 +++-- app/views/cards/display/common/_meta.html.erb | 3 +++ 3 files changed, 13 insertions(+), 2 deletions(-) diff --git a/app/assets/stylesheets/cards.css b/app/assets/stylesheets/cards.css index 8a30732ed..57024929f 100644 --- a/app/assets/stylesheets/cards.css +++ b/app/assets/stylesheets/cards.css @@ -50,6 +50,13 @@ .card__tags { font-size: var(--text-small); } + + &:is(.card--drafted) { + --card-color: var(--color-subtle-dark) !important; + + border-color: var(--card-color) !important; + border-style: dashed !important; + } } } diff --git a/app/views/cards/display/_mini.html.erb b/app/views/cards/display/_mini.html.erb index 2dd1ff438..8ed453216 100644 --- a/app/views/cards/display/_mini.html.erb +++ b/app/views/cards/display/_mini.html.erb @@ -1,4 +1,5 @@ -
+<%= tag.div class: ["card card--mini border flex flex-column gap position-relative txt-align-start full-width border-radius fill-white", { "card--drafted": card.drafted? }], + style: "--card-color: #{ card.color }; view-transition-name: #{ dom_id(card, :ticket) };" do %>
<%= card.collection.name %> @@ -20,4 +21,4 @@ <%= link_to collection_card_path(card.collection, card), class: "card__link" do %> <%= card_title(card) %> <% end %> -
+<% end %> diff --git a/app/views/cards/display/common/_meta.html.erb b/app/views/cards/display/common/_meta.html.erb index d27ff3485..eda0a910b 100644 --- a/app/views/cards/display/common/_meta.html.erb +++ b/app/views/cards/display/common/_meta.html.erb @@ -4,6 +4,9 @@
Added <%= local_datetime_tag(card.created_at, style: :daysago) %> + <% if card.drafted? %> + (Draft) + <% end %>