Show the walk's running total in the ledger
The lines sum to Adjustable, and checking that they do meant adding eight-digit numbers in your head. The column closes on the Adjustable row, so the walk visibly lands where it says it does. Value only. A cumulative price is meaningless -- prices do not add -- and a second running column for units doubles the width to say what the value column already implies. It appears only when there is more than one line to accumulate. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
2814b4073c
commit
62c815da63
@ -483,6 +483,21 @@ function ScaleLedger({ currentTotals, scaleInputs, setScaleInputs, scalePlug, se
|
||||
return { ...prev, [key]: { field, raw: cur ? raw : '' } }
|
||||
})
|
||||
|
||||
// A running total across the walk, in the primary measure. The lines sum to
|
||||
// Adjustable, and without this you are adding eight-digit numbers in your
|
||||
// head to check that they do.
|
||||
//
|
||||
// Value only: a cumulative price is meaningless -- prices do not add -- and a
|
||||
// second running column for units doubles the width to say something the
|
||||
// value column already implies.
|
||||
const runningByKey = (() => {
|
||||
const out = new Map()
|
||||
let acc = 0
|
||||
for (const e of lines) { acc += e.value || 0; out.set(e.key, acc) }
|
||||
return out
|
||||
})()
|
||||
const showRunning = !!valueCol && lines.length > 1
|
||||
|
||||
const numCell = 'text-right font-mono tabular-nums whitespace-nowrap px-2'
|
||||
const rule = <td className="p-0"><div className="border-t border-gray-300 my-1" /></td>
|
||||
|
||||
@ -498,6 +513,11 @@ function ScaleLedger({ currentTotals, scaleInputs, setScaleInputs, scalePlug, se
|
||||
{m.hint && <span className="text-gray-500"> · {m.hint}</span>}
|
||||
</th>
|
||||
))}
|
||||
{showRunning && (
|
||||
<th className="text-right font-normal pb-1 px-2 whitespace-nowrap text-gray-500">
|
||||
running
|
||||
</th>
|
||||
)}
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@ -521,7 +541,7 @@ function ScaleLedger({ currentTotals, scaleInputs, setScaleInputs, scalePlug, se
|
||||
))}
|
||||
|
||||
{exclLines.length > 0 && (
|
||||
<tr>{rule}{measures.map(m => <td key={m.key} className="p-0 px-2"><div className="border-t border-gray-300 my-1" /></td>)}</tr>
|
||||
<tr>{rule}{measures.map(m => <td key={m.key} className="p-0 px-2"><div className="border-t border-gray-300 my-1" /></td>)}{showRunning && <td className="p-0 px-2"><div className="border-t border-gray-300 my-1" /></td>}</tr>
|
||||
)}
|
||||
|
||||
{/* the walk from baseline to current, by initiative */}
|
||||
@ -537,10 +557,13 @@ function ScaleLedger({ currentTotals, scaleInputs, setScaleInputs, scalePlug, se
|
||||
{m.key === 'price' ? fmtNum(priceOf(e), m.dp) : fmtNum(e[m.key], m.dp)}
|
||||
</td>
|
||||
))}
|
||||
{showRunning && (
|
||||
<td className={`${numCell} text-gray-500`}>{fmtNum(runningByKey.get(e.key), 0)}</td>
|
||||
)}
|
||||
</tr>
|
||||
))}
|
||||
|
||||
<tr>{rule}{measures.map(m => <td key={m.key} className="p-0 px-2"><div className="border-t border-gray-300 my-1" /></td>)}</tr>
|
||||
<tr>{rule}{measures.map(m => <td key={m.key} className="p-0 px-2"><div className="border-t border-gray-300 my-1" /></td>)}{showRunning && <td className="p-0 px-2"><div className="border-t border-gray-300 my-1" /></td>}</tr>
|
||||
|
||||
<tr className={onTotal ? 'text-gray-600' : 'font-semibold text-gray-700'}>
|
||||
<td className="pr-3 whitespace-nowrap">
|
||||
@ -549,6 +572,9 @@ function ScaleLedger({ currentTotals, scaleInputs, setScaleInputs, scalePlug, se
|
||||
{measures.map(m => (
|
||||
<td key={m.key} className={numCell}>{fmtNum(m.current, m.dp)}</td>
|
||||
))}
|
||||
{showRunning && (
|
||||
<td className={`${numCell} text-gray-500`}>{fmtNum(total.value, 0)}</td>
|
||||
)}
|
||||
</tr>
|
||||
|
||||
|
||||
@ -571,14 +597,14 @@ function ScaleLedger({ currentTotals, scaleInputs, setScaleInputs, scalePlug, se
|
||||
silently below. */}
|
||||
{nothingToAdjust && (
|
||||
<tr>
|
||||
<td colSpan={measures.length + 1} className="pt-2 text-amber-700 leading-snug">
|
||||
<td colSpan={measures.length + 1 + (showRunning ? 1 : 0)} className="pt-2 text-amber-700 leading-snug">
|
||||
Nothing in this selection can be adjusted — all of it is {exclName},
|
||||
loaded as {(currentTotals?.excludedIters || []).join(' / ') || 'reference'}.
|
||||
</td>
|
||||
</tr>
|
||||
)}
|
||||
|
||||
<tr>{rule}{measures.map(m => <td key={m.key} className="p-0 px-2"><div className="border-t border-gray-300 my-1" /></td>)}</tr>
|
||||
<tr>{rule}{measures.map(m => <td key={m.key} className="p-0 px-2"><div className="border-t border-gray-300 my-1" /></td>)}{showRunning && <td className="p-0 px-2"><div className="border-t border-gray-300 my-1" /></td>}</tr>
|
||||
|
||||
{/* the edit — three equivalent ways to say the same thing */}
|
||||
{FIELDS.map(([field, label]) => (
|
||||
@ -605,7 +631,7 @@ function ScaleLedger({ currentTotals, scaleInputs, setScaleInputs, scalePlug, se
|
||||
|
||||
{outcome && (
|
||||
<>
|
||||
<tr>{rule}{measures.map(m => <td key={m.key} className="p-0 px-2"><div className="border-t border-gray-300 my-1" /></td>)}</tr>
|
||||
<tr>{rule}{measures.map(m => <td key={m.key} className="p-0 px-2"><div className="border-t border-gray-300 my-1" /></td>)}{showRunning && <td className="p-0 px-2"><div className="border-t border-gray-300 my-1" /></td>}</tr>
|
||||
<tr className="font-semibold text-gray-700">
|
||||
<td className="pr-3 whitespace-nowrap">Result</td>
|
||||
{measures.map(m => (
|
||||
|
||||
Loading…
Reference in New Issue
Block a user