fix(ui/profiles): preserve ANTHROPIC_EXTRA_MODELS on untouched edit-dialog save

The edit dialog cannot pre-populate `extraModels` from the existing
profile (the Profile type carries no env data), so the field always
opens blank in edit mode. Forwarding that blank value unconditionally
clobbered any saved ANTHROPIC_EXTRA_MODELS, since the PUT route treats
an empty string as a delete signal.

Track react-hook-form's `dirtyFields.extraModels` and only include the
field in the update payload when the user actually touched it. Typing
then clearing still marks the field dirty, so the explicit-clear UX
keeps working.
This commit is contained in:
Tam Nhu Tran
2026-04-25 11:45:51 -04:00
parent 7f14c565df
commit 9122f68dd4
@@ -57,7 +57,7 @@ export function ProfileDialog({ open, onClose, profile }: ProfileDialogProps) {
const {
register,
handleSubmit,
formState: { errors },
formState: { errors, dirtyFields },
reset,
control,
} = useForm<FormData>({
@@ -97,14 +97,20 @@ export function ProfileDialog({ open, onClose, profile }: ProfileDialogProps) {
const onSubmit = async (data: FormData) => {
try {
if (profile) {
// Update mode
// Update mode. The dialog cannot pre-populate `extraModels` from the
// existing profile (Profile type carries no env data), so the field
// always starts blank in edit mode. Forwarding that blank value
// unconditionally would clobber any saved ANTHROPIC_EXTRA_MODELS via
// the route's "empty string deletes" semantics. Only forward the
// field if the user actually edited it — typing then clearing still
// marks it dirty, preserving the explicit-clear UX.
await updateMutation.mutateAsync({
name: profile.name,
data: {
baseUrl: data.baseUrl,
apiKey: data.apiKey,
model: data.model,
extraModels: data.extraModels,
...(dirtyFields.extraModels ? { extraModels: data.extraModels } : {}),
opusModel: data.opusModel,
sonnetModel: data.sonnetModel,
haikuModel: data.haikuModel,