1
- import { Button , Icon , Modal , Title , TitleSizes } from '@patternfly/react-core' ;
2
- import type { WizardStepFunctionType } from '@patternfly/react-core/deprecated' ;
3
- import { Wizard } from '@patternfly/react-core/deprecated' ;
1
+ import { Button , Icon , Modal , Title , TitleSizes , Wizard , WizardHeader , WizardStep } from '@patternfly/react-core' ;
2
+ import { ModalVariant } from '@patternfly/react-core/next' ;
4
3
import { ExclamationTriangleIcon } from '@patternfly/react-icons/dist/esm/icons/exclamation-triangle-icon' ;
5
4
import { addCostModel } from 'api/costModels' ;
6
5
import type { MetricHash } from 'api/metrics' ;
@@ -33,12 +32,12 @@ interface InternalWizardBaseProps extends WrappedComponentProps {
33
32
isSuccess : boolean ;
34
33
closeFnc : ( ) => void ;
35
34
isOpen : boolean ;
36
- onMove : WizardStepFunctionType ;
35
+ onMove : ( id : number ) => void ;
37
36
validators : ( ( any ) => boolean ) [ ] ;
38
37
steps : any [ ] ;
39
38
current : number ;
40
39
context : any ;
41
- setError : ( string ) => void ;
40
+ setError : ( error : string ) => void ;
42
41
setSuccess : ( ) => void ;
43
42
updateCostModel : ( ) => void ;
44
43
metricsHash : MetricHash ;
@@ -73,80 +72,105 @@ const InternalWizardBase: React.FC<InternalWizardBaseProps> = ({
73
72
onMove,
74
73
validators,
75
74
steps,
76
- current = 1 ,
75
+ current = 0 ,
77
76
context,
78
77
setError,
79
78
setSuccess,
80
79
updateCostModel,
81
80
} ) => {
82
- const newSteps = steps . map ( ( step , ix ) => {
83
- return {
84
- ...step ,
85
- canJumpTo : current > ix ,
86
- } ;
87
- } ) ;
88
- newSteps [ current - 1 ] . enableNext = validators [ current - 1 ] ( context ) ;
89
- const isAddingRate = context . type === 'OCP' && current === 2 && ! validators [ current - 1 ] ( context ) ;
81
+ const EmptyFooter = ( ) => null ;
82
+ const isAddingRate = context . type === 'OCP' && current === 1 && ! validators [ current ] ( context ) ;
83
+ const isFooterHidden = isSuccess || isProcess || isAddingRate ;
84
+
85
+ const newSteps = [ ...steps ] ;
86
+ newSteps [ current ] . isNextDisabled = ! validators [ current ] ( context ) ;
87
+
90
88
if ( current === steps . length && context . type !== '' ) {
91
- newSteps [ current - 1 ] . nextButtonText = intl . formatMessage ( messages . create ) ;
89
+ newSteps [ current ] . nextButtonText = intl . formatMessage ( messages . create ) ;
92
90
}
93
-
94
- return isOpen ? (
95
- < Wizard
96
- className = "costManagement"
97
- isOpen
98
- title = { intl . formatMessage ( messages . createCostModelTitle ) }
99
- description = { intl . formatMessage ( messages . createCostModelDesc ) }
100
- steps = { newSteps }
101
- startAtStep = { current }
102
- onNext = { onMove }
103
- onBack = { onMove }
104
- onGoToStep = { onMove }
105
- onClose = { closeFnc }
106
- footer = { isSuccess || isProcess || isAddingRate ? < div /> : null }
107
- onSave = { ( ) => {
108
- const {
109
- currency,
110
- description,
111
- distribution,
112
- distributeNetwork,
113
- distributePlatformUnallocated,
114
- distributeStorage,
115
- distributeWorkerUnallocated,
116
- isDiscount,
117
- markup,
118
- name,
119
- type,
120
- tiers,
121
- sources,
122
- } = context ;
123
- addCostModel ( {
124
- name,
125
- source_type : type ,
126
- currency,
127
- description,
128
- distribution_info : {
129
- distribution_type : distribution ,
130
- network_unattributed : distributeNetwork ,
131
- platform_cost : distributePlatformUnallocated ,
132
- storage_unattributed : distributeStorage ,
133
- worker_cost : distributeWorkerUnallocated ,
134
- } ,
135
- rates : tiers ,
136
- markup : {
137
- value : `${ isDiscount ? '-' : '' } ${ unFormat ( markup ) } ` ,
138
- unit : 'percent' ,
139
- } ,
140
- source_uuids : sources . map ( src => src . uuid ) ,
91
+ if ( current === steps . length - 1 ) {
92
+ newSteps [ current ] . onNext = ( ) => {
93
+ const {
94
+ currency,
95
+ description,
96
+ distribution,
97
+ distributeNetwork,
98
+ distributePlatformUnallocated,
99
+ distributeStorage,
100
+ distributeWorkerUnallocated,
101
+ isDiscount,
102
+ markup,
103
+ name,
104
+ type,
105
+ tiers,
106
+ sources,
107
+ } = context ;
108
+ addCostModel ( {
109
+ name,
110
+ source_type : type ,
111
+ currency,
112
+ description,
113
+ distribution_info : {
114
+ distribution_type : distribution ,
115
+ network_unattributed : distributeNetwork ,
116
+ platform_cost : distributePlatformUnallocated ,
117
+ storage_unattributed : distributeStorage ,
118
+ worker_cost : distributeWorkerUnallocated ,
119
+ } ,
120
+ rates : tiers ,
121
+ markup : {
122
+ value : `${ isDiscount ? '-' : '' } ${ unFormat ( markup ) } ` ,
123
+ unit : 'percent' ,
124
+ } ,
125
+ source_uuids : sources . map ( src => src . uuid ) ,
126
+ } )
127
+ . then ( ( ) => {
128
+ setSuccess ( ) ;
129
+ updateCostModel ( ) ;
141
130
} )
142
- . then ( ( ) => {
143
- setSuccess ( ) ;
144
- updateCostModel ( ) ;
145
- } )
146
- . catch ( err => setError ( parseApiError ( err ) ) ) ;
147
- } }
148
- />
149
- ) : null ;
131
+ . catch ( err => setError ( parseApiError ( err ) ) ) ;
132
+ } ;
133
+ }
134
+
135
+ // Todo: Remove key={newSteps.length} workaround -- see https://github.com/patternfly/patternfly-react/issues/9752
136
+ return (
137
+ < Modal className = "costManagement" hasNoBodyWrapper isOpen = { isOpen } showClose = { false } variant = { ModalVariant . large } >
138
+ < Wizard
139
+ header = {
140
+ < WizardHeader
141
+ description = { intl . formatMessage ( messages . createCostModelDesc ) }
142
+ onClose = { closeFnc }
143
+ title = { intl . formatMessage ( messages . createCostModelTitle ) }
144
+ />
145
+ }
146
+ isVisitRequired
147
+ key = { newSteps . length }
148
+ onClose = { closeFnc }
149
+ onStepChange = { ( _evt , currentStep ) => onMove ( currentStep . id as number ) }
150
+ >
151
+ { newSteps . map ( step => (
152
+ < WizardStep
153
+ footer = {
154
+ isFooterHidden ? (
155
+ < EmptyFooter />
156
+ ) : (
157
+ {
158
+ isNextDisabled : step . isNextDisabled ,
159
+ ...( step . nextButtonText && { nextButtonText : step . nextButtonText } ) ,
160
+ ...( step . onNext && { onNext : step . onNext } ) ,
161
+ }
162
+ )
163
+ }
164
+ id = { step . id }
165
+ key = { step . id }
166
+ name = { step . name }
167
+ >
168
+ { step . component }
169
+ </ WizardStep >
170
+ ) ) }
171
+ </ Wizard >
172
+ </ Modal >
173
+ ) ;
150
174
} ;
151
175
152
176
const InternalWizard = injectIntl ( InternalWizardBase ) ;
@@ -238,7 +262,7 @@ class CostModelWizardBase extends React.Component<CostModelWizardProps, CostMode
238
262
} ,
239
263
query : { } ,
240
264
sources : [ ] ,
241
- step : 1 ,
265
+ step : 0 ,
242
266
tiers : [ ] as Rate [ ] ,
243
267
total : 0 ,
244
268
type : '' ,
@@ -256,105 +280,105 @@ class CostModelWizardBase extends React.Component<CostModelWizardProps, CostMode
256
280
const stepsHash = ( ) => ( {
257
281
'' : [
258
282
{
259
- id : 1 ,
283
+ id : 0 ,
260
284
name : intl . formatMessage ( messages . costModelsWizardStepsGenInfo ) ,
261
285
component : < GeneralInformation /> ,
262
286
} ,
263
287
] ,
264
288
Azure : [
265
289
{
266
- id : 1 ,
290
+ id : 0 ,
267
291
name : intl . formatMessage ( messages . costModelsWizardStepsGenInfo ) ,
268
292
component : < GeneralInformation /> ,
269
293
} ,
270
294
{
271
- id : 2 ,
295
+ id : 1 ,
272
296
name : intl . formatMessage ( messages . costCalculations ) ,
273
297
component : < Markup /> ,
274
298
} ,
275
299
{
276
- id : 3 ,
300
+ id : 2 ,
277
301
name : intl . formatMessage ( messages . costModelsWizardStepsSources ) ,
278
302
component : < Sources /> ,
279
303
} ,
280
304
{
281
- id : 4 ,
305
+ id : 3 ,
282
306
name : intl . formatMessage ( messages . costModelsWizardStepsReview ) ,
283
307
component : < Review /> ,
284
308
} ,
285
309
] ,
286
310
AWS : [
287
311
{
288
- id : 1 ,
312
+ id : 0 ,
289
313
name : intl . formatMessage ( messages . costModelsWizardStepsGenInfo ) ,
290
314
component : < GeneralInformation /> ,
291
315
} ,
292
316
{
293
- id : 2 ,
317
+ id : 1 ,
294
318
name : intl . formatMessage ( messages . costCalculations ) ,
295
319
component : < Markup /> ,
296
320
} ,
297
321
{
298
- id : 3 ,
322
+ id : 2 ,
299
323
name : intl . formatMessage ( messages . costModelsWizardStepsSources ) ,
300
324
component : < Sources /> ,
301
325
} ,
302
326
{
303
- id : 4 ,
327
+ id : 3 ,
304
328
name : intl . formatMessage ( messages . costModelsWizardStepsReview ) ,
305
329
component : < Review /> ,
306
330
} ,
307
331
] ,
308
332
GCP : [
309
333
{
310
- id : 1 ,
334
+ id : 0 ,
311
335
name : intl . formatMessage ( messages . costModelsWizardStepsGenInfo ) ,
312
336
component : < GeneralInformation /> ,
313
337
} ,
314
338
{
315
- id : 2 ,
339
+ id : 1 ,
316
340
name : intl . formatMessage ( messages . costCalculations ) ,
317
341
component : < Markup /> ,
318
342
} ,
319
343
{
320
- id : 3 ,
344
+ id : 2 ,
321
345
name : intl . formatMessage ( messages . costModelsWizardStepsSources ) ,
322
346
component : < Sources /> ,
323
347
} ,
324
348
{
325
- id : 4 ,
349
+ id : 3 ,
326
350
name : intl . formatMessage ( messages . costModelsWizardStepsReview ) ,
327
351
component : < Review /> ,
328
352
} ,
329
353
] ,
330
354
OCP : [
331
355
{
332
- id : 1 ,
356
+ id : 0 ,
333
357
name : intl . formatMessage ( messages . costModelsWizardStepsGenInfo ) ,
334
358
component : < GeneralInformation /> ,
335
359
} ,
336
360
{
337
- id : 2 ,
361
+ id : 1 ,
338
362
name : intl . formatMessage ( messages . priceList ) ,
339
363
component : < PriceList /> ,
340
364
} ,
341
365
{
342
- id : 3 ,
366
+ id : 2 ,
343
367
name : intl . formatMessage ( messages . costCalculations ) ,
344
368
component : < Markup /> ,
345
369
} ,
346
370
{
347
- id : 4 ,
371
+ id : 3 ,
348
372
name : intl . formatMessage ( messages . costDistribution ) ,
349
373
component : < Distribution /> ,
350
374
} ,
351
375
{
352
- id : 5 ,
376
+ id : 4 ,
353
377
name : intl . formatMessage ( messages . costModelsWizardStepsSources ) ,
354
378
component : < Sources /> ,
355
379
} ,
356
380
{
357
- id : 6 ,
381
+ id : 5 ,
358
382
name : intl . formatMessage ( messages . costModelsWizardStepsReview ) ,
359
383
component : < Review /> ,
360
384
} ,
@@ -527,16 +551,16 @@ class CostModelWizardBase extends React.Component<CostModelWizardProps, CostMode
527
551
isSuccess = { this . state . createSuccess }
528
552
closeFnc = { ( ) => {
529
553
if (
530
- ( this . state . type === 'OCP' && this . state . step > 1 && this . state . tiers . length > 0 ) ||
531
- ( this . state . type !== 'OCP' && this . state . step > 2 )
554
+ ( this . state . type === 'OCP' && this . state . step > 0 && this . state . tiers . length > 0 ) ||
555
+ ( this . state . type !== 'OCP' && this . state . step > 1 )
532
556
) {
533
557
this . setState ( { isDialogOpen : true } , this . props . closeWizard ) ;
534
558
} else {
535
559
this . setState ( { ...this . defaultState } , this . props . closeWizard ) ;
536
560
}
537
561
} }
538
562
isOpen = { this . props . isOpen }
539
- onMove = { curr => this . setState ( { step : Number ( curr . id ) } ) }
563
+ onMove = { id => this . setState ( { step : Number ( id ) } ) }
540
564
steps = { stepsHash ( ) [ this . state . type ] }
541
565
current = { this . state . step }
542
566
validators = { validatorsHash [ this . state . type ] }
0 commit comments