fix: enable save button when changing currency default value (#16864)
Closes #16792 ## Problem When editing a currency field’s default value (for example, changing from **USD** to **UYU**), the **Save** button remained disabled. However, if the format setting was changed first (**short → full → short**), the Save button would then work correctly for currency changes. ## Root Cause The form was using **React Hook Form’s `values` mode**, which did not properly track dirty state for the `defaultValue` and `settings` fields. ## Solution Switched to the **`defaultValues` + `reset()`** pattern: - Initialize the form with `defaultValues` (using placeholder values) - Call `reset()` when `fieldMetadataItem` loads This correctly tracks dirty state by comparing against the most recent `reset` values. ## Note A similar pattern is used in: - `useWebhookForm` - `useImapSmtpCaldavConnectionForm` Those hooks call `reset()` via query callbacks. In this case, `reset()` is called inside a `useEffect` because the data comes from synchronous Recoil state rather than an async query. Found two solutions to the problem, created commits for both. I feel the useEffect pattern makes more sense here since it's cleaner in terms of code. --------- Co-authored-by: Félix Malfait <felix.malfait@gmail.com>
This commit is contained in:
@@ -43,6 +43,7 @@ import { Section } from 'twenty-ui/layout';
|
||||
import { FieldMetadataType } from '~/generated-metadata/graphql';
|
||||
import { useNavigateApp } from '~/hooks/useNavigateApp';
|
||||
import { useNavigateSettings } from '~/hooks/useNavigateSettings';
|
||||
import { getFieldMetadataItemInitialValues } from '~/pages/settings/data-model/utils/getFieldMetadataItemInitialValues';
|
||||
|
||||
//TODO: fix this type
|
||||
export type SettingsDataModelFieldEditFormValues = z.infer<
|
||||
@@ -107,6 +108,9 @@ export const SettingsObjectFieldEdit = () => {
|
||||
const getRelationMetadata = useGetRelationMetadata();
|
||||
const { updateOneFieldMetadataItem } = useUpdateOneFieldMetadataItem();
|
||||
|
||||
const { settings, defaultValue } =
|
||||
getFieldMetadataItemInitialValues(fieldMetadataItem);
|
||||
|
||||
const formConfig = useForm<SettingsDataModelFieldEditFormValues>({
|
||||
mode: 'onTouched',
|
||||
resolver: zodResolver(settingsFieldFormSchema()),
|
||||
@@ -116,7 +120,8 @@ export const SettingsObjectFieldEdit = () => {
|
||||
label: fieldMetadataItem?.label ?? '',
|
||||
description: fieldMetadataItem?.description,
|
||||
isLabelSyncedWithName: fieldMetadataItem?.isLabelSyncedWithName ?? true,
|
||||
settings: fieldMetadataItem?.settings,
|
||||
settings,
|
||||
defaultValue,
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
+35
@@ -0,0 +1,35 @@
|
||||
import { type FieldMetadataItem } from '@/object-metadata/types/FieldMetadataItem';
|
||||
import { isNonEmptyString } from '@sniptt/guards';
|
||||
import { CurrencyCode } from 'twenty-shared/constants';
|
||||
import { FieldMetadataType } from '~/generated-metadata/graphql';
|
||||
import { DEFAULT_DECIMAL_VALUE } from '~/utils/format/formatNumber';
|
||||
import { applySimpleQuotesToString } from '~/utils/string/applySimpleQuotesToString';
|
||||
|
||||
export const getFieldMetadataItemInitialValues = (
|
||||
fieldMetadataItem: FieldMetadataItem | undefined,
|
||||
) => {
|
||||
if (fieldMetadataItem?.type !== FieldMetadataType.CURRENCY) {
|
||||
return {
|
||||
settings: fieldMetadataItem?.settings ?? undefined,
|
||||
defaultValue: fieldMetadataItem?.defaultValue ?? undefined,
|
||||
};
|
||||
}
|
||||
|
||||
const settings = fieldMetadataItem.settings ?? {
|
||||
format: 'short',
|
||||
decimals: DEFAULT_DECIMAL_VALUE,
|
||||
};
|
||||
|
||||
const currencyCode = isNonEmptyString(
|
||||
fieldMetadataItem.defaultValue?.currencyCode,
|
||||
)
|
||||
? fieldMetadataItem.defaultValue?.currencyCode
|
||||
: applySimpleQuotesToString(CurrencyCode.USD);
|
||||
|
||||
const defaultValue = {
|
||||
amountMicros: fieldMetadataItem.defaultValue?.amountMicros ?? null,
|
||||
currencyCode,
|
||||
};
|
||||
|
||||
return { settings, defaultValue };
|
||||
};
|
||||
Reference in New Issue
Block a user