Skip to content

Commit f00d8e3

Browse files
authored
Merge pull request wso2#818 from samithkavishke/issue-1696
[BI] Resolve type editor creation flow
2 parents e4d8263 + beb87bf commit f00d8e3

File tree

4 files changed

+41
-15
lines changed

4 files changed

+41
-15
lines changed

workspaces/ballerina/ballerina-visualizer/src/views/BI/Forms/FormGenerator/index.tsx

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1217,10 +1217,10 @@ export const FormGenerator = forwardRef<FormExpressionEditorRef, FormProps>(func
12171217
});
12181218
};
12191219

1220-
const getDefaultValue = () => {
1220+
const getDefaultValue = (typeName?: string) => {
12211221
return ({
12221222
type: {
1223-
name: "MyType",
1223+
name: typeName || "MyType",
12241224
members: [] as Member[],
12251225
editable: true,
12261226
metadata: {
@@ -1238,8 +1238,8 @@ export const FormGenerator = forwardRef<FormExpressionEditorRef, FormProps>(func
12381238
})
12391239
}
12401240

1241-
const getNewTypeCreateForm = () => {
1242-
pushTypeStack(getDefaultValue());
1241+
const getNewTypeCreateForm = (typeName?: string) => {
1242+
pushTypeStack(getDefaultValue(typeName));
12431243
}
12441244

12451245
// handle if node form

workspaces/ballerina/ballerina-visualizer/src/views/BI/Forms/FormGeneratorNew/index.tsx

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -310,10 +310,10 @@ export function FormGeneratorNew(props: FormProps) {
310310
closePopup: closeModal
311311
}
312312

313-
const defaultType = (): Type => {
313+
const defaultType = (typeName?: string): Type => {
314314
if (!isGraphqlEditor || typeEditorState.field?.type === 'PARAM_MANAGER') {
315315
return {
316-
name: typeEditorState.newTypeValue || "MyType",
316+
name: typeName || typeEditorState.newTypeValue || "MyType",
317317
editable: true,
318318
metadata: {
319319
label: "",
@@ -328,7 +328,7 @@ export function FormGeneratorNew(props: FormProps) {
328328
allowAdditionalFields: false
329329
};
330330
} return {
331-
name: typeEditorState.newTypeValue || "MyType",
331+
name: typeName || typeEditorState.newTypeValue || "MyType",
332332
editable: true,
333333
metadata: {
334334
label: "",
@@ -818,9 +818,9 @@ export function FormGeneratorNew(props: FormProps) {
818818
setTypeEditorState({ ...typeEditorState, isOpen: state });
819819
}
820820

821-
const getNewTypeCreateForm = () => {
821+
const getNewTypeCreateForm = (typeName?: string) => {
822822
pushTypeStack({
823-
type: defaultType(),
823+
type: defaultType(typeName),
824824
isDirty: false
825825
})
826826
}

workspaces/ballerina/ballerina-visualizer/src/views/BI/TypeEditor/index.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ type FormTypeEditorProps = {
4747
isGraphql?: boolean;
4848
onCloseCompletions?: () => void;
4949
onTypeCreate: (typeName?: string) => void;
50-
getNewTypeCreateForm: () => void;
50+
getNewTypeCreateForm: (typeName?: string) => void;
5151
onSaveType: (type: Type | string) => void
5252
refetchTypes: boolean;
5353
isPopupTypeForm: boolean;
@@ -239,7 +239,7 @@ export const FormTypeEditor = (props: FormTypeEditorProps) => {
239239
};
240240

241241
const handleTypeCreate = (typeName?: string) => {
242-
getNewTypeCreateForm();
242+
getNewTypeCreateForm(typeName);
243243
};
244244

245245
return (

workspaces/ballerina/type-editor/src/TypeEditor/Tabs/TypeCreatorTab.tsx

Lines changed: 30 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -193,6 +193,9 @@ export function TypeCreatorTab(props: TypeCreatorTabProps) {
193193
default:
194194
setSelectedTypeKind(TypeKind.RECORD);
195195
}
196+
197+
// Ensure tempName is initialized when editing a new type (prevents focus loss due to replacing the main type on each keystroke)
198+
setTempName(editingType.name);
196199
}
197200

198201
setIsNewType(newType);
@@ -420,10 +423,24 @@ export function TypeCreatorTab(props: TypeCreatorTabProps) {
420423
}
421424

422425
const handleOnTypeNameChange = (value: string) => {
426+
if (isNewType) {
427+
setTempName(value);
428+
validateTypeName(value);
429+
return;
430+
}
423431
handleSetType({ ...type, name: value });
424432
validateTypeName(value);
425433
}
426434

435+
const commitNewTypeName = () => {
436+
if (!isNewType) {
437+
return;
438+
}
439+
if (tempName && tempName !== type.name) {
440+
handleSetType({ ...type, name: tempName } as Type);
441+
}
442+
};
443+
427444
// Function to validate before saving to verify names created in nested forms
428445
const handleSaveWithValidation = async (typeToSave: Type) => {
429446

@@ -600,13 +617,18 @@ export function TypeCreatorTab(props: TypeCreatorTabProps) {
600617
<TextFieldWrapper>
601618
<TextField
602619
label="Name"
603-
value={type.name}
620+
value={tempName}
604621
errorMsg={nameError}
605-
onBlur={handleOnBlur}
622+
onBlur={(e) => {
623+
// commit local name into type on blur and validate
624+
commitNewTypeName();
625+
handleOnBlur(e);
626+
}}
606627
onChange={(e) => handleOnTypeNameChange(e.target.value)}
607628
onKeyDown={(e) => {
608629
if (e.key === 'Enter') {
609-
handleOnTypeNameChange((e.target as HTMLInputElement).value);
630+
// commit on Enter
631+
commitNewTypeName();
610632
}
611633
}}
612634
onFocus={(e) => { e.target.select(); validateTypeName(e.target.value) }}
@@ -622,7 +644,11 @@ export function TypeCreatorTab(props: TypeCreatorTabProps) {
622644
<Footer>
623645
<Button
624646
data-testid="type-create-save"
625-
onClick={() => handleSaveWithValidation(type)}
647+
onClick={() => {
648+
// Ensure Save uses the latest tempName for new types without causing extra re-renders
649+
const typeToSave = isNewType ? { ...type, name: tempName } : type;
650+
handleSaveWithValidation(typeToSave);
651+
}}
626652
disabled={onValidationError || !isTypeNameValid || isEditing || isSaving}>
627653
{isSaving ? <Typography variant="progress">Saving...</Typography> : "Save"}
628654
</Button>

0 commit comments

Comments
 (0)