Skip to content

Commit ae5bd0e

Browse files
committed
Update CreateManagedControlPlaneWizardContainer.tsx
1 parent 4447695 commit ae5bd0e

File tree

1 file changed

+162
-100
lines changed

1 file changed

+162
-100
lines changed

src/components/Wizards/CreateManagedControlPlaneWizardContainer.tsx

Lines changed: 162 additions & 100 deletions
Original file line numberDiff line numberDiff line change
@@ -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

5656
export 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

Comments
 (0)