@codecabinet.online/codecabinet.online-sni-custom-grid-library
Version:
codecabinet.online created an astonishing grid library
1 lines • 142 kB
Source Map (JSON)
{"version":3,"file":"codecabinet.online-codecabinet.online-sni-custom-grid-library.mjs","sources":["../../../projects/custom-grid-library/src/lib/constants/constants.ts","../../../projects/custom-grid-library/src/lib/constants/gridOptions.ts","../../../projects/custom-grid-library/src/lib/customGridComponents/custom-grid-models/constants.ts","../../../projects/custom-grid-library/src/lib/customGridComponents/custom-grid-column/custom-grid-column.component.ts","../../../projects/custom-grid-library/src/lib/customGridComponents/custom-grid-column/custom-grid-column.component.html","../../../projects/custom-grid-library/src/lib/services/notification.service.ts","../../../projects/custom-grid-library/src/lib/customGridComponents/directives/zipcode.directive.ts","../../../projects/custom-grid-library/src/lib/customGridComponents/directives/routeTransformerDirective.directive.ts","../../../projects/custom-grid-library/src/lib/pipes/sanitize-html.pipe.ts","../../../projects/custom-grid-library/src/lib/customGridComponents/custom-grid/custom-grid.component.ts","../../../projects/custom-grid-library/src/lib/customGridComponents/custom-grid/custom-grid.component.html","../../../projects/custom-grid-library/src/lib/customGridComponents/directives/twodigitdecimalnumber.directive.ts","../../../projects/custom-grid-library/src/lib/modules/sharedModule.ts","../../../projects/custom-grid-library/src/lib/pipes/quantityToString.pipe.ts","../../../projects/custom-grid-library/src/lib/pipes/replaceIfNull.pipe.ts","../../../projects/custom-grid-library/src/lib/pipes/valueToString.pipe.ts","../../../projects/custom-grid-library/src/lib/modules/pipe.module.ts","../../../projects/custom-grid-library/src/lib/customGridComponents/custom-grid.module.ts","../../../projects/custom-grid-library/src/public-api.ts","../../../projects/custom-grid-library/src/codecabinet.online-codecabinet.online-sni-custom-grid-library.ts"],"sourcesContent":["export const emptyGuid = \"00000000-0000-0000-0000-000000000000\";\nexport const defaultDebounceTime = 1000;\n\nexport const ONE_DAY = 86400000;\n\nexport const isNotEmpty = (value: any) => {\n return value !== undefined && value !== null && value !== \"\" && value !== \"00000000-0000-0000-0000-000000000000\";\n };","export const gridSettings = {\n pageSize: \"pageSize\"\n}\n","export const filterMethod = {\n local : \"local\",\n server : \"server-side\"\n}\n\nexport const detailsLoadMethod = {\n local : \"local\",\n server : \"server-side\"\n}\n\nexport const columnTypes = {\n text: \"text\",\n dropdown: \"dropdown\",\n switch: \"switch\",\n date: \"date\",\n number: \"number\",\n list: \"list\",\n modal: \"modal\",\n icon: \"icon\",\n daterange: \"daterange\",\n button: \"button\",\n textnumber: \"text-number\"\n}\n\nexport const customDetailTypes = {\n text: \"text\",\n button: \"button\",\n warningText: \"text-warning\",\n piechart: \"piechart\"\n}\n\nexport const isNotEmpty = (value: any) => {\n return value !== undefined && value !== null && value !== \"\" && value !== \"00000000-0000-0000-0000-000000000000\";\n };","import { AfterViewInit, Component, ContentChild, ContentChildren, EventEmitter, Input, OnInit, Output } from '@angular/core';\nimport { TranslateService } from '@ngx-translate/core';\nimport { CustomGridComponent } from '../custom-grid/custom-grid.component';\nimport { columnTypes } from '../custom-grid-models/constants'\n\n@Component({\n selector: 'custom-grid-column',\n templateUrl: './custom-grid-column.component.html',\n styleUrls: ['./custom-grid-column.component.scss']\n})\nexport class CustomGridColumnComponent implements OnInit {\n\n //----------Data properties\n @Input() title: any;\n @Input() field: any;\n @Input() data: any;\n @Input() tooltipList: any;\n @Input() startDate: any = null;\n @Input() endDate: any = null;\n @Input() filterKey: string = undefined;\n @Input() props: any = { readonly: false, rendered: true };\n @Input() colTemplate: string = null;\n @Input() iconHoverText: string = null;\n @Input() filterDataSource: any[] = null;\n @Input() isRedirectActive: string = null;\n @Input() highlightedAnchorKey: any;\n @Input() hoverIcon: string;\n\n //---------Features properties\n @Input() redirectLink: any;\n @Input() columnType: string = columnTypes.text;\n @Input() disabled: string = \"false\";\n @Input() hasFilter: boolean = true;\n @Input() displayedItems: any[] = [];\n @Input() missingText: string;\n @Input() disabledTooltipList: any;\n @Input() hiddenContent: string = \"false\";\n @Input() textAlign: string = \"inherit\";\n\n //----------Styling properties\n @Input() width: string;\n @Input() background: any;\n @Input() stateClasses: any;\n @Input() columnClasses: string;\n\n //---------Local properties\n\n @Output() iconClickHandler: EventEmitter<any> = new EventEmitter<any>();\n @Output() action: EventEmitter<any> = new EventEmitter<any>();\n\n constructor(\n private _translate: TranslateService\n ) { }\n\n ngOnInit(): void {\n }\n\n public getColumn() {\n return this.field;\n }\n}\n","","import { Injectable } from '@angular/core';\nimport { TranslateService } from '@ngx-translate/core';\nimport { ToastrService } from 'ngx-toastr';\n \n@Injectable({\n providedIn: 'root'\n})\nexport class NotificationService {\n \n constructor(private toastr: ToastrService,\n private translate: TranslateService,\n ) { }\n \n showSuccess(message, title, url?: string){\n this.toastr.success(message, title)\n .onTap\n .subscribe(() => this.toasterClickedHandler(url))\n }\n \n showError(message, title, url?: string){\n this.toastr.error(message, title)\n .onTap\n .subscribe(() => this.toasterClickedHandler(url))\n }\n \n showInfo(message, title, url?: string, disableTimeOut: boolean = false){\n this.toastr.info(message, title, {disableTimeOut: disableTimeOut})\n .onTap\n .subscribe(() => this.toasterClickedHandler(url))\n }\n \n showWarning(message, title, url?: string){\n this.toastr.warning(message, title)\n .onTap\n .subscribe(() => this.toasterClickedHandler(url))\n }\n\n toasterClickedHandler(url: string) {\n if(url)\n {\n window.location.href = url;\n }\n }\n \n}","import { Directive, ElementRef, HostListener } from '@angular/core';\n\n@Directive({\n selector: '[zipcodedirective]'\n})\nexport class ZipCodeDirective {\n private navigationKeys: Array<string> = ['Backspace', 'Tab', 'End', 'Home', 'ArrowLeft', 'ArrowRight', 'Del', 'Delete'];\n\n constructor(private el: ElementRef) {\n }\n @HostListener('keydown', ['$event'])\n onKeyDown(e: KeyboardEvent) {\n if (\n this.navigationKeys.indexOf(e.key) > -1 ||\n (e.key === 'a' && e.ctrlKey === true) ||\n (e.key === 'c' && e.ctrlKey === true) ||\n (e.key === 'x' && e.ctrlKey === true) ||\n (e.key === 'a' && e.metaKey === true) ||\n (e.key === 'c' && e.metaKey === true) ||\n (e.key === 'x' && e.metaKey === true)\n ) {\n return;\n }\n if (e.key === ' ' || isNaN(Number(e.key))) {\n e.preventDefault();\n }\n }\n}","import { Directive, ElementRef, HostListener } from '@angular/core';\nimport { Router } from '@angular/router';\n\n@Directive({\n selector: '[routeTransformer]'\n})\nexport class RouteTransformerDirective {\n\n constructor(private el: ElementRef, private router: Router) { }\n\n @HostListener('click', ['$event'])\n public onClick(event) {\n if (event.target.tagName === 'A') {\n this.router.navigate([event.target.getAttribute('href')]);\n event.preventDefault();\n } else {\n return;\n }\n }\n\n};","import { Pipe, PipeTransform } from '@angular/core';\nimport { DomSanitizer, SafeHtml } from '@angular/platform-browser';\n\n@Pipe({\n name: 'sanitizeHtml'\n})\nexport class SanitizeHtmlPipe implements PipeTransform {\n\n constructor(private sanitizer: DomSanitizer) { }\n\n transform(v: string): SafeHtml {\n return this.sanitizer.bypassSecurityTrustHtml(v);\n }\n}\n","import { EventEmitter, OnChanges, Output } from '@angular/core';\nimport { AfterViewInit, Component, ContentChildren, ElementRef, Input, OnDestroy, OnInit, QueryList, Renderer2, ViewChild } from '@angular/core';\nimport { Router } from '@angular/router';\nimport { TranslateService } from '@ngx-translate/core';\nimport { Subject, Subscription, fromEvent } from 'rxjs';\nimport { defaultDebounceTime, isNotEmpty } from '../../constants/constants';\nimport { gridSettings } from '../../constants/gridOptions';\nimport { NotificationService } from '../../services/notification.service';\nimport { CustomGridColumnComponent } from '../custom-grid-column/custom-grid-column.component';\nimport { columnTypes, customDetailTypes, detailsLoadMethod } from '../custom-grid-models/constants'\nimport { ApexNonAxisChartSeries, ApexPlotOptions, ApexChart, ChartComponent, ApexFill } from \"ng-apexcharts\";\nimport { debounceTime } from 'rxjs/operators'\n\nexport type ChartOptions = {\n series: ApexNonAxisChartSeries;\n chart: ApexChart;\n labels: string[];\n plotOptions: ApexPlotOptions;\n fill: ApexFill;\n};\n\n@Component({\n selector: 'custom-grid',\n templateUrl: './custom-grid.component.html',\n styleUrls: ['./custom-grid.component.scss']\n})\nexport class CustomGridComponent implements OnInit, AfterViewInit, OnDestroy, OnChanges {\n\n /* Data properties */\n /*----------------------------------------------------*/\n @ContentChildren(CustomGridColumnComponent) columns: QueryList<CustomGridColumnComponent>;\n\n @Input() dataSource: any[];\n @Input() dataSourcePK: string;\n @Input() filtersDataType: any;\n @Input() rowHasDetails: boolean = false;\n @Input() hasGridDetails: boolean = false;\n @Input() hasFilters: boolean = false;\n @Input() rowDetails: any[] = [];\n @Input() disabledRows: any[] = [];\n @Input() disabledReasons: any[] = [];\n @Input() gridDetails: any[] = [];\n @Input() gridDetailsOrder: string[] = [];\n\n /* Styling properties */\n /*-------------------------------------------------------*/\n @Input() width: string;\n /*width of the table*/\n @Input() height: string;\n /*height of the table*/\n @Input() overflowX: string = \"\";\n /*overflow style - types : scroll,hidden,auto*/\n @Input() overflowY: string = \"\";\n /*overflow style - types : scroll,hidden,auto*/\n @Input() rowTemplate: string;\n /*if set, ignores default grid template*/\n @Input() rowClass: any[] = [];\n /*if set, ignores default grid noRecords*/\n @Input() noRecordsInnerHTML: string = null;\n\n /* Customization properties */\n /*-------------------------------------------------------*/\n @Input() popoverConfiguration: any = null;\n @Input() noDataImg: any;\n @Input() detailsLoadMethod: string;\n @Input() rowCheckable: boolean = false;\n @Input() checkedRows: any[] = [];\n @Input() customDetails: any[] = [];\n @Input() detailsTitle: string = \"\";\n @Input() toggleDetailsText: any = null;\n @Input() translationKey: string = \"\";\n @Input() gridDetailsTrasnlationKey: string = \"\";\n @Input() hasNumbering: boolean = false;\n @Input() hasStockInputIcon: boolean = false;\n @Input() dataLoaded: boolean = false;\n @Input() displayedDetails: string[] = [];\n @Input() popOverReturnOption: string = \"id\";\n\n /* Filtering */\n /*-------------------------------------------------------*/\n @Input() filterable: boolean;\n @Input() filters: any[] = [];\n @Input() filterMethod: string;\n filtersChange: any = new Subject<string>();\n filterSubscription: Subscription;\n\n /* Output */\n /*-------------------------------------------------------*/\n @Output() triggerFilters: EventEmitter<any> = new EventEmitter<any>();\n @Output() popOver: EventEmitter<any> = new EventEmitter<any>();\n @Output() scroll: EventEmitter<any> = new EventEmitter<any>();\n @Output() detailsToggled: EventEmitter<any> = new EventEmitter<any>();\n @Output() toggleChanged: EventEmitter<any> = new EventEmitter<any>();\n @Output() imageEnlarge: EventEmitter<any> = new EventEmitter<any>();\n @Output() customDetailsAction: EventEmitter<any> = new EventEmitter<any>();\n @Output() tooltipHover: EventEmitter<any> = new EventEmitter<any>();\n @Output() modalClickHandler: EventEmitter<any> = new EventEmitter<any>();\n @Output() mapHandler: EventEmitter<any> = new EventEmitter<any>();\n @Output() checkedRowsChange = new EventEmitter<any[]>();\n\n /* Scrolling properties */\n /*-------------------------------------------------------*/\n\n scrollWindow: any;\n @ViewChild('customgrid', { static: false, read: ElementRef }) elementRef;\n\n /* Local properties */\n /*-------------------------------------------------------*/\n @Input() pageable: boolean = true;\n @Input() hasPageSizeSelection: boolean = false;\n pageSizes = [10, 20, 50, 100];\n pageSize: number;\n @ViewChild(\"chart\") chart: ChartComponent;\n public chartOptions: Partial<ChartOptions>;\n\n /* Local properties */\n /*-------------------------------------------------------*/\n dataSourceColumns: any[] = [];\n columnsDefinition: any[] = [];\n grid: any[] = [];\n norecords: boolean = false;\n columnTypes = columnTypes;\n init: boolean = true;\n allSelected: boolean = false;\n hasSelected: boolean = false;\n localCheckedRows: any[] = [];\n customDetailTypes = customDetailTypes;\n tooltipList: any[] = [];\n public _periodRange = { start: null, end: null };\n public showDateRangePopup: boolean = false;\n\n datasourcesDef: any[];\n\n objectKeys = Object.keys;\n\n constructor(\n private renderer: Renderer2,\n private _router: Router,\n private _toastService: NotificationService,\n private _translate: TranslateService\n ) {\n\n this.filterSubscription = this.filtersChange.pipe(debounceTime(defaultDebounceTime)).subscribe(x => {\n let filterEvent = { filters: this.filters, filterMethod: this.filterMethod };\n this.triggerFilters.emit(filterEvent);\n });\n\n this.chartOptions = {\n chart: {\n height: 200,\n type: \"radialBar\"\n },\n series: [67],\n plotOptions: {\n radialBar: {\n hollow: {\n margin: 15,\n size: \"65%\",\n },\n dataLabels: {\n value: {\n offsetY: -7,\n color: \"#000\",\n fontSize: \"16px\",\n show: true\n }\n },\n }\n },\n labels: [\"\"],\n fill: {\n colors: [\"#5ec12d\"],\n }\n };\n }\n\n ngOnDestroy(): void {\n if (this.filterSubscription) {\n this.filterSubscription.unsubscribe();\n }\n\n if (this.scrollWindow) {\n this.scrollWindow.unsubscribe();\n }\n }\n\n ngOnInit(): void {\n let ls_page = localStorage.getItem(gridSettings.pageSize);\n if (ls_page) {\n this.pageSize = JSON.parse(ls_page);\n }\n }\n\n ngOnChanges() {\n this.norecords = this.dataSource && this.dataSource.length == 0;\n\n if (this.dataSource && this.init) {\n this.init = false;\n this.dataSource.forEach(element => {\n element.isExpanded = false;\n // element.isSelected = false;\n element.isDisabled = false;\n if (this.detailsLoadMethod == detailsLoadMethod.server) { element.isDetailLoaded = false; }\n });\n }\n\n var columnsDef = this.columns?.toArray().map(x => {\n return {\n field: isNotEmpty(x.filterKey) ? x.filterKey : x.field,\n title: x.title,\n }\n });\n\n var columnLabels = this.columns?.toArray().map(x => x.filterDataSource);\n this.datasourcesDef = columnLabels ? this.renameKeys(columnLabels, this.dataSourceColumns) : null;\n }\n\n ngAfterViewInit() {\n setTimeout(() => {\n var columns = this.columns.toArray();\n this.dataSourceColumns = columns.map(x => {\n return {\n field: isNotEmpty(x.filterKey) ? x.filterKey : x.field,\n title: x.title,\n filterKey: isNotEmpty(x.filterKey) ? x.filterKey : x.field,\n highlightedAnchorKey: x.highlightedAnchorKey\n }\n });\n\n let colProperties = columns.map(x => {\n return {\n width: x.width,\n background: x.background,\n redirectLink: x.redirectLink,\n columnType: x.columnType,\n disabled: x.disabled,\n hasFilter: x.hasFilter,\n stateClasses: x.stateClasses,\n tooltipList: x.tooltipList,\n filterKey: x.filterKey,\n displayedItems: x.displayedItems,\n missingText: x.missingText,\n disabledTooltipList: x.disabledTooltipList,\n hiddenContent: x.hiddenContent,\n textAlign: x.textAlign,\n props: x.props,\n colTemplate: x.colTemplate,\n iconHoverText: x.iconHoverText,\n isRedirectActive: x.isRedirectActive,\n columnClasses: x.columnClasses\n }\n });\n this.columnsDefinition = this.renameKeys(colProperties, this.dataSourceColumns);\n\n var columnLabels = this.columns?.toArray().map(x => x.filterDataSource);\n this.datasourcesDef = columnLabels ? this.renameKeys(columnLabels, this.dataSourceColumns) : null;\n\n // var filters = columns.map(x => this.filters[x.field]);\n // this.filters = this.renameKeys(filters, this.dataSourceColumns);//not needed anymore\n }, 0);\n\n const SCROLLABLE_AREA = this.height && this.height.search(\"%\") == -1 ? this.elementRef.nativeElement : window;\n this.scrollWindow = fromEvent(SCROLLABLE_AREA, 'scroll').subscribe((event) => {\n this.scrollHandler(event);\n });\n }\n\n generateDynamicHtml(htmlTemplateProvided: string, row: any, stateClasses: any[]) {\n // console.log(\"[DEBUG]: GenerateDynamicHtml\" + htmlTemplateProvided);\n // console.log(row);\n const regex = /\\{{(.*?)\\}}/;\n\n var matched = regex.exec(htmlTemplateProvided);\n while (matched) {\n htmlTemplateProvided = htmlTemplateProvided.replace(matched[0], row[matched[1]]);\n matched = regex.exec(htmlTemplateProvided);\n }\n\n if (stateClasses?.length > 0) {\n const regexClass = /\\{#(.*?)\\#}/;\n var matchedClass = regexClass.exec(htmlTemplateProvided);\n while (matchedClass) {\n htmlTemplateProvided = htmlTemplateProvided.replace(matchedClass[0], this.selectClass(stateClasses, row, matchedClass[1]));\n matchedClass = regexClass.exec(htmlTemplateProvided);\n }\n }\n\n return htmlTemplateProvided;\n }\n\n private renameKeys(obj: any, newKeys) {\n const keyValues = Object.keys(obj).map(key => {\n const newKey = newKeys[key] || key;\n return { [newKey.field]: obj[key] };\n });\n return Object.assign({}, ...keyValues);\n }\n\n public checkRedirectIsActive(isRedirectActive: string, row: any) {\n return isRedirectActive != null && eval(isRedirectActive);\n }\n\n public redirectRoute(route: string = null, id: string, isRedirectActive: string, row: any) {\n if (isNotEmpty(route) && this.checkRedirectIsActive(isRedirectActive, row)) {\n if (isNotEmpty(id)) {\n this._router.navigate([route + '/' + id]);\n }\n else {\n this._router.navigate([route]);\n }\n }\n }\n\n redirectUrl(link: any, row: any) {\n if (this.checkDisabledRow(row)) {\n return;\n }\n if (link.isExternal) {\n window.location.href = link.url;\n }\n else {\n this._router.navigate([link.url], { queryParams: link.queryParams });\n }\n }\n\n /* Details */\n\n toggleDetailsContainer(rowIndex: number, id: string = null) {\n this.dataSource.forEach((element, index) => {\n if (element.isExpanded && index != rowIndex) {\n element.isExpanded = false;\n }\n });\n\n var isExpanded = this.dataSource[rowIndex].isExpanded;\n var isDetailLoaded = this.dataSource[rowIndex].isDetailLoaded;\n this.dataSource[rowIndex].isExpanded = !isExpanded;\n\n if (!isExpanded && this.detailsLoadMethod == detailsLoadMethod.server && !isDetailLoaded) {\n this.dataSource[rowIndex].isDetailLoaded = true;\n let event = { id: id, rowIndex: rowIndex };\n this.detailsToggled.emit(event);\n }\n }\n\n formatDate(date: string) {\n var stringToDate = new Date(date);\n var fullDate = stringToDate.toLocaleDateString(\n localStorage.getItem(\"selectedLanguage\")\n );\n return fullDate;\n }\n\n disabledSwitch(row: any, disabledExpression: string) {\n return eval(disabledExpression);\n }\n\n disabledPopoverButtons(row: any, disabledExpression: string) {\n return eval(disabledExpression);\n }\n\n hidePopoverButtons(row: any, hiddenExpression: string) {\n return eval(hiddenExpression);\n }\n\n checkDisabledRow(row: any) {\n if (this.disabledRows.find(y => {\n return y.key != null ? row[this.dataSourcePK] == y.key : y.index == this.dataSource.indexOf(row)\n }) != undefined) {\n return true;\n }\n return false;\n }\n\n checkDisabledCheckboxRow(row: any) {\n if (row.isDisabled) {\n return true;\n }\n return this.checkDisabledRow(row);\n }\n\n selectClass(event: any, row: any, classTarget: string = null) {\n return this.selectClassTemplate(event, row, classTarget);\n }\n\n selectRowClass(row: any) {\n if (this.rowClass) {\n return this.selectClassTemplate(this.rowClass, row);\n }\n }\n\n selectClassTemplate(classArray: any, row: any, classTarget: string = null) {\n var returnedClass = \"default-class\";\n if (classArray) {\n classArray.forEach(element => {\n if (eval(element.expression) && (element.classTarget == classTarget || !classTarget || !element.classTarget)) {\n returnedClass = element.className;\n return;\n }\n });\n }\n return returnedClass;\n }\n\n disable(exp: string, row: any) {\n return eval(exp);\n }\n\n hideCustomDetail(exp: string, row: any) {\n return eval(exp);\n }\n\n evaluateExpression(exp: string, row: any) {\n return eval(exp);\n }\n\n isNotEmpty(element: any) {\n return isNotEmpty(element);\n }\n\n checkHiddenCell(row: any, expression) {\n return !eval(expression);\n }\n\n /* Emitters */\n /*-------------------------------------------------------*/\n\n toggleValueChange(id: string) {\n this.toggleChanged.emit(id);\n }\n\n popoverAction(action: any, rowData: any) {\n let event = { action: action, id: undefined, rowData: undefined };\n if (this.popOverReturnOption === \"id\") {\n event.id = rowData[this.dataSourcePK];\n }\n if (this.popOverReturnOption === \"rowData\") {\n event.rowData = rowData;\n }\n\n if (action != null) {\n this.popOver.emit(event);\n }\n return;\n }\n\n scrollHandler(event: any) {\n if (this.pageable) {\n this.scroll.emit(event);\n }\n }\n\n imageClickHandler(photo: any) {\n this.imageEnlarge.emit(photo);\n }\n\n tooltipHoverHandler(event: any, rowIndex: number) {\n let objEvent = { success: event, rowIndex: rowIndex, data: this.dataSource[rowIndex] };\n this.tooltipHover.emit(objEvent);\n }\n\n modalHandler(row: any, colField: string) {\n if (this.columnsDefinition[colField].disabled) {\n return;\n }\n this.modalClickHandler.emit(row);\n }\n\n iconClickedHandler(row: any, colField: string) {\n if (this.evaluateExpression(this.columnsDefinition[colField].disabled, row) || this.checkDisabledRow(row)) {\n return;\n }\n let iconColumn = this.columns.toArray().find(x => x.field == colField);\n if (iconColumn) {\n iconColumn.iconClickHandler.emit(row);\n }\n }\n\n cellActionHandler(row: any, colField: string) {\n if (eval(this.columnsDefinition[colField].disabled) || this.checkDisabledRow(row)) {\n return;\n }\n let column = this.columns.toArray().find(x => x.field == colField);\n if (column && column.action/*.observers && column.action.observers.length > 0*/) {\n column.action.emit(row);\n }\n }\n\n redirectMap(event: any, row: any) {\n if (this.checkDisabledRow(row)) {\n return;\n }\n let eventObject = {\n event: event,\n row: row\n }\n this.mapHandler.emit(eventObject);\n }\n\n /* Handlers */\n /*-------------------------------------------------------*/\n\n changePageSize(event: any) {\n localStorage.setItem(gridSettings.pageSize, JSON.stringify(event));\n window.location.reload();\n return;\n }\n\n public selectHandler(event: any, rowIndex: number) {\n setTimeout(() => {\n this.dataSource[rowIndex].isSelected = event;\n this.allSelected = this.dataSource.every(x => x.isSelected);\n this.checkedRows = this.dataSource.filter(x => x.isSelected);\n this.checkedRowsChange.emit(this.checkedRows);\n });\n }\n\n public selectAllHandler() {\n setTimeout(() => {\n this.dataSource.filter(x => (\n x.isSelected != this.allSelected &&\n !this.checkDisabledRow(x) && !x.isDisabled\n )).forEach(x => { x.isSelected = this.allSelected; });\n this.checkedRows = this.dataSource.filter(x => x.isSelected);\n this.checkedRowsChange.emit(this.checkedRows);\n });\n }\n\n customTemplateActionHandler(action: string, id: string) {\n let event = { action: action, id: id };\n if (action) {\n this.customDetailsAction.emit(event);\n }\n }\n\n isDecimal(value: any) {\n return !isNaN(value);\n }\n\n valueChanged(event: any, popup: any) {\n this.showDateRangePopup = false;\n popup.show = false;\n\n this.filtersChange.next(event);\n }\n\n clearDate(event: any, popup: any) {\n this.showDateRangePopup = false;\n popup.show = false;\n\n if (this.filters[\"startDate\"] || this.filters[\"endDate\"]) {\n this.filters[\"startDate\"] = null;\n this.filters[\"endDate\"] = null;\n }\n \n this.filtersChange.next(event);\n }\n\n activateCalendar(popup: any){\n this.showDateRangePopup = true;\n popup.show = true;\n }\n\n openPopup(event: any){ \n if(!this.showDateRangePopup){\n event.preventDefault();\n }\n }\n\n closePopup(event: any){ \n if(this.showDateRangePopup){\n event.preventDefault();\n }\n }\n\n}\n","<div class=\"custom-grid-wrap\" [ngStyle]=\"{'width':width,'height':height,'overflow-x': overflowX, 'overflow-y': overflowY}\" #customgrid>\n <ng-container *ngIf=\"(hasFilters || !norecords)\">\n <div class=\"custom-grid-table\" [ngStyle]=\"{'width':width}\">\n <div class=\"custom-grid-thead\">\n <div class=\"custom-grid-thead-tr header-border-custom-grid\">\n <div class=\"custom-grid-thead-cell cell-disabled\"></div> <!-- disabled row cell -->\n <div *ngIf=\"rowCheckable\" class=\"custom-grid-thead-cell cell-checkbox cell-fixed\"> <!-- row cell checkbox-->\n <input type=\"checkbox\"\n class=\"k-checkbox custom-grid-checkbox\" \n [(ngModel)]=\"allSelected\" \n (ngModelChange)=\"selectAllHandler()\"\n [disabled]=\"dataSourceColumns != null && dataSourceColumns.length == 0\">\n </div>\n <div *ngIf=\"hasNumbering\" class=\"custom-grid-thead-cell cell-numbering cell-fixed\"> <!-- row cell numbering-->\n {{'customGrid.numbering' | translate}}\n </div>\n <!-- row cells data-->\n <div *ngFor=\"let col of dataSourceColumns; let colIndex = index\"\n class=\"custom-grid-thead-cell cell-thead-filter {{columnsDefinition[col.field].columnClasses}}\"\n [hidden]=\"!columnsDefinition[col.field].props.rendered\"\n [ngClass]=\"{\n 'cell-empty': !col.title, 'cell-data': col.title,\n 'cell-date': !datasourcesDef[col.field] && columnsDefinition[col.field].columnType == columnTypes.date || columnsDefinition[col.field].columnType == columnTypes.daterange\n }\"\n >\n <a class=\"table-header-title-custom-grid a-header-custom-grid\" *ngIf=\"col.title\">\n {{ col.title | translate }}\n </a>\n </div>\n <div *ngIf=\"popoverConfiguration != null\" class=\"custom-grid-thead-cell cell-popover cell-fixed\"></div> <!-- disabled row cell popover -->\n </div> <!-- END custom-grid-thead-tr -->\n <div class=\"custom-grid-thead-tr custom-grid-thead-filters\">\n <div class=\"custom-grid-thead-cell cell-disabled\"></div> <!-- disabled row cell -->\n <div *ngIf=\"rowCheckable\" class=\"custom-grid-thead-cell cell-checkbox cell-fixed\"></div> <!-- disabled row cell checkbox -->\n <div *ngIf=\"hasNumbering\" class=\"custom-grid-thead-cell cell-numbering cell-fixed\"></div> <!-- disabled row cell numbering -->\n <!-- row cells data-->\n <div class=\"custom-grid-thead-cell cell-thead-filter {{columnsDefinition[col.field].columnClasses}}\" \n *ngFor=\"let col of dataSourceColumns ; let colIndex = index\"\n [ngClass]=\"{\n 'cell-date': !datasourcesDef[col.field] && columnsDefinition[col.field].columnType == columnTypes.date || columnsDefinition[col.field].columnType == columnTypes.daterange,\n 'cell-empty': !columnsDefinition[col.field].hasFilter,\n 'cell-data': datasourcesDef[col.field] || (!datasourcesDef[col.field] && columnsDefinition[col.field].hasFilter),\n 'cell-dropdown': datasourcesDef[col.field]\n }\"\n >\n \n <ng-container *ngIf=\"datasourcesDef[col.field]; else notDropdown\">\n <div class=\"custom-grid-filter-container custom-grid-combobox\" *ngIf=\"columnsDefinition[col.field].props.rendered\">\n <kendo-combobox placeholder=\"{{'common.actions.filter' | translate}}\"\n [data]=\"datasourcesDef[col.field]\"\n [(ngModel)]=\"filters[col.filterKey]\" \n (ngModelChange)=\"filtersChange.next($event)\"\n valueField=\"id\"\n textField=\"name\"\n [valuePrimitive]=\"true\">\n </kendo-combobox>\n </div>\n </ng-container>\n <ng-template #notDropdown>\n <ng-container [ngSwitch]=\"columnsDefinition[col.field].columnType\">\n <ng-container *ngIf=\"columnsDefinition[col.field].hasFilter\">\n <ng-container *ngSwitchDefault>\n <div class=\"custom-grid-filter-container\" *ngIf=\"columnsDefinition[col.field].props.rendered\">\n <i class=\"icon icon-search wa-icon wa-icon-search\"></i>\n <input type=\"text\" placeholder=\"{{'common.actions.filter' | translate}}\"\n class=\"filter-header-box-custom-grid\" [(ngModel)]=\"filters[col.filterKey]\" (ngModelChange)=\"filtersChange.next($event)\">\n </div>\n </ng-container>\n \n <ng-container *ngSwitchCase=\"columnTypes.text\">\n <div class=\"custom-grid-filter-container\" *ngIf=\"columnsDefinition[col.field].props.rendered\">\n <i class=\"icon icon-search wa-icon wa-icon-search\"></i>\n <input type=\"text\" placeholder=\"{{'common.actions.filter' | translate}}\"\n class=\"filter-header-box-custom-grid\" [(ngModel)]=\"filters[col.filterKey]\" (ngModelChange)=\"filtersChange.next($event)\">\n </div>\n </ng-container>\n \n <ng-container *ngSwitchCase=\"columnTypes.date\">\n <kendo-datepicker class=\"custom-grid-filter-container kendo-datepicker-placeholder\" [format]=\"'d'\" [(ngModel)]=\"filters[col.filterKey]\"\n (ngModelChange)=\"filtersChange.next($event)\" *ngIf=\"columnsDefinition[col.field].props.rendered\">\n <kendo-datepicker-messages today=\"{{ 'calendar.today' | translate }}\"\n toggle=\"{{ 'calendar.toggle' | translate }}\"></kendo-datepicker-messages>\n </kendo-datepicker>\n </ng-container>\n \n <ng-container *ngSwitchCase=\"columnTypes.daterange\">\n <kendo-daterange class=\"custom-grid-filter-container custom-grid-date-range\" *ngIf=\"columnsDefinition[col.field].props.rendered\">\n <div class=\"custom-grid-date-range-anchor d-flex align-items-center\" #anchor (click)=\"activateCalendar(customGridDateRangePopup)\">\n <label class=\"custom-grid-date-range-label d-flex align-items-center\">\n <kendo-dateinput kendoDateRangeStartInput\n [(value)]=\"filters['startDate']\" \n placeholder=\"{{ 'customGrid.startDate' | translate }}\"\n (valueChange)=\"filters['endDate'] = null\"\n class=\"daterange-dateinput\">\n </kendo-dateinput>\n </label>\n <label class=\"custom-grid-date-range-label d-flex align-items-center\">\n <kendo-dateinput kendoDateRangeEndInput\n [(value)]=\"filters['endDate']\" \n placeholder=\"{{ 'customGrid.endDate' | translate }}\"\n class=\"daterange-dateinput\">\n </kendo-dateinput>\n <span class=\"k-icon k-i-calendar\"></span>\n </label>\n </div>\n <kendo-daterange-popup #customGridDateRangePopup (open)=\"openPopup($event)\" (close)=\"closePopup($event)\"\n [anchor]=\"anchor\" \n [anchorAlign]=\"{ horizontal: 'center', vertical: 'bottom'}\"\n [popupAlign]=\"{ horizontal: 'center', vertical: 'top' }\"\n >\n <ng-template kendoDateRangePopupTemplate [ngIf]=\"true\">\n <kendo-multiviewcalendar kendoDateRangeSelection>\n </kendo-multiviewcalendar>\n <div class=\"custom-grid-filter-btn-section\">\n <button class=\"custom-grid-clear-daterange\" \n (click)=\"clearDate($event, customGridDateRangePopup)\">\n {{'common.actions.clear' | translate}}\n </button>\n <button class=\"custom-grid-filter-daterange\" \n (click)=\"valueChanged($event, customGridDateRangePopup)\">\n {{'common.actions.filter' | translate}}\n </button>\n </div> \n </ng-template>\n </kendo-daterange-popup>\n </kendo-daterange>\n </ng-container>\n \n <ng-container *ngSwitchCase=\"columnTypes.textnumber\">\n <div class=\"custom-grid-filter-container\" *ngIf=\"columnsDefinition[col.field].props.rendered\">\n <i class=\"icon icon-search wa-icon wa-icon-search\"></i>\n <input type=\"number\" min=\"0\" zipcodedirective placeholder=\"{{'common.actions.filter' | translate}}\"\n class=\"filter-header-box-custom-grid\" [(ngModel)]=\"filters[col.filterKey]\" (ngModelChange)=\"filtersChange.next($event)\">\n </div>\n </ng-container>\n \n </ng-container>\n </ng-container>\n </ng-template>\n </div>\n <div *ngIf=\"popoverConfiguration != null\" class=\"custom-grid-thead-cell cell-popover cell-fixed\"></div> <!-- disabled row cell popover -->\n </div> <!-- END custom-grid-thead-tr -->\n </div> <!-- END custom-grid-thead -->\n <div class=\"custom-grid-tbody\" *ngIf=\"!norecords\">\n <ng-container *ngFor=\"let row of dataSource; let rowIndex = index\">\n <ng-container *ngIf=\"row\">\n <ng-container *ngIf=\"rowTemplate; else defaultRowTemplate\">\n <ng-container *ngFor=\"let col of dataSourceColumns; let colIndex = index\">\n <div [innerHtml]=\"rowTemplate | sanitizeHtml\"></div>\n </ng-container>\n </ng-container>\n\n <!-- custom-grid-tbody-tr row data-->\n <ng-template #defaultRowTemplate>\n <div class=\"custom-grid-tbody-tr row-box-custom-grid {{selectRowClass(row)}}\"\n [ngClass]=\"{'custom-grid-disabled-row': checkDisabledRow(row), 'row-has-details': rowHasDetails}\">\n <div *ngIf=\"rowCheckable\" class=\"custom-grid-tbody-cell cell-checkbox cell-fixed\"> <!-- row cell checkbox-->\n <input type=\"checkbox\" \n class=\"k-checkbox custom-grid-checkbox\" \n [(ngModel)]=\"row.isSelected\" \n (ngModelChange)=\"selectHandler($event, rowIndex)\" \n [disabled]=\"checkDisabledCheckboxRow(row)\"\n >\n </div>\n <div class=\"custom-grid-tbody-cell cell-disabled\"> <!-- row cell disabled -->\n <ng-container *ngIf=\"checkDisabledRow(row)\">\n <i class=\"icon icon-warning-circle wa-icon wa-icon-warning-circle tooltip-trigger\"\n [ngbTooltip]=\"reasonDisabled\" placement=\"right\"></i>\n <ng-template #reasonDisabled>\n <div class=\"tooltip-container\">\n <ng-container *ngFor=\"let reason of disabledReasons; let reasonIndex = index\">\n <div class=\"tooltip-title\">\n {{reason.title | translate}}\n </div>\n <div class=\"tooltip-content\">\n {{reason.description | translate}}\n </div>\n </ng-container>\n </div>\n </ng-template>\n </ng-container>\n </div>\n <div *ngIf=\"hasNumbering\" class=\"custom-grid-tbody-cell cell-numbering cell-fixed\"> <!-- row cell numbering-->\n {{rowIndex + 1}}.\n </div>\n <!-- row cells data-->\n <ng-container *ngFor=\"let col of dataSourceColumns; let colIndex = index\">\n <ng-container *ngIf=\"!columnsDefinition[col.field].redirectLink; else linkColumn\">\n <ng-container *ngIf=\"columnsDefinition[col.field].colTemplate; else withoutTemplate\">\n <div class=\"custom-grid-tbody-cell cell-data {{columnsDefinition[col.field].columnClasses}}\">\n <div [innerHtml]=\"generateDynamicHtml(columnsDefinition[col.field].colTemplate, row, columnsDefinition[col.field].stateClasses)\"\n class=\"grid-colTemplate-container\">\n </div>\n </div>\n </ng-container>\n\n <ng-template #withoutTemplate>\n <ng-container [ngSwitch]=\"columnsDefinition[col.field].columnType\">\n <ng-container *ngSwitchDefault>\n <div class=\"custom-grid-tbody-cell cell-data {{columnsDefinition[col.field].columnClasses}}\"\n [ngClass]=\"{\n 'custom-grid-disabled-col': evaluateExpression(columnsDefinition[col.field].disabled, row)\n }\"\n (click)=\"cellActionHandler(row, col.field)\"\n *ngIf=\"columnsDefinition[col.field].props.rendered\">\n <span [ngClass]=\"selectClass(columnsDefinition[col.field].stateClasses,row)\"\n *ngIf=\"checkHiddenCell(row, columnsDefinition[col.field].hiddenContent)\">\n {{isNotEmpty(row[col.field]) ? row[col.field] : (columnsDefinition[col.field].missingText | translate)}}\n </span>\n </div>\n </ng-container>\n\n <ng-container *ngSwitchCase=\"columnTypes.text || columnTypes.textnumber\">\n <div class=\"custom-grid-tbody-cell cell-data cell-text {{columnsDefinition[col.field].columnClasses}}\"\n [ngClass]=\"{\n 'custom-grid-disabled-col': evaluateExpression(columnsDefinition[col.field].disabled, row),\n 'position-relative': row[col.highlightedAnchorKey]\n }\"\n (click)=\"cellActionHandler(row, col.field)\"\n *ngIf=\"columnsDefinition[col.field].props.rendered\">\n <div [class.div-container-highlight]=\"row[col.highlightedAnchorKey]\">\n <div [ngClass]=\"selectClass(columnsDefinition[col.field].stateClasses,row)\"\n [ngStyle]=\"{'text-align': columnsDefinition[col.field].textAlign}\"\n *ngIf=\"checkHiddenCell(row, columnsDefinition[col.field].hiddenContent)\">\n {{isNotEmpty(row[col.field]) ? row[col.field] : (columnsDefinition[col.field].missingText | translate)}}\n </div>\n </div>\n </div>\n </ng-container>\n\n <ng-container *ngSwitchCase=\"columnTypes.number\">\n <div class=\"custom-grid-tbody-cell cell-data cell-number {{columnsDefinition[col.field].columnClasses}}\"\n [ngClass]=\"{\n 'custom-grid-disabled-col': evaluateExpression(columnsDefinition[col.field].disabled, row)\n }\"\n (click)=\"cellActionHandler(row, col.field)\"\n *ngIf=\"columnsDefinition[col.field].props.rendered\">\n <span [ngClass]=\"selectClass(columnsDefinition[col.field].stateClasses,row)\"\n [ngStyle]=\"{'text-align': columnsDefinition[col.field].textAlign}\"\n *ngIf=\"checkHiddenCell(row, columnsDefinition[col.field].hiddenContent)\">\n {{isNotEmpty(row[col.field]) ? (row[col.field] | number : '1.2-2') : (columnsDefinition[col.field].missingText | translate)}}\n </span>\n </div>\n </ng-container>\n\n <ng-container *ngSwitchCase=\"columnTypes.date\">\n <div class=\"custom-grid-tbody-cell cell-data cell-date {{columnsDefinition[col.field].columnClasses}}\"\n [ngClass]=\"{\n 'custom-grid-disabled-col': evaluateExpression(columnsDefinition[col.field].disabled, row)\n }\"\n (click)=\"cellActionHandler(row, col.field)\"\n *ngIf=\"columnsDefinition[col.field].props.rendered\">\n <span [ngClass]=\"selectClass(columnsDefinition[col.field].stateClasses,row)\"\n [ngStyle]=\"{'text-align': columnsDefinition[col.field].textAlign}\"\n *ngIf=\"checkHiddenCell(row, columnsDefinition[col.field].hiddenContent)\">\n {{isNotEmpty(row[col.field]) ? formatDate(row[col.field]) : (columnsDefinition[col.field].missingText | translate)}}\n </span>\n </div>\n </ng-container>\n\n <ng-container *ngS