UNPKG

@cauca-911/datagrid

Version:

Run `npm install @cauca-911/datagrid --save` to add this library to your project

545 lines (534 loc) 195 kB
import * as i0 from '@angular/core'; import { input, ViewChild, HostBinding, Optional, ViewEncapsulation, ChangeDetectionStrategy, Component, signal, output, Injectable, InjectionToken, linkedSignal, ContentChild, ContentChildren, Inject, QueryList, inject, effect, TemplateRef, EventEmitter, DestroyRef, makeEnvironmentProviders, provideAppInitializer, forwardRef, computed, model } from '@angular/core'; import * as i1 from '@angular/material/table'; import { MatColumnDef, MatCellDef, MatHeaderCellDef, MatFooterCellDef, MatTable, MatHeaderRowDef, MatFooterRowDef, MatNoDataRow, MatRowDef, MatTableDataSource, MatHeaderCell, MatFooterCell, MatRow, MatHeaderRow, MatFooterRow, MatCell } from '@angular/material/table'; import { CDK_DRAG_CONFIG, moveItemInArray, CdkDropList, CdkDrag, CdkDragHandle } from '@angular/cdk/drag-drop'; import * as i1$2 from '@cauca-911/core'; import { toLowerCaseAndWithoutDiacritics, CaucaCoreService } from '@cauca-911/core'; import { MatPaginatorIntl, MatPaginator } from '@angular/material/paginator'; import * as i3 from '@angular/forms'; import { FormControl, ReactiveFormsModule, FormsModule } from '@angular/forms'; import * as i1$1 from '@angular/material/form-field'; import { MatFormFieldModule } from '@angular/material/form-field'; import { MatIcon } from '@angular/material/icon'; import * as i2 from '@angular/material/input'; import { MatInputModule } from '@angular/material/input'; import { IconButtonComponent, RaisedButtonComponent, BasicButtonComponent, StrokedButtonComponent, MenuItemComponent, StatusMessageComponent, IconComponent, Iso8601TimeSpanPipe } from '@cauca-911/material'; import * as i1$3 from '@ngx-translate/core'; import { TranslatePipe } from '@ngx-translate/core'; import { Subject, debounceTime, takeUntil, BehaviorSubject, of, distinctUntilChanged, filter } from 'rxjs'; import { MatSort, MatSortHeader } from '@angular/material/sort'; import { CdkConnectedOverlay, CdkOverlayOrigin } from '@angular/cdk/overlay'; import * as i1$4 from '@angular/material/card'; import { MatCardModule } from '@angular/material/card'; import * as i2$1 from '@angular/material/checkbox'; import { MatCheckboxModule } from '@angular/material/checkbox'; import * as i3$1 from '@angular/material/menu'; import { MatMenuModule } from '@angular/material/menu'; import { NgTemplateOutlet, NgStyle, NgClass, DatePipe } from '@angular/common'; import * as i1$5 from '@angular/material/progress-spinner'; import { MatProgressSpinnerModule } from '@angular/material/progress-spinner'; import { outputToObservable, takeUntilDestroyed } from '@angular/core/rxjs-interop'; import { Router, ActivatedRoute, NavigationEnd, RouterLink } from '@angular/router'; import { ODataDataSource } from 'odata-data-source'; import * as i1$6 from '@angular/common/http'; import { MatTooltip } from '@angular/material/tooltip'; import dayjs from 'dayjs'; class DataGridRowDropEvent { constructor(data) { Object.assign(this, data); } } class BaseGridColumnComponent { constructor(table) { this.table = table; this.prop = input('', /* @ts-ignore */ ...(ngDevMode ? [{ debugName: "prop" }] : /* istanbul ignore next */ [])); this.showLabel = input(true, /* @ts-ignore */ ...(ngDevMode ? [{ debugName: "showLabel" }] : /* istanbul ignore next */ [])); this.label = input(undefined, /* @ts-ignore */ ...(ngDevMode ? [{ debugName: "label" }] : /* istanbul ignore next */ [])); this.isInColumnChooser = input(true, /* @ts-ignore */ ...(ngDevMode ? [{ debugName: "isInColumnChooser" }] : /* istanbul ignore next */ [])); this.width = input('', /* @ts-ignore */ ...(ngDevMode ? [{ debugName: "width" }] : /* istanbul ignore next */ [])); this.showToolTip = input(false, /* @ts-ignore */ ...(ngDevMode ? [{ debugName: "showToolTip" }] : /* istanbul ignore next */ [])); this.selected = true; } ngOnInit() { if (this.columnDef) { if (!this.columnDef.name) { this.columnDef.name = this.prop(); } this.columnDef.cell = this.cellDef; this.columnDef.headerCell = this.headerCellDef; this.columnDef.footerCell = this.footerCellDef; } } ngOnDestroy() { if (this.table) { this.table.removeColumnDef(this.columnDef); } } capitalize(value) { return value.charAt(0).toUpperCase() + value.slice(1); } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.0", ngImport: i0, type: BaseGridColumnComponent, deps: [{ token: i1.MatTable, optional: true }], target: i0.ɵɵFactoryTarget.Component }); } static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "22.1.0", type: BaseGridColumnComponent, isStandalone: true, selector: "ng-component", inputs: { prop: { classPropertyName: "prop", publicName: "prop", isSignal: true, isRequired: false, transformFunction: null }, showLabel: { classPropertyName: "showLabel", publicName: "showLabel", isSignal: true, isRequired: false, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, isInColumnChooser: { classPropertyName: "isInColumnChooser", publicName: "isInColumnChooser", isSignal: true, isRequired: false, transformFunction: null }, width: { classPropertyName: "width", publicName: "width", isSignal: true, isRequired: false, transformFunction: null }, showToolTip: { classPropertyName: "showToolTip", publicName: "showToolTip", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "attr.ariaHidden": "this.ariaHidden", "class": "this.classes" } }, viewQueries: [{ propertyName: "columnDef", first: true, predicate: MatColumnDef, descendants: true, static: true }, { propertyName: "cellDef", first: true, predicate: MatCellDef, descendants: true, static: true }, { propertyName: "headerCellDef", first: true, predicate: MatHeaderCellDef, descendants: true, static: true }, { propertyName: "footerCellDef", first: true, predicate: MatFooterCellDef, descendants: true, static: true }], ngImport: i0, template: '', isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.0", ngImport: i0, type: BaseGridColumnComponent, decorators: [{ type: Component, args: [{ template: '', changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None }] }], ctorParameters: () => [{ type: i1.MatTable, decorators: [{ type: Optional }] }], propDecorators: { prop: [{ type: i0.Input, args: [{ isSignal: true, alias: "prop", required: false }] }], showLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "showLabel", required: false }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], isInColumnChooser: [{ type: i0.Input, args: [{ isSignal: true, alias: "isInColumnChooser", required: false }] }], width: [{ type: i0.Input, args: [{ isSignal: true, alias: "width", required: false }] }], showToolTip: [{ type: i0.Input, args: [{ isSignal: true, alias: "showToolTip", required: false }] }], ariaHidden: [{ type: HostBinding, args: ['attr.ariaHidden'] }], classes: [{ type: HostBinding, args: ['class'] }], columnDef: [{ type: ViewChild, args: [MatColumnDef, { static: true }] }], cellDef: [{ type: ViewChild, args: [MatCellDef, { static: true }] }], headerCellDef: [{ type: ViewChild, args: [MatHeaderCellDef, { static: true }] }], footerCellDef: [{ type: ViewChild, args: [MatFooterCellDef, { static: true }] }] } }); class DataGridHeaderComponent { constructor() { this.filterControl = new FormControl(''); /** Written from the debounced valueChanges subscription and by OdataGridComponent when it * restores persisted state, so it is a signal: neither is a change-detection trigger * under zoneless (ADR-0004). */ this.showClearButton = signal(false, /* @ts-ignore */ ...(ngDevMode ? [{ debugName: "showClearButton" }] : /* istanbul ignore next */ [])); this.showAddButton = input(false, /* @ts-ignore */ ...(ngDevMode ? [{ debugName: "showAddButton" }] : /* istanbul ignore next */ [])); this.showRefreshButton = input(false, /* @ts-ignore */ ...(ngDevMode ? [{ debugName: "showRefreshButton" }] : /* istanbul ignore next */ [])); this.addButtonLabel = input('', /* @ts-ignore */ ...(ngDevMode ? [{ debugName: "addButtonLabel" }] : /* istanbul ignore next */ [])); this.disableAddButton = input(false, /* @ts-ignore */ ...(ngDevMode ? [{ debugName: "disableAddButton" }] : /* istanbul ignore next */ [])); this.filterChange = output(); this.addButtonClick = output(); this.refreshRequest = output(); this._onDestroy = new Subject(); } ngOnInit() { this.filterControl.valueChanges .pipe(debounceTime(500), takeUntil(this._onDestroy)) .subscribe((filter) => { this.filterChange.emit(filter); this.showClearButton.set(!!filter); }); } ngOnDestroy() { this._onDestroy.next(); this._onDestroy.complete(); } onRefresh() { this.refreshRequest.emit(); } clearSearchValue() { this.filterControl.setValue(''); } onAddButtonClick() { this.addButtonClick.emit(); } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.0", ngImport: i0, type: DataGridHeaderComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); } static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.0", type: DataGridHeaderComponent, isStandalone: true, selector: "cauca-data-grid-header", inputs: { showAddButton: { classPropertyName: "showAddButton", publicName: "showAddButton", isSignal: true, isRequired: false, transformFunction: null }, showRefreshButton: { classPropertyName: "showRefreshButton", publicName: "showRefreshButton", isSignal: true, isRequired: false, transformFunction: null }, addButtonLabel: { classPropertyName: "addButtonLabel", publicName: "addButtonLabel", isSignal: true, isRequired: false, transformFunction: null }, disableAddButton: { classPropertyName: "disableAddButton", publicName: "disableAddButton", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { filterChange: "filterChange", addButtonClick: "addButtonClick", refreshRequest: "refreshRequest" }, ngImport: i0, template: "<div class=\"grid-header\">\n\n <mat-form-field appearance=\"outline\" class=\"full-width-field grid-search-box\" subscriptSizing=\"dynamic\">\n @if (showClearButton()) { <cauca-icon-button matPrefix (buttonClick)=\"clearSearchValue()\" icon=\"close\" /> }\n <mat-label>{{ 'dataGrid.keywordsLabel' | translate}}</mat-label>\n <input matInput [formControl]=\"filterControl\">\n <mat-icon matSuffix>search</mat-icon>\n </mat-form-field>\n\n <ng-content select=\"[filterRow]\" ngProjectAs=\"[filterRow]\" />\n\n @if (showRefreshButton()) { <cauca-icon-button (buttonClick)=\"onRefresh()\" icon=\"refresh\" class=\"grid-refresh-button\" /> }\n\n @if (showAddButton()) { <cauca-raised-button icon=\"add\" color=\"primary\" [label]=\"addButtonLabel()\" [translateLabel]=\"false\" class=\"grid-new-button\" [isDisabled]=\"disableAddButton()\" (buttonClick)=\"onAddButtonClick()\" /> }\n</div>", styles: [".grid-header{display:flex;justify-content:space-between;gap:16px;align-items:center;flex-wrap:nowrap;align-content:normal;padding:0 16px}.grid-search-box{display:block;flex-grow:1;flex-basis:0;min-width:0;align-self:auto}.grid-refresh-button,.grid-new-button{flex-shrink:0}@media(max-width:500px){.grid-header{gap:8px}}.grid-new-button{display:block;flex-basis:auto;align-self:auto}.grid-new-button>mat-icon{color:inherit}\n"], dependencies: [{ kind: "ngmodule", type: MatFormFieldModule }, { kind: "component", type: i1$1.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i1$1.MatLabel, selector: "mat-label" }, { kind: "directive", type: i1$1.MatPrefix, selector: "[matPrefix], [matIconPrefix], [matTextPrefix]", inputs: ["matTextPrefix"] }, { kind: "directive", type: i1$1.MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "component", type: IconButtonComponent, selector: "cauca-icon-button" }, { kind: "component", type: RaisedButtonComponent, selector: "cauca-raised-button" }, { 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: ReactiveFormsModule }, { kind: "directive", type: i3.DefaultValueAccessor, selector: "input:not([type=checkbox]):not([ngNoCva])[formControlName],textarea:not([ngNoCva])[formControlName],input:not([type=checkbox]):not([ngNoCva])[formControl],textarea:not([ngNoCva])[formControl],input:not([type=checkbox]):not([ngNoCva])[ngModel],textarea:not([ngNoCva])[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i3.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i3.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "component", type: MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.0", ngImport: i0, type: DataGridHeaderComponent, decorators: [{ type: Component, args: [{ selector: 'cauca-data-grid-header', changeDetection: ChangeDetectionStrategy.OnPush, imports: [MatFormFieldModule, IconButtonComponent, RaisedButtonComponent, MatInputModule, ReactiveFormsModule, TranslatePipe, MatIcon], template: "<div class=\"grid-header\">\n\n <mat-form-field appearance=\"outline\" class=\"full-width-field grid-search-box\" subscriptSizing=\"dynamic\">\n @if (showClearButton()) { <cauca-icon-button matPrefix (buttonClick)=\"clearSearchValue()\" icon=\"close\" /> }\n <mat-label>{{ 'dataGrid.keywordsLabel' | translate}}</mat-label>\n <input matInput [formControl]=\"filterControl\">\n <mat-icon matSuffix>search</mat-icon>\n </mat-form-field>\n\n <ng-content select=\"[filterRow]\" ngProjectAs=\"[filterRow]\" />\n\n @if (showRefreshButton()) { <cauca-icon-button (buttonClick)=\"onRefresh()\" icon=\"refresh\" class=\"grid-refresh-button\" /> }\n\n @if (showAddButton()) { <cauca-raised-button icon=\"add\" color=\"primary\" [label]=\"addButtonLabel()\" [translateLabel]=\"false\" class=\"grid-new-button\" [isDisabled]=\"disableAddButton()\" (buttonClick)=\"onAddButtonClick()\" /> }\n</div>", styles: [".grid-header{display:flex;justify-content:space-between;gap:16px;align-items:center;flex-wrap:nowrap;align-content:normal;padding:0 16px}.grid-search-box{display:block;flex-grow:1;flex-basis:0;min-width:0;align-self:auto}.grid-refresh-button,.grid-new-button{flex-shrink:0}@media(max-width:500px){.grid-header{gap:8px}}.grid-new-button{display:block;flex-basis:auto;align-self:auto}.grid-new-button>mat-icon{color:inherit}\n"] }] }], propDecorators: { showAddButton: [{ type: i0.Input, args: [{ isSignal: true, alias: "showAddButton", required: false }] }], showRefreshButton: [{ type: i0.Input, args: [{ isSignal: true, alias: "showRefreshButton", required: false }] }], addButtonLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "addButtonLabel", required: false }] }], disableAddButton: [{ type: i0.Input, args: [{ isSignal: true, alias: "disableAddButton", required: false }] }], filterChange: [{ type: i0.Output, args: ["filterChange"] }], addButtonClick: [{ type: i0.Output, args: ["addButtonClick"] }], refreshRequest: [{ type: i0.Output, args: ["refreshRequest"] }] } }); var Density; (function (Density) { Density["Compact"] = "compact"; Density["Standard"] = "standard"; Density["Comfortable"] = "comfortable"; })(Density || (Density = {})); class Preference { } class GridConfiguration { } class MatPaginatorLocalizationService extends MatPaginatorIntl { constructor(translateService) { super(); this.translateService = translateService; this.itemsPerPageLabel = 'Items per page'; this.nextPageLabel = 'Next page'; this.previousPageLabel = 'Previous page'; this.ofLabel = 'of'; this.getRangeLabel = (page, pageSize, length) => { if (length == 0 || pageSize == 0) { return `0 ${this.ofLabel} ${length}`; } length = Math.max(length, 0); const startIndex = page * pageSize; const endIndex = startIndex < length ? Math.min(startIndex + pageSize, length) : startIndex + pageSize; return `${startIndex + 1} – ${endIndex} ${this.ofLabel} ${length}`; }; this.translateService.onLangChange.subscribe(() => this.loadTranslations()); this.loadTranslations(); } loadTranslations() { this.translateService.get([ 'paginator.itemsPerPage', 'paginator.nextPage', 'paginator.previousPage', 'paginator.of' ]) .subscribe(translation => { this.itemsPerPageLabel = translation['paginator.itemsPerPage']; this.nextPageLabel = translation['paginator.nextPage']; this.previousPageLabel = translation['paginator.previousPage']; this.ofLabel = translation['paginator.of']; this.changes.next(); }); } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.0", ngImport: i0, type: MatPaginatorLocalizationService, deps: [{ token: i1$2.TranslateService }], target: i0.ɵɵFactoryTarget.Injectable }); } static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.1.0", ngImport: i0, type: MatPaginatorLocalizationService, providedIn: 'root' }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.0", ngImport: i0, type: MatPaginatorLocalizationService, decorators: [{ type: Injectable, args: [{ providedIn: 'root' }] }], ctorParameters: () => [{ type: i1$2.TranslateService }] }); class PreferenceService { constructor() { this.preference = new BehaviorSubject(new Preference()); this.gridConfiguration = []; const data = localStorage.getItem('GridPreference'); const configuration = localStorage.getItem('GridConfiguration'); if (data) { this.preference.next(JSON.parse(data)); } if (configuration) { this.gridConfiguration = JSON.parse(configuration); } } getPreference() { return this.preference.value; } setPreferenceDensity(density) { const preference = this.getPreference(); if (density === preference.gridDensity) return; preference.gridDensity = density; this.preference.next(preference); this.addOrUpdatePreference(); } addOrUpdatePreference() { localStorage.setItem('GridPreference', JSON.stringify(this.getPreference())); } getPreferenceForGrid(gridName) { return of(this.getPreferenceForGridNotObservable(gridName)); } addOrUpdateGridPreference(gridName, visibleColumns) { const configuration = this.getPreferenceForGridNotObservable(gridName); configuration.visibleColumns = visibleColumns || []; localStorage.setItem('GridConfiguration', JSON.stringify(this.gridConfiguration)); return of(); } getPreferenceForGridNotObservable(gridName) { const configuration = this.gridConfiguration.find(g => g.name == gridName); if (configuration) { return configuration; } const newConfiguration = new GridConfiguration(); newConfiguration.name = gridName; this.gridConfiguration.push(newConfiguration); return newConfiguration; } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.0", ngImport: i0, type: PreferenceService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); } static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.1.0", ngImport: i0, type: PreferenceService, providedIn: 'root' }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.0", ngImport: i0, type: PreferenceService, decorators: [{ type: Injectable, args: [{ providedIn: 'root' }] }], ctorParameters: () => [] }); const PREFERENCE_SERVICE_TOKEN = new InjectionToken('CaucaGridPreferenceService'); function provideCaucaGrid(options) { return [ { provide: CDK_DRAG_CONFIG, useValue: { previewContainer: 'parent' } }, { provide: MatPaginatorIntl, useClass: MatPaginatorLocalizationService }, { provide: PREFERENCE_SERVICE_TOKEN, useClass: options?.gridPreferenceService || PreferenceService } ]; } class BaseDataGridComponent { get density() { return Density; } constructor(translateService, preferenceService) { this.preferenceService = preferenceService; this.resourceName = input.required(/* @ts-ignore */ ...(ngDevMode ? [{ debugName: "resourceName" }] : /* istanbul ignore next */ [])); this.displayedColumns = input([], /* @ts-ignore */ ...(ngDevMode ? [{ debugName: "displayedColumns" }] : /* istanbul ignore next */ [])); this.showAddButton = input(false, /* @ts-ignore */ ...(ngDevMode ? [{ debugName: "showAddButton" }] : /* istanbul ignore next */ [])); this.disableAddButton = input(false, /* @ts-ignore */ ...(ngDevMode ? [{ debugName: "disableAddButton" }] : /* istanbul ignore next */ [])); this.addButtonLabel = input('', /* @ts-ignore */ ...(ngDevMode ? [{ debugName: "addButtonLabel" }] : /* istanbul ignore next */ [])); this.searchableColumns = input(/* @ts-ignore */ ...(ngDevMode ? [undefined, { debugName: "searchableColumns" }] : /* istanbul ignore next */ [])); this.showTableOptions = input(false, /* @ts-ignore */ ...(ngDevMode ? [{ debugName: "showTableOptions" }] : /* istanbul ignore next */ [])); this.showColumnViewer = input(true, /* @ts-ignore */ ...(ngDevMode ? [{ debugName: "showColumnViewer" }] : /* istanbul ignore next */ [])); this.showPaginator = input(false, /* @ts-ignore */ ...(ngDevMode ? [{ debugName: "showPaginator" }] : /* istanbul ignore next */ [])); this.hidePageSize = input(false, /* @ts-ignore */ ...(ngDevMode ? [{ debugName: "hidePageSize" }] : /* istanbul ignore next */ [])); this.showExpandButton = input(false, /* @ts-ignore */ ...(ngDevMode ? [{ debugName: "showExpandButton" }] : /* istanbul ignore next */ [])); this.addButtonClick = output(); this.expandedElement = signal(null, /* @ts-ignore */ ...(ngDevMode ? [{ debugName: "expandedElement" }] : /* istanbul ignore next */ [])); this.defaultAddButtonLabel = ''; /** * Derived from the column inputs, but overwritten when the user picks columns in the table * options — which is exactly what linkedSignal models. It replaces the ngOnChanges mirroring * this class used to do (ADR-0003). */ this.allDisplayedColumns = linkedSignal(() => this.computeDisplayedColumns(), /* @ts-ignore */ ...(ngDevMode ? [{ debugName: "allDisplayedColumns" }] : /* istanbul ignore next */ [])); this.sort = null; this.defaultAddButtonLabel = translateService.instant('dataGrid.defaultAddButtonLabel'); } ngAfterContentInit() { this.setUpPaginator(this.paginator, this.showPaginator()); this.setUpFilterPredicate(); if (this.table && this.regularColumns && this.rowDefs && this.columnDefs) { this.applyColumns(); } if (this.showTableOptions()) { this.preferenceService.preference.subscribe((preference) => { this.preference = preference; }); } else { this.preference = new Preference(); } } onExpand(element) { if (this.expandedElement() === element) { this.expandedElement.set(null); } else { this.expandedElement.set(element); } } clearFilter() { this.header?.clearSearchValue(); } renderRows() { this.forceReloadFilter(); this.applyColumns(); this.table.renderRows(); } onDensityChanged(density) { this.preferenceService.setPreferenceDensity(density); } /** The set of columns to render, before the user's own column selection is applied. */ computeDisplayedColumns() { return [...this.displayedColumns()]; } setUpPaginator(_paginator, _showPaginator) { // nothing } onColumnsChanged(columns) { this.allDisplayedColumns.set([...columns]); const columnsToSave = this.removeMandatoryColumns([...columns]); this.preferenceService.addOrUpdateGridPreference(this.resourceName(), columnsToSave).subscribe(); } applyColumns() { this.regularColumns.forEach(dynColumn => this.table.addColumnDef(dynColumn.columnDef)); this.rowDefs.forEach(rowDef => this.table.addRowDef(rowDef)); this.table.setNoDataRow(this.noDataRow); this.columnDefs.forEach(columnDef => { this.table.addColumnDef(columnDef); this.sort.register({ id: columnDef.name, start: 'desc', disableClear: false }); }); } removeMandatoryColumns(columns) { let index = columns.indexOf(""); if (index > -1) { columns.splice(index, 1); } index = columns.indexOf("position"); if (index > -1) { columns.splice(index, 1); } index = columns.indexOf("buttons"); if (index > -1) { columns.splice(index, 1); } index = columns.indexOf("menu"); if (index > -1) { columns.splice(index, 1); } index = columns.indexOf("expand"); if (index > -1) { columns.splice(index, 1); } return columns; } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.0", ngImport: i0, type: BaseDataGridComponent, deps: [{ token: i1$3.TranslateService }, { token: PREFERENCE_SERVICE_TOKEN }], target: i0.ɵɵFactoryTarget.Component }); } static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "22.1.0", type: BaseDataGridComponent, isStandalone: true, selector: "ng-component", inputs: { resourceName: { classPropertyName: "resourceName", publicName: "resourceName", isSignal: true, isRequired: true, transformFunction: null }, displayedColumns: { classPropertyName: "displayedColumns", publicName: "displayedColumns", isSignal: true, isRequired: false, transformFunction: null }, showAddButton: { classPropertyName: "showAddButton", publicName: "showAddButton", isSignal: true, isRequired: false, transformFunction: null }, disableAddButton: { classPropertyName: "disableAddButton", publicName: "disableAddButton", isSignal: true, isRequired: false, transformFunction: null }, addButtonLabel: { classPropertyName: "addButtonLabel", publicName: "addButtonLabel", isSignal: true, isRequired: false, transformFunction: null }, searchableColumns: { classPropertyName: "searchableColumns", publicName: "searchableColumns", isSignal: true, isRequired: false, transformFunction: null }, showTableOptions: { classPropertyName: "showTableOptions", publicName: "showTableOptions", isSignal: true, isRequired: false, transformFunction: null }, showColumnViewer: { classPropertyName: "showColumnViewer", publicName: "showColumnViewer", isSignal: true, isRequired: false, transformFunction: null }, showPaginator: { classPropertyName: "showPaginator", publicName: "showPaginator", isSignal: true, isRequired: false, transformFunction: null }, hidePageSize: { classPropertyName: "hidePageSize", publicName: "hidePageSize", isSignal: true, isRequired: false, transformFunction: null }, showExpandButton: { classPropertyName: "showExpandButton", publicName: "showExpandButton", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { addButtonClick: "addButtonClick" }, queries: [{ propertyName: "headerRowDef", first: true, predicate: MatHeaderRowDef, descendants: true }, { propertyName: "footerRowDef", first: true, predicate: MatFooterRowDef, descendants: true }, { propertyName: "noDataRow", first: true, predicate: MatNoDataRow, descendants: true }, { propertyName: "regularColumns", predicate: BaseGridColumnComponent }, { propertyName: "columnDefs", predicate: MatColumnDef }, { propertyName: "rowDefs", predicate: MatRowDef }], viewQueries: [{ propertyName: "header", first: true, predicate: DataGridHeaderComponent, descendants: true }, { propertyName: "table", first: true, predicate: MatTable, descendants: true, static: true }, { propertyName: "paginator", first: true, predicate: MatPaginator, descendants: true }], ngImport: i0, template: '', isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.0", ngImport: i0, type: BaseDataGridComponent, decorators: [{ type: Component, args: [{ changeDetection: ChangeDetectionStrategy.OnPush, template: '' }] }], ctorParameters: () => [{ type: i1$3.TranslateService }, { type: undefined, decorators: [{ type: Inject, args: [PREFERENCE_SERVICE_TOKEN] }] }], propDecorators: { resourceName: [{ type: i0.Input, args: [{ isSignal: true, alias: "resourceName", required: true }] }], displayedColumns: [{ type: i0.Input, args: [{ isSignal: true, alias: "displayedColumns", required: false }] }], showAddButton: [{ type: i0.Input, args: [{ isSignal: true, alias: "showAddButton", required: false }] }], disableAddButton: [{ type: i0.Input, args: [{ isSignal: true, alias: "disableAddButton", required: false }] }], addButtonLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "addButtonLabel", required: false }] }], searchableColumns: [{ type: i0.Input, args: [{ isSignal: true, alias: "searchableColumns", required: false }] }], showTableOptions: [{ type: i0.Input, args: [{ isSignal: true, alias: "showTableOptions", required: false }] }], showColumnViewer: [{ type: i0.Input, args: [{ isSignal: true, alias: "showColumnViewer", required: false }] }], showPaginator: [{ type: i0.Input, args: [{ isSignal: true, alias: "showPaginator", required: false }] }], hidePageSize: [{ type: i0.Input, args: [{ isSignal: true, alias: "hidePageSize", required: false }] }], showExpandButton: [{ type: i0.Input, args: [{ isSignal: true, alias: "showExpandButton", required: false }] }], addButtonClick: [{ type: i0.Output, args: ["addButtonClick"] }], header: [{ type: ViewChild, args: [DataGridHeaderComponent] }], table: [{ type: ViewChild, args: [MatTable, { static: true }] }], regularColumns: [{ type: ContentChildren, args: [BaseGridColumnComponent] }], columnDefs: [{ type: ContentChildren, args: [MatColumnDef] }], headerRowDef: [{ type: ContentChild, args: [MatHeaderRowDef] }], footerRowDef: [{ type: ContentChild, args: [MatFooterRowDef] }], rowDefs: [{ type: ContentChildren, args: [MatRowDef] }], noDataRow: [{ type: ContentChild, args: [MatNoDataRow] }], paginator: [{ type: ViewChild, args: [MatPaginator] }] } }); class ButtonPopoverComponent { constructor() { this.buttonLabel = input(null, /* @ts-ignore */ ...(ngDevMode ? [{ debugName: "buttonLabel" }] : /* istanbul ignore next */ [])); this.buttonIcon = input('', /* @ts-ignore */ ...(ngDevMode ? [{ debugName: "buttonIcon" }] : /* istanbul ignore next */ [])); this.color = input('primary', /* @ts-ignore */ ...(ngDevMode ? [{ debugName: "color" }] : /* istanbul ignore next */ [])); this.isActive = signal(false, /* @ts-ignore */ ...(ngDevMode ? [{ debugName: "isActive" }] : /* istanbul ignore next */ [])); } ; toggle() { this.isActive.set(!this.isActive()); } close() { if (this.isActive()) { this.isActive.set(false); } } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.0", ngImport: i0, type: ButtonPopoverComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); } static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "22.1.0", type: ButtonPopoverComponent, isStandalone: true, selector: "cauca-button-popover", inputs: { buttonLabel: { classPropertyName: "buttonLabel", publicName: "buttonLabel", isSignal: true, isRequired: false, transformFunction: null }, buttonIcon: { classPropertyName: "buttonIcon", publicName: "buttonIcon", isSignal: true, isRequired: false, transformFunction: null }, color: { classPropertyName: "color", publicName: "color", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "<cauca-basic-button [icon]=\"buttonIcon()\" [color]=\"color()\" [label]=\"buttonLabel()\" [translateLabel]=\"false\" (buttonClick)=\"toggle()\" cdkOverlayOrigin #popoverTrigger=\"cdkOverlayOrigin\" />\n\n<ng-template\n cdkConnectedOverlay\n [cdkConnectedOverlayOrigin]=\"popoverTrigger\"\n [cdkConnectedOverlayOpen]=\"isActive()\"\n [cdkConnectedOverlayHasBackdrop]=\"isActive()\"\n [cdkConnectedOverlayBackdropClass]=\"'cdk-overlay-transparent-backdrop-cs'\"\n (backdropClick)=\"toggle()\">\n <ng-content></ng-content>\n</ng-template>", styles: [".popover{background-color:#fff;border:1px solid #DDD;pointer-events:none;opacity:0;position:absolute;transition:all .5s ease 0s}.active{opacity:1;pointer-events:auto}\n"], dependencies: [{ kind: "directive", type: CdkConnectedOverlay, selector: "[cdk-connected-overlay], [connected-overlay], [cdkConnectedOverlay]", inputs: ["cdkConnectedOverlayOrigin", "cdkConnectedOverlayPositions", "cdkConnectedOverlayPositionStrategy", "cdkConnectedOverlayOffsetX", "cdkConnectedOverlayOffsetY", "cdkConnectedOverlayWidth", "cdkConnectedOverlayHeight", "cdkConnectedOverlayMinWidth", "cdkConnectedOverlayMinHeight", "cdkConnectedOverlayBackdropClass", "cdkConnectedOverlayPanelClass", "cdkConnectedOverlayViewportMargin", "cdkConnectedOverlayScrollStrategy", "cdkConnectedOverlayOpen", "cdkConnectedOverlayDisableClose", "cdkConnectedOverlayTransformOriginOn", "cdkConnectedOverlayHasBackdrop", "cdkConnectedOverlayLockPosition", "cdkConnectedOverlayFlexibleDimensions", "cdkConnectedOverlayGrowAfterOpen", "cdkConnectedOverlayPush", "cdkConnectedOverlayDisposeOnNavigation", "cdkConnectedOverlayUsePopover", "cdkConnectedOverlayMatchWidth", "cdkConnectedOverlay"], outputs: ["backdropClick", "positionChange", "attach", "detach", "overlayKeydown", "overlayOutsideClick"], exportAs: ["cdkConnectedOverlay"] }, { kind: "component", type: BasicButtonComponent, selector: "cauca-basic-button" }, { kind: "directive", type: CdkOverlayOrigin, selector: "[cdk-overlay-origin], [overlay-origin], [cdkOverlayOrigin]", exportAs: ["cdkOverlayOrigin"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.0", ngImport: i0, type: ButtonPopoverComponent, decorators: [{ type: Component, args: [{ selector: 'cauca-button-popover', imports: [CdkConnectedOverlay, BasicButtonComponent, CdkOverlayOrigin], changeDetection: ChangeDetectionStrategy.OnPush, template: "<cauca-basic-button [icon]=\"buttonIcon()\" [color]=\"color()\" [label]=\"buttonLabel()\" [translateLabel]=\"false\" (buttonClick)=\"toggle()\" cdkOverlayOrigin #popoverTrigger=\"cdkOverlayOrigin\" />\n\n<ng-template\n cdkConnectedOverlay\n [cdkConnectedOverlayOrigin]=\"popoverTrigger\"\n [cdkConnectedOverlayOpen]=\"isActive()\"\n [cdkConnectedOverlayHasBackdrop]=\"isActive()\"\n [cdkConnectedOverlayBackdropClass]=\"'cdk-overlay-transparent-backdrop-cs'\"\n (backdropClick)=\"toggle()\">\n <ng-content></ng-content>\n</ng-template>", styles: [".popover{background-color:#fff;border:1px solid #DDD;pointer-events:none;opacity:0;position:absolute;transition:all .5s ease 0s}.active{opacity:1;pointer-events:auto}\n"] }] }], propDecorators: { buttonLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "buttonLabel", required: false }] }], buttonIcon: [{ type: i0.Input, args: [{ isSignal: true, alias: "buttonIcon", required: false }] }], color: [{ type: i0.Input, args: [{ isSignal: true, alias: "color", required: false }] }] } }); class DataGridTableOptionsComponent { constructor() { this.gridName = input.required(/* @ts-ignore */ ...(ngDevMode ? [{ debugName: "gridName" }] : /* istanbul ignore next */ [])); this.showColumnViewer = input(true, /* @ts-ignore */ ...(ngDevMode ? [{ debugName: "showColumnViewer" }] : /* istanbul ignore next */ [])); this.allColumns = input(new QueryList(), /* @ts-ignore */ ...(ngDevMode ? [{ debugName: "allColumns" }] : /* istanbul ignore next */ [])); this.densityChanged = output(); this.columnsChanged = output(); this.columnsSearch = ''; this.preferenceService = inject(PREFERENCE_SERVICE_TOKEN); } get density() { return Density; } get columns() { return this.allColumns().filter(c => c.prop() !== 'buttons' && c.prop() !== 'menu' && c.prop() !== '' && c.isInColumnChooser()); } get currentDensityIcon() { const currentDensity = this.preferenceService.getPreference()?.gridDensity; if (currentDensity === Density.Compact) { return 'density_small'; } if (currentDensity === Density.Comfortable) { return 'density_large'; } return 'density_medium'; } ngOnInit() { this.preferenceService.getPreferenceForGrid(this.gridName()).subscribe({ next: configuration => { if (configuration?.visibleColumns) { this.selectOnlyUserColumns(configuration.visibleColumns); } else { this.selectAllColumns(); } this.onColumnsChanged(); } }); } closeColumnViewer() { if (this.columnViewer) { this.columnViewer.close(); } } changeDensity(newDensity) { this.densityChanged.emit(newDensity); } onColumnsChanged() { const newColumns = this.allColumns().filter(column => column.selected); this.columnsChanged.emit(newColumns.map((column) => column.prop())); } resetColumns() { this.allColumns().forEach((column => column.selected = true)); this.columnsChanged.emit(this.allColumns().map((column) => column.prop())); } selectOnlyUserColumns(configurationVisibleColumns) { this.allColumns().forEach((column => { const index = configurationVisibleColumns.findIndex(c => c === column.prop()); if (index === -1 && column.prop() !== 'buttons' && column.prop() !== 'menu' && column.prop() !== '') { column.selected = false; } })); } selectAllColumns() { this.allColumns().forEach((column => { column.selected = true; })); } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.0", ngImport: i0, type: DataGridTableOptionsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); } static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.0", type: DataGridTableOptionsComponent, isStandalone: true, selector: "cauca-data-grid-table-options", inputs: { gridName: { classPropertyName: "gridName", publicName: "gridName", isSignal: true, isRequired: true, transformFunction: null }, showColumnViewer: { classPropertyName: "showColumnViewer", publicName: "showColumnViewer", isSignal: true, isRequired: false, transformFunction: null }, allColumns: { classPropertyName: "allColumns", publicName: "allColumns", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { densityChanged: "densityChanged", columnsChanged: "columnsChanged" }, viewQueries: [{ propertyName: "columnViewer", first: true, predicate: ButtonPopoverComponent, descendants: true, static: true }], ngImport: i0, template: "<div class=\"table-options-bar\">\n <div class=\"table-options\">\n @if (showColumnViewer()) { <cauca-button-popover [buttonLabel]=\"'dataGrid.columns' | translate\" buttonIcon=\"view_column\">\n <mat-card>\n <mat-card-content>\n <div class=\"columns\">\n @for (column of columns; track column) {\n <mat-checkbox color=\"primary\" [(ngModel)]=\"column.selected\"\n (change)=\"onColumnsChanged()\">\n {{column.label()}}\n </mat-checkbox>\n }\n </div>\n </mat-card-content>\n <mat-card-actions>\n <cauca-stroked-button [small]=\"true\" color=\"primary\" (buttonClick)=\"resetColumns()\" label=\"dataGrid.columnChooser.reset\" [translateLabel]=\"true\" />\n <cauca-raised-button [small]=\"true\" color=\"primary\" (buttonClick)=\"resetColumns()\" label=\"dataGrid.columnChooser.showAll\" [translateLabel]=\"true\" />\n </mat-card-actions>\n </mat-card>\n </cauca-button-popover> }\n <cauca-basic-button color=\"primary\" [matMenuTriggerFor]=\"densityMenu\" class=\"open-menu-button\" [icon]=\"currentDensityIcon\" label=\"dataGrid.density.title\" [translateLabel]=\"true\" />\n </div>\n\n <ng-content select=\"[customFilter]\"> </ng-content>\n</div>\n\n<mat-menu #densityMenu=\"matMenu\">\n <cauca-menu-item label=\"dataGrid.density.compact\" [translateLabel]=\"true\" icon=\"density_small\" (buttonClick)=\"changeDensity(density.Compact)\" class=\"density-compact\" />\n <cauca-menu-item label=\"dataGrid.density.standard\" [translateLabel]=\"true\" icon=\"density_medium\" (buttonClick)=\"changeDensity(density.Standard)\" class=\"density-standard\" />\n <cauca-menu-item label=\"dataGrid.density.comfortable\" [translateLabel]=\"true\" icon=\"density_large\" (buttonClick)=\"changeDensity(density.Comfortable)\" class=\"density-comfortable\" />\n</mat-menu>", styles: [".table-options-bar{display:flex;padding:8px 16px;align-items:center;align-self:stretch}.table-options{flex:1 0 0;display:flex;gap:8px;align-items:center;align-content:normal;text-transform:capitalize}.columns{display:flex;flex-direction:column;max-height:650px}mat-card{box-shadow:0 8px 10px 1px #00000024}mat-card>mat-card-actions{gap:32px;padding:16px;justify-content:space-between}.column-viewer-header{display:flex;flex-direction:row-reverse;padding:4px 4px 0px px 0px}.mat-mdc-icon-button.mat-mdc-button-base{height:24px}mat-card-content{padding:0 8px}.button-small{height:32px;line-height:18px}.small-icon-button{height:24px;width:24px;padding:0}.small-icon-button>span{height:24px!important;width:24px!important}.small-icon-button>.mat-mdc-icon-button .mat-mdc-button-touch-target{display:none;height:24px!important;width:24px!important}.small-icon{font-size:18px;height:unset;width:unset}\n"], dependencies: [{ kind: "ngmodule", type: MatCardModule }, { kind: "component", type: i1$4.MatCard, selector: "mat-card", inputs: ["appearance"], exportAs: ["matCard"] }, { kind: "directive", type: i1$4.MatCardActions, selector: "mat-card-actions", inputs: ["align"], exportAs: ["matCardActions"] }, { kind: "directive", type: i1$4.MatCardContent, selector: "mat-card-content" }, { kind: "component", type: ButtonPopoverComponent, selector: "cauca-button-popover", inputs: ["buttonLabel", "buttonIcon", "color"] }, { kind: "ngmodule", type: MatCheckboxModule }, { kind: "component", type: i2$1.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: "component", type: StrokedButtonComponent, selector: "cauca-stroked-button" }, { kind: "component", type: RaisedButtonComponent, selector: "cauca-raised-button" }, { kind: "component", type: BasicButtonComponent, selector: "cauca-basic-button" }, { kind: "ngmodule", type: MatMenuModule }, { kind: "component", type: i3$1.MatMenu, selector: "mat-menu", inputs: ["backdropClass", "aria-label", "aria-labelledby", "aria-describedby", "xPosition", "yPosition", "overlapTrigger", "hasBackdrop", "class", "classList"], outputs: ["closed", "close"], exportAs: ["matMenu"] }, { kind: "directive", type: i3$1.MatMenuTrigger, selector: "[mat-menu-trigger-for], [matMenuTriggerFor]", inputs: ["mat-menu-trigger-for", "matMenuTriggerFor", "matMenuTriggerData", "matMenuTriggerRestoreFocus"], outputs: ["menuOpened", "onMenuOpen", "menuClosed", "onMenuClose"], exportAs: ["matMenuTrigger"] }, { kind: "ngmodule", type: FormsModule }, { 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: MenuItemComponent, selector: "cauca-menu-item", inputs: ["translateLabel", "trigger"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.0", ngImport: i0, type: DataGridTableOptionsComponent, decorators: [{ type: Component, args: [{ selector: 'cauca-data-grid-table-options', changeDetection: ChangeDetectionStrategy.OnPush, imports: [MatCardModule, ButtonPopoverComponent, MatCheckboxModule, StrokedButtonComponent, RaisedButtonComponent, BasicButtonComponent, MatMenuModule, FormsModule, TranslatePipe, MenuItemComponent], template: "<div class=\"table-options-bar\">\n <div class=\"table-options\">\n @if (showColumnViewer()) { <cauca-button-popover [buttonLabel]=\"'dataGrid.columns' | translate\" buttonIcon=\"view_column\">\n <mat-card>\n <mat-card-content>\n <div class=\"columns\">\n @for (column of columns; track column) {\n <mat-checkbox color=\"primary\" [(ngModel)]=\"column.selected\"\n (change)=\"onColumnsChanged()\">\n {{column.label()}}\n </mat-checkbox>\n }\n </div>\n </mat-card-content>\n <mat-card-actions>\n <cauca-stroked-button [small]=\"true\" color=\"primary\" (buttonClick)=\"resetColumns()\" label=\"dataGrid.columnChooser.reset\" [translateLabel]=\"true\" />\n <cauca-raised-button [small]=\"true\" color=\"primary\" (buttonClick)=\"resetColumns()\" label=\"dataGrid.columnChooser.showAll\" [translateLabel]=\"true\" />\n </mat-card-actions>\n </mat-card>\n </cauca-button-popover> }\n <cauca-basic-button color=\"primary\" [matMenuTriggerFor]=\"densityMenu\" class=\"open-menu-button\" [icon]=\"currentDensityIcon\" label=\"dataGrid.density.title\" [translateLabel]=\"true\" />\n </div>\n\n <ng-content select=\"[customFilter]\"> </ng-content>\n</div>\n\n<mat-menu #densityMenu=\"matMenu\">\n <cauca-menu-item label=\"dataGrid.density.compact\" [translateLabel]=\"true\" icon=\"density_small\" (buttonClick)=\"changeDensity(density.Compact)\" class=\"density-compact\" />\n <cauca-menu-item label=\"dataGrid.density.standard\" [translateLabel]=\"true\" icon=\"density_medium\" (buttonClick)=\"changeDensity(density.Standard)\" class=\"density-standard\" />\n <cauca-menu-item label=\"dataGrid.density.comfortable\" [translateLabel]=\"true\" icon=\"density_large\" (buttonClick)=\"changeDensity(density.Comfortable)\" class=\"density-comfortable\" />\n</mat-menu>", styles: [".table-optio