UNPKG

ngx-t-reports

Version:

Angular module for creating dynamic reports and dashboards. Supports various data sources, custom templates, and real-time updates.

1,915 lines 152 kB
import * as i0 from '@angular/core';
import { EventEmitter, Output, Input, Component, Injectable, inject, ViewChild, ChangeDetectionStrategy, InjectionToken, Optional, Inject } from '@angular/core';
import * as i1 from 'ngx-echarts';
import { NgxEchartsModule, provideEchartsCore } from 'ngx-echarts';
import * as echarts from 'echarts/core';
import { GridComponent } from 'echarts/components';
import { CanvasRenderer } from 'echarts/renderers';
import * as i2 from '@angular/common';
import { CommonModule } from '@angular/common';
import { BarChart, BoxplotChart, CandlestickChart, CustomChart, EffectScatterChart, FunnelChart, GaugeChart, GraphChart, HeatmapChart, LineChart, LinesChart, MapChart, ParallelChart, PictorialBarChart, PieChart, RadarChart, SankeyChart, ScatterChart, SunburstChart, ThemeRiverChart, TreeChart, TreemapChart } from 'echarts/charts';
import * as i4$1 from '@angular/material/progress-spinner';
import { MatProgressSpinnerModule } from '@angular/material/progress-spinner';
import * as i3 from '@angular/cdk/drag-drop';
import { moveItemInArray, DragDropModule, CdkDropList, CdkDrag } from '@angular/cdk/drag-drop';
import * as i8 from '@angular/material/button';
import { MatButtonModule } from '@angular/material/button';
import * as i1$1 from '@angular/material/card';
import { MatCardModule, MatCardContent, MatCardHeader, MatCardTitle, MatCardSubtitle } from '@angular/material/card';
import * as i7 from '@angular/material/icon';
import { MatIconModule } from '@angular/material/icon';
import * as i5 from '@angular/material/menu';
import { MatMenuModule } from '@angular/material/menu';
import * as i9 from '@angular/material/toolbar';
import { MatToolbarModule, MatToolbar } from '@angular/material/toolbar';
import * as i2$1 from '@angular/material/divider';
import { MatDividerModule } from '@angular/material/divider';
import * as i4 from '@angular/material/chips';
import { MatChipsModule } from '@angular/material/chips';
import * as i12 from '@angular/material/table';
import { MatTableModule } from '@angular/material/table';
import * as i6 from '@angular/material/tooltip';
import { MatTooltipModule } from '@angular/material/tooltip';
import { ComponentStore } from '@ngrx/component-store';
import { combineLatest, map, switchMap, tap, distinctUntilChanged, of, BehaviorSubject, Observable, Subscription, take, catchError } from 'rxjs';
import * as XLSX from 'xlsx';
import * as i13 from '@angular/cdk/scrolling';
import { ScrollingModule } from '@angular/cdk/scrolling';
import * as i1$2 from '@angular/material/dialog';
import * as i7$1 from '@angular/material/expansion';
import { MatExpansionModule } from '@angular/material/expansion';
import { assignDeepPropertyToObject, TDynamicDataEditComponent, NGX_T_FORMS_CONFIG_TOKEN, getSectionElements } from 'ngx-t-forms';
import { ElementEditorTypes, SpecialElementKeys, InputDataTypes, ElementTypes } from 'ngx-t-forms-types';
import * as i7$2 from '@angular/forms';
import { FormGroup, FormControl, FormsModule, ReactiveFormsModule } from '@angular/forms';
import * as i6$1 from '@angular/material/datepicker';
import { MatDatepickerModule } from '@angular/material/datepicker';
import * as i5$1 from '@angular/material/form-field';
import { MatFormFieldModule } from '@angular/material/form-field';
import { MAT_DATE_LOCALE, DateAdapter, MAT_DATE_FORMATS } from '@angular/material/core';
import { MomentDateAdapter } from '@angular/material-moment-adapter';
import moment from 'moment-timezone';
import moment$1 from 'moment';

echarts.use([
    BarChart, BoxplotChart, CandlestickChart, CustomChart, EffectScatterChart,
    FunnelChart, GaugeChart, GraphChart, HeatmapChart, LineChart, LinesChart,
    MapChart, ParallelChart, PictorialBarChart, PieChart, RadarChart, SankeyChart,
    ScatterChart, SunburstChart, ThemeRiverChart, TreeChart, TreemapChart,
    GridComponent, CanvasRenderer
]);
class EChartsComponent {
    constructor() {
        this.chartClick = new EventEmitter();
    }
    ngOnChanges(changes) {
        if (changes['options']) {
            this.chartOption = this.options;
        }
    }
    onChartClick(event) {
        this.chartClick.emit(event);
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: EChartsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
    static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.14", type: EChartsComponent, isStandalone: true, selector: "app-e-charts", inputs: { loading: "loading", options: "options" }, outputs: { chartClick: "chartClick" }, providers: [
            provideEchartsCore({ echarts }),
        ], usesOnChanges: true, ngImport: i0, template: "@if (chartOption ) {\r\n<div echarts style=\"height:338px;\" (chartClick)=\"onChartClick($event)\" [options]=\"chartOption\" [loading]=\"loading\"\r\n    class=\"chart\"></div>\r\n}", styles: [""], dependencies: [{ kind: "ngmodule", type: NgxEchartsModule }, { kind: "directive", type: i1.NgxEchartsDirective, selector: "echarts, [echarts]", inputs: ["options", "theme", "initOpts", "merge", "autoResize", "loading", "loadingType", "loadingOpts"], outputs: ["chartInit", "optionsError", "chartClick", "chartDblClick", "chartMouseDown", "chartMouseMove", "chartMouseUp", "chartMouseOver", "chartMouseOut", "chartGlobalOut", "chartContextMenu", "chartHighlight", "chartDownplay", "chartSelectChanged", "chartLegendSelectChanged", "chartLegendSelected", "chartLegendUnselected", "chartLegendLegendSelectAll", "chartLegendLegendInverseSelect", "chartLegendScroll", "chartDataZoom", "chartDataRangeSelected", "chartGraphRoam", "chartGeoRoam", "chartTreeRoam", "chartTimelineChanged", "chartTimelinePlayChanged", "chartRestore", "chartDataViewChanged", "chartMagicTypeChanged", "chartGeoSelectChanged", "chartGeoSelected", "chartGeoUnselected", "chartAxisAreaSelected", "chartBrush", "chartBrushEnd", "chartBrushSelected", "chartGlobalCursorTaken", "chartRendered", "chartFinished"], exportAs: ["echarts"] }, { kind: "ngmodule", type: CommonModule }] }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: EChartsComponent, decorators: [{
            type: Component,
            args: [{ selector: 'app-e-charts', standalone: true, imports: [
                        NgxEchartsModule,
                        CommonModule
                    ], providers: [
                        provideEchartsCore({ echarts }),
                    ], template: "@if (chartOption ) {\r\n<div echarts style=\"height:338px;\" (chartClick)=\"onChartClick($event)\" [options]=\"chartOption\" [loading]=\"loading\"\r\n    class=\"chart\"></div>\r\n}" }]
        }], propDecorators: { loading: [{
                type: Input
            }], options: [{
                type: Input
            }], chartClick: [{
                type: Output
            }] } });

function createADonutChart(id, title, dataSeries) {
    return {
        title,
        id: id,
        chart: {
            toolbox: {
                show: true,
                feature: {
                    mark: { show: true },
                    dataView: { show: true, readOnly: false },
                    restore: { show: true },
                    saveAsImage: { show: true }
                }
            },
            grid: {
                top: 100,
            },
            tooltip: {
                trigger: 'item'
            },
            legend: {
                top: '5%',
                left: 'center'
            },
            series: [{
                    name: title,
                    type: 'pie',
                    radius: ['40%', '70%'],
                    avoidLabelOverlap: false,
                    itemStyle: {
                        borderRadius: 10,
                        borderColor: '#fff',
                        borderWidth: 2
                    },
                    label: {
                        show: true
                    },
                    emphasis: {
                        label: {
                            show: true,
                            fontSize: '40',
                            fontWeight: 'bold'
                        }
                    },
                    labelLine: {
                        lineStyle: {
                            color: '#235894'
                        }
                    },
                    data: dataSeries
                }],
        }
    };
}
function createABarChart(id, title, dataSeries) {
    return {
        title,
        id,
        chart: {
            toolbox: {
                show: true,
                feature: {
                    mark: { show: true },
                    dataView: { show: true, readOnly: false },
                    restore: { show: true },
                    saveAsImage: { show: true }
                }
            },
            tooltip: {
                trigger: 'axis',
                axisPointer: {
                    type: 'shadow'
                }
            },
            grid: {
                left: '3%',
                right: '4%',
                bottom: '3%',
                containLabel: true
            },
            xAxis: [
                {
                    type: 'category',
                    data: dataSeries.map(v => v.name),
                    axisTick: {
                        alignWithLabel: true
                    }
                }
            ],
            yAxis: [
                {
                    type: 'value'
                }
            ],
            series: [
                {
                    name: '',
                    type: 'bar',
                    label: {
                        show: true
                    },
                    emphasis: {
                        label: {
                            show: true,
                            fontSize: '40',
                            fontWeight: 'bold'
                        }
                    },
                    labelLine: {
                        lineStyle: {
                            color: '#235894'
                        }
                    },
                    data: dataSeries.map((v, index) => ({
                        ...v,
                        itemStyle: {
                            color: getColors(dataSeries.length)[index]
                        }
                    }))
                }
            ],
        },
    };
}
function createRoseTypeChart(id, title, dataSeries) {
    return {
        title,
        id,
        chart: {
            legend: {
                top: 'bottom'
            },
            toolbox: {
                show: true,
                feature: {
                    mark: { show: true },
                    dataView: { show: true, readOnly: false },
                    restore: { show: true },
                    saveAsImage: { show: true }
                }
            },
            series: [
                {
                    name: title,
                    type: 'pie',
                    radius: [50, 250],
                    center: ['50%', '50%'],
                    roseType: 'area',
                    itemStyle: {
                        borderRadius: 8
                    },
                    data: dataSeries
                }
            ]
        }
    };
}
function createAPolarChart(id, title, dataSeries) {
    return {
        title,
        id,
        chart: {
            title: [
                {
                    text: title
                }
            ],
            toolbox: {
                show: true,
                feature: {
                    mark: { show: true },
                    dataView: { show: true, readOnly: false },
                    restore: { show: true },
                    saveAsImage: { show: true }
                }
            },
            polar: {
                radius: [30, '80%']
            },
            angleAxis: {
                startAngle: 75
            },
            radiusAxis: {
                type: 'category',
                data: dataSeries.map(v => v.name)
            },
            tooltip: {},
            series: {
                type: 'bar',
                data: dataSeries.map(v => v.value),
                coordinateSystem: 'polar',
                label: {
                    show: true,
                    position: 'middle',
                    formatter: '{b}: {c}'
                }
            }
        }
    };
}
const colors = [
    '#4285F4',
    '#FBBC05',
    '#34A853',
    '#EA4335',
    '#55ACEE',
    '#3B5998',
    '#7CBB00',
    '#00A1F1',
    '#7B0099',
    '#146EB4'
];
function getColors(n) {
    const result = [];
    for (let i = 0; i < n; i++) {
        result.push(colors[i % colors.length]);
    }
    return result;
}

class GroupingChartComponent {
    constructor() {
        this.groups = [];
        this.numberProperties = [];
        this.lastHash = null;
        this.chartConfig = {};
        this.chatTypesEnum = ChartTypes;
    }
    get totalDistributionPerGroup() {
        // Create a hash or identifier based on the content of the groups to detect changes
        const currentHash = JSON.stringify(this.groups);
        if (this.lastHash === currentHash && this.cache) {
            // If the hash hasn't changed, return the cached result
            return this.cache;
        }
        // Compute the distribution if data has changed
        const result = this.numberProperties?.map((property, index) => ({
            title: property.label,
            id: index.toString(),
            dataSeries: this.groups.map(g => ({
                name: g.name,
                value: Number(g.totals?.[property.formControlName] || 0)
            }))
        }))
            .map(chart => {
            const type = this.chartConfig[chart.id]?.chartType || ChartTypes.Donut;
            if (type === ChartTypes.Donut || !type) {
                return createADonutChart(chart.id, chart.title, chart.dataSeries);
            }
            if (type === ChartTypes.Bar) {
                return createABarChart(chart.id, chart.title, chart.dataSeries);
            }
            if (type === ChartTypes.Polar) {
                return createAPolarChart(chart.id, chart.title, chart.dataSeries);
            }
            if (type === ChartTypes.RoseType) {
                return createRoseTypeChart(chart.id, chart.title, chart.dataSeries);
            }
            return;
        });
        // Update cache and hash
        this.cache = result;
        this.lastHash = currentHash;
        return result;
    }
    isExpanded() {
        return this.chartConfig[this.activeChart || '']?.full;
    }
    chartType() {
        return this.chartConfig[this.activeChart || '']?.chartType;
    }
    setChartType(type) {
        if (!this.chartConfig[this.activeChart || '']) {
            this.chartConfig[this.activeChart || ''] = {
                full: false,
                chartType: this.chatTypesEnum.Donut
            };
        }
        if (!this.chartConfig[this.activeChart || ''])
            return;
        this.chartConfig[this.activeChart || '']['chartType'] = type;
        this.lastHash = null;
    }
    toggleExpansion() {
        const st = !!this.chartConfig[this.activeChart || '']?.full;
        if (!this.chartConfig[this.activeChart || '']) {
            this.chartConfig[this.activeChart || ''] = {
                full: false,
                chartType: this.chatTypesEnum.Donut
            };
        }
        if (!this.chartConfig[this.activeChart || ''])
            return;
        return this.chartConfig[this.activeChart || ''].full = !st;
    }
    getChartSize(id) {
        return this.chartConfig[id]?.full ? '12' : '4';
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: GroupingChartComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
    static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.14", type: GroupingChartComponent, isStandalone: true, selector: "app-grouping-chart", inputs: { groups: "groups", numberProperties: "numberProperties" }, ngImport: i0, template: "<section style=\"background: var(--mat-sys-surface-container);\">\r\n\r\n\r\n    <div class=\"row\">\r\n        @for (chart of totalDistributionPerGroup||[]; track chart.id) {\r\n        <div *ngIf=\"!!chart\" class=\"chart-container\" [class]=\"'col-md-'+getChartSize(chart.id)\">\r\n            <mat-card (mouseover)=\"activeChart = chart.id\">\r\n                <mat-card-header>\r\n                    <mat-card-title>\r\n                        <h4>\r\n                            {{chart.title}}\r\n                            <button [matMenuTriggerFor]=\"menu\" style=\"position: absolute;right: 24px;top:24px\"\r\n                                mat-icon-button>\r\n                                <mat-icon>\r\n                                    more_vert\r\n                                </mat-icon>\r\n                            </button>\r\n                        </h4>\r\n\r\n                    </mat-card-title>\r\n\r\n                </mat-card-header>\r\n                <mat-card-content>\r\n                    <app-e-charts [options]=\"chart.chart\">\r\n\r\n                    </app-e-charts>\r\n                </mat-card-content>\r\n\r\n            </mat-card>\r\n        </div>\r\n        }\r\n\r\n    </div>\r\n</section>\r\n\r\n<mat-menu #menu=\"matMenu\">\r\n    <h5> Chart settings </h5>\r\n    <button (click)=\"toggleExpansion()\" mat-menu-item>\r\n        <mat-icon>{{isExpanded()?'close_fullscreen':'open_in_full'}} </mat-icon>\r\n        <span> {{isExpanded()?'Close full view':'View in full size' }}</span>\r\n    </button>\r\n    <h5> Chart type </h5>\r\n    <button (click)=\"setChartType(chatTypesEnum.Donut)\" mat-menu-item>\r\n        <mat-icon [color]=\"chartType() ===chatTypesEnum.Donut|| !chartType()?'primary':''\">donut_large</mat-icon>\r\n        <span [style.font-weight]=\"chartType() ===chatTypesEnum.Donut|| !chartType()?'bold':''\">Donut chart</span>\r\n    </button>\r\n    <button (click)=\"setChartType(chatTypesEnum.Bar)\" mat-menu-item>\r\n        <mat-icon [color]=\"chartType() ===chatTypesEnum.Bar?'primary':''\">bar_chart</mat-icon>\r\n        <span [style.font-weight]=\"chartType() ===chatTypesEnum.Bar?'bold':''\">bar</span>\r\n    </button>\r\n    <button (click)=\"setChartType(chatTypesEnum.Polar)\" mat-menu-item>\r\n        <mat-icon [color]=\"chartType() ===chatTypesEnum.Polar?'primary':''\">radar</mat-icon>\r\n        <span [style.font-weight]=\"chartType() ===chatTypesEnum.Bar?'bold':''\">Polar </span>\r\n    </button>\r\n    <button (click)=\"setChartType(chatTypesEnum.RoseType)\" mat-menu-item>\r\n        <mat-icon [color]=\"chartType() ===chatTypesEnum.RoseType?'primary':''\">filter_vintage</mat-icon>\r\n        <span [style.font-weight]=\"chartType() ===chatTypesEnum.Bar?'bold':''\">Rose </span>\r\n    </button>\r\n\r\n</mat-menu>", styles: ["mat-card{margin:5px}h5{margin-left:16px;margin-bottom:10px}.chart-container{padding:0}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: EChartsComponent, selector: "app-e-charts", inputs: ["loading", "options"], outputs: ["chartClick"] }, { kind: "ngmodule", type: MatCardModule }, { kind: "component", type: i1$1.MatCard, selector: "mat-card", inputs: ["appearance"], exportAs: ["matCard"] }, { kind: "directive", type: i1$1.MatCardContent, selector: "mat-card-content" }, { kind: "component", type: i1$1.MatCardHeader, selector: "mat-card-header" }, { kind: "directive", type: i1$1.MatCardTitle, selector: "mat-card-title, [mat-card-title], [matCardTitle]" }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i8.MatIconButton, selector: "button[mat-icon-button]", exportAs: ["matButton"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i7.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatMenuModule }, { kind: "component", type: i5.MatMenu, selector: "mat-menu", inputs: ["backdropClass", "aria-label", "aria-labelledby", "aria-describedby", "xPosition", "yPosition", "overlapTrigger", "hasBackdrop", "class", "classList"], outputs: ["closed", "close"], exportAs: ["matMenu"] }, { kind: "component", type: i5.MatMenuItem, selector: "[mat-menu-item]", inputs: ["role", "disabled", "disableRipple"], exportAs: ["matMenuItem"] }, { kind: "directive", type: i5.MatMenuTrigger, selector: "[mat-menu-trigger-for], [matMenuTriggerFor]", inputs: ["mat-menu-trigger-for", "matMenuTriggerFor", "matMenuTriggerData", "matMenuTriggerRestoreFocus"], outputs: ["menuOpened", "onMenuOpen", "menuClosed", "onMenuClose"], exportAs: ["matMenuTrigger"] }] }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: GroupingChartComponent, decorators: [{
            type: Component,
            args: [{ selector: 'app-grouping-chart', standalone: true, imports: [CommonModule, EChartsComponent, MatCardModule, MatButtonModule, MatIconModule, MatMenuModule], template: "<section style=\"background: var(--mat-sys-surface-container);\">\r\n\r\n\r\n    <div class=\"row\">\r\n        @for (chart of totalDistributionPerGroup||[]; track chart.id) {\r\n        <div *ngIf=\"!!chart\" class=\"chart-container\" [class]=\"'col-md-'+getChartSize(chart.id)\">\r\n            <mat-card (mouseover)=\"activeChart = chart.id\">\r\n                <mat-card-header>\r\n                    <mat-card-title>\r\n                        <h4>\r\n                            {{chart.title}}\r\n                            <button [matMenuTriggerFor]=\"menu\" style=\"position: absolute;right: 24px;top:24px\"\r\n                                mat-icon-button>\r\n                                <mat-icon>\r\n                                    more_vert\r\n                                </mat-icon>\r\n                            </button>\r\n                        </h4>\r\n\r\n                    </mat-card-title>\r\n\r\n                </mat-card-header>\r\n                <mat-card-content>\r\n                    <app-e-charts [options]=\"chart.chart\">\r\n\r\n                    </app-e-charts>\r\n                </mat-card-content>\r\n\r\n            </mat-card>\r\n        </div>\r\n        }\r\n\r\n    </div>\r\n</section>\r\n\r\n<mat-menu #menu=\"matMenu\">\r\n    <h5> Chart settings </h5>\r\n    <button (click)=\"toggleExpansion()\" mat-menu-item>\r\n        <mat-icon>{{isExpanded()?'close_fullscreen':'open_in_full'}} </mat-icon>\r\n        <span> {{isExpanded()?'Close full view':'View in full size' }}</span>\r\n    </button>\r\n    <h5> Chart type </h5>\r\n    <button (click)=\"setChartType(chatTypesEnum.Donut)\" mat-menu-item>\r\n        <mat-icon [color]=\"chartType() ===chatTypesEnum.Donut|| !chartType()?'primary':''\">donut_large</mat-icon>\r\n        <span [style.font-weight]=\"chartType() ===chatTypesEnum.Donut|| !chartType()?'bold':''\">Donut chart</span>\r\n    </button>\r\n    <button (click)=\"setChartType(chatTypesEnum.Bar)\" mat-menu-item>\r\n        <mat-icon [color]=\"chartType() ===chatTypesEnum.Bar?'primary':''\">bar_chart</mat-icon>\r\n        <span [style.font-weight]=\"chartType() ===chatTypesEnum.Bar?'bold':''\">bar</span>\r\n    </button>\r\n    <button (click)=\"setChartType(chatTypesEnum.Polar)\" mat-menu-item>\r\n        <mat-icon [color]=\"chartType() ===chatTypesEnum.Polar?'primary':''\">radar</mat-icon>\r\n        <span [style.font-weight]=\"chartType() ===chatTypesEnum.Bar?'bold':''\">Polar </span>\r\n    </button>\r\n    <button (click)=\"setChartType(chatTypesEnum.RoseType)\" mat-menu-item>\r\n        <mat-icon [color]=\"chartType() ===chatTypesEnum.RoseType?'primary':''\">filter_vintage</mat-icon>\r\n        <span [style.font-weight]=\"chartType() ===chatTypesEnum.Bar?'bold':''\">Rose </span>\r\n    </button>\r\n\r\n</mat-menu>", styles: ["mat-card{margin:5px}h5{margin-left:16px;margin-bottom:10px}.chart-container{padding:0}\n"] }]
        }], ctorParameters: () => [], propDecorators: { groups: [{
                type: Input
            }], numberProperties: [{
                type: Input
            }] } });
