Skip to content

Commit 99e8359

Browse files
committed
adding pagination support
1 parent 1c873af commit 99e8359

15 files changed

+267
-30
lines changed
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,3 @@
11
export * from './lib/comparison-tool.component';
2+
export * from './lib/comparison-tool.helpers';
3+
export * from './lib/comparison-tool.variables';

libs/explorers/comparison-tool/src/lib/comparison-tool-table/base-table/base-table.component.html

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
<div class="base-table-container">
2-
@let pagination = shouldPaginate() && data().length !== 0 ? paginationConfig : null;
2+
@let pagination = shouldPaginate() ? paginationConfig : null;
33
<p-table
44
#table
55
[value]="data()"
66
[totalRecords]="totalRecords() ?? data().length"
77
[lazy]="true"
8+
(onLazyLoad)="onLazyLoad($event)"
89
[customSort]="true"
910
(sortFunction)="sortCallback($event)"
1011
sortMode="multiple"
@@ -14,7 +15,7 @@
1415
showGridlines
1516
[paginator]="!!pagination"
1617
[paginatorStyleClass]="pagination?.paginatorStyleClass ?? ''"
17-
[rows]="pagination?.rows ?? undefined"
18+
[rows]="pagination?.rows"
1819
[showCurrentPageReport]="!!pagination?.showCurrentPageReport"
1920
[currentPageReportTemplate]="pagination?.currentPageReportTemplate ?? ''"
2021
[showPageLinks]="pagination?.showPageLinks ?? null"

