From 6c8fe164b3369c992bc3f0c973728ed3fe18e146 Mon Sep 17 00:00:00 2001 From: Kevin McConnell Date: Thu, 17 Apr 2025 09:37:34 +0100 Subject: [PATCH 01/33] Read a card should dismiss all notifications Previous code assumed that there was a single notification to dismiss for that card, but in practice there can be zero or many. If it's zero, we need to avoid the crash. If it's many, we should dismiss them all. Also re-rendering the notification stack after dismissing enables us to remove all the removed cards, as well as reveal any older ones that were previously outside the visible page size. This reverts commit 6135909b7e7b34ffdc7430a8b609c1b561085ba4. --- app/controllers/cards/readings_controller.rb | 4 ++-- app/views/cards/readings/create.turbo_stream.erb | 4 +++- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/app/controllers/cards/readings_controller.rb b/app/controllers/cards/readings_controller.rb index bbc4d53c0..dbb379b15 100644 --- a/app/controllers/cards/readings_controller.rb +++ b/app/controllers/cards/readings_controller.rb @@ -2,7 +2,7 @@ class Cards::ReadingsController < ApplicationController include CardScoped def create - @notification = Current.user.notifications.find_by(card: @card) - @notification.read + Current.user.notifications.unread.where(card: @card).read_all + @notifications = Current.user.notifications.unread.ordered.limit(20) end end diff --git a/app/views/cards/readings/create.turbo_stream.erb b/app/views/cards/readings/create.turbo_stream.erb index 1f3b07b47..8f758752e 100644 --- a/app/views/cards/readings/create.turbo_stream.erb +++ b/app/views/cards/readings/create.turbo_stream.erb @@ -1 +1,3 @@ -<%= turbo_stream.remove @notification %> +<%= turbo_stream.update "notifications" do %> + <%= render collection: @notifications, partial: "notifications/notification" %> +<% end %> From a5de4863fa7bd22a1ac0a35fc8a9b77982e784fc Mon Sep 17 00:00:00 2001 From: David Heinemeier Hansson Date: Thu, 17 Apr 2025 11:39:05 +0200 Subject: [PATCH 02/33] Allow for multiple notifications to be read cc @kevinmcconnell --- app/controllers/cards/readings_controller.rb | 4 ++-- app/views/cards/readings/create.turbo_stream.erb | 4 ++-- test/controllers/cards/readings_controller_test.rb | 12 +++++++++++- test/fixtures/notifications.yml | 7 +++++++ 4 files changed, 22 insertions(+), 5 deletions(-) diff --git a/app/controllers/cards/readings_controller.rb b/app/controllers/cards/readings_controller.rb index dbb379b15..2d8b51ac6 100644 --- a/app/controllers/cards/readings_controller.rb +++ b/app/controllers/cards/readings_controller.rb @@ -2,7 +2,7 @@ class Cards::ReadingsController < ApplicationController include CardScoped def create - Current.user.notifications.unread.where(card: @card).read_all - @notifications = Current.user.notifications.unread.ordered.limit(20) + @notifications = Current.user.notifications.where(card: @card) + @notifications.each(&:read) end end diff --git a/app/views/cards/readings/create.turbo_stream.erb b/app/views/cards/readings/create.turbo_stream.erb index 8f758752e..5d7fe7801 100644 --- a/app/views/cards/readings/create.turbo_stream.erb +++ b/app/views/cards/readings/create.turbo_stream.erb @@ -1,3 +1,3 @@ -<%= turbo_stream.update "notifications" do %> - <%= render collection: @notifications, partial: "notifications/notification" %> +<% @notifications.each do |notification| %> + <%= turbo_stream.remove notification %> <% end %> diff --git a/test/controllers/cards/readings_controller_test.rb b/test/controllers/cards/readings_controller_test.rb index c169517e2..a880e46c7 100644 --- a/test/controllers/cards/readings_controller_test.rb +++ b/test/controllers/cards/readings_controller_test.rb @@ -5,11 +5,21 @@ class Cards::ReadingsControllerTest < ActionDispatch::IntegrationTest sign_in_as :kevin end - test "index" do + test "read one notification on card visit" do assert_changes -> { notifications(:logo_published_kevin).reload.read? }, from: false, to: true do post card_reading_path(cards(:logo)), as: :turbo_stream end assert_response :success end + + test "read multiple notifications on card visit" do + assert_changes -> { notifications(:logo_published_kevin).reload.read? }, from: false, to: true do + assert_changes -> { notifications(:logo_assignment_kevin).reload.read? }, from: false, to: true do + post card_reading_path(cards(:logo)), as: :turbo_stream + end + end + + assert_response :success + end end diff --git a/test/fixtures/notifications.yml b/test/fixtures/notifications.yml index d6db9d360..7579f8eb6 100644 --- a/test/fixtures/notifications.yml +++ b/test/fixtures/notifications.yml @@ -5,6 +5,13 @@ logo_published_kevin: resource: logo (Card) created_at: <%= 1.week.ago %> +logo_assignment_kevin: + user: kevin + event: logo_assignment_km + card: logo + resource: logo (Card) + created_at: <%= 1.week.ago %> + layout_commented_kevin: user: kevin event: layout_commented From bf99da8914242f1ac70daf47adb5719fb6b55a07 Mon Sep 17 00:00:00 2001 From: David Heinemeier Hansson Date: Thu, 17 Apr 2025 13:33:20 +0200 Subject: [PATCH 03/33] Style --- app/views/cards/show.html.erb | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/app/views/cards/show.html.erb b/app/views/cards/show.html.erb index f1f2ea95a..b25af4f3c 100644 --- a/app/views/cards/show.html.erb +++ b/app/views/cards/show.html.erb @@ -31,18 +31,14 @@
" style="--card-color: <%= @card.color %>;"> - <%= render "cards/doing_toggle", card: @card %> From b5d6d40462a991824071a806759e352d6730e10a Mon Sep 17 00:00:00 2001 From: David Heinemeier Hansson Date: Thu, 17 Apr 2025 13:42:06 +0200 Subject: [PATCH 04/33] Use domain language termn --- .../cards/{_doing_toggle.html.erb => _engagement.html.erb} | 0 app/views/cards/show.html.erb | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) rename app/views/cards/{_doing_toggle.html.erb => _engagement.html.erb} (100%) diff --git a/app/views/cards/_doing_toggle.html.erb b/app/views/cards/_engagement.html.erb similarity index 100% rename from app/views/cards/_doing_toggle.html.erb rename to app/views/cards/_engagement.html.erb diff --git a/app/views/cards/show.html.erb b/app/views/cards/show.html.erb index b25af4f3c..813fff2bc 100644 --- a/app/views/cards/show.html.erb +++ b/app/views/cards/show.html.erb @@ -31,7 +31,7 @@
" style="--card-color: <%= @card.color %>;"> - <%= render "cards/doing_toggle", card: @card %> + <%= render "cards/engagement", card: @card %> From 547e5ea24fb7217eed627286d0d2742f551ebc34 Mon Sep 17 00:00:00 2001 From: David Heinemeier Hansson Date: Thu, 17 Apr 2025 14:54:29 +0200 Subject: [PATCH 16/33] Rerender instead of redirect --- app/controllers/cards/goldnesses_controller.rb | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/app/controllers/cards/goldnesses_controller.rb b/app/controllers/cards/goldnesses_controller.rb index 4be611d14..2c37ad80a 100644 --- a/app/controllers/cards/goldnesses_controller.rb +++ b/app/controllers/cards/goldnesses_controller.rb @@ -3,11 +3,16 @@ class Cards::GoldnessesController < ApplicationController def create @card.gild - redirect_to @card + rerender_card_container end def destroy @card.ungild - redirect_to @card + rerender_card_container end + + private + def rerender_card_container + render turbo_stream: turbo_stream.replace([ @card, :card_container ], partial: "cards/container", locals: { card: @card.reload }) + end end From 06da295f44d30df7883a34f3e4ddc17389f3ece7 Mon Sep 17 00:00:00 2001 From: David Heinemeier Hansson Date: Thu, 17 Apr 2025 14:56:53 +0200 Subject: [PATCH 17/33] Fix tests --- .../cards/goldnesses_controller_test.rb | 18 ++++++------------ 1 file changed, 6 insertions(+), 12 deletions(-) diff --git a/test/controllers/cards/goldnesses_controller_test.rb b/test/controllers/cards/goldnesses_controller_test.rb index b8cfb9469..50fd411b0 100644 --- a/test/controllers/cards/goldnesses_controller_test.rb +++ b/test/controllers/cards/goldnesses_controller_test.rb @@ -6,22 +6,16 @@ class Cards::GoldnessesControllerTest < ActionDispatch::IntegrationTest end test "create" do - card = cards(:text) - - assert_changes -> { card.reload.golden? }, from: false, to: true do - post card_goldness_path(card) + assert_changes -> { cards(:text).reload.golden? }, from: false, to: true do + post card_goldness_path(cards(:text)), as: :turbo_stream + assert_response :success end - - assert_redirected_to collection_card_path(card.collection, card) end test "destroy" do - card = cards(:logo) - - assert_changes -> { card.reload.golden? }, from: true, to: false do - delete card_goldness_path(card) + assert_changes -> { cards(:logo).reload.golden? }, from: true, to: false do + delete card_goldness_path(cards(:logo)), as: :turbo_stream + assert_response :success end - - assert_redirected_to collection_card_path(card.collection, card) end end From 770029c26d09beae97a9c288ae22ada08a7fa5a8 Mon Sep 17 00:00:00 2001 From: David Heinemeier Hansson Date: Thu, 17 Apr 2025 14:59:15 +0200 Subject: [PATCH 18/33] Stick with domain language --- app/views/cards/_container.html.erb | 2 +- app/views/cards/{_golden_toggle.html.erb => _gild.html.erb} | 0 2 files changed, 1 insertion(+), 1 deletion(-) rename app/views/cards/{_golden_toggle.html.erb => _gild.html.erb} (100%) diff --git a/app/views/cards/_container.html.erb b/app/views/cards/_container.html.erb index 183315dcb..4807d0028 100644 --- a/app/views/cards/_container.html.erb +++ b/app/views/cards/_container.html.erb @@ -2,7 +2,7 @@ <%= render "cards/engagement", card: card %>
From 7adbd8d6348e1885bb12a9db2eada25c98df1c9a Mon Sep 17 00:00:00 2001 From: David Heinemeier Hansson Date: Thu, 17 Apr 2025 15:20:27 +0200 Subject: [PATCH 20/33] Use card rerendering instead of redirects --- app/controllers/cards/assignments_controller.rb | 1 + app/controllers/cards/closures_controller.rb | 4 ++-- app/controllers/cards/engagements_controller.rb | 4 ++-- app/controllers/cards/goldnesses_controller.rb | 5 ----- app/controllers/cards/stagings_controller.rb | 2 ++ app/controllers/cards/taggings_controller.rb | 1 + app/controllers/concerns/card_scoped.rb | 4 ++++ app/views/cards/assignments/create.turbo_stream.erb | 1 - app/views/cards/stagings/create.turbo_stream.erb | 8 -------- app/views/cards/taggings/create.turbo_stream.erb | 1 - test/controllers/cards/assignments_controller_test.rb | 4 ++-- test/controllers/cards/closures_controller_test.rb | 6 ++---- test/controllers/cards/engagements_controller_test.rb | 11 +++++++---- test/controllers/cards/goldnesses_controller_test.rb | 4 ++-- test/controllers/cards/taggings_controller_test.rb | 4 ++-- test/test_helper.rb | 2 +- test/test_helpers/card_test_helper.rb | 5 +++++ 17 files changed, 33 insertions(+), 34 deletions(-) delete mode 100644 app/views/cards/assignments/create.turbo_stream.erb delete mode 100644 app/views/cards/stagings/create.turbo_stream.erb delete mode 100644 app/views/cards/taggings/create.turbo_stream.erb create mode 100644 test/test_helpers/card_test_helper.rb diff --git a/app/controllers/cards/assignments_controller.rb b/app/controllers/cards/assignments_controller.rb index 63dce613c..bba888bf4 100644 --- a/app/controllers/cards/assignments_controller.rb +++ b/app/controllers/cards/assignments_controller.rb @@ -6,5 +6,6 @@ class Cards::AssignmentsController < ApplicationController def create @card.toggle_assignment @collection.users.active.find(params[:assignee_id]) + rerender_card_container end end diff --git a/app/controllers/cards/closures_controller.rb b/app/controllers/cards/closures_controller.rb index 3682552ee..f79608036 100644 --- a/app/controllers/cards/closures_controller.rb +++ b/app/controllers/cards/closures_controller.rb @@ -3,11 +3,11 @@ class Cards::ClosuresController < ApplicationController def create @card.close(user: Current.user, reason: params[:reason]) - redirect_to @card + rerender_card_container end def destroy @card.reopen - redirect_to @card + rerender_card_container end end diff --git a/app/controllers/cards/engagements_controller.rb b/app/controllers/cards/engagements_controller.rb index 72025d16a..e1178f1b3 100644 --- a/app/controllers/cards/engagements_controller.rb +++ b/app/controllers/cards/engagements_controller.rb @@ -3,11 +3,11 @@ class Cards::EngagementsController < ApplicationController def create @card.engage - redirect_to @card + rerender_card_container end def destroy @card.reconsider - redirect_to @card + rerender_card_container end end diff --git a/app/controllers/cards/goldnesses_controller.rb b/app/controllers/cards/goldnesses_controller.rb index 2c37ad80a..fb6076eec 100644 --- a/app/controllers/cards/goldnesses_controller.rb +++ b/app/controllers/cards/goldnesses_controller.rb @@ -10,9 +10,4 @@ class Cards::GoldnessesController < ApplicationController @card.ungild rerender_card_container end - - private - def rerender_card_container - render turbo_stream: turbo_stream.replace([ @card, :card_container ], partial: "cards/container", locals: { card: @card.reload }) - end end diff --git a/app/controllers/cards/stagings_controller.rb b/app/controllers/cards/stagings_controller.rb index 071d19f5a..728cad8a5 100644 --- a/app/controllers/cards/stagings_controller.rb +++ b/app/controllers/cards/stagings_controller.rb @@ -9,6 +9,8 @@ class Cards::StagingsController < ApplicationController else @card.update!(stage: nil) end + + rerender_card_container end private diff --git a/app/controllers/cards/taggings_controller.rb b/app/controllers/cards/taggings_controller.rb index 710b59fdd..a44b8a4df 100644 --- a/app/controllers/cards/taggings_controller.rb +++ b/app/controllers/cards/taggings_controller.rb @@ -7,6 +7,7 @@ class Cards::TaggingsController < ApplicationController def create @card.toggle_tag_with sanitized_tag_title_param + rerender_card_container end private diff --git a/app/controllers/concerns/card_scoped.rb b/app/controllers/concerns/card_scoped.rb index ef40d56e3..e89bf7f4d 100644 --- a/app/controllers/concerns/card_scoped.rb +++ b/app/controllers/concerns/card_scoped.rb @@ -13,4 +13,8 @@ module CardScoped def set_collection @collection = @card.collection end + + def rerender_card_container + render turbo_stream: turbo_stream.replace([ @card, :card_container ], partial: "cards/container", locals: { card: @card.reload }) + end end diff --git a/app/views/cards/assignments/create.turbo_stream.erb b/app/views/cards/assignments/create.turbo_stream.erb deleted file mode 100644 index f05f15d8d..000000000 --- a/app/views/cards/assignments/create.turbo_stream.erb +++ /dev/null @@ -1 +0,0 @@ -<%= turbo_stream.replace([ @card, :meta ], partial: "cards/display/perma/meta", locals: { card: @card }) %> diff --git a/app/views/cards/stagings/create.turbo_stream.erb b/app/views/cards/stagings/create.turbo_stream.erb deleted file mode 100644 index ac3942d6a..000000000 --- a/app/views/cards/stagings/create.turbo_stream.erb +++ /dev/null @@ -1,8 +0,0 @@ -<%= turbo_stream.replace dom_id(@card, "stages") do %> - <%= render partial: "cards/stagings/stages", locals: { card: @card } %> -<% end %> - -<%= turbo_stream.set_css_variable dom_id(@card, :card_closure_toggle), name: "--card-color", value: @card.color %> -<%= turbo_stream.set_css_variable dom_id(@card, :card_container), name: "--card-color", value: @card.color %> -<%= turbo_stream.set_css_variable dom_id(@card, :card_engagement_toggle), name: "--card-color", value: @card.color %> -<%= turbo_stream.set_css_variable dom_id(@card, :ticket), name: "--card-color", value: @card.color %> diff --git a/app/views/cards/taggings/create.turbo_stream.erb b/app/views/cards/taggings/create.turbo_stream.erb deleted file mode 100644 index f1775e2f8..000000000 --- a/app/views/cards/taggings/create.turbo_stream.erb +++ /dev/null @@ -1 +0,0 @@ -<%= turbo_stream.replace([ @card, :tags ], partial: "cards/display/perma/tags", locals: { card: @card }) %> diff --git a/test/controllers/cards/assignments_controller_test.rb b/test/controllers/cards/assignments_controller_test.rb index c92f57627..e0629aee4 100644 --- a/test/controllers/cards/assignments_controller_test.rb +++ b/test/controllers/cards/assignments_controller_test.rb @@ -13,12 +13,12 @@ class Cards::AssignmentsControllerTest < ActionDispatch::IntegrationTest test "create" do assert_changes "cards(:logo).assigned_to?(users(:david))", from: false, to: true do post card_assignments_path(cards(:logo)), params: { assignee_id: users(:david).id }, as: :turbo_stream + assert_card_container_rerendered(cards(:logo)) end - assert_response :success assert_changes "cards(:logo).assigned_to?(users(:david))", from: true, to: false do post card_assignments_path(cards(:logo)), params: { assignee_id: users(:david).id }, as: :turbo_stream + assert_card_container_rerendered(cards(:logo)) end - assert_response :success end end diff --git a/test/controllers/cards/closures_controller_test.rb b/test/controllers/cards/closures_controller_test.rb index 1729010a9..1e8f85871 100644 --- a/test/controllers/cards/closures_controller_test.rb +++ b/test/controllers/cards/closures_controller_test.rb @@ -10,11 +10,10 @@ class Cards::ClosuresControllerTest < ActionDispatch::IntegrationTest assert_changes -> { card.reload.closed? }, from: false, to: true do post card_closure_path(card, reason: "Scope too big") + assert_card_container_rerendered(card) end assert_equal "Scope too big", card.closure.reason - - assert_redirected_to collection_card_path(card.collection, card) end test "destroy" do @@ -22,8 +21,7 @@ class Cards::ClosuresControllerTest < ActionDispatch::IntegrationTest assert_changes -> { card.reload.closed? }, from: true, to: false do delete card_closure_path(card) + assert_card_container_rerendered(card) end - - assert_redirected_to collection_card_path(card.collection, card) end end diff --git a/test/controllers/cards/engagements_controller_test.rb b/test/controllers/cards/engagements_controller_test.rb index 1e966108c..6b4265b86 100644 --- a/test/controllers/cards/engagements_controller_test.rb +++ b/test/controllers/cards/engagements_controller_test.rb @@ -10,9 +10,8 @@ class Cards::EngagementsControllerTest < ActionDispatch::IntegrationTest assert_changes -> { card.reload.doing? }, from: false, to: true do post card_engagement_path(card) + assert_card_container_rerendered(card) end - - assert_redirected_to collection_card_path(card.collection, card) end test "destroy" do @@ -20,8 +19,12 @@ class Cards::EngagementsControllerTest < ActionDispatch::IntegrationTest assert_changes -> { card.reload.doing? }, from: true, to: false do delete card_engagement_path(card) + assert_card_container_rerendered(card) end - - assert_redirected_to collection_card_path(card.collection, card) end + + private + def assert_card_container_rerendered(card) + assert_turbo_stream action: :replace, target: dom_id(card, :card_container) + end end diff --git a/test/controllers/cards/goldnesses_controller_test.rb b/test/controllers/cards/goldnesses_controller_test.rb index 50fd411b0..447aa2b71 100644 --- a/test/controllers/cards/goldnesses_controller_test.rb +++ b/test/controllers/cards/goldnesses_controller_test.rb @@ -8,14 +8,14 @@ class Cards::GoldnessesControllerTest < ActionDispatch::IntegrationTest test "create" do assert_changes -> { cards(:text).reload.golden? }, from: false, to: true do post card_goldness_path(cards(:text)), as: :turbo_stream - assert_response :success + assert_card_container_rerendered(cards(:text)) end end test "destroy" do assert_changes -> { cards(:logo).reload.golden? }, from: true, to: false do delete card_goldness_path(cards(:logo)), as: :turbo_stream - assert_response :success + assert_card_container_rerendered(cards(:logo)) end end end diff --git a/test/controllers/cards/taggings_controller_test.rb b/test/controllers/cards/taggings_controller_test.rb index ad5a8fa91..60f4cf743 100644 --- a/test/controllers/cards/taggings_controller_test.rb +++ b/test/controllers/cards/taggings_controller_test.rb @@ -13,14 +13,14 @@ class Cards::TaggingsControllerTest < ActionDispatch::IntegrationTest test "toggle tag on" do assert_changes "cards(:logo).tagged_with?(tags(:mobile))", from: false, to: true do post card_taggings_path(cards(:logo)), params: { tag_title: tags(:mobile).title }, as: :turbo_stream + assert_card_container_rerendered(cards(:logo)) end - assert_response :success end test "toggle tag off" do assert_changes "cards(:logo).tagged_with?(tags(:web))", from: true, to: false do post card_taggings_path(cards(:logo)), params: { tag_title: tags(:web).title }, as: :turbo_stream + assert_card_container_rerendered(cards(:logo)) end - assert_response :success end end diff --git a/test/test_helper.rb b/test/test_helper.rb index f7cc1e088..1447430b1 100644 --- a/test/test_helper.rb +++ b/test/test_helper.rb @@ -10,6 +10,6 @@ module ActiveSupport # Setup all fixtures in test/fixtures/*.yml for all tests in alphabetical order. fixtures :all - include ChangeTestHelper, SessionTestHelper + include CardTestHelper, ChangeTestHelper, SessionTestHelper end end diff --git a/test/test_helpers/card_test_helper.rb b/test/test_helpers/card_test_helper.rb new file mode 100644 index 000000000..6de139c86 --- /dev/null +++ b/test/test_helpers/card_test_helper.rb @@ -0,0 +1,5 @@ +module CardTestHelper + def assert_card_container_rerendered(card) + assert_turbo_stream action: :replace, target: dom_id(card, :card_container) + end +end From 4dbd8205cebed7d1bc73475ba6bcd59b558718cc Mon Sep 17 00:00:00 2001 From: David Heinemeier Hansson Date: Thu, 17 Apr 2025 15:21:14 +0200 Subject: [PATCH 21/33] Fix trailing space --- app/controllers/cards/stagings_controller.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/controllers/cards/stagings_controller.rb b/app/controllers/cards/stagings_controller.rb index 728cad8a5..37d4f91d7 100644 --- a/app/controllers/cards/stagings_controller.rb +++ b/app/controllers/cards/stagings_controller.rb @@ -9,7 +9,7 @@ class Cards::StagingsController < ApplicationController else @card.update!(stage: nil) end - + rerender_card_container end From b788ef1638c296d36536f696a99a700d68ff8b14 Mon Sep 17 00:00:00 2001 From: David Heinemeier Hansson Date: Thu, 17 Apr 2025 15:23:40 +0200 Subject: [PATCH 22/33] Match domain language --- app/views/cards/{_closure_toggle.html.erb => _closure.html.erb} | 0 app/views/cards/_container.html.erb | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) rename app/views/cards/{_closure_toggle.html.erb => _closure.html.erb} (100%) diff --git a/app/views/cards/_closure_toggle.html.erb b/app/views/cards/_closure.html.erb similarity index 100% rename from app/views/cards/_closure_toggle.html.erb rename to app/views/cards/_closure.html.erb diff --git a/app/views/cards/_container.html.erb b/app/views/cards/_container.html.erb index 4807d0028..69f486b97 100644 --- a/app/views/cards/_container.html.erb +++ b/app/views/cards/_container.html.erb @@ -22,6 +22,6 @@ <% end %> <% unless card.drafted? || card.creating? %> - <%= render "cards/closure_toggle", card: card %> + <%= render "cards/closure", card: card %> <% end %>
From df1f6234356ea1dadefc0fc2ff9c02f373d30042 Mon Sep 17 00:00:00 2001 From: David Heinemeier Hansson Date: Thu, 17 Apr 2025 15:25:11 +0200 Subject: [PATCH 23/33] Group partials for container --- app/views/cards/_container.html.erb | 8 ++++---- app/views/cards/{ => container}/_closure.html.erb | 0 app/views/cards/{ => container}/_engagement.html.erb | 0 app/views/cards/{ => container}/_gild.html.erb | 0 app/views/cards/{ => container}/_image.html.erb | 0 5 files changed, 4 insertions(+), 4 deletions(-) rename app/views/cards/{ => container}/_closure.html.erb (100%) rename app/views/cards/{ => container}/_engagement.html.erb (100%) rename app/views/cards/{ => container}/_gild.html.erb (100%) rename app/views/cards/{ => container}/_image.html.erb (100%) diff --git a/app/views/cards/_container.html.erb b/app/views/cards/_container.html.erb index 69f486b97..86844aaa6 100644 --- a/app/views/cards/_container.html.erb +++ b/app/views/cards/_container.html.erb @@ -1,9 +1,9 @@
" style="--card-color: <%= card.color %>;"> - <%= render "cards/engagement", card: card %> + <%= render "cards/container/engagement", card: card %>
diff --git a/app/views/cards/_closure.html.erb b/app/views/cards/container/_closure.html.erb similarity index 100% rename from app/views/cards/_closure.html.erb rename to app/views/cards/container/_closure.html.erb diff --git a/app/views/cards/_engagement.html.erb b/app/views/cards/container/_engagement.html.erb similarity index 100% rename from app/views/cards/_engagement.html.erb rename to app/views/cards/container/_engagement.html.erb diff --git a/app/views/cards/_gild.html.erb b/app/views/cards/container/_gild.html.erb similarity index 100% rename from app/views/cards/_gild.html.erb rename to app/views/cards/container/_gild.html.erb diff --git a/app/views/cards/_image.html.erb b/app/views/cards/container/_image.html.erb similarity index 100% rename from app/views/cards/_image.html.erb rename to app/views/cards/container/_image.html.erb From 62088b66d156e9902f822d10ecb99136498cee4b Mon Sep 17 00:00:00 2001 From: David Heinemeier Hansson Date: Thu, 17 Apr 2025 15:30:55 +0200 Subject: [PATCH 24/33] Suffix qualifier is unnnecessary --- app/controllers/cards/assignments_controller.rb | 2 +- app/controllers/cards/closures_controller.rb | 4 ++-- app/controllers/cards/engagements_controller.rb | 4 ++-- app/controllers/cards/goldnesses_controller.rb | 4 ++-- app/controllers/cards/stagings_controller.rb | 2 +- app/controllers/cards/taggings_controller.rb | 2 +- app/controllers/concerns/card_scoped.rb | 2 +- 7 files changed, 10 insertions(+), 10 deletions(-) diff --git a/app/controllers/cards/assignments_controller.rb b/app/controllers/cards/assignments_controller.rb index bba888bf4..d2d8b8aa6 100644 --- a/app/controllers/cards/assignments_controller.rb +++ b/app/controllers/cards/assignments_controller.rb @@ -6,6 +6,6 @@ class Cards::AssignmentsController < ApplicationController def create @card.toggle_assignment @collection.users.active.find(params[:assignee_id]) - rerender_card_container + rerender_card end end diff --git a/app/controllers/cards/closures_controller.rb b/app/controllers/cards/closures_controller.rb index f79608036..ac2e0ec46 100644 --- a/app/controllers/cards/closures_controller.rb +++ b/app/controllers/cards/closures_controller.rb @@ -3,11 +3,11 @@ class Cards::ClosuresController < ApplicationController def create @card.close(user: Current.user, reason: params[:reason]) - rerender_card_container + rerender_card end def destroy @card.reopen - rerender_card_container + rerender_card end end diff --git a/app/controllers/cards/engagements_controller.rb b/app/controllers/cards/engagements_controller.rb index e1178f1b3..9baaa7609 100644 --- a/app/controllers/cards/engagements_controller.rb +++ b/app/controllers/cards/engagements_controller.rb @@ -3,11 +3,11 @@ class Cards::EngagementsController < ApplicationController def create @card.engage - rerender_card_container + rerender_card end def destroy @card.reconsider - rerender_card_container + rerender_card end end diff --git a/app/controllers/cards/goldnesses_controller.rb b/app/controllers/cards/goldnesses_controller.rb index fb6076eec..95a821fc3 100644 --- a/app/controllers/cards/goldnesses_controller.rb +++ b/app/controllers/cards/goldnesses_controller.rb @@ -3,11 +3,11 @@ class Cards::GoldnessesController < ApplicationController def create @card.gild - rerender_card_container + rerender_card end def destroy @card.ungild - rerender_card_container + rerender_card end end diff --git a/app/controllers/cards/stagings_controller.rb b/app/controllers/cards/stagings_controller.rb index 37d4f91d7..a3fa96d64 100644 --- a/app/controllers/cards/stagings_controller.rb +++ b/app/controllers/cards/stagings_controller.rb @@ -10,7 +10,7 @@ class Cards::StagingsController < ApplicationController @card.update!(stage: nil) end - rerender_card_container + rerender_card end private diff --git a/app/controllers/cards/taggings_controller.rb b/app/controllers/cards/taggings_controller.rb index a44b8a4df..1d46d6a78 100644 --- a/app/controllers/cards/taggings_controller.rb +++ b/app/controllers/cards/taggings_controller.rb @@ -7,7 +7,7 @@ class Cards::TaggingsController < ApplicationController def create @card.toggle_tag_with sanitized_tag_title_param - rerender_card_container + rerender_card end private diff --git a/app/controllers/concerns/card_scoped.rb b/app/controllers/concerns/card_scoped.rb index e89bf7f4d..65cd75920 100644 --- a/app/controllers/concerns/card_scoped.rb +++ b/app/controllers/concerns/card_scoped.rb @@ -14,7 +14,7 @@ module CardScoped @collection = @card.collection end - def rerender_card_container + def rerender_card render turbo_stream: turbo_stream.replace([ @card, :card_container ], partial: "cards/container", locals: { card: @card.reload }) end end From ac9cbad4f92afe4d614ec0189050af065c4dc4cd Mon Sep 17 00:00:00 2001 From: David Heinemeier Hansson Date: Thu, 17 Apr 2025 15:32:09 +0200 Subject: [PATCH 25/33] I like this even better --- app/controllers/cards/assignments_controller.rb | 2 +- app/controllers/cards/closures_controller.rb | 4 ++-- app/controllers/cards/engagements_controller.rb | 4 ++-- app/controllers/cards/goldnesses_controller.rb | 4 ++-- app/controllers/cards/stagings_controller.rb | 2 +- app/controllers/cards/taggings_controller.rb | 2 +- app/controllers/concerns/card_scoped.rb | 2 +- 7 files changed, 10 insertions(+), 10 deletions(-) diff --git a/app/controllers/cards/assignments_controller.rb b/app/controllers/cards/assignments_controller.rb index d2d8b8aa6..0dd3d460e 100644 --- a/app/controllers/cards/assignments_controller.rb +++ b/app/controllers/cards/assignments_controller.rb @@ -6,6 +6,6 @@ class Cards::AssignmentsController < ApplicationController def create @card.toggle_assignment @collection.users.active.find(params[:assignee_id]) - rerender_card + render_card_replacement end end diff --git a/app/controllers/cards/closures_controller.rb b/app/controllers/cards/closures_controller.rb index ac2e0ec46..29dcfd30c 100644 --- a/app/controllers/cards/closures_controller.rb +++ b/app/controllers/cards/closures_controller.rb @@ -3,11 +3,11 @@ class Cards::ClosuresController < ApplicationController def create @card.close(user: Current.user, reason: params[:reason]) - rerender_card + render_card_replacement end def destroy @card.reopen - rerender_card + render_card_replacement end end diff --git a/app/controllers/cards/engagements_controller.rb b/app/controllers/cards/engagements_controller.rb index 9baaa7609..50a6daa83 100644 --- a/app/controllers/cards/engagements_controller.rb +++ b/app/controllers/cards/engagements_controller.rb @@ -3,11 +3,11 @@ class Cards::EngagementsController < ApplicationController def create @card.engage - rerender_card + render_card_replacement end def destroy @card.reconsider - rerender_card + render_card_replacement end end diff --git a/app/controllers/cards/goldnesses_controller.rb b/app/controllers/cards/goldnesses_controller.rb index 95a821fc3..1a0912a24 100644 --- a/app/controllers/cards/goldnesses_controller.rb +++ b/app/controllers/cards/goldnesses_controller.rb @@ -3,11 +3,11 @@ class Cards::GoldnessesController < ApplicationController def create @card.gild - rerender_card + render_card_replacement end def destroy @card.ungild - rerender_card + render_card_replacement end end diff --git a/app/controllers/cards/stagings_controller.rb b/app/controllers/cards/stagings_controller.rb index a3fa96d64..102c17599 100644 --- a/app/controllers/cards/stagings_controller.rb +++ b/app/controllers/cards/stagings_controller.rb @@ -10,7 +10,7 @@ class Cards::StagingsController < ApplicationController @card.update!(stage: nil) end - rerender_card + render_card_replacement end private diff --git a/app/controllers/cards/taggings_controller.rb b/app/controllers/cards/taggings_controller.rb index 1d46d6a78..a8fe7ecf9 100644 --- a/app/controllers/cards/taggings_controller.rb +++ b/app/controllers/cards/taggings_controller.rb @@ -7,7 +7,7 @@ class Cards::TaggingsController < ApplicationController def create @card.toggle_tag_with sanitized_tag_title_param - rerender_card + render_card_replacement end private diff --git a/app/controllers/concerns/card_scoped.rb b/app/controllers/concerns/card_scoped.rb index 65cd75920..2ea4752c4 100644 --- a/app/controllers/concerns/card_scoped.rb +++ b/app/controllers/concerns/card_scoped.rb @@ -14,7 +14,7 @@ module CardScoped @collection = @card.collection end - def rerender_card + def render_card_replacement render turbo_stream: turbo_stream.replace([ @card, :card_container ], partial: "cards/container", locals: { card: @card.reload }) end end From 182d1c934b24d4d84c029f8fc0a88c9b0b16ec1a Mon Sep 17 00:00:00 2001 From: David Heinemeier Hansson Date: Thu, 17 Apr 2025 15:35:56 +0200 Subject: [PATCH 26/33] Note that we dont want to keep reloading these frames --- app/views/cards/_container.html.erb | 1 + 1 file changed, 1 insertion(+) diff --git a/app/views/cards/_container.html.erb b/app/views/cards/_container.html.erb index 86844aaa6..76bc48262 100644 --- a/app/views/cards/_container.html.erb +++ b/app/views/cards/_container.html.erb @@ -15,6 +15,7 @@
<% if card.published? %> + <%# FIXME: Let's move this aside outside of the card container section so these frames don't reload/flicker when card is replaced %>
From 0e442ac0d04840cbeea1758571d85690541bad63 Mon Sep 17 00:00:00 2001 From: David Heinemeier Hansson Date: Thu, 17 Apr 2025 15:56:54 +0200 Subject: [PATCH 30/33] Use card replacement for card updates too --- app/controllers/cards_controller.rb | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/app/controllers/cards_controller.rb b/app/controllers/cards_controller.rb index e62146d4e..25428545f 100644 --- a/app/controllers/cards_controller.rb +++ b/app/controllers/cards_controller.rb @@ -25,16 +25,16 @@ class CardsController < ApplicationController def edit end + def update + @card.update! card_params + render_card_replacement + end + def destroy @card.destroy! redirect_to cards_path(collection_ids: [ @card.collection ]), notice: ("Card deleted" unless @card.creating?) end - def update - @card.update! card_params - redirect_to @card - end - private def set_card @card = @collection.cards.find params[:id] @@ -51,4 +51,8 @@ class CardsController < ApplicationController def card_params params.expect(card: [ :status, :title, :color, :due_on, :image, :draft_comment, tag_ids: [] ]) end + + def render_card_replacement + render turbo_stream: turbo_stream.replace([ @card, :card_container ], partial: "cards/container", locals: { card: @card.reload }) + end end From b8775d41f51193aa900b81b725c895dce8e79339 Mon Sep 17 00:00:00 2001 From: David Heinemeier Hansson Date: Thu, 17 Apr 2025 16:06:28 +0200 Subject: [PATCH 31/33] Inline perma to container partial Reveals all the container elements and perma wasnt used elsewhere. --- app/views/cards/_container.html.erb | 20 +++++++++++- app/views/cards/container/_title.html.erb | 14 ++++++++ app/views/cards/display/_perma.html.erb | 39 ----------------------- 3 files changed, 33 insertions(+), 40 deletions(-) create mode 100644 app/views/cards/container/_title.html.erb delete mode 100644 app/views/cards/display/_perma.html.erb diff --git a/app/views/cards/_container.html.erb b/app/views/cards/_container.html.erb index d3a2f1423..a817a21af 100644 --- a/app/views/cards/_container.html.erb +++ b/app/views/cards/_container.html.erb @@ -10,7 +10,25 @@
- <%= render "cards/display/perma", card: card %> + <%= card_article_tag card, class: "card" do %> +
+ <%= link_to card.collection.name, cards_path(collection_ids: [ card.collection ]), + class: "card__collection txt-uppercase overflow-ellipsis txt-reversed" %> + + <%= render "cards/display/perma/tags", card: card %> +
+ +
+ <%= render "cards/container/title", card: card %> + <%= render "cards/stagings/stages", card: card if card.doing? %> +
+ +
+ <%= render "cards/display/perma/meta", card: card %> +
+ + <%= render "cards/display/common/background", card: card %> + <% end %>
<% if card.published? %> diff --git a/app/views/cards/container/_title.html.erb b/app/views/cards/container/_title.html.erb new file mode 100644 index 000000000..b62eb2fb4 --- /dev/null +++ b/app/views/cards/container/_title.html.erb @@ -0,0 +1,14 @@ +

