Skip to content

EDM-3687: Allow user to go back to step to fix problems#625

Open
celdrake wants to merge 3 commits into
flightctl:mainfrom
celdrake:EDM-3687-enable-create-fleet-wizard-step
Open

EDM-3687: Allow user to go back to step to fix problems#625
celdrake wants to merge 3 commits into
flightctl:mainfrom
celdrake:EDM-3687-enable-create-fleet-wizard-step

Conversation

@celdrake
Copy link
Copy Markdown
Collaborator

@celdrake celdrake commented Apr 20, 2026

Fixes the issue in the CreateFleetWizard whereby when a validation error was present in step N, and user moved to N-1, then they couldn't move back to step N.

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Apr 20, 2026

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Enterprise

Run ID: 3a9459f2-9e4c-41c8-b0ae-3b80ad94d0a8

📥 Commits

Reviewing files that changed from the base of the PR and between dc63d36 and 11ba06b.

📒 Files selected for processing (10)
  • libs/ui-components/src/components/Catalog/AddCatalogItemWizard/AddCatalogItemWizard.tsx
  • libs/ui-components/src/components/Catalog/EditWizard/EditAppWizard.tsx
  • libs/ui-components/src/components/Catalog/EditWizard/EditOsWizard.tsx
  • libs/ui-components/src/components/Catalog/InstallWizard/InstallAppWizard.tsx
  • libs/ui-components/src/components/Catalog/InstallWizard/InstallOsWizard.tsx
  • libs/ui-components/src/components/Device/EditDeviceWizard/EditDeviceWizard.tsx
  • libs/ui-components/src/components/Fleet/CreateFleet/CreateFleetWizard.tsx
  • libs/ui-components/src/components/ImageBuilds/CreateImageBuildWizard/CreateImageBuildWizard.tsx
  • libs/ui-components/src/components/ImportResourceWizard/ImportResourceWizard.tsx
  • libs/ui-components/src/utils/wizards.ts
🚧 Files skipped from review as they are similar to previous changes (8)
  • libs/ui-components/src/utils/wizards.ts
  • libs/ui-components/src/components/Catalog/InstallWizard/InstallOsWizard.tsx
  • libs/ui-components/src/components/Catalog/EditWizard/EditAppWizard.tsx
  • libs/ui-components/src/components/ImageBuilds/CreateImageBuildWizard/CreateImageBuildWizard.tsx
  • libs/ui-components/src/components/ImportResourceWizard/ImportResourceWizard.tsx
  • libs/ui-components/src/components/Catalog/AddCatalogItemWizard/AddCatalogItemWizard.tsx
  • libs/ui-components/src/components/Catalog/InstallWizard/InstallAppWizard.tsx
  • libs/ui-components/src/components/Device/EditDeviceWizard/EditDeviceWizard.tsx

Summary by CodeRabbit

  • Tests

    • Added an end-to-end test covering the Create Fleet wizard: entering a name, triggering validation with an invalid system image, and verifying Back/Next navigation, disabled Next on error, and retention of the invalid value across steps.
  • Refactor

    • Centralized and standardized wizard step enable/disable logic across multiple wizards for more consistent validation and navigation behavior.

Walkthrough

Adds a shared wizard-step gating utility used across many wizards, refactors wizard components to use it (computing ordered/valid step IDs from Formik where needed), and adds a Cypress E2E test plus a page-object getter for the wizard Back button.

Changes

Wizard Step Logic Update

