UNPKG

sb-dashlets

Version:

A Simple extensible angular library to render JSON data into different chart formats

1,085 lines (1,063 loc) 58.5 kB
import { InjectionToken, EventEmitter, ɵɵdefineInjectable, ɵɵinject, Injectable, Inject, ViewChild, Component, ViewContainerRef, Directive, TemplateRef, Input, ComponentFactoryResolver, Output, ContentChildren, ChangeDetectorRef, NgModule } from '@angular/core'; import { of, Subject, zip } from 'rxjs'; import { tap, takeUntil, debounceTime, distinctUntilChanged, map, startWith, pairwise } from 'rxjs/operators'; import * as jsonexport from 'jsonexport/dist'; import { __decorate, __extends, __awaiter, __generator, __assign, __rest, __param, __spread, __read } from 'tslib'; import { HttpClient, HttpClientModule } from '@angular/common/http'; import { BaseChartDirective, ThemeService, ChartsModule } from 'ng2-charts'; import { groupBy, get, mapValues, sumBy, remove, toNumber, minBy, maxBy, omitBy, isEmpty, compact, sortBy, uniq, forEach, filter, every, some, trim, toLower } from 'lodash-es'; import { v4 } from 'uuid'; import { DataTableDirective, DataTablesModule } from 'angular-datatables'; import { FormBuilder, ReactiveFormsModule } from '@angular/forms'; import * as momentImported from 'moment'; import { CommonModule } from '@angular/common'; import { NgMultiSelectDropDownModule } from 'ng-multiselect-dropdown'; import { NgxDaterangepickerMd } from 'ngx-daterangepicker-material'; var ChartType; (function (ChartType) { ChartType["BAR"] = "bar"; ChartType["LINE"] = "line"; ChartType["PIE"] = "pie"; ChartType["DOUGHNUT"] = "doughnut"; ChartType["POLAR"] = "polar"; ChartType["RADAR"] = "radar"; ChartType["BUBBLE"] = "bubble"; ChartType["SCATTER"] = "scatter"; ChartType["AREA"] = "area"; ChartType["HORIZONTAL_BAR"] = "bar"; ChartType["VERTICAL_BAR"] = "verticalBar"; ChartType["BIG_NUMBER"] = "bigNumber"; })(ChartType || (ChartType = {})); var IReportType; (function (IReportType) { IReportType["CHART"] = "chart"; IReportType["TABLE"] = "table"; })(IReportType || (IReportType = {})); var ReportState; (function (ReportState) { ReportState["PENDING"] = "pending"; ReportState["DONE"] = "done"; })(ReportState || (ReportState = {})); var TableType; (function (TableType) { TableType["TABLE"] = "table"; })(TableType || (TableType = {})); var DASHLET_CONSTANTS = new InjectionToken('CONSTANTS', { factory: function () { return constants; } }); var constants = { INVALID_INPUT: "invalid input", METHOD_NOT_IMPLEMENTED: "Method not implemented", CHART_NOT_INITIALIZED: "Chart is not initialized" }; var jsonExport = jsonexport; var BaseComponent = /** @class */ (function () { function BaseComponent(dataService) { this.dataService = dataService; this.data = []; this._isInitialized = false; this.state = new EventEmitter(); this.events = new EventEmitter(); this.exportOptions = []; } BaseComponent.prototype.fetchData = function (config) { var _this = this; var _a = config || {}, _b = _a.values, values = _b === void 0 ? null : _b, _c = _a.location, _d = _c === void 0 ? {} : _c, _e = _d.url, url = _e === void 0 ? null : _e, _f = _d.options, options = _f === void 0 ? {} : _f, _g = _d.method, method = _g === void 0 ? 'GET' : _g; if (values) return of(values); if (!url) throw new Error('invalid input'); this.state.emit(ReportState.PENDING); return this.dataService.fetchData({ method: method, url: url, options: options }).pipe(tap(function (_) { return _this.state.emit(ReportState.DONE); })); }; BaseComponent.prototype.getConfigValue = function (key) { return this.config && this.config[key]; }; BaseComponent.prototype.checkIfInitialized = function () { if (!this._isInitialized) { throw Error(constants.CHART_NOT_INITIALIZED); } }; BaseComponent.prototype._downloadFile = function (url, filename) { var link = document.createElement("a"); link.setAttribute("href", url); link.setAttribute("download", filename); link.click(); }; BaseComponent.prototype.exportAsCsv = function (data) { var _this = this; jsonExport(data || this.data, function (error, csv) { if (!error && csv) { var blob = new Blob([csv], { type: 'text/csv;charset=utf-8;' }); var url = URL.createObjectURL(blob); _this._downloadFile(url, 'data.csv'); } }); }; return BaseComponent; }()); var DataService = /** @class */ (function () { function DataService(httpClient) { this.httpClient = httpClient; this.cachedData = new Map(); } DataService.prototype.fetchData = function (config) { var _this = this; var stringifiedConfig = JSON.stringify(config); if (this.cachedData.has(stringifiedConfig)) return this.cachedData.get(stringifiedConfig); var method = config.method, url = config.url, options = config.options; return this.httpClient.request(method, url, options).pipe(tap(function (response) { _this.cachedData.set(stringifiedConfig, response); })); }; DataService.ctorParameters = function () { return [ { type: HttpClient } ]; }; DataService.ngInjectableDef = ɵɵdefineInjectable({ factory: function DataService_Factory() { return new DataService(ɵɵinject(HttpClient)); }, token: DataService, providedIn: "root" }); DataService = __decorate([ Injectable({ providedIn: 'root' }) ], DataService); return DataService; }()); var DEFAULT_CONFIG = new InjectionToken('DEFAULT_CONFIG'); var CHART_DEFAULT_CONFIG = { labels: [], datasets: [], legend: true, options: {}, colors: [] }; var ɵ0 = CHART_DEFAULT_CONFIG; /** * @dynamic */ var ChartJsComponent = /** @class */ (function (_super) { __extends(ChartJsComponent, _super); function ChartJsComponent(dataService, defaultConfig, CONSTANTS) { var _this = _super.call(this, dataService) || this; _this.dataService = dataService; _this.CONSTANTS = CONSTANTS; _this.reportType = IReportType.CHART; _this.inputParameters = {}; _this.exportOptions = ['png', 'csv', 'jpg']; _this._defaultConfig = defaultConfig; return _this; } /** * @description initializes the component with the passed config and data * @param {InputParams} { config, type, data } * @return {*} {Promise<any>} * @memberof ChartJsComponent */ ChartJsComponent.prototype.initialize = function (_a) { var config = _a.config, type = _a.type, data = _a.data; return __awaiter(this, void 0, void 0, function () { var fetchedJSON, _b; return __generator(this, function (_c) { switch (_c.label) { case 0: if (!(config && type && data)) throw new SyntaxError(this.CONSTANTS.INVALID_INPUT); this.config = config = __assign({}, config, { type: type }); _b = this; return [4 /*yield*/, this.fetchData(data).toPromise().catch(function (err) { return []; })]; case 1: fetchedJSON = _b.data = _c.sent(); this.builder(config, fetchedJSON); this._isInitialized = true; this.state.emit(ReportState.DONE); return [2 /*return*/]; } }); }); }; /** * @description It's a high order function responsible for getting labels and datasets, addition and removal of data. * @private * @param {string} labelExpr * @param {IDataset[]} datasets * @return {*} * @memberof ChartJsComponent */ ChartJsComponent.prototype.getLabelsAndDatasetsClosure = function (labelExpr, datasets) { return function (data) { var getDataGroupedByLabelExpr = function (data) { return groupBy(data, function (val) { var value = get(val, labelExpr); return value && typeof value === 'string' ? value.toLowerCase().trim() : ''; }); }; var getLabels = function (data) { return Object.keys(data); }; var getDatasets = function (data) { return datasets.map(function (dataset) { return __assign({}, dataset, (dataset.dataExpr && { data: Object.values(mapValues(data, function (rows) { return sumBy(rows, function (row) { return +(row[dataset.dataExpr] || 0); }); })) })); }); }; var findDataByLabelPredicate = function (label) { return function (row) { return row[labelExpr] === label; }; }; return { addData: function (newData) { data = data.concat(newData); return this.getData(data); }, getData: function (overriddenData) { data = overriddenData || data; var groupedData = getDataGroupedByLabelExpr(data); return { labels: getLabels(groupedData), datasets: getDatasets(groupedData) }; }, removeData: function (label) { remove(data, findDataByLabelPredicate(label)); return this.getData(data); } }; }; }; /** * @description prepared the chart data using the configuration passed * @param {Partial<IChartOptions>} config * @param {*} data * @memberof ChartJsComponent */ ChartJsComponent.prototype.builder = function (config, data) { var _a; var _b = config.labels, labels = _b === void 0 ? [] : _b, _c = config.labelExpr, labelExpr = _c === void 0 ? null : _c, _d = config.type, type = _d === void 0 ? null : _d, _e = config.legend, legend = _e === void 0 ? true : _e, _f = config.colors, colors = _f === void 0 ? [] : _f, _g = config.datasets, datasets = _g === void 0 ? [] : _g, _h = config.options, options = _h === void 0 ? {} : _h, others = __rest(config, ["labels", "labelExpr", "type", "legend", "colors", "datasets", "options"]); options = __assign({}, others, options); if (labelExpr) { this._labelsAndDatasetsClosure = this.getLabelsAndDatasetsClosure(labelExpr, datasets)(data); var getData = this._labelsAndDatasetsClosure.getData; (_a = getData(), labels = _a.labels, datasets = _a.datasets); } this.setChartData({ labels: labels, datasets: datasets, options: options, type: type, legend: legend, colors: colors }); }; ChartJsComponent.prototype.setChartData = function (config) { if (config === void 0) { config = {}; } this.inputParameters = __assign({}, this._defaultConfig, this.inputParameters, config); this.$context = { data: this.data, config: this.config, inputParameters: this.inputParameters, exportOptions: this.exportOptions }; }; ChartJsComponent.prototype.reset = function () { // throw new Error('Method not implemented.'); }; ChartJsComponent.prototype.destroy = function () { this.baseChartDirective.chart.destroy(); }; ChartJsComponent.prototype.ngOnDestroy = function () { this.destroy(); }; /** * @description updates the type, data or Dashlet configuration * @param {InputParams} input * @memberof ChartJsComponent */ ChartJsComponent.prototype.update = function (input) { var _a; this.checkIfInitialized(); if (!input) throw new Error(this.CONSTANTS.INVALID_INPUT); var _b = input.type, type = _b === void 0 ? null : _b, _c = input.config, config = _c === void 0 ? {} : _c, _d = input.data, data = _d === void 0 ? null : _d; var labels, datasets; if (data) { var _e = config, labelExpr = _e.labelExpr, datasetsConfig = _e.datasets; if (labelExpr || datasets) { this._labelsAndDatasetsClosure = this.getLabelsAndDatasetsClosure(labelExpr || this.getConfigValue(labelExpr), datasetsConfig || this.getConfigValue(datasets))(data); } (_a = this._labelsAndDatasetsClosure.getData(data), labels = _a.labels, datasets = _a.datasets); } this.setChartData(__assign({}, config, (type && { type: type }), (labels && datasets && { labels: labels, datasets: datasets }))); this.baseChartDirective.update(); }; ChartJsComponent.prototype.addData = function (data) { this.checkIfInitialized(); if (!data) throw new Error(this.CONSTANTS.INVALID_INPUT); if (this._labelsAndDatasetsClosure) { data = Array.isArray(data) ? data : [data]; var _a = this._labelsAndDatasetsClosure.addData(data), labels = _a.labels, datasets = _a.datasets; this.setChartData({ labels: labels, datasets: datasets }); } }; ChartJsComponent.prototype.refreshChart = function () { throw new Error(this.CONSTANTS.METHOD_NOT_IMPLEMENTED); }; /** * @description Removes data associated with a label * @param {string} label * @memberof ChartJsComponent */ ChartJsComponent.prototype.removeData = function (label) { this.checkIfInitialized(); var _a = this._labelsAndDatasetsClosure.removeData(label), labels = _a.labels, datasets = _a.datasets; this.setChartData({ labels: labels, datasets: datasets }); }; ChartJsComponent.prototype.getTelemetry = function () { throw new Error(this.CONSTANTS.METHOD_NOT_IMPLEMENTED); }; ChartJsComponent.prototype.getCurrentSelection = function () { throw new Error(this.CONSTANTS.METHOD_NOT_IMPLEMENTED); }; ChartJsComponent.prototype.getDatasetAtIndex = function (index) { throw new Error(this.CONSTANTS.METHOD_NOT_IMPLEMENTED); }; ChartJsComponent.prototype.onChartClicked = function (event) { this.events.emit({ type: 'CLICK', event: event }); }; ChartJsComponent.prototype.onChartHovered = function (event) { this.events.emit({ type: 'HOVER', event: event }); }; ChartJsComponent.prototype.exportAsImage = function (format) { if (format === void 0) { format = 'jpg'; } var dataUrl = document.getElementById(this.id).toDataURL("image/" + format, 1); var fileName = "image." + format; this._downloadFile(dataUrl, fileName); }; ChartJsComponent.prototype.exportAs = function (format) { if (!this.exportOptions.includes(format)) { throw new Error('given type not supported'); } switch (format) { case 'csv': { this.exportAsCsv(); break; } default: { this.exportAsImage(format); break; } } }; ChartJsComponent.ctorParameters = function () { return [ { type: DataService }, { type: Object, decorators: [{ type: Inject, args: [DEFAULT_CONFIG,] }] }, { type: undefined, decorators: [{ type: Inject, args: [DASHLET_CONSTANTS,] }] } ]; }; __decorate([ ViewChild(BaseChartDirective, { static: false }) ], ChartJsComponent.prototype, "baseChartDirective", void 0); ChartJsComponent = __decorate([ Component({ selector: 'sb-chart-js', template: "<ng-template #defaultFilterTemplate let-context>\n <sb-dashlets-filters [data]=\"context?.data\" [config]=\"context?.config?.filters\"\n (filteredData)=\"update({data: $event})\">\n </sb-dashlets-filters>\n</ng-template>\n\n<ng-container *ngIf=\"$context?.config?.filters\" [ngTemplateOutlet]=\"templateRefs?.filter || defaultFilterTemplate\"\n [ngTemplateOutletContext]=\"{'$implicit': $context}\">\n</ng-container>\n\n<ng-container *ngIf=\"templateRefs?.header && $context\" [ngTemplateOutlet]=\"templateRefs?.header\"\n [ngTemplateOutletContext]=\"{'$implicit': $context}\">\n</ng-container>\n\n<div *ngIf=\"$context?.inputParameters as data\">\n <canvas [id]=\"id\" baseChart width=\"400\" height=\"400\" [datasets]=\"data?.datasets\" [labels]=\"data?.labels\"\n [options]=\"data?.options\" [colors]=\"data?.colors\" [legend]=\"data?.legend\" [chartType]=\"data?.type\"\n (chartClick)=\"onChartClicked($event)\" (chartHover)=\"onChartHovered($event)\"></canvas>\n</div>\n\n<ng-container *ngIf=\"templateRefs?.footer && $context\" [ngTemplateOutlet]=\"templateRefs?.footer\"\n [ngTemplateOutletContext]=\"{'$implicit': $context}\">\n</ng-container>", providers: [ ThemeService, { provide: DEFAULT_CONFIG, useValue: ɵ0 } ], styles: [""] }), __param(1, Inject(DEFAULT_CONFIG)), __param(2, Inject(DASHLET_CONSTANTS)) ], ChartJsComponent); return ChartJsComponent; }(BaseComponent)); var chartJs_component = /*#__PURE__*/Object.freeze({ __proto__: null, ChartJsComponent: ChartJsComponent, ɵ0: ɵ0 }); var ReportWrapperDirective = /** @class */ (function () { function ReportWrapperDirective(viewContainerRef) { this.viewContainerRef = viewContainerRef; } ReportWrapperDirective.ctorParameters = function () { return [ { type: ViewContainerRef } ]; }; ReportWrapperDirective = __decorate([ Directive({ selector: '[sbReportWrapper]' }) ], ReportWrapperDirective); return ReportWrapperDirective; }()); var TemplateRefsDirective = /** @class */ (function () { function TemplateRefsDirective(templateRef) { this.templateRef = templateRef; } TemplateRefsDirective.ctorParameters = function () { return [ { type: TemplateRef } ]; }; __decorate([ Input('sbTemplateRef') ], TemplateRefsDirective.prototype, "slot", void 0); TemplateRefsDirective = __decorate([ Directive({ selector: '[sbTemplateRef]' }) ], TemplateRefsDirective); return TemplateRefsDirective; }()); var _a; var TYPE_TO_COMPONENT_MAPPING = (_a = {}, _a[ChartType.LINE] = function () { return Promise.resolve().then(function () { return chartJs_component; }).then(function (module) { return module.ChartJsComponent; }); }, _a[ChartType.BAR] = function () { return Promise.resolve().then(function () { return chartJs_component; }).then(function (module) { return module.ChartJsComponent; }); }, _a[ChartType.PIE] = function () { return Promise.resolve().then(function () { return chartJs_component; }).then(function (module) { return module.ChartJsComponent; }); }, _a[ChartType.AREA] = function () { return Promise.resolve().then(function () { return chartJs_component; }).then(function (module) { return module.ChartJsComponent; }); }, _a[ChartType.BUBBLE] = function () { return Promise.resolve().then(function () { return chartJs_component; }).then(function (module) { return module.ChartJsComponent; }); }, _a[ChartType.DOUGHNUT] = function () { return Promise.resolve().then(function () { return chartJs_component; }).then(function (module) { return module.ChartJsComponent; }); }, _a[ChartType.POLAR] = function () { return Promise.resolve().then(function () { return chartJs_component; }).then(function (module) { return module.ChartJsComponent; }); }, _a[ChartType.SCATTER] = function () { return Promise.resolve().then(function () { return chartJs_component; }).then(function (module) { return module.ChartJsComponent; }); }, _a[ChartType.DOUGHNUT] = function () { return Promise.resolve().then(function () { return chartJs_component; }).then(function (module) { return module.ChartJsComponent; }); }, _a[ChartType.BIG_NUMBER] = function () { return Promise.resolve().then(function () { return bigNumber_component; }).then(function (module) { return module.BigNumberComponent; }); }, _a[TableType.TABLE] = function () { return Promise.resolve().then(function () { return dtTable_component; }).then(function (module) { return module.DtTableComponent; }); }, _a); var transformTemplates = function (result, current) { result[current.slot] = current.templateRef; return result; }; var ɵ0$1 = transformTemplates; var DashletComponent = /** @class */ (function () { function DashletComponent(componentFactoryResolver) { this.componentFactoryResolver = componentFactoryResolver; this.events = new EventEmitter(); this._typeToComponentMapping = Object.freeze(TYPE_TO_COMPONENT_MAPPING); } Object.defineProperty(DashletComponent.prototype, "instance", { get: function () { return this._componentInstance; }, set: function (componentInstance) { this._componentInstance = componentInstance; }, enumerable: true, configurable: true }); DashletComponent.prototype.ngOnInit = function () { this.id = v4(); if (!this.type && !this.config && !this.data) { throw new SyntaxError('Syntax Error. Please check configuration'); } this.loadComponent(this.type).catch(function (err) { console.error(err); throw err; }); }; DashletComponent.prototype.loadComponent = function (type) { return __awaiter(this, void 0, void 0, function () { var componentResolver, component, componentFactory, componentRef, instance; return __generator(this, function (_a) { switch (_a.label) { case 0: componentResolver = this._typeToComponentMapping[type]; if (!componentResolver) { throw new Error('Given Type not supported'); } return [4 /*yield*/, componentResolver()]; case 1: component = _a.sent(); this.reportWrapper.viewContainerRef.clear(); componentFactory = this.componentFactoryResolver.resolveComponentFactory(component); componentRef = this.reportWrapper.viewContainerRef.createComponent(componentFactory); instance = this.instance = componentRef.instance; if (this.templateRefs.length) { instance['templateRefs'] = this.templateRefs.toArray().reduce(transformTemplates, {}); } instance.id = this.id; instance.initialize({ config: this.config, type: this.type, data: this.data }); instance.state.subscribe(this._stateEventsHandler.bind(this)); instance.events.subscribe(this._eventsHandler.bind(this)); return [2 /*return*/]; } }); }); }; DashletComponent.prototype._stateEventsHandler = function (event) { this.events.emit({ type: 'STATE', event: event }); }; DashletComponent.prototype._eventsHandler = function (event) { this.events.emit(event); }; DashletComponent.prototype.filter = function (filteredData) { this.instance.update({ data: filteredData }); }; DashletComponent.ctorParameters = function () { return [ { type: ComponentFactoryResolver } ]; }; __decorate([ Input() ], DashletComponent.prototype, "type", void 0); __decorate([ Input() ], DashletComponent.prototype, "config", void 0); __decorate([ Input() ], DashletComponent.prototype, "data", void 0); __decorate([ Output() ], DashletComponent.prototype, "events", void 0); __decorate([ ViewChild(ReportWrapperDirective, { static: true }) ], DashletComponent.prototype, "reportWrapper", void 0); __decorate([ ContentChildren(TemplateRefsDirective) ], DashletComponent.prototype, "templateRefs", void 0); DashletComponent = __decorate([ Component({ selector: 'sb-dashlet', template: "<div>\n <ng-template sbReportWrapper></ng-template>\n</div>", styles: [""] }) ], DashletComponent); return DashletComponent; }()); var iterateeFn = function (key) { return function (row) { return toNumber(row[key]); }; }; var ɵ0$2 = iterateeFn; var SUM = function (data) { return function (key) { return sumBy(data, iterateeFn(key)); }; }; var ɵ1 = SUM; var MIN = function (data) { return function (key) { return minBy(data, iterateeFn(key))[key]; }; }; var ɵ2 = MIN; var MAX = function (data) { return function (key) { return maxBy(data, iterateeFn(key))[key]; }; }; var ɵ3 = MAX; var AVG = function (data) { return function (key) { var length = data.length || 0; if (length === 0) return 0; var totalSum = SUM(data)(key); return (totalSum / length).toFixed(2); }; }; var ɵ4 = AVG; var $operations = new Map([ ['SUM', SUM], ['MIN', MIN], ['MAX', MAX], ['AVG', AVG] ]); var runAggregator = function (aggregateFn, data, key) { var aggregateFnUpper = aggregateFn.toUpperCase(); if ($operations.has(aggregateFnUpper)) { return $operations.get(aggregateFnUpper)(data)(key); } throw new Error('Specified Aggregator function does not exists'); }; var ɵ0$3 = { header: '', footer: '', operation: 'SUM' }; var BigNumberComponent = /** @class */ (function (_super) { __extends(BigNumberComponent, _super); function BigNumberComponent(dataService, defaultConfig, cdr, CONSTANTS) { var _this = _super.call(this, dataService) || this; _this.dataService = dataService; _this.cdr = cdr; _this.CONSTANTS = CONSTANTS; _this.reportType = IReportType.CHART; _this.type = ChartType.BIG_NUMBER; _this.inputParameters = {}; _this.exportOptions = ['csv']; _this.bigNumberDataClosure = function (dataExpr) { return function ($aggregateFn) { return function (data) { return { getData: function (overriddenData) { data = overriddenData || data; return runAggregator($aggregateFn, data, dataExpr); }, addData: function (newData) { data = data.concat(newData); return this.getData(); } }; }; }; }; _this._defaultConfig = defaultConfig; return _this; } BigNumberComponent.prototype.initialize = function (_a) { var config = _a.config, data = _a.data, _b = _a.type, type = _b === void 0 ? "bigNumber" : _b; return __awaiter(this, void 0, void 0, function () { var fetchedJSON, _c; return __generator(this, function (_d) { switch (_d.label) { case 0: if (!(config && data)) throw new SyntaxError(this.CONSTANTS.INVALID_INPUT); this.config = config = __assign({}, config, { type: type }); _c = this; return [4 /*yield*/, this.fetchData(data).toPromise().catch(function (err) { return []; })]; case 1: fetchedJSON = _c.data = _d.sent(); this.builder(config, fetchedJSON); this._isInitialized = true; this.state.emit(ReportState.DONE); return [2 /*return*/]; } }); }); }; BigNumberComponent.prototype.builder = function (config, JSONData) { var _a = config.header, header = _a === void 0 ? this._defaultConfig.header : _a, _b = config.footer, footer = _b === void 0 ? this._defaultConfig.footer : _b, dataExpr = config.dataExpr, _c = config.operation, operation = _c === void 0 ? this._defaultConfig.operation : _c; if (!dataExpr || !JSONData) { throw Error(this.CONSTANTS.INVALID_INPUT); } this._bigNumberClosure = this.bigNumberDataClosure(dataExpr)(operation)(JSONData); var bigNumberObj = { header: header, footer: footer, data: this._bigNumberClosure.getData() }; this.setBigNumberData(bigNumberObj); }; BigNumberComponent.prototype.setBigNumberData = function (config) { if (config === void 0) { config = {}; } this.inputParameters = __assign({}, this._defaultConfig, this.inputParameters, config); this.$context = { data: this.data, config: this.config, inputParameters: this.inputParameters, exportOptions: this.exportOptions }; this.cdr.detectChanges(); }; BigNumberComponent.prototype.reset = function () { throw new Error(this.CONSTANTS.METHOD_NOT_IMPLEMENTED); }; BigNumberComponent.prototype.destroy = function () { throw new Error(this.CONSTANTS.METHOD_NOT_IMPLEMENTED); }; BigNumberComponent.prototype.update = function (input) { this.checkIfInitialized(); if (!input) throw new Error(this.CONSTANTS.INVALID_INPUT); var _a = input.config, config = _a === void 0 ? {} : _a, _b = input.data, data = _b === void 0 ? null : _b; var _c = config, header = _c.header, footer = _c.footer, dataExpr = _c.dataExpr, _d = _c.operation, operation = _d === void 0 ? 'SUM' : _d; var bigNumber; if (data) { this._bigNumberClosure = (dataExpr && this.bigNumberDataClosure(dataExpr)(operation)(data)) || this._bigNumberClosure; bigNumber = this._bigNumberClosure.getData(data); } this.setBigNumberData(__assign({}, (header && { header: header }), (footer && { footer: footer }), (bigNumber && { data: bigNumber }))); }; BigNumberComponent.prototype.addData = function (data) { if (!data) throw new Error(this.CONSTANTS.INVALID_INPUT); data = Array.isArray(data) ? data : [data]; var bigNumber = this._bigNumberClosure.addData(data); this.setBigNumberData({ data: bigNumber }); }; BigNumberComponent.prototype.refreshChart = function () { throw new Error(this.CONSTANTS.METHOD_NOT_IMPLEMENTED); }; BigNumberComponent.prototype.getTelemetry = function () { throw new Error(this.CONSTANTS.METHOD_NOT_IMPLEMENTED); }; BigNumberComponent.prototype.exportAs = function (format) { if (!this.exportOptions.includes(format)) { throw new Error('given type not supported'); } this.exportAsCsv(); }; BigNumberComponent.ctorParameters = function () { return [ { type: DataService }, { type: undefined, decorators: [{ type: Inject, args: [DEFAULT_CONFIG,] }] }, { type: ChangeDetectorRef }, { type: undefined, decorators: [{ type: Inject, args: [DASHLET_CONSTANTS,] }] } ]; }; BigNumberComponent = __decorate([ Component({ selector: 'sb-big-number', template: "<ng-template #defaultTemplate let-config>\n <div class=\"ui cards\">\n <div class=\"card\">\n <div class=\"content\">\n <div class=\"header\">{{config?.inputParameters?.header}}</div>\n <div class=\"meta\">{{config?.inputParameters?.footer}}</div>\n <div class=\"description\">\n {{config?.inputParameters?.data}}\n </div>\n </div>\n </div>\n </div>\n</ng-template>\n\n<ng-template #defaultFilterTemplate let-context>\n <sb-dashlets-filters [data]=\"context?.data\" [config]=\"context?.config?.filters\"\n (filteredData)=\"update({data: $event})\">\n </sb-dashlets-filters>\n</ng-template>\n\n<ng-container *ngIf=\"$context?.config?.filters\" [ngTemplateOutlet]=\"templateRefs?.filter || defaultFilterTemplate\"\n [ngTemplateOutletContext]=\"{'$implicit': $context}\">\n</ng-container>\n\n\n<ng-container *ngIf=\"templateRefs?.header && $context\" [ngTemplateOutlet]=\"templateRefs?.header\"\n [ngTemplateOutletContext]=\"{'$implicit': $context}\">\n</ng-container>\n\n<ng-container *ngIf=\"$context\" [ngTemplateOutlet]=\"templateRefs?.body || defaultTemplate\"\n [ngTemplateOutletContext]=\"{'$implicit': $context}\">\n</ng-container>\n\n<ng-container *ngIf=\"templateRefs?.footer && $context\" [ngTemplateOutlet]=\"templateRefs?.footer\"\n [ngTemplateOutletContext]=\"{'$implicit': $context}\">\n</ng-container>", providers: [ { provide: DEFAULT_CONFIG, useValue: ɵ0$3 } ], styles: [""] }), __param(1, Inject(DEFAULT_CONFIG)), __param(3, Inject(DASHLET_CONSTANTS)) ], BigNumberComponent); return BigNumberComponent; }(BaseComponent)); var bigNumber_component = /*#__PURE__*/Object.freeze({ __proto__: null, BigNumberComponent: BigNumberComponent, ɵ0: ɵ0$3 }); var TABLE_DEFAULT_CONFIG = { tableLevelConfig: { autoWidth: true, paging: false, bFilter: false, bInfo: false, info: false, searchable: false, bLengthChange: false }, columnConfig: { searchable: true, orderable: true, visible: true, autoWidth: true } }; var jsonExport$1 = jsonexport; var ɵ0$4 = TABLE_DEFAULT_CONFIG; var DtTableComponent = /** @class */ (function (_super) { __extends(DtTableComponent, _super); function DtTableComponent(dataService, defaultConfig, CONSTANTS) { var _this = _super.call(this, dataService) || this; _this.dataService = dataService; _this.CONSTANTS = CONSTANTS; _this.reportType = IReportType.TABLE; _this.inputParameters = {}; _this.exportOptions = ['csv']; _this.rowClickHandler = function (row, data, index) { var self = _this; $('td', row).off('click'); $('td', row).on('click', function () { _this.events.emit({ type: 'CLICK', event: data }); }); return row; }; _this._addDefaultToColumn = function (column) { return __assign({}, _this._defaultConfig['columnConfig'], column); }; _this._defaultConfig = defaultConfig; return _this; } DtTableComponent.prototype.initialize = function (_a) { var config = _a.config, type = _a.type, data = _a.data; return __awaiter(this, void 0, void 0, function () { var fetchedJSON, _b; return __generator(this, function (_c) { switch (_c.label) { case 0: if (!(config && type && data)) throw new SyntaxError(this.CONSTANTS.INVALID_INPUT); this.config = config = __assign({}, config, { type: type }); _b = this; return [4 /*yield*/, this.fetchData(data).toPromise().catch(function (err) { return []; })]; case 1: fetchedJSON = _b.data = _c.sent(); this.builder(config, fetchedJSON); this._isInitialized = true; this.state.emit(ReportState.DONE); return [2 /*return*/]; } }); }); }; DtTableComponent.prototype.ngAfterViewInit = function () { this._dtClosure = this._tableOpsClosure(this.dataTableElement && this.dataTableElement.dtInstance); }; DtTableComponent.prototype.builder = function (config, data) { var columnConfig = config.columnConfig, others = __rest(config, ["columnConfig"]); var columns = columnConfig.map(this._addDefaultToColumn); this._setTableOptions(__assign({}, others, { data: data, columns: columns, rowCallback: this.rowClickHandler.bind(this) })); }; DtTableComponent.prototype._setTableOptions = function (config) { if (config === void 0) { config = {}; } this.inputParameters = __assign({}, this._defaultConfig['tableLevelConfig'], this.inputParameters, config); this.$context = { data: this.data, config: this.config, inputParameters: this.inputParameters, exportOptions: this.exportOptions }; }; DtTableComponent.prototype.getRowsCount = function () { return this._dtClosure && this._dtClosure.rowsCount(); }; // resets to the original state. DtTableComponent.prototype.reset = function () { this._dtClosure.updateData(this.data); }; DtTableComponent.prototype.destroy = function () { var destroy = this._dtClosure.destroy; if (destroy && typeof destroy === 'function') { try { destroy.call(this._dtClosure); } catch (err) { console.error('component not destroyed', err); } } }; DtTableComponent.prototype.update = function (input) { this.checkIfInitialized(); if (!input) throw new Error(this.CONSTANTS.INVALID_INPUT); var _a = input.config, config = _a === void 0 ? {} : _a, _b = input.data, data = _b === void 0 ? null : _b; var _c = config, columns = _c.columnConfig, others = __rest(_c, ["columnConfig"]); if (data && this._dtClosure) { this._dtClosure.updateData(data); } this._setTableOptions(__assign({}, others, (data && { data: data }), (columns && { columns: columns }))); }; ; DtTableComponent.prototype.addRows = function (data) { this.addData(data); }; DtTableComponent.prototype.getRowAtIndex = function (index) { var getRowAtIndex = this._dtClosure.getRowAtIndex; if (getRowAtIndex) { return getRowAtIndex.bind(this._dtClosure, index); } }; DtTableComponent.prototype.removeRow = function (index) { return __awaiter(this, void 0, void 0, function () { var data; return __generator(this, function (_a) { switch (_a.label) { case 0: return [4 /*yield*/, this._dtClosure.getData()]; case 1: data = _a.sent(); data.splice(index, 1); return [4 /*yield*/, this._dtClosure.updateData(data)]; case 2: _a.sent(); return [2 /*return*/]; } }); }); }; DtTableComponent.prototype.addData = function (data) { var addData = this._dtClosure.addData; if (addData && typeof addData === 'function') { try { addData.call(this._dtClosure, data); } catch (error) { console.error('addition of data failed', error); } } }; DtTableComponent.prototype._tableOpsClosure = function (tableInstance) { return { get instance() { return tableInstance; }, addData: function (data) { return __awaiter(this, void 0, void 0, function () { var instance; return __generator(this, function (_a) { switch (_a.label) { case 0: return [4 /*yield*/, this.instance]; case 1: instance = _a.sent(); instance.row.add(data); instance.draw(); return [2 /*return*/]; } }); }); }, draw: function () { return __awaiter(this, void 0, void 0, function () { var instance; return __generator(this, function (_a) { switch (_a.label) { case 0: return [4 /*yield*/, this.instance]; case 1: instance = _a.sent(); instance.draw(); return [2 /*return*/, instance]; } }); }); }, destroy: function () { return __awaiter(this, void 0, void 0, function () { var instance; return __generator(this, function (_a) { switch (_a.label) { case 0: return [4 /*yield*/, this.instance]; case 1: instance = _a.sent(); instance.destroy(); return [2 /*return*/, instance]; } }); }); }, updateData: function (data) { return __awaiter(this, void 0, void 0, function () { var instance; return __generator(this, function (_a) { switch (_a.label) { case 0: return [4 /*yield*/, this.instance]; case 1: instance = _a.sent(); instance.clear(); instance.rows.add(data); instance.draw(); return [2 /*return*/]; } }); }); }, rowsCount: function () { return __awaiter(this, void 0, void 0, function () { var instance; return __generator(this, function (_a) { switch (_a.label) { case 0: return [4 /*yield*/, this.instance]; case 1: instance = _a.sent(); return [2 /*return*/, instance.rows().count()]; } }); }); }, getData: function () { return __awaiter(this, void 0, void 0, function () { var instance; return __generator(this, function (_a) { switch (_a.label) { case 0: return [4 /*yield*/, this.instance]; case 1: instance = _a.sent(); return [2 /*return*/, instance.rows().data()]; } }); }); }, getRowAtIndex: function (index) { return __awaiter(this, void 0, void 0, function () { var data; return __generator(this, function (_a) { switch (_a.label) { case 0: return [4 /*yield*/, this.getData()]; case 1: data = _a.sent(); return [2 /*return*/, data[index]]; } }); }); } }; }; // Returns the csv string for the mobile platform DtTableComponent.prototype.exportCsv = function () { var _this = this; return new Promise(function (resolve, reject) { jsonExport$1(_this.data, function (error, csv) { if (csv) { resolve(csv); } else { reject(error); } }); }); }; DtTableComponent.prototype.exportAs = function (format) { if (!this.exportOptions.includes(format)) { throw new Error('given type not supported'); } switch (format) { case 'csv': { this.exportAsCsv(); break; } } }; DtTableComponent.ctorParameters = function () { return [ { type: DataService }, { type: undefined, decorators: [{ type: Inject, args: [DEFAULT_CONFIG,] }] }, { type: undefined, decorators: [{ type: Inject, args: [DASHLET_CONSTANTS,] }] } ]; }; __decorate([ ViewChild(DataTableDirective, { static: false }) ], DtTableComponent.prototype, "dataTableElement", void 0); DtTableComponent = __decorate([ Component({ selector: 'sb-dt-table', template: "<ng-template #defaultFilterTemplate let-context>\n <sb-dashlets-filters [data]=\"context?.data\" [config]=\"context?.config?.filters\"\n (filteredData)=\"update({data: $event})\">\n </sb-dashlets-filters>\n</ng-template>\n\n<ng-container *ngIf=\"$context?.config?.filters\" [ngTemplateOutlet]=\"templateRefs?.filter || defaultFilterTemplate\"\n [ngTemplateOutletContext]=\"{'$implicit': $context}\">\n</ng-container>\n\n<ng-container *ngIf=\"templateRefs?.header && $context\" [ngTemplateOutlet]=\"templateRefs?.header\"\n [ngTemplateOutletContext]=\"{'$implicit': $context}\">\n</ng-container>\n\n<table datatable [dtOptions]=\"$context?.inputParameters\" class=\"row-border hover\"></table>\n\n<ng-container *ngIf=\"templateRefs?.footer && $context\" [ngTemplateOutlet]=\"templateRefs?.footer\"\n [ngTemplateOutletContext]=\"{'$implicit': $context}\">\n</ng-container>", providers: [ { provide: DEFAULT_CONFIG, useValue: ɵ0$4 } ], styles: [""] }), __param(1, Inject(DEFAULT_CONFIG)), __param(2, Inject(DASHLET_CONSTANTS)) ], DtTableComponent); return DtTableComponent; }(BaseComponent)); var dtTable_component = /*#__PURE__*/Object.freeze({ __proto__: null, DtTableComponent: DtTableComponent, ɵ0: ɵ0$4 }); var FILTER_DEFAULT_CONFIG = { config: { controlType: 'multi-select', searchable: true, default: [], placeholder: 'Select Option', options: [], dateFormat: 'DD-MM-YYYY' }, dropdownSettings: { singleSelection: false, idField: 'item_id', textField: 'item_text', selectAllText: 'Select All', unSelectAllText: 'UnSelect All', itemsShowLimit: 3, allowSearchFilter: true } }; var moment = momentImported; var ranges = { 'Today': [moment(), moment()], 'Yesterday': [moment().subtract(1, 'days'), moment().subtract(1, 'days')], 'Last 7 Days': [moment().subtract(6, 'days'), moment()], 'Last 30 Days': [moment().subtract(29, 'days'), moment()], 'This Month': [moment().startOf('month'), moment().endOf('month')], 'Last Month': [moment().subtract(1, 'month').startOf('month'), moment().subtract(1, 'month').endOf('month')] }; var sortDates = function (dates, format) { if (format === void 0) { format = 'DD-MM-YYYY'; } return dates.sort(function (pre, next) { var preDate = moment(pre, format), nextDate = moment(next, format); if (preDate.isSame(nextDate)) return 0; if (preDate.isBefore(nextDate)) return -1; return 1; }); }; var ɵ0$5 = sortDates; var ɵ1$1 = FILTER_DEFAULT_CONFIG; var FiltersComponent = /** @class */ (function () { function FiltersComponent(fb, defaultConfig) { var _this = this; this.fb = fb; this.defaultConfig = defaultConfig; this.config = []; this.filteredData = new EventEmitter(); this.unsubscribe$ = new Subject(); this.ranges = ranges; this.locale = { applyLabel: 'Set Date', format: 'DD-MM-YYYY' }; this._omitEmptyFilters = function (filters) { return omitBy(filters, isEmpty); }; this.transformFilterValues = function (filters) { return mapValues(filters, function (values) { return Array.isArray(values) ? values : [values]; }); }; this.getSelectedFiltersObservable = function () { return _this.filtersFormGroup.valueChanges .pipe(takeUntil(_this.unsubscribe$), debounceTime(1000), distinctUntilChanged(), map(_this._omitEmptyFilters.bind(_this)), map(_this.transformFilterValues.bind(_this)), startWith({}), pairwise()); }; } FiltersComponent.prototype.ngOnInit = function () { this._data = this.data; this.init(this.config, this._data); this.handleFilterValueChanges(); }; FiltersComponent.prototype._setDropdownSettings = function (config) { if (config === void 0) { config = {}; } return __assign({}, this.defaultConfig.dropdownSettings, config); }; FiltersComponent.prototype._getFilterOptions = function (dataExpr, data) { var getFilterValue = function (dataExpr) { return function (row) { return (row && row[dataExpr]) || ''; }; }; var inputDataArr = (data && Array.isArray(data) && data.map(getFilterValue(dataExpr))) || []; return compact(sortBy(uniq(inputDataArr))); }; FiltersComponent.prototype.init = function (config, data) { var _this = this; this.filters = []; this.filtersFormGroup = this.fb.group({}); config.forEach(function (filter) { var filterObj = __assign({}, _this.defaultConfig.config, filter); var reference = filterObj.reference, defaultValue = fi