Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions .changeset/25858-grid-group-order-by.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
---
'@object-ui/plugin-grid': patch
---

fix(plugin-grid): a grouped grid orders a level's groups by its `grouping.fields[].orderBy`, the label still from `field`

Clause-②: no
Metadata-protocol: none

A view grouped by `period_label` with `orderBy: 'period_start', order: 'desc'` now lists one header per label in descending `period_start` order, where it used to list the labels as text (`Nov 2026` before `Oct 2026` before `Q1 2027`).

- **Server-grouped grid.** The grid forwards the level's `orderBy` into the group header query, so the query carries the `min` (asc) / `max` (desc) column the spec compiles for it, and sorts the header rows by the column `listViewGroupOrderColumn` names. An `orderBy` field the user may not read is not forwarded: that level orders by its own key.
- **Rows handed in whole.** Each group's order value is the `min` (asc) or `max` (desc) of `orderBy` over its rows, so a group sits where its first row would if the rows were sorted by `orderBy`.
- **Both paths.** A group with no `orderBy` value 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 without `orderBy`, or with `orderBy` naming the grouping field itself, orders exactly as before.
2 changes: 1 addition & 1 deletion scripts/sdui-manifest.record.json
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,6 @@
"ui/packages/types"
],
"registrySources": 922,
"registrySourcesSha256": "ad9e0875b83f339e03c528fc3be774592615dfdc5ee5fe9becc4376ddb5f0d52"
"registrySourcesSha256": "7734fe6bc3763fe8318db624b9e0dd4c48b2dc7b15bf2a3fb1f78e46bb8d959e"
}
}
17 changes: 14 additions & 3 deletions ui/packages/plugin-grid/src/ObjectGrid.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3430,18 +3430,29 @@ export const ObjectGrid: React.FC<ObjectGridComponentProps> = ({
// [objectui#7189] The entries the SERVER groups by: the render grouping less
// any key this principal may not read (see `groupingKeyReadable`). Keyed on
// the names, so a host rebuilding `grouping` every render re-asks nothing.
// [objectstack#25786] A level's `orderBy` rides along — the header query
// compiles its `min` / `max` column from it — under the same read gate: an
// `orderBy` this principal may not read is dropped, and the level orders by
// its own key, since the header row would carry that field's value and the
// group order would disclose it.
const serverGroupingKey = serverGroupedFetch
? JSON.stringify(
usableGroupingFields(groupingForRender?.fields)
.filter((gf) => groupingKeyReadable(gf.field))
.map((gf) => [gf.field, gf.order ?? null, gf.collapsed ?? null]),
.map((gf) => [
gf.field,
gf.order ?? null,
gf.collapsed ?? null,
gf.orderBy && groupingKeyReadable(gf.orderBy) ? gf.orderBy : null,
]),
)
: '[]';
const serverGroupingFields = React.useMemo(
() => (JSON.parse(serverGroupingKey) as Array<[string, 'asc' | 'desc' | null, boolean | null]>)
.map(([field, order, collapsed]) => ({
() => (JSON.parse(serverGroupingKey) as Array<[string, 'asc' | 'desc' | null, boolean | null, string | null]>)
.map(([field, order, collapsed, orderBy]) => ({
field,
...(order ? { order } : {}),
...(orderBy !== null ? { orderBy } : {}),
...(collapsed !== null ? { collapsed } : {}),
})),
[serverGroupingKey],
Expand Down
Loading
Loading