Skip to content

Commit 5505cd1

Browse files
committed
refactor: reset field default value on type change in Settings
Related issue: #5412
1 parent 5448512 commit 5505cd1

20 files changed

+186
-100
lines changed

packages/twenty-front/src/modules/object-metadata/validation-schemas/selectOptionsSchema.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { z } from 'zod';
22

33
import { FieldMetadataItemOption } from '@/object-metadata/types/FieldMetadataItem';
4-
import { getOptionValueFromLabel } from '@/settings/data-model/fields/forms/utils/getOptionValueFromLabel';
4+
import { getOptionValueFromLabel } from '@/settings/data-model/fields/forms/select/utils/getOptionValueFromLabel';
55
import { themeColorSchema } from '@/ui/theme/utils/themeColorSchema';
66
import { computeOptionValueFromLabelOrThrow } from '~/pages/settings/data-model/utils/compute-option-value-from-label.utils';
77

Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
1-
import { useEffect } from 'react';
21
import { Controller, useFormContext } from 'react-hook-form';
32
import styled from '@emotion/styled';
43
import { IconCheck, IconX } from 'twenty-ui';
54
import { z } from 'zod';
65

76
import { FieldMetadataItem } from '@/object-metadata/types/FieldMetadataItem';
7+
import { useBooleanSettingsFormInitialValues } from '@/settings/data-model/fields/forms/boolean/hooks/useBooleanSettingsFormInitialValues';
88
import { Select } from '@/ui/input/components/Select';
99
import { CardContent } from '@/ui/layout/card/components/CardContent';
1010
import { isDefined } from '~/utils/isDefined';
@@ -13,13 +13,13 @@ export const settingsDataModelFieldBooleanFormSchema = z.object({
1313
defaultValue: z.boolean(),
1414
});
1515

16-
type SettingsDataModelFieldBooleanFormValues = z.infer<
16+
export type SettingsDataModelFieldBooleanFormValues = z.infer<
1717
typeof settingsDataModelFieldBooleanFormSchema
1818
>;
1919

2020
type SettingsDataModelFieldBooleanFormProps = {
2121
className?: string;
22-
fieldMetadataItem?: Pick<FieldMetadataItem, 'defaultValue'>;
22+
fieldMetadataItem: Pick<FieldMetadataItem, 'defaultValue'>;
2323
};
2424