libs/explorers/comparison-tool/src/lib/comparison-tool-table/base-table/base-table.component.ts

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
import { Component, inject, input, ViewEncapsulation } from '@angular/core';
1+
import { Component, inject, input, output, ViewEncapsulation } from '@angular/core';
22
import { ComparisonToolService } from '@sagebionetworks/explorers/services';
33
import { CommaSeparatePipe } from '@sagebionetworks/explorers/util';
44
import { SortEvent } from 'primeng/api';
5-
import { TableModule } from 'primeng/table';
5+
import { TableModule, TableLazyLoadEvent } from 'primeng/table';
66
import { TooltipModule } from 'primeng/tooltip';
77
import { ComparisonToolTableLinkComponent } from '../comparison-tool-table-link/comparison-tool-table-link.component';
88
import { HeatmapCircleComponent } from '../heatmap-circle/heatmap-circle.component';
@@ -41,6 +41,8 @@ export class BaseTableComponent {
4141
columnWidth = input<string>('auto');
4242
totalRecords = input<number | undefined>(undefined);
4343

44+
lazyLoad = output<TableLazyLoadEvent>();
45+
4446
paginationConfig: PaginationOptions = {
4547
rows: 10,
4648
showCurrentPageReport: true,
@@ -52,4 +54,8 @@ export class BaseTableComponent {
5254
sortCallback(event: SortEvent) {
5355
this.comparisonToolService.setSort(event);
5456
}
57+
58+
onLazyLoad(event: TableLazyLoadEvent) {
59+
this.lazyLoad.emit(event);
60+
}
5561
}

libs/explorers/comparison-tool/src/lib/comparison-tool-table/comparison-tool-table.component.html

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,5 +67,6 @@
6767
[shouldShowNoDataMessage]="true"
6868
[columnWidth]="columnWidth"
6969
[totalRecords]="totalResultsCount()"
70+
(lazyLoad)="onLazyLoad($event)"
7071
/>
7172
</div>

libs/explorers/comparison-tool/src/lib/comparison-tool-table/comparison-tool-table.component.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import {
55
ElementRef,
66
HostListener,
77
inject,
8+
output,
89
viewChild,
910
ViewEncapsulation,
1011
} from '@angular/core';
@@ -18,6 +19,7 @@ import {
1819
import { DownloadDomImageComponent } from '@sagebionetworks/explorers/ui';
1920
import { SvgIconComponent } from '@sagebionetworks/explorers/util';
2021
import { TooltipModule } from 'primeng/tooltip';
22+
import { TableLazyLoadEvent } from 'primeng/table';
2123
import { BaseTableComponent } from './base-table/base-table.component';
2224
import { ComparisonToolColumnsComponent } from './comparison-tool-columns/comparison-tool-columns.component';
2325

@@ -57,6 +59,8 @@ export class ComparisonToolTableComponent implements AfterViewInit {
5759
pinnedData = this.comparisonToolService.pinnedData;
5860
unpinnedData = this.comparisonToolService.unpinnedData;
5961

62+
lazyLoad = output<TableLazyLoadEvent>();
63+
6064
columnWidth = 'auto';
6165
primaryColumnWidth = 300;
6266

@@ -123,4 +127,8 @@ export class ComparisonToolTableComponent implements AfterViewInit {
123127
const count = Math.max(nCols, 5);
124128
return Math.ceil((tableWidth - this.primaryColumnWidth) / count) + 'px';
125129
}
130+
131+
onLazyLoad(event: TableLazyLoadEvent) {
132+
this.lazyLoad.emit(event);
133+
}
126134
}

libs/explorers/comparison-tool/src/lib/comparison-tool.component.html

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,16 @@
33
<div id="loading">
44
<explorers-loading-container [count]="loadingResultsCount()"></explorers-loading-container>
55
</div>
6-
} @else {
6+
}
7+
8+
<div [style.display]="isLoading() ? 'none' : 'block'">
79
<explorers-comparison-tool-header (filterToggle)="toggleFilterPanel()" />
810
<explorers-comparison-tool-filter-list />
911
<div class="comparison-tool-body">
1012
<div class="comparison-tool-body-inner">
1113
<div class="comparison-tool-tables">
1214
<explorers-comparison-tool-controls />
13-
<explorers-comparison-tool-table />
15+
<explorers-comparison-tool-table (lazyLoad)="onLazyLoad($event)" />
1416
<ng-content></ng-content>
1517
<explorers-help-links />
1618
<explorers-comparison-tool-filter-panel
@@ -20,5 +22,5 @@
2022
</div>
2123
</div>
2224
</div>
23-
}
25+
</div>
2426
</main>

libs/explorers/comparison-tool/src/lib/comparison-tool.component.spec.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import { provideHttpClient } from '@angular/common/http';
2+
import { provideNoopAnimations } from '@angular/platform-browser/animations';
13
import {
24
provideComparisonToolFilterService,
35
provideComparisonToolService,
@@ -16,6 +18,8 @@ async function setup() {
1618
const { fixture } = await render(ComparisonToolComponent, {
1719
imports: [LoadingContainerComponent],
1820
providers: [
21+
provideHttpClient(),
22+
provideNoopAnimations(),
1923
provideLoadingIconColors(),
2024
...provideComparisonToolService({
2125
configs: mockComparisonToolConfigs,

libs/explorers/comparison-tool/src/lib/comparison-tool.component.ts

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
1-
import { Component, inject, input, model } from '@angular/core';
1+
import { Component, inject, input, model, output } from '@angular/core';
22
import { ComparisonToolService } from '@sagebionetworks/explorers/services';
33
import { LoadingContainerComponent } from '@sagebionetworks/explorers/util';
4+
import { TableLazyLoadEvent } from 'primeng/table';
45
import { ComparisonToolControlsComponent } from './comparison-tool-controls/comparison-tool-controls.component';
56
import { ComparisonToolFilterListComponent } from './comparison-tool-filter-list/comparison-tool-filter-list.component';
67
import { ComparisonToolFilterPanelComponent } from './comparison-tool-filter-panel/comparison-tool-filter-panel.component';
@@ -27,6 +28,8 @@ export class ComparisonToolComponent {
2728

2829
isLoading = input(true);
2930

31+
lazyLoad = output<TableLazyLoadEvent>();
32+
3033
currentConfig = this.comparisonToolService.currentConfig;
3134
loadingResultsCount = this.comparisonToolService.loadingResultsCount;
3235

@@ -35,4 +38,8 @@ export class ComparisonToolComponent {
3538
toggleFilterPanel() {
3639
this.isFilterPanelOpen.update((isOpen) => !isOpen);
3740
}
41+
42+
onLazyLoad(event: TableLazyLoadEvent) {
43+
this.lazyLoad.emit(event);
44+
}
3845
}
Lines changed: 170 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,170 @@
1+
import { TableLazyLoadEvent } from 'primeng/table';
2+
import { getPaginationParams } from './comparison-tool.helpers';
3+
import { NUMBER_OF_ROWS_TO_DISPLAY } from './comparison-tool.variables';
4+
5+
describe('comparison-tool.helpers', () => {
6+
describe('getPaginationParams', () => {
7+
it('should calculate correct pagination for first page', () => {
8+
const event: TableLazyLoadEvent = {
9+
first: 0,
10+
rows: 10,
11+
};
12+
13+
const result = getPaginationParams(event);
14+
15+
expect(result).toEqual({
16+
pageNumber: 0,
17+
pageSize: 10,
18+
});
19+
});
20+
21+
it('should calculate correct pagination for second page', () => {
22+
const event: TableLazyLoadEvent = {
23+
first: 10,
24+
rows: 10,
25+
};
26+
27+
const result = getPaginationParams(event);
28+
29+
expect(result).toEqual({
30+
pageNumber: 1,
31+
pageSize: 10,
32+
});
33+
});
34+
35+
it('should calculate correct pagination for third page', () => {
36+
const event: TableLazyLoadEvent = {
37+
first: 20,
38+
rows: 10,
39+
};
40+
41+
const result = getPaginationParams(event);
42+
43+
expect(result).toEqual({
44+
pageNumber: 2,
45+
pageSize: 10,
46+
});
47+
});
48+
49+
it('should handle different page sizes', () => {
50+
const event: TableLazyLoadEvent = {
51+
first: 25,
52+
rows: 25,
53+
};
54+
55+
const result = getPaginationParams(event);
56+
57+
expect(result).toEqual({
58+
pageNumber: 1,
59+
pageSize: 25,
60+
});
61+
});
62+
63+
it('should use default page size when rows is undefined', () => {
64+
const event: TableLazyLoadEvent = {
65+
first: 0,
66+
};
67+
68+
const result = getPaginationParams(event);
69+
70+
expect(result).toEqual({
71+
pageNumber: 0,
72+
pageSize: NUMBER_OF_ROWS_TO_DISPLAY,
73+
});
74+
});
75+
76+
it('should use default page size when rows is null', () => {
77+
const event: TableLazyLoadEvent = {
78+
first: 0,
79+
rows: null as unknown as number,
80+
};
81+
82+
const result = getPaginationParams(event);
83+
84+
expect(result).toEqual({
85+
pageNumber: 0,
86+
pageSize: NUMBER_OF_ROWS_TO_DISPLAY,
87+
});
88+
});
89+
90+
it('should default to page 0 when first is undefined', () => {
91+
const event: TableLazyLoadEvent = {
92+
rows: 10,
93+
};
94+
95+
const result = getPaginationParams(event);
96+
97+
expect(result).toEqual({
98+
pageNumber: 0,
99+
pageSize: 10,
100+
});
101+
});
102+
103+
it('should default to page 0 when first is null', () => {
104+
const event: TableLazyLoadEvent = {
105+
first: null as unknown as number,
106+
rows: 10,
107+
};
108+
109+
const result = getPaginationParams(event);
110+
111+
expect(result).toEqual({
112+
pageNumber: 0,
113+
pageSize: 10,
114+
});
115+
});
116+
117+
it('should handle both first and rows being undefined', () => {
118+
const event: TableLazyLoadEvent = {};
119+
120+
const result = getPaginationParams(event);
121+
122+
expect(result).toEqual({
123+
pageNumber: 0,
124+
pageSize: NUMBER_OF_ROWS_TO_DISPLAY,
125+
});
126+
});
127+
128+
it('should correctly calculate page number with non-standard offsets', () => {
129+
const event: TableLazyLoadEvent = {
130+
first: 15,
131+
rows: 10,
132+
};
133+
134+
const result = getPaginationParams(event);
135+
136+
expect(result).toEqual({
137+
pageNumber: 1,
138+
pageSize: 10,
139+
});
140+
});
141+
142+
it('should handle large page numbers', () => {
143+
const event: TableLazyLoadEvent = {
144+
first: 1000,
145+
rows: 50,
146+
};
147+
148+
const result = getPaginationParams(event);
149+
150+
expect(result).toEqual({
151+
pageNumber: 20,
152+
pageSize: 50,
153+
});
154+
});
155+
156+
it('should handle zero rows per page (edge case)', () => {
157+
const event: TableLazyLoadEvent = {
158+
first: 0,
159+
rows: 0,
160+
};
161+
162+
const result = getPaginationParams(event);
163+
164+
// When rows is 0, Math.floor(0/0) = NaN, but the nullish coalescing
165+
// operator doesn't catch 0, so we get NaN
166+
expect(result.pageNumber).toBeNaN();
167+
expect(result.pageSize).toBe(0);
168+
});
169+
});
170+
});
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
import { TableLazyLoadEvent } from 'primeng/table';
2+
import { NUMBER_OF_ROWS_TO_DISPLAY, PaginationParams } from './comparison-tool.variables';
3+
4+
/**
5+
* Calculates pagination parameters from a PrimeNG TableLazyLoadEvent
6+
* @param event The lazy load event from PrimeNG table
7+
* @returns Object containing pageNumber (zero-based) and pageSize
8+
*/
9+
export function getPaginationParams(event: TableLazyLoadEvent): PaginationParams {
10+
const pageNumber = Math.floor((event.first ?? 0) / (event.rows ?? NUMBER_OF_ROWS_TO_DISPLAY));
11+
const pageSize = event.rows ?? NUMBER_OF_ROWS_TO_DISPLAY;
12+
return { pageNumber, pageSize };
13+
}

0 commit comments

Comments
 (0)