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 1b38f7016..da67d9c74 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 @@ -12,6 +12,7 @@ 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 { 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 { @@ -22,6 +23,7 @@ import { FieldMetadata, FieldMultiSelectValue, FieldPhonesValue, + FormFieldCurrencyValue, } from '@/object-record/record-field/types/FieldMetadata'; import { isFieldAddress } from '@/object-record/record-field/types/guards/isFieldAddress'; import { isFieldBoolean } from '@/object-record/record-field/types/guards/isFieldBoolean'; @@ -37,6 +39,7 @@ 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'; type FormFieldInputProps = { @@ -157,5 +160,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 000000000..ccd93ff6d --- /dev/null +++ b/packages/twenty-front/src/modules/object-record/record-field/form-types/components/FormCurrencyFieldInput.tsx @@ -0,0 +1,73 @@ +import { useMemo } from 'react'; +import { CurrencyCode } from '@/object-record/record-field/types/CurrencyCode'; +import { FormFieldCurrencyValue } 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'; + +type FormCurrencyFieldInputProps = { + label?: string; + defaultValue?: FormFieldCurrencyValue | null; + onPersist: (value: FormFieldCurrencyValue) => 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 = ( + newAmountMicros: string | number | null, + ) => { + onPersist({ + currencyCode: defaultValue?.currencyCode ?? null, + amountMicros: newAmountMicros ?? null, + }); + }; + + const handleCurrencyCodeChange = (newCurrencyCode: string | null) => { + onPersist({ + currencyCode: (newCurrencyCode as CurrencyCode) ?? null, + 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.stories.tsx b/packages/twenty-front/src/modules/object-record/record-field/form-types/components/__stories__/FormCurrencyFieldInput.stories.tsx new file mode 100644 index 000000000..d139f5aa0 --- /dev/null +++ b/packages/twenty-front/src/modules/object-record/record-field/form-types/components/__stories__/FormCurrencyFieldInput.stories.tsx @@ -0,0 +1,33 @@ +import { FormCurrencyFieldInput } from '../FormCurrencyFieldInput'; +import { Meta, StoryObj } from '@storybook/react'; +import { FieldCurrencyValue } from '@/object-record/record-field/types/FieldMetadata'; +import { CurrencyCode } from '@/object-record/record-field/types/CurrencyCode'; +import { within } from '@storybook/test'; + +const meta: Meta = { + title: 'UI/Data/Field/Form/Input/FormCurrencyFieldInput', + component: FormCurrencyFieldInput, + args: {}, + argTypes: {}, +}; + +export default meta; + +type Story = StoryObj; + +const defaultSalaryValue: FieldCurrencyValue = { + currencyCode: CurrencyCode.USD, + amountMicros: 44000000, +}; + +export const Default: Story = { + args: { + label: 'Salary', + defaultValue: defaultSalaryValue, + }, + play: async ({ canvasElement }) => { + const canvas = within(canvasElement); + await canvas.findByText('Currency Code'); + await canvas.findByText('Amount Micros'); + }, +}; diff --git a/packages/twenty-front/src/modules/object-record/record-field/types/FieldMetadata.ts b/packages/twenty-front/src/modules/object-record/record-field/types/FieldMetadata.ts index faca16b44..c04cca016 100644 --- a/packages/twenty-front/src/modules/object-record/record-field/types/FieldMetadata.ts +++ b/packages/twenty-front/src/modules/object-record/record-field/types/FieldMetadata.ts @@ -232,6 +232,10 @@ export type FieldCurrencyValue = { currencyCode: CurrencyCode; amountMicros: number | null; }; +export type FormFieldCurrencyValue = { + currencyCode: CurrencyCode | null; + amountMicros: number | string | null; +}; export type FieldFullNameValue = { firstName: string; lastName: string }; export type FieldAddressValue = { addressStreet1: string;