11import React , { cloneElement } from 'react' ;
22import { createPortal } from 'react-dom' ;
33import PropTypes from 'prop-types' ;
4- import { WizardHeader , WizardNav , WizardNavItem , Backdrop , Bullseye } from '@patternfly/react-core' ;
4+ import { WizardHeader , Backdrop , Bullseye , WizardNav } from '@patternfly/react-core' ;
55import WizardStep from './wizard-step' ;
66import './wizard-styles.scss' ;
77import get from 'lodash/get' ;
88import set from 'lodash/set' ;
99import flattenDeep from 'lodash/flattenDeep' ;
1010import handleEnter from '@data-driven-forms/common/src/wizard/enter-handler' ;
11+ import WizardNavigation from './wizard-nav' ;
1112
1213const DYNAMIC_WIZARD_TYPES = [ 'function' , 'object' ] ;
1314
@@ -106,11 +107,12 @@ class Wizard extends React.Component {
106107 const currentStep = this . findCurrentStep ( prevState . prevSteps [ index ] ) ;
107108 const currentStepHasStepMapper = DYNAMIC_WIZARD_TYPES . includes ( typeof currentStep . nextStep ) ;
108109
110+ const hardcodedCrossroads = this . props . crossroads ;
109111 const dynamicStepShouldDisableNav = prevState . isDynamic && ( currentStepHasStepMapper || ! this . props . predictSteps ) ;
110112
111113 const invalidStepShouldDisableNav = valid === false ;
112114
113- if ( dynamicStepShouldDisableNav ) {
115+ if ( dynamicStepShouldDisableNav && ! hardcodedCrossroads ) {
114116 newState = {
115117 navSchema : this . props . predictSteps ? this . createSchema ( { currentIndex : index } ) : prevState . navSchema . slice ( 0 , index + INDEXING_BY_ZERO ) ,
116118 prevSteps : prevState . prevSteps . slice ( 0 , index ) ,
@@ -181,73 +183,62 @@ class Wizard extends React.Component {
181183 return schema ;
182184 } ;
183185
186+ handleSubmitFinal = ( ) => this . props . formOptions . onSubmit (
187+ this . handleSubmit (
188+ this . props . formOptions . getState ( ) . values ,
189+ [ ...this . state . prevSteps , this . state . activeStep ] ,
190+ this . props . formOptions . getRegisteredFields ,
191+ ) ,
192+ this . props . formOptions
193+ ) ;
194+
195+ setPrevSteps = ( ) => this . setState ( ( prevState ) => ( {
196+ navSchema : this . createSchema ( { currentIndex : this . state . activeStepIndex } ) ,
197+ prevSteps : prevState . prevSteps . slice ( 0 , this . state . activeStepIndex ) ,
198+ maxStepIndex : this . state . activeStepIndex ,
199+ } ) )
200+
184201 render ( ) {
185202 if ( this . state . loading ) {
186203 return null ;
187204 }
188205
189206 const {
190- title, description, FieldProvider, formOptions, buttonLabels, buttonsClassName, inModal, setFullWidth, setFullHeight, isCompactNav, showTitles,
207+ title,
208+ description,
209+ FieldProvider,
210+ formOptions,
211+ buttonLabels,
212+ buttonsClassName,
213+ inModal,
214+ setFullWidth,
215+ setFullHeight,
216+ isCompactNav,
217+ showTitles,
218+ FormSpyProvider,
219+ crossroads,
191220 } = this . props ;
192- const { activeStepIndex, navSchema, maxStepIndex } = this . state ;
193-
194- const handleSubmit = ( ) =>
195- formOptions . onSubmit (
196- this . handleSubmit (
197- formOptions . getState ( ) . values ,
198- [ ...this . state . prevSteps , this . state . activeStep ] ,
199- formOptions . getRegisteredFields ,
200- ) ,
201- formOptions
202- ) ;
221+ const { activeStepIndex, navSchema, maxStepIndex, isDynamic } = this . state ;
203222
204223 const currentStep = (
205224 < WizardStep
206225 { ...this . findCurrentStep ( this . state . activeStep ) }
207226 formOptions = { {
208227 ...formOptions ,
209- handleSubmit,
228+ handleSubmit : this . handleSubmitFinal ,
210229 } }
211230 buttonLabels = { buttonLabels }
212231 FieldProvider = { FieldProvider }
213232 buttonsClassName = { buttonsClassName }
214233 showTitles = { showTitles }
215234 /> ) ;
216235
217- const createStepsMap = ( ) => navSchema
218- . filter ( field => field . primary )
219- . map ( step => {
220- const substeps = step . substepOf && navSchema . filter ( field => field . substepOf === step . substepOf ) ;
221-
222- return < WizardNavItem
223- key = { step . substepOf || step . title }
224- text = { step . substepOf || step . title }
225- isCurrent = { substeps ? activeStepIndex >= step . index && activeStepIndex < step . index + substeps . length : activeStepIndex === step . index }
226- isDisabled = { formOptions . valid ? maxStepIndex < step . index : step . index > activeStepIndex }
227- onNavItemClick = { ( ind ) => this . jumpToStep ( ind , formOptions . valid ) }
228- step = { step . index }
229- >
230- { substeps && < WizardNav returnList >
231- { substeps . map ( substep => < WizardNavItem
232- key = { substep . title }
233- text = { substep . title }
234- isCurrent = { activeStepIndex === substep . index }
235- isDisabled = { formOptions . valid ?
236- maxStepIndex < substep . index
237- : substep . index > activeStepIndex }
238- onNavItemClick = { ( ind ) => this . jumpToStep ( ind , formOptions . valid ) }
239- step = { substep . index }
240- /> ) }
241- </ WizardNav > }
242- </ WizardNavItem > ;
243- } ) ;
244-
245236 return (
246237 < Modal inModal = { inModal } container = { this . container } >
247238 < div className = { `pf-c-wizard ${ inModal ? '' : 'no-shadow' } ${ isCompactNav ? 'pf-m-compact-nav' : '' } ${ setFullWidth ? 'pf-m-full-width' : '' } ${ setFullHeight ? 'pf-m-full-height' : '' } ` }
248239 role = "dialog"
249240 aria-modal = { inModal ? 'true' : undefined }
250- onKeyDown = { e => handleEnter ( e , formOptions , this . state . activeStep , this . findCurrentStep , this . handleNext , handleSubmit ) }
241+ onKeyDown = { e => handleEnter ( e , formOptions , this . state . activeStep , this . findCurrentStep , this . handleNext , this . handleSubmitFinal ) }
251242 >
252243 { title && < WizardHeader
253244 title = { title }
@@ -256,7 +247,21 @@ class Wizard extends React.Component {
256247 /> }
257248 < div className = "pf-c-wizard__outer-wrap" >
258249 < WizardNav >
259- { createStepsMap ( ) }
250+ < FormSpyProvider >
251+ { ( { values } ) => (
252+ < WizardNavigation
253+ navSchema = { navSchema }
254+ activeStepIndex = { activeStepIndex }
255+ formOptions = { formOptions }
256+ maxStepIndex = { maxStepIndex }
257+ jumpToStep = { this . jumpToStep }
258+ crossroads = { crossroads }
259+ isDynamic = { isDynamic }
260+ values = { values }
261+ setPrevSteps = { this . setPrevSteps }
262+ />
263+ ) }
264+ </ FormSpyProvider >
260265 </ WizardNav >
261266 { cloneElement ( currentStep , {
262267 handleNext : ( nextStep ) => this . handleNext ( nextStep , formOptions . getRegisteredFields ) ,
@@ -281,6 +286,7 @@ Wizard.propTypes = {
281286 title : PropTypes . any ,
282287 description : PropTypes . any ,
283288 FieldProvider : PropTypes . PropTypes . oneOfType ( [ PropTypes . object , PropTypes . func ] ) . isRequired ,
289+ FormSpyProvider : PropTypes . PropTypes . oneOfType ( [ PropTypes . object , PropTypes . func ] ) . isRequired ,
284290 formOptions : PropTypes . shape ( {
285291 getState : PropTypes . func . isRequired ,
286292 onSubmit : PropTypes . func . isRequired ,
@@ -298,6 +304,7 @@ Wizard.propTypes = {
298304 isDynamic : PropTypes . bool ,
299305 showTitles : PropTypes . bool ,
300306 predictSteps : PropTypes . bool ,
307+ crossroads : PropTypes . arrayOf ( PropTypes . string ) ,
301308} ;
302309
303310const defaultLabels = {
0 commit comments