UNPKG

@igo2/common

Version:
267 lines (259 loc) 20.8 kB
import * as i0 from '@angular/core'; import { EventEmitter, ViewChild, Output, Input, Component, NgModule } from '@angular/core'; import { SelectionModel } from '@angular/cdk/collections'; import { NgIf, NgFor, NgClass } from '@angular/common'; import * as i6 from '@angular/material/button'; import { MatButtonModule } from '@angular/material/button'; import * as i5 from '@angular/material/checkbox'; import { MatCheckboxModule } from '@angular/material/checkbox'; import * as i1 from '@angular/material/form-field'; import { MatFormFieldModule } from '@angular/material/form-field'; import * as i7 from '@angular/material/icon'; import { MatIconModule } from '@angular/material/icon'; import * as i2 from '@angular/material/input'; import { MatInputModule } from '@angular/material/input'; import * as i4 from '@angular/material/sort'; import { MatSortModule, MatSort } from '@angular/material/sort'; import * as i3 from '@angular/material/table'; import { MatTableModule } from '@angular/material/table'; import { IgoLanguageModule } from '@igo2/core/language'; import { ObjectUtils } from '@igo2/utils'; import { BehaviorSubject, merge, fromEvent } from 'rxjs'; import { map, debounceTime, distinctUntilChanged } from 'rxjs/operators'; import { DataSource } from '@angular/cdk/table'; import * as i8 from '@ngx-translate/core'; var TableActionColor; (function (TableActionColor) { TableActionColor[TableActionColor["primary"] = 0] = "primary"; TableActionColor[TableActionColor["accent"] = 1] = "accent"; TableActionColor[TableActionColor["warn"] = 2] = "warn"; })(TableActionColor || (TableActionColor = {})); class TableDatabase { /** Stream that emits whenever the data has been modified. */ dataChange = new BehaviorSubject([]); get data() { return this.dataChange.value; } constructor(data) { if (data) { this.dataChange.next(data); } } set(data) { this.dataChange.next(data); } add(item) { const copiedData = this.data.slice(); copiedData.push(item); this.set(copiedData); } remove(item) { const copiedData = this.data.slice(); const index = copiedData.indexOf(item); copiedData.splice(index, 1); this.set(copiedData); } } class TableDataSource extends DataSource { _database; _model; _sort; get filter() { return this._filterChange.value; } set filter(filter) { this._filterChange.next(filter); } _filterChange = new BehaviorSubject(''); constructor(_database, _model, _sort) { super(); this._database = _database; this._model = _model; this._sort = _sort; } // Connect function called by the table to retrieve one stream containing // the data to render. connect() { if (!this._database) { return merge([]); } const displayDataChanges = [ this._database.dataChange, this._filterChange, this._sort.sortChange ]; return merge(...displayDataChanges).pipe(map(() => { return this.getFilteredData(this._database.data); }), map((data) => { return this.getSortedData(data); })); } disconnect() { // empty } getFilteredData(data) { if (!this.filter) { return data; } return data.slice().filter((item) => { const searchStr = this._model.columns .filter((c) => c.filterable) .map((c) => ObjectUtils.resolve(item, c.name)) .join(' ') .toLowerCase(); return searchStr.indexOf(this.filter.toLowerCase()) !== -1; }); } getSortedData(data) { if (!this._sort.active || this._sort.direction === '') { return data; } return data.sort((a, b) => { const propertyA = ObjectUtils.resolve(a, this._sort.active); const propertyB = ObjectUtils.resolve(b, this._sort.active); return ObjectUtils.naturalCompare(propertyB, propertyA, this._sort.direction); }); } } class TableComponent { get database() { return this._database; } set database(value) { this._database = value; } _database; get model() { return this._model; } set model(value) { this._model = value; } _model; get hasFilterInput() { return this._hasFIlterInput; } set hasFilterInput(value) { this._hasFIlterInput = value; } _hasFIlterInput = true; displayedColumns; dataSource; selection = new SelectionModel(true, []); select = new EventEmitter(); filter; sort; ngOnInit() { this.dataSource = new TableDataSource(this.database, this.model, this.sort); if (this.model) { this.displayedColumns = this.model.columns .filter((c) => c.displayed !== false) .map((c) => c.name); if (this.model.selectionCheckbox) { this.displayedColumns.unshift('selectionCheckbox'); } if (this.model.actions && this.model.actions.length) { this.displayedColumns.push('action'); } } this.selection.changed.subscribe((e) => this.select.emit(e)); } ngAfterViewInit() { if (this.filter) { fromEvent(this.filter.nativeElement, 'keyup') .pipe(debounceTime(150), distinctUntilChanged()) .subscribe(() => { if (!this.dataSource) { return; } this.dataSource.filter = this.filter.nativeElement.value; }); } } ngOnChanges(change) { if (change.database) { this.dataSource = new TableDataSource(this.database, this.model, this.sort); this.selection.clear(); } } getActionColor(colorId) { return TableActionColor[colorId]; } getValue(row, key) { return ObjectUtils.resolve(row, key); } /** Whether the number of selected elements matches the total number of rows. */ isAllSelected() { const numSelected = this.selection.selected.length; const numRows = this.database.data.length; return numSelected === numRows; } /** Selects all rows if they are not all selected; otherwise clear selection. */ masterToggle() { this.isAllSelected() ? this.selection.clear() : this.database.data.forEach((row) => this.selection.select(row)); } handleClickAction(event, action, row) { event.stopPropagation(); action.click(row); } static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.15", ngImport: i0, type: TableComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.15", type: TableComponent, isStandalone: true, selector: "igo-table", inputs: { database: "database", model: "model", hasFilterInput: "hasFilterInput" }, outputs: { select: "select" }, viewQueries: [{ propertyName: "filter", first: true, predicate: ["filter"], descendants: true }, { propertyName: "sort", first: true, predicate: MatSort, descendants: true, static: true }], usesOnChanges: true, ngImport: i0, template: "<div class=\"table-box\">\n <div class=\"table-header\" *ngIf=\"hasFilterInput\">\n <mat-form-field floatPlaceholder=\"never\">\n <input\n matInput\n #filter\n [placeholder]=\"'igo.common.table.filter' | translate\"\n />\n </mat-form-field>\n </div>\n\n <div class=\"table-container\">\n <table mat-table #table [dataSource]=\"dataSource\" matSort>\n <!-- Checkbox Column -->\n <ng-container matColumnDef=\"selectionCheckbox\">\n <th mat-header-cell *matHeaderCellDef>\n <mat-checkbox\n (change)=\"$event ? masterToggle() : null\"\n [checked]=\"selection.hasValue() && isAllSelected()\"\n [indeterminate]=\"selection.hasValue() && !isAllSelected()\"\n >\n </mat-checkbox>\n </th>\n <td mat-cell *matCellDef=\"let row\">\n <mat-checkbox\n (click)=\"$event.stopPropagation()\"\n (change)=\"$event ? selection.toggle(row) : null\"\n [checked]=\"selection.isSelected(row)\"\n >\n </mat-checkbox>\n </td>\n </ng-container>\n\n <ng-container\n [matColumnDef]=\"column.name\"\n *ngFor=\"let column of model.columns\"\n >\n <ng-container *ngIf=\"column.sortable\">\n <th mat-header-cell *matHeaderCellDef mat-sort-header>\n {{ column.title }}\n </th>\n </ng-container>\n\n <ng-container *ngIf=\"!column.sortable\">\n <th mat-header-cell *matHeaderCellDef>{{ column.title }}</th>\n </ng-container>\n\n <ng-container *ngIf=\"!column.html; else cellHTML\">\n <td\n mat-cell\n *matCellDef=\"let row\"\n class=\"mat-cell-text\"\n [ngClass]=\"\n model.cellClassFunc ? model.cellClassFunc(row, column) : {}\n \"\n >\n {{ getValue(row, column.name) }}\n </td>\n </ng-container>\n\n <ng-template #cellHTML>\n <td\n mat-cell\n *matCellDef=\"let row\"\n class=\"mat-cell-text\"\n [ngClass]=\"\n model.cellClassFunc ? model.cellClassFunc(row, column) : {}\n \"\n [innerHTML]=\"getValue(row, column.name)\"\n ></td>\n </ng-template>\n </ng-container>\n\n <!-- Action Column -->\n <ng-container matColumnDef=\"action\">\n <th mat-header-cell *matHeaderCellDef></th>\n <td mat-cell *matCellDef=\"let row\">\n <button\n *ngFor=\"let action of model.actions\"\n mat-mini-fab\n [color]=\"getActionColor(action.color)\"\n (click)=\"handleClickAction($event, action, row)\"\n >\n <mat-icon>{{ action.icon }}</mat-icon>\n </button>\n </td>\n </ng-container>\n\n <tr mat-header-row *matHeaderRowDef=\"displayedColumns\"></tr>\n <tr\n mat-row\n *matRowDef=\"let row; columns: displayedColumns\"\n [ngClass]=\"model.rowClassFunc ? model.rowClassFunc(row) : {}\"\n (click)=\"selection.toggle(row)\"\n ></tr>\n </table>\n </div>\n</div>\n", styles: [":host{width:100%;height:100%;display:block}.table-container{display:flex;flex-direction:column;height:100%;overflow:auto;flex:1 1 auto}.table-box{height:100%;display:flex;flex-direction:column}.table-header{min-height:64px;max-width:500px;display:flex;flex:0 1 auto;align-items:baseline;padding:8px 24px 0;font-size:20px;justify-content:space-between}tr[mat-header-row],tr[mat-row]{height:60px}.mat-cell-text{overflow:hidden;word-wrap:break-word}td[mat-cell]{padding-right:15px}th.mat-mdc-header-cell{padding-right:5px}button{margin-right:10px}\n"], dependencies: [{ kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "component", type: i1.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i2.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly", "disabledInteractive"], exportAs: ["matInput"] }, { kind: "ngmodule", type: MatTableModule }, { kind: "component", type: i3.MatTable, selector: "mat-table, table[mat-table]", exportAs: ["matTable"] }, { kind: "directive", type: i3.MatHeaderCellDef, selector: "[matHeaderCellDef]" }, { kind: "directive", type: i3.MatHeaderRowDef, selector: "[matHeaderRowDef]", inputs: ["matHeaderRowDef", "matHeaderRowDefSticky"] }, { kind: "directive", type: i3.MatColumnDef, selector: "[matColumnDef]", inputs: ["matColumnDef"] }, { kind: "directive", type: i3.MatCellDef, selector: "[matCellDef]" }, { kind: "directive", type: i3.MatRowDef, selector: "[matRowDef]", inputs: ["matRowDefColumns", "matRowDefWhen"] }, { kind: "directive", type: i3.MatHeaderCell, selector: "mat-header-cell, th[mat-header-cell]" }, { kind: "directive", type: i3.MatCell, selector: "mat-cell, td[mat-cell]" }, { kind: "component", type: i3.MatHeaderRow, selector: "mat-header-row, tr[mat-header-row]", exportAs: ["matHeaderRow"] }, { kind: "component", type: i3.MatRow, selector: "mat-row, tr[mat-row]", exportAs: ["matRow"] }, { kind: "ngmodule", type: MatSortModule }, { kind: "directive", type: i4.MatSort, selector: "[matSort]", inputs: ["matSortActive", "matSortStart", "matSortDirection", "matSortDisableClear", "matSortDisabled"], outputs: ["matSortChange"], exportAs: ["matSort"] }, { kind: "component", type: i4.MatSortHeader, selector: "[mat-sort-header]", inputs: ["mat-sort-header", "arrowPosition", "start", "disabled", "sortActionDescription", "disableClear"], exportAs: ["matSortHeader"] }, { kind: "ngmodule", type: MatCheckboxModule }, { kind: "component", type: i5.MatCheckbox, selector: "mat-checkbox", inputs: ["aria-label", "aria-labelledby", "aria-describedby", "aria-expanded", "aria-controls", "aria-owns", "id", "required", "labelPosition", "name", "value", "disableRipple", "tabIndex", "color", "disabledInteractive", "checked", "disabled", "indeterminate"], outputs: ["change", "indeterminateChange"], exportAs: ["matCheckbox"] }, { kind: "directive", type: NgFor, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i6.MatMiniFabButton, selector: "button[mat-mini-fab]", exportAs: ["matButton"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i7.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: IgoLanguageModule }, { kind: "pipe", type: i8.TranslatePipe, name: "translate" }] }); } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.15", ngImport: i0, type: TableComponent, decorators: [{ type: Component, args: [{ selector: 'igo-table', imports: [ NgIf, MatFormFieldModule, MatInputModule, MatTableModule, MatSortModule, MatCheckboxModule, NgFor, NgClass, MatButtonModule, MatIconModule, IgoLanguageModule ], template: "<div class=\"table-box\">\n <div class=\"table-header\" *ngIf=\"hasFilterInput\">\n <mat-form-field floatPlaceholder=\"never\">\n <input\n matInput\n #filter\n [placeholder]=\"'igo.common.table.filter' | translate\"\n />\n </mat-form-field>\n </div>\n\n <div class=\"table-container\">\n <table mat-table #table [dataSource]=\"dataSource\" matSort>\n <!-- Checkbox Column -->\n <ng-container matColumnDef=\"selectionCheckbox\">\n <th mat-header-cell *matHeaderCellDef>\n <mat-checkbox\n (change)=\"$event ? masterToggle() : null\"\n [checked]=\"selection.hasValue() && isAllSelected()\"\n [indeterminate]=\"selection.hasValue() && !isAllSelected()\"\n >\n </mat-checkbox>\n </th>\n <td mat-cell *matCellDef=\"let row\">\n <mat-checkbox\n (click)=\"$event.stopPropagation()\"\n (change)=\"$event ? selection.toggle(row) : null\"\n [checked]=\"selection.isSelected(row)\"\n >\n </mat-checkbox>\n </td>\n </ng-container>\n\n <ng-container\n [matColumnDef]=\"column.name\"\n *ngFor=\"let column of model.columns\"\n >\n <ng-container *ngIf=\"column.sortable\">\n <th mat-header-cell *matHeaderCellDef mat-sort-header>\n {{ column.title }}\n </th>\n </ng-container>\n\n <ng-container *ngIf=\"!column.sortable\">\n <th mat-header-cell *matHeaderCellDef>{{ column.title }}</th>\n </ng-container>\n\n <ng-container *ngIf=\"!column.html; else cellHTML\">\n <td\n mat-cell\n *matCellDef=\"let row\"\n class=\"mat-cell-text\"\n [ngClass]=\"\n model.cellClassFunc ? model.cellClassFunc(row, column) : {}\n \"\n >\n {{ getValue(row, column.name) }}\n </td>\n </ng-container>\n\n <ng-template #cellHTML>\n <td\n mat-cell\n *matCellDef=\"let row\"\n class=\"mat-cell-text\"\n [ngClass]=\"\n model.cellClassFunc ? model.cellClassFunc(row, column) : {}\n \"\n [innerHTML]=\"getValue(row, column.name)\"\n ></td>\n </ng-template>\n </ng-container>\n\n <!-- Action Column -->\n <ng-container matColumnDef=\"action\">\n <th mat-header-cell *matHeaderCellDef></th>\n <td mat-cell *matCellDef=\"let row\">\n <button\n *ngFor=\"let action of model.actions\"\n mat-mini-fab\n [color]=\"getActionColor(action.color)\"\n (click)=\"handleClickAction($event, action, row)\"\n >\n <mat-icon>{{ action.icon }}</mat-icon>\n </button>\n </td>\n </ng-container>\n\n <tr mat-header-row *matHeaderRowDef=\"displayedColumns\"></tr>\n <tr\n mat-row\n *matRowDef=\"let row; columns: displayedColumns\"\n [ngClass]=\"model.rowClassFunc ? model.rowClassFunc(row) : {}\"\n (click)=\"selection.toggle(row)\"\n ></tr>\n </table>\n </div>\n</div>\n", styles: [":host{width:100%;height:100%;display:block}.table-container{display:flex;flex-direction:column;height:100%;overflow:auto;flex:1 1 auto}.table-box{height:100%;display:flex;flex-direction:column}.table-header{min-height:64px;max-width:500px;display:flex;flex:0 1 auto;align-items:baseline;padding:8px 24px 0;font-size:20px;justify-content:space-between}tr[mat-header-row],tr[mat-row]{height:60px}.mat-cell-text{overflow:hidden;word-wrap:break-word}td[mat-cell]{padding-right:15px}th.mat-mdc-header-cell{padding-right:5px}button{margin-right:10px}\n"] }] }], propDecorators: { database: [{ type: Input }], model: [{ type: Input }], hasFilterInput: [{ type: Input }], select: [{ type: Output }], filter: [{ type: ViewChild, args: ['filter'] }], sort: [{ type: ViewChild, args: [MatSort, { static: true }] }] } }); /** * @deprecated import the TableComponent directly */ class IgoTableModule { static forRoot() { return { ngModule: IgoTableModule, providers: [] }; } static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.15", ngImport: i0, type: IgoTableModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); static ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "19.2.15", ngImport: i0, type: IgoTableModule, imports: [TableComponent], exports: [TableComponent] }); static ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "19.2.15", ngImport: i0, type: IgoTableModule, imports: [TableComponent] }); } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.15", ngImport: i0, type: IgoTableModule, decorators: [{ type: NgModule, args: [{ imports: [TableComponent], exports: [TableComponent] }] }] }); /** * Generated bundle index. Do not edit. */ export { IgoTableModule, TableActionColor, TableComponent, TableDataSource, TableDatabase }; //# sourceMappingURL=igo2-common-table.mjs.map