fix: reset default value on field type switch in Settings/Data Model … (#5436)
…field form Closes #5412
This commit is contained in:
@ -3,23 +3,23 @@ import omit from 'lodash.omit';
|
|||||||
import { z } from 'zod';
|
import { z } from 'zod';
|
||||||
|
|
||||||
import { FieldMetadataItem } from '@/object-metadata/types/FieldMetadataItem';
|
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 {
|
import {
|
||||||
SettingsDataModelFieldBooleanForm,
|
SettingsDataModelFieldBooleanForm,
|
||||||
settingsDataModelFieldBooleanFormSchema,
|
settingsDataModelFieldBooleanFormSchema,
|
||||||
} from '@/settings/data-model/components/SettingsDataModelDefaultValue';
|
} from '@/settings/data-model/fields/forms/components/boolean/SettingsDataModelFieldBooleanForm';
|
||||||
import { SettingsDataModelPreviewFormCard } from '@/settings/data-model/components/SettingsDataModelPreviewFormCard';
|
|
||||||
import { settingsDataModelFieldRelationFormSchema } from '@/settings/data-model/components/SettingsObjectFieldRelationForm';
|
|
||||||
import {
|
|
||||||
settingsDataModelFieldMultiSelectFormSchema,
|
|
||||||
settingsDataModelFieldSelectFormSchema,
|
|
||||||
} from '@/settings/data-model/components/SettingsObjectFieldSelectForm';
|
|
||||||
import { SETTINGS_FIELD_TYPE_CONFIGS } from '@/settings/data-model/constants/SettingsFieldTypeConfigs';
|
|
||||||
import {
|
import {
|
||||||
SettingsDataModelFieldCurrencyForm,
|
SettingsDataModelFieldCurrencyForm,
|
||||||
settingsDataModelFieldCurrencyFormSchema,
|
settingsDataModelFieldCurrencyFormSchema,
|
||||||
} from '@/settings/data-model/fields/forms/components/SettingsDataModelFieldCurrencyForm';
|
} from '@/settings/data-model/fields/forms/components/currency/SettingsDataModelFieldCurrencyForm';
|
||||||
import { SettingsDataModelFieldRelationSettingsFormCard } from '@/settings/data-model/fields/forms/components/SettingsDataModelFieldRelationSettingsFormCard';
|
import { settingsDataModelFieldRelationFormSchema } from '@/settings/data-model/fields/forms/components/relation/SettingsDataModelFieldRelationForm';
|
||||||
import { SettingsDataModelFieldSelectSettingsFormCard } from '@/settings/data-model/fields/forms/components/SettingsDataModelFieldSelectSettingsFormCard';
|
import { SettingsDataModelFieldRelationSettingsFormCard } from '@/settings/data-model/fields/forms/components/relation/SettingsDataModelFieldRelationSettingsFormCard';
|
||||||
|
import {
|
||||||
|
settingsDataModelFieldMultiSelectFormSchema,
|
||||||
|
settingsDataModelFieldSelectFormSchema,
|
||||||
|
} from '@/settings/data-model/fields/forms/components/select/SettingsDataModelFieldSelectForm';
|
||||||
|
import { SettingsDataModelFieldSelectSettingsFormCard } from '@/settings/data-model/fields/forms/components/select/SettingsDataModelFieldSelectSettingsFormCard';
|
||||||
import {
|
import {
|
||||||
SettingsDataModelFieldPreviewCard,
|
SettingsDataModelFieldPreviewCard,
|
||||||
SettingsDataModelFieldPreviewCardProps,
|
SettingsDataModelFieldPreviewCardProps,
|
||||||
|
|||||||
@ -1,3 +1,4 @@
|
|||||||
|
import { useEffect } from 'react';
|
||||||
import { Controller, useFormContext } from 'react-hook-form';
|
import { Controller, useFormContext } from 'react-hook-form';
|
||||||
import styled from '@emotion/styled';
|
import styled from '@emotion/styled';
|
||||||
import { IconCheck, IconX } from 'twenty-ui';
|
import { IconCheck, IconX } from 'twenty-ui';
|
||||||
@ -8,8 +9,6 @@ import { Select } from '@/ui/input/components/Select';
|
|||||||
import { CardContent } from '@/ui/layout/card/components/CardContent';
|
import { CardContent } from '@/ui/layout/card/components/CardContent';
|
||||||
import { isDefined } from '~/utils/isDefined';
|
import { isDefined } from '~/utils/isDefined';
|
||||||
|
|
||||||
// TODO: rename to SettingsDataModelFieldBooleanForm and move to settings/data-model/fields/forms/components
|
|
||||||
|
|
||||||
export const settingsDataModelFieldBooleanFormSchema = z.object({
|
export const settingsDataModelFieldBooleanFormSchema = z.object({
|
||||||
defaultValue: z.boolean(),
|
defaultValue: z.boolean(),
|
||||||
});
|
});
|
||||||
@ -33,18 +32,23 @@ const StyledLabel = styled.span`
|
|||||||
font-size: ${({ theme }) => theme.font.size.xs};
|
font-size: ${({ theme }) => theme.font.size.xs};
|
||||||
font-weight: ${({ theme }) => theme.font.weight.semiBold};
|
font-weight: ${({ theme }) => theme.font.weight.semiBold};
|
||||||
margin-bottom: 6px;
|
margin-bottom: 6px;
|
||||||
margin-top: ${({ theme }) => theme.spacing(1)};
|
|
||||||
`;
|
`;
|
||||||
|
|
||||||
export const SettingsDataModelFieldBooleanForm = ({
|
export const SettingsDataModelFieldBooleanForm = ({
|
||||||
className,
|
className,
|
||||||
fieldMetadataItem,
|
fieldMetadataItem,
|
||||||
}: SettingsDataModelFieldBooleanFormProps) => {
|
}: SettingsDataModelFieldBooleanFormProps) => {
|
||||||
const { control } = useFormContext<SettingsDataModelFieldBooleanFormValues>();
|
const { control, resetField } =
|
||||||
|
useFormContext<SettingsDataModelFieldBooleanFormValues>();
|
||||||
|
|
||||||
const isEditMode = isDefined(fieldMetadataItem?.defaultValue);
|
const isEditMode = isDefined(fieldMetadataItem?.defaultValue);
|
||||||
const initialValue = fieldMetadataItem?.defaultValue ?? true;
|
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]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<StyledContainer>
|
<StyledContainer>
|
||||||
<StyledLabel>Default Value</StyledLabel>
|
<StyledLabel>Default Value</StyledLabel>
|
||||||
@ -1,3 +1,4 @@
|
|||||||
|
import { useEffect } from 'react';
|
||||||
import { Controller, useFormContext } from 'react-hook-form';
|
import { Controller, useFormContext } from 'react-hook-form';
|
||||||
import { z } from 'zod';
|
import { z } from 'zod';
|
||||||
|
|
||||||
@ -13,6 +14,7 @@ import { simpleQuotesStringSchema } from '~/utils/validation-schemas/simpleQuote
|
|||||||
|
|
||||||
export const settingsDataModelFieldCurrencyFormSchema = z.object({
|
export const settingsDataModelFieldCurrencyFormSchema = z.object({
|
||||||
defaultValue: z.object({
|
defaultValue: z.object({
|
||||||
|
amountMicros: z.null(),
|
||||||
currencyCode: simpleQuotesStringSchema.refine(
|
currencyCode: simpleQuotesStringSchema.refine(
|
||||||
(value) =>
|
(value) =>
|
||||||
currencyCodeSchema.safeParse(stripSimpleQuotesFromString(value))
|
currencyCodeSchema.safeParse(stripSimpleQuotesFromString(value))
|
||||||
@ -43,19 +45,38 @@ export const SettingsDataModelFieldCurrencyForm = ({
|
|||||||
disabled,
|
disabled,
|
||||||
fieldMetadataItem,
|
fieldMetadataItem,
|
||||||
}: SettingsDataModelFieldCurrencyFormProps) => {
|
}: SettingsDataModelFieldCurrencyFormProps) => {
|
||||||
const { control } =
|
const { control, resetField } =
|
||||||
useFormContext<SettingsDataModelFieldCurrencyFormValues>();
|
useFormContext<SettingsDataModelFieldCurrencyFormValues>();
|
||||||
|
|
||||||
const initialValue =
|
const initialAmountMicrosValue = null;
|
||||||
|
const initialCurrencyCode =
|
||||||
(fieldMetadataItem?.defaultValue?.currencyCode as CurrencyCode) ??
|
(fieldMetadataItem?.defaultValue?.currencyCode as CurrencyCode) ??
|
||||||
CurrencyCode.USD;
|
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]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<CardContent>
|
<CardContent>
|
||||||
|
<Controller
|
||||||
|
name="defaultValue.amountMicros"
|
||||||
|
control={control}
|
||||||
|
defaultValue={initialAmountMicrosValue}
|
||||||
|
render={() => <></>}
|
||||||
|
/>
|
||||||
<Controller
|
<Controller
|
||||||
name="defaultValue.currencyCode"
|
name="defaultValue.currencyCode"
|
||||||
control={control}
|
control={control}
|
||||||
defaultValue={applySimpleQuotesToString(initialValue)}
|
defaultValue={initialCurrencyCodeValue}
|
||||||
render={({ field: { onChange, value } }) => (
|
render={({ field: { onChange, value } }) => (
|
||||||
<Select
|
<Select
|
||||||
fullWidth
|
fullWidth
|
||||||
@ -7,16 +7,13 @@ import { useFilteredObjectMetadataItems } from '@/object-metadata/hooks/useFilte
|
|||||||
import { FieldMetadataItem } from '@/object-metadata/types/FieldMetadataItem';
|
import { FieldMetadataItem } from '@/object-metadata/types/FieldMetadataItem';
|
||||||
import { isObjectMetadataAvailableForRelation } from '@/object-metadata/utils/isObjectMetadataAvailableForRelation';
|
import { isObjectMetadataAvailableForRelation } from '@/object-metadata/utils/isObjectMetadataAvailableForRelation';
|
||||||
import { fieldMetadataItemSchema } from '@/object-metadata/validation-schemas/fieldMetadataItemSchema';
|
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/hooks/useRelationSettingsFormInitialValues';
|
||||||
|
import { RelationType } from '@/settings/data-model/types/RelationType';
|
||||||
import { IconPicker } from '@/ui/input/components/IconPicker';
|
import { IconPicker } from '@/ui/input/components/IconPicker';
|
||||||
import { Select } from '@/ui/input/components/Select';
|
import { Select } from '@/ui/input/components/Select';
|
||||||
import { TextInput } from '@/ui/input/components/TextInput';
|
import { TextInput } from '@/ui/input/components/TextInput';
|
||||||
|
|
||||||
import { RELATION_TYPES } from '../constants/RelationTypes';
|
|
||||||
import { RelationType } from '../types/RelationType';
|
|
||||||
|
|
||||||
// TODO: rename to SettingsDataModelFieldRelationForm and move to settings/data-model/fields/forms/components
|
|
||||||
|
|
||||||
export const settingsDataModelFieldRelationFormSchema = z.object({
|
export const settingsDataModelFieldRelationFormSchema = z.object({
|
||||||
relation: z.object({
|
relation: z.object({
|
||||||
field: fieldMetadataItemSchema.pick({
|
field: fieldMetadataItemSchema.pick({
|
||||||
@ -4,11 +4,11 @@ import styled from '@emotion/styled';
|
|||||||
import { useFilteredObjectMetadataItems } from '@/object-metadata/hooks/useFilteredObjectMetadataItems';
|
import { useFilteredObjectMetadataItems } from '@/object-metadata/hooks/useFilteredObjectMetadataItems';
|
||||||
import { FieldMetadataItem } from '@/object-metadata/types/FieldMetadataItem';
|
import { FieldMetadataItem } from '@/object-metadata/types/FieldMetadataItem';
|
||||||
import { SettingsDataModelPreviewFormCard } from '@/settings/data-model/components/SettingsDataModelPreviewFormCard';
|
import { SettingsDataModelPreviewFormCard } from '@/settings/data-model/components/SettingsDataModelPreviewFormCard';
|
||||||
|
import { RELATION_TYPES } from '@/settings/data-model/constants/RelationTypes';
|
||||||
import {
|
import {
|
||||||
SettingsDataModelFieldRelationForm,
|
SettingsDataModelFieldRelationForm,
|
||||||
SettingsDataModelFieldRelationFormValues,
|
SettingsDataModelFieldRelationFormValues,
|
||||||
} from '@/settings/data-model/components/SettingsObjectFieldRelationForm';
|
} from '@/settings/data-model/fields/forms/components/relation/SettingsDataModelFieldRelationForm';
|
||||||
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/hooks/useRelationSettingsFormInitialValues';
|
||||||
import {
|
import {
|
||||||
SettingsDataModelFieldPreviewCard,
|
SettingsDataModelFieldPreviewCard,
|
||||||
@ -1,3 +1,4 @@
|
|||||||
|
import { useEffect } from 'react';
|
||||||
import { Controller, useFormContext } from 'react-hook-form';
|
import { Controller, useFormContext } from 'react-hook-form';
|
||||||
import styled from '@emotion/styled';
|
import styled from '@emotion/styled';
|
||||||
import { DropResult } from '@hello-pangea/dnd';
|
import { DropResult } from '@hello-pangea/dnd';
|
||||||
@ -23,9 +24,7 @@ import { toSpliced } from '~/utils/array/toSpliced';
|
|||||||
import { applySimpleQuotesToString } from '~/utils/string/applySimpleQuotesToString';
|
import { applySimpleQuotesToString } from '~/utils/string/applySimpleQuotesToString';
|
||||||
import { simpleQuotesStringSchema } from '~/utils/validation-schemas/simpleQuotesStringSchema';
|
import { simpleQuotesStringSchema } from '~/utils/validation-schemas/simpleQuotesStringSchema';
|
||||||
|
|
||||||
import { SettingsObjectFieldSelectFormOptionRow } from './SettingsObjectFieldSelectFormOptionRow';
|
import { SettingsDataModelFieldSelectFormOptionRow } from './SettingsDataModelFieldSelectFormOptionRow';
|
||||||
|
|
||||||
// TODO: rename to SettingsDataModelFieldSelectForm and move to settings/data-model/fields/forms/components
|
|
||||||
|
|
||||||
export const settingsDataModelFieldSelectFormSchema = z.object({
|
export const settingsDataModelFieldSelectFormSchema = z.object({
|
||||||
defaultValue: simpleQuotesStringSchema.nullable(),
|
defaultValue: simpleQuotesStringSchema.nullable(),
|
||||||
@ -87,6 +86,7 @@ export const SettingsDataModelFieldSelectForm = ({
|
|||||||
setValue: setFormValue,
|
setValue: setFormValue,
|
||||||
watch: watchFormValue,
|
watch: watchFormValue,
|
||||||
getValues,
|
getValues,
|
||||||
|
resetField,
|
||||||
} = useFormContext<SettingsDataModelFieldSelectFormValues>();
|
} = useFormContext<SettingsDataModelFieldSelectFormValues>();
|
||||||
|
|
||||||
const handleDragEnd = (
|
const handleDragEnd = (
|
||||||
@ -168,6 +168,11 @@ 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 (
|
return (
|
||||||
<>
|
<>
|
||||||
<Controller
|
<Controller
|
||||||
@ -195,7 +200,7 @@ export const SettingsDataModelFieldSelectForm = ({
|
|||||||
index={index}
|
index={index}
|
||||||
isDragDisabled={options.length === 1}
|
isDragDisabled={options.length === 1}
|
||||||
itemComponent={
|
itemComponent={
|
||||||
<SettingsObjectFieldSelectFormOptionRow
|
<SettingsDataModelFieldSelectFormOptionRow
|
||||||
key={option.id}
|
key={option.id}
|
||||||
option={option}
|
option={option}
|
||||||
onChange={(nextOption) => {
|
onChange={(nextOption) => {
|
||||||
@ -23,7 +23,7 @@ import { MenuItem } from '@/ui/navigation/menu-item/components/MenuItem';
|
|||||||
import { MenuItemSelectColor } from '@/ui/navigation/menu-item/components/MenuItemSelectColor';
|
import { MenuItemSelectColor } from '@/ui/navigation/menu-item/components/MenuItemSelectColor';
|
||||||
import { MAIN_COLOR_NAMES } from '@/ui/theme/constants/MainColorNames';
|
import { MAIN_COLOR_NAMES } from '@/ui/theme/constants/MainColorNames';
|
||||||
|
|
||||||
type SettingsObjectFieldSelectFormOptionRowProps = {
|
type SettingsDataModelFieldSelectFormOptionRowProps = {
|
||||||
className?: string;
|
className?: string;
|
||||||
isDefault?: boolean;
|
isDefault?: boolean;
|
||||||
onChange: (value: FieldMetadataItemOption) => void;
|
onChange: (value: FieldMetadataItemOption) => void;
|
||||||
@ -55,7 +55,7 @@ const StyledOptionInput = styled(TextInput)`
|
|||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
export const SettingsObjectFieldSelectFormOptionRow = ({
|
export const SettingsDataModelFieldSelectFormOptionRow = ({
|
||||||
className,
|
className,
|
||||||
isDefault,
|
isDefault,
|
||||||
onChange,
|
onChange,
|
||||||
@ -63,7 +63,7 @@ export const SettingsObjectFieldSelectFormOptionRow = ({
|
|||||||
onSetAsDefault,
|
onSetAsDefault,
|
||||||
onRemoveAsDefault,
|
onRemoveAsDefault,
|
||||||
option,
|
option,
|
||||||
}: SettingsObjectFieldSelectFormOptionRowProps) => {
|
}: SettingsDataModelFieldSelectFormOptionRowProps) => {
|
||||||
const theme = useTheme();
|
const theme = useTheme();
|
||||||
|
|
||||||
const dropdownIds = useMemo(() => {
|
const dropdownIds = useMemo(() => {
|
||||||
@ -8,7 +8,7 @@ import {
|
|||||||
settingsDataModelFieldMultiSelectFormSchema,
|
settingsDataModelFieldMultiSelectFormSchema,
|
||||||
SettingsDataModelFieldSelectForm,
|
SettingsDataModelFieldSelectForm,
|
||||||
settingsDataModelFieldSelectFormSchema,
|
settingsDataModelFieldSelectFormSchema,
|
||||||
} from '@/settings/data-model/components/SettingsObjectFieldSelectForm';
|
} from '@/settings/data-model/fields/forms/components/select/SettingsDataModelFieldSelectForm';
|
||||||
import { useSelectSettingsFormInitialValues } from '@/settings/data-model/fields/forms/hooks/useSelectSettingsFormInitialValues';
|
import { useSelectSettingsFormInitialValues } from '@/settings/data-model/fields/forms/hooks/useSelectSettingsFormInitialValues';
|
||||||
import {
|
import {
|
||||||
SettingsDataModelFieldPreviewCard,
|
SettingsDataModelFieldPreviewCard,
|
||||||
@ -1,3 +1,5 @@
|
|||||||
|
import { isString } from '@sniptt/guards';
|
||||||
|
|
||||||
import { FieldMetadataItem } from '@/object-metadata/types/FieldMetadataItem';
|
import { FieldMetadataItem } from '@/object-metadata/types/FieldMetadataItem';
|
||||||
import { ObjectMetadataItem } from '@/object-metadata/types/ObjectMetadataItem';
|
import { ObjectMetadataItem } from '@/object-metadata/types/ObjectMetadataItem';
|
||||||
import { getLabelIdentifierFieldMetadataItem } from '@/object-metadata/utils/getLabelIdentifierFieldMetadataItem';
|
import { getLabelIdentifierFieldMetadataItem } from '@/object-metadata/utils/getLabelIdentifierFieldMetadataItem';
|
||||||
@ -23,17 +25,18 @@ export const getFieldDefaultPreviewValue = ({
|
|||||||
relationObjectMetadataItem?: ObjectMetadataItem;
|
relationObjectMetadataItem?: ObjectMetadataItem;
|
||||||
}) => {
|
}) => {
|
||||||
if (fieldMetadataItem.type === FieldMetadataType.Select) {
|
if (fieldMetadataItem.type === FieldMetadataType.Select) {
|
||||||
const defaultValue = fieldMetadataItem.defaultValue
|
const defaultValue = isString(fieldMetadataItem.defaultValue)
|
||||||
? stripSimpleQuotesFromString(fieldMetadataItem.defaultValue)
|
? stripSimpleQuotesFromString(fieldMetadataItem.defaultValue)
|
||||||
: null;
|
: null;
|
||||||
return defaultValue ?? fieldMetadataItem.options?.[0]?.value ?? null;
|
return defaultValue ?? fieldMetadataItem.options?.[0]?.value ?? null;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fieldMetadataItem.type === FieldMetadataType.MultiSelect) {
|
if (fieldMetadataItem.type === FieldMetadataType.MultiSelect) {
|
||||||
const defaultValues = fieldMetadataItem.defaultValue?.map(
|
const defaultValues = Array.isArray(fieldMetadataItem.defaultValue)
|
||||||
(defaultValue: `'${string}'`) =>
|
? fieldMetadataItem.defaultValue?.map((defaultValue: `'${string}'`) =>
|
||||||
stripSimpleQuotesFromString(defaultValue),
|
stripSimpleQuotesFromString(defaultValue),
|
||||||
);
|
)
|
||||||
|
: null;
|
||||||
return defaultValues?.length
|
return defaultValues?.length
|
||||||
? defaultValues
|
? defaultValues
|
||||||
: fieldMetadataItem.options?.map(({ value }) => value) ?? null;
|
: fieldMetadataItem.options?.map(({ value }) => value) ?? null;
|
||||||
|
|||||||
Reference in New Issue
Block a user