FlowFuse / FlowFuse/flowfuse

StepSlider blocks all navigation when disableNextStep is true, not just forward navigation

Open
#7,837 0 comments 0 reactions 0 assignees View on GitHub
area:frontend needs-triage
Dominant language
JavaScript
Stars
400
Forks
89
Avg merge
1d 20h
Merged PRs (30d)
149

Description

### Current Behavior

In StepSlider.vue:54, the select method bails out entirely when disableNextStep is true:
```js
select (key, disabled) {
if (this.disableNextStep) {
return
}
// ...
}
```
`disableNextStep` semantically means "the current step isn't complete, don't let the user advance." But the check blocks all step clicks, including going back to already completed steps. If you're on step 3 and the step isn't valid yet, you can't click step 1 or 2 either.

The guard should only block navigation when the target step is ahead of the current one (`key` > `currentEntry`).

Fixing that introduces a second problem. There's nothing preventing users from skipping intermediary steps entirely. `MultiStepForm.selectStep` just sets `currentStepKey` directly with no bounds checking:
```js
selectStep (key) {
this.currentStepKey = key
}
```
So clicking from step 1 straight to step 3 would work as long as `disableNextStep` is false on step 1, bypassing step 2's validation completely.

### Suggested approach

**Phase 1**: Track a "high water mark" of the furthest step the user has validly reached. Only allow navigation to steps up to that point. Any change on step N resets the high water mark back to N, forcing the user to re-walk through N+1, N+2, etc. This is intentionally blunt but safe.

Concretely this means:
- New state in `MultiStepForm` (something like `maxReachedStep`) that increments as the user progresses forward via the Next button
- Pass it down to `StepSlider` as a prop to gate which steps are clickable
- When a step emits an update (via step-updated), reset the high water mark to the current step
- Fix the `disableNextStep` guard to only block forward navigation, not backward

*Phase 2 (follow-up)**: The blunt reset is too aggressive for forms where steps aren't all interdependent. For example, changing something in step 1 shouldn't force re-walking step 2 if step 2 has no dependency on step 1. This would introduce per-step dependency declarations so concrete form implementations can define which steps depend on which. A change on step N would then only invalidate steps that declare a dependency on it. The step definition format already supports disabled and hidden, so something like a `dependsOn` array or a validation callback per step could slot in there.

### Expected Behavior

_No response_

### Steps To Reproduce

_No response_

### Environment

- FlowFuse version: 2.32.0
- Node.js version:
- npm version:
- Platform/OS:
- Browser:

### Have you provided an initial effort estimate for this issue?

I have provided an initial effort estimate

Contributor guide

Open the contributing guide

Research direction

Start by reading StepSlider.vue:54 and MultiStepForm.selectStep, then trace the step-updated event and the Next-button progression. Implement the stated Phase 1 boundary so backward navigation remains available, forward navigation cannot skip intermediary steps, and edits reset the reachable boundary to the current step. Confirm the behavior against the issue's step 1-to-3 and step 3-to-1 scenarios.

Written by the indexing model from the issue text.

Assessment

Tech stack
javascript
Domain
frontend
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
48/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.