From 1eb5bebaf7d1c045407d2396bdf6ac855b25fc58 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tha=C3=AFs?= Date: Fri, 15 Dec 2023 11:01:06 +0100 Subject: [PATCH] feat: select default Unit for Currency field (#2996) Closes #2347 Co-authored-by: Thais GUIGON --- .../hooks/useFieldMetadataItem.ts | 2 + .../types/FieldMetadataItem.ts | 2 +- .../meta-types/hooks/useCurrencyField.ts | 9 ++-- .../object-record/field/types/CurrencyCode.ts | 10 ++++ .../field/types/FieldMetadata.ts | 4 +- .../types/guards/isFieldCurrencyValue.ts | 3 +- .../SettingsObjectFieldCurrencyForm.tsx | 39 +++++++++++++++ .../SettingsObjectFieldTypeSelectSection.tsx | 20 +++++++- .../constants/settingsFieldCurrencyCodes.ts | 48 +++++++++++++++++++ .../constants/settingsFieldMetadataTypes.ts | 3 +- .../data-model/hooks/useFieldMetadataForm.ts | 37 +++++++++++--- .../src/modules/ui/display/icon/index.ts | 5 ++ .../modules/ui/input/components/Select.tsx | 5 +- .../data-model/SettingsObjectFieldEdit.tsx | 13 ++++- .../SettingsObjectNewFieldStep2.tsx | 8 ++++ 15 files changed, 190 insertions(+), 18 deletions(-) create mode 100644 packages/twenty-front/src/modules/object-record/field/types/CurrencyCode.ts create mode 100644 packages/twenty-front/src/modules/settings/data-model/components/SettingsObjectFieldCurrencyForm.tsx create mode 100644 packages/twenty-front/src/modules/settings/data-model/constants/settingsFieldCurrencyCodes.ts diff --git a/packages/twenty-front/src/modules/object-metadata/hooks/useFieldMetadataItem.ts b/packages/twenty-front/src/modules/object-metadata/hooks/useFieldMetadataItem.ts index 7aacb031f..34f94996f 100644 --- a/packages/twenty-front/src/modules/object-metadata/hooks/useFieldMetadataItem.ts +++ b/packages/twenty-front/src/modules/object-metadata/hooks/useFieldMetadataItem.ts @@ -19,6 +19,7 @@ export const useFieldMetadataItem = () => { const createMetadataField = ( input: Pick & { + defaultValue?: unknown; objectMetadataId: string; options?: Omit[]; type: FieldMetadataType; @@ -26,6 +27,7 @@ export const useFieldMetadataItem = () => { ) => createOneFieldMetadataItem({ ...formatFieldMetadataItemInput(input), + defaultValue: input.defaultValue, objectMetadataId: input.objectMetadataId, type: input.type as FieldType, }); diff --git a/packages/twenty-front/src/modules/object-metadata/types/FieldMetadataItem.ts b/packages/twenty-front/src/modules/object-metadata/types/FieldMetadataItem.ts index f03050981..2116e008f 100644 --- a/packages/twenty-front/src/modules/object-metadata/types/FieldMetadataItem.ts +++ b/packages/twenty-front/src/modules/object-metadata/types/FieldMetadataItem.ts @@ -21,7 +21,7 @@ export type FieldMetadataItem = Omit< >; }) | null; - defaultValue?: string; + defaultValue?: unknown; options?: { color: ThemeColor; id: string; diff --git a/packages/twenty-front/src/modules/object-record/field/meta-types/hooks/useCurrencyField.ts b/packages/twenty-front/src/modules/object-record/field/meta-types/hooks/useCurrencyField.ts index 753339e3d..fcc942c8b 100644 --- a/packages/twenty-front/src/modules/object-record/field/meta-types/hooks/useCurrencyField.ts +++ b/packages/twenty-front/src/modules/object-record/field/meta-types/hooks/useCurrencyField.ts @@ -1,6 +1,7 @@ import { useContext } from 'react'; import { useRecoilState } from 'recoil'; +import { CurrencyCode } from '@/object-record/field/types/CurrencyCode'; import { FieldInitialValue } from '@/object-record/field/types/FieldInitialValue'; import { canBeCastAsIntegerOrNull } from '~/utils/cast-as-integer-or-null'; import { @@ -22,17 +23,17 @@ const initializeValue = ( fieldValue: FieldCurrencyValue, ) => { if (fieldInitialValue?.isEmpty) { - return { amount: null, currencyCode: 'USD' }; + return { amount: null, currencyCode: CurrencyCode.USD }; } if (!isNaN(Number(fieldInitialValue?.value))) { return { amount: Number(fieldInitialValue?.value), - currencyCode: 'USD', + currencyCode: CurrencyCode.USD, }; } if (!fieldValue) { - return { amount: null, currencyCode: 'USD' }; + return { amount: null, currencyCode: CurrencyCode.USD }; } return { @@ -73,7 +74,7 @@ export const useCurrencyField = () => { amountMicros: isNaN(amount) ? null : convertCurrencyToCurrencyMicros(amount), - currencyCode: currencyCode, + currencyCode, }; if (!isFieldCurrencyValue(newCurrencyValue)) { diff --git a/packages/twenty-front/src/modules/object-record/field/types/CurrencyCode.ts b/packages/twenty-front/src/modules/object-record/field/types/CurrencyCode.ts new file mode 100644 index 000000000..89afeca90 --- /dev/null +++ b/packages/twenty-front/src/modules/object-record/field/types/CurrencyCode.ts @@ -0,0 +1,10 @@ +export enum CurrencyCode { + CAD = 'CAD', + CHF = 'CHF', + CNY = 'CNY', + EUR = 'EUR', + GBP = 'GBP', + HKD = 'HKD', + JPY = 'JPY', + USD = 'USD', +} diff --git a/packages/twenty-front/src/modules/object-record/field/types/FieldMetadata.ts b/packages/twenty-front/src/modules/object-record/field/types/FieldMetadata.ts index 0d70c3b97..f752ab825 100644 --- a/packages/twenty-front/src/modules/object-record/field/types/FieldMetadata.ts +++ b/packages/twenty-front/src/modules/object-record/field/types/FieldMetadata.ts @@ -1,6 +1,8 @@ import { EntityForSelect } from '@/object-record/relation-picker/types/EntityForSelect'; import { ThemeColor } from '@/ui/theme/constants/colors'; +import { CurrencyCode } from './CurrencyCode'; + export type FieldUuidMetadata = { objectMetadataNameSingular?: string; fieldName: string; @@ -111,7 +113,7 @@ export type FieldPhoneValue = string; export type FieldEmailValue = string; export type FieldLinkValue = { url: string; label: string }; export type FieldCurrencyValue = { - currencyCode: string; + currencyCode: CurrencyCode; amountMicros: number | null; }; export type FieldFullNameValue = { firstName: string; lastName: string }; diff --git a/packages/twenty-front/src/modules/object-record/field/types/guards/isFieldCurrencyValue.ts b/packages/twenty-front/src/modules/object-record/field/types/guards/isFieldCurrencyValue.ts index e46ab93d3..edabc36e0 100644 --- a/packages/twenty-front/src/modules/object-record/field/types/guards/isFieldCurrencyValue.ts +++ b/packages/twenty-front/src/modules/object-record/field/types/guards/isFieldCurrencyValue.ts @@ -1,9 +1,10 @@ import { z } from 'zod'; +import { CurrencyCode } from '../CurrencyCode'; import { FieldCurrencyValue } from '../FieldMetadata'; const currencySchema = z.object({ - currencyCode: z.string().nullable(), + currencyCode: z.nativeEnum(CurrencyCode).nullable(), amountMicros: z.number().nullable(), }); diff --git a/packages/twenty-front/src/modules/settings/data-model/components/SettingsObjectFieldCurrencyForm.tsx b/packages/twenty-front/src/modules/settings/data-model/components/SettingsObjectFieldCurrencyForm.tsx new file mode 100644 index 000000000..2b2f5ee91 --- /dev/null +++ b/packages/twenty-front/src/modules/settings/data-model/components/SettingsObjectFieldCurrencyForm.tsx @@ -0,0 +1,39 @@ +import { CurrencyCode } from '@/object-record/field/types/CurrencyCode'; +import { Select } from '@/ui/input/components/Select'; +import { CardContent } from '@/ui/layout/card/components/CardContent'; + +import { settingsFieldCurrencyCodes } from '../constants/settingsFieldCurrencyCodes'; + +export type SettingsObjectFieldCurrencyFormValues = { + currencyCode: CurrencyCode; +}; + +type SettingsObjectFieldCurrencyFormProps = { + disabled?: boolean; + onChange: (values: Partial) => void; + values: SettingsObjectFieldCurrencyFormValues; +}; + +export const SettingsObjectFieldCurrencyForm = ({ + disabled, + onChange, + values, +}: SettingsObjectFieldCurrencyFormProps) => ( + +