Skip to content

Commit ea2b099

Browse files
author
Andrea Barbasso
committed
[DURACOM-386] fix rotation, focus and rollover
1 parent d8f543d commit ea2b099

3 files changed

Lines changed: 89 additions & 13 deletions

File tree

src/app/shared/pagination/pagination.component.html

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@
6464
[page]="(currentPage$|async)"
6565
(pageChange)="doPageChange($event)"
6666
[pageSize]="(pageSize$ |async)"
67-
[rotate]="paginationOptions.enablePaginationInput || paginationOptions.rotate"
67+
[rotate]="paginationOptions.rotate"
6868
[size]="isXs ? 'sm' : paginationOptions.size">
6969
@if (paginationOptions.enablePaginationInput) {
7070
<ng-template ngbPaginationPages let-page let-pages="pages">
@@ -76,6 +76,7 @@
7676
[dsBtnDisabled]="!paginationOptions.enablePaginationInput"
7777
[ngbPopover]="paginationInputPopover"
7878
[autoClose]="'outside'"
79+
#pop="ngbPopover"
7980
>
8081
...
8182
</button>
@@ -89,12 +90,11 @@
8990
class="form-control border-info page-input"
9091
id="paginationInput"
9192
[placeholder]="'pagination.page' | translate"
92-
(keyup.enter)="selectPage(input.value)"
93-
(blur)="selectPage(input.value)"
93+
(keyup.enter)="selectPage(input.value, pop)"
9494
(input)="formatInput($any($event).target)"
9595
aria-label="Page input"
9696
/>
97-
<button class="btn btn-outline-info search-button" type="button" (click)="selectPage(input.value)" tabindex="0" [attr.aria-label]="'paginator.go-to-page' | translate">
97+
<button class="btn btn-outline-info search-button" type="button" (click)="selectPage(input.value, pop)" tabindex="0" [attr.aria-label]="'paginator.go-to-page' | translate">
9898
{{'pagination.go-to-page' | translate}}
9999
</button>
100100
</span>

src/app/shared/pagination/pagination.component.spec.ts

Lines changed: 58 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -66,14 +66,14 @@ function expectPages(fixture: ComponentFixture<any>, pagesDef: string[]): void {
6666
expect(pages[i].classList.contains('disabled')).toBeTruthy();
6767
expect(normalizeText(pages[i].textContent)).toEqual(normalizeText(pageDef));
6868
if (normalizeText(pages[i].textContent) !== '...') {
69-
expect(pages[i].querySelector('a').getAttribute('tabindex')).toEqual('-1');
69+
expect((pages[i].querySelector('a') || pages[i].querySelector('button')).getAttribute('tabindex')).toEqual('-1');
7070
}
7171
} else {
7272
expect(pages[i].classList.contains('active')).toBeFalsy();
7373
expect(pages[i].classList.contains('disabled')).toBeFalsy();
7474
expect(normalizeText(pages[i].textContent)).toEqual(normalizeText(pageDef));
7575
if (normalizeText(pages[i].textContent) !== '...') {
76-
expect(pages[i].querySelector('a').hasAttribute('tabindex')).toBeFalsy();
76+
expect((pages[i].querySelector('a') || pages[i].querySelector('button')).hasAttribute('tabindex')).toBeFalsy();
7777
}
7878
}
7979
}
@@ -291,11 +291,15 @@ describe('Pagination component', () => {
291291

292292
it('should call the updateRoute method on the paginationService with the correct params', fakeAsync(() => {
293293
testComp.collectionSize = 60;
294+
testFixture.detectChanges();
294295

295296
changePage(testFixture, 3);
296297
tick();
297298
expect(paginationService.updateRoute).toHaveBeenCalledWith('test', Object.assign({ page: 3 }), {}, false);
298299

300+
currentPagination.next(Object.assign(new PaginationComponentOptions(), pagination, { currentPage: 3 }));
301+
testFixture.detectChanges();
302+
299303
changePage(testFixture, 0);
300304
tick();
301305
expect(paginationService.updateRoute).toHaveBeenCalledWith('test', Object.assign({ page: 2 }), {}, false);
@@ -482,6 +486,58 @@ describe('Pagination component', () => {
482486
expect(input).toBeDefined();
483487
expect(input.nativeElement.disabled).toBeFalse();
484488
});
489+
490+
describe('selectPage', () => {
491+
// collectionSize (200) / pageSize (10) => 20 pages
492+
let paginationServiceStub: any;
493+
494+
beforeEach(() => {
495+
paginationServiceStub = TestBed.inject(PaginationService);
496+
spyOn(paginationServiceStub, 'updateRoute').and.callThrough();
497+
spyOn(component.pageChange, 'emit');
498+
spyOn(component.paginationChange, 'emit');
499+
});
500+
501+
it('should navigate to the requested page when it is within range', () => {
502+
component.selectPage('7');
503+
expect(paginationServiceStub.updateRoute).toHaveBeenCalledWith('test', { page: 7 }, {}, false);
504+
expect(component.pageChange.emit).toHaveBeenCalledWith(7);
505+
});
506+
507+
it('should clamp a page number that is too high to the last page', () => {
508+
component.selectPage('999');
509+
expect(paginationServiceStub.updateRoute).toHaveBeenCalledWith('test', { page: 20 }, {}, false);
510+
expect(component.pageChange.emit).toHaveBeenCalledWith(20);
511+
});
512+
513+
it('should clamp a page number below 1 to the first page', () => {
514+
component.selectPage('0');
515+
expect(paginationServiceStub.updateRoute).toHaveBeenCalledWith('test', { page: 1 }, {}, false);
516+
expect(component.pageChange.emit).toHaveBeenCalledWith(1);
517+
});
518+
519+
it('should ignore non-numeric input', () => {
520+
component.selectPage('abc');
521+
expect(paginationServiceStub.updateRoute).not.toHaveBeenCalled();
522+
expect(component.pageChange.emit).not.toHaveBeenCalled();
523+
});
524+
525+
it('should emit a paginationChange event so the results are reloaded', () => {
526+
component.selectPage('3');
527+
expect(component.paginationChange.emit).toHaveBeenCalled();
528+
});
529+
530+
it('should not emit a paginationChange event for invalid input', () => {
531+
component.selectPage('abc');
532+
expect(component.paginationChange.emit).not.toHaveBeenCalled();
533+
});
534+
535+
it('should close the popover when one is provided', () => {
536+
const popover = jasmine.createSpyObj('NgbPopover', ['close']);
537+
component.selectPage('3', popover);
538+
expect(popover.close).toHaveBeenCalled();
539+
});
540+
});
485541
});
486542

487543
});

src/app/shared/pagination/pagination.component.ts

Lines changed: 27 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
import {
22
AsyncPipe,
33
NgClass,
4-
NgStyle,
54
} from '@angular/common';
65
import {
76
ChangeDetectionStrategy,
@@ -34,6 +33,7 @@ import {
3433
import {
3534
NgbDropdownModule,
3635
NgbPaginationModule,
36+
NgbPopover,
3737
NgbTooltip,
3838
} from '@ng-bootstrap/ng-bootstrap';
3939
import { TranslateModule } from '@ngx-translate/core';
@@ -75,9 +75,9 @@ interface PaginationDetails {
7575
EnumKeysPipe,
7676
NgbDropdownModule,
7777
NgbPaginationModule,
78+
NgbPopover,
7879
NgbTooltip,
7980
NgClass,
80-
NgStyle,
8181
RSSComponent,
8282
TranslateModule,
8383
],
@@ -463,12 +463,32 @@ export class PaginationComponent implements OnChanges, OnDestroy, OnInit {
463463

464464
/**
465465
* Select any given page.
466+
*
467+
* The requested page is clamped to the valid range: values below 1 navigate to the first page,
468+
* values above the last page navigate to the last page. This mirrors the behaviour of the
469+
* regular page buttons and prevents navigating to an out-of-range page (which would render an
470+
* empty result set).
471+
*
466472
* @param page
467-
*/
468-
selectPage(page: string) {
469-
const pageNumber = parseInt(page, 10);
470-
this.pageChange.emit(pageNumber);
471-
this.updatePagination(pageNumber, true);
473+
* The requested page (as entered in the pagination input).
474+
* @param popover
475+
* Optional reference to the pagination input popover, which is closed once a page is selected.
476+
*/
477+
selectPage(page: string | number, popover?: NgbPopover) {
478+
const pageNumber = parseInt(`${page}`, 10);
479+
if (isNaN(pageNumber)) {
480+
return;
481+
}
482+
this.paginationService.getCurrentPagination(this.id, this.paginationOptions).pipe(take(1)).subscribe((currentPaginationOptions) => {
483+
const totalPages = Math.max(1, Math.ceil(this.collectionSize / currentPaginationOptions.pageSize));
484+
const boundedPage = Math.min(Math.max(pageNumber, 1), totalPages);
485+
this.pageChange.emit(boundedPage);
486+
this.updateParams({ page: boundedPage });
487+
this.emitPaginationChange();
488+
});
489+
if (hasValue(popover)) {
490+
popover.close();
491+
}
472492
}
473493

474494
/**

0 commit comments

Comments
 (0)