+ <% if card.published? %> + <%= turbo_frame_tag card, :edit do %> + <%= link_to card.title, edit_collection_card_path(card.collection, card), class: "card__title-link overflow-line-clamp" %> + <% end %> + <% else %> + <%= form_with model: card, url: collection_card_path(card.collection, card), id: "card_form", data: { controller: "auto-save" } do |form| %> + <%= form.text_area :title, placeholder: "Name it…", + class: "input input--textarea full-width borderless txt-align-start #{ "fill-highlight" if card.creating? }", + autofocus: card.title.blank?, + data: { action: "auto-save#change blur->auto-save#submit keydown.enter->auto-save#submit:prevent keydown.ctrl+enter->auto-save#submit:prevent" } %> + <% end %> + <% end %> +

diff --git a/app/views/cards/display/_perma.html.erb b/app/views/cards/display/_perma.html.erb deleted file mode 100644 index f70b9d2c8..000000000 --- a/app/views/cards/display/_perma.html.erb +++ /dev/null @@ -1,39 +0,0 @@ -<% cache card do %> - <%= card_article_tag card, class: "card" do %> -
- <%= link_to card.collection.name, cards_path(collection_ids: [card.collection]), - class: "card__collection txt-uppercase overflow-ellipsis txt-reversed" %> - - <%= render "cards/display/perma/tags", card: card %> -
- -
-

