Repository navigation
fix(plugin-grid): order a grouped grid's groups by the level's orderBy - #25977
Merged
Merged
Conversation
A level naming grouping.fields[].orderBy now orders its groups by that field: the server path forwards orderBy into the header query and reads the min/max column listViewGroupOrderColumn names; the client path folds min (asc) / max (desc) from each group's rows. Nulls sort last in both directions; ties fall back to the key comparison in the same direction. Claude-Session: https://claude.ai/code/session_01Baqv5mDLFH63hvh9G4YGn5 Co-authored-by: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Baqv5mDLFH63hvh9G4YGn5 Co-authored-by: Claude <noreply@anthropic.com>
…om text order Claude-Session: https://claude.ai/code/session_01Baqv5mDLFH63hvh9G4YGn5 Co-authored-by: Claude <noreply@anthropic.com>
… edit sdui.manifest.json is byte-identical; only the recorded source hash moves. Claude-Session: https://claude.ai/code/session_01Baqv5mDLFH63hvh9G4YGn5 Co-authored-by: Claude <noreply@anthropic.com>
Contributor
Author
席位核对 · ACCEPT · seat
|
This was referenced Oct 26, 2026
os-steve
pushed a commit
that referenced
this pull request
Oct 26, 2026
Resolve the scripts/sdui-manifest.record.json conflict with #25977 by regenerating the record with node scripts/gen-sdui-manifest-node.mjs. Claude-Session: https://claude.ai/code/session_01C6T942afhqAP5w9XBmfTDC Co-authored-by: Claude <noreply@anthropic.com>
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 Steve · project thread
Fixes #25858
Clause-②: no
Metadata-protocol: none
What changes
A grouped grid now orders a level's groups by the level's
grouping.fields[].orderBy(the spec key landed in #25828), while the group label still comes fromfield. A list grouped byperiod_labelwithorderBy: 'period_start', order: 'desc'renders one header per label in descendingperiod_startorder, the undated group last.Measured on
origin/mainbefore the change, the key was dropped in three places, not one:ObjectGrid.tsx(serverGroupingKey): the server grouping entries were rebuilt as field, order and collapsed only, soorderBynever left the grid.useServerGrouping.ts(groupingOf): the header query was compiled from field names alone, socompileListViewGroupQuerynever added themin_FIELD/max_FIELDnode and the header rows never carried an order value.useGroupedData.ts(compareGroupEntries): noorderByhandling on either sort path.The card named (3) and allowed (1) and (2) "if the header column is not forwarded"; it was not, so all three are fixed here.
ObjectGridforwardsorderBy;useServerGroupHeaderscompiles each level with itsorderByandorder(a level ordered by its own key still carries the name alone, so flipping itsorderre-asks nothing; a changedorderByre-asks, since it changes the answer's columns).useGroupedDatareads each level's order value off the columnlistViewGroupOrderColumn(grouping, depth)names, never a re-derived alias.min(asc) ormax(desc) oforderByover its rows, folded once before the sort.compareGroupEntriesorders by the order value first, inorder; anullvalue sorts last in both directions; equal values fall back to the existing key comparison (declared option order, then label) in the same direction. A level withoutorderBy, or withorderBynaming the grouping field, is unchanged. Values are reduced with@object-ui/core'sgetSortValue/compareSortValues; a numeric string (a driver's decimal) is read as the number it spells, so3.10does not sort after3.9.orderBythe principal may not read (groupingKeyReadable, the gate the grouping key already passes) is not forwarded, and that level orders by its own key: the header row would otherwise carry the hidden field's min/max and the group order would disclose it.UsableGroupingFieldderives from@objectstack/spec/ui'sGroupingConfig, and the@object-ui/typeszod faces takeGroupingConfigSchemaby reference, soorderBywas already on both.scripts/sdui-manifest.record.jsonis re-recorded becausecheck-sdui-manifesthashes theui/packagesregistry sources;sdui.manifest.jsonitself is byte-identical (106 components, sha256 1f6e1ccb925a…).Tests
New
ui/packages/plugin-grid/src/__tests__/groupOrderBy-25858.test.tsx, 18 tests:Q4 2025,Sep 2026,Oct 2026,Q4 2026,Nov 2026,Q1 2027, plus an undated period) on header rows produced by answeringcompileListViewGroupQuery's own output, both directions, the undated group last in both; an outer level of a two-level grouping; counts unchanged;min-for-asc /max-for-desc over a group whose rows span values, and numeric-string values;ObjectGrid: the header query carriesmax_period_startand the painted headers read in descending start; rows handed in order the same way;orderBy(label order, option order, and a header query whose only aggregation iscount), andorderBynaming the grouping field itself.Runs (code tree
b3b58b69; the final head19f3f573adds only the sdui record file):pnpm exec vitest run packages/plugin-grid/src/__tests__/groupOrderBy-25858.test.tsx(fromui/): Test Files 1 passed, Tests 18 passed.pnpm exec vitest run packages/plugin-grid/(fromui/): Test Files 248 passed (248), Tests 2222 passed (2222).pnpm --filter @object-ui/plugin-grid run type-check(tsc --noEmit && tsc -p tsconfig.test.json): exit 0.Ablations, each through
scripts/ablation-replace.mjs(anchor hit 1, restored blob equal to HEAD,git diff HEADempty), none left in the tree:compareGroupEntriesdisabled: 10 failed / 8 passed (everyorderByassertion red, every control green);headerLevelOfforwarding noorderBy: 1 failed (theObjectGridserver-path test);ObjectGridforwarding noorderBy: 1 failed (the same test).Gates
node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstackat19f3f573derives 47 families; all 47 were run and exited 0, and--ranwith per-command exit codes answers "47 run, 0 NOT-MEASURED (a DERIVED zero)".check-sdui-manifestwas red before the record was regenerated (node scripts/gen-sdui-manifest-node.mjs) and is green after. The type-check lanes and the CI-owned whole-tree families are left to this PR's checks.Acceptance notes
valueprovider): a grid orListViewthat fetches its own rows over a source with no header query refuses grouping (objectui#10881), so no projection change is needed fororderBythere; such hosts' rows already carry every field.forecast.view.tsedit. Its follow-up is to drop the outerperiod_startlevel once this lands.🤖 Generated with Claude Code
https://claude.ai/code/session_01Baqv5mDLFH63hvh9G4YGn5
Generated by Claude Code