Skip to content

Commit

Permalink
Merge pull request #435 from UiPath/feat/selectable-page-index
Browse files Browse the repository at this point in the history
feat(grid): add selectable page index
  • Loading branch information
CalinaCristian authored Dec 4, 2023
2 parents 2158bee + 515f42d commit 9b68149
Show file tree
Hide file tree
Showing 14 changed files with 148 additions and 13 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
# v15.0.10 (2023-12-04)
* **grid** add selectable page index
* **fix** increase loading buffer size

# v15.0.9 (2023-11-24)
* **grid** column width reacts on resize strategy changes
* **grid** handle single sticky column case
Expand Down
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "angular-components",
"version": "15.0.9",
"version": "15.0.10",
"author": {
"name": "UiPath Inc",
"url": "https://uipath.com"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,27 @@
</button>
<div class="mat-mdc-paginator-page-label">
<ng-container *ngIf="!hideTotalCount">
{{_intl.getPageLabel(pageIndex+1, pageCount)}}
<ng-container *ngIf="selectablePageIndex && pageCount > 1; else defaultPageLabel">
{{ _intl.getPageOnlyLabel() }}
<mat-form-field [appearance]="_formFieldAppearance!"
[color]="color ?? 'primary'"
class="mat-mdc-paginator-page-index-select">
<mat-select (selectionChange)="changePage($event.value)"
[value]="pageIndex"
[aria-label]="_intl.pageSelectLabel"
data-cy="page-index-select">
<mat-option *ngFor="let possiblePage of possiblePages"
[value]="possiblePage.value">
{{ possiblePage.label }}
</mat-option>
</mat-select>
</mat-form-field>
{{ _intl.getTotalPages(pageCount) }}
</ng-container>

<ng-template #defaultPageLabel>
{{_intl.getPageLabel(pageIndex+1, pageCount)}}
</ng-template>
</ng-container>
<ng-container *ngIf="hideTotalCount">
{{ pageIndex + 1 }}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ $mat-paginator-selector-trigger-width: 56px;
$mat-paginator-selector-trigger-outline-width: 64px;
$mat-paginator-selector-trigger-fill-width: 64px;

$mat-paginator-index-selector-width: 48px;

$mat-paginator-page-label-margin: 0 32px 0 24px;
$mat-paginator-button-icon-size: 14px;
$mat-paginator-button-size: 32px;
Expand Down Expand Up @@ -54,6 +56,11 @@ ui-grid-custom-paginator {
.mat-mdc-paginator-page-size-label {
margin: $mat-paginator-items-per-page-label-margin;
}
.mat-mdc-paginator-page-index-select {
margin: $mat-paginator-selector-margin;
width: $mat-paginator-index-selector-width;
}

.mat-mdc-paginator-page-size-select {
margin: $mat-paginator-selector-margin;
width: $mat-paginator-selector-trigger-width;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import {
TestBed,
} from '@angular/core/testing';
import { By } from '@angular/platform-browser';
import { NoopAnimationsModule } from '@angular/platform-browser/animations';
import { EventGenerator } from '@uipath/angular/testing';

import {
Expand All @@ -20,7 +21,8 @@ import { UiGridCustomPaginatorModule } from './ui-grid-custom-paginator.module';
<ui-grid-custom-paginator [pageIndex]="pageIndex"
[pageSize]="pageSize"
[length]="length"
[showFirstLastButtons]="true">
[showFirstLastButtons]="true"
[selectablePageIndex]="selectablePageIndex">
</ui-grid-custom-paginator>
`,
})
Expand All @@ -32,6 +34,7 @@ class TestFixtureComponent {
pageIndex = 0;
pageSize = 10;
length = 120;
selectablePageIndex = false;
}

describe('Component: UiGrid', () => {
Expand All @@ -40,10 +43,11 @@ describe('Component: UiGrid', () => {
let component: TestFixtureComponent;
let intl: UiMatPaginatorIntl;

beforeEach(() => {
const setup = (selectablePageIndex = false, length = 120) => {
TestBed.configureTestingModule({
imports: [
UiGridCustomPaginatorModule,
NoopAnimationsModule,
],
providers: [
UiMatPaginatorIntl,
Expand All @@ -55,22 +59,26 @@ describe('Component: UiGrid', () => {

intl = TestBed.inject(UiMatPaginatorIntl);
fixture = TestBed.createComponent(TestFixtureComponent);
component = fixture.componentInstance;

fixture.detectChanges();
component.selectablePageIndex = selectablePageIndex;
component.length = length;

component = fixture.componentInstance;
});
fixture.detectChanges();
};

afterEach(() => {
fixture.destroy();
});

it('should display correct page label', () => {
setup();
const label = fixture.debugElement.query(By.css('.mat-mdc-paginator-page-label'));
expect(label.nativeElement.innerText).toEqual(intl.getPageLabel(1, 12));
});

it('should update page label on page change', () => {
setup();
const nextButton = fixture.debugElement.query(By.css('.mat-mdc-paginator-navigation-next'));
const label = fixture.debugElement.query(By.css('.mat-mdc-paginator-page-label'));

Expand All @@ -81,6 +89,47 @@ describe('Component: UiGrid', () => {

expect(label.nativeElement.innerText).toEqual(intl.getPageLabel(2, 12));
});

it('should be able to change page index if selectablePageIndex is true and length is greater than pageSize', async () => {
setup(true);
const SELECTED_PAGE = 2;

const pageIndexInputDebugEl = fixture.debugElement.query(By.css('[data-cy="page-index-select"]'));
const pageIndexInput: HTMLInputElement = pageIndexInputDebugEl.nativeElement;

pageIndexInput.click();

fixture.detectChanges();
await fixture.whenStable();
fixture.detectChanges();

const secondOption: HTMLElement = fixture.debugElement.queryAll(By.css('.mat-mdc-option'))[SELECTED_PAGE].nativeElement;
secondOption.click();

fixture.detectChanges();
await fixture.whenStable();
fixture.detectChanges();

const pageRangeLabel = fixture.debugElement.query(By.css('.mat-mdc-paginator-range-label'));

expect(pageRangeLabel.nativeElement.innerText).toEqual(
component.paginator._intl.getRangeLabel(SELECTED_PAGE, component.pageSize, component.length),
);
});

it('should not display page index select if selectablePageIndex is true and length is less than pageSize', () => {
setup(true, 9);
const pageIndexInput = fixture.debugElement.query(By.css('[data-cy="page-index-select"]'));

expect(pageIndexInput).toBeNull();
});

it('should not display page index select if selectablePageIndex is false', () => {
setup();
const pageIndexInput = fixture.debugElement.query(By.css('[data-cy="page-index-select"]'));

expect(pageIndexInput).toBeNull();
});
});

describe('Service: UiMatPaginatorIntl', () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,22 @@ import {

@Injectable()
export class UiMatPaginatorIntl extends MatPaginatorIntl {
pageSelectLabel = 'Select page';

getPageLabel(currentPage: number, pageCount?: number): string {
if (!pageCount) {
return `Page ${currentPage}`;
}
return `Page ${currentPage} / ${pageCount}`;
}

getPageOnlyLabel(): string {
return 'Page';
}

getTotalPages(pageCount: number): string {
return `/ ${pageCount}`;
}
}

@Component({
Expand All @@ -46,8 +56,12 @@ export class UiGridCustomPaginatorComponent extends _MatPaginatorBase<MatPaginat
* Whether to show total count in custom paginator
*
*/
@Input()
hideTotalCount = false;
@Input() hideTotalCount = false;

/**
* Whether to be able to select the page index
*/
@Input() selectablePageIndex = false;

@HostBinding('class')
hostClass = 'mat-mdc-paginator';
Expand All @@ -60,6 +74,20 @@ export class UiGridCustomPaginatorComponent extends _MatPaginatorBase<MatPaginat
return Math.min(this.length, (this.pageIndex + 1) * this.pageSize);
}

set length(value: number) {
super.length = value;

this.possiblePages = Array.from({ length: this.pageCount }, (_, i) => ({
label: i + 1,
value: i,
}));
}
get length() {
return super.length;
}

possiblePages: { label: number; value: number }[] = [];

constructor(
changeDetectorRef: ChangeDetectorRef,
@Optional()
Expand All @@ -74,4 +102,17 @@ export class UiGridCustomPaginatorComponent extends _MatPaginatorBase<MatPaginat
this._formFieldAppearance = defaults.formFieldAppearance;
}
}

changePage(pageIndex: number) {
const prevIndex = this.pageIndex;

this.pageIndex = pageIndex;

this.page.emit({
pageIndex,
previousPageIndex: prevIndex,
pageSize: this.pageSize,
length: this.length,
});
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -29,4 +29,5 @@ export interface GridOptions<T> {
idProperty?: keyof T;
rowSize?: number;
resizeStrategy?: ResizeStrategy;
selectablePageIndex?: boolean;
}
Original file line number Diff line number Diff line change
Expand Up @@ -383,6 +383,7 @@
[showFirstLastButtons]="footer.showFirstLastButtons"
[hidePageSize]="footer.hidePageSize"
[hideTotalCount]="footer.hideTotalCount"
[selectablePageIndex]="selectablePageIndex"
(page)="footer.pageChange.next($event)">
</ui-grid-custom-paginator>
</div>
Expand Down
8 changes: 8 additions & 0 deletions projects/angular/components/ui-grid/src/ui-grid.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -438,6 +438,13 @@ export class UiGridComponent<T extends IGridDataEntry>
}
}

/**
* Configure if the pagination should be selectable
*
*/
@Input()
selectablePageIndex: boolean;

/**
* Emits an event with the sort model when a column sort changes.
*
Expand Down Expand Up @@ -867,6 +874,7 @@ export class UiGridComponent<T extends IGridDataEntry>
this._collapseFiltersCount$ = new BehaviorSubject(
_gridOptions?.collapseFiltersCount ?? (_gridOptions?.collapsibleFilters === true ? 0 : Number.POSITIVE_INFINITY),
);
this.selectablePageIndex = _gridOptions?.selectablePageIndex ?? false;

this.isProjected = this._ref.nativeElement.classList.contains('ui-grid-state-responsive');

Expand Down
2 changes: 1 addition & 1 deletion projects/angular/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@uipath/angular",
"version": "15.0.9",
"version": "15.0.10",
"license": "MIT",
"author": {
"name": "UiPath Inc",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@
[expandMode]="'preserve'"
[resizeStrategy]="inputs.isScrollable ? scrollableGridStrategy : immediateNeighbourHaltStrategy"
[customFilterValue]="inputs.customFilter ? [{property: 'parity', method: 'eq', value: 'odd'}] : []"
[allowHighlight]="inputs.allowHighlight">
[allowHighlight]="inputs.allowHighlight"
[selectablePageIndex]="inputs.selectablePageIndex">

<ui-grid-header [search]="header.searchable">
<ui-header-button *ngFor="let button of generateButtons(header.main)"
Expand Down
1 change: 1 addition & 0 deletions projects/playground/src/app/pages/grid/grid.models.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ export interface IInputs {
hideTotalCount: boolean;
isScrollable: boolean;
allowHighlight: boolean;
selectablePageIndex: boolean;
}

export interface IGridSettings {
Expand Down
2 changes: 2 additions & 0 deletions projects/playground/src/app/pages/grid/grid.page.ts
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ export class GridPageComponent implements AfterViewInit, OnDestroy {
'useCardView',
'isScrollable',
'allowHighlight',
'selectablePageIndex',
];

buttonKeys = [
Expand Down Expand Up @@ -131,6 +132,7 @@ export class GridPageComponent implements AfterViewInit, OnDestroy {
useCardView: [false],
isScrollable: [false],
allowHighlight: [false],
selectablePageIndex: [true],
}),
header: this._fb.group({
searchable: [true],
Expand Down

0 comments on commit 9b68149

Please sign in to comment.