Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit4412f19

Browse files
authored
fix: sync websocket params with form params (#17895)
The current issue is that when multiple parameters are added or removedfrom a form because a user change in a conditional parameter value. Thewebsocket parameters response gets out of sync with the state of theparameters in the form.The form state needs to be maintained because this is what getssubmitted when the user attempts to create a workspace.Fixes:1. When autofill params are set from the url, mark these params astouched in the form. This is necessary as only touched params are sentin the request to the websocket. These params should technically countas being touched because they were preset from the url params.2. Create a hook to synchronize the parameters from the websocketresponse with the current state of the parameters stored in the form.
1 parent766277c commit4412f19

File tree

1 file changed

+77
-4
lines changed

1 file changed

+77
-4
lines changed

‎site/src/pages/CreateWorkspacePage/CreateWorkspacePageViewExperimental.tsx

Lines changed: 77 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,27 @@ export const CreateWorkspacePageViewExperimental: FC<
113113
setSuggestedName(()=>generateWorkspaceName());
114114
},[]);
115115

116+
constautofillByName=Object.fromEntries(
117+
autofillParameters.map((param)=>[param.name,param]),
118+
);
119+
120+
// Only touched fields are sent to the websocket
121+
// Autofilled parameters are marked as touched since they have been modified
122+
constinitialTouched=parameters.reduce(
123+
(touched,parameter)=>{
124+
if(autofillByName[parameter.name]!==undefined){
125+
touched[parameter.name]=true;
126+
}
127+
returntouched;
128+
},
129+
{}asRecord<string,boolean>,
130+
);
131+
132+
// The form parameters values hold the working state of the parameters that will be submitted when creating a workspace
133+
// 1. The form parameter values are initialized from the websocket response when the form is mounted
134+
// 2. Only touched form fields are sent to the websocket, a field is touched if edited by the user or set by autofill
135+
// 3. The websocket response may add or remove parameters, these are added or removed from the form values in the useSyncFormParameters hook
136+
// 4. All existing form parameters are updated to match the websocket response in the useSyncFormParameters hook
116137
constform:FormikContextType<TypesGen.CreateWorkspaceRequest>=
117138
useFormik<TypesGen.CreateWorkspaceRequest>({
118139
initialValues:{
@@ -123,6 +144,7 @@ export const CreateWorkspacePageViewExperimental: FC<
123144
autofillParameters,
124145
),
125146
},
147+
initialTouched,
126148
validationSchema:Yup.object({
127149
name:nameValidator("Workspace Name"),
128150
rich_parameter_values:
@@ -140,10 +162,6 @@ export const CreateWorkspacePageViewExperimental: FC<
140162
},
141163
});
142164

143-
constautofillByName=Object.fromEntries(
144-
autofillParameters.map((param)=>[param.name,param]),
145-
);
146-
147165
useEffect(()=>{
148166
if(error){
149167
window.scrollTo(0,0);
@@ -250,6 +268,12 @@ export const CreateWorkspacePageViewExperimental: FC<
250268
sendDynamicParamsRequest(parameter,value);
251269
};
252270

271+
useSyncFormParameters({
272+
parameters,
273+
formValues:form.values.rich_parameter_values??[],
274+
setFieldValue:form.setFieldValue,
275+
});
276+
253277
return(
254278
<>
255279
<divclassName="sticky top-5 ml-10">
@@ -579,3 +603,52 @@ const Diagnostics: FC<DiagnosticsProps> = ({ diagnostics }) => {
579603
</div>
580604
);
581605
};
606+
607+
typeUseSyncFormParametersProps={
608+
parameters:readonlyPreviewParameter[];
609+
formValues:readonlyTypesGen.WorkspaceBuildParameter[];
610+
setFieldValue:(
611+
field:string,
612+
value:TypesGen.WorkspaceBuildParameter[],
613+
)=>void;
614+
};
615+
616+
functionuseSyncFormParameters({
617+
parameters,
618+
formValues,
619+
setFieldValue,
620+
}:UseSyncFormParametersProps){
621+
// Form values only needs to be updated when parameters change
622+
// Keep track of form values in a ref to avoid unnecessary updates to rich_parameter_values
623+
constformValuesRef=useRef(formValues);
624+
625+
useEffect(()=>{
626+
formValuesRef.current=formValues;
627+
},[formValues]);
628+
629+
useEffect(()=>{
630+
if(!parameters)return;
631+
constcurrentFormValues=formValuesRef.current;
632+
633+
constnewParameterValues=parameters.map((param)=>{
634+
return{
635+
name:param.name,
636+
value:param.value.valid ?param.value.value :"",
637+
};
638+
});
639+
640+
constisChanged=
641+
currentFormValues.length!==newParameterValues.length||
642+
newParameterValues.some(
643+
(p)=>
644+
!currentFormValues.find(
645+
(formValue)=>
646+
formValue.name===p.name&&formValue.value===p.value,
647+
),
648+
);
649+
650+
if(isChanged){
651+
setFieldValue("rich_parameter_values",newParameterValues);
652+
}
653+
},[parameters,setFieldValue]);
654+
}

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp