UNPKG

novo-elements

Version:

927 lines (920 loc) 150 kB
import * as i1 from '@angular/cdk/table'; import { CdkCellDef, CdkHeaderCellDef, CdkColumnDef, CdkHeaderCell, CdkCell, CdkHeaderRowDef, CdkRowDef, CdkHeaderRow, CdkRow, CDK_ROW_TEMPLATE, DataSource, CdkTable, CDK_TABLE, CdkTableModule } from '@angular/cdk/table'; import * as i0 from '@angular/core'; import { EventEmitter, Injectable, Directive, Output, Input, HostBinding, Optional, Component, ChangeDetectionStrategy, ViewChild, ViewEncapsulation, NgModule } from '@angular/core'; import * as i1$1 from 'novo-elements/services'; import { Helpers, DateUtil, notify } from 'novo-elements/utils'; import * as i3 from '@angular/forms'; import { FormsModule } from '@angular/forms'; import * as i4 from 'novo-elements/elements/checkbox'; import { NovoCheckboxModule } from 'novo-elements/elements/checkbox'; import * as i6 from '@angular/common'; import { CommonModule } from '@angular/common'; import * as i8 from 'novo-elements/elements/common'; import { NovoCommonModule, NovoOptionModule } from 'novo-elements/elements/common'; import * as i8$1 from 'novo-elements/elements/button'; import { NovoButtonModule } from 'novo-elements/elements/button'; import * as i9 from 'novo-elements/elements/dropdown'; import { NovoDropdownElement, NovoDropdownModule } from 'novo-elements/elements/dropdown'; import { coerceBooleanProperty } from '@angular/cdk/coercion'; import { startOfTomorrow, startOfToday } from 'date-fns'; import * as i5 from 'novo-elements/elements/date-picker'; import { NovoDatePickerModule } from 'novo-elements/elements/date-picker'; import * as i7 from 'novo-elements/elements/tiles'; import { NovoTilesModule } from 'novo-elements/elements/tiles'; import * as i4$1 from 'novo-elements/elements/select'; import { NovoSelectModule } from 'novo-elements/elements/select'; import { NovoFormExtrasModule } from 'novo-elements/elements/form'; import * as i6$1 from 'novo-elements/elements/loading'; import { NovoLoadingModule } from 'novo-elements/elements/loading'; import * as i7$1 from 'novo-elements/elements/search'; import { NovoSearchBoxModule } from 'novo-elements/elements/search'; import { _DisposeViewRepeaterStrategy, _VIEW_REPEATER_STRATEGY } from '@angular/cdk/collections'; import { of, merge } from 'rxjs'; import { startWith, switchMap, map, catchError } from 'rxjs/operators'; class ActivityTableRenderers { static propertyRenderer(prop) { const ret = (data) => { // TODO - allow for dots and sub props return data[prop]; }; return ret; } static dateRenderer(prop) { const ret = (data) => { return data[prop] ? new Date(data[prop]).toLocaleDateString() : ''; }; return ret; } } class NovoActivityTableState { constructor() { this.id = Math.random(); this.sort = undefined; this.filter = undefined; this.page = 0; this.pageSize = undefined; this.globalSearch = undefined; this.selectedRows = new Map(); this.updates = new EventEmitter(); this.onReset = new EventEmitter(); } get userFiltered() { return !!(this.filter || this.sort || this.globalSearch || this.outsideFilter); } reset(fireUpdate = true, persistUserFilters) { if (!persistUserFilters) { this.sort = undefined; this.globalSearch = undefined; this.filter = undefined; } this.page = 0; this.selectedRows.clear(); this.onReset.emit(true); if (fireUpdate) { this.updates.emit({ sort: this.sort, filter: this.filter, globalSearch: this.globalSearch, }); } } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: NovoActivityTableState, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); } static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: NovoActivityTableState }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: NovoActivityTableState, decorators: [{ type: Injectable }] }); class NovoSortFilter { constructor(state) { this.state = state; } filter(id, value, transform) { let filter; if (!Helpers.isBlank(value)) { filter = { id, value, transform }; } else { filter = undefined; } this.state.filter = filter; this.state.reset(false, true); this.state.updates.next({ filter, sort: this.state.sort }); } sort(id, value, transform) { const sort = { id, value, transform }; this.state.sort = sort; this.state.reset(false, true); this.state.updates.next({ sort, filter: this.state.filter }); } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: NovoSortFilter, deps: [{ token: NovoActivityTableState }], target: i0.ɵɵFactoryTarget.Directive }); } static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "20.3.19", type: NovoSortFilter, isStandalone: false, selector: "[novoSortFilter]", ngImport: i0 }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: NovoSortFilter, decorators: [{ type: Directive, args: [{ selector: '[novoSortFilter]', standalone: false, }] }], ctorParameters: () => [{ type: NovoActivityTableState }] }); class NovoSelection { constructor(state) { this.state = state; this.novoSelectAllToggle = new EventEmitter(); this.allRows = new Map(); } register(id, row) { this.allRows.set(id, row); } deregister(id) { this.allRows.delete(id); this.state.selectedRows.delete(id); clearTimeout(this.throttleTimeout); this.throttleTimeout = setTimeout(() => { if (this.state.selectedRows.size === 0) { this.novoSelectAllToggle.emit(false); } }); } ngOnDestroy() { this.allRows.clear(); this.state.selectedRows.clear(); } toggle(id, selected, row) { if (selected) { this.state.selectedRows.set(id, row); } else { this.state.selectedRows.delete(id); } } selectAll(value) { if (value) { this.state.selectedRows = new Map(this.allRows); } else { this.state.selectedRows.clear(); } this.novoSelectAllToggle.emit(value); } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: NovoSelection, deps: [{ token: NovoActivityTableState }], target: i0.ɵɵFactoryTarget.Directive }); } static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "20.3.19", type: NovoSelection, isStandalone: false, selector: "[novoSelection]", outputs: { novoSelectAllToggle: "novoSelectAllToggle" }, ngImport: i0 }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: NovoSelection, decorators: [{ type: Directive, args: [{ selector: '[novoSelection]', standalone: false, }] }], ctorParameters: () => [{ type: NovoActivityTableState }], propDecorators: { novoSelectAllToggle: [{ type: Output }] } }); /** Workaround for https://github.com/angular/angular/issues/17849 */ const _NovoCellDef = CdkCellDef; const _NovoHeaderCellDef = CdkHeaderCellDef; const _NovoColumnDef = CdkColumnDef; const _NovoHeaderCell = CdkHeaderCell; const _NovoCell = CdkCell; class NovoSimpleCellDef extends _NovoCellDef { static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: NovoSimpleCellDef, deps: null, target: i0.ɵɵFactoryTarget.Directive }); } static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "20.3.19", type: NovoSimpleCellDef, isStandalone: false, selector: "[novoSimpleCellDef]", providers: [{ provide: CdkCellDef, useExisting: NovoSimpleCellDef }], usesInheritance: true, ngImport: i0 }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: NovoSimpleCellDef, decorators: [{ type: Directive, args: [{ selector: '[novoSimpleCellDef]', providers: [{ provide: CdkCellDef, useExisting: NovoSimpleCellDef }], standalone: false, }] }] }); class NovoSimpleHeaderCellDef extends _NovoHeaderCellDef { static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: NovoSimpleHeaderCellDef, deps: null, target: i0.ɵɵFactoryTarget.Directive }); } static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "20.3.19", type: NovoSimpleHeaderCellDef, isStandalone: false, selector: "[novoSimpleHeaderCellDef]", providers: [{ provide: CdkHeaderCellDef, useExisting: NovoSimpleHeaderCellDef }], usesInheritance: true, ngImport: i0 }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: NovoSimpleHeaderCellDef, decorators: [{ type: Directive, args: [{ selector: '[novoSimpleHeaderCellDef]', providers: [{ provide: CdkHeaderCellDef, useExisting: NovoSimpleHeaderCellDef }], standalone: false, }] }] }); class NovoSimpleColumnDef extends _NovoColumnDef { get name() { return this._name; } set name(name) { this._setNameInput(name); } /** * This has been extracted to a util because of TS 4 and VE. * View Engine doesn't support property rename inheritance. * TS 4.0 doesn't allow properties to override accessors or vice-versa. * @docs-private */ _setNameInput(value) { // If the directive is set without a name (updated programatically), then this setter will // trigger with an empty string and should not overwrite the programatically set value. if (value) { this._name = value; this.cssClassFriendlyName = value.replace(/[^a-z0-9_-]/gi, '-'); this._updateColumnCssClassName(); } } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: NovoSimpleColumnDef, deps: null, target: i0.ɵɵFactoryTarget.Directive }); } static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "20.3.19", type: NovoSimpleColumnDef, isStandalone: false, selector: "[novoSimpleColumnDef]", inputs: { name: ["novoSimpleColumnDef", "name"] }, providers: [{ provide: CdkColumnDef, useExisting: NovoSimpleColumnDef }], usesInheritance: true, ngImport: i0 }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: NovoSimpleColumnDef, decorators: [{ type: Directive, args: [{ selector: '[novoSimpleColumnDef]', providers: [{ provide: CdkColumnDef, useExisting: NovoSimpleColumnDef }], standalone: false, }] }], propDecorators: { name: [{ type: Input, args: ['novoSimpleColumnDef'] }] } }); class NovoSimpleHeaderCell extends _NovoHeaderCell { constructor(columnDef, elementRef, renderer) { super(columnDef, elementRef); this.elementRef = elementRef; this.renderer = renderer; this.role = 'columnheader'; renderer.setAttribute(elementRef.nativeElement, 'data-automation-id', `novo-column-header-${columnDef.cssClassFriendlyName}`); renderer.addClass(elementRef.nativeElement, `novo-column-${columnDef.cssClassFriendlyName}`); renderer.addClass(elementRef.nativeElement, 'novo-simple-header-cell'); } ngOnInit() { if (this.column.width) { this.renderer.setStyle(this.elementRef.nativeElement, 'min-width', `${this.column.width}px`); this.renderer.setStyle(this.elementRef.nativeElement, 'max-width', `${this.column.width}px`); this.renderer.setStyle(this.elementRef.nativeElement, 'width', `${this.column.width}px`); } } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: NovoSimpleHeaderCell, deps: [{ token: i1.CdkColumnDef }, { token: i0.ElementRef }, { token: i0.Renderer2 }], target: i0.ɵɵFactoryTarget.Directive }); } static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "20.3.19", type: NovoSimpleHeaderCell, isStandalone: false, selector: "novo-simple-header-cell", inputs: { column: "column" }, host: { properties: { "attr.role": "this.role" } }, usesInheritance: true, ngImport: i0 }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: NovoSimpleHeaderCell, decorators: [{ type: Directive, args: [{ selector: 'novo-simple-header-cell', standalone: false, }] }], ctorParameters: () => [{ type: i1.CdkColumnDef }, { type: i0.ElementRef }, { type: i0.Renderer2 }], propDecorators: { role: [{ type: HostBinding, args: ['attr.role'] }], column: [{ type: Input }] } }); class NovoSimpleEmptyHeaderCell extends _NovoHeaderCell { constructor(columnDef, elementRef, renderer) { super(columnDef, elementRef); this.role = 'columnheader'; renderer.setAttribute(elementRef.nativeElement, 'data-automation-id', `novo-column-header-${columnDef.cssClassFriendlyName}`); renderer.addClass(elementRef.nativeElement, `novo-column-${columnDef.cssClassFriendlyName}`); renderer.addClass(elementRef.nativeElement, 'novo-simple-empty-header-cell'); } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: NovoSimpleEmptyHeaderCell, deps: [{ token: i1.CdkColumnDef }, { token: i0.ElementRef }, { token: i0.Renderer2 }], target: i0.ɵɵFactoryTarget.Directive }); } static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "20.3.19", type: NovoSimpleEmptyHeaderCell, isStandalone: false, selector: "novo-simple-empty-header-cell", host: { properties: { "attr.role": "this.role" } }, usesInheritance: true, ngImport: i0 }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: NovoSimpleEmptyHeaderCell, decorators: [{ type: Directive, args: [{ selector: 'novo-simple-empty-header-cell', standalone: false, }] }], ctorParameters: () => [{ type: i1.CdkColumnDef }, { type: i0.ElementRef }, { type: i0.Renderer2 }], propDecorators: { role: [{ type: HostBinding, args: ['attr.role'] }] } }); class NovoSimpleCheckboxHeaderCell extends _NovoHeaderCell { constructor(columnDef, elementRef, renderer, ref, _selection) { super(columnDef, elementRef); this._selection = _selection; this.role = 'columnheader'; this.selectAll = false; renderer.setAttribute(elementRef.nativeElement, 'data-automation-id', `novo-checkbox-column-header-${columnDef.cssClassFriendlyName}`); renderer.addClass(elementRef.nativeElement, `novo-checkbox-column-${columnDef.cssClassFriendlyName}`); renderer.addClass(elementRef.nativeElement, 'novo-simple-checkbox-header-cell'); this.selectAllSubscription = _selection.novoSelectAllToggle.subscribe((value) => { this.selectAll = value; ref.markForCheck(); }); } ngOnDestroy() { this.selectAllSubscription.unsubscribe(); } toggle(value) { this._selection.selectAll(value); } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: NovoSimpleCheckboxHeaderCell, deps: [{ token: i1.CdkColumnDef }, { token: i0.ElementRef }, { token: i0.Renderer2 }, { token: i0.ChangeDetectorRef }, { token: NovoSelection, optional: true }], target: i0.ɵɵFactoryTarget.Component }); } static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.19", type: NovoSimpleCheckboxHeaderCell, isStandalone: false, selector: "novo-simple-checkbox-header-cell", host: { properties: { "attr.role": "this.role" } }, usesInheritance: true, ngImport: i0, template: '<novo-checkbox [(ngModel)]="selectAll" (ngModelChange)="toggle($event)"></novo-checkbox>', isInline: true, dependencies: [{ kind: "directive", type: i3.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i3.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: i4.NovoCheckboxElement, selector: "novo-checkbox", inputs: ["aria-label", "aria-labelledby", "aria-describedby", "id", "name", "label", "disabled", "layoutOptions", "color", "value", "tabIndex", "required", "checked", "indeterminate"], outputs: ["change", "indeterminateChange", "onSelect"] }] }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: NovoSimpleCheckboxHeaderCell, decorators: [{ type: Component, args: [{ selector: 'novo-simple-checkbox-header-cell', template: '<novo-checkbox [(ngModel)]="selectAll" (ngModelChange)="toggle($event)"></novo-checkbox>', standalone: false, }] }], ctorParameters: () => [{ type: i1.CdkColumnDef }, { type: i0.ElementRef }, { type: i0.Renderer2 }, { type: i0.ChangeDetectorRef }, { type: NovoSelection, decorators: [{ type: Optional }] }], propDecorators: { role: [{ type: HostBinding, args: ['attr.role'] }] } }); class NovoSimpleCell extends _NovoCell { constructor(columnDef, elementRef, renderer) { super(columnDef, elementRef); this.elementRef = elementRef; this.renderer = renderer; this.role = 'gridcell'; renderer.setAttribute(elementRef.nativeElement, 'data-automation-id', `novo-column-${columnDef.cssClassFriendlyName}`); renderer.addClass(elementRef.nativeElement, `novo-column-${columnDef.cssClassFriendlyName}`); renderer.addClass(elementRef.nativeElement, 'novo-simple-cell'); } ngOnInit() { if (this.column.customClass) { this.renderer.addClass(this.elementRef.nativeElement, this.column.customClass(this.row)); } if (this.column.width) { this.renderer.setStyle(this.elementRef.nativeElement, 'min-width', `${this.column.width}px`); this.renderer.setStyle(this.elementRef.nativeElement, 'max-width', `${this.column.width}px`); this.renderer.setStyle(this.elementRef.nativeElement, 'width', `${this.column.width}px`); } } onClick(event) { Helpers.swallowEvent(event); if (this.column.onClick) { this.column.onClick(this.row); } return; } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: NovoSimpleCell, deps: [{ token: i1.CdkColumnDef }, { token: i0.ElementRef }, { token: i0.Renderer2 }], target: i0.ɵɵFactoryTarget.Component }); } static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.19", type: NovoSimpleCell, isStandalone: false, selector: "novo-simple-cell", inputs: { row: "row", column: "column" }, host: { properties: { "attr.role": "this.role" } }, usesInheritance: true, ngImport: i0, template: ' <span [class.clickable]="!!column.onClick" (click)="onClick($event)" #span>{{ column.renderer(row) }}</span> ', isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: NovoSimpleCell, decorators: [{ type: Component, args: [{ selector: 'novo-simple-cell', template: ' <span [class.clickable]="!!column.onClick" (click)="onClick($event)" #span>{{ column.renderer(row) }}</span> ', changeDetection: ChangeDetectionStrategy.OnPush, standalone: false, }] }], ctorParameters: () => [{ type: i1.CdkColumnDef }, { type: i0.ElementRef }, { type: i0.Renderer2 }], propDecorators: { role: [{ type: HostBinding, args: ['attr.role'] }], row: [{ type: Input }], column: [{ type: Input }] } }); class NovoSimpleCheckboxCell extends _NovoCell { constructor(columnDef, elementRef, renderer, _selection) { super(columnDef, elementRef); this.columnDef = columnDef; this._selection = _selection; this.role = 'gridcell'; this.selected = false; renderer.setAttribute(elementRef.nativeElement, 'data-automation-id', `novo-checkbox-column-${columnDef.cssClassFriendlyName}`); renderer.addClass(elementRef.nativeElement, `novo-checkbox-column-${columnDef.cssClassFriendlyName}`); renderer.addClass(elementRef.nativeElement, 'novo-simple-checkbox-cell'); this.selectAllSubscription = _selection.novoSelectAllToggle.subscribe((value) => { this.selected = value; }); } ngOnInit() { this._selection.register(this.row.id || this.index, this.row); this.selected = this._selection.state.selectedRows.has(this.row.id || this.index); } ngOnDestroy() { this._selection.deregister(this.row.id || this.index); this.selectAllSubscription.unsubscribe(); } toggle(value) { this._selection.toggle(this.row.id || this.index, value, this.row); } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: NovoSimpleCheckboxCell, deps: [{ token: i1.CdkColumnDef }, { token: i0.ElementRef }, { token: i0.Renderer2 }, { token: NovoSelection, optional: true }], target: i0.ɵɵFactoryTarget.Component }); } static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.19", type: NovoSimpleCheckboxCell, isStandalone: false, selector: "novo-simple-checkbox-cell", inputs: { row: "row", index: "index" }, host: { properties: { "attr.role": "this.role" } }, usesInheritance: true, ngImport: i0, template: ' <novo-checkbox [ngModel]="selected" (ngModelChange)="toggle($event)"></novo-checkbox> ', isInline: true, dependencies: [{ kind: "directive", type: i3.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i3.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: i4.NovoCheckboxElement, selector: "novo-checkbox", inputs: ["aria-label", "aria-labelledby", "aria-describedby", "id", "name", "label", "disabled", "layoutOptions", "color", "value", "tabIndex", "required", "checked", "indeterminate"], outputs: ["change", "indeterminateChange", "onSelect"] }] }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: NovoSimpleCheckboxCell, decorators: [{ type: Component, args: [{ selector: 'novo-simple-checkbox-cell', template: ' <novo-checkbox [ngModel]="selected" (ngModelChange)="toggle($event)"></novo-checkbox> ', standalone: false, }] }], ctorParameters: () => [{ type: i1.CdkColumnDef }, { type: i0.ElementRef }, { type: i0.Renderer2 }, { type: NovoSelection, decorators: [{ type: Optional }] }], propDecorators: { role: [{ type: HostBinding, args: ['attr.role'] }], row: [{ type: Input }], index: [{ type: Input }] } }); class NovoSimpleActionCell extends _NovoCell { constructor(columnDef, elementRef, renderer, labels) { super(columnDef, elementRef); this.elementRef = elementRef; this.renderer = renderer; this.labels = labels; this.role = 'gridcell'; renderer.setAttribute(elementRef.nativeElement, 'data-automation-id', `novo-action-column-${columnDef.cssClassFriendlyName}`); } ngOnInit() { if (this.column.options) { this.renderer.addClass(this.elementRef.nativeElement, 'novo-simple-dropdown-cell'); } else { this.renderer.addClass(this.elementRef.nativeElement, 'novo-simple-button-cell'); } } isDisabled(check, row) { if (check.disabled === true) { return true; } if (check.disabledCheck) { return check.disabledCheck(row); } return false; } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: NovoSimpleActionCell, deps: [{ token: i1.CdkColumnDef }, { token: i0.ElementRef }, { token: i0.Renderer2 }, { token: i1$1.NovoLabelService }], target: i0.ɵɵFactoryTarget.Component }); } static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.19", type: NovoSimpleActionCell, isStandalone: false, selector: "novo-simple-action-cell", inputs: { row: "row", column: "column" }, host: { properties: { "attr.role": "this.role" } }, usesInheritance: true, ngImport: i0, template: ` <ng-container *ngIf="!column.options"> <novo-button theme="icon" [icon]="column.icon" (click)="column.onClick(row)" [disabled]="isDisabled(column, row)"></novo-button> </ng-container> <ng-container *ngIf="column.options"> <novo-dropdown parentScrollSelector=".novo-simple-table" containerClass="novo-table-dropdown-cell"> <novo-button type="button" theme="dialogue" icon="collapse" inverse>{{ column.label || labels.actions }}</novo-button> <list> <item *ngFor="let option of column.options" (action)="option.onClick(row)" [disabled]="isDisabled(option, row)"> <span [attr.data-automation-id]="option.label">{{ option.label }}</span> </item> </list> </novo-dropdown> </ng-container> `, isInline: true, dependencies: [{ kind: "directive", type: i6.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i6.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i8.ThemeColorDirective, selector: "[theme]", inputs: ["theme"] }, { kind: "component", type: i8$1.NovoButtonElement, selector: "novo-button,button[theme]", inputs: ["color", "side", "size", "theme", "loading", "icon", "secondIcon", "disabled"] }, { kind: "component", type: i9.NovoDropdownElement, selector: "novo-dropdown", inputs: ["parentScrollSelector", "parentScrollAction", "containerClass", "side", "scrollStrategy", "keepOpen", "height", "width", "appendToBody", "multiple", "scrollToActiveItemOnOpen"], outputs: ["toggled"] }, { kind: "component", type: i9.NovoItemElement, selector: "item", inputs: ["disabled", "keepOpen"], outputs: ["action"] }, { kind: "component", type: i9.NovoDropdownListElement, selector: "list" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: NovoSimpleActionCell, decorators: [{ type: Component, args: [{ selector: 'novo-simple-action-cell', template: ` <ng-container *ngIf="!column.options"> <novo-button theme="icon" [icon]="column.icon" (click)="column.onClick(row)" [disabled]="isDisabled(column, row)"></novo-button> </ng-container> <ng-container *ngIf="column.options"> <novo-dropdown parentScrollSelector=".novo-simple-table" containerClass="novo-table-dropdown-cell"> <novo-button type="button" theme="dialogue" icon="collapse" inverse>{{ column.label || labels.actions }}</novo-button> <list> <item *ngFor="let option of column.options" (action)="option.onClick(row)" [disabled]="isDisabled(option, row)"> <span [attr.data-automation-id]="option.label">{{ option.label }}</span> </item> </list> </novo-dropdown> </ng-container> `, changeDetection: ChangeDetectionStrategy.OnPush, standalone: false, }] }], ctorParameters: () => [{ type: i1.CdkColumnDef }, { type: i0.ElementRef }, { type: i0.Renderer2 }, { type: i1$1.NovoLabelService }], propDecorators: { role: [{ type: HostBinding, args: ['attr.role'] }], row: [{ type: Input }], column: [{ type: Input }] } }); class NovoSimpleFilterFocus { constructor(element) { this.element = element; } ngAfterViewInit() { this.element.nativeElement.focus(); } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: NovoSimpleFilterFocus, deps: [{ token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Directive }); } static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "20.3.19", type: NovoSimpleFilterFocus, isStandalone: false, selector: "[novoSimpleFilterFocus]", ngImport: i0 }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: NovoSimpleFilterFocus, decorators: [{ type: Directive, args: [{ selector: '[novoSimpleFilterFocus]', standalone: false, }] }], ctorParameters: () => [{ type: i0.ElementRef }] }); class NovoSimpleCellHeader { get config() { return this._config; } set config(v) { if (!v) { this._config = { sortable: false, filterable: false, filterConfig: { type: 'text', }, }; } else { this._config = { sortable: coerceBooleanProperty(v.sortable), filterable: coerceBooleanProperty(v.filterable), transforms: v.transforms || {}, filterConfig: v.filterConfig || { type: 'text', }, }; if (this._config.filterConfig.type === 'date' && !this._config.filterConfig.options) { this._config.filterConfig.options = this.getDefaultDateFilterOptions(); } } } constructor(changeDetectorRef, labels, state, _sort, _cdkColumnDef) { this.changeDetectorRef = changeDetectorRef; this.labels = labels; this.state = state; this._sort = _sort; this._cdkColumnDef = _cdkColumnDef; this.icon = 'sortable'; this.filterActive = false; this.sortActive = false; this.showCustomRange = false; this._rerenderSubscription = state.updates.subscribe((change) => { if (change.sort && change.sort.id === this.id) { this.icon = `sort-${change.sort.value}`; this.sortActive = true; } else { this.icon = 'sortable'; this.sortActive = false; } if (change.filter && change.filter.id === this.id) { this.filterActive = true; this.filter = change.filter.value; } else { this.filterActive = false; this.filter = undefined; } changeDetectorRef.markForCheck(); }); } ngOnInit() { if (this._cdkColumnDef) { this.id = this._cdkColumnDef.name; } if (this.defaultSort && this.id === this.defaultSort.id) { this.icon = `sort-${this.defaultSort.value}`; this.sortActive = true; this.changeDetectorRef.markForCheck(); } } ngOnDestroy() { this._rerenderSubscription.unsubscribe(); } sort() { if (this.changeTimeout) { clearTimeout(this.changeTimeout); } this.changeTimeout = setTimeout(() => { this.direction = this.getNextSortDirection(this.direction); this._sort.sort(this.id, this.direction, this._config.transforms.sort); this.changeDetectorRef.markForCheck(); }, 300); } toggleCustomRange(event, value) { Helpers.swallowEvent(event); this.showCustomRange = value; this.changeDetectorRef.markForCheck(); this.dropdown.openPanel(); // Ensures that the panel correctly updates to the dynamic size of the dropdown } filterData(filter) { let actualFilter = filter; if (this.config.filterConfig.type === 'date' && filter) { this.activeDateFilter = filter.label || this.labels.customDateRange; if (filter.startDate && filter.endDate) { actualFilter = { min: DateUtil.startOfDay(filter.startDate.date), max: DateUtil.startOfDay(DateUtil.addDays(DateUtil.startOfDay(filter.endDate.date), 1)), }; } else { actualFilter = { min: filter.min ? DateUtil.addDays(startOfToday(), filter.min) : startOfToday(), max: filter.max ? DateUtil.addDays(startOfTomorrow(), filter.max) : startOfTomorrow(), }; } } if (actualFilter && actualFilter.hasOwnProperty('value')) { actualFilter = filter.value; } if (this.changeTimeout) { clearTimeout(this.changeTimeout); } this.changeTimeout = setTimeout(() => { if (actualFilter === '') { actualFilter = undefined; } this._sort.filter(this.id, actualFilter, this.config.transforms.filter); this.changeDetectorRef.markForCheck(); }, 300); } clearFilter() { this.filter = undefined; this.activeDateFilter = undefined; this.filterData(); } getNextSortDirection(direction) { if (!direction) { return 'asc'; } if (direction === 'asc') { return 'desc'; } return 'asc'; } getDefaultDateFilterOptions() { const opts = [ { label: this.labels.past1Day, min: -1, max: 0 }, { label: this.labels.past7Days, min: -7, max: 0 }, { label: this.labels.past30Days, min: -30, max: 0 }, { label: this.labels.past90Days, min: -90, max: 0 }, { label: this.labels.past1Year, min: -366, max: 0 }, { label: this.labels.next1Day, min: 0, max: 1 }, { label: this.labels.next7Days, min: 0, max: 7 }, { label: this.labels.next30Days, min: 0, max: 30 }, { label: this.labels.next90Days, min: 0, max: 90 }, { label: this.labels.next1Year, min: 0, max: 366 }, ]; return opts; } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: NovoSimpleCellHeader, deps: [{ token: i0.ChangeDetectorRef }, { token: i1$1.NovoLabelService }, { token: NovoActivityTableState }, { token: NovoSortFilter, optional: true }, { token: i1.CdkColumnDef, optional: true }], target: i0.ɵɵFactoryTarget.Component }); } static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.19", type: NovoSimpleCellHeader, isStandalone: false, selector: "[novo-simple-cell-config]", inputs: { defaultSort: "defaultSort", config: ["novo-simple-cell-config", "config"] }, viewQueries: [{ propertyName: "dropdown", first: true, predicate: NovoDropdownElement, descendants: true }], ngImport: i0, template: ` <label (click)="sort()" data-automation-id="novo-activity-table-label" [class.sort-disabled]="!config.sortable"> <ng-content></ng-content> </label> <div> <novo-button *ngIf="config.sortable" theme="icon" [icon]="icon" (click)="sort()" [class.active]="sortActive" data-automation-id="novo-activity-table-sort" ></novo-button> <novo-dropdown *ngIf="config.filterable" side="right" parentScrollSelector=".novo-simple-table" containerClass="simple-table-dropdown" data-automation-id="novo-activity-table-filter" > <novo-button type="button" theme="icon" icon="filter" [class.active]="filterActive"></novo-button> <div class="header"> <span>{{ labels.filters }}</span> <novo-button theme="dialogue" color="negative" icon="times" (click)="clearFilter()" *ngIf="filter" data-automation-id="novo-activity-table-filter-clear" > {{ labels.clear }} </novo-button> </div> <ng-container [ngSwitch]="config.filterConfig.type"> <novo-optgroup *ngSwitchCase="'date'"> <ng-container *ngIf="!showCustomRange"> <novo-option [class.active]="activeDateFilter === option.label" *ngFor="let option of config.filterConfig.options" (click)="filterData(option)" [attr.data-automation-id]="'novo-activity-table-filter-' + option.label" > {{ option.label }} <i class="bhi-check" *ngIf="activeDateFilter === option.label"></i> </novo-option> </ng-container> <novo-option [class.active]="labels.customDateRange === activeDateFilter" (click)="toggleCustomRange($event, true)" *ngIf="config.filterConfig.allowCustomRange && !showCustomRange" [keepOpen]="true" > {{ labels.customDateRange }} <i class="bhi-check" *ngIf="labels.customDateRange === activeDateFilter"></i> </novo-option> <div class="calendar-container" *ngIf="showCustomRange"> <div (click)="toggleCustomRange($event, false)"><i class="bhi-previous"></i>{{ labels.backToPresetFilters }}</div> <novo-date-picker (onSelect)="filterData($event)" [(ngModel)]="filter" range="true"></novo-date-picker> </div> </novo-optgroup> <novo-optgroup *ngSwitchCase="'select'"> <novo-option [class.active]="filter === option" *ngFor="let option of config.filterConfig.options" (click)="filterData(option)" [attr.data-automation-id]="'novo-activity-table-filter-' + (option?.label || option)" > <span>{{ option?.label || option }}</span> <i class="bhi-check" *ngIf="option.hasOwnProperty('value') ? filter === option.value : filter === option"></i> </novo-option> </novo-optgroup> <novo-optgroup *ngSwitchDefault> <novo-option class="filter-search" keepOpen> <input type="text" [(ngModel)]="filter" (ngModelChange)="filterData($event)" novoSimpleFilterFocus data-automation-id="novo-activity-table-filter-input" /> </novo-option> </novo-optgroup> </ng-container> </novo-dropdown> </div> `, isInline: true, dependencies: [{ kind: "component", type: i5.NovoDatePickerElement, selector: "novo-date-picker", inputs: ["minYear", "maxYear", "start", "end", "inline", "weekStart", "preselected", "hideOverflowDays", "hideFooter", "hideToday", "disabledDateMessage", "dateForInitialView", "numberOfMonths", "mode", "range", "weekRangeSelect"], outputs: ["onSelect"] }, { kind: "directive", type: i6.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i6.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i6.NgSwitch, selector: "[ngSwitch]", inputs: ["ngSwitch"] }, { kind: "directive", type: i6.NgSwitchCase, selector: "[ngSwitchCase]", inputs: ["ngSwitchCase"] }, { kind: "directive", type: i6.NgSwitchDefault, selector: "[ngSwitchDefault]" }, { kind: "directive", type: i3.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i3.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i3.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: i8.ThemeColorDirective, selector: "[theme]", inputs: ["theme"] }, { kind: "component", type: i8$1.NovoButtonElement, selector: "novo-button,button[theme]", inputs: ["color", "side", "size", "theme", "loading", "icon", "secondIcon", "disabled"] }, { kind: "component", type: i9.NovoDropdownElement, selector: "novo-dropdown", inputs: ["parentScrollSelector", "parentScrollAction", "containerClass", "side", "scrollStrategy", "keepOpen", "height", "width", "appendToBody", "multiple", "scrollToActiveItemOnOpen"], outputs: ["toggled"] }, { kind: "component", type: i8.NovoOption, selector: "novo-option", inputs: ["selected", "keepOpen", "novoInert", "value", "disabled"], exportAs: ["novoOption"] }, { kind: "component", type: i8.NovoOptgroup, selector: "novo-optgroup", inputs: ["disabled", "label"], exportAs: ["novoOptgroup"] }, { kind: "directive", type: NovoSimpleFilterFocus, selector: "[novoSimpleFilterFocus]" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: NovoSimpleCellHeader, decorators: [{ type: Component, args: [{ selector: '[novo-simple-cell-config]', template: ` <label (click)="sort()" data-automation-id="novo-activity-table-label" [class.sort-disabled]="!config.sortable"> <ng-content></ng-content> </label> <div> <novo-button *ngIf="config.sortable" theme="icon" [icon]="icon" (click)="sort()" [class.active]="sortActive" data-automation-id="novo-activity-table-sort" ></novo-button> <novo-dropdown *ngIf="config.filterable" side="right" parentScrollSelector=".novo-simple-table" containerClass="simple-table-dropdown" data-automation-id="novo-activity-table-filter" > <novo-button type="button" theme="icon" icon="filter" [class.active]="filterActive"></novo-button> <div class="header"> <span>{{ labels.filters }}</span> <novo-button theme="dialogue" color="negative" icon="times" (click)="clearFilter()" *ngIf="filter" data-automation-id="novo-activity-table-filter-clear" > {{ labels.clear }} </novo-button> </div> <ng-container [ngSwitch]="config.filterConfig.type"> <novo-optgroup *ngSwitchCase="'date'"> <ng-container *ngIf="!showCustomRange"> <novo-option [class.active]="activeDateFilter === option.label" *ngFor="let option of config.filterConfig.options" (click)="filterData(option)" [attr.data-automation-id]="'novo-activity-table-filter-' + option.label" > {{ option.label }} <i class="bhi-check" *ngIf="activeDateFilter === option.label"></i> </novo-option> </ng-container> <novo-option [class.active]="labels.customDateRange === activeDateFilter" (click)="toggleCustomRange($event, true)" *ngIf="config.filterConfig.allowCustomRange && !showCustomRange" [keepOpen]="true" > {{ labels.customDateRange }} <i class="bhi-check" *ngIf="labels.customDateRange === activeDateFilter"></i> </novo-option> <div class="calendar-container" *ngIf="showCustomRange"> <div (click)="toggleCustomRange($event, false)"><i class="bhi-previous"></i>{{ labels.backToPresetFilters }}</div> <novo-date-picker (onSelect)="filterData($event)" [(ngModel)]="filter" range="true"></novo-date-picker> </div> </novo-optgroup> <novo-optgroup *ngSwitchCase="'select'"> <novo-option [class.active]="filter === option" *ngFor="let option of config.filterConfig.options" (click)="filterData(option)" [attr.data-automation-id]="'novo-activity-table-filter-' + (option?.label || option)" > <span>{{ option?.label || option }}</span> <i class="bhi-check" *ngIf="option.hasOwnProperty('value') ? filter === option.value : filter === option"></i> </novo-option> </novo-optgroup> <novo-optgroup *ngSwitchDefault> <novo-option class="filter-search" keepOpen> <input type="text" [(ngModel)]="filter" (ngModelChange)="filterData($event)" novoSimpleFilterFocus data-automation-id="novo-activity-table-filter-input" /> </novo-option> </novo-optgroup> </ng-container> </novo-dropdown> </div> `, encapsulation: ViewEncapsulation.None, changeDetection: ChangeDetectionStrategy.OnPush, standalone: false, }] }], ctorParameters: () => [{ type: i0.ChangeDetectorRef }, { type: i1$1.NovoLabelService }, { type: NovoActivityTableState }, { type: NovoSortFilter, decorators: [{ type: Optional }] }, { type: i1.CdkColumnDef, decorators: [{ type: Optional }] }], propDecorators: { dropdown: [{ type: ViewChild, args: [NovoDropdownElement] }], defaultSort: [{ type: Input }], config: [{ type: Input, args: ['novo-simple-cell-config'] }] } }); const DEFAULT_PAGE_SIZE = 50; class NovoSimpleTablePagination { get page() { return this._page; } set page(page) { this._page = page; this.changeDetectorRef.markForCheck(); this.longRangeLabel = this.labels.getRangeText(this.page, this.pageSize, this.length, false); this.shortRangeLabel = this.labels.getRangeText(this.page, this.pageSize, this.length, true); this.state.page = this._page; } get length() { return this._length; } set length(length) { this._length = length; this.changeDetectorRef.markForCheck(); this.longRangeLabel = this.labels.getRangeText(this.page, this.pageSize, this.length, false); this.shortRangeLabel = this.labels.getRangeText(this.page, this.pageSize, this.length, true); } get pageSize() { return this._pageSize; } set pageSize(pageSize) { this._pageSize = pageSize; this.updateDisplayedPageSizeOptions(); this.state.pageSize = this._pageSize; } get pageSizeOptions() { return this._pageSizeOptions; } set pageSizeOptions(pageSizeOptions) { this._pageSizeOptions = pageSizeOptions; this.updateDisplayedPageSizeOptions(); } constructor(changeDetectorRef, labels, state) { this.changeDetectorRef = changeDetectorRef; this.labels = labels; this.state = state; this._page = 0; this._length = 0; this._pageSizeOptions = []; this.pageChange = new EventEmitter(); if (state && state.onReset) { this.resetSubscription = this.state.onReset.subscribe((clear) => { if (clear) { this.page = 0; this.changeDetectorRef.markForCheck(); } }); } } ngOnInit() { this._initialized = true; this.updateDisplayedPageSizeOptions(); } ngOnDestroy() { this.resetSubscription.unsubscribe(); } nextPage() { if (!this.hasNextPage()) { return; } this.page++; this.emitPageEvent(); } previousPage() { if (!this.hasPreviousPage()) { return; } this.page--; this.emitPageEvent();