Repository navigation
fix(plugin-list): a filter row with no value is not a filter, a date sort reads Oldest → Newest, one sort row per field, and an empty list says how to start - #28423
Merged
Conversation
…read Oldest → Newest, one sort row per field, and an empty list says how to start - A filter-panel row with no value is not counted on the badge, does not make the list "No matching records", and is not handed to the host's onFilterChange (so it is not stored as the user's list state). - SortBuilder reads an optional field type: date/datetime rows name the direction "Oldest → Newest"; a field another row holds is unavailable, "Add sort" seeds the first free field and disables when none is left. - The search-emptied empty state offers "Clear search". - The empty state offers Create whenever the host gives a create path and the user may create; an explicit addRecord.enabled: false still withholds it, and object-view hands no create path when Create is turned off. Co-Authored-By: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01L6bhgVW2q9rsHS1vCrQ8Q9
…ns to one row per field - A view that declares addRecord.enabled keeps its empty-state Create with or without a host handler, as before; a host create path now adds it. - The two removable-only controls read each field from its own row and expect "Add sort" to start on the first free field. - object-view's renderListView branch is host-only, and Studio folds its New into the list through it with showCreate: false, so its create path stays as it was. Co-Authored-By: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01L6bhgVW2q9rsHS1vCrQ8Q9
Co-Authored-By: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01L6bhgVW2q9rsHS1vCrQ8Q9
Co-Authored-By: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01L6bhgVW2q9rsHS1vCrQ8Q9
Contributor
Author
|
domain:ui#4 · os-sales · session_01L6bhgWqjXeTcS3jtug46Dv 维护者速读
席位意见:ACCEPT。「填完才算筛选」的判定和 席位核对 — ACCEPT · domain:ui#4 · Head-sha
|
This was referenced Oct 31, 2026
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.
Requested by Sales · project thread
Part of #27520 (rows 7 and 17 built; row 21 measured and not built because it no longer reproduces; the card's other open rows stay on it)
Clause-②: yes (widening:
@object-ui/i18ngainslist.clearSearch,sortBuilder.oldestFirstandsortBuilder.newestFirstin all ten locales, andSortBuilder'sfieldsentries take an optionaltype; no accept set moves)Metadata-protocol: none
维护者速读
addRecord.enabled。listNew)约束,作者显式写addRecord.enabled: false仍然隐藏。回滚即 revert 本 PR。ui/packages/plugin-list/src/ListView.tsx(appliedFilterGroup、emptyStateOffersCreate、onClearSearch);ui/packages/components/src/custom/sort-builder.tsx(takenElsewhere、directionLabels);ListView.toolbarRows-27520.test.tsx。pnpm --dir ui exec vitest run packages/plugin-list/src/__tests__/ListView.toolbarRows-27520.test.tsx packages/components/src/__tests__/sort-builder-date-direction-duplicates-27520.test.tsx→ 2 个文件 19 个用例全绿。What changes
Measured on
mainaf6ca001before any code, by reading the code and then pinning each item red through the realListView/SortBuilder:mainshownFilterCountcounted every row), made the list "No matching records", and was handed whole toonFilterChange, which the console stores as the user's list state (listPrefs.patchView)SortBuilderhad no field type, so every row read "A → Z"date/datetimerow reads "Oldest → Newest" / "Newest → Oldest";ListViewhands each sort field's typeonSearchChange(''))addRecord.enabled: true, which few views do, although the console handsonAddRecordexactly when its header New is offeredmayCreateallows it; an explicitaddRecord: { enabled: false }oruserActions.addRecordForm: falsestill withholds it; a view that declares the inline block keeps it as beforetitle={t('list.sittingInQueueHint')}in all ten packs and is drawn only on an object the server serves with its injectedqueuecolumn (objectHasOwnershipQueue), both since #27264 (2302b92b, an ancestor of the walkthrough'sc4c515ad)Not built here, reported: Studio's list-view sort (
ui/packages/app-shell/src/views/studio-design/ObjectListViewInspector.tsx, held by #28148) handsSortBuilderfields withouttype, so its date label stays "A → Z" until that file passestype: f.type. The duplicate refusal lives inSortBuilderitself, so Studio's sort gets it with no edit there.The search box's own clear (×) button is still unnamed; it is frozen in
iconOnlyButtonCensus-12143's backlog and is left to that card.Tests
ui/packages/components/src/__tests__/sort-builder-date-direction-duplicates-27520.test.tsx(8),ui/packages/plugin-list/src/__tests__/ListView.toolbarRows-27520.test.tsx(11). Each negative sits beside a control on the same rig.onFilterChangereceives the unfinished row, no "Clear search", noempty-state-add-record).ListView.sortRemovableOnly-11943.test.tsx, two controls that read the old duplicate behaviour ("Add sort" seeded the field the first row held; a field held by the other row was read from the first row's dropdown).vitest run packages/plugin-list/ packages/components/ packages/plugin-view/ packages/i18n/under the verify lock: 816 files, 6 reds in 4 files, all from this change's first cut (the two adapted controls; twoemptyStateLink-12270and oneObjectGallery.emptyState-12217case that read a declaredaddRecord.enabledwith no host handler, answered by keeping that leg; oneiconOnlyButtonCensus-12143count from an aria-label I then took back out). Those 7 files rerun green: 50/50.scripts/ablation-replace.mjs, each restored to the HEAD blob (git diff HEADempty after every leg): taken-elsewhere returns false → 1 red; date label test → false → 2 red; "Add sort" ignores held fields → 2 red; emit the whole group → 1 red; badge from the whole group → 3 red; sort fields untyped → 1 red; host create leg off → 1 red; clear search off → 1 red; user query counts unfinished rows → 1 red.Acceptance notes
@object-ui/plugin-viewObjectView.tsxwas added to the claim's surface (amendment 6543827414) for one line, and is left unchanged: itsrenderListViewbranch is entered only when a host passes that prop, and Studio's design surface folds "+ New" into the list through it withshowCreate: false, so withholdingonAddRecordthere would break Studio's New.ListViewwith the realFilterBuilder/SortBuilderand RadixSelect.Verification
All local readings at head
81af3395(the merge oforigin/main380a1078is in it).Derived gate families: 34 derived, 34 run, 0 NOT-MEASURED
node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstackderived 34 commands; each was run with stdin from/dev/nulland its exit code captured before any pipe. All 34 exited 0, among themnode scripts/check-sdui-manifest.mjs,pnpm check:nul-bytes,pnpm check:type-check-debtandpnpm --dir ui exec vitest run scripts/(169 files passed, 2 skipped; 4901 tests).--ranon the recorded list: "34 derived, 34 run, 0 NOT-MEASURED, 0 UNRUN … a DERIVED zero — all 34 recorded an exit code and none of them is 3".Lint, type-check, merge-tree
eslinton the changed sources, the two new tests, the adapted test andui/packages/i18n/src/locales/: 0 errors; 154 warnings, none on a changed line.pnpm --filter @object-ui/components --filter @object-ui/plugin-list --filter @object-ui/i18n run type-check(eachtsc --noEmit && tsc -p tsconfig.test.json): exit 0 after typing the new fixtures asFilterBuilderRow.git merge-tree --write-treeagainst the open PRs that share a file (feat(runtime,metadata-protocol,client,console): Studio publish takes a change note; item history names the person #28422 and feat(plugin-detail)!: a tab row under the record header; an open panel face is the active tab #28394, the ten locale packs) and the other open ui PRs (feat(fields): a lookup pick fills the fields its lookupAutofill declares, in the record form and the line-item grid #28322, feat(console): entering an app loads its metadata bundle once, and a record open reads no metadata #28321, feat(plugin-report): a report chart draws its seriesBy split #28305, fix(components): a field's Esc in the record drawer no longer steps the pane back or restores it from maximized #28294): exit 0, no conflict.CI check-runs: not started at the time of writing.
Generated by Claude Code
🤖 Generated with Claude Code
https://claude.ai/code/session_01L6bhgVW2q9rsHS1vCrQ8Q9