var ChartTypes;
(function (ChartTypes) {
    ChartTypes["Donut"] = "donutChart";
    ChartTypes["Bar"] = "bar";
    ChartTypes["Polar"] = "polar";
    ChartTypes["RoseType"] = "roseType";
})(ChartTypes || (ChartTypes = {}));

const COLOR_CODES = {
    secondary: {
        color1: '#FFF5EB', // Very light orange tint (5% of base)
        color2: '#FFEBD6', // Light orange tint (10% of base)
        color3: '#FFE1C2', // Light-medium orange tint (15% of base)
        color4: '#FFD7AD', // Medium orange tint (20% of base)
        color5: '#FFCD99', // Medium-deep orange tint (25% of base)
        color6: '#FFC285', // Deeper orange tint (30% of base)
        color7: '#FFB870', // Even deeper orange tint (35% of base)
        color8: '#F68C1E' // Base color
    },
    blue: {
        color1: '#DAE5FC', // Very light tint (5% of base)
        color2: '#C0D2F9', // Light tint (10% of base)
        color3: '#A6C0F7', // Light-medium tint (15% of base)
        color4: '#8DADF5', // Medium tint (20% of base)
        color5: '#739BF2', // Medium-deep tint (25% of base)
        color6: '#5988F0', // Deeper tint (30% of base)
        color7: '#3F76ED', // Even deeper tint (35% of base)
        color8: '#2563EB', // Base color
    },
    green: {
        color1: '#ECF2DB', // Very light tint (5% of base)
        color2: '#DFE9C2', // Light tint (10% of base)
        color3: '#D2E0A9', // Light-medium tint (15% of base)
        color4: '#C5D790', // Medium tint (20% of base)
        color5: '#B8CE77', // Medium-deep tint (25% of base)
        color6: '#ABC55E', // Deeper tint (30% of base)
        color7: '#9EBC45', // Even deeper tint (35% of base)
        color8: '#91B32C', // Base color
    },
    blueviolet: {
        color1: '#EBDBFA', // Very light tint (5% of base)
        color2: '#DDC2F7', // Light tint (10% of base)
        color3: '#CFA9F3', // Light-medium tint (15% of base)
        color4: '#C290F0', // Medium tint (20% of base)
        color5: '#B477EC', // Medium-deep tint (25% of base)
        color6: '#A65DE9', // Deeper tint (30% of base)
        color7: '#9844E5', // Even deeper tint (35% of base)
        color8: '#8A2BE2', // Base color
    },
    red: {
        color1: '#FDE5E1', // Very light tint (5% of base)
        color2: '#FBD3CB', // Light tint (10% of base)
        color3: '#FAC1B6', // Light-medium tint (15% of base)
        color4: '#F8AFA1', // Medium tint (20% of base)
        color5: '#F79D8B', // Medium-deep tint (25% of base)
        color6: '#F58A76', // Deeper tint (30% of base)
        color7: '#F47860', // Even deeper tint (35% of base)
        color8: '#F2664B', // Base color
    },
    purple: {
        color1: '#E5DDEE', // Very light tint (5% of base)
        color2: '#D3C4E2', // Light tint (10% of base)
        color3: '#C1ACD6', // Light-medium tint (15% of base)
        color4: '#AF94C9', // Medium tint (20% of base)
        color5: '#9D7CBD', // Medium-deep tint (25% of base)
        color6: '#8A63B1', // Deeper tint (30% of base)
        color7: '#784BA5', // Even deeper tint (35% of base)
        color8: '#663399', // Base color
    },
    // Spectrum Harmony - Best for business applications and financial data
    spectrumHarmony: {
        color1: '#E3F2FD', // Light blue - first level
        color2: '#BBDEFB', // Slightly deeper blue
        color3: '#DCEDC8', // Light green - second level
        color4: '#C5E1A5', // Slightly deeper green
        color5: '#FFF9C4', // Light yellow - third level
        color6: '#FFECB3', // Light amber - fourth level
        color7: '#FFE082', // Medium amber
        color8: '#FFCCBC' // Light red/orange - fifth level
    },
    // Vibrant Distinction - Best for complex hierarchical data requiring quick differentiation
    vibrantDistinction: {
        color1: '#E8F5E9', // Mint green - first level
        color2: '#C8E6C9', // Medium mint
        color3: '#E1F5FE', // Light blue - second level
        color4: '#B3E5FC', // Medium light blue
        color5: '#F3E5F5', // Lavender - third level
        color6: '#FFF8E1', // Light amber - fourth level
        color7: '#FFECB3', // Medium amber
        color8: '#FFEBEE' // Light pink - fifth level
    },
    // Natural Progression - Best for environmental data and science applications
    naturalProgression: {
        color1: '#E0F7FA', // Light cyan - first level
        color2: '#B2EBF2', // Medium cyan
        color3: '#C8E6C9', // Light green - second level
        color4: '#A5D6A7', // Medium green
        color5: '#F0F4C3', // Light lime - third level
        color6: '#FFE0B2', // Light orange - fourth level
        color7: '#FFCC80', // Medium orange
        color8: '#FFCDD2' // Light red - fifth level
    },
    // Colorblind-Friendly - Best for accessibility-focused and public-facing applications
    colorblindFriendly: {
        color1: '#F5F5F5', // Light gray - first level
        color2: '#E0E0E0', // Medium light gray
        color3: '#BBDEFB', // Light blue - second level
        color4: '#90CAF9', // Medium light blue
        color5: '#FFECB3', // Light amber - third level
        color6: '#C8E6C9', // Light green - fourth level
        color7: '#A5D6A7', // Medium green
        color8: '#E1BEE7' // Light purple - fifth level
    },
    // Corporate Structure - Best for formal reports and corporate environments
    corporateStructure: {
        color1: '#ECEFF1', // Very light blue-gray - first level
        color2: '#CFD8DC', // Light blue-gray - second level
        color3: '#B0BEC5', // Medium blue-gray - third level
        color4: '#90A4AE', // Medium-dark blue-gray - fourth level
        color5: '#78909C', // Dark blue-gray - fifth level
        color6: '#607D8B', // Deeper blue-gray
        color7: '#546E7A', // Very dark blue-gray
        color8: '#455A64' // Extremely dark blue-gray
    }
};
// You can implement a function to get random color codes similar to the original example
let colorDeck = [];
const randomColorCode = () => {
    // If the deck is empty, refill and shuffle it
    if (colorDeck.length === 0) {
        colorDeck = [...Object.values(COLOR_CODES)];
        // Fisher-Yates shuffle algorithm
        for (let i = colorDeck.length - 1; i > 0; i--) {
            const j = Math.floor(Math.random() * (i + 1));
            [colorDeck[i], colorDeck[j]] = [colorDeck[j], colorDeck[i]];
        }
    }
    // Take the top color from our shuffled deck
    return colorDeck.pop();
};

var SectionTypeGroups;
(function (SectionTypeGroups) {
    SectionTypeGroups["Transactions"] = "transactions";
    SectionTypeGroups["Processes"] = "processes";
    SectionTypeGroups["System"] = "system";
    SectionTypeGroups["FormPreview"] = "formPreview";
    SectionTypeGroups["Home"] = "home";
    SectionTypeGroups["Transaction"] = "transaction";
    SectionTypeGroups["Report"] = "Report";
})(SectionTypeGroups || (SectionTypeGroups = {}));
var DocumentLitsLabelConfigInterfaceValueType;
(function (DocumentLitsLabelConfigInterfaceValueType) {
    DocumentLitsLabelConfigInterfaceValueType["currency"] = "currency";
    DocumentLitsLabelConfigInterfaceValueType["number"] = "number";
    DocumentLitsLabelConfigInterfaceValueType["string"] = "string";
    DocumentLitsLabelConfigInterfaceValueType["date"] = "date";
    DocumentLitsLabelConfigInterfaceValueType["daysAgo"] = "daysAgo";
    DocumentLitsLabelConfigInterfaceValueType["systemReference"] = "systemReference";
})(DocumentLitsLabelConfigInterfaceValueType || (DocumentLitsLabelConfigInterfaceValueType = {}));

/**
 * Compares previous and current objects, returning only properties that changed.
 * - Properties in prev but not in current: set to undefined
 * - Properties in current but not in prev: included with current value
 * - Properties in both with different values: included with current value
 *
 * @example
 * // prev = {a: 8, b: 0}, current = {b: 5}
 * // result = {b: 5, a: undefined}
 */
function getChangedProperties(prevPassed, currentPassed) {
    // Handle edge cases
    // remove undefined in prev 
    const prev = prevPassed ? Object.keys(prevPassed).reduce((acc, key) => {
        if (prevPassed[key] !== undefined) {
            acc[key] = prevPassed[key];
        }
        return acc;
    }, {}) : undefined;
    // remove undefined in current
    const current = currentPassed ? Object.keys(currentPassed).reduce((acc, key) => {
        if (currentPassed[key] !== undefined) {
            acc[key] = currentPassed[key];
        }
        return acc;
    }, {}) : undefined;
    // if both are undefined return empty object
    if (!prev && !current)
        return {};
    if (!prev)
        return { ...current };
    if (!current) {
        return Object.keys(prev).reduce((acc, key) => {
            acc[key] = undefined;
            return acc;
        }, {});
    }
    const changedProperties = {};
    // Check properties from prev
    for (const key in prev) {
        if (!(key in current)) {
            // Property removed in current
            changedProperties[key] = undefined;
        }
        else if (!_isEqual(prev[key], current[key])) {
            // Property value changed
            changedProperties[key] = current[key];
        }
    }
    // Check for new properties in current
    for (const key in current) {
        if (!(key in prev)) {
            // New property added
            changedProperties[key] = current[key];
        }
    }
    return changedProperties;
}
function _isEqual(prev, next) {
    if (prev === next)
        return true;
    const prevType = typeof prev;
    const nextType = typeof next;
    if (prevType !== nextType)
        return false;
    if (prevType === 'number') {
        return (prev === next) || (Number.isNaN(prev) && Number.isNaN(next));
    }
    if (prevType === 'string' || prevType === 'boolean') {
        return prev === next;
    }
    if (Array.isArray(prev) && Array.isArray(next)) {
        if (prev.length !== next.length)
            return false;
        for (let i = 0; i < prev.length; i++) {
            if (!_isEqual(prev[i], next[i]))
                return false;
        }
        return true;
    }
    if (prevType === 'object' && prev !== null && next !== null) {
        const prevConstructor = prev.constructor;
        const nextConstructor = next.constructor;
        if (prevConstructor !== nextConstructor)
            return false;
        if (prevConstructor === Date) {
            return prev.getTime() === next.getTime();
        }
        if (prevConstructor === RegExp) {
            return prev.source === next.source && prev.flags === next.flags;
        }
        const prevKeys = Object.keys(prev);
        const nextKeys = Object.keys(next);
        if (prevKeys.length !== nextKeys.length)
            return false;
        for (const key of prevKeys) {
            if (!Object.prototype.hasOwnProperty.call(next, key))
                return false;
            if (!_isEqual(prev[key], next[key]))
                return false;
        }
        return true;
    }
    return prev === null && next === null;
}

function groupData(items, keys, level = 0) {
    if (keys.length === 0)
        return new Map([[level, items]]); // No more keys, return items wrapped in a Map
    const key = keys[0];
    if (!key)
        return new Map([[level, items]]);
    const restKeys = keys.slice(1);
    const grouped = new Map();
    for (const item of items) {
        const keyValue = item[key];
        if (!grouped.has(keyValue)) {
            grouped.set(keyValue, []);
        }
        grouped.get(keyValue).push(item);
    }
    if (restKeys.length > 0) {
        grouped.forEach((value, key) => {
            grouped.set(key, groupData(value, restKeys, level + 1));
        });
    }
    return grouped;
}
function matrixTableGroupedData(array, propertyName, closedGroups, listConfig) {
    // Use a Map to handle grouping which can be more efficient for lookups and updates
    const numberProperties = listConfig.filter((config) => config.valueType === 'number'
        || config.valueType === 'currency').map((config) => config.formControlName);
    const noneEmptyPropertyNames = propertyName.filter(n => !!n && (n.length > 0));
    const noneEmptyArray = array.filter(a => !!a && Object.keys(a).length > 0);
    const groupedData = groupData(noneEmptyArray, noneEmptyPropertyNames);
    const result = flattenGroupedData(groupedData, propertyName);
    return result;
    function getSums(data) {
        if (!Array.isArray(data)) {
            return {};
        }
        const sums = {
            IS_SUM_ROW: true
        };
        numberProperties.forEach((property) => {
            sums[property] = `${data.reduce((acc, item) => acc + Number(item[property] || 0), 0)}`;
        });
        return sums;
    }
    function flattenGroupedData(grouped, keys, currentLevel = 0) {
        let result = [];
        if (keys.length === currentLevel) {
            return Array.from(grouped.values()).flat();
        }
        grouped.forEach((value, key) => {
            const isClosed = closedGroups.includes(key);
            let _data = [];
            _data = flattenGroupedData(value, keys, currentLevel + 1);
            const objectProperty = propertyName[currentLevel];
            const propertyConfig = listConfig.find(l => l.formControlName === objectProperty);
            const groupConfig = {
                name: key,
                propertyLabel: propertyConfig?.label || objectProperty || '',
                IS_GROUP_CONFIG: true,
                LEVELS_BEFORE: Array.from({ length: currentLevel }, (_, i) => i + 1),
                level: currentLevel,
                totals: getSums(_data),
                IS_CLOSED: isClosed
            };
            result.push(groupConfig);
            result = result.concat(isClosed ? [] : _data);
        });
        return result;
    }
}

