diff --git a/packages/twenty-front/src/modules/object-record/record-field/ui/meta-types/input/components/CurrencyFieldInput.tsx b/packages/twenty-front/src/modules/object-record/record-field/ui/meta-types/input/components/CurrencyFieldInput.tsx index d3fee39eda..039ee6d5cd 100644 --- a/packages/twenty-front/src/modules/object-record/record-field/ui/meta-types/input/components/CurrencyFieldInput.tsx +++ b/packages/twenty-front/src/modules/object-record/record-field/ui/meta-types/input/components/CurrencyFieldInput.tsx @@ -54,7 +54,8 @@ export const CurrencyFieldInput = () => { amountText: string; currencyCode: string; }) => { - const amount = parseFloat(amountText); + const normalizedAmountText = amountText.replace(',', '.'); + const amount = parseFloat(normalizedAmountText); const newCurrencyValue = { amountMicros: isNaN(amount) diff --git a/packages/twenty-front/src/modules/ui/field/input/components/CurrencyInput.tsx b/packages/twenty-front/src/modules/ui/field/input/components/CurrencyInput.tsx index 28fa9ba15b..b9df3974a9 100644 --- a/packages/twenty-front/src/modules/ui/field/input/components/CurrencyInput.tsx +++ b/packages/twenty-front/src/modules/ui/field/input/components/CurrencyInput.tsx @@ -3,12 +3,14 @@ import { styled } from '@linaria/react'; import { useContext, useEffect, useRef, useState } from 'react'; import { useRegisterInputEvents } from '@/object-record/record-field/ui/meta-types/input/hooks/useRegisterInputEvents'; +import { useNumberFormat } from '@/localization/hooks/useNumberFormat'; import { CURRENCIES } from '@/settings/data-model/constants/Currencies'; import { CurrencyPickerDropdownButton } from '@/ui/input/components/internal/currency/components/CurrencyPickerDropdownButton'; import { type Currency } from '@/ui/input/components/internal/types/Currency'; import { IMaskInput } from 'react-imask'; import { type IconComponent } from 'twenty-ui/display'; import { ThemeContext, themeCssVariables } from 'twenty-ui/theme-constants'; +import { getSeparatorsForNumberFormat } from '~/utils/format/getSeparatorsForNumberFormat'; export const StyledIMaskInput = styled.div` display: contents; @@ -87,9 +89,13 @@ export const CurrencyInput = ({ }: CurrencyInputProps) => { const { theme } = useContext(ThemeContext); const [internalText, setInternalText] = useState(value); + const { numberFormat } = useNumberFormat(); const wrapperRef = useRef(null); + const { thousandsSeparator, radix } = + getSeparatorsForNumberFormat(numberFormat); + const handleChange = (value: string) => { setInternalText(value); onChange?.(value); @@ -132,8 +138,8 @@ export const CurrencyInput = ({ handleChange(value)} inputRef={wrapperRef} diff --git a/packages/twenty-front/src/utils/format/__tests__/getSeparatorsForNumberFormat.test.ts b/packages/twenty-front/src/utils/format/__tests__/getSeparatorsForNumberFormat.test.ts new file mode 100644 index 0000000000..07278ad975 --- /dev/null +++ b/packages/twenty-front/src/utils/format/__tests__/getSeparatorsForNumberFormat.test.ts @@ -0,0 +1,49 @@ +import { NumberFormat } from '@/localization/constants/NumberFormat'; +import { + getSeparatorsForNumberFormat, + type NumberFormatSeparators, +} from '~/utils/format/getSeparatorsForNumberFormat'; + +const expectSeparators = ( + format: NumberFormat, + expected: NumberFormatSeparators, +) => { + expect(getSeparatorsForNumberFormat(format)).toEqual(expected); +}; + +describe('getSeparatorsForNumberFormat', () => { + it('returns comma thousands and dot radix for COMMAS_AND_DOT', () => { + expectSeparators(NumberFormat.COMMAS_AND_DOT, { + thousandsSeparator: ',', + radix: '.', + }); + }); + + it('returns space thousands and comma radix for SPACES_AND_COMMA', () => { + expectSeparators(NumberFormat.SPACES_AND_COMMA, { + thousandsSeparator: ' ', + radix: ',', + }); + }); + + it('returns dot thousands and comma radix for DOTS_AND_COMMA', () => { + expectSeparators(NumberFormat.DOTS_AND_COMMA, { + thousandsSeparator: '.', + radix: ',', + }); + }); + + it('returns apostrophe thousands and dot radix for APOSTROPHE_AND_DOT', () => { + expectSeparators(NumberFormat.APOSTROPHE_AND_DOT, { + thousandsSeparator: "'", + radix: '.', + }); + }); + + it('falls back to COMMAS_AND_DOT separators for SYSTEM', () => { + expectSeparators(NumberFormat.SYSTEM, { + thousandsSeparator: ',', + radix: '.', + }); + }); +}); diff --git a/packages/twenty-front/src/utils/format/getSeparatorsForNumberFormat.ts b/packages/twenty-front/src/utils/format/getSeparatorsForNumberFormat.ts new file mode 100644 index 0000000000..7213306bf7 --- /dev/null +++ b/packages/twenty-front/src/utils/format/getSeparatorsForNumberFormat.ts @@ -0,0 +1,35 @@ +import { NumberFormat } from '@/localization/constants/NumberFormat'; + +export type NumberFormatSeparators = { + thousandsSeparator: string; + radix: string; +}; + +export const getSeparatorsForNumberFormat = ( + format: NumberFormat, +): NumberFormatSeparators => { + switch (format) { + case NumberFormat.SPACES_AND_COMMA: + return { + thousandsSeparator: ' ', + radix: ',', + }; + case NumberFormat.DOTS_AND_COMMA: + return { + thousandsSeparator: '.', + radix: ',', + }; + case NumberFormat.APOSTROPHE_AND_DOT: + return { + thousandsSeparator: "'", + radix: '.', + }; + case NumberFormat.SYSTEM: + case NumberFormat.COMMAS_AND_DOT: + default: + return { + thousandsSeparator: ',', + radix: '.', + }; + } +};