expect(listDaemonsSpy).toHaveBeenCalledTimes(1);
expect(component.daemons).toEqual([daemon]);
expect(fixture.debugElement.query(By.css('cd-table')).nativeElement.textContent).toContain(
- 'total 1'
+ 'total of 1'
);
fixture.destroy();
import { PipesModule } from '~/app/shared/pipes/pipes.module';
import { configureTestBed } from '~/testing/unit-test-helper';
import { TableKeyValueComponent } from '../table-key-value/table-key-value.component';
+import { TablePaginationComponent } from '../table-pagination/table-pagination.component';
import { TableComponent } from '../table/table.component';
import { CRUDTableComponent } from './crud-table.component';
let fixture: ComponentFixture<CRUDTableComponent>;
configureTestBed({
- declarations: [CRUDTableComponent, TableComponent, TableKeyValueComponent],
+ declarations: [
+ CRUDTableComponent,
+ TableComponent,
+ TableKeyValueComponent,
+ TablePaginationComponent
+ ],
imports: [
NgxDatatableModule,
FormsModule,
import { CRUDTableComponent } from './crud-table/crud-table.component';
import { TableActionsComponent } from './table-actions/table-actions.component';
import { TableKeyValueComponent } from './table-key-value/table-key-value.component';
+import { TablePaginationComponent } from './table-pagination/table-pagination.component';
import { TableComponent } from './table/table.component';
@NgModule({
ComponentsModule,
RouterModule
],
- declarations: [TableComponent, TableKeyValueComponent, TableActionsComponent, CRUDTableComponent],
+ declarations: [
+ TableComponent,
+ TableKeyValueComponent,
+ TableActionsComponent,
+ CRUDTableComponent,
+ TablePaginationComponent
+ ],
exports: [
TableComponent,
NgxDatatableModule,
TableKeyValueComponent,
TableActionsComponent,
- CRUDTableComponent
+ CRUDTableComponent,
+ TablePaginationComponent
]
})
export class DataTableModule {}
import { CdDatePipe } from '~/app/shared/pipes/cd-date.pipe';
import { PipesModule } from '~/app/shared/pipes/pipes.module';
import { configureTestBed } from '~/testing/unit-test-helper';
+import { TablePaginationComponent } from '../table-pagination/table-pagination.component';
import { TableComponent } from '../table/table.component';
import { TableKeyValueComponent } from './table-key-value.component';
let fixture: ComponentFixture<TableKeyValueComponent>;
configureTestBed({
- declarations: [TableComponent, TableKeyValueComponent],
+ declarations: [TableComponent, TableKeyValueComponent, TablePaginationComponent],
imports: [
FormsModule,
NgxDatatableModule,
--- /dev/null
+<nav class="pagination"
+ aria-label="Pagination"
+ i18n-aria-label>
+ <button
+ class="pagination__btn pagination__btn_first"
+ aria-label="Go to first page"
+ i18n-aria-label
+ [disabled]="!canPrevious()"
+ (click)="selectPage(1)"
+ >
+ <i class="fa fa-angle-double-left"
+ aria-hidden="true"></i>
+ </button>
+ <button
+ class="pagination__btn pagination__btn_prev"
+ aria-label="Go to previous page"
+ i18n-aria-label
+ [disabled]="!canPrevious()"
+ (click)="prevPage()"
+ >
+ <i class="fa fa-angle-left"
+ aria-hidden="true"></i>
+ </button>
+ <div class="pagination__pages">
+ <input
+ #pageNumber
+ class="pagination__page_input"
+ aria-label="Current page"
+ i18n-aria-label
+ type="number"
+ min="1"
+ [max]="totalPages"
+ [value]="page"
+ (input)="selectPage(pageNumber.valueAsNumber)"
+ />
+ <span aria-hidden="true"> of {{ totalPages }} </span>
+ </div>
+ <button
+ class="pagination__btn pagination__btn_next"
+ aria-label="Go to next page"
+ i18n-aria-label
+ (click)="nextPage()"
+ [disabled]="!canNext()"
+ >
+ <i class="fa fa-angle-right"
+ aria-hidden="true"></i>
+ </button>
+ <button
+ class="pagination__btn pagination__btn_last"
+ aria-label="Go to last page"
+ i18n-aria-label
+ [disabled]="!canNext()"
+ (click)="selectPage(totalPages)"
+ >
+ <i class="fa fa-angle-double-right"
+ aria-hidden="true"></i>
+ </button>
+</nav>
--- /dev/null
+@use './src/styles/vendor/variables' as vv;
+
+.pagination {
+ align-items: center;
+ display: flex;
+}
+
+.pagination__btn {
+ background: none;
+ border: 0;
+
+ &:disabled {
+ color: vv.$gray-500;
+ }
+}
+
+.pagination__page_input {
+ border: 1px solid vv.$gray-500;
+ border-radius: 0.25rem;
+ padding-left: 0.25rem;
+}
--- /dev/null
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { TablePaginationComponent } from './table-pagination.component';
+
+describe('TablePaginationComponent', () => {
+ let component: TablePaginationComponent;
+ let fixture: ComponentFixture<TablePaginationComponent>;
+ let element: HTMLElement;
+
+ beforeEach(async () => {
+ await TestBed.configureTestingModule({
+ declarations: [TablePaginationComponent]
+ }).compileComponents();
+ });
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(TablePaginationComponent);
+ component = fixture.componentInstance;
+ element = fixture.debugElement.nativeElement;
+ component.page = 1;
+ component.size = 10;
+ component.count = 100;
+ fixture.detectChanges();
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+
+ it('should contain valid inputs', () => {
+ expect(component.page).toEqual(1);
+ expect(component.size).toEqual(10);
+ expect(component.count).toEqual(100);
+ });
+
+ it('should change page', () => {
+ const input = element.querySelector('input');
+ input.value = '5';
+ input.dispatchEvent(new Event('input'));
+ expect(component.page).toEqual(5);
+ });
+
+ it('should disable prev button', () => {
+ const prev: HTMLButtonElement = element.querySelector('.pagination__btn_prev');
+ expect(prev.disabled).toBeTruthy();
+ });
+
+ it('should disable next button', () => {
+ const next: HTMLButtonElement = element.querySelector('.pagination__btn_next');
+ component.size = 100;
+ fixture.detectChanges();
+ expect(next.disabled).toBeTruthy();
+ });
+});
--- /dev/null
+import { Component, EventEmitter, Input, Output } from '@angular/core';
+
+@Component({
+ selector: 'cd-table-pagination',
+ templateUrl: './table-pagination.component.html',
+ styleUrls: ['./table-pagination.component.scss']
+})
+export class TablePaginationComponent {
+ private _size = 0;
+ private _count = 0;
+ private _page = 1;
+ pages: any;
+
+ @Input()
+ set size(value: number) {
+ this._size = value;
+ this.pages = this.calcPages();
+ }
+
+ get size(): number {
+ return this._size;
+ }
+
+ @Input()
+ set page(value: number) {
+ this._page = value;
+ }
+
+ get page(): number {
+ return this._page;
+ }
+
+ @Input()
+ set count(value: number) {
+ this._count = value;
+ }
+
+ get count(): number {
+ return this._count;
+ }
+
+ get totalPages(): number {
+ const count = this.size < 1 ? 1 : Math.ceil(this._count / this._size);
+ return Math.max(count || 0, 1);
+ }
+
+ @Output() pageChange: EventEmitter<any> = new EventEmitter();
+
+ canPrevious(): boolean {
+ return this._page > 1;
+ }
+
+ canNext(): boolean {
+ return this._page < this.totalPages;
+ }
+
+ prevPage(): void {
+ this.selectPage(this._page - 1);
+ }
+
+ nextPage(): void {
+ this.selectPage(this._page + 1);
+ }
+
+ selectPage(page: number): void {
+ if (page > 0 && page <= this.totalPages && page !== this.page) {
+ this._page = page;
+ this.pageChange.emit({
+ page
+ });
+ } else if (page > 0 && page >= this.totalPages) {
+ this._page = this.totalPages;
+ this.pageChange.emit({
+ page: this.totalPages
+ });
+ }
+ }
+
+ calcPages(page?: number): any[] {
+ const pages = [];
+ let startPage = 1;
+ let endPage = this.totalPages;
+ const maxSize = 5;
+ const isMaxSized = maxSize < this.totalPages;
+
+ page = page || this.page;
+
+ if (isMaxSized) {
+ startPage = page - Math.floor(maxSize / 2);
+ endPage = page + Math.floor(maxSize / 2);
+
+ if (startPage < 1) {
+ startPage = 1;
+ endPage = Math.min(startPage + maxSize - 1, this.totalPages);
+ } else if (endPage > this.totalPages) {
+ startPage = Math.max(this.totalPages - maxSize + 1, 1);
+ endPage = this.totalPages;
+ }
+ }
+
+ for (let num = startPage; num <= endPage; num++) {
+ pages.push({
+ number: num,
+ text: <string>(<any>num)
+ });
+ }
+
+ return pages;
+ }
+}
{{ rowCount }} <ng-container i18n="X total">total</ng-container>
</ng-template>
</div>
- <datatable-pager [pagerLeftArrowIcon]="paginationClasses.pagerPrevious"
- [pagerRightArrowIcon]="paginationClasses.pagerNext"
- [pagerPreviousIcon]="paginationClasses.pagerLeftArrow"
- [pagerNextIcon]="paginationClasses.pagerRightArrow"
- [page]="curPage"
- [size]="pageSize"
- [count]="rowCount"
- [hidden]="!((rowCount / pageSize) > 1)"
- (change)="table.onFooterPage($event)">
- </datatable-pager>
+ <cd-table-pagination [page]="curPage"
+ [size]="pageSize"
+ [count]="rowCount"
+ [hidden]="!((rowCount / pageSize) > 1)"
+ (pageChange)="table.onFooterPage($event)"></cd-table-pagination>
</ng-template>
</ngx-datatable-footer>
</ngx-datatable>
import { CdTableSelection } from '~/app/shared/models/cd-table-selection';
import { PipesModule } from '~/app/shared/pipes/pipes.module';
import { configureTestBed } from '~/testing/unit-test-helper';
+import { TablePaginationComponent } from '../table-pagination/table-pagination.component';
import { TableComponent } from './table.component';
describe('TableComponent', () => {
};
configureTestBed({
- declarations: [TableComponent],
+ declarations: [TableComponent, TablePaginationComponent],
imports: [
BrowserAnimationsModule,
NgxDatatableModule,