Set back amount micros (#17124)

The amount to amount micros in UI breaks variable. Setting back amount
micros in UI with a hint

<img width="399" height="178" alt="Capture d’écran 2026-01-13 à 15 54
04"
src="https://github.com/user-attachments/assets/52f53a78-05a8-421d-80fe-f5cd0e8aad19"
/>
This commit is contained in:
Thomas Trompette
2026-01-14 14:18:28 +01:00
committed by GitHub
parent 245bd510ae
commit ef8d7c18c1
65 changed files with 281 additions and 309 deletions
@@ -1,4 +1,3 @@
import { t } from '@lingui/core/macro';
import { FormFieldInputContainer } from '@/object-record/record-field/ui/form-types/components/FormFieldInputContainer';
import { FormNestedFieldInputContainer } from '@/object-record/record-field/ui/form-types/components/FormNestedFieldInputContainer';
import { FormNumberFieldInput } from '@/object-record/record-field/ui/form-types/components/FormNumberFieldInput';
@@ -7,37 +6,10 @@ import { type VariablePickerComponent } from '@/object-record/record-field/ui/fo
import { type FormFieldCurrencyValue } from '@/object-record/record-field/ui/types/FieldMetadata';
import { CURRENCIES } from '@/settings/data-model/constants/Currencies';
import { InputLabel } from '@/ui/input/components/InputLabel';
import { t } from '@lingui/core/macro';
import { useMemo } from 'react';
import { type CurrencyCode } from 'twenty-shared/constants';
import { IconCircleOff } from 'twenty-ui/display';
import {
convertCurrencyAmountToCurrencyMicros,
convertCurrencyMicrosToCurrencyAmount,
} from '~/utils/convertCurrencyToCurrencyMicros';
const formatMicrosToDisplayAmount = (
amountMicros: string | number | null | undefined,
): string | number => {
if (amountMicros == null) {
return '';
}
if (Number.isFinite(+amountMicros)) {
return convertCurrencyMicrosToCurrencyAmount(+amountMicros);
}
return amountMicros;
};
const parseDisplayAmountToMicros = (
displayAmount: string | number | null,
): number | null => {
if (displayAmount == null) {
return null;
}
if (Number.isFinite(+displayAmount)) {
return convertCurrencyAmountToCurrencyMicros(Number(displayAmount));
}
return null;
};
type FormCurrencyFieldInputProps = {
label?: string;
@@ -70,7 +42,7 @@ export const FormCurrencyFieldInput = ({
) => {
onChange({
currencyCode: defaultValue?.currencyCode ?? null,
amountMicros: parseDisplayAmountToMicros(newAmountMicros),
amountMicros: newAmountMicros,
});
};
@@ -94,11 +66,11 @@ export const FormCurrencyFieldInput = ({
readonly={readonly}
/>
<FormNumberFieldInput
label={t`Amount`}
defaultValue={formatMicrosToDisplayAmount(defaultValue?.amountMicros)}
label={t`Amount Micros`}
defaultValue={defaultValue?.amountMicros ?? ''}
onChange={handleAmountMicrosChange}
VariablePicker={VariablePicker}
placeholder={t`Set 3.21 for $3.21`}
hint={t`Enter amount x 1 000 000 (e.g. $3.21 → 3210000)`}
readonly={readonly}
/>
</FormNestedFieldInputContainer>
@@ -32,7 +32,7 @@ export const Default: Story = {
play: async ({ canvasElement }) => {
const canvas = within(canvasElement);
await canvas.findByText('Currency Code');
await canvas.findByText('Amount');
await canvas.findByText('Amount Micros');
},
};
@@ -47,10 +47,10 @@ export const WithVariable: Story = {
play: async ({ canvasElement }) => {
const canvas = within(canvasElement);
const amountMicros = await canvas.findByText('Amount Micros');
const amountMicros = await canvas.findAllByText('Amount Micros');
const currencyCode = await canvas.findAllByText('Currency Code');
expect(amountMicros).toBeVisible();
expect(amountMicros).toHaveLength(2);
expect(currencyCode).toHaveLength(2);
},
};
@@ -81,7 +81,7 @@ export const Disabled: Story = {
const currency = await canvas.findByText(/USD/);
expect(currency).toBeVisible();
const amountInput = await canvas.findByDisplayValue('44');
const amountInput = await canvas.findByDisplayValue('44000000');
expect(amountInput).toBeVisible();
expect(amountInput).toBeDisabled();