function NgxTMatrixTableStoreSelectors(store) {
    const state$ = store.select(state => state);
    const reportName$ = store.select(state => state.reportName);
    const list$ = store.select(state => state.list);
    const listConfig$ = store.select(state => state.listConfig);
    const aggregates$ = store.select(state => state.aggregates);
    const groupOptions$ = store.select(state => state.groupOptions);
    const closedGroups$ = store.select(state => state.closedGroups);
    const isOpen$ = store.select(state => state.isOpen);
    const groupChart$ = store.select(state => state.groupChart);
    const draggedGroup$ = store.select(state => state.draggedGroup);
    const scrollIndex$ = store.select(state => state.scrollIndex);
    const tableColumns$ = listConfig$;
    let itemsToDisplay = 0;
    combineLatest([
        groupOptions$,
        listConfig$
    ])
        .pipe(map(([groupOptions, listConfig]) => [{ formControlName: 'tree', label: '' }, ...listConfig || []]
        .filter((col) => !col.isHidden).map((col) => ({
        ...col,
        INCLUDED_IN_GROUP: Boolean(groupOptions?.columns?.includes(col.formControlName))
    }))));
    const displayedColumns$ = tableColumns$.pipe(map(tableColumns => tableColumns?.map((config) => config.formControlName) || []));
    const groupLabelConfig$ = groupOptions$.pipe(map(groupOptions => groupOptions?.columns?.map((col, index) => ({ level: index, formControlName: index.toString(), label: '' })) || []));
    const getGroupedData$ = combineLatest([list$,
        listConfig$,
        groupOptions$,
        closedGroups$,
        scrollIndex$]).pipe(map(([list, listConfig, groupOptions, closedGroups, scrollIndex]) => {
        const groupBy = groupOptions?.columns || [];
        const data = matrixTableGroupedData(list || [], groupBy, closedGroups, listConfig || []);
        const filteredData = data.filter(d => !(d.name === undefined && d.IS_GROUP_CONFIG));
        const numberOfFilteredItems = filteredData.length;
        const pageSize = 100; // Define your desired multiple
        if (numberOfFilteredItems === 0) {
            return filteredData.slice(0, 0);
        }
        if (scrollIndex <= pageSize) {
            return filteredData.slice(0, pageSize);
        }
        itemsToDisplay = Math.ceil((scrollIndex + 1) / pageSize) * pageSize;
        return filteredData.slice(0, itemsToDisplay);
    }));
    const groupedColumns$ = combineLatest([
        groupOptions$,
        listConfig$
    ]).pipe(map(([groupOptions, listConfig]) => (groupOptions?.columns?.filter((col) => !groupOptions.hiddenColumns?.includes(col)) || []).map(groupCol => ({
        formControlName: groupCol,
        label: listConfig?.find((config) => config.formControlName === groupCol)?.label || ''
    }))));
    return {
        state$,
        reportName$,
        list$,
        listConfig$,
        closedGroups$,
        isOpen$,
        aggregates$,
        groupOptions$,
        tableColumns$,
        displayedColumns$,
        groupLabelConfig$,
        getGroupedData$,
        groupedColumns$,
        groupChart$,
        draggedGroup$,
        scrollIndex$
    };
}

function NgxTMatrixTableStoreActions(store) {
    return {
        setReportName: store.updater((state, reportName) => ({
            ...state,
            reportName
        })),
        setList: store.updater((state, list) => ({
            ...state,
            list
        })),
        setListConfig: store.updater((state, listConfig) => ({
            ...state,
            listConfig
        })),
        setAggregates: store.updater((state, aggregates) => ({
            ...state,
            aggregates
        })),
        setGroupOptions: store.updater((state, groupOptions) => ({
            ...state,
            groupOptions
        })),
        toggleMenu: store.updater((state, row) => ({
            ...state,
            isOpen: _isEqual(state.isOpen, row) ? undefined : row
        })),
        setGroupChart: store.updater((state, groupChart) => ({
            ...state,
            groupChart
        })),
        setDraggedGroup: store.updater((state, draggedGroup) => ({
            ...state,
            draggedGroup
        })),
        setScrollIndex: store.updater((state, scrollIndex) => ({
            ...state,
            scrollIndex
        })),
        toggleCloseGroup: store.updater((state, name) => {
            const closedGroups = state.closedGroups || [];
            const isClosed = closedGroups.includes(name);
            return {
                ...state,
                closedGroups: isClosed ? closedGroups.filter(g => g !== name) : [...closedGroups, name]
            };
        }),
        removeGroupColumn: store.updater((state, columnName) => {
            return {
                ...state,
                groupOptions: state.groupOptions ? {
                    ...state.groupOptions,
                    columns: state.groupOptions.columns?.filter((col) => col !== columnName)
                } : null
            };
        }),
        dropGroupColumn: store.updater((state) => {
            const newGroup = state.draggedGroup;
            const doesNotInclude = !state.groupOptions?.columns?.includes(newGroup || '');
            if (doesNotInclude && newGroup !== undefined && newGroup !== '') {
                return {
                    ...state,
                    groupOptions: {
                        ...state.groupOptions,
                        columns: [...(state.groupOptions?.columns || []), newGroup]
                    }
                };
            }
            return state;
        }),
        dropGroupingToSortGroups: store.updater((state, event) => {
            const newColumns = [...(state.groupOptions?.columns || [])];
            moveItemInArray(newColumns, event.previousIndex, event.currentIndex);
            return {
                ...state,
                groupOptions: {
                    ...state.groupOptions,
                    columns: newColumns
                }
            };
        }),
        addToGrouping: store.updater((state, formControlName) => {
            let columns = state.groupOptions?.columns || [];
            if (!columns.includes(formControlName)) {
                columns = [...columns, formControlName];
            }
            else {
                columns = columns.filter((col) => col !== formControlName);
            }
            return {
                ...state,
                groupOptions: {
                    ...state.groupOptions,
                    columns
                }
            };
        })
    };
}

function toCamelCase(arrayOfObjects) {
    return arrayOfObjects.map((obj) => {
        const newObj = {};
        Object.keys(obj).forEach((key) => {
            const newKey = ''.concat(key);
            const camelCaseKey = camelize(newKey);
            newObj[camelCaseKey] = obj[key];
        });
        return newObj;
    });
}
function camelize(str) {
    if (!!str) {
        return str
            .replace(/(?:^\w|[A-Z]|\b\w)/g, function (word, index) {
            return index === 0 ? word.toLowerCase() : word.toUpperCase();
        })
            .replace(/\s+/g, '');
    }
    else {
        return;
    }
}

const getFileName = (name) => {
    let timeSpan = new Date().toISOString();
    let sheetName = name || 'ExportResult';
    let fileName = `${sheetName}-${timeSpan}`;
    return {
        sheetName,
        fileName,
    };
};
class TableUtil {
    static exportTableToExcel(tableId, name) {
        let { sheetName, fileName } = getFileName(name);
        let targetTableElm = document.getElementById(tableId);
        let wb = XLSX.utils.table_to_book(targetTableElm, {
            sheet: sheetName,
        });
        XLSX.writeFile(wb, `${fileName}.xlsx`);
    }
    static exportArrayToExcel(arr, name) {
        const { sheetName, fileName } = getFileName(name);
        const wb = XLSX.utils.book_new();
        // Process the main array
        const mainArray = arr.map(item => this.processSimpleObject(item));
        const mainSheet = XLSX.utils.json_to_sheet(mainArray);
        XLSX.utils.book_append_sheet(wb, mainSheet, this.sanitizeSheetName(sheetName));
        // Process nested arrays
        arr.forEach((item, index) => {
            const arrayProperties = this.findArrayProperties(item);
            arrayProperties.forEach((arrayData, propertyName) => {
                // Only process if the array contains data
                if (arrayData.length > 0) {
                    // Create a sheet name combining property name and parent index
                    const nestedSheetName = this.sanitizeSheetName(`${propertyName}_${index + 1}`);
                    // Process the nested array items
                    const processedArray = arrayData.map(nestedItem => {
                        if (typeof nestedItem === 'object' && nestedItem !== null) {
                            return this.processSimpleObject(nestedItem);
                        }
                        // If it's a primitive value, wrap it in an object
                        return { value: nestedItem };
                    });
                    // Create and append the sheet if it has data
                    if (processedArray.length > 0) {
                        const nestedSheet = XLSX.utils.json_to_sheet(processedArray);
                        try {
                            XLSX.utils.book_append_sheet(wb, nestedSheet, nestedSheetName);
                        }
                        catch (e) {
                            const msg = e instanceof Error ? e.message : 'Unknown error';
                            console.warn(`Could not create sheet for ${nestedSheetName}: ${msg}`);
                        }
                    }
                }
            });
        });
        // Write the workbook to file
        XLSX.writeFile(wb, `${fileName}.xlsx`);
    }
    static onFileChange(event) {
        return new Promise((resolve, reject) => {
            try {
                const target = event.target;
                if (target.files.length !== 1)
                    throw new Error('Cannot use multiple files');
                const reader = new FileReader();
                reader.onload = (e) => {
                    const bstr = e.target.result;
                    const workbook = XLSX.read(bstr, { type: 'binary' });
                    const firstSheetName = workbook.SheetNames[0];
                    if (!firstSheetName)
                        throw new Error('No sheet found');
                    const worksheet = workbook.Sheets[firstSheetName];
                    if (!worksheet)
                        throw new Error('No worksheet found');
                    const arrayData = XLSX.utils.sheet_to_json(worksheet, { raw: false });
                    // Iterate through each row and format date cells
                    arrayData.forEach((row) => {
                        for (const key in row) {
                            if (row.hasOwnProperty(key) &&
                                typeof row[key] === 'number' &&
                                XLSX.SSF.isValidDate(row[key])) {
                                row[key] = XLSX.SSF.format_date(row[key], 'yyyy-mm-dd');
                            }
                        }
                    });
                    // Do something with arrayData
                    resolve(toCamelCase(arrayData));
                };
                reader.onerror = (e) => reject(e);
                const file = target.files[0];
                if (!file)
                    throw new Error('No file found');
                reader.readAsBinaryString(file);
            }
            catch (error) {
                reject(error);
            }
        });
    }
    static processSimpleObject(obj) {
        const newObj = {};
        for (const key in obj) {
            if (typeof obj[key] === 'object' && obj[key] !== null) {
                // If it's not an array, convert to string
                if (!Array.isArray(obj[key])) {
                    newObj[key] = JSON.stringify(obj[key]);
                }
                // Arrays will be handled separately, so we skip them here
            }
            else {
                newObj[key] = obj[key];
            }
        }
        return newObj;
    }
    static findArrayProperties(obj) {
        const arrayProps = new Map();
        for (const key in obj) {
            if (Array.isArray(obj[key])) {
                arrayProps.set(key, obj[key]);
            }
        }
        return arrayProps;
    }
    static sanitizeSheetName(name) {
        // Excel sheet names can't exceed 31 characters and can't contain certain characters
        return name.replace(/[\[\]\*\/\\\?\:]/g, '_').substring(0, 31);
    }
}

function NgxTMatrixTableStoreEffects(store) {
    const exportData = store.effect((trigger$) => trigger$.pipe(switchMap(() => combineLatest([
        store.selectors.getGroupedData$,
        store.selectors.reportName$
    ]).pipe(tap(([data, reportName]) => {
        TableUtil.exportArrayToExcel(data || [], reportName || 'report');
    })))));
    const mainShowChart = store.effect((trigger$) => trigger$.pipe(switchMap(() => combineLatest([
        store.selectors.getGroupedData$,
        store.selectors.listConfig$,
        store.selectors.groupOptions$
    ]).pipe(tap(([data, listConfig, groupOptions]) => {
        const mainGroups = data.filter(row => !!row?.IS_GROUP_CONFIG && row?.level === 0);
        const numberProperties = listConfig?.filter((config) => config.valueType === 'number' || config.valueType === 'currency') || [];
        const groupChart = { groups: mainGroups, numberProperties, mainTitle: groupOptions?.columns?.[0] || '' };
        store.actions.setGroupChart(groupChart);
    })))));
    const showReport = store.effect((row$) => row$.pipe(switchMap((row) => combineLatest([
        store.selectors.getGroupedData$,
        store.selectors.listConfig$
    ]).pipe(tap(([data, listConfig]) => {
        if (!!row?.IS_GROUP_CONFIG && row?.level !== undefined) {
            const i = data.map(d => d?.name).indexOf(row.name);
            const mainGroups = [];
            for (let index = i + 1; index < data.length; index++) {
                const nextRow = data[index];
                if (mainGroups.length === 0 && !nextRow?.IS_GROUP_CONFIG
                    || nextRow?.IS_GROUP_CONFIG && nextRow?.level === row.level
                    || mainGroups.length === 0 && nextRow?.level === row.level) {
                    break;
                }
                if (nextRow?.IS_GROUP_CONFIG && nextRow?.level === row.level + 1) {
                    mainGroups.push(nextRow);
                }
            }
            const numberProperties = listConfig?.filter((config) => config.valueType === 'number' || config.valueType === 'currency') || [];
            const groupChart = {
                groups: mainGroups,
                numberProperties,
                mainTitle: row.propertyLabel + ': ' + row.name
            };
            store.actions.setGroupChart(groupChart);
        }
    })))));
    const foldUnFoldGroup = store.effect((row$) => row$.pipe(switchMap((row) => combineLatest([
        store.selectors.getGroupedData$
    ]).pipe(tap(([data]) => {
        const i = data.map(d => d?.name).indexOf(row.name);
        const mainGroups = [];
        for (let index = i + 1; index < data.length; index++) {
            const nextRow = data[index];
            if (mainGroups.length === 0 && !nextRow?.IS_GROUP_CONFIG
                || nextRow?.IS_GROUP_CONFIG && nextRow?.level === row.level
                || mainGroups.length === 0 && nextRow?.level === row.level) {
                break;
            }
            if (nextRow?.IS_GROUP_CONFIG && nextRow?.level === row.level + 1) {
                mainGroups.push(nextRow);
                store.actions.toggleCloseGroup(nextRow.name);
            }
        }
    })))));
    return {
        exportData,
        mainShowChart, foldUnFoldGroup, showReport
    };
}

const initialMscoaState = {
    reportName: null,
    list: null,
    listConfig: null,
    aggregates: null,
    groupOptions: null,
    closedGroups: [],
    isOpen: undefined,
    groupChart: null,
    draggedGroup: '',
    scrollIndex: 0
};
class NgxTMatrixTableStoreService extends ComponentStore {
    constructor() {
        super(initialMscoaState);
        this.selectors = NgxTMatrixTableStoreSelectors(this);
        this.actions = NgxTMatrixTableStoreActions(this);
        this.effects = NgxTMatrixTableStoreEffects(this); // Assuming effects are also part of actions for simplicity
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: NgxTMatrixTableStoreService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
    static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: NgxTMatrixTableStoreService, providedIn: 'root' }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: NgxTMatrixTableStoreService, decorators: [{
            type: Injectable,
            args: [{
                    providedIn: 'root'
                }]
        }], ctorParameters: () => [] });

class NgxTMatrixTableComponent {
    get tableContainerHeight() {
        return this.scrollContainer?.nativeElement.clientHeight;
    }
    set list(value) {
        this.store.actions.setList(value);
    }
    set reportName(value) {
        this.store.actions.setReportName(value);
    }
    set listConfig(value) {
        this.store.actions.setListConfig(value);
    }
    set aggregates(value) {
        this.store.actions.setAggregates(value);
    }
    set groupOptions(value) {
        this.store.actions.setGroupOptions(value);
    }
    constructor(dialog) {
        this.dialog = dialog;
        this.store = inject(NgxTMatrixTableStoreService);
        this.tableColumns$ = this.store.selectors.tableColumns$;
        this.displayedColumns$ = this.store.selectors.displayedColumns$;
        this.groupLabelConfig$ = this.store.selectors.groupLabelConfig$;
        this.groupOptions$ = this.store.selectors.groupOptions$;
        this.getGroupedData$ = this.store.selectors.getGroupedData$;
        this.groupedColumns$ = this.store.selectors.groupedColumns$;
        this.isOpen$ = this.store.selectors.isOpen$;
        this.groupChart$ = this.store.selectors.groupChart$;
        this.closedGroups$ = this.store.selectors.closedGroups$;
        this.draggedGroup$ = this.store.selectors.draggedGroup$;
        this.vm$ = combineLatest([
            this.groupOptions$,
            this.tableColumns$,
            this.displayedColumns$,
            this.groupLabelConfig$,
            this.getGroupedData$.pipe(distinctUntilChanged((prev, curr) => _isEqual(prev, curr))),
            this.groupedColumns$,
            this.isOpen$,
            this.closedGroups$,
            this.groupChart$,
            this.draggedGroup$
        ]).pipe(map(([groupOptions, tableColumns, displayedColumns, groupLabelConfig, getGroupedData, groupedColumns, isOpen, closedGroups, groupChart, draggedGroup]) => ({
            groupOptions,
            tableColumns,
            displayedColumns,
            groupLabelConfig,
            getGroupedData,
            groupedColumns,
            isOpen,
            closedGroups,
            groupChart,
            draggedGroup
        })));
        this.ValueTypes = DocumentLitsLabelConfigInterfaceValueType;
        this.levelColors = randomColorCode();
    }
    ngOnInit() {
        this.setLevelColors();
    }
    // @HostListener('document:click', ['$event'])
    // onClickOutside(event: Event) {
    //   if (!this.elementRef.nativeElement.contains(event.target)) {
    //     this.isOpen = undefined
    //   }
    // }
    toggleMenu(row) {
        this.store.actions.toggleMenu(row);
    }
    remove(groupCol) {
        this.store.actions.removeGroupColumn(groupCol);
    }
    drop(event) {
        this.store.actions.dropGroupColumn();
    }
    export() {
        this.store.effects.exportData(of());
    }
    dropChip(event) {
        this.store.actions.dropGroupingToSortGroups(event);
    }
    addToGrouping(formControlName) {
        this.store.actions.addToGrouping(formControlName);
    }
    toggleCloseGroup(name) {
        this.store.actions.toggleCloseGroup(name);
    }
    mainShowChart() {
        this.store.effects.mainShowChart(of());
    }
    foldUnFoldGroup(row) {
        this.store.effects.foldUnFoldGroup(row);
    }
    setDraggedGroup(col) {
        this.store.actions.setDraggedGroup(col);
    }
    showReport(row) {
        this.store.effects.showReport(of(row));
    }
    // Coding 
    setLevelColors() {
        // Set the CSS variables
        Object.keys(this.levelColors).forEach((key, index) => {
            document.body.style.setProperty(`--custom-level-color-${index + 1}`, this.levelColors[key]);
        });
    }
    get colorPalletArray() {
        const colors = COLOR_CODES;
        return Object.values(colors).map(v => Object.values(v));
    }
    selectColor(colors) {
        const c = colors.reduce((acc, color, index) => {
            acc[`color${index + 1}`] = color;
            return acc;
        }, {});
        this.updateColors(c);
    }
    // Method to update colors dynamically
    updateColors(newColors) {
        this.levelColors = { ...this.levelColors, ...newColors };
        this.setLevelColors();
    }
    scrollIndex(event) {
        this.store.actions.setScrollIndex(event);
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: NgxTMatrixTableComponent, deps: [{ token: i1$2.MatDialog }], target: i0.ɵɵFactoryTarget.Component }); }
    static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.14", type: NgxTMatrixTableComponent, isStandalone: true, selector: "app-ngx-t-matrix-table", inputs: { list: "list", reportName: "reportName", listConfig: "listConfig", aggregates: "aggregates", groupOptions: "groupOptions" }, providers: [NgxTMatrixTableStoreService,], viewQueries: [{ propertyName: "scrollContainer", first: true, predicate: ["viewPortScroll"], descendants: true }], ngImport: i0, template: "<ng-container *ngIf=\"( vm$ |async) as vm\">\r\n\r\n  @if (\r\n  !!vm.groupChart\r\n  ) {\r\n\r\n  <mat-toolbar class=\"chartToolbar\">\r\n    <h1 style=\"    font-weight: bold;\r\n        font-size: 1.4rem; \r\n        text-transform: capitalize;\">\r\n      {{vm.groupChart.mainTitle}}\r\n    </h1>\r\n    <span class=\"spacer\"></span>\r\n    <button (click)=\"vm.groupChart = null\" mat-stroked-button>\r\n      Close\r\n      <mat-icon>\r\n        close\r\n      </mat-icon>\r\n    </button>\r\n  </mat-toolbar>\r\n\r\n\r\n\r\n  <mat-divider></mat-divider>\r\n  <br>\r\n  <app-grouping-chart [groups]=\"vm.groupChart.groups\"\r\n    [numberProperties]=\"vm.groupChart.numberProperties\"></app-grouping-chart>\r\n  }@else {\r\n\r\n\r\n  <section class=\"tableContainer\" #tableContainer>\r\n  <mat-toolbar style=\"background: none;\" (cdkDropListDropped)=\"dropChip($event)\"\r\n    [cdkDropListData]=\"vm.groupOptions?.columns ||[]\" cdkDropList>\r\n\r\n\r\n    @for(groupCol of vm.groupedColumns; track groupCol){\r\n    <mat-chip-option color=\"tertiary\" class=\"dragBox\" [style.margin-left]=\"$index !==0? '5px':''\" cdkDrag selected\r\n      (removed)=\"remove(groupCol.formControlName)\">\r\n      <div class=\"placeholder\" *cdkDragPlaceholder></div>\r\n      {{ groupCol.label }}\r\n      <button matChipRemove [attr.aria-label]=\"'remove ' + groupCol.label\">\r\n        <mat-icon color=\"warn\">cancel</mat-icon>\r\n      </button>\r\n    </mat-chip-option>\r\n    }\r\n    @if (vm.groupedColumns.length === 0) {\r\n\r\n    <div\r\n      style=\"font-size: 14px; font-weight: 400; opacity: 0.7; padding: 8px; color: #666; display: flex; align-items: center;\">\r\n      Drag column headers here to group your data\r\n    </div>\r\n\r\n\r\n    }\r\n\r\n\r\n    <span class=\"spacer\"></span>\r\n\r\n    <button [matMenuTriggerFor]=\"colorPallet\" mat-icon-button matTooltip=\"Select table color coding\">\r\n      <mat-icon>\r\n        palette\r\n      </mat-icon>\r\n    </button>\r\n\r\n    <button (click)=\"mainShowChart()\" mat-icon-button matTooltip=\"Show main grouping chart analytics\">\r\n      <mat-icon>\r\n        analytics\r\n      </mat-icon>\r\n    </button>\r\n    <button (click)=\"export()\" mat-icon-button matTooltip=\"Export to excel\">\r\n      <mat-icon>\r\n        download\r\n      </mat-icon>\r\n    </button>\r\n\r\n  </mat-toolbar>\r\n\r\n\r\n    @defer (on viewport; prefetch on idle) {\r\n    <cdk-virtual-scroll-viewport (scrolledIndexChange)=\"scrollIndex($event)\" \r\n    #viewPortScroll [itemSize]=\"30\"\r\n      style=\"resize: vertical;height:400px;\" >\r\n      <table (cdkDropListDropped)=\"drop($event)\" \r\n      [multiTemplateDataRows]=\"true\"\r\n      cdkDropList mat-table [dataSource]=\"vm.getGroupedData||[]\"\r\n        style=\"border-collapse: collapse;\" class=\"example-table\" matSort matSortActive=\"created\" matSortDisableClear\r\n        matSortDirection=\"desc\">\r\n        @for (col of vm.tableColumns||[]; track col.formControlName) {\r\n        <ng-container [matColumnDef]=\"col.formControlName\">\r\n          <th cdkDrag (cdkDragStarted)=\"setDraggedGroup(col.formControlName)\"\r\n            [attr.data-column-size]=\"col.formControlName\"\r\n            style=\"width: fit-content !important; white-space: nowrap !important;\" mat-header-cell *matHeaderCellDef>\r\n            @if($index === 0 && vm.closedGroups.length > 0){\r\n            <button class=\"cancelGrouping\" (click)=\"vm.closedGroups= []\" color=\"warn\" mat-icon-button>\r\n              <mat-icon>highlight_off</mat-icon>\r\n            </button>\r\n            } @else {\r\n            <div class=\"colTitle\" style=\"display: inline-flex; align-items: center;\"\r\n              [style.color]=\"col.INCLUDED_IN_GROUP?'':''\" [matTooltip]=\"'Click to group by '+col.label\"\r\n              (click)=\"addToGrouping(col.formControlName)\" matRipple>\r\n              {{col.label}}\r\n            </div>\r\n            }\r\n          </th>\r\n          <td mat-cell style=\"\r\n        width: fit-content !important;\r\n        white-space: nowrap !important;\" [style.border-top]=\"!!row?.IS_SUM_ROW && $index !==0? '1px solid black':''\"\r\n            [style.border-bottom-color]=\"!!row?.IS_GROUP_CONFIG ?'#ffffff00':''\"\r\n            [style.background]=\"!!row?.IS_GROUP_CONFIG?'':'none'\"\r\n            [style.overflow]=\"!!row?.IS_GROUP_CONFIG ?'visible':''\" *matCellDef=\"let row\">\r\n\r\n            @if (!!row?.IS_GROUP_CONFIG ) {\r\n            @if( $index ===0){\r\n            <div disabled=\"true\" class=\"levelClass\" *ngFor=\"let item of row.LEVELS_BEFORE\" mat-button>\r\n              <span>- <div class=\"verticalCenterLine\"></div></span>\r\n            </div>\r\n            <button (click)=\"toggleCloseGroup(row['name']);\" mat-button>\r\n              <mat-icon>{{row['IS_CLOSED'] ?'keyboard_arrow_right':'keyboard_arrow_down'}}</mat-icon>\r\n              <span\r\n                style=\"color: var(--mat-table-header-headline-color, var(--mat-sys-on-surface, rgba(0, 0, 0, 0.87)));\">\r\n                {{row['name']}}\r\n              </span>\r\n            </button>\r\n\r\n            <span class=\"rowMenu\">\r\n              <button [color]=\"vm.isOpen?.name === row?.name && vm.isOpen?.level === row.level?'warn':''\"\r\n                class=\"groupOptions\" mat-icon-button (click)=\"toggleMenu(row)\">\r\n\r\n                <mat-icon>\r\n                  {{vm.isOpen?.name === row?.name && vm.isOpen?.level === row.level? 'close':'more_horiz'}}\r\n                </mat-icon>\r\n              </button>\r\n              @if(vm.isOpen?.name === row?.name && vm.isOpen?.level === row.level){\r\n              <button (click)=\"showReport(row)\" mat-icon-button>\r\n                <mat-icon>\r\n                  analytics\r\n                </mat-icon>\r\n              </button>\r\n              <button (click)=\"foldUnFoldGroup(row)\" mat-icon-button>\r\n                <mat-icon>\r\n                  compress\r\n                </mat-icon>\r\n              </button>\r\n              }\r\n\r\n\r\n            </span>\r\n\r\n\r\n            } @else if (row['totals'][col.formControlName]) {\r\n            <h5 [style.opacity]=\"row['IS_CLOSED']&& row['level'] !==0 ? '0.5':1\">\r\n              {{(row['totals'][col.formControlName]) |formatData: col.valueType}}\r\n\r\n            </h5>\r\n            }\r\n            }\r\n\r\n            @if (!row['IS_GROUP_CONFIG'] && $index ===0 ) {\r\n            @for (item of row['LEVELS_BEFORE']||[]; track item) {\r\n            <div disabled=\"true\" class=\"levelClass\" mat-button>\r\n              <span>\r\n                @if ($last) {\r\n                \u2022\r\n                }@else {\r\n                -\r\n                }\r\n\r\n                <div class=\"verticalCenterLine\"></div>\r\n              </span>\r\n            </div>\r\n            }\r\n\r\n            }\r\n            @if (!row?.IS_GROUP_CONFIG && $index !==0 ){\r\n\r\n            <div \r\n            class=\"row-value-col\"\r\n            >\r\n              {{ row[col.formControlName]|formatData: col.valueType }}\r\n\r\n\r\n\r\n            </div>\r\n\r\n            }\r\n          </td>\r\n        </ng-container>\r\n        }\r\n        <tr mat-header-row *matHeaderRowDef=\"vm.displayedColumns\"></tr>\r\n        <tr mat-row *matRowDef=\"let row; columns: vm.displayedColumns;\" [class.is-group-row]=\"!!row?.IS_GROUP_CONFIG\"\r\n          [class]=\"'row-'+row.level\" [class.is-sum-row]=\"!!row['IS_SUM_ROW']\"\r\n          style=\"border-bottom: solid 1px rgba(0, 0, 0, .04)\"></tr>\r\n      </table>\r\n    </cdk-virtual-scroll-viewport>\r\n    } @placeholder {\r\n    <div style=\"display: flex; justify-content: center; align-items: center; padding: 40px; flex-direction: column;\">\r\n      <mat-spinner diameter=\"50\"></mat-spinner>\r\n      <p style=\"margin-top: 15px;\">Loading table data...</p>\r\n    </div>\r\n    } @loading {\r\n    <div style=\"padding: 20px; text-align: center;\">\r\n      <mat-spinner diameter=\"50\"></mat-spinner>\r\n      <p style=\"margin-top: 10px;\">Preparing table view...</p>\r\n    </div>\r\n    } @error {\r\n    <p style=\"color: red; text-align: center; padding: 20px;\">Table failed to load.</p>\r\n    }\r\n  </section>\r\n  }\r\n\r\n</ng-container>\r\n\r\n\r\n<mat-menu #colorPallet=\"matMenu\">\r\n  <p>Select Table color coding</p>\r\n\r\n  <button *ngFor=\"let item of colorPalletArray\" (click)=\"selectColor(item)\" mat-menu-item>\r\n\r\n    <div [style.background]=\"color\" *ngFor=\"let color of item\" style=\"width: 16px;height:24px;display:inline-block\">\r\n\r\n    </div>\r\n\r\n\r\n\r\n  </button>\r\n\r\n</mat-menu>", styles: [".example-table{width:auto!important;margin:8px!important;border-spacing:0!important;border-collapse:collapse!important}.example-table .mat-mdc-cell,.example-table .mat-mdc-header-cell{padding:0!important;width:fit-content!important;min-width:fit-content!important;max-width:fit-content!important;white-space:nowrap!important;border:none!important}.example-table .mat-mdc-cell>*,.example-table .mat-mdc-header-cell>*{margin:0!important;padding:0!important}.example-table .mat-mdc-row,.example-table .mat-mdc-header-row{display:table-row!important;padding:0!important;height:auto!important;min-height:0!important}.example-table .mat-mdc-row{--level-color-1: var(--custom-level-color-1, #caf0f8);--level-color-2: var(--custom-level-color-2, #ADE8F4);--level-color-3: var(--custom-level-color-3, #90E0EF);--level-color-4: var(--custom-level-color-4, #48CAE4);--level-color-5: var(--custom-level-color-5, #00B4D8);--level-color-6: var(--custom-level-color-6, #0096C7);--level-color-7: var(--custom-level-color-7, #0077B6);--level-color-8: var(--custom-level-color-8, #023E8A);border-bottom:solid 1px rgba(0,0,0,.04);transition:background-color .2s ease}.example-table .mat-mdc-row.row-0{background-color:var(--level-color-5)!important;color:var(--level-text-color-5, #000000)}.example-table .mat-mdc-row.row-1{background-color:var(--level-color-1)!important;color:var(--level-text-color-1, #000000)}.example-table .mat-mdc-row.row-2{background-color:var(--level-color-2)!important;color:var(--level-text-color-2, #000000)}.example-table .mat-mdc-row.row-3{background-color:var(--level-color-3)!important;color:var(--level-text-color-3, #000000)}.example-table .mat-mdc-row.row-4{background-color:var(--level-color-4)!important;color:var(--level-text-color-4, #000000)}.example-table .mat-mdc-row.row-5{background-color:var(--level-color-5)!important;color:var(--level-text-color-5, #000000)}.example-table .mat-mdc-row.row-6{background-color:var(--level-color-1)!important;color:var(--level-text-color-1, #000000)}.example-table .mat-mdc-row.row-7{background-color:var(--level-color-2)!important;color:var(--level-text-color-2, #000000)}.example-table .mat-mdc-row.row-8{background-color:var(--level-color-3)!important;color:var(--level-text-color-3, #000000)}.example-table .mat-mdc-row.row-9{background-color:var(--level-color-4)!important;color:var(--level-text-color-4, #000000)}.example-table .mat-mdc-row.row-10{background-color:var(--level-color-5)!important;color:var(--level-text-color-5, #000000)}.example-table .mat-mdc-row.row-11{background-color:var(--level-color-1)!important;color:var(--level-text-color-1, #000000)}.example-table .mat-mdc-row.row-12{background-color:var(--level-color-2)!important;color:var(--level-text-color-2, #000000)}.example-table .mat-mdc-row.row-13{background-color:var(--level-color-3)!important;color:var(--level-text-color-3, #000000)}.example-table .mat-mdc-row.row-14{background-color:var(--level-color-4)!important;color:var(--level-text-color-4, #000000)}.example-table .mat-mdc-row.row-15{background-color:var(--level-color-5)!important;color:var(--level-text-color-5, #000000)}.example-table .mat-mdc-row.row-16{background-color:var(--level-color-1)!important;color:var(--level-text-color-1, #000000)}.example-table .mat-mdc-row.row-17{background-color:var(--level-color-2)!important;color:var(--level-text-color-2, #000000)}.example-table .mat-mdc-row.row-18{background-color:var(--level-color-3)!important;color:var(--level-text-color-3, #000000)}.example-table .mat-mdc-row.row-19{background-color:var(--level-color-4)!important;color:var(--level-text-color-4, #000000)}.example-table .mat-mdc-row.row-20{background-color:var(--level-color-5)!important;color:var(--level-text-color-5, #000000)}.example-table .mat-mdc-row.is-group-row{font-weight:500}.example-table .mat-mdc-row.is-sum-row{font-weight:700}.example-table .mat-mdc-row:hover{position:relative}.example-table .mat-mdc-row:hover:after{content:\"\";position:absolute;inset:0;background-color:#0011ff0a;pointer-events:none}.example-table [class*=row-].row-1{padding-left:16px}.example-table [class*=row-].row-2{padding-left:32px}.example-table [class*=row-].row-3{padding-left:48px}.example-table [class*=row-].row-4{padding-left:64px}.example-table [class*=row-].row-5{padding-left:80px}.example-table [class*=row-].row-6{padding-left:96px}.example-table [class*=row-].row-7{padding-left:112px}.example-table [class*=row-].row-8{padding-left:128px}.example-table [class*=row-].row-9{padding-left:144px}.example-table [class*=row-].row-10{padding-left:160px}.example-table [class*=row-].row-11{padding-left:176px}.example-table [class*=row-].row-12{padding-left:192px}.example-table [class*=row-].row-13{padding-left:208px}.example-table [class*=row-].row-14{padding-left:224px}.example-table [class*=row-].row-15{padding-left:240px}.example-table [class*=row-].row-16{padding-left:256px}.example-table [class*=row-].row-17{padding-left:272px}.example-table [class*=row-].row-18{padding-left:288px}.example-table [class*=row-].row-19{padding-left:304px}.example-table [class*=row-].row-20{padding-left:320px}.example-table button.mat-mdc-icon-button{width:24px!important;height:24px!important;padding:0!important;line-height:24px!important}.example-table .mat-mdc-cell:not(:empty),.example-table .mat-mdc-header-cell:not(:empty){padding:0 4px!important}.example-table .mat-mdc-header-row{background-color:var(--mat-sys-surface-container)!important}::ng-deep .mat-mdc-table{background:transparent!important}::ng-deep .mat-mdc-table .mat-mdc-row:not([class*=mat-elevation-z]){box-shadow:none!important}.levelClass{width:18px;margin-right:8px;display:inline-block;text-align:center;color:#243d91;opacity:.6}.verticalCenterLine{border-right:1px solid #243d91;width:8px;height:12px;opacity:.4;position:absolute}.groupOptions{opacity:.2;height:fit-content}.groupOptions:hover{opacity:1}.rowMenu{display:inline-flex;margin-left:8px;margin-right:8px;align-items:center;justify-content:flex-end;gap:4px;vertical-align:middle;z-index:2}small{opacity:.7}.tableContainer{flex-grow:1;overflow-y:auto;max-width:100vw;padding:0;margin-left:16px;margin-right:16px;min-height:0;border:solid 1px var(--mat-divider-color, var(--mat-sys-outline));border-radius:8px 8px 0}.row-value-col{min-height:37px;display:flex;align-items:center;max-width:200px;overflow:hidden;white-space:nowrap;text-overflow:ellipsis;transition:max-width .35s ease-in-out,background-color .35s ease-in-out,box-shadow .35s ease-in-out;position:relative;cursor:default}.row-value-col:hover{white-space:normal;overflow:visible;text-overflow:clip;min-height:fit-content}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "pipe", type: i2.AsyncPipe, name: "async" }, { kind: "component", type: GroupingChartComponent, selector: "app-grouping-chart", inputs: ["groups", "numberProperties"] }, { kind: "ngmodule", type: DragDropModule }, { kind: "directive", type: i3.CdkDropList, selector: "[cdkDropList], cdk-drop-list", inputs: ["cdkDropListConnectedTo", "cdkDropListData", "cdkDropListOrientation", "id", "cdkDropListLockAxis", "cdkDropListDisabled", "cdkDropListSortingDisabled", "cdkDropListEnterPredicate", "cdkDropListSortPredicate", "cdkDropListAutoScrollDisabled", "cdkDropListAutoScrollStep", "cdkDropListElementContainer"], outputs: ["cdkDropListDropped", "cdkDropListEntered", "cdkDropListExited", "cdkDropListSorted"], exportAs: ["cdkDropList"] }, { kind: "directive", type: i3.CdkDrag, selector: "[cdkDrag]", inputs: ["cdkDragData", "cdkDragLockAxis", "cdkDragRootElement", "cdkDragBoundary", "cdkDragStartDelay", "cdkDragFreeDragPosition", "cdkDragDisabled", "cdkDragConstrainPosition", "cdkDragPreviewClass", "cdkDragPreviewContainer", "cdkDragScale"], outputs: ["cdkDragStarted", "cdkDragReleased", "cdkDragEnded", "cdkDragEntered", "cdkDragExited", "cdkDragDropped", "cdkDragMoved"], exportAs: ["cdkDrag"] }, { kind: "directive", type: i3.CdkDragPlaceholder, selector: "ng-template[cdkDragPlaceholder]", inputs: ["data"] }, { kind: "ngmodule", type: MatChipsModule }, { kind: "component", type: i4.MatChipOption, selector: "mat-basic-chip-option, [mat-basic-chip-option], mat-chip-option, [mat-chip-option]", inputs: ["selectable", "selected"], outputs: ["selectionChange"] }, { kind: "directive", type: i4.MatChipRemove, selector: "[matChipRemove]" }, { kind: "ngmodule", type: MatMenuModule }, { kind: "component", type: i5.MatMenu, selector: "mat-menu", inputs: ["backdropClass", "aria-label", "aria-labelledby", "aria-describedby", "xPosition", "yPosition", "overlapTrigger", "hasBackdrop", "class", "classList"], outputs: ["closed", "close"], exportAs: ["matMenu"] }, { kind: "component", type: i5.MatMenuItem, selector: "[mat-menu-item]", inputs: ["role", "disabled", "disableRipple"], exportAs: ["matMenuItem"] }, { kind: "directive", type: i5.MatMenuTrigger, selector: "[mat-menu-trigger-for], [matMenuTriggerFor]", inputs: ["mat-menu-trigger-for", "matMenuTriggerFor", "matMenuTriggerData", "matMenuTriggerRestoreFocus"], outputs: ["menuOpened", "onMenuOpen", "menuClosed", "onMenuClose"], exportAs: ["matMenuTrigger"] }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i6.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i7.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i8.MatButton, selector: "    button[mat-button], button[mat-raised-button], button[mat-flat-button],    button[mat-stroked-button]  ", exportAs: ["matButton"] }, { kind: "component", type: i8.MatIconButton, selector: "button[mat-icon-button]", exportAs: ["matButton"] }, { kind: "ngmodule", type: MatTableModule }, { kind: "ngmodule", type: MatToolbarModule }, { kind: "component", type: i9.MatToolbar, selector: "mat-toolbar", inputs: ["color"], exportAs: ["matToolbar"] }, { kind: "ngmodule", type: MatProgressSpinnerModule }, { kind: "component", type: i4$1.MatProgressSpinner, selector: "mat-progress-spinner, mat-spinner", inputs: ["color", "mode", "value", "diameter", "strokeWidth"], exportAs: ["matProgressSpinner"] }, { kind: "ngmodule", type: ScrollingModule }, { kind: "ngmodule", type: MatDividerModule }, { kind: "component", type: i2$1.MatDivider, selector: "mat-divider", inputs: ["vertical", "inset"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, deferBlockDependencies: [() => [i2.NgForOf, i3.CdkDropList, i3.CdkDrag, i6.MatTooltip, i7.MatIcon, i8.MatButton, i8.MatIconButton, i12.MatTable, i12.MatHeaderCellDef, i12.MatHeaderRowDef, i12.MatColumnDef, i12.MatCellDef, i12.MatRowDef, i12.MatHeaderCell, i12.MatCell, i12.MatHeaderRow, i12.MatRow, import('./ngx-t-reports-format-Data.pipe-B5jqpvJP.mjs').then(m => m.FormatDataPipe), i13.CdkFixedSizeVirtualScroll, i13.CdkVirtualScrollViewport]] }); }
}
i0.ɵɵngDeclareClassMetadataAsync({ minVersion: "18.0.0", version: "19.2.14", ngImport: i0, type: NgxTMatrixTableComponent, resolveDeferredDeps: () => [import('./ngx-t-reports-format-Data.pipe-B5jqpvJP.mjs').then(m => m.FormatDataPipe)], resolveMetadata: FormatDataPipe => ({ decorators: [{
                type: Component,
                args: [{ selector: 'app-ngx-t-matrix-table', standalone: true, imports: [CommonModule, GroupingChartComponent, DragDropModule, MatChipsModule,
                            CdkDropList, CdkDrag, MatMenuModule,
                            MatTooltipModule,
                            MatIconModule,
                            MatButtonModule,
                            MatTableModule,
                            MatToolbarModule,
                            FormatDataPipe,
                            MatProgressSpinnerModule,
                            ScrollingModule,
                            MatDividerModule], providers: [NgxTMatrixTableStoreService,], changeDetection: ChangeDetectionStrategy.OnPush, template: "<ng-container *ngIf=\"( vm$ |async) as vm\">\r\n\r\n  @if (\r\n  !!vm.groupChart\r\n  ) {\r\n\r\n  <mat-toolbar class=\"chartToolbar\">\r\n    <h1 style=\"    font-weight: bold;\r\n        font-size: 1.4rem; \r\n        text-transform: capitalize;\">\r\n      {{vm.groupChart.mainTitle}}\r\n    </h1>\r\n    <span class=\"spacer\"></span>\r\n    <button (click)=\"vm.groupChart = null\" mat-stroked-button>\r\n      Close\r\n      <mat-icon>\r\n        close\r\n      </mat-icon>\r\n    </button>\r\n  </mat-toolbar>\r\n\r\n\r\n\r\n  <mat-divider></mat-divider>\r\n  <br>\r\n  <app-grouping-chart [groups]=\"vm.groupChart.groups\"\r\n    [numberProperties]=\"vm.groupChart.numberProperties\"></app-grouping-chart>\r\n  }@else {\r\n\r\n\r\n  <section class=\"tableContainer\" #tableContainer>\r\n  <mat-toolbar style=\"background: none;\" (cdkDropListDropped)=\"dropChip($event)\"\r\n    [cdkDropListData]=\"vm.groupOptions?.columns ||[]\" cdkDropList>\r\n\r\n\r\n    @for(groupCol of vm.groupedColumns; track groupCol){\r\n    <mat-chip-option color=\"tertiary\" class=\"dragBox\" [style.margin-left]=\"$index !==0? '5px':''\" cdkDrag selected\r\n      (removed)=\"remove(groupCol.formControlName)\">\r\n      <div class=\"placeholder\" *cdkDragPlaceholder></div>\r\n      {{ groupCol.label }}\r\n      <button matChipRemove [attr.aria-label]=\"'remove ' + groupCol.label\">\r\n        <mat-icon color=\"warn\">cancel</mat-icon>\r\n      </button>\r\n    </mat-chip-option>\r\n    }\r\n    @if (vm.groupedColumns.length === 0) {\r\n\r\n    <div\r\n      style=\"font-size: 14px; font-weight: 400; opacity: 0.7; padding: 8px; color: #666; display: flex; align-items: center;\">\r\n      Drag column headers here to group your data\r\n    </div>\r\n\r\n\r\n    }\r\n\r\n\r\n    <span class=\"spacer\"></span>\r\n\r\n    <button [matMenuTriggerFor]=\"colorPallet\" mat-icon-button matTooltip=\"Select table color coding\">\r\n      <mat-icon>\r\n        palette\r\n      </mat-icon>\r\n    </button>\r\n\r\n    <button (click)=\"mainShowChart()\" mat-icon-button matTooltip=\"Show main grouping chart analytics\">\r\n      <mat-icon>\r\n        analytics\r\n      </mat-icon>\r\n    </button>\r\n    <button (click)=\"export()\" mat-icon-button matTooltip=\"Export to excel\">\r\n      <mat-icon>\r\n        download\r\n      </mat-icon>\r\n    </button>\r\n\r\n  </mat-toolbar>\r\n\r\n\r\n    @defer (on viewport; prefetch on idle) {\r\n    <cdk-virtual-scroll-viewport (scrolledIndexChange)=\"scrollIndex($event)\" \r\n    #viewPortScroll [itemSize]=\"30\"\r\n      style=\"resize: vertical;height:400px;\" >\r\n      <table (cdkDropListDropped)=\"drop($event)\" \r\n      [multiTemplateDataRows]=\"true\"\r\n      cdkDropList mat-table [dataSource]=\"vm.getGroupedData||[]\"\r\n        style=\"border-collapse: collapse;\" class=\"example-table\" matSort matSortActive=\"created\" matSortDisableClear\r\n        matSortDirection=\"desc\">\r\n        @for (col of vm.tableColumns||[]; track col.formControlName) {\r\n        <ng-container [matColumnDef]=\"col.formControlName\">\r\n          <th cdkDrag (cdkDragStarted)=\"setDraggedGroup(col.formControlName)\"\r\n            [attr.data-column-size]=\"col.formControlName\"\r\n            style=\"width: fit-content !important; white-space: nowrap !important;\" mat-header-cell *matHeaderCellDef>\r\n            @if($index === 0 && vm.closedGroups.length > 0){\r\n            <button class=\"cancelGrouping\" (click)=\"vm.closedGroups= []\" color=\"warn\" mat-icon-button>\r\n              <mat-icon>highlight_off</mat-icon>\r\n            </button>\r\n            } @else {\r\n            <div class=\"colTitle\" style=\"display: inline-flex; align-items: center;\"\r\n              [style.color]=\"col.INCLUDED_IN_GROUP?'':''\" [matTooltip]=\"'Click to group by '+col.label\"\r\n              (click)=\"addToGrouping(col.formControlName)\" matRipple>\r\n              {{col.label}}\r\n            </div>\r\n            }\r\n          </th>\r\n          <td mat-cell style=\"\r\n        width: fit-content !important;\r\n        white-space: nowrap !important;\" [style.border-top]=\"!!row?.IS_SUM_ROW && $index !==0? '1px solid black':''\"\r\n            [style.border-bottom-color]=\"!!row?.IS_GROUP_CONFIG ?'#ffffff00':''\"\r\n            [style.background]=\"!!row?.IS_GROUP_CONFIG?'':'none'\"\r\n            [style.overflow]=\"!!row?.IS_GROUP_CONFIG ?'visible':''\" *matCellDef=\"let row\">\r\n\r\n            @if (!!row?.IS_GROUP_CONFIG ) {\r\n            @if( $index ===0){\r\n            <div disabled=\"true\" class=\"levelClass\" *ngFor=\"let item of row.LEVELS_BEFORE\" mat-button>\r\n              <span>- <div class=\"verticalCenterLine\"></div></span>\r\n            </div>\r\n            <button (click)=\"toggleCloseGroup(row['name']);\" mat-button>\r\n              <mat-icon>{{row['IS_CLOSED'] ?'keyboard_arrow_right':'keyboard_arrow_down'}}</mat-icon>\r\n              <span\r\n                style=\"color: var(--mat-table-header-headline-color, var(--mat-sys-on-surface, rgba(0, 0, 0, 0.87)));\">\r\n                {{row['name']}}\r\n              </span>\r\n            </button>\r\n\r\n            <span class=\"rowMenu\">\r\n              <button [color]=\"vm.isOpen?.name === row?.name && vm.isOpen?.level === row.level?'warn':''\"\r\n                class=\"groupOptions\" mat-icon-button (click)=\"toggleMenu(row)\">\r\n\r\n                <mat-icon>\r\n                  {{vm.isOpen?.name === row?.name && vm.isOpen?.level === row.level? 'close':'more_horiz'}}\r\n                </mat-icon>\r\n              </button>\r\n              @if(vm.isOpen?.name === row?.name && vm.isOpen?.level === row.level){\r\n              <button (click)=\"showReport(row)\" mat-icon-button>\r\n                <mat-icon>\r\n                  analytics\r\n                </mat-icon>\r\n              </button>\r\n              <button (click)=\"foldUnFoldGroup(row)\" mat-icon-button>\r\n                <mat-icon>\r\n                  compress\r\n                </mat-icon>\r\n              </button>\r\n              }\r\n\r\n\r\n            </span>\r\n\r\n\r\n            } @else if (row['totals'][col.formControlName]) {\r\n            <h5 [style.opacity]=\"row['IS_CLOSED']&& row['level'] !==0 ? '0.5':1\">\r\n              {{(row['totals'][col.formControlName]) |formatData: col.valueType}}\r\n\r\n            </h5>\r\n            }\r\n            }\r\n\r\n            @if (!row['IS_GROUP_CONFIG'] && $index ===0 ) {\r\n            @for (item of row['LEVELS_BEFORE']||[]; track item) {\r\n            <div disabled=\"true\" class=\"levelClass\" mat-button>\r\n              <span>\r\n                @if ($last) {\r\n                \u2022\r\n                }@else {\r\n                -\r\n                }\r\n\r\n                <div class=\"verticalCenterLine\"></div>\r\n              </span>\r\n            </div>\r\n            }\r\n\r\n            }\r\n            @if (!row?.IS_GROUP_CONFIG && $index !==0 ){\r\n\r\n            <div \r\n            class=\"row-value-col\"\r\n            >\r\n              {{ row[col.formControlName]|formatData: col.valueType }}\r\n\r\n\r\n\r\n            </div>\r\n\r\n            }\r\n          </td>\r\n        </ng-container>\r\n        }\r\n        <tr mat-header-row *matHeaderRowDef=\"vm.displayedColumns\"></tr>\r\n        <tr mat-row *matRowDef=\"let row; columns: vm.displayedColumns;\" [class.is-group-row]=\"!!row?.IS_GROUP_CONFIG\"\r\n          [class]=\"'row-'+row.level\" [class.is-sum-row]=\"!!row['IS_SUM_ROW']\"\r\n          style=\"border-bottom: solid 1px rgba(0, 0, 0, .04)\"></tr>\r\n      </table>\r\n    </cdk-virtual-scroll-viewport>\r\n    } @placeholder {\r\n    <div style=\"display: flex; justify-content: center; align-items: center; padding: 40px; flex-direction: column;\">\r\n      <mat-spinner diameter=\"50\"></mat-spinner>\r\n      <p style=\"margin-top: 15px;\">Loading table data...</p>\r\n    </div>\r\n    } @loading {\r\n    <div style=\"padding: 20px; text-align: center;\">\r\n      <mat-spinner diameter=\"50\"></mat-spinner>\r\n      <p style=\"margin-top: 10px;\">Preparing table view...</p>\r\n    </div>\r\n    } @error {\r\n    <p style=\"color: red; text-align: center; padding: 20px;\">Table failed to load.</p>\r\n    }\r\n  </section>\r\n  }\r\n\r\n</ng-container>\r\n\r\n\r\n<mat-menu #colorPallet=\"matMenu\">\r\n  <p>Select Table color coding</p>\r\n\r\n  <button *ngFor=\"let item of colorPalletArray\" (click)=\"selectColor(item)\" mat-menu-item>\r\n\r\n    <div [style.background]=\"color\" *ngFor=\"let color of item\" style=\"width: 16px;height:24px;display:inline-block\">\r\n\r\n    </div>\r\n\r\n\r\n\r\n  </button>\r\n\r\n</mat-menu>", styles: [".example-table{width:auto!important;margin:8px!important;border-spacing:0!important;border-collapse:collapse!important}.example-table .mat-mdc-cell,.example-table .mat-mdc-header-cell{padding:0!important;width:fit-content!important;min-width:fit-content!important;max-width:fit-content!important;white-space:nowrap!important;border:none!important}.example-table .mat-mdc-cell>*,.example-table .mat-mdc-header-cell>*{margin:0!important;padding:0!important}.example-table .mat-mdc-row,.example-table .mat-mdc-header-row{display:table-row!important;padding:0!important;height:auto!important;min-height:0!important}.example-table .mat-mdc-row{--level-color-1: var(--custom-level-color-1, #caf0f8);--level-color-2: var(--custom-level-color-2, #ADE8F4);--level-color-3: var(--custom-level-color-3, #90E0EF);--level-color-4: var(--custom-level-color-4, #48CAE4);--level-color-5: var(--custom-level-color-5, #00B4D8);--level-color-6: var(--custom-level-color-6, #0096C7);--level-color-7: var(--custom-level-color-7, #0077B6);--level-color-8: var(--custom-level-color-8, #023E8A);border-bottom:solid 1px rgba(0,0,0,.04);transition:background-color .2s ease}.example-table .mat-mdc-row.row-0{background-color:var(--level-color-5)!important;color:var(--level-text-color-5, #000000)}.example-table .mat-mdc-row.row-1{background-color:var(--level-color-1)!important;color:var(--level-text-color-1, #000000)}.example-table .mat-mdc-row.row-2{background-color:var(--level-color-2)!important;color:var(--level-text-color-2, #000000)}.example-table .mat-mdc-row.row-3{background-color:var(--level-color-3)!important;color:var(--level-text-color-3, #000000)}.example-table .mat-mdc-row.row-4{background-color:var(--level-color-4)!important;color:var(--level-text-color-4, #000000)}.example-table .mat-mdc-row.row-5{background-color:var(--level-color-5)!important;color:var(--level-text-color-5, #000000)}.example-table .mat-mdc-row.row-6{background-color:var(--level-color-1)!important;color:var(--level-text-color-1, #000000)}.example-table .mat-mdc-row.row-7{background-color:var(--level-color-2)!important;color:var(--level-text-color-2, #000000)}.example-table .mat-mdc-row.row-8{background-color:var(--level-color-3)!important;color:var(--level-text-color-3, #000000)}.example-table .mat-mdc-row.row-9{background-color:var(--level-color-4)!important;color:var(--level-text-color-4, #000000)}.example-table .mat-mdc-row.row-10{background-color:var(--level-color-5)!important;color:var(--level-text-color-5, #000000)}.example-table .mat-mdc-row.row-11{background-color:var(--level-color-1)!important;color:var(--level-text-color-1, #000000)}.example-table .mat-mdc-row.row-12{background-color:var(--level-color-2)!important;color:var(--level-text-color-2, #000000)}.example-table .mat-mdc-row.row-13{background-color:var(--level-color-3)!important;color:var(--level-text-color-3, #000000)}.example-table .mat-mdc-row.row-14{background-color:var(--level-color-4)!important;color:var(--level-text-color-4, #000000)}.example-table .mat-mdc-row.row-15{background-color:var(--level-color-5)!important;color:var(--level-text-color-5, #000000)}.example-table .mat-mdc-row.row-16{background-color:var(--level-color-1)!important;color:var(--level-text-color-1, #000000)}.example-table .mat-mdc-row.row-17{background-color:var(--level-color-2)!important;color:var(--level-text-color-2, #000000)}.example-table .mat-mdc-row.row-18{background-color:var(--level-color-3)!important;color:var(--level-text-color-3, #000000)}.example-table .mat-mdc-row.row-19{background-color:var(--level-color-4)!important;color:var(--level-text-color-4, #000000)}.example-table .mat-mdc-row.row-20{background-color:var(--level-color-5)!important;color:var(--level-text-color-5, #000000)}.example-table .mat-mdc-row.is-group-row{font-weight:500}.example-table .mat-mdc-row.is-sum-row{font-weight:700}.example-table .mat-mdc-row:hover{position:relative}.example-table .mat-mdc-row:hover:after{content:\"\";position:absolute;inset:0;background-color:#0011ff0a;pointer-events:none}.example-table [class*=row-].row-1{padding-left:16px}.example-table [class*=row-].row-2{padding-left:32px}.example-table [class*=row-].row-3{padding-left:48px}.example-table [class*=row-].row-4{padding-left:64px}.example-table [class*=row-].row-5{padding-left:80px}.example-table [class*=row-].row-6{padding-left:96px}.example-table [class*=row-].row-7{padding-left:112px}.example-table [class*=row-].row-8{padding-left:128px}.example-table [class*=row-].row-9{padding-left:144px}.example-table [class*=row-].row-10{padding-left:160px}.example-table [class*=row-].row-11{padding-left:176px}.example-table [class*=row-].row-12{padding-left:192px}.example-table [class*=row-].row-13{padding-left:208px}.example-table [class*=row-].row-14{padding-left:224px}.example-table [class*=row-].row-15{padding-left:240px}.example-table [class*=row-].row-16{padding-left:256px}.example-table [class*=row-].row-17{padding-left:272px}.example-table [class*=row-].row-18{padding-left:288px}.example-table [class*=row-].row-19{padding-left:304px}.example-table [class*=row-].row-20{padding-left:320px}.example-table button.mat-mdc-icon-button{width:24px!important;height:24px!important;padding:0!important;line-height:24px!important}.example-table .mat-mdc-cell:not(:empty),.example-table .mat-mdc-header-cell:not(:empty){padding:0 4px!important}.example-table .mat-mdc-header-row{background-color:var(--mat-sys-surface-container)!important}::ng-deep .mat-mdc-table{background:transparent!important}::ng-deep .mat-mdc-table .mat-mdc-row:not([class*=mat-elevation-z]){box-shadow:none!important}.levelClass{width:18px;margin-right:8px;display:inline-block;text-align:center;color:#243d91;opacity:.6}.verticalCenterLine{border-right:1px solid #243d91;width:8px;height:12px;opacity:.4;position:absolute}.groupOptions{opacity:.2;height:fit-content}.groupOptions:hover{opacity:1}.rowMenu{display:inline-flex;margin-left:8px;margin-right:8px;align-items:center;justify-content:flex-end;gap:4px;vertical-align:middle;z-index:2}small{opacity:.7}.tableContainer{flex-grow:1;overflow-y:auto;max-width:100vw;padding:0;margin-left:16px;margin-right:16px;min-height:0;border:solid 1px var(--mat-divider-color, var(--mat-sys-outline));border-radius:8px 8px 0}.row-value-col{min-height:37px;display:flex;align-items:center;max-width:200px;overflow:hidden;white-space:nowrap;text-overflow:ellipsis;transition:max-width .35s ease-in-out,background-color .35s ease-in-out,box-shadow .35s ease-in-out;position:relative;cursor:default}.row-value-col:hover{white-space:normal;overflow:visible;text-overflow:clip;min-height:fit-content}\n"] }]
            }], ctorParameters: () => [{ type: i1$2.MatDialog }], propDecorators: { scrollContainer: [{
                    type: ViewChild,
                    args: ['viewPortScroll']
                }], list: [{
                    type: Input
                }], reportName: [{
                    type: Input
                }], listConfig: [{
                    type: Input
                }], aggregates: [{
                    type: Input
                }], groupOptions: [{
                    type: Input
                }] } }) });

