From 70622306638af741dc2e0cae8f290eee2abf63ae Mon Sep 17 00:00:00 2001 From: "Nichols, Kieran" Date: Fri, 6 Oct 2023 11:04:20 -0400 Subject: [PATCH] fix(paginator): fixed a bug where setting the `offset` property before `total` would result in the page size not changing when `total` was updated --- src/lib/paginator/paginator-foundation.ts | 33 +++++++++++++----- src/test/spec/paginator/paginator.spec.ts | 41 +++++++++++++++++++++++ 2 files changed, 65 insertions(+), 9 deletions(-) diff --git a/src/lib/paginator/paginator-foundation.ts b/src/lib/paginator/paginator-foundation.ts index c05a9a473..1bed84c2b 100644 --- a/src/lib/paginator/paginator-foundation.ts +++ b/src/lib/paginator/paginator-foundation.ts @@ -21,6 +21,7 @@ export class PaginatorFoundation { // Backing models private _pageIndex = PAGINATOR_CONSTANTS.numbers.DEFAULT_PAGE_INDEX; private _pageSize = PAGINATOR_CONSTANTS.numbers.DEFAULT_PAGE_SIZE; + private _offset = 0; private _total = PAGINATOR_CONSTANTS.numbers.DEFAULT_TOTAL; private _pageSizeOptions: ISelectOption[] = []; private _label = PAGINATOR_CONSTANTS.strings.DEFAULT_LABEL; @@ -82,24 +83,24 @@ export class PaginatorFoundation { /** Sets page index by providing the number of items to skip. */ public set offset(value: number) { - if (value >= this._total) { - if (this._total >= this._pageSize) { - value = this._total - this._pageSize; - } else { - value = 0; - } + if (this._offset !== value) { + this._offset = value; + this._computePageIndexFromOffset(value); } - const clampedValue = Math.min(Math.max(value, 0), this._total); - this.pageIndex = Math.floor(clampedValue / this._pageSize); } public get offset(): number { - return this._pageIndex * this._pageSize; + return this._offset; } /** The total number of items to be paginated. Default is 0. */ public set total(value: number) { if (this._total !== value) { this._total = value; + + if (this._offset > 0 && this._total > 0) { + this._computePageIndexFromOffset(this._offset); + } + this._update(); this._adapter.setHostAttribute(PAGINATOR_CONSTANTS.attributes.TOTAL, this._total.toString()); } @@ -362,6 +363,8 @@ export class PaginatorFoundation { * Updates our internal state as well as updating the UI. */ private _update(): void { + this._offset = this._pageIndex * this._pageSize; + // Create and update the range label if (this.pageSize > 1) { const startIndex = this._pageIndex * this._pageSize; @@ -469,4 +472,16 @@ export class PaginatorFoundation { // same as has next page return this._hasNextPage(); } + + private _computePageIndexFromOffset(value: number): void { + if (value >= this._total) { + if (this._total >= this._pageSize) { + value = this._total - this._pageSize; + } else { + value = 0; + } + } + const clampedValue = Math.min(Math.max(value, 0), this._total); + this.pageIndex = Math.floor(clampedValue / this._pageSize); + } } diff --git a/src/test/spec/paginator/paginator.spec.ts b/src/test/spec/paginator/paginator.spec.ts index 28e44d1ee..c1ec3790c 100644 --- a/src/test/spec/paginator/paginator.spec.ts +++ b/src/test/spec/paginator/paginator.spec.ts @@ -418,6 +418,47 @@ describe('PaginatorComponent', function(this: ITestContext) { expect(this.context.paginator.pageIndex).toBe(0); }); + it('should set page index via offset property if total is not > 0 initially', function(this: ITestContext) { + this.context = setupTestContext(); + const pageSizeOptions = [5, 10, 25]; + this.context.paginator.pageSizeOptions = pageSizeOptions; + this.context.paginator.pageSize = 25; + + expect(this.context.paginator.total).toBe(0); + + this.context.paginator.offset = 25; + expect(this.context.paginator.pageIndex).toBe(0); + + this.context.paginator.total = 100; + expect(this.context.paginator.pageIndex).toBe(1); + }); + + it('should update offset when page index changes', function(this: ITestContext) { + this.context = setupTestContext(); + const pageSizeOptions = [5, 10, 25]; + this.context.paginator.pageSizeOptions = pageSizeOptions; + this.context.paginator.pageSize = 25; + this.context.paginator.total = 100; + + expect(this.context.paginator.pageIndex).toBe(0); + expect(this.context.paginator.offset).toBe(0); + + this.context.paginator.pageIndex = 1; + + expect(this.context.paginator.pageIndex).toBe(1); + expect(this.context.paginator.offset).toBe(25); + + this.context.paginator.pageIndex = 3; + + expect(this.context.paginator.pageIndex).toBe(3); + expect(this.context.paginator.offset).toBe(75); + + this.context.paginator.pageIndex = 0; + + expect(this.context.paginator.pageIndex).toBe(0); + expect(this.context.paginator.offset).toBe(0); + }); + it('should get offset', function(this: ITestContext) { this.context = setupTestContext(); const pageSizeOptions = [5, 10, 25];