diff --git a/ui/src/components/OperationPanel.jsx b/ui/src/components/OperationPanel.jsx index d5373fd..8dcb1aa 100644 --- a/ui/src/components/OperationPanel.jsx +++ b/ui/src/components/OperationPanel.jsx @@ -296,6 +296,51 @@ function ScaleLedger({ currentTotals, scaleInputs, setScaleInputs, scalePlug, se } const dollarsOnly = filled('value') && !filled('units') && !filled('price') + // Where the edit lands, for all three measures at once. The rows above each + // show only their own input, so a dollar figure entered with plug = volume + // left units and price blank -- exactly the two numbers you need to see to + // know whether you asked for a price change or a volume change. + const numOf = (key, field) => { + const raw = derived[key]?.[field] + const n = parseFloat(raw) + return isFinite(n) ? n : null + } + + const outcome = (() => { + const curValue = basisOf('value') ?? 0 + const curUnits = basisOf('units') ?? 0 + if (!filled('value') && !filled('units') && !filled('price')) return null + + let newValue, newUnits + + if (filled('price') && !filled('value')) { + // price is the input; dollars fall out of price x volume + const targetPrice = numOf('price', 'new') + newUnits = filled('units') ? numOf('units', 'new') : curUnits + newValue = targetPrice != null && newUnits != null ? targetPrice * newUnits : null + } else { + newValue = filled('value') ? numOf('value', 'new') : curValue + if (filled('units')) newUnits = numOf('units', 'new') + else if (dollarsOnly && scalePlug === 'volume') newUnits = curValue === 0 ? null + : curUnits * (newValue / curValue) + else newUnits = curUnits + } + + if (newValue == null || newUnits == null) return null + const newPrice = newUnits === 0 ? null : newValue / newUnits + const curPriceLocal = curUnits === 0 ? null : curValue / curUnits + return { + value: newValue, + units: newUnits, + price: newPrice, + moved: { + value: Math.abs(newValue - curValue) > 1e-9, + units: Math.abs(newUnits - curUnits) > 1e-9, + price: curPriceLocal != null && newPrice != null && Math.abs(newPrice - curPriceLocal) > 1e-9, + }, + } + })() + const setEdit = (key, field, raw) => setScaleInputs(prev => ({ ...prev, [key]: { field, raw } })) @@ -407,6 +452,22 @@ function ScaleLedger({ currentTotals, scaleInputs, setScaleInputs, scalePlug, se })} ))} + + {outcome && ( + <> + {rule}{measures.map(m =>
)} + + Result + {measures.map(m => ( + + + {fmtNum(outcome[m.key], m.dp)} + + + ))} + + + )}