diff --git a/packages/twenty-front/src/modules/object-record/record-field/ui/meta-types/hooks/useCurrencyField.ts b/packages/twenty-front/src/modules/object-record/record-field/ui/meta-types/hooks/useCurrencyField.ts
index 5eadc2ca91..771b7ead68 100644
--- a/packages/twenty-front/src/modules/object-record/record-field/ui/meta-types/hooks/useCurrencyField.ts
+++ b/packages/twenty-front/src/modules/object-record/record-field/ui/meta-types/hooks/useCurrencyField.ts
@@ -10,6 +10,7 @@ import { isFieldCurrency } from '@/object-record/record-field/ui/types/guards/is
import { recordStoreFamilySelector } from '@/object-record/record-store/states/selectors/recordStoreFamilySelector';
import { useRecoilComponentValue } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValue';
import { FieldMetadataType } from '~/generated-metadata/graphql';
+import { DEFAULT_DECIMAL_VALUE } from '~/utils/format/formatNumber';
export const useCurrencyField = () => {
const { recordId, fieldDefinition } = useContext(FieldContext);
@@ -37,6 +38,9 @@ export const useCurrencyField = () => {
const defaultValue = fieldDefinition.defaultValue;
+ const decimals =
+ fieldDefinition.metadata.settings?.decimals ?? DEFAULT_DECIMAL_VALUE;
+
return {
fieldDefinition,
fieldValue,
@@ -44,5 +48,6 @@ export const useCurrencyField = () => {
setDraftValue,
setFieldValue,
defaultValue,
+ decimals,
};
};
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 b071e71475..d3fee39eda 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
@@ -17,7 +17,8 @@ import { convertCurrencyAmountToCurrencyMicros } from '~/utils/convertCurrencyTo
import { isUndefinedOrNull } from '~/utils/isUndefinedOrNull';
export const CurrencyFieldInput = () => {
- const { draftValue, setDraftValue, defaultValue } = useCurrencyField();
+ const { draftValue, setDraftValue, defaultValue, decimals } =
+ useCurrencyField();
const { onClickOutside, onEnter, onEscape, onShiftTab, onTab } = useContext(
FieldInputEventContext,
@@ -137,6 +138,7 @@ export const CurrencyFieldInput = () => {
instanceId={instanceId}
value={draftValue?.amount?.toString() ?? ''}
currencyCode={currencyCode}
+ decimals={decimals}
autoFocus
placeholder={t`Currency`}
onClickOutside={handleClickOutside}
diff --git a/packages/twenty-front/src/modules/object-record/record-field/ui/types/FieldMetadata.ts b/packages/twenty-front/src/modules/object-record/record-field/ui/types/FieldMetadata.ts
index 234779a272..57d1639443 100644
--- a/packages/twenty-front/src/modules/object-record/record-field/ui/types/FieldMetadata.ts
+++ b/packages/twenty-front/src/modules/object-record/record-field/ui/types/FieldMetadata.ts
@@ -91,6 +91,7 @@ export type FieldCurrencyMetadata = BaseFieldMetadata & {
isPositive?: boolean;
settings?: {
format: FieldCurrencyFormat | null;
+ decimals?: number;
};
};
diff --git a/packages/twenty-front/src/modules/object-record/record-field/ui/validation-schemas/currencyFieldSettingsSchema.ts b/packages/twenty-front/src/modules/object-record/record-field/ui/validation-schemas/currencyFieldSettingsSchema.ts
index 4663db477c..b36e75af56 100644
--- a/packages/twenty-front/src/modules/object-record/record-field/ui/validation-schemas/currencyFieldSettingsSchema.ts
+++ b/packages/twenty-front/src/modules/object-record/record-field/ui/validation-schemas/currencyFieldSettingsSchema.ts
@@ -3,4 +3,5 @@ import { z } from 'zod';
export const currencyFieldSettingsSchema = z.object({
format: z.enum(fieldMetadataCurrencyFormat),
+ decimals: z.number().int().min(0).max(5).optional(),
});
diff --git a/packages/twenty-front/src/modules/settings/data-model/fields/forms/currency/components/SettingsDataModelFieldCurrencyForm.tsx b/packages/twenty-front/src/modules/settings/data-model/fields/forms/currency/components/SettingsDataModelFieldCurrencyForm.tsx
index ab0bfff816..a7cbae7d32 100644
--- a/packages/twenty-front/src/modules/settings/data-model/fields/forms/currency/components/SettingsDataModelFieldCurrencyForm.tsx
+++ b/packages/twenty-front/src/modules/settings/data-model/fields/forms/currency/components/SettingsDataModelFieldCurrencyForm.tsx
@@ -1,15 +1,26 @@
import { Controller, useFormContext } from 'react-hook-form';
import { z } from 'zod';
-import { type FieldCurrencyFormat } from '@/object-record/record-field/ui/types/FieldMetadata';
+import {
+ fieldMetadataCurrencyFormat,
+ type FieldCurrencyFormat,
+} from '@/object-record/record-field/ui/types/FieldMetadata';
import { currencyFieldDefaultValueSchema } from '@/object-record/record-field/ui/validation-schemas/currencyFieldDefaultValueSchema';
import { currencyFieldSettingsSchema } from '@/object-record/record-field/ui/validation-schemas/currencyFieldSettingsSchema';
+import { Separator } from '@/settings/components/Separator';
+import { SettingsOptionCardContentCounter } from '@/settings/components/SettingsOptions/SettingsOptionCardContentCounter';
import { SettingsOptionCardContentSelect } from '@/settings/components/SettingsOptions/SettingsOptionCardContentSelect';
import { CURRENCIES } from '@/settings/data-model/constants/Currencies';
import { useCurrencySettingsFormInitialValues } from '@/settings/data-model/fields/forms/currency/hooks/useCurrencySettingsFormInitialValues';
import { Select } from '@/ui/input/components/Select';
+import { plural } from '@lingui/core/macro';
import { useLingui } from '@lingui/react/macro';
-import { IconCheckbox, IconCurrencyDollar } from 'twenty-ui/display';
+import {
+ IconCheckbox,
+ IconCurrencyDollar,
+ IconDecimal,
+} from 'twenty-ui/display';
+import { DEFAULT_DECIMAL_VALUE } from '~/utils/format/formatNumber';
import { applySimpleQuotesToString } from '~/utils/string/applySimpleQuotesToString';
export const settingsDataModelFieldCurrencyFormSchema = z.object({
@@ -75,31 +86,65 @@ export const SettingsDataModelFieldCurrencyForm = ({
)}
/>
+
(
-
-
- )}
+ defaultValue={initialSettingsValue}
+ render={({ field: { onChange, value } }) => {
+ const format = value?.format ?? fieldMetadataCurrencyFormat[0];
+ const decimals = value?.decimals ?? DEFAULT_DECIMAL_VALUE;
+
+ return (
+ <>
+
+
+
+ {format === 'full' && (
+
+ onChange({ format, decimals: newDecimals })
+ }
+ disabled={disabled}
+ minValue={0}
+ maxValue={5}
+ />
+ )}
+ >
+ );
+ }}
/>
>
);
diff --git a/packages/twenty-front/src/modules/settings/data-model/fields/forms/currency/hooks/useCurrencySettingsFormInitialValues.ts b/packages/twenty-front/src/modules/settings/data-model/fields/forms/currency/hooks/useCurrencySettingsFormInitialValues.ts
index b427ab1ce2..e0cd4d9376 100644
--- a/packages/twenty-front/src/modules/settings/data-model/fields/forms/currency/hooks/useCurrencySettingsFormInitialValues.ts
+++ b/packages/twenty-front/src/modules/settings/data-model/fields/forms/currency/hooks/useCurrencySettingsFormInitialValues.ts
@@ -4,6 +4,7 @@ import { useFieldMetadataItemById } from '@/object-metadata/hooks/useFieldMetada
import { type SettingsDataModelFieldCurrencyFormValues } from '@/settings/data-model/fields/forms/currency/components/SettingsDataModelFieldCurrencyForm';
import { isNonEmptyString } from '@sniptt/guards';
import { CurrencyCode } from 'twenty-shared/constants';
+import { DEFAULT_DECIMAL_VALUE } from '~/utils/format/formatNumber';
import { applySimpleQuotesToString } from '~/utils/string/applySimpleQuotesToString';
import { stripSimpleQuotesFromString } from '~/utils/string/stripSimpleQuotesFromString';
@@ -28,6 +29,7 @@ export const useCurrencySettingsFormInitialValues = ({
const initialFormValues: SettingsDataModelFieldCurrencyFormValues = {
settings: {
format: fieldMetadataItem?.settings?.format ?? 'short',
+ decimals: fieldMetadataItem?.settings?.decimals ?? DEFAULT_DECIMAL_VALUE,
},
defaultValue: {
amountMicros: initialAmountMicrosValue,
diff --git a/packages/twenty-front/src/modules/ui/field/display/components/CurrencyDisplay.tsx b/packages/twenty-front/src/modules/ui/field/display/components/CurrencyDisplay.tsx
index 9c554fdfc1..c4b61fd10d 100644
--- a/packages/twenty-front/src/modules/ui/field/display/components/CurrencyDisplay.tsx
+++ b/packages/twenty-front/src/modules/ui/field/display/components/CurrencyDisplay.tsx
@@ -9,6 +9,7 @@ import {
import { SETTINGS_FIELD_CURRENCY_CODES } from '@/settings/data-model/constants/SettingsFieldCurrencyCodes';
import { EllipsisDisplay } from '@/ui/field/display/components/EllipsisDisplay';
import { isDefined } from 'twenty-shared/utils';
+import { DEFAULT_DECIMAL_VALUE } from '~/utils/format/formatNumber';
import { formatToShortNumber } from '~/utils/format/formatToShortNumber';
import { isUndefinedOrNull } from '~/utils/isUndefinedOrNull';
@@ -32,6 +33,9 @@ export const CurrencyDisplay = ({
: currencyValue?.amountMicros / 1000000;
const format = fieldDefinition.metadata.settings?.format;
+ const decimals = fieldDefinition.metadata.settings?.decimals;
+ const decimalsToUse = decimals ?? DEFAULT_DECIMAL_VALUE;
+
const { formatNumber } = useNumberFormat();
return (
@@ -48,7 +52,7 @@ export const CurrencyDisplay = ({
{amountToDisplay !== null
? !isDefined(format) || format === 'short'
? formatToShortNumber(amountToDisplay)
- : formatNumber(amountToDisplay)
+ : formatNumber(amountToDisplay, { decimals: decimalsToUse })
: null}
);
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 53bb97d0c0..00cbb6c583 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
@@ -41,6 +41,7 @@ export type CurrencyInputProps = {
placeholder?: string;
autoFocus?: boolean;
value: string;
+ decimals?: number;
currencyCode: string;
onEnter: (newText: string) => void;
onEscape: (newText: string) => void;
@@ -64,6 +65,7 @@ export const CurrencyInput = ({
onClickOutside,
onChange,
onSelect,
+ decimals,
}: CurrencyInputProps) => {
const theme = useTheme();
@@ -114,6 +116,7 @@ export const CurrencyInput = ({
mask={Number}
thousandsSeparator=","
radix="."
+ scale={decimals}
onAccept={(value: string) => handleChange(value)}
inputRef={wrapperRef}
autoComplete="off"