Skip to content

Commit 1adc5b9

Browse files
committed
refactor: convert groupedRows to signal input
Converts `groupedRows` and `groupRowsBy` to signal inputs. Introduces a new `_internalGroupedRows` which contains the combination of both inputs. BREAKING CHANGE: Previously, the `groupedRows` input was updated by the datatable, when `groupRowsBy` was used. This behavior was dropped. `groupedRows` will only contain application provided values. The table calculates internal the actual `groupedRows` without exposing them.
1 parent fc36697 commit 1adc5b9

File tree

3 files changed

+40
-59
lines changed

3 files changed

+40
-59
lines changed

projects/ngx-datatable/src/lib/components/body/body.component.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -284,7 +284,6 @@ export class DataTableBodyComponent<TRow extends Row = any> implements OnInit, O
284284
// TODO: Find a better way to handle default expansion state with signal input
285285
@Input() groupExpansionDefault?: boolean;
286286
readonly innerWidth = input.required<number>();
287-
readonly groupRowsBy = input<keyof TRow>();
288287
readonly virtualization = input<boolean>();
289288
readonly summaryRow = input<boolean>();
290289
readonly summaryPosition = input.required<string>();

projects/ngx-datatable/src/lib/components/datatable.component.html

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
[scrollbarH]="scrollbarH()"
99
[innerWidth]="_innerWidth"
1010
[offsetX]="_offsetX"
11-
[dealsWithGroup]="groupedRows !== undefined"
11+
[dealsWithGroup]="_internalGroupedRows() !== undefined"
1212
[columns]="_internalColumns()"
1313
[headerHeight]="headerHeight()"
1414
[reorderable]="reorderable()"
@@ -32,8 +32,7 @@
3232
<datatable-body
3333
tabindex="0"
3434
role="rowgroup"
35-
[groupRowsBy]="groupRowsBy"
36-
[groupedRows]="groupedRows"
35+
[groupedRows]="_internalGroupedRows()"
3736
[rows]="_internalRows()"
3837
[groupExpansionDefault]="groupExpansionDefault()"
3938
[scrollbarV]="scrollbarV()"
@@ -95,8 +94,8 @@
9594
</div>
9695
@if (footerHeight()) {
9796
<datatable-footer
98-
[rowCount]="groupedRows !== undefined ? _internalRows().length : rowCount"
99-
[groupCount]="groupedRows !== undefined ? rowCount : undefined"
97+
[rowCount]="_internalGroupedRows() !== undefined ? _internalRows().length : rowCount"
98+
[groupCount]="_internalGroupedRows() !== undefined ? rowCount : undefined"
10099
[pageSize]="pageSize"
101100
[offset]="offset"
102101
[footerHeight]="footerHeight()"

projects/ngx-datatable/src/lib/components/datatable.component.ts

Lines changed: 36 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -123,19 +123,7 @@ export class DatatableComponent<TRow extends Row = any>
123123
/**
124124
* This attribute allows the user to set the name of the column to group the data with
125125
*/
126-
@Input() set groupRowsBy(val: keyof TRow | undefined) {
127-
if (val) {
128-
this._groupRowsBy = val;
129-
if (this._groupRowsBy) {
130-
// creates a new array with the data grouped
131-
this.groupedRows = this.groupArrayBy(this.rows() ?? [], this._groupRowsBy);
132-
}
133-
}
134-
}
135-
136-
get groupRowsBy() {
137-
return this._groupRowsBy;
138-
}
126+
readonly groupRowsBy = input<keyof TRow>();
139127

140128
/**
141129
* This attribute allows the user to set a grouped array in the following format:
@@ -152,7 +140,7 @@ export class DatatableComponent<TRow extends Row = any>
152140
* ]}
153141
* ]
154142
*/
155-
@Input() groupedRows?: Group<TRow>[];
143+
readonly groupedRows = input<Group<TRow>[]>();
156144

157145
/**
158146
* Columns to be displayed.
@@ -677,7 +665,6 @@ export class DatatableComponent<TRow extends Row = any>
677665

678666
_offsetX = 0;
679667
_offset = 0;
680-
_groupRowsBy?: keyof TRow;
681668
readonly _internalRows = computed(() => {
682669
this._rowDiffCount(); // to trigger recalculation when row differ detects a change
683670
let rows = this.rows()?.slice() ?? [];
@@ -702,6 +689,36 @@ export class DatatableComponent<TRow extends Row = any>
702689

703690
return rows;
704691
});
692+
693+
readonly _internalGroupedRows = computed(() => {
694+
let groupedRows = this.groupedRows();
695+
const groupRowsBy = this.groupRowsBy();
696+
697+
if (!groupedRows && groupRowsBy) {
698+
this._rowDiffCount(); // to trigger recalculation when row differ detects a change
699+
groupedRows = this.groupArrayBy(this.rows() ?? [], groupRowsBy);
700+
}
701+
702+
if (!groupedRows) {
703+
// return here to prevent subscription to sorts when no grouping
704+
return undefined;
705+
}
706+
707+
const sorts = this.sorts();
708+
if (sorts.length && !this.externalSorting()) {
709+
if (groupedRows?.length) {
710+
groupedRows = sortGroupedRows(
711+
groupedRows,
712+
this._internalColumns(),
713+
sorts,
714+
sorts.find(sortColumns => sortColumns.prop === groupRowsBy)
715+
);
716+
}
717+
}
718+
719+
return groupedRows;
720+
});
721+
705722
// TODO: consider removing internal modifications of the columns.
706723
// This requires a different strategy for certain properties like width.
707724
readonly _internalColumns = linkedSignal(() =>
@@ -765,19 +782,6 @@ export class DatatableComponent<TRow extends Row = any>
765782
const rowDiffers = this.rowDiffer.diff(this.rows());
766783
if (rowDiffers || this.disableRowCheck()) {
767784
this._rowDiffCount.update(count => count + 1);
768-
// we don't sort again when ghost loader adds a dummy row
769-
if (
770-
!this.ghostLoadingIndicator() &&
771-
!this.externalSorting() &&
772-
this._internalColumns().length
773-
) {
774-
this.sortInternalRows();
775-
}
776-
777-
if (this._groupRowsBy && rowDiffers) {
778-
// If a column has been specified in _groupRowsBy create a new array with the data grouped by that row
779-
this.groupedRows = this.groupArrayBy(this.rows() ?? [], this._groupRowsBy);
780-
}
781785
if (rowDiffers) {
782786
queueMicrotask(() => {
783787
this._rowInitDone.set(true);
@@ -825,7 +829,7 @@ export class DatatableComponent<TRow extends Row = any>
825829
* (`fn(x) === fn(y)` instead of `x === y`)
826830
*/
827831
@Input() rowIdentity: (x: RowOrGroup<TRow>) => unknown = x => {
828-
if (this._groupRowsBy) {
832+
if (this.groupRowsBy()) {
829833
// each group in groupedRows are stored as {key, value: [rows]},
830834
// where key is the groupRowsBy index
831835
return (x as Group<TRow>).key ?? x;
@@ -1043,8 +1047,9 @@ export class DatatableComponent<TRow extends Row = any>
10431047
*/
10441048
calcRowCount(): number {
10451049
if (!this.externalPaging()) {
1046-
if (this.groupedRows) {
1047-
return this.groupedRows.length;
1050+
const groupedRows = this._internalGroupedRows();
1051+
if (groupedRows) {
1052+
return groupedRows.length;
10481053
} else {
10491054
return this._internalRows().length;
10501055
}
@@ -1150,13 +1155,6 @@ export class DatatableComponent<TRow extends Row = any>
11501155

11511156
this.sorts.set(event.sorts);
11521157

1153-
// this could be optimized better since it will resort
1154-
// the rows again on the 'push' detection...
1155-
if (!this.externalSorting()) {
1156-
// don't use normal setter so we don't resort
1157-
this.sortInternalRows();
1158-
}
1159-
11601158
// Always go to first page when sorting to see the newly sorted data
11611159
this.offset = 0;
11621160
this.bodyComponent.updateOffsetY(this.offset);
@@ -1239,19 +1237,4 @@ export class DatatableComponent<TRow extends Row = any>
12391237
ngOnDestroy() {
12401238
this._subscriptions.forEach(subscription => subscription.unsubscribe());
12411239
}
1242-
1243-
private sortInternalRows(): void {
1244-
if (this.groupedRows?.length) {
1245-
const sortOnGroupHeader = this.sorts()?.find(
1246-
sortColumns => sortColumns.prop === this._groupRowsBy
1247-
);
1248-
this.groupedRows = this.groupArrayBy(this.rows() ?? [], this._groupRowsBy!);
1249-
this.groupedRows = sortGroupedRows(
1250-
this.groupedRows,
1251-
this._internalColumns(),
1252-
this.sorts(),
1253-
sortOnGroupHeader
1254-
);
1255-
}
1256-
}
12571240
}

0 commit comments

Comments
 (0)