Repository navigation
fix(plugin-list): a held user filter does not narrow the fetch on a dataset-bound chart (objectui#10512) - #10597
Conversation
…ataset-bound chart (objectui#10512) objectui#10327 withholds the toolbar Filter builder and the UserFilters chips while a dataset-bound chart is on screen, but only the controls: a group the host restored at mount, or one set on a grid before a switch, still reached ListView's own fetch and so narrowed the record-count bar with nothing on screen to show or clear it. The applied user filter (appliedFilters / appliedUserFilterConditions) is now derived empty while datasetChartOnScreen, beside the held state, as searchTerm is beside searchInput (objectui#10326). The fetch, the export, the page-reset signature, selfQueryFilter and the empty-state copy read the applied values; the builder, its badge, the chips and the host write-back keep the held state, so a switch back applies it again. schema.filter stays applied. Each source is swapped only when it holds something, so a switch with nothing held re-issues no query (objectui#7394). Claude-Session: https://claude.ai/code/session_01KUxVUa7e39aNjhkKi1gsoy Co-authored-by: Claude <noreply@anthropic.com>
Also notes, in the switch pin, why the chip's own return is not asserted. Claude-Session: https://claude.ai/code/session_01KUxVUa7e39aNjhkKi1gsoy Co-authored-by: Claude <noreply@anthropic.com>
… (objectui#10512) Keeps the derivation from adding a no-explicit-any finding. Claude-Session: https://claude.ai/code/session_01KUxVUa7e39aNjhkKi1gsoy Co-authored-by: Claude <noreply@anthropic.com>
…lied-filter Claude-Session: https://claude.ai/code/session_01KUxVUa7e39aNjhkKi1gsoy Co-authored-by: Claude <noreply@anthropic.com>
|
changeset-claim-re-read
|
✅ Console Performance Budget
The eager closure is every chunk the entry reaches through static imports — what the browser fetches and parses before the app renders. The entry chunk on its own is a small fraction of it. 📦 Bundle Size Report
Size Limits
|
Contract reviewServed-tier: Refs: ① Derived judgments
② Semver level
Changeset prose, sentence by sentence against the diff:
Pending changesets naming ③ Boundary flags
Implemented-by: VERDICT: PASS |
Fixes #10512
Clause-②: no
What changes
objectui#10327 withholds the toolbar Filter builder and the
UserFilterschips while a dataset-boundchartis on screen (datasetChartOnScreen), but only the controls. A group the host restored at mount (initialFilters), or one set on a grid before an in-list switch, still reachedListView's own fetch, and so the record-count bar. This PR withholds the APPLIED user filter too, in the shape objectui#10326 gave Search (searchTermderived empty beside the heldsearchInput), as the triage ruled (comment 5829668693).appliedFilters/appliedUserFilterConditionsare derived beside the heldcurrentFilters/userFilterConditions: empty whiledatasetChartOnScreen, the held value otherwise.onFilterChangeis not called for the switch.schema.filteris not the user's filter and stays in the query.showFilters/showUserFilters) from objectui#10327 is unchanged: no diff line touches either flag.Readers of the user filter
Switched to the applied value:
buildEffectiveFilterin the fetch effect, and the effect's dependency list;buildEffectiveFilterin the export callback, and its dependency list (the client export writesdata, the fetch's own answer);pageResetSignature;selfQueryFilter, with no behaviour change: its consumers (the gantt, tree and object-bound chart nodes) are views on whichdatasetChartOnScreenis false, so applied equals held there, and the dataset node carries no filter (objectui#10327). Switched so that its comment, "the SAME effective filter this component's own fetch sends", stays literally true;hasActiveQuery, with no behaviour change (grid only, where applied equals held).Left on the held state, deliberately:
value, and its trigger'shasFiltershighlight and badge count: the control that shows and edits the held group, not rendered on the dataset chart;UserFilters, which keeps its own selection state and is not rendered on the dataset chart;onFilterChange,onUserFilterSelectionsChange), fired only by the controls, so the host's storage keeps the held state.H0, measured first (objectui
origin/maina506001)A component-level probe (not committed): the real
ListView, anobject-chartstand-in that records the node it is handed, a dataset-boundchartblock, andinitialFiltersrestoringstatus equals openover three rows. Readings on the base:dataset: task_ds, nofilterkey);ListView's fetch ran, 1 call, with$filter=["status","=","open"];1 record(3 rows unnarrowed);The fetch runs AND the count bar draws, so the narrowing is user-visible and the fix lands. ⛔ Not rendered in a browser: the count bar is
ListView's own DOM, independent of the chart renderer.Pins
ListView.datasetChartAppliedFilter-10512.test.tsxinpackages/plugin-list/src/__tests__, 6 cases. Each asserts the query the data source receives (the fake answers from the fields its$filternames, so the count bar reads a different number for a narrowed query):1 record.$filterin any call, the bar reads3 records,onFilterChangenot called.filterstays in the query on the dataset chart, alone: every call's$filterequals the base filter, the bar reads2 records.onFilterChangeis never called.Reverse verification (from the committed fix)
ListView.tsxchecked out at the basea506001(on-disk blob03798adequal to the base blob; 0 occurrences ofappliedFilterson disk), the pin run, then restored withgit checkout HEAD --under a trap (restored blobd86a5dbequal to the HEAD blob,git diff HEAD0 bytes):Tests 3 failed | 3 passed (6); red are cases 3, 4 and 5, green are the three controls;Tests 6 passed (6).Ablation (the objectui#7394 control can fail)
Predicted before running: an unconditional swap of the Filter group turns case 6 red and nothing else. Run through
ablation-replace.mjs(anchordatasetChartOnScreen && currentFilters.conditions && currentFilters.conditions.length > 0, 1 hit, anchor count 1 to 0, blobd86a5dbtod364171): exit 1,Tests 1 failed | 5 passed (6), the failed case is case 6. Restored: blob equal to HEAD,git diff HEADempty. Observed direction matches the prediction.Verification (final head
ad119b4, after mergingorigin/mainf5178a2)pnpm exec vitest run packages/plugin-list/ --maxWorkers=2: exit 0,Test Files 94 passed (94),Tests 1131 passed (1131).pnpm turbo run type-check --filter @object-ui/plugin-list --concurrency=2: exit 0,Tasks: 14 successful, 14 total, plugin-list a cache miss;tsconfig.test.jsonlists the new pin (--listFilesOnly, 1 hit).pnpm exec eslintonListView.tsxand the new pin: exit 0, 0 errors; per-rule warning counts onListView.tsxequal to the base file's (compared in one--format jsonrun).pnpm check:control-bytes,check:test-path-roots,check:vi-mock-specifiers,check:vi-mock-inherit,check:vi-mock-override-shape,check:new-line-citations(0 new citations),check:changeset-claims,check:pending-changeset-literals,check:shell-escape-residue,check:handler-key-reads,check:i18n-keys,check:unreferenced-sources: each exit 0.node scripts/check-changeset-presence.mjs,check-changeset-no-major.mjs,check-type-check-coverage.mjs,check-lint-coverage.mjs: each exit 0.pnpm lintand the fullpnpm testare CI's.check:changeset-claimsnames 7 pending changesets that mentionListView.tsx(7070-no-invented-gantt-date-fields,7499-gantt-non-axis-floors-omitted,7773-kanban-adapter-groupfield-write,7780-object-kanban-record-source,8990-object-kanban-groupby-optional,list-user-actions-collision-5398,listview-comment-pair-4559). Each paragraph was read; none is about how the user filter is applied, and none is made false by this diff.Changeset
.changeset/10512-dataset-chart-applied-filter.md,patchfor@object-ui/plugin-list.Acceptance notes
a506001with the same probe harness: toggle aUserFilterschip ON on a grid, switch to the dataset chart, switch back. The chip renders OFF again (its button carries the outline variant), whileListView's helduserFilterConditionsstill sends["priority","!=",null]and the count bar reads2 records.UserFilterskeeps its selection in its own state, and the objectui#10327 gate unmounts it on the dataset chart. This PR leaves the grid leg exactly as it was (applied equals held there); the pin deliberately does not assert the chip's return. Reported to the seat as a separate finding. Dropdown and tab chips were not measured.FilterOperatorError). A held group whose every row is unfinished therefore still swaps on a switch into the dataset chart, and that one switch re-issues a query equal to the one before it.The session that implemented this:
https://claude.ai/code/session_01KUxVUa7e39aNjhkKi1gsoy(domain:ui seat 5 dispatch).Generated by Claude Code