diff --git a/packages/twenty-front/src/modules/object-record/record-field/components/FormFieldInput.tsx b/packages/twenty-front/src/modules/object-record/record-field/components/FormFieldInput.tsx index bfa0a901c7..7e9b3dcd98 100644 --- a/packages/twenty-front/src/modules/object-record/record-field/components/FormFieldInput.tsx +++ b/packages/twenty-front/src/modules/object-record/record-field/components/FormFieldInput.tsx @@ -10,10 +10,13 @@ import { FormRawJsonFieldInput } from '@/object-record/record-field/form-types/c import { FormSelectFieldInput } from '@/object-record/record-field/form-types/components/FormSelectFieldInput'; import { FormTextFieldInput } from '@/object-record/record-field/form-types/components/FormTextFieldInput'; import { FormUuidFieldInput } from '@/object-record/record-field/form-types/components/FormUuidFieldInput'; +import { FormDateTimeFieldInput } from '@/object-record/record-field/form-types/components/FormDateTimeFieldInput'; +import { FormCurrencyFieldInput } from '@/object-record/record-field/form-types/components/FormCurrencyFieldInput'; import { VariablePickerComponent } from '@/object-record/record-field/form-types/types/VariablePickerComponent'; import { FieldDefinition } from '@/object-record/record-field/types/FieldDefinition'; import { FieldAddressValue, + FieldCurrencyValue, FieldEmailsValue, FieldFullNameValue, FieldLinksValue, @@ -33,8 +36,8 @@ import { isFieldRawJson } from '@/object-record/record-field/types/guards/isFiel import { isFieldSelect } from '@/object-record/record-field/types/guards/isFieldSelect'; import { isFieldText } from '@/object-record/record-field/types/guards/isFieldText'; import { isFieldUuid } from '@/object-record/record-field/types/guards/isFieldUuid'; +import { isFieldCurrency } from '@/object-record/record-field/types/guards/isFieldCurrency'; import { JsonValue } from 'type-fest'; -import { FormDateTimeFieldInput } from '@/object-record/record-field/form-types/components/FormDateTimeFieldInput'; type FormFieldInputProps = { field: FieldDefinition; @@ -147,5 +150,12 @@ export const FormFieldInput = ({ placeholder={field.label} VariablePicker={VariablePicker} /> + ) : isFieldCurrency(field) ? ( + ) : null; }; diff --git a/packages/twenty-front/src/modules/object-record/record-field/form-types/components/FormCurrencyFieldInput.tsx b/packages/twenty-front/src/modules/object-record/record-field/form-types/components/FormCurrencyFieldInput.tsx new file mode 100644 index 0000000000..5b867953f2 --- /dev/null +++ b/packages/twenty-front/src/modules/object-record/record-field/form-types/components/FormCurrencyFieldInput.tsx @@ -0,0 +1,82 @@ +import { useMemo } from 'react'; +import { isDefined } from 'twenty-ui'; +import { isString } from '@sniptt/guards'; +import { CurrencyCode } from '@/object-record/record-field/types/CurrencyCode'; +import { FieldCurrencyValue } from '@/object-record/record-field/types/FieldMetadata'; +import { VariablePickerComponent } from '@/object-record/record-field/form-types/types/VariablePickerComponent'; +import { FormFieldInputContainer } from '@/object-record/record-field/form-types/components/FormFieldInputContainer'; +import { InputLabel } from '@/ui/input/components/InputLabel'; +import { FormNestedFieldInputContainer } from '@/object-record/record-field/form-types/components/FormNestedFieldInputContainer'; +import { FormNumberFieldInput } from '@/object-record/record-field/form-types/components/FormNumberFieldInput'; +import { FormSelectFieldInput } from '@/object-record/record-field/form-types/components/FormSelectFieldInput'; +import { SETTINGS_FIELD_CURRENCY_CODES } from '@/settings/data-model/constants/SettingsFieldCurrencyCodes'; +import { convertCurrencyAmountToCurrencyMicros } from '~/utils/convertCurrencyToCurrencyMicros'; + +type FormCurrencyFieldInputProps = { + label?: string; + defaultValue?: FieldCurrencyValue | null; + onPersist: (value: FieldCurrencyValue) => void; + VariablePicker?: VariablePickerComponent; +}; + +export const FormCurrencyFieldInput = ({ + label, + defaultValue, + onPersist, + VariablePicker, +}: FormCurrencyFieldInputProps) => { + const currencies = useMemo(() => { + return Object.entries(SETTINGS_FIELD_CURRENCY_CODES).map( + ([key, { Icon, label }]) => ({ + value: key, + icon: Icon, + label: `${label} (${key})`, + }), + ); + }, []); + + const handleAmountMicrosChange = (newAmount: string | number | null) => { + const formattedAmount = isString(newAmount) + ? parseFloat(newAmount) + : (newAmount ?? null); + + const formattedAmountMicros = + !isDefined(formattedAmount) || isNaN(formattedAmount) + ? null + : convertCurrencyAmountToCurrencyMicros(formattedAmount); + onPersist({ + currencyCode: (defaultValue?.currencyCode ?? '') as CurrencyCode, + amountMicros: formattedAmountMicros, + }); + }; + + const handleCurrencyCodeChange = (newCurrencyCode: string | null) => { + onPersist({ + currencyCode: (newCurrencyCode ?? '') as CurrencyCode, + amountMicros: defaultValue?.amountMicros ?? null, + }); + }; + + return ( + + {label ? {label} : null} + + + + + + ); +}; diff --git a/packages/twenty-front/src/modules/object-record/record-field/form-types/components/__stories__/FormCurrencyFieldInput.story.tsx b/packages/twenty-front/src/modules/object-record/record-field/form-types/components/__stories__/FormCurrencyFieldInput.story.tsx new file mode 100644 index 0000000000..e69de29bb2