Skip to content

Morph card title and description on broadcast refreshes#2990

Merged
flavorjones merged 1 commit into
mainfrom
card-description-turbo-refresh
Jul 22, 2026
Merged

Morph card title and description on broadcast refreshes#2990
flavorjones merged 1 commit into
mainfrom
card-description-turbo-refresh

Conversation

@flavorjones

@flavorjones flavorjones commented Jul 22, 2026

Copy link
Copy Markdown
Member

When a card's title or description was edited, other sessions viewing
the card never saw the change until a manual reload. The refresh
broadcast fired and other sessions morphed, but the title and
description sat inside an unconditional data-turbo-permanent wrapper,
so every morph skipped them and preserved the stale content.

The wrapper existed to solve two real problems: d6b602b made the
edit frame permanent so a broadcast refresh couldn't morph away an
edit in progress, and 649888d moved the attribute off the frame onto
an id-less wrapper div to stop Turbo transplanting the frame and
duplicating the Lexxy editor (basecamp/lexxy#263). The side effect
was that the exemption applied to every card being viewed, not just
to a card being edited.

Permanence is now applied only while editing. The morph-guard
Stimulus controller, attached to the card edit form, marks the
enclosing turbo-frame data-turbo-permanent on connect and removes it
on disconnect. Display mode morphs normally and an open editor still
survives refreshes. The attribute never appears in server-rendered
markup, so Turbo never transplants the frame across page loads and
the lexxy#263 dup can't recur (its underlying bug was also fixed
upstream in basecamp/lexxy#474, included in the 0.9.23 we pin).

When a card's title or description was edited, other sessions viewing
the card never saw the change until a manual reload. The refresh
broadcast fired and other sessions morphed, but the title and
description sat inside an unconditional data-turbo-permanent wrapper,
so every morph skipped them and preserved the stale content.

The wrapper existed to solve two real problems: d6b602b made the
edit frame permanent so a broadcast refresh couldn't morph away an
edit in progress, and 649888d moved the attribute off the frame onto
an id-less wrapper div to stop Turbo transplanting the frame and
duplicating the Lexxy editor (basecamp/lexxy#263). The side effect
was that the exemption applied to every card being viewed, not just
to a card being edited.

Permanence is now applied only while editing. The morph-guard
Stimulus controller, attached to the card edit form, marks the
enclosing turbo-frame data-turbo-permanent on connect and removes it
on disconnect. Display mode morphs normally and an open editor still
survives refreshes. The attribute never appears in server-rendered
markup, so Turbo never transplants the frame across page loads and
the lexxy#263 dup can't recur (its underlying bug was also fixed
upstream in basecamp/lexxy#474, included in the 0.9.23 we pin).
Copilot AI review requested due to automatic review settings July 22, 2026 15:12

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR fixes stale card title/description during Turbo broadcast refreshes by scoping data-turbo-permanent to edit mode only, so display mode can morph normally while an in-progress editor is still protected from refresh morphs.

Changes:

  • Remove unconditional data-turbo-permanent wrapper from the card content container so broadcast refreshes can update title/description.
  • Add a morph-guard Stimulus controller that marks the enclosing turbo-frame permanent only while the edit form is connected.
  • Add a system test suite (CardRefreshTest) that exercises refresh/morph behavior in view/edit/cancel scenarios and centralize the Lexxy test helper.

Tip

If you aren't ready for review, convert to a draft PR.
Click "Convert to draft" or run gh pr ready --undo.
Click "Ready for review" or run gh pr ready to reengage.

Reviewed changes

Copilot reviewed 6 out of 6 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
test/system/smoke_test.rb Removes a local Lexxy helper now shared via the system test base class.
test/system/card_refresh_test.rb Adds end-to-end system coverage for broadcast refresh behavior in view/edit/cancel flows.
test/application_system_test_case.rb Centralizes fill_in_lexxy helper for system tests.
app/views/cards/edit.html.erb Attaches morph-guard controller to the card edit form (edit-mode-only permanence).
app/views/cards/container/_content.html.erb Removes unconditional permanent wrapper so title/description can morph on refresh.
app/javascript/controllers/morph_guard_controller.js New Stimulus controller that toggles data-turbo-permanent on the enclosing frame while editing.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread test/application_system_test_case.rb
@flavorjones
flavorjones merged commit 1476c21 into main Jul 22, 2026
14 checks passed
@flavorjones
flavorjones deleted the card-description-turbo-refresh branch July 22, 2026 15:39
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants