feat: the people filter answers in two tiers, and the bar fits on one row - #309
Merged
Conversation
Ticking one person now finds the queues that person is on, not only the queues that need nobody else. The strict rule is unchanged and is still what `exact` means; the queues it used to DROP are drawn under a rule instead of thrown away. - `peopleMatch()` answers `exact` / `also` / `none` and reports how many required people the selection is short of. `membersMatchPeople()` is now `tier === "exact"`, so the server's pick rule and its browser mirror did not move. - `splitByMatch()` orders the also-in tier by that distance, stable, so the near misses read first and the file order survives inside a tier. - `AlsoInDivider` names who the queues below it still want, up to three people then a count. It renders nothing when there is nothing below it. - Chip counts cover BOTH tiers. Counting only exact matches is why a person who never has a queue to herself read `0` while her queues were on the screen under Anyone. - The provider filter is a MULTI-SELECT: `?only=` is a comma list, and `?only=kavita` / `?only=all` — every address the single-select era wrote — still parse. Its pills join the people's wrapping flow after a hairline rather than owning a row of their own. - Two dropdown layouts sit behind `?layout=combos|compact` as a PREVIEW, so the chip row can be compared against the two multi-select comboboxes the owner proposed. Two of the three go when he picks.
…s not offered Three rows became one at nine people, and the bar stops offering combinations that cannot exist. - The first FOUR of the roster are chips, plus every ticked person wherever they sit in it. The rest go behind `+ N more` — a Charcuterie `Combobox isMultiple` with a search field, a face, a name and a count per row. Quick-pick membership is ROSTER ORDER, not a usage ranking: a control that reorders itself as you use it cannot be learned. - The provider pills stay pills, on the right of the same row. They take their own line only in the Narrow View. - A person the selection shares NO QUEUE with is not offered: the chip disappears, the dropdown row is disabled. A ticked person is never hidden and never disabled — clicking a ticked chip is the way out of a selection that has filtered the page to nothing. -⚠️ The dead-end test is `hasQueueFor`, not a count of zero. A queue nobody is filed on passes every people filter by design, so the count for two people who share nothing is at least 1 and a count-based test would never have fired once. - `⚙` and `▾` are outside Outfit's Latin subset and were painting a tofu box on the live landing. Both are inline SVGs now, the route `SchemeIcons.tsx` already took. The three-layout preview switch and `?layout=` are deleted; the owner picked from a served build.
`shot-queue-filter.ts` boots the server on the landing fixtures, adds the six invented EXTENDED CAST people over the API and writes the queue trays, then takes five frames. The trays are written rather than seeded from group claims because the shape the frames need — one adult with queues of her own, a partner with none, and a queue naming two specific children — is not one a group claim can express. Each frame prints what it measured, so the harness reports the claim rather than only illustrating it: the bar is 3 rows on main and 1 on the branch, `?people=sven` is 1 shelf and no rule on main and 6 rows with a rule on the branch, and `?people=omar` has no +N more control on main. The seven PR images are committed under docs/images/, and AGENTS.md now names the extended cast so the next harness that needs a household-sized roster reuses it rather than inventing a seventh set of names.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What changes
Two things, both from the same report: the people filter answered with one word when it needed
two, and the bar it lives on had grown to three rows.
1. The filter answers in two tiers
Ticking one person now finds the queues that person is on, not only the queues that need
nobody else.
the rule that shipped on 2026-08-26, unchanged, and it is still the rule the SERVER picks on.
not ticked. Drawn under a rule that names who, up to three people then a count.
A queue where a ticked person is not on the roster at all is still not shown. That is the one
thing the second tier does not relax.
Chip counts cover both tiers. Counting only exact matches is why somebody who never has a queue
to herself read
0while her queues were plainly on the screen under Anyone.2. The bar is quick picks plus a dropdown
The rest go behind one
+ N more— a CharcuterieCombobox isMultiplewith a search field.?only=is a comma list) and its pills sit on theright of the same row. Every address the single-select era wrote still parses.
dropdown row is disabled. A ticked person is never hidden either way — clicking a ticked
chip is the way out of a selection that shows nothing.
Before / after
The bar, unfiltered, nine people. Three rows become one.
?people=sven— Sven is on four queues and has none of her own. Before: one card, and herchip says
1. After: the exact match, a rule, and the four queues she is on.?people=grace,linus— the queue that names exactly those two is an exact match; the familyqueue that also wants the adults is under the rule.
?people=omar— Omar shares no queue with Hedy, Alan or Priya, so their rows are disabledand their chips are gone. Nadia is on
shortswith him and stays live.Narrow View, 390px. Wraps, does not pan.
Two things that bite
people filter — that is the 2026-08-26 rule and it is right — so the count for two people who
share nothing is however many unfiled queues the house owns, which is at least one. The test
is
hasQueueFor, which asks only about queues that carry a roster. A count-based test wouldnever have fired once.
⚙and▾do not render in this app. Both are outside the Latin subset of Outfit thatvite.config.tspreloads, and⚙ Edit peoplehad been painting a tofu box on the livelanding. Both are inline SVGs now.
Checks
yarn workspace queuepilot-web test— 24 files, 344 tests, all pass (11 new).tsc --noEmitclean in web/ and e2e/.biome checkadds no finding; the 74 warnings arepre-existing
useExhaustiveDependenciesin files this branch does not touch.e2e/shot-queue-filter.tsrun onmainand on the branch. It prints what it measured:3 rows → 1 row,
?people=sven1 shelf and no rule → 6 rows with a rule.Screenshots are fixture data
The cast is the landing fixture's Ada, Grace and Linus plus six invented people the harness
adds — Sven, Hedy, Alan, Nadia, Omar and Priya. Nine, because a filter that does not scale
cannot be shown with three. AGENTS.md names them so the next harness reuses them.
Decisions
docs/decisions/2026-09-05-the-people-filter-answers-in-two-tiers-exact-then-also-in.mddocs/decisions/2026-09-05-the-filter-bar-is-quick-picks-plus-a-dropdown-and-a-dead-end-is-not-offered.md🤖 Generated with Claude Code