/** * Server-side GROUP row model (SSRM grouping) - the first-class * companion to `createServerDataSource`. Grouping, aggregation, and lazy * expansion all flow through the SAME `ServerDataSource.getRows` contract: * * - The request carries `groupBy` (the columns grouped on) and `groupKeys` * (the path of the group being expanded). While `groupKeys.length < * groupBy.length` the server returns GROUP rows (one per distinct key at * that level, carrying the key + aggregate values); at the bottom level it * returns the leaf rows under that path. * - Expanding a group is just another `getRows` with `groupKeys` set to that * group's path. This controller owns the group tree: expand / collapse, * per-node lazy fetch + cache, race-safety, and flattening to a display * list the grid renders (group rows with an expander, leaves underneath). * * Headless and framework-agnostic on purpose: render from `state.displayRows` * and call `toggleGroup` from the group cell's expander. */ import type { ServerAggregation, ServerDataSource, ServerDisplayRow, ServerFilterModel, ServerGroupRow, ServerSortModel } from './server-data-source'; export type ServerGroupState = { /** The flattened tree: top-level groups, with expanded groups' children spliced in. */ displayRows: ServerDisplayRow[]; groupBy: string[]; /** True during the initial top-level fetch (before the root has ever loaded). */ loading: boolean; /** The rejection from the last failed top-level fetch, else null. */ error: unknown; sortModel: ServerSortModel; filterModel: ServerFilterModel; /** Ids (JSON of the path) of the currently expanded groups. */ expandedGroups: string[]; }; export type ServerGroupControllerOptions = { /** Columns to group on, outer to inner. Empty in `treeData` mode. */ groupBy?: string[]; /** Value columns to roll up per group. */ aggregations?: ServerAggregation[]; /** Max children fetched per group in one request. Default 200. */ pageSize?: number; /** * Self-referential tree mode: instead of grouping flat rows by columns, each * row is a node whose children are fetched on expand. Requires `getRowId` * (the node id, which builds the `groupKeys` path) and `hasChildren` (whether * a node is expandable). `getRows` receives `groupKeys` = the path to the * node being expanded, and returns that node's direct children. */ treeData?: boolean; /** Node id, used to build the `groupKeys` path. Required in `treeData` mode. */ getRowId?: (row: TData) => string; /** Whether a node can be expanded. Required in `treeData` mode. */ hasChildren?: (row: TData) => boolean; /** Emit a subtotal "footer" row after each expanded group's children. */ groupFooters?: boolean; /** Placeholder rows shown while a group's first block is loading. Default 3. */ skeletonRows?: number; onChange: (state: ServerGroupState) => void; }; export type ServerGroupController = { /** (Re-)fetch the tree from the top. Call once to load the first level. */ refresh(): void; setSort(sortModel: ServerSortModel): void; setFilter(filterModel: ServerFilterModel): void; /** Change the grouping columns. Collapses everything and reloads the top level. */ setGroupBy(groupBy: string[]): void; /** Expand or collapse a group row (from its expander). */ toggleGroup(row: ServerGroupRow): void; expandGroup(path: string[]): void; collapseGroup(path: string[]): void; /** Fetch the next block of a group's children (intra-group paging). */ loadMoreChildren(path: string[]): void; isExpanded(path: string[]): boolean; getState(): ServerGroupState; /** Stop accepting in-flight responses. Call on unmount. */ dispose(): void; }; /** * Map a `ServerGroupState.displayRows` to grid rows: each row's data spread at * the top level (so normal `field` columns show group subtotals on group rows * and cell values on leaves) plus a `__group` marker the built-in `SvGroupCell` * reads to draw the expander + indentation. Feed the result to ``. */ export type ServerGroupGridRow = TData & { __group: ServerDisplayRow; }; export declare function serverGroupRows(state: ServerGroupState | undefined | null): ServerGroupGridRow[]; /** * Build the `serverGroup` prop for `` from a controller, so the grid's * built-in tree keyboard (ArrowRight / ArrowLeft expand / collapse) and treegrid * a11y work with no app-level key handling. Reads the `__group` marker that * `serverGroupRows` attaches. Usage: ``. */ export declare function serverGroupNav(ctl: ServerGroupController): { isGroup: (row: ServerGroupGridRow) => boolean; level: (row: ServerGroupGridRow) => number; expanded: (row: ServerGroupGridRow) => boolean; onToggle: (row: ServerGroupGridRow) => void; }; export declare function createServerGroupModel(source: ServerDataSource, options: ServerGroupControllerOptions): ServerGroupController;