@anglr/grid
Version:
Angular module displaying grid
217 lines • 11.3 kB
JavaScript
import { Component, ChangeDetectionStrategy, signal, computed, effect } from '@angular/core';
import { CommonModule } from '@angular/common';
import { Paginator, isPresent } from '@jscrpt/common';
import { PagingAbstractComponent } from '../pagingAbstract.component';
import { DEFAULT_OPTIONS } from '../../../misc/tokens';
import { InfinityNaNPipe } from '../../../pipes';
import * as i0 from "@angular/core";
import * as i1 from "@angular/common";
/**
* Default options for paging
*/
const defaultOptions = {
initialItemsPerPage: 10,
initialPage: 1,
itemsPerPageValues: [],
pagesDispersion: 4,
cssClasses: {
pagingContainer: 'grid-flex-row',
pagingElement: 'grid-flex-row pages',
pagingSeparatorElement: 'grid-flex-1',
itemsPerPageContainer: 'grid-flex-row',
itemsCountElement: 'paging-items-count',
itemsPerPageElement: 'grid-flex-row items-per-page',
},
};
/**
* Component used for rendering basic simple paging
*/
export class BasicPagingComponent extends PagingAbstractComponent {
//######################### public properties #########################
/**
* @inheritdoc
*/
get firstItemIndex() {
const offset = this.paginator.getOffset();
return isNaN(offset) ? 0 : offset;
}
//######################### public properties - overrides #########################
/**
* @inheritdoc
*/
get options() {
return super.options;
}
set options(options) {
super.options = options;
this.optionsValue.update(opts => {
return {
...opts,
itemsPerPageValues: options.itemsPerPageValues ?? opts.itemsPerPageValues,
};
});
}
//######################### constructor #########################
constructor() {
super();
//######################### protected fields #########################
/**
* Paginator used for getting page numbers
*/
this.paginator = new Paginator();
//######################### protected properties - template bindings #########################
/**
* Text displaying items count
*/
this.displayedItemsCount = signal('').asReadonly();
/**
* Array of pages that are rendered
*/
this.pages = signal([]).asReadonly();
this.itemsPerPageItems = computed(() => {
const itemsPerPageValues = this.optionsValue().itemsPerPageValues;
const itemsPerPage = this.itemsPerPageValue() ?? NaN;
const result = [];
for (const val of itemsPerPageValues) {
result.push({
value: val,
isActive: val == itemsPerPage || (isNaN(val) && isNaN(itemsPerPage))
});
}
return result;
});
}
//######################### public methods - implementation of OnDestroy #########################
/**
* Called when component is destroyed
*/
ngOnDestroy() {
this.pageGuardEffect?.destroy();
this.pageGuardEffect = null;
}
//######################### public methods - overrides #########################
/**
* @inheritdoc
*/
async initialize(force) {
await super.initialize(force);
this.pageGuardEffect?.destroy();
this.pageGuardEffect = null;
this.pageGuardEffect = effect(() => {
this.paginator.setPage(this.pageValue() ?? 1);
this.paginator.setItemsPerPage(this.itemsPerPageValue() ?? NaN);
this.paginator.setItemCount(this.totalCount());
const pageCount = this.paginator.getPageCount() || 1;
//Applied when displaying all items
if (isNaN(pageCount)) {
if (this.pageValue() != 1) {
this.paginator.setPage(1);
this.pageValue.set(1);
}
return;
}
//move to last page
if (!isNaN(pageCount) && pageCount < (this.pageValue() ?? 1) && this.totalCount() > 0) {
this.setPageItem({
page: pageCount,
isActive: false,
isDisabled: false,
title: '',
});
}
}, { manualCleanup: true, injector: this.injector, allowSignalWrites: true });
this.displayedItemsCount = computed(() => {
this.paginator.setPage(this.pageValue() ?? 1);
this.paginator.setItemsPerPage(this.itemsPerPageValue() ?? NaN);
this.paginator.setItemCount(this.totalCount());
const displayedItems = this.paginator.getOffset() + this.paginator.getLength();
const totalCount = this.totalCount();
let result = '';
if (isNaN(displayedItems) && isPresent(totalCount)) {
result = totalCount.toString();
}
else if (!isNaN(displayedItems) && isPresent(totalCount)) {
result = `${displayedItems}/${totalCount}`;
}
return result;
});
this.pages = computed(() => {
this.paginator.setPage(this.pageValue() ?? 1);
this.paginator.setItemsPerPage(this.itemsPerPageValue() ?? NaN);
this.paginator.setItemCount(this.totalCount());
const pageCount = this.paginator.getPageCount() || 1;
//ignore, handled by pageguard
if (isNaN(pageCount)) {
return [];
}
//ignore, handled by pageguard
if (!isNaN(pageCount) && pageCount < (this.pageValue() ?? 1) && this.totalCount() > 0) {
return [];
}
const result = [];
result.push({
isActive: false,
isDisabled: this.paginator.isFirst(),
title: '«',
page: this.paginator.getFirstPage()
});
this.paginator.getPagesWithTrimDispersion(this.optionsValue().pagesDispersion).forEach(page => {
result.push({
isActive: this.paginator.getPage() == page,
isDisabled: false,
title: page.toString(),
page: page
});
});
result.push({
isActive: false,
isDisabled: this.paginator.isLast(),
title: '»',
page: this.paginator.getLastPage()
});
return result;
});
this.changeDetector.detectChanges();
}
//######################### protected methods - template bindings #########################
/**
* Sets page item to current paging
* @param page - Page item to be set
*/
setPageItem(page) {
if (page.isActive || page.isDisabled) {
return;
}
this.setPage(page.page);
}
/**
* Sets items per page to current paging
* @param itemsPerPage - Items per page item to be set
*/
setItemsPerPageItem(itemsPerPage) {
if (itemsPerPage.isActive) {
return;
}
this.setItemsPerPage(itemsPerPage.value);
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.1.0", ngImport: i0, type: BasicPagingComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.1.0", type: BasicPagingComponent, isStandalone: true, selector: "ng-basic-paging", providers: [
{
provide: DEFAULT_OPTIONS,
useValue: defaultOptions,
},
], usesInheritance: true, ngImport: i0, template: "<div [ngClass]=\"optionsValue().cssClasses.pagingContainer\">\r\n <div [ngClass]=\"optionsValue().cssClasses.pagingElement\">\r\n @for(page of pages(); track page)\r\n {\r\n <a (click)=\"setPageItem(page)\" [ngClass]=\"{disabled: page.isDisabled, active: page.isActive}\">\r\n <span [innerHtml]=\"page.title\"></span>\r\n </a>\r\n }\r\n </div>\r\n\r\n <div [ngClass]=\"optionsValue().cssClasses.pagingSeparatorElement\"></div>\r\n\r\n @if(itemsPerPageItems().length)\r\n {\r\n <div [ngClass]=\"optionsValue().cssClasses.itemsPerPageContainer\">\r\n <div [ngClass]=\"optionsValue().cssClasses.itemsCountElement\">{{displayedItemsCount()}}</div>\r\n\r\n <div [ngClass]=\"optionsValue().cssClasses.itemsPerPageElement\">\r\n @for (itemsPerPage of itemsPerPageItems(); track itemsPerPage)\r\n {\r\n <a (click)=\"setItemsPerPageItem(itemsPerPage)\" [ngClass]=\"{active: itemsPerPage.isActive}\">\r\n <span [innerHtml]=\"itemsPerPage.value | infinityNaN\"></span>\r\n </a>\r\n }\r\n </div>\r\n </div>\r\n }\r\n</div>", dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "pipe", type: InfinityNaNPipe, name: "infinityNaN" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.0", ngImport: i0, type: BasicPagingComponent, decorators: [{
type: Component,
args: [{ selector: 'ng-basic-paging', imports: [
CommonModule,
InfinityNaNPipe,
], providers: [
{
provide: DEFAULT_OPTIONS,
useValue: defaultOptions,
},
], changeDetection: ChangeDetectionStrategy.OnPush, template: "<div [ngClass]=\"optionsValue().cssClasses.pagingContainer\">\r\n <div [ngClass]=\"optionsValue().cssClasses.pagingElement\">\r\n @for(page of pages(); track page)\r\n {\r\n <a (click)=\"setPageItem(page)\" [ngClass]=\"{disabled: page.isDisabled, active: page.isActive}\">\r\n <span [innerHtml]=\"page.title\"></span>\r\n </a>\r\n }\r\n </div>\r\n\r\n <div [ngClass]=\"optionsValue().cssClasses.pagingSeparatorElement\"></div>\r\n\r\n @if(itemsPerPageItems().length)\r\n {\r\n <div [ngClass]=\"optionsValue().cssClasses.itemsPerPageContainer\">\r\n <div [ngClass]=\"optionsValue().cssClasses.itemsCountElement\">{{displayedItemsCount()}}</div>\r\n\r\n <div [ngClass]=\"optionsValue().cssClasses.itemsPerPageElement\">\r\n @for (itemsPerPage of itemsPerPageItems(); track itemsPerPage)\r\n {\r\n <a (click)=\"setItemsPerPageItem(itemsPerPage)\" [ngClass]=\"{active: itemsPerPage.isActive}\">\r\n <span [innerHtml]=\"itemsPerPage.value | infinityNaN\"></span>\r\n </a>\r\n }\r\n </div>\r\n </div>\r\n }\r\n</div>" }]
}], ctorParameters: () => [] });
//# sourceMappingURL=basicPaging.component.js.map