UNPKG

@rxap/data-source

Version:

Provides a set of classes and decorators for creating and managing data sources in Angular applications, including base classes, static data sources, observable data sources, and method data sources. It also includes a component for displaying data source

469 lines (459 loc) 20.6 kB
import * as i0 from '@angular/core'; import { InjectionToken, isDevMode, Injectable, Optional, Inject, Pipe } from '@angular/core'; import * as i1$1 from '@rxap/data-source'; import { RXAP_DATA_SOURCE_METADATA, RxapDataSourceError } from '@rxap/data-source'; import { AbstractPaginationDataSource, RxapAbstractPaginationDataSource } from '@rxap/data-source/pagination'; import { ToggleSubject } from '@rxap/rxjs'; import { hasIndexSignature, clone, equals } from '@rxap/utilities'; import * as i1 from 'rxjs'; import { BehaviorSubject, combineLatest, of } from 'rxjs'; import { startWith, tap, debounceTime, map, distinctUntilChanged, switchMap, retry } from 'rxjs/operators'; const RXAP_TABLE_DATA_SOURCE_PAGINATOR = new InjectionToken('rxap/data-source/table/paginator'); const RXAP_TABLE_DATA_SOURCE_SORT = new InjectionToken('rxap/data-source/table/sort'); const RXAP_TABLE_DATA_SOURCE_FILTER = new InjectionToken('rxap/data-source/table/filter'); const RXAP_TABLE_DATA_SOURCE_PARAMETERS = new InjectionToken('rxap/data-source/table/parameters'); const RXAP_TABLE_DATA_SOURCE = new InjectionToken('rxap/data-source/table/source'); const RXAP_TABLE_METHOD = new InjectionToken('rxap/data-source/table/table-method'); class AbstractTableDataSource extends AbstractPaginationDataSource { constructor(paginator = null, sort = null, filter = null, parameters = null, metadata = null) { super(paginator, metadata); this.loading$ = new ToggleSubject(true); if (parameters) { this.parameters = parameters; } if (sort) { this.sort = sort; } if (filter) { this.filter = filter; } } get sortByColumn() { return this.sort?.active; } get sortDirection() { return this.sort?.direction; } get totalRowCount() { return this.paginator.length; } get filterValue() { return this.filter?.current; } applySortBy(data, column, direction) { return column ? data.slice().sort((a, b) => { if (!hasIndexSignature(a) || !hasIndexSignature(b)) { return 0; } const aColumn = a[column]; const bColumn = b[column]; const type = typeof aColumn; let sort = 0; switch (type) { case 'boolean': sort = aColumn === bColumn ? 0 : aColumn ? 1 : -1; break; case 'string': sort = aColumn.localeCompare(bColumn); break; case 'number': case 'bigint': sort = aColumn - bColumn; break; } return direction === 'desc' ? sort * -1 : sort; }) : data.slice(); } applyFilterBy(data, filter) { if (filter) { if (typeof filter === 'string') { if (isDevMode()) { console.error('The filter is a string. Currently not supported by the AbstractTableDataSource'); } return data.slice(); } else { return data.filter(row => { return Object.entries(filter).every(([key, value]) => { const type = typeof value; if (row[key] !== undefined && hasIndexSignature(row)) { switch (type) { case 'undefined': return true; case 'object': return value === null || value === undefined || value === row[key]; case 'boolean': return value === row[key]; case 'number': return value === row[key]; case 'string': return (row[key] || '').toString().toLowerCase().includes(value.toLowerCase()); case 'function': return value(row[key]); case 'bigint': return value === row[key]; } } return true; }); }); } } else { return data.slice(); } } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.16", ngImport: i0, type: AbstractTableDataSource, deps: [{ token: RXAP_TABLE_DATA_SOURCE_PAGINATOR, optional: true }, { token: RXAP_TABLE_DATA_SOURCE_SORT, optional: true }, { token: RXAP_TABLE_DATA_SOURCE_FILTER, optional: true }, { token: RXAP_TABLE_DATA_SOURCE_PARAMETERS, optional: true }, { token: RXAP_DATA_SOURCE_METADATA, optional: true }], target: i0.ɵɵFactoryTarget.Injectable }); } static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.16", ngImport: i0, type: AbstractTableDataSource }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.16", ngImport: i0, type: AbstractTableDataSource, decorators: [{ type: Injectable }], ctorParameters: () => [{ type: undefined, decorators: [{ type: Optional }, { type: Inject, args: [RXAP_TABLE_DATA_SOURCE_PAGINATOR] }] }, { type: undefined, decorators: [{ type: Optional }, { type: Inject, args: [RXAP_TABLE_DATA_SOURCE_SORT] }] }, { type: undefined, decorators: [{ type: Optional }, { type: Inject, args: [RXAP_TABLE_DATA_SOURCE_FILTER] }] }, { type: i1.Observable, decorators: [{ type: Optional }, { type: Inject, args: [RXAP_TABLE_DATA_SOURCE_PARAMETERS] }] }, { type: undefined, decorators: [{ type: Optional }, { type: Inject, args: [RXAP_DATA_SOURCE_METADATA] }] }] }); function RxapAbstractTableDataSource(metadataOrId, className = 'AbstractTableDataSource', packageName = '@rxap/data-source/table') { return function (target) { RxapAbstractPaginationDataSource(metadataOrId, className, packageName)(target); }; } /** * @deprecated removed use RXAP_TABLE_METHOD instead */ const RXAP_TABLE_REMOTE_METHOD = new InjectionToken('rxap/data-source/table/remote-method'); class DynamicTableDataSource extends AbstractTableDataSource { constructor(method, paginator = null, sort = null, filter = null, parameters = null, metadata = method.metadata) { super(paginator, sort, filter, parameters, metadata); this.method = method; this.paginatorMap = new Map(); this.sortMap = new Map(); this.filterMap = new Map(); this.parametersMap = new Map(); this._refresh$ = new BehaviorSubject(Date.now()); } /** * @deprecated use method instead * @private */ get remoteMethod() { return this.method; } // eslint-disable-next-line @angular-eslint/contextual-lifecycle ngOnInit() { this._data$ = this.createTableDataLoader(this.paginator, this.sort, this.filter, this.parameters); } setTotalLengthFactory(id) { const paginator = id ? this.paginatorMap.get(id) : this.paginator; function setTotalLength(length) { if (paginator) { paginator.length = length; } } return setTotalLength; } setTotalLength(length, id) { if (id) { if (this.paginatorMap.has(id)) { this.paginatorMap.get(id).length = length; } } else { if (this.paginator) { this.paginator.length = length; } } } refresh() { this._refresh$.next(Date.now()); } setPaginator(paginator, id) { if (paginator) { if (id) { this.paginatorMap.set(id, paginator); } else { this.paginator = paginator; } } } setSort(sort, id) { if (sort) { if (id) { this.sortMap.set(id, sort); } else { this.sort = sort; } } } setFilter(tableFilter, id) { if (tableFilter) { if (id) { this.filterMap.set(id, tableFilter); } else { this.filter = tableFilter; } } } setParameters(parameters, id) { if (parameters) { if (id) { this.parametersMap.set(id, parameters); } else { this.parameters = parameters; } } } genericRetryFunction(error, retryCount) { this.loading$.disable(); return super.genericRetryFunction(error, retryCount); } _connect(viewer) { // call to ensure all parent logic is executed let data = super._connect(viewer); if (viewer.id && this.hasDynamicInputs(viewer.id)) { data = this.createTableDataLoader(this.paginatorMap.get(viewer.id), this.sortMap.get(viewer.id), this.filterMap.get(viewer.id), this.parametersMap.get(viewer.id), viewer.id); } return data; } _disconnect(viewerId) { if (this.hasDynamicInputs(viewerId)) { this.paginatorMap.delete(viewerId); this.sortMap.delete(viewerId); this.filterMap.delete(viewerId); this.parametersMap.delete(viewerId); } super._disconnect(viewerId); } async loadPage(tableEvent) { try { return await this.method.call(tableEvent); } catch (e) { console.error(`Failed to load page: ${e.message}`); this.handelError(e); this.hasError$.enable(); this.error$.next(e); } return []; } handelError(error) { if (isDevMode()) { console.error(`Failed to load page: ${error.message}`, error); } } hasDynamicInputs(id) { return this.paginatorMap.has(id) || this.sortMap.has(id) || this.filterMap.has(id) || this.parametersMap.has(id); } createTableDataLoader(paginatorLike, sortLike, filterLike, parametersLike, id) { return combineLatest([ paginatorLike?.page?.pipe(startWith({ pageIndex: paginatorLike?.pageIndex ?? 0, pageSize: paginatorLike?.pageSize ?? Number.MAX_SAFE_INTEGER, length: paginatorLike?.length, })) ?? of(undefined), sortLike?.sortChange?.pipe(startWith({ active: sortLike?.active, direction: sortLike?.direction, })) ?? of(undefined), filterLike?.change?.pipe(tap(() => paginatorLike?.firstPage && paginatorLike?.firstPage())) ?? of(undefined), parametersLike ?? of(undefined), this._refresh$, this._retry$.pipe(startWith(null)), ]).pipe(debounceTime(100), map(([page, sort, filter, parameters, refresh]) => { const tableEvent = { page, start: page ? page.pageSize * page.pageIndex : 0, end: page ? page.pageSize * page.pageIndex + page.pageSize : Number.MAX_SAFE_INTEGER, sort, filter, parameters, refresh, }; return { ...clone(tableEvent), setTotalLength: this.setTotalLengthFactory(id), }; }), distinctUntilChanged((a, b) => equals(a, b)), tap(() => { this.loading$.enable(); if (this.hasError$.value) { this.hasError$.disable(); } }), switchMap(tableEvent => this.loadPage(tableEvent)), tap({ next: () => this.loading$.disable(), error: error => { this.hasError$.enable(); this.error$.next(error); this.handelError(error); }, }), retry({ delay: (error, retryCount) => this.genericRetryFunction(error, retryCount), })); } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.16", ngImport: i0, type: DynamicTableDataSource, deps: [{ token: RXAP_TABLE_METHOD, optional: true }, { token: RXAP_TABLE_DATA_SOURCE_PAGINATOR, optional: true }, { token: RXAP_TABLE_DATA_SOURCE_SORT, optional: true }, { token: RXAP_TABLE_DATA_SOURCE_FILTER, optional: true }, { token: RXAP_TABLE_DATA_SOURCE_PARAMETERS, optional: true }, { token: RXAP_DATA_SOURCE_METADATA, optional: true }], target: i0.ɵɵFactoryTarget.Injectable }); } static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.16", ngImport: i0, type: DynamicTableDataSource }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.16", ngImport: i0, type: DynamicTableDataSource, decorators: [{ type: Injectable }], ctorParameters: () => [{ type: undefined, decorators: [{ type: Optional }, { type: Inject, args: [RXAP_TABLE_METHOD] }] }, { type: undefined, decorators: [{ type: Optional }, { type: Inject, args: [RXAP_TABLE_DATA_SOURCE_PAGINATOR] }] }, { type: undefined, decorators: [{ type: Optional }, { type: Inject, args: [RXAP_TABLE_DATA_SOURCE_SORT] }] }, { type: undefined, decorators: [{ type: Optional }, { type: Inject, args: [RXAP_TABLE_DATA_SOURCE_FILTER] }] }, { type: i1.Observable, decorators: [{ type: Optional }, { type: Inject, args: [RXAP_TABLE_DATA_SOURCE_PARAMETERS] }] }, { type: undefined, decorators: [{ type: Optional }, { type: Inject, args: [RXAP_DATA_SOURCE_METADATA] }] }] }); class RxapTableDataSourceError extends RxapDataSourceError { constructor(message, code, className) { super(message, code, className); this.addSubPackageName('table'); } } class TableDataSource extends AbstractTableDataSource { constructor(dataSource, paginator = null, sort = null, filter = null, parameters = null, metadata = dataSource.metadata) { super(paginator, sort, filter, parameters, metadata); this.dataSource = dataSource; } refresh() { this.dataSource.refresh(); } _connect(viewer) { return [ this.dataSource.connect(viewer).pipe(tap((data) => this.updateTotalLength(data.length)), tap(() => this.loading$.disable()), switchMap((data) => { this.assertPaginator(); if (this.paginator && this.paginator.page) { return combineLatest([ this.paginator.page.pipe(startWith({ pageIndex: this.paginator.pageIndex, pageSize: this.paginator.pageSize, length: this.paginator.length, })), this.sort?.sortChange?.pipe(startWith({ active: this.sort?.active, direction: this.sort?.direction, })) ?? of(null), this.filter?.change.pipe(startWith({})) ?? of(null), ]).pipe(map(([page, sort, filter]) => { let filteredData = data; if (filter) { filteredData = this.applyFilterBy(filteredData, filter); } let sortData = filteredData; if (sort) { sortData = this.applySortBy(sortData, sort.active, sort.direction); } return this.applyPagination(sortData, page.pageSize, page.pageIndex); })); } throw new Error('The paginator have not a defined page property!'); })), () => this.dataSource.disconnect(viewer), ]; } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.16", ngImport: i0, type: TableDataSource, deps: [{ token: RXAP_TABLE_DATA_SOURCE }, { token: RXAP_TABLE_DATA_SOURCE_PAGINATOR, optional: true }, { token: RXAP_TABLE_DATA_SOURCE_SORT, optional: true }, { token: RXAP_TABLE_DATA_SOURCE_FILTER, optional: true }, { token: RXAP_TABLE_DATA_SOURCE_PARAMETERS, optional: true }, { token: RXAP_DATA_SOURCE_METADATA, optional: true }], target: i0.ɵɵFactoryTarget.Injectable }); } static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.16", ngImport: i0, type: TableDataSource }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.16", ngImport: i0, type: TableDataSource, decorators: [{ type: Injectable }], ctorParameters: () => [{ type: i1$1.BaseDataSource, decorators: [{ type: Inject, args: [RXAP_TABLE_DATA_SOURCE] }] }, { type: undefined, decorators: [{ type: Optional }, { type: Inject, args: [RXAP_TABLE_DATA_SOURCE_PAGINATOR] }] }, { type: undefined, decorators: [{ type: Optional }, { type: Inject, args: [RXAP_TABLE_DATA_SOURCE_SORT] }] }, { type: undefined, decorators: [{ type: Optional }, { type: Inject, args: [RXAP_TABLE_DATA_SOURCE_FILTER] }] }, { type: i1.Observable, decorators: [{ type: Optional }, { type: Inject, args: [RXAP_TABLE_DATA_SOURCE_PARAMETERS] }] }, { type: undefined, decorators: [{ type: Optional }, { type: Inject, args: [RXAP_DATA_SOURCE_METADATA] }] }] }); function RxapTableDataSource(metadataOrId, className = 'TableDataSource', packageName = '@rxap/data-source/table') { return function (target) { RxapAbstractTableDataSource(metadataOrId, className, packageName)(target); }; } class ToTableDataSourcePipe { transform(dataSource, paginator, sort, filter) { return new TableDataSource(dataSource, paginator, sort, filter); } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.16", ngImport: i0, type: ToTableDataSourcePipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe }); } static { this.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "19.2.16", ngImport: i0, type: ToTableDataSourcePipe, isStandalone: true, name: "toTableDataSource" }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.16", ngImport: i0, type: ToTableDataSourcePipe, decorators: [{ type: Pipe, args: [{ name: 'toTableDataSource', standalone: true, }] }] }); // region // endregion /** * Generated bundle index. Do not edit. */ export { AbstractTableDataSource, DynamicTableDataSource, RXAP_TABLE_DATA_SOURCE, RXAP_TABLE_DATA_SOURCE_FILTER, RXAP_TABLE_DATA_SOURCE_PAGINATOR, RXAP_TABLE_DATA_SOURCE_PARAMETERS, RXAP_TABLE_DATA_SOURCE_SORT, RXAP_TABLE_METHOD, RXAP_TABLE_REMOTE_METHOD, RxapAbstractTableDataSource, RxapTableDataSource, RxapTableDataSourceError, TableDataSource, ToTableDataSourcePipe }; //# sourceMappingURL=rxap-data-source-table.mjs.map