refactor: reset field default value on type change in Settings (#5534)

Related issue: #5412

See https://github.com/twentyhq/twenty/pull/5436#discussion_r1609470484
for context.
This commit is contained in:
Thaïs 2024-05-24 12:15:17 +02:00 committed by GitHub
parent 18fafbdeb5
commit 7f7ea59b51
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
23 changed files with 326 additions and 131 deletions

View File

@ -1,7 +1,7 @@
import { z } from 'zod';
import { FieldMetadataItemOption } from '@/object-metadata/types/FieldMetadataItem';
import { getOptionValueFromLabel } from '@/settings/data-model/fields/forms/utils/getOptionValueFromLabel';
import { getOptionValueFromLabel } from '@/settings/data-model/fields/forms/select/utils/getOptionValueFromLabel';
import { themeColorSchema } from '@/ui/theme/utils/themeColorSchema';
import { computeOptionValueFromLabelOrThrow } from '~/pages/settings/data-model/utils/compute-option-value-from-label.utils';

View File

@ -1,10 +1,10 @@
import { useEffect } from 'react';
import { Controller, useFormContext } from 'react-hook-form';
import styled from '@emotion/styled';
import { IconCheck, IconX } from 'twenty-ui';
import { z } from 'zod';
import { FieldMetadataItem } from '@/object-metadata/types/FieldMetadataItem';
import { useBooleanSettingsFormInitialValues } from '@/settings/data-model/fields/forms/boolean/hooks/useBooleanSettingsFormInitialValues';
import { Select } from '@/ui/input/components/Select';
import { CardContent } from '@/ui/layout/card/components/CardContent';
import { isDefined } from '~/utils/isDefined';
@ -13,13 +13,13 @@ export const settingsDataModelFieldBooleanFormSchema = z.object({
defaultValue: z.boolean(),
});
type SettingsDataModelFieldBooleanFormValues = z.infer<
export type SettingsDataModelFieldBooleanFormValues = z.infer<
typeof settingsDataModelFieldBooleanFormSchema
>;
type SettingsDataModelFieldBooleanFormProps = {
className?: string;
fieldMetadataItem?: Pick<FieldMetadataItem, 'defaultValue'>;
fieldMetadataItem: Pick<FieldMetadataItem, 'defaultValue'>;
};
const StyledContainer = styled(CardContent)`
@ -38,16 +38,12 @@ export const SettingsDataModelFieldBooleanForm = ({
className,
fieldMetadataItem,
}: SettingsDataModelFieldBooleanFormProps) => {
const { control, resetField } =
useFormContext<SettingsDataModelFieldBooleanFormValues>();
const { control } = useFormContext<SettingsDataModelFieldBooleanFormValues>();
const isEditMode = isDefined(fieldMetadataItem?.defaultValue);
const initialValue = fieldMetadataItem?.defaultValue ?? true;
// Reset defaultValue on mount, so it doesn't conflict with other field types.
useEffect(() => {
resetField('defaultValue', { defaultValue: initialValue });
}, [initialValue, resetField]);
const { initialDefaultValue } = useBooleanSettingsFormInitialValues({
fieldMetadataItem,
});
return (
<StyledContainer>
@ -55,7 +51,7 @@ export const SettingsDataModelFieldBooleanForm = ({
<Controller
name="defaultValue"
control={control}
defaultValue={initialValue}
defaultValue={initialDefaultValue}
render={({ field: { onChange, value } }) => (
<Select
className={className}

View File

@ -0,0 +1,57 @@
import { useFormContext } from 'react-hook-form';
import styled from '@emotion/styled';
import { FieldMetadataItem } from '@/object-metadata/types/FieldMetadataItem';
import { SettingsDataModelPreviewFormCard } from '@/settings/data-model/components/SettingsDataModelPreviewFormCard';
import {
SettingsDataModelFieldBooleanForm,
SettingsDataModelFieldBooleanFormValues,
} from '@/settings/data-model/fields/forms/boolean/components/SettingsDataModelFieldBooleanForm';
import { useBooleanSettingsFormInitialValues } from '@/settings/data-model/fields/forms/boolean/hooks/useBooleanSettingsFormInitialValues';
import {
SettingsDataModelFieldPreviewCard,
SettingsDataModelFieldPreviewCardProps,
} from '@/settings/data-model/fields/preview/components/SettingsDataModelFieldPreviewCard';
type SettingsDataModelFieldBooleanSettingsFormCardProps = {
fieldMetadataItem: Pick<
FieldMetadataItem,
'icon' | 'label' | 'type' | 'defaultValue'
>;
} & Pick<SettingsDataModelFieldPreviewCardProps, 'objectMetadataItem'>;
const StyledFieldPreviewCard = styled(SettingsDataModelFieldPreviewCard)`
display: grid;
flex: 1 1 100%;
`;
export const SettingsDataModelFieldBooleanSettingsFormCard = ({
fieldMetadataItem,
objectMetadataItem,
}: SettingsDataModelFieldBooleanSettingsFormCardProps) => {
const { initialDefaultValue } = useBooleanSettingsFormInitialValues({
fieldMetadataItem,
});
const { watch: watchFormValue } =
useFormContext<SettingsDataModelFieldBooleanFormValues>();
return (
<SettingsDataModelPreviewFormCard
preview={
<StyledFieldPreviewCard
fieldMetadataItem={{
...fieldMetadataItem,
defaultValue: watchFormValue('defaultValue', initialDefaultValue),
}}
objectMetadataItem={objectMetadataItem}
/>
}
form={
<SettingsDataModelFieldBooleanForm
fieldMetadataItem={fieldMetadataItem}
/>
}
/>
);
};

View File

@ -0,0 +1,26 @@
import { useFormContext } from 'react-hook-form';
import { FieldMetadataItem } from '@/object-metadata/types/FieldMetadataItem';
import { SettingsDataModelFieldBooleanFormValues } from '@/settings/data-model/fields/forms/boolean/components/SettingsDataModelFieldBooleanForm';
export const useBooleanSettingsFormInitialValues = ({
fieldMetadataItem,
}: {
fieldMetadataItem?: Pick<FieldMetadataItem, 'defaultValue'>;
}) => {
const initialDefaultValue =
(fieldMetadataItem?.defaultValue as SettingsDataModelFieldBooleanFormValues['defaultValue']) ??
true;
const { resetField } =
useFormContext<SettingsDataModelFieldBooleanFormValues>();
const resetDefaultValueField = () => {
resetField('defaultValue', { defaultValue: initialDefaultValue });
};
return {
initialDefaultValue,
resetDefaultValueField,
};
};

View File

@ -5,21 +5,17 @@ import { z } from 'zod';
import { FieldMetadataItem } from '@/object-metadata/types/FieldMetadataItem';
import { SettingsDataModelPreviewFormCard } from '@/settings/data-model/components/SettingsDataModelPreviewFormCard';
import { SETTINGS_FIELD_TYPE_CONFIGS } from '@/settings/data-model/constants/SettingsFieldTypeConfigs';
import {
SettingsDataModelFieldBooleanForm,
settingsDataModelFieldBooleanFormSchema,
} from '@/settings/data-model/fields/forms/components/boolean/SettingsDataModelFieldBooleanForm';
import {
SettingsDataModelFieldCurrencyForm,
settingsDataModelFieldCurrencyFormSchema,
} from '@/settings/data-model/fields/forms/components/currency/SettingsDataModelFieldCurrencyForm';
import { settingsDataModelFieldRelationFormSchema } from '@/settings/data-model/fields/forms/components/relation/SettingsDataModelFieldRelationForm';
import { SettingsDataModelFieldRelationSettingsFormCard } from '@/settings/data-model/fields/forms/components/relation/SettingsDataModelFieldRelationSettingsFormCard';
import { settingsDataModelFieldBooleanFormSchema } from '@/settings/data-model/fields/forms/boolean/components/SettingsDataModelFieldBooleanForm';
import { SettingsDataModelFieldBooleanSettingsFormCard } from '@/settings/data-model/fields/forms/boolean/components/SettingsDataModelFieldBooleanSettingsFormCard';
import { settingsDataModelFieldCurrencyFormSchema } from '@/settings/data-model/fields/forms/currency/components/SettingsDataModelFieldCurrencyForm';
import { SettingsDataModelFieldCurrencySettingsFormCard } from '@/settings/data-model/fields/forms/currency/components/SettingsDataModelFieldCurrencySettingsFormCard';
import { settingsDataModelFieldRelationFormSchema } from '@/settings/data-model/fields/forms/relation/components/SettingsDataModelFieldRelationForm';
import { SettingsDataModelFieldRelationSettingsFormCard } from '@/settings/data-model/fields/forms/relation/components/SettingsDataModelFieldRelationSettingsFormCard';
import {
settingsDataModelFieldMultiSelectFormSchema,
settingsDataModelFieldSelectFormSchema,
} from '@/settings/data-model/fields/forms/components/select/SettingsDataModelFieldSelectForm';
import { SettingsDataModelFieldSelectSettingsFormCard } from '@/settings/data-model/fields/forms/components/select/SettingsDataModelFieldSelectSettingsFormCard';
} from '@/settings/data-model/fields/forms/select/components/SettingsDataModelFieldSelectForm';
import { SettingsDataModelFieldSelectSettingsFormCard } from '@/settings/data-model/fields/forms/select/components/SettingsDataModelFieldSelectSettingsFormCard';
import {
SettingsDataModelFieldPreviewCard,
SettingsDataModelFieldPreviewCardProps,
@ -108,6 +104,25 @@ export const SettingsDataModelFieldSettingsFormCard = ({
}: SettingsDataModelFieldSettingsFormCardProps) => {
if (!previewableTypes.includes(fieldMetadataItem.type)) return null;
if (fieldMetadataItem.type === FieldMetadataType.Boolean) {
return (
<SettingsDataModelFieldBooleanSettingsFormCard
fieldMetadataItem={fieldMetadataItem}
objectMetadataItem={objectMetadataItem}
/>
);
}
if (fieldMetadataItem.type === FieldMetadataType.Currency) {
return (
<SettingsDataModelFieldCurrencySettingsFormCard
disabled={disableCurrencyForm}
fieldMetadataItem={fieldMetadataItem}
objectMetadataItem={objectMetadataItem}
/>
);
}
if (fieldMetadataItem.type === FieldMetadataType.Relation) {
return (
<SettingsDataModelFieldRelationSettingsFormCard
@ -137,18 +152,6 @@ export const SettingsDataModelFieldSettingsFormCard = ({
objectMetadataItem={objectMetadataItem}
/>
}
form={
fieldMetadataItem.type === FieldMetadataType.Boolean ? (
<SettingsDataModelFieldBooleanForm
fieldMetadataItem={fieldMetadataItem}
/>
) : fieldMetadataItem.type === FieldMetadataType.Currency ? (
<SettingsDataModelFieldCurrencyForm
disabled={disableCurrencyForm}
fieldMetadataItem={fieldMetadataItem}
/>
) : undefined
}
/>
);
};

View File

@ -7,6 +7,9 @@ import {
SETTINGS_FIELD_TYPE_CONFIGS,
SettingsFieldTypeConfig,
} from '@/settings/data-model/constants/SettingsFieldTypeConfigs';
import { useBooleanSettingsFormInitialValues } from '@/settings/data-model/fields/forms/boolean/hooks/useBooleanSettingsFormInitialValues';
import { useCurrencySettingsFormInitialValues } from '@/settings/data-model/fields/forms/currency/hooks/useCurrencySettingsFormInitialValues';
import { useSelectSettingsFormInitialValues } from '@/settings/data-model/fields/forms/select/hooks/useSelectSettingsFormInitialValues';
import { SettingsSupportedFieldType } from '@/settings/data-model/types/SettingsSupportedFieldType';
import { Select, SelectOption } from '@/ui/input/components/Select';
import { FieldMetadataType } from '~/generated-metadata/graphql';
@ -28,7 +31,10 @@ type SettingsDataModelFieldTypeSelectProps = {
className?: string;
disabled?: boolean;
excludedFieldTypes?: SettingsSupportedFieldType[];
fieldMetadataItem?: FieldMetadataItem;
fieldMetadataItem?: Pick<
FieldMetadataItem,
'defaultValue' | 'options' | 'type'
>;
};
export const SettingsDataModelFieldTypeSelect = ({
@ -51,6 +57,34 @@ export const SettingsDataModelFieldTypeSelect = ({
value: key as SettingsSupportedFieldType,
}));
const { resetDefaultValueField: resetBooleanDefaultValueField } =
useBooleanSettingsFormInitialValues({ fieldMetadataItem });
const { resetDefaultValueField: resetCurrencyDefaultValueField } =
useCurrencySettingsFormInitialValues({ fieldMetadataItem });
const { resetDefaultValueField: resetSelectDefaultValueField } =
useSelectSettingsFormInitialValues({ fieldMetadataItem });
// Reset defaultValue on type change with a valid value for the selected type
// so the form does not become invalid.
const resetDefaultValueField = (nextValue: SettingsSupportedFieldType) => {
switch (nextValue) {
case FieldMetadataType.Boolean:
resetBooleanDefaultValueField();
break;
case FieldMetadataType.Currency:
resetCurrencyDefaultValueField();
break;
case FieldMetadataType.Select:
case FieldMetadataType.MultiSelect:
resetSelectDefaultValueField();
break;
default:
break;
}
};
return (
<Controller
name="type"
@ -67,7 +101,10 @@ export const SettingsDataModelFieldTypeSelect = ({
disabled={disabled}
dropdownId="object-field-type-select"
value={value}
onChange={onChange}
onChange={(nextValue) => {
onChange(nextValue);
resetDefaultValueField(nextValue);
}}
options={fieldTypeOptions}
/>
)}

View File

@ -1,11 +1,10 @@
import { useEffect } from 'react';
import { Controller, useFormContext } from 'react-hook-form';
import { z } from 'zod';
import { FieldMetadataItem } from '@/object-metadata/types/FieldMetadataItem';
import { CurrencyCode } from '@/object-record/record-field/types/CurrencyCode';
import { currencyCodeSchema } from '@/object-record/record-field/validation-schemas/currencyCodeSchema';
import { SETTINGS_FIELD_CURRENCY_CODES } from '@/settings/data-model/constants/SettingsFieldCurrencyCodes';
import { useCurrencySettingsFormInitialValues } from '@/settings/data-model/fields/forms/currency/hooks/useCurrencySettingsFormInitialValues';
import { Select } from '@/ui/input/components/Select';
import { CardContent } from '@/ui/layout/card/components/CardContent';
import { applySimpleQuotesToString } from '~/utils/string/applySimpleQuotesToString';
@ -14,7 +13,7 @@ import { simpleQuotesStringSchema } from '~/utils/validation-schemas/simpleQuote
export const settingsDataModelFieldCurrencyFormSchema = z.object({
defaultValue: z.object({
amountMicros: z.null(),
amountMicros: z.number().nullable(),
currencyCode: simpleQuotesStringSchema.refine(
(value) =>
currencyCodeSchema.safeParse(stripSimpleQuotesFromString(value))
@ -24,13 +23,13 @@ export const settingsDataModelFieldCurrencyFormSchema = z.object({
}),
});
type SettingsDataModelFieldCurrencyFormValues = z.infer<
export type SettingsDataModelFieldCurrencyFormValues = z.infer<
typeof settingsDataModelFieldCurrencyFormSchema
>;
type SettingsDataModelFieldCurrencyFormProps = {
disabled?: boolean;
fieldMetadataItem?: Pick<FieldMetadataItem, 'defaultValue'>;
fieldMetadataItem: Pick<FieldMetadataItem, 'defaultValue'>;
};
const OPTIONS = Object.entries(SETTINGS_FIELD_CURRENCY_CODES).map(
@ -45,25 +44,11 @@ export const SettingsDataModelFieldCurrencyForm = ({
disabled,
fieldMetadataItem,
}: SettingsDataModelFieldCurrencyFormProps) => {
const { control, resetField } =
const { control } =
useFormContext<SettingsDataModelFieldCurrencyFormValues>();
const initialAmountMicrosValue = null;
const initialCurrencyCode =
(fieldMetadataItem?.defaultValue?.currencyCode as CurrencyCode) ??
CurrencyCode.USD;
const initialCurrencyCodeValue =
applySimpleQuotesToString(initialCurrencyCode);
// Reset defaultValue on mount, so it doesn't conflict with other field types.
useEffect(() => {
resetField('defaultValue', {
defaultValue: {
amountMicros: initialAmountMicrosValue,
currencyCode: initialCurrencyCodeValue,
},
});
}, [initialCurrencyCodeValue, resetField]);
const { initialAmountMicrosValue, initialCurrencyCodeValue } =
useCurrencySettingsFormInitialValues({ fieldMetadataItem });
return (
<CardContent>

View File

@ -0,0 +1,60 @@
import { useFormContext } from 'react-hook-form';
import styled from '@emotion/styled';
import { FieldMetadataItem } from '@/object-metadata/types/FieldMetadataItem';
import { SettingsDataModelPreviewFormCard } from '@/settings/data-model/components/SettingsDataModelPreviewFormCard';
import {
SettingsDataModelFieldCurrencyForm,
SettingsDataModelFieldCurrencyFormValues,
} from '@/settings/data-model/fields/forms/currency/components/SettingsDataModelFieldCurrencyForm';
import { useCurrencySettingsFormInitialValues } from '@/settings/data-model/fields/forms/currency/hooks/useCurrencySettingsFormInitialValues';
import {
SettingsDataModelFieldPreviewCard,
SettingsDataModelFieldPreviewCardProps,
} from '@/settings/data-model/fields/preview/components/SettingsDataModelFieldPreviewCard';
type SettingsDataModelFieldCurrencySettingsFormCardProps = {
disabled?: boolean;
fieldMetadataItem: Pick<
FieldMetadataItem,
'icon' | 'label' | 'type' | 'defaultValue'
>;
} & Pick<SettingsDataModelFieldPreviewCardProps, 'objectMetadataItem'>;
const StyledFieldPreviewCard = styled(SettingsDataModelFieldPreviewCard)`
display: grid;
flex: 1 1 100%;
`;
export const SettingsDataModelFieldCurrencySettingsFormCard = ({
disabled,
fieldMetadataItem,
objectMetadataItem,
}: SettingsDataModelFieldCurrencySettingsFormCardProps) => {
const { initialDefaultValue } = useCurrencySettingsFormInitialValues({
fieldMetadataItem,
});
const { watch: watchFormValue } =
useFormContext<SettingsDataModelFieldCurrencyFormValues>();
return (
<SettingsDataModelPreviewFormCard
preview={
<StyledFieldPreviewCard
fieldMetadataItem={{
...fieldMetadataItem,
defaultValue: watchFormValue('defaultValue', initialDefaultValue),
}}
objectMetadataItem={objectMetadataItem}
/>
}
form={
<SettingsDataModelFieldCurrencyForm
disabled={disabled}
fieldMetadataItem={fieldMetadataItem}
/>
}
/>
);
};

View File

@ -0,0 +1,37 @@
import { useFormContext } from 'react-hook-form';
import { FieldMetadataItem } from '@/object-metadata/types/FieldMetadataItem';
import { CurrencyCode } from '@/object-record/record-field/types/CurrencyCode';
import { SettingsDataModelFieldCurrencyFormValues } from '@/settings/data-model/fields/forms/currency/components/SettingsDataModelFieldCurrencyForm';
import { applySimpleQuotesToString } from '~/utils/string/applySimpleQuotesToString';
export const useCurrencySettingsFormInitialValues = ({
fieldMetadataItem,
}: {
fieldMetadataItem?: Pick<FieldMetadataItem, 'defaultValue'>;
}) => {
const initialAmountMicrosValue =
(fieldMetadataItem?.defaultValue?.amountMicros as number | null) ?? null;
const initialCurrencyCode =
(fieldMetadataItem?.defaultValue?.currencyCode as CurrencyCode) ??
CurrencyCode.USD;
const initialCurrencyCodeValue =
applySimpleQuotesToString(initialCurrencyCode);
const initialDefaultValue = {
amountMicros: initialAmountMicrosValue,
currencyCode: initialCurrencyCodeValue,
};
const { resetField } =
useFormContext<SettingsDataModelFieldCurrencyFormValues>();
const resetDefaultValueField = () =>
resetField('defaultValue', { defaultValue: initialDefaultValue });
return {
initialAmountMicrosValue,
initialCurrencyCodeValue,
initialDefaultValue,
resetDefaultValueField,
};
};

View File

@ -1,38 +0,0 @@
import { useMemo } from 'react';
import { v4 } from 'uuid';
import {
FieldMetadataItem,
FieldMetadataItemOption,
} from '@/object-metadata/types/FieldMetadataItem';
import { getOptionValueFromLabel } from '@/settings/data-model/fields/forms/utils/getOptionValueFromLabel';
const DEFAULT_OPTION: FieldMetadataItemOption = {
color: 'green',
id: v4(),
label: 'Option 1',
position: 0,
value: getOptionValueFromLabel('Option 1'),
};
export const useSelectSettingsFormInitialValues = ({
fieldMetadataItem,
}: {
fieldMetadataItem: Pick<FieldMetadataItem, 'defaultValue' | 'options'>;
}) => {
const initialDefaultValue = fieldMetadataItem.defaultValue ?? null;
const initialOptions = useMemo(
() =>
fieldMetadataItem.options?.length
? [...fieldMetadataItem.options].sort(
(optionA, optionB) => optionA.position - optionB.position,
)
: [DEFAULT_OPTION],
[fieldMetadataItem.options],
);
return {
initialDefaultValue,
initialOptions,
};
};

View File

@ -8,7 +8,7 @@ import { FieldMetadataItem } from '@/object-metadata/types/FieldMetadataItem';
import { isObjectMetadataAvailableForRelation } from '@/object-metadata/utils/isObjectMetadataAvailableForRelation';
import { fieldMetadataItemSchema } from '@/object-metadata/validation-schemas/fieldMetadataItemSchema';
import { RELATION_TYPES } from '@/settings/data-model/constants/RelationTypes';
import { useRelationSettingsFormInitialValues } from '@/settings/data-model/fields/forms/hooks/useRelationSettingsFormInitialValues';
import { useRelationSettingsFormInitialValues } from '@/settings/data-model/fields/forms/relation/hooks/useRelationSettingsFormInitialValues';
import { RelationType } from '@/settings/data-model/types/RelationType';
import { IconPicker } from '@/ui/input/components/IconPicker';
import { Select } from '@/ui/input/components/Select';
@ -32,7 +32,7 @@ export type SettingsDataModelFieldRelationFormValues = z.infer<
>;
type SettingsDataModelFieldRelationFormProps = {
fieldMetadataItem?: Pick<
fieldMetadataItem: Pick<
FieldMetadataItem,
'fromRelationMetadata' | 'toRelationMetadata' | 'type'
>;

View File

@ -8,8 +8,8 @@ import { RELATION_TYPES } from '@/settings/data-model/constants/RelationTypes';
import {
SettingsDataModelFieldRelationForm,
SettingsDataModelFieldRelationFormValues,
} from '@/settings/data-model/fields/forms/components/relation/SettingsDataModelFieldRelationForm';
import { useRelationSettingsFormInitialValues } from '@/settings/data-model/fields/forms/hooks/useRelationSettingsFormInitialValues';
} from '@/settings/data-model/fields/forms/relation/components/SettingsDataModelFieldRelationForm';
import { useRelationSettingsFormInitialValues } from '@/settings/data-model/fields/forms/relation/hooks/useRelationSettingsFormInitialValues';
import {
SettingsDataModelFieldPreviewCard,
SettingsDataModelFieldPreviewCardProps,

View File

@ -1,4 +1,3 @@
import { useEffect } from 'react';
import { Controller, useFormContext } from 'react-hook-form';
import styled from '@emotion/styled';
import { DropResult } from '@hello-pangea/dnd';
@ -10,8 +9,8 @@ import {
FieldMetadataItemOption,
} from '@/object-metadata/types/FieldMetadataItem';
import { selectOptionsSchema } from '@/object-metadata/validation-schemas/selectOptionsSchema';
import { useSelectSettingsFormInitialValues } from '@/settings/data-model/fields/forms/hooks/useSelectSettingsFormInitialValues';
import { generateNewSelectOption } from '@/settings/data-model/fields/forms/utils/generateNewSelectOption';
import { useSelectSettingsFormInitialValues } from '@/settings/data-model/fields/forms/select/hooks/useSelectSettingsFormInitialValues';
import { generateNewSelectOption } from '@/settings/data-model/fields/forms/select/utils/generateNewSelectOption';
import { isSelectOptionDefaultValue } from '@/settings/data-model/utils/isSelectOptionDefaultValue';
import { LightButton } from '@/ui/input/button/components/LightButton';
import { CardContent } from '@/ui/layout/card/components/CardContent';
@ -86,7 +85,6 @@ export const SettingsDataModelFieldSelectForm = ({
setValue: setFormValue,
watch: watchFormValue,
getValues,
resetField,
} = useFormContext<SettingsDataModelFieldSelectFormValues>();
const handleDragEnd = (
@ -168,11 +166,6 @@ export const SettingsDataModelFieldSelectForm = ({
}
};
// Reset defaultValue on mount or on field type change, so it doesn't conflict with other field types.
useEffect(() => {
resetField('defaultValue', { defaultValue: initialDefaultValue });
}, [initialDefaultValue, initialOptions, resetField, fieldMetadataItem.type]);
return (
<>
<Controller

View File

@ -12,7 +12,7 @@ import {
import { v4 } from 'uuid';
import { FieldMetadataItemOption } from '@/object-metadata/types/FieldMetadataItem';
import { getOptionValueFromLabel } from '@/settings/data-model/fields/forms/utils/getOptionValueFromLabel';
import { getOptionValueFromLabel } from '@/settings/data-model/fields/forms/select/utils/getOptionValueFromLabel';
import { LightIconButton } from '@/ui/input/button/components/LightIconButton';
import { TextInput } from '@/ui/input/components/TextInput';
import { Dropdown } from '@/ui/layout/dropdown/components/Dropdown';

View File

@ -8,8 +8,8 @@ import {
settingsDataModelFieldMultiSelectFormSchema,
SettingsDataModelFieldSelectForm,
settingsDataModelFieldSelectFormSchema,
} from '@/settings/data-model/fields/forms/components/select/SettingsDataModelFieldSelectForm';
import { useSelectSettingsFormInitialValues } from '@/settings/data-model/fields/forms/hooks/useSelectSettingsFormInitialValues';
} from '@/settings/data-model/fields/forms/select/components/SettingsDataModelFieldSelectForm';
import { useSelectSettingsFormInitialValues } from '@/settings/data-model/fields/forms/select/hooks/useSelectSettingsFormInitialValues';
import {
SettingsDataModelFieldPreviewCard,
SettingsDataModelFieldPreviewCardProps,
@ -20,7 +20,7 @@ const selectOrMultiSelectFormSchema = z.union([
settingsDataModelFieldMultiSelectFormSchema,
]);
type SettingsDataModelFieldSettingsFormValues = z.infer<
type SettingsDataModelFieldSelectOrMultiSelectFormValues = z.infer<
typeof selectOrMultiSelectFormSchema
>;
@ -46,7 +46,7 @@ export const SettingsDataModelFieldSelectSettingsFormCard = ({
});
const { watch: watchFormValue } =
useFormContext<SettingsDataModelFieldSettingsFormValues>();
useFormContext<SettingsDataModelFieldSelectOrMultiSelectFormValues>();
return (
<SettingsDataModelPreviewFormCard

View File

@ -0,0 +1,49 @@
import { useMemo } from 'react';
import { useFormContext } from 'react-hook-form';
import { v4 } from 'uuid';
import {
FieldMetadataItem,
FieldMetadataItemOption,
} from '@/object-metadata/types/FieldMetadataItem';
import { SettingsDataModelFieldSelectFormValues } from '@/settings/data-model/fields/forms/select/components/SettingsDataModelFieldSelectForm';
import { getOptionValueFromLabel } from '@/settings/data-model/fields/forms/select/utils/getOptionValueFromLabel';
const DEFAULT_OPTION: FieldMetadataItemOption = {
color: 'green',
id: v4(),
label: 'Option 1',
position: 0,
value: getOptionValueFromLabel('Option 1'),
};
export const useSelectSettingsFormInitialValues = ({
fieldMetadataItem,
}: {
fieldMetadataItem?: Pick<FieldMetadataItem, 'defaultValue' | 'options'>;
}) => {
const initialDefaultValue =
(fieldMetadataItem?.defaultValue as SettingsDataModelFieldSelectFormValues['defaultValue']) ??
null;
const initialOptions = useMemo(
() =>
fieldMetadataItem?.options?.length
? [...fieldMetadataItem.options].sort(
(optionA, optionB) => optionA.position - optionB.position,
)
: [DEFAULT_OPTION],
[fieldMetadataItem?.options],
);
const { resetField } =
useFormContext<SettingsDataModelFieldSelectFormValues>();
const resetDefaultValueField = () =>
resetField('defaultValue', { defaultValue: initialDefaultValue });
return {
initialDefaultValue,
initialOptions,
resetDefaultValueField,
};
};

View File

@ -1,4 +1,4 @@
import { generateNewSelectOptionLabel } from '@/settings/data-model/fields/forms/utils/generateNewSelectOptionLabel';
import { generateNewSelectOptionLabel } from '../generateNewSelectOptionLabel';
describe('generateNewSelectOptionLabel', () => {
it('generates a new select option label', () => {

View File

@ -1,4 +1,4 @@
import { getOptionValueFromLabel } from '@/settings/data-model/fields/forms/utils/getOptionValueFromLabel';
import { getOptionValueFromLabel } from '../getOptionValueFromLabel';
describe('getOptionValueFromLabel', () => {
it('should return the option value from the label', () => {

View File

@ -2,8 +2,8 @@ import { getNextThemeColor } from 'twenty-ui';
import { v4 } from 'uuid';
import { FieldMetadataItemOption } from '@/object-metadata/types/FieldMetadataItem';
import { generateNewSelectOptionLabel } from '@/settings/data-model/fields/forms/utils/generateNewSelectOptionLabel';
import { getOptionValueFromLabel } from '@/settings/data-model/fields/forms/utils/getOptionValueFromLabel';
import { generateNewSelectOptionLabel } from '@/settings/data-model/fields/forms/select/utils/generateNewSelectOptionLabel';
import { getOptionValueFromLabel } from '@/settings/data-model/fields/forms/select/utils/getOptionValueFromLabel';
export const generateNewSelectOption = (
options: FieldMetadataItemOption[],

View File

@ -215,16 +215,6 @@ export const SettingsObjectNewFieldStep2 = () => {
} else {
const createdMetadataField = await createMetadataField({
...formValues,
defaultValue:
formValues.type === FieldMetadataType.Currency &&
'defaultValue' in formValues
? {
...formValues.defaultValue,
amountMicros: null,
}
: 'defaultValue' in formValues
? formValues.defaultValue
: undefined,
objectMetadataId: activeObjectMetadataItem.id,
});