@gridkitjs/core 0.7.0 → 0.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +345 -7
- package/dist/index.js +469 -8
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -77,7 +77,10 @@ function buildKeyShortcuts(capabilities) {
|
|
|
77
77
|
// handle to size the column to its content — same gate as the nudge
|
|
78
78
|
// shortcuts, since both are resize actions.
|
|
79
79
|
capabilities.resizable ? "Alt+ArrowLeft Alt+ArrowRight Alt+Enter" : "",
|
|
80
|
-
capabilities.sortable ? "Alt+ArrowUp" : ""
|
|
80
|
+
capabilities.sortable ? "Alt+ArrowUp" : "",
|
|
81
|
+
// Down rather than reusing Up: it reads as "drill into groups", and Up is
|
|
82
|
+
// already sort's own mnemonic on the same header.
|
|
83
|
+
capabilities.groupable ? "Alt+ArrowDown" : ""
|
|
81
84
|
].filter(Boolean).join(" ");
|
|
82
85
|
}
|
|
83
86
|
function accessDotted(obj, path) {
|
|
@@ -95,7 +98,21 @@ function clampFocus(focus, rowCount, columnCount) {
|
|
|
95
98
|
)
|
|
96
99
|
};
|
|
97
100
|
}
|
|
98
|
-
function
|
|
101
|
+
function noRowsSkippable() {
|
|
102
|
+
return false;
|
|
103
|
+
}
|
|
104
|
+
function skipSkippableRows(rowIndex, direction, rowCount, isSkippableRow, fallback) {
|
|
105
|
+
let next = rowIndex;
|
|
106
|
+
while (next >= 0 && next < rowCount && isSkippableRow(next)) {
|
|
107
|
+
const stepped = next + direction;
|
|
108
|
+
if (stepped < HEADER_ROW || stepped >= rowCount) {
|
|
109
|
+
return fallback;
|
|
110
|
+
}
|
|
111
|
+
next = stepped;
|
|
112
|
+
}
|
|
113
|
+
return next;
|
|
114
|
+
}
|
|
115
|
+
function nextFocusForKey(key, modifiers, focus, rowCount, columnCount, pageSize, isSkippableRow = noRowsSkippable) {
|
|
99
116
|
if (modifiers.altKey) {
|
|
100
117
|
return null;
|
|
101
118
|
}
|
|
@@ -108,19 +125,64 @@ function nextFocusForKey(key, modifiers, focus, rowCount, columnCount, pageSize)
|
|
|
108
125
|
if (modifiers.ctrlKey) return null;
|
|
109
126
|
return { rowIndex, columnIndex: columnIndex + 1 };
|
|
110
127
|
case "ArrowUp":
|
|
111
|
-
return {
|
|
128
|
+
return {
|
|
129
|
+
rowIndex: skipSkippableRows(
|
|
130
|
+
rowIndex - 1,
|
|
131
|
+
-1,
|
|
132
|
+
rowCount,
|
|
133
|
+
isSkippableRow,
|
|
134
|
+
rowIndex
|
|
135
|
+
),
|
|
136
|
+
columnIndex
|
|
137
|
+
};
|
|
112
138
|
case "ArrowDown":
|
|
113
|
-
return {
|
|
139
|
+
return {
|
|
140
|
+
rowIndex: skipSkippableRows(
|
|
141
|
+
rowIndex + 1,
|
|
142
|
+
1,
|
|
143
|
+
rowCount,
|
|
144
|
+
isSkippableRow,
|
|
145
|
+
rowIndex
|
|
146
|
+
),
|
|
147
|
+
columnIndex
|
|
148
|
+
};
|
|
114
149
|
// Ctrl takes Home and End to the grid's ends rather than the row's, which
|
|
115
150
|
// is the one place Ctrl is navigation rather than reorder.
|
|
116
151
|
case "Home":
|
|
117
152
|
return modifiers.ctrlKey ? { rowIndex: HEADER_ROW, columnIndex: 0 } : { rowIndex, columnIndex: 0 };
|
|
118
153
|
case "End":
|
|
119
|
-
return modifiers.ctrlKey ? {
|
|
154
|
+
return modifiers.ctrlKey ? {
|
|
155
|
+
rowIndex: skipSkippableRows(
|
|
156
|
+
rowCount - 1,
|
|
157
|
+
-1,
|
|
158
|
+
rowCount,
|
|
159
|
+
isSkippableRow,
|
|
160
|
+
rowIndex
|
|
161
|
+
),
|
|
162
|
+
columnIndex: columnCount - 1
|
|
163
|
+
} : { rowIndex, columnIndex: columnCount - 1 };
|
|
120
164
|
case "PageUp":
|
|
121
|
-
return {
|
|
165
|
+
return {
|
|
166
|
+
rowIndex: skipSkippableRows(
|
|
167
|
+
rowIndex - pageSize,
|
|
168
|
+
-1,
|
|
169
|
+
rowCount,
|
|
170
|
+
isSkippableRow,
|
|
171
|
+
rowIndex
|
|
172
|
+
),
|
|
173
|
+
columnIndex
|
|
174
|
+
};
|
|
122
175
|
case "PageDown":
|
|
123
|
-
return {
|
|
176
|
+
return {
|
|
177
|
+
rowIndex: skipSkippableRows(
|
|
178
|
+
rowIndex + pageSize,
|
|
179
|
+
1,
|
|
180
|
+
rowCount,
|
|
181
|
+
isSkippableRow,
|
|
182
|
+
rowIndex
|
|
183
|
+
),
|
|
184
|
+
columnIndex
|
|
185
|
+
};
|
|
124
186
|
default:
|
|
125
187
|
return null;
|
|
126
188
|
}
|
|
@@ -302,6 +364,7 @@ function resolveColumnWidths(columns, sizing, options) {
|
|
|
302
364
|
label: resolveColumnLabel(column),
|
|
303
365
|
resizable: column.resizable ?? options?.resizable ?? false,
|
|
304
366
|
reorderable: column.reorderable ?? options?.reorderable ?? false,
|
|
367
|
+
groupByDraggable: column.groupByDraggable ?? options?.groupByDraggable ?? false,
|
|
305
368
|
alignment: column.alignment ?? alignmentForType(column.type ?? "string")
|
|
306
369
|
};
|
|
307
370
|
});
|
|
@@ -655,6 +718,137 @@ function filterRows(rows, filter, columns) {
|
|
|
655
718
|
);
|
|
656
719
|
}
|
|
657
720
|
|
|
721
|
+
// src/util/grouping.ts
|
|
722
|
+
function groupRowId(path) {
|
|
723
|
+
return JSON.stringify(path);
|
|
724
|
+
}
|
|
725
|
+
function bucketKey(value) {
|
|
726
|
+
if (value === null || value === void 0) {
|
|
727
|
+
return "\0empty";
|
|
728
|
+
}
|
|
729
|
+
if (value instanceof Date) {
|
|
730
|
+
return `\0date:${String(value.getTime())}`;
|
|
731
|
+
}
|
|
732
|
+
switch (typeof value) {
|
|
733
|
+
case "string":
|
|
734
|
+
case "number":
|
|
735
|
+
case "boolean":
|
|
736
|
+
case "bigint":
|
|
737
|
+
case "symbol":
|
|
738
|
+
return `\0${typeof value}:${String(value)}`;
|
|
739
|
+
case "function":
|
|
740
|
+
return "\0function";
|
|
741
|
+
default:
|
|
742
|
+
return `\0object:${JSON.stringify(value)}`;
|
|
743
|
+
}
|
|
744
|
+
}
|
|
745
|
+
function partitionByValue(rows, column, direction) {
|
|
746
|
+
const buckets = /* @__PURE__ */ new Map();
|
|
747
|
+
for (const row of rows) {
|
|
748
|
+
const value = accessDotted(row.row, column.field);
|
|
749
|
+
const key = bucketKey(value);
|
|
750
|
+
const bucket = buckets.get(key);
|
|
751
|
+
if (bucket === void 0) {
|
|
752
|
+
buckets.set(key, { value, rows: [row] });
|
|
753
|
+
} else {
|
|
754
|
+
bucket.rows.push(row);
|
|
755
|
+
}
|
|
756
|
+
}
|
|
757
|
+
const groups = [...buckets.values()];
|
|
758
|
+
groups.sort((a, b) => {
|
|
759
|
+
const result = compareValues(a.value, b.value, column.type);
|
|
760
|
+
return direction === "asc" ? result : -result;
|
|
761
|
+
});
|
|
762
|
+
return groups;
|
|
763
|
+
}
|
|
764
|
+
function buildLevel(rows, levels, parentPath, expansion, byId, out) {
|
|
765
|
+
const level = levels[0];
|
|
766
|
+
if (level === void 0) {
|
|
767
|
+
out.push(...rows);
|
|
768
|
+
return;
|
|
769
|
+
}
|
|
770
|
+
const column = byId.get(level.columnId);
|
|
771
|
+
if (column === void 0) {
|
|
772
|
+
out.push(...rows);
|
|
773
|
+
return;
|
|
774
|
+
}
|
|
775
|
+
const rest = levels.slice(1);
|
|
776
|
+
const groups = partitionByValue(rows, column, level.direction ?? "asc");
|
|
777
|
+
for (const group of groups) {
|
|
778
|
+
const path = [...parentPath, group.value];
|
|
779
|
+
const groupId = groupRowId(path);
|
|
780
|
+
const expanded = !expansion.includes(groupId);
|
|
781
|
+
const header = {
|
|
782
|
+
kind: "group",
|
|
783
|
+
groupId,
|
|
784
|
+
level: parentPath.length,
|
|
785
|
+
columnId: level.columnId,
|
|
786
|
+
value: group.value,
|
|
787
|
+
path,
|
|
788
|
+
expanded,
|
|
789
|
+
count: group.rows.length,
|
|
790
|
+
// Renumbered globally once `groupRows` has the whole flattened array —
|
|
791
|
+
// a header has no row of its own to carry a dataset position, so
|
|
792
|
+
// `datasetIndex` takes the same renumbered value `rowIndex` does.
|
|
793
|
+
rowIndex: -1,
|
|
794
|
+
datasetIndex: -1,
|
|
795
|
+
// Set by `withGroupAggregates`, downstream of grouping — empty here
|
|
796
|
+
// since `groupRows` itself never knows about `AggregateState`.
|
|
797
|
+
aggregates: /* @__PURE__ */ new Map()
|
|
798
|
+
};
|
|
799
|
+
out.push(header);
|
|
800
|
+
if (expanded) {
|
|
801
|
+
buildLevel(group.rows, rest, path, expansion, byId, out);
|
|
802
|
+
}
|
|
803
|
+
}
|
|
804
|
+
}
|
|
805
|
+
function groupRows(rows, groupBy, expansion, columns) {
|
|
806
|
+
if (groupBy.length === 0) {
|
|
807
|
+
return rows;
|
|
808
|
+
}
|
|
809
|
+
const byId = new Map(columns.map((entry) => [entry.id, entry.column]));
|
|
810
|
+
const active = groupBy.filter((entry) => byId.has(entry.columnId));
|
|
811
|
+
if (active.length === 0) {
|
|
812
|
+
return rows;
|
|
813
|
+
}
|
|
814
|
+
const out = [];
|
|
815
|
+
buildLevel(rows, active, [], expansion, byId, out);
|
|
816
|
+
return out.map((entry, index) => {
|
|
817
|
+
if ("kind" in entry) {
|
|
818
|
+
return entry.rowIndex === index && entry.datasetIndex === index ? entry : { ...entry, rowIndex: index, datasetIndex: index };
|
|
819
|
+
}
|
|
820
|
+
return entry.rowIndex === index ? entry : { ...entry, rowIndex: index };
|
|
821
|
+
});
|
|
822
|
+
}
|
|
823
|
+
function toggleGroupExpansion(expansion, groupId) {
|
|
824
|
+
return expansion.includes(groupId) ? expansion.filter((id) => id !== groupId) : [...expansion, groupId];
|
|
825
|
+
}
|
|
826
|
+
function expandAllGroups(expansion) {
|
|
827
|
+
return expansion.length === 0 ? expansion : [];
|
|
828
|
+
}
|
|
829
|
+
function collapseAllGroups(rows) {
|
|
830
|
+
return rows.filter((entry) => "kind" in entry).map((entry) => entry.groupId);
|
|
831
|
+
}
|
|
832
|
+
function moveGroupByBefore(groupBy, columnId, beforeColumnId) {
|
|
833
|
+
if (columnId === beforeColumnId) {
|
|
834
|
+
return groupBy;
|
|
835
|
+
}
|
|
836
|
+
const without = groupBy.filter((entry) => entry.columnId !== columnId);
|
|
837
|
+
const moved = groupBy.find((entry) => entry.columnId === columnId) ?? {
|
|
838
|
+
columnId
|
|
839
|
+
};
|
|
840
|
+
const target = beforeColumnId === null ? without.length : without.findIndex((entry) => entry.columnId === beforeColumnId);
|
|
841
|
+
if (target === -1) {
|
|
842
|
+
return groupBy;
|
|
843
|
+
}
|
|
844
|
+
const next = [...without];
|
|
845
|
+
next.splice(target, 0, moved);
|
|
846
|
+
return next.length === groupBy.length && next.every((entry, index) => entry === groupBy[index]) ? groupBy : next;
|
|
847
|
+
}
|
|
848
|
+
function movesGroupBy(groupBy, columnId, beforeColumnId) {
|
|
849
|
+
return moveGroupByBefore(groupBy, columnId, beforeColumnId) !== groupBy;
|
|
850
|
+
}
|
|
851
|
+
|
|
658
852
|
// src/util/rows.ts
|
|
659
853
|
function resolveShownRows(rows, filter, sort, columns) {
|
|
660
854
|
return sortRows(filterRows(rows, filter, columns), sort, columns);
|
|
@@ -691,6 +885,262 @@ function resolveCell(rowsById, columns, cell) {
|
|
|
691
885
|
value: accessDotted(entry.row, column.column.field)
|
|
692
886
|
};
|
|
693
887
|
}
|
|
888
|
+
|
|
889
|
+
// src/util/paging.ts
|
|
890
|
+
function unitsOf(rows) {
|
|
891
|
+
const units = [];
|
|
892
|
+
let start = 0;
|
|
893
|
+
let openedByGroup = false;
|
|
894
|
+
for (let index = 0; index < rows.length; index++) {
|
|
895
|
+
const entry = rows[index];
|
|
896
|
+
if (entry === void 0) {
|
|
897
|
+
continue;
|
|
898
|
+
}
|
|
899
|
+
const isTopLevelHeader = "kind" in entry && entry.kind === "group" && entry.level === 0;
|
|
900
|
+
const isBoundary = index !== start && (isTopLevelHeader || !openedByGroup);
|
|
901
|
+
if (isBoundary) {
|
|
902
|
+
units.push({ start, end: index });
|
|
903
|
+
start = index;
|
|
904
|
+
openedByGroup = isTopLevelHeader;
|
|
905
|
+
} else if (index === start) {
|
|
906
|
+
openedByGroup = isTopLevelHeader;
|
|
907
|
+
}
|
|
908
|
+
}
|
|
909
|
+
if (start < rows.length) {
|
|
910
|
+
units.push({ start, end: rows.length });
|
|
911
|
+
}
|
|
912
|
+
return units;
|
|
913
|
+
}
|
|
914
|
+
function paginateRows(rows, pagination) {
|
|
915
|
+
const pageSize = Math.max(1, pagination.pageSize);
|
|
916
|
+
const units = unitsOf(rows);
|
|
917
|
+
const pageCount = Math.ceil(units.length / pageSize);
|
|
918
|
+
if (pageCount === 0) {
|
|
919
|
+
return { rows: [], pageCount: 0, pageIndex: 0 };
|
|
920
|
+
}
|
|
921
|
+
const pageIndex = Math.min(Math.max(pagination.pageIndex, 0), pageCount - 1);
|
|
922
|
+
const firstUnit = units[pageIndex * pageSize];
|
|
923
|
+
const lastUnit = units[Math.min(pageIndex * pageSize + pageSize, units.length) - 1];
|
|
924
|
+
if (firstUnit === void 0 || lastUnit === void 0) {
|
|
925
|
+
return { rows: [], pageCount, pageIndex };
|
|
926
|
+
}
|
|
927
|
+
const page = rows.slice(firstUnit.start, lastUnit.end);
|
|
928
|
+
const renumbered = page.map(
|
|
929
|
+
(entry, index) => entry.rowIndex === index ? entry : { ...entry, rowIndex: index }
|
|
930
|
+
);
|
|
931
|
+
return { rows: renumbered, pageCount, pageIndex };
|
|
932
|
+
}
|
|
933
|
+
|
|
934
|
+
// src/util/paginationWindow.ts
|
|
935
|
+
function paginationWindow(currentPage, pageCount, options) {
|
|
936
|
+
if (pageCount <= 0) {
|
|
937
|
+
return [];
|
|
938
|
+
}
|
|
939
|
+
const boundaryCount = Math.max(0, options?.boundaryCount ?? 1);
|
|
940
|
+
const siblingCount = Math.max(0, options?.siblingCount ?? 1);
|
|
941
|
+
const current = Math.min(Math.max(currentPage, 1), pageCount);
|
|
942
|
+
const pages = /* @__PURE__ */ new Set();
|
|
943
|
+
for (let page = 1; page <= Math.min(boundaryCount, pageCount); page++) {
|
|
944
|
+
pages.add(page);
|
|
945
|
+
}
|
|
946
|
+
for (let page = Math.max(pageCount - boundaryCount + 1, 1); page <= pageCount; page++) {
|
|
947
|
+
pages.add(page);
|
|
948
|
+
}
|
|
949
|
+
for (let page = Math.max(current - siblingCount, 1); page <= Math.min(current + siblingCount, pageCount); page++) {
|
|
950
|
+
pages.add(page);
|
|
951
|
+
}
|
|
952
|
+
const sorted = Array.from(pages).sort((a, b) => a - b);
|
|
953
|
+
const entries = [];
|
|
954
|
+
let previous;
|
|
955
|
+
for (const page of sorted) {
|
|
956
|
+
if (previous !== void 0) {
|
|
957
|
+
if (page - previous === 2) {
|
|
958
|
+
entries.push(previous + 1);
|
|
959
|
+
} else if (page - previous > 2) {
|
|
960
|
+
entries.push("ellipsis");
|
|
961
|
+
}
|
|
962
|
+
}
|
|
963
|
+
entries.push(page);
|
|
964
|
+
previous = page;
|
|
965
|
+
}
|
|
966
|
+
return entries;
|
|
967
|
+
}
|
|
968
|
+
|
|
969
|
+
// src/util/aggregation.ts
|
|
970
|
+
function isEmpty2(value) {
|
|
971
|
+
return value === null || value === void 0;
|
|
972
|
+
}
|
|
973
|
+
function toNumber(value) {
|
|
974
|
+
return Number(value);
|
|
975
|
+
}
|
|
976
|
+
function distinctKey(value) {
|
|
977
|
+
if (isEmpty2(value)) {
|
|
978
|
+
return "\0empty";
|
|
979
|
+
}
|
|
980
|
+
if (value instanceof Date) {
|
|
981
|
+
return `\0date:${String(value.getTime())}`;
|
|
982
|
+
}
|
|
983
|
+
switch (typeof value) {
|
|
984
|
+
case "string":
|
|
985
|
+
case "number":
|
|
986
|
+
case "boolean":
|
|
987
|
+
case "bigint":
|
|
988
|
+
case "symbol":
|
|
989
|
+
return `\0${typeof value}:${String(value)}`;
|
|
990
|
+
case "function":
|
|
991
|
+
return "\0function";
|
|
992
|
+
default:
|
|
993
|
+
return `\0object:${JSON.stringify(value)}`;
|
|
994
|
+
}
|
|
995
|
+
}
|
|
996
|
+
function reduceBuiltIn(rows, fn, column) {
|
|
997
|
+
if (fn === "count") {
|
|
998
|
+
return rows.length;
|
|
999
|
+
}
|
|
1000
|
+
const field = column?.column.field;
|
|
1001
|
+
const values = field === void 0 ? [] : rows.map((row) => accessDotted(row, field));
|
|
1002
|
+
switch (fn) {
|
|
1003
|
+
case "sum": {
|
|
1004
|
+
let total = 0;
|
|
1005
|
+
for (const value of values) {
|
|
1006
|
+
if (isEmpty2(value)) continue;
|
|
1007
|
+
total += toNumber(value);
|
|
1008
|
+
}
|
|
1009
|
+
return total;
|
|
1010
|
+
}
|
|
1011
|
+
case "avg": {
|
|
1012
|
+
const present = values.filter((value) => !isEmpty2(value));
|
|
1013
|
+
if (present.length === 0) return void 0;
|
|
1014
|
+
const total = present.reduce(
|
|
1015
|
+
(acc, value) => acc + toNumber(value),
|
|
1016
|
+
0
|
|
1017
|
+
);
|
|
1018
|
+
return total / present.length;
|
|
1019
|
+
}
|
|
1020
|
+
case "min":
|
|
1021
|
+
case "max": {
|
|
1022
|
+
const type = column?.column.type;
|
|
1023
|
+
let result;
|
|
1024
|
+
for (const value of values) {
|
|
1025
|
+
if (isEmpty2(value)) continue;
|
|
1026
|
+
if (result === void 0) {
|
|
1027
|
+
result = value;
|
|
1028
|
+
continue;
|
|
1029
|
+
}
|
|
1030
|
+
const comparison = compareValues(value, result, type);
|
|
1031
|
+
if (fn === "min" ? comparison < 0 : comparison > 0) {
|
|
1032
|
+
result = value;
|
|
1033
|
+
}
|
|
1034
|
+
}
|
|
1035
|
+
return result;
|
|
1036
|
+
}
|
|
1037
|
+
case "countDistinct": {
|
|
1038
|
+
const seen = /* @__PURE__ */ new Set();
|
|
1039
|
+
for (const value of values) {
|
|
1040
|
+
if (isEmpty2(value)) continue;
|
|
1041
|
+
seen.add(distinctKey(value));
|
|
1042
|
+
}
|
|
1043
|
+
return seen.size;
|
|
1044
|
+
}
|
|
1045
|
+
}
|
|
1046
|
+
}
|
|
1047
|
+
function keyOf(spec) {
|
|
1048
|
+
return spec.id ?? spec.columnId;
|
|
1049
|
+
}
|
|
1050
|
+
function computeAggregates(rows, specs, columns) {
|
|
1051
|
+
const results = /* @__PURE__ */ new Map();
|
|
1052
|
+
if (specs.length === 0) {
|
|
1053
|
+
return results;
|
|
1054
|
+
}
|
|
1055
|
+
const byId = new Map(columns.map((entry) => [entry.id, entry]));
|
|
1056
|
+
for (const spec of specs) {
|
|
1057
|
+
const value = typeof spec.fn === "function" ? spec.fn(rows) : reduceBuiltIn(rows, spec.fn, byId.get(spec.columnId));
|
|
1058
|
+
results.set(keyOf(spec), value);
|
|
1059
|
+
}
|
|
1060
|
+
return results;
|
|
1061
|
+
}
|
|
1062
|
+
function leafDescendantsOf(flatRows, path, groupBy, byId) {
|
|
1063
|
+
const keys = path.map((value) => bucketKey(value));
|
|
1064
|
+
return flatRows.filter(
|
|
1065
|
+
(row) => keys.every((key, level) => {
|
|
1066
|
+
const columnId = groupBy[level]?.columnId;
|
|
1067
|
+
const column = columnId === void 0 ? void 0 : byId.get(columnId);
|
|
1068
|
+
if (column === void 0) return false;
|
|
1069
|
+
return bucketKey(accessDotted(row.row, column.field)) === key;
|
|
1070
|
+
})
|
|
1071
|
+
).map((row) => row.row);
|
|
1072
|
+
}
|
|
1073
|
+
function appendAggregatedSpan(displayRows, start, levelFloor, flatRows, groupBy, byId, specs, columns, display, out) {
|
|
1074
|
+
let index = start;
|
|
1075
|
+
while (index < displayRows.length) {
|
|
1076
|
+
const entry = displayRows[index];
|
|
1077
|
+
if (entry === void 0) {
|
|
1078
|
+
index++;
|
|
1079
|
+
continue;
|
|
1080
|
+
}
|
|
1081
|
+
if (levelFloor !== null && "kind" in entry && entry.kind === "group" && entry.level <= levelFloor) {
|
|
1082
|
+
break;
|
|
1083
|
+
}
|
|
1084
|
+
index++;
|
|
1085
|
+
if (!("kind" in entry) || entry.kind !== "group") {
|
|
1086
|
+
out.push(entry);
|
|
1087
|
+
continue;
|
|
1088
|
+
}
|
|
1089
|
+
const leaves = leafDescendantsOf(flatRows, entry.path, groupBy, byId);
|
|
1090
|
+
const aggregates = computeAggregates(leaves, specs, columns);
|
|
1091
|
+
const withAggregates = { ...entry, aggregates };
|
|
1092
|
+
out.push(withAggregates);
|
|
1093
|
+
index = appendAggregatedSpan(
|
|
1094
|
+
displayRows,
|
|
1095
|
+
index,
|
|
1096
|
+
entry.level,
|
|
1097
|
+
flatRows,
|
|
1098
|
+
groupBy,
|
|
1099
|
+
byId,
|
|
1100
|
+
specs,
|
|
1101
|
+
columns,
|
|
1102
|
+
display,
|
|
1103
|
+
out
|
|
1104
|
+
);
|
|
1105
|
+
if (display === "row") {
|
|
1106
|
+
const summary = {
|
|
1107
|
+
kind: "group-summary",
|
|
1108
|
+
groupId: entry.groupId,
|
|
1109
|
+
level: entry.level,
|
|
1110
|
+
rowIndex: -1,
|
|
1111
|
+
datasetIndex: -1,
|
|
1112
|
+
aggregates
|
|
1113
|
+
};
|
|
1114
|
+
out.push(summary);
|
|
1115
|
+
}
|
|
1116
|
+
}
|
|
1117
|
+
return index;
|
|
1118
|
+
}
|
|
1119
|
+
function withGroupAggregates(displayRows, flatRows, groupBy, specs, columns, display = "inline") {
|
|
1120
|
+
if (specs.length === 0) {
|
|
1121
|
+
return displayRows;
|
|
1122
|
+
}
|
|
1123
|
+
const byId = new Map(columns.map((entry) => [entry.id, entry.column]));
|
|
1124
|
+
const out = [];
|
|
1125
|
+
appendAggregatedSpan(
|
|
1126
|
+
displayRows,
|
|
1127
|
+
0,
|
|
1128
|
+
null,
|
|
1129
|
+
flatRows,
|
|
1130
|
+
groupBy,
|
|
1131
|
+
byId,
|
|
1132
|
+
specs,
|
|
1133
|
+
columns,
|
|
1134
|
+
display,
|
|
1135
|
+
out
|
|
1136
|
+
);
|
|
1137
|
+
return out.map((entry, position) => {
|
|
1138
|
+
if ("kind" in entry) {
|
|
1139
|
+
return entry.rowIndex === position && entry.datasetIndex === position ? entry : { ...entry, rowIndex: position, datasetIndex: position };
|
|
1140
|
+
}
|
|
1141
|
+
return entry.rowIndex === position ? entry : { ...entry, rowIndex: position };
|
|
1142
|
+
});
|
|
1143
|
+
}
|
|
694
1144
|
export {
|
|
695
1145
|
DEFAULT_COLUMN_SIZES,
|
|
696
1146
|
HEADER_ROW,
|
|
@@ -706,19 +1156,28 @@ export {
|
|
|
706
1156
|
clampFocus,
|
|
707
1157
|
clearAllFilters,
|
|
708
1158
|
clearSelection,
|
|
1159
|
+
collapseAllGroups,
|
|
709
1160
|
compareValues,
|
|
1161
|
+
computeAggregates,
|
|
710
1162
|
defineColumnsFromRows,
|
|
711
1163
|
diffSelection,
|
|
1164
|
+
expandAllGroups,
|
|
712
1165
|
filterQueryFor,
|
|
713
1166
|
filterRows,
|
|
714
1167
|
fitColumnsToWidth,
|
|
715
1168
|
getColumnId,
|
|
1169
|
+
groupRowId,
|
|
1170
|
+
groupRows,
|
|
716
1171
|
intentOf,
|
|
717
1172
|
isSameCell,
|
|
718
1173
|
matchesQuery,
|
|
719
1174
|
moveColumnBefore,
|
|
1175
|
+
moveGroupByBefore,
|
|
720
1176
|
movesColumn,
|
|
1177
|
+
movesGroupBy,
|
|
721
1178
|
nextFocusForKey,
|
|
1179
|
+
paginateRows,
|
|
1180
|
+
paginationWindow,
|
|
722
1181
|
resolveCell,
|
|
723
1182
|
resolveColumnConstraints,
|
|
724
1183
|
resolveColumnLabel,
|
|
@@ -741,7 +1200,9 @@ export {
|
|
|
741
1200
|
sortRows,
|
|
742
1201
|
toggleCellSelection,
|
|
743
1202
|
toggleColumnSort,
|
|
1203
|
+
toggleGroupExpansion,
|
|
744
1204
|
toggleSelection,
|
|
745
|
-
totalColumnWidth
|
|
1205
|
+
totalColumnWidth,
|
|
1206
|
+
withGroupAggregates
|
|
746
1207
|
};
|
|
747
1208
|
//# sourceMappingURL=index.js.map
|