const NGX_T_REPORTS_CONFIG_TOKEN = new InjectionToken('NGX_T_REPORTS_CONFIG');

class ElementEditorComponent {
    constructor() {
        this.inEdit = {};
        this.label = '';
        this.subTitle = '';
        this.editorSections = [];
        this.formInputs = [];
        this.saveButtonLabel = "Save ";
        this.closeEditor = new EventEmitter();
        this.saveElement = new EventEmitter();
        this.newValue = null;
        this.elementConfigurationChanged = (value, ele) => {
            this.newValue = {
                ...this.inEdit
            };
            assignDeepPropertyToObject(this.newValue, ele.deepBind, value);
        };
        this.elementBlur = (event, element) => {
        };
    }
    get saveIsDisabled() {
        if (!this.newValue)
            return true;
        if (this.editorSections.length === 0)
            return true;
        return Boolean(_isEqual(this.newValue, this.inEdit));
    }
    save() {
        this.saveElement.emit(this.newValue);
        this.newValue = null;
    }
    close() {
        this.closeEditor.emit();
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: ElementEditorComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
    static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.14", type: ElementEditorComponent, isStandalone: true, selector: "lib-element-editor", inputs: { inEdit: "inEdit", label: "label", subTitle: "subTitle", editorSections: "editorSections", formInputs: "formInputs", saveButtonLabel: "saveButtonLabel" }, outputs: { closeEditor: "closeEditor", saveElement: "saveElement" }, ngImport: i0, template: "<mat-card \r\n\r\nstyle=\"\r\n\r\nbackground: var(--mat-sys-surface-container, var(--mat-app-surface));\r\nmargin:0px;\r\nborder:solid 1px var(--mat-divider-color, var(--mat-app-outline))\">\r\n \r\n    <mat-card-header >\r\n        <mat-card-title>\r\n           {{label}}\r\n        </mat-card-title>\r\n        <mat-card-subtitle>   {{subTitle }}</mat-card-subtitle>\r\n     \r\n      </mat-card-header>\r\n    \r\n\r\n\r\n    \r\n      <mat-toolbar class=\"section-header\">\r\n        <span class=\"header\">Element configuration</span>\r\n        <span class=\"spacer\"></span>\r\n    </mat-toolbar>\r\n    <mat-divider></mat-divider>\r\n\r\n        @defer (on viewport) {\r\n        \r\n            <mat-accordion togglePosition=\"before\">\r\n                @for(section of (editorSections||[]); track section.id) {\r\n                <mat-expansion-panel>\r\n                    <mat-expansion-panel-header>\r\n                        <mat-panel-title>\r\n                            {{section.label}}\r\n                            <span class=\"spacer\"></span>\r\n                          \r\n                            <span class=\"showItemValue\" *ngIf=\"section.showItemValue && !!(inEdit)\">\r\n                                {{inEdit[section.showItemValue]}}\r\n                            </span>\r\n                            <mat-divider style=\"position: absolute; left:0px; width:100%; bottom:0px;\"></mat-divider>\r\n                        </mat-panel-title>\r\n                    </mat-expansion-panel-header>\r\n            \r\n                    <div style=\"margin-top: 16px;\"></div>\r\n            \r\n                    <!-- Element type selector (only in first section) -->\r\n                 \r\n            \r\n                    <!-- Section elements -->\r\n                    @for(element of section.elements; track element.id) {\r\n                    <p style=\"margin-bottom: 16px; margin-top: 8px;\">\r\n                        @defer (on viewport) {\r\n                        <lib-t-dynamic-data-edit \r\n                            [editorConfig]=\"element\" [data]=\"inEdit\"\r\n                            [validationErrors]=\"element.computedErrors||[]\"\r\n                            (valueChange)=\"elementConfigurationChanged($event, element)\" \r\n                            [formInputs]=\"formInputs\"\r\n                            (blur)=\"elementBlur($event, element)\">\r\n                        </lib-t-dynamic-data-edit>\r\n                       \r\n                         \r\n                        } @placeholder {\r\n                    <div style=\"padding: 50px; display:flex; justify-content:center; align-items:center; text-align: center;\">\r\n                        <mat-spinner diameter=\"18\"></mat-spinner>\r\n                    </div>\r\n                    }\r\n                    </p>\r\n                    }\r\n                </mat-expansion-panel>\r\n                }\r\n            </mat-accordion>\r\n            } @placeholder {\r\n            <div style=\"padding: 50px; display:flex; justify-content:center; align-items:center; text-align: center;\">\r\n                <mat-spinner diameter=\"50\" />\r\n            </div>\r\n            } @error {\r\n      \r\n                <h1>Error loading element editor</h1>\r\n                <p>An error occurred while loading the element editor. Please try again later.</p>\r\n        \r\n            }\r\n    \r\n    \r\n    \r\n    \r\n\r\n\r\n\r\n     \r\n\r\n      <br>\r\n      <mat-divider></mat-divider>\r\n     \r\n      <mat-card-actions >\r\n            <button         (click)=\"close()\"  class=\"\" mat-button>close</button>\r\n            <span class=\"spacer\"></span>\r\n            <button mat-flat-button \r\n            \r\n        (click)=\"save()\"\r\n            color=\"primary\">{{\r\n                saveButtonLabel\r\n            }}</button>\r\n        \r\n    </mat-card-actions>\r\n</mat-card>", styles: [".showItemValue{opacity:.6}mat-form-field{width:100%}mat-slider{width:100%}.header{margin-bottom:0;font-size:small;opacity:.6}.section-header{height:38px;margin-top:12px}\n"], dependencies: [{ kind: "ngmodule", type: MatCardModule }, { kind: "component", type: i1$1.MatCard, selector: "mat-card", inputs: ["appearance"], exportAs: ["matCard"] }, { kind: "directive", type: i1$1.MatCardActions, selector: "mat-card-actions", inputs: ["align"], exportAs: ["matCardActions"] }, { kind: "component", type: i1$1.MatCardHeader, selector: "mat-card-header" }, { kind: "directive", type: i1$1.MatCardSubtitle, selector: "mat-card-subtitle, [mat-card-subtitle], [matCardSubtitle]" }, { kind: "directive", type: i1$1.MatCardTitle, selector: "mat-card-title, [mat-card-title], [matCardTitle]" }, { kind: "ngmodule", type: MatDividerModule }, { kind: "component", type: i2$1.MatDivider, selector: "mat-divider", inputs: ["vertical", "inset"] }, { kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: MatToolbarModule }, { kind: "component", type: i9.MatToolbar, selector: "mat-toolbar", inputs: ["color"], exportAs: ["matToolbar"] }, { kind: "ngmodule", type: MatProgressSpinnerModule }, { kind: "component", type: i4$1.MatProgressSpinner, selector: "mat-progress-spinner, mat-spinner", inputs: ["color", "mode", "value", "diameter", "strokeWidth"], exportAs: ["matProgressSpinner"] }, { kind: "ngmodule", type: MatExpansionModule }, { kind: "ngmodule", type: MatIconModule }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i8.MatButton, selector: "    button[mat-button], button[mat-raised-button], button[mat-flat-button],    button[mat-stroked-button]  ", exportAs: ["matButton"] }], deferBlockDependencies: [() => [i2$1.MatDivider, i2.NgIf, i4$1.MatProgressSpinner, i7$1.MatAccordion, i7$1.MatExpansionPanel, i7$1.MatExpansionPanelHeader, i7$1.MatExpansionPanelTitle], () => [TDynamicDataEditComponent]] }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: ElementEditorComponent, decorators: [{
            type: Component,
            args: [{ selector: 'lib-element-editor', standalone: true, imports: [
                        MatCardModule,
                        MatCardContent,
                        MatCardHeader,
                        MatCardTitle,
                        MatCardSubtitle,
                        MatDividerModule,
                        CommonModule,
                        MatToolbarModule,
                        MatProgressSpinnerModule,
                        MatExpansionModule,
                        TDynamicDataEditComponent,
                        MatIconModule,
                        MatButtonModule
                    ], template: "<mat-card \r\n\r\nstyle=\"\r\n\r\nbackground: var(--mat-sys-surface-container, var(--mat-app-surface));\r\nmargin:0px;\r\nborder:solid 1px var(--mat-divider-color, var(--mat-app-outline))\">\r\n \r\n    <mat-card-header >\r\n        <mat-card-title>\r\n           {{label}}\r\n        </mat-card-title>\r\n        <mat-card-subtitle>   {{subTitle }}</mat-card-subtitle>\r\n     \r\n      </mat-card-header>\r\n    \r\n\r\n\r\n    \r\n      <mat-toolbar class=\"section-header\">\r\n        <span class=\"header\">Element configuration</span>\r\n        <span class=\"spacer\"></span>\r\n    </mat-toolbar>\r\n    <mat-divider></mat-divider>\r\n\r\n        @defer (on viewport) {\r\n        \r\n            <mat-accordion togglePosition=\"before\">\r\n                @for(section of (editorSections||[]); track section.id) {\r\n                <mat-expansion-panel>\r\n                    <mat-expansion-panel-header>\r\n                        <mat-panel-title>\r\n                            {{section.label}}\r\n                            <span class=\"spacer\"></span>\r\n                          \r\n                            <span class=\"showItemValue\" *ngIf=\"section.showItemValue && !!(inEdit)\">\r\n                                {{inEdit[section.showItemValue]}}\r\n                            </span>\r\n                            <mat-divider style=\"position: absolute; left:0px; width:100%; bottom:0px;\"></mat-divider>\r\n                        </mat-panel-title>\r\n                    </mat-expansion-panel-header>\r\n            \r\n                    <div style=\"margin-top: 16px;\"></div>\r\n            \r\n                    <!-- Element type selector (only in first section) -->\r\n                 \r\n            \r\n                    <!-- Section elements -->\r\n                    @for(element of section.elements; track element.id) {\r\n                    <p style=\"margin-bottom: 16px; margin-top: 8px;\">\r\n                        @defer (on viewport) {\r\n                        <lib-t-dynamic-data-edit \r\n                            [editorConfig]=\"element\" [data]=\"inEdit\"\r\n                            [validationErrors]=\"element.computedErrors||[]\"\r\n                            (valueChange)=\"elementConfigurationChanged($event, element)\" \r\n                            [formInputs]=\"formInputs\"\r\n                            (blur)=\"elementBlur($event, element)\">\r\n                        </lib-t-dynamic-data-edit>\r\n                       \r\n                         \r\n                        } @placeholder {\r\n                    <div style=\"padding: 50px; display:flex; justify-content:center; align-items:center; text-align: center;\">\r\n                        <mat-spinner diameter=\"18\"></mat-spinner>\r\n                    </div>\r\n                    }\r\n                    </p>\r\n                    }\r\n                </mat-expansion-panel>\r\n                }\r\n            </mat-accordion>\r\n            } @placeholder {\r\n            <div style=\"padding: 50px; display:flex; justify-content:center; align-items:center; text-align: center;\">\r\n                <mat-spinner diameter=\"50\" />\r\n            </div>\r\n            } @error {\r\n      \r\n                <h1>Error loading element editor</h1>\r\n                <p>An error occurred while loading the element editor. Please try again later.</p>\r\n        \r\n            }\r\n    \r\n    \r\n    \r\n    \r\n\r\n\r\n\r\n     \r\n\r\n      <br>\r\n      <mat-divider></mat-divider>\r\n     \r\n      <mat-card-actions >\r\n            <button         (click)=\"close()\"  class=\"\" mat-button>close</button>\r\n            <span class=\"spacer\"></span>\r\n            <button mat-flat-button \r\n            \r\n        (click)=\"save()\"\r\n            color=\"primary\">{{\r\n                saveButtonLabel\r\n            }}</button>\r\n        \r\n    </mat-card-actions>\r\n</mat-card>", styles: [".showItemValue{opacity:.6}mat-form-field{width:100%}mat-slider{width:100%}.header{margin-bottom:0;font-size:small;opacity:.6}.section-header{height:38px;margin-top:12px}\n"] }]
        }], propDecorators: { inEdit: [{
                type: Input
            }], label: [{
                type: Input
            }], subTitle: [{
                type: Input
            }], editorSections: [{
                type: Input
            }], formInputs: [{
                type: Input
            }], saveButtonLabel: [{
                type: Input
            }], closeEditor: [{
                type: Output
            }], saveElement: [{
                type: Output
            }] } });

var ConfigTypes;
(function (ConfigTypes) {
    ConfigTypes["SheetConfig"] = "SheetConfig";
})(ConfigTypes || (ConfigTypes = {}));
const SheetConfig = {
    label: "Matrix Report Configuration",
    subTitle: "Customize how your data appears and organizes in the report",
    saveButtonLabel: "Apply Report Settings",
    editorSections: [
        {
            label: "Data Sources",
            id: "dataSources",
            elements: [
                {
                    name: SpecialElementKeys.Default,
                    deepBind: ['dataSources'],
                    editType: ElementEditorTypes.DataSourcePicker,
                    hint: `Connect and manage data sources for your report. Select from REST APIs or create MongoDB aggregation pipelines.`,
                    label: 'Connect Data',
                    id: "10c7237d-b0a8-4964-97e6-811b93569c68"
                },
            ]
        },
        {
            label: "Column Layout",
            id: "tableColumns",
            elements: [
                {
                    name: SpecialElementKeys.Default,
                    deepBind: ['listConfig'],
                    editType: ElementEditorTypes.ListLabelConfigEditor,
                    fetchOptions: ['ALL_POSSIBLE_FIELDS'],
                    hint: `Customize your table display by selecting fields, arranging columns, and setting visibility options.`,
                    label: 'Visible Columns',
                    id: "6ed1283c-63e9-435e-a435-16d3a0c6d3f3"
                }
            ]
        },
        {
            label: "Data Hierarchy & Grouping",
            id: "dataGrouping",
            elements: [
                {
                    name: SpecialElementKeys.Default,
                    deepBind: ['groupOptions', 'columns'],
                    editType: ElementEditorTypes.ChipOptionsCreator,
                    hint: `Define columns for grouping and hierarchy. Ensure the entered column matches column form control names.`,
                    label: 'Group By',
                    id: "36877d92-4331-498a-b02f-4d0eaef17372"
                },
                {
                    name: SpecialElementKeys.Default,
                    deepBind: ['groupOptions', 'hiddenColumns'],
                    editType: ElementEditorTypes.ChipOptionsCreator,
                    hint: `Defined grouped columns that should be hidden. Ensure the entered column matches column form control names.`,
                    label: 'Define hidden grouped columns',
                    id: "2452e44f-d0c9-4935-a743-7d89fbd9a095"
                }
            ]
        },
        {
            label: "Date Range configuration",
            id: "dataGrouping",
            elements: [
                {
                    name: SpecialElementKeys.Default,
                    deepBind: ['dateRangeMin'],
                    editType: ElementEditorTypes.OptionSelect,
                    fetchOptions: ['EXTERNAL_DATA_INTEGRATION_OPTIONS'],
                    hint: `Minimum date for the report. This is used to filter the data in the report.`,
                    label: 'Min Date',
                    id: "5d31a27a-a4d1-43db-9845-d1a2ce666e17"
                },
                {
                    name: SpecialElementKeys.Default,
                    deepBind: ['dateRangeMax'],
                    editType: ElementEditorTypes.OptionSelect,
                    fetchOptions: ['EXTERNAL_DATA_INTEGRATION_OPTIONS'],
                    hint: `Maximum date for the report. `,
                    label: 'max Date',
                    id: "739ce399-3f25-42c1-b2fe-47d2bf14aa38"
                },
                {
                    name: SpecialElementKeys.Default,
                    deepBind: ['dateRangeComparisonStart'],
                    editType: ElementEditorTypes.OptionSelect,
                    fetchOptions: ['EXTERNAL_DATA_INTEGRATION_OPTIONS'],
                    hint: `Highlighted date comparison start date for the picker. `,
                    label: 'Comparison Start',
                    id: "e34f377b-f824-4331-924d-5c3e9ee5f08e"
                },
                {
                    name: SpecialElementKeys.Default,
                    deepBind: ['dateRangeComparisonEnd'],
                    editType: ElementEditorTypes.OptionSelect,
                    fetchOptions: ['EXTERNAL_DATA_INTEGRATION_OPTIONS'],
                    hint: `Highlighted date comparison end date for the picker. `,
                    label: 'Comparison End',
                    id: "1e65d445-b3ed-4ab6-8689-1f7fe2d85da6"
                },
            ]
        },
    ]
};
const REPORT_SHEET_SIDE_MENU_OPTIONS = [
    {
        title: "Sheet Configuration",
        subTitle: "Configure how your data appears and organizes in the report",
        config: ConfigTypes.SheetConfig,
        icon: 'construction',
        color: '#1976d2'
    },
];

const REPORT_DATE_RANGE_PICKER = {
    "id": "491523bc-4170-476c-95c9-0a4041e073e2",
    "formControlName": "dateRange",
    "sectionId": "9bb19b6a-829c-49fb-8cd9-9df753140d92",
    "label": "Date range",
    "element": ElementTypes.DateRangePicker,
    "dataType": InputDataTypes.Date,
    "appearance": "outline",
    "isCalculatedField": false,
    "required": true,
    "onlySetTempErrorOnTouch": false,
    "colSize": 12,
    "validators": [],
    "startDateControl": "start",
    "endDateControl": "end"
};
const REPORT_SHEET_INPUTS = [
    REPORT_DATE_RANGE_PICKER,
];

class TimeZoneAdapterService extends MomentDateAdapter {
    constructor(dateLocale) {
        super(dateLocale);
        // Get user's device locale if not specified otherwise
        if (!dateLocale) {
            this.setLocale(navigator.language);
        }
        // Get the user's timezone from their device
        this.userTimezone = Intl.DateTimeFormat().resolvedOptions().timeZone;
    }
    // Override parse method to handle user timezone
    parse(value, parseFormat) {
        if (value && typeof value === 'string') {
            return moment.tz(value, parseFormat, this.locale, true, this.userTimezone);
        }
        return value ? moment.tz(value, this.userTimezone).locale(this.locale) : null;
    }
    // Override format to display in user timezone
    format(date, displayFormat) {
        if (!this.isValid(date)) {
            return '';
        }
        return date.tz(this.userTimezone).locale(this.locale).format(displayFormat);
    }
    // Override create date to use user timezone
    createDate(year, month, date) {
        return moment.tz([year, month, date], this.userTimezone).locale(this.locale);
    }
    // Override to use timezone
    today() {
        return moment().tz(this.userTimezone).locale(this.locale);
    }
    // Make sure deserialize maintains timezone
    deserialize(value) {
        let date;
        if (value instanceof Date) {
            date = moment(value).tz(this.userTimezone).locale(this.locale);
        }
        if (typeof value === 'string') {
            if (!value) {
                return null;
            }
            date = moment(value, moment.ISO_8601).tz(this.userTimezone).locale(this.locale);
        }
        if (date && this.isValid(date)) {
            return date;
        }
        return super.deserialize(value);
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: TimeZoneAdapterService, deps: [{ token: MAT_DATE_LOCALE, optional: true }], target: i0.ɵɵFactoryTarget.Injectable }); }
    static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: TimeZoneAdapterService, providedIn: 'root' }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: TimeZoneAdapterService, decorators: [{
            type: Injectable,
            args: [{
                    providedIn: 'root'
                }]
        }], ctorParameters: () => [{ type: undefined, decorators: [{
                    type: Optional
                }, {
                    type: Inject,
                    args: [MAT_DATE_LOCALE]
                }] }] });

const CUSTOM_DATE_FORMATS = {
    parse: {
        dateInput: 'L', // Keep this for parsing
    },
    display: {
        // Be more explicit about the format you want
        dateInput: 'DD MMM YYYY', // This will show dates like "16 May 2024"
        // Or use 'DD/MM/YYYY' for a more compact format
        monthYearLabel: 'MMM YYYY',
        dateA11yLabel: 'LL',
        monthYearA11yLabel: 'MMMM YYYY',
    },
};
class ReportSheetComponent {
    constructor() {
        this._config = null;
        this.NGX_T_REPORTS_CONFIG_TOKEN = inject(NGX_T_REPORTS_CONFIG_TOKEN);
        this.NGX_T_FORMS_CONFIG = inject(NGX_T_FORMS_CONFIG_TOKEN);
        this.EXTERNAL_DATA_INTEGRATION = this.NGX_T_REPORTS_CONFIG_TOKEN.dataIntegration;
        this.externalDataIntegration$ = this.EXTERNAL_DATA_INTEGRATION().pipe(distinctUntilChanged((prev, curr) => _isEqual(prev, curr)));
        this.reportName = null;
        this.editMode = false;
        this.sideMenuOptions = REPORT_SHEET_SIDE_MENU_OPTIONS;
        this.configChange = new EventEmitter();
        this.error$ = new BehaviorSubject(undefined);
        this.dataList$ = new BehaviorSubject([]);
        this.loading$ = new BehaviorSubject(false);
        // Add a class property to track the debounce timer
        this.loadDataDebounceTimer = null;
        this.configInEdit = null;
        this.showSidePanel = false;
        this.formsUtils = {
            httpGetDataFunction: (url, options) => this.NGX_T_FORMS_CONFIG.formBuilder.httpGetDataFunction(url, options),
            httpPostDataFunction: (url, data, options) => this.NGX_T_FORMS_CONFIG.formBuilder.httpPostDataFunction(url, data, options),
            submitForm: () => new Observable(subscriber => { subscriber.complete(); }),
            setSubmissionStatusValue: (status) => { },
            saveFormData: function () {
                throw new Error('Function not implemented.');
            },
            runPipeLine: function (pipeline, workflowId) {
                throw new Error('Function not implemented.');
            },
            fileUpload: function (file, fileName, fileType) {
                throw new Error('Function not implemented.');
            },
            getUserSignature: function () {
                throw new Error('Function not implemented.');
            },
            saveUserSignature: function (signature) {
                throw new Error('Function not implemented.');
            }
        };
        this.range = new FormGroup({
            startDate: new FormControl(moment$1().subtract(1, 'year')),
            endDate: new FormControl(moment$1()), //
        });
        this.report_inputs = REPORT_SHEET_INPUTS;
        this.subscription = new Subscription();
        this.config$ = combineLatest([
            this.dataList$.asObservable(),
            this.externalDataIntegration$
        ]).pipe(map(([dataList, dataIntegration]) => {
            // Create a completely new object
            const configCopy = this._config ? JSON.parse(JSON.stringify(this._config)) : {};
            return Object.freeze({
                ...configCopy,
                ALL_POSSIBLE_FIELDS: [...new Set(dataList.map((i) => Object.keys(i)).flat())],
                EXTERNAL_DATA_INTEGRATION_OPTIONS: Object.keys(dataIntegration).map((key) => ({
                    value: key,
                    label: key.replace(/([A-Z])/g, ' $1').trim()
                }))
            });
        }));
        this.dateChanged = null;
    }
    set config(config) {
        if (_isEqual(this._config, config))
            return;
        this._config = config;
        this.loadData();
    }
    get config() {
        return this._config;
    }
    // Modified loadData method with debounce
    loadData() {
        // Clear any existing timer to restart the countdown
        if (this.loadDataDebounceTimer) {
            clearTimeout(this.loadDataDebounceTimer);
        }
        // Set a new timer that will execute after 300ms of inactivity
        this.loadDataDebounceTimer = setTimeout(() => {
            const dataSource = this.config?.dataSources.at(0);
            console.error("Data Source", this.config);
            if (!dataSource) {
                this.error$.next("No data source found");
                return;
            }
            dataSource.source === 'api'
                ? this.loadApiData(dataSource.config)
                : this.loadMongoData(dataSource.config);
            // Clear the timer reference after execution
            this.loadDataDebounceTimer = null;
        }, 300);
    }
    loadMongoData(config) {
        if (!config.pipeline || config.pipeline.length === 0) {
            this.error$.next("No pipeline found");
            return;
        }
        if (!config.workflowId) {
            this.error$.next("No workflowId found");
            return;
        }
        this.loading$.next(true);
        this.NGX_T_REPORTS_CONFIG_TOKEN.runPipeLine(config.pipeline, config.workflowId).pipe(take(1), tap((data) => {
            this.dataList$.next(data.results);
            this.loading$.next(false);
            this.error$.next(undefined);
        }), catchError((error) => {
            console.error("Error", error);
            const msg = error instanceof Error ? error.message : "Unknown error";
            this.error$.next(msg);
            this.loading$.next(false);
            return error;
        })).subscribe();
    }
    loadApiData(config) {
        const missingInputs = [];
        const postData = config.backEndConfig.minimumInputRequired.reduce((acc, curr) => {
            const rangeValue = this.range.value;
            if (curr.type === "default") {
                acc[curr.name] = curr.defaultValue;
                return acc;
            }
            if (curr.type === "mapto" && rangeValue[curr.name]) {
                acc[curr.name] = rangeValue[curr.name];
                return acc;
            }
            missingInputs.push(curr.name);
            return acc;
        }, {});
        if (missingInputs.length > 0) {
            this.error$.next(`Missing inputs: ${missingInputs.join(", ")}`);
            return;
        }
        this.loading$.next(true);
        this.NGX_T_REPORTS_CONFIG_TOKEN.postToServer(config.httpEndPoint, postData).pipe(take(1), tap((response) => {
            this.dataList$.next(response);
            this.loading$.next(false);
            this.error$.next(undefined);
        }), catchError((error) => {
            const msg = !error.error.message && error instanceof Error ? error.message : error.error.message;
            console.error("Error", error);
            this.error$.next(msg);
            this.loading$.next(false);
            return error;
        })).subscribe();
        /*************  ✨ Windsurf Command ⭐  *************/
        /**
         * Loads data from an API based on the provided configuration.
         *
         * @param config - The configuration object specifying the API endpoint, method, and other parameters
         * required for fetching the data.
         */
        /*******  f6089262-9e73-4765-b244-aec461c2f1be  *******/ console.log("API Data Loading", config);
    }
    get listConfig() {
        return this.config?.listConfig || [];
    }
    set listConfig(value) {
        if (this._config) {
            this._config = {
                ...this._config,
                listConfig: value
            };
            this.configChange.emit(this._config);
        }
    }
    get groupingConfig() {
        return this.config?.groupOptions || {};
    }
    set groupingConfig(value) {
        if (this._config) {
            this._config = {
                ...this._config,
                groupOptions: value
            };
            this.configChange.emit(this._config);
        }
    }
    setConfigInEdit(type) {
        this.configInEdit = type;
    }
    setShowSidePanel() {
        this.showSidePanel = !this.showSidePanel;
        if (!this.showSidePanel) {
            this.configInEdit = null;
        }
    }
    get configActiveConfig() {
        if (this.configInEdit === null)
            return null;
        const config = {
            ...SheetConfig
        };
        return {
            ...config,
            editorSections: config.editorSections.map((section) => {
                const elements = getSectionElements(section.elements, {}, this.NGX_T_FORMS_CONFIG, this.formsUtils, []);
                return {
                    ...section,
                    elements: [...elements],
                };
            })
        };
    }
    saveElement(value) {
        let newConfig = {
            ...this.config,
            ...value
        };
        this.configChange.emit(newConfig);
        this.configInEdit = null;
    }
    set configActiveConfig(config) {
        this.configInEdit = null;
    }
    ngOnInit() {
        this.subscription.add(this.minMaxDateAndComp$.pipe(distinctUntilChanged((prev, curr) => _isEqual(prev, curr)), tap((data) => {
            if (data.minDate) {
                this.range.patchValue({
                    startDate: data.minDate
                });
            }
            if (data.maxDate) {
                this.range.patchValue({
                    endDate: data.maxDate
                });
            }
        })).subscribe());
    }
    ngOnDestroy() {
        this.subscription.unsubscribe();
    }
    get minMaxDateAndComp$() {
        return combineLatest([this.config$, this.externalDataIntegration$]).pipe(map(([config, dataIntegration]) => {
            const integrationMinKey = config?.dateRangeMin || '';
            const integrationMaxKey = config?.dateRangeMax || '';
            const integrationCompStartKey = config?.dateRangeComparisonStart || '';
            const integrationCompEndKey = config?.dateRangeComparisonEnd || '';
            // Convert to moment objects if values exist, otherwise null
            const minDate = dataIntegration[integrationMinKey]
                ? moment$1(dataIntegration[integrationMinKey])
                : null;
            const maxDate = dataIntegration[integrationMaxKey]
                ? moment$1(dataIntegration[integrationMaxKey])
                : null;
            const compStartDate = dataIntegration[integrationCompStartKey]
                ? moment$1(dataIntegration[integrationCompStartKey])
                : null;
            const compEndDate = dataIntegration[integrationCompEndKey]
                ? moment$1(dataIntegration[integrationCompEndKey])
                : null;
            return {
                minDate,
                maxDate,
                compStartDate,
                compEndDate
            };
        }));
    }
    dateRangeChanged(event, control) {
        const value = event.value;
        if (this.range) {
            this.range.patchValue({
                [control]: value
            });
            this.dateChanged = {
                ...this.dateChanged,
                [control]: value
            };
        }
        this.loadData();
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: ReportSheetComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
    static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.14", type: ReportSheetComponent, isStandalone: true, selector: "app-report-sheet", inputs: { reportName: "reportName", editMode: "editMode", config: "config" }, outputs: { configChange: "configChange" }, providers: [
            { provide: MAT_DATE_LOCALE, useFactory: () => navigator.language },
            { provide: DateAdapter, useClass: TimeZoneAdapterService },
            { provide: MAT_DATE_FORMATS, useValue: CUSTOM_DATE_FORMATS }
        ], ngImport: i0, template: "@if(error$|async){\r\n<mat-toolbar class=\"error-toolbar\">\r\n    <mat-icon  color=\"warn\"  aria-hidden=\"false\" aria-label=\"Error loading transactions\">error_outline</mat-icon>\r\n    <span class=\"error-message\">\r\n        <div class=\"error-title\">\r\n            Failed To load report sheet\r\n        </div>\r\n        <div class=\"error-details\">\r\n            {{error$|async}}\r\n        </div>\r\n    </span>\r\n    <span class=\"spacer\"></span>\r\n    <button (click)=\"loadData()\" mat-flat-button color=\"primary\" aria-label=\"Retry loading transactions\">\r\n        <mat-icon>refresh</mat-icon>\r\n        Retry\r\n    </button>\r\n</mat-toolbar>\r\n}\r\n\r\n\r\n\r\n<div class=\"report-sheet-container\">\r\n    <div class=\"report-sheet-content\">\r\n        @if(loading$|async){\r\n        <div\r\n            style=\"max-width:400px; margin:auto; padding: 20px; height: 80%; display: flex; align-items: center; justify-content: center;\">\r\n            <div style=\"display: flex; flex-direction: column; align-items: center;\">\r\n                <mat-spinner diameter=\"40\" mode=\"indeterminate\"></mat-spinner>\r\n                <div style=\"text-align: center; margin-top: 10px;\">Loading Report...</div>\r\n            </div>\r\n\r\n        </div>\r\n\r\n\r\n        }@else {\r\n        <mat-toolbar class=\"report-inputs-toolbar\">\r\n            <mat-form-field [subscriptSizing]=\"'dynamic'\" appearance=\"fill\" class=\"date-range-input\">\r\n                <mat-label>Enter a date range</mat-label>\r\n                <mat-date-range-input [min]=\"(minMaxDateAndComp$|async)?.minDate\" [max]=\"(minMaxDateAndComp$|async)?.maxDate\" [formGroup]=\"range\"\r\n                 \r\n                [rangePicker]=\"picker\"\r\n                [comparisonStart]=\"(minMaxDateAndComp$|async)?.compStartDate\"\r\n                [comparisonEnd]=\"(minMaxDateAndComp$|async)?.compEndDate\"\r\n                >\r\n                    <input    matStartDate (dateChange)=\"dateRangeChanged($event, 'startDate')\" formControlName=\"startDate\"\r\n                        placeholder=\"Start date\">\r\n                    <input  (dateChange)=\"dateRangeChanged($event, 'endDate')\" matEndDate formControlName=\"endDate\"\r\n                        placeholder=\"End date\">\r\n                </mat-date-range-input>\r\n\r\n                <mat-datepicker-toggle matIconSuffix [for]=\"picker\"></mat-datepicker-toggle>\r\n                <mat-date-range-picker touchUi #picker>\r\n                    <mat-date-range-picker-actions>\r\n                        <button mat-button matDateRangePickerCancel>Cancel</button>\r\n                        <button mat-raised-button color=\"primary\" style=\"min-width:120px;border-radius:16px\" matDateRangePickerApply>Apply</button>\r\n                    </mat-date-range-picker-actions>\r\n                </mat-date-range-picker>\r\n\r\n                @if (range?.controls?.['startDate']?.hasError('matStartDateInvalid')) {\r\n                <mat-error>Invalid start date</mat-error>\r\n                }\r\n                @if (range?.controls?.['endDate']?.hasError('matEndDateInvalid')) {\r\n                <mat-error>Invalid end date</mat-error>\r\n                }\r\n                <button matSuffix mat-icon-button style=\"    margin-right: px;\r\n    margin-left: px;\" color=\"primary\" (click)=\"loadData()\" matTooltip=\"Refresh data\" [matTooltipPosition]=\"'before'\">\r\n                    <mat-icon>\r\n                        refresh\r\n                    </mat-icon>\r\n                </button>\r\n            </mat-form-field>\r\n\r\n\r\n\r\n\r\n        </mat-toolbar>\r\n        <mat-divider></mat-divider>\r\n\r\n        <app-ngx-t-matrix-table\r\n            \r\n        [list]=\"dataList$|async\" [listConfig]=\"listConfig\" [groupOptions]=\"groupingConfig\"\r\n            [reportName]=\"reportName\">\r\n            <ng-content ></ng-content>\r\n            \r\n        </app-ngx-t-matrix-table>}\r\n    </div>\r\n    <div class=\"report-sheet-sidebar-right\">\r\n\r\n\r\n        @if(showSidePanel && configActiveConfig === null){\r\n        <div class=\"side-buttons-container\">\r\n            @for(item of sideMenuOptions; track item.config){\r\n            <button (click)=\"setConfigInEdit(item.config)\" mat-icon-button [matTooltip]=\"item.title\"\r\n                [matTooltipPosition]=\"'before'\">\r\n                <mat-icon [style.color]=\"item.color\">{{item.icon}}</mat-icon>\r\n\r\n            </button>\r\n\r\n            }\r\n        </div>\r\n        }\r\n\r\n\r\n        @if(configActiveConfig && configInEdit !== null){\r\n        <lib-element-editor [inEdit]=\"config$|async\" [label]=\"configActiveConfig.label\"\r\n            [subTitle]=\"configActiveConfig.subTitle\" [editorSections]=\"configActiveConfig.editorSections\"\r\n            [formInputs]=\"  report_inputs \" [saveButtonLabel]=\"configActiveConfig.saveButtonLabel\"\r\n            (closeEditor)=\"configActiveConfig = null\" (saveElement)=\"saveElement($event)\">\r\n        </lib-element-editor>\r\n        }\r\n\r\n        @if(editMode && configInEdit === null){\r\n        <button (click)=\"setShowSidePanel()\" mat-flat-button class=\"config-options\" color=\"accent\">\r\n            <mat-icon>\r\n                {{\r\n                showSidePanel ? 'navigate_next' : 'navigate_before'\r\n                }}\r\n\r\n            </mat-icon>\r\n            <span class=\"label\">\r\n                {{\r\n                showSidePanel ? 'Hide side panel' : 'Show side panel'\r\n                }}\r\n\r\n            </span>\r\n\r\n        </button>\r\n        }\r\n\r\n\r\n\r\n    </div>\r\n\r\n</div>\r\n\r\n\r\n\r\n<!-- @for(item of tMatrixTableConfigMenu; track item.config){\r\n    <button (click)=\"setActiveConfig(item.config)\" mat-menu-item>\r\n      <mat-icon>{{item.icon}}</mat-icon>\r\n      <span>\r\n        <div>{{item.title}}</div>\r\n        <small>\r\n          {{item.subTitle}}\r\n        </small>\r\n      </span>\r\n      \r\n    </button>\r\n    \r\n    <mat-divider></mat-divider>\r\n  \r\n  } -->", styles: [".error-message{margin-left:16px}.error-title{font-size:14px;font-weight:500;line-height:1.5}.error-details{font-size:14px;opacity:.8;line-height:normal}.report-sheet-container{display:flex;flex-direction:row;max-width:100vw;height:100%;min-height:0}.report-sheet-content{flex:1 1 auto;overflow-y:auto;overflow-x:hidden;padding:0;min-height:0;height:100%;max-height:100%}.report-sheet-sidebar-right{flex:0 1 auto;min-width:0;max-width:480px;border-left:1px solid rgba(0,0,0,.12);background-color:var(--mat-sys-surface-container);height:100%}.config-options{border-radius:58px 0 0 58px!important;transition:all .3s cubic-bezier(.25,1,.5,1);padding-right:10px;z-index:1000;position:absolute;bottom:16px;min-width:0px;right:0;overflow:hidden}.config-options .label{display:none}.config-options:hover{padding-right:28px;box-shadow:#32325d4d 0 4px 6px -1px,#00000059 0 2px 4px -1px}.config-options:hover .label{display:block}.config-options mat-icon{color:#fff!important}.side-buttons-container{display:flex;flex-direction:column;gap:4px;padding:4px}.report-inputs-toolbar{height:fit-content;padding-top:28px;padding-bottom:0}.date-range-input{min-width:100%}.error-toolbar{background:var(--mat-sys-on-error-container)!important;color:var(--mat-sys-on-error)!important}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "pipe", type: i2.AsyncPipe, name: "async" }, { kind: "component", type: MatToolbar, selector: "mat-toolbar", inputs: ["color"], exportAs: ["matToolbar"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i7.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: NgxTMatrixTableComponent, selector: "app-ngx-t-matrix-table", inputs: ["list", "reportName", "listConfig", "aggregates", "groupOptions"] }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i6.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "ngmodule", type: MatDividerModule }, { kind: "component", type: i2$1.MatDivider, selector: "mat-divider", inputs: ["vertical", "inset"] }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "component", type: i5$1.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i5$1.MatLabel, selector: "mat-label" }, { kind: "directive", type: i5$1.MatError, selector: "mat-error, [matError]", inputs: ["id"] }, { kind: "directive", type: i5$1.MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "ngmodule", type: MatDatepickerModule }, { kind: "component", type: i6$1.MatDatepickerToggle, selector: "mat-datepicker-toggle", inputs: ["for", "tabIndex", "aria-label", "disabled", "disableRipple"], exportAs: ["matDatepickerToggle"] }, { kind: "component", type: i6$1.MatDateRangeInput, selector: "mat-date-range-input", inputs: ["rangePicker", "required", "dateFilter", "min", "max", "disabled", "separator", "comparisonStart", "comparisonEnd"], exportAs: ["matDateRangeInput"] }, { kind: "directive", type: i6$1.MatStartDate, selector: "input[matStartDate]", outputs: ["dateChange", "dateInput"] }, { kind: "directive", type: i6$1.MatEndDate, selector: "input[matEndDate]", outputs: ["dateChange", "dateInput"] }, { kind: "component", type: i6$1.MatDateRangePicker, selector: "mat-date-range-picker", exportAs: ["matDateRangePicker"] }, { kind: "component", type: i6$1.MatDatepickerActions, selector: "mat-datepicker-actions, mat-date-range-picker-actions" }, { kind: "directive", type: i6$1.MatDatepickerCancel, selector: "[matDatepickerCancel], [matDateRangePickerCancel]" }, { kind: "directive", type: i6$1.MatDatepickerApply, selector: "[matDatepickerApply], [matDateRangePickerApply]" }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i7$2.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i7$2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i7$2.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i7$2.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i7$2.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "ngmodule", type: MatProgressSpinnerModule }, { kind: "component", type: i4$1.MatProgressSpinner, selector: "mat-progress-spinner, mat-spinner", inputs: ["color", "mode", "value", "diameter", "strokeWidth"], exportAs: ["matProgressSpinner"] }, { kind: "component", type: ElementEditorComponent, selector: "lib-element-editor", inputs: ["inEdit", "label", "subTitle", "editorSections", "formInputs", "saveButtonLabel"], outputs: ["closeEditor", "saveElement"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i8.MatButton, selector: "    button[mat-button], button[mat-raised-button], button[mat-flat-button],    button[mat-stroked-button]  ", exportAs: ["matButton"] }, { kind: "component", type: i8.MatIconButton, selector: "button[mat-icon-button]", exportAs: ["matButton"] }] }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: ReportSheetComponent, decorators: [{
            type: Component,
            args: [{ selector: 'app-report-sheet', standalone: true, imports: [CommonModule, MatToolbar, MatIconModule, NgxTMatrixTableComponent,
                        MatTooltipModule,
                        MatDividerModule,
                        MatFormFieldModule, MatDatepickerModule, FormsModule, ReactiveFormsModule,
                        MatProgressSpinnerModule,
                        ElementEditorComponent,
                        MatButtonModule], providers: [
                        { provide: MAT_DATE_LOCALE, useFactory: () => navigator.language },
                        { provide: DateAdapter, useClass: TimeZoneAdapterService },
                        { provide: MAT_DATE_FORMATS, useValue: CUSTOM_DATE_FORMATS }
                    ], template: "@if(error$|async){\r\n<mat-toolbar class=\"error-toolbar\">\r\n    <mat-icon  color=\"warn\"  aria-hidden=\"false\" aria-label=\"Error loading transactions\">error_outline</mat-icon>\r\n    <span class=\"error-message\">\r\n        <div class=\"error-title\">\r\n            Failed To load report sheet\r\n        </div>\r\n        <div class=\"error-details\">\r\n            {{error$|async}}\r\n        </div>\r\n    </span>\r\n    <span class=\"spacer\"></span>\r\n    <button (click)=\"loadData()\" mat-flat-button color=\"primary\" aria-label=\"Retry loading transactions\">\r\n        <mat-icon>refresh</mat-icon>\r\n        Retry\r\n    </button>\r\n</mat-toolbar>\r\n}\r\n\r\n\r\n\r\n<div class=\"report-sheet-container\">\r\n    <div class=\"report-sheet-content\">\r\n        @if(loading$|async){\r\n        <div\r\n            style=\"max-width:400px; margin:auto; padding: 20px; height: 80%; display: flex; align-items: center; justify-content: center;\">\r\n            <div style=\"display: flex; flex-direction: column; align-items: center;\">\r\n                <mat-spinner diameter=\"40\" mode=\"indeterminate\"></mat-spinner>\r\n                <div style=\"text-align: center; margin-top: 10px;\">Loading Report...</div>\r\n            </div>\r\n\r\n        </div>\r\n\r\n\r\n        }@else {\r\n        <mat-toolbar class=\"report-inputs-toolbar\">\r\n            <mat-form-field [subscriptSizing]=\"'dynamic'\" appearance=\"fill\" class=\"date-range-input\">\r\n                <mat-label>Enter a date range</mat-label>\r\n                <mat-date-range-input [min]=\"(minMaxDateAndComp$|async)?.minDate\" [max]=\"(minMaxDateAndComp$|async)?.maxDate\" [formGroup]=\"range\"\r\n                 \r\n                [rangePicker]=\"picker\"\r\n                [comparisonStart]=\"(minMaxDateAndComp$|async)?.compStartDate\"\r\n                [comparisonEnd]=\"(minMaxDateAndComp$|async)?.compEndDate\"\r\n                >\r\n                    <input    matStartDate (dateChange)=\"dateRangeChanged($event, 'startDate')\" formControlName=\"startDate\"\r\n                        placeholder=\"Start date\">\r\n                    <input  (dateChange)=\"dateRangeChanged($event, 'endDate')\" matEndDate formControlName=\"endDate\"\r\n                        placeholder=\"End date\">\r\n                </mat-date-range-input>\r\n\r\n                <mat-datepicker-toggle matIconSuffix [for]=\"picker\"></mat-datepicker-toggle>\r\n                <mat-date-range-picker touchUi #picker>\r\n                    <mat-date-range-picker-actions>\r\n                        <button mat-button matDateRangePickerCancel>Cancel</button>\r\n                        <button mat-raised-button color=\"primary\" style=\"min-width:120px;border-radius:16px\" matDateRangePickerApply>Apply</button>\r\n                    </mat-date-range-picker-actions>\r\n                </mat-date-range-picker>\r\n\r\n                @if (range?.controls?.['startDate']?.hasError('matStartDateInvalid')) {\r\n                <mat-error>Invalid start date</mat-error>\r\n                }\r\n                @if (range?.controls?.['endDate']?.hasError('matEndDateInvalid')) {\r\n                <mat-error>Invalid end date</mat-error>\r\n                }\r\n                <button matSuffix mat-icon-button style=\"    margin-right: px;\r\n    margin-left: px;\" color=\"primary\" (click)=\"loadData()\" matTooltip=\"Refresh data\" [matTooltipPosition]=\"'before'\">\r\n                    <mat-icon>\r\n                        refresh\r\n                    </mat-icon>\r\n                </button>\r\n            </mat-form-field>\r\n\r\n\r\n\r\n\r\n        </mat-toolbar>\r\n        <mat-divider></mat-divider>\r\n\r\n        <app-ngx-t-matrix-table\r\n            \r\n        [list]=\"dataList$|async\" [listConfig]=\"listConfig\" [groupOptions]=\"groupingConfig\"\r\n            [reportName]=\"reportName\">\r\n            <ng-content ></ng-content>\r\n            \r\n        </app-ngx-t-matrix-table>}\r\n    </div>\r\n    <div class=\"report-sheet-sidebar-right\">\r\n\r\n\r\n        @if(showSidePanel && configActiveConfig === null){\r\n        <div class=\"side-buttons-container\">\r\n            @for(item of sideMenuOptions; track item.config){\r\n            <button (click)=\"setConfigInEdit(item.config)\" mat-icon-button [matTooltip]=\"item.title\"\r\n                [matTooltipPosition]=\"'before'\">\r\n                <mat-icon [style.color]=\"item.color\">{{item.icon}}</mat-icon>\r\n\r\n            </button>\r\n\r\n            }\r\n        </div>\r\n        }\r\n\r\n\r\n        @if(configActiveConfig && configInEdit !== null){\r\n        <lib-element-editor [inEdit]=\"config$|async\" [label]=\"configActiveConfig.label\"\r\n            [subTitle]=\"configActiveConfig.subTitle\" [editorSections]=\"configActiveConfig.editorSections\"\r\n            [formInputs]=\"  report_inputs \" [saveButtonLabel]=\"configActiveConfig.saveButtonLabel\"\r\n            (closeEditor)=\"configActiveConfig = null\" (saveElement)=\"saveElement($event)\">\r\n        </lib-element-editor>\r\n        }\r\n\r\n        @if(editMode && configInEdit === null){\r\n        <button (click)=\"setShowSidePanel()\" mat-flat-button class=\"config-options\" color=\"accent\">\r\n            <mat-icon>\r\n                {{\r\n                showSidePanel ? 'navigate_next' : 'navigate_before'\r\n                }}\r\n\r\n            </mat-icon>\r\n            <span class=\"label\">\r\n                {{\r\n                showSidePanel ? 'Hide side panel' : 'Show side panel'\r\n                }}\r\n\r\n            </span>\r\n\r\n        </button>\r\n        }\r\n\r\n\r\n\r\n    </div>\r\n\r\n</div>\r\n\r\n\r\n\r\n<!-- @for(item of tMatrixTableConfigMenu; track item.config){\r\n    <button (click)=\"setActiveConfig(item.config)\" mat-menu-item>\r\n      <mat-icon>{{item.icon}}</mat-icon>\r\n      <span>\r\n        <div>{{item.title}}</div>\r\n        <small>\r\n          {{item.subTitle}}\r\n        </small>\r\n      </span>\r\n      \r\n    </button>\r\n    \r\n    <mat-divider></mat-divider>\r\n  \r\n  } -->", styles: [".error-message{margin-left:16px}.error-title{font-size:14px;font-weight:500;line-height:1.5}.error-details{font-size:14px;opacity:.8;line-height:normal}.report-sheet-container{display:flex;flex-direction:row;max-width:100vw;height:100%;min-height:0}.report-sheet-content{flex:1 1 auto;overflow-y:auto;overflow-x:hidden;padding:0;min-height:0;height:100%;max-height:100%}.report-sheet-sidebar-right{flex:0 1 auto;min-width:0;max-width:480px;border-left:1px solid rgba(0,0,0,.12);background-color:var(--mat-sys-surface-container);height:100%}.config-options{border-radius:58px 0 0 58px!important;transition:all .3s cubic-bezier(.25,1,.5,1);padding-right:10px;z-index:1000;position:absolute;bottom:16px;min-width:0px;right:0;overflow:hidden}.config-options .label{display:none}.config-options:hover{padding-right:28px;box-shadow:#32325d4d 0 4px 6px -1px,#00000059 0 2px 4px -1px}.config-options:hover .label{display:block}.config-options mat-icon{color:#fff!important}.side-buttons-container{display:flex;flex-direction:column;gap:4px;padding:4px}.report-inputs-toolbar{height:fit-content;padding-top:28px;padding-bottom:0}.date-range-input{min-width:100%}.error-toolbar{background:var(--mat-sys-on-error-container)!important;color:var(--mat-sys-on-error)!important}\n"] }]
        }], propDecorators: { reportName: [{
                type: Input
            }], editMode: [{
                type: Input
            }], config: [{
                type: Input
            }], configChange: [{
                type: Output
            }] } });

/*
 * Public API Surface of ngx-t-reports
 */

/**
 * Generated bundle index. Do not edit.
 */

export { EChartsComponent, NGX_T_REPORTS_CONFIG_TOKEN, NgxTMatrixTableComponent, ReportSheetComponent, TimeZoneAdapterService };
//# sourceMappingURL=ngx-t-reports.mjs.map