Skip to content

Commit

Permalink
fix(Wizard.Pattern): allow disabling previous and next steps in Wizar…
Browse files Browse the repository at this point in the history
…d.Pattern (patternfly#529)

affects: patternfly-react

ISSUES CLOSED: patternfly#526 patternfly#527
  • Loading branch information
rawagner authored and jeff-phillips-18 committed Aug 30, 2018
1 parent aa839a8 commit 529eeeb
Show file tree
Hide file tree
Showing 4 changed files with 52 additions and 6 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -36,13 +36,14 @@ class StatefulWizardPattern extends React.Component {
};

render() {
const { shouldDisableNextStep, ...otherProps } = this.props;
const { shouldDisableNextStep, shouldDisablePreviousStep, ...otherProps } = this.props;
const { activeStepIndex } = this.state;
// NOTE: the steps array is passed down with ...otherProps, including any shouldPreventEnter or shouldPreventExit functions inside it.
// These functions are for StatefulWizardPattern only and should not be used in WizardPattern despite being passed down here.
return (
<WizardPattern
nextStepDisabled={shouldDisableNextStep(activeStepIndex)}
previousStepDisabled={shouldDisablePreviousStep(activeStepIndex)}
{...excludeKeys(otherProps, ['shouldPreventStepChange'])}
activeStepIndex={activeStepIndex} // Value from state, as set by getDerivedStateFromProps
onStepChanged={this.onStepChanged}
Expand All @@ -52,7 +53,7 @@ class StatefulWizardPattern extends React.Component {
}

StatefulWizardPattern.propTypes = {
...excludeKeys(WizardPattern.propTypes, ['nextStepDisabled']),
...excludeKeys(WizardPattern.propTypes, ['nextStepDisabled', 'previousStepDisabled']),
steps: PropTypes.arrayOf(
PropTypes.shape({
...wizardStepShape,
Expand All @@ -61,12 +62,14 @@ StatefulWizardPattern.propTypes = {
})
),
shouldDisableNextStep: PropTypes.func,
shouldDisablePreviousStep: PropTypes.func,
shouldPreventStepChange: PropTypes.func
};

StatefulWizardPattern.defaultProps = {
...excludeKeys(WizardPattern.defaultProps, ['activeStepIndex', 'nextStepDisabled']),
...excludeKeys(WizardPattern.defaultProps, ['activeStepIndex', 'nextStepDisabled', 'previousStepDisabled']),
shouldDisableNextStep: noop,
shouldDisablePreviousStep: noop,
shouldPreventStepChange: noop
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ const WizardPattern = ({
onNext,
onBack,
nextStepDisabled,
previousStepDisabled,
title,
loadingTitle,
loadingMessage,
Expand Down Expand Up @@ -76,14 +77,15 @@ const WizardPattern = ({

const preventExitActive = activeStep.preventExit;
const preventEnterTarget = targetStep.preventEnter || (stepBeforeTarget && stepBeforeTarget.isInvalid);
const nextStepClicked = newStepIndex === activeStepIndex + 1;
const nextStepClicked = newStepIndex > activeStepIndex;

return preventExitActive || preventEnterTarget || (nextStepClicked && nextStepDisabled);
return preventExitActive || preventEnterTarget || nextStepClicked ? nextStepDisabled : previousStepDisabled;
};

const activeStepStr = (activeStepIndex + 1).toString();

const prevStepUnreachable = onFirstStep || activeStep.preventExit || getPrevStep().preventEnter;
const prevStepUnreachable =
previousStepDisabled || onFirstStep || activeStep.preventExit || getPrevStep().preventEnter;
// nextStepUnreachable is still true onFinalStep, because the Next button turns into a Close button
const nextStepUnreachable =
nextStepDisabled || activeStep.isInvalid || activeStep.preventExit || getNextStep().preventEnter;
Expand Down Expand Up @@ -152,6 +154,7 @@ WizardPattern.propTypes = {
closeText: PropTypes.string,
steps: PropTypes.arrayOf(PropTypes.shape(wizardStepShape)),
nextStepDisabled: PropTypes.bool,
previousStepDisabled: PropTypes.bool,
stepButtonsDisabled: PropTypes.bool,
nextButtonRef: PropTypes.func,
bodyHeader: PropTypes.node,
Expand All @@ -175,6 +178,7 @@ WizardPattern.defaultProps = {
closeText: 'Close',
steps: [],
nextStepDisabled: false,
previousStepDisabled: false,
stepButtonsDisabled: false,
nextButtonRef: noop,
bodyHeader: null,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -312,6 +312,7 @@ const testStatefulWizardPattern = props => {
onExited={onExited}
title="Wizard Pattern Stateful Example"
shouldDisableNextStep={() => false}
shouldDisablePreviousStep={() => false}
shouldPreventStepChange={() => false}
steps={[
{ title: 'General', render: () => <p>General</p> },
Expand Down Expand Up @@ -378,6 +379,28 @@ const testDisableNextStepWizard = props => {
);
};

const testDisablePreviousStepWizard = props => {
const onHide = jest.fn();
const onExited = jest.fn();
const onStepChanged = jest.fn();
return (
<Wizard.Pattern.Stateful
show
onHide={onHide}
onExited={onExited}
onStepChanged={onStepChanged}
title="Wizard Disable Next Step"
shouldDisablePreviousStep={() => true}
steps={[
{ title: '1', render: () => <p>1</p> },
{ title: '2', render: () => <p className=".step2">2</p> },
{ title: '3', render: () => <p>3</p> }
]}
{...props}
/>
);
};

test('Wizard Stateful with shouldDisableNextStep should disable next step', () => {
const component = mount(testDisableNextStepWizard());
expect(
Expand All @@ -387,3 +410,18 @@ test('Wizard Stateful with shouldDisableNextStep should disable next step', () =
.getDOMNode().disabled
).toBe(true);
});

test('Wizard Stateful with shouldDisablePreviousStep should disable previous step', () => {
const component = mount(testDisablePreviousStepWizard());
component
.find('.wizard-pf-footer .btn')
.at(2)
.simulate('click');
expect(component.exists('.step2')).toEqual(true);
expect(
component
.find('.wizard-pf-footer .btn')
.at(1)
.getDOMNode().disabled
).toBe(true);
});
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,7 @@ exports[`Wizard Stateful Pattern renders properly: Wizard stateful pattern snaps
onHide={[MockFunction]}
onNext={[Function]}
onStepChanged={[Function]}
previousStepDisabled={false}
show={true}
stepButtonsDisabled={false}
steps={
Expand Down

0 comments on commit 529eeeb

Please sign in to comment.