- <% if card.published? %> - <%= turbo_frame_tag card, :edit do %> - <%= link_to card.title, edit_collection_card_path(card.collection, card), class: "card__title-link overflow-line-clamp" %> - <% end %> - <% else %> - <%= form_with model: card, url: collection_card_path(card.collection, card), id: "card_form", data: { controller: "auto-save" } do |form| %> - <%= form.text_area :title, placeholder: "Name it…", - class: "input input--textarea full-width borderless txt-align-start #{ "fill-highlight" if card.creating? }", - autofocus: card.title.blank?, - data: { action: "auto-save#change blur->auto-save#submit keydown.enter->auto-save#submit:prevent keydown.ctrl+enter->auto-save#submit:prevent" } %> - <% end %> - <% end %> -

- - <% if card.doing? %> - <%= turbo_frame_tag dom_id(@card, :stages) do %> - <%= render "cards/stagings/stages", card: card %> - <% end %> - <% end %> -
- -
- <%= render "cards/display/perma/meta", card: card %> -
- - <%= render "cards/display/common/background", card: card %> - <% end %> -<% end %> From 36e9ff47fb9b7da2b25394f9d785b868b44007fe Mon Sep 17 00:00:00 2001 From: Kevin McConnell Date: Thu, 17 Apr 2025 16:27:01 +0100 Subject: [PATCH 32/33] Less noisy logging in production --- config/deploy.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/config/deploy.yml b/config/deploy.yml index 29eb15ba4..3ee355012 100644 --- a/config/deploy.yml +++ b/config/deploy.yml @@ -25,7 +25,7 @@ accessories: beamer-primary: <<: *beamer-accessory service: beamer-primary - cmd: beamer primary --debug --remove-after=1h --dir=/storage + cmd: beamer primary --remove-after=1h --dir=/storage port: 5000:80 roles: - web @@ -33,7 +33,7 @@ accessories: beamer-replica: <<: *beamer-accessory service: beamer-replica - cmd: beamer replica --debug --primary=http://fizzy-app-101:5000/ --dir=/storage + cmd: beamer replica --primary=http://fizzy-app-101:5000/ --dir=/storage roles: - web-replica From 09e544a881de6c62de6b898860fe456ba2f62d08 Mon Sep 17 00:00:00 2001 From: Kevin McConnell Date: Thu, 17 Apr 2025 16:28:20 +0100 Subject: [PATCH 33/33] Run beamer accessories in production only --- config/deploy.production.yml | 29 +++++++++++++++++++++++++++++ config/deploy.yml | 36 +++--------------------------------- 2 files changed, 32 insertions(+), 33 deletions(-) diff --git a/config/deploy.production.yml b/config/deploy.production.yml index 00a4b176e..cc05d75b5 100644 --- a/config/deploy.production.yml +++ b/config/deploy.production.yml @@ -18,3 +18,32 @@ proxy: ssh: user: app + + +x-beamer-accessory: &beamer-accessory + image: basecamp/beamer + registry: + username: bcbot + password: + - BASECAMP_REGISTRY_PASSWORD + options: + user: 1000 # Match the UID of the Rails app, for volume permissions + volumes: + - fizzy:/storage + + +accessories: + beamer-primary: + <<: *beamer-accessory + service: beamer-primary + cmd: beamer primary --remove-after=1h --dir=/storage + port: 5000:80 + roles: + - web + + beamer-replica: + <<: *beamer-accessory + service: beamer-replica + cmd: beamer replica --primary=http://fizzy-app-101:5000/ --dir=/storage + roles: + - web-replica diff --git a/config/deploy.yml b/config/deploy.yml index 3ee355012..9617a8b87 100644 --- a/config/deploy.yml +++ b/config/deploy.yml @@ -1,42 +1,10 @@ service: fizzy image: basecamp/fizzy - -x-basecamp-registry: &basecamp-registry - username: bcbot - password: - - BASECAMP_REGISTRY_PASSWORD - -x-beamer-accessory: &beamer-accessory - image: basecamp/beamer - registry: - <<: *basecamp-registry - options: - user: 1000 # Match the UID of the Rails app, for volume permissions - volumes: - - fizzy:/storage - - servers: jobs: cmd: bin/jobs -accessories: - beamer-primary: - <<: *beamer-accessory - service: beamer-primary - cmd: beamer primary --remove-after=1h --dir=/storage - port: 5000:80 - roles: - - web - - beamer-replica: - <<: *beamer-accessory - service: beamer-replica - cmd: beamer replica --primary=http://fizzy-app-101:5000/ --dir=/storage - roles: - - web-replica - volumes: - fizzy:/rails/storage @@ -44,7 +12,9 @@ proxy: ssl: true registry: - <<: *basecamp-registry + username: bcbot + password: + - BASECAMP_REGISTRY_PASSWORD builder: arch: amd64