Skip to content

Commit a081069

Browse files
sethherrclaude
andcommitted
Carry the impound multi-update flash in the layout's flash region
The multi-update form redirects back to a turbo_stream response, so its flash needed a copy inside the results frame to survive. Replace #flash-messages alongside the frame instead, and drop the render_flash local and the bootstrap alert markup it rendered. The flash component renders its container even when empty, so the turbo_stream has something to target. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
1 parent 31266fd commit a081069

5 files changed

Lines changed: 14 additions & 24 deletions

File tree

app/components/ui/alerts/flash_message/component.rb

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,14 +10,12 @@ def initialize(flash: {})
1010
@flash = flash
1111
end
1212

13-
def render?
14-
messages.any?
15-
end
16-
1713
private
1814

15+
# Renders even when empty: #flash-messages is the turbo_stream target for
16+
# frame updates that carry a flash (see organized/impound_records).
1917
def messages
20-
@messages ||= @flash.filter_map do |type, message|
18+
@flash.filter_map do |type, message|
2119
next unless message.is_a?(String)
2220
{text: message, kind: kind_for(type)}
2321
end

app/views/organized/impound_records/_results.html.erb

Lines changed: 0 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,3 @@
1-
<%#
2-
render_flash is passed only by index.turbo_stream.erb: the multi-update
3-
form redirects back here and the frame is replaced via turbo_stream, so the
4-
flash must live inside the frame to survive. On a full page load the layout
5-
renders the flash instead.
6-
%>
7-
8-
<% if local_assigns[:render_flash] %>
9-
<div class="bootstrapstyle primary-alert-block">
10-
<% flash.each do |name, msg| %>
11-
<%= render partial: "/shared/alert", locals: {body: msg, type: name} %>
12-
<% end %>
13-
</div>
14-
<% end %>
15-
161
<% if @render_chart %>
172
<%= render(UI::ChartAsyncFrame::Component.new(
183
id: :impound_records_chart_frame,
Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
11
<%= turbo_stream.update :impound_records_results_frame do %>
2-
<%= render partial: "results", locals: {render_flash: true} %>
2+
<%= render partial: "results" %>
3+
<% end %>
4+
5+
<%# The multi-update form redirects back here, so carry its flash along with the frame %>
6+
<%= turbo_stream.replace "flash-messages" do %>
7+
<%= render(UI::Alerts::FlashMessage::Component.new(flash:)) %>
38
<% end %>

spec/components/ui/alerts/flash_message/component_spec.rb

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,8 +48,9 @@
4848
context "with empty flash" do
4949
let(:flash) { {} }
5050

51-
it "renders nothing" do
52-
expect(component.to_html).to be_blank
51+
it "renders the container with no alerts, so turbo_streams can target it" do
52+
expect(component).to have_css("#flash-messages")
53+
expect(component).not_to have_css("[role='alert']")
5354
end
5455
end
5556

spec/integration/organized/impound_records_spec.rb

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -163,7 +163,8 @@ def check_for_update(impound_record)
163163
expect(page).to have_no_css("[role=alert]", text: /select at least one record/i)
164164
within("#impoundRecordUpdateForm") { find("button[type=submit]").click }
165165

166-
expect(page).to have_content("Updated 1 impound record", wait: 10)
166+
# The turbo_stream response replaces the layout's flash region alongside the frame
167+
expect(page).to have_css("#flash-messages", text: "Updated 1 impound record", wait: 10)
167168
expect(registered.impound_record_updates.pluck(:kind)).to eq ["retrieved_by_owner"]
168169
expect(unregistered.impound_record_updates).to be_empty
169170

0 commit comments

Comments
 (0)