Give the tag field back its space

The six quick-pick pills under it wrapped onto two rows as soon as the tags
were longer than a word, which most are, and the operations panel docked at
the bottom has a fixed height to spend -- so the form ran past its own
border. The same tags complete from the input's datalist, which costs no
space and is not capped at six.

The datalist now carries the tag alone. An option's text content renders as
a second column beside the value, so the use count was widening every row
of the list to show a number nobody picks on.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
Paul Trowbridge 2026-09-21 22:05:14 -04:00
parent 2fdf113636
commit b015b0c09b
3 changed files with 21 additions and 23 deletions

View File

@ -348,6 +348,15 @@ no adjustments.
The `pf_bucket` datalist on the Baseline page was already per version The `pf_bucket` datalist on the Baseline page was already per version
(`bucketsInUse`), so the two now agree. (`bucketsInUse`), so the two now agree.
**Completion is the datalist and nothing else.** The operation panel used to
carry six quick-pick pills under the tag field as well. They wrapped to two rows
as soon as the tags were longer than a word, and the panel docked at the bottom
has a fixed height, so they pushed the form past its own border. The datalist
costs no space, is not capped at six, and now shows the tag alone — an option's
text content renders as a second column beside the value, so the use count was
widening every row of the pick list to carry a number nobody picks on. `uses`
and `last_used` still come back from the route; nothing reads them.
--- ---
## Renaming a version ## Renaming a version

View File

@ -898,7 +898,7 @@ export default function OperationPanel({
scaleInputs, setScaleInputs, scaleInputs, setScaleInputs,
scalePlug, setScalePlug, scalePlug, setScalePlug,
targetBasis, setTargetBasis, targetBasis, setTargetBasis,
opTag, setOpTag, knownTags = [], logMeta = {}, opTag, setOpTag, logMeta = {},
scaleNote, setScaleNote, scaleNote, setScaleNote,
recodeSet, setRecodeSet, recodeSet, setRecodeSet,
recodeNote, setRecodeNote, recodeNote, setRecodeNote,
@ -1066,24 +1066,12 @@ export default function OperationPanel({
)} )}
</Field> </Field>
{/* Under the tag field and inside the same column, so they read as {/* The six quick-pick pills that used to sit here are gone. They
values for it rather than as a row of unexplained buttons. */} wrapped onto two rows once the tags were more than a word long,
{knownTags.length > 0 && ( which is most of them, and the panel docked at the bottom has a
<Field label=""> fixed height to spend -- so they pushed the form past its own
<div className="flex items-center gap-1 flex-wrap"> border. The same tags complete from the input's datalist, which
{knownTags.slice(0, 6).map(t => ( costs no space and is not capped at six. */}
<button key={t.tag} onClick={() => setOpTag(t.tag)}
title={`${t.uses} previous use${t.uses === 1 ? '' : 's'}`}
className={`px-2 py-0.5 rounded-full border text-xs whitespace-nowrap ${
opTag.trim() === t.tag
? 'bg-blue-600 border-blue-600 text-white'
: 'bg-white border-gray-300 text-gray-700 hover:border-blue-400 hover:text-blue-700'}`}>
{t.tag}
</button>
))}
</div>
</Field>
)}
<Field label="note"> <Field label="note">
<input value={note} onChange={e => setNote(e.target.value)} <input value={note} onChange={e => setNote(e.target.value)}

View File

@ -1881,7 +1881,7 @@ export default function Forecast({ sources = [], sourceId, versions = [], versio
scaleInputs, setScaleInputs, scaleInputs, setScaleInputs,
scalePlug, setScalePlug, scalePlug, setScalePlug,
targetBasis, setTargetBasis, targetBasis, setTargetBasis,
opTag, setOpTag, knownTags, logMeta, opTag, setOpTag, logMeta,
scaleNote, setScaleNote, scaleNote, setScaleNote,
recodeSet, setRecodeSet, recodeSet, setRecodeSet,
recodeNote, setRecodeNote, recodeNote, setRecodeNote,
@ -1898,10 +1898,11 @@ export default function Forecast({ sources = [], sourceId, versions = [], versio
{/* Tag completions, shared by the operation panel and the change log's {/* Tag completions, shared by the operation panel and the change log's
inline editor. Lives here so it is in the DOM even when the panel is shut. */} inline editor. Lives here so it is in the DOM even when the panel is shut. */}
{/* Value only. A datalist option's text content renders as a second
column beside the value, so the use count widened every row of the
pick list to carry a number nobody picks on. */}
<datalist id="pf-tag-options"> <datalist id="pf-tag-options">
{knownTags.map(t => ( {knownTags.map(t => <option key={t.tag} value={t.tag} />)}
<option key={t.tag} value={t.tag}>{t.uses} use{t.uses === 1 ? '' : 's'}</option>
))}
</datalist> </datalist>
{/* Toolbar */} {/* Toolbar */}