From bb93b3608dfdac35dfa3c4a6a5770b5f75e559bc Mon Sep 17 00:00:00 2001 From: Iris Scholten Date: Mon, 7 Jan 2019 16:33:55 -0800 Subject: [PATCH] fix(ui/onboarding): Prevent unskippable steps from being skipped with progress bar --- .../components/wizard/ProgressBar.scss | 4 ++ .../components/wizard/ProgressBar.tsx | 47 +++++++++++++++++-- .../containers/OnboardingWizard.tsx | 3 +- 3 files changed, 50 insertions(+), 4 deletions(-) diff --git a/ui/src/clockface/components/wizard/ProgressBar.scss b/ui/src/clockface/components/wizard/ProgressBar.scss index 8751b0fa55..c9a65ce3c7 100644 --- a/ui/src/clockface/components/wizard/ProgressBar.scss +++ b/ui/src/clockface/components/wizard/ProgressBar.scss @@ -84,6 +84,10 @@ } } +.unclickable { + cursor: default; +} + .wizard--progress-connector { min-width: 20px; width: 100%; diff --git a/ui/src/clockface/components/wizard/ProgressBar.tsx b/ui/src/clockface/components/wizard/ProgressBar.tsx index e4e33d130b..3566154f0b 100644 --- a/ui/src/clockface/components/wizard/ProgressBar.tsx +++ b/ui/src/clockface/components/wizard/ProgressBar.tsx @@ -13,6 +13,7 @@ interface Props { handleSetCurrentStep: (stepNumber: number) => void stepStatuses: StepStatus[] stepTitles: string[] + stepSkippable: boolean[] } @ErrorHandling @@ -21,11 +22,51 @@ class ProgressBar extends PureComponent { return
{this.WizardProgress}
} - private handleSetCurrentStep = i => () => { - const {handleSetCurrentStep} = this.props + private handleSetCurrentStep = (i: number) => () => { + const {handleSetCurrentStep, currentStepIndex} = this.props + + const isAfterCurrentUnskippableStep = + !this.isStepSkippable && i > currentStepIndex + const isAfterNextUnskippableStep = + this.nextNonSkippableStep !== -1 && i > this.nextNonSkippableStep + + const preventSkip = + isAfterCurrentUnskippableStep || isAfterNextUnskippableStep + + if (preventSkip) { + return + } + handleSetCurrentStep(i) } + private get nextNonSkippableStep(): number { + const {currentStepIndex, stepSkippable, stepStatuses} = this.props + return _.findIndex(stepSkippable, (isSkippable, i) => { + return ( + !isSkippable && + i > currentStepIndex && + stepStatuses[i] !== StepStatus.Complete + ) + }) + } + + private get isStepSkippable(): boolean { + const {stepSkippable, stepStatuses, currentStepIndex} = this.props + + return ( + stepSkippable[currentStepIndex] || + stepStatuses[currentStepIndex] === StepStatus.Complete + ) + } + + private getStepClass(i: number): string { + if (!this.isStepSkippable && i > this.props.currentStepIndex) { + return 'wizard--progress-button unclickable' + } + return 'wizard--progress-button' + } + private get WizardProgress(): JSX.Element[] { const {stepStatuses, stepTitles, currentStepIndex} = this.props @@ -47,7 +88,7 @@ class ProgressBar extends PureComponent { const stepEle = (
{ 'Complete', ] - public stepSkippable = [false, false, false, false, false, false] + public stepSkippable = [true, false, true, true, true, true] constructor(props: Props) { super(props) @@ -190,6 +190,7 @@ class OnboardingWizard extends PureComponent { handleSetCurrentStep={onSetCurrentStepIndex} stepStatuses={stepStatuses} stepTitles={this.stepTitles} + stepSkippable={this.stepSkippable} /> )