Skip to content

Sort groups by aggregate, key, or column (#1303)#1304

Merged
mstijak merged 3 commits into
masterfrom
feature/sort-groups-by-aggregate
Jun 22, 2026
Merged

Sort groups by aggregate, key, or column (#1303)#1304
mstijak merged 3 commits into
masterfrom
feature/sort-groups-by-aggregate

Conversation

@mstijak

@mstijak mstijak commented Jun 22, 2026

Copy link
Copy Markdown
Member

Closes #1303.

Summary

GroupAdapter could only order groups by key, ascending. This adds first-class group sorting by aggregate, key, or name — both declaratively and via interactive column sorting.

Changes

GroupAdapter

  • Grouping levels now accept sortField + sortDirection, or a sorters array. Sort fields resolve against the group's key fields, aggregate aliases and $name, so sortField: "total" orders groups by an aggregate. Precedence: explicit comparersortField/sorters → implicit key order (unchanged default).
  • New sortGroupsBySorters flag: the active record sorters reorder groups too. A column only reorders groups at levels where its field is a group key or aggregate — sorting any other column leaves the configured group order untouched.
  • Sort fields are read straight off the GroupResult (no per-comparison cloning of group data).

Grid

  • New sortGroups prop (wired to sortGroupsBySorters), so sorting a column header reorders groups when the field maps to a group key/aggregate. Ignored when preserveGroupOrder is set.
  • GridGroupingConfig typed with sortField/sortDirection/sorters.

Docs & example

  • Extended the grouping example with sortGroups and sortable columns.
  • New "Sorting Groups" section and config-table updates across grouping, grid, and group-adapter docs.

Tests

Black-box tests through GroupAdapter.getRecords covering aggregate/key sortField, multi-field sorters, default key order, explicit-comparer precedence, column-sort reordering, and the non-group-column fallback. yarn test → 525 passing; yarn check-types clean.

Notes

  • Changelog intentionally left out — to be added with the release.
  • A leading -/+ string-shorthand for direction was considered but dropped: it's not an existing CxJS idiom. Direction is expressed via the object form (sortField/sortDirection), consistent with the rest of the framework.

mstijak added 3 commits June 22, 2026 11:28
NumberField never applied the `clear` state class nor reserved
right padding, so the value sat under the clear icon when showClear
was on. Mirror TextField's handling.
Group sorting could only order by key, ascending. This adds declarative
group sorting and column-driven group sorting.

- GroupAdapter grouping levels accept `sortField`/`sortDirection` or a
  `sorters` array, resolved against the group key fields, aggregate
  aliases and name. An explicit `comparer` still wins.
- New `sortGroups` flag on Grid (maps to GroupAdapter
  `sortGroupsBySorters`): sorting a column whose field is a group key or
  aggregate reorders the groups; other columns leave group order intact.
- Sort fields read straight off the GroupResult, no per-comparison cloning.
- Docs and the grouping example updated; tests added.

Closes #1303
- Move `ExtendedSorter` to `data/comparer` (the module that defines the
  sorting contract), re-exporting it from `ArrayAdapter` so `cx/ui`
  consumers are unaffected. It is now also available from `cx/data`.
- Drop `comparer.ts`'s private, duplicate `Sorter` interface; the helpers
  now use the shared `ExtendedSorter`.
- Simplify `sort()` to take `ExtendedSorter[]` instead of the redundant
  `Sorter[] | ExtendedSorter[]` union (a plain Sorter is already assignable).
- Widen `Sorter.value` to `Prop<any>`: it is resolved via `getSelector`
  and is commonly a binding, not just an accessor function.
@mstijak mstijak merged commit b7aeeed into master Jun 22, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Support sorting groups by aggregate value in GroupAdapter / Grid

1 participant