From 0e22181190450527c97ce341ccc98ace9a3fddb1 Mon Sep 17 00:00:00 2001 From: Daniel Campbell Date: Thu, 19 Jul 2018 15:46:17 -0700 Subject: [PATCH] Add navigation ability to wizard buttons, close wizard on final Co-authored-by: Daniel Campbell Co-authored-by: Deniz Kusefoglu --- .../components/wizard/WizardCloak.tsx | 52 ++++++++++++++++--- .../components/wizard/WizardOverlay.tsx | 21 ++++++-- .../components/wizard/WizardStep.tsx | 32 ++++++++++-- ui/src/sources/components/GrandWizard.tsx | 46 ++++++++++++++-- ui/src/sources/containers/ManageSources.tsx | 5 +- 5 files changed, 133 insertions(+), 23 deletions(-) diff --git a/ui/src/reusable_ui/components/wizard/WizardCloak.tsx b/ui/src/reusable_ui/components/wizard/WizardCloak.tsx index 44c2af1f4..045c19ea9 100644 --- a/ui/src/reusable_ui/components/wizard/WizardCloak.tsx +++ b/ui/src/reusable_ui/components/wizard/WizardCloak.tsx @@ -1,11 +1,14 @@ import React, {PureComponent, ReactElement, ReactNode} from 'react' import WizardProgressBar from 'src/reusable_ui/components/wizard/WizardProgressBar' -import WizardStep from 'src/reusable_ui/components/wizard/WizardStep' interface WizardStepProps { children: ReactNode title: string isComplete: () => boolean + onPrevious: () => void + onNext: () => void + increment?: () => void + decrement?: () => void } enum StepStatus { @@ -25,12 +28,13 @@ interface State { } interface Props { - children: ReactElement + children: Array> + toggleVisibility: (isVisible: boolean) => () => void } class WizardCloak extends PureComponent { - public static getDerivedStateFromProps(props: Props) { - let currentStepIndex = -1 + public static getDerivedStateFromProps(props: Props, state: State) { + let {currentStepIndex} = state const childSteps = React.Children.map( props.children, (child: ReactElement, i) => { @@ -50,6 +54,14 @@ class WizardCloak extends PureComponent { return {steps: childSteps, currentStepIndex} } + constructor(props: Props) { + super(props) + this.state = { + steps: [], + currentStepIndex: -1, + } + } + public render() { const {steps, currentStepIndex} = this.state @@ -61,11 +73,37 @@ class WizardCloak extends PureComponent { ) } - private get CurrentChild(): JSX.Element { - const {children} = this.props + private incrementStep = () => { const {currentStepIndex} = this.state - return children[currentStepIndex] + this.setState({ + currentStepIndex: currentStepIndex + 1, + }) + } + + private decrementStep = () => { + const {currentStepIndex} = this.state + + this.setState({ + currentStepIndex: currentStepIndex - 1, + }) + } + + private get CurrentChild(): JSX.Element { + const {children, toggleVisibility} = this.props + const {currentStepIndex, steps} = this.state + + const advance = + currentStepIndex === steps.length - 1 + ? toggleVisibility(false) + : this.incrementStep + + const retreat = currentStepIndex === 0 ? null : this.decrementStep + + return React.cloneElement(children[currentStepIndex], { + increment: advance, + decrement: retreat, + }) } } diff --git a/ui/src/reusable_ui/components/wizard/WizardOverlay.tsx b/ui/src/reusable_ui/components/wizard/WizardOverlay.tsx index 0bfd55a06..043af31b6 100644 --- a/ui/src/reusable_ui/components/wizard/WizardOverlay.tsx +++ b/ui/src/reusable_ui/components/wizard/WizardOverlay.tsx @@ -1,28 +1,39 @@ -import React, {PureComponent, ReactNode} from 'react' +import React, {PureComponent, ReactElement, ReactNode} from 'react' import OverlayBody from 'src/reusable_ui/components/overlays/OverlayBody' import OverlayContainer from 'src/reusable_ui/components/overlays/OverlayContainer' import OverlayTechnology from 'src/reusable_ui/components/overlays/OverlayTechnology' import WizardCloak from 'src/reusable_ui/components/wizard/WizardCloak' import OverlayHeading from 'src/reusable_ui/components/overlays/OverlayHeading' - +interface WizardStepProps { + children: ReactNode + title: string + isComplete: () => boolean + onPrevious: () => void + onNext: () => void + increment?: () => void + decrement?: () => void +} // import {} from 'src/types' interface Props { - children: ReactNode + children: Array> visible: boolean title: string + toggleVisibility: (isVisible: boolean) => () => void } class WizardOverlay extends PureComponent { public render() { - const {children, visible, title} = this.props + const {children, visible, title, toggleVisibility} = this.props return ( - {children} + + {children} + diff --git a/ui/src/reusable_ui/components/wizard/WizardStep.tsx b/ui/src/reusable_ui/components/wizard/WizardStep.tsx index 674ba7cfc..fffee5e75 100644 --- a/ui/src/reusable_ui/components/wizard/WizardStep.tsx +++ b/ui/src/reusable_ui/components/wizard/WizardStep.tsx @@ -10,27 +10,49 @@ interface Props { isComplete: () => boolean onPrevious: () => void onNext: () => void + increment?: () => void + decrement?: () => void } class WizardStep extends PureComponent { public render() { - const {children, title, onPrevious, onNext} = this.props + const {children, title, decrement} = this.props return (

{title}

{children}
- - + )} +
) } + + private handleClickPrevious = () => { + const {onPrevious, decrement} = this.props + onPrevious() // TODO wait if async function + decrement() + } + + private handleClickNext = () => { + const {onNext, increment} = this.props + onNext() + increment() + } } export default WizardStep diff --git a/ui/src/sources/components/GrandWizard.tsx b/ui/src/sources/components/GrandWizard.tsx index f8b355cd8..04ed2fe10 100644 --- a/ui/src/sources/components/GrandWizard.tsx +++ b/ui/src/sources/components/GrandWizard.tsx @@ -6,6 +6,7 @@ import WizardStep from 'src/reusable_ui/components/wizard/WizardStep' interface Props { wizardVisibility: boolean + toggleVisibility: (isVisible: boolean) => () => void } interface State { @@ -13,24 +14,29 @@ interface State { } class WizardWithSteps extends PureComponent { - constructor(props) { + constructor(props: Props) { super(props) this.state = { completion: { - first: false, + first: true, second: false, third: false, }, } } public render() { - const {wizardVisibility} = this.props - + const {wizardVisibility, toggleVisibility} = this.props return ( - + some first children @@ -38,6 +44,7 @@ class WizardWithSteps extends PureComponent { title="Second Real Step" isComplete={this.completeTest('second')} onNext={this.handleSecondNext} + onPrevious={this.handleSecondPrev} > some second children
@@ -45,6 +52,7 @@ class WizardWithSteps extends PureComponent { title="Third Real Step" isComplete={this.completeTest('third')} onNext={this.handleThirdNext} + onPrevious={this.handleThirdPrev} > some third children @@ -57,6 +65,13 @@ class WizardWithSteps extends PureComponent { return completion[curr] } + private handleFirstNext = () => { + const {completion} = this.state + this.setState({ + completion: {...completion, first: true}, + }) + } + private handleSecondNext = () => { const {completion} = this.state this.setState({ @@ -70,6 +85,27 @@ class WizardWithSteps extends PureComponent { completion: {...completion, third: true}, }) } + + private handleFirstPrev = () => { + const {completion} = this.state + this.setState({ + completion: {...completion, first: false}, + }) + } + + private handleSecondPrev = () => { + const {completion} = this.state + this.setState({ + completion: {...completion, second: false}, + }) + } + + private handleThirdPrev = () => { + const {completion} = this.state + this.setState({ + completion: {...completion, third: false}, + }) + } } export default WizardWithSteps diff --git a/ui/src/sources/containers/ManageSources.tsx b/ui/src/sources/containers/ManageSources.tsx index 6de138cde..8e445b6af 100644 --- a/ui/src/sources/containers/ManageSources.tsx +++ b/ui/src/sources/containers/ManageSources.tsx @@ -78,7 +78,10 @@ class ManageSources extends PureComponent {

Chronograf Version: {VERSION}

- + ) }