Skip to content

feat(site/src/pages/TemplateBuilder): keep Continue button enabled with inline validation - #28940

Merged
chrifro merged 7 commits into
mainfrom
feat/template-builder-continue-always-enabled
Sep 9, 2026
Merged

feat(site/src/pages/TemplateBuilder): keep Continue button enabled with inline validation#28940
chrifro merged 7 commits into
mainfrom
feat/template-builder-continue-always-enabled

Conversation

@chrifro

@chrifro chrifro commented Sep 3, 2026

Copy link
Copy Markdown
Contributor

Summary

On the template builder (/templates/new/builder), the Continue button was disabled until the current step's requirements were met, leaving users with no explanation for why they could not advance.

This PR keeps the Continue button enabled at all times. When the current step is incomplete, clicking Continue no longer advances; instead it:

  • shows a red validation message (12px) below the button explaining what is missing, and
  • outlines the required input fields that are blocking continuation in red.

Changes

  • Removed the disabled={!canContinue} guard from the Continue button so it is always clickable.
  • handleNext blocks navigation when the step is incomplete and reveals the red validation message instead.
  • Added continueErrorMessage(stepId) with a step-specific reason (base template not selected, required parameters/module settings missing, no provisioner online).
  • Validation message uses a 12px (text-xs) font.
  • When validation is triggered, empty required fields in the base-parameters and module-settings steps are outlined in red (aria-invalid + border-border-destructive). Optional fields are unaffected.
  • The message and outlines clear automatically once the step's requirements are satisfied or the user moves to another step.
  • Added Storybook interaction tests: TemplateBuilderPageView (Continue stays enabled, message appears then clears), BaseTemplateParametersStep and ModuleSettingsStep (required field flagged invalid when empty).

The final-step "Create Template" button keeps its existing provisioner-based disable behavior; this change is scoped to the Continue button as requested.

Visual proof

Base template step (?step=base-infra), no base selected:

Before (Continue disabled) After (Continue enabled) After (validation error on click)
before after enabled after error

Module settings step (?step=module-settings) — required field outlined in red with the 12px message on Continue:

module outline

Testing

  • pnpm check, pnpm lint, pnpm lint:types, pnpm format pass.
  • Storybook interaction tests pass (vitest --project=storybook for the three step/page stories).
  • Verified manually against the running dev app on port 8080.
Implementation notes

Requirement: "for the template builder (/templates/new/builder) always keep the continue button enabled. If the requirements to continue are not met, show the error in red." Follow-up: "use 12px for the font size for the error message and highlight the input fields that cause the error with a red outline if applicable."

Approach:

  1. Keep the Continue button always enabled by dropping the disabled prop.
  2. Gate navigation in handleNext: when canContinue is false, set a local showContinueError flag and return instead of navigating.
  3. Render a red (text-content-destructive), 12px (text-xs) validation message below the nav controls when showContinueError && !canContinue.
  4. Pass showContinueError into the step renderers as showErrors; the base-parameters and module-settings steps mark each required-but-empty field's field.error, which FormField renders as aria-invalid plus a red border.
  5. Clear the flag (and thus the message and outlines) when requirements become satisfied or on step change, so nothing lingers.
  6. Message text is derived per step via continueErrorMessage(stepId).

This PR was generated by Coder Agents on behalf of @chrifro.

Copy link
Copy Markdown
Contributor

Review notes

I checked out the branch and ran the frontend checks against the diff:

  • pnpm lint:types — pass
  • pnpm check (Biome) — pass
  • pnpm test:storybook for the 3 new story files — 6/6 pass

The core mechanism is clean: dropping the disabled guard, short-circuiting in handleNext, and reusing the existing FormField error plumbing (aria-invalid + border-border-destructive) via the showErrors prop. Well tested with real play interactions.

A few findings:

1. Dead branch in continueErrorMessage for "customizations" (minor)
"customizations" returns "A provisioner must be online to continue.", but it's the last visible step, so isLastStep is true and the Create Template button renders instead of Continue. showContinueError is only set from handleNext, which only fires from the Continue button, so this message can never display. Harmless (the default case covers it), but the branch is unreachable — consider removing it or confirming intent.

2. useEffect for the step-change reset vs. FE8 (minor / style)

useEffect(() => { setShowContinueError(false); }, [currentStep.id]);

FE8 says use useEffect only to synchronize with external systems, not to reset derived state. The canContinue case already uses the recommended render-time adjustment pattern, so this is slightly inconsistent. Could be folded into the same render-time reset by tracking the previous step id. Behavior is correct; purely stylistic.

3. Required bool variables get no visual outline (edge case)
In both variableToField functions, the bool branch returns a "switch" and ignores the error argument. A required, empty bool makes canContinue false (so Continue is blocked and the message shows) but the switch itself isn't flagged, unlike text fields. Rare, and switches can't really render "empty," but the required-field highlighting is silently incomplete for that type.

Nothing blocking — #1 is the only one I'd suggest addressing before merge.


Generated by Coder Agents on behalf of @jeremyruppel.

@chrifro
chrifro requested a review from jeremyruppel September 4, 2026 07:31

@aqandrew aqandrew 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.

Thanks for this Christin! Tested locally and it works perfectly 🙂

Just a few nits about redundant comments and a function name, lgtm otherwise

Comment thread site/src/pages/TemplateBuilder/BaseTemplateParametersStep.tsx Outdated
Comment thread site/src/pages/TemplateBuilder/ModuleSettingsStep.tsx Outdated
Comment thread site/src/pages/TemplateBuilder/TemplateBuilderPageView.tsx Outdated
Comment thread site/src/pages/TemplateBuilder/TemplateBuilderPageView.tsx Outdated
chrifro and others added 7 commits September 7, 2026 07:29
The template builder Continue button was disabled until the current step's
requirements were met, which left users guessing why they could not advance.
Keep the button enabled at all times and, when the step is incomplete,
surface a red validation message explaining what is missing instead of
advancing.
…nk error text

Use a 12px (text-xs) font for the Continue validation message and outline the
required input fields that block continuation in red when the user tries to
advance an incomplete step.
Remove the unreachable customizations branch from continueErrorMessage (the
final step renders Create Template, not Continue) and replace the step-change
reset effect with a render-time state adjustment that tracks the active step.
…essage

Clarify the helper name so it reads as "get a continue-error-message".
@chrifro
chrifro force-pushed the feat/template-builder-continue-always-enabled branch from 1e84f6c to 35ac744 Compare September 7, 2026 07:33
@chrifro
chrifro requested a review from aqandrew September 7, 2026 07:52
@chrifro
chrifro merged commit d44f87e into main Sep 9, 2026
26 checks passed
@chrifro
chrifro deleted the feat/template-builder-continue-always-enabled branch September 9, 2026 07:02
@github-actions github-actions Bot locked and limited conversation to collaborators Sep 9, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants