Collapse untagged adjustments into one bridge step
buildSteps keyed every untagged log entry by its own pf_logid, so a version with two dozen routine untagged scale/recode passes drew two dozen separate bars -- one per operation, none of them named. The ledger in OperationPanel.jsx already collapses these into a single "N untagged adjustments" line; Bridge now does the same, and groups tagged entries case-insensitively too, carrying the most-used spelling as the label, matching the ledger's own grouping exactly. The old per-row "untagged"/"×N" captions are dropped where they'd now just repeat what the collapsed label already says. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
parent
c5993d5f88
commit
6018001f4e
@ -126,17 +126,32 @@ export function buildSteps(rows, {
|
|||||||
// label first, the same precedence pf_segment uses, so the bridge and the
|
// label first, the same precedence pf_segment uses, so the bridge and the
|
||||||
// pivot call a step by the same name
|
// pivot call a step by the same name
|
||||||
const tag = (meta.label || meta.tag || '').trim()
|
const tag = (meta.label || meta.tag || '').trim()
|
||||||
const label = tag || (meta.note || '').trim() ||
|
// Untagged entries collapse into one step, the same as the ledger's
|
||||||
`${(meta.operation || r.pf_iter || 'adj')}${r.pf_logid != null ? ` #${r.pf_logid}` : ''}`
|
// "N untagged adjustments" line in OperationPanel.jsx -- one bar per
|
||||||
const key = tag ? `tag:${tag}` : `log:${r.pf_logid}`
|
// untagged scale/recode would otherwise turn a routine cleanup pass into
|
||||||
const g = byTag.get(key) ||
|
// a wall of identical-looking bars. Tagged entries group case-
|
||||||
{ key, label, tagged: !!tag, value: 0, units: 0, rows: 0, logIds: new Set(), first: r.pf_logid }
|
// insensitively for the same reason the ledger does: "Pull Forward" and
|
||||||
|
// "pull forward" are one initiative, not two, and the most-used spelling
|
||||||
|
// is what gets shown.
|
||||||
|
const key = tag ? `tag:${tag.toLowerCase()}` : 'untagged'
|
||||||
|
const g = byTag.get(key) || {
|
||||||
|
key, tagged: !!tag, value: 0, units: 0, rows: 0, logIds: new Set(), first: r.pf_logid,
|
||||||
|
spellings: tag ? new Map() : null,
|
||||||
|
}
|
||||||
g.value += v; g.units += u; g.rows += 1
|
g.value += v; g.units += u; g.rows += 1
|
||||||
if (r.pf_logid != null) { g.logIds.add(r.pf_logid); g.first = Math.min(g.first ?? r.pf_logid, r.pf_logid) }
|
if (r.pf_logid != null) { g.logIds.add(r.pf_logid); g.first = Math.min(g.first ?? r.pf_logid, r.pf_logid) }
|
||||||
|
if (tag) g.spellings.set(tag, (g.spellings.get(tag) || 0) + 1)
|
||||||
byTag.set(key, g)
|
byTag.set(key, g)
|
||||||
}
|
}
|
||||||
|
|
||||||
const mid = [...byTag.values()].sort((a, b) => (a.first ?? 0) - (b.first ?? 0))
|
const mid = [...byTag.values()]
|
||||||
|
.sort((a, b) => (a.first ?? 0) - (b.first ?? 0))
|
||||||
|
.map(g => ({
|
||||||
|
...g,
|
||||||
|
label: g.tagged
|
||||||
|
? [...g.spellings.entries()].sort((a, b) => b[1] - a[1])[0]?.[0] || ''
|
||||||
|
: `${g.logIds.size} untagged adjustment${g.logIds.size === 1 ? '' : 's'}`,
|
||||||
|
}))
|
||||||
const useBasis = !!basis && basisT.rows > 0
|
const useBasis = !!basis && basisT.rows > 0
|
||||||
|
|
||||||
const out = []
|
const out = []
|
||||||
@ -534,17 +549,14 @@ export default function BridgeView({
|
|||||||
<tspan key={li} x={x + barW / 2} dy={li === 0 ? 0 : 11}>{ln}</tspan>
|
<tspan key={li} x={x + barW / 2} dy={li === 0 ? 0 : 11}>{ln}</tspan>
|
||||||
))}
|
))}
|
||||||
</text>
|
</text>
|
||||||
{/* below the label, however many lines it took */}
|
{/* below the label, however many lines it took. Skipped for the
|
||||||
{!isAnchor && s.entries > 1 && (
|
untagged bucket -- its label already reads "N untagged
|
||||||
|
adjustments", so a ×N here would just repeat the count. */}
|
||||||
|
{!isAnchor && s.tagged && s.entries > 1 && (
|
||||||
<text x={x + barW / 2} y={subY} textAnchor="middle" fontSize="9" fill={INK_DIM}>
|
<text x={x + barW / 2} y={subY} textAnchor="middle" fontSize="9" fill={INK_DIM}>
|
||||||
×{s.entries}
|
×{s.entries}
|
||||||
</text>
|
</text>
|
||||||
)}
|
)}
|
||||||
{!s.tagged && !isAnchor && (
|
|
||||||
<text x={x + barW / 2} y={subY} textAnchor="middle" fontSize="9" fill={INK_DIM}>
|
|
||||||
untagged
|
|
||||||
</text>
|
|
||||||
)}
|
|
||||||
</g>
|
</g>
|
||||||
)
|
)
|
||||||
})}
|
})}
|
||||||
@ -587,9 +599,7 @@ export default function BridgeView({
|
|||||||
<tbody>
|
<tbody>
|
||||||
{steps.map(s => (
|
{steps.map(s => (
|
||||||
<tr key={s.key} className="border-b border-gray-100">
|
<tr key={s.key} className="border-b border-gray-100">
|
||||||
<td className="py-1.5 pr-3 text-gray-800">
|
<td className="py-1.5 pr-3 text-gray-800">{s.label}</td>
|
||||||
{s.label}{!s.tagged && s.kind === 'step' && <span className="text-gray-600"> · untagged</span>}
|
|
||||||
</td>
|
|
||||||
<td className="py-1.5 px-2 text-right font-mono tabular-nums text-gray-800">
|
<td className="py-1.5 px-2 text-right font-mono tabular-nums text-gray-800">
|
||||||
{s.kind === 'anchor' ? fmt(s.end) : fmtSigned(s.delta)}
|
{s.kind === 'anchor' ? fmt(s.end) : fmtSigned(s.delta)}
|
||||||
</td>
|
</td>
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user