Skip to content

Add a configurable Next steps screener component - #576

Merged
prestoncabe merged 16 commits into
mainfrom
556-next-steps-component
Oct 27, 2026
Merged

prestoncabe merged 16 commits into
mainfrom
556-next-steps-component

Conversation

@prestoncabe

@prestoncabe prestoncabe commented Oct 22, 2026 •

Copy link
Copy Markdown
Collaborator

Screeners can now include a Next steps form component. It shows application instructions and contacts for eligible benefits, unmet requirements and an analyst note for ineligible benefits, and the benefits that still need more information. Analysts can show decisions as they arrive or wait until every benefit is decided.

Closes #556. Fourth PR for #552, following #574. Print summary and AI draft integration follow in #557 and #558.

The editor loads benefit sources in the background and copies their content into each new component's schema configuration. Only a new component's content editing and form saving wait for its pending copy; other editor work stays available. A modal lets analysts edit that screener's copy or reset an individual benefit from its source. Missing copies are flagged, removed benefits are ignored, and importing a schema preserves its saved content. Publishing uses the existing form-schema snapshot; public viewers do not fetch working benefit content.

Publishing preserves benefit IDs in the published subcollection so evaluation results match the schema's copied content. Screener transfers and example imports remap those content keys when allocating new benefit IDs, preserving analyst edits.

Markdown is sanitized without template evaluation. HTTP(S) links open in a new tab; email and phone links use their contact apps. Pending or failed evaluations suppress stale instructions. Visible Next steps fields announce completion and replace the page's completion message; hidden or absent fields retain that fallback.

Modal saves preserve focus and other benefits' latest content, and discarding unsaved modal edits requires confirmation. Form saves prevent duplicate requests and keep newer edits marked unsaved. Deferred copies survive undo/redo and retries, follow the original component object, and never rewrite imported components that reuse an ID.

Publishing requires a saved form and rejects a missing artifact before changing publication metadata. Storage write failures reach the caller, save and publish errors remain visible for retry, and saving a new unedited form stores its initialized schema. Publication timestamps are recorded after the artifact work succeeds.

The rebase brings in the updated icon library from main. Individual icon imports prevent the development server from loading the library's entire icon source tree, which exhausted Chromium resources during repeated full-page navigation in CI. Four consecutive page loads and evaluations passed locally with seven distinct icon modules and no resource errors.

Validation:

  • All 285 frontend tests passed across 47 files, including save/publish errors, initial form saves, save state, late-loaded modal content, pending copies, undo/redo, retries, and imported component IDs.
  • Production frontend build passed.
  • All 235 builder API tests passed, including missing-form rejection, storage failures, publication ordering, and the nested component import regression.
  • Both public-screening Playwright tests passed locally, covering display modes, partial completion, eligibility changes, safe Markdown, pending evaluations, and failures.
  • Verified the viewer layout, content modal, and properties-panel edits in Chromium.
  • Authenticated end-to-end coverage passed in CI for copying, editing, resetting, saving, publishing content, and matching published benefit IDs.
  • All five CI checks passed on the rebased head with the icon-loading fix: frontend, builder API, library API, end-to-end, and documentation. Browser coverage includes recovery from an unsaved form by saving and publishing it.
  • git diff --check passed.

prestoncabe and others added 15 commits October 27, 2026 13:03
A leftover document from a failed delete made create() throw
ALREADY_EXISTS partway through publishing, leaving the published
screener with only some of its benefits.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Saving rebuilt the editor's benefit, so the keyed Show remounted it
mid-save: the saved status never appeared and focus was lost.
Remount only for another benefit or a reset.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Switching benefits, resetting, closing or pressing Escape in the
next steps modal silently dropped edits that hadn't been saved.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A Next steps field hidden by a condition still suppressed the
page's completion message, so respondents saw no completion signal.
Fields now report whether they are rendered, and the page drops its
message only while one is.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Replacing the page's role="status" completion message with a plain
heading meant screen readers no longer heard that screening was
complete. Keep a live region in the field that announces it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The properties panel checked component content against the benefits
that loaded, so a benefit whose fetch failed was never flagged even
though the content modal reported it. Check against the screener's
benefits instead.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Links other than http(s) lost their href, so mailto: and tel: links
analysts wrote showed as plain text. They now stay clickable without
opening a new tab.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The canvas and Save waited for one request per benefit on every
visit to the Form Editor, and any benefit change refetched them all.
Load content in the background, fetch each benefit once, and fill
Next steps components added before it arrived.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The viewer's webLink re-implemented the editor's http(s) check and
had drifted: it skipped the hostname rules, so it showed links the
editor would refuse to save. Move normalizeHttpUrl to a shared util
and build webLink on it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The Switch shows its Saving branch first, so isSaving() is always
false in the other two branches.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Now that the editor stays mounted through a save, its "Next steps
saved." status appeared next to the modal's own. Keep the modal's
message, which says the form still needs saving.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@prestoncabe
prestoncabe marked this pull request as ready for review October 27, 2026 17:18
@prestoncabe
prestoncabe merged commit c81a758 into main Oct 27, 2026
5 checks passed
@prestoncabe
prestoncabe deleted the 556-next-steps-component branch October 27, 2026 17:24
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.

Add a Next steps screener component

1 participant