Add Currency form field

This commit is contained in:
martmull 2024-12-20 17:11:02 +01:00
parent 8ba995fbad
commit b43a885b8e
3 changed files with 93 additions and 1 deletions

View File

@ -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 { FormSelectFieldInput } from '@/object-record/record-field/form-types/components/FormSelectFieldInput';
import { FormTextFieldInput } from '@/object-record/record-field/form-types/components/FormTextFieldInput'; import { FormTextFieldInput } from '@/object-record/record-field/form-types/components/FormTextFieldInput';
import { FormUuidFieldInput } from '@/object-record/record-field/form-types/components/FormUuidFieldInput'; 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 { VariablePickerComponent } from '@/object-record/record-field/form-types/types/VariablePickerComponent';
import { FieldDefinition } from '@/object-record/record-field/types/FieldDefinition'; import { FieldDefinition } from '@/object-record/record-field/types/FieldDefinition';
import { import {
FieldAddressValue, FieldAddressValue,
FieldCurrencyValue,
FieldEmailsValue, FieldEmailsValue,
FieldFullNameValue, FieldFullNameValue,
FieldLinksValue, 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 { isFieldSelect } from '@/object-record/record-field/types/guards/isFieldSelect';
import { isFieldText } from '@/object-record/record-field/types/guards/isFieldText'; import { isFieldText } from '@/object-record/record-field/types/guards/isFieldText';
import { isFieldUuid } from '@/object-record/record-field/types/guards/isFieldUuid'; 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 { JsonValue } from 'type-fest';
import { FormDateTimeFieldInput } from '@/object-record/record-field/form-types/components/FormDateTimeFieldInput';
type FormFieldInputProps = { type FormFieldInputProps = {
field: FieldDefinition<FieldMetadata>; field: FieldDefinition<FieldMetadata>;
@ -147,5 +150,12 @@ export const FormFieldInput = ({
placeholder={field.label} placeholder={field.label}
VariablePicker={VariablePicker} VariablePicker={VariablePicker}
/> />
) : isFieldCurrency(field) ? (
<FormCurrencyFieldInput
label={field.label}
defaultValue={defaultValue as FieldCurrencyValue | null}
onPersist={onPersist}
VariablePicker={VariablePicker}
/>
) : null; ) : null;
}; };

View File

@ -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 (
<FormFieldInputContainer>
{label ? <InputLabel>{label}</InputLabel> : null}
<FormNestedFieldInputContainer>
<FormSelectFieldInput
label="Currency Code"
defaultValue={defaultValue?.currencyCode ?? ''}
onPersist={handleCurrencyCodeChange}
options={currencies}
clearLabel={label}
VariablePicker={VariablePicker}
/>
<FormNumberFieldInput
label="Amount Micros"
defaultValue={defaultValue?.amountMicros ?? ''}
onPersist={handleAmountMicrosChange}
VariablePicker={VariablePicker}
placeholder="Amount Micros"
/>
</FormNestedFieldInputContainer>
</FormFieldInputContainer>
);
};