Repository navigation
fix(app-shell): a view-tab switch starts the next view with the quick filters its own URL carries (objectui#11992) - #11998
Merged
Conversation
… filters its own URL carries (objectui#11992) The console object page read the `uf_FIELD` quick-filter selections once per page mount, through a `useState` initializer over `window.location`. A view switch keeps the page mounted and remounts the list, whose `UserFilters` restore them at that mount, so every view after the first restored the first view's selections while its address bar showed none. The selections are now read from the router's current location once per list identity (object + view), the identity `listSeedRef` already seeds on, and handed to `ListView` under the same name. Claude-Session: https://claude.ai/code/session_01MgfduSkFrfM3eorB3UGfAU Co-authored-by: Claude <noreply@anthropic.com>
…sence, so tsc narrows them (objectui#11992) `tsc --noEmit` refused the conditional read of the per-identity ref (TS18048, possibly undefined). Once `listIdentityKey` is set, the block above it has already made the held entry that identity's, so the read keys on the identity's presence alone. Claude-Session: https://claude.ai/code/session_01MgfduSkFrfM3eorB3UGfAU Co-authored-by: Claude <noreply@anthropic.com>
Contributor
✅ 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
|
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.
Fixes #11992
Clause-②: no
What changed
The console object page handed
ListViewtheuf_FIELDquick-filter selections throughinitialUfSelectionsinpackages/app-shell/src/views/ObjectView.tsx. It was auseStateinitializer overwindow.location.search, so the page read the selections once per PAGE mount. A view-tab switch keeps the page mounted and remountsListView, whose key is the object and the view. The remountedUserFiltersthen restored the FIRST view's selections from that captured value, while the new view's address bar carried nouf_param.initialUfSelectionsis now read from the router's current location (searchParams) once per list identity. That identity islistIdentityKey: the same object and view thatlistSeedRefseeds the Filter panel, search and sort on (objectui#11915), and thatrenderListViewkeys the list on. The value is held in a ref per identity, so the list's own chip writes do not rebuild the list schema. The variable's name, its hand-off toListView(userFilterSelections={initialUfSelections}) and therenderListViewdependency list are unchanged. The diff stays in theinitialUfSelectionsdeclaration, with no helper.Producer, measured: this page, not
plugin-list.UserFiltersreadsinitialSelectionsonly in its ownuseStateinitializer. It applies restored values to the query on mount and does not report them throughonSelectionsChange. So the stale value handed to it was the whole carry-over, and nothing wrote it to the URL.The dispatch's hypotheses, measured
0bbb67b9a. Onqa?uf_priority=urgentfollowed by theqbtab, the list query onqbcarried["priority","=","urgent"]. The reverse was broken as well: onqbfollowed by a link toqa?uf_priority=urgent, the list queried no filter, because the capture from the first mount held none.UserFilters(above) is not where the carry-over comes from.6eb2c9fac(below).qbpath with an empty query string, andwindow.history.lengthgrows by exactly one. That is the same at base, under the ablation, and with the fix: the pin is green in all three.Pins
New file
packages/app-shell/src/views/ObjectView.ufViewSwitch-11992.test.tsx, 6 tests. It renders this page,plugin-view'sObjectViewwith its tab bar andplugin-list'sListViewwith itsUserFiltersfor real, and reads the list query at the data source. The switch is a click on the tab bar's ownview-tab-qbbutton. The router is aBrowserRouter, as in the console, so the page's location andwindow.locationare one thing here as they are in production. Every URL reading in the harness asserts that they are equal. AMemoryRouterdoes not movewindow.location, and the measurement on objectui#11860 had to set it by hand for that reason.qa?uf_priority=urgentapplies it: query, chip count and URL.qa?uf_priority=urgentfollowed by theqbtab: no quick filter in the query, on the chip, or in the URL.qbfollowed by a link toqa?uf_priority=urgentrestores the filter.qa?uf_priority=urgent, thenqb, then Back restores the filter.Ablation
The fix was committed first. Then
objectstack/scripts/ablation-replace.mjsin wrap mode put the once-per-page-mount capture back verbatim (theuseStateinitializer overwindow.location.search), under its restore trap. The test subject is imported fromsrcdirectly (./ObjectView), so there is nodistleg.6eb2c9fac: anchor 1 to 0, blob912960d4f7a5to86e98c562fe0. Predicted before the run: 4 failed and 2 passed, with the control and H3 green. Measured:Tests 4 failed | 2 passed (6), with the red ones being pins 2, 3, 4 and 5. Restore: blob after restore equals blob at HEAD (912960d4f7a5), andgit diff HEADis empty.f3c33636fmeasured the same4 failed | 2 passed (6), with the same restore proof.Gates, all at
6eb2c9fac(git rev-parse --short HEADafter the last commit)pnpm exec vitest run --maxWorkers=2and passed as two invocations. It contains every test file that namesObjectView,userFilter,uf_orlistUrlState(git grep -l -Eover*.test.tsand*.test.tsx: 326 files), the new pin file, and the two scanners the dispatch named (packages/core/src/utils/__tests__/column-identity.ratchet.test.tsandscripts/__tests__/one-authority-per-exported-name-6273.test.ts).scripts/__tests__(137 files):Test Files 137 passed (137),Tests 1835 passed (1835).Test Files 191 passed (191),Tests 4472 passed (4472).pnpm --filter @object-ui/app-shell type-check(tsc --noEmit && tsc -p tsconfig.test.json), run after the dependency closure was built (turbo run build --filter=@object-ui/app-shell^...,Tasks: 28 successful, 28 total): exit 0.tsc -p tsconfig.test.json --listFilesOnlylists the new test file.node scripts/check-changeset-presence.mjs: "2 source file(s) of 1 released package(s) changed, and this change declares 1 changeset(s)".node scripts/check-changeset-no-major.mjs: "No changeset declares amajorbump."pnpm check:new-line-citations:VERDICT new-cross-file-line-citations: 0 new citation(s).pnpm check:control-bytes: OK.pnpm exec eslinton both touched source files: 0 errors (warnings only, of the repo's existingno-explicit-anykind).Acceptance notes
ownListParamsRef. Stripping the chip from the URL there would be a new write on that path, and none was added (H3).uf_params does not remount the list and is not re-read. This is the same once-per-identity bound as objectui#11915's seed.InterfaceListPage.tsxandObjectDataPage.tsxkeep the same mount-time capture overwindow.location.search. Whether either one remounts its list under a page that stays mounted was not measured. Carrier: none; noted, not filed.848fe53e5(git merge-tree --write-tree) is clean, exit 0.Session:
https://claude.ai/code/session_01MgfduSkFrfM3eorB3UGfAUGenerated by Claude Code