Layer / File(s) Summary
Shared utility
libs/ui-components/src/utils/wizards.ts
Adds isWizardStepDisabled(stepId, orderedStepIds, validStepIds) to compute step disabled state by checking prior ordered steps against valid step ids.
Catalog & Edit wizards
libs/ui-components/src/components/Catalog/..., libs/ui-components/src/components/Catalog/EditWizard/*
Replaces local isDisabledStep logic with the shared utility; introduces/getValidStepIds helpers and uses Formik errors to derive valid step IDs where applicable.
Install wizards
libs/ui-components/src/components/Catalog/InstallWizard/*
Adds getValidStepIds helpers, imports FormikErrors typing, and uses isWizardStepDisabled for Select/Config/Review step gating.
Device, Fleet, ImageBuild, Import wizards
libs/ui-components/src/components/Device/..., .../Fleet/CreateFleet/..., .../ImageBuilds/..., .../ImportResourceWizard.tsx
Migrates per-file disable logic to isWizardStepDisabled, computes ordered/valid step IDs in render, and removes local index-based helpers.
Cypress Test Addition
libs/cypress/e2e/fleets/createFleet.cy.ts
New test validating wizard back navigation, field retention after navigation, and that the Next button disables on validation errors.
Page Object Enhancement
libs/cypress/pages/CreateFleetWizardPage.ts
Added backFleetWizardButton getter to access the wizard's Back button via cy.contains('button', 'Back').

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly describes the main objective: allowing users to navigate back to earlier steps to fix validation problems, which aligns with the core bug fix across all modified wizard components.
Description check ✅ Passed The description accurately relates to the changeset by explaining the specific bug being fixed in the CreateFleetWizard where users couldn't return to a step with validation errors.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.


Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

🧹 Nitpick comments (1)
libs/cypress/e2e/fleets/createFleet.cy.ts (1)

71-73: Assert the validation state is still active after returning.

The test confirms the invalid value is preserved, but it should also confirm the invalid step still disables Next after re-entry.

Suggested test assertion
     createFleetWizardPage.backFleetWizardButton.click();
     createFleetWizardPage.nextFleetWizardButton.should('be.enabled').click();
 
     createFleetWizardPage.newFleetSystemImageField.should('be.visible').should('have.value', 'invalid!oci');
+    createFleetWizardPage.nextFleetWizardButton.should('be.disabled');
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@libs/cypress/e2e/fleets/createFleet.cy.ts` around lines 71 - 73, The test
currently checks that createFleetWizardPage.newFleetSystemImageField retains the
invalid value but doesn't assert the wizard step remains invalid; after
navigating back (where
createFleetWizardPage.nextFleetWizardButton.should('be.enabled').click() is used
to advance), add an assertion that createFleetWizardPage.nextFleetWizardButton
is disabled when re-entering the step with the invalid value (e.g., assert
.should('be.disabled') before attempting to proceed) so the invalid validation
state is enforced; reference createFleetWizardPage.nextFleetWizardButton and
createFleetWizardPage.newFleetSystemImageField to locate where to add the check.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@libs/cypress/e2e/fleets/createFleet.cy.ts`:
- Around line 71-73: The test currently checks that
createFleetWizardPage.newFleetSystemImageField retains the invalid value but
doesn't assert the wizard step remains invalid; after navigating back (where
createFleetWizardPage.nextFleetWizardButton.should('be.enabled').click() is used
to advance), add an assertion that createFleetWizardPage.nextFleetWizardButton
is disabled when re-entering the step with the invalid value (e.g., assert
.should('be.disabled') before attempting to proceed) so the invalid validation
state is enforced; reference createFleetWizardPage.nextFleetWizardButton and
createFleetWizardPage.newFleetSystemImageField to locate where to add the check.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 2baa480f-44ef-41a2-9275-cf855b783eb0

📥 Commits

Reviewing files that changed from the base of the PR and between fc240a7 and 9f2b94a.

📒 Files selected for processing (3)
  • libs/cypress/e2e/fleets/createFleet.cy.ts
  • libs/cypress/pages/CreateFleetWizardPage.ts
  • libs/ui-components/src/components/Fleet/CreateFleet/CreateFleetWizard.tsx

Comment on lines +62 to +65
const stepIdx = orderedIds.findIndex((orderedStepId) => orderedStepId === stepId);
return orderedIds.some((orderedId, orderedStepIdx) => {
return orderedStepIdx < stepIdx && !validStepIds.includes(orderedId);
});
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

the condition is quite confusing TBH.
Can't we just pass a current step ID to this function and return early ?

Suggested change
const stepIdx = orderedIds.findIndex((orderedStepId) => orderedStepId === stepId);
return orderedIds.some((orderedId, orderedStepIdx) => {
return orderedStepIdx < stepIdx && !validStepIds.includes(orderedId);
});
const isDisabledStep = (currentStepId: string, stepId: string, validStepIds: string[]) => {
if (currentStepId === stepId) {
return false; //current step is never disabled
}
const validIndex = validStepIds.indexOf(stepId);
return validIndex === -1 || validIndex !== orderedIds.indexOf(stepId);
}

also we use this condition in multiple wizards - maybe its worth making it a common func.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

With this change, the initial bug would not be fixed: When on step 2 with some invalid input, users can go back to step 1. And now clicking on "Next" does nothing since the step with the error is a "future step" from the POV of the new current step.

I agree that it would be better to unify the check for the disabled steps in the different Wizards.
I can see two options:

  • Use in the CreateFleetWizard the pattern we have in the other wizards, that for step N+2, they check the steps N, N+1.
  • Make this function reusable and use it in all the wizards.

Personally I find the second one better in the long run, even though it's harder to understand. We could properly document it and it would not require new custom logic for any new Wizards.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Ok, sounds good. Lets go with the second one then.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Thanks.
I think it should be clearer now.

@celdrake celdrake force-pushed the EDM-3687-enable-create-fleet-wizard-step branch from 9f2b94a to dc63d36 Compare May 14, 2026 09:05
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

🧹 Nitpick comments (1)
libs/ui-components/src/utils/wizards.ts (1)

1-7: ⚡ Quick win

Add focused tests for the shared step-gating helper.

This function now controls navigation gating across multiple wizards, so a small table-driven test suite here would materially reduce regression risk (especially for “current step stays enabled when invalid” and “future step blocked when any prior step is invalid”).

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@libs/ui-components/src/utils/wizards.ts` around lines 1 - 7, Add a focused,
table-driven test suite for isWizardStepDisabled that exercises gating behavior
across orderedStepIds and validStepIds: include cases where (1) the current step
is invalid but should remain enabled (stepId present and invalid but no prior
invalid steps => expect false), (2) a future step is blocked when any prior step
is invalid (expect true when any orderedId with index < stepId is missing from
validStepIds), (3) all steps valid (expect false), and (4) the first step
behavior (expect false). Implement tests that call isWizardStepDisabled with
named scenarios and assert the Boolean result for each to prevent regressions.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@libs/ui-components/src/utils/wizards.ts`:
- Around line 1-7: Add a focused, table-driven test suite for
isWizardStepDisabled that exercises gating behavior across orderedStepIds and
validStepIds: include cases where (1) the current step is invalid but should
remain enabled (stepId present and invalid but no prior invalid steps => expect
false), (2) a future step is blocked when any prior step is invalid (expect true
when any orderedId with index < stepId is missing from validStepIds), (3) all
steps valid (expect false), and (4) the first step behavior (expect false).
Implement tests that call isWizardStepDisabled with named scenarios and assert
the Boolean result for each to prevent regressions.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Enterprise

Run ID: 11cf7821-f4d6-4209-a467-8fc185eb103d

📥 Commits

Reviewing files that changed from the base of the PR and between 9f2b94a and dc63d36.

📒 Files selected for processing (12)
  • libs/cypress/e2e/fleets/createFleet.cy.ts
  • libs/cypress/pages/CreateFleetWizardPage.ts
  • libs/ui-components/src/components/Catalog/AddCatalogItemWizard/AddCatalogItemWizard.tsx
  • libs/ui-components/src/components/Catalog/EditWizard/EditAppWizard.tsx
  • libs/ui-components/src/components/Catalog/EditWizard/EditOsWizard.tsx
  • libs/ui-components/src/components/Catalog/InstallWizard/InstallAppWizard.tsx
  • libs/ui-components/src/components/Catalog/InstallWizard/InstallOsWizard.tsx
  • libs/ui-components/src/components/Device/EditDeviceWizard/EditDeviceWizard.tsx
  • libs/ui-components/src/components/Fleet/CreateFleet/CreateFleetWizard.tsx
  • libs/ui-components/src/components/ImageBuilds/CreateImageBuildWizard/CreateImageBuildWizard.tsx
  • libs/ui-components/src/components/ImportResourceWizard/ImportResourceWizard.tsx
  • libs/ui-components/src/utils/wizards.ts
🚧 Files skipped from review as they are similar to previous changes (2)
  • libs/cypress/e2e/fleets/createFleet.cy.ts
  • libs/cypress/pages/CreateFleetWizardPage.ts

@celdrake celdrake force-pushed the EDM-3687-enable-create-fleet-wizard-step branch from dc63d36 to 11ba06b Compare May 14, 2026 09:28
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