Add Currency form field (#9389)
This commit is contained in:
@ -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 { 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 { 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 {
|
||||||
@ -22,6 +23,7 @@ import {
|
|||||||
FieldMetadata,
|
FieldMetadata,
|
||||||
FieldMultiSelectValue,
|
FieldMultiSelectValue,
|
||||||
FieldPhonesValue,
|
FieldPhonesValue,
|
||||||
|
FormFieldCurrencyValue,
|
||||||
} from '@/object-record/record-field/types/FieldMetadata';
|
} from '@/object-record/record-field/types/FieldMetadata';
|
||||||
import { isFieldAddress } from '@/object-record/record-field/types/guards/isFieldAddress';
|
import { isFieldAddress } from '@/object-record/record-field/types/guards/isFieldAddress';
|
||||||
import { isFieldBoolean } from '@/object-record/record-field/types/guards/isFieldBoolean';
|
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 { 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';
|
||||||
|
|
||||||
type FormFieldInputProps = {
|
type FormFieldInputProps = {
|
||||||
@ -157,5 +160,12 @@ export const FormFieldInput = ({
|
|||||||
placeholder={field.label}
|
placeholder={field.label}
|
||||||
VariablePicker={VariablePicker}
|
VariablePicker={VariablePicker}
|
||||||
/>
|
/>
|
||||||
|
) : isFieldCurrency(field) ? (
|
||||||
|
<FormCurrencyFieldInput
|
||||||
|
label={field.label}
|
||||||
|
defaultValue={defaultValue as FormFieldCurrencyValue | null}
|
||||||
|
onPersist={onPersist}
|
||||||
|
VariablePicker={VariablePicker}
|
||||||
|
/>
|
||||||
) : null;
|
) : null;
|
||||||
};
|
};
|
||||||
|
|||||||
@ -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 (
|
||||||
|
<FormFieldInputContainer>
|
||||||
|
{label ? <InputLabel>{label}</InputLabel> : null}
|
||||||
|
<FormNestedFieldInputContainer>
|
||||||
|
<FormSelectFieldInput
|
||||||
|
label="Currency Code"
|
||||||
|
defaultValue={defaultValue?.currencyCode ?? ''}
|
||||||
|
onPersist={handleCurrencyCodeChange}
|
||||||
|
options={currencies}
|
||||||
|
clearLabel={'Currency Code'}
|
||||||
|
VariablePicker={VariablePicker}
|
||||||
|
/>
|
||||||
|
<FormNumberFieldInput
|
||||||
|
label="Amount Micros"
|
||||||
|
defaultValue={defaultValue?.amountMicros ?? ''}
|
||||||
|
onPersist={handleAmountMicrosChange}
|
||||||
|
VariablePicker={VariablePicker}
|
||||||
|
placeholder="Set 3210000 for 3.21$"
|
||||||
|
/>
|
||||||
|
</FormNestedFieldInputContainer>
|
||||||
|
</FormFieldInputContainer>
|
||||||
|
);
|
||||||
|
};
|
||||||
@ -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<typeof FormCurrencyFieldInput> = {
|
||||||
|
title: 'UI/Data/Field/Form/Input/FormCurrencyFieldInput',
|
||||||
|
component: FormCurrencyFieldInput,
|
||||||
|
args: {},
|
||||||
|
argTypes: {},
|
||||||
|
};
|
||||||
|
|
||||||
|
export default meta;
|
||||||
|
|
||||||
|
type Story = StoryObj<typeof FormCurrencyFieldInput>;
|
||||||
|
|
||||||
|
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');
|
||||||
|
},
|
||||||
|
};
|
||||||
@ -232,6 +232,10 @@ export type FieldCurrencyValue = {
|
|||||||
currencyCode: CurrencyCode;
|
currencyCode: CurrencyCode;
|
||||||
amountMicros: number | null;
|
amountMicros: number | null;
|
||||||
};
|
};
|
||||||
|
export type FormFieldCurrencyValue = {
|
||||||
|
currencyCode: CurrencyCode | null;
|
||||||
|
amountMicros: number | string | null;
|
||||||
|
};
|
||||||
export type FieldFullNameValue = { firstName: string; lastName: string };
|
export type FieldFullNameValue = { firstName: string; lastName: string };
|
||||||
export type FieldAddressValue = {
|
export type FieldAddressValue = {
|
||||||
addressStreet1: string;
|
addressStreet1: string;
|
||||||
|
|||||||
Reference in New Issue
Block a user