From 1d6cc37bb4dc50978cc9b840e031611184d60b9d Mon Sep 17 00:00:00 2001 From: Jorge Manrubia Date: Mon, 3 Nov 2025 10:57:35 +0100 Subject: [PATCH 1/2] Add missing blank content validation --- app/models/step.rb | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/models/step.rb b/app/models/step.rb index c4e35f33e..c2063dfaa 100644 --- a/app/models/step.rb +++ b/app/models/step.rb @@ -3,6 +3,8 @@ class Step < ApplicationRecord scope :completed, -> { where(completed: true) } + validates :content, presence: true + def completed? completed end From da6d1011fd60cfeef3ff9c6b5c3377851e123b12 Mon Sep 17 00:00:00 2001 From: Jorge Manrubia Date: Mon, 3 Nov 2025 10:57:58 +0100 Subject: [PATCH 2/2] Replace card replacement with stream actions to prevent flickering when managing steps --- app/controllers/cards/steps_controller.rb | 3 --- app/views/cards/display/perma/_steps.html.erb | 4 ++-- app/views/cards/steps/create.turbo_stream.erb | 3 +++ app/views/cards/steps/destroy.turbo_stream.erb | 1 + app/views/cards/steps/update.turbo_stream.erb | 3 +++ test/controllers/cards/steps_controller_test.rb | 10 +++++----- 6 files changed, 14 insertions(+), 10 deletions(-) create mode 100644 app/views/cards/steps/create.turbo_stream.erb create mode 100644 app/views/cards/steps/destroy.turbo_stream.erb create mode 100644 app/views/cards/steps/update.turbo_stream.erb diff --git a/app/controllers/cards/steps_controller.rb b/app/controllers/cards/steps_controller.rb index 4f3434632..305890508 100644 --- a/app/controllers/cards/steps_controller.rb +++ b/app/controllers/cards/steps_controller.rb @@ -5,7 +5,6 @@ class Cards::StepsController < ApplicationController def create @step = @card.steps.create!(step_params) - render_card_replacement end def show @@ -16,12 +15,10 @@ class Cards::StepsController < ApplicationController def update @step.update!(step_params) - render_card_replacement end def destroy @step.destroy! - render_card_replacement end private diff --git a/app/views/cards/display/perma/_steps.html.erb b/app/views/cards/display/perma/_steps.html.erb index 5ce71f721..6cca251d2 100644 --- a/app/views/cards/display/perma/_steps.html.erb +++ b/app/views/cards/display/perma/_steps.html.erb @@ -1,9 +1,9 @@
    <%= render partial: "cards/steps/step", collection: card.steps, as: :step %> -
  1. +
  2. - <%= form_with model: [card, Step.new], url: card_steps_path(card), data: { controller: "form", action: "submit->form#preventEmptySubmit" } do |form| %> + <%= form_with model: [card, Step.new], url: card_steps_path(card), data: { controller: "form", action: "submit->form#preventEmptySubmit turbo:submit-end->form#reset" } do |form| %> <%= form.text_field :content, class: "input step__content hide-focus-ring", placeholder: "Add a step…", autocomplete: "off", data: { form_target: "input" }, aria: { label: "Add a step" } %> <% end %>
  3. diff --git a/app/views/cards/steps/create.turbo_stream.erb b/app/views/cards/steps/create.turbo_stream.erb new file mode 100644 index 000000000..399593809 --- /dev/null +++ b/app/views/cards/steps/create.turbo_stream.erb @@ -0,0 +1,3 @@ +<%= turbo_stream.before dom_id(@card, :new_step) do %> + <%= render "cards/steps/step", step: @step %> +<% end %> diff --git a/app/views/cards/steps/destroy.turbo_stream.erb b/app/views/cards/steps/destroy.turbo_stream.erb new file mode 100644 index 000000000..a5c5deefb --- /dev/null +++ b/app/views/cards/steps/destroy.turbo_stream.erb @@ -0,0 +1 @@ +<%= turbo_stream.remove @step %> diff --git a/app/views/cards/steps/update.turbo_stream.erb b/app/views/cards/steps/update.turbo_stream.erb new file mode 100644 index 000000000..24fd7f934 --- /dev/null +++ b/app/views/cards/steps/update.turbo_stream.erb @@ -0,0 +1,3 @@ +<%= turbo_stream.replace @step do %> + <%= render "cards/steps/step", step: @step %> +<% end %> diff --git a/test/controllers/cards/steps_controller_test.rb b/test/controllers/cards/steps_controller_test.rb index 677279a2a..72c24f071 100644 --- a/test/controllers/cards/steps_controller_test.rb +++ b/test/controllers/cards/steps_controller_test.rb @@ -10,7 +10,7 @@ class Cards::StepsControllerTest < ActionDispatch::IntegrationTest assert_difference -> { card.steps.count }, +1 do post card_steps_path(card), params: { step: { content: "Research alternatives" } }, as: :turbo_stream - assert_card_container_rerendered(card) + assert_turbo_stream action: :before, target: dom_id(card, :new_step) end assert_equal "Research alternatives", card.steps.last.content @@ -22,7 +22,7 @@ class Cards::StepsControllerTest < ActionDispatch::IntegrationTest assert_changes -> { step.reload.content }, from: "Original content", to: "Updated content" do put card_step_path(card, step), params: { step: { content: "Updated content" } }, as: :turbo_stream - assert_card_container_rerendered(card) + assert_turbo_stream action: :replace, target: dom_id(step) end end @@ -32,7 +32,7 @@ class Cards::StepsControllerTest < ActionDispatch::IntegrationTest assert_difference -> { card.steps.count }, -1 do delete card_step_path(card, step), as: :turbo_stream - assert_card_container_rerendered(card) + assert_turbo_stream action: :remove, target: dom_id(step) end end @@ -43,13 +43,13 @@ class Cards::StepsControllerTest < ActionDispatch::IntegrationTest # Toggle to completed assert_changes -> { step.reload.completed? }, from: false, to: true do put card_step_path(card, step), params: { step: { completed: "1" } }, as: :turbo_stream - assert_card_container_rerendered(card) + assert_turbo_stream action: :replace, target: dom_id(step) end # Toggle back to incomplete assert_changes -> { step.reload.completed? }, from: true, to: false do put card_step_path(card, step), params: { step: { completed: "0" } }, as: :turbo_stream - assert_card_container_rerendered(card) + assert_turbo_stream action: :replace, target: dom_id(step) end end end