med-table
Version:
Wrapper over table of primeng library for Ministry of Health
918 lines (885 loc) • 77.1 kB
JavaScript
import * as i1 from 'med-dynamic-form';
import { PATTERN_TYPES, FIELD_TYPES, MedDynamicFormModule } from 'med-dynamic-form';
export { FIELD_TYPES, PATTERN_TYPES } from 'med-dynamic-form';
import * as i0 from '@angular/core';
import { Directive, Input, Injectable, Component, ContentChildren, ViewChild, EventEmitter, Output, forwardRef, NgModule } from '@angular/core';
import { get, isEqual, set } from 'lodash';
import * as i1$1 from 'primeng/api';
import * as XLSX from 'xlsx-js-style';
import * as i2 from 'primeng/table';
import { TableModule } from 'primeng/table';
import * as i10 from '@angular/common';
import * as i3 from 'primeng/multiselect';
import { MultiSelectModule } from 'primeng/multiselect';
import * as i5 from '@angular/forms';
import { NG_VALUE_ACCESSOR, FormGroup, FormsModule, ReactiveFormsModule } from '@angular/forms';
import * as i1$2 from 'primeng/calendar';
import { CalendarModule } from 'primeng/calendar';
import * as i11 from 'primeng/inputtext';
import { InputTextModule } from 'primeng/inputtext';
import * as i12 from 'primeng/button';
import { ButtonModule } from 'primeng/button';
import { BrowserModule } from '@angular/platform-browser';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
var CELL_TYPES;
(function (CELL_TYPES) {
CELL_TYPES["TEXT"] = "text";
CELL_TYPES["LINK"] = "link";
})(CELL_TYPES || (CELL_TYPES = {}));
var FILTER_TYPES;
(function (FILTER_TYPES) {
FILTER_TYPES["TEXT"] = "text";
FILTER_TYPES["SELECT"] = "select";
FILTER_TYPES["DATE"] = "date";
FILTER_TYPES["CHECKBOX"] = "checkbox";
})(FILTER_TYPES || (FILTER_TYPES = {}));
class MedTemplateDirective {
constructor(template) {
this.template = template;
}
getType() {
return this.name;
}
}
MedTemplateDirective.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.2.7", ngImport: i0, type: MedTemplateDirective, deps: [{ token: i0.TemplateRef }], target: i0.ɵɵFactoryTarget.Directive });
MedTemplateDirective.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "12.0.0", version: "13.2.7", type: MedTemplateDirective, selector: "[mTemplate]", inputs: { type: "type", name: ["mTemplate", "name"] }, ngImport: i0 });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.2.7", ngImport: i0, type: MedTemplateDirective, decorators: [{
type: Directive,
args: [{
selector: '[mTemplate]'
}]
}], ctorParameters: function () { return [{ type: i0.TemplateRef }]; }, propDecorators: { type: [{
type: Input
}], name: [{
type: Input,
args: ['mTemplate']
}] } });
class MedTableService {
constructor(dynamicFormService) {
this.dynamicFormService = dynamicFormService;
this._filters = {};
this._filterSelectData = {};
this._data = [];
}
setFilterSelectData(data, key) {
this._filterSelectData[key] = data;
}
getFilterSelectData(key) {
return this._filterSelectData[key] || [];
}
setSelectData(data, key) {
this.dynamicFormService.setSelectData(data, key);
}
setDatalist(data, key) {
this.dynamicFormService.setDatalist(data, key);
}
get filters() {
return this._filters;
}
set filters(data) {
this._filters = data;
}
get data() {
return this._data;
}
set data(data) {
this._data = data;
}
}
MedTableService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.2.7", ngImport: i0, type: MedTableService, deps: [{ token: i1.MedDynamicFormService }], target: i0.ɵɵFactoryTarget.Injectable });
MedTableService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "13.2.7", ngImport: i0, type: MedTableService, providedIn: 'root' });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.2.7", ngImport: i0, type: MedTableService, decorators: [{
type: Injectable,
args: [{
providedIn: 'root'
}]
}], ctorParameters: function () { return [{ type: i1.MedDynamicFormService }]; } });
const APP_SELECTOR = 'med-table';
const SELECTOR_AFTER_WEB_COMPONENT = 'div'; // web component doesn't have a height
const FOOTER_SELECTOR = 'body footer';
const TABLE_SELECTOR = `${APP_SELECTOR} p-table .p-datatable-wrapper`;
const PAGINATOR_SELECTOR = `${APP_SELECTOR} p-paginator ${SELECTOR_AFTER_WEB_COMPONENT}`;
const UP_SCROLL_SELECTOR = `${APP_SELECTOR} .med-table__up-scroll`;
class StickyHeader {
/**
* should call in "ngAfterViewInit" hook
*/
get tableHeight() {
const MARGINS = 20; // 20px margin app in prod
const contentHeight = this.headerHeight() + this.footerHeight()
+ this.paginatorHeight() + this.upScrollHeight() + MARGINS;
return `calc(100vh - ${contentHeight}px)`;
}
headerHeight() {
const app = document.querySelector(TABLE_SELECTOR);
if (!app)
return 0;
return app.getBoundingClientRect().top;
}
paginatorHeight() {
return this.getElementHeight(PAGINATOR_SELECTOR);
}
footerHeight() {
return this.getElementHeight(FOOTER_SELECTOR);
}
upScrollHeight() {
return this.getElementHeight(UP_SCROLL_SELECTOR);
}
getElementHeight(selector) {
const block = document.querySelector(selector);
if (!block)
return 0;
return block.offsetHeight;
}
}
class TemplatesMixin {
ngAfterContentInit() {
this.templates.forEach((item) => {
switch (item.getType()) {
case 'toolbar':
this.toolbarTemplate = item.template;
break;
case 'caption':
this.captionTemplate = item.template;
break;
case 'tableHead':
this.tableHeadTemplate = item.template;
break;
case 'tableData':
this.tableDataTemplate = item.template;
break;
case 'paginator':
this.paginatorTemplate = item.template;
break;
case 'rowExpansion':
this.rowExpansion = item.template;
break;
}
});
}
}
TemplatesMixin.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.2.7", ngImport: i0, type: TemplatesMixin, deps: [], target: i0.ɵɵFactoryTarget.Component });
TemplatesMixin.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.2.7", type: TemplatesMixin, selector: "ng-component", queries: [{ propertyName: "templates", predicate: MedTemplateDirective }], ngImport: i0, template: '', isInline: true });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.2.7", ngImport: i0, type: TemplatesMixin, decorators: [{
type: Component,
args: [{
template: '',
}]
}], propDecorators: { templates: [{
type: ContentChildren,
args: [MedTemplateDirective]
}] } });
const PRIMENG_TRANSLATIONS = {
'dayNames': ['Неділя', 'Понеділок', 'Вівторок', 'Середа', 'Четвер', 'П\'ятниця', 'Субота'],
'dayNamesShort': ['Нд', 'Пн', 'Вт', 'Ср', 'Чт', 'Пт', 'Сб'],
'dayNamesMin': ['Нд', 'Пн', 'Вт', 'Ср', 'Чт', 'Пт', 'Сб'],
'monthNames': ['Січень', 'Лютий', 'Березень', 'Квітень', 'Травень', 'Червень', 'Липень', 'Серпень', 'Вересень', 'Жовтень', 'Листопад', 'Грудень'],
'monthNamesShort': ['Січ.', 'Лют.', 'Бер.', 'Квіт.', 'Трав.', 'Черв.', 'Лип.', 'Серп.', 'Вер.', 'Жовт.', 'Лис.', 'Гру.'],
};
class FilterMethods {
static dateRangeHandler(value, filter) {
const END_DATE = { HOURS: 23, MINUTES: 59 };
const [startDate, endDate] = filter || [];
if (!startDate)
return true;
if (!value)
return false;
const currentDate = new Date(value).getTime();
if (endDate) {
return startDate.getTime() <= currentDate && currentDate < endDate.setHours(END_DATE.HOURS, END_DATE.MINUTES);
}
return startDate.getTime() <= currentDate;
}
static selectHandler(value, filter) {
return !filter ? true : filter.includes(value || '');
}
static checkboxHandler(value, filter) {
if (filter === null) {
return true;
}
return Boolean(value) === filter;
}
static textHandler(value, filter) {
const regexp = new RegExp(`${filter?.trim()}`, 'i');
return regexp.test(value || '');
}
}
class PrimengConfigMixin extends TemplatesMixin {
constructor(primeConfig, filterService) {
super();
this.primeConfig = primeConfig;
this.filterService = filterService;
}
ngOnInit() {
this.primeConfig.setTranslation(PRIMENG_TRANSLATIONS);
this.filterService.register('custom-contains', FilterMethods.textHandler);
}
}
PrimengConfigMixin.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.2.7", ngImport: i0, type: PrimengConfigMixin, deps: [{ token: i1$1.PrimeNGConfig }, { token: i1$1.FilterService }], target: i0.ɵɵFactoryTarget.Component });
PrimengConfigMixin.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.2.7", type: PrimengConfigMixin, selector: "ng-component", usesInheritance: true, ngImport: i0, template: '', isInline: true });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.2.7", ngImport: i0, type: PrimengConfigMixin, decorators: [{
type: Component,
args: [{
template: '',
}]
}], ctorParameters: function () { return [{ type: i1$1.PrimeNGConfig }, { type: i1$1.FilterService }]; } });
const CONFIG_KEY_CHILDREN = 'children';
class CellConfigsFactory {
build(list) {
return this.flatChildren(list).map(el => this.cellBuilder(el));
}
flatChildren(list) {
const newList = list.map(el => el.children ? el.children : el).flat();
const hasChildren = newList.some(el => el.children);
if (hasChildren) {
return this.flatChildren(newList);
}
return newList;
}
cellBuilder(el) {
return {
...el,
key: el.key || '',
children: undefined,
};
}
}
const DEFAULT_TABLE_SETTINGS = {
rows: 25,
lazy: false,
sticky: true,
filterDelay: 0,
totalRecords: 0,
paginator: true,
scrollHeight: 'flex',
colMinWidth: '15rem',
colMaxWidth: '20rem',
expandedDataKey: '',
doubleScrollbar: false,
showCurrentPageReport: true,
showGlobalSearchFilter: true,
emptyMessage: 'Дані відсутні.',
rowsPerPageOptions: [10, 25, 50, 100],
currentPageReportTemplate: 'Показано {first} – {last} із {totalRecords} записів',
};
const FONTS = {
TIMES: 'Times New Roman',
};
const FONT_SIZES = {
SMALL: 12,
MEDIUM: 14,
LARGE: 16,
EXTRA_LARGE: 18,
};
const CELL_TYPE_STRING = 's';
const DEFAULT_CELL_STYLE = {
size: FONT_SIZES.SMALL,
bold: false,
};
class CellBuilder {
createEmptyCell() {
return this.createTextCell('');
}
createTextCell(v, style) {
const { size, bold } = style || DEFAULT_CELL_STYLE;
return {
v,
t: CELL_TYPE_STRING,
s: {
font: {
name: FONTS.TIMES,
sz: size,
bold,
},
alignment: {
wrapText: true,
vertical: 'top',
},
},
};
}
createLinkCell(v, link) {
return {
v,
t: CELL_TYPE_STRING,
l: { Target: link },
s: {
font: {
name: FONTS.TIMES,
sz: FONT_SIZES.SMALL,
underline: true,
color: {
rgb: '0563c1',
},
},
alignment: {
wrapText: true,
vertical: 'top',
},
},
};
}
}
const STRING = {
EMPTY: '',
SPACE: ' ',
DOT: '.',
ZERO: '0',
HASHTAG: '#',
SEMICOLON: ';',
HYPHEN: '–',
DASH: '-',
LINE_BREAK: '\n',
DELIMITER: {
HYPHEN_WITH_SPACE: ' – ',
COMMA: ', ',
},
};
const DEFAULT_VIEW_HANDLER = (data) => data;
class RowBuilder {
constructor() {
this.cellBuilder = new CellBuilder();
}
createTableRow(config, row) {
return config.map((item) => this.cellBuilder.createTextCell(this.getField(row, item)));
}
getField(data, config) {
const { key, sortKey, defaultValue = STRING.HYPHEN, viewHandler = DEFAULT_VIEW_HANDLER } = config;
const field = viewHandler(get(data, sortKey || key));
return field || defaultValue;
}
}
class WorkSheetSettings {
constructor() {
this._rowIndex = 0;
this._merges = [];
}
get merges() {
return this._merges;
}
updateRowIndex(count) {
this._rowIndex += count || 1;
}
addColMerge(start, end) {
// s - start, e - end; r - row, c - column
this._merges.push({
s: { r: this._rowIndex, c: start },
e: { r: this._rowIndex, c: end },
});
}
addRowMerge(count, colIndex) {
// s - start, e - end; r - row, c - column
this._merges.push({
s: { r: this._rowIndex, c: colIndex },
e: { r: this._rowIndex + (count - 1), c: colIndex },
});
}
}
const isExist = (value) => value !== undefined && value !== null && value !== '' || Array.isArray(value) && value.length;
const deepClone = (data) => JSON.parse(JSON.stringify(data));
const getMaxDeepKeyLevel = (data, key, deep = 1) => {
const STEP = 1;
const levels = data.map(({ [key]: prop }) => prop ? getMaxDeepKeyLevel(prop, key, deep + STEP) : deep);
return Math.max(...levels);
};
const getNestedList = (data, key, deep) => {
const STEP = 1;
if (!deep)
return data;
const mapHandler = (data) => data.map(el => el ? el[key] : el).flat(deep);
return deep - STEP ? mapHandler(getNestedList(data, key, deep - STEP)) : mapHandler(data);
};
const getColspanByKey = (column, key) => {
const ONE_COL = 1;
const { [key]: prop } = column;
if (!prop || !prop.length)
return ONE_COL;
let total = 0;
prop.forEach(el => {
total += el[key] ? getColspanByKey(el, key) : ONE_COL;
});
return total;
};
const getRowspanByLevelAndKey = (data, key, deepLevel, currentLevel) => {
const DELTA = 1;
const { [key]: prop = [] } = data;
const levelsToDown = getMaxDeepKeyLevel(prop, key);
const emptyRows = !currentLevel ? deepLevel - (levelsToDown + DELTA) : 0;
if (!isFinite(levelsToDown))
return deepLevel - currentLevel;
return deepLevel - (levelsToDown + currentLevel + emptyRows);
};
const getObjectsByLevel = (list, level, childKey) => {
if (!level)
return list;
const newList = list.map(el => el[childKey] ? el[childKey] : el).flat();
const hasChildren = newList.some(el => el[childKey]);
if (hasChildren) {
return getObjectsByLevel(newList, --level, childKey);
}
return newList;
};
const getColumnIndex = (list, obj, childKey) => {
const index = list.findIndex((el) => isEqual(obj, el));
if (index < 0)
return 0;
const elementsBeforeCurrent = list.slice(0, index);
return elementsBeforeCurrent
.map(({ [childKey]: children }) => children ? children.length : 1)
.reduce((acc, cur) => acc + cur, 0);
};
const createArrayByNumber = (length) => Array(length).fill(0).map((x, i) => i);
class TableHeaderBuilder {
constructor(sheetSettings, columnsConfig) {
this.sheetSettings = sheetSettings;
this.columnsConfig = columnsConfig;
this.cellBuilder = new CellBuilder();
}
get maxDeepKeyLevel() {
return getMaxDeepKeyLevel(this.columnsConfig, CONFIG_KEY_CHILDREN);
}
get tableHeadLevels() {
return createArrayByNumber(this.maxDeepKeyLevel);
}
getHeaderRows() {
return this.tableHeadLevels.map((level, index) => {
if (index)
this.sheetSettings.updateRowIndex();
const allColumnsBeforeLevel = this.getAllColumnsBeforeLevel(level);
const visibleColumns = this.getVisibleColumns(level);
return allColumnsBeforeLevel.map((column, index) => {
const cols = [];
const range = this.getColspan(column);
const isVisibleColumn = Boolean(visibleColumns.find(col => isEqual(col, column)));
const startIndex = getColumnIndex(allColumnsBeforeLevel, column, CONFIG_KEY_CHILDREN);
this.sheetSettings.addColMerge(startIndex, startIndex + range);
if (isVisibleColumn) {
cols.push(this.cellBuilder.createTextCell(column.label, { bold: true }));
}
else {
cols.push(this.cellBuilder.createEmptyCell());
}
createArrayByNumber(range).map(() => {
cols.push(this.cellBuilder.createEmptyCell());
});
return cols;
}).flat();
});
}
getAllColumnsBeforeLevel(level) {
return getObjectsByLevel(this.columnsConfig, level, CONFIG_KEY_CHILDREN);
}
getVisibleColumns(level) {
return getNestedList(this.columnsConfig, CONFIG_KEY_CHILDREN, level).filter(Boolean);
}
getColspan(column) {
const DELTA = 1;
return getColspanByKey(column, CONFIG_KEY_CHILDREN) - DELTA;
}
}
class SheetsGenerator {
constructor(data, config) {
this.data = data;
this.rowBuilder = new RowBuilder();
this.settings = new WorkSheetSettings();
const filteredColumns = this.hidePrivateFields(config);
this.headerBuilder = new TableHeaderBuilder(this.settings, filteredColumns);
this.dataRowConfig = new CellConfigsFactory().build(filteredColumns);
}
generate(fileName = 'document') {
const wb = XLSX.utils.book_new();
const ws = XLSX.utils.aoa_to_sheet([
this.headerBuilder.getHeaderRows(),
this.createTableData(),
].flat());
ws['!merges'] = this.settings.merges;
XLSX.utils.book_append_sheet(wb, ws);
XLSX.writeFile(wb, `${fileName}.xlsx`);
}
hidePrivateFields(list) {
return list.filter(({ hideExport }) => !hideExport).map(column => {
if (column.children) {
return {
...column,
children: this.hidePrivateFields(column.children),
};
}
return column;
});
}
createTableData() {
return this.data.map(row => this.rowBuilder.createTableRow(this.dataRowConfig, row));
}
}
const DEFAULT_HANDLER = (data) => data;
class TableCell {
constructor() {
this._item = {};
this._config = { key: '', label: '' };
}
get fieldData() {
return this.getValue(this._item, this._config.key);
}
get previewData() {
const { viewHandler = DEFAULT_HANDLER, key, sortKey } = this._config;
const value = this.getValue(this._item, sortKey || key);
return value ? viewHandler(value) : this.defaultValue;
}
get defaultValue() {
const { defaultValue, filterType } = this._config;
if (defaultValue !== undefined)
return defaultValue;
if (filterType === FILTER_TYPES.CHECKBOX)
return 0;
return STRING.HYPHEN;
}
getValue(data, key) {
return get(data, key) || '';
}
setItem(data) {
this._item = data;
}
setConfig(config) {
this._config = config;
}
}
const filterMethodsMap = new Map()
.set(FILTER_TYPES.TEXT, FilterMethods.textHandler)
.set(FILTER_TYPES.SELECT, FilterMethods.selectHandler)
.set(FILTER_TYPES.CHECKBOX, FilterMethods.checkboxHandler)
.set(FILTER_TYPES.DATE, FilterMethods.dateRangeHandler);
class FilterDataHandler {
constructor() {
this._data = [];
this._config = [];
}
filter(filters, exitKey) {
return this._data.filter(row => this._config.every((col) => {
const key = col.sortKey || col.key;
const { value } = filters[key] || { matchMode: '' };
if (this.isEmptyValue(value, col.filterType) || exitKey === key)
return true;
const filterType = col.filterType || FILTER_TYPES.TEXT;
const tableCell = new TableCell();
tableCell.setItem(row);
tableCell.setConfig(col);
const filterFn = filterMethodsMap.get(filterType);
return filterFn ? filterFn(tableCell.previewData, value) : true;
}));
}
setData(data) {
this._data = data;
}
setConfig(config) {
this._config = config;
}
isEmptyValue(value, filterType) {
if (filterType === FILTER_TYPES.SELECT || filterType === FILTER_TYPES.DATE) {
return !value || Array.isArray(value) && !value.length;
}
if (filterType === FILTER_TYPES.CHECKBOX) {
return false;
}
return !value;
}
}
class TableHeadCellComponent {
get isEmptyTemplate() {
// TODO should show default value if slot "template" is empty
const { nativeElement } = this.contentRef || {};
return !(nativeElement && nativeElement.innerText);
}
}
TableHeadCellComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.2.7", ngImport: i0, type: TableHeadCellComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
TableHeadCellComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.2.7", type: TableHeadCellComponent, selector: "table-head-cell", inputs: { config: "config", template: "template" }, viewQueries: [{ propertyName: "contentRef", first: true, predicate: ["contentRef"], descendants: true }], ngImport: i0, template: "<span>\n <span #contentRef>\n <ng-container *ngTemplateOutlet=\"\n template || defaultTemplate;\n context: { $implicit: config }\"\n ></ng-container>\n </span>\n\n <ng-container\n *ngIf=\"isEmptyTemplate\"\n [ngTemplateOutlet]=\"defaultTemplate\"\n ></ng-container>\n</span>\n\n<p-sortIcon\n *ngIf=\"config.label && config.key && !config.hideSortIcon\"\n [field]=\"config.sortKey || config.key\"\n></p-sortIcon>\n\n<ng-template #defaultTemplate>\n {{ config.label }}\n</ng-template>\n", styles: [""], components: [{ type: i2.SortIcon, selector: "p-sortIcon", inputs: ["field"] }], directives: [{ type: i10.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet"] }, { type: i10.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }] });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.2.7", ngImport: i0, type: TableHeadCellComponent, decorators: [{
type: Component,
args: [{ selector: 'table-head-cell', template: "<span>\n <span #contentRef>\n <ng-container *ngTemplateOutlet=\"\n template || defaultTemplate;\n context: { $implicit: config }\"\n ></ng-container>\n </span>\n\n <ng-container\n *ngIf=\"isEmptyTemplate\"\n [ngTemplateOutlet]=\"defaultTemplate\"\n ></ng-container>\n</span>\n\n<p-sortIcon\n *ngIf=\"config.label && config.key && !config.hideSortIcon\"\n [field]=\"config.sortKey || config.key\"\n></p-sortIcon>\n\n<ng-template #defaultTemplate>\n {{ config.label }}\n</ng-template>\n", styles: [""] }]
}], propDecorators: { config: [{
type: Input
}], template: [{
type: Input
}], contentRef: [{
type: ViewChild,
args: ['contentRef']
}] } });
class FilterSelectComponent {
constructor(store, cd) {
this.store = store;
this.cd = cd;
}
get filterSelectOptions() {
if (this.settings.lazy) {
return this.store.getFilterSelectData(this.key) || [];
}
const filteredData = this.filterDataHandler.filter(this.store.filters, this.key);
const options = filteredData.map(obj => get(obj, this.key)).filter(Boolean);
return [...new Set(options)]; // delete duplicates
}
ngAfterViewInit() {
this.cd.detectChanges();
}
onFilter({ filter }) {
const regexp = new RegExp(filter, 'i');
this.selectRef._filteredOptions = this.filterSelectOptions.filter((value) => regexp.test(value));
}
}
FilterSelectComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.2.7", ngImport: i0, type: FilterSelectComponent, deps: [{ token: MedTableService }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
FilterSelectComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.2.7", type: FilterSelectComponent, selector: "filter-select", inputs: { key: "key", settings: "settings", filterDataHandler: "filterDataHandler" }, viewQueries: [{ propertyName: "selectRef", first: true, predicate: ["selectRef"], descendants: true }], ngImport: i0, template: "<p-columnFilter [field]=\"key\" matchMode=\"in\" [showMenu]=\"false\">\n <ng-template pTemplate=\"filter\" let-value let-filter=\"filterCallback\">\n <p-multiSelect\n #selectRef\n placeholder=\"\u0412\u0441\u0456\"\n styleClass=\"filter-select\"\n [ngModel]=\"value\"\n [options]=\"filterSelectOptions\"\n (onChange)=\"filter($event.value)\"\n (onFilter)=\"onFilter($event)\"\n >\n </p-multiSelect>\n </ng-template>\n</p-columnFilter>\n", styles: [":host ::ng-deep .filter-select .p-inputtext{min-width:180px}:host ::ng-deep .filter-select .p-multiselect-items{max-width:360px}:host ::ng-deep .filter-select .p-multiselect-item{white-space:break-spaces}\n"], components: [{ type: i2.ColumnFilter, selector: "p-columnFilter", inputs: ["field", "type", "display", "showMenu", "matchMode", "operator", "showOperator", "showClearButton", "showApplyButton", "showMatchModes", "showAddButton", "hideOnClear", "placeholder", "matchModeOptions", "maxConstraints", "minFractionDigits", "maxFractionDigits", "prefix", "suffix", "locale", "localeMatcher", "currency", "currencyDisplay", "useGrouping"] }, { type: i3.MultiSelect, selector: "p-multiSelect", inputs: ["style", "styleClass", "panelStyle", "panelStyleClass", "inputId", "disabled", "readonly", "group", "filter", "filterPlaceHolder", "filterLocale", "overlayVisible", "tabindex", "appendTo", "dataKey", "name", "label", "ariaLabelledBy", "displaySelectedLabel", "maxSelectedLabels", "selectionLimit", "selectedItemsLabel", "showToggleAll", "emptyFilterMessage", "emptyMessage", "resetFilterOnHide", "dropdownIcon", "optionLabel", "optionValue", "optionDisabled", "optionGroupLabel", "optionGroupChildren", "showHeader", "autoZIndex", "baseZIndex", "filterBy", "virtualScroll", "itemSize", "showTransitionOptions", "hideTransitionOptions", "ariaFilterLabel", "filterMatchMode", "tooltip", "tooltipPosition", "tooltipPositionStyle", "tooltipStyleClass", "autofocusFilter", "display", "autocomplete", "scrollHeight", "defaultLabel", "placeholder", "options", "filterValue"], outputs: ["onChange", "onFilter", "onFocus", "onBlur", "onClick", "onPanelShow", "onPanelHide"] }], directives: [{ type: i1$1.PrimeTemplate, selector: "[pTemplate]", inputs: ["type", "pTemplate"] }, { type: i5.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { type: i5.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }] });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.2.7", ngImport: i0, type: FilterSelectComponent, decorators: [{
type: Component,
args: [{ selector: 'filter-select', template: "<p-columnFilter [field]=\"key\" matchMode=\"in\" [showMenu]=\"false\">\n <ng-template pTemplate=\"filter\" let-value let-filter=\"filterCallback\">\n <p-multiSelect\n #selectRef\n placeholder=\"\u0412\u0441\u0456\"\n styleClass=\"filter-select\"\n [ngModel]=\"value\"\n [options]=\"filterSelectOptions\"\n (onChange)=\"filter($event.value)\"\n (onFilter)=\"onFilter($event)\"\n >\n </p-multiSelect>\n </ng-template>\n</p-columnFilter>\n", styles: [":host ::ng-deep .filter-select .p-inputtext{min-width:180px}:host ::ng-deep .filter-select .p-multiselect-items{max-width:360px}:host ::ng-deep .filter-select .p-multiselect-item{white-space:break-spaces}\n"] }]
}], ctorParameters: function () { return [{ type: MedTableService }, { type: i0.ChangeDetectorRef }]; }, propDecorators: { key: [{
type: Input
}], settings: [{
type: Input
}], filterDataHandler: [{
type: Input
}], selectRef: [{
type: ViewChild,
args: ['selectRef']
}] } });
class FormInputMixin {
constructor() {
this._value = '';
this.leave = new EventEmitter();
this.inputId = '';
}
set value(val) {
this._value = val;
this.onChange(this._value);
}
get value() {
return this._value;
}
ngAfterViewInit() {
if (this.autoFocus) {
setTimeout(() => {
const { nativeElement, el } = this.inputEl;
if (el === undefined) {
return nativeElement.focus();
}
el.nativeElement.querySelector('input').focus();
}, 0);
}
}
onChange(_) { }
writeValue(value) {
this.value = value;
}
registerOnChange(fn) {
this.onChange = fn;
}
registerOnTouched() { }
}
FormInputMixin.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.2.7", ngImport: i0, type: FormInputMixin, deps: [], target: i0.ɵɵFactoryTarget.Component });
FormInputMixin.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.2.7", type: FormInputMixin, selector: "ng-component", inputs: { handler: "handler", autoFocus: "autoFocus", inputId: "inputId", value: "value" }, outputs: { leave: "leave" }, viewQueries: [{ propertyName: "inputEl", first: true, predicate: ["input"], descendants: true }], ngImport: i0, template: '', isInline: true });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.2.7", ngImport: i0, type: FormInputMixin, decorators: [{
type: Component,
args: [{
template: '',
}]
}], propDecorators: { inputEl: [{
type: ViewChild,
args: ['input']
}], leave: [{
type: Output
}], handler: [{
type: Input
}], autoFocus: [{
type: Input
}], inputId: [{
type: Input
}], value: [{
type: Input
}] } });
class DateRangeComponent extends FormInputMixin {
constructor() {
super(...arguments);
this._value = [];
this.select = new EventEmitter();
}
}
DateRangeComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.2.7", ngImport: i0, type: DateRangeComponent, deps: null, target: i0.ɵɵFactoryTarget.Component });
DateRangeComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.2.7", type: DateRangeComponent, selector: "date-range", outputs: { select: "select" }, providers: [{
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => DateRangeComponent),
multi: true
}], usesInheritance: true, ngImport: i0, template: "<p-calendar\n #input\n [touchUI]=\"true\"\n [showIcon]=\"true\"\n [inputId]=\"inputId\"\n [(ngModel)]=\"value\"\n dateFormat=\"dd.mm.yy\"\n selectionMode=\"range\"\n appendTo=\"body\"\n (focusout)=\"leave.emit()\"\n (keydown.enter)=\"leave.emit()\"\n (onClose)=\"select.emit(value)\"\n [panelStyle]=\"{'mim-width': '0', 'max-width': '360px'}\"\n></p-calendar>\n\n", styles: [""], components: [{ type: i1$2.Calendar, selector: "p-calendar", inputs: ["style", "styleClass", "inputStyle", "inputId", "name", "inputStyleClass", "placeholder", "ariaLabelledBy", "iconAriaLabel", "disabled", "dateFormat", "multipleSeparator", "rangeSeparator", "inline", "showOtherMonths", "selectOtherMonths", "showIcon", "icon", "appendTo", "readonlyInput", "shortYearCutoff", "monthNavigator", "yearNavigator", "hourFormat", "timeOnly", "stepHour", "stepMinute", "stepSecond", "showSeconds", "required", "showOnFocus", "showWeek", "dataType", "selectionMode", "maxDateCount", "showButtonBar", "todayButtonStyleClass", "clearButtonStyleClass", "autoZIndex", "baseZIndex", "panelStyleClass", "panelStyle", "keepInvalid", "hideOnDateTimeSelect", "touchUI", "timeSeparator", "focusTrap", "showTransitionOptions", "hideTransitionOptions", "tabindex", "view", "defaultDate", "minDate", "maxDate", "disabledDates", "disabledDays", "yearRange", "showTime", "responsiveOptions", "numberOfMonths", "firstDayOfWeek", "locale"], outputs: ["onFocus", "onBlur", "onClose", "onSelect", "onInput", "onTodayClick", "onClearClick", "onMonthChange", "onYearChange", "onClickOutside", "onShow"] }], directives: [{ type: i5.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { type: i5.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }] });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.2.7", ngImport: i0, type: DateRangeComponent, decorators: [{
type: Component,
args: [{ selector: 'date-range', providers: [{
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => DateRangeComponent),
multi: true
}], template: "<p-calendar\n #input\n [touchUI]=\"true\"\n [showIcon]=\"true\"\n [inputId]=\"inputId\"\n [(ngModel)]=\"value\"\n dateFormat=\"dd.mm.yy\"\n selectionMode=\"range\"\n appendTo=\"body\"\n (focusout)=\"leave.emit()\"\n (keydown.enter)=\"leave.emit()\"\n (onClose)=\"select.emit(value)\"\n [panelStyle]=\"{'mim-width': '0', 'max-width': '360px'}\"\n></p-calendar>\n\n", styles: [""] }]
}], propDecorators: { select: [{
type: Output
}] } });
const dateRangeFilterName = 'date-range';
class FilterDateComponent {
constructor(filterService) {
this.filterService = filterService;
this.matchModeOptions = [
{ label: 'Date range', value: dateRangeFilterName },
];
}
ngOnInit() {
this.filterService.register(dateRangeFilterName, FilterMethods.dateRangeHandler);
}
}
FilterDateComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.2.7", ngImport: i0, type: FilterDateComponent, deps: [{ token: i1$1.FilterService }], target: i0.ɵɵFactoryTarget.Component });
FilterDateComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.2.7", type: FilterDateComponent, selector: "filter-date", inputs: { key: "key" }, ngImport: i0, template: "<p-columnFilter\n type=\"date\"\n matchMode=\"date-range\"\n [showMenu]=\"false\"\n [field]=\"key\"\n [matchModeOptions]=\"matchModeOptions\"\n>\n <ng-template pTemplate=\"filter\" let-value let-filter=\"filterCallback\">\n <date-range\n [ngModel]=\"value\"\n (select)=\"filter($event)\"\n ></date-range>\n </ng-template>\n</p-columnFilter>\n", styles: [""], components: [{ type: i2.ColumnFilter, selector: "p-columnFilter", inputs: ["field", "type", "display", "showMenu", "matchMode", "operator", "showOperator", "showClearButton", "showApplyButton", "showMatchModes", "showAddButton", "hideOnClear", "placeholder", "matchModeOptions", "maxConstraints", "minFractionDigits", "maxFractionDigits", "prefix", "suffix", "locale", "localeMatcher", "currency", "currencyDisplay", "useGrouping"] }, { type: DateRangeComponent, selector: "date-range", outputs: ["select"] }], directives: [{ type: i1$1.PrimeTemplate, selector: "[pTemplate]", inputs: ["type", "pTemplate"] }, { type: i5.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { type: i5.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }] });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.2.7", ngImport: i0, type: FilterDateComponent, decorators: [{
type: Component,
args: [{ selector: 'filter-date', template: "<p-columnFilter\n type=\"date\"\n matchMode=\"date-range\"\n [showMenu]=\"false\"\n [field]=\"key\"\n [matchModeOptions]=\"matchModeOptions\"\n>\n <ng-template pTemplate=\"filter\" let-value let-filter=\"filterCallback\">\n <date-range\n [ngModel]=\"value\"\n (select)=\"filter($event)\"\n ></date-range>\n </ng-template>\n</p-columnFilter>\n", styles: [""] }]
}], ctorParameters: function () { return [{ type: i1$1.FilterService }]; }, propDecorators: { key: [{
type: Input
}] } });
const checkboxFilterName = 'bool-exact';
class FilterCheckboxComponent {
constructor(filterService) {
this.filterService = filterService;
this.matchModeOptions = [
{ label: 'Checkbox', value: checkboxFilterName },
];
}
ngOnInit() {
this.filterService.register(checkboxFilterName, FilterMethods.checkboxHandler);
}
}
FilterCheckboxComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.2.7", ngImport: i0, type: FilterCheckboxComponent, deps: [{ token: i1$1.FilterService }], target: i0.ɵɵFactoryTarget.Component });
FilterCheckboxComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.2.7", type: FilterCheckboxComponent, selector: "filter-checkbox", inputs: { key: "key" }, ngImport: i0, template: "<p-columnFilter\n type=\"boolean\"\n matchMode=\"bool-exact\"\n [field]=\"key\"\n [matchModeOptions]=\"matchModeOptions\"\n></p-columnFilter>\n", styles: [""], components: [{ type: i2.ColumnFilter, selector: "p-columnFilter", inputs: ["field", "type", "display", "showMenu", "matchMode", "operator", "showOperator", "showClearButton", "showApplyButton", "showMatchModes", "showAddButton", "hideOnClear", "placeholder", "matchModeOptions", "maxConstraints", "minFractionDigits", "maxFractionDigits", "prefix", "suffix", "locale", "localeMatcher", "currency", "currencyDisplay", "useGrouping"] }] });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.2.7", ngImport: i0, type: FilterCheckboxComponent, decorators: [{
type: Component,
args: [{ selector: 'filter-checkbox', template: "<p-columnFilter\n type=\"boolean\"\n matchMode=\"bool-exact\"\n [field]=\"key\"\n [matchModeOptions]=\"matchModeOptions\"\n></p-columnFilter>\n", styles: [""] }]
}], ctorParameters: function () { return [{ type: i1$1.FilterService }]; }, propDecorators: { key: [{
type: Input
}] } });
class FilterTextComponent {
}
FilterTextComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.2.7", ngImport: i0, type: FilterTextComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
FilterTextComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.2.7", type: FilterTextComponent, selector: "filter-text", inputs: { key: "key" }, ngImport: i0, template: "<p-columnFilter\n type=\"text\"\n matchMode=\"contains\"\n [field]=\"key\"\n [showMenu]=\"false\"\n [showClearButton]=\"false\"\n></p-columnFilter>\n", styles: [""], components: [{ type: i2.ColumnFilter, selector: "p-columnFilter", inputs: ["field", "type", "display", "showMenu", "matchMode", "operator", "showOperator", "showClearButton", "showApplyButton", "showMatchModes", "showAddButton", "hideOnClear", "placeholder", "matchModeOptions", "maxConstraints", "minFractionDigits", "maxFractionDigits", "prefix", "suffix", "locale", "localeMatcher", "currency", "currencyDisplay", "useGrouping"] }] });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.2.7", ngImport: i0, type: FilterTextComponent, decorators: [{
type: Component,
args: [{ selector: 'filter-text', template: "<p-columnFilter\n type=\"text\"\n matchMode=\"contains\"\n [field]=\"key\"\n [showMenu]=\"false\"\n [showClearButton]=\"false\"\n></p-columnFilter>\n", styles: [""] }]
}], propDecorators: { key: [{
type: Input
}] } });
class EditorBuilder {
constructor(options) {
this.onLeave = () => { };
this.autoFocus = true;
this.wrappers = [];
this.inputMask = '';
this.fieldWrapperSelector = '.table-cell__content';
this.pattern = PATTERN_TYPES.NONE;
this.key = options.key;
this.onLeave = options.onLeave;
this.editorType = options.editorType || FIELD_TYPES.TEXT;
this.inputMask = options.inputMask || this.inputMask;
this.pattern = options.pattern || this.pattern;
}
}
const DEFAULT_VISIBLE_EDITOR_HANDLER = () => true;
class TableCellComponent {
constructor(cd, fb) {
this.cd = cd;
this.fb = fb;
this.update = new EventEmitter();
this.onFocus = new EventEmitter();
this.cellType = CELL_TYPES;
this.fields = [];
this.form = new FormGroup({});
this._item = {};
this._config = { key: '', label: '' };
this._tableCell = new TableCell();
}
set config(newValue) {
this._tableCell.setConfig(newValue);
this._config = newValue;
}
get config() {
return this._config;
}
set item(newValue) {
this._tableCell.setItem(newValue);
this._item = newValue;
}
get item() {
return this._item;
}
get fieldData() {
return this._tableCell.fieldData;
}
get previewData() {
return this._tableCell.previewData;
}
get linkUrl() {
const { url, keyParam } = this.config.linkOptions || {};
if (!url)
return STRING.EMPTY;
if (keyParam) {
const param = this._tableCell.getValue(this.item, keyParam);
return `${url}?${keyParam}=${param}`;
}
return url;
}
get linkTarget() {
const { linkOptions: { target } = {} } = this.config;
return target ? target : '_self';
}
get isEditable() {
const { editorType, visibleEditorHandler = DEFAULT_VISIBLE_EDITOR_HANDLER } = this.config;
return Boolean(editorType) && visibleEditorHandler(this.item);
}
get isEmptyTemplate() {
// TODO should show default value if slot "template" is empty
const { nativeElement } = this.contentRef || {};
return !(nativeElement && nativeElement.innerText);
}
ngOnInit() {
const { key } = this.config;
const keyList = key.split(STRING.DOT);
this.form.addControl(...this.setFormControl(keyList));
}
ngAfterViewInit() {
this.cd.detectChanges();
}
setEditor() {
if (!this.isEditable) {
return;
}
const field = new EditorBuilder({
...this.config,
onLeave: this.onLeave.bind(this),
});
this.onFocus.emit({ item: this.item, key: this.config.key });
this.fields.push(field);
}
onLeave() {
const { key } = this.config;
const { value } = this.form;
if (this._tableCell.getValue(value, key) !== this.fieldData) {
const item = set(deepClone(this.item), key, this._tableCell.getValue(value, key));
this.update.emit({ item, key });
}
this.fields = [];
}
setFormControl([firstKey, ...keys]) {
if (!keys.length)
return [firstKey, this.fb.control(this.fieldData)];
const [newKey, control] = this.setFormControl(keys);
return [firstKey, this.fb.group({ [newKey]: control })];
}
}
TableCellComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.2.7", ngImport: i0, type: TableCellComponent, deps: [{ token: i0.ChangeDetectorRef }, { token: i5.FormBuilder }], target: i0.ɵɵFactoryTarget.Component });
TableCellComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.2.7", type: TableCellComponent, selector: "table-cell", inputs: { template: "template", config: "config", item: "item" }, outputs: { update: "update", onFocus: "onFocus" }, viewQueries: [{ propertyName: "contentRef", first: true, predicate: ["contentRef"], descendants: true }], ngImport: i0, template: "<div class=\"table-cell__item\">\n <span class=\"table-cell__column-title\">\n {{ config.label }}\n </span>\n\n <span class=\"table-cell__content\">\n <med-dynamic-form\n *ngIf=\"fields.length\"\n [config]=\"fields\"\n [form]=\"form\"\n ></med-dynamic-form>\n\n <div\n [hidden]=\"fields.length\"\n [className]=\"isEditable ? 'table-cell__editable' : ''\"\n (click)=\"setEditor()\"\n >\n <span #contentRef>\n <ng-container *ngTemplateOutlet=\"\n template || defaultTemplate;\n context: { $implicit: previewData, item: item }\"\n ></ng-container>\n </span>\n\n <ng-container\n *ngIf=\"isEmptyTemplate\"\n [ngTemplateOutlet]=\"config.cellType === cellType.LINK ? linkTemplate : defaultTemplate\"\n ></ng-container>\n </div>\n </span>\n</div>\n\n<ng-template #linkTemplate>\n <a [attr.href]=\"linkUrl\" [attr.target]=\"linkTarget\" class=\"table-cell__link\">{{ previewData }}</a>\n</ng-template>\n\n<ng-template #defaultTemplate>\n {{ previewData }}\n</ng-template>\n", styles: [":host{width:100%}.table-cell__item{display:flex;width:100%;justify-content:flex-start!important}@media screen and (max-width: 960px){.table-cell__item{font-size:14px}}.table-cell__column-title{display:none;padding:5px;font-weight:700;flex:0 0 40%}@media screen and (max-width: 960px){.table-cell__column-title{display:block}}.table-cell__content{width:100%;height:100%;padding:5px;overflow-wrap:break-word;word-wrap:break-word;-webkit-hyphens:auto;hyphens:auto;word-break:break-all}.table-cell__editable{cursor:pointer;width:100%;height:100%;color:var(--green-700)}.table-cell__editable:hover{color:var(--green-400)}.table-cell__link{cursor:pointer;width:100%;height:100%;color:#3b82f6;text-decoration:none}.table-cell__link:hover{color:#3b6bff;text-decoration:underline}\n"], components: [{ type: i1.MedDynamicFormComponent, selector: "med-dynamic-form", inputs: ["config", "form"] }], directives: [{ type: i10.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i10.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet"] }] });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.2.7", ngImport: i0, type: TableCellComponent, decorators: [{
type: Component,
args: [{ selector: 'table-cell', template: "<div class=\"table-cell__item\">\n <span class=\"table-cell__column-title\">\n {{ config.label }}\n </span>\n\n <span class=\"table-cell__content\">\n <med-dynamic-form\n *ngIf=\"fields.length\"\n [config]=\"fields\"\n [form]=\"form\"\n ></med-dynamic-form>\n\n <div\n [hidden]=\"fields.length\"\n [className]=\"isEditable ? 'table-cell__editable' : ''\"\n (click)=\"setEditor()\"\n >\n <span #contentRef>\n <ng-container *ngTemplateOutlet=\"\n template || defaultTemplate;\n context: { $implicit: previewData, item: item }\"\n ></ng-container>\n </span>\n\n <ng-container\n *ngIf=\"isEmptyTemplate\"\n [ngTemplateOutlet]=\"config.cellType === cellType.LINK ? linkTemplate : defaultTemplate\"\n ></ng-container>\n </div>\n </span>\n</div>\n\n<ng-template #linkTemplate>\n <a [attr.href]=\"linkUrl\" [attr.target]=\"linkTarget\" class=\"table-cell__link\">{{ previewData }}</a>\n</ng-template>\n\n<ng-template #defaultTemplate>\n {{ previewData }}\n</ng-template>\n", styles: [":host{width:100%}.table-cell__item{display:flex;width:100%;justify-content:flex-start!important}@media screen and (max-width: 960px){.table-cell__item{font-size:14px}}.table-cell__column-title{display:none;padding:5px;font-weight:700;flex:0 0 40%}@media screen and (max-width: 960px){.table-cell__column-title{display:block}}.table-cell__content{width:100%;height:100%;padding:5px;overflow-wrap:break-word;word-wrap:break-word;-webkit-hyphens:auto;hyphens:auto;word-break:break-all}.table-cell__editable{cursor:pointer;width:100%;height:100%;color:var(--green-700)}.table-cell__editable:hover{color:var(--green-400)}.table-cell__link{cursor:pointer;width:100%;height:100%;color:#3b82f6;text-decoration:none}.table-cell__link:hover{color:#3b6bff;text-decoration:underline}\n"] }]
}], ctorParameters: function () { return [{ type: i0.ChangeDetectorRef }, { type: i5.FormBuilder }]; }, propDecorators: { template: [{
type: Input
}], config: [{
type: Input
}],