Give the operation badge its own column, and drop seq
"referenceYTD Sales" ran together because the badge shared the note column, and that column had lost width to label and counts-toward. The badge is a fixed-width token, so it gets a column of its own and stops competing with free text. seq goes with it. The label carries the sort order now -- it is typed with its own "01 - " prefix -- so a separate ordinal column is one more thing to keep in agreement with it for no gain. saveSeq and its state go too. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
af9e6de88e
commit
893a395529
@ -141,7 +141,6 @@ export default function Baseline({ sources = [], sourceId, versions = [], versio
|
|||||||
// are carried into the pivot as a "01 · " prefix, because Perspective orders
|
// are carried into the pivot as a "01 · " prefix, because Perspective orders
|
||||||
// column groups by the value string and no sort setting can express an
|
// column groups by the value string and no sort setting can express an
|
||||||
// arbitrary order.
|
// arbitrary order.
|
||||||
const [seqs, setSeqs] = useState({})
|
|
||||||
const [bucketOrder, setBucketOrder] = useState([])
|
const [bucketOrder, setBucketOrder] = useState([])
|
||||||
|
|
||||||
// Label and bucket are presentation, not definition: they change what the pivot
|
// Label and bucket are presentation, not definition: they change what the pivot
|
||||||
@ -180,22 +179,6 @@ export default function Baseline({ sources = [], sourceId, versions = [], versio
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function saveSeq(entry, value) {
|
|
||||||
const raw = String(value).trim()
|
|
||||||
const next = raw === '' ? null : parseInt(raw)
|
|
||||||
if (raw !== '' && !Number.isFinite(next)) { flash('Sequence must be a number', 'error'); return }
|
|
||||||
if (next === (entry.seq ?? null)) return
|
|
||||||
try {
|
|
||||||
const res = await fetch(`/api/log/${entry.id}`, {
|
|
||||||
method: 'PATCH',
|
|
||||||
headers: { 'Content-Type': 'application/json' },
|
|
||||||
body: JSON.stringify({ seq: next }),
|
|
||||||
})
|
|
||||||
if (!res.ok) { const d = await res.json(); flash(d.error, 'error'); return }
|
|
||||||
loadLog()
|
|
||||||
flash('Order saved')
|
|
||||||
} catch (err) { flash(err.message, 'error') }
|
|
||||||
}
|
|
||||||
|
|
||||||
async function saveBucketOrder(next) {
|
async function saveBucketOrder(next) {
|
||||||
setBucketOrder(next)
|
setBucketOrder(next)
|
||||||
@ -486,8 +469,8 @@ export default function Baseline({ sources = [], sourceId, versions = [], versio
|
|||||||
<tr className="text-left text-gray-400 border-b border-gray-100">
|
<tr className="text-left text-gray-400 border-b border-gray-100">
|
||||||
<th className="px-3 py-1.5 font-medium w-6"></th>
|
<th className="px-3 py-1.5 font-medium w-6"></th>
|
||||||
<th className="px-3 py-1.5 font-medium">#</th>
|
<th className="px-3 py-1.5 font-medium">#</th>
|
||||||
<th className="px-3 py-1.5 font-medium w-14 text-right">seq</th>
|
<th className="px-3 py-1.5 font-medium w-20">kind</th>
|
||||||
<th className="px-3 py-1.5 font-medium w-40">label</th>
|
<th className="px-3 py-1.5 font-medium w-48">label</th>
|
||||||
<th className="px-3 py-1.5 font-medium">note</th>
|
<th className="px-3 py-1.5 font-medium">note</th>
|
||||||
<th className="px-3 py-1.5 font-medium w-36">counts toward</th>
|
<th className="px-3 py-1.5 font-medium w-36">counts toward</th>
|
||||||
<th className="px-3 py-1.5 font-medium text-right">rows</th>
|
<th className="px-3 py-1.5 font-medium text-right">rows</th>
|
||||||
@ -525,15 +508,13 @@ export default function Baseline({ sources = [], sourceId, versions = [], versio
|
|||||||
>
|
>
|
||||||
<td className="px-3 py-2 text-gray-400 w-6"><span className="text-gray-300 text-xs">{isOpen ? '▾' : '▸'}</span></td>
|
<td className="px-3 py-2 text-gray-400 w-6"><span className="text-gray-300 text-xs">{isOpen ? '▾' : '▸'}</span></td>
|
||||||
<td className="px-3 py-2 text-gray-400">{log.length - i}</td>
|
<td className="px-3 py-2 text-gray-400">{log.length - i}</td>
|
||||||
<td className="px-3 py-2 text-right" onClick={e => e.stopPropagation()}>
|
{/* The operation badge gets its own column. Sharing one with
|
||||||
<input
|
the note put "reference" hard against "YTD Sales" as soon
|
||||||
value={seqs[entry.id] ?? (entry.seq ?? '')}
|
as the note column lost width to label and bucket. */}
|
||||||
onChange={e => setSeqs(v => ({ ...v, [entry.id]: e.target.value }))}
|
<td className="px-3 py-2">
|
||||||
onBlur={e => saveSeq(entry, e.target.value)}
|
<span className={`inline-block px-1.5 py-0.5 rounded text-xs font-medium ${entry.operation === 'reference' ? 'bg-purple-50 text-purple-600' : 'bg-blue-50 text-blue-600'}`}>
|
||||||
placeholder="—"
|
{entry.operation}
|
||||||
className="w-10 text-right border border-transparent hover:border-gray-200
|
</span>
|
||||||
focus:border-blue-400 rounded px-1 py-0.5 text-xs
|
|
||||||
focus:outline-none bg-transparent tabular-nums" />
|
|
||||||
</td>
|
</td>
|
||||||
<td className="px-3 py-2" onClick={e => e.stopPropagation()}>
|
<td className="px-3 py-2" onClick={e => e.stopPropagation()}>
|
||||||
<input
|
<input
|
||||||
@ -546,9 +527,6 @@ export default function Baseline({ sources = [], sourceId, versions = [], versio
|
|||||||
focus:outline-none bg-transparent" />
|
focus:outline-none bg-transparent" />
|
||||||
</td>
|
</td>
|
||||||
<td className="px-3 py-2">
|
<td className="px-3 py-2">
|
||||||
<span className={`inline-block mr-2 px-1.5 py-0.5 rounded text-xs font-medium ${entry.operation === 'reference' ? 'bg-purple-50 text-purple-600' : 'bg-blue-50 text-blue-600'}`}>
|
|
||||||
{entry.operation}
|
|
||||||
</span>
|
|
||||||
{entry.note || <span className="text-gray-300">—</span>}
|
{entry.note || <span className="text-gray-300">—</span>}
|
||||||
</td>
|
</td>
|
||||||
<td className="px-3 py-2" onClick={e => e.stopPropagation()}>
|
<td className="px-3 py-2" onClick={e => e.stopPropagation()}>
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user