diff --git a/browser/data-browser/src/views/TablePage/EditorCells/FloatCell.tsx b/browser/data-browser/src/views/TablePage/EditorCells/FloatCell.tsx index 73d0c4431..cf7267a0c 100644 --- a/browser/data-browser/src/views/TablePage/EditorCells/FloatCell.tsx +++ b/browser/data-browser/src/views/TablePage/EditorCells/FloatCell.tsx @@ -54,7 +54,7 @@ function FloatCellDisplay({ const formattedValue = formatNumber( value as number | undefined, - decimalPlaces ?? 2, + decimalPlaces, numberFormatting, ); diff --git a/browser/data-browser/src/views/TablePage/PropertyForm/Inputs/DecimalPlacesInput.tsx b/browser/data-browser/src/views/TablePage/PropertyForm/Inputs/DecimalPlacesInput.tsx index b78cd9a50..e4ea9e701 100644 --- a/browser/data-browser/src/views/TablePage/PropertyForm/Inputs/DecimalPlacesInput.tsx +++ b/browser/data-browser/src/views/TablePage/PropertyForm/Inputs/DecimalPlacesInput.tsx @@ -21,7 +21,7 @@ export function DecimalPlacesInput({ commit: true, }); - const [__, setDecimalPlaces] = useNumber( + const [decimalPlaces, setDecimalPlaces] = useNumber( resource, urls.properties.constraints.decimalPlaces, { commit: true }, @@ -32,8 +32,10 @@ export function DecimalPlacesInput({ const newValue = e.target.value; const num = Number.parseInt(newValue, 10); - if (num < 0) { - setError('Value must be eighter positive, zero or empty.'); + if (num < 0 || num > 20) { + setError('Value must be between 0 and 20.', true); + + return; } else { setError(undefined); } @@ -63,7 +65,9 @@ export function DecimalPlacesInput({ diff --git a/browser/data-browser/src/views/TablePage/helpers/formatNumber.ts b/browser/data-browser/src/views/TablePage/helpers/formatNumber.ts index e3d5f75c5..4a0689025 100644 --- a/browser/data-browser/src/views/TablePage/helpers/formatNumber.ts +++ b/browser/data-browser/src/views/TablePage/helpers/formatNumber.ts @@ -2,26 +2,40 @@ import { urls } from '@tomic/react'; export function formatNumber( value: number | undefined, - numberOfDecimalPlaces: number, + fractionDigits: number | undefined, formatting?: string, ): string { if (value === undefined) { return ''; } + // Bad data like negative values will cause a crash so we need to make it valid before formatting. + const fixedFractionDigits = fixInvalidFractionDigits(fractionDigits); + if (formatting === urls.instances.numberFormats.percentage) { const formatter = new Intl.NumberFormat('default', { style: 'percent', - minimumFractionDigits: numberOfDecimalPlaces, + minimumFractionDigits: fixedFractionDigits, }); - return formatter.format(value); + return formatter.format(value / 100); } const formatter = new Intl.NumberFormat('default', { style: 'decimal', - minimumFractionDigits: numberOfDecimalPlaces, + minimumFractionDigits: fixedFractionDigits, }); return formatter.format(value); } + +function fixInvalidFractionDigits( + fractionDigits: number | undefined, +): number | undefined { + if (fractionDigits === undefined) { + return undefined; + } + + // INTL only supports 0-20 fraction digits + return Math.min(20, Math.max(0, fractionDigits)); +}