Skip to content
This repository was archived by the owner on Jun 1, 2025. It is now read-only.

Commit fd9bbaa

Browse files
authored
Merge pull request #382 from ghiscoding/feat/pagination-rewrite
(pagination): rewrite simpler pagination service and component
2 parents a9a52a0 + cd50d80 commit fd9bbaa

23 files changed

+397
-313
lines changed

src/app/examples/grid-graphql.component.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -243,7 +243,7 @@ export class GridGraphqlComponent implements OnInit, OnDestroy {
243243
setTimeout(() => {
244244
this.graphqlQuery = this.angularGrid.backendService.buildQuery();
245245
resolve(mockedResult);
246-
}, 250);
246+
}, 100);
247247
});
248248
}
249249

src/app/examples/grid-odata.component.ts

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -291,16 +291,17 @@ export class GridOdataComponent implements OnInit {
291291
countPropName = (this.odataVersion === 4) ? '@odata.count' : 'odata.count';
292292
}
293293
const backendResult = { items: updatedData, [countPropName]: countTotalItems, query };
294-
console.log('Backend Result', backendResult);
294+
// console.log('Backend Result', backendResult);
295295
resolve(backendResult);
296-
}, 250);
296+
}, 100);
297297
});
298298
});
299299
}
300300

301301
/** Dispatched event of a Grid State Changed event */
302302
gridStateChanged(gridStateChanges: GridStateChange) {
303-
console.log('Client sample, Grid State changed:: ', gridStateChanges);
303+
// console.log('Client sample, Grid State changed:: ', gridStateChanges);
304+
console.log('Client sample, Grid State changed:: ', gridStateChanges.change);
304305
}
305306

306307
// THE FOLLOWING METHODS ARE ONLY FOR DEMO PURPOSES DO NOT USE THIS CODE

src/app/modules/angular-slickgrid/components/__tests__/angular-slickgrid-constructor.spec.ts

Lines changed: 44 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ import {
2020
SharedService,
2121
SortService,
2222
} from '../../services';
23-
import { Column, CurrentFilter, CurrentSorter, GraphqlPaginatedResult, GraphqlServiceApi, GraphqlServiceOption, GridOption, GridState, GridStateChange, GridStateType, Pagination } from '../../models';
23+
import { Column, CurrentFilter, CurrentSorter, GraphqlPaginatedResult, GraphqlServiceApi, GraphqlServiceOption, GridOption, GridState, GridStateChange, GridStateType, Pagination, ServicePagination } from '../../models';
2424
import { Filters } from '../../filters';
2525
import { Editors } from '../../editors';
2626
import * as utilities from '../../services/backend-utilities';
@@ -116,10 +116,17 @@ const gridStateServiceStub = {
116116
} as unknown as GridStateService;
117117

118118
const paginationServiceStub = {
119+
totalItems: 0,
119120
init: jest.fn(),
120121
dispose: jest.fn(),
122+
onPaginationChanged: new Subject<ServicePagination>(),
121123
} as unknown as PaginationService;
122124

125+
Object.defineProperty(paginationServiceStub, 'totalItems', {
126+
get: jest.fn(() => 0),
127+
set: jest.fn()
128+
});
129+
123130
const resizerServiceStub = {
124131
init: jest.fn(),
125132
dispose: jest.fn(),
@@ -676,6 +683,22 @@ describe('Angular-Slickgrid Custom Component instantiated via Constructor', () =
676683
expect(component.gridOptions.backendServiceApi.internalPostProcess).toEqual(expect.any(Function));
677684
});
678685

686+
it('should execute the "internalPostProcess" callback and expect totalItems to be updated in the PaginationService when "refreshGridData" is called on the 2nd time', () => {
687+
jest.spyOn(component.gridOptions.backendServiceApi.service, 'getDatasetName').mockReturnValue('users');
688+
const refreshSpy = jest.spyOn(component, 'refreshGridData');
689+
const paginationSpy = jest.spyOn(paginationServiceStub, 'totalItems', 'set');
690+
const mockDataset = [{ firstName: 'John' }, { firstName: 'Jane' }];
691+
692+
component.ngAfterViewInit();
693+
component.gridOptions.backendServiceApi.internalPostProcess({ data: { users: { nodes: mockDataset, totalCount: mockDataset.length } } } as GraphqlPaginatedResult);
694+
component.refreshGridData(mockDataset, 1);
695+
component.refreshGridData(mockDataset, 1);
696+
697+
expect(refreshSpy).toHaveBeenCalledTimes(3);
698+
expect(paginationSpy).toHaveBeenCalledWith(2);
699+
expect(component.gridOptions.backendServiceApi.internalPostProcess).toEqual(expect.any(Function));
700+
});
701+
679702
it('should execute the "internalPostProcess" callback method that was created by "createBackendApiInternalPostProcessCallback" without Pagination (when disabled)', () => {
680703
component.gridOptions.enablePagination = false;
681704
jest.spyOn(component.gridOptions.backendServiceApi.service, 'getDatasetName').mockReturnValue('users');
@@ -1100,6 +1123,26 @@ describe('Angular-Slickgrid Custom Component instantiated via Constructor', () =
11001123
});
11011124
});
11021125

