Repository navigation
feat(app-shell): the /data filter bar offers single-value relation fields, so Members View all filters by User - #13313
Merged
objectstack-fleet[bot] merged 2 commits intoOct 21, 2026
Conversation
…value relation fields ObjectDataPage derives its filter bar from the object definition because "View all" anchors no declared view (objectui#12741). It now offers single-value lookup, master_detail and user fields after the picklist fields, under the same four-field cap, through UserFilters' existing LookupValuePicker; a pick filters by the related record's id and persists in uf_* like the picklist filters. Multi-value relations stay out. Co-authored-by: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XVp19E1MYUTFM3dnkwz8gB
… location in an effect Co-authored-by: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XVp19E1MYUTFM3dnkwz8gB
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
|
objectstack-fleet
Bot
deleted the
claude/issue-13310-data-page-relation-filters
branch
October 21, 2026 10:25
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 #13310
Clause-②: no
What
ObjectDataPage(the/datasurface "View all" opens; it anchors no declared view, objectui#12741) derives its filter bar from the object definition. It derived picklist-like fields only. It now also offers single-value relation fields (lookup,master_detail,user), so an organization's Members "View all" page can be filtered by User (ruling F1 on objectstack-ai/objectstack#24815).deriveDataPageUserFilterFields: picklist fields first in declaration order (exactly the old set and order), then single-value relation fields in declaration order, under the unchangedMAX_USER_FILTERScap of 4. Hidden fields, unreadable fields andmultiple: truerelations are never offered.UserFilters' existingLookupValuePickerbranch (search by name; the query goes through the caller's data source); a pick emits[field, 'in', [id]], the id predicateListViewalready ANDs into the list query; the selection rides the existinguf_FIELDURL param.UserFilters.tsx,userFilterUrlState.tsandLookupValuePickerare untouched.Ruling 2 (cap and order). Measured:
sys_memberdeclaresorganization_id,user_idandrole, three fields, so the cap does not cost the Members page its User filter and the cap stays 4. Relations are ordered AFTER picklists so that an object whose picklists already fill the cap keeps exactly the bar it had; that order is pinned. On Members the bar reads Role, Organization, User.Pin (b), which of the two. The field IS offered, matching what
LookupValuePickeralready does: it scopes by asking the caller's data source, not by hiding the chip. An unreadable related object answers with a refusal and the picker lists no options (it shows the refusal text).Tests
New
packages/app-shell/src/views/ObjectDataPage.relationUserFilters-13310.test.tsx: the realObjectDataPage, withListViewreplaced by a stand-in that handsschema.userFilters, the restoreduf_*selections and the selection callback to the REALUserFiltersand realLookupValuePicker.user_id in [id]and keeps 1 row, a non-member keeps 0. Auser-typed field filters by id the same way.demo_vaultthrough the data source; the refusal leaves no options.multiple: trueuser field, amultiple: truelookup, a hidden lookup and an unreadable lookup are not offered.uf_user_id; a reload with that URL restores the condition and the resolved label; a staleuf_user_id=u_goneshowsu_gone, no error.Run on the tree committed as
76f01dd1a2(the final commit), under the shared verify lock: the new file plus the families naming the touched file (ObjectDataPage.*five files,userFilterUrlState.listState-11860), 7 files, 85 tests passed.@object-ui/app-shelltype-check(bothtsc --noEmitandtsconfig.test.json, which lists the new test) exit 0 after a turbo build of the@object-ui/app-shell^...closure. The fullpackages/app-shell/directory is declared to CI, not run locally.Ablation (through
ablation-replace.mjs, anchor hit 1 to 0):USER_FILTER_RELATION_TYPESemptied. Predicted: (a), (e) and the ordering case RED; (c) GREEN. Observed: 6 failed, 3 passed. Red: both (a) cases, (b), (d), (e), the relation-order case. Green: (c), the picklists-keep-their-slots case, the no-fields case. (b) and (d) also went red, which the prediction did not say: both assert the single-value relation chips are present (the field offered in b;assignee/vaultremaining in d), so they need the relation set too. Restore proved by blob hash:d8f37661c3feafter restore equals the HEAD blob,git diff HEADempty.Browser measurement (Done when)
A real stack: objectstack
origin/main28c9a2cb66examples/app-showcase(objectstack dev --seed-admin --freshon a private port), with this branch's console (apps/consolevite, proxied to it), driven by Playwright Chromium, signed in as the seeded admin. Data: the Default Organization; Ada Auditor (demo) removed from it through better-authorganization/remove-member, so she is a user who is not a member./apps/setup/sys_member/data?filter[organization_id]=org_mvhxp7nxzorku6glwith 2 records. Bar: Role, Organization, User.uf_user_id=AVv0T5ffUcGSwUccNvxX3YUU3zN5ysf0.uf_user_id=usr_showcase_auditor_demo.Gates (exit codes, final commit
76f01dd1a2)All 0:
check:phantom-deps,check:self-import,check:unreferenced-sources,check:doc-example-readers,check:handler-key-reads,check:side-effects-array,check:element-data-source-declaration,check:spec-symbols,check:action-forward-parity,check:designer-field-key-parity,check:icon-record-names,check:i18n-keys,check:i18n-drift,check:i18n-designer-parity,check:control-bytes,check:new-line-citations,check-hand-rolled-comment-mask.mjs,check-changeset-fixed.mjs,check-changeset-presence.mjs.eslint --no-inline-confignarrowed to the two changed source files: exit 0, 0 errors, 14 warnings, the same count theorigin/maincopy ofObjectDataPage.tsxproduces (one newonly-export-componentsfor the exported helper, oneno-explicit-anyremoved). The narrowing is a measurement: both files sit under the config's**/*.{ts,tsx}block; the file count is 2 from--format json; the config enables no type-aware linting (noparserOptions.project/projectService), so this diff cannot move a verdict on an untouched file. The repo-widepnpm lintis CI's.Acceptance notes
created_by,updated_byandowner_idlookups now become eligible after the declared fields, inside the same cap.sys_membercarries none.docs/adr/0055-parameterized-bare-data-surface.mdpoint 4 still says the bar derives from enum-ish fields. An ADR is a dated record, so it is not edited here; carrier: none..changeset/13310-data-page-relation-filters.md,@object-ui/app-shellpatch.The session for this change is
https://claude.ai/code/session_01XVp19E1MYUTFM3dnkwz8gB.Generated by Claude Code