Skip to content

Commit 1dbec82

Browse files
chore: java data helper group sorting (#4791)
1 parent ad89ea3 commit 1dbec82

File tree

1 file changed

+32
-6
lines changed

1 file changed

+32
-6
lines changed

examples-standalone/kendoangular-java-integration/backend/src/main/java/telerik/demo/datasource/QueryableExtensions.java

Lines changed: 32 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -48,9 +48,34 @@ public static <T> DataSourceResult toDataSourceResult(List<T> data, DataSourceRe
4848
// Get total count after filtering (before paging)
4949
long total = filteredData.size();
5050

51-
// Apply sorting
51+
// Apply sorting - need to combine group sorting with regular sorting
52+
List<SortDescriptor> sortDescriptors = new ArrayList<>();
53+
54+
// First, add sorts from group descriptors (groups take precedence)
55+
if (request.getGroup() != null && !request.getGroup().isEmpty()) {
56+
for (GroupDescriptor group : request.getGroup()) {
57+
SortDescriptor sort = new SortDescriptor();
58+
sort.setField(group.getField());
59+
// Use group's dir if specified, otherwise default to ascending
60+
sort.setDir(group.getDir() != null && !group.getDir().isEmpty() ? group.getDir() : "asc");
61+
sortDescriptors.add(sort);
62+
}
63+
}
64+
65+
// Then add regular sort descriptors (if they don't conflict with group sorting)
5266
if (request.getSort() != null && !request.getSort().isEmpty()) {
53-
filteredData = applySort(filteredData, request.getSort());
67+
for (SortDescriptor sort : request.getSort()) {
68+
boolean alreadySorted = sortDescriptors.stream()
69+
.anyMatch(s -> s.getField().equals(sort.getField()));
70+
if (!alreadySorted) {
71+
sortDescriptors.add(sort);
72+
}
73+
}
74+
}
75+
76+
// Apply the combined sorting
77+
if (!sortDescriptors.isEmpty()) {
78+
filteredData = applySort(filteredData, sortDescriptors);
5479
}
5580

5681
// Apply grouping (grouping should NOT be affected by paging unless groupPaging is enabled)
@@ -471,14 +496,16 @@ private static <T> List<GroupResult> applyGrouping(List<T> data, List<GroupDescr
471496
}
472497

473498
GroupDescriptor currentGroup = groupDescriptors.get(level);
499+
500+
// Use LinkedHashMap to preserve insertion order (data is already sorted)
474501
Map<Object, List<T>> grouped = data.stream()
475502
.collect(Collectors.groupingBy(item -> {
476503
try {
477504
return getFieldValue(item, currentGroup.getField());
478505
} catch (Exception e) {
479506
return null;
480507
}
481-
}));
508+
}, LinkedHashMap::new, Collectors.toList()));
482509

483510
List<GroupResult> results = new ArrayList<>();
484511
boolean hasMoreGroups = level + 1 < groupDescriptors.size();
@@ -489,22 +516,21 @@ private static <T> List<GroupResult> applyGrouping(List<T> data, List<GroupDescr
489516
groupResult.setValue(entry.getKey());
490517

491518
if (hasMoreGroups) {
492-
// Recursively group
519+
// Recursively group nested levels
493520
List<GroupResult> subGroups = applyGrouping(entry.getValue(), groupDescriptors, level + 1);
494521
groupResult.setItems(subGroups);
495522
groupResult.setHasSubgroups(true);
496-
// Count total items in all subgroups
497523
int totalItems = subGroups.stream()
498524
.mapToInt(g -> g.getItemCount() != null ? g.getItemCount() : 0)
499525
.sum();
500526
groupResult.setItemCount(totalItems);
501527
} else {
528+
// Leaf level - store the actual items
502529
groupResult.setItems(entry.getValue());
503530
groupResult.setHasSubgroups(false);
504531
groupResult.setItemCount(entry.getValue().size());
505532
}
506533

507-
// Calculate aggregates for this group
508534
if (currentGroup.getAggregates() != null && !currentGroup.getAggregates().isEmpty()) {
509535
List<AggregateDescriptor> aggregateDescriptors = currentGroup.getAggregates().stream()
510536
.map(af -> {

0 commit comments

Comments
 (0)