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 : '' } }
|
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 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>
|
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>}
|
{m.hint && <span className="text-gray-500"> · {m.hint}</span>}
|
||||||
</th>
|
</th>
|
||||||
))}
|
))}
|
||||||
|
{showRunning && (
|
||||||
|
<th className="text-right font-normal pb-1 px-2 whitespace-nowrap text-gray-500">
|
||||||
|
running
|
||||||
|
</th>
|
||||||
|
)}
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
@ -521,7 +541,7 @@ function ScaleLedger({ currentTotals, scaleInputs, setScaleInputs, scalePlug, se
|
|||||||
))}
|
))}
|
||||||
|
|
||||||
{exclLines.length > 0 && (
|
{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 */}
|
{/* 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)}
|
{m.key === 'price' ? fmtNum(priceOf(e), m.dp) : fmtNum(e[m.key], m.dp)}
|
||||||
</td>
|
</td>
|
||||||
))}
|
))}
|
||||||
|
{showRunning && (
|
||||||
|
<td className={`${numCell} text-gray-500`}>{fmtNum(runningByKey.get(e.key), 0)}</td>
|
||||||
|
)}
|
||||||
</tr>
|
</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'}>
|
<tr className={onTotal ? 'text-gray-600' : 'font-semibold text-gray-700'}>
|
||||||
<td className="pr-3 whitespace-nowrap">
|
<td className="pr-3 whitespace-nowrap">
|
||||||
@ -549,6 +572,9 @@ function ScaleLedger({ currentTotals, scaleInputs, setScaleInputs, scalePlug, se
|
|||||||
{measures.map(m => (
|
{measures.map(m => (
|
||||||
<td key={m.key} className={numCell}>{fmtNum(m.current, m.dp)}</td>
|
<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>
|
</tr>
|
||||||
|
|
||||||
|
|
||||||
@ -571,14 +597,14 @@ function ScaleLedger({ currentTotals, scaleInputs, setScaleInputs, scalePlug, se
|
|||||||
silently below. */}
|
silently below. */}
|
||||||
{nothingToAdjust && (
|
{nothingToAdjust && (
|
||||||
<tr>
|
<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},
|
Nothing in this selection can be adjusted — all of it is {exclName},
|
||||||
loaded as {(currentTotals?.excludedIters || []).join(' / ') || 'reference'}.
|
loaded as {(currentTotals?.excludedIters || []).join(' / ') || 'reference'}.
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</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 */}
|
{/* the edit — three equivalent ways to say the same thing */}
|
||||||
{FIELDS.map(([field, label]) => (
|
{FIELDS.map(([field, label]) => (
|
||||||
@ -605,7 +631,7 @@ function ScaleLedger({ currentTotals, scaleInputs, setScaleInputs, scalePlug, se
|
|||||||
|
|
||||||
{outcome && (
|
{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">
|
<tr className="font-semibold text-gray-700">
|
||||||
<td className="pr-3 whitespace-nowrap">Result</td>
|
<td className="pr-3 whitespace-nowrap">Result</td>
|
||||||
{measures.map(m => (
|
{measures.map(m => (
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user