diff --git a/ui/src/components/OperationPanel.jsx b/ui/src/components/OperationPanel.jsx index b36b337..70f0478 100644 --- a/ui/src/components/OperationPanel.jsx +++ b/ui/src/components/OperationPanel.jsx @@ -189,7 +189,10 @@ const FIELDS = [ ] // given the active edit for a measure, what do the three rows read? -function derive(current, edit) { +// dp is the measure's own precision, so the editable rows read the same way as +// the lines above them -- whole dollars against whole dollars, five places +// against five. The percentage is its own scale and stays at one. +function derive(current, edit, dp = 2) { const blank = { new: '', change: '', pct: '' } if (!edit || edit.raw === '' || edit.raw == null) return blank const n = parseFloat(edit.raw) @@ -203,8 +206,8 @@ function derive(current, edit) { const change = next - current const pct = current === 0 ? null : (change / Math.abs(current)) * 100 const out = { - new: fmtNum(next), - change: fmtNum(change), + new: fmtNum(next, dp), + change: fmtNum(change, dp), pct: pct == null ? '—' : fmtNum(pct, 1), } out[edit.field] = edit.raw // keep what you typed exactly as typed @@ -285,13 +288,16 @@ function ScaleLedger({ currentTotals, scaleInputs, setScaleInputs, scalePlug, se // measure columns, in ledger order const measures = [ - valueCol && { key: 'value', label: valueCol, current: total.value, dp: 2 }, - unitsCol && { key: 'units', label: unitsCol, current: total.units, dp: 2 }, - (valueCol && unitsCol) && { key: 'price', label: 'price', current: curPrice, dp: 4, hint: 'value / units' }, + // Whole units for the measures -- the figures run to eight digits, where two + // decimals are noise. Price is the opposite: it sits around 0.27, so it needs + // the places to show a move at all. + valueCol && { key: 'value', label: valueCol, current: total.value, dp: 0 }, + unitsCol && { key: 'units', label: unitsCol, current: total.units, dp: 0 }, + (valueCol && unitsCol) && { key: 'price', label: 'price', current: curPrice, dp: 5, hint: 'value / units' }, ].filter(Boolean) const derived = Object.fromEntries( - measures.map(m => [m.key, derive(basisOf(m.key) ?? 0, scaleInputs[m.key])]) + measures.map(m => [m.key, derive(basisOf(m.key) ?? 0, scaleInputs[m.key], m.dp)]) ) // an edit is dollars-only when value carries a number and neither units nor