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
JavaScript
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