1126+
it('should call trigger a gridStage change event when "onPaginationChanged" from the Pagination Service is triggered', () => {
1127+
const mockPagination = { pageNumber: 2, pageSize: 20, pageSizes: [5, 10, 15, 20] } as Pagination;
1128+
const mockServicePagination = {
1129+
...mockPagination,
1130+
dataFrom: 5,
1131+
dataTo: 10,
1132+
pageCount: 1,
1133+
} as ServicePagination;
1134+
const spy = jest.spyOn(gridStateServiceStub.onGridStateChanged, 'next');
1135+
jest.spyOn(gridStateServiceStub, 'getCurrentGridState').mockReturnValue({ columns: [], pagination: mockPagination } as GridState);
1136+
1137+
component.ngAfterViewInit();
1138+
paginationServiceStub.onPaginationChanged.next(mockServicePagination);
1139+
1140+
expect(spy).toHaveBeenCalledWith({
1141+
change: { newValues: mockPagination, type: GridStateType.pagination },
1142+
gridState: { columns: [], pagination: mockPagination }
1143+
});
1144+
});
1145+
11031146
it('should call trigger a gridStage change and reset selected rows when pagination change is triggered and "enableRowSelection" is set', () => {
11041147
const mockPagination = { pageNumber: 2, pageSize: 20 } as Pagination;
11051148
const stateChangedSpy = jest.spyOn(gridStateServiceStub.onGridStateChanged, 'next');

src/app/modules/angular-slickgrid/components/__tests__/slick-pagination-without-translate.component.spec.ts

Lines changed: 19 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -3,56 +3,19 @@ import { By } from '@angular/platform-browser';
33
import { Subject } from 'rxjs';
44

55
import { SlickPaginationComponent } from '../slick-pagination.component';
6-
import { Column, GridOption, Locale, Pager } from '../../models';
6+
import { Locale, ServicePagination } from '../../models';
77
import { PaginationService } from '../../services';
88

9-
const dataviewStub = {
10-
onPagingInfoChanged: jest.fn(),
11-
onRowCountChanged: jest.fn(),
12-
onRowsChanged: jest.fn(),
13-
};
14-
15-
const mockBackendService = {
16-
resetPaginationOptions: jest.fn(),
17-
buildQuery: jest.fn(),
18-
updateOptions: jest.fn(),
19-
processOnFilterChanged: jest.fn(),
20-
processOnSortChanged: jest.fn(),
21-
processOnPaginationChanged: jest.fn(),
22-
};
23-
24-
const mockGridOption = {
25-
enableAutoResize: true,
26-
enablePagination: true,
27-
backendServiceApi: {
28-
service: mockBackendService,
29-
process: jest.fn(),
30-
options: {
31-
columnDefinitions: [{ id: 'name', field: 'name' }] as Column[],
32-
datasetName: 'user',
33-
}
34-
},
35-
pagination: {
36-
pageSizes: [10, 15, 20, 25, 30, 40, 50, 75, 100],
37-
pageSize: 25,
38-
totalItems: 85
39-
}
40-
} as GridOption;
41-
42-
const gridStub = {
43-
autosizeColumns: jest.fn(),
44-
getColumnIndex: jest.fn(),
45-
getOptions: () => mockGridOption,
46-
getColumns: jest.fn(),
47-
setColumns: jest.fn(),
48-
onColumnsReordered: jest.fn(),
49-
onColumnsResized: jest.fn(),
50-
registerPlugin: jest.fn(),
51-
};
52-
539
const paginationServiceStub = {
54-
onPaginationRefreshed: new Subject<boolean>(),
55-
onPaginationChanged: new Subject<Pager>(),
10+
dataFrom: 5,
11+
dataTo: 10,
12+
pageNumber: 2,
13+
pageCount: 1,
14+
itemsPerPage: 5,
15+
pageSize: 10,
16+
totalItems: 100,
17+
availablePageSizes: [5, 10, 15, 20],
18+
pageInfoTotalItems: jest.fn(),
5619
goToFirstPage: jest.fn(),
5720
goToLastPage: jest.fn(),
5821
goToNextPage: jest.fn(),
@@ -61,12 +24,14 @@ const paginationServiceStub = {
6124
changeItemPerPage: jest.fn(),
6225
dispose: jest.fn(),
6326
init: jest.fn(),
27+
onPaginationRefreshed: new Subject<boolean>(),
28+
onPaginationChanged: new Subject<ServicePagination>(),
6429
} as unknown as PaginationService;
6530

6631
describe('without ngx-translate', () => {
6732
let fixture: ComponentFixture<SlickPaginationComponent>;
6833
let component: SlickPaginationComponent;
69-
let mockPager: Pager;
34+
let mockServicePagination: ServicePagination;
7035

7136
beforeEach(async(() => {
7237
TestBed.configureTestingModule({
@@ -82,34 +47,24 @@ describe('without ngx-translate', () => {
8247
fixture = TestBed.createComponent(SlickPaginationComponent);
8348
component = fixture.debugElement.componentInstance;
8449

85-
mockPager = {
86-
from: 5,
87-
to: 10,
88-
itemsPerPage: 5,
50+
mockServicePagination = {
51+
dataFrom: 5,
52+
dataTo: 10,
53+
pageSize: 5,
8954
pageCount: 1,
9055
pageNumber: 2,
91-
availablePageSizes: [5, 10, 15, 20],
56+
pageSizes: [5, 10, 15, 20],
9257
totalItems: 100,
9358
};
9459
component.enableTranslate = false;
95-
component.grid = gridStub;
96-
component.options = {
97-
pageNumber: mockPager.pageNumber,
98-
pageSizes: mockPager.availablePageSizes,
99-
pageSize: mockPager.itemsPerPage,
100-
totalItems: mockPager.totalItems,
101-
};
102-
component.backendServiceApi = mockGridOption.backendServiceApi;
103-
component.totalItems = mockPager.totalItems;
10460
component.locales = {
10561
TEXT_ITEMS_PER_PAGE: 'items per page',
10662
TEXT_ITEMS: 'items',
10763
TEXT_OF: 'of',
10864
TEXT_PAGE: 'page'
10965
} as Locale;
11066

111-
paginationServiceStub.init(gridStub, dataviewStub, component.options, component.backendServiceApi);
112-
paginationServiceStub.onPaginationChanged.next(mockPager);
67+
paginationServiceStub.onPaginationChanged.next(mockServicePagination);
11368
fixture.detectChanges();
11469
}));
11570

@@ -137,7 +92,6 @@ describe('without ngx-translate', () => {
13792
it('should have defined locale and expect new text in the UI', (done) => {
13893
component.enableTranslate = false;
13994
fixture.detectChanges();
140-
paginationServiceStub.onPaginationRefreshed.next(true);
14195

14296
setTimeout(() => {
14397
fixture.detectChanges();

src/app/modules/angular-slickgrid/components/__tests__/slick-pagination.component.spec.ts

Lines changed: 29 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -4,56 +4,19 @@ import { TranslateModule, TranslateService } from '@ngx-translate/core';
44
import { Subject } from 'rxjs';
55

66
import { SlickPaginationComponent } from '../slick-pagination.component';
7-
import { Column, GridOption, Pager } from '../../models';
7+
import { ServicePagination } from '../../models';
88
import { PaginationService } from '../../services';
99

10-
const dataviewStub = {
11-
onPagingInfoChanged: jest.fn(),
12-
onRowCountChanged: jest.fn(),
13-
onRowsChanged: jest.fn(),
14-
};
15-
16-
const mockBackendService = {
17-
resetPaginationOptions: jest.fn(),
18-
buildQuery: jest.fn(),
19-
updateOptions: jest.fn(),
20-
processOnFilterChanged: jest.fn(),
21-
processOnSortChanged: jest.fn(),
22-
processOnPaginationChanged: jest.fn(),
23-
};
24-
25-
const mockGridOption = {
26-
enableAutoResize: true,
27-
enablePagination: true,
28-
backendServiceApi: {
29-
service: mockBackendService,
30-
process: jest.fn(),
31-
options: {
32-
columnDefinitions: [{ id: 'name', field: 'name' }] as Column[],
33-
datasetName: 'user',
34-
}
35-
},
36-
pagination: {
37-
pageSizes: [10, 15, 20, 25, 30, 40, 50, 75, 100],
38-
pageSize: 25,
39-
totalItems: 85
40-
}
41-
} as GridOption;
42-
43-
const gridStub = {
44-
autosizeColumns: jest.fn(),
45-
getColumnIndex: jest.fn(),
46-
getOptions: () => mockGridOption,
47-
getColumns: jest.fn(),
48-
setColumns: jest.fn(),
49-
onColumnsReordered: jest.fn(),
50-
onColumnsResized: jest.fn(),
51-
registerPlugin: jest.fn(),
52-
};
53-
5410
const paginationServiceStub = {
55-
onPaginationRefreshed: new Subject<boolean>(),
56-
onPaginationChanged: new Subject<Pager>(),
11+
dataFrom: 5,
12+
dataTo: 10,
13+
pageNumber: 2,
14+
pageCount: 1,
15+
itemsPerPage: 5,
16+
pageSize: 10,
17+
totalItems: 100,
18+
availablePageSizes: [5, 10, 15, 20],
19+
pageInfoTotalItems: jest.fn(),
5720
goToFirstPage: jest.fn(),
5821
goToLastPage: jest.fn(),
5922
goToNextPage: jest.fn(),
@@ -62,13 +25,15 @@ const paginationServiceStub = {
6225
changeItemPerPage: jest.fn(),
6326
dispose: jest.fn(),
6427
init: jest.fn(),
28+
onPaginationRefreshed: new Subject<boolean>(),
29+
onPaginationChanged: new Subject<ServicePagination>(),
6530
} as unknown as PaginationService;
6631

6732
describe('App Component', () => {
6833
let fixture: ComponentFixture<SlickPaginationComponent>;
6934
let component: SlickPaginationComponent;
7035
let translate: TranslateService;
71-
let mockPager: Pager;
36+
let mockServicePagination: ServicePagination;
7237

7338
beforeEach(async(() => {
7439
TestBed.configureTestingModule({
@@ -113,28 +78,17 @@ describe('App Component', () => {
11378

11479
describe('Integration Tests', () => {
11580
beforeEach(() => {
116-
mockPager = {
117-
from: 5,
118-
to: 10,
119-
itemsPerPage: 5,
81+
mockServicePagination = {
82+
dataFrom: 5,
83+
dataTo: 10,
84+
pageSize: 5,
12085
pageCount: 1,
12186
pageNumber: 2,
122-
availablePageSizes: [5, 10, 15, 20],
87+
pageSizes: [5, 10, 15, 20],
12388
totalItems: 100,
12489
};
12590
component.enableTranslate = true;
126-
component.grid = gridStub;
127-
component.options = {
128-
pageNumber: mockPager.pageNumber,
129-
pageSizes: mockPager.availablePageSizes,
130-
pageSize: mockPager.itemsPerPage,
131-
totalItems: mockPager.totalItems,
132-
};
133-
component.backendServiceApi = mockGridOption.backendServiceApi;
134-
component.totalItems = mockPager.totalItems;
135-
136-
paginationServiceStub.init(gridStub, dataviewStub, component.options, component.backendServiceApi);
137-
paginationServiceStub.onPaginationChanged.next(mockPager);
91+
paginationServiceStub.onPaginationChanged.next(mockServicePagination);
13892
fixture.detectChanges();
13993
});
14094

@@ -145,6 +99,16 @@ describe('App Component', () => {
14599
fixture.destroy();
146100
});
147101

102+
describe('getters & setters', () => {
103+
// the following 2 setters unit test are simply here for code coverage,
104+
// these 2 setters don't actually do anything
105+
it('should use the "itemsPerPage" setter but do nothing with it', () => {
106+
fixture.detectChanges();
107+
component.pageNumber = 3;
108+
expect(component.pageNumber).toBe(2);
109+
});
110+
});
111+
148112
it('should create a the Slick-Pagination component in the DOM', () => {
149113
fixture.detectChanges();
150114

src/app/modules/angular-slickgrid/components/angular-slickgrid.component.html

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,7 @@
44

55
<!-- Pagination section under the grid -->
66
<slick-pagination id="slickPagingContainer-{{gridId}}" *ngIf="showPagination"
7-
(onPaginationChanged)="paginationChanged($event)" [enableTranslate]="gridOptions.enableTranslate"
8-
[dataView]="dataView" [grid]="grid" [options]="paginationOptions" [locales]="locales" [totalItems]="totalItems"
9-
[backendServiceApi]="backendServiceApi">
7+
[enableTranslate]="gridOptions.enableTranslate" [locales]="locales">
108
</slick-pagination>
119

1210
<!-- Custom Footer section under the grid -->

0 commit comments

Comments
 (0)