@@ -51,19 +51,24 @@ type CreateManagedControlPlaneWizardContainerProps = {
5151 workspaceName ?: string ;
5252} ;
5353
54- type WizardStep = 'metadata' | 'members' | 'summarize' | 'success' ;
54+ type WizardStepType = 'metadata' | 'members' | 'summarize' | 'success' ;
5555
5656export const CreateManagedControlPlaneWizardContainer : FC <
5757 CreateManagedControlPlaneWizardContainerProps
5858> = ( { isOpen, setIsOpen, projectName = '' , workspaceName = '' } ) => {
59+ const { t } = useTranslation ( ) ;
60+ const { user } = useAuth ( ) ;
61+ const errorDialogRef = useRef < ErrorDialogHandle > ( null ) ;
62+
63+ const [ selectedStep , setSelectedStep ] = useState < WizardStepType > ( 'metadata' ) ;
64+
5965 const {
6066 register,
6167 handleSubmit,
6268 resetField,
6369 setValue,
6470 reset,
6571 getValues,
66-
6772 formState : { errors, isValid } ,
6873 watch,
6974 } = useForm < CreateDialogProps > ( {
@@ -74,150 +79,211 @@ export const CreateManagedControlPlaneWizardContainer: FC<
7479 chargingTarget : '' ,
7580 members : [ ] ,
7681 } ,
82+ mode : 'onChange' ,
7783 } ) ;
78- const { t } = useTranslation ( ) ;
79- const nextBtText = useMemo (
84+
85+ // Memoize next button text to avoid unnecessary recalculations
86+ const nextButtonText = useMemo (
8087 ( ) => ( {
8188 metadata : t ( 'buttons.next' ) ,
8289 members : t ( 'buttons.next' ) ,
8390 summarize : t ( 'buttons.create' ) ,
8491 success : t ( 'buttons.close' ) ,
8592 } ) ,
86- [ ] ,
93+ [ t ] ,
8794 ) ;
88- const errorDialogRef = useRef < ErrorDialogHandle > ( null ) ;
89- const resetFormAndClose = ( ) => {
95+
96+ // Helper to reset form and close dialog
97+ const resetFormAndClose = useCallback ( ( ) => {
9098 reset ( ) ;
9199 setSelectedStep ( 'metadata' ) ;
92100 setIsOpen ( false ) ;
93- } ;
94- console . log ( errors ) ;
95- // const { t } = useTranslation();
96- const { user } = useAuth ( ) ;
97- const [ selectedStep , setSelectedStep ] = useState < WizardStep > ( 'metadata' ) ;
98- const username = user ?. email ;
101+ } , [ reset , setIsOpen ] ) ;
99102
100- const clearForm = useCallback ( ( ) => {
103+ // Helper to clear only the form fields, not the members
104+ const clearFormFields = useCallback ( ( ) => {
101105 resetField ( 'name' ) ;
102106 resetField ( 'chargingTarget' ) ;
103107 resetField ( 'displayName' ) ;
104108 } , [ resetField ] ) ;
105109
110+ // Set default member (current user) on open, clear fields on close
106111 useEffect ( ( ) => {
107- if ( username ) {
112+ if ( user ?. email && isOpen ) {
108113 setValue ( 'members' , [
109- { name : username , roles : [ MemberRoles . admin ] , kind : 'User' } ,
114+ { name : user . email , roles : [ MemberRoles . admin ] , kind : 'User' } ,
110115 ] ) ;
111116 }
112117 if ( ! isOpen ) {
113- clearForm ( ) ;
118+ clearFormFields ( ) ;
114119 }
115- } , [ resetField , setValue , username , isOpen , clearForm ] ) ;
120+ // Only run when dialog open/close or user changes
121+ } , [ user ?. email , isOpen , setValue , clearFormFields ] ) ;
122+
123+ // API mutation hook
116124 const { trigger } = useApiResourceMutation < CreateManagedControlPlaneType > (
117125 CreateManagedControlPlaneResource ( projectName , workspaceName ) ,
118126 ) ;
119127
120- const handleCreateManagedControlPlane = async ( {
121- name,
122- displayName,
123- chargingTarget,
124- members,
125- } : OnCreatePayload ) : Promise < boolean > => {
126- try {
127- await trigger (
128- CreateManagedControlPlane ( name , `${ projectName } --ws-${ workspaceName } ` , {
129- displayName : displayName ,
130- chargingTarget : chargingTarget ,
131- members : members ,
132- } ) ,
133- ) ;
134-
135- setSelectedStep ( 'success' ) ;
136- return true ;
137- } catch ( e ) {
138- console . error ( e ) ;
139- if ( e instanceof APIError ) {
140- if ( errorDialogRef . current ) {
128+ // Handles the creation API call and error dialog
129+ const handleCreateManagedControlPlane = useCallback (
130+ async ( {
131+ name,
132+ displayName,
133+ chargingTarget,
134+ members,
135+ } : OnCreatePayload ) : Promise < boolean > => {
136+ try {
137+ await trigger (
138+ CreateManagedControlPlane (
139+ name ,
140+ `${ projectName } --ws-${ workspaceName } ` ,
141+ {
142+ displayName,
143+ chargingTarget,
144+ members,
145+ } ,
146+ ) ,
147+ ) ;
148+ setSelectedStep ( 'success' ) ;
149+ return true ;
150+ } catch ( e ) {
151+ // Only show error dialog for APIError
152+ if ( e instanceof APIError && errorDialogRef . current ) {
141153 errorDialogRef . current . showErrorDialog (
142154 `${ e . message } : ${ JSON . stringify ( e . info ) } ` ,
143155 ) ;
156+ } else {
157+ console . error ( e ) ;
144158 }
159+ return false ;
145160 }
146- return false ;
147- }
148- } ;
149- const handleStepChange = (
150- e : Ui5CustomEvent < WizardDomRef , WizardStepChangeEventDetail > ,
151- ) => {
152- setSelectedStep ( ( e . detail . step . dataset . step ?? '' ) as WizardStep ) ;
153- } ;
154- const onNextClick = ( ) => {
155- if ( selectedStep === 'metadata' ) {
156- handleSubmit (
157- ( ) => {
158- setSelectedStep ( 'members' ) ;
159- } ,
160- ( ) => {
161- console . log ( errors ) ;
162- } ,
163- ) ( ) ;
164- }
165- if ( selectedStep === 'members' ) {
166- setSelectedStep ( 'summarize' ) ;
167- }
168- if ( selectedStep === 'summarize' ) {
169- handleCreateManagedControlPlane ( getValues ( ) ) ;
170- }
171- if ( selectedStep === 'success' ) {
172- setIsOpen ( false ) ;
173- clearForm ( ) ;
174- setSelectedStep ( 'metadata' ) ;
161+ } ,
162+ [ trigger , projectName , workspaceName ] ,
163+ ) ;
164+
165+ // Handles wizard step change (if user clicks on step header)
166+ const handleStepChange = useCallback (
167+ ( e : Ui5CustomEvent < WizardDomRef , WizardStepChangeEventDetail > ) => {
168+ const step = ( e . detail . step . dataset . step ?? '' ) as WizardStepType ;
169+ setSelectedStep ( step ) ;
170+ } ,
171+ [ ] ,
172+ ) ;
173+
174+ // Handles the Next/Create/Close button logic
175+ const onNextClick = useCallback ( ( ) => {
176+ switch ( selectedStep ) {
177+ case 'metadata' :
178+ handleSubmit (
179+ ( ) => setSelectedStep ( 'members' ) ,
180+ ( ) => {
181+ // Optionally, show a toast or error message here
182+ } ,
183+ ) ( ) ;
184+ break ;
185+ case 'members' :
186+ setSelectedStep ( 'summarize' ) ;
187+ break ;
188+ case 'summarize' :
189+ handleCreateManagedControlPlane ( getValues ( ) ) ;
190+ break ;
191+ case 'success' :
192+ resetFormAndClose ( ) ;
193+ break ;
194+ default :
195+ break ;
175196 }
176- } ;
177- const setMembers = ( members : Member [ ] ) => {
178- setValue ( 'members' , members ) ;
179- } ;
197+ } , [
198+ selectedStep ,
199+ handleSubmit ,
200+ setSelectedStep ,
201+ handleCreateManagedControlPlane ,
202+ getValues ,
203+ resetFormAndClose ,
204+ ] ) ;
205+
206+ // Update members in form state
207+ const setMembers = useCallback (
208+ ( members : Member [ ] ) => {
209+ setValue ( 'members' , members , { shouldValidate : true } ) ;
210+ } ,
211+ [ setValue ] ,
212+ ) ;
213+
214+ // Helper to determine if a step should be disabled
215+ const isStepDisabled = useCallback (
216+ ( step : WizardStepType ) => {
217+ switch ( step ) {
218+ case 'metadata' :
219+ return false ;
220+ case 'members' :
221+ return selectedStep === 'metadata' || ! isValid ;
222+ case 'summarize' :
223+ return (
224+ selectedStep === 'metadata' ||
225+ selectedStep === 'members' ||
226+ ! isValid
227+ ) ;
228+ case 'success' :
229+ // Success step should only be enabled when selectedStep is 'success'
230+ return selectedStep !== 'success' ;
231+ default :
232+ return false ;
233+ }
234+ } ,
235+ [ selectedStep , isValid ] ,
236+ ) ;
180237
238+ // Render
181239 return (
182240 < Dialog
183- stretch = { true }
184- headerText = { 'Create Managed Control Plane' }
241+ stretch
242+ headerText = { t ( 'createMCP.dialogTitle' ) || 'Create Managed Control Plane' }
185243 open = { isOpen }
186244 initialFocus = "project-name-input"
187245 footer = {
188246 < Bar
189247 design = "Footer"
190248 endContent = {
191- < div style = { { display : 'flex' , alignItems : 'center' , gap : '8px' } } >
249+ < div style = { { display : 'flex' , alignItems : 'center' , gap : 8 } } >
192250 { selectedStep !== 'success' && (
193- < Button design = { ' Negative' } onClick = { resetFormAndClose } >
251+ < Button design = " Negative" onClick = { resetFormAndClose } >
194252 { t ( 'buttons.close' ) }
195253 </ Button >
196254 ) }
197- < Button design = "Emphasized" onClick = { onNextClick } >
198- { nextBtText [ selectedStep ] }
255+ < Button
256+ design = "Emphasized"
257+ disabled = {
258+ ( selectedStep === 'metadata' && ! isValid ) ||
259+ ( selectedStep === 'summarize' && ! isValid )
260+ }
261+ onClick = { onNextClick }
262+ >
263+ { nextButtonText [ selectedStep ] }
199264 </ Button >
200265 </ div >
201266 }
202267 />
203268 }
204- onClose = { ( ) => setIsOpen ( false ) }
269+ data-testid = "create-mcp-dialog"
270+ onClose = { resetFormAndClose }
205271 >
206- < Wizard contentLayout = { ' SingleStep' } onStepChange = { handleStepChange } >
272+ < Wizard contentLayout = " SingleStep" onStepChange = { handleStepChange } >
207273 < WizardStep
208- icon = { ' create-form' }
274+ icon = " create-form"
209275 titleText = { t ( 'common.metadata' ) }
210- disabled = { false }
276+ disabled = { isStepDisabled ( 'metadata' ) }
211277 selected = { selectedStep === 'metadata' }
212- data-step = { ' metadata' }
278+ data-step = " metadata"
213279 >
214280 < MetadataForm register = { register } errors = { errors } />
215281 </ WizardStep >
216282 < WizardStep
217283 titleText = { t ( 'common.members' ) }
218284 selected = { selectedStep === 'members' }
219- data-step = { ' members' }
220- disabled = { selectedStep === 'metadata' || ! isValid }
285+ data-step = " members"
286+ disabled = { isStepDisabled ( 'members' ) }
221287 >
222288 < Form >
223289 < FormGroup
@@ -232,27 +298,22 @@ export const CreateManagedControlPlaneWizardContainer: FC<
232298 </ Form >
233299 </ WizardStep >
234300 < WizardStep
235- icon = { ' activities' }
301+ icon = " activities"
236302 titleText = { t ( 'common.summarize' ) }
237- disabled = {
238- selectedStep === 'metadata' ||
239- selectedStep === 'members' ||
240- ! isValid
241- }
303+ disabled = { isStepDisabled ( 'summarize' ) }
242304 selected = { selectedStep === 'summarize' }
243- data-step = { ' summarize' }
305+ data-step = " summarize"
244306 >
245307 < h1 > { t ( 'common.summarize' ) } </ h1 >
246308 < Grid defaultSpan = "XL6 L6 M6 S6" >
247309 < div >
248- < List headerText = { t ( 'common.members ' ) } >
310+ < List headerText = { t ( 'common.metadata ' ) } >
249311 < ListItemStandard
250- text = { 'Name:' }
312+ text = { t ( 'common.name' ) }
251313 additionalText = { getValues ( 'name' ) }
252314 />
253315 < ListItemStandard
254- title = { t ( 'common.metadata' ) }
255- text = { 'Display name:' }
316+ text = { t ( 'common.displayName' ) }
256317 additionalText = { getValues ( 'displayName' ) }
257318 />
258319 < ListItemStandard
@@ -261,8 +322,9 @@ export const CreateManagedControlPlaneWizardContainer: FC<
261322 />
262323 < ListItemStandard
263324 text = { t ( 'common.namespace' ) }
264- additionalText = { '' }
325+ additionalText = { ` ${ projectName } --ws- ${ workspaceName } ` }
265326 />
327+ { /* If region is available, show it; otherwise, leave blank */ }
266328 < ListItemStandard
267329 text = { t ( 'common.region' ) }
268330 additionalText = { '' }
@@ -298,11 +360,11 @@ export const CreateManagedControlPlaneWizardContainer: FC<
298360 </ Grid >
299361 </ WizardStep >
300362 < WizardStep
301- icon = { ' activities' }
363+ icon = " activities"
302364 titleText = { t ( 'common.success' ) }
303- disabled = { selectedStep !== 'success' || ! isValid }
365+ disabled = { isStepDisabled ( 'success' ) }
304366 selected = { selectedStep === 'success' }
305- data-step = { ' success' }
367+ data-step = " success"
306368 >
307369 < IllustratedBanner
308370 illustrationName = { IllustrationMessageType . SuccessScreen }
0 commit comments