dynamic-mat-table
Version:
dynamic-mat-table is an Angular component for presenting large and complex data with a lightning fast performance (at least 10x faster) and excellent level of control over the presentation.
680 lines • 118 kB
JavaScript
import { Component, QueryList, ElementRef, ViewChild, TemplateRef, Renderer2, ChangeDetectorRef, Input, ContentChildren, Injector, HostBinding, ChangeDetectionStrategy, } from '@angular/core';
import { TableCoreDirective } from '../cores/table.core.directive';
import { TableService } from './dynamic-mat-table.service';
import { HeaderFilterComponent } from './extensions/filter/header-filter.component';
import { MatDialog } from '@angular/material/dialog';
import { trigger, transition, style, animate, query, stagger, state, } from '@angular/animations';
import { ResizeColumn } from '../models/resize-column.mode';
import { TableIntl } from '../international/table-Intl';
import { moveItemInArray, } from '@angular/cdk/drag-drop';
import { isNullorUndefined } from '../cores/type';
import { TableSetting } from '../models/table-setting.model';
import { delay, filter } from 'rxjs/operators';
import { MatMenuTrigger } from '@angular/material/menu';
import { Overlay, OverlayContainer, OverlayPositionBuilder, } from '@angular/cdk/overlay';
import { requestFullscreen } from '../utilizes/html.helper';
import { TooltipComponent } from '../tooltip/tooltip.component';
import { ComponentPortal } from '@angular/cdk/portal';
export const tableAnimation = trigger("tableAnimation", [
transition("void => *", [
query(":enter", style({ transform: "translateX(-50%)", opacity: 0 }), {
//limit: 5,
optional: true,
}),
query(":enter", stagger("0.01s", [
animate("0.5s ease", style({ transform: "translateX(0%)", opacity: 1 })),
]), {
//limit: 5,
optional: true,
}),
]),
]);
export const expandAnimation = trigger("detailExpand", [
state("collapsed", style({ height: "0px", minHeight: "0" })),
state("expanded", style({ height: "*" })),
transition("expanded <=> collapsed", animate("100ms cubic-bezier(0.4, 0.0, 0.2, 1)")),
]);
export class DynamicMatTableComponent extends TableCoreDirective {
constructor(dialog, renderer, languagePack, tableService, cdr, overlay, overlayContainer, overlayPositionBuilder, config) {
super(tableService, cdr, config);
this.dialog = dialog;
this.renderer = renderer;
this.languagePack = languagePack;
this.tableService = tableService;
this.cdr = cdr;
this.overlay = overlay;
this.overlayContainer = overlayContainer;
this.overlayPositionBuilder = overlayPositionBuilder;
this.config = config;
this.init = false;
this.height = null;
this.contextMenuPosition = { x: "0px", y: "0px" };
this.dragDropData = { dragColumnIndex: -1, dropColumnIndex: -1 };
this.printing = true;
this.printTemplate = null;
this.resizeColumn = new ResizeColumn();
/* Tooltip */
this.overlayRef = null;
this.indexTrackFn = (index) => {
return index;
};
this.currentContextMenuSender = {};
this.overlayContainer
.getContainerElement()
.addEventListener("contextmenu", (e) => {
e.preventDefault();
return false;
});
this.eventsSubscription = this.resizeColumn.widthUpdate
.pipe(delay(150), filter((data) => data.e.columnIndex >= 0) /* Checkbox Column */)
.subscribe((data) => {
var _a;
let i = data.e.columnIndex;
if (data.e.resizeHandler === "left") {
const visibleColumns = this.columns.filter((c) => c.display !== "hidden" && c.index < data.e.columnIndex);
i = visibleColumns[visibleColumns.length - 1].index;
}
// this.columns[i].width = data.w;
const unit = this.columns[i].widthUnit || "px";
let style = "";
if (this.columns[i].minWidth) {
data.w = Math.min(this.columns[i].minWidth, data.w);
}
if (unit === "px") {
style = data.w + "px";
}
else if (unit === "%") {
const widthChanges = ((_a = this.tableSetting.columnSetting[i].width) !== null && _a !== void 0 ? _a : 0) - data.w;
console.log(this.tableSetting.columnSetting[i].width, data.w, widthChanges);
style = `calc( ${this.columns[i].widthPercentage}% + ${widthChanges}px)`;
}
this.columns[i].style = Object.assign(Object.assign({}, this.columns[i].style), { "max-width": style, "min-width": style });
/* store latest width in setting if exists */
if (this.tableSetting.columnSetting[i]) {
this.tableSetting.columnSetting[i].width = data.w;
}
this.refreshGrid();
});
}
get setting() {
return this.tableSetting;
}
set setting(value) {
var _a;
if (!isNullorUndefined(value)) {
value.alternativeRowStyle =
value.alternativeRowStyle || this.tableSetting.alternativeRowStyle;
value.columnSetting =
value.columnSetting || this.tableSetting.columnSetting;
value.direction = value.direction || this.tableSetting.direction;
value.normalRowStyle =
value.normalRowStyle || this.tableSetting.normalRowStyle;
value.visibleActionMenu =
value.visibleActionMenu || this.tableSetting.visibleActionMenu;
value.visibleTableMenu =
value.visibleTableMenu || this.tableSetting.visibleTableMenu;
value.autoHeight = value.autoHeight || this.tableSetting.autoHeight;
value.saveSettingMode =
value.saveSettingMode || this.tableSetting.saveSettingMode || "simple";
this.pagination.pageSize = value.pageSize || this.tableSetting.pageSize || this.pagination.pageSize;
/* Dynamic Cell must update when setting change */
(_a = value === null || value === void 0 ? void 0 : value.columnSetting) === null || _a === void 0 ? void 0 : _a.forEach((column) => {
var _a;
const originalColumn = (_a = this.columns) === null || _a === void 0 ? void 0 : _a.find((c) => c.name === column.name);
if (originalColumn) {
column = Object.assign(Object.assign({}, originalColumn), column);
}
});
this.tableSetting = value;
this.setDisplayedColumns();
}
}
ngAfterViewInit() {
this.tvsDataSource.paginator = this.paginator;
this.tvsDataSource.sort = this.sort;
this.dataSource.subscribe((x) => {
x = x || [];
this.rowSelectionModel.clear();
this.tvsDataSource.data = [];
this.initSystemField(x);
this.tvsDataSource.data = x;
// this.cdr.detectChanges();
this.refreshUI();
// window.requestAnimationFrame(() => {
// });
});
this.tvsDataSource.sort.sortChange.subscribe((sort) => {
this.pagination.pageIndex = 0;
this.onTableEvent.emit({ event: "SortChanged", sender: sort });
});
}
tooltip_onChanged(column, row, elementRef, show) {
if (column.cellTooltipEnable === true) {
if (show === true && row[column.name]) {
if (this.overlayRef !== null) {
this.closeTooltip();
}
const positionStrategy = this.overlayPositionBuilder
.flexibleConnectedTo(elementRef)
.withPositions([
{
originX: "center",
originY: "top",
overlayX: "center",
overlayY: "bottom",
offsetY: -8,
},
]);
this.overlayRef = this.overlay.create({ positionStrategy });
const option = {
providers: [{
provide: "tooltipConfig",
useValue: row[column.name],
}],
};
const injector = Injector.create(option);
const tooltipRef = this.overlayRef.attach(new ComponentPortal(TooltipComponent, null, injector));
setTimeout(() => {
tooltipRef.destroy();
}, 5000);
}
else if (show === false && this.overlayRef !== null) {
this.closeTooltip();
}
}
}
closeTooltip() {
var _a;
(_a = this.overlayRef) === null || _a === void 0 ? void 0 : _a.detach();
this.overlayRef = null;
}
ellipsis(column, cell = true) {
if (cell === true && column.cellEllipsisRow > 0) {
return {
display: "-webkit-box",
"-webkit-line-clamp": column === null || column === void 0 ? void 0 : column.cellEllipsisRow,
"-webkit-box-orient": "vertical",
overflow: "hidden",
"white-space": "pre-wrap",
};
}
else if (cell === true && column.headerEllipsisRow > 0) {
return {
display: "-webkit-box",
"-webkit-line-clamp": column === null || column === void 0 ? void 0 : column.headerEllipsisRow,
"-webkit-box-orient": "vertical",
overflow: "hidden",
"white-space": "pre-wrap",
};
}
}
trackColumn(index, item) {
return `${item.index}`;
}
ngOnDestroy() {
if (this.eventsSubscription) {
this.eventsSubscription.unsubscribe();
}
}
refreshUI() {
var _a, _b;
if (this.tableSetting.autoHeight === true) {
this.height = this.autoHeight();
}
else {
this.height = null;
}
this.refreshColumn(this.tableColumns);
this.tvsDataSource.columns = this.columns;
const scrollStrategy = this.viewport["_scrollStrategy"];
(_a = scrollStrategy === null || scrollStrategy === void 0 ? void 0 : scrollStrategy.viewport) === null || _a === void 0 ? void 0 : _a.checkViewportSize();
(_b = scrollStrategy === null || scrollStrategy === void 0 ? void 0 : scrollStrategy.viewport) === null || _b === void 0 ? void 0 : _b.scrollToOffset(0);
this.cdr.detectChanges();
}
ngOnInit() {
setTimeout(() => {
this.init = true;
}, 1000);
const scrollStrategy = this.viewport["_scrollStrategy"];
scrollStrategy.offsetChange.subscribe((offset) => { });
this.viewport.renderedRangeStream.subscribe((t) => {
// in expanding row scrolling make not good appearance therefor close it.
if (this.expandedElement &&
this.expandedElement.option &&
this.expandedElement.option.expand) {
// this.expandedElement.option.expand = false;
// this.expandedElement = null;
}
});
}
get inverseOfTranslation() {
if (!this.viewport || !this.viewport["_renderedContentOffset"]) {
return -0;
}
let offset = this.viewport["_renderedContentOffset"];
return -offset;
}
headerClass(column) {
return column === null || column === void 0 ? void 0 : column.classNames;
}
rowStyle(row) {
var _a;
let style = ((_a = row === null || row === void 0 ? void 0 : row.option) === null || _a === void 0 ? void 0 : _a.style) || {};
if (this.setting.alternativeRowStyle && row.id % 2 === 0) {
// style is high priority
style = Object.assign(Object.assign({}, this.setting.alternativeRowStyle), style);
}
if (this.setting.rowStyle) {
style = Object.assign(Object.assign({}, this.setting.rowStyle), style);
}
return style;
}
cellClass(option, column) {
let className = null;
if (option && column.name) {
className = option[column.name] ? option[column.name].style : null;
}
if (className === null) {
return column.cellClass;
}
else {
return Object.assign(Object.assign({}, className), column.cellClass);
}
}
cellStyle(option, column) {
let style = null;
if (option && column.name) {
style = option[column.name] ? option[column.name].style : null;
}
/* consider to column width resize */
if (style === null) {
return Object.assign(Object.assign({}, column.cellStyle), column.style);
}
else {
return Object.assign(Object.assign(Object.assign({}, style), column.cellStyle), column === null || column === void 0 ? void 0 : column.style);
}
}
cellIcon(option, cellName) {
if (option && cellName) {
return option[cellName] ? option[cellName].icon : null;
}
else {
return null;
}
}
filter_onChanged(column, filter) {
this.pending = true;
this.tvsDataSource.setFilter(column.name, filter).subscribe(() => {
this.clearSelection();
this.pending = false;
});
}
onContextMenu(event, column, row) {
var _a, _b;
if (((_a = this.currentContextMenuSender) === null || _a === void 0 ? void 0 : _a.time) &&
new Date().getTime() - this.currentContextMenuSender.time < 500) {
return;
}
this.contextMenu.closeMenu();
if (((_b = this.contextMenuItems) === null || _b === void 0 ? void 0 : _b.length) === 0) {
return;
}
event.preventDefault();
this.contextMenuPosition.x = event.clientX + "px";
this.contextMenuPosition.y = event.clientY + "px";
this.currentContextMenuSender = {
column: column,
row: row,
time: new Date().getTime(),
};
this.contextMenu.menuData = this.currentContextMenuSender;
this.contextMenu.menu.focusFirstItem("mouse");
this.onRowEvent.emit({
event: "BeforeContextMenuOpen",
sender: { row: row, column: column, contextMenu: this.contextMenuItems },
});
this.contextMenu.openMenu();
}
onContextMenuItemClick(data) {
this.contextMenu.menuData.item = data;
this.onRowEvent.emit({
event: "ContextMenuClick",
sender: this.contextMenu.menuData,
});
}
tableMenuActionChange(e) {
var _a;
if (e.type === "TableSetting") {
this.settingChange.emit({ type: 'apply', setting: this.tableSetting });
this.refreshColumn(this.tableSetting.columnSetting);
}
else if (e.type === "DefaultSetting") {
(this.setting.settingList || []).forEach((setting) => {
if (setting.settingName === e.data) {
setting.isDefaultSetting = true;
}
else {
setting.isDefaultSetting = false;
}
});
this.settingChange.emit({ type: 'default', setting: this.tableSetting });
}
else if (e.type === "SaveSetting") {
const newSetting = Object.assign({}, this.setting);
delete newSetting.settingList;
newSetting.settingName = e.data;
const settingIndex = (this.setting.settingList || []).findIndex((f) => f.settingName === e.data);
if (settingIndex === -1) {
this.setting.settingList.push(JSON.parse(JSON.stringify(newSetting)));
this.settingChange.emit({ type: 'create', setting: this.tableSetting });
}
else {
this.setting.settingList[settingIndex] = JSON.parse(JSON.stringify(newSetting));
this.settingChange.emit({ type: 'save', setting: this.tableSetting });
}
}
else if (e.type === "DeleteSetting") {
this.setting.settingList = this.setting.settingList.filter((s) => s.settingName !== e.data.settingName);
this.setting.columnSetting.filter(f => f.display === 'hidden').forEach(f => f.display = 'visible');
this.refreshColumn(this.setting.columnSetting);
this.settingChange.emit({ type: 'delete', setting: this.tableSetting });
}
else if (e.type === "SelectSetting") {
if (e.data != null) {
let setting = null;
this.setting.settingList.forEach((s) => {
if (s.settingName === e.data) {
s.isCurrentSetting = true;
setting = Object.assign({}, this.setting.settingList.find((s) => s.settingName === e.data));
}
else {
s.isCurrentSetting = false;
}
});
setting.settingList = this.setting.settingList;
delete setting.isCurrentSetting;
delete setting.isDefaultSetting;
if (this.pagingMode !== 'none' && this.pagination.pageSize != (setting === null || setting === void 0 ? void 0 : setting.pageSize)) {
this.pagination.pageSize =
(setting === null || setting === void 0 ? void 0 : setting.pageSize) || this.pagination.pageSize;
this.paginationChange.emit(this.pagination);
}
/* Dynamic Cell must update when setting change */
(_a = setting.columnSetting) === null || _a === void 0 ? void 0 : _a.forEach((column) => {
const originalColumn = this.columns.find((c) => c.name === column.name);
column = Object.assign(Object.assign({}, originalColumn), column);
});
this.tableSetting = setting;
this.refreshColumn(this.setting.columnSetting);
this.settingChange.emit({ type: 'select', setting: this.tableSetting });
}
else {
const columns = [];
this.columns.forEach(c => {
columns.push(Object.assign({}, c));
});
this.refreshColumn(columns);
this.refreshUI();
}
}
else if (e.type === "FullScreenMode") {
requestFullscreen(this.tbl.elementRef);
}
else if (e.type === "Download") {
this.onTableEvent.emit({
event: 'ExportData',
sender: { type: e.data, columns: this.columns, data: this.tvsDataSource.filteredData, dataSelection: this.rowSelectionModel }
});
// if (e.data === "CSV")
// {
// this.tableService.exportToCsv<T>(
// this.columns,
// this.tvsDataSource.filteredData,
// this.rowSelectionModel
// );
// } else if (e.data === "JSON")
// {
// this.tableService.exportToJson(this.tvsDataSource.filteredData);
// }
}
else if (e.type === "FilterClear") {
this.tvsDataSource.clearFilter();
this.headerFilterList.forEach((hf) => hf.clearColumn_OnClick());
}
else if (e.type === "Print") {
this.onTableEvent.emit({
event: 'ExportData',
sender: { type: 'Print', columns: this.columns, data: this.tvsDataSource.filteredData, dataSelection: this.rowSelectionModel }
});
// this.printConfig.title = this.printConfig.title || this.tableName;
// this.printConfig.direction = this.tableSetting.direction || "ltr";
// debugger
// this.printConfig.columns = this.tableColumns.filter(t => t.display !== 'hidden' && t.printable !== false);
// this.printConfig.displayedFields = this.printConfig.columns.map((o) => o.name);
// this.printConfig.data = this.tvsDataSource.filteredData;
// const params = this.tvsDataSource.toTranslate();
// this.printConfig.tablePrintParameters = [];
// params.forEach((item) =>
// {
// this.printConfig.tablePrintParameters.push(item);
// });
// this.dialog.open(PrintTableDialogComponent, {
// width: "90vw",
// data: this.printConfig,
// });
}
}
rowMenuActionChange(contextMenuItem, row) {
this.onRowEvent.emit({
event: "RowActionMenu",
sender: { row: row, action: contextMenuItem },
});
// this.rowActionMenuChange.emit({actionItem: contextMenuItem, rowItem: row });
}
pagination_onChange(e) {
if (this.pagingMode !== "none") {
this.pending = true;
this.tvsDataSource.refreshFilterPredicate();
this.pagination.length = e.length;
this.pagination.pageIndex = e.pageIndex;
this.pagination.pageSize = e.pageSize;
this.setting.pageSize =
e.pageSize; /* Save Page Size when need in setting config */
this.paginationChange.emit(this.pagination);
}
}
autoHeight() {
const minHeight = this.headerHeight +
(this.rowHeight + 1) * this.dataSource.value.length +
this.footerHeight * 0;
return minHeight.toString();
}
reload_onClick() {
this.onTableEvent.emit({ sender: null, event: "ReloadData" });
}
/////////////////////////////////////////////////////////////////
onResizeColumn(event, index, type) {
this.resizeColumn.resizeHandler = type;
this.resizeColumn.startX = event.pageX;
if (this.resizeColumn.resizeHandler === "right") {
this.resizeColumn.startWidth = event.target.parentElement.clientWidth;
this.resizeColumn.columnIndex = index;
}
else {
if (event.target.parentElement.previousElementSibling === null) {
/* for first column not resize */
return;
}
else {
this.resizeColumn.startWidth = event.target.parentElement.previousElementSibling.clientWidth;
this.resizeColumn.columnIndex = index;
}
}
event.preventDefault();
this.mouseMove(index);
}
mouseMove(index) {
this.resizableMousemove = this.renderer.listen("document", "mousemove", (event) => {
if (this.resizeColumn.resizeHandler !== null && event.buttons) {
const rtl = this.direction === "rtl" ? -1 : 1;
let width = 0;
if (this.resizeColumn.resizeHandler === "right") {
const dx = event.pageX - this.resizeColumn.startX;
width = this.resizeColumn.startWidth + rtl * dx;
}
else {
const dx = this.resizeColumn.startX - event.pageX;
width = this.resizeColumn.startWidth - rtl * dx;
}
if (this.resizeColumn.columnIndex === index &&
width > this.minWidth) {
// this.resizeColumn.columnIndex = index;
this.resizeColumn.widthUpdate.next({
e: this.resizeColumn,
w: width,
});
}
}
});
this.resizableMouseup = this.renderer.listen("document", "mouseup", (event) => {
if (this.resizeColumn.resizeHandler !== null) {
this.resizeColumn.resizeHandler = null;
this.resizeColumn.columnIndex = -1;
/* fix issue sticky column */
this.table.updateStickyColumnStyles();
/* Remove Event Listen */
this.resizableMousemove();
}
});
}
expandRow(rowIndex, mode = true) {
if (rowIndex === null || rowIndex === undefined) {
throw "Row index is not defined.";
}
if (this.expandedElement === this.tvsDataSource.allData[rowIndex]) {
this.expandedElement.option.expand = mode;
this.expandedElement =
this.expandedElement === this.tvsDataSource.allData[rowIndex]
? null
: this.tvsDataSource.allData[rowIndex];
}
else {
if (this.expandedElement &&
this.expandedElement !== this.tvsDataSource.allData[rowIndex]) {
this.expandedElement.option.expand = false;
}
this.expandedElement = null;
if (mode === true) {
this.expandedElement =
this.expandedElement === this.tvsDataSource.allData[rowIndex]
? null
: this.tvsDataSource.allData[rowIndex];
if (this.expandedElement.option === undefined ||
this.expandedElement.option === null) {
this.expandedElement.option = { expand: false };
}
this.expandedElement.option.expand = true;
}
}
}
onRowSelection(e, row, column) {
if (this.rowSelectionMode &&
this.rowSelectionMode !== "none" &&
column.rowSelectable !== false) {
this.onRowSelectionChange(e, row);
}
}
onCellClick(e, row, column) {
if (column.cellTooltipEnable === true) {
this.closeTooltip(); /* Fixed BUG: Open Overlay when redirect to other route */
}
this.onRowSelection(e, row, column);
if (column.clickable !== false &&
(column.clickType === null || column.clickType === "cell")) {
this.onRowEvent.emit({
event: "CellClick",
sender: { row: row, column: column },
});
}
}
onLabelClick(e, row, column) {
if (column.clickable !== false && column.clickType === "label") {
this.onRowEvent.emit({
event: "LabelClick",
sender: { row: row, column: column, e: e },
});
}
}
onRowDblClick(e, row) {
this.onRowEvent.emit({ event: "DoubleClick", sender: { row: row, e: e } });
}
onRowClick(e, row) {
this.onRowEvent.emit({ event: "RowClick", sender: { row: row, e: e } });
}
/************************************ Drag & Drop Column *******************************************/
dragStarted(event) {
// this.dragDropData.dragColumnIndex = event.source.;
}
dropListDropped(event) {
if (event) {
this.dragDropData.dropColumnIndex = event.currentIndex;
this.moveColumn(event.previousIndex, event.currentIndex);
}
}
drop(event) {
moveItemInArray(event.container.data, event.previousIndex, event.currentIndex);
// updates moved data and table, but not dynamic if more dropzones
// this.dataSource.data = clonedeep(this.dataSource.data);
}
/************************************ *******************************************/
copyProperty(from, to) {
const keys = Object.keys(from);
keys.forEach((key) => {
if (from[key] !== undefined && from[key] === null) {
to[key] = Array.isArray(from[key])
? Object.assign([], from[key])
: Object.assign({}, from[key]);
}
});
}
}
/** @type {!Array<{type: !Function, args: (undefined|!Array<?>)}>} */
DynamicMatTableComponent.decorators = [
{ type: Component, args: [{
selector: "dynamic-mat-table",
template: "<cdk-virtual-scroll-viewport #tbl [ngClass]=\"viewportClass\" [tvsItemSize]=\"rowHeight || 48\"\r\n [headerHeight]=\"headerHeight || 56\" [footerHeight]=\"headerHeight || 56\" [headerEnabled]=\"headerEnable || true\"\r\n [footerEnabled]=\"footerEnable || false\" [ngStyle]=\"{'background-color': backgroundColor || 'white'}\"\r\n [class.print-preview]=\"printing\">\r\n\r\n <mat-table matSort class=\"dynamic-table\" multiTemplateDataRows [cdkDropListDisabled]=\"false\" cdkDropList\r\n cdkDropListOrientation=\"horizontal\" (cdkDragStarted)=\"dragStarted($event)\"\r\n (cdkDropListDropped)=\"dropListDropped($event)\" [trackBy]=\"indexTrackFn\" [dataSource]=\"tvsDataSource\">\r\n <!-- Select Checkbox Column -->\r\n <ng-container matColumnDef=\"row-checkbox\">\r\n <!-- HEADER -->\r\n <mat-header-cell *matHeaderCellDef class=\"row-checkbox\" style=\"z-index: 2;\">\r\n <mat-checkbox style=\"z-index: 10;\" (change)=\"$event ? masterToggle() : null\"\r\n [checked]=\"rowSelectionModel.hasValue() && isAllSelected()\"\r\n [indeterminate]=\"rowSelectionModel.hasValue() && !isAllSelected()\" *ngIf=\"rowSelectionMode === 'multi'\">\r\n </mat-checkbox>\r\n <!-- <mat-icon *ngIf=\"rowSelectionMode === 'single'\">indeterminate_check_box</mat-icon> -->\r\n </mat-header-cell>\r\n <!-- DATA -->\r\n <mat-cell *matCellDef=\"let row\" class=\"row-checkbox\">\r\n <mat-checkbox (click)=\"$event.stopPropagation()\" (change)=\"onRowSelectionChange($event, row)\"\r\n [checked]=\"rowSelectionModel?.isSelected(row)\">\r\n </mat-checkbox>\r\n </mat-cell>\r\n <!-- FOOTER -->\r\n <mat-footer-cell *matFooterCellDef></mat-footer-cell>\r\n </ng-container>\r\n\r\n <!-- Table Columns -->\r\n <ng-container *ngFor=\"let column of columns; let i = index; trackBy: trackColumn\" [matColumnDef]=\"column.name\"\r\n [sticky]=\"column.sticky === 'start' ? true : false\" [stickyEnd]=\"column.sticky === 'end' ? true : false\">\r\n <!-- HEADER -->\r\n <mat-header-cell *matHeaderCellDef cdkDrag [cdkDragDisabled]=\"column?.draggable === false\"\r\n cdkDragBoundary=\"mat-header-row\" cdkDropListLockAxis=\"x\" [ngClass]=\"headerClass(column)\"\r\n [cdkDragData]=\"{name: column.name, columIndex: i}\" [ngStyle]=\"column.style\"\r\n [class.active-resize]=\"resizeColumn.columnIndex == i\" cdkDragBoundary=\"mat-header-row\">\r\n <!-- class=\"left-resize-handler\" -->\r\n <div class=\"resize-handler\"\r\n [ngClass]=\"{'left-resize-handler': tableSetting.direction === 'ltr', 'right-resize-handler': tableSetting.direction === 'rtl'}\"\r\n (mousedown)=\"onResizeColumn($event, i, 'left')\"></div>\r\n <header-filter [field]=\"column\" (filterChanged)=\"filter_onChanged(column, $event)\"\r\n [filters]=\"tvsDataSource.getFilter(column.name)\">\r\n <mat-icon class=\"column-icon\" [ngStyle]=\"{ 'color': column?.iconColor }\">{{column?.icon}}</mat-icon>\r\n <mat-icon *ngIf=\"column?.draggable != false\" class=\"drag-indicator\" cdkDragHandle>drag_indicator</mat-icon>\r\n <div mat-sort-header [matTooltip]=\"column.header\" matTooltipClass=\"cell-tooltip\"\r\n [disabled]=\"column.sort === 'none'\" class=\"header-caption\">{{ column.header }}</div>\r\n </header-filter>\r\n <!-- class=\"right-resize-handler\" -->\r\n <div class=\"resize-handler\"\r\n [ngClass]=\"{'right-resize-handler': tableSetting.direction === 'ltr', 'left-resize-handler': tableSetting.direction === 'rtl'}\"\r\n (mousedown)=\"onResizeColumn($event, i, 'right')\"></div>\r\n </mat-header-cell>\r\n <!-- DATA -->\r\n <mat-cell *matCellDef=\"let row;\" #cell (mouseenter)=\"tooltip_onChanged(column, row, cell,true)\"\r\n (mouseleave)=\"tooltip_onChanged(column, row, cell,false)\" [class]=\"row[column.cellClass]\"\r\n (click)=\"onCellClick($event, row, column)\" [ngClass]=\"cellClass(row?.option, column)\"\r\n [ngStyle]=\"cellStyle(row?.option, column)\" (contextmenu)=\"onContextMenu($event, column, row)\">\r\n <label *ngIf=\"!column.dynamicCellComponent\" (click)=\"onLabelClick($event, row, column)\"\r\n [class.rtl-cell]=\"direction === 'rtl'\" [class.ltr-cell]=\"direction === 'ltr'\" [ngStyle]=\"ellipsis(column)\"\r\n class=\"label-cell\">{{row[column.name]}}</label>\r\n <ng-container *ngIf=\"column.dynamicCellComponent\" dynamicCell [component]=\"column.dynamicCellComponent\"\r\n [column]=\"column\" [row]=\"row\" [onRowEvent]=\"onRowEvent\">\r\n </ng-container>\r\n </mat-cell>\r\n <!-- FOOTER -->\r\n <mat-footer-cell *matFooterCellDef [ngStyle]=\"column.style\">\r\n <div *ngFor=\"let footer of column?.footer\" class=\"footer-column\">\r\n <div [style.height.px]=\"footerHeight\" class=\"footer-row\">\r\n <span> {{footer.aggregateText}}</span>\r\n </div>\r\n </div>\r\n </mat-footer-cell>\r\n </ng-container>\r\n\r\n <ng-container matColumnDef=\"progress\">\r\n <mat-header-cell *matHeaderCellDef [attr.colspan]=\"displayedColumns.length\">\r\n <mat-progress-bar mode=\"indeterminate\" [class.show]=\"pending\">\r\n </mat-progress-bar>\r\n </mat-header-cell>\r\n </ng-container>\r\n\r\n <!-- Expanded Content Column - The detail row is made up of Dynamic Cell -->\r\n <ng-container *ngIf=\"expandColumn.length > 0\" matColumnDef=\"expandedDetail\">\r\n <td mat-cell *matCellDef=\"let row\" [attr.colspan]=\"displayedColumns.length\" class=\"expanded-detail-cell\">\r\n <div class=\"expanded-detail\" [@detailExpand]=\"row == expandedElement ? 'expanded' : 'collapsed'\">\r\n <ng-container dynamicCell [component]=\"expandComponent\" [row]=\"row\" [onRowEvent]=\"onRowEvent\">\r\n </ng-container>\r\n </div>\r\n </td>\r\n </ng-container>\r\n\r\n <!-- Table Menu[ Sort, Visible, Export] -->\r\n <ng-container matColumnDef=\"table-menu\" [stickyEnd]=\"true\" *ngIf=\"setting?.visibleTableMenu !== false\">\r\n <mat-header-cell *matHeaderCellDef class=\"table-menu\">\r\n <table-menu [(tableSetting)]=\"tableSetting\" (menuActionChange)=\"tableMenuActionChange($event)\"></table-menu>\r\n </mat-header-cell>\r\n <mat-cell *matCellDef=\"let row\" class=\"table-menu\">\r\n <row-menu *ngIf=\"rowContextMenuItems && rowContextMenuItems.length > 0\" [rowActionMenu]=\"row?.actionMenu\"\r\n [actionMenus]=\"rowContextMenuItems\" [tableSetting]=\"tableSetting\"\r\n (rowActionChange)=\"rowMenuActionChange($event, row)\"></row-menu>\r\n </mat-cell>\r\n </ng-container>\r\n\r\n <!-- Row Table[Header, Data, Footer] -->\r\n <mat-row *matRowDef=\"let row; columns: displayedColumns;\" (dblclick)=\"onRowDblClick($event, row)\"\r\n (click)=\"onRowClick($event, row)\" [style.height.px]=\"rowHeight\" class=\"table-row\" [ngClass]=\"row?.option?.class\"\r\n [ngStyle]=\"rowStyle(row)\" [class.expanded-row]=\"expandedElement === row\"\r\n [class.row-selection]=\"rowSelectionModel ? rowSelectionModel.isSelected(row) : false\"\r\n (contextmenu)=\"onContextMenu($event, null, row)\">\r\n </mat-row>\r\n\r\n <ng-container *ngIf=\"expandColumn.length > 0\">\r\n <tr mat-row *matRowDef=\"let expandRow; columns: expandColumn\" class=\"detail-row\"></tr>\r\n </ng-container>\r\n\r\n <mat-header-row class=\"header\" [@tableAnimation] *matHeaderRowDef=\"displayedColumns; sticky: sticky\"\r\n [style.top.px]=\"inverseOfTranslation\"></mat-header-row>\r\n <ng-container *ngIf=\"displayedFooter.length > 0\">\r\n <mat-footer-row class=\"footer\" [@tableAnimation] *matFooterRowDef=\"displayedFooter;\"></mat-footer-row>\r\n </ng-container>\r\n <mat-header-row class=\"progress\" *matHeaderRowDef=\"progressColumn; sticky: sticky\"\r\n [style.top.px]=\"inverseOfTranslation + headerHeight - 5\"></mat-header-row>\r\n </mat-table>\r\n</cdk-virtual-scroll-viewport>\r\n<pagination\r\n *ngIf=\"pagingMode !== 'none'\"\r\n [dir]=\"'ltr'\"\r\n [pageIndex]=\"pagination?.pageIndex\"\r\n [pageSize]=\"pagination?.pageSize\"\r\n [pageSizeOptions]=\"pagination?.pageSizeOptions\"\r\n [length]=\"pagination?.length\"\r\n (page)=\"pagination_onChange($event)\">\r\n</pagination>\r\n<!-- <ng-content></ng-content> -->\r\n<ng-container *ngIf=\"showNoData && init === true\">\r\n <div class=\"no-records\" *ngIf=\"tvsDataSource.data.length == 0\">\r\n {{ languagePack?.tableLabels?.NoData }}\r\n <br>\r\n <button mat-icon-button type=\"button\" *ngIf=\"showReload === true\" color=\"primary\" (click)=\"reload_onClick()\">\r\n <mat-icon>autorenew</mat-icon>\r\n </button>\r\n </div>\r\n</ng-container>\r\n\r\n<!-- Context Menu -->\r\n<div style=\"visibility: hidden; position: fixed\" [style.left]=\"contextMenuPosition.x\"\r\n [style.top]=\"contextMenuPosition.y\" [matMenuTriggerFor]=\"contextMenu\">\r\n</div>\r\n<mat-menu #contextMenu=\"matMenu\">\r\n <ng-template matMenuContent let-item=\"item\">\r\n <ng-container *ngFor=\"let menu of contextMenuItems\">\r\n <button mat-button type=\"button\" [class.ltr-menu]=\"tableSetting.direction === 'rtl'\" [color]=\"menu.color\"\r\n class=\"button-menu\" [disabled]=\"menu.disabled\" (click)=\"onContextMenuItemClick(menu)\">\r\n <mat-icon>{{menu.icon}}</mat-icon>\r\n <span [class.text-align-right]=\"tableSetting.direction === 'rtl'\" class=\"text-align-left\">{{menu.text}}</span>\r\n </button>\r\n <mat-divider *ngIf=\"menu.divider === true\"></mat-divider>\r\n </ng-container>\r\n </ng-template>\r\n</mat-menu>\r\n",
animations: [tableAnimation, expandAnimation],
changeDetection: ChangeDetectionStrategy.OnPush,
styles: ["@media print{.print-preview{background-color:#fff;position:fixed;width:100%;height:auto;z-index:99999999;margin:0;padding:0;top:0;left:0;overflow:visible;display:block}}.disable-backdrop-click .cdk-overlay-backdrop.cdk-overlay-transparent-backdrop.cdk-overlay-backdrop-showing{pointer-events:none}:host{display:flex;flex-direction:column;table-layout:fixed;min-height:200px;position:relative;overflow:auto;transition:.3s cubic-bezier(.46,-.72,.46,1.54);background-color:#f3f3f3;border:2px #009688}::ng-deep .cdk-virtual-scroll-content-wrapper{left:auto!important}::ng-deep .mat-menu-panel{min-height:48px}.label-cell{width:100%}mat-cell:first-of-type,mat-header-cell:first-of-type:not(.row-checkbox),mat-footer-cell:first-of-type{padding-left:0!important}.rtl-cell{padding-right:20px}.ltr-cell{padding-left:20px}.viewport{height:calc(100% - 0px)}.viewport-with-pagination{height:calc(100% - 48px)}.table-paginator{position:sticky;bottom:0;display:flex;flex-wrap:wrap;max-height:48px;align-items:center;overflow:hidden;direction:ltr}mat-footer-row,mat-row{min-height:auto!important}mat-row,tr.mat-header-row,mat-footer-row{display:flex;border-width:0;border-bottom-width:1px;border-bottom-color:#d2d2d2;border-style:solid;align-items:center;box-sizing:border-box}mat-cell,mat-footer-cell,mat-header-cell{align-self:stretch;color:inherit;background-color:inherit}.mat-table .row-selection{background-color:#f7f5f5}.mat-table .mat-row:hover{background-color:#fafafa}.mat-table mat-cell{box-sizing:border-box}.mat-header-row.progress{border:none;max-height:4px;min-height:4px;height:0;margin-top:-4px;background-color:transparent!important;border-top:transparent!important;background:transparent!important}.mat-header-row.progress .mat-header-cell{border:0;padding:0}.mat-header-row.progress mat-progress-bar{transition:height .3s,opacity .25s linear}.mat-header-row.progress mat-progress-bar:not(.show){height:0;opacity:0}.no-records{display:flex;align-items:center;top:50%;left:50%;margin:-42px 0 0 -25px;line-height:42px;position:absolute;z-index:1;pointer-events:none}.no-records button{pointer-events:initial}::ng-deep .dmf{min-width:100%}::ng-deep dynamic-mat-table cdk-virtual-scroll-viewport .cdk-virtual-scroll-content-wrapper .mat-table mat-row .mat-cell mat-form-field{max-width:100%}::ng-deep dynamic-mat-table cdk-virtual-scroll-viewport .cdk-virtual-scroll-content-wrapper .mat-table mat-row .mat-cell mat-form-field .mat-form-field-wrapper{padding-bottom:0!important}::ng-deep dynamic-mat-table cdk-virtual-scroll-viewport .cdk-virtual-scroll-content-wrapper .mat-table mat-row .mat-cell mat-form-field ::ng-deep .mat-form-field-underline{bottom:0!important}mat-header-cell:hover .left-resize-handler{height:100%;transition:height .4s ease-out}mat-header-cell:hover .right-resize-handler{height:100%;transition:height .4s ease-out}.resize-handler{display:inline-block;min-width:1px;height:0;position:sticky;cursor:col-resize;border-width:0;z-index:10}.left-resize-handler{left:0;padding-right:10px;margin-right:-10px;border-left:solid 2px #8b8b8b}.right-resize-handler{right:0px;padding-left:10px;margin-left:-10px;border-right:solid 2px #8b8b8b}.active-resize{background-color:#f5f5f566}.ltr-menu span{float:left}.button-menu{width:100%;line-height:48px}.button-menu::ng-deep .mat-button-wrapper{display:flex}.button-menu::ng-deep .mat-button-wrapper span{display:inline-block;width:100%;text-align:left}.button-menu::ng-deep .mat-button-wrapper mat-icon{line-height:48px;height:48px;margin:0 5px}mat-button-wrapper .button-menu{display:inline-block!important}.text-align-left{text-align:left!important}.text-align-right{text-align:right!important}.mat-menu-panel{min-height:unset!important}.mat-sort-header-arrow{margin:0 6px!important}cdk-virtual-scroll-viewport{min-height:100px;height:inherit;overflow:auto}.header-caption{font-weight:bolder;font-size:14px;width:100%}.header{-webkit-user-select:none;-moz-user-select:none;user-select:none;background-color:#fff}.footer{-webkit-user-select:none;-moz-user-select:none;user-select:none;background-color:#fff}.row-checkbox{padding-left:0!important;padding-right:0!important;max-width:46px;min-width:46px}.row-checkbox mat-checkbox{padding:10px}.row-checkbox mat-icon{padding:11px!important}.table-menu{max-width:42px;min-width:0;min-width:initial;padding:0!important;background-color:inherit}:host .mat-header-row>.mat-header-cell:hover .column-icon{opacity:0;transform:translateY(5px);transition:all .2s}.drag-indicator{position:absolute;color:#0000004d;display:flex;opacity:0;transform:translateY(-5px);cursor:pointer;transition-duration:.4s;transition-property:opacity,transform;cursor:move}:host .mat-header-row>.mat-header-cell:hover .drag-indicator{opacity:1;pointer-events:fill;transform:translateY(0)}.drag-indicator:hover{color:#bfc0c0!important}.cdk-drag-preview{color:#000;min-height:55px;border:solid 1px #d4d4d4;background-color:#f5f5f5;box-sizing:border-box;border-radius:4px;box-shadow:0 5px 5px -3px #0003,0 8px 10px 1px #00000024,0 3px 14px 2px #0000001f}.cdk-drag-placeholder{border:dotted 1px #9c9c9c;background-color:#d3d3d3;content:none}.cdk-drag-animating{transition:transform .25s cubic-bezier(0,0,.2,1)}.cdk-drop-list-dragging{transition:transform .25s cubic-bezier(0,0,.2,1)}.detail-row{height:0px;display:inline!important;width:100%}.table-row:not(.expanded-row):hover{background:whitesmoke}.table-row:not(.expanded-row):active{background:#efefef}.table-row mat-cell{border-bottom-width:0}.expanded-detail{overflow:hidden;display:flex;background-color:#fafafa}.expanded-detail-cell{display:block;border-width:0;padding:0!important;width:100%;z-index:2}::ng-deep .cell-tooltip{padding:8px;font-size:12px;min-width:100px;text-align:center;margin-right:-20px}.tooltip{position:relative;display:inline-block;border-bottom:1px dotted black}.tooltip .tooltiptext{visibility:hidden;min-width:120px;background-color:#e91e63;color:#fff;text-align:center;border-radius:6px;padding:5px 0;position:absolute;z-index:1;left:0;top:43px;margin-left:-86%}.tooltip:hover .tooltiptext{visibility:visible;white-space:pre}::ng-deep .mat-footer-cell{flex-direction:column!important}.footer-column{display:flex;flex-direction:column}.footer-column .footer-row{display:flex;flex-direction:row}.footer-column .footer-row span{display:inherit;align-items:center}\n"]
},] }
];
/**
* @type {function(): !Array<(null|{
* type: ?,
* decorators: (undefined|!Array<{type: !Function, args: (undefined|!Array<?>)}>),
* })>}
* @nocollapse
*/
DynamicMatTableComponent.ctorParameters = () => [
{ type: MatDialog },
{ type: Renderer2 },
{ type: TableIntl },
{ type: TableService },
{ type: ChangeDetectorRef },
{ type: Overlay },
{ type: OverlayContainer },
{ type: OverlayPositionBuilder },
{ type: TableSetting }
];
/** @type {!Object<string, !Array<{type: !Function, args: (undefined|!Array<?>)}>>} */
DynamicMatTableComponent.propDecorators = {
tbl: [{ type: ViewChild, args: ["tbl", { static: true },] }],
setting: [{ type: Input }],
height: [{ type: HostBinding, args: ["style.height.px",] }],
tooltipRef: [{ type: ViewChild, args: ["tooltip",] }],
contextMenu: [{ type: ViewChild, args: [MatMenuTrigger,] }],
printRef: [{ type: ViewChild, args: ["printRef", { static: true },] }],
printContentRef: [{ type: ViewChild, args: ["printContentRef", { static: true },] }],
headerFilterList: [{ type: ContentChildren, args: [HeaderFilterComponent,] }]
};
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZHluYW1pYy1tYXQtdGFibGUuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvZHluYW1pYy1tYXQtdGFibGUvc3JjL2xpYi9keW5hbWljLW1hdC10YWJsZS9keW5hbWljLW1hdC10YWJsZS5jb21wb25lbnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUNMLFNBQVMsRUFHVCxTQUFTLEVBQ1QsVUFBVSxFQUNWLFNBQVMsRUFDVCxXQUFXLEVBQ1gsU0FBUyxFQUNULGlCQUFpQixFQUNqQixLQUFLLEVBRUwsZUFBZSxFQUNmLFFBQVEsRUFFUixXQUFXLEVBQ1gsdUJBQXVCLEdBQ3hCLE1BQU0sZUFBZSxDQUFDO0FBQ3ZCLE9BQU8sRUFBRSxrQkFBa0IsRUFBRSxNQUFNLCtCQUErQixDQUFDO0FBQ25FLE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSw2QkFBNkIsQ0FBQztBQUczRCxPQUFPLEVBQUUscUJBQXFCLEVBQUUsTUFBTSw2Q0FBNkMsQ0FBQztBQUNwRixPQUFPLEVBQUUsU0FBUyxFQUFFLE1BQU0sMEJBQTBCLENBQUM7QUFDckQsT0FBTyxFQUNMLE9BQU8sRUFDUCxVQUFVLEVBQ1YsS0FBSyxFQUNMLE9BQU8sRUFDUCxLQUFLLEVBQ0wsT0FBTyxFQUNQLEtBQUssR0FDTixNQUFNLHFCQUFxQixDQUFDO0FBQzdCLE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSw4QkFBOEIsQ0FBQztBQUM1RCxPQUFPLEVBQUUsU0FBUyxFQUFFLE1BQU0sNkJBQTZCLENBQUM7QUFFeEQsT0FBTyxFQUdMLGVBQWUsR0FDaEIsTUFBTSx3QkFBd0IsQ0FBQztBQUNoQyxPQUFPLEVBQVcsaUJBQWlCLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDM0QsT0FBTyxFQUFlLFlBQVksRUFBRSxNQUFNLCtCQUErQixDQUFDO0FBQzFFLE9BQU8sRUFBRSxLQUFLLEVBQUUsTUFBTSxFQUFFLE1BQU0sZ0JB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