2525
const StyledContainer = styled(CardContent)`
@@ -38,24 +38,20 @@ export const SettingsDataModelFieldBooleanForm = ({
3838
className,
3939
fieldMetadataItem,
4040
}: SettingsDataModelFieldBooleanFormProps) => {
41-
const { control, resetField } =
42-
useFormContext<SettingsDataModelFieldBooleanFormValues>();
41+
const { control } = useFormContext<SettingsDataModelFieldBooleanFormValues>();
4342

4443
const isEditMode = isDefined(fieldMetadataItem?.defaultValue);
45-
const initialValue = fieldMetadataItem?.defaultValue ?? true;
46-
47-
// Reset defaultValue on mount, so it doesn't conflict with other field types.
48-
useEffect(() => {
49-
resetField('defaultValue', { defaultValue: initialValue });
50-
}, [initialValue, resetField]);
44+
const { initialDefaultValue } = useBooleanSettingsFormInitialValues({
45+
fieldMetadataItem,
46+
});
5147

5248
return (
5349
<StyledContainer>
5450
<StyledLabel>Default Value</StyledLabel>
5551
<Controller
5652
name="defaultValue"
5753
control={control}
58-
defaultValue={initialValue}
54+
defaultValue={initialDefaultValue}
5955
render={({ field: { onChange, value } }) => (
6056
<Select
6157
className={className}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import { useFormContext } from 'react-hook-form';
2+
3+
import { FieldMetadataItem } from '@/object-metadata/types/FieldMetadataItem';
4+
import { SettingsDataModelFieldBooleanFormValues } from '@/settings/data-model/fields/forms/boolean/components/SettingsDataModelFieldBooleanForm';
5+
6+
export const useBooleanSettingsFormInitialValues = ({
7+
fieldMetadataItem,
8+
}: {
9+
fieldMetadataItem?: Pick<FieldMetadataItem, 'defaultValue'>;
10+
}) => {
11+
const initialDefaultValue =
12+
(fieldMetadataItem?.defaultValue as
13+
| SettingsDataModelFieldBooleanFormValues['defaultValue']
14+
| undefined) ?? true;
15+
16+
const { resetField } =
17+
useFormContext<SettingsDataModelFieldBooleanFormValues>();
18+
19+
const resetDefaultValueField = () => {
20+
resetField('defaultValue', { defaultValue: initialDefaultValue });
21+
};
22+
23+
return {
24+
initialDefaultValue,
25+
resetDefaultValueField,
26+
};
27+
};

packages/twenty-front/src/modules/settings/data-model/fields/forms/components/SettingsDataModelFieldSettingsFormCard.tsx

+6-6
Original file line numberDiff line numberDiff line change
@@ -8,18 +8,18 @@ import { SETTINGS_FIELD_TYPE_CONFIGS } from '@/settings/data-model/constants/Set
88
import {
99
SettingsDataModelFieldBooleanForm,
1010
settingsDataModelFieldBooleanFormSchema,
11-
} from '@/settings/data-model/fields/forms/components/boolean/SettingsDataModelFieldBooleanForm';
11+
} from '@/settings/data-model/fields/forms/boolean/components/SettingsDataModelFieldBooleanForm';
1212
import {
1313
SettingsDataModelFieldCurrencyForm,
1414
settingsDataModelFieldCurrencyFormSchema,
15-
} from '@/settings/data-model/fields/forms/components/currency/SettingsDataModelFieldCurrencyForm';
16-
import { settingsDataModelFieldRelationFormSchema } from '@/settings/data-model/fields/forms/components/relation/SettingsDataModelFieldRelationForm';
17-
import { SettingsDataModelFieldRelationSettingsFormCard } from '@/settings/data-model/fields/forms/components/relation/SettingsDataModelFieldRelationSettingsFormCard';
15+
} from '@/settings/data-model/fields/forms/currency/components/SettingsDataModelFieldCurrencyForm';
16+
import { settingsDataModelFieldRelationFormSchema } from '@/settings/data-model/fields/forms/relation/components/SettingsDataModelFieldRelationForm';
17+
import { SettingsDataModelFieldRelationSettingsFormCard } from '@/settings/data-model/fields/forms/relation/components/SettingsDataModelFieldRelationSettingsFormCard';
1818
import {
1919
settingsDataModelFieldMultiSelectFormSchema,
2020
settingsDataModelFieldSelectFormSchema,
21-
} from '@/settings/data-model/fields/forms/components/select/SettingsDataModelFieldSelectForm';
22-
import { SettingsDataModelFieldSelectSettingsFormCard } from '@/settings/data-model/fields/forms/components/select/SettingsDataModelFieldSelectSettingsFormCard';
21+
} from '@/settings/data-model/fields/forms/select/components/SettingsDataModelFieldSelectForm';
22+
import { SettingsDataModelFieldSelectSettingsFormCard } from '@/settings/data-model/fields/forms/select/components/SettingsDataModelFieldSelectSettingsFormCard';
2323
import {
2424
SettingsDataModelFieldPreviewCard,
2525
SettingsDataModelFieldPreviewCardProps,

packages/twenty-front/src/modules/settings/data-model/fields/forms/components/SettingsDataModelFieldTypeSelect.tsx

+39-2
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,9 @@ import {
77
SETTINGS_FIELD_TYPE_CONFIGS,
88
SettingsFieldTypeConfig,
99
} from '@/settings/data-model/constants/SettingsFieldTypeConfigs';
10+
import { useBooleanSettingsFormInitialValues } from '@/settings/data-model/fields/forms/boolean/hooks/useBooleanSettingsFormInitialValues';
11+
import { useCurrencySettingsFormInitialValues } from '@/settings/data-model/fields/forms/currency/hooks/useCurrencySettingsFormInitialValues';
12+
import { useSelectSettingsFormInitialValues } from '@/settings/data-model/fields/forms/select/hooks/useSelectSettingsFormInitialValues';
1013
import { SettingsSupportedFieldType } from '@/settings/data-model/types/SettingsSupportedFieldType';
1114
import { Select, SelectOption } from '@/ui/input/components/Select';
1215
import { FieldMetadataType } from '~/generated-metadata/graphql';
@@ -28,7 +31,10 @@ type SettingsDataModelFieldTypeSelectProps = {
2831
className?: string;
2932
disabled?: boolean;
3033
excludedFieldTypes?: SettingsSupportedFieldType[];
31-
fieldMetadataItem?: FieldMetadataItem;
34+
fieldMetadataItem?: Pick<
35+
FieldMetadataItem,
36+
'defaultValue' | 'options' | 'type'
37+
>;
3238
};
3339

3440
export const SettingsDataModelFieldTypeSelect = ({
@@ -51,6 +57,34 @@ export const SettingsDataModelFieldTypeSelect = ({
5157
value: key as SettingsSupportedFieldType,
5258
}));
5359

60+
const { resetDefaultValueField: resetBooleanDefaultValueField } =
61+
useBooleanSettingsFormInitialValues({ fieldMetadataItem });
62+
63+
const { resetDefaultValueField: resetCurrencyDefaultValueField } =
64+
useCurrencySettingsFormInitialValues({ fieldMetadataItem });
65+
66+
const { resetDefaultValueField: resetSelectDefaultValueField } =
67+
useSelectSettingsFormInitialValues({ fieldMetadataItem });
68+
69+
// Reset defaultValue on type change with a valid value for the selected type
70+
// so the form does not become invalid.
71+
const resetDefaultValueField = (nextValue: SettingsSupportedFieldType) => {
72+
switch (nextValue) {
73+
case FieldMetadataType.Boolean:
74+
resetBooleanDefaultValueField();
75+
break;
76+
case FieldMetadataType.Currency:
77+
resetCurrencyDefaultValueField();
78+
break;
79+
case FieldMetadataType.Select:
80+
case FieldMetadataType.MultiSelect:
81+
resetSelectDefaultValueField();
82+
break;
83+
default:
84+
break;
85+
}
86+
};
87+
5488
return (
5589
<Controller
5690
name="type"
@@ -67,7 +101,10 @@ export const SettingsDataModelFieldTypeSelect = ({
67101
disabled={disabled}
68102
dropdownId="object-field-type-select"
69103
value={value}
70-
onChange={onChange}
104+
onChange={(nextValue) => {
105+
onChange(nextValue);
106+
resetDefaultValueField(nextValue);
107+
}}
71108
options={fieldTypeOptions}
72109
/>
73110
)}
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,10 @@
1-
import { useEffect } from 'react';
21
import { Controller, useFormContext } from 'react-hook-form';
32
import { z } from 'zod';
43

54
import { FieldMetadataItem } from '@/object-metadata/types/FieldMetadataItem';
6-
import { CurrencyCode } from '@/object-record/record-field/types/CurrencyCode';
75
import { currencyCodeSchema } from '@/object-record/record-field/validation-schemas/currencyCodeSchema';
86
import { SETTINGS_FIELD_CURRENCY_CODES } from '@/settings/data-model/constants/SettingsFieldCurrencyCodes';
7+
import { useCurrencySettingsFormInitialValues } from '@/settings/data-model/fields/forms/currency/hooks/useCurrencySettingsFormInitialValues';
98
import { Select } from '@/ui/input/components/Select';
109
import { CardContent } from '@/ui/layout/card/components/CardContent';
1110
import { applySimpleQuotesToString } from '~/utils/string/applySimpleQuotesToString';
@@ -24,13 +23,13 @@ export const settingsDataModelFieldCurrencyFormSchema = z.object({
2423
}),
2524
});
2625

27-
type SettingsDataModelFieldCurrencyFormValues = z.infer<
26+
export type SettingsDataModelFieldCurrencyFormValues = z.infer<
2827
typeof settingsDataModelFieldCurrencyFormSchema
2928
>;
3029

3130
type SettingsDataModelFieldCurrencyFormProps = {
3231
disabled?: boolean;
33-
fieldMetadataItem?: Pick<FieldMetadataItem, 'defaultValue'>;
32+
fieldMetadataItem: Pick<FieldMetadataItem, 'defaultValue'>;
3433
};
3534

3635
const OPTIONS = Object.entries(SETTINGS_FIELD_CURRENCY_CODES).map(
@@ -45,25 +44,11 @@ export const SettingsDataModelFieldCurrencyForm = ({
4544
disabled,
4645
fieldMetadataItem,
4746
}: SettingsDataModelFieldCurrencyFormProps) => {
48-
const { control, resetField } =
47+
const { control } =
4948
useFormContext<SettingsDataModelFieldCurrencyFormValues>();
5049

51-
const initialAmountMicrosValue = null;
52-
const initialCurrencyCode =
53-
(fieldMetadataItem?.defaultValue?.currencyCode as CurrencyCode) ??
54-
CurrencyCode.USD;
55-
const initialCurrencyCodeValue =
56-
applySimpleQuotesToString(initialCurrencyCode);
57-
58-
// Reset defaultValue on mount, so it doesn't conflict with other field types.
59-
useEffect(() => {
60-
resetField('defaultValue', {
61-
defaultValue: {
62-
amountMicros: initialAmountMicrosValue,
63-
currencyCode: initialCurrencyCodeValue,
64-
},
65-
});
66-
}, [initialCurrencyCodeValue, resetField]);
50+
const { initialAmountMicrosValue, initialCurrencyCodeValue } =
51+
useCurrencySettingsFormInitialValues({ fieldMetadataItem });
6752

6853
return (
6954
<CardContent>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
import { useFormContext } from 'react-hook-form';
2+
3+
import { FieldMetadataItem } from '@/object-metadata/types/FieldMetadataItem';
4+
import { CurrencyCode } from '@/object-record/record-field/types/CurrencyCode';
5+
import { SettingsDataModelFieldCurrencyFormValues } from '@/settings/data-model/fields/forms/currency/components/SettingsDataModelFieldCurrencyForm';
6+
import { applySimpleQuotesToString } from '~/utils/string/applySimpleQuotesToString';
7+
8+
export const useCurrencySettingsFormInitialValues = ({
9+
fieldMetadataItem,
10+
}: {
11+
fieldMetadataItem?: Pick<FieldMetadataItem, 'defaultValue'>;
12+
}) => {
13+
const initialAmountMicrosValue = null;
14+
const initialCurrencyCode =
15+
(fieldMetadataItem?.defaultValue?.currencyCode as CurrencyCode) ??
16+
CurrencyCode.USD;
17+
const initialCurrencyCodeValue =
18+
applySimpleQuotesToString(initialCurrencyCode);
19+
const initialDefaultValue = {
20+
amountMicros: initialAmountMicrosValue,
21+
currencyCode: initialCurrencyCodeValue,
22+
};
23+
24+
const { resetField } =
25+
useFormContext<SettingsDataModelFieldCurrencyFormValues>();
26+
27+
const resetDefaultValueField = () =>
28+
resetField('defaultValue', { defaultValue: initialDefaultValue });
29+
30+
return {
31+
initialAmountMicrosValue,
32+
initialCurrencyCodeValue,
33+
initialDefaultValue,
34+
resetDefaultValueField,
35+
};
36+
};

packages/twenty-front/src/modules/settings/data-model/fields/forms/hooks/useSelectSettingsFormInitialValues.ts

-38
This file was deleted.
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import { FieldMetadataItem } from '@/object-metadata/types/FieldMetadataItem';
88
import { isObjectMetadataAvailableForRelation } from '@/object-metadata/utils/isObjectMetadataAvailableForRelation';
99
import { fieldMetadataItemSchema } from '@/object-metadata/validation-schemas/fieldMetadataItemSchema';
1010
import { RELATION_TYPES } from '@/settings/data-model/constants/RelationTypes';
11-
import { useRelationSettingsFormInitialValues } from '@/settings/data-model/fields/forms/hooks/useRelationSettingsFormInitialValues';
11+
import { useRelationSettingsFormInitialValues } from '@/settings/data-model/fields/forms/relation/hooks/useRelationSettingsFormInitialValues';
1212
import { RelationType } from '@/settings/data-model/types/RelationType';
1313
import { IconPicker } from '@/ui/input/components/IconPicker';
1414
import { Select } from '@/ui/input/components/Select';
@@ -32,7 +32,7 @@ export type SettingsDataModelFieldRelationFormValues = z.infer<
3232
>;
3333

3434
type SettingsDataModelFieldRelationFormProps = {
35-
fieldMetadataItem?: Pick<
35+
fieldMetadataItem: Pick<
3636
FieldMetadataItem,
3737
'fromRelationMetadata' | 'toRelationMetadata' | 'type'
3838
>;
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@ import { RELATION_TYPES } from '@/settings/data-model/constants/RelationTypes';
88
import {
99
SettingsDataModelFieldRelationForm,
1010
SettingsDataModelFieldRelationFormValues,
11-
} from '@/settings/data-model/fields/forms/components/relation/SettingsDataModelFieldRelationForm';
12-
import { useRelationSettingsFormInitialValues } from '@/settings/data-model/fields/forms/hooks/useRelationSettingsFormInitialValues';
11+
} from '@/settings/data-model/fields/forms/relation/components/SettingsDataModelFieldRelationForm';
12+
import { useRelationSettingsFormInitialValues } from '@/settings/data-model/fields/forms/relation/hooks/useRelationSettingsFormInitialValues';
1313
import {
1414
SettingsDataModelFieldPreviewCard,
1515
SettingsDataModelFieldPreviewCardProps,
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
import { useEffect } from 'react';
21
import { Controller, useFormContext } from 'react-hook-form';
32
import styled from '@emotion/styled';
43
import { DropResult } from '@hello-pangea/dnd';
@@ -10,8 +9,8 @@ import {
109
FieldMetadataItemOption,
1110
} from '@/object-metadata/types/FieldMetadataItem';
1211
import { selectOptionsSchema } from '@/object-metadata/validation-schemas/selectOptionsSchema';
13-
import { useSelectSettingsFormInitialValues } from '@/settings/data-model/fields/forms/hooks/useSelectSettingsFormInitialValues';
14-
import { generateNewSelectOption } from '@/settings/data-model/fields/forms/utils/generateNewSelectOption';
12+
import { useSelectSettingsFormInitialValues } from '@/settings/data-model/fields/forms/select/hooks/useSelectSettingsFormInitialValues';
13+
import { generateNewSelectOption } from '@/settings/data-model/fields/forms/select/utils/generateNewSelectOption';
1514
import { isSelectOptionDefaultValue } from '@/settings/data-model/utils/isSelectOptionDefaultValue';
1615
import { LightButton } from '@/ui/input/button/components/LightButton';
1716
import { CardContent } from '@/ui/layout/card/components/CardContent';
@@ -86,7 +85,6 @@ export const SettingsDataModelFieldSelectForm = ({
8685
setValue: setFormValue,
8786
watch: watchFormValue,
8887
getValues,
89-
resetField,
9088
} = useFormContext<SettingsDataModelFieldSelectFormValues>();
9189

9290
const handleDragEnd = (
@@ -168,11 +166,6 @@ export const SettingsDataModelFieldSelectForm = ({
168166
}
169167
};
170168

171-
// Reset defaultValue on mount or on field type change, so it doesn't conflict with other field types.
172-
useEffect(() => {
173-
resetField('defaultValue', { defaultValue: initialDefaultValue });
174-
}, [initialDefaultValue, initialOptions, resetField, fieldMetadataItem.type]);
175-
176169
return (
177170
<>
178171
<Controller
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import {
1111
import { v4 } from 'uuid';
1212

1313
import { FieldMetadataItemOption } from '@/object-metadata/types/FieldMetadataItem';
14-
import { getOptionValueFromLabel } from '@/settings/data-model/fields/forms/utils/getOptionValueFromLabel';
14+
import { getOptionValueFromLabel } from '@/settings/data-model/fields/forms/select/utils/getOptionValueFromLabel';
1515
import { ColorSample } from '@/ui/display/color/components/ColorSample';
1616
import { LightIconButton } from '@/ui/input/button/components/LightIconButton';
1717
import { TextInput } from '@/ui/input/components/TextInput';

0 commit comments

Comments
 (0)