Skip to content

feat(ui): searchable, grouped field picker with labels; technical rows hidden; choice labels in pickers (#16) - #25

Open
PrjShrestha wants to merge 1 commit into
masterfrom
9c_field_picker
Open

PrjShrestha wants to merge 1 commit into
masterfrom
9c_field_picker

Conversation

@PrjShrestha

Copy link
Copy Markdown
Collaborator

Closes #16 (T9c). Parent epic #9. Plan: docs/plans/9_complex_logic_calculation_relevant_constraint/README.md (on the T9 docs branch). Independent of #23 / #24; branched from master.

What

One field picker for every place a rule picks a field: the inline strip, the "✎ build" modal, the calculation builder's field references, and the strip's value cell when the value is another question.

shared/src/xlsform/fieldMeta.ts (pure, node-tested): per named row, the resolved label, the innermost section (group label or name; both begin group spellings), the field kind, and whether the row is technical (note, r_*, __*, hidden type or appearance). A calculate is not technical: the harvest calculate that re-exports ../inputs/contact/sex is the sanctioned way to reach a contact value, and the existing Slice 1 e2e picks it.

client/src/ui/SurveyFieldPicker.tsx: [search] [select ▾] [☐ show technical rows].

  • The select stays native and keeps ref-chip-select, so keyboard behaviour, form semantics and every existing e2e selectOption keep working. Options read "Label (name)", grouped by section.
  • Typing narrows by label or name and turns the select into a visible list, so matches show on the first keystrokes and one click picks; picking clears the search. Enter picks a sole match.
  • Technical rows are withheld until the toggle; the current value is always kept so a saved selection is never stranded.
  • Metadata comes from a FieldMetaContext provided once per form by FormEditor. Callers keep passing their dependency-ordered name list (earlierFields), so the picker never offers a field the caller withheld.

FormEditor: the v0.3 "Typical for this check / Other fields" partition and its "Show all fields" checkbox are gone (the review found the box read as unchecked while everything was shown). Op-typicality survives as ordering inside each section and never hides a field. The value cell shows choice labels and the readback chips use labels; the cell written keeps the name. The free-text value cell no longer says value or ${other_field}: an "another question" toggle swaps it for the same picker and writes ${name}.

Found on the way: the search box grew on focus, so a mousedown on "+ insert" blurred it, shrank it, and moved the button out from under the cursor before mouseup; the click was lost. No width change on focus now.

Display only: no XLSForm bytes change (corpus sweep output byte-identical to master).

Tests

  • fieldMeta.test.ts: label resolution, section nesting, technical reasons, query matching.
  • field-picker.spec.ts (Playwright): search by name and by label with technical rows behind the toggle; choice labels in the value picker and the readback with the choice name on disk; the "another question" value writes ${patient_id}; the modal uses the same picker and emits the same ${lmp_date} = ''; on the real 280-row geriatric pregnancy form "lmp" lists a handful of fields grouped by section (skipped when that config is absent).
  • condition-builder.spec.ts: the three v0.3 picker specs rewritten for section grouping, typicality-as-ordering, and the technical toggle (acceptance "nothing technical appears until the toggle is on").

Validate

Check Result
pnpm typecheck clean
pnpm lint fails on master already (164 problems in untouched files); the new files lint clean, the three legacy files touched add no new problems
pnpm --filter @cht-ui/shared build && test 822 pass, 0 fail (4 new)
Playwright condition-builder, field-picker, form-editing, pick-preexisting-values, form-data-passing, demo 35 pass, 2 fail in demo.spec.ts ("add inside", "+ Type") that fail identically on a clean master
node scripts/corpus-sweep.mjs output byte-identical to master

🤖 Generated with Claude Code

…s hidden; choice labels in pickers and readback (#16)

The "show this question when" dropdown listed about 230 rows of a real
pregnancy form by name in sheet order, every *_note, r_* summary row,
__* hidden output and plumbing calculate included, with no search, no
labels and no grouping (UX review finding 2, P0). One component now
serves every place a rule picks a field: the inline strip, the "build"
modal, the calculation builder's field references, and the strip's value
cell when the value is another question.

shared/src/xlsform/fieldMeta.ts (pure, node-tested): per named row, the
resolved label (first non-empty in locale order), the innermost section
(group label or name, both `begin group` spellings), the field kind, and
whether the row is technical: note, r_*, __*, hidden type/appearance. A
calculate is NOT technical: the harvest calculate that re-exports
../inputs/contact/sex is the sanctioned way to reach a contact value.

client/src/ui/SurveyFieldPicker.tsx: [search] [select] [show technical
rows]. The select stays native and keeps `ref-chip-select`, so keyboard
behaviour and every existing e2e `selectOption` keep working; options
read "Label (name)", grouped by section as optgroups. Typing narrows by
label OR name and turns the select into a visible list, so matches show
on the first keystrokes and one click picks; picking clears the search.
Technical rows are withheld until the toggle. The current value is always
kept in the list so a saved selection is never stranded. Metadata comes
from a FieldMetaContext provided once per form by FormEditor; callers
keep passing the dependency-ordered name list, so the picker never offers
a field the caller withheld.

FormEditor: the v0.3 "Typical for this check" / "Other fields" partition
and its "Show all fields" checkbox are gone (the review found the box
read as unchecked while everything was shown); op-typicality survives as
ordering inside each section and never hides a field. The value cell
shows choice labels ("Vaginal bleeding (vaginal_bleeding)") and the
readback chips use labels; the written cell keeps the name. The free-text
value cell no longer says `value or ${other_field}`: an "another question"
toggle swaps it for the same picker and writes `${name}`.

Found on the way: the search box grew on focus, so a mousedown on
"+ insert" blurred it, shrank it, and moved the button out from under the
cursor before mouseup; the click was lost. No width change on focus now.

Tests: fieldMeta node tests (labels, sections, technical reasons,
search); Playwright field-picker.spec.ts (search by name and by label,
technical toggle, labels in value picker and readback with the name on
disk, "another question" value, the modal uses the same picker, and on
the real 280-row geriatric form "lmp" lists a handful grouped by section,
skipped when that config is absent). The three v0.3 picker specs are
rewritten for the section grouping and the technical toggle. Open-and-
save is unaffected: corpus sweep output byte-identical to master.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

T9c: Searchable, grouped field picker; technical rows hidden; choice labels

1 participant