yw-charts-library 0.0.2 → 0.0.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/fesm2022/yw-charts-library.mjs +1723 -1658
- package/fesm2022/yw-charts-library.mjs.map +1 -1
- package/index.d.ts +6 -1
- package/package.json +1 -1
|
@@ -94,7 +94,8 @@ const YwDashboardWidgetTypes = [
|
|
|
94
94
|
{ code: "chart-bar", description: "Chart Bar" },
|
|
95
95
|
{ code: "chart-line", description: "Chart Bar" },
|
|
96
96
|
{ code: "chart-doughnut", description: "Chart Doughnut" },
|
|
97
|
-
{ code: "chart-gauge", description: "Chart Gauge" }
|
|
97
|
+
{ code: "chart-gauge", description: "Chart Gauge" },
|
|
98
|
+
{ code: "chart-bubble", description: "Chart Bubble" }
|
|
98
99
|
];
|
|
99
100
|
|
|
100
101
|
const YwDashboardWidgetFilterTypes = [
|
|
@@ -250,14 +251,14 @@ const resolveJoinedTableData = (allTablesData, configJoins) => {
|
|
|
250
251
|
return out;
|
|
251
252
|
};
|
|
252
253
|
let currentRows = baseData.map((r) => prefixRow(r, baseTable));
|
|
253
|
-
|
|
254
|
+
for (const rel of relations) {
|
|
254
255
|
const { leftTable, leftId, rightTable, rightId } = rel;
|
|
255
256
|
if (!allTablesData[rightTable]) {
|
|
256
257
|
throw new Error(`La tabla destino "${rightTable}" especificada en el join no existe en los datos.`);
|
|
257
258
|
}
|
|
258
259
|
const targetData = allTablesData[rightTable] || [];
|
|
259
260
|
if (targetData.length === 0) {
|
|
260
|
-
|
|
261
|
+
return [];
|
|
261
262
|
}
|
|
262
263
|
if (targetData[0][rightId] === undefined) {
|
|
263
264
|
throw new Error(`La columna "${rightId}" no existe en la tabla destino "${rightTable}".`);
|
|
@@ -270,18 +271,10 @@ const resolveJoinedTableData = (allTablesData, configJoins) => {
|
|
|
270
271
|
}
|
|
271
272
|
});
|
|
272
273
|
let matchCount = 0;
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
// if (foreignKeyVal === undefined) {
|
|
276
|
-
// const foundKey = Object.keys(row).find(
|
|
277
|
-
// (k) => k === leftId || k.endsWith(`.${leftId}`),
|
|
278
|
-
// );
|
|
279
|
-
// if (foundKey) foreignKeyVal = row[foundKey];
|
|
280
|
-
// }
|
|
281
|
-
// REVSISAR COMO ESTA FUNCIONADO EL PARCHE
|
|
274
|
+
const nextRows = [];
|
|
275
|
+
currentRows.forEach((row) => {
|
|
282
276
|
let foreignKeyVal = row[`${leftTable}.${leftId}`];
|
|
283
277
|
if (foreignKeyVal === undefined) {
|
|
284
|
-
// Si no está, aplicas tu respaldo anterior
|
|
285
278
|
const foundKey = Object.keys(row).find((k) => k === leftId || k.endsWith(`.${leftId}`));
|
|
286
279
|
if (foundKey)
|
|
287
280
|
foreignKeyVal = row[foundKey];
|
|
@@ -289,14 +282,14 @@ const resolveJoinedTableData = (allTablesData, configJoins) => {
|
|
|
289
282
|
if (foreignKeyVal !== undefined && targetMap.has(String(foreignKeyVal))) {
|
|
290
283
|
matchCount++;
|
|
291
284
|
const matchedRow = targetMap.get(String(foreignKeyVal));
|
|
292
|
-
|
|
285
|
+
nextRows.push({ ...row, ...matchedRow });
|
|
293
286
|
}
|
|
294
|
-
return row;
|
|
295
287
|
});
|
|
288
|
+
currentRows = nextRows;
|
|
296
289
|
if (matchCount === 0) {
|
|
297
|
-
|
|
290
|
+
return [];
|
|
298
291
|
}
|
|
299
|
-
}
|
|
292
|
+
}
|
|
300
293
|
return currentRows;
|
|
301
294
|
};
|
|
302
295
|
// ACCESO A PROPIEDADES ANIDADAS (SOPORTA NOTACIÓN DE PUNTOS Y TOLERANCIA DE PREFIJOS)
|
|
@@ -1716,13 +1709,17 @@ const parseDataPie = parseSyncFusionData$2;
|
|
|
1716
1709
|
const detectCategoryKey = (row) => {
|
|
1717
1710
|
if (!row)
|
|
1718
1711
|
return undefined;
|
|
1712
|
+
const isDateKey = (k) => {
|
|
1713
|
+
const lk = k.toLowerCase();
|
|
1714
|
+
return lk.includes('fecha') || lk.includes('date') || lk.includes('time') || lk.includes('timestamp');
|
|
1715
|
+
};
|
|
1719
1716
|
const candidates = ['x', 'name', 'label', 'category', 'categoria', 'sucursal', 'producto', 'key', 'title'];
|
|
1720
1717
|
for (const c of candidates) {
|
|
1721
|
-
if (row[c] !== undefined && row[c] !== null && typeof row[c] === 'string')
|
|
1718
|
+
if (row[c] !== undefined && row[c] !== null && typeof row[c] === 'string' && !isDateKey(c))
|
|
1722
1719
|
return c;
|
|
1723
1720
|
}
|
|
1724
1721
|
for (const k of Object.keys(row)) {
|
|
1725
|
-
if (typeof row[k] === 'string')
|
|
1722
|
+
if (typeof row[k] === 'string' && !isDateKey(k))
|
|
1726
1723
|
return k;
|
|
1727
1724
|
}
|
|
1728
1725
|
return undefined;
|
|
@@ -1821,7 +1818,7 @@ const parseForSyncfusion$1 = (rawData, config) => {
|
|
|
1821
1818
|
if (!row)
|
|
1822
1819
|
return;
|
|
1823
1820
|
let xVal = effectiveXKey ? getNestedValue(row, effectiveXKey) : undefined;
|
|
1824
|
-
if (xVal === undefined) {
|
|
1821
|
+
if (xVal === undefined && !xKey) {
|
|
1825
1822
|
const autoX = detectCategoryKey(row);
|
|
1826
1823
|
if (autoX)
|
|
1827
1824
|
xVal = row[autoX];
|
|
@@ -1912,6 +1909,7 @@ const buildPieResult = (dataSource, total, config, cfg, chartTitle, startAngle,
|
|
|
1912
1909
|
: (config?.showLegend ?? true);
|
|
1913
1910
|
const legendPosition = legends?.position ?? config?.legendPosition ?? 'Bottom';
|
|
1914
1911
|
const visualConfig = {
|
|
1912
|
+
title: chartTitle,
|
|
1915
1913
|
legendSettings: {
|
|
1916
1914
|
visible: isLegendVisible,
|
|
1917
1915
|
position: legendPosition,
|
|
@@ -1970,12 +1968,26 @@ class PieChartSyncfusionComponent {
|
|
|
1970
1968
|
this._idComponent = '';
|
|
1971
1969
|
this.chartData = [];
|
|
1972
1970
|
this.dataChartParse = [];
|
|
1971
|
+
this.chartTitle = '';
|
|
1973
1972
|
this._lastWidth = 0;
|
|
1974
1973
|
this._lastHeight = 0;
|
|
1974
|
+
this._dataSnapshot = '';
|
|
1975
1975
|
}
|
|
1976
1976
|
ngOnInit() {
|
|
1977
1977
|
this.updateParsedData();
|
|
1978
1978
|
}
|
|
1979
|
+
ngDoCheck() {
|
|
1980
|
+
try {
|
|
1981
|
+
const snap = JSON.stringify(this.chartData);
|
|
1982
|
+
if (snap !== this._dataSnapshot) {
|
|
1983
|
+
this._dataSnapshot = snap;
|
|
1984
|
+
this.updateParsedData();
|
|
1985
|
+
}
|
|
1986
|
+
}
|
|
1987
|
+
catch {
|
|
1988
|
+
// Ignorar si hay referencias circulares en los datos
|
|
1989
|
+
}
|
|
1990
|
+
}
|
|
1979
1991
|
ngAfterViewInit() {
|
|
1980
1992
|
if (typeof ResizeObserver === 'undefined')
|
|
1981
1993
|
return;
|
|
@@ -2036,12 +2048,23 @@ class PieChartSyncfusionComponent {
|
|
|
2036
2048
|
this.legendSettings = parsedResult.visualConfig.legendSettings;
|
|
2037
2049
|
this.tooltip = parsedResult.visualConfig.tooltip;
|
|
2038
2050
|
this.dataLabel = parsedResult.visualConfig.dataLabel;
|
|
2051
|
+
this.chartTitle = parsedResult.visualConfig.title || parsedResult.labelData?.title || this.config.title || '';
|
|
2052
|
+
}
|
|
2053
|
+
else {
|
|
2054
|
+
this.chartTitle = parsedResult.labelData?.title || this.config.title || '';
|
|
2039
2055
|
}
|
|
2040
2056
|
}
|
|
2041
2057
|
else {
|
|
2042
2058
|
this.dataChartParse = [];
|
|
2043
2059
|
this.centerLabel = undefined;
|
|
2044
2060
|
this.centerLabelSettings = undefined;
|
|
2061
|
+
this.chartTitle = this.config?.title || '';
|
|
2062
|
+
}
|
|
2063
|
+
this.cdr.markForCheck();
|
|
2064
|
+
if (this.chartInstance) {
|
|
2065
|
+
setTimeout(() => {
|
|
2066
|
+
this.chartInstance?.refresh();
|
|
2067
|
+
});
|
|
2045
2068
|
}
|
|
2046
2069
|
}
|
|
2047
2070
|
onChartLoaded(args) {
|
|
@@ -2061,13 +2084,13 @@ class PieChartSyncfusionComponent {
|
|
|
2061
2084
|
}
|
|
2062
2085
|
}
|
|
2063
2086
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.30", ngImport: i0, type: PieChartSyncfusionComponent, deps: [{ token: i0.ElementRef }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component }); }
|
|
2064
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "
|
|
2087
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.30", type: PieChartSyncfusionComponent, isStandalone: true, selector: "yw-pie-chart-syncfusion", inputs: { idComponent: "idComponent", chartData: "chartData", config: "config" }, providers: [
|
|
2065
2088
|
AccumulationLegendService,
|
|
2066
2089
|
AccumulationTooltipService,
|
|
2067
2090
|
AccumulationDataLabelService,
|
|
2068
2091
|
PieSeriesService,
|
|
2069
2092
|
AccumulationAnnotationService,
|
|
2070
|
-
], viewQueries: [{ propertyName: "chartInstance", first: true, predicate: ["accChart"], descendants: true }], usesOnChanges: true, ngImport: i0, template: "<div class=\"
|
|
2093
|
+
], viewQueries: [{ propertyName: "chartInstance", first: true, predicate: ["accChart"], descendants: true }], usesOnChanges: true, ngImport: i0, template: "<div class=\"pie-container\">\r\n @if (chartTitle) {\r\n <div class=\"pie-header-title\" [title]=\"chartTitle\">\r\n {{ chartTitle }}\r\n </div>\r\n }\r\n\r\n <div class=\"pie-wrapper\">\r\n <ejs-accumulationchart\r\n #accChart\r\n [id]=\"idComponent\"\r\n [title]=\"''\"\r\n [legendSettings]=\"legendSettings\"\r\n [tooltip]=\"tooltip\"\r\n [centerLabel]=\"centerLabelSettings\"\r\n (loaded)=\"onChartLoaded($event)\"\r\n width=\"100%\"\r\n height=\"100%\"\r\n [enableAnimation]=\"true\">\r\n\r\n <e-accumulation-series-collection>\r\n <e-accumulation-series\r\n [dataSource]=\"dataChartParse\"\r\n xName=\"x\"\r\n yName=\"y\"\r\n pointColorMapping=\"fill\"\r\n [type]=\"'Pie'\"\r\n [radius]=\"seriesConfig.radius || '80%'\"\r\n [innerRadius]=\"seriesConfig.innerRadius || '0%'\"\r\n [startAngle]=\"seriesConfig.startAngle || 0\"\r\n [endAngle]=\"seriesConfig.endAngle || 360\"\r\n [explode]=\"config.explodeSlice ?? true\"\r\n [explodeIndex]=\"config.explodeIndex || 0\"\r\n [explodeOffset]=\"config.explodeOffset || '10%'\"\r\n [dataLabel]=\"dataLabel\">\r\n </e-accumulation-series>\r\n </e-accumulation-series-collection>\r\n\r\n </ejs-accumulationchart>\r\n </div>\r\n</div>\r\n", styles: ["@charset \"UTF-8\";:host{display:flex;flex-direction:column;width:100%;height:100%;min-height:260px;box-sizing:border-box;overflow:hidden}.pie-container{display:flex;flex-direction:column;width:100%;height:100%;min-height:260px;box-sizing:border-box;overflow:hidden;background:#fff;border-radius:8px;flex-grow:1}.pie-header-title{padding:10px 14px 2px;font-size:clamp(.85rem,2.2vw,1.05rem);font-weight:600;color:#1e293b;text-align:center;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;-webkit-user-select:none;user-select:none;flex-shrink:0}.pie-wrapper{display:flex;justify-content:center;align-items:center;width:100%;height:100%;flex:1;min-width:0;overflow:hidden}:host ::ng-deep ejs-accumulationchart{display:block;width:100%!important;height:100%!important;flex-grow:1}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: AccumulationChartModule }, { kind: "component", type: i1.AccumulationChartComponent, selector: "ejs-accumulationchart", inputs: ["accessibility", "allowExport", "annotations", "background", "backgroundImage", "border", "center", "centerLabel", "currencyCode", "dataSource", "enableAnimation", "enableBorderOnMouseMove", "enableExport", "enableHtmlSanitizer", "enablePersistence", "enableRtl", "enableSmartLabels", "focusBorderColor", "focusBorderMargin", "focusBorderWidth", "height", "highlightColor", "highlightMode", "highlightPattern", "isMultiSelect", "legendSettings", "locale", "margin", "selectedDataIndexes", "selectionMode", "selectionPattern", "series", "subTitle", "subTitleStyle", "theme", "title", "titleStyle", "tooltip", "useGroupingSeparator", "width"], outputs: ["afterExport", "animationComplete", "annotationRender", "beforePrint", "beforeResize", "chartDoubleClick", "chartMouseClick", "chartMouseDown", "chartMouseLeave", "chartMouseMove", "chartMouseUp", "legendClick", "legendRender", "load", "loaded", "pointClick", "pointMove", "pointRender", "resized", "selectionComplete", "seriesRender", "textRender", "tooltipRender", "dataSourceChange"] }, { kind: "directive", type: i1.AccumulationSeriesDirective, selector: "e-accumulation-series-collection>e-accumulation-series", inputs: ["accessibility", "animation", "applyPattern", "border", "borderRadius", "dashArray", "dataLabel", "dataSource", "emptyPointSettings", "enableTooltip", "endAngle", "explode", "explodeAll", "explodeIndex", "explodeOffset", "gapRatio", "groupMode", "groupTo", "height", "innerRadius", "legendImageUrl", "legendShape", "name", "neckHeight", "neckWidth", "opacity", "palettes", "pointColorMapping", "pyramidMode", "query", "radius", "selectionStyle", "startAngle", "tooltipMappingName", "type", "visible", "width", "xName", "yName"] }, { kind: "directive", type: i1.AccumulationSeriesCollectionDirective, selector: "ej-accumulationchart>e-accumulation-series-collection" }] }); }
|
|
2071
2094
|
}
|
|
2072
2095
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.30", ngImport: i0, type: PieChartSyncfusionComponent, decorators: [{
|
|
2073
2096
|
type: Component,
|
|
@@ -2077,7 +2100,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.30", ngImpo
|
|
|
2077
2100
|
AccumulationDataLabelService,
|
|
2078
2101
|
PieSeriesService,
|
|
2079
2102
|
AccumulationAnnotationService,
|
|
2080
|
-
], template: "<div class=\"
|
|
2103
|
+
], template: "<div class=\"pie-container\">\r\n @if (chartTitle) {\r\n <div class=\"pie-header-title\" [title]=\"chartTitle\">\r\n {{ chartTitle }}\r\n </div>\r\n }\r\n\r\n <div class=\"pie-wrapper\">\r\n <ejs-accumulationchart\r\n #accChart\r\n [id]=\"idComponent\"\r\n [title]=\"''\"\r\n [legendSettings]=\"legendSettings\"\r\n [tooltip]=\"tooltip\"\r\n [centerLabel]=\"centerLabelSettings\"\r\n (loaded)=\"onChartLoaded($event)\"\r\n width=\"100%\"\r\n height=\"100%\"\r\n [enableAnimation]=\"true\">\r\n\r\n <e-accumulation-series-collection>\r\n <e-accumulation-series\r\n [dataSource]=\"dataChartParse\"\r\n xName=\"x\"\r\n yName=\"y\"\r\n pointColorMapping=\"fill\"\r\n [type]=\"'Pie'\"\r\n [radius]=\"seriesConfig.radius || '80%'\"\r\n [innerRadius]=\"seriesConfig.innerRadius || '0%'\"\r\n [startAngle]=\"seriesConfig.startAngle || 0\"\r\n [endAngle]=\"seriesConfig.endAngle || 360\"\r\n [explode]=\"config.explodeSlice ?? true\"\r\n [explodeIndex]=\"config.explodeIndex || 0\"\r\n [explodeOffset]=\"config.explodeOffset || '10%'\"\r\n [dataLabel]=\"dataLabel\">\r\n </e-accumulation-series>\r\n </e-accumulation-series-collection>\r\n\r\n </ejs-accumulationchart>\r\n </div>\r\n</div>\r\n", styles: ["@charset \"UTF-8\";:host{display:flex;flex-direction:column;width:100%;height:100%;min-height:260px;box-sizing:border-box;overflow:hidden}.pie-container{display:flex;flex-direction:column;width:100%;height:100%;min-height:260px;box-sizing:border-box;overflow:hidden;background:#fff;border-radius:8px;flex-grow:1}.pie-header-title{padding:10px 14px 2px;font-size:clamp(.85rem,2.2vw,1.05rem);font-weight:600;color:#1e293b;text-align:center;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;-webkit-user-select:none;user-select:none;flex-shrink:0}.pie-wrapper{display:flex;justify-content:center;align-items:center;width:100%;height:100%;flex:1;min-width:0;overflow:hidden}:host ::ng-deep ejs-accumulationchart{display:block;width:100%!important;height:100%!important;flex-grow:1}\n"] }]
|
|
2081
2104
|
}], ctorParameters: () => [{ type: i0.ElementRef }, { type: i0.ChangeDetectorRef }], propDecorators: { chartInstance: [{
|
|
2082
2105
|
type: ViewChild,
|
|
2083
2106
|
args: ['accChart']
|
|
@@ -2522,6 +2545,18 @@ class GaugeChartSyncfusionComponent {
|
|
|
2522
2545
|
get chartData() {
|
|
2523
2546
|
return this._chartData;
|
|
2524
2547
|
}
|
|
2548
|
+
/** HTML con estilos inline para la annotation central del gauge */
|
|
2549
|
+
get annotationHtml() {
|
|
2550
|
+
const text = this.animatedLabelText || (this.gaugePoint?.text ?? '');
|
|
2551
|
+
return this.buildAnnotationHtml(text);
|
|
2552
|
+
}
|
|
2553
|
+
buildAnnotationHtml(text) {
|
|
2554
|
+
const size = this.currentLabelSize || this.visualConfig?.labelSize || '24px';
|
|
2555
|
+
const isBold = this.visualConfig?.labelBold || this.visualConfig?.labelWeight === 'bold' || this.visualConfig?.labelWeight === '700';
|
|
2556
|
+
const weight = isBold ? 'bold' : (this.visualConfig?.labelWeight || 'normal');
|
|
2557
|
+
const color = this.visualConfig?.labelColor || '#1F2937';
|
|
2558
|
+
return `<div style="font-size:${size};font-weight:${weight};color:${color};text-align:center;font-family:inherit;line-height:1.1;white-space:nowrap;">${text}</div>`;
|
|
2559
|
+
}
|
|
2525
2560
|
constructor(cdr, elRef) {
|
|
2526
2561
|
this.cdr = cdr;
|
|
2527
2562
|
this.elRef = elRef;
|
|
@@ -2648,6 +2683,12 @@ class GaugeChartSyncfusionComponent {
|
|
|
2648
2683
|
else {
|
|
2649
2684
|
this.currentLabelSize = `${parsedSize}px`;
|
|
2650
2685
|
}
|
|
2686
|
+
if (this.gaugeInstance && this.visualConfig?.showLabel && !this._isAnimating) {
|
|
2687
|
+
try {
|
|
2688
|
+
this.gaugeInstance.setAnnotationValue(0, 0, this.annotationHtml);
|
|
2689
|
+
}
|
|
2690
|
+
catch { }
|
|
2691
|
+
}
|
|
2651
2692
|
this.cdr.markForCheck();
|
|
2652
2693
|
return;
|
|
2653
2694
|
}
|
|
@@ -2655,6 +2696,12 @@ class GaugeChartSyncfusionComponent {
|
|
|
2655
2696
|
// Proporción estándar ideal (~7.5% del ancho del contenedor, acotado entre 13px y 26px)
|
|
2656
2697
|
const base = Math.max(13, Math.min(26, Math.round(width * 0.075)));
|
|
2657
2698
|
this.currentLabelSize = `${base}px`;
|
|
2699
|
+
if (this.gaugeInstance && this.visualConfig?.showLabel && !this._isAnimating) {
|
|
2700
|
+
try {
|
|
2701
|
+
this.gaugeInstance.setAnnotationValue(0, 0, this.annotationHtml);
|
|
2702
|
+
}
|
|
2703
|
+
catch { }
|
|
2704
|
+
}
|
|
2658
2705
|
this.cdr.markForCheck();
|
|
2659
2706
|
}
|
|
2660
2707
|
/**
|
|
@@ -2744,7 +2791,7 @@ class GaugeChartSyncfusionComponent {
|
|
|
2744
2791
|
this.animatedLabelText = labelText;
|
|
2745
2792
|
if (this.gaugeInstance) {
|
|
2746
2793
|
try {
|
|
2747
|
-
this.gaugeInstance.setAnnotationValue(0, 0, labelText);
|
|
2794
|
+
this.gaugeInstance.setAnnotationValue(0, 0, this.buildAnnotationHtml(labelText));
|
|
2748
2795
|
}
|
|
2749
2796
|
catch {
|
|
2750
2797
|
// Ignorar si la anotación aún no se ha montado
|
|
@@ -2761,7 +2808,7 @@ class GaugeChartSyncfusionComponent {
|
|
|
2761
2808
|
this.animatedLabelText = finalLabel;
|
|
2762
2809
|
if (this.gaugeInstance) {
|
|
2763
2810
|
try {
|
|
2764
|
-
this.gaugeInstance.setAnnotationValue(0, 0, finalLabel);
|
|
2811
|
+
this.gaugeInstance.setAnnotationValue(0, 0, this.buildAnnotationHtml(finalLabel));
|
|
2765
2812
|
}
|
|
2766
2813
|
catch { }
|
|
2767
2814
|
}
|
|
@@ -2789,11 +2836,11 @@ class GaugeChartSyncfusionComponent {
|
|
|
2789
2836
|
return index;
|
|
2790
2837
|
}
|
|
2791
2838
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.30", ngImport: i0, type: GaugeChartSyncfusionComponent, deps: [{ token: i0.ChangeDetectorRef }, { token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Component }); }
|
|
2792
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.30", type: GaugeChartSyncfusionComponent, isStandalone: true, selector: "yw-gauge-chart-syncfusion", inputs: { idComponent: "idComponent", chartData: "chartData", config: "config" }, providers: [AnnotationsService, GaugeTooltipService], viewQueries: [{ propertyName: "gaugeInstance", first: true, predicate: ["circulargauge"], descendants: true }], usesOnChanges: true, ngImport: i0, template: "<div class=\"gauge-container\">\r\n\r\n @if (visualConfig && visualConfig.title) {\r\n <div class=\"gauge-header-title\" [title]=\"visualConfig.title\">\r\n {{ visualConfig.title }}\r\n </div>\r\n }\r\n\r\n <div class=\"gauge-wrapper\">\r\n <ejs-circulargauge\r\n #circulargauge\r\n [id]=\"idComponent\"\r\n [title]=\"''\"\r\n height=\"100%\"\r\n width=\"100%\"\r\n [enablePointerDrag]=\"false\"\r\n [tooltip]=\"{ enable: visualConfig.enableTooltip }\"\r\n (loaded)=\"onGaugeLoaded($event)\">\r\n\r\n <e-axes>\r\n <e-axis\r\n [minimum]=\"visualConfig.minimum\"\r\n [maximum]=\"visualConfig.maximum\"\r\n [startAngle]=\"visualConfig.startAngle\"\r\n [endAngle]=\"visualConfig.endAngle\"\r\n [lineStyle]=\"{ width: 0 }\"\r\n [labelStyle]=\"visualConfig.showTicks ? { position: 'Outside', offset: visualConfig.labelOffset, font: { size: '11px' } } : { position: 'Outside', font: { size: '0px' } }\"\r\n [majorTicks]=\"visualConfig.showTicks ? { position: visualConfig.tickPosition, width: 2, height: 10 } : { width: 0 }\"\r\n [minorTicks]=\"visualConfig.showTicks ? { position: visualConfig.tickPosition, width: 1, height: 5 } : { width: 0 }\">\r\n\r\n <!-- Rangos de color sobre el arco (modo convencional por rangos o modo ancho variable) -->\r\n @if (!visualConfig.enableProgressTrack || visualConfig.isVariableWidth) {\r\n <e-ranges>\r\n @for (range of visualConfig.ranges; track $index) {\r\n <e-range\r\n [start]=\"range.start\"\r\n [end]=\"range.end\"\r\n [color]=\"range.color\"\r\n [startWidth]=\"range.startWidth ?? range.width ?? 8\"\r\n [endWidth]=\"range.endWidth ?? range.width ?? 8\"\r\n [roundedCornerRadius]=\"range.roundedCornerRadius ?? 0\">\r\n </e-range>\r\n }\r\n </e-ranges>\r\n }\r\n\r\n <!-- Punteros: tanto la l\u00EDnea de fondo (vac\u00EDo) como la de llenado (l\u00EDquido) usan RangeBar para alineaci\u00F3n perfecta -->\r\n <e-pointers>\r\n @if (visualConfig.enableProgressTrack && !visualConfig.isVariableWidth) {\r\n <!-- L\u00EDnea 1: Fondo / vac\u00EDo (del m\u00EDnimo al m\u00E1ximo) -->\r\n <e-pointer\r\n type=\"RangeBar\"\r\n [value]=\"visualConfig.maximum\"\r\n [color]=\"visualConfig.trackColor\"\r\n [pointerWidth]=\"visualConfig.progressWidth\"\r\n [roundedCornerRadius]=\"visualConfig.cornerRadius\"\r\n [animation]=\"{ enable: false }\">\r\n </e-pointer>\r\n\r\n <!-- L\u00EDnea 2: Llenado progresivo / l\u00EDquido (del m\u00EDnimo al valor actual) -->\r\n <e-pointer\r\n type=\"RangeBar\"\r\n [value]=\"gaugePoint.value\"\r\n [color]=\"visualConfig.progressColor\"\r\n [pointerWidth]=\"visualConfig.progressWidth\"\r\n [roundedCornerRadius]=\"visualConfig.cornerRadius\"\r\n [animation]=\"{ enable: true, duration: 900 }\">\r\n </e-pointer>\r\n }\r\n\r\n @if ((!visualConfig.enableProgressTrack || visualConfig.showNeedleWithProgress) && (!visualConfig.isVariableWidth || visualConfig.showNeedleWithProgress)) {\r\n <e-pointer\r\n [value]=\"gaugePoint.value\"\r\n type=\"Needle\"\r\n [color]=\"visualConfig.pointerColor\"\r\n [needleTail]=\"{ length: '18%' }\"\r\n [cap]=\"{ radius: 8, color: visualConfig.pointerColor }\">\r\n </e-pointer>\r\n }\r\n </e-pointers>\r\n\r\n <!-- Etiqueta central con el valor -->\r\n @if (visualConfig.showLabel) {\r\n <e-annotations>\r\n <e-annotation\r\n [angle]=\"visualConfig.labelAngle\"\r\n [radius]=\"visualConfig.labelRadius\"\r\n zIndex=\"1\"\r\n [content]=\"
|
|
2839
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.30", type: GaugeChartSyncfusionComponent, isStandalone: true, selector: "yw-gauge-chart-syncfusion", inputs: { idComponent: "idComponent", chartData: "chartData", config: "config" }, providers: [AnnotationsService, GaugeTooltipService], viewQueries: [{ propertyName: "gaugeInstance", first: true, predicate: ["circulargauge"], descendants: true }], usesOnChanges: true, ngImport: i0, template: "<div class=\"gauge-container\">\r\n\r\n @if (visualConfig && visualConfig.title) {\r\n <div class=\"gauge-header-title\" [title]=\"visualConfig.title\">\r\n {{ visualConfig.title }}\r\n </div>\r\n }\r\n\r\n <div class=\"gauge-wrapper\">\r\n <ejs-circulargauge\r\n #circulargauge\r\n [id]=\"idComponent\"\r\n [title]=\"''\"\r\n height=\"100%\"\r\n width=\"100%\"\r\n [enablePointerDrag]=\"false\"\r\n [tooltip]=\"{ enable: visualConfig.enableTooltip }\"\r\n (loaded)=\"onGaugeLoaded($event)\">\r\n\r\n <e-axes>\r\n <e-axis\r\n [minimum]=\"visualConfig.minimum\"\r\n [maximum]=\"visualConfig.maximum\"\r\n [startAngle]=\"visualConfig.startAngle\"\r\n [endAngle]=\"visualConfig.endAngle\"\r\n [lineStyle]=\"{ width: 0 }\"\r\n [labelStyle]=\"visualConfig.showTicks ? { position: 'Outside', offset: visualConfig.labelOffset, font: { size: '11px' } } : { position: 'Outside', font: { size: '0px' } }\"\r\n [majorTicks]=\"visualConfig.showTicks ? { position: visualConfig.tickPosition, width: 2, height: 10 } : { width: 0 }\"\r\n [minorTicks]=\"visualConfig.showTicks ? { position: visualConfig.tickPosition, width: 1, height: 5 } : { width: 0 }\">\r\n\r\n <!-- Rangos de color sobre el arco (modo convencional por rangos o modo ancho variable) -->\r\n @if (!visualConfig.enableProgressTrack || visualConfig.isVariableWidth) {\r\n <e-ranges>\r\n @for (range of visualConfig.ranges; track $index) {\r\n <e-range\r\n [start]=\"range.start\"\r\n [end]=\"range.end\"\r\n [color]=\"range.color\"\r\n [startWidth]=\"range.startWidth ?? range.width ?? 8\"\r\n [endWidth]=\"range.endWidth ?? range.width ?? 8\"\r\n [roundedCornerRadius]=\"range.roundedCornerRadius ?? 0\">\r\n </e-range>\r\n }\r\n </e-ranges>\r\n }\r\n\r\n <!-- Punteros: tanto la l\u00EDnea de fondo (vac\u00EDo) como la de llenado (l\u00EDquido) usan RangeBar para alineaci\u00F3n perfecta -->\r\n <e-pointers>\r\n @if (visualConfig.enableProgressTrack && !visualConfig.isVariableWidth) {\r\n <!-- L\u00EDnea 1: Fondo / vac\u00EDo (del m\u00EDnimo al m\u00E1ximo) -->\r\n <e-pointer\r\n type=\"RangeBar\"\r\n [value]=\"visualConfig.maximum\"\r\n [color]=\"visualConfig.trackColor\"\r\n [pointerWidth]=\"visualConfig.progressWidth\"\r\n [roundedCornerRadius]=\"visualConfig.cornerRadius\"\r\n [animation]=\"{ enable: false }\">\r\n </e-pointer>\r\n\r\n <!-- L\u00EDnea 2: Llenado progresivo / l\u00EDquido (del m\u00EDnimo al valor actual) -->\r\n <e-pointer\r\n type=\"RangeBar\"\r\n [value]=\"gaugePoint.value\"\r\n [color]=\"visualConfig.progressColor\"\r\n [pointerWidth]=\"visualConfig.progressWidth\"\r\n [roundedCornerRadius]=\"visualConfig.cornerRadius\"\r\n [animation]=\"{ enable: true, duration: 900 }\">\r\n </e-pointer>\r\n }\r\n\r\n @if ((!visualConfig.enableProgressTrack || visualConfig.showNeedleWithProgress) && (!visualConfig.isVariableWidth || visualConfig.showNeedleWithProgress)) {\r\n <e-pointer\r\n [value]=\"gaugePoint.value\"\r\n type=\"Needle\"\r\n [color]=\"visualConfig.pointerColor\"\r\n [needleTail]=\"{ length: '18%' }\"\r\n [cap]=\"{ radius: 8, color: visualConfig.pointerColor }\">\r\n </e-pointer>\r\n }\r\n </e-pointers>\r\n\r\n <!-- Etiqueta central con el valor -->\r\n @if (visualConfig.showLabel) {\r\n <e-annotations>\r\n <e-annotation\r\n [angle]=\"visualConfig.labelAngle\"\r\n [radius]=\"visualConfig.labelRadius\"\r\n zIndex=\"1\"\r\n [content]=\"annotationHtml\">\r\n </e-annotation>\r\n </e-annotations>\r\n }\r\n\r\n </e-axis>\r\n </e-axes>\r\n\r\n </ejs-circulargauge>\r\n </div>\r\n\r\n</div>\r\n", styles: ["@charset \"UTF-8\";:host{display:flex;flex-direction:column;width:100%;height:100%;min-height:260px;box-sizing:border-box;overflow:hidden}.gauge-container{display:flex;flex-direction:column;width:100%;height:100%;min-height:260px;box-sizing:border-box;overflow:hidden;background:#fff;border-radius:8px}.gauge-header-title{padding:10px 14px 2px;font-size:clamp(.85rem,2.2vw,1.05rem);font-weight:600;color:#1e293b;text-align:center;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;-webkit-user-select:none;user-select:none;flex-shrink:0}.gauge-wrapper{display:flex;justify-content:center;align-items:center;width:100%;height:100%;min-height:240px;flex:1;min-width:0;overflow:hidden}:host ::ng-deep ejs-circulargauge{display:block;width:100%!important;height:100%!important;flex-grow:1}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: CircularGaugeModule }, { kind: "component", type: i1$1.CircularGaugeComponent, selector: "ejs-circulargauge", inputs: ["allowImageExport", "allowMargin", "allowPdfExport", "allowPrint", "allowRangePreRender", "animationDuration", "axes", "background", "border", "centerX", "centerY", "description", "enablePersistence", "enablePointerDrag", "enableRangeDrag", "enableRtl", "height", "legendSettings", "locale", "margin", "moveToCenter", "tabIndex", "theme", "title", "titleStyle", "tooltip", "useGroupingSeparator", "width"], outputs: ["animationComplete", "annotationRender", "axisLabelRender", "beforePrint", "dragEnd", "dragMove", "dragStart", "gaugeMouseDown", "gaugeMouseLeave", "gaugeMouseMove", "gaugeMouseUp", "legendRender", "load", "loaded", "radiusCalculate", "resized", "tooltipRender"] }, { kind: "directive", type: i1$1.AnnotationDirective, selector: "e-annotations>e-annotation", inputs: ["angle", "autoAngle", "content", "description", "radius", "textStyle", "zIndex"] }, { kind: "directive", type: i1$1.AnnotationsDirective, selector: "ej-circulargauge>e-axes>e-axis>e-annotations" }, { kind: "directive", type: i1$1.RangeDirective, selector: "e-ranges>e-range", inputs: ["color", "end", "endWidth", "legendText", "linearGradient", "offset", "opacity", "position", "radialGradient", "radius", "roundedCornerRadius", "start", "startWidth"] }, { kind: "directive", type: i1$1.RangesDirective, selector: "ej-circulargauge>e-axes>e-axis>e-ranges" }, { kind: "directive", type: i1$1.PointerDirective, selector: "e-pointers>e-pointer", inputs: ["animation", "border", "cap", "color", "description", "enableDrag", "imageUrl", "linearGradient", "markerHeight", "markerShape", "markerWidth", "needleEndWidth", "needleStartWidth", "needleTail", "offset", "pointerWidth", "position", "radialGradient", "radius", "roundedCornerRadius", "text", "textStyle", "type", "value"] }, { kind: "directive", type: i1$1.PointersDirective, selector: "ej-circulargauge>e-axes>e-axis>e-pointers" }, { kind: "directive", type: i1$1.AxisDirective, selector: "e-axes>e-axis", inputs: ["annotations", "background", "direction", "endAngle", "hideIntersectingLabel", "labelStyle", "lineStyle", "majorTicks", "maximum", "minimum", "minorTicks", "pointers", "radius", "rangeGap", "ranges", "roundingPlaces", "showLastLabel", "startAndEndRangeGap", "startAngle"] }, { kind: "directive", type: i1$1.AxesDirective, selector: "ej-circulargauge>e-axes" }] }); }
|
|
2793
2840
|
}
|
|
2794
2841
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.30", ngImport: i0, type: GaugeChartSyncfusionComponent, decorators: [{
|
|
2795
2842
|
type: Component,
|
|
2796
|
-
args: [{ selector: 'yw-gauge-chart-syncfusion', standalone: true, imports: [CommonModule, CircularGaugeModule], providers: [AnnotationsService, GaugeTooltipService], template: "<div class=\"gauge-container\">\r\n\r\n @if (visualConfig && visualConfig.title) {\r\n <div class=\"gauge-header-title\" [title]=\"visualConfig.title\">\r\n {{ visualConfig.title }}\r\n </div>\r\n }\r\n\r\n <div class=\"gauge-wrapper\">\r\n <ejs-circulargauge\r\n #circulargauge\r\n [id]=\"idComponent\"\r\n [title]=\"''\"\r\n height=\"100%\"\r\n width=\"100%\"\r\n [enablePointerDrag]=\"false\"\r\n [tooltip]=\"{ enable: visualConfig.enableTooltip }\"\r\n (loaded)=\"onGaugeLoaded($event)\">\r\n\r\n <e-axes>\r\n <e-axis\r\n [minimum]=\"visualConfig.minimum\"\r\n [maximum]=\"visualConfig.maximum\"\r\n [startAngle]=\"visualConfig.startAngle\"\r\n [endAngle]=\"visualConfig.endAngle\"\r\n [lineStyle]=\"{ width: 0 }\"\r\n [labelStyle]=\"visualConfig.showTicks ? { position: 'Outside', offset: visualConfig.labelOffset, font: { size: '11px' } } : { position: 'Outside', font: { size: '0px' } }\"\r\n [majorTicks]=\"visualConfig.showTicks ? { position: visualConfig.tickPosition, width: 2, height: 10 } : { width: 0 }\"\r\n [minorTicks]=\"visualConfig.showTicks ? { position: visualConfig.tickPosition, width: 1, height: 5 } : { width: 0 }\">\r\n\r\n <!-- Rangos de color sobre el arco (modo convencional por rangos o modo ancho variable) -->\r\n @if (!visualConfig.enableProgressTrack || visualConfig.isVariableWidth) {\r\n <e-ranges>\r\n @for (range of visualConfig.ranges; track $index) {\r\n <e-range\r\n [start]=\"range.start\"\r\n [end]=\"range.end\"\r\n [color]=\"range.color\"\r\n [startWidth]=\"range.startWidth ?? range.width ?? 8\"\r\n [endWidth]=\"range.endWidth ?? range.width ?? 8\"\r\n [roundedCornerRadius]=\"range.roundedCornerRadius ?? 0\">\r\n </e-range>\r\n }\r\n </e-ranges>\r\n }\r\n\r\n <!-- Punteros: tanto la l\u00EDnea de fondo (vac\u00EDo) como la de llenado (l\u00EDquido) usan RangeBar para alineaci\u00F3n perfecta -->\r\n <e-pointers>\r\n @if (visualConfig.enableProgressTrack && !visualConfig.isVariableWidth) {\r\n <!-- L\u00EDnea 1: Fondo / vac\u00EDo (del m\u00EDnimo al m\u00E1ximo) -->\r\n <e-pointer\r\n type=\"RangeBar\"\r\n [value]=\"visualConfig.maximum\"\r\n [color]=\"visualConfig.trackColor\"\r\n [pointerWidth]=\"visualConfig.progressWidth\"\r\n [roundedCornerRadius]=\"visualConfig.cornerRadius\"\r\n [animation]=\"{ enable: false }\">\r\n </e-pointer>\r\n\r\n <!-- L\u00EDnea 2: Llenado progresivo / l\u00EDquido (del m\u00EDnimo al valor actual) -->\r\n <e-pointer\r\n type=\"RangeBar\"\r\n [value]=\"gaugePoint.value\"\r\n [color]=\"visualConfig.progressColor\"\r\n [pointerWidth]=\"visualConfig.progressWidth\"\r\n [roundedCornerRadius]=\"visualConfig.cornerRadius\"\r\n [animation]=\"{ enable: true, duration: 900 }\">\r\n </e-pointer>\r\n }\r\n\r\n @if ((!visualConfig.enableProgressTrack || visualConfig.showNeedleWithProgress) && (!visualConfig.isVariableWidth || visualConfig.showNeedleWithProgress)) {\r\n <e-pointer\r\n [value]=\"gaugePoint.value\"\r\n type=\"Needle\"\r\n [color]=\"visualConfig.pointerColor\"\r\n [needleTail]=\"{ length: '18%' }\"\r\n [cap]=\"{ radius: 8, color: visualConfig.pointerColor }\">\r\n </e-pointer>\r\n }\r\n </e-pointers>\r\n\r\n <!-- Etiqueta central con el valor -->\r\n @if (visualConfig.showLabel) {\r\n <e-annotations>\r\n <e-annotation\r\n [angle]=\"visualConfig.labelAngle\"\r\n [radius]=\"visualConfig.labelRadius\"\r\n zIndex=\"1\"\r\n [content]=\"
|
|
2843
|
+
args: [{ selector: 'yw-gauge-chart-syncfusion', standalone: true, imports: [CommonModule, CircularGaugeModule], providers: [AnnotationsService, GaugeTooltipService], template: "<div class=\"gauge-container\">\r\n\r\n @if (visualConfig && visualConfig.title) {\r\n <div class=\"gauge-header-title\" [title]=\"visualConfig.title\">\r\n {{ visualConfig.title }}\r\n </div>\r\n }\r\n\r\n <div class=\"gauge-wrapper\">\r\n <ejs-circulargauge\r\n #circulargauge\r\n [id]=\"idComponent\"\r\n [title]=\"''\"\r\n height=\"100%\"\r\n width=\"100%\"\r\n [enablePointerDrag]=\"false\"\r\n [tooltip]=\"{ enable: visualConfig.enableTooltip }\"\r\n (loaded)=\"onGaugeLoaded($event)\">\r\n\r\n <e-axes>\r\n <e-axis\r\n [minimum]=\"visualConfig.minimum\"\r\n [maximum]=\"visualConfig.maximum\"\r\n [startAngle]=\"visualConfig.startAngle\"\r\n [endAngle]=\"visualConfig.endAngle\"\r\n [lineStyle]=\"{ width: 0 }\"\r\n [labelStyle]=\"visualConfig.showTicks ? { position: 'Outside', offset: visualConfig.labelOffset, font: { size: '11px' } } : { position: 'Outside', font: { size: '0px' } }\"\r\n [majorTicks]=\"visualConfig.showTicks ? { position: visualConfig.tickPosition, width: 2, height: 10 } : { width: 0 }\"\r\n [minorTicks]=\"visualConfig.showTicks ? { position: visualConfig.tickPosition, width: 1, height: 5 } : { width: 0 }\">\r\n\r\n <!-- Rangos de color sobre el arco (modo convencional por rangos o modo ancho variable) -->\r\n @if (!visualConfig.enableProgressTrack || visualConfig.isVariableWidth) {\r\n <e-ranges>\r\n @for (range of visualConfig.ranges; track $index) {\r\n <e-range\r\n [start]=\"range.start\"\r\n [end]=\"range.end\"\r\n [color]=\"range.color\"\r\n [startWidth]=\"range.startWidth ?? range.width ?? 8\"\r\n [endWidth]=\"range.endWidth ?? range.width ?? 8\"\r\n [roundedCornerRadius]=\"range.roundedCornerRadius ?? 0\">\r\n </e-range>\r\n }\r\n </e-ranges>\r\n }\r\n\r\n <!-- Punteros: tanto la l\u00EDnea de fondo (vac\u00EDo) como la de llenado (l\u00EDquido) usan RangeBar para alineaci\u00F3n perfecta -->\r\n <e-pointers>\r\n @if (visualConfig.enableProgressTrack && !visualConfig.isVariableWidth) {\r\n <!-- L\u00EDnea 1: Fondo / vac\u00EDo (del m\u00EDnimo al m\u00E1ximo) -->\r\n <e-pointer\r\n type=\"RangeBar\"\r\n [value]=\"visualConfig.maximum\"\r\n [color]=\"visualConfig.trackColor\"\r\n [pointerWidth]=\"visualConfig.progressWidth\"\r\n [roundedCornerRadius]=\"visualConfig.cornerRadius\"\r\n [animation]=\"{ enable: false }\">\r\n </e-pointer>\r\n\r\n <!-- L\u00EDnea 2: Llenado progresivo / l\u00EDquido (del m\u00EDnimo al valor actual) -->\r\n <e-pointer\r\n type=\"RangeBar\"\r\n [value]=\"gaugePoint.value\"\r\n [color]=\"visualConfig.progressColor\"\r\n [pointerWidth]=\"visualConfig.progressWidth\"\r\n [roundedCornerRadius]=\"visualConfig.cornerRadius\"\r\n [animation]=\"{ enable: true, duration: 900 }\">\r\n </e-pointer>\r\n }\r\n\r\n @if ((!visualConfig.enableProgressTrack || visualConfig.showNeedleWithProgress) && (!visualConfig.isVariableWidth || visualConfig.showNeedleWithProgress)) {\r\n <e-pointer\r\n [value]=\"gaugePoint.value\"\r\n type=\"Needle\"\r\n [color]=\"visualConfig.pointerColor\"\r\n [needleTail]=\"{ length: '18%' }\"\r\n [cap]=\"{ radius: 8, color: visualConfig.pointerColor }\">\r\n </e-pointer>\r\n }\r\n </e-pointers>\r\n\r\n <!-- Etiqueta central con el valor -->\r\n @if (visualConfig.showLabel) {\r\n <e-annotations>\r\n <e-annotation\r\n [angle]=\"visualConfig.labelAngle\"\r\n [radius]=\"visualConfig.labelRadius\"\r\n zIndex=\"1\"\r\n [content]=\"annotationHtml\">\r\n </e-annotation>\r\n </e-annotations>\r\n }\r\n\r\n </e-axis>\r\n </e-axes>\r\n\r\n </ejs-circulargauge>\r\n </div>\r\n\r\n</div>\r\n", styles: ["@charset \"UTF-8\";:host{display:flex;flex-direction:column;width:100%;height:100%;min-height:260px;box-sizing:border-box;overflow:hidden}.gauge-container{display:flex;flex-direction:column;width:100%;height:100%;min-height:260px;box-sizing:border-box;overflow:hidden;background:#fff;border-radius:8px}.gauge-header-title{padding:10px 14px 2px;font-size:clamp(.85rem,2.2vw,1.05rem);font-weight:600;color:#1e293b;text-align:center;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;-webkit-user-select:none;user-select:none;flex-shrink:0}.gauge-wrapper{display:flex;justify-content:center;align-items:center;width:100%;height:100%;min-height:240px;flex:1;min-width:0;overflow:hidden}:host ::ng-deep ejs-circulargauge{display:block;width:100%!important;height:100%!important;flex-grow:1}\n"] }]
|
|
2797
2844
|
}], ctorParameters: () => [{ type: i0.ChangeDetectorRef }, { type: i0.ElementRef }], propDecorators: { gaugeInstance: [{
|
|
2798
2845
|
type: ViewChild,
|
|
2799
2846
|
args: ['circulargauge']
|
|
@@ -2870,1822 +2917,1840 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.30", ngImpo
|
|
|
2870
2917
|
args: ['config']
|
|
2871
2918
|
}] } });
|
|
2872
2919
|
|
|
2873
|
-
|
|
2874
|
-
|
|
2875
|
-
|
|
2876
|
-
this.componentWidgetId = '';
|
|
2877
|
-
this.typeComponent = '';
|
|
2878
|
-
this.varShowConfigButtons = false;
|
|
2879
|
-
this.styleWidget = input(DEFAULT_WIDGET_STYLE, ...(ngDevMode ? [{ debugName: "styleWidget" }] : []));
|
|
2880
|
-
// Signal calculada que combina los valores recibidos con los valores por defecto
|
|
2881
|
-
this.instanceStyleWidget = computed(() => ({
|
|
2882
|
-
widgetBackgroundColor: this.styleWidget()?.widgetBackgroundColor ?? DEFAULT_WIDGET_STYLE.widgetBackgroundColor,
|
|
2883
|
-
widgetBorderColor: this.styleWidget()?.widgetBorderColor ?? DEFAULT_WIDGET_STYLE.widgetBorderColor
|
|
2884
|
-
}), ...(ngDevMode ? [{ debugName: "instanceStyleWidget" }] : []));
|
|
2885
|
-
this.configWidget = {
|
|
2886
|
-
widgetId: '',
|
|
2887
|
-
title: '',
|
|
2888
|
-
typeComponent: '',
|
|
2889
|
-
showConfigButtons: false,
|
|
2890
|
-
widgetStyle: DEFAULT_WIDGET_STYLE,
|
|
2891
|
-
layoutConfig: { id: '', w: 0, h: 0, content: undefined },
|
|
2892
|
-
controlConfig: {},
|
|
2893
|
-
controlTables: []
|
|
2894
|
-
};
|
|
2895
|
-
this.controlConfig = {};
|
|
2896
|
-
this.controlData = {};
|
|
2897
|
-
this.isLocked = model(false, ...(ngDevMode ? [{ debugName: "isLocked" }] : []));
|
|
2898
|
-
this.isMaximized = signal(false, ...(ngDevMode ? [{ debugName: "isMaximized" }] : []));
|
|
2899
|
-
this.eventDeleteRequest = output();
|
|
2900
|
-
this.eventLockToggleRequest = output();
|
|
2901
|
-
this.eventMaximizeToggleRequest = output();
|
|
2902
|
-
this.eventShowConfigFormRequest = output();
|
|
2920
|
+
const parseSyncFusionData = (allTablesData, configData_) => {
|
|
2921
|
+
if (!allTablesData || !configData_) {
|
|
2922
|
+
return { series: [], labelData: {} };
|
|
2903
2923
|
}
|
|
2904
|
-
|
|
2905
|
-
|
|
2906
|
-
|
|
2907
|
-
|
|
2908
|
-
|
|
2909
|
-
controlData: this.controlData
|
|
2910
|
-
};
|
|
2911
|
-
console.log('DATOS INICIALES INIT:');
|
|
2912
|
-
console.log(this.dataWidget);
|
|
2924
|
+
console.log("bubble data:--", allTablesData, configData_);
|
|
2925
|
+
// SI LO MANDAN COMO UN ARREGLO PLANO, LO ENVOLVEMOS AUTOMÁTICAMENTE
|
|
2926
|
+
if (Array.isArray(allTablesData)) {
|
|
2927
|
+
const defaultTableName = configData_?.configData?.table || 'default';
|
|
2928
|
+
allTablesData = { [defaultTableName]: allTablesData };
|
|
2913
2929
|
}
|
|
2914
|
-
|
|
2915
|
-
|
|
2930
|
+
const { ruleColorPoint, configData, xLabelText, yLabelText, title, chartoColoredLine, opacity, emptyPointSettings } = configData_;
|
|
2931
|
+
console.log("configData_:.::", configData_);
|
|
2932
|
+
const cfg = configData || {};
|
|
2933
|
+
const { xAxis, yAxis, joins, configJoins, table, serie, tooltip, legends } = cfg;
|
|
2934
|
+
let series = [];
|
|
2935
|
+
// Función auxiliar robusta para obtener propiedades (soporta notación con puntos de los joins)
|
|
2936
|
+
// const getNestedValue = (obj: any, path: string) => {
|
|
2937
|
+
// if (!obj || !path) return undefined;
|
|
2938
|
+
// if (obj[path] !== undefined) return obj[path];
|
|
2939
|
+
// return path.split('.').reduce((acc, part) => (acc && acc[part] !== undefined ? acc[part] : undefined), obj);
|
|
2940
|
+
// };
|
|
2941
|
+
const sortByXAxis = (data) => {
|
|
2942
|
+
if (!xAxis)
|
|
2943
|
+
return data;
|
|
2944
|
+
return [...data].sort((a, b) => {
|
|
2945
|
+
const aValue = getNestedValue(a, xAxis);
|
|
2946
|
+
const bValue = getNestedValue(b, xAxis);
|
|
2947
|
+
if (aValue == null)
|
|
2948
|
+
return 1;
|
|
2949
|
+
if (bValue == null)
|
|
2950
|
+
return -1;
|
|
2951
|
+
return String(aValue).localeCompare(String(bValue), undefined, { numeric: true, sensitivity: 'base' });
|
|
2952
|
+
});
|
|
2953
|
+
};
|
|
2954
|
+
if (joins === true) {
|
|
2955
|
+
if (!configJoins) {
|
|
2956
|
+
series = [];
|
|
2957
|
+
}
|
|
2958
|
+
else {
|
|
2959
|
+
const unifiedTable = resolveJoinedTableData(allTablesData, configJoins);
|
|
2960
|
+
console.log('unifiedTable bubble', unifiedTable);
|
|
2961
|
+
if (unifiedTable && unifiedTable.length > 0) {
|
|
2962
|
+
// const validRawData = unifiedTable.filter(
|
|
2963
|
+
// (item: any) =>
|
|
2964
|
+
// item &&
|
|
2965
|
+
// xAxis &&
|
|
2966
|
+
// getNestedValue(item, xAxis) !== undefined &&
|
|
2967
|
+
// getNestedValue(item, xAxis) !== null,
|
|
2968
|
+
// );
|
|
2969
|
+
const validRawData = unifiedTable.filter((item) => item &&
|
|
2970
|
+
xAxis &&
|
|
2971
|
+
getNestedValue(item, xAxis) !== undefined &&
|
|
2972
|
+
getNestedValue(item, xAxis) !== null);
|
|
2973
|
+
const orderedRawData = sortByXAxis(validRawData);
|
|
2974
|
+
if (orderedRawData.length > 0) {
|
|
2975
|
+
if (serie) {
|
|
2976
|
+
// 2. Agrupamos los datos por el valor de la serie (ej. sucursal o vendedor)
|
|
2977
|
+
const groupedBySerie = orderedRawData.reduce((acc, item) => {
|
|
2978
|
+
const serieVal = getNestedValue(item, serie);
|
|
2979
|
+
const serieKey = serieVal !== undefined && serieVal !== null
|
|
2980
|
+
? String(serieVal)
|
|
2981
|
+
: 'Desconocido';
|
|
2982
|
+
if (!acc[serieKey]) {
|
|
2983
|
+
acc[serieKey] = [];
|
|
2984
|
+
}
|
|
2985
|
+
acc[serieKey].push(item);
|
|
2986
|
+
return acc;
|
|
2987
|
+
}, {});
|
|
2988
|
+
series = Object.entries(groupedBySerie).map(([serieName, groupItems]) => {
|
|
2989
|
+
const orderedGroupItems = [...groupItems].sort((a, b) => {
|
|
2990
|
+
const aValue = getNestedValue(a, xAxis);
|
|
2991
|
+
const bValue = getNestedValue(b, xAxis);
|
|
2992
|
+
return String(aValue).localeCompare(String(bValue), undefined, {
|
|
2993
|
+
numeric: true,
|
|
2994
|
+
sensitivity: 'base'
|
|
2995
|
+
});
|
|
2996
|
+
});
|
|
2997
|
+
console.log("SERIES NAME:", orderedGroupItems);
|
|
2998
|
+
const dataSource = orderedGroupItems.map((item) => {
|
|
2999
|
+
const rawVal = getNestedValue(item, yAxis);
|
|
3000
|
+
const valorFinal = rawVal !== undefined
|
|
3001
|
+
? typeof rawVal === 'number'
|
|
3002
|
+
? rawVal
|
|
3003
|
+
: Number(rawVal) || 0
|
|
3004
|
+
: 0;
|
|
3005
|
+
const sizeFinal = Math.abs(valorFinal) !== 0 ? Math.abs(valorFinal) * 0.05 : 0;
|
|
3006
|
+
return {
|
|
3007
|
+
x: String(getNestedValue(item, xAxis)),
|
|
3008
|
+
y: valorFinal,
|
|
3009
|
+
size: sizeFinal,
|
|
3010
|
+
name: String(getNestedValue(item, xAxis)),
|
|
3011
|
+
// ...(chartoColoredLine
|
|
3012
|
+
// ? { color: getRandomProfessionalHex() }
|
|
3013
|
+
// : {})
|
|
3014
|
+
};
|
|
3015
|
+
});
|
|
3016
|
+
return {
|
|
3017
|
+
name: serieName === 'default' ? 'Serie 1' : serieName,
|
|
3018
|
+
dataSource: aggregateByX(dataSource),
|
|
3019
|
+
opacity: opacity,
|
|
3020
|
+
emptyPointSettings: emptyPointSettings,
|
|
3021
|
+
// dashArray: dashArray !== undefined ? dashArray : undefined,
|
|
3022
|
+
// width: width !== undefined ? width : undefined,
|
|
3023
|
+
// widthLine: widthLine !== undefined ? widthLine : undefined,
|
|
3024
|
+
};
|
|
3025
|
+
});
|
|
3026
|
+
}
|
|
3027
|
+
else {
|
|
3028
|
+
const dataSource = orderedRawData.map((item) => {
|
|
3029
|
+
let valorFinal = 0;
|
|
3030
|
+
let sizeFinal = 0;
|
|
3031
|
+
// const shouldColorLine = chartoColoredLine;
|
|
3032
|
+
const rawVal = getNestedValue(item, yAxis);
|
|
3033
|
+
// const rawSize = getNestedValue(item, size); // <--- Extraer el valor real
|
|
3034
|
+
if (rawVal !== undefined) {
|
|
3035
|
+
valorFinal = typeof rawVal === 'number' ? rawVal : Number(rawVal) || 0;
|
|
3036
|
+
}
|
|
3037
|
+
// if (rawSize !== undefined) {
|
|
3038
|
+
sizeFinal = Math.abs(valorFinal) !== 0 ? Math.abs(valorFinal) * 0.05 : 0;
|
|
3039
|
+
// }
|
|
3040
|
+
return {
|
|
3041
|
+
x: String(getNestedValue(item, xAxis)),
|
|
3042
|
+
y: valorFinal,
|
|
3043
|
+
size: sizeFinal, // <--- Valor numérico extraído
|
|
3044
|
+
name: String(getNestedValue(item, xAxis)),
|
|
3045
|
+
// ...(shouldColorLine ? { color: getRandomProfessionalHex() } : {})
|
|
3046
|
+
};
|
|
3047
|
+
});
|
|
3048
|
+
series = [
|
|
3049
|
+
{
|
|
3050
|
+
name: xAxis.split(".")[0] && xAxis !== 'default' ? xAxis.split(".")[0] : 'Serie Join',
|
|
3051
|
+
dataSource: aggregateByX(dataSource),
|
|
3052
|
+
opacity: opacity,
|
|
3053
|
+
emptyPointSettings: emptyPointSettings,
|
|
3054
|
+
// dashArray: dashArray !== undefined ? dashArray : undefined,
|
|
3055
|
+
// width: width !== undefined ? width : undefined,
|
|
3056
|
+
// widthLine: widthLine !== undefined ? widthLine : undefined,
|
|
3057
|
+
}
|
|
3058
|
+
];
|
|
3059
|
+
}
|
|
3060
|
+
}
|
|
3061
|
+
}
|
|
3062
|
+
}
|
|
2916
3063
|
}
|
|
2917
|
-
|
|
2918
|
-
|
|
2919
|
-
|
|
2920
|
-
|
|
2921
|
-
;
|
|
3064
|
+
else {
|
|
3065
|
+
let normalizedTables = [];
|
|
3066
|
+
if (Array.isArray(table)) {
|
|
3067
|
+
normalizedTables = table.filter((t) => typeof t === 'string' && t.trim() !== '');
|
|
2922
3068
|
}
|
|
2923
|
-
if (
|
|
2924
|
-
|
|
3069
|
+
else if (typeof table === 'string' && table.trim() !== '') {
|
|
3070
|
+
normalizedTables = [table];
|
|
2925
3071
|
}
|
|
2926
|
-
|
|
2927
|
-
|
|
2928
|
-
this.dataWidget = { idComponent: this.componentWidgetId,
|
|
2929
|
-
controlConfig: this.controlConfig,
|
|
2930
|
-
controlData: this.controlData
|
|
2931
|
-
};
|
|
3072
|
+
else {
|
|
3073
|
+
normalizedTables = Object.keys(allTablesData);
|
|
2932
3074
|
}
|
|
2933
|
-
|
|
2934
|
-
|
|
2935
|
-
|
|
2936
|
-
|
|
2937
|
-
|
|
2938
|
-
|
|
2939
|
-
|
|
2940
|
-
|
|
2941
|
-
|
|
2942
|
-
|
|
2943
|
-
|
|
2944
|
-
|
|
2945
|
-
|
|
2946
|
-
|
|
2947
|
-
|
|
2948
|
-
|
|
2949
|
-
|
|
2950
|
-
|
|
2951
|
-
|
|
2952
|
-
|
|
2953
|
-
|
|
2954
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.30", type: YwDashboardWidgetComponent, isStandalone: true, selector: "yw-dashboard-widget", inputs: { styleWidget: { classPropertyName: "styleWidget", publicName: "styleWidget", isSignal: true, isRequired: false, transformFunction: null }, configWidget: { classPropertyName: "configWidget", publicName: "configWidget", isSignal: false, isRequired: false, transformFunction: null }, controlConfig: { classPropertyName: "controlConfig", publicName: "controlConfig", isSignal: false, isRequired: false, transformFunction: null }, controlData: { classPropertyName: "controlData", publicName: "controlData", isSignal: false, isRequired: false, transformFunction: null }, isLocked: { classPropertyName: "isLocked", publicName: "isLocked", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { isLocked: "isLockedChange", eventDeleteRequest: "eventDeleteRequest", eventLockToggleRequest: "eventLockToggleRequest", eventMaximizeToggleRequest: "eventMaximizeToggleRequest", eventShowConfigFormRequest: "eventShowConfigFormRequest" }, host: { properties: { "style.--widget-bg": "instanceStyleWidget().widgetBackgroundColor", "style.--widget-border-color": "instanceStyleWidget().widgetBorderColor" } }, usesOnChanges: true, ngImport: i0, template: "\r\n<!-- <div class=\"widget-action-bar\"> \r\n <button [hidden]=\"!varShowConfigButtons\" class=\"btn-action\" (click)=\"onLockClick()\">{{ isLocked() ? '\uD83D\uDD12' : '\uD83D\uDD13' }}</button>\r\n <button class=\"btn-action\" (click)=\"onMaximizeClick()\">{{ isMaximized() ? '\uD83D\uDDD7' : '\uD83D\uDDD6' }}</button>\r\n <button [hidden]=\"!varShowConfigButtons\" class=\"btn-delete\" (click)=\"onDeleteClick()\">\uD83D\uDDD1\uFE0F</button>\r\n <button [hidden]=\"!varShowConfigButtons\" class=\"btn-config\" (click)=\"onShowFormConfigClick()\">\u2699\uFE0F</button>\r\n</div> -->\r\n\r\n<div class=\"widget-action-bar\">\r\n <!-- Bot\u00F3n Bloquear / Desbloquear -->\r\n <button [hidden]=\"!varShowConfigButtons\" class=\"btn-action\" (click)=\"onLockClick()\" [title]=\"isLocked() ? 'Desbloquear' : 'Bloquear'\">\r\n <svg *ngIf=\"isLocked(); else unlockedIcon\" width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><rect x=\"3\" y=\"11\" width=\"18\" height=\"11\" rx=\"2\" ry=\"2\"></rect><path d=\"M7 11V7a5 5 0 0 1 10 0v4\"></path></svg>\r\n <ng-template #unlockedIcon>\r\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><rect x=\"3\" y=\"11\" width=\"18\" height=\"11\" rx=\"2\" ry=\"2\"></rect><path d=\"M7 11V7a5 5 0 0 1 9.9-1\"></path></svg>\r\n </ng-template>\r\n </button>\r\n\r\n <!-- Bot\u00F3n Maximizar / Restaurar -->\r\n <button class=\"btn-action\" (click)=\"onMaximizeClick()\" [title]=\"isMaximized() ? 'Restaurar' : 'Maximizar'\">\r\n <svg *ngIf=\"isMaximized(); else maxIcon\" width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M8 3v3a2 2 0 0 1-2 2H3m18 0h-3a2 2 0 0 1-2-2V3m0 18v-3a2 2 0 0 1 2-2h3M3 16h3a2 2 0 0 1 2 2v3\"></path></svg>\r\n <ng-template #maxIcon>\r\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M15 3h6v6M9 21H3v-6M21 3l-7 7M3 21l7-7\"></path></svg>\r\n </ng-template>\r\n </button>\r\n\r\n <!-- Bot\u00F3n Eliminar -->\r\n <button [hidden]=\"!varShowConfigButtons\" class=\"btn-delete\" (click)=\"onDeleteClick()\" title=\"Eliminar\">\r\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><polyline points=\"3 6 5 6 21 6\"></polyline><path d=\"M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6m3 0V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2\"></path></svg>\r\n </button>\r\n\r\n <!-- Bot\u00F3n Configuraci\u00F3n -->\r\n <button [hidden]=\"!varShowConfigButtons\" class=\"btn-config\" (click)=\"onShowFormConfigClick()\" title=\"Configurar\">\r\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><circle cx=\"12\" cy=\"12\" r=\"3\"></circle><path d=\"M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 0 1 0 2.83 2 2 0 0 1-2.83 0l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 0 1-2 2 2 2 0 0 1-2-2v-.09A1.65 1.65 0 0 0 9 19.4a1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 0 1-2.83 0 2 2 0 0 1 0-2.83l.06-.06a1.65 1.65 0 0 0 .33-1.82 1.65 1.65 0 0 0-1.51-1H3a2 2 0 0 1-2-2 2 2 0 0 1 2-2h.09A1.65 1.65 0 0 0 4.6 9a1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 0 1 0-2.83 2 2 0 0 1 2.83 0l.06.06a1.65 1.65 0 0 0 1.82.33H9a1.65 1.65 0 0 0 1-1.51V3a2 2 0 0 1 2-2 2 2 0 0 1 2 2v.09a1.65 1.65 0 0 0 1 1.51 1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 0 1 2.83 0 2 2 0 0 1 0 2.83l-.06.06a1.65 1.65 0 0 0-.33 1.82V9a1.65 1.65 0 0 0 1.51 1H21a2 2 0 0 1 2 2 2 2 0 0 1-2 2h-.09a1.65 1.65 0 0 0-1.51 1z\"></path></svg>\r\n </button>\r\n</div>\r\n\r\n<div class=\"widget-content-wrapper\">\r\n @if ( typeComponent == 'dummy' ) {\r\n <ng-container *ngTemplateOutlet=\"testdummy; context: { control: dataWidget }\"></ng-container>\r\n }\r\n @if ( typeComponent == 'empty-visual' ) {\r\n <ng-container *ngTemplateOutlet=\"emptyvisual; context: { control: dataWidget }\"></ng-container>\r\n }\r\n @if ( typeComponent == 'chart-bar' ) {\r\n <ng-container *ngTemplateOutlet=\"chartbar; context: { control: dataWidget }\"></ng-container>\r\n }\r\n @if ( typeComponent == 'chart-line' ) {\r\n <ng-container *ngTemplateOutlet=\"chartline; context: { control: dataWidget }\"></ng-container>\r\n }\r\n @if ( typeComponent == 'chart-doughnut' ) {\r\n <ng-container *ngTemplateOutlet=\"chartdoughnut; context: { control: dataWidget }\"></ng-container>\r\n } \r\n @if ( typeComponent == 'chart-gauge' ) {\r\n <ng-container *ngTemplateOutlet=\"chartgauge; context: { control: dataWidget }\"></ng-container>\r\n } \r\n \r\n \r\n</div>\r\n\r\n\r\n<!--------------------------------------------------------------->\r\n<!---------------------- DUMMY TEMPLATE ---------------------->\r\n<!--------------------------------------------------------------->\r\n<ng-template #testdummy let-control = \"control\">\r\n <lib-test-chart [idComponent]=\"control.idComponent\" > \r\n </lib-test-chart>\r\n</ng-template>\r\n<!--------------------------------------------------------------->\r\n<!---------------------- EMPTY VISUAL TEMPLATE ---------------------->\r\n<!--------------------------------------------------------------->\r\n<ng-template #emptyvisual let-control = \"control\">\r\n <yw-empty-visual [idComponent]=\"control.idComponent\"\r\n [config]=\"control.controlConfig\" \r\n > \r\n </yw-empty-visual>\r\n</ng-template>\r\n\r\n<!--------------------------------------------------------------->\r\n<!---------------------- BAR CHART TEMPLATE ---------------------->\r\n<!--------------------------------------------------------------->\r\n<ng-template #chartbar let-control = \"control\">\r\n <yw-bar-chart [idComponent]=\"control.idComponent\"\r\n [chartData]=\"control.controlData\"\r\n [config]=\"control.controlConfig\" \r\n >\r\n </yw-bar-chart>\r\n</ng-template>\r\n\r\n<!--------------------------------------------------------------->\r\n<!---------------------- LINE CHART TEMPLATE ---------------------->\r\n<!--------------------------------------------------------------->\r\n<ng-template #chartline let-control = \"control\">\r\n <yw-line-chart [idComponent]=\"control.idComponent\"\r\n [chartData]=\"control.controlData\"\r\n [config]=\"control.controlConfig\" \r\n >\r\n </yw-line-chart>\r\n</ng-template>\r\n\r\n\r\n<!--------------------------------------------------------------->\r\n<!---------------------- LINE DOUGHNUT TEMPLATE ---------------------->\r\n<!--------------------------------------------------------------->\r\n<ng-template #chartdoughnut let-control = \"control\">\r\n <yw-pie-chart [idComponent]=\"control.idComponent\"\r\n [chartData]=\"control.controlData\"\r\n [config]=\"control.controlConfig\" \r\n >\r\n </yw-pie-chart>\r\n</ng-template>\r\n\r\n \r\n<!--------------------------------------------------------------->\r\n<!---------------------- LINE GAUGE TEMPLATE ---------------------->\r\n<!--------------------------------------------------------------->\r\n<ng-template #chartgauge let-control = \"control\">\r\n <yw-gauge-chart [idComponent]=\"control.idComponent\"\r\n [chartData]=\"control.controlData\"\r\n [config]=\"control.controlConfig\" \r\n >\r\n </yw-gauge-chart>\r\n</ng-template>\r\n", styles: ["@charset \"UTF-8\";:host{display:block;flex-direction:column;width:100%;overflow:hidden;box-sizing:border-box;background-color:var(--widget-bg, #ffffff);border:1px solid var(--widget-border-color, #007bff)}:host *,:host *:before,:host *:after{box-sizing:border-box}.widget-action-bar{display:flex;justify-content:flex-end;gap:4px;padding:5px 10px;flex-shrink:0;width:100%}.widget-content-wrapper{width:100%;flex-grow:1;height:0;display:flex;flex-direction:column}.widget-action-bar button,.widget-action-bar .btn-action,.widget-action-bar .btn-delete,.widget-action-bar .btn-config{background:transparent;border:1px solid #d9d9d9;border-radius:4px;cursor:pointer;width:26px;height:26px;display:inline-flex;align-items:center;justify-content:center;color:#595959;padding:0;transition:all .2s ease}.widget-action-bar button svg,.widget-action-bar .btn-action svg,.widget-action-bar .btn-delete svg,.widget-action-bar .btn-config svg{width:14px;height:14px}.widget-action-bar button:hover,.widget-action-bar .btn-action:hover,.widget-action-bar .btn-delete:hover,.widget-action-bar .btn-config:hover{background-color:#f5f5f5;color:#262626;border-color:#bfbfbf}.widget-action-bar button:active,.widget-action-bar .btn-action:active,.widget-action-bar .btn-delete:active,.widget-action-bar .btn-config:active{background-color:#e6e6e6}.widget-action-bar .btn-delete:hover{background-color:#fff1f0;color:#ff4d4f;border-color:#ffa39e}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1$2.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: TestChartComponent, selector: "lib-test-chart", inputs: ["idComponent"] }, { kind: "component", type: YwEmptyVisualComponent, selector: "yw-empty-visual", inputs: ["idComponent", "config"] }, { kind: "component", type: LineChartComponent, selector: "yw-line-chart", inputs: ["chartData", "config", "idComponent"] }, { kind: "component", type: BarChartComponent, selector: "yw-bar-chart", inputs: ["chartData", "config", "idComponent"] }, { kind: "component", type: PieChartComponent, selector: "yw-pie-chart", inputs: ["idComponent", "chartData", "config"] }, { kind: "component", type: GaugeChartComponent, selector: "yw-gauge-chart", inputs: ["idComponent", "chartData", "config"] }] }); }
|
|
2955
|
-
|
|
2956
|
-
|
|
2957
|
-
|
|
2958
|
-
|
|
2959
|
-
|
|
2960
|
-
|
|
2961
|
-
|
|
2962
|
-
|
|
2963
|
-
|
|
2964
|
-
|
|
2965
|
-
|
|
2966
|
-
|
|
2967
|
-
|
|
2968
|
-
|
|
2969
|
-
|
|
2970
|
-
|
|
2971
|
-
|
|
2972
|
-
|
|
2973
|
-
|
|
2974
|
-
|
|
2975
|
-
|
|
3075
|
+
series = normalizedTables
|
|
3076
|
+
.map((tableName) => {
|
|
3077
|
+
const rawData = (allTablesData && allTablesData[tableName]) ? allTablesData[tableName] : [];
|
|
3078
|
+
if (!rawData || rawData.length === 0)
|
|
3079
|
+
return null;
|
|
3080
|
+
const orderedRawData = rawData.filter((item) => item && xAxis && getNestedValue(item, xAxis) !== undefined && getNestedValue(item, xAxis) !== null);
|
|
3081
|
+
if (orderedRawData.length === 0)
|
|
3082
|
+
return null;
|
|
3083
|
+
const dataSource = orderedRawData.map((item) => {
|
|
3084
|
+
let valorFinal = 0;
|
|
3085
|
+
let sizeFinal = 0;
|
|
3086
|
+
const shouldColorLine = chartoColoredLine;
|
|
3087
|
+
const rawVal = getNestedValue(item, yAxis);
|
|
3088
|
+
// const rawSize = getNestedValue(item, size);
|
|
3089
|
+
if (rawVal !== undefined) {
|
|
3090
|
+
valorFinal = typeof rawVal === "number" ? rawVal : Number(rawVal) || 0;
|
|
3091
|
+
}
|
|
3092
|
+
// if (rawSize !== undefined) {
|
|
3093
|
+
sizeFinal = Math.abs(valorFinal) !== 0 ? Math.abs(valorFinal) * 0.05 : 0;
|
|
3094
|
+
// }
|
|
3095
|
+
return {
|
|
3096
|
+
x: String(getNestedValue(item, xAxis)),
|
|
3097
|
+
y: valorFinal,
|
|
3098
|
+
size: sizeFinal, // <--- Valor numérico extraído
|
|
3099
|
+
name: String(getNestedValue(item, xAxis))
|
|
3100
|
+
// ...(shouldColorLine ? { color: getRandomProfessionalHex() } : {})
|
|
3101
|
+
};
|
|
3102
|
+
});
|
|
3103
|
+
return {
|
|
3104
|
+
name: tableName === 'default' ? xAxis : tableName,
|
|
3105
|
+
dataSource: aggregateByX(dataSource),
|
|
3106
|
+
opacity: opacity,
|
|
3107
|
+
emptyPointSettings: emptyPointSettings,
|
|
3108
|
+
// dashArray: dashArray !== undefined ? dashArray : undefined,
|
|
3109
|
+
// width: width !== undefined ? width : undefined,
|
|
3110
|
+
// widthLine: widthLine !== undefined ? widthLine : undefined,
|
|
3111
|
+
};
|
|
3112
|
+
})
|
|
3113
|
+
.filter((item) => item !== null);
|
|
3114
|
+
}
|
|
3115
|
+
const labelData = {
|
|
3116
|
+
title: title || "",
|
|
3117
|
+
titleStyle: {
|
|
3118
|
+
size: '16px',
|
|
3119
|
+
fontWeight: '600',
|
|
3120
|
+
color: '#2b2b2b',
|
|
3121
|
+
fontFamily: 'Inherit',
|
|
3122
|
+
textAlignment: 'Center'
|
|
3123
|
+
},
|
|
3124
|
+
axisX: {
|
|
3125
|
+
valueType: 'Category',
|
|
3126
|
+
// title: typeof xLabelText === 'string' ? xLabelText : 'Categoría',
|
|
3127
|
+
// labelIntersectAction: 'Rotate90',
|
|
3128
|
+
// labelIntersectAction: 'Rotate45',
|
|
3129
|
+
majorGridLines: { width: 0 },
|
|
3130
|
+
majorTickLines: { width: 0 },
|
|
3131
|
+
lineStyle: { width: 0 },
|
|
3132
|
+
labelStyle: { color: '#64748B', size: '12px', fontFamily: 'Inherit' }
|
|
3133
|
+
},
|
|
3134
|
+
axisY: {
|
|
3135
|
+
title: typeof yLabelText === 'string' ? yLabelText : 'Valor',
|
|
3136
|
+
minimum: 0,
|
|
3137
|
+
edgeLabelPlacement: 'Shift',
|
|
3138
|
+
lineStyle: { width: 0 },
|
|
3139
|
+
majorTickLines: { width: 0 },
|
|
3140
|
+
minorTickLines: { width: 0 },
|
|
3141
|
+
majorGridLines: { width: 0.5, color: '#E2E8F0', dashArray: '4,4' },
|
|
3142
|
+
labelStyle: { color: '#94A3B8', size: '12px', fontFamily: 'Inherit' },
|
|
3143
|
+
titleStyle: { size: '12px', color: '#64748B', fontFamily: 'Inherit' }
|
|
3144
|
+
},
|
|
3145
|
+
marker: {
|
|
3146
|
+
visible: true,
|
|
3147
|
+
width: 8,
|
|
3148
|
+
height: 8,
|
|
3149
|
+
dataLabel: {
|
|
3150
|
+
visible: true,
|
|
3151
|
+
position: 'Top', // Centra el texto exactamente en el medio de la burbuja
|
|
3152
|
+
name: 'text', // Asegúrate de que apunte al campo de tu data que trae el nombre (ej: 'text' o 'name')
|
|
3153
|
+
font: {
|
|
3154
|
+
fontWeight: '600',
|
|
3155
|
+
color: '#334155', // Color del texto (oscuro para que contraste con el fondo claro) o '#FFFFFF' si prefieres blanco
|
|
3156
|
+
size: '12px',
|
|
3157
|
+
fontFamily: 'Inherit'
|
|
3158
|
+
}
|
|
3159
|
+
}
|
|
3160
|
+
},
|
|
3161
|
+
palettes: ['#6366F1', '#22D3EE', '#F59E0B', '#10B981', '#F43F5E'],
|
|
3162
|
+
border: { width: 0 },
|
|
3163
|
+
chartArea: { border: { width: 0 }, margin: { bottom: 12 } },
|
|
3164
|
+
tooltip: {
|
|
3165
|
+
...(tooltip?.enable !== undefined ? { enable: tooltip.enable } : {}),
|
|
3166
|
+
...(tooltip?.format ? { format: tooltip.format } : {}),
|
|
3167
|
+
...(tooltip?.header ? { header: tooltip.header } : {}),
|
|
3168
|
+
...(tooltip?.shared !== undefined ? { shared: tooltip.shared } : {}),
|
|
3169
|
+
enableHighlight: true,
|
|
3170
|
+
},
|
|
3171
|
+
legendSettings: {
|
|
3172
|
+
visible: legends?.visible !== undefined ? legends.visible : undefined,
|
|
3173
|
+
position: legends?.position !== undefined ? legends.position : undefined
|
|
3174
|
+
},
|
|
3175
|
+
ruleColorPoint: ruleColorPoint !== undefined ? ruleColorPoint : undefined
|
|
3176
|
+
};
|
|
3177
|
+
return {
|
|
3178
|
+
series,
|
|
3179
|
+
labelData
|
|
3180
|
+
};
|
|
3181
|
+
};
|
|
2976
3182
|
|
|
2977
|
-
class
|
|
2978
|
-
constructor() {
|
|
2979
|
-
|
|
3183
|
+
class BubbleChartSyncfusionComponent {
|
|
3184
|
+
constructor(elRef, cdr) {
|
|
3185
|
+
this.elRef = elRef;
|
|
3186
|
+
this.cdr = cdr;
|
|
2980
3187
|
this.idComponent = '';
|
|
2981
|
-
this.
|
|
2982
|
-
this.
|
|
2983
|
-
this.
|
|
2984
|
-
this.max = input(...(ngDevMode ? [undefined, { debugName: "max" }] : []));
|
|
2985
|
-
this.step = input(1, ...(ngDevMode ? [{ debugName: "step" }] : []));
|
|
2986
|
-
this.minCurrent = input(...(ngDevMode ? [undefined, { debugName: "minCurrent" }] : []));
|
|
2987
|
-
this.maxCurrent = input(...(ngDevMode ? [undefined, { debugName: "maxCurrent" }] : []));
|
|
2988
|
-
this.minNumber = 0;
|
|
2989
|
-
this.maxNumber = 1000;
|
|
2990
|
-
this.minDate = '2020-01-01';
|
|
2991
|
-
this.maxDate = '2022-12-31';
|
|
2992
|
-
// Evento de salida
|
|
2993
|
-
this.rangeChange = output();
|
|
2994
|
-
// Signals para las fechas seleccionadas
|
|
2995
|
-
this.startDate = signal('2020-01-01', ...(ngDevMode ? [{ debugName: "startDate" }] : []));
|
|
2996
|
-
this.endDate = signal('2022-09-22', ...(ngDevMode ? [{ debugName: "endDate" }] : []));
|
|
2997
|
-
// Signals para los numeros seleccionadas
|
|
2998
|
-
this.startVal = signal(0, ...(ngDevMode ? [{ debugName: "startVal" }] : []));
|
|
2999
|
-
this.endVal = signal(1000, ...(ngDevMode ? [{ debugName: "endVal" }] : []));
|
|
3000
|
-
this.minTimestamp = computed(() => new Date(this.minDate).getTime(), ...(ngDevMode ? [{ debugName: "minTimestamp" }] : []));
|
|
3001
|
-
this.maxTimestamp = computed(() => new Date(this.maxDate).getTime(), ...(ngDevMode ? [{ debugName: "maxTimestamp" }] : []));
|
|
3002
|
-
this.startTimestamp = computed(() => new Date(this.startDate()).getTime(), ...(ngDevMode ? [{ debugName: "startTimestamp" }] : []));
|
|
3003
|
-
this.endTimestamp = computed(() => new Date(this.endDate()).getTime(), ...(ngDevMode ? [{ debugName: "endTimestamp" }] : []));
|
|
3004
|
-
// Inicializar valores al arrancar
|
|
3005
|
-
effect(() => {
|
|
3006
|
-
if (this.dataType == 'date') {
|
|
3007
|
-
this.startDate.set(this.minCurrent() || this.minDate);
|
|
3008
|
-
this.endDate.set(this.maxCurrent() || this.maxDate);
|
|
3009
|
-
}
|
|
3010
|
-
if (this.dataType == 'number') {
|
|
3011
|
-
this.startVal.set(this.minCurrent() || this.minNumber);
|
|
3012
|
-
this.endVal.set(this.maxCurrent() || this.maxNumber);
|
|
3013
|
-
}
|
|
3014
|
-
}, { allowSignalWrites: true });
|
|
3015
|
-
// Notificar al padre cada vez que cambien los valores
|
|
3016
|
-
effect(() => {
|
|
3017
|
-
if (this.dataType == 'date') {
|
|
3018
|
-
this.rangeChange.emit({
|
|
3019
|
-
startDate: this.startDate(),
|
|
3020
|
-
endDate: this.endDate()
|
|
3021
|
-
});
|
|
3022
|
-
}
|
|
3023
|
-
if (this.dataType == 'number') {
|
|
3024
|
-
this.rangeChange.emit({
|
|
3025
|
-
minValue: this.startVal(),
|
|
3026
|
-
maxValue: this.endVal()
|
|
3027
|
-
});
|
|
3028
|
-
}
|
|
3029
|
-
});
|
|
3188
|
+
this.dataChartParse = [];
|
|
3189
|
+
this.currentLabelSize = '';
|
|
3190
|
+
this.currentWidgetWidth = 0; // Valor inicial por defecto
|
|
3030
3191
|
}
|
|
3031
3192
|
ngOnInit() {
|
|
3032
|
-
|
|
3033
|
-
this.minDate = this.min();
|
|
3034
|
-
this.maxDate = this.max();
|
|
3035
|
-
this.minTimestamp = computed(() => new Date(this.minDate).getTime(), ...(ngDevMode ? [{ debugName: "minTimestamp" }] : []));
|
|
3036
|
-
this.maxTimestamp = computed(() => new Date(this.maxDate).getTime(), ...(ngDevMode ? [{ debugName: "maxTimestamp" }] : []));
|
|
3037
|
-
this.startTimestamp = computed(() => new Date(this.startDate()).getTime(), ...(ngDevMode ? [{ debugName: "startTimestamp" }] : []));
|
|
3038
|
-
this.endTimestamp = computed(() => new Date(this.endDate()).getTime(), ...(ngDevMode ? [{ debugName: "endTimestamp" }] : []));
|
|
3039
|
-
}
|
|
3040
|
-
if (this.dataType == 'number') {
|
|
3041
|
-
this.minNumber = this.min();
|
|
3042
|
-
this.maxNumber = this.max();
|
|
3043
|
-
}
|
|
3044
|
-
}
|
|
3045
|
-
// Handlers para la entrada manual de fechas
|
|
3046
|
-
onStartDateInput(value) {
|
|
3047
|
-
if (value && value <= this.endDate()) {
|
|
3048
|
-
this.startDate.set(value);
|
|
3049
|
-
}
|
|
3193
|
+
this.updateParsedData();
|
|
3050
3194
|
}
|
|
3051
|
-
|
|
3052
|
-
if (
|
|
3053
|
-
this.
|
|
3195
|
+
ngOnChanges(changes) {
|
|
3196
|
+
if (changes['chartData'] || changes['config']) {
|
|
3197
|
+
this.updateParsedData();
|
|
3054
3198
|
}
|
|
3055
3199
|
}
|
|
3056
|
-
|
|
3057
|
-
|
|
3058
|
-
const value = Number(event.target.value);
|
|
3059
|
-
if (!isNaN(value) && value <= this.endVal() && value >= this.min()) {
|
|
3060
|
-
this.startVal.set(value);
|
|
3061
|
-
}
|
|
3200
|
+
ngAfterViewInit() {
|
|
3201
|
+
this._startResizeObserver();
|
|
3062
3202
|
}
|
|
3063
|
-
|
|
3064
|
-
|
|
3065
|
-
if (!isNaN(value) && value >= this.startVal() && value <= this.max()) {
|
|
3066
|
-
this.endVal.set(value);
|
|
3067
|
-
}
|
|
3203
|
+
ngOnDestroy() {
|
|
3204
|
+
this._resizeObserver?.disconnect();
|
|
3068
3205
|
}
|
|
3069
|
-
|
|
3070
|
-
|
|
3071
|
-
|
|
3072
|
-
|
|
3073
|
-
|
|
3074
|
-
if (
|
|
3075
|
-
this.
|
|
3206
|
+
updateParsedData() {
|
|
3207
|
+
if (this.chartData && this.config) {
|
|
3208
|
+
const rawParsed = parseSyncFusionData(this.chartData, this.config);
|
|
3209
|
+
this.dataChartParse = rawParsed.series;
|
|
3210
|
+
this.labelData = rawParsed.labelData;
|
|
3211
|
+
if (this.dataLabel && this.labelData) {
|
|
3212
|
+
this.labelData.dataLabel = this.dataLabel;
|
|
3076
3213
|
}
|
|
3077
|
-
|
|
3078
|
-
|
|
3079
|
-
|
|
3080
|
-
|
|
3081
|
-
|
|
3214
|
+
this.cdr.markForCheck();
|
|
3215
|
+
if (this.chartInstance) {
|
|
3216
|
+
setTimeout(() => {
|
|
3217
|
+
this.chartInstance?.refresh();
|
|
3218
|
+
});
|
|
3082
3219
|
}
|
|
3083
3220
|
}
|
|
3084
3221
|
}
|
|
3085
|
-
|
|
3086
|
-
|
|
3087
|
-
|
|
3088
|
-
|
|
3089
|
-
|
|
3090
|
-
|
|
3222
|
+
pointRender(args) {
|
|
3223
|
+
const yValue = Number(args.point.y);
|
|
3224
|
+
// =====================================================
|
|
3225
|
+
// EMPTY POINT / VALOR 0
|
|
3226
|
+
// Tiene prioridad sobre ruleColorPoint
|
|
3227
|
+
// =====================================================
|
|
3228
|
+
if (yValue === 0) {
|
|
3229
|
+
const emptyPoint = this.config.emptyPointSettings;
|
|
3230
|
+
if (emptyPoint && emptyPoint !== '') {
|
|
3231
|
+
args.fill = emptyPoint;
|
|
3091
3232
|
}
|
|
3233
|
+
return;
|
|
3092
3234
|
}
|
|
3093
|
-
|
|
3094
|
-
|
|
3095
|
-
|
|
3096
|
-
|
|
3097
|
-
|
|
3235
|
+
// =====================================================
|
|
3236
|
+
// RULE COLOR POINT
|
|
3237
|
+
// =====================================================
|
|
3238
|
+
const configPoint = this.config.ruleColorPoint || null;
|
|
3239
|
+
if (!configPoint) {
|
|
3240
|
+
return;
|
|
3241
|
+
}
|
|
3242
|
+
let passesRule = false;
|
|
3243
|
+
switch (configPoint.rule) {
|
|
3244
|
+
case 'threshold':
|
|
3245
|
+
passesRule =
|
|
3246
|
+
yValue >= (configPoint.thresholdValue || 0);
|
|
3247
|
+
break;
|
|
3248
|
+
case 'pair':
|
|
3249
|
+
passesRule = yValue % 2 === 0;
|
|
3250
|
+
break;
|
|
3251
|
+
case 'range':
|
|
3252
|
+
const min = configPoint.minRange || 0;
|
|
3253
|
+
const max = configPoint.maxRange || 100;
|
|
3254
|
+
passesRule =
|
|
3255
|
+
yValue >= min &&
|
|
3256
|
+
yValue <= max;
|
|
3257
|
+
break;
|
|
3258
|
+
default:
|
|
3259
|
+
passesRule = true;
|
|
3098
3260
|
}
|
|
3261
|
+
args.fill = passesRule
|
|
3262
|
+
? (configPoint.trueColor || '#10B981')
|
|
3263
|
+
: (configPoint.falseColor || '#EF4444');
|
|
3099
3264
|
}
|
|
3100
|
-
|
|
3101
|
-
|
|
3102
|
-
|
|
3103
|
-
|
|
3104
|
-
|
|
3105
|
-
|
|
3106
|
-
|
|
3107
|
-
|
|
3108
|
-
|
|
3109
|
-
|
|
3110
|
-
|
|
3111
|
-
|
|
3112
|
-
|
|
3113
|
-
|
|
3114
|
-
|
|
3115
|
-
|
|
3116
|
-
|
|
3117
|
-
this.idComponent = '';
|
|
3118
|
-
this.label = input('Tipo de producto', ...(ngDevMode ? [{ debugName: "label" }] : []));
|
|
3119
|
-
this.options = input([], ...(ngDevMode ? [{ debugName: "options" }] : []));
|
|
3120
|
-
this.allowMultiple = input(true, ...(ngDevMode ? [{ debugName: "allowMultiple" }] : [])); // Permite cambiar a selección única si es necesario
|
|
3121
|
-
// Evento de salida con la lista de IDs seleccionados
|
|
3122
|
-
this.selectionChange = output();
|
|
3123
|
-
// Signal con los IDs seleccionados
|
|
3124
|
-
this.selectedIds = signal(new Set(), ...(ngDevMode ? [{ debugName: "selectedIds" }] : []));
|
|
3125
|
-
// Current IDs seleccionados
|
|
3126
|
-
this.currentIds = input([], ...(ngDevMode ? [{ debugName: "currentIds" }] : []));
|
|
3127
|
-
// Emitir el listado en Array cada vez que la Signal de selección cambie
|
|
3128
|
-
effect(() => {
|
|
3129
|
-
this.selectionChange.emit(Array.from(this.selectedIds()));
|
|
3265
|
+
_startResizeObserver() {
|
|
3266
|
+
if (typeof ResizeObserver === 'undefined')
|
|
3267
|
+
return;
|
|
3268
|
+
const hostEl = this.elRef.nativeElement;
|
|
3269
|
+
this._resizeObserver = new ResizeObserver((entries) => {
|
|
3270
|
+
window.requestAnimationFrame(() => {
|
|
3271
|
+
for (const entry of entries) {
|
|
3272
|
+
this.currentWidgetWidth = entry.contentRect.width;
|
|
3273
|
+
if (this.currentWidgetWidth > 0) {
|
|
3274
|
+
this._updateAdaptiveLabelSize(this.currentWidgetWidth);
|
|
3275
|
+
if (this.chartInstance) {
|
|
3276
|
+
// SI ACTIVAMSO EL REFRESH DA UN REBOTE AL REDIMENCIONAR
|
|
3277
|
+
this.chartInstance.refresh();
|
|
3278
|
+
}
|
|
3279
|
+
}
|
|
3280
|
+
}
|
|
3281
|
+
});
|
|
3130
3282
|
});
|
|
3283
|
+
this._resizeObserver.observe(hostEl);
|
|
3131
3284
|
}
|
|
3132
|
-
|
|
3133
|
-
if (this.
|
|
3134
|
-
this.
|
|
3135
|
-
|
|
3136
|
-
this.
|
|
3137
|
-
|
|
3285
|
+
_updateAdaptiveLabelSize(width) {
|
|
3286
|
+
if (this.config?.labelSize) {
|
|
3287
|
+
const parsedSize = typeof this.config.labelSize === 'number'
|
|
3288
|
+
? this.config.labelSize
|
|
3289
|
+
: parseFloat(this.config.labelSize);
|
|
3290
|
+
if (!isNaN(parsedSize)) {
|
|
3291
|
+
if (width < 260) {
|
|
3292
|
+
const scale = Math.max(0.65, width / 260);
|
|
3293
|
+
this.currentLabelSize = `${Math.round(parsedSize * scale)}px`;
|
|
3294
|
+
}
|
|
3295
|
+
else {
|
|
3296
|
+
this.currentLabelSize = `${parsedSize}px`;
|
|
3297
|
+
}
|
|
3298
|
+
this.cdr.markForCheck();
|
|
3299
|
+
return;
|
|
3300
|
+
}
|
|
3138
3301
|
}
|
|
3302
|
+
// Proporción estándar ideal (~7.5% del ancho del contenedor, acotado entre 13px y 26px)
|
|
3303
|
+
const base = Math.max(13, Math.min(26, Math.round(width * 0.075)));
|
|
3304
|
+
this.currentLabelSize = `${base}px`;
|
|
3305
|
+
this.cdr.markForCheck();
|
|
3139
3306
|
}
|
|
3140
|
-
|
|
3141
|
-
this.
|
|
3142
|
-
this.selectionChange.emit([]);
|
|
3307
|
+
refresh() {
|
|
3308
|
+
this.updateParsedData();
|
|
3143
3309
|
}
|
|
3144
|
-
//
|
|
3145
|
-
|
|
3146
|
-
|
|
3147
|
-
|
|
3148
|
-
|
|
3149
|
-
|
|
3310
|
+
// pointRender(args: any) {
|
|
3311
|
+
// if (args.point?.y === 0) {
|
|
3312
|
+
// args.fill = this.emptyPointSettings.fill;
|
|
3313
|
+
// args.border = {
|
|
3314
|
+
// width: this.emptyPointSettings.border?.width ?? 0,
|
|
3315
|
+
// color: this.emptyPointSettings.border?.color ?? ''
|
|
3316
|
+
// };
|
|
3317
|
+
// }
|
|
3318
|
+
// }
|
|
3319
|
+
axisLabelRender(args) {
|
|
3320
|
+
const umbralWidget = 700;
|
|
3321
|
+
if (this.currentWidgetWidth > umbralWidget) {
|
|
3322
|
+
return;
|
|
3323
|
+
}
|
|
3324
|
+
// Si la tarjeta es estrecha, aplicamos el recorte de etiquetas
|
|
3325
|
+
if (args.text && typeof args.text === 'string') {
|
|
3326
|
+
const palabras = args.text.split(' ');
|
|
3327
|
+
if (palabras.length > 1) {
|
|
3328
|
+
const primeraPalabra = palabras[0];
|
|
3329
|
+
const inicialSegunda = palabras[1].charAt(0).toUpperCase();
|
|
3330
|
+
args.text = `${primeraPalabra} ${inicialSegunda}.`;
|
|
3150
3331
|
}
|
|
3151
3332
|
else {
|
|
3152
|
-
|
|
3333
|
+
if (args.text.length > 10) {
|
|
3334
|
+
args.text = args.text.substring(0, 9) + '.';
|
|
3335
|
+
}
|
|
3153
3336
|
}
|
|
3154
3337
|
}
|
|
3155
|
-
else {
|
|
3156
|
-
// Si es selección única
|
|
3157
|
-
current.clear();
|
|
3158
|
-
current.add(id);
|
|
3159
|
-
}
|
|
3160
|
-
this.selectedIds.set(current);
|
|
3161
|
-
}
|
|
3162
|
-
isSelected(id) {
|
|
3163
|
-
return this.selectedIds().has(id);
|
|
3164
3338
|
}
|
|
3165
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.30", ngImport: i0, type:
|
|
3166
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.30", type:
|
|
3339
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.30", ngImport: i0, type: BubbleChartSyncfusionComponent, deps: [{ token: i0.ElementRef }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component }); }
|
|
3340
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.30", type: BubbleChartSyncfusionComponent, isStandalone: true, selector: "yw-bubble-chart-syncfusion", inputs: { chartData: "chartData", config: "config", idComponent: "idComponent" }, providers: [BubbleSeriesService, CategoryService, CategoryService,
|
|
3341
|
+
TooltipService,
|
|
3342
|
+
LegendService,
|
|
3343
|
+
DateTimeService, DataLabelService], viewQueries: [{ propertyName: "chartInstance", first: true, predicate: ["chart"], descendants: true }], usesOnChanges: true, ngImport: i0, template: "<div class=\"control-section\">\r\n <ejs-chart \r\n #chart \r\n [primaryXAxis]=\"labelData.axisX\" \r\n [primaryYAxis]=\"labelData.axisY\" \r\n [title]=\"labelData.title\" \r\n [palettes]=\"labelData.palettes\"\r\n [chartArea]=\"labelData.chartArea\"\r\n [titleStyle]=\"labelData.titleStyle\"\r\n\r\n (pointRender)=\"pointRender($event)\" \r\n height=\"100%\"\r\n width=\"100%\"\r\n [legendSettings]=\"labelData.legendSettings\"\r\n (axisLabelRender)=\"axisLabelRender($event)\"\r\n\r\n [tooltip]=\"labelData.tooltip\">\r\n <e-series-collection>\r\n @for(series of dataChartParse; track $index){\r\n <e-series \r\n [opacity]=\"series.opacity\"\r\n [dataSource]='series.dataSource' \r\n type='Bubble' \r\n xName='x' \r\n yName='y' \r\n size='size'\r\n [name]='series.name' \r\n\r\n [marker]=\"labelData.marker\"\r\n \r\n >\r\n <!-- [dataLabel]='series.dataLabel' -->\r\n </e-series>\r\n\r\n }\r\n </e-series-collection>\r\n</ejs-chart>\r\n</div>", styles: ["@charset \"UTF-8\";:host{display:flex;flex-direction:column;width:100%;height:100%;min-height:260px;box-sizing:border-box;overflow:hidden}.control-section{display:flex;flex-direction:column;width:100%;height:100%;min-height:260px;box-sizing:border-box;overflow:hidden;background:#fff;border-radius:8px}:host ::ng-deep ejs-circulargauge{display:block;width:100%!important;height:100%!important;flex-grow:1}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: ChartModule }, { kind: "component", type: i1.ChartComponent, selector: "ejs-chart", inputs: ["accessibility", "allowExport", "allowMultiSelection", "annotations", "axes", "background", "backgroundImage", "border", "chartArea", "columns", "crosshair", "currencyCode", "dataSource", "description", "enableAnimation", "enableAutoIntervalOnBothAxis", "enableCanvas", "enableExport", "enableHtmlSanitizer", "enablePersistence", "enableRtl", "enableSideBySidePlacement", "focusBorderColor", "focusBorderMargin", "focusBorderWidth", "height", "highlightColor", "highlightMode", "highlightPattern", "indicators", "isMultiSelect", "isTransposed", "legendSettings", "locale", "margin", "palettes", "primaryXAxis", "primaryYAxis", "rangeColorSettings", "rows", "selectedDataIndexes", "selectionMode", "selectionPattern", "series", "subTitle", "subTitleStyle", "tabIndex", "theme", "title", "titleStyle", "tooltip", "useGroupingSeparator", "width", "zoomSettings"], outputs: ["afterExport", "animationComplete", "annotationRender", "axisLabelClick", "axisLabelRender", "axisMultiLabelRender", "axisRangeCalculated", "beforeExport", "beforePrint", "beforeResize", "chartDoubleClick", "chartMouseClick", "chartMouseDown", "chartMouseLeave", "chartMouseMove", "chartMouseUp", "drag", "dragComplete", "dragEnd", "dragStart", "legendClick", "legendRender", "load", "loaded", "multiLevelLabelClick", "onZooming", "pointClick", "pointDoubleClick", "pointMove", "pointRender", "resized", "scrollChanged", "scrollEnd", "scrollStart", "selectionComplete", "seriesRender", "sharedTooltipRender", "textRender", "tooltipRender", "zoomComplete", "dataSourceChange"] }, { kind: "directive", type: i1.SeriesDirective, selector: "e-series-collection>e-series", inputs: ["accessibility", "animation", "bearFillColor", "binInterval", "border", "boxPlotMode", "bullFillColor", "cardinalSplineTension", "close", "colorName", "columnFacet", "columnSpacing", "columnWidth", "columnWidthInPixel", "connector", "cornerRadius", "dashArray", "dataSource", "dragSettings", "drawType", "emptyPointSettings", "enableComplexProperty", "enableSolidCandles", "enableTooltip", "errorBar", "fill", "groupName", "high", "intermediateSumIndexes", "isClosed", "legendImageUrl", "legendShape", "low", "marker", "maxRadius", "minRadius", "name", "negativeFillColor", "noRisers", "nonHighlightStyle", "opacity", "open", "paretoOptions", "pointColorMapping", "query", "segmentAxis", "segments", "selectionStyle", "showMean", "showNormalDistribution", "size", "splineType", "stackingGroup", "step", "sumIndexes", "summaryFillColor", "tooltipFormat", "tooltipMappingName", "trendlines", "type", "unSelectedStyle", "visible", "volume", "width", "xAxisName", "xName", "yAxisName", "yName", "zOrder"] }, { kind: "directive", type: i1.SeriesCollectionDirective, selector: "ej-chart>e-series-collection" }] }); }
|
|
3167
3344
|
}
|
|
3168
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.30", ngImport: i0, type:
|
|
3345
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.30", ngImport: i0, type: BubbleChartSyncfusionComponent, decorators: [{
|
|
3169
3346
|
type: Component,
|
|
3170
|
-
args: [{ selector: 'yw-
|
|
3171
|
-
|
|
3172
|
-
|
|
3173
|
-
|
|
3174
|
-
|
|
3175
|
-
|
|
3347
|
+
args: [{ selector: 'yw-bubble-chart-syncfusion', standalone: true, imports: [CommonModule, ChartModule], providers: [BubbleSeriesService, CategoryService, CategoryService,
|
|
3348
|
+
TooltipService,
|
|
3349
|
+
LegendService,
|
|
3350
|
+
DateTimeService, DataLabelService], template: "<div class=\"control-section\">\r\n <ejs-chart \r\n #chart \r\n [primaryXAxis]=\"labelData.axisX\" \r\n [primaryYAxis]=\"labelData.axisY\" \r\n [title]=\"labelData.title\" \r\n [palettes]=\"labelData.palettes\"\r\n [chartArea]=\"labelData.chartArea\"\r\n [titleStyle]=\"labelData.titleStyle\"\r\n\r\n (pointRender)=\"pointRender($event)\" \r\n height=\"100%\"\r\n width=\"100%\"\r\n [legendSettings]=\"labelData.legendSettings\"\r\n (axisLabelRender)=\"axisLabelRender($event)\"\r\n\r\n [tooltip]=\"labelData.tooltip\">\r\n <e-series-collection>\r\n @for(series of dataChartParse; track $index){\r\n <e-series \r\n [opacity]=\"series.opacity\"\r\n [dataSource]='series.dataSource' \r\n type='Bubble' \r\n xName='x' \r\n yName='y' \r\n size='size'\r\n [name]='series.name' \r\n\r\n [marker]=\"labelData.marker\"\r\n \r\n >\r\n <!-- [dataLabel]='series.dataLabel' -->\r\n </e-series>\r\n\r\n }\r\n </e-series-collection>\r\n</ejs-chart>\r\n</div>", styles: ["@charset \"UTF-8\";:host{display:flex;flex-direction:column;width:100%;height:100%;min-height:260px;box-sizing:border-box;overflow:hidden}.control-section{display:flex;flex-direction:column;width:100%;height:100%;min-height:260px;box-sizing:border-box;overflow:hidden;background:#fff;border-radius:8px}:host ::ng-deep ejs-circulargauge{display:block;width:100%!important;height:100%!important;flex-grow:1}\n"] }]
|
|
3351
|
+
}], ctorParameters: () => [{ type: i0.ElementRef }, { type: i0.ChangeDetectorRef }], propDecorators: { chartInstance: [{
|
|
3352
|
+
type: ViewChild,
|
|
3353
|
+
args: ['chart']
|
|
3354
|
+
}], chartData: [{
|
|
3355
|
+
type: Input,
|
|
3356
|
+
args: ['chartData']
|
|
3357
|
+
}], config: [{
|
|
3358
|
+
type: Input,
|
|
3359
|
+
args: ['config']
|
|
3360
|
+
}], idComponent: [{
|
|
3361
|
+
type: Input,
|
|
3362
|
+
args: ['idComponent']
|
|
3363
|
+
}] } });
|
|
3176
3364
|
|
|
3177
|
-
|
|
3365
|
+
// import { LineChartSyncfusionComponent } from '../../../../../adapters/charts/line-chart/syncfusion/visual/yw-line-chart-syncfusion.component';
|
|
3366
|
+
// import { YwLineMappingConfig } from '../../../../../models/config/chart/yw-line-chart-config.interface';
|
|
3367
|
+
class BubbleChartComponent {
|
|
3178
3368
|
constructor() {
|
|
3179
|
-
// Entradas generales
|
|
3180
3369
|
this.idComponent = '';
|
|
3181
|
-
this.label = input('Filtro Jerárquico', ...(ngDevMode ? [{ debugName: "label" }] : []));
|
|
3182
|
-
this.clearTitleLabel = input('Limpiar Seleccion', ...(ngDevMode ? [{ debugName: "clearTitleLabel" }] : []));
|
|
3183
|
-
// Opción 1: Entregar datos en árbol de texto directo
|
|
3184
|
-
this.rawData = input([], ...(ngDevMode ? [{ debugName: "rawData" }] : []));
|
|
3185
|
-
// Opción 2: Generar desde fechas
|
|
3186
|
-
this.dataType = input('date', ...(ngDevMode ? [{ debugName: "dataType" }] : []));
|
|
3187
|
-
this.minDate = input('', ...(ngDevMode ? [{ debugName: "minDate" }] : [])); // Formato 'YYYY-MM-DD'
|
|
3188
|
-
this.maxDate = input('', ...(ngDevMode ? [{ debugName: "maxDate" }] : []));
|
|
3189
|
-
this.dateHierarchyType = input('YEAR_TRIMESTER_MONTH', ...(ngDevMode ? [{ debugName: "dateHierarchyType" }] : []));
|
|
3190
|
-
this.monthNames = input(['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'], ...(ngDevMode ? [{ debugName: "monthNames" }] : []));
|
|
3191
|
-
// Evento de salida con el ID/Nodo seleccionado
|
|
3192
|
-
this.selectionChange = output();
|
|
3193
|
-
this.filterValueChange = output(); // Output 2 (Rangos o Hojas)
|
|
3194
|
-
// ID del elemento seleccionado (Selección Simple)
|
|
3195
|
-
this.selectedId = signal(null, ...(ngDevMode ? [{ debugName: "selectedId" }] : []));
|
|
3196
|
-
this.currentSelectedId = input(null, ...(ngDevMode ? [{ debugName: "currentSelectedId" }] : []));
|
|
3197
|
-
// Arbol de nodos computado
|
|
3198
|
-
this.treeNodes = computed(() => {
|
|
3199
|
-
if (this.dataType() == 'date' && this.minDate() && this.maxDate()) {
|
|
3200
|
-
return this.generateDateHierarchy(this.minDate(), this.maxDate(), this.dateHierarchyType());
|
|
3201
|
-
}
|
|
3202
|
-
return this.rawData();
|
|
3203
|
-
}, ...(ngDevMode ? [{ debugName: "treeNodes" }] : []));
|
|
3204
|
-
effect(() => {
|
|
3205
|
-
const currentId = this.selectedId();
|
|
3206
|
-
if (!currentId) {
|
|
3207
|
-
this.selectionChange.emit(null);
|
|
3208
|
-
this.filterValueChange.emit(null);
|
|
3209
|
-
return;
|
|
3210
|
-
}
|
|
3211
|
-
const node = this.findNodeById(this.treeNodes(), currentId);
|
|
3212
|
-
this.selectionChange.emit(node);
|
|
3213
|
-
if (node) {
|
|
3214
|
-
// Emitir el segundo Output según el modo
|
|
3215
|
-
const calculatedValue = this.processFilterOutput(node);
|
|
3216
|
-
this.filterValueChange.emit(calculatedValue);
|
|
3217
|
-
}
|
|
3218
|
-
});
|
|
3219
3370
|
}
|
|
3220
3371
|
ngOnInit() {
|
|
3221
|
-
|
|
3222
|
-
this.selectedId.set(this.currentSelectedId());
|
|
3223
|
-
}
|
|
3224
|
-
}
|
|
3225
|
-
// Métodos de Selección y Expansión
|
|
3226
|
-
toggleExpand(node, event) {
|
|
3227
|
-
event.stopPropagation();
|
|
3228
|
-
node.expanded = !node.expanded;
|
|
3229
|
-
}
|
|
3230
|
-
selectNode(node, event) {
|
|
3231
|
-
event.stopPropagation();
|
|
3232
|
-
this.selectedId.set(this.selectedId() === node.id ? null : node.id);
|
|
3372
|
+
console.log("EL ID DEL COMPONENTE:", this.idComponent);
|
|
3233
3373
|
}
|
|
3234
|
-
|
|
3235
|
-
|
|
3236
|
-
|
|
3374
|
+
ngOnChanges(changes) {
|
|
3375
|
+
if (changes['chartData']) {
|
|
3376
|
+
console.log('change chartDataBubble:', changes['chartData'].currentValue);
|
|
3377
|
+
}
|
|
3378
|
+
if (changes['config']) {
|
|
3379
|
+
console.log('change configBubble:', changes['config'].currentValue);
|
|
3380
|
+
}
|
|
3237
3381
|
}
|
|
3238
|
-
|
|
3239
|
-
|
|
3240
|
-
// 1. Obtener todas las hojas (nodos del nivel más bajo) pertenecientes al bloque seleccionado
|
|
3241
|
-
const leaves = this.getLeafNodes(selectedNode);
|
|
3242
|
-
if (this.dataType() == 'date') {
|
|
3243
|
-
// Extraer todas las fechas de las hojas del bloque
|
|
3244
|
-
const dates = leaves
|
|
3245
|
-
.map(leaf => leaf.value)
|
|
3246
|
-
.filter(d => d instanceof Date)
|
|
3247
|
-
.sort((a, b) => a.getTime() - b.getTime());
|
|
3248
|
-
if (dates.length > 0) {
|
|
3249
|
-
const minD = dates[0];
|
|
3250
|
-
// Para la fecha máxima, tomamos el último día del mes correspondiente
|
|
3251
|
-
const maxD = new Date(dates[dates.length - 1].getFullYear(), dates[dates.length - 1].getMonth() + 1, 0);
|
|
3252
|
-
return {
|
|
3253
|
-
type: 'DATE_RANGE',
|
|
3254
|
-
dateRange: {
|
|
3255
|
-
minDate: minD.toISOString().split('T')[0],
|
|
3256
|
-
maxDate: maxD.toISOString().split('T')[0]
|
|
3257
|
-
},
|
|
3258
|
-
currentNodeId: selectedNode.id
|
|
3259
|
-
};
|
|
3260
|
-
}
|
|
3261
|
-
}
|
|
3262
|
-
// Modo Texto: Entregar arreglo con las hojas
|
|
3263
|
-
return {
|
|
3264
|
-
type: 'TEXT_LEAVES',
|
|
3265
|
-
leafNodes: leaves,
|
|
3266
|
-
leafIds: leaves.map(l => l.id),
|
|
3267
|
-
currentNodeId: selectedNode.id
|
|
3268
|
-
};
|
|
3269
|
-
}
|
|
3270
|
-
// Recorrido recursivo para obtener solo los nodos terminales (sin hijos)
|
|
3271
|
-
getLeafNodes(node) {
|
|
3272
|
-
if (!node.children || node.children.length === 0) {
|
|
3273
|
-
return [node];
|
|
3274
|
-
}
|
|
3275
|
-
let leaves = [];
|
|
3276
|
-
for (const child of node.children) {
|
|
3277
|
-
leaves = leaves.concat(this.getLeafNodes(child));
|
|
3278
|
-
}
|
|
3279
|
-
return leaves;
|
|
3280
|
-
}
|
|
3281
|
-
findNodeById(nodes, id) {
|
|
3282
|
-
for (const node of nodes) {
|
|
3283
|
-
if (node.id === id)
|
|
3284
|
-
return node;
|
|
3285
|
-
if (node.children) {
|
|
3286
|
-
const found = this.findNodeById(node.children, id);
|
|
3287
|
-
if (found)
|
|
3288
|
-
return found;
|
|
3289
|
-
}
|
|
3290
|
-
}
|
|
3291
|
-
return null;
|
|
3292
|
-
}
|
|
3293
|
-
// Generador de Jerarquía por Fechas
|
|
3294
|
-
generateDateHierarchy(startStr, endStr, type) {
|
|
3295
|
-
const start = new Date(startStr);
|
|
3296
|
-
const end = new Date(endStr);
|
|
3297
|
-
const tree = [];
|
|
3298
|
-
const monthNames = this.monthNames();
|
|
3299
|
-
if (type === 'YEAR_TRIMESTER_MONTH') {
|
|
3300
|
-
let current = new Date(start);
|
|
3301
|
-
while (current <= end) {
|
|
3302
|
-
const year = current.getFullYear();
|
|
3303
|
-
let yearNode = tree.find(n => n.id === `Y_${year}`);
|
|
3304
|
-
if (!yearNode) {
|
|
3305
|
-
yearNode = { id: `Y_${year}`, label: `${year}`, children: [], expanded: false };
|
|
3306
|
-
tree.push(yearNode);
|
|
3307
|
-
}
|
|
3308
|
-
const month = current.getMonth();
|
|
3309
|
-
const qtrNum = Math.floor(month / 3) + 1;
|
|
3310
|
-
let qtrNode = yearNode.children.find(n => n.id === `Q_${year}_${qtrNum}`);
|
|
3311
|
-
if (!qtrNode) {
|
|
3312
|
-
qtrNode = { id: `Q_${year}_${qtrNum}`, label: `Qtr ${qtrNum}`, children: [], expanded: false };
|
|
3313
|
-
yearNode.children.push(qtrNode);
|
|
3314
|
-
}
|
|
3315
|
-
const monthId = `M_${year}_${month + 1}`;
|
|
3316
|
-
if (!qtrNode.children.some(n => n.id === monthId)) {
|
|
3317
|
-
qtrNode.children.push({
|
|
3318
|
-
id: monthId,
|
|
3319
|
-
label: monthNames[month],
|
|
3320
|
-
value: new Date(year, month, 1) // Fecha inicial del mes
|
|
3321
|
-
});
|
|
3322
|
-
}
|
|
3323
|
-
current.setMonth(current.getMonth() + 1);
|
|
3324
|
-
}
|
|
3325
|
-
}
|
|
3326
|
-
if (type === 'YEAR_SEMESTER_MONTH') {
|
|
3327
|
-
let current = new Date(start);
|
|
3328
|
-
while (current <= end) {
|
|
3329
|
-
const year = current.getFullYear();
|
|
3330
|
-
let yearNode = tree.find(n => n.id === `Y_${year}`);
|
|
3331
|
-
if (!yearNode) {
|
|
3332
|
-
yearNode = { id: `Y_${year}`, label: `${year}`, children: [], expanded: false };
|
|
3333
|
-
tree.push(yearNode);
|
|
3334
|
-
}
|
|
3335
|
-
const month = current.getMonth();
|
|
3336
|
-
const qtrNum = Math.floor(month / 6) + 1;
|
|
3337
|
-
let qtrNode = yearNode.children.find(n => n.id === `S_${year}_${qtrNum}`);
|
|
3338
|
-
if (!qtrNode) {
|
|
3339
|
-
qtrNode = { id: `S_${year}_${qtrNum}`, label: `S ${qtrNum}`, children: [], expanded: false };
|
|
3340
|
-
yearNode.children.push(qtrNode);
|
|
3341
|
-
}
|
|
3342
|
-
const monthId = `M_${year}_${month + 1}`;
|
|
3343
|
-
if (!qtrNode.children.some(n => n.id === monthId)) {
|
|
3344
|
-
qtrNode.children.push({
|
|
3345
|
-
id: monthId,
|
|
3346
|
-
label: monthNames[month],
|
|
3347
|
-
value: new Date(year, month, 1) // Fecha inicial del mes
|
|
3348
|
-
});
|
|
3349
|
-
}
|
|
3350
|
-
current.setMonth(current.getMonth() + 1);
|
|
3351
|
-
}
|
|
3352
|
-
}
|
|
3353
|
-
return tree;
|
|
3354
|
-
}
|
|
3355
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.30", ngImport: i0, type: YwListSlicerComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
3356
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.30", type: YwListSlicerComponent, isStandalone: true, selector: "yw-list-slicer", inputs: { idComponent: { classPropertyName: "idComponent", publicName: "idComponent", isSignal: false, isRequired: false, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, clearTitleLabel: { classPropertyName: "clearTitleLabel", publicName: "clearTitleLabel", isSignal: true, isRequired: false, transformFunction: null }, rawData: { classPropertyName: "rawData", publicName: "rawData", isSignal: true, isRequired: false, transformFunction: null }, dataType: { classPropertyName: "dataType", publicName: "dataType", isSignal: true, isRequired: false, transformFunction: null }, minDate: { classPropertyName: "minDate", publicName: "minDate", isSignal: true, isRequired: false, transformFunction: null }, maxDate: { classPropertyName: "maxDate", publicName: "maxDate", isSignal: true, isRequired: false, transformFunction: null }, dateHierarchyType: { classPropertyName: "dateHierarchyType", publicName: "dateHierarchyType", isSignal: true, isRequired: false, transformFunction: null }, monthNames: { classPropertyName: "monthNames", publicName: "monthNames", isSignal: true, isRequired: false, transformFunction: null }, currentSelectedId: { classPropertyName: "currentSelectedId", publicName: "currentSelectedId", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { selectionChange: "selectionChange", filterValueChange: "filterValueChange" }, host: { properties: { "attr.id": "idComponent" } }, ngImport: i0, template: "<div class=\"filter-container\">\r\n <!-- Cabecera con t\u00EDtulo y acciones de filtro -->\r\n <div class=\"filter-header\">\r\n <span class=\"filter-label\">{{ label() }}</span>\r\n <div class=\"header-actions\">\r\n <!--<button class=\"icon-btn\" title=\"Filtro\">\uD83D\uDD3B</button>-->\r\n <button class=\"icon-btn\" (click)=\"clearSelection()\" title=\"{{clearTitleLabel}}\">\uD83E\uDDF9</button>\r\n <!--<button class=\"icon-btn\" title=\"M\u00E1s opciones\">\u22EE</button>-->\r\n </div>\r\n </div>\r\n\r\n <!-- Vista en \u00C1rbol con scroll interno -->\r\n <div class=\"tree-scroll-container\">\r\n <ng-container *ngTemplateOutlet=\"nodeListTemplate; context: { $implicit: treeNodes(), level: 0 }\"></ng-container>\r\n </div>\r\n</div>\r\n\r\n<!-- Plantilla Recursiva para renderizar niveles del \u00C1rbol -->\r\n<ng-template #nodeListTemplate let-nodes let-level=\"level\">\r\n <div class=\"tree-level\">\r\n @for (node of nodes; track node.id) {\r\n <div class=\"tree-node-wrapper\">\r\n <!-- Fila de opci\u00F3n -->\r\n <div \r\n class=\"tree-node-row\" \r\n [class.selected]=\"selectedId() === node.id\"\r\n [style.padding-left.px]=\"level * 18 + 6\"\r\n (click)=\"selectNode(node, $event)\">\r\n \r\n <!-- Flecha expandir/colapsar (si tiene hijos) -->\r\n @if (node.children && node.children.length > 0) {\r\n <span class=\"chevron-icon\" (click)=\"toggleExpand(node, $event)\">\r\n {{ node.expanded ? '\uD83D\uDF83' : '\uD83D\uDF82' }}\r\n </span>\r\n } @else {\r\n <span class=\"chevron-spacer\"></span>\r\n }\r\n\r\n <!-- Radio Button (Selecci\u00F3n simple) -->\r\n <div class=\"radio-circle\" [class.checked]=\"selectedId() === node.id\">\r\n <div class=\"radio-inner\"></div>\r\n </div>\r\n\r\n <!-- Etiqueta del Nodo -->\r\n <span class=\"node-label\">{{ node.label }}</span>\r\n </div>\r\n\r\n <!-- Renderizado de hijos si est\u00E1 expandido -->\r\n @if (node.children && node.children.length > 0 && node.expanded) {\r\n <ng-container *ngTemplateOutlet=\"nodeListTemplate; context: { $implicit: node.children, level: level + 1 }\"></ng-container>\r\n }\r\n </div>\r\n }\r\n </div>\r\n</ng-template>", styles: ["@charset \"UTF-8\";:host{display:block;font-family:Segoe UI,Tahoma,Geneva,Verdana,sans-serif;width:100%;max-width:320px;background:#fff}.filter-container{display:flex;flex-direction:column;border:1px solid #e0e0e0;border-radius:4px;background-color:#fff}.filter-header{display:flex;align-items:center;justify-content:space-between;padding:6px 10px;border-bottom:1px solid #f0f0f0}.filter-label{font-size:13px;font-weight:600;color:#252423}.header-actions{display:flex;gap:4px}.icon-btn{background:none;border:none;cursor:pointer;font-size:12px;color:#605e5c;padding:2px 4px;border-radius:2px}.icon-btn:hover{background-color:#f3f2f1}.tree-scroll-container{max-height:220px;overflow-y:auto;padding:4px 0}.tree-level{display:flex;flex-direction:column}.tree-node-row{display:flex;align-items:center;height:28px;cursor:pointer;-webkit-user-select:none;user-select:none;gap:6px;transition:background-color .1s ease}.tree-node-row:hover{background-color:#f3f2f1}.tree-node-row.selected{background-color:#e1dfdd}.chevron-icon{display:inline-flex;align-items:center;justify-content:center;width:16px;height:16px;font-size:10px;color:#323130}.chevron-spacer{width:16px}.radio-circle{width:14px;height:14px;border-radius:50%;border:1.5px solid #605e5c;display:flex;align-items:center;justify-content:center;box-sizing:border-box;background-color:#fff}.radio-circle.checked{border-color:#0078d4}.radio-circle.checked .radio-inner{width:6px;height:6px;border-radius:50%;background-color:#0078d4}.node-label{font-size:13px;color:#323130;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.tree-scroll-container::-webkit-scrollbar{width:6px}.tree-scroll-container::-webkit-scrollbar-track{background:#f1f1f1}.tree-scroll-container::-webkit-scrollbar-thumb{background:#8a8886;border-radius:3px}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$2.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }] }); }
|
|
3382
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.30", ngImport: i0, type: BubbleChartComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
3383
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.30", type: BubbleChartComponent, isStandalone: true, selector: "yw-bubble-chart", inputs: { chartData: "chartData", config: "config", idComponent: "idComponent" }, usesOnChanges: true, ngImport: i0, template: "@if(config.provider==='syncfusion'){\r\n <div style=\"position: relative; width: 100%; height: 100%;\">\r\n <yw-bubble-chart-syncfusion \r\n [idComponent]=\"idComponent\"\r\n [chartData]=\"chartData\" \r\n [config]=\"config\" style=\"display: block; width: 100%; height: 100%;\">\r\n </yw-bubble-chart-syncfusion>\r\n</div>\r\n}", styles: [":host{display:block;width:100%;height:100%;min-height:260px;min-width:0;overflow:hidden}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "component", type: BubbleChartSyncfusionComponent, selector: "yw-bubble-chart-syncfusion", inputs: ["chartData", "config", "idComponent"] }] }); }
|
|
3357
3384
|
}
|
|
3358
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.30", ngImport: i0, type:
|
|
3385
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.30", ngImport: i0, type: BubbleChartComponent, decorators: [{
|
|
3359
3386
|
type: Component,
|
|
3360
|
-
args: [{ selector: 'yw-
|
|
3361
|
-
|
|
3362
|
-
|
|
3363
|
-
|
|
3364
|
-
|
|
3365
|
-
|
|
3387
|
+
args: [{ selector: 'yw-bubble-chart', standalone: true, imports: [CommonModule, BubbleChartSyncfusionComponent], template: "@if(config.provider==='syncfusion'){\r\n <div style=\"position: relative; width: 100%; height: 100%;\">\r\n <yw-bubble-chart-syncfusion \r\n [idComponent]=\"idComponent\"\r\n [chartData]=\"chartData\" \r\n [config]=\"config\" style=\"display: block; width: 100%; height: 100%;\">\r\n </yw-bubble-chart-syncfusion>\r\n</div>\r\n}", styles: [":host{display:block;width:100%;height:100%;min-height:260px;min-width:0;overflow:hidden}\n"] }]
|
|
3388
|
+
}], propDecorators: { chartData: [{
|
|
3389
|
+
type: Input,
|
|
3390
|
+
args: ['chartData']
|
|
3391
|
+
}], config: [{
|
|
3392
|
+
type: Input,
|
|
3393
|
+
args: ['config']
|
|
3394
|
+
}], idComponent: [{
|
|
3395
|
+
type: Input,
|
|
3396
|
+
args: ['idComponent']
|
|
3397
|
+
}] } });
|
|
3366
3398
|
|
|
3367
|
-
|
|
3399
|
+
/*BEGIN - COMPONENTES VALIDOS PARA WIDGET*/
|
|
3400
|
+
class YwDashboardWidgetComponent {
|
|
3368
3401
|
constructor() {
|
|
3369
3402
|
this.componentWidgetId = '';
|
|
3370
3403
|
this.typeComponent = '';
|
|
3371
3404
|
this.varShowConfigButtons = false;
|
|
3405
|
+
this.styleWidget = input(DEFAULT_WIDGET_STYLE, ...(ngDevMode ? [{ debugName: "styleWidget" }] : []));
|
|
3406
|
+
// Signal calculada que combina los valores recibidos con los valores por defecto
|
|
3407
|
+
this.instanceStyleWidget = computed(() => ({
|
|
3408
|
+
widgetBackgroundColor: this.styleWidget()?.widgetBackgroundColor ?? DEFAULT_WIDGET_STYLE.widgetBackgroundColor,
|
|
3409
|
+
widgetBorderColor: this.styleWidget()?.widgetBorderColor ?? DEFAULT_WIDGET_STYLE.widgetBorderColor
|
|
3410
|
+
}), ...(ngDevMode ? [{ debugName: "instanceStyleWidget" }] : []));
|
|
3372
3411
|
this.configWidget = {
|
|
3373
3412
|
widgetId: '',
|
|
3374
|
-
|
|
3413
|
+
title: '',
|
|
3375
3414
|
typeComponent: '',
|
|
3376
|
-
|
|
3415
|
+
showConfigButtons: false,
|
|
3416
|
+
widgetStyle: DEFAULT_WIDGET_STYLE,
|
|
3417
|
+
layoutConfig: { id: '', w: 0, h: 0, content: undefined },
|
|
3418
|
+
controlConfig: {},
|
|
3419
|
+
controlTables: []
|
|
3377
3420
|
};
|
|
3378
|
-
this.controlConfig =
|
|
3379
|
-
this.controlData =
|
|
3421
|
+
this.controlConfig = {};
|
|
3422
|
+
this.controlData = {};
|
|
3423
|
+
this.isLocked = model(false, ...(ngDevMode ? [{ debugName: "isLocked" }] : []));
|
|
3424
|
+
this.isMaximized = signal(false, ...(ngDevMode ? [{ debugName: "isMaximized" }] : []));
|
|
3380
3425
|
this.eventDeleteRequest = output();
|
|
3426
|
+
this.eventLockToggleRequest = output();
|
|
3427
|
+
this.eventMaximizeToggleRequest = output();
|
|
3381
3428
|
this.eventShowConfigFormRequest = output();
|
|
3382
|
-
this.selectionChange = output();
|
|
3383
|
-
effect(() => {
|
|
3384
|
-
const value_controlConfig = this.fnFormatConfigData();
|
|
3385
|
-
this.dataWidget = { idComponent: this.componentWidgetId,
|
|
3386
|
-
configWidget: this.configWidget,
|
|
3387
|
-
controlConfig: value_controlConfig
|
|
3388
|
-
};
|
|
3389
|
-
});
|
|
3390
3429
|
}
|
|
3391
3430
|
ngOnInit() {
|
|
3392
|
-
this.componentWidgetId = this.configWidget.widgetId;
|
|
3431
|
+
this.componentWidgetId = 'cmpnt-' + this.configWidget.widgetId;
|
|
3393
3432
|
this.typeComponent = this.configWidget.typeComponent;
|
|
3394
|
-
const value_controlConfig = this.fnFormatConfigData();
|
|
3395
3433
|
this.dataWidget = { idComponent: this.componentWidgetId,
|
|
3396
|
-
|
|
3397
|
-
|
|
3434
|
+
controlConfig: this.controlConfig,
|
|
3435
|
+
controlData: this.controlData
|
|
3398
3436
|
};
|
|
3437
|
+
// console.log('DATOS INICIALES INIT:');
|
|
3438
|
+
// console.log(this.dataWidget);
|
|
3399
3439
|
}
|
|
3400
|
-
|
|
3401
|
-
|
|
3402
|
-
|
|
3403
|
-
|
|
3404
|
-
|
|
3405
|
-
|
|
3406
|
-
|
|
3407
|
-
|
|
3408
|
-
const currentData = this.controlConfig();
|
|
3409
|
-
if (dataType == 'date') {
|
|
3410
|
-
const fieldName = this.controlConfig().filterField;
|
|
3411
|
-
const fechas = this.controlData.map((d) => new Date(d[fieldName]).getTime());
|
|
3412
|
-
const val_min = new Date(Math.min(...fechas)).toISOString().split("T")[0];
|
|
3413
|
-
const val_max = new Date(Math.max(...fechas)).toISOString().split("T")[0];
|
|
3414
|
-
responsedata = { dataType: dataType, min: val_min, max: val_max, minCurrent: currentData?.minCurrent, maxCurrent: currentData?.maxCurrent };
|
|
3415
|
-
}
|
|
3416
|
-
if (dataType == 'number') {
|
|
3417
|
-
const fieldName = this.controlConfig().filterField;
|
|
3418
|
-
const valStep = this.controlConfig().step;
|
|
3419
|
-
const DataNumbers = this.controlData.map((d) => d[fieldName]);
|
|
3420
|
-
const val_min = Math.min(...DataNumbers);
|
|
3421
|
-
const val_max = Math.max(...DataNumbers);
|
|
3422
|
-
responsedata = { dataType: dataType, min: val_min, max: val_max, step: valStep, minCurrent: currentData?.minCurrent, maxCurrent: currentData?.maxCurrent };
|
|
3423
|
-
}
|
|
3440
|
+
ngAfterViewInit() {
|
|
3441
|
+
this.varShowConfigButtons = this.configWidget.showConfigButtons || false;
|
|
3442
|
+
}
|
|
3443
|
+
ngOnChanges(changes) {
|
|
3444
|
+
if (changes['configWidget']) {
|
|
3445
|
+
//console.log('Nuevo valor configWidget:', this.configWidget);
|
|
3446
|
+
this.varShowConfigButtons = this.configWidget.showConfigButtons || false;
|
|
3447
|
+
;
|
|
3424
3448
|
}
|
|
3425
|
-
if (
|
|
3426
|
-
|
|
3427
|
-
const fieldNameId = this.controlConfig().filterFieldId;
|
|
3428
|
-
const val_allowMultiple = this.controlConfig().allowMultiple;
|
|
3429
|
-
const currentData = this.controlConfig();
|
|
3430
|
-
let listoptions = this.controlData.map((item) => { return { 'id': item[fieldNameId], 'label': item[fieldName] }; });
|
|
3431
|
-
const listoptionsunicos = [...new Map(listoptions.map(d => [d.id, d])).values()];
|
|
3432
|
-
responsedata = { options: listoptionsunicos, allowMultiple: val_allowMultiple, currentIds: currentData?.currentIds };
|
|
3449
|
+
if (changes['controlConfig']) {
|
|
3450
|
+
// console.log('Nuevo valor controlConfig:', this.controlConfig);
|
|
3433
3451
|
}
|
|
3434
|
-
if (
|
|
3435
|
-
|
|
3436
|
-
|
|
3437
|
-
|
|
3438
|
-
|
|
3439
|
-
|
|
3440
|
-
const fechas = this.controlData.map((d) => new Date(d[fieldName]).getTime());
|
|
3441
|
-
const val_min = new Date(Math.min(...fechas)).toISOString().split("T")[0];
|
|
3442
|
-
const val_max = new Date(Math.max(...fechas)).toISOString().split("T")[0];
|
|
3443
|
-
responsedata = { dataType: dataType, minDate: val_min, maxDate: val_max, dateHierarchyType: val_dateHierarchyType, currentSelectedId: currentData.currentSelectedId };
|
|
3444
|
-
}
|
|
3445
|
-
if (dataType == 'text') {
|
|
3446
|
-
const fieldName1 = this.controlConfig().filterField;
|
|
3447
|
-
const fieldName2 = this.controlConfig().filterFieldN2;
|
|
3448
|
-
const fieldName3 = this.controlConfig().filterFieldN3;
|
|
3449
|
-
let foundN2 = false;
|
|
3450
|
-
let foundN3 = false;
|
|
3451
|
-
let lsizeN2 = 0;
|
|
3452
|
-
let lsizeN3 = 0;
|
|
3453
|
-
let nodebase = { id: '', label: '' };
|
|
3454
|
-
let nodeN2 = { id: '', label: '' };
|
|
3455
|
-
let nodeN3 = { id: '', label: '' };
|
|
3456
|
-
let listNivel1 = [];
|
|
3457
|
-
let listNivel2 = [];
|
|
3458
|
-
let listNivel3 = [];
|
|
3459
|
-
this.controlData.forEach((item) => {
|
|
3460
|
-
nodebase = { id: item[fieldName1], label: item[fieldName1] };
|
|
3461
|
-
//NIVEL 2
|
|
3462
|
-
if (fieldName2) {
|
|
3463
|
-
foundN2 = false;
|
|
3464
|
-
lsizeN2 = Object.keys(listNivel2).length;
|
|
3465
|
-
for (let i = 0; i < lsizeN2; i++) {
|
|
3466
|
-
const itemN2 = listNivel2[i];
|
|
3467
|
-
if (itemN2.id == item[fieldName2]) {
|
|
3468
|
-
itemN2.children.push(nodebase);
|
|
3469
|
-
nodeN2 = itemN2;
|
|
3470
|
-
foundN2 = true;
|
|
3471
|
-
break;
|
|
3472
|
-
}
|
|
3473
|
-
}
|
|
3474
|
-
;
|
|
3475
|
-
if (foundN2 == false) {
|
|
3476
|
-
nodeN2 = { id: item[fieldName2], label: item[fieldName2], expanded: true, children: [nodebase] };
|
|
3477
|
-
if (fieldName3) {
|
|
3478
|
-
nodeN2.parentId = item[fieldName3];
|
|
3479
|
-
}
|
|
3480
|
-
listNivel2.push(nodeN2);
|
|
3481
|
-
}
|
|
3482
|
-
}
|
|
3483
|
-
else {
|
|
3484
|
-
listNivel1.push(nodebase);
|
|
3485
|
-
}
|
|
3486
|
-
});
|
|
3487
|
-
//NIVEL 1 - Basico no hay Jerarquia
|
|
3488
|
-
responsedata = { dataType: dataType, rawData: listNivel1, currentSelectedId: currentData.currentSelectedId };
|
|
3489
|
-
//NIVEL 2 - Jerarquia de 2 niveles
|
|
3490
|
-
if (fieldName2) {
|
|
3491
|
-
responsedata = { dataType: dataType, rawData: listNivel2, currentSelectedId: currentData.currentSelectedId };
|
|
3492
|
-
}
|
|
3493
|
-
//NIVEL 3 - Jerarquia de 3 niveles
|
|
3494
|
-
if (fieldName3) {
|
|
3495
|
-
listNivel2.forEach((item) => {
|
|
3496
|
-
nodebase = item;
|
|
3497
|
-
foundN3 = false;
|
|
3498
|
-
lsizeN3 = Object.keys(listNivel3).length;
|
|
3499
|
-
for (let i = 0; i < lsizeN3; i++) {
|
|
3500
|
-
const itemN3 = listNivel3[i];
|
|
3501
|
-
if (itemN3.id == item.parentId) {
|
|
3502
|
-
itemN3.children.push(nodebase);
|
|
3503
|
-
foundN3 = true;
|
|
3504
|
-
break;
|
|
3505
|
-
}
|
|
3506
|
-
}
|
|
3507
|
-
;
|
|
3508
|
-
if (foundN3 == false) {
|
|
3509
|
-
nodeN3 = { id: item[fieldName3], label: item[fieldName3], expanded: true, children: [nodebase] };
|
|
3510
|
-
listNivel3.push(nodeN3);
|
|
3511
|
-
}
|
|
3512
|
-
});
|
|
3513
|
-
responsedata = { dataType: dataType, rawData: listNivel3, currentSelectedId: currentData.currentSelectedId };
|
|
3514
|
-
}
|
|
3515
|
-
}
|
|
3452
|
+
if (changes['controlData']) {
|
|
3453
|
+
//console.log('Nuevo valor controlData:', this.controlData);
|
|
3454
|
+
this.dataWidget = { idComponent: this.componentWidgetId,
|
|
3455
|
+
controlConfig: this.controlConfig,
|
|
3456
|
+
controlData: this.controlData
|
|
3457
|
+
};
|
|
3516
3458
|
}
|
|
3517
|
-
return responsedata;
|
|
3518
|
-
}
|
|
3519
|
-
//Filtro Slicer
|
|
3520
|
-
onFilterSlicerChange(range) {
|
|
3521
|
-
console.log('Filtro actualizado:', range);
|
|
3522
|
-
this.selectionChange.emit({ widgetId: this.componentWidgetId, eventResponse: range });
|
|
3523
|
-
}
|
|
3524
|
-
//Filtro Button
|
|
3525
|
-
onFilterButtonChange(selectedIds) {
|
|
3526
|
-
console.log('Tipos seleccionados:', selectedIds);
|
|
3527
|
-
this.selectionChange.emit({ widgetId: this.componentWidgetId, eventResponse: selectedIds });
|
|
3528
3459
|
}
|
|
3529
|
-
|
|
3530
|
-
|
|
3531
|
-
|
|
3532
|
-
|
|
3533
|
-
//this.selectionChange.emit({widgetId:this.componentWidgetId,eventResponse:selectedData});
|
|
3460
|
+
/* BEGIN - BARRA DE EVENTOS DEL WIDGET */
|
|
3461
|
+
//Eliminacion de Widget - Conectado al Dashboard
|
|
3462
|
+
onDeleteClick() {
|
|
3463
|
+
this.eventDeleteRequest.emit(this.configWidget.widgetId);
|
|
3534
3464
|
}
|
|
3535
|
-
|
|
3536
|
-
|
|
3537
|
-
|
|
3538
|
-
|
|
3539
|
-
|
|
3540
|
-
}
|
|
3541
|
-
if (data.type === 'DATE_RANGE') {
|
|
3542
|
-
//console.log('Rango a filtrar en SQL/Dashboard:', data.dateRange?.minDate, 'hasta', data.dateRange?.maxDate);
|
|
3543
|
-
this.selectionChange.emit({ widgetId: this.componentWidgetId, eventResponse: { minDate: data.dateRange?.minDate, maxDate: data.dateRange?.maxDate, currentNodeId: data.currentNodeId } });
|
|
3544
|
-
}
|
|
3545
|
-
else if (data.type === 'TEXT_LEAVES') {
|
|
3546
|
-
//console.log('Lista de elementos terminales seleccionados:', data.leafIds);
|
|
3547
|
-
this.selectionChange.emit({ widgetId: this.componentWidgetId, eventResponse: { ids: data.leafIds, currentNodeId: data.currentNodeId } });
|
|
3548
|
-
}
|
|
3465
|
+
onLockClick() {
|
|
3466
|
+
// Invertimos el estado local y notificamos al padre
|
|
3467
|
+
const nextState = !this.isLocked();
|
|
3468
|
+
this.isLocked.set(nextState);
|
|
3469
|
+
this.eventLockToggleRequest.emit({ widgetId: this.configWidget.widgetId, shouldLock: nextState });
|
|
3549
3470
|
}
|
|
3550
|
-
|
|
3471
|
+
onMaximizeClick() {
|
|
3472
|
+
const nextState = !this.isMaximized();
|
|
3473
|
+
this.isMaximized.set(nextState);
|
|
3474
|
+
this.eventMaximizeToggleRequest.emit({ widgetId: this.configWidget.widgetId, shouldMaximize: nextState });
|
|
3551
3475
|
}
|
|
3552
3476
|
onShowFormConfigClick() {
|
|
3477
|
+
this.eventShowConfigFormRequest.emit(this.configWidget.widgetId);
|
|
3553
3478
|
}
|
|
3554
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.30", ngImport: i0, type:
|
|
3555
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.30", type: YwDashboardFilterWidgetComponent, isStandalone: true, selector: "yw-dashboard-filter-widget", inputs: { configWidget: { classPropertyName: "configWidget", publicName: "configWidget", isSignal: false, isRequired: false, transformFunction: null }, controlConfig: { classPropertyName: "controlConfig", publicName: "controlConfig", isSignal: true, isRequired: false, transformFunction: null }, controlData: { classPropertyName: "controlData", publicName: "controlData", isSignal: false, isRequired: false, transformFunction: null } }, outputs: { eventDeleteRequest: "eventDeleteRequest", eventShowConfigFormRequest: "eventShowConfigFormRequest", selectionChange: "selectionChange" }, ngImport: i0, template: "\r\n<div class=\"widget-filter-action-bar\"> \r\n <button [hidden]=\"!varShowConfigButtons\" class=\"btn-delete\" (click)=\"onDeleteClick()\">\uD83D\uDDD1\uFE0F</button>\r\n <button [hidden]=\"!varShowConfigButtons\" class=\"btn-config\" (click)=\"onShowFormConfigClick()\">\u2699\uFE0F</button>\r\n</div>\r\n<div class=\"widget-filter-content-wrapper\">\r\n @if ( typeComponent == 'empty-visual' ) { \r\n <ng-container *ngTemplateOutlet=\"emptyvisual; context: { control: dataWidget }\"></ng-container>\r\n }\r\n @if ( typeComponent == 'filter-slicer' ) { \r\n <ng-container *ngTemplateOutlet=\"filterslicer; context: { control: dataWidget }\"></ng-container>\r\n }\r\n @if ( typeComponent == 'filter-button' ) { \r\n <ng-container *ngTemplateOutlet=\"filterbutton; context: { control: dataWidget }\"></ng-container>\r\n }\r\n @if ( typeComponent == 'filter-list' ) { \r\n <ng-container *ngTemplateOutlet=\"filterlist; context: { control: dataWidget }\"></ng-container>\r\n } \r\n \r\n</div>\r\n\r\n\r\n<!--------------------------------------------------------------->\r\n<!---------------------- EMPTY VISUAL TEMPLATE ---------------------->\r\n<!--------------------------------------------------------------->\r\n<ng-template #emptyvisual let-control = \"control\">\r\n <yw-empty-visual [idComponent]=\"control.idComponent\"\r\n [config]=\"control.controlConfig\" \r\n > \r\n </yw-empty-visual>\r\n</ng-template>\r\n\r\n<!--------------------------------------------------------------->\r\n<!---------------------- FILTER SLICER TEMPLATE ---------------------->\r\n<!--------------------------------------------------------------->\r\n<ng-template #filterslicer let-control = \"control\"> \r\n @if (control.controlConfig.dataType === 'date') { \r\n <yw-base-slicer [idComponent]=\"control.idComponent\"\r\n [dataType]=\"control.controlConfig.dataType\"\r\n [label]=\"control.configWidget.label\"\r\n [min]=\"control.controlConfig.min\"\r\n [max]=\"control.controlConfig.max\" \r\n [minCurrent]=\"control.controlConfig.minCurrent\"\r\n [maxCurrent]=\"control.controlConfig.maxCurrent\" \r\n (rangeChange)=\"onFilterSlicerChange($event)\"\r\n >\r\n </yw-base-slicer>\r\n }\r\n @if (control.controlConfig.dataType === 'number') { \r\n <yw-base-slicer [idComponent]=\"control.idComponent\"\r\n [dataType]=\"control.controlConfig.dataType\"\r\n [label]=\"control.configWidget.label\"\r\n [min]=\"control.controlConfig.min\"\r\n [max]=\"control.controlConfig.max\"\r\n [minCurrent]=\"control.controlConfig.minCurrent\"\r\n [maxCurrent]=\"control.controlConfig.maxCurrent\"\r\n [step]=\"control.controlConfig.step\"\r\n (rangeChange)=\"onFilterSlicerChange($event)\"\r\n >\r\n </yw-base-slicer>\r\n }\r\n</ng-template>\r\n\r\n<!--------------------------------------------------------------->\r\n<!---------------------- FILTER BUTTON TEMPLATE ---------------------->\r\n<!--------------------------------------------------------------->\r\n<ng-template #filterbutton let-control = \"control\"> \r\n <yw-button-slicer [idComponent]=\"control.idComponent\" \r\n [label]=\"control.configWidget.label\"\r\n [options]=\"control.controlConfig.options\"\r\n [allowMultiple]=\"control.controlConfig.allowMultiple\"\r\n [currentIds]=\"control.controlConfig.currentIds\"\r\n (selectionChange)=\"onFilterButtonChange($event)\" \r\n >\r\n </yw-button-slicer>\r\n</ng-template>\r\n\r\n\r\n<!--------------------------------------------------------------->\r\n<!---------------------- FILTER LIST TEMPLATE ---------------------->\r\n<!--------------------------------------------------------------->\r\n<ng-template #filterlist let-control = \"control\"> \r\n \r\n @if (control.controlConfig.dataType === 'date') { \r\n <yw-list-slicer [idComponent]=\"control.idComponent\" \r\n [label]=\"control.configWidget.label\"\r\n [dataType]=\"control.controlConfig.dataType\"\r\n [minDate]=\"control.controlConfig.minDate\"\r\n [maxDate]=\"control.controlConfig.maxDate\"\r\n [dateHierarchyType]=\"control.controlConfig.dateHierarchyType\"\r\n [currentSelectedId]=\"control.controlConfig.currentSelectedId\"\r\n (selectionChange)=\"onFilterListChange($event)\"\r\n (filterValueChange)=\"onFilterListCalculated($event)\" \r\n >\r\n </yw-list-slicer>\r\n }\r\n\r\n\r\n @if (control.controlConfig.dataType === 'text') { \r\n <yw-list-slicer [idComponent]=\"control.idComponent\"\r\n [label]=\"control.configWidget.label\"\r\n [dataType]=\"control.controlConfig.dataType\"\r\n [rawData]=\"control.controlConfig.rawData\"\r\n [currentSelectedId]=\"control.controlConfig.currentSelectedId\"\r\n (selectionChange)=\"onFilterListChange($event)\"\r\n (filterValueChange)=\"onFilterListCalculated($event)\" \r\n >\r\n </yw-list-slicer>\r\n }\r\n\r\n\r\n</ng-template>", styles: ["@charset \"UTF-8\";:host{display:flex;flex-direction:column;width:100%;box-sizing:border-box;background-color:var(--widget-bg, #ffffff);border:1px solid var(--widget-border-color, #040404);border-radius:var(--widget-border-radius, 8px);padding:var(--widget-padding, 10px)}:host *,:host *:before,:host *:after{box-sizing:border-box}.widget-filter-action-bar{display:flex;justify-content:flex-end;gap:4px;padding:5px 10px;flex-shrink:0;width:100%}.widget-filter-content-wrapper{width:100%;display:flex;flex-direction:column}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$2.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: YwEmptyVisualComponent, selector: "yw-empty-visual", inputs: ["idComponent", "config"] }, { kind: "component", type: YwBaseSlicerComponent, selector: "yw-base-slicer", inputs: ["idComponent", "dataType", "label", "min", "max", "step", "minCurrent", "maxCurrent"], outputs: ["rangeChange"] }, { kind: "component", type: YwButtonSlicerComponent, selector: "yw-button-slicer", inputs: ["idComponent", "label", "options", "allowMultiple", "currentIds"], outputs: ["selectionChange"] }, { kind: "component", type: YwListSlicerComponent, selector: "yw-list-slicer", inputs: ["idComponent", "label", "clearTitleLabel", "rawData", "dataType", "minDate", "maxDate", "dateHierarchyType", "monthNames", "currentSelectedId"], outputs: ["selectionChange", "filterValueChange"] }] }); }
|
|
3479
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.30", ngImport: i0, type: YwDashboardWidgetComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
3480
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.30", type: YwDashboardWidgetComponent, isStandalone: true, selector: "yw-dashboard-widget", inputs: { styleWidget: { classPropertyName: "styleWidget", publicName: "styleWidget", isSignal: true, isRequired: false, transformFunction: null }, configWidget: { classPropertyName: "configWidget", publicName: "configWidget", isSignal: false, isRequired: false, transformFunction: null }, controlConfig: { classPropertyName: "controlConfig", publicName: "controlConfig", isSignal: false, isRequired: false, transformFunction: null }, controlData: { classPropertyName: "controlData", publicName: "controlData", isSignal: false, isRequired: false, transformFunction: null }, isLocked: { classPropertyName: "isLocked", publicName: "isLocked", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { isLocked: "isLockedChange", eventDeleteRequest: "eventDeleteRequest", eventLockToggleRequest: "eventLockToggleRequest", eventMaximizeToggleRequest: "eventMaximizeToggleRequest", eventShowConfigFormRequest: "eventShowConfigFormRequest" }, host: { properties: { "style.--widget-bg": "instanceStyleWidget().widgetBackgroundColor", "style.--widget-border-color": "instanceStyleWidget().widgetBorderColor" } }, usesOnChanges: true, ngImport: i0, template: "\r\n<!-- <div class=\"widget-action-bar\"> \r\n <button [hidden]=\"!varShowConfigButtons\" class=\"btn-action\" (click)=\"onLockClick()\">{{ isLocked() ? '\uD83D\uDD12' : '\uD83D\uDD13' }}</button>\r\n <button class=\"btn-action\" (click)=\"onMaximizeClick()\">{{ isMaximized() ? '\uD83D\uDDD7' : '\uD83D\uDDD6' }}</button>\r\n <button [hidden]=\"!varShowConfigButtons\" class=\"btn-delete\" (click)=\"onDeleteClick()\">\uD83D\uDDD1\uFE0F</button>\r\n <button [hidden]=\"!varShowConfigButtons\" class=\"btn-config\" (click)=\"onShowFormConfigClick()\">\u2699\uFE0F</button>\r\n</div> -->\r\n\r\n<div class=\"widget-action-bar\">\r\n <!-- Bot\u00F3n Bloquear / Desbloquear -->\r\n <button [hidden]=\"!varShowConfigButtons\" class=\"btn-action\" (click)=\"onLockClick()\" [title]=\"isLocked() ? 'Desbloquear' : 'Bloquear'\">\r\n <svg *ngIf=\"isLocked(); else unlockedIcon\" width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><rect x=\"3\" y=\"11\" width=\"18\" height=\"11\" rx=\"2\" ry=\"2\"></rect><path d=\"M7 11V7a5 5 0 0 1 10 0v4\"></path></svg>\r\n <ng-template #unlockedIcon>\r\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><rect x=\"3\" y=\"11\" width=\"18\" height=\"11\" rx=\"2\" ry=\"2\"></rect><path d=\"M7 11V7a5 5 0 0 1 9.9-1\"></path></svg>\r\n </ng-template>\r\n </button>\r\n\r\n <!-- Bot\u00F3n Maximizar / Restaurar -->\r\n <button class=\"btn-action\" (click)=\"onMaximizeClick()\" [title]=\"isMaximized() ? 'Restaurar' : 'Maximizar'\">\r\n <svg *ngIf=\"isMaximized(); else maxIcon\" width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M8 3v3a2 2 0 0 1-2 2H3m18 0h-3a2 2 0 0 1-2-2V3m0 18v-3a2 2 0 0 1 2-2h3M3 16h3a2 2 0 0 1 2 2v3\"></path></svg>\r\n <ng-template #maxIcon>\r\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M15 3h6v6M9 21H3v-6M21 3l-7 7M3 21l7-7\"></path></svg>\r\n </ng-template>\r\n </button>\r\n\r\n <!-- Bot\u00F3n Eliminar -->\r\n <button [hidden]=\"!varShowConfigButtons\" class=\"btn-delete\" (click)=\"onDeleteClick()\" title=\"Eliminar\">\r\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><polyline points=\"3 6 5 6 21 6\"></polyline><path d=\"M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6m3 0V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2\"></path></svg>\r\n </button>\r\n\r\n <!-- Bot\u00F3n Configuraci\u00F3n -->\r\n <button [hidden]=\"!varShowConfigButtons\" class=\"btn-config\" (click)=\"onShowFormConfigClick()\" title=\"Configurar\">\r\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><circle cx=\"12\" cy=\"12\" r=\"3\"></circle><path d=\"M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 0 1 0 2.83 2 2 0 0 1-2.83 0l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 0 1-2 2 2 2 0 0 1-2-2v-.09A1.65 1.65 0 0 0 9 19.4a1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 0 1-2.83 0 2 2 0 0 1 0-2.83l.06-.06a1.65 1.65 0 0 0 .33-1.82 1.65 1.65 0 0 0-1.51-1H3a2 2 0 0 1-2-2 2 2 0 0 1 2-2h.09A1.65 1.65 0 0 0 4.6 9a1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 0 1 0-2.83 2 2 0 0 1 2.83 0l.06.06a1.65 1.65 0 0 0 1.82.33H9a1.65 1.65 0 0 0 1-1.51V3a2 2 0 0 1 2-2 2 2 0 0 1 2 2v.09a1.65 1.65 0 0 0 1 1.51 1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 0 1 2.83 0 2 2 0 0 1 0 2.83l-.06.06a1.65 1.65 0 0 0-.33 1.82V9a1.65 1.65 0 0 0 1.51 1H21a2 2 0 0 1 2 2 2 2 0 0 1-2 2h-.09a1.65 1.65 0 0 0-1.51 1z\"></path></svg>\r\n </button>\r\n</div>\r\n\r\n<div class=\"widget-content-wrapper\">\r\n @if ( typeComponent == 'dummy' ) {\r\n <ng-container *ngTemplateOutlet=\"testdummy; context: { control: dataWidget }\"></ng-container>\r\n }\r\n @if ( typeComponent == 'empty-visual' ) {\r\n <ng-container *ngTemplateOutlet=\"emptyvisual; context: { control: dataWidget }\"></ng-container>\r\n }\r\n @if ( typeComponent == 'chart-bar' ) {\r\n <ng-container *ngTemplateOutlet=\"chartbar; context: { control: dataWidget }\"></ng-container>\r\n }\r\n @if ( typeComponent == 'chart-line' ) {\r\n <ng-container *ngTemplateOutlet=\"chartline; context: { control: dataWidget }\"></ng-container>\r\n }\r\n @if ( typeComponent == 'chart-doughnut' ) {\r\n <ng-container *ngTemplateOutlet=\"chartdoughnut; context: { control: dataWidget }\"></ng-container>\r\n } \r\n @if ( typeComponent == 'chart-gauge' ) {\r\n <ng-container *ngTemplateOutlet=\"chartgauge; context: { control: dataWidget }\"></ng-container>\r\n } \r\n @if ( typeComponent == 'chart-bubble' ) {\r\n <ng-container *ngTemplateOutlet=\"chartbubble; context: { control: dataWidget }\"></ng-container>\r\n } \r\n \r\n \r\n</div>\r\n\r\n\r\n<!--------------------------------------------------------------->\r\n<!---------------------- DUMMY TEMPLATE ---------------------->\r\n<!--------------------------------------------------------------->\r\n<ng-template #testdummy let-control = \"control\">\r\n <lib-test-chart [idComponent]=\"control.idComponent\" > \r\n </lib-test-chart>\r\n</ng-template>\r\n<!--------------------------------------------------------------->\r\n<!---------------------- EMPTY VISUAL TEMPLATE ---------------------->\r\n<!--------------------------------------------------------------->\r\n<ng-template #emptyvisual let-control = \"control\">\r\n <yw-empty-visual [idComponent]=\"control.idComponent\"\r\n [config]=\"control.controlConfig\" \r\n > \r\n </yw-empty-visual>\r\n</ng-template>\r\n\r\n<!--------------------------------------------------------------->\r\n<!---------------------- BAR CHART TEMPLATE ---------------------->\r\n<!--------------------------------------------------------------->\r\n<ng-template #chartbar let-control = \"control\">\r\n <yw-bar-chart [idComponent]=\"control.idComponent\"\r\n [chartData]=\"control.controlData\"\r\n [config]=\"control.controlConfig\" \r\n >\r\n </yw-bar-chart>\r\n</ng-template>\r\n\r\n<!--------------------------------------------------------------->\r\n<!---------------------- LINE CHART TEMPLATE ---------------------->\r\n<!--------------------------------------------------------------->\r\n<ng-template #chartline let-control = \"control\">\r\n <yw-line-chart [idComponent]=\"control.idComponent\"\r\n [chartData]=\"control.controlData\"\r\n [config]=\"control.controlConfig\" \r\n >\r\n </yw-line-chart>\r\n</ng-template>\r\n\r\n\r\n<!--------------------------------------------------------------->\r\n<!---------------------- LINE DOUGHNUT TEMPLATE ---------------------->\r\n<!--------------------------------------------------------------->\r\n<ng-template #chartdoughnut let-control = \"control\">\r\n <yw-pie-chart [idComponent]=\"control.idComponent\"\r\n [chartData]=\"control.controlData\"\r\n [config]=\"control.controlConfig\" \r\n >\r\n </yw-pie-chart>\r\n</ng-template>\r\n\r\n \r\n<!--------------------------------------------------------------->\r\n<!---------------------- LINE GAUGE TEMPLATE ---------------------->\r\n<!--------------------------------------------------------------->\r\n<ng-template #chartgauge let-control = \"control\">\r\n <yw-gauge-chart [idComponent]=\"control.idComponent\"\r\n [chartData]=\"control.controlData\"\r\n [config]=\"control.controlConfig\" \r\n >\r\n </yw-gauge-chart>\r\n</ng-template>\r\n\r\n\r\n<!--------------------------------------------------------------->\r\n<!---------------------- BUBBLE TEMPLATE ---------------------->\r\n<!--------------------------------------------------------------->\r\n<ng-template #chartbubble let-control=\"control\">\r\n \r\n <yw-bubble-chart \r\n [idComponent]=\"control.idComponent\"\r\n [chartData]=\"control.controlData\"\r\n [config]=\"control.controlConfig\">\r\n </yw-bubble-chart>\r\n</ng-template> ", styles: ["@charset \"UTF-8\";:host{display:block;flex-direction:column;width:100%;overflow:hidden;box-sizing:border-box;background-color:var(--widget-bg, #ffffff);border:1px solid var(--widget-border-color, #007bff)}:host *,:host *:before,:host *:after{box-sizing:border-box}.widget-action-bar{display:flex;justify-content:flex-end;gap:4px;padding:5px 10px;flex-shrink:0;width:100%}.widget-content-wrapper{width:100%;flex-grow:1;height:0;display:flex;flex-direction:column}.widget-action-bar button,.widget-action-bar .btn-action,.widget-action-bar .btn-delete,.widget-action-bar .btn-config{background:transparent;border:1px solid #d9d9d9;border-radius:4px;cursor:pointer;width:26px;height:26px;display:inline-flex;align-items:center;justify-content:center;color:#595959;padding:0;transition:all .2s ease}.widget-action-bar button svg,.widget-action-bar .btn-action svg,.widget-action-bar .btn-delete svg,.widget-action-bar .btn-config svg{width:14px;height:14px}.widget-action-bar button:hover,.widget-action-bar .btn-action:hover,.widget-action-bar .btn-delete:hover,.widget-action-bar .btn-config:hover{background-color:#f5f5f5;color:#262626;border-color:#bfbfbf}.widget-action-bar button:active,.widget-action-bar .btn-action:active,.widget-action-bar .btn-delete:active,.widget-action-bar .btn-config:active{background-color:#e6e6e6}.widget-action-bar .btn-delete:hover{background-color:#fff1f0;color:#ff4d4f;border-color:#ffa39e}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1$2.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: TestChartComponent, selector: "lib-test-chart", inputs: ["idComponent"] }, { kind: "component", type: YwEmptyVisualComponent, selector: "yw-empty-visual", inputs: ["idComponent", "config"] }, { kind: "component", type: LineChartComponent, selector: "yw-line-chart", inputs: ["chartData", "config", "idComponent"] }, { kind: "component", type: BarChartComponent, selector: "yw-bar-chart", inputs: ["chartData", "config", "idComponent"] }, { kind: "component", type: PieChartComponent, selector: "yw-pie-chart", inputs: ["idComponent", "chartData", "config"] }, { kind: "component", type: GaugeChartComponent, selector: "yw-gauge-chart", inputs: ["idComponent", "chartData", "config"] }, { kind: "component", type: BubbleChartComponent, selector: "yw-bubble-chart", inputs: ["chartData", "config", "idComponent"] }] }); }
|
|
3556
3481
|
}
|
|
3557
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.30", ngImport: i0, type:
|
|
3482
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.30", ngImport: i0, type: YwDashboardWidgetComponent, decorators: [{
|
|
3558
3483
|
type: Component,
|
|
3559
|
-
args: [{ selector: 'yw-dashboard-
|
|
3484
|
+
args: [{ selector: 'yw-dashboard-widget', standalone: true, imports: [CommonModule,
|
|
3485
|
+
TestChartComponent,
|
|
3560
3486
|
YwEmptyVisualComponent,
|
|
3561
|
-
|
|
3562
|
-
|
|
3563
|
-
|
|
3564
|
-
|
|
3565
|
-
|
|
3487
|
+
LineChartComponent,
|
|
3488
|
+
BarChartComponent,
|
|
3489
|
+
PieChartComponent,
|
|
3490
|
+
GaugeChartComponent, BubbleChartComponent], host: {
|
|
3491
|
+
'[style.--widget-bg]': 'instanceStyleWidget().widgetBackgroundColor',
|
|
3492
|
+
'[style.--widget-border-color]': 'instanceStyleWidget().widgetBorderColor'
|
|
3493
|
+
}, template: "\r\n<!-- <div class=\"widget-action-bar\"> \r\n <button [hidden]=\"!varShowConfigButtons\" class=\"btn-action\" (click)=\"onLockClick()\">{{ isLocked() ? '\uD83D\uDD12' : '\uD83D\uDD13' }}</button>\r\n <button class=\"btn-action\" (click)=\"onMaximizeClick()\">{{ isMaximized() ? '\uD83D\uDDD7' : '\uD83D\uDDD6' }}</button>\r\n <button [hidden]=\"!varShowConfigButtons\" class=\"btn-delete\" (click)=\"onDeleteClick()\">\uD83D\uDDD1\uFE0F</button>\r\n <button [hidden]=\"!varShowConfigButtons\" class=\"btn-config\" (click)=\"onShowFormConfigClick()\">\u2699\uFE0F</button>\r\n</div> -->\r\n\r\n<div class=\"widget-action-bar\">\r\n <!-- Bot\u00F3n Bloquear / Desbloquear -->\r\n <button [hidden]=\"!varShowConfigButtons\" class=\"btn-action\" (click)=\"onLockClick()\" [title]=\"isLocked() ? 'Desbloquear' : 'Bloquear'\">\r\n <svg *ngIf=\"isLocked(); else unlockedIcon\" width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><rect x=\"3\" y=\"11\" width=\"18\" height=\"11\" rx=\"2\" ry=\"2\"></rect><path d=\"M7 11V7a5 5 0 0 1 10 0v4\"></path></svg>\r\n <ng-template #unlockedIcon>\r\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><rect x=\"3\" y=\"11\" width=\"18\" height=\"11\" rx=\"2\" ry=\"2\"></rect><path d=\"M7 11V7a5 5 0 0 1 9.9-1\"></path></svg>\r\n </ng-template>\r\n </button>\r\n\r\n <!-- Bot\u00F3n Maximizar / Restaurar -->\r\n <button class=\"btn-action\" (click)=\"onMaximizeClick()\" [title]=\"isMaximized() ? 'Restaurar' : 'Maximizar'\">\r\n <svg *ngIf=\"isMaximized(); else maxIcon\" width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M8 3v3a2 2 0 0 1-2 2H3m18 0h-3a2 2 0 0 1-2-2V3m0 18v-3a2 2 0 0 1 2-2h3M3 16h3a2 2 0 0 1 2 2v3\"></path></svg>\r\n <ng-template #maxIcon>\r\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M15 3h6v6M9 21H3v-6M21 3l-7 7M3 21l7-7\"></path></svg>\r\n </ng-template>\r\n </button>\r\n\r\n <!-- Bot\u00F3n Eliminar -->\r\n <button [hidden]=\"!varShowConfigButtons\" class=\"btn-delete\" (click)=\"onDeleteClick()\" title=\"Eliminar\">\r\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><polyline points=\"3 6 5 6 21 6\"></polyline><path d=\"M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6m3 0V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2\"></path></svg>\r\n </button>\r\n\r\n <!-- Bot\u00F3n Configuraci\u00F3n -->\r\n <button [hidden]=\"!varShowConfigButtons\" class=\"btn-config\" (click)=\"onShowFormConfigClick()\" title=\"Configurar\">\r\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><circle cx=\"12\" cy=\"12\" r=\"3\"></circle><path d=\"M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 0 1 0 2.83 2 2 0 0 1-2.83 0l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 0 1-2 2 2 2 0 0 1-2-2v-.09A1.65 1.65 0 0 0 9 19.4a1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 0 1-2.83 0 2 2 0 0 1 0-2.83l.06-.06a1.65 1.65 0 0 0 .33-1.82 1.65 1.65 0 0 0-1.51-1H3a2 2 0 0 1-2-2 2 2 0 0 1 2-2h.09A1.65 1.65 0 0 0 4.6 9a1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 0 1 0-2.83 2 2 0 0 1 2.83 0l.06.06a1.65 1.65 0 0 0 1.82.33H9a1.65 1.65 0 0 0 1-1.51V3a2 2 0 0 1 2-2 2 2 0 0 1 2 2v.09a1.65 1.65 0 0 0 1 1.51 1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 0 1 2.83 0 2 2 0 0 1 0 2.83l-.06.06a1.65 1.65 0 0 0-.33 1.82V9a1.65 1.65 0 0 0 1.51 1H21a2 2 0 0 1 2 2 2 2 0 0 1-2 2h-.09a1.65 1.65 0 0 0-1.51 1z\"></path></svg>\r\n </button>\r\n</div>\r\n\r\n<div class=\"widget-content-wrapper\">\r\n @if ( typeComponent == 'dummy' ) {\r\n <ng-container *ngTemplateOutlet=\"testdummy; context: { control: dataWidget }\"></ng-container>\r\n }\r\n @if ( typeComponent == 'empty-visual' ) {\r\n <ng-container *ngTemplateOutlet=\"emptyvisual; context: { control: dataWidget }\"></ng-container>\r\n }\r\n @if ( typeComponent == 'chart-bar' ) {\r\n <ng-container *ngTemplateOutlet=\"chartbar; context: { control: dataWidget }\"></ng-container>\r\n }\r\n @if ( typeComponent == 'chart-line' ) {\r\n <ng-container *ngTemplateOutlet=\"chartline; context: { control: dataWidget }\"></ng-container>\r\n }\r\n @if ( typeComponent == 'chart-doughnut' ) {\r\n <ng-container *ngTemplateOutlet=\"chartdoughnut; context: { control: dataWidget }\"></ng-container>\r\n } \r\n @if ( typeComponent == 'chart-gauge' ) {\r\n <ng-container *ngTemplateOutlet=\"chartgauge; context: { control: dataWidget }\"></ng-container>\r\n } \r\n @if ( typeComponent == 'chart-bubble' ) {\r\n <ng-container *ngTemplateOutlet=\"chartbubble; context: { control: dataWidget }\"></ng-container>\r\n } \r\n \r\n \r\n</div>\r\n\r\n\r\n<!--------------------------------------------------------------->\r\n<!---------------------- DUMMY TEMPLATE ---------------------->\r\n<!--------------------------------------------------------------->\r\n<ng-template #testdummy let-control = \"control\">\r\n <lib-test-chart [idComponent]=\"control.idComponent\" > \r\n </lib-test-chart>\r\n</ng-template>\r\n<!--------------------------------------------------------------->\r\n<!---------------------- EMPTY VISUAL TEMPLATE ---------------------->\r\n<!--------------------------------------------------------------->\r\n<ng-template #emptyvisual let-control = \"control\">\r\n <yw-empty-visual [idComponent]=\"control.idComponent\"\r\n [config]=\"control.controlConfig\" \r\n > \r\n </yw-empty-visual>\r\n</ng-template>\r\n\r\n<!--------------------------------------------------------------->\r\n<!---------------------- BAR CHART TEMPLATE ---------------------->\r\n<!--------------------------------------------------------------->\r\n<ng-template #chartbar let-control = \"control\">\r\n <yw-bar-chart [idComponent]=\"control.idComponent\"\r\n [chartData]=\"control.controlData\"\r\n [config]=\"control.controlConfig\" \r\n >\r\n </yw-bar-chart>\r\n</ng-template>\r\n\r\n<!--------------------------------------------------------------->\r\n<!---------------------- LINE CHART TEMPLATE ---------------------->\r\n<!--------------------------------------------------------------->\r\n<ng-template #chartline let-control = \"control\">\r\n <yw-line-chart [idComponent]=\"control.idComponent\"\r\n [chartData]=\"control.controlData\"\r\n [config]=\"control.controlConfig\" \r\n >\r\n </yw-line-chart>\r\n</ng-template>\r\n\r\n\r\n<!--------------------------------------------------------------->\r\n<!---------------------- LINE DOUGHNUT TEMPLATE ---------------------->\r\n<!--------------------------------------------------------------->\r\n<ng-template #chartdoughnut let-control = \"control\">\r\n <yw-pie-chart [idComponent]=\"control.idComponent\"\r\n [chartData]=\"control.controlData\"\r\n [config]=\"control.controlConfig\" \r\n >\r\n </yw-pie-chart>\r\n</ng-template>\r\n\r\n \r\n<!--------------------------------------------------------------->\r\n<!---------------------- LINE GAUGE TEMPLATE ---------------------->\r\n<!--------------------------------------------------------------->\r\n<ng-template #chartgauge let-control = \"control\">\r\n <yw-gauge-chart [idComponent]=\"control.idComponent\"\r\n [chartData]=\"control.controlData\"\r\n [config]=\"control.controlConfig\" \r\n >\r\n </yw-gauge-chart>\r\n</ng-template>\r\n\r\n\r\n<!--------------------------------------------------------------->\r\n<!---------------------- BUBBLE TEMPLATE ---------------------->\r\n<!--------------------------------------------------------------->\r\n<ng-template #chartbubble let-control=\"control\">\r\n \r\n <yw-bubble-chart \r\n [idComponent]=\"control.idComponent\"\r\n [chartData]=\"control.controlData\"\r\n [config]=\"control.controlConfig\">\r\n </yw-bubble-chart>\r\n</ng-template> ", styles: ["@charset \"UTF-8\";:host{display:block;flex-direction:column;width:100%;overflow:hidden;box-sizing:border-box;background-color:var(--widget-bg, #ffffff);border:1px solid var(--widget-border-color, #007bff)}:host *,:host *:before,:host *:after{box-sizing:border-box}.widget-action-bar{display:flex;justify-content:flex-end;gap:4px;padding:5px 10px;flex-shrink:0;width:100%}.widget-content-wrapper{width:100%;flex-grow:1;height:0;display:flex;flex-direction:column}.widget-action-bar button,.widget-action-bar .btn-action,.widget-action-bar .btn-delete,.widget-action-bar .btn-config{background:transparent;border:1px solid #d9d9d9;border-radius:4px;cursor:pointer;width:26px;height:26px;display:inline-flex;align-items:center;justify-content:center;color:#595959;padding:0;transition:all .2s ease}.widget-action-bar button svg,.widget-action-bar .btn-action svg,.widget-action-bar .btn-delete svg,.widget-action-bar .btn-config svg{width:14px;height:14px}.widget-action-bar button:hover,.widget-action-bar .btn-action:hover,.widget-action-bar .btn-delete:hover,.widget-action-bar .btn-config:hover{background-color:#f5f5f5;color:#262626;border-color:#bfbfbf}.widget-action-bar button:active,.widget-action-bar .btn-action:active,.widget-action-bar .btn-delete:active,.widget-action-bar .btn-config:active{background-color:#e6e6e6}.widget-action-bar .btn-delete:hover{background-color:#fff1f0;color:#ff4d4f;border-color:#ffa39e}\n"] }]
|
|
3494
|
+
}], ctorParameters: () => [], propDecorators: { styleWidget: [{ type: i0.Input, args: [{ isSignal: true, alias: "styleWidget", required: false }] }], configWidget: [{
|
|
3566
3495
|
type: Input
|
|
3567
|
-
}], controlConfig: [{
|
|
3496
|
+
}], controlConfig: [{
|
|
3568
3497
|
type: Input
|
|
3569
|
-
}],
|
|
3498
|
+
}], controlData: [{
|
|
3499
|
+
type: Input
|
|
3500
|
+
}], isLocked: [{ type: i0.Input, args: [{ isSignal: true, alias: "isLocked", required: false }] }, { type: i0.Output, args: ["isLockedChange"] }], eventDeleteRequest: [{ type: i0.Output, args: ["eventDeleteRequest"] }], eventLockToggleRequest: [{ type: i0.Output, args: ["eventLockToggleRequest"] }], eventMaximizeToggleRequest: [{ type: i0.Output, args: ["eventMaximizeToggleRequest"] }], eventShowConfigFormRequest: [{ type: i0.Output, args: ["eventShowConfigFormRequest"] }] } });
|
|
3570
3501
|
|
|
3571
|
-
class
|
|
3502
|
+
class YwBaseSlicerComponent {
|
|
3572
3503
|
constructor() {
|
|
3573
|
-
|
|
3574
|
-
|
|
3575
|
-
|
|
3576
|
-
|
|
3577
|
-
};
|
|
3578
|
-
this.
|
|
3579
|
-
this.
|
|
3580
|
-
this.
|
|
3581
|
-
|
|
3582
|
-
|
|
3583
|
-
this.
|
|
3584
|
-
this.
|
|
3585
|
-
|
|
3586
|
-
|
|
3587
|
-
|
|
3588
|
-
|
|
3589
|
-
|
|
3590
|
-
|
|
3591
|
-
|
|
3592
|
-
|
|
3593
|
-
|
|
3594
|
-
|
|
3595
|
-
|
|
3596
|
-
});
|
|
3597
|
-
|
|
3598
|
-
|
|
3599
|
-
|
|
3600
|
-
|
|
3601
|
-
|
|
3602
|
-
|
|
3603
|
-
if (prmTableName.localeCompare(curTableRef.tableName) == 0) {
|
|
3604
|
-
dataresponse = curTableRef.tableData;
|
|
3504
|
+
// Inputs de configuración del rango de fechas
|
|
3505
|
+
this.idComponent = '';
|
|
3506
|
+
this.dataType = 'date';
|
|
3507
|
+
this.label = input('Fecha', ...(ngDevMode ? [{ debugName: "label" }] : []));
|
|
3508
|
+
this.min = input(...(ngDevMode ? [undefined, { debugName: "min" }] : []));
|
|
3509
|
+
this.max = input(...(ngDevMode ? [undefined, { debugName: "max" }] : []));
|
|
3510
|
+
this.step = input(1, ...(ngDevMode ? [{ debugName: "step" }] : []));
|
|
3511
|
+
this.minCurrent = input(...(ngDevMode ? [undefined, { debugName: "minCurrent" }] : []));
|
|
3512
|
+
this.maxCurrent = input(...(ngDevMode ? [undefined, { debugName: "maxCurrent" }] : []));
|
|
3513
|
+
this.minNumber = 0;
|
|
3514
|
+
this.maxNumber = 1000;
|
|
3515
|
+
this.minDate = '2020-01-01';
|
|
3516
|
+
this.maxDate = '2022-12-31';
|
|
3517
|
+
// Evento de salida
|
|
3518
|
+
this.rangeChange = output();
|
|
3519
|
+
// Signals para las fechas seleccionadas
|
|
3520
|
+
this.startDate = signal('2020-01-01', ...(ngDevMode ? [{ debugName: "startDate" }] : []));
|
|
3521
|
+
this.endDate = signal('2022-09-22', ...(ngDevMode ? [{ debugName: "endDate" }] : []));
|
|
3522
|
+
// Signals para los numeros seleccionadas
|
|
3523
|
+
this.startVal = signal(0, ...(ngDevMode ? [{ debugName: "startVal" }] : []));
|
|
3524
|
+
this.endVal = signal(1000, ...(ngDevMode ? [{ debugName: "endVal" }] : []));
|
|
3525
|
+
this.minTimestamp = computed(() => new Date(this.minDate).getTime(), ...(ngDevMode ? [{ debugName: "minTimestamp" }] : []));
|
|
3526
|
+
this.maxTimestamp = computed(() => new Date(this.maxDate).getTime(), ...(ngDevMode ? [{ debugName: "maxTimestamp" }] : []));
|
|
3527
|
+
this.startTimestamp = computed(() => new Date(this.startDate()).getTime(), ...(ngDevMode ? [{ debugName: "startTimestamp" }] : []));
|
|
3528
|
+
this.endTimestamp = computed(() => new Date(this.endDate()).getTime(), ...(ngDevMode ? [{ debugName: "endTimestamp" }] : []));
|
|
3529
|
+
// Inicializar valores al arrancar
|
|
3530
|
+
effect(() => {
|
|
3531
|
+
if (this.dataType == 'date') {
|
|
3532
|
+
this.startDate.set(this.minCurrent() || this.minDate);
|
|
3533
|
+
this.endDate.set(this.maxCurrent() || this.maxDate);
|
|
3605
3534
|
}
|
|
3606
|
-
|
|
3607
|
-
|
|
3608
|
-
|
|
3609
|
-
onFilterChange(eventData) {
|
|
3610
|
-
this.filterSelectionChange.emit({ widgetId: eventData.widgetId, eventResponse: eventData.eventResponse });
|
|
3611
|
-
}
|
|
3612
|
-
fnSetControlFilterCurrentValues(prmControlConfig) {
|
|
3613
|
-
if (prmControlConfig.typeComponent == 'filter-slicer') {
|
|
3614
|
-
let curConfigComponent = prmControlConfig.configComponent;
|
|
3615
|
-
if (prmControlConfig.configComponent.dataType == 'date') {
|
|
3616
|
-
curConfigComponent.minCurrent = prmControlConfig.controlFilterData['startDate'];
|
|
3617
|
-
curConfigComponent.maxCurrent = prmControlConfig.controlFilterData['endDate'];
|
|
3535
|
+
if (this.dataType == 'number') {
|
|
3536
|
+
this.startVal.set(this.minCurrent() || this.minNumber);
|
|
3537
|
+
this.endVal.set(this.maxCurrent() || this.maxNumber);
|
|
3618
3538
|
}
|
|
3619
|
-
|
|
3620
|
-
|
|
3621
|
-
|
|
3539
|
+
}, { allowSignalWrites: true });
|
|
3540
|
+
// Notificar al padre cada vez que cambien los valores
|
|
3541
|
+
effect(() => {
|
|
3542
|
+
if (this.dataType == 'date') {
|
|
3543
|
+
this.rangeChange.emit({
|
|
3544
|
+
startDate: this.startDate(),
|
|
3545
|
+
endDate: this.endDate()
|
|
3546
|
+
});
|
|
3622
3547
|
}
|
|
3623
|
-
|
|
3624
|
-
|
|
3625
|
-
|
|
3626
|
-
|
|
3627
|
-
|
|
3628
|
-
return curConfigComponent;
|
|
3629
|
-
}
|
|
3630
|
-
if (prmControlConfig.typeComponent == 'filter-list') {
|
|
3631
|
-
let curConfigComponent = prmControlConfig.configComponent;
|
|
3632
|
-
curConfigComponent.currentSelectedId = prmControlConfig.controlFilterData['currentNodeId'];
|
|
3633
|
-
return curConfigComponent;
|
|
3634
|
-
}
|
|
3635
|
-
}
|
|
3636
|
-
handleClearFilter() {
|
|
3637
|
-
this.controlListConfig = [];
|
|
3638
|
-
this.dashboardFilterConfig.controlListConfig.forEach((item) => {
|
|
3639
|
-
const tableName = item.controlTable;
|
|
3640
|
-
const prmcontrolData = this.fn_getDataForWidgetFilterComponent(tableName, this.dashboardData);
|
|
3641
|
-
const prmconfigWidget = { ...item };
|
|
3642
|
-
if (item.controlFilterData) {
|
|
3643
|
-
item.configComponent = this.fnSetControlFilterClearValues(prmconfigWidget);
|
|
3548
|
+
if (this.dataType == 'number') {
|
|
3549
|
+
this.rangeChange.emit({
|
|
3550
|
+
minValue: this.startVal(),
|
|
3551
|
+
maxValue: this.endVal()
|
|
3552
|
+
});
|
|
3644
3553
|
}
|
|
3645
|
-
const configControl = { configWidget: prmconfigWidget,
|
|
3646
|
-
controlData: prmcontrolData,
|
|
3647
|
-
controlConfig: item.configComponent
|
|
3648
|
-
};
|
|
3649
|
-
this.controlListConfig.push(configControl);
|
|
3650
3554
|
});
|
|
3651
3555
|
}
|
|
3652
|
-
|
|
3653
|
-
if (
|
|
3654
|
-
|
|
3655
|
-
|
|
3656
|
-
|
|
3657
|
-
|
|
3658
|
-
|
|
3659
|
-
|
|
3660
|
-
let curConfigComponent = prmControlConfig.configComponent;
|
|
3661
|
-
curConfigComponent.currentIds = [];
|
|
3662
|
-
return curConfigComponent;
|
|
3556
|
+
ngOnInit() {
|
|
3557
|
+
if (this.dataType == 'date') {
|
|
3558
|
+
this.minDate = this.min();
|
|
3559
|
+
this.maxDate = this.max();
|
|
3560
|
+
this.minTimestamp = computed(() => new Date(this.minDate).getTime(), ...(ngDevMode ? [{ debugName: "minTimestamp" }] : []));
|
|
3561
|
+
this.maxTimestamp = computed(() => new Date(this.maxDate).getTime(), ...(ngDevMode ? [{ debugName: "maxTimestamp" }] : []));
|
|
3562
|
+
this.startTimestamp = computed(() => new Date(this.startDate()).getTime(), ...(ngDevMode ? [{ debugName: "startTimestamp" }] : []));
|
|
3563
|
+
this.endTimestamp = computed(() => new Date(this.endDate()).getTime(), ...(ngDevMode ? [{ debugName: "endTimestamp" }] : []));
|
|
3663
3564
|
}
|
|
3664
|
-
if (
|
|
3665
|
-
|
|
3666
|
-
|
|
3667
|
-
return curConfigComponent;
|
|
3565
|
+
if (this.dataType == 'number') {
|
|
3566
|
+
this.minNumber = this.min();
|
|
3567
|
+
this.maxNumber = this.max();
|
|
3668
3568
|
}
|
|
3669
3569
|
}
|
|
3670
|
-
|
|
3671
|
-
|
|
3570
|
+
// Handlers para la entrada manual de fechas
|
|
3571
|
+
onStartDateInput(value) {
|
|
3572
|
+
if (value && value <= this.endDate()) {
|
|
3573
|
+
this.startDate.set(value);
|
|
3574
|
+
}
|
|
3575
|
+
}
|
|
3576
|
+
onEndDateInput(value) {
|
|
3577
|
+
if (value && value >= this.startDate()) {
|
|
3578
|
+
this.endDate.set(value);
|
|
3579
|
+
}
|
|
3580
|
+
}
|
|
3581
|
+
// Métodos para cambiar desde el Input Numérico
|
|
3582
|
+
onStartInput(event) {
|
|
3583
|
+
const value = Number(event.target.value);
|
|
3584
|
+
if (!isNaN(value) && value <= this.endVal() && value >= this.min()) {
|
|
3585
|
+
this.startVal.set(value);
|
|
3586
|
+
}
|
|
3587
|
+
}
|
|
3588
|
+
onEndInput(event) {
|
|
3589
|
+
const value = Number(event.target.value);
|
|
3590
|
+
if (!isNaN(value) && value >= this.startVal() && value <= this.max()) {
|
|
3591
|
+
this.endVal.set(value);
|
|
3592
|
+
}
|
|
3593
|
+
}
|
|
3594
|
+
// Handlers para el movimiento del slider
|
|
3595
|
+
onStartSliderChange(event) {
|
|
3596
|
+
if (this.dataType == 'date') {
|
|
3597
|
+
const val = Number(event.target.value);
|
|
3598
|
+
const dateStr = new Date(val).toISOString().split('T')[0];
|
|
3599
|
+
if (val < this.endTimestamp()) {
|
|
3600
|
+
this.startDate.set(dateStr);
|
|
3601
|
+
}
|
|
3602
|
+
}
|
|
3603
|
+
if (this.dataType == 'number') {
|
|
3604
|
+
const val = Number(event.target.value);
|
|
3605
|
+
if (val < this.endVal()) {
|
|
3606
|
+
this.startVal.set(val);
|
|
3607
|
+
}
|
|
3608
|
+
}
|
|
3609
|
+
}
|
|
3610
|
+
onEndSliderChange(event) {
|
|
3611
|
+
if (this.dataType == 'date') {
|
|
3612
|
+
const val = Number(event.target.value);
|
|
3613
|
+
const dateStr = new Date(val).toISOString().split('T')[0];
|
|
3614
|
+
if (val > this.startTimestamp()) {
|
|
3615
|
+
this.endDate.set(dateStr);
|
|
3616
|
+
}
|
|
3617
|
+
}
|
|
3618
|
+
if (this.dataType == 'number') {
|
|
3619
|
+
const val = Number(event.target.value);
|
|
3620
|
+
if (val > this.startVal()) {
|
|
3621
|
+
this.endVal.set(val);
|
|
3622
|
+
}
|
|
3623
|
+
}
|
|
3624
|
+
}
|
|
3625
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.30", ngImport: i0, type: YwBaseSlicerComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
3626
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.30", type: YwBaseSlicerComponent, isStandalone: true, selector: "yw-base-slicer", inputs: { idComponent: { classPropertyName: "idComponent", publicName: "idComponent", isSignal: false, isRequired: false, transformFunction: null }, dataType: { classPropertyName: "dataType", publicName: "dataType", isSignal: false, isRequired: false, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, min: { classPropertyName: "min", publicName: "min", isSignal: true, isRequired: false, transformFunction: null }, max: { classPropertyName: "max", publicName: "max", isSignal: true, isRequired: false, transformFunction: null }, step: { classPropertyName: "step", publicName: "step", isSignal: true, isRequired: false, transformFunction: null }, minCurrent: { classPropertyName: "minCurrent", publicName: "minCurrent", isSignal: true, isRequired: false, transformFunction: null }, maxCurrent: { classPropertyName: "maxCurrent", publicName: "maxCurrent", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { rangeChange: "rangeChange" }, host: { properties: { "attr.id": "idComponent" } }, ngImport: i0, template: "<div class=\"filter-container\">\r\n <label class=\"filter-label\">{{ label() }}</label>\r\n\r\n <!-- Inputs de fecha superiores -->\r\n <div class=\"date-inputs-row\">\r\n <div class=\"input-wrapper\">\r\n @if (dataType === 'date') { \r\n <input \r\n type=\"date\" \r\n [value]=\"startDate()\"\r\n [min]=\"minDate\"\r\n [max]=\"endDate()\"\r\n (change)=\"onStartDateInput($any($event.target).value)\" \r\n />\r\n }\r\n @if (dataType === 'number') { \r\n <input \r\n type=\"number\" \r\n [value]=\"startVal()\"\r\n [min]=\"minNumber\"\r\n [max]=\"endVal()\"\r\n [step]=\"step()\"\r\n (input)=\"onStartInput($event)\" \r\n />\r\n } \r\n </div>\r\n\r\n <div class=\"input-wrapper\">\r\n @if (dataType === 'date') { \r\n <input \r\n type=\"date\" \r\n [value]=\"endDate()\"\r\n [min]=\"startDate()\"\r\n [max]=\"maxDate\"\r\n (change)=\"onEndDateInput($any($event.target).value)\" \r\n />\r\n }\r\n @if (dataType === 'number') { \r\n <input \r\n type=\"number\" \r\n [value]=\"endVal()\"\r\n [min]=\"startVal()\"\r\n [max]=\"maxNumber\"\r\n [step]=\"step()\"\r\n (input)=\"onEndInput($event)\" \r\n />\r\n }\r\n </div>\r\n </div>\r\n\r\n <!-- Dual Slider personalizado -->\r\n <div class=\"slider-container\">\r\n <div class=\"slider-track\"></div>\r\n @if (dataType === 'date') { \r\n <!-- Slider Inicio -->\r\n <input \r\n type=\"range\" \r\n [min]=\"minTimestamp()\" \r\n [max]=\"maxTimestamp()\" \r\n [value]=\"startTimestamp()\"\r\n (input)=\"onStartSliderChange($event)\"\r\n class=\"thumb thumb-left\"\r\n />\r\n\r\n <!-- Slider Fin -->\r\n <input \r\n type=\"range\" \r\n [min]=\"minTimestamp()\" \r\n [max]=\"maxTimestamp()\" \r\n [value]=\"endTimestamp()\"\r\n (input)=\"onEndSliderChange($event)\"\r\n class=\"thumb thumb-right\"\r\n />\r\n }\r\n\r\n @if (dataType === 'number') { \r\n\r\n <input \r\n type=\"range\" \r\n [min]=\"minNumber\" \r\n [max]=\"maxNumber\" \r\n [step]=\"step()\"\r\n [value]=\"startVal()\"\r\n (input)=\"onStartSliderChange($event)\"\r\n class=\"thumb thumb-left\"\r\n />\r\n\r\n <!-- Slider M\u00E1ximo -->\r\n <input \r\n type=\"range\" \r\n [min]=\"minNumber\" \r\n [max]=\"maxNumber\" \r\n [step]=\"step()\"\r\n [value]=\"endVal()\"\r\n (input)=\"onEndSliderChange($event)\"\r\n class=\"thumb thumb-right\"\r\n />\r\n\r\n }\r\n\r\n </div>\r\n</div>", styles: ["@charset \"UTF-8\";:host{display:block;font-family:Arial,Helvetica,sans-serif;width:100%;max-width:360px}.filter-container{display:flex;flex-direction:column;gap:8px}.filter-label{font-size:13px;font-weight:600;color:#333}.date-inputs-row,.number-inputs-row{display:flex;gap:8px}.input-wrapper input[type=date]{border:1px solid #e2e8f0;border-radius:2px;padding:4px 8px;font-size:13px;color:#333;outline:none;background-color:#fff;box-shadow:0 1px 2px #0000000d}.input-wrapper input[type=date]:focus{border-color:#a0aec0}.input-wrapper input[type=number]{border:1px solid #e2e8f0;border-radius:2px;padding:4px 8px;font-size:13px;color:#333;width:90px;outline:none;background-color:#fff;box-shadow:0 1px 2px #0000000d}.input-wrapper input[type=number]:focus{border-color:#a0aec0}.slider-container{position:relative;width:100%;height:30px;display:flex;align-items:center;margin-top:4px}.slider-track{position:absolute;width:100%;height:2px;background-color:#666;border-radius:1px;z-index:1}.thumb{position:absolute;width:100%;appearance:none;-webkit-appearance:none;background:none;pointer-events:none;outline:none;margin:0;z-index:2}.thumb-right{z-index:3}.thumb::-webkit-slider-thumb{appearance:none;-webkit-appearance:none;pointer-events:auto;width:22px;height:22px;border-radius:50%;background:#fff;border:3px solid #666666;cursor:pointer;box-sizing:border-box;transition:transform .1s ease}.thumb::-webkit-slider-thumb:hover{transform:scale(1.1);border-color:#333}.thumb::-moz-range-thumb{pointer-events:auto;width:22px;height:22px;border-radius:50%;background:#fff;border:3px solid #666666;cursor:pointer;box-sizing:border-box}\n"] }); }
|
|
3672
3627
|
}
|
|
3673
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.30", ngImport: i0, type:
|
|
3628
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.30", ngImport: i0, type: YwBaseSlicerComponent, decorators: [{
|
|
3674
3629
|
type: Component,
|
|
3675
|
-
args: [{ selector: 'yw-
|
|
3676
|
-
|
|
3677
|
-
|
|
3678
|
-
|
|
3679
|
-
], template: "\r\n <div class=\"dashboard-filter-content-bar\">\r\n @if ( dashboardFilterConfig.showConfigButtons ) { \r\n <button nz-button nzType=\"primary\" >\r\n <span nz-icon nz-type=\"plus\"></span> A\u00F1adir widget\r\n </button>\r\n }\r\n <button nz-button \r\n nzType=\"default\" \r\n nzShape=\"circle\" \r\n (click)=\"handleClearFilter()\" \r\n class=\"btn-clean\" \r\n > \r\n <!-- Icono de Borrador (Eraser) activo / relleno --> \r\n <svg \r\n xmlns=\"http://www.w3.org/2000/svg\" \r\n width=\"16\" height=\"16\" \r\n viewBox=\"0 0 24 24\" \r\n fill=\"currentColor\">\r\n <path d=\"M16.24 3.56a2.12 2.12 0 0 1 3 0l1.2 1.2a2.12 2.12 0 0 1 0 3l-8.5 8.5H6.5a1.5 1.5 0 0 1-1.5-1.5v-5.44l11.24-11.24zM19 19H5a1 1 0 0 1 0-2h14a1 1 0 0 1 0 2z\"/>\r\n </svg>\r\n \r\n </button>\r\n </div>\r\n\r\n <div class=\"dashboard-filter-content-wrapper\">\r\n @for ( colFilter of controlListConfig; track colFilter) { \r\n <div class=\"dashboard-filter-content-wrapper-item\">\r\n \r\n <yw-dashboard-filter-widget \r\n [configWidget]=\"colFilter.configWidget\"\r\n [controlConfig]=\"colFilter.controlConfig\"\r\n [controlData]=\"colFilter.controlData\"\r\n (selectionChange)=\"onFilterChange($event)\"\r\n > \r\n </yw-dashboard-filter-widget>\r\n\r\n </div>\r\n }\r\n </div>", styles: [":host{display:flex;flex-direction:column;width:100%;height:100%;overflow:hidden;box-sizing:border-box}.dashboard-filter-content-bar{display:flex;justify-content:flex-end;gap:4px;padding:5px 10px;flex-shrink:0;width:100%;box-sizing:border-box}.dashboard-filter-content-wrapper{flex:1 1 auto;min-height:0;overflow-y:auto;overflow-x:hidden;width:100%;display:flex;flex-direction:column;box-sizing:border-box}.dashboard-filter-content-wrapper-item{padding-bottom:5px}.btn-clean{display:inline-flex;align-items:center;justify-content:center;padding:0;width:32px;height:32px;border-radius:50%;transition:all .3s ease}.btn-clean.active{color:#fff;background-color:#1890ff;border-color:#1890ff}.btn-clean.active:hover{background-color:#40a9ff;border-color:#40a9ff}\n"] }]
|
|
3680
|
-
}], ctorParameters: () => [], propDecorators: { dashboardFilterConfig: [{
|
|
3630
|
+
args: [{ selector: 'yw-base-slicer', imports: [], host: {
|
|
3631
|
+
'[attr.id]': 'idComponent' // Vincula el atributo id al valor de la propiedad
|
|
3632
|
+
}, template: "<div class=\"filter-container\">\r\n <label class=\"filter-label\">{{ label() }}</label>\r\n\r\n <!-- Inputs de fecha superiores -->\r\n <div class=\"date-inputs-row\">\r\n <div class=\"input-wrapper\">\r\n @if (dataType === 'date') { \r\n <input \r\n type=\"date\" \r\n [value]=\"startDate()\"\r\n [min]=\"minDate\"\r\n [max]=\"endDate()\"\r\n (change)=\"onStartDateInput($any($event.target).value)\" \r\n />\r\n }\r\n @if (dataType === 'number') { \r\n <input \r\n type=\"number\" \r\n [value]=\"startVal()\"\r\n [min]=\"minNumber\"\r\n [max]=\"endVal()\"\r\n [step]=\"step()\"\r\n (input)=\"onStartInput($event)\" \r\n />\r\n } \r\n </div>\r\n\r\n <div class=\"input-wrapper\">\r\n @if (dataType === 'date') { \r\n <input \r\n type=\"date\" \r\n [value]=\"endDate()\"\r\n [min]=\"startDate()\"\r\n [max]=\"maxDate\"\r\n (change)=\"onEndDateInput($any($event.target).value)\" \r\n />\r\n }\r\n @if (dataType === 'number') { \r\n <input \r\n type=\"number\" \r\n [value]=\"endVal()\"\r\n [min]=\"startVal()\"\r\n [max]=\"maxNumber\"\r\n [step]=\"step()\"\r\n (input)=\"onEndInput($event)\" \r\n />\r\n }\r\n </div>\r\n </div>\r\n\r\n <!-- Dual Slider personalizado -->\r\n <div class=\"slider-container\">\r\n <div class=\"slider-track\"></div>\r\n @if (dataType === 'date') { \r\n <!-- Slider Inicio -->\r\n <input \r\n type=\"range\" \r\n [min]=\"minTimestamp()\" \r\n [max]=\"maxTimestamp()\" \r\n [value]=\"startTimestamp()\"\r\n (input)=\"onStartSliderChange($event)\"\r\n class=\"thumb thumb-left\"\r\n />\r\n\r\n <!-- Slider Fin -->\r\n <input \r\n type=\"range\" \r\n [min]=\"minTimestamp()\" \r\n [max]=\"maxTimestamp()\" \r\n [value]=\"endTimestamp()\"\r\n (input)=\"onEndSliderChange($event)\"\r\n class=\"thumb thumb-right\"\r\n />\r\n }\r\n\r\n @if (dataType === 'number') { \r\n\r\n <input \r\n type=\"range\" \r\n [min]=\"minNumber\" \r\n [max]=\"maxNumber\" \r\n [step]=\"step()\"\r\n [value]=\"startVal()\"\r\n (input)=\"onStartSliderChange($event)\"\r\n class=\"thumb thumb-left\"\r\n />\r\n\r\n <!-- Slider M\u00E1ximo -->\r\n <input \r\n type=\"range\" \r\n [min]=\"minNumber\" \r\n [max]=\"maxNumber\" \r\n [step]=\"step()\"\r\n [value]=\"endVal()\"\r\n (input)=\"onEndSliderChange($event)\"\r\n class=\"thumb thumb-right\"\r\n />\r\n\r\n }\r\n\r\n </div>\r\n</div>", styles: ["@charset \"UTF-8\";:host{display:block;font-family:Arial,Helvetica,sans-serif;width:100%;max-width:360px}.filter-container{display:flex;flex-direction:column;gap:8px}.filter-label{font-size:13px;font-weight:600;color:#333}.date-inputs-row,.number-inputs-row{display:flex;gap:8px}.input-wrapper input[type=date]{border:1px solid #e2e8f0;border-radius:2px;padding:4px 8px;font-size:13px;color:#333;outline:none;background-color:#fff;box-shadow:0 1px 2px #0000000d}.input-wrapper input[type=date]:focus{border-color:#a0aec0}.input-wrapper input[type=number]{border:1px solid #e2e8f0;border-radius:2px;padding:4px 8px;font-size:13px;color:#333;width:90px;outline:none;background-color:#fff;box-shadow:0 1px 2px #0000000d}.input-wrapper input[type=number]:focus{border-color:#a0aec0}.slider-container{position:relative;width:100%;height:30px;display:flex;align-items:center;margin-top:4px}.slider-track{position:absolute;width:100%;height:2px;background-color:#666;border-radius:1px;z-index:1}.thumb{position:absolute;width:100%;appearance:none;-webkit-appearance:none;background:none;pointer-events:none;outline:none;margin:0;z-index:2}.thumb-right{z-index:3}.thumb::-webkit-slider-thumb{appearance:none;-webkit-appearance:none;pointer-events:auto;width:22px;height:22px;border-radius:50%;background:#fff;border:3px solid #666666;cursor:pointer;box-sizing:border-box;transition:transform .1s ease}.thumb::-webkit-slider-thumb:hover{transform:scale(1.1);border-color:#333}.thumb::-moz-range-thumb{pointer-events:auto;width:22px;height:22px;border-radius:50%;background:#fff;border:3px solid #666666;cursor:pointer;box-sizing:border-box}\n"] }]
|
|
3633
|
+
}], ctorParameters: () => [], propDecorators: { idComponent: [{
|
|
3681
3634
|
type: Input
|
|
3682
|
-
}],
|
|
3635
|
+
}], dataType: [{
|
|
3683
3636
|
type: Input
|
|
3684
|
-
}],
|
|
3637
|
+
}], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], min: [{ type: i0.Input, args: [{ isSignal: true, alias: "min", required: false }] }], max: [{ type: i0.Input, args: [{ isSignal: true, alias: "max", required: false }] }], step: [{ type: i0.Input, args: [{ isSignal: true, alias: "step", required: false }] }], minCurrent: [{ type: i0.Input, args: [{ isSignal: true, alias: "minCurrent", required: false }] }], maxCurrent: [{ type: i0.Input, args: [{ isSignal: true, alias: "maxCurrent", required: false }] }], rangeChange: [{ type: i0.Output, args: ["rangeChange"] }] } });
|
|
3685
3638
|
|
|
3686
|
-
|
|
3687
|
-
|
|
3688
|
-
|
|
3689
|
-
|
|
3690
|
-
|
|
3691
|
-
|
|
3639
|
+
class YwButtonSlicerComponent {
|
|
3640
|
+
constructor() {
|
|
3641
|
+
// Configuración de entradas
|
|
3642
|
+
this.idComponent = '';
|
|
3643
|
+
this.label = input('Tipo de producto', ...(ngDevMode ? [{ debugName: "label" }] : []));
|
|
3644
|
+
this.options = input([], ...(ngDevMode ? [{ debugName: "options" }] : []));
|
|
3645
|
+
this.allowMultiple = input(true, ...(ngDevMode ? [{ debugName: "allowMultiple" }] : [])); // Permite cambiar a selección única si es necesario
|
|
3646
|
+
// Evento de salida con la lista de IDs seleccionados
|
|
3647
|
+
this.selectionChange = output();
|
|
3648
|
+
// Signal con los IDs seleccionados
|
|
3649
|
+
this.selectedIds = signal(new Set(), ...(ngDevMode ? [{ debugName: "selectedIds" }] : []));
|
|
3650
|
+
// Current IDs seleccionados
|
|
3651
|
+
this.currentIds = input([], ...(ngDevMode ? [{ debugName: "currentIds" }] : []));
|
|
3652
|
+
// Emitir el listado en Array cada vez que la Signal de selección cambie
|
|
3692
3653
|
effect(() => {
|
|
3693
|
-
|
|
3694
|
-
console.log('El estado de bloqueo cambió a:', isLocked);
|
|
3695
|
-
this.fn_lockPositionWidgets(isLocked);
|
|
3654
|
+
this.selectionChange.emit(Array.from(this.selectedIds()));
|
|
3696
3655
|
});
|
|
3697
|
-
*/
|
|
3698
|
-
this.environmentInjector = environmentInjector;
|
|
3699
|
-
this.appRef = appRef;
|
|
3700
|
-
this.widgetsActivos = new Map();
|
|
3701
|
-
this.showControls = input(false, ...(ngDevMode ? [{ debugName: "showControls" }] : []));
|
|
3702
|
-
this.showFilter = input(false, ...(ngDevMode ? [{ debugName: "showFilter" }] : []));
|
|
3703
|
-
this.allIsLocked = signal(false, ...(ngDevMode ? [{ debugName: "allIsLocked" }] : []));
|
|
3704
|
-
this.drawerfiltervisible = false;
|
|
3705
|
-
this.drawerconfigvisible = false;
|
|
3706
|
-
this.drawerCurrentWidgetObject = {};
|
|
3707
|
-
this.isLocked = false;
|
|
3708
|
-
this.countWidget = 1;
|
|
3709
|
-
this.layoutConfig = {
|
|
3710
|
-
margin: 10,
|
|
3711
|
-
cellHeight: 100,
|
|
3712
|
-
columns: 24
|
|
3713
|
-
};
|
|
3714
|
-
/* ejemplo de Items
|
|
3715
|
-
items: [
|
|
3716
|
-
{ id: 'div-1', x: 0, y: 0, w: 14, h: 2, content: 'DIV 1' , contentData : {}},
|
|
3717
|
-
{ id: 'div-2', x: 5, y: 2, w: 19, h: 1, content: 'DIV 2' , contentData : {}},
|
|
3718
|
-
{ id: 'div-3', x: 0, y: 3, w: 22, h: 1, content: 'DIV 3', contentData : {} }
|
|
3719
|
-
]
|
|
3720
|
-
*/
|
|
3721
|
-
this.dashboardStyle = {
|
|
3722
|
-
canvasBackgroundColor: "#f5f5f5",
|
|
3723
|
-
widgetBackgroundColor: "#ffffff",
|
|
3724
|
-
widgetBorderColor: "#007bff"
|
|
3725
|
-
};
|
|
3726
|
-
this.dashboardConfig = {
|
|
3727
|
-
showConfigButtons: false,
|
|
3728
|
-
lockPositionWidgets: false,
|
|
3729
|
-
layoutConfig: {
|
|
3730
|
-
margin: 0,
|
|
3731
|
-
cellHeight: 0,
|
|
3732
|
-
columns: 0
|
|
3733
|
-
},
|
|
3734
|
-
controlListConfig: []
|
|
3735
|
-
};
|
|
3736
|
-
this.dashboardData = [];
|
|
3737
|
-
this.dashboardItems = [];
|
|
3738
|
-
/* REF FILTROS */
|
|
3739
|
-
this.dashboardFilterConfig = {
|
|
3740
|
-
showConfigButtons: false,
|
|
3741
|
-
lockPositionWidgets: false,
|
|
3742
|
-
controlListConfig: []
|
|
3743
|
-
};
|
|
3744
3656
|
}
|
|
3745
3657
|
ngOnInit() {
|
|
3746
|
-
|
|
3747
|
-
|
|
3748
|
-
|
|
3749
|
-
|
|
3750
|
-
|
|
3751
|
-
}
|
|
3752
|
-
if (changes['dashboardData']) {
|
|
3753
|
-
console.log('Nuevo valor dashboardData:', this.dashboardData);
|
|
3754
|
-
//this.initCanvasGrid();
|
|
3658
|
+
if (this.currentIds() && this.currentIds().length > 0) {
|
|
3659
|
+
this.selectedIds().clear();
|
|
3660
|
+
this.currentIds().forEach((itemId) => {
|
|
3661
|
+
this.selectedIds().add(itemId);
|
|
3662
|
+
});
|
|
3755
3663
|
}
|
|
3756
3664
|
}
|
|
3757
|
-
|
|
3758
|
-
this.
|
|
3759
|
-
|
|
3760
|
-
initCanvasGrid() {
|
|
3761
|
-
this.layoutConfig = this.dashboardConfig.layoutConfig;
|
|
3762
|
-
// Opciones para restringir colisiones y comportamiento
|
|
3763
|
-
let options = {
|
|
3764
|
-
column: this.layoutConfig.columns,
|
|
3765
|
-
cellHeight: this.layoutConfig.cellHeight,
|
|
3766
|
-
margin: this.layoutConfig.margin,
|
|
3767
|
-
float: true, // Evita que los divs floten automáticamente hacia arriba
|
|
3768
|
-
//noOverlap: true, // CLAVE: Bloquea el movimiento si colisiona con otro DIV
|
|
3769
|
-
resizable: { handles: 'e, se, s, sw, w, nw, n, ne', autoHide: true } // Permite redimensionar desde todos los bordes
|
|
3770
|
-
};
|
|
3771
|
-
if (this.layoutConfig.columnOpts) {
|
|
3772
|
-
options = {
|
|
3773
|
-
column: this.layoutConfig.columns,
|
|
3774
|
-
cellHeight: this.layoutConfig.cellHeight,
|
|
3775
|
-
margin: this.layoutConfig.margin,
|
|
3776
|
-
columnOpts: {
|
|
3777
|
-
breakpointForWindow: this.layoutConfig.columnOpts.breakpointForWindow, // Mide el ancho de la ventana gráfica
|
|
3778
|
-
breakpoints: this.layoutConfig.columnOpts.breakpoints,
|
|
3779
|
-
layout: this.layoutConfig.columnOpts.layout || 'list', // Mantiene el orden de los widgets secuencialmente al colapsar
|
|
3780
|
-
},
|
|
3781
|
-
float: true, // Evita que los divs floten automáticamente hacia arriba
|
|
3782
|
-
//noOverlap: true, // CLAVE: Bloquea el movimiento si colisiona con otro DIV
|
|
3783
|
-
resizable: { handles: 'e, se, s, sw, w, nw, n, ne', autoHide: true } // Permite redimensionar desde todos los bordes
|
|
3784
|
-
};
|
|
3785
|
-
}
|
|
3786
|
-
/*EXAMPLE OF "columnOpts"
|
|
3787
|
-
columnOpts: {
|
|
3788
|
-
breakpointForWindow: true,
|
|
3789
|
-
breakpoints: [
|
|
3790
|
-
{ w: 768, c: 1 },
|
|
3791
|
-
{ w: 992, c: 6 },
|
|
3792
|
-
{ w: 1200, c: this.layoutConfig.columns } // 👈 Usa tu variable para consistencia en Desktop
|
|
3793
|
-
],
|
|
3794
|
-
layout: 'list'
|
|
3795
|
-
}
|
|
3796
|
-
*/
|
|
3797
|
-
// Inicializar el canvas
|
|
3798
|
-
this.grid = GridStack.init(options, this.gridContainer.nativeElement);
|
|
3799
|
-
// Cargar los elementos iniciales desde el JSON
|
|
3800
|
-
//this.loadLayoutFromJSON(this.dashboardItems);
|
|
3801
|
-
this.loadLayoutFromJSON(this.dashboardConfig, this.dashboardStyle);
|
|
3802
|
-
//Evaluar Bloqueo de Widgets en Inicializacion
|
|
3803
|
-
if (this.dashboardConfig.lockPositionWidgets) {
|
|
3804
|
-
this.fn_lockPositionWidgets(this.dashboardConfig.lockPositionWidgets);
|
|
3805
|
-
}
|
|
3806
|
-
// Listener para detectar cambios y actualizar el JSON
|
|
3807
|
-
this.grid.on('change', (event, items) => {
|
|
3808
|
-
this.saveLayoutToJSON();
|
|
3809
|
-
});
|
|
3810
|
-
//Listener para detectar cuando cambia las dimenciones de un widget
|
|
3811
|
-
this.grid.on('resizestop', (event, el) => {
|
|
3812
|
-
// Disparamos el evento nativo del navegador de forma controlada
|
|
3813
|
-
window.dispatchEvent(new Event('resize'));
|
|
3814
|
-
});
|
|
3665
|
+
clearSelection() {
|
|
3666
|
+
this.selectedIds().clear();
|
|
3667
|
+
this.selectionChange.emit([]);
|
|
3815
3668
|
}
|
|
3816
|
-
//
|
|
3817
|
-
|
|
3818
|
-
|
|
3819
|
-
|
|
3820
|
-
|
|
3821
|
-
|
|
3822
|
-
|
|
3823
|
-
|
|
3824
|
-
|
|
3825
|
-
|
|
3826
|
-
}
|
|
3827
|
-
});
|
|
3828
|
-
});
|
|
3669
|
+
// Toggle para seleccionar / deseleccionar
|
|
3670
|
+
toggleSelection(id) {
|
|
3671
|
+
const current = new Set(this.selectedIds());
|
|
3672
|
+
if (this.allowMultiple()) {
|
|
3673
|
+
if (current.has(id)) {
|
|
3674
|
+
current.delete(id);
|
|
3675
|
+
}
|
|
3676
|
+
else {
|
|
3677
|
+
current.add(id);
|
|
3678
|
+
}
|
|
3829
3679
|
}
|
|
3830
3680
|
else {
|
|
3831
|
-
|
|
3832
|
-
|
|
3833
|
-
|
|
3681
|
+
// Si es selección única
|
|
3682
|
+
current.clear();
|
|
3683
|
+
current.add(id);
|
|
3834
3684
|
}
|
|
3835
|
-
|
|
3836
|
-
return object_base_response;
|
|
3685
|
+
this.selectedIds.set(current);
|
|
3837
3686
|
}
|
|
3838
|
-
|
|
3839
|
-
|
|
3840
|
-
|
|
3841
|
-
|
|
3842
|
-
|
|
3843
|
-
|
|
3844
|
-
|
|
3845
|
-
|
|
3846
|
-
|
|
3847
|
-
|
|
3848
|
-
|
|
3849
|
-
|
|
3687
|
+
isSelected(id) {
|
|
3688
|
+
return this.selectedIds().has(id);
|
|
3689
|
+
}
|
|
3690
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.30", ngImport: i0, type: YwButtonSlicerComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
3691
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.30", type: YwButtonSlicerComponent, isStandalone: true, selector: "yw-button-slicer", inputs: { idComponent: { classPropertyName: "idComponent", publicName: "idComponent", isSignal: false, isRequired: false, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, options: { classPropertyName: "options", publicName: "options", isSignal: true, isRequired: false, transformFunction: null }, allowMultiple: { classPropertyName: "allowMultiple", publicName: "allowMultiple", isSignal: true, isRequired: false, transformFunction: null }, currentIds: { classPropertyName: "currentIds", publicName: "currentIds", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { selectionChange: "selectionChange" }, host: { properties: { "attr.id": "idComponent" } }, ngImport: i0, template: "<div class=\"filter-container\">\r\n \r\n <div class=\"filter-header\">\r\n <span class=\"filter-label\">{{ label() }}</span>\r\n <div class=\"header-actions\"> \r\n <button class=\"icon-btn\" (click)=\"clearSelection()\" >\uD83E\uDDF9</button> \r\n </div>\r\n </div>\r\n\r\n\r\n <!-- Contenedor con barra de desplazamiento interna -->\r\n <div class=\"grid-scroll-container\">\r\n <div class=\"buttons-grid\">\r\n @for (item of options(); track item.id) {\r\n <button \r\n type=\"button\" \r\n class=\"option-btn\" \r\n [class.selected]=\"isSelected(item.id)\"\r\n (click)=\"toggleSelection(item.id)\"\r\n [title]=\"item.label\">\r\n <span class=\"btn-text\">{{ item.label }}</span>\r\n </button>\r\n }\r\n </div>\r\n </div>\r\n</div>", styles: ["@charset \"UTF-8\";:host{display:block;font-family:Arial,Helvetica,sans-serif;width:100%;max-width:320px}.filter-container{display:flex;flex-direction:column;gap:8px}.filter-header{display:flex;align-items:center;justify-content:space-between;padding:6px 10px;border-bottom:1px solid #f0f0f0}.filter-label{font-size:13px;font-weight:600;color:#333}.header-actions{display:flex;gap:4px}.grid-scroll-container{max-height:145px;overflow-y:auto;padding-right:4px}.buttons-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:8px}.option-btn{display:flex;align-items:center;justify-content:center;height:38px;padding:4px 6px;background-color:#fff;border:1px solid #d1d5db;border-radius:4px;cursor:pointer;transition:all .15s ease-in-out;outline:none;box-sizing:border-box}.option-btn:hover{border-color:#9ca3af;background-color:#f9fafb}.btn-text{font-size:12px;color:#374151;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;width:100%;text-align:center}.option-btn.selected{border-color:#2563eb;background-color:#eff6ff;box-shadow:0 0 0 1px #2563eb}.option-btn.selected .btn-text{color:#1d4ed8;font-weight:600}.grid-scroll-container::-webkit-scrollbar{width:6px}.grid-scroll-container::-webkit-scrollbar-track{background:#f1f1f1;border-radius:4px}.grid-scroll-container::-webkit-scrollbar-thumb{background:#71717a;border-radius:4px}.grid-scroll-container::-webkit-scrollbar-thumb:hover{background:#52525b}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }] }); }
|
|
3692
|
+
}
|
|
3693
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.30", ngImport: i0, type: YwButtonSlicerComponent, decorators: [{
|
|
3694
|
+
type: Component,
|
|
3695
|
+
args: [{ selector: 'yw-button-slicer', standalone: true, imports: [CommonModule], host: {
|
|
3696
|
+
'[attr.id]': 'idComponent' // Vincula el atributo id al valor de la propiedad
|
|
3697
|
+
}, template: "<div class=\"filter-container\">\r\n \r\n <div class=\"filter-header\">\r\n <span class=\"filter-label\">{{ label() }}</span>\r\n <div class=\"header-actions\"> \r\n <button class=\"icon-btn\" (click)=\"clearSelection()\" >\uD83E\uDDF9</button> \r\n </div>\r\n </div>\r\n\r\n\r\n <!-- Contenedor con barra de desplazamiento interna -->\r\n <div class=\"grid-scroll-container\">\r\n <div class=\"buttons-grid\">\r\n @for (item of options(); track item.id) {\r\n <button \r\n type=\"button\" \r\n class=\"option-btn\" \r\n [class.selected]=\"isSelected(item.id)\"\r\n (click)=\"toggleSelection(item.id)\"\r\n [title]=\"item.label\">\r\n <span class=\"btn-text\">{{ item.label }}</span>\r\n </button>\r\n }\r\n </div>\r\n </div>\r\n</div>", styles: ["@charset \"UTF-8\";:host{display:block;font-family:Arial,Helvetica,sans-serif;width:100%;max-width:320px}.filter-container{display:flex;flex-direction:column;gap:8px}.filter-header{display:flex;align-items:center;justify-content:space-between;padding:6px 10px;border-bottom:1px solid #f0f0f0}.filter-label{font-size:13px;font-weight:600;color:#333}.header-actions{display:flex;gap:4px}.grid-scroll-container{max-height:145px;overflow-y:auto;padding-right:4px}.buttons-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:8px}.option-btn{display:flex;align-items:center;justify-content:center;height:38px;padding:4px 6px;background-color:#fff;border:1px solid #d1d5db;border-radius:4px;cursor:pointer;transition:all .15s ease-in-out;outline:none;box-sizing:border-box}.option-btn:hover{border-color:#9ca3af;background-color:#f9fafb}.btn-text{font-size:12px;color:#374151;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;width:100%;text-align:center}.option-btn.selected{border-color:#2563eb;background-color:#eff6ff;box-shadow:0 0 0 1px #2563eb}.option-btn.selected .btn-text{color:#1d4ed8;font-weight:600}.grid-scroll-container::-webkit-scrollbar{width:6px}.grid-scroll-container::-webkit-scrollbar-track{background:#f1f1f1;border-radius:4px}.grid-scroll-container::-webkit-scrollbar-thumb{background:#71717a;border-radius:4px}.grid-scroll-container::-webkit-scrollbar-thumb:hover{background:#52525b}\n"] }]
|
|
3698
|
+
}], ctorParameters: () => [], propDecorators: { idComponent: [{
|
|
3699
|
+
type: Input
|
|
3700
|
+
}], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], options: [{ type: i0.Input, args: [{ isSignal: true, alias: "options", required: false }] }], allowMultiple: [{ type: i0.Input, args: [{ isSignal: true, alias: "allowMultiple", required: false }] }], selectionChange: [{ type: i0.Output, args: ["selectionChange"] }], currentIds: [{ type: i0.Input, args: [{ isSignal: true, alias: "currentIds", required: false }] }] } });
|
|
3701
|
+
|
|
3702
|
+
class YwListSlicerComponent {
|
|
3703
|
+
constructor() {
|
|
3704
|
+
// Entradas generales
|
|
3705
|
+
this.idComponent = '';
|
|
3706
|
+
this.label = input('Filtro Jerárquico', ...(ngDevMode ? [{ debugName: "label" }] : []));
|
|
3707
|
+
this.clearTitleLabel = input('Limpiar Seleccion', ...(ngDevMode ? [{ debugName: "clearTitleLabel" }] : []));
|
|
3708
|
+
// Opción 1: Entregar datos en árbol de texto directo
|
|
3709
|
+
this.rawData = input([], ...(ngDevMode ? [{ debugName: "rawData" }] : []));
|
|
3710
|
+
// Opción 2: Generar desde fechas
|
|
3711
|
+
this.dataType = input('date', ...(ngDevMode ? [{ debugName: "dataType" }] : []));
|
|
3712
|
+
this.minDate = input('', ...(ngDevMode ? [{ debugName: "minDate" }] : [])); // Formato 'YYYY-MM-DD'
|
|
3713
|
+
this.maxDate = input('', ...(ngDevMode ? [{ debugName: "maxDate" }] : []));
|
|
3714
|
+
this.dateHierarchyType = input('YEAR_TRIMESTER_MONTH', ...(ngDevMode ? [{ debugName: "dateHierarchyType" }] : []));
|
|
3715
|
+
this.monthNames = input(['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'], ...(ngDevMode ? [{ debugName: "monthNames" }] : []));
|
|
3716
|
+
// Evento de salida con el ID/Nodo seleccionado
|
|
3717
|
+
this.selectionChange = output();
|
|
3718
|
+
this.filterValueChange = output(); // Output 2 (Rangos o Hojas)
|
|
3719
|
+
// ID del elemento seleccionado (Selección Simple)
|
|
3720
|
+
this.selectedId = signal(null, ...(ngDevMode ? [{ debugName: "selectedId" }] : []));
|
|
3721
|
+
this.currentSelectedId = input(null, ...(ngDevMode ? [{ debugName: "currentSelectedId" }] : []));
|
|
3722
|
+
// Arbol de nodos computado
|
|
3723
|
+
this.treeNodes = computed(() => {
|
|
3724
|
+
if (this.dataType() == 'date' && this.minDate() && this.maxDate()) {
|
|
3725
|
+
return this.generateDateHierarchy(this.minDate(), this.maxDate(), this.dateHierarchyType());
|
|
3726
|
+
}
|
|
3727
|
+
return this.rawData();
|
|
3728
|
+
}, ...(ngDevMode ? [{ debugName: "treeNodes" }] : []));
|
|
3729
|
+
effect(() => {
|
|
3730
|
+
const currentId = this.selectedId();
|
|
3731
|
+
if (!currentId) {
|
|
3732
|
+
this.selectionChange.emit(null);
|
|
3733
|
+
this.filterValueChange.emit(null);
|
|
3734
|
+
return;
|
|
3735
|
+
}
|
|
3736
|
+
const node = this.findNodeById(this.treeNodes(), currentId);
|
|
3737
|
+
this.selectionChange.emit(node);
|
|
3738
|
+
if (node) {
|
|
3739
|
+
// Emitir el segundo Output según el modo
|
|
3740
|
+
const calculatedValue = this.processFilterOutput(node);
|
|
3741
|
+
this.filterValueChange.emit(calculatedValue);
|
|
3742
|
+
}
|
|
3743
|
+
});
|
|
3744
|
+
}
|
|
3745
|
+
ngOnInit() {
|
|
3746
|
+
if (this.currentSelectedId()) {
|
|
3747
|
+
this.selectedId.set(this.currentSelectedId());
|
|
3850
3748
|
}
|
|
3851
|
-
|
|
3852
|
-
|
|
3749
|
+
}
|
|
3750
|
+
// Métodos de Selección y Expansión
|
|
3751
|
+
toggleExpand(node, event) {
|
|
3752
|
+
event.stopPropagation();
|
|
3753
|
+
node.expanded = !node.expanded;
|
|
3754
|
+
}
|
|
3755
|
+
selectNode(node, event) {
|
|
3756
|
+
event.stopPropagation();
|
|
3757
|
+
this.selectedId.set(this.selectedId() === node.id ? null : node.id);
|
|
3758
|
+
}
|
|
3759
|
+
clearSelection() {
|
|
3760
|
+
this.selectedId.set(null);
|
|
3761
|
+
this.filterValueChange.emit(null);
|
|
3762
|
+
}
|
|
3763
|
+
// --- LÓGICA DE PROCESAMIENTO DE LAS HOJAS / RANGOS ---
|
|
3764
|
+
processFilterOutput(selectedNode) {
|
|
3765
|
+
// 1. Obtener todas las hojas (nodos del nivel más bajo) pertenecientes al bloque seleccionado
|
|
3766
|
+
const leaves = this.getLeafNodes(selectedNode);
|
|
3767
|
+
if (this.dataType() == 'date') {
|
|
3768
|
+
// Extraer todas las fechas de las hojas del bloque
|
|
3769
|
+
const dates = leaves
|
|
3770
|
+
.map(leaf => leaf.value)
|
|
3771
|
+
.filter(d => d instanceof Date)
|
|
3772
|
+
.sort((a, b) => a.getTime() - b.getTime());
|
|
3773
|
+
if (dates.length > 0) {
|
|
3774
|
+
const minD = dates[0];
|
|
3775
|
+
// Para la fecha máxima, tomamos el último día del mes correspondiente
|
|
3776
|
+
const maxD = new Date(dates[dates.length - 1].getFullYear(), dates[dates.length - 1].getMonth() + 1, 0);
|
|
3777
|
+
return {
|
|
3778
|
+
type: 'DATE_RANGE',
|
|
3779
|
+
dateRange: {
|
|
3780
|
+
minDate: minD.toISOString().split('T')[0],
|
|
3781
|
+
maxDate: maxD.toISOString().split('T')[0]
|
|
3782
|
+
},
|
|
3783
|
+
currentNodeId: selectedNode.id
|
|
3784
|
+
};
|
|
3785
|
+
}
|
|
3853
3786
|
}
|
|
3854
|
-
|
|
3787
|
+
// Modo Texto: Entregar arreglo con las hojas
|
|
3788
|
+
return {
|
|
3789
|
+
type: 'TEXT_LEAVES',
|
|
3790
|
+
leafNodes: leaves,
|
|
3791
|
+
leafIds: leaves.map(l => l.id),
|
|
3792
|
+
currentNodeId: selectedNode.id
|
|
3793
|
+
};
|
|
3855
3794
|
}
|
|
3856
|
-
//
|
|
3857
|
-
|
|
3858
|
-
|
|
3859
|
-
|
|
3860
|
-
|
|
3861
|
-
|
|
3862
|
-
const
|
|
3863
|
-
|
|
3864
|
-
|
|
3865
|
-
|
|
3866
|
-
|
|
3867
|
-
|
|
3868
|
-
|
|
3869
|
-
|
|
3870
|
-
|
|
3871
|
-
|
|
3795
|
+
// Recorrido recursivo para obtener solo los nodos terminales (sin hijos)
|
|
3796
|
+
getLeafNodes(node) {
|
|
3797
|
+
if (!node.children || node.children.length === 0) {
|
|
3798
|
+
return [node];
|
|
3799
|
+
}
|
|
3800
|
+
let leaves = [];
|
|
3801
|
+
for (const child of node.children) {
|
|
3802
|
+
leaves = leaves.concat(this.getLeafNodes(child));
|
|
3803
|
+
}
|
|
3804
|
+
return leaves;
|
|
3805
|
+
}
|
|
3806
|
+
findNodeById(nodes, id) {
|
|
3807
|
+
for (const node of nodes) {
|
|
3808
|
+
if (node.id === id)
|
|
3809
|
+
return node;
|
|
3810
|
+
if (node.children) {
|
|
3811
|
+
const found = this.findNodeById(node.children, id);
|
|
3812
|
+
if (found)
|
|
3813
|
+
return found;
|
|
3814
|
+
}
|
|
3815
|
+
}
|
|
3816
|
+
return null;
|
|
3817
|
+
}
|
|
3818
|
+
// Generador de Jerarquía por Fechas
|
|
3819
|
+
generateDateHierarchy(startStr, endStr, type) {
|
|
3820
|
+
const start = new Date(startStr);
|
|
3821
|
+
const end = new Date(endStr);
|
|
3822
|
+
const tree = [];
|
|
3823
|
+
const monthNames = this.monthNames();
|
|
3824
|
+
if (type === 'YEAR_TRIMESTER_MONTH') {
|
|
3825
|
+
let current = new Date(start);
|
|
3826
|
+
while (current <= end) {
|
|
3827
|
+
const year = current.getFullYear();
|
|
3828
|
+
let yearNode = tree.find(n => n.id === `Y_${year}`);
|
|
3829
|
+
if (!yearNode) {
|
|
3830
|
+
yearNode = { id: `Y_${year}`, label: `${year}`, children: [], expanded: false };
|
|
3831
|
+
tree.push(yearNode);
|
|
3872
3832
|
}
|
|
3873
|
-
|
|
3874
|
-
|
|
3875
|
-
|
|
3876
|
-
|
|
3877
|
-
|
|
3833
|
+
const month = current.getMonth();
|
|
3834
|
+
const qtrNum = Math.floor(month / 3) + 1;
|
|
3835
|
+
let qtrNode = yearNode.children.find(n => n.id === `Q_${year}_${qtrNum}`);
|
|
3836
|
+
if (!qtrNode) {
|
|
3837
|
+
qtrNode = { id: `Q_${year}_${qtrNum}`, label: `Qtr ${qtrNum}`, children: [], expanded: false };
|
|
3838
|
+
yearNode.children.push(qtrNode);
|
|
3878
3839
|
}
|
|
3879
|
-
|
|
3880
|
-
|
|
3840
|
+
const monthId = `M_${year}_${month + 1}`;
|
|
3841
|
+
if (!qtrNode.children.some(n => n.id === monthId)) {
|
|
3842
|
+
qtrNode.children.push({
|
|
3843
|
+
id: monthId,
|
|
3844
|
+
label: monthNames[month],
|
|
3845
|
+
value: new Date(year, month, 1) // Fecha inicial del mes
|
|
3846
|
+
});
|
|
3847
|
+
}
|
|
3848
|
+
current.setMonth(current.getMonth() + 1);
|
|
3849
|
+
}
|
|
3881
3850
|
}
|
|
3851
|
+
if (type === 'YEAR_SEMESTER_MONTH') {
|
|
3852
|
+
let current = new Date(start);
|
|
3853
|
+
while (current <= end) {
|
|
3854
|
+
const year = current.getFullYear();
|
|
3855
|
+
let yearNode = tree.find(n => n.id === `Y_${year}`);
|
|
3856
|
+
if (!yearNode) {
|
|
3857
|
+
yearNode = { id: `Y_${year}`, label: `${year}`, children: [], expanded: false };
|
|
3858
|
+
tree.push(yearNode);
|
|
3859
|
+
}
|
|
3860
|
+
const month = current.getMonth();
|
|
3861
|
+
const qtrNum = Math.floor(month / 6) + 1;
|
|
3862
|
+
let qtrNode = yearNode.children.find(n => n.id === `S_${year}_${qtrNum}`);
|
|
3863
|
+
if (!qtrNode) {
|
|
3864
|
+
qtrNode = { id: `S_${year}_${qtrNum}`, label: `S ${qtrNum}`, children: [], expanded: false };
|
|
3865
|
+
yearNode.children.push(qtrNode);
|
|
3866
|
+
}
|
|
3867
|
+
const monthId = `M_${year}_${month + 1}`;
|
|
3868
|
+
if (!qtrNode.children.some(n => n.id === monthId)) {
|
|
3869
|
+
qtrNode.children.push({
|
|
3870
|
+
id: monthId,
|
|
3871
|
+
label: monthNames[month],
|
|
3872
|
+
value: new Date(year, month, 1) // Fecha inicial del mes
|
|
3873
|
+
});
|
|
3874
|
+
}
|
|
3875
|
+
current.setMonth(current.getMonth() + 1);
|
|
3876
|
+
}
|
|
3877
|
+
}
|
|
3878
|
+
return tree;
|
|
3882
3879
|
}
|
|
3883
|
-
|
|
3884
|
-
|
|
3885
|
-
|
|
3886
|
-
|
|
3887
|
-
|
|
3888
|
-
|
|
3889
|
-
|
|
3890
|
-
|
|
3891
|
-
|
|
3892
|
-
|
|
3893
|
-
|
|
3894
|
-
|
|
3895
|
-
|
|
3896
|
-
|
|
3897
|
-
|
|
3898
|
-
|
|
3899
|
-
|
|
3900
|
-
this.
|
|
3901
|
-
|
|
3902
|
-
|
|
3903
|
-
|
|
3904
|
-
|
|
3905
|
-
};
|
|
3906
|
-
//Datos de Widget y sus Contenidos
|
|
3907
|
-
const widgetConfig = {
|
|
3908
|
-
widgetId: newWidgetId,
|
|
3909
|
-
title: '',
|
|
3910
|
-
typeComponent: 'empty-visual',
|
|
3911
|
-
showConfigButtons: true,
|
|
3912
|
-
widgetStyle: DEFAULT_WIDGET_STYLE,
|
|
3913
|
-
layoutConfig: {
|
|
3914
|
-
id: '',
|
|
3915
|
-
w: 0,
|
|
3916
|
-
h: 0,
|
|
3917
|
-
content: undefined
|
|
3918
|
-
},
|
|
3919
|
-
controlConfig: {},
|
|
3920
|
-
controlTables: []
|
|
3880
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.30", ngImport: i0, type: YwListSlicerComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
3881
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.30", type: YwListSlicerComponent, isStandalone: true, selector: "yw-list-slicer", inputs: { idComponent: { classPropertyName: "idComponent", publicName: "idComponent", isSignal: false, isRequired: false, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, clearTitleLabel: { classPropertyName: "clearTitleLabel", publicName: "clearTitleLabel", isSignal: true, isRequired: false, transformFunction: null }, rawData: { classPropertyName: "rawData", publicName: "rawData", isSignal: true, isRequired: false, transformFunction: null }, dataType: { classPropertyName: "dataType", publicName: "dataType", isSignal: true, isRequired: false, transformFunction: null }, minDate: { classPropertyName: "minDate", publicName: "minDate", isSignal: true, isRequired: false, transformFunction: null }, maxDate: { classPropertyName: "maxDate", publicName: "maxDate", isSignal: true, isRequired: false, transformFunction: null }, dateHierarchyType: { classPropertyName: "dateHierarchyType", publicName: "dateHierarchyType", isSignal: true, isRequired: false, transformFunction: null }, monthNames: { classPropertyName: "monthNames", publicName: "monthNames", isSignal: true, isRequired: false, transformFunction: null }, currentSelectedId: { classPropertyName: "currentSelectedId", publicName: "currentSelectedId", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { selectionChange: "selectionChange", filterValueChange: "filterValueChange" }, host: { properties: { "attr.id": "idComponent" } }, ngImport: i0, template: "<div class=\"filter-container\">\r\n <!-- Cabecera con t\u00EDtulo y acciones de filtro -->\r\n <div class=\"filter-header\">\r\n <span class=\"filter-label\">{{ label() }}</span>\r\n <div class=\"header-actions\">\r\n <!--<button class=\"icon-btn\" title=\"Filtro\">\uD83D\uDD3B</button>-->\r\n <button class=\"icon-btn\" (click)=\"clearSelection()\" title=\"{{clearTitleLabel}}\">\uD83E\uDDF9</button>\r\n <!--<button class=\"icon-btn\" title=\"M\u00E1s opciones\">\u22EE</button>-->\r\n </div>\r\n </div>\r\n\r\n <!-- Vista en \u00C1rbol con scroll interno -->\r\n <div class=\"tree-scroll-container\">\r\n <ng-container *ngTemplateOutlet=\"nodeListTemplate; context: { $implicit: treeNodes(), level: 0 }\"></ng-container>\r\n </div>\r\n</div>\r\n\r\n<!-- Plantilla Recursiva para renderizar niveles del \u00C1rbol -->\r\n<ng-template #nodeListTemplate let-nodes let-level=\"level\">\r\n <div class=\"tree-level\">\r\n @for (node of nodes; track node.id) {\r\n <div class=\"tree-node-wrapper\">\r\n <!-- Fila de opci\u00F3n -->\r\n <div \r\n class=\"tree-node-row\" \r\n [class.selected]=\"selectedId() === node.id\"\r\n [style.padding-left.px]=\"level * 18 + 6\"\r\n (click)=\"selectNode(node, $event)\">\r\n \r\n <!-- Flecha expandir/colapsar (si tiene hijos) -->\r\n @if (node.children && node.children.length > 0) {\r\n <span class=\"chevron-icon\" (click)=\"toggleExpand(node, $event)\">\r\n {{ node.expanded ? '\uD83D\uDF83' : '\uD83D\uDF82' }}\r\n </span>\r\n } @else {\r\n <span class=\"chevron-spacer\"></span>\r\n }\r\n\r\n <!-- Radio Button (Selecci\u00F3n simple) -->\r\n <div class=\"radio-circle\" [class.checked]=\"selectedId() === node.id\">\r\n <div class=\"radio-inner\"></div>\r\n </div>\r\n\r\n <!-- Etiqueta del Nodo -->\r\n <span class=\"node-label\">{{ node.label }}</span>\r\n </div>\r\n\r\n <!-- Renderizado de hijos si est\u00E1 expandido -->\r\n @if (node.children && node.children.length > 0 && node.expanded) {\r\n <ng-container *ngTemplateOutlet=\"nodeListTemplate; context: { $implicit: node.children, level: level + 1 }\"></ng-container>\r\n }\r\n </div>\r\n }\r\n </div>\r\n</ng-template>", styles: ["@charset \"UTF-8\";:host{display:block;font-family:Segoe UI,Tahoma,Geneva,Verdana,sans-serif;width:100%;max-width:320px;background:#fff}.filter-container{display:flex;flex-direction:column;border:1px solid #e0e0e0;border-radius:4px;background-color:#fff}.filter-header{display:flex;align-items:center;justify-content:space-between;padding:6px 10px;border-bottom:1px solid #f0f0f0}.filter-label{font-size:13px;font-weight:600;color:#252423}.header-actions{display:flex;gap:4px}.icon-btn{background:none;border:none;cursor:pointer;font-size:12px;color:#605e5c;padding:2px 4px;border-radius:2px}.icon-btn:hover{background-color:#f3f2f1}.tree-scroll-container{max-height:220px;overflow-y:auto;padding:4px 0}.tree-level{display:flex;flex-direction:column}.tree-node-row{display:flex;align-items:center;height:28px;cursor:pointer;-webkit-user-select:none;user-select:none;gap:6px;transition:background-color .1s ease}.tree-node-row:hover{background-color:#f3f2f1}.tree-node-row.selected{background-color:#e1dfdd}.chevron-icon{display:inline-flex;align-items:center;justify-content:center;width:16px;height:16px;font-size:10px;color:#323130}.chevron-spacer{width:16px}.radio-circle{width:14px;height:14px;border-radius:50%;border:1.5px solid #605e5c;display:flex;align-items:center;justify-content:center;box-sizing:border-box;background-color:#fff}.radio-circle.checked{border-color:#0078d4}.radio-circle.checked .radio-inner{width:6px;height:6px;border-radius:50%;background-color:#0078d4}.node-label{font-size:13px;color:#323130;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.tree-scroll-container::-webkit-scrollbar{width:6px}.tree-scroll-container::-webkit-scrollbar-track{background:#f1f1f1}.tree-scroll-container::-webkit-scrollbar-thumb{background:#8a8886;border-radius:3px}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$2.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }] }); }
|
|
3882
|
+
}
|
|
3883
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.30", ngImport: i0, type: YwListSlicerComponent, decorators: [{
|
|
3884
|
+
type: Component,
|
|
3885
|
+
args: [{ selector: 'yw-list-slicer', standalone: true, imports: [CommonModule], host: {
|
|
3886
|
+
'[attr.id]': 'idComponent' // Vincula el atributo id al valor de la propiedad
|
|
3887
|
+
}, template: "<div class=\"filter-container\">\r\n <!-- Cabecera con t\u00EDtulo y acciones de filtro -->\r\n <div class=\"filter-header\">\r\n <span class=\"filter-label\">{{ label() }}</span>\r\n <div class=\"header-actions\">\r\n <!--<button class=\"icon-btn\" title=\"Filtro\">\uD83D\uDD3B</button>-->\r\n <button class=\"icon-btn\" (click)=\"clearSelection()\" title=\"{{clearTitleLabel}}\">\uD83E\uDDF9</button>\r\n <!--<button class=\"icon-btn\" title=\"M\u00E1s opciones\">\u22EE</button>-->\r\n </div>\r\n </div>\r\n\r\n <!-- Vista en \u00C1rbol con scroll interno -->\r\n <div class=\"tree-scroll-container\">\r\n <ng-container *ngTemplateOutlet=\"nodeListTemplate; context: { $implicit: treeNodes(), level: 0 }\"></ng-container>\r\n </div>\r\n</div>\r\n\r\n<!-- Plantilla Recursiva para renderizar niveles del \u00C1rbol -->\r\n<ng-template #nodeListTemplate let-nodes let-level=\"level\">\r\n <div class=\"tree-level\">\r\n @for (node of nodes; track node.id) {\r\n <div class=\"tree-node-wrapper\">\r\n <!-- Fila de opci\u00F3n -->\r\n <div \r\n class=\"tree-node-row\" \r\n [class.selected]=\"selectedId() === node.id\"\r\n [style.padding-left.px]=\"level * 18 + 6\"\r\n (click)=\"selectNode(node, $event)\">\r\n \r\n <!-- Flecha expandir/colapsar (si tiene hijos) -->\r\n @if (node.children && node.children.length > 0) {\r\n <span class=\"chevron-icon\" (click)=\"toggleExpand(node, $event)\">\r\n {{ node.expanded ? '\uD83D\uDF83' : '\uD83D\uDF82' }}\r\n </span>\r\n } @else {\r\n <span class=\"chevron-spacer\"></span>\r\n }\r\n\r\n <!-- Radio Button (Selecci\u00F3n simple) -->\r\n <div class=\"radio-circle\" [class.checked]=\"selectedId() === node.id\">\r\n <div class=\"radio-inner\"></div>\r\n </div>\r\n\r\n <!-- Etiqueta del Nodo -->\r\n <span class=\"node-label\">{{ node.label }}</span>\r\n </div>\r\n\r\n <!-- Renderizado de hijos si est\u00E1 expandido -->\r\n @if (node.children && node.children.length > 0 && node.expanded) {\r\n <ng-container *ngTemplateOutlet=\"nodeListTemplate; context: { $implicit: node.children, level: level + 1 }\"></ng-container>\r\n }\r\n </div>\r\n }\r\n </div>\r\n</ng-template>", styles: ["@charset \"UTF-8\";:host{display:block;font-family:Segoe UI,Tahoma,Geneva,Verdana,sans-serif;width:100%;max-width:320px;background:#fff}.filter-container{display:flex;flex-direction:column;border:1px solid #e0e0e0;border-radius:4px;background-color:#fff}.filter-header{display:flex;align-items:center;justify-content:space-between;padding:6px 10px;border-bottom:1px solid #f0f0f0}.filter-label{font-size:13px;font-weight:600;color:#252423}.header-actions{display:flex;gap:4px}.icon-btn{background:none;border:none;cursor:pointer;font-size:12px;color:#605e5c;padding:2px 4px;border-radius:2px}.icon-btn:hover{background-color:#f3f2f1}.tree-scroll-container{max-height:220px;overflow-y:auto;padding:4px 0}.tree-level{display:flex;flex-direction:column}.tree-node-row{display:flex;align-items:center;height:28px;cursor:pointer;-webkit-user-select:none;user-select:none;gap:6px;transition:background-color .1s ease}.tree-node-row:hover{background-color:#f3f2f1}.tree-node-row.selected{background-color:#e1dfdd}.chevron-icon{display:inline-flex;align-items:center;justify-content:center;width:16px;height:16px;font-size:10px;color:#323130}.chevron-spacer{width:16px}.radio-circle{width:14px;height:14px;border-radius:50%;border:1.5px solid #605e5c;display:flex;align-items:center;justify-content:center;box-sizing:border-box;background-color:#fff}.radio-circle.checked{border-color:#0078d4}.radio-circle.checked .radio-inner{width:6px;height:6px;border-radius:50%;background-color:#0078d4}.node-label{font-size:13px;color:#323130;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.tree-scroll-container::-webkit-scrollbar{width:6px}.tree-scroll-container::-webkit-scrollbar-track{background:#f1f1f1}.tree-scroll-container::-webkit-scrollbar-thumb{background:#8a8886;border-radius:3px}\n"] }]
|
|
3888
|
+
}], ctorParameters: () => [], propDecorators: { idComponent: [{
|
|
3889
|
+
type: Input
|
|
3890
|
+
}], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], clearTitleLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "clearTitleLabel", required: false }] }], rawData: [{ type: i0.Input, args: [{ isSignal: true, alias: "rawData", required: false }] }], dataType: [{ type: i0.Input, args: [{ isSignal: true, alias: "dataType", required: false }] }], minDate: [{ type: i0.Input, args: [{ isSignal: true, alias: "minDate", required: false }] }], maxDate: [{ type: i0.Input, args: [{ isSignal: true, alias: "maxDate", required: false }] }], dateHierarchyType: [{ type: i0.Input, args: [{ isSignal: true, alias: "dateHierarchyType", required: false }] }], monthNames: [{ type: i0.Input, args: [{ isSignal: true, alias: "monthNames", required: false }] }], selectionChange: [{ type: i0.Output, args: ["selectionChange"] }], filterValueChange: [{ type: i0.Output, args: ["filterValueChange"] }], currentSelectedId: [{ type: i0.Input, args: [{ isSignal: true, alias: "currentSelectedId", required: false }] }] } });
|
|
3891
|
+
|
|
3892
|
+
class YwDashboardFilterWidgetComponent {
|
|
3893
|
+
constructor() {
|
|
3894
|
+
this.componentWidgetId = '';
|
|
3895
|
+
this.typeComponent = '';
|
|
3896
|
+
this.varShowConfigButtons = false;
|
|
3897
|
+
this.configWidget = {
|
|
3898
|
+
widgetId: '',
|
|
3899
|
+
label: '',
|
|
3900
|
+
typeComponent: '',
|
|
3901
|
+
controlTable: '',
|
|
3921
3902
|
};
|
|
3922
|
-
|
|
3923
|
-
|
|
3924
|
-
this.
|
|
3925
|
-
|
|
3926
|
-
|
|
3927
|
-
|
|
3928
|
-
|
|
3929
|
-
|
|
3930
|
-
|
|
3903
|
+
this.controlConfig = input(...(ngDevMode ? [undefined, { debugName: "controlConfig" }] : []));
|
|
3904
|
+
this.controlData = [];
|
|
3905
|
+
this.eventDeleteRequest = output();
|
|
3906
|
+
this.eventShowConfigFormRequest = output();
|
|
3907
|
+
this.selectionChange = output();
|
|
3908
|
+
effect(() => {
|
|
3909
|
+
const value_controlConfig = this.fnFormatConfigData();
|
|
3910
|
+
this.dataWidget = { idComponent: this.componentWidgetId,
|
|
3911
|
+
configWidget: this.configWidget,
|
|
3912
|
+
controlConfig: value_controlConfig
|
|
3913
|
+
};
|
|
3914
|
+
});
|
|
3931
3915
|
}
|
|
3932
|
-
|
|
3933
|
-
|
|
3934
|
-
this.
|
|
3935
|
-
const
|
|
3936
|
-
this.
|
|
3937
|
-
|
|
3938
|
-
|
|
3916
|
+
ngOnInit() {
|
|
3917
|
+
this.componentWidgetId = this.configWidget.widgetId;
|
|
3918
|
+
this.typeComponent = this.configWidget.typeComponent;
|
|
3919
|
+
const value_controlConfig = this.fnFormatConfigData();
|
|
3920
|
+
this.dataWidget = { idComponent: this.componentWidgetId,
|
|
3921
|
+
configWidget: this.configWidget,
|
|
3922
|
+
controlConfig: value_controlConfig
|
|
3923
|
+
};
|
|
3939
3924
|
}
|
|
3940
|
-
|
|
3941
|
-
|
|
3942
|
-
|
|
3943
|
-
|
|
3944
|
-
|
|
3945
|
-
|
|
3946
|
-
|
|
3947
|
-
|
|
3948
|
-
|
|
3949
|
-
|
|
3925
|
+
/*
|
|
3926
|
+
Los Datos a este componente llegan a un nivel basico, sin embargo es necesario configurar la informacion, para que se adapte a los componentes.
|
|
3927
|
+
*/
|
|
3928
|
+
fnFormatConfigData() {
|
|
3929
|
+
let responsedata = {};
|
|
3930
|
+
const typeComponent = this.configWidget.typeComponent;
|
|
3931
|
+
if (typeComponent == 'filter-slicer') {
|
|
3932
|
+
const dataType = this.controlConfig().dataType;
|
|
3933
|
+
const currentData = this.controlConfig();
|
|
3934
|
+
if (dataType == 'date') {
|
|
3935
|
+
const fieldName = this.controlConfig().filterField;
|
|
3936
|
+
const fechas = this.controlData.map((d) => new Date(d[fieldName]).getTime());
|
|
3937
|
+
const val_min = new Date(Math.min(...fechas)).toISOString().split("T")[0];
|
|
3938
|
+
const val_max = new Date(Math.max(...fechas)).toISOString().split("T")[0];
|
|
3939
|
+
responsedata = { dataType: dataType, min: val_min, max: val_max, minCurrent: currentData?.minCurrent, maxCurrent: currentData?.maxCurrent };
|
|
3940
|
+
}
|
|
3941
|
+
if (dataType == 'number') {
|
|
3942
|
+
const fieldName = this.controlConfig().filterField;
|
|
3943
|
+
const valStep = this.controlConfig().step;
|
|
3944
|
+
const DataNumbers = this.controlData.map((d) => d[fieldName]);
|
|
3945
|
+
const val_min = Math.min(...DataNumbers);
|
|
3946
|
+
const val_max = Math.max(...DataNumbers);
|
|
3947
|
+
responsedata = { dataType: dataType, min: val_min, max: val_max, step: valStep, minCurrent: currentData?.minCurrent, maxCurrent: currentData?.maxCurrent };
|
|
3948
|
+
}
|
|
3949
|
+
}
|
|
3950
|
+
if (typeComponent == 'filter-button') {
|
|
3951
|
+
const fieldName = this.controlConfig().filterField;
|
|
3952
|
+
const fieldNameId = this.controlConfig().filterFieldId;
|
|
3953
|
+
const val_allowMultiple = this.controlConfig().allowMultiple;
|
|
3954
|
+
const currentData = this.controlConfig();
|
|
3955
|
+
let listoptions = this.controlData.map((item) => { return { 'id': item[fieldNameId], 'label': item[fieldName] }; });
|
|
3956
|
+
const listoptionsunicos = [...new Map(listoptions.map(d => [d.id, d])).values()];
|
|
3957
|
+
responsedata = { options: listoptionsunicos, allowMultiple: val_allowMultiple, currentIds: currentData?.currentIds };
|
|
3958
|
+
}
|
|
3959
|
+
if (typeComponent == 'filter-list') {
|
|
3960
|
+
const dataType = this.controlConfig().dataType;
|
|
3961
|
+
const currentData = this.controlConfig();
|
|
3962
|
+
if (dataType == 'date') {
|
|
3963
|
+
const fieldName = this.controlConfig().filterField;
|
|
3964
|
+
const val_dateHierarchyType = this.controlConfig().dateHierarchyType;
|
|
3965
|
+
const fechas = this.controlData.map((d) => new Date(d[fieldName]).getTime());
|
|
3966
|
+
const val_min = new Date(Math.min(...fechas)).toISOString().split("T")[0];
|
|
3967
|
+
const val_max = new Date(Math.max(...fechas)).toISOString().split("T")[0];
|
|
3968
|
+
responsedata = { dataType: dataType, minDate: val_min, maxDate: val_max, dateHierarchyType: val_dateHierarchyType, currentSelectedId: currentData.currentSelectedId };
|
|
3969
|
+
}
|
|
3970
|
+
if (dataType == 'text') {
|
|
3971
|
+
const fieldName1 = this.controlConfig().filterField;
|
|
3972
|
+
const fieldName2 = this.controlConfig().filterFieldN2;
|
|
3973
|
+
const fieldName3 = this.controlConfig().filterFieldN3;
|
|
3974
|
+
let foundN2 = false;
|
|
3975
|
+
let foundN3 = false;
|
|
3976
|
+
let lsizeN2 = 0;
|
|
3977
|
+
let lsizeN3 = 0;
|
|
3978
|
+
let nodebase = { id: '', label: '' };
|
|
3979
|
+
let nodeN2 = { id: '', label: '' };
|
|
3980
|
+
let nodeN3 = { id: '', label: '' };
|
|
3981
|
+
let listNivel1 = [];
|
|
3982
|
+
let listNivel2 = [];
|
|
3983
|
+
let listNivel3 = [];
|
|
3984
|
+
this.controlData.forEach((item) => {
|
|
3985
|
+
nodebase = { id: item[fieldName1], label: item[fieldName1] };
|
|
3986
|
+
//NIVEL 2
|
|
3987
|
+
if (fieldName2) {
|
|
3988
|
+
foundN2 = false;
|
|
3989
|
+
lsizeN2 = Object.keys(listNivel2).length;
|
|
3990
|
+
for (let i = 0; i < lsizeN2; i++) {
|
|
3991
|
+
const itemN2 = listNivel2[i];
|
|
3992
|
+
if (itemN2.id == item[fieldName2]) {
|
|
3993
|
+
itemN2.children.push(nodebase);
|
|
3994
|
+
nodeN2 = itemN2;
|
|
3995
|
+
foundN2 = true;
|
|
3996
|
+
break;
|
|
3997
|
+
}
|
|
3998
|
+
}
|
|
3999
|
+
;
|
|
4000
|
+
if (foundN2 == false) {
|
|
4001
|
+
nodeN2 = { id: item[fieldName2], label: item[fieldName2], expanded: true, children: [nodebase] };
|
|
4002
|
+
if (fieldName3) {
|
|
4003
|
+
nodeN2.parentId = item[fieldName3];
|
|
4004
|
+
}
|
|
4005
|
+
listNivel2.push(nodeN2);
|
|
4006
|
+
}
|
|
4007
|
+
}
|
|
4008
|
+
else {
|
|
4009
|
+
listNivel1.push(nodebase);
|
|
4010
|
+
}
|
|
4011
|
+
});
|
|
4012
|
+
//NIVEL 1 - Basico no hay Jerarquia
|
|
4013
|
+
responsedata = { dataType: dataType, rawData: listNivel1, currentSelectedId: currentData.currentSelectedId };
|
|
4014
|
+
//NIVEL 2 - Jerarquia de 2 niveles
|
|
4015
|
+
if (fieldName2) {
|
|
4016
|
+
responsedata = { dataType: dataType, rawData: listNivel2, currentSelectedId: currentData.currentSelectedId };
|
|
4017
|
+
}
|
|
4018
|
+
//NIVEL 3 - Jerarquia de 3 niveles
|
|
4019
|
+
if (fieldName3) {
|
|
4020
|
+
listNivel2.forEach((item) => {
|
|
4021
|
+
nodebase = item;
|
|
4022
|
+
foundN3 = false;
|
|
4023
|
+
lsizeN3 = Object.keys(listNivel3).length;
|
|
4024
|
+
for (let i = 0; i < lsizeN3; i++) {
|
|
4025
|
+
const itemN3 = listNivel3[i];
|
|
4026
|
+
if (itemN3.id == item.parentId) {
|
|
4027
|
+
itemN3.children.push(nodebase);
|
|
4028
|
+
foundN3 = true;
|
|
4029
|
+
break;
|
|
4030
|
+
}
|
|
4031
|
+
}
|
|
4032
|
+
;
|
|
4033
|
+
if (foundN3 == false) {
|
|
4034
|
+
nodeN3 = { id: item[fieldName3], label: item[fieldName3], expanded: true, children: [nodebase] };
|
|
4035
|
+
listNivel3.push(nodeN3);
|
|
4036
|
+
}
|
|
4037
|
+
});
|
|
4038
|
+
responsedata = { dataType: dataType, rawData: listNivel3, currentSelectedId: currentData.currentSelectedId };
|
|
4039
|
+
}
|
|
4040
|
+
}
|
|
4041
|
+
}
|
|
4042
|
+
return responsedata;
|
|
3950
4043
|
}
|
|
3951
|
-
|
|
3952
|
-
|
|
3953
|
-
|
|
3954
|
-
|
|
3955
|
-
newControlConfig['provider'] = 'syncfusion';
|
|
3956
|
-
this.eventUpdateWidgetControlConfig(idWidget, newControlConfig);
|
|
4044
|
+
//Filtro Slicer
|
|
4045
|
+
onFilterSlicerChange(range) {
|
|
4046
|
+
console.log('Filtro actualizado:', range);
|
|
4047
|
+
this.selectionChange.emit({ widgetId: this.componentWidgetId, eventResponse: range });
|
|
3957
4048
|
}
|
|
3958
|
-
|
|
3959
|
-
|
|
3960
|
-
|
|
3961
|
-
|
|
3962
|
-
newControlData = [
|
|
3963
|
-
{ month: 'Ene', sales: 35, expenses: 28 },
|
|
3964
|
-
{ month: 'Feb', sales: 28, expenses: 22 },
|
|
3965
|
-
{ month: 'Mar', sales: 34, expenses: 25 },
|
|
3966
|
-
{ month: 'Abr', sales: 32, expenses: 27 },
|
|
3967
|
-
{ month: 'May', sales: 40, expenses: 30 },
|
|
3968
|
-
{ month: 'Jun', sales: 32, expenses: 26 },
|
|
3969
|
-
{ month: 'Jul', sales: 45, expenses: 32 },
|
|
3970
|
-
{ month: 'Ago', sales: 38, expenses: 29 },
|
|
3971
|
-
{ month: 'Sep', sales: 42, expenses: 31 },
|
|
3972
|
-
{ month: 'Oct', sales: 48, expenses: 35 },
|
|
3973
|
-
{ month: 'Nov', sales: 52, expenses: 38 },
|
|
3974
|
-
{ month: 'Dic', sales: 58, expenses: 42 },
|
|
3975
|
-
];
|
|
3976
|
-
this.eventUpdateWidgetControlData(idWidget, newControlData);
|
|
4049
|
+
//Filtro Button
|
|
4050
|
+
onFilterButtonChange(selectedIds) {
|
|
4051
|
+
console.log('Tipos seleccionados:', selectedIds);
|
|
4052
|
+
this.selectionChange.emit({ widgetId: this.componentWidgetId, eventResponse: selectedIds });
|
|
3977
4053
|
}
|
|
3978
|
-
|
|
3979
|
-
|
|
3980
|
-
|
|
3981
|
-
//
|
|
3982
|
-
|
|
3983
|
-
// 2. Obtener el contenedor interno generado por Gridstack
|
|
3984
|
-
const contentElement = el.querySelector('.grid-stack-item-content');
|
|
3985
|
-
if (contentElement) {
|
|
3986
|
-
// 3. Crear dinámicamente la instancia del componente Angular
|
|
3987
|
-
const componentRef = createComponent(YwDashboardWidgetComponent, {
|
|
3988
|
-
environmentInjector: this.environmentInjector, // Requerido para resolver dependencias
|
|
3989
|
-
hostElement: contentElement // Renderiza directamente aquí dentro
|
|
3990
|
-
});
|
|
3991
|
-
// 4. Pasar las propiedades/Inputs al componente creado
|
|
3992
|
-
//Evaluar Estilos
|
|
3993
|
-
componentRef.setInput('styleWidget', widgetConfig.widgetStyle);
|
|
3994
|
-
//componentRef.instance.configWidget = widgetConfig;
|
|
3995
|
-
componentRef.setInput('configWidget', widgetConfig);
|
|
3996
|
-
componentRef.setInput('controlConfig', controlConfig);
|
|
3997
|
-
componentRef.setInput('controlData', controlData);
|
|
3998
|
-
/* BEGIN - Eventos que provienen desde widget */
|
|
3999
|
-
componentRef.instance.eventDeleteRequest.subscribe((idWidget) => {
|
|
4000
|
-
// Ejecutamos la función de borrado que ya programamos en el paso anterior
|
|
4001
|
-
this.eventRemoveWidgetById(idWidget);
|
|
4002
|
-
});
|
|
4003
|
-
componentRef.instance.eventLockToggleRequest.subscribe((event) => {
|
|
4004
|
-
this.eventToggleLockWidget(event.widgetId, event.shouldLock);
|
|
4005
|
-
});
|
|
4006
|
-
componentRef.instance.eventMaximizeToggleRequest.subscribe((event) => {
|
|
4007
|
-
this.eventToggleMaximizeWidget(event.widgetId, event.shouldMaximize);
|
|
4008
|
-
});
|
|
4009
|
-
//Mostrar
|
|
4010
|
-
componentRef.instance.eventShowConfigFormRequest.subscribe((idWidget) => {
|
|
4011
|
-
this.eventShowFormConfigWidget(idWidget);
|
|
4012
|
-
});
|
|
4013
|
-
/* END - Eventos que provienen desde widget */
|
|
4014
|
-
// 5. Mover los nodos del DOM generados por Angular dentro del DIV del Widget
|
|
4015
|
-
this.appRef.attachView(componentRef.hostView);
|
|
4016
|
-
// Guardar la referencia de Componentes para hacer operaciones con estas.
|
|
4017
|
-
this.widgetsActivos.set(item.id, componentRef);
|
|
4018
|
-
//El componente interno no aparece bien dimensionado, con esto disparamos el evento para que se ajuste a las dimenciones correctas
|
|
4019
|
-
setTimeout(() => {
|
|
4020
|
-
window.dispatchEvent(new Event('resize'));
|
|
4021
|
-
}, 50);
|
|
4022
|
-
}
|
|
4054
|
+
//Filtro Lista - 1
|
|
4055
|
+
onFilterListChange(selectedData) {
|
|
4056
|
+
console.log('Tipos seleccionados:', selectedData);
|
|
4057
|
+
// Filtrar la información del dashboard
|
|
4058
|
+
//this.selectionChange.emit({widgetId:this.componentWidgetId,eventResponse:selectedData});
|
|
4023
4059
|
}
|
|
4024
|
-
|
|
4025
|
-
|
|
4026
|
-
|
|
4027
|
-
|
|
4028
|
-
if (!componentRef) {
|
|
4029
|
-
console.warn(`No se encontró un widget activo con el ID: ${idWidget}`);
|
|
4060
|
+
//Filtro Lista - 2
|
|
4061
|
+
onFilterListCalculated(data) {
|
|
4062
|
+
if (!data) {
|
|
4063
|
+
this.selectionChange.emit({ widgetId: this.componentWidgetId, eventResponse: null });
|
|
4030
4064
|
return;
|
|
4031
4065
|
}
|
|
4032
|
-
|
|
4033
|
-
|
|
4034
|
-
|
|
4035
|
-
|
|
4036
|
-
|
|
4037
|
-
|
|
4038
|
-
|
|
4039
|
-
eventUpdateWidgetControlData(idWidget, newControlData) {
|
|
4040
|
-
//Obtener la referencia del componente almacenada en el Map
|
|
4041
|
-
const componentRef = this.widgetsActivos.get(idWidget);
|
|
4042
|
-
if (!componentRef) {
|
|
4043
|
-
console.warn(`No se encontró un widget activo con el ID: ${idWidget}`);
|
|
4044
|
-
return;
|
|
4066
|
+
if (data.type === 'DATE_RANGE') {
|
|
4067
|
+
//console.log('Rango a filtrar en SQL/Dashboard:', data.dateRange?.minDate, 'hasta', data.dateRange?.maxDate);
|
|
4068
|
+
this.selectionChange.emit({ widgetId: this.componentWidgetId, eventResponse: { minDate: data.dateRange?.minDate, maxDate: data.dateRange?.maxDate, currentNodeId: data.currentNodeId } });
|
|
4069
|
+
}
|
|
4070
|
+
else if (data.type === 'TEXT_LEAVES') {
|
|
4071
|
+
//console.log('Lista de elementos terminales seleccionados:', data.leafIds);
|
|
4072
|
+
this.selectionChange.emit({ widgetId: this.componentWidgetId, eventResponse: { ids: data.leafIds, currentNodeId: data.currentNodeId } });
|
|
4045
4073
|
}
|
|
4046
|
-
//Actualizar el Input usando la API oficial setInput
|
|
4047
|
-
componentRef.setInput('controlData', newControlData);
|
|
4048
|
-
// NOTA: setInput dispara automáticamente la detección de cambios (ChangeDetectionStrategy.OnPush).
|
|
4049
|
-
// Si deseas asegurarte manualmente, puedes forzar un render:
|
|
4050
|
-
componentRef.changeDetectorRef.detectChanges();
|
|
4051
|
-
}
|
|
4052
|
-
/****************************************************** */
|
|
4053
|
-
/* BEGIN - DRAWER */
|
|
4054
|
-
handleShowFormFilterDrawer() {
|
|
4055
|
-
this.drawerfiltervisible = true;
|
|
4056
4074
|
}
|
|
4057
|
-
|
|
4058
|
-
this.drawerfiltervisible = false;
|
|
4075
|
+
onDeleteClick() {
|
|
4059
4076
|
}
|
|
4060
|
-
|
|
4061
|
-
this.drawerconfigvisible = false;
|
|
4077
|
+
onShowFormConfigClick() {
|
|
4062
4078
|
}
|
|
4063
|
-
|
|
4064
|
-
|
|
4065
|
-
|
|
4066
|
-
|
|
4067
|
-
|
|
4068
|
-
|
|
4069
|
-
|
|
4070
|
-
|
|
4071
|
-
|
|
4072
|
-
|
|
4079
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.30", ngImport: i0, type: YwDashboardFilterWidgetComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
4080
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.30", type: YwDashboardFilterWidgetComponent, isStandalone: true, selector: "yw-dashboard-filter-widget", inputs: { configWidget: { classPropertyName: "configWidget", publicName: "configWidget", isSignal: false, isRequired: false, transformFunction: null }, controlConfig: { classPropertyName: "controlConfig", publicName: "controlConfig", isSignal: true, isRequired: false, transformFunction: null }, controlData: { classPropertyName: "controlData", publicName: "controlData", isSignal: false, isRequired: false, transformFunction: null } }, outputs: { eventDeleteRequest: "eventDeleteRequest", eventShowConfigFormRequest: "eventShowConfigFormRequest", selectionChange: "selectionChange" }, ngImport: i0, template: "\r\n<div class=\"widget-filter-action-bar\"> \r\n <button [hidden]=\"!varShowConfigButtons\" class=\"btn-delete\" (click)=\"onDeleteClick()\">\uD83D\uDDD1\uFE0F</button>\r\n <button [hidden]=\"!varShowConfigButtons\" class=\"btn-config\" (click)=\"onShowFormConfigClick()\">\u2699\uFE0F</button>\r\n</div>\r\n<div class=\"widget-filter-content-wrapper\">\r\n @if ( typeComponent == 'empty-visual' ) { \r\n <ng-container *ngTemplateOutlet=\"emptyvisual; context: { control: dataWidget }\"></ng-container>\r\n }\r\n @if ( typeComponent == 'filter-slicer' ) { \r\n <ng-container *ngTemplateOutlet=\"filterslicer; context: { control: dataWidget }\"></ng-container>\r\n }\r\n @if ( typeComponent == 'filter-button' ) { \r\n <ng-container *ngTemplateOutlet=\"filterbutton; context: { control: dataWidget }\"></ng-container>\r\n }\r\n @if ( typeComponent == 'filter-list' ) { \r\n <ng-container *ngTemplateOutlet=\"filterlist; context: { control: dataWidget }\"></ng-container>\r\n } \r\n \r\n</div>\r\n\r\n\r\n<!--------------------------------------------------------------->\r\n<!---------------------- EMPTY VISUAL TEMPLATE ---------------------->\r\n<!--------------------------------------------------------------->\r\n<ng-template #emptyvisual let-control = \"control\">\r\n <yw-empty-visual [idComponent]=\"control.idComponent\"\r\n [config]=\"control.controlConfig\" \r\n > \r\n </yw-empty-visual>\r\n</ng-template>\r\n\r\n<!--------------------------------------------------------------->\r\n<!---------------------- FILTER SLICER TEMPLATE ---------------------->\r\n<!--------------------------------------------------------------->\r\n<ng-template #filterslicer let-control = \"control\"> \r\n @if (control.controlConfig.dataType === 'date') { \r\n <yw-base-slicer [idComponent]=\"control.idComponent\"\r\n [dataType]=\"control.controlConfig.dataType\"\r\n [label]=\"control.configWidget.label\"\r\n [min]=\"control.controlConfig.min\"\r\n [max]=\"control.controlConfig.max\" \r\n [minCurrent]=\"control.controlConfig.minCurrent\"\r\n [maxCurrent]=\"control.controlConfig.maxCurrent\" \r\n (rangeChange)=\"onFilterSlicerChange($event)\"\r\n >\r\n </yw-base-slicer>\r\n }\r\n @if (control.controlConfig.dataType === 'number') { \r\n <yw-base-slicer [idComponent]=\"control.idComponent\"\r\n [dataType]=\"control.controlConfig.dataType\"\r\n [label]=\"control.configWidget.label\"\r\n [min]=\"control.controlConfig.min\"\r\n [max]=\"control.controlConfig.max\"\r\n [minCurrent]=\"control.controlConfig.minCurrent\"\r\n [maxCurrent]=\"control.controlConfig.maxCurrent\"\r\n [step]=\"control.controlConfig.step\"\r\n (rangeChange)=\"onFilterSlicerChange($event)\"\r\n >\r\n </yw-base-slicer>\r\n }\r\n</ng-template>\r\n\r\n<!--------------------------------------------------------------->\r\n<!---------------------- FILTER BUTTON TEMPLATE ---------------------->\r\n<!--------------------------------------------------------------->\r\n<ng-template #filterbutton let-control = \"control\"> \r\n <yw-button-slicer [idComponent]=\"control.idComponent\" \r\n [label]=\"control.configWidget.label\"\r\n [options]=\"control.controlConfig.options\"\r\n [allowMultiple]=\"control.controlConfig.allowMultiple\"\r\n [currentIds]=\"control.controlConfig.currentIds\"\r\n (selectionChange)=\"onFilterButtonChange($event)\" \r\n >\r\n </yw-button-slicer>\r\n</ng-template>\r\n\r\n\r\n<!--------------------------------------------------------------->\r\n<!---------------------- FILTER LIST TEMPLATE ---------------------->\r\n<!--------------------------------------------------------------->\r\n<ng-template #filterlist let-control = \"control\"> \r\n \r\n @if (control.controlConfig.dataType === 'date') { \r\n <yw-list-slicer [idComponent]=\"control.idComponent\" \r\n [label]=\"control.configWidget.label\"\r\n [dataType]=\"control.controlConfig.dataType\"\r\n [minDate]=\"control.controlConfig.minDate\"\r\n [maxDate]=\"control.controlConfig.maxDate\"\r\n [dateHierarchyType]=\"control.controlConfig.dateHierarchyType\"\r\n [currentSelectedId]=\"control.controlConfig.currentSelectedId\"\r\n (selectionChange)=\"onFilterListChange($event)\"\r\n (filterValueChange)=\"onFilterListCalculated($event)\" \r\n >\r\n </yw-list-slicer>\r\n }\r\n\r\n\r\n @if (control.controlConfig.dataType === 'text') { \r\n <yw-list-slicer [idComponent]=\"control.idComponent\"\r\n [label]=\"control.configWidget.label\"\r\n [dataType]=\"control.controlConfig.dataType\"\r\n [rawData]=\"control.controlConfig.rawData\"\r\n [currentSelectedId]=\"control.controlConfig.currentSelectedId\"\r\n (selectionChange)=\"onFilterListChange($event)\"\r\n (filterValueChange)=\"onFilterListCalculated($event)\" \r\n >\r\n </yw-list-slicer>\r\n }\r\n\r\n\r\n</ng-template>", styles: ["@charset \"UTF-8\";:host{display:flex;flex-direction:column;width:100%;box-sizing:border-box;background-color:var(--widget-bg, #ffffff);border:1px solid var(--widget-border-color, #040404);border-radius:var(--widget-border-radius, 8px);padding:var(--widget-padding, 10px)}:host *,:host *:before,:host *:after{box-sizing:border-box}.widget-filter-action-bar{display:flex;justify-content:flex-end;gap:4px;padding:5px 10px;flex-shrink:0;width:100%}.widget-filter-content-wrapper{width:100%;display:flex;flex-direction:column}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$2.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: YwEmptyVisualComponent, selector: "yw-empty-visual", inputs: ["idComponent", "config"] }, { kind: "component", type: YwBaseSlicerComponent, selector: "yw-base-slicer", inputs: ["idComponent", "dataType", "label", "min", "max", "step", "minCurrent", "maxCurrent"], outputs: ["rangeChange"] }, { kind: "component", type: YwButtonSlicerComponent, selector: "yw-button-slicer", inputs: ["idComponent", "label", "options", "allowMultiple", "currentIds"], outputs: ["selectionChange"] }, { kind: "component", type: YwListSlicerComponent, selector: "yw-list-slicer", inputs: ["idComponent", "label", "clearTitleLabel", "rawData", "dataType", "minDate", "maxDate", "dateHierarchyType", "monthNames", "currentSelectedId"], outputs: ["selectionChange", "filterValueChange"] }] }); }
|
|
4081
|
+
}
|
|
4082
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.30", ngImport: i0, type: YwDashboardFilterWidgetComponent, decorators: [{
|
|
4083
|
+
type: Component,
|
|
4084
|
+
args: [{ selector: 'yw-dashboard-filter-widget', standalone: true, imports: [CommonModule,
|
|
4085
|
+
YwEmptyVisualComponent,
|
|
4086
|
+
YwBaseSlicerComponent,
|
|
4087
|
+
YwButtonSlicerComponent,
|
|
4088
|
+
YwListSlicerComponent,
|
|
4089
|
+
], template: "\r\n<div class=\"widget-filter-action-bar\"> \r\n <button [hidden]=\"!varShowConfigButtons\" class=\"btn-delete\" (click)=\"onDeleteClick()\">\uD83D\uDDD1\uFE0F</button>\r\n <button [hidden]=\"!varShowConfigButtons\" class=\"btn-config\" (click)=\"onShowFormConfigClick()\">\u2699\uFE0F</button>\r\n</div>\r\n<div class=\"widget-filter-content-wrapper\">\r\n @if ( typeComponent == 'empty-visual' ) { \r\n <ng-container *ngTemplateOutlet=\"emptyvisual; context: { control: dataWidget }\"></ng-container>\r\n }\r\n @if ( typeComponent == 'filter-slicer' ) { \r\n <ng-container *ngTemplateOutlet=\"filterslicer; context: { control: dataWidget }\"></ng-container>\r\n }\r\n @if ( typeComponent == 'filter-button' ) { \r\n <ng-container *ngTemplateOutlet=\"filterbutton; context: { control: dataWidget }\"></ng-container>\r\n }\r\n @if ( typeComponent == 'filter-list' ) { \r\n <ng-container *ngTemplateOutlet=\"filterlist; context: { control: dataWidget }\"></ng-container>\r\n } \r\n \r\n</div>\r\n\r\n\r\n<!--------------------------------------------------------------->\r\n<!---------------------- EMPTY VISUAL TEMPLATE ---------------------->\r\n<!--------------------------------------------------------------->\r\n<ng-template #emptyvisual let-control = \"control\">\r\n <yw-empty-visual [idComponent]=\"control.idComponent\"\r\n [config]=\"control.controlConfig\" \r\n > \r\n </yw-empty-visual>\r\n</ng-template>\r\n\r\n<!--------------------------------------------------------------->\r\n<!---------------------- FILTER SLICER TEMPLATE ---------------------->\r\n<!--------------------------------------------------------------->\r\n<ng-template #filterslicer let-control = \"control\"> \r\n @if (control.controlConfig.dataType === 'date') { \r\n <yw-base-slicer [idComponent]=\"control.idComponent\"\r\n [dataType]=\"control.controlConfig.dataType\"\r\n [label]=\"control.configWidget.label\"\r\n [min]=\"control.controlConfig.min\"\r\n [max]=\"control.controlConfig.max\" \r\n [minCurrent]=\"control.controlConfig.minCurrent\"\r\n [maxCurrent]=\"control.controlConfig.maxCurrent\" \r\n (rangeChange)=\"onFilterSlicerChange($event)\"\r\n >\r\n </yw-base-slicer>\r\n }\r\n @if (control.controlConfig.dataType === 'number') { \r\n <yw-base-slicer [idComponent]=\"control.idComponent\"\r\n [dataType]=\"control.controlConfig.dataType\"\r\n [label]=\"control.configWidget.label\"\r\n [min]=\"control.controlConfig.min\"\r\n [max]=\"control.controlConfig.max\"\r\n [minCurrent]=\"control.controlConfig.minCurrent\"\r\n [maxCurrent]=\"control.controlConfig.maxCurrent\"\r\n [step]=\"control.controlConfig.step\"\r\n (rangeChange)=\"onFilterSlicerChange($event)\"\r\n >\r\n </yw-base-slicer>\r\n }\r\n</ng-template>\r\n\r\n<!--------------------------------------------------------------->\r\n<!---------------------- FILTER BUTTON TEMPLATE ---------------------->\r\n<!--------------------------------------------------------------->\r\n<ng-template #filterbutton let-control = \"control\"> \r\n <yw-button-slicer [idComponent]=\"control.idComponent\" \r\n [label]=\"control.configWidget.label\"\r\n [options]=\"control.controlConfig.options\"\r\n [allowMultiple]=\"control.controlConfig.allowMultiple\"\r\n [currentIds]=\"control.controlConfig.currentIds\"\r\n (selectionChange)=\"onFilterButtonChange($event)\" \r\n >\r\n </yw-button-slicer>\r\n</ng-template>\r\n\r\n\r\n<!--------------------------------------------------------------->\r\n<!---------------------- FILTER LIST TEMPLATE ---------------------->\r\n<!--------------------------------------------------------------->\r\n<ng-template #filterlist let-control = \"control\"> \r\n \r\n @if (control.controlConfig.dataType === 'date') { \r\n <yw-list-slicer [idComponent]=\"control.idComponent\" \r\n [label]=\"control.configWidget.label\"\r\n [dataType]=\"control.controlConfig.dataType\"\r\n [minDate]=\"control.controlConfig.minDate\"\r\n [maxDate]=\"control.controlConfig.maxDate\"\r\n [dateHierarchyType]=\"control.controlConfig.dateHierarchyType\"\r\n [currentSelectedId]=\"control.controlConfig.currentSelectedId\"\r\n (selectionChange)=\"onFilterListChange($event)\"\r\n (filterValueChange)=\"onFilterListCalculated($event)\" \r\n >\r\n </yw-list-slicer>\r\n }\r\n\r\n\r\n @if (control.controlConfig.dataType === 'text') { \r\n <yw-list-slicer [idComponent]=\"control.idComponent\"\r\n [label]=\"control.configWidget.label\"\r\n [dataType]=\"control.controlConfig.dataType\"\r\n [rawData]=\"control.controlConfig.rawData\"\r\n [currentSelectedId]=\"control.controlConfig.currentSelectedId\"\r\n (selectionChange)=\"onFilterListChange($event)\"\r\n (filterValueChange)=\"onFilterListCalculated($event)\" \r\n >\r\n </yw-list-slicer>\r\n }\r\n\r\n\r\n</ng-template>", styles: ["@charset \"UTF-8\";:host{display:flex;flex-direction:column;width:100%;box-sizing:border-box;background-color:var(--widget-bg, #ffffff);border:1px solid var(--widget-border-color, #040404);border-radius:var(--widget-border-radius, 8px);padding:var(--widget-padding, 10px)}:host *,:host *:before,:host *:after{box-sizing:border-box}.widget-filter-action-bar{display:flex;justify-content:flex-end;gap:4px;padding:5px 10px;flex-shrink:0;width:100%}.widget-filter-content-wrapper{width:100%;display:flex;flex-direction:column}\n"] }]
|
|
4090
|
+
}], ctorParameters: () => [], propDecorators: { configWidget: [{
|
|
4091
|
+
type: Input
|
|
4092
|
+
}], controlConfig: [{ type: i0.Input, args: [{ isSignal: true, alias: "controlConfig", required: false }] }], controlData: [{
|
|
4093
|
+
type: Input
|
|
4094
|
+
}], eventDeleteRequest: [{ type: i0.Output, args: ["eventDeleteRequest"] }], eventShowConfigFormRequest: [{ type: i0.Output, args: ["eventShowConfigFormRequest"] }], selectionChange: [{ type: i0.Output, args: ["selectionChange"] }] } });
|
|
4095
|
+
|
|
4096
|
+
class YwDashboardFilterComponent {
|
|
4097
|
+
constructor() {
|
|
4098
|
+
this.dashboardFilterConfig = {
|
|
4099
|
+
showConfigButtons: false,
|
|
4100
|
+
lockPositionWidgets: false,
|
|
4101
|
+
controlListConfig: []
|
|
4102
|
+
};
|
|
4103
|
+
this.dashboardData = [];
|
|
4104
|
+
this.filterSelectionChange = output();
|
|
4105
|
+
this.controlListConfig = [];
|
|
4073
4106
|
}
|
|
4074
|
-
|
|
4075
|
-
|
|
4076
|
-
|
|
4077
|
-
|
|
4078
|
-
const
|
|
4079
|
-
|
|
4080
|
-
|
|
4081
|
-
this.
|
|
4107
|
+
ngOnInit() {
|
|
4108
|
+
this.controlListConfig = [];
|
|
4109
|
+
this.dashboardFilterConfig.controlListConfig.forEach((item) => {
|
|
4110
|
+
const tableName = item.controlTable;
|
|
4111
|
+
const prmcontrolData = this.fn_getDataForWidgetFilterComponent(tableName, this.dashboardData);
|
|
4112
|
+
const prmconfigWidget = { ...item };
|
|
4113
|
+
if (item.controlFilterData) {
|
|
4114
|
+
item.configComponent = this.fnSetControlFilterCurrentValues(prmconfigWidget);
|
|
4082
4115
|
}
|
|
4083
|
-
|
|
4116
|
+
const configControl = { configWidget: prmconfigWidget,
|
|
4117
|
+
controlData: prmcontrolData,
|
|
4118
|
+
controlConfig: item.configComponent
|
|
4119
|
+
};
|
|
4120
|
+
this.controlListConfig.push(configControl);
|
|
4121
|
+
});
|
|
4084
4122
|
}
|
|
4085
|
-
|
|
4086
|
-
|
|
4087
|
-
|
|
4088
|
-
|
|
4089
|
-
|
|
4090
|
-
|
|
4091
|
-
|
|
4092
|
-
const minDate = item.controlFilterData['startDate'];
|
|
4093
|
-
const maxDate = item.controlFilterData['endDate'];
|
|
4094
|
-
if (minDate && maxDate) {
|
|
4095
|
-
const filterData = tableSelected.tableData.filter((y) => (minDate <= y[fieldName] && y[fieldName] <= maxDate));
|
|
4096
|
-
tableSelected.tableData = filterData;
|
|
4097
|
-
}
|
|
4098
|
-
}
|
|
4099
|
-
if (item.configComponent.dataType == 'number') {
|
|
4100
|
-
const minNum = Number(item.controlFilterData['minValue']);
|
|
4101
|
-
const maxNum = Number(item.controlFilterData['maxValue']);
|
|
4102
|
-
if (minNum && maxNum) {
|
|
4103
|
-
const filterData = tableSelected.tableData.filter((y) => (minNum <= y[fieldName] && y[fieldName] <= maxNum));
|
|
4104
|
-
tableSelected.tableData = filterData;
|
|
4105
|
-
}
|
|
4106
|
-
}
|
|
4107
|
-
}
|
|
4108
|
-
if (item.typeComponent == 'filter-button' && tableSelected && item.controlFilterData) {
|
|
4109
|
-
const fieldName = item.configComponent.filterField;
|
|
4110
|
-
const listValues = item.controlFilterData || [];
|
|
4111
|
-
if (listValues && listValues.length > 0) {
|
|
4112
|
-
const filterData = tableSelected.tableData.filter((y) => (listValues.includes(y[fieldName])));
|
|
4113
|
-
tableSelected.tableData = filterData;
|
|
4114
|
-
}
|
|
4115
|
-
}
|
|
4116
|
-
if (item.typeComponent == 'filter-list' && tableSelected && item.controlFilterData) {
|
|
4117
|
-
const fieldName = item.configComponent.filterField;
|
|
4118
|
-
if (item.configComponent.dataType == 'text') {
|
|
4119
|
-
const listValues = item.controlFilterData['ids'] || [];
|
|
4120
|
-
if (listValues && listValues.length > 0) {
|
|
4121
|
-
const listValues1D = listValues;
|
|
4122
|
-
const filterData = tableSelected.tableData.filter((y) => (listValues1D.includes(y[fieldName])));
|
|
4123
|
-
tableSelected.tableData = filterData;
|
|
4124
|
-
}
|
|
4125
|
-
}
|
|
4126
|
-
if (item.configComponent.dataType == 'date') {
|
|
4127
|
-
const minDate = item.controlFilterData['minDate'];
|
|
4128
|
-
const maxDate = item.controlFilterData['maxDate'];
|
|
4129
|
-
if (minDate && maxDate) {
|
|
4130
|
-
const filterData = tableSelected.tableData.filter((y) => (minDate <= y[fieldName] && y[fieldName] <= maxDate));
|
|
4131
|
-
tableSelected.tableData = filterData;
|
|
4132
|
-
}
|
|
4133
|
-
}
|
|
4123
|
+
//Filtrar Datos por Componente del Widget
|
|
4124
|
+
fn_getDataForWidgetFilterComponent(prmTableName, prmdashboardData) {
|
|
4125
|
+
let dataresponse = [];
|
|
4126
|
+
const ldsize = prmdashboardData.length;
|
|
4127
|
+
prmdashboardData.forEach((curTableRef) => {
|
|
4128
|
+
if (prmTableName.localeCompare(curTableRef.tableName) == 0) {
|
|
4129
|
+
dataresponse = curTableRef.tableData;
|
|
4134
4130
|
}
|
|
4135
4131
|
});
|
|
4136
|
-
|
|
4137
|
-
this.dashboardConfig.controlListConfig.forEach((item) => {
|
|
4138
|
-
const controlData = this.fn_getDataForWidgetComponent(item.controlTables, copyDashboardData);
|
|
4139
|
-
this.eventUpdateWidgetControlData(item.widgetId, controlData);
|
|
4140
|
-
});
|
|
4132
|
+
return dataresponse;
|
|
4141
4133
|
}
|
|
4142
|
-
|
|
4143
|
-
|
|
4144
|
-
|
|
4145
|
-
|
|
4146
|
-
|
|
4147
|
-
|
|
4148
|
-
|
|
4149
|
-
|
|
4150
|
-
|
|
4134
|
+
onFilterChange(eventData) {
|
|
4135
|
+
this.filterSelectionChange.emit({ widgetId: eventData.widgetId, eventResponse: eventData.eventResponse });
|
|
4136
|
+
}
|
|
4137
|
+
fnSetControlFilterCurrentValues(prmControlConfig) {
|
|
4138
|
+
if (prmControlConfig.typeComponent == 'filter-slicer') {
|
|
4139
|
+
let curConfigComponent = prmControlConfig.configComponent;
|
|
4140
|
+
if (prmControlConfig.configComponent.dataType == 'date') {
|
|
4141
|
+
curConfigComponent.minCurrent = prmControlConfig.controlFilterData['startDate'];
|
|
4142
|
+
curConfigComponent.maxCurrent = prmControlConfig.controlFilterData['endDate'];
|
|
4143
|
+
}
|
|
4144
|
+
if (prmControlConfig.configComponent.dataType == 'number') {
|
|
4145
|
+
curConfigComponent.minCurrent = prmControlConfig.controlFilterData['minValue'];
|
|
4146
|
+
curConfigComponent.maxCurrent = prmControlConfig.controlFilterData['maxValue'];
|
|
4147
|
+
}
|
|
4148
|
+
return curConfigComponent;
|
|
4151
4149
|
}
|
|
4152
|
-
|
|
4153
|
-
|
|
4154
|
-
|
|
4155
|
-
|
|
4156
|
-
this.appRef.detachView(componentRef.hostView);
|
|
4157
|
-
// Destruye el componente y libera la memoria RAM
|
|
4158
|
-
componentRef.destroy();
|
|
4159
|
-
// Eliminamos el registro de nuestro Mapa
|
|
4160
|
-
this.widgetsActivos.delete(widgetId);
|
|
4150
|
+
if (prmControlConfig.typeComponent == 'filter-button') {
|
|
4151
|
+
let curConfigComponent = prmControlConfig.configComponent;
|
|
4152
|
+
curConfigComponent.currentIds = prmControlConfig.controlFilterData || [];
|
|
4153
|
+
return curConfigComponent;
|
|
4161
4154
|
}
|
|
4162
|
-
|
|
4163
|
-
|
|
4164
|
-
|
|
4165
|
-
|
|
4166
|
-
if (elementoHtml) {
|
|
4167
|
-
// La API de Gridstack nos permite congelar un nodo específico pasándole true/false
|
|
4168
|
-
this.grid.movable(elementoHtml, !shouldLock);
|
|
4169
|
-
this.grid.resizable(elementoHtml, !shouldLock);
|
|
4170
|
-
//console.log(`Widget ${widgetId} cambiado a estado bloqueado: ${shouldLock}`);
|
|
4155
|
+
if (prmControlConfig.typeComponent == 'filter-list') {
|
|
4156
|
+
let curConfigComponent = prmControlConfig.configComponent;
|
|
4157
|
+
curConfigComponent.currentSelectedId = prmControlConfig.controlFilterData['currentNodeId'];
|
|
4158
|
+
return curConfigComponent;
|
|
4171
4159
|
}
|
|
4172
4160
|
}
|
|
4173
|
-
|
|
4174
|
-
|
|
4175
|
-
|
|
4176
|
-
|
|
4177
|
-
|
|
4178
|
-
|
|
4179
|
-
|
|
4180
|
-
this.
|
|
4181
|
-
this.grid.resizable(elementoHtml, false);
|
|
4182
|
-
}
|
|
4183
|
-
else {
|
|
4184
|
-
elementoHtml.classList.remove('widget-maximized');
|
|
4185
|
-
// Restauramos los permisos normales leyendo si el componente de Angular estaba bloqueado previamente
|
|
4186
|
-
const componentRef = this.widgetsActivos.get(widgetId);
|
|
4187
|
-
const isCurrentlyLocked = componentRef?.instance.isLocked() || false;
|
|
4188
|
-
this.grid.movable(elementoHtml, !isCurrentlyLocked);
|
|
4189
|
-
this.grid.resizable(elementoHtml, !isCurrentlyLocked);
|
|
4161
|
+
handleClearFilter() {
|
|
4162
|
+
this.controlListConfig = [];
|
|
4163
|
+
this.dashboardFilterConfig.controlListConfig.forEach((item) => {
|
|
4164
|
+
const tableName = item.controlTable;
|
|
4165
|
+
const prmcontrolData = this.fn_getDataForWidgetFilterComponent(tableName, this.dashboardData);
|
|
4166
|
+
const prmconfigWidget = { ...item };
|
|
4167
|
+
if (item.controlFilterData) {
|
|
4168
|
+
item.configComponent = this.fnSetControlFilterClearValues(prmconfigWidget);
|
|
4190
4169
|
}
|
|
4191
|
-
|
|
4192
|
-
|
|
4193
|
-
|
|
4194
|
-
}
|
|
4195
|
-
|
|
4170
|
+
const configControl = { configWidget: prmconfigWidget,
|
|
4171
|
+
controlData: prmcontrolData,
|
|
4172
|
+
controlConfig: item.configComponent
|
|
4173
|
+
};
|
|
4174
|
+
this.controlListConfig.push(configControl);
|
|
4175
|
+
});
|
|
4196
4176
|
}
|
|
4197
|
-
|
|
4198
|
-
|
|
4199
|
-
|
|
4177
|
+
fnSetControlFilterClearValues(prmControlConfig) {
|
|
4178
|
+
if (prmControlConfig.typeComponent == 'filter-slicer') {
|
|
4179
|
+
let curConfigComponent = prmControlConfig.configComponent;
|
|
4180
|
+
curConfigComponent.minCurrent = null;
|
|
4181
|
+
curConfigComponent.maxCurrent = null;
|
|
4182
|
+
return curConfigComponent;
|
|
4183
|
+
}
|
|
4184
|
+
if (prmControlConfig.typeComponent == 'filter-button') {
|
|
4185
|
+
let curConfigComponent = prmControlConfig.configComponent;
|
|
4186
|
+
curConfigComponent.currentIds = [];
|
|
4187
|
+
return curConfigComponent;
|
|
4188
|
+
}
|
|
4189
|
+
if (prmControlConfig.typeComponent == 'filter-list') {
|
|
4190
|
+
let curConfigComponent = prmControlConfig.configComponent;
|
|
4191
|
+
curConfigComponent.currentSelectedId = null;
|
|
4192
|
+
return curConfigComponent;
|
|
4193
|
+
}
|
|
4200
4194
|
}
|
|
4201
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.30", ngImport: i0, type:
|
|
4202
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.30", type: YwDashboardComponent, isStandalone: true, selector: "yw-dashboard", inputs: { showControls: { classPropertyName: "showControls", publicName: "showControls", isSignal: true, isRequired: false, transformFunction: null }, showFilter: { classPropertyName: "showFilter", publicName: "showFilter", isSignal: true, isRequired: false, transformFunction: null }, dashboardStyle: { classPropertyName: "dashboardStyle", publicName: "dashboardStyle", isSignal: false, isRequired: false, transformFunction: null }, dashboardConfig: { classPropertyName: "dashboardConfig", publicName: "dashboardConfig", isSignal: false, isRequired: false, transformFunction: null }, dashboardData: { classPropertyName: "dashboardData", publicName: "dashboardData", isSignal: false, isRequired: false, transformFunction: null }, dashboardFilterConfig: { classPropertyName: "dashboardFilterConfig", publicName: "dashboardFilterConfig", isSignal: false, isRequired: false, transformFunction: null } }, viewQueries: [{ propertyName: "gridContainer", first: true, predicate: ["gridContainer"], descendants: true, static: true }], usesOnChanges: true, ngImport: i0, template: "<!-- <div class=\"controls\" [hidden]=\"!showControls()\">\r\n <button (click)=\"saveLayoutToJSON()\">Guardar JSON en Consola</button>\r\n <button (click)=\"fn_btn_addWidget()\">add widget</button>\r\n <button (click)=\"fn_btn_lockPositionWidgets()\">Lock widgets</button>\r\n <button (click)=\"handleShowFormFilterDrawer()\" class=\"btn-filtro\">\r\n <svg *ngIf=\"drawerfiltervisible; else filtroInactivo\" \r\n xmlns=\"http://www.w3.org/2000/svg\" \r\n width=\"20\" height=\"20\" \r\n viewBox=\"0 0 24 24\" \r\n fill=\"currentColor\">\r\n <path d=\"M10 18h4v-2h-4v2zM3 6v2h18V6H3zm3 7h12v-2H6v2z\"/>\r\n </svg>\r\n <ng-template #filtroInactivo>\r\n <svg xmlns=\"http://www.w3.org/2000/svg\" \r\n width=\"20\" height=\"20\" \r\n viewBox=\"0 0 24 24\" \r\n fill=\"none\" \r\n stroke=\"currentColor\" \r\n stroke-width=\"2\">\r\n <polygon points=\"22 3 2 3 10 12.46 10 19 14 21 14 12.46 22 3\"/>\r\n </svg>\r\n </ng-template>\r\n </button>\r\n</div> -->\r\n\r\n<div class=\"controls-container\" >\r\n @if ( showControls() ) { \r\n <!-- Botones principales con nz-button y tipos de Ant Design -->\r\n <button nz-button nzType=\"default\" (click)=\"saveLayoutToJSON()\" >\r\n <span nz-icon nz-type=\"code\"></span> Guardar JSON\r\n </button>\r\n\r\n <button nz-button nzType=\"primary\" (click)=\"fn_btn_addWidget()\" >\r\n <span nz-icon nz-type=\"plus\"></span> A\u00F1adir widget\r\n </button>\r\n\r\n <button nz-button [nzType]=\"isLocked ? 'primary' : 'default'\" nzDanger (click)=\"fn_btn_lockPositionWidgets()\" >\r\n <span nz-icon [nzType]=\"isLocked ? 'lock' : 'unlock'\"></span> \r\n {{ isLocked ? 'Bloqueado' : 'Bloquear' }}\r\n </button>\r\n }\r\n @if ( showFilter() ) { \r\n <!-- Bot\u00F3n de filtro con estilo ic\u00F3nico -->\r\n <button nz-button nzType=\"default\" nzShape=\"circle\" (click)=\"handleShowFormFilterDrawer()\" class=\"btn-filtro\" [class.active]=\"drawerfiltervisible\" >\r\n <svg *ngIf=\"drawerfiltervisible; else filtroInactivo\" \r\n xmlns=\"http://www.w3.org/2000/svg\" \r\n width=\"16\" height=\"16\" \r\n viewBox=\"0 0 24 24\" \r\n fill=\"currentColor\">\r\n <path d=\"M10 18h4v-2h-4v2zM3 6v2h18V6H3zm3 7h12v-2H6v2z\"/>\r\n </svg>\r\n <ng-template #filtroInactivo>\r\n <svg xmlns=\"http://www.w3.org/2000/svg\" \r\n width=\"16\" height=\"16\" \r\n viewBox=\"0 0 24 24\" \r\n fill=\"none\" \r\n stroke=\"currentColor\" \r\n stroke-width=\"2\">\r\n <polygon points=\"22 3 2 3 10 12.46 10 19 14 21 14 12.46 22 3\"/>\r\n </svg>\r\n </ng-template>\r\n </button>\r\n }\r\n</div>\r\n<div #gridContainer class=\"grid-stack canvas-container\"\r\n [style.--canvas-bg]=\"dashboardStyle.canvasBackgroundColor\"\r\n></div>\r\n\r\n\r\n\r\n\r\n<!-- DRAWER - FILTER -->\r\n\r\n<nz-drawer\r\n[nzVisible]=\"drawerfiltervisible\"\r\n[nzMaskClosable]=\"false\"\r\nnzPlacement=\"right\"\r\n[nzWidth]=\"fnGetDrawerWidth(50)\"\r\n(nzOnClose)=\"handleCloseFormFilterDrawer()\"\r\n>\r\n<ng-container *nzDrawerContent>\r\n <div class=\"widget-details-info\">\r\n <h6 nz-typography>Filtros</h6>\r\n <yw-dashboard-filter\r\n [dashboardFilterConfig]=\"dashboardFilterConfig\"\r\n [dashboardData]=\"dashboardData\"\r\n (filterSelectionChange)=\"onFilterSelectionChange($event)\"\r\n >\r\n </yw-dashboard-filter>\r\n </div>\r\n\r\n <!--\r\n <nz-tabset nzCentered>\r\n <nz-tab nzTitle=\"Secion de Filtros\">\r\n <div class=\"controls\">\r\n aqui botones de control:\r\n\r\n </div>\r\n <div>\r\n \r\n\r\n </div>\r\n\r\n </nz-tab>\r\n \r\n </nz-tabset>\r\n-->\r\n</ng-container>\r\n</nz-drawer>\r\n\r\n\r\n\r\n<!-- DRAWER - CONFIGURACION -->\r\n<nz-drawer\r\n[nzVisible]=\"drawerconfigvisible\"\r\n[nzMaskClosable]=\"false\"\r\nnzPlacement=\"right\"\r\n[nzWidth]=\"fnGetDrawerWidth(50)\"\r\n(nzOnClose)=\"handleCloseFormDrawer()\"\r\n>\r\n<ng-container *nzDrawerContent>\r\n <div class=\"widget-details-info\">\r\n <h6 nz-typography>{{ drawerCurrentWidgetObject.widgetId }}</h6>\r\n </div>\r\n <nz-tabset nzCentered>\r\n <nz-tab nzTitle=\"{{ drawerCurrentWidgetObject.widgetId }}\">\r\n <div class=\"controls\">\r\n <button (click)=\"fn_btn_updateWidgetControlConfig(drawerCurrentWidgetObject.widgetId)\">Actualiza Configuracion</button>\r\n <button (click)=\"fn_btn_updateWidgetControlData(drawerCurrentWidgetObject.widgetId)\">Actualiza Data</button> \r\n </div>\r\n <div>\r\n bla bla bla\r\n </div>\r\n\r\n </nz-tab>\r\n \r\n </nz-tabset>\r\n</ng-container>\r\n</nz-drawer>", styles: ["@charset \"UTF-8\";:host{display:block;width:100%}.canvas-container{background-color:var(--canvas-bg, #f5f5f5);min-height:500px;padding:10px}::vdeep .card-inner{background:#fff;border:1px solid #ccc;height:100%;display:flex;align-items:center;justify-content:center}:host ::ng-deep .grid-stack-item-content{border-radius:6px;box-shadow:0 2px 5px #0000001a;display:flex;align-items:center;justify-content:center;font-weight:700;overflow:hidden}::ng-deep .grid-stack-item.widget-maximized{position:fixed!important;top:0!important;left:0!important;width:100vw!important;height:100vh!important;z-index:9999!important;transform:none!important;margin:0!important;padding:5px}::ng-deep .grid-stack-item.widget-maximized .grid-stack-item-content{position:absolute!important;inset:0!important;width:100%!important;height:100%!important;margin:0!important;padding:0!important;border:none!important;border-radius:0!important;box-shadow:none!important;background-color:#fff!important;overflow:hidden}::ng-deep .grid-stack>.grid-stack-item>.ui-resizable-handle{opacity:0!important;background-image:none!important}.widget-details-info{padding-top:30px;text-align:center}.widget-details-info h6{font-family:manrope,sans-serif;font-size:20px;font-weight:700;line-height:26px;color:#2d3144}.widget-details-info p{font-family:manrope,sans-serif;font-size:14px;font-weight:400;line-height:21px;color:#4b5064}.controls-container{display:flex;flex-wrap:wrap;align-items:center;gap:12px;padding:12px 16px;background:#fff;border-bottom:1px solid #f0f0f0;box-shadow:0 2px 8px #0000000a;border-radius:6px;margin-bottom:16px;width:100%;box-sizing:border-box}.controls-container button{white-space:nowrap}.controls-container .btn-filtro{display:inline-flex;align-items:center;justify-content:center;padding:0;width:32px;height:32px;border-radius:50%;transition:all .3s ease}.controls-container .btn-filtro.active{color:#fff;background-color:#1890ff;border-color:#1890ff}.controls-container .btn-filtro.active:hover{background-color:#40a9ff;border-color:#40a9ff}@media(max-width:576px){.controls-container{gap:8px;padding:8px 10px}.controls-container button[nz-button]{font-size:13px;padding:0 10px}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: NzDrawerModule }, { kind: "component", type: i2.NzDrawerComponent, selector: "nz-drawer", inputs: ["nzContent", "nzCloseIcon", "nzClosable", "nzMaskClosable", "nzMask", "nzCloseOnNavigation", "nzNoAnimation", "nzKeyboard", "nzTitle", "nzExtra", "nzFooter", "nzPlacement", "nzSize", "nzMaskStyle", "nzBodyStyle", "nzWrapClassName", "nzWidth", "nzHeight", "nzZIndex", "nzOffsetX", "nzOffsetY", "nzVisible"], outputs: ["nzOnViewInit", "nzOnClose", "nzVisibleChange"], exportAs: ["nzDrawer"] }, { kind: "directive", type: i2.NzDrawerContentDirective, selector: "[nzDrawerContent]", exportAs: ["nzDrawerContent"] }, { kind: "ngmodule", type: NzTabsModule }, { kind: "component", type: i3.NzTabsComponent, selector: "nz-tabs,nz-tabset", inputs: ["nzSelectedIndex", "nzTabPosition", "nzTabBarExtraContent", "nzCanDeactivate", "nzAddIcon", "nzTabBarStyle", "nzType", "nzSize", "nzAnimated", "nzTabBarGutter", "nzHideAdd", "nzCentered", "nzHideAll", "nzLinkRouter", "nzLinkExact", "nzDestroyInactiveTabPane"], outputs: ["nzSelectChange", "nzSelectedIndexChange", "nzTabListScroll", "nzClose", "nzAdd"], exportAs: ["nzTabs"] }, { kind: "component", type: i3.NzTabComponent, selector: "nz-tab", inputs: ["nzTitle", "nzClosable", "nzCloseIcon", "nzDisabled", "nzForceRender"], outputs: ["nzSelect", "nzDeselect", "nzClick", "nzContextmenu"], exportAs: ["nzTab"] }, { kind: "ngmodule", type: NzIconModule }, { kind: "directive", type: i1$3.NzIconDirective, selector: "nz-icon,[nz-icon]", inputs: ["nzSpin", "nzRotate", "nzType", "nzTheme", "nzTwotoneColor", "nzIconfont"], exportAs: ["nzIcon"] }, { kind: "ngmodule", type: NzButtonModule }, { kind: "component", type: i5.NzButtonComponent, selector: "button[nz-button], a[nz-button]", inputs: ["nzBlock", "nzGhost", "nzSearch", "nzLoading", "nzDanger", "disabled", "tabIndex", "nzType", "nzShape", "nzSize"], exportAs: ["nzButton"] }, { kind: "directive", type: i6.ɵNzTransitionPatchDirective, selector: "[nz-button], [nz-icon], nz-icon, [nz-menu-item], [nz-submenu], nz-select-top-control, nz-select-placeholder, nz-input-group", inputs: ["hidden"] }, { kind: "directive", type: i7.NzWaveDirective, selector: "[nz-wave],button[nz-button]:not([nzType=\"link\"]):not([nzType=\"text\"])", inputs: ["nzWaveExtraNode"], exportAs: ["nzWave"] }, { kind: "component", type: YwDashboardFilterComponent, selector: "yw-dashboard-filter", inputs: ["dashboardFilterConfig", "dashboardData"], outputs: ["filterSelectionChange"] }] }); }
|
|
4195
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.30", ngImport: i0, type: YwDashboardFilterComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
4196
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.30", type: YwDashboardFilterComponent, isStandalone: true, selector: "yw-dashboard-filter", inputs: { dashboardFilterConfig: "dashboardFilterConfig", dashboardData: "dashboardData" }, outputs: { filterSelectionChange: "filterSelectionChange" }, ngImport: i0, template: "\r\n <div class=\"dashboard-filter-content-bar\">\r\n @if ( dashboardFilterConfig.showConfigButtons ) { \r\n <button nz-button nzType=\"primary\" >\r\n <span nz-icon nz-type=\"plus\"></span> A\u00F1adir widget\r\n </button>\r\n }\r\n <button nz-button \r\n nzType=\"default\" \r\n nzShape=\"circle\" \r\n (click)=\"handleClearFilter()\" \r\n class=\"btn-clean\" \r\n > \r\n <!-- Icono de Borrador (Eraser) activo / relleno --> \r\n <svg \r\n xmlns=\"http://www.w3.org/2000/svg\" \r\n width=\"16\" height=\"16\" \r\n viewBox=\"0 0 24 24\" \r\n fill=\"currentColor\">\r\n <path d=\"M16.24 3.56a2.12 2.12 0 0 1 3 0l1.2 1.2a2.12 2.12 0 0 1 0 3l-8.5 8.5H6.5a1.5 1.5 0 0 1-1.5-1.5v-5.44l11.24-11.24zM19 19H5a1 1 0 0 1 0-2h14a1 1 0 0 1 0 2z\"/>\r\n </svg>\r\n \r\n </button>\r\n </div>\r\n\r\n <div class=\"dashboard-filter-content-wrapper\">\r\n @for ( colFilter of controlListConfig; track colFilter) { \r\n <div class=\"dashboard-filter-content-wrapper-item\">\r\n \r\n <yw-dashboard-filter-widget \r\n [configWidget]=\"colFilter.configWidget\"\r\n [controlConfig]=\"colFilter.controlConfig\"\r\n [controlData]=\"colFilter.controlData\"\r\n (selectionChange)=\"onFilterChange($event)\"\r\n > \r\n </yw-dashboard-filter-widget>\r\n\r\n </div>\r\n }\r\n </div>", styles: [":host{display:flex;flex-direction:column;width:100%;height:100%;overflow:hidden;box-sizing:border-box}.dashboard-filter-content-bar{display:flex;justify-content:flex-end;gap:4px;padding:5px 10px;flex-shrink:0;width:100%;box-sizing:border-box}.dashboard-filter-content-wrapper{flex:1 1 auto;min-height:0;overflow-y:auto;overflow-x:hidden;width:100%;display:flex;flex-direction:column;box-sizing:border-box}.dashboard-filter-content-wrapper-item{padding-bottom:5px}.btn-clean{display:inline-flex;align-items:center;justify-content:center;padding:0;width:32px;height:32px;border-radius:50%;transition:all .3s ease}.btn-clean.active{color:#fff;background-color:#1890ff;border-color:#1890ff}.btn-clean.active:hover{background-color:#40a9ff;border-color:#40a9ff}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "component", type: YwDashboardFilterWidgetComponent, selector: "yw-dashboard-filter-widget", inputs: ["configWidget", "controlConfig", "controlData"], outputs: ["eventDeleteRequest", "eventShowConfigFormRequest", "selectionChange"] }, { kind: "ngmodule", type: NzIconModule }, { kind: "directive", type: i1$3.NzIconDirective, selector: "nz-icon,[nz-icon]", inputs: ["nzSpin", "nzRotate", "nzType", "nzTheme", "nzTwotoneColor", "nzIconfont"], exportAs: ["nzIcon"] }, { kind: "ngmodule", type: NzButtonModule }, { kind: "component", type: i5.NzButtonComponent, selector: "button[nz-button], a[nz-button]", inputs: ["nzBlock", "nzGhost", "nzSearch", "nzLoading", "nzDanger", "disabled", "tabIndex", "nzType", "nzShape", "nzSize"], exportAs: ["nzButton"] }, { kind: "directive", type: i6.ɵNzTransitionPatchDirective, selector: "[nz-button], [nz-icon], nz-icon, [nz-menu-item], [nz-submenu], nz-select-top-control, nz-select-placeholder, nz-input-group", inputs: ["hidden"] }, { kind: "directive", type: i7.NzWaveDirective, selector: "[nz-wave],button[nz-button]:not([nzType=\"link\"]):not([nzType=\"text\"])", inputs: ["nzWaveExtraNode"], exportAs: ["nzWave"] }] }); }
|
|
4203
4197
|
}
|
|
4204
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.30", ngImport: i0, type:
|
|
4198
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.30", ngImport: i0, type: YwDashboardFilterComponent, decorators: [{
|
|
4205
4199
|
type: Component,
|
|
4206
|
-
args: [{ selector: 'yw-dashboard', standalone: true, imports: [CommonModule,
|
|
4207
|
-
|
|
4208
|
-
NzDrawerModule,
|
|
4209
|
-
NzTabsModule,
|
|
4210
|
-
YwBaseSlicerComponent,
|
|
4200
|
+
args: [{ selector: 'yw-dashboard-filter', standalone: true, imports: [CommonModule,
|
|
4201
|
+
YwDashboardFilterWidgetComponent,
|
|
4211
4202
|
NzIconModule,
|
|
4212
4203
|
NzButtonModule,
|
|
4213
|
-
|
|
4214
|
-
|
|
4215
|
-
YwDashboardFilterComponent
|
|
4216
|
-
], template: "<!-- <div class=\"controls\" [hidden]=\"!showControls()\">\r\n <button (click)=\"saveLayoutToJSON()\">Guardar JSON en Consola</button>\r\n <button (click)=\"fn_btn_addWidget()\">add widget</button>\r\n <button (click)=\"fn_btn_lockPositionWidgets()\">Lock widgets</button>\r\n <button (click)=\"handleShowFormFilterDrawer()\" class=\"btn-filtro\">\r\n <svg *ngIf=\"drawerfiltervisible; else filtroInactivo\" \r\n xmlns=\"http://www.w3.org/2000/svg\" \r\n width=\"20\" height=\"20\" \r\n viewBox=\"0 0 24 24\" \r\n fill=\"currentColor\">\r\n <path d=\"M10 18h4v-2h-4v2zM3 6v2h18V6H3zm3 7h12v-2H6v2z\"/>\r\n </svg>\r\n <ng-template #filtroInactivo>\r\n <svg xmlns=\"http://www.w3.org/2000/svg\" \r\n width=\"20\" height=\"20\" \r\n viewBox=\"0 0 24 24\" \r\n fill=\"none\" \r\n stroke=\"currentColor\" \r\n stroke-width=\"2\">\r\n <polygon points=\"22 3 2 3 10 12.46 10 19 14 21 14 12.46 22 3\"/>\r\n </svg>\r\n </ng-template>\r\n </button>\r\n</div> -->\r\n\r\n<div class=\"controls-container\" >\r\n @if ( showControls() ) { \r\n <!-- Botones principales con nz-button y tipos de Ant Design -->\r\n <button nz-button nzType=\"default\" (click)=\"saveLayoutToJSON()\" >\r\n <span nz-icon nz-type=\"code\"></span> Guardar JSON\r\n </button>\r\n\r\n <button nz-button nzType=\"primary\" (click)=\"fn_btn_addWidget()\" >\r\n <span nz-icon nz-type=\"plus\"></span> A\u00F1adir widget\r\n </button>\r\n\r\n <button nz-button [nzType]=\"isLocked ? 'primary' : 'default'\" nzDanger (click)=\"fn_btn_lockPositionWidgets()\" >\r\n <span nz-icon [nzType]=\"isLocked ? 'lock' : 'unlock'\"></span> \r\n {{ isLocked ? 'Bloqueado' : 'Bloquear' }}\r\n </button>\r\n }\r\n @if ( showFilter() ) { \r\n <!-- Bot\u00F3n de filtro con estilo ic\u00F3nico -->\r\n <button nz-button nzType=\"default\" nzShape=\"circle\" (click)=\"handleShowFormFilterDrawer()\" class=\"btn-filtro\" [class.active]=\"drawerfiltervisible\" >\r\n <svg *ngIf=\"drawerfiltervisible; else filtroInactivo\" \r\n xmlns=\"http://www.w3.org/2000/svg\" \r\n width=\"16\" height=\"16\" \r\n viewBox=\"0 0 24 24\" \r\n fill=\"currentColor\">\r\n <path d=\"M10 18h4v-2h-4v2zM3 6v2h18V6H3zm3 7h12v-2H6v2z\"/>\r\n </svg>\r\n <ng-template #filtroInactivo>\r\n <svg xmlns=\"http://www.w3.org/2000/svg\" \r\n width=\"16\" height=\"16\" \r\n viewBox=\"0 0 24 24\" \r\n fill=\"none\" \r\n stroke=\"currentColor\" \r\n stroke-width=\"2\">\r\n <polygon points=\"22 3 2 3 10 12.46 10 19 14 21 14 12.46 22 3\"/>\r\n </svg>\r\n </ng-template>\r\n </button>\r\n }\r\n</div>\r\n<div #gridContainer class=\"grid-stack canvas-container\"\r\n [style.--canvas-bg]=\"dashboardStyle.canvasBackgroundColor\"\r\n></div>\r\n\r\n\r\n\r\n\r\n<!-- DRAWER - FILTER -->\r\n\r\n<nz-drawer\r\n[nzVisible]=\"drawerfiltervisible\"\r\n[nzMaskClosable]=\"false\"\r\nnzPlacement=\"right\"\r\n[nzWidth]=\"fnGetDrawerWidth(50)\"\r\n(nzOnClose)=\"handleCloseFormFilterDrawer()\"\r\n>\r\n<ng-container *nzDrawerContent>\r\n <div class=\"widget-details-info\">\r\n <h6 nz-typography>Filtros</h6>\r\n <yw-dashboard-filter\r\n [dashboardFilterConfig]=\"dashboardFilterConfig\"\r\n [dashboardData]=\"dashboardData\"\r\n (filterSelectionChange)=\"onFilterSelectionChange($event)\"\r\n >\r\n </yw-dashboard-filter>\r\n </div>\r\n\r\n <!--\r\n <nz-tabset nzCentered>\r\n <nz-tab nzTitle=\"Secion de Filtros\">\r\n <div class=\"controls\">\r\n aqui botones de control:\r\n\r\n </div>\r\n <div>\r\n \r\n\r\n </div>\r\n\r\n </nz-tab>\r\n \r\n </nz-tabset>\r\n-->\r\n</ng-container>\r\n</nz-drawer>\r\n\r\n\r\n\r\n<!-- DRAWER - CONFIGURACION -->\r\n<nz-drawer\r\n[nzVisible]=\"drawerconfigvisible\"\r\n[nzMaskClosable]=\"false\"\r\nnzPlacement=\"right\"\r\n[nzWidth]=\"fnGetDrawerWidth(50)\"\r\n(nzOnClose)=\"handleCloseFormDrawer()\"\r\n>\r\n<ng-container *nzDrawerContent>\r\n <div class=\"widget-details-info\">\r\n <h6 nz-typography>{{ drawerCurrentWidgetObject.widgetId }}</h6>\r\n </div>\r\n <nz-tabset nzCentered>\r\n <nz-tab nzTitle=\"{{ drawerCurrentWidgetObject.widgetId }}\">\r\n <div class=\"controls\">\r\n <button (click)=\"fn_btn_updateWidgetControlConfig(drawerCurrentWidgetObject.widgetId)\">Actualiza Configuracion</button>\r\n <button (click)=\"fn_btn_updateWidgetControlData(drawerCurrentWidgetObject.widgetId)\">Actualiza Data</button> \r\n </div>\r\n <div>\r\n bla bla bla\r\n </div>\r\n\r\n </nz-tab>\r\n \r\n </nz-tabset>\r\n</ng-container>\r\n</nz-drawer>", styles: ["@charset \"UTF-8\";:host{display:block;width:100%}.canvas-container{background-color:var(--canvas-bg, #f5f5f5);min-height:500px;padding:10px}::vdeep .card-inner{background:#fff;border:1px solid #ccc;height:100%;display:flex;align-items:center;justify-content:center}:host ::ng-deep .grid-stack-item-content{border-radius:6px;box-shadow:0 2px 5px #0000001a;display:flex;align-items:center;justify-content:center;font-weight:700;overflow:hidden}::ng-deep .grid-stack-item.widget-maximized{position:fixed!important;top:0!important;left:0!important;width:100vw!important;height:100vh!important;z-index:9999!important;transform:none!important;margin:0!important;padding:5px}::ng-deep .grid-stack-item.widget-maximized .grid-stack-item-content{position:absolute!important;inset:0!important;width:100%!important;height:100%!important;margin:0!important;padding:0!important;border:none!important;border-radius:0!important;box-shadow:none!important;background-color:#fff!important;overflow:hidden}::ng-deep .grid-stack>.grid-stack-item>.ui-resizable-handle{opacity:0!important;background-image:none!important}.widget-details-info{padding-top:30px;text-align:center}.widget-details-info h6{font-family:manrope,sans-serif;font-size:20px;font-weight:700;line-height:26px;color:#2d3144}.widget-details-info p{font-family:manrope,sans-serif;font-size:14px;font-weight:400;line-height:21px;color:#4b5064}.controls-container{display:flex;flex-wrap:wrap;align-items:center;gap:12px;padding:12px 16px;background:#fff;border-bottom:1px solid #f0f0f0;box-shadow:0 2px 8px #0000000a;border-radius:6px;margin-bottom:16px;width:100%;box-sizing:border-box}.controls-container button{white-space:nowrap}.controls-container .btn-filtro{display:inline-flex;align-items:center;justify-content:center;padding:0;width:32px;height:32px;border-radius:50%;transition:all .3s ease}.controls-container .btn-filtro.active{color:#fff;background-color:#1890ff;border-color:#1890ff}.controls-container .btn-filtro.active:hover{background-color:#40a9ff;border-color:#40a9ff}@media(max-width:576px){.controls-container{gap:8px;padding:8px 10px}.controls-container button[nz-button]{font-size:13px;padding:0 10px}}\n"] }]
|
|
4217
|
-
}], ctorParameters: () => [{ type: i0.EnvironmentInjector }, { type: i0.ApplicationRef }], propDecorators: { gridContainer: [{
|
|
4218
|
-
type: ViewChild,
|
|
4219
|
-
args: ['gridContainer', { static: true }]
|
|
4220
|
-
}], showControls: [{ type: i0.Input, args: [{ isSignal: true, alias: "showControls", required: false }] }], showFilter: [{ type: i0.Input, args: [{ isSignal: true, alias: "showFilter", required: false }] }], dashboardStyle: [{
|
|
4221
|
-
type: Input
|
|
4222
|
-
}], dashboardConfig: [{
|
|
4204
|
+
], template: "\r\n <div class=\"dashboard-filter-content-bar\">\r\n @if ( dashboardFilterConfig.showConfigButtons ) { \r\n <button nz-button nzType=\"primary\" >\r\n <span nz-icon nz-type=\"plus\"></span> A\u00F1adir widget\r\n </button>\r\n }\r\n <button nz-button \r\n nzType=\"default\" \r\n nzShape=\"circle\" \r\n (click)=\"handleClearFilter()\" \r\n class=\"btn-clean\" \r\n > \r\n <!-- Icono de Borrador (Eraser) activo / relleno --> \r\n <svg \r\n xmlns=\"http://www.w3.org/2000/svg\" \r\n width=\"16\" height=\"16\" \r\n viewBox=\"0 0 24 24\" \r\n fill=\"currentColor\">\r\n <path d=\"M16.24 3.56a2.12 2.12 0 0 1 3 0l1.2 1.2a2.12 2.12 0 0 1 0 3l-8.5 8.5H6.5a1.5 1.5 0 0 1-1.5-1.5v-5.44l11.24-11.24zM19 19H5a1 1 0 0 1 0-2h14a1 1 0 0 1 0 2z\"/>\r\n </svg>\r\n \r\n </button>\r\n </div>\r\n\r\n <div class=\"dashboard-filter-content-wrapper\">\r\n @for ( colFilter of controlListConfig; track colFilter) { \r\n <div class=\"dashboard-filter-content-wrapper-item\">\r\n \r\n <yw-dashboard-filter-widget \r\n [configWidget]=\"colFilter.configWidget\"\r\n [controlConfig]=\"colFilter.controlConfig\"\r\n [controlData]=\"colFilter.controlData\"\r\n (selectionChange)=\"onFilterChange($event)\"\r\n > \r\n </yw-dashboard-filter-widget>\r\n\r\n </div>\r\n }\r\n </div>", styles: [":host{display:flex;flex-direction:column;width:100%;height:100%;overflow:hidden;box-sizing:border-box}.dashboard-filter-content-bar{display:flex;justify-content:flex-end;gap:4px;padding:5px 10px;flex-shrink:0;width:100%;box-sizing:border-box}.dashboard-filter-content-wrapper{flex:1 1 auto;min-height:0;overflow-y:auto;overflow-x:hidden;width:100%;display:flex;flex-direction:column;box-sizing:border-box}.dashboard-filter-content-wrapper-item{padding-bottom:5px}.btn-clean{display:inline-flex;align-items:center;justify-content:center;padding:0;width:32px;height:32px;border-radius:50%;transition:all .3s ease}.btn-clean.active{color:#fff;background-color:#1890ff;border-color:#1890ff}.btn-clean.active:hover{background-color:#40a9ff;border-color:#40a9ff}\n"] }]
|
|
4205
|
+
}], ctorParameters: () => [], propDecorators: { dashboardFilterConfig: [{
|
|
4223
4206
|
type: Input
|
|
4224
4207
|
}], dashboardData: [{
|
|
4225
4208
|
type: Input
|
|
4226
|
-
}],
|
|
4227
|
-
type: Input
|
|
4228
|
-
}] } });
|
|
4209
|
+
}], filterSelectionChange: [{ type: i0.Output, args: ["filterSelectionChange"] }] } });
|
|
4229
4210
|
|
|
4230
|
-
|
|
4231
|
-
|
|
4232
|
-
|
|
4211
|
+
/* END - FILTROS */
|
|
4212
|
+
class YwDashboardComponent {
|
|
4213
|
+
/* */
|
|
4214
|
+
constructor(environmentInjector, appRef) {
|
|
4215
|
+
//Configurar Bloqueo de Widgets
|
|
4216
|
+
/*
|
|
4217
|
+
effect(() => {
|
|
4218
|
+
const isLocked = this.allIsLocked();
|
|
4219
|
+
console.log('El estado de bloqueo cambió a:', isLocked);
|
|
4220
|
+
this.fn_lockPositionWidgets(isLocked);
|
|
4221
|
+
});
|
|
4222
|
+
*/
|
|
4223
|
+
this.environmentInjector = environmentInjector;
|
|
4224
|
+
this.appRef = appRef;
|
|
4225
|
+
this.widgetsActivos = new Map();
|
|
4226
|
+
this.showControls = input(false, ...(ngDevMode ? [{ debugName: "showControls" }] : []));
|
|
4227
|
+
this.showFilter = input(false, ...(ngDevMode ? [{ debugName: "showFilter" }] : []));
|
|
4228
|
+
this.allIsLocked = signal(false, ...(ngDevMode ? [{ debugName: "allIsLocked" }] : []));
|
|
4229
|
+
this.drawerfiltervisible = false;
|
|
4230
|
+
this.drawerconfigvisible = false;
|
|
4231
|
+
this.drawerCurrentWidgetObject = {};
|
|
4232
|
+
this.isLocked = false;
|
|
4233
|
+
this.countWidget = 1;
|
|
4234
|
+
this.layoutConfig = {
|
|
4235
|
+
margin: 10,
|
|
4236
|
+
cellHeight: 100,
|
|
4237
|
+
columns: 24
|
|
4238
|
+
};
|
|
4239
|
+
/* ejemplo de Items
|
|
4240
|
+
items: [
|
|
4241
|
+
{ id: 'div-1', x: 0, y: 0, w: 14, h: 2, content: 'DIV 1' , contentData : {}},
|
|
4242
|
+
{ id: 'div-2', x: 5, y: 2, w: 19, h: 1, content: 'DIV 2' , contentData : {}},
|
|
4243
|
+
{ id: 'div-3', x: 0, y: 3, w: 22, h: 1, content: 'DIV 3', contentData : {} }
|
|
4244
|
+
]
|
|
4245
|
+
*/
|
|
4246
|
+
this.dashboardStyle = {
|
|
4247
|
+
canvasBackgroundColor: "#f5f5f5",
|
|
4248
|
+
widgetBackgroundColor: "#ffffff",
|
|
4249
|
+
widgetBorderColor: "#007bff"
|
|
4250
|
+
};
|
|
4251
|
+
this.dashboardConfig = {
|
|
4252
|
+
showConfigButtons: false,
|
|
4253
|
+
lockPositionWidgets: false,
|
|
4254
|
+
layoutConfig: {
|
|
4255
|
+
margin: 0,
|
|
4256
|
+
cellHeight: 0,
|
|
4257
|
+
columns: 0
|
|
4258
|
+
},
|
|
4259
|
+
controlListConfig: []
|
|
4260
|
+
};
|
|
4261
|
+
this.dashboardData = [];
|
|
4262
|
+
this.dashboardItems = [];
|
|
4263
|
+
/* REF FILTROS */
|
|
4264
|
+
this.dashboardFilterConfig = {
|
|
4265
|
+
showConfigButtons: false,
|
|
4266
|
+
lockPositionWidgets: false,
|
|
4267
|
+
controlListConfig: []
|
|
4268
|
+
};
|
|
4233
4269
|
}
|
|
4234
|
-
|
|
4235
|
-
|
|
4236
|
-
if (Array.isArray(allTablesData)) {
|
|
4237
|
-
const defaultTableName = configData_?.configData?.table || 'default';
|
|
4238
|
-
allTablesData = { [defaultTableName]: allTablesData };
|
|
4270
|
+
ngOnInit() {
|
|
4271
|
+
// console.log("DATA QUE LLEGA AL DASHBOARD:",this.dashboardConfig)
|
|
4239
4272
|
}
|
|
4240
|
-
|
|
4241
|
-
|
|
4242
|
-
|
|
4243
|
-
|
|
4244
|
-
|
|
4245
|
-
|
|
4246
|
-
|
|
4247
|
-
|
|
4248
|
-
|
|
4249
|
-
|
|
4250
|
-
|
|
4251
|
-
|
|
4252
|
-
|
|
4253
|
-
|
|
4254
|
-
|
|
4255
|
-
|
|
4256
|
-
|
|
4257
|
-
|
|
4258
|
-
|
|
4259
|
-
|
|
4260
|
-
|
|
4261
|
-
|
|
4262
|
-
|
|
4263
|
-
|
|
4264
|
-
|
|
4265
|
-
|
|
4266
|
-
|
|
4273
|
+
ngOnChanges(changes) {
|
|
4274
|
+
if (changes['dashboardConfig']) {
|
|
4275
|
+
console.log('Nuevo valor dashboardConfig:', this.dashboardConfig);
|
|
4276
|
+
//this.initCanvasGrid();
|
|
4277
|
+
}
|
|
4278
|
+
if (changes['dashboardData']) {
|
|
4279
|
+
console.log('Nuevo valor dashboardData:', this.dashboardData);
|
|
4280
|
+
//this.initCanvasGrid();
|
|
4281
|
+
}
|
|
4282
|
+
}
|
|
4283
|
+
ngAfterViewInit() {
|
|
4284
|
+
this.initCanvasGrid();
|
|
4285
|
+
}
|
|
4286
|
+
initCanvasGrid() {
|
|
4287
|
+
this.layoutConfig = this.dashboardConfig.layoutConfig;
|
|
4288
|
+
// Opciones para restringir colisiones y comportamiento
|
|
4289
|
+
let options = {
|
|
4290
|
+
column: this.layoutConfig.columns,
|
|
4291
|
+
cellHeight: this.layoutConfig.cellHeight,
|
|
4292
|
+
margin: this.layoutConfig.margin,
|
|
4293
|
+
float: true, // Evita que los divs floten automáticamente hacia arriba
|
|
4294
|
+
//noOverlap: true, // CLAVE: Bloquea el movimiento si colisiona con otro DIV
|
|
4295
|
+
resizable: { handles: 'e, se, s, sw, w, nw, n, ne', autoHide: true } // Permite redimensionar desde todos los bordes
|
|
4296
|
+
};
|
|
4297
|
+
if (this.layoutConfig.columnOpts) {
|
|
4298
|
+
options = {
|
|
4299
|
+
column: this.layoutConfig.columns,
|
|
4300
|
+
cellHeight: this.layoutConfig.cellHeight,
|
|
4301
|
+
margin: this.layoutConfig.margin,
|
|
4302
|
+
columnOpts: {
|
|
4303
|
+
breakpointForWindow: this.layoutConfig.columnOpts.breakpointForWindow, // Mide el ancho de la ventana gráfica
|
|
4304
|
+
breakpoints: this.layoutConfig.columnOpts.breakpoints,
|
|
4305
|
+
layout: this.layoutConfig.columnOpts.layout || 'list', // Mantiene el orden de los widgets secuencialmente al colapsar
|
|
4306
|
+
},
|
|
4307
|
+
float: true, // Evita que los divs floten automáticamente hacia arriba
|
|
4308
|
+
//noOverlap: true, // CLAVE: Bloquea el movimiento si colisiona con otro DIV
|
|
4309
|
+
resizable: { handles: 'e, se, s, sw, w, nw, n, ne', autoHide: true } // Permite redimensionar desde todos los bordes
|
|
4310
|
+
};
|
|
4267
4311
|
}
|
|
4268
|
-
|
|
4269
|
-
|
|
4270
|
-
|
|
4271
|
-
|
|
4272
|
-
|
|
4273
|
-
|
|
4274
|
-
|
|
4275
|
-
|
|
4276
|
-
|
|
4277
|
-
// getNestedValue(item, xAxis) !== null,
|
|
4278
|
-
// );
|
|
4279
|
-
const validRawData = unifiedTable.filter((item) => item &&
|
|
4280
|
-
xAxis &&
|
|
4281
|
-
getNestedValue(item, xAxis) !== undefined &&
|
|
4282
|
-
getNestedValue(item, xAxis) !== null);
|
|
4283
|
-
const orderedRawData = sortByXAxis(validRawData);
|
|
4284
|
-
if (orderedRawData.length > 0) {
|
|
4285
|
-
if (serie) {
|
|
4286
|
-
// 2. Agrupamos los datos por el valor de la serie (ej. sucursal o vendedor)
|
|
4287
|
-
const groupedBySerie = orderedRawData.reduce((acc, item) => {
|
|
4288
|
-
const serieVal = getNestedValue(item, serie);
|
|
4289
|
-
const serieKey = serieVal !== undefined && serieVal !== null
|
|
4290
|
-
? String(serieVal)
|
|
4291
|
-
: 'Desconocido';
|
|
4292
|
-
if (!acc[serieKey]) {
|
|
4293
|
-
acc[serieKey] = [];
|
|
4294
|
-
}
|
|
4295
|
-
acc[serieKey].push(item);
|
|
4296
|
-
return acc;
|
|
4297
|
-
}, {});
|
|
4298
|
-
series = Object.entries(groupedBySerie).map(([serieName, groupItems]) => {
|
|
4299
|
-
const orderedGroupItems = [...groupItems].sort((a, b) => {
|
|
4300
|
-
const aValue = getNestedValue(a, xAxis);
|
|
4301
|
-
const bValue = getNestedValue(b, xAxis);
|
|
4302
|
-
return String(aValue).localeCompare(String(bValue), undefined, {
|
|
4303
|
-
numeric: true,
|
|
4304
|
-
sensitivity: 'base'
|
|
4305
|
-
});
|
|
4306
|
-
});
|
|
4307
|
-
console.log("SERIES NAME:", orderedGroupItems);
|
|
4308
|
-
const dataSource = orderedGroupItems.map((item) => {
|
|
4309
|
-
const rawVal = getNestedValue(item, yAxis);
|
|
4310
|
-
const valorFinal = rawVal !== undefined
|
|
4311
|
-
? typeof rawVal === 'number'
|
|
4312
|
-
? rawVal
|
|
4313
|
-
: Number(rawVal) || 0
|
|
4314
|
-
: 0;
|
|
4315
|
-
const sizeFinal = Math.abs(valorFinal) !== 0 ? Math.abs(valorFinal) * 0.05 : 0;
|
|
4316
|
-
return {
|
|
4317
|
-
x: String(getNestedValue(item, xAxis)),
|
|
4318
|
-
y: valorFinal,
|
|
4319
|
-
size: sizeFinal,
|
|
4320
|
-
name: String(getNestedValue(item, xAxis)),
|
|
4321
|
-
// ...(chartoColoredLine
|
|
4322
|
-
// ? { color: getRandomProfessionalHex() }
|
|
4323
|
-
// : {})
|
|
4324
|
-
};
|
|
4325
|
-
});
|
|
4326
|
-
return {
|
|
4327
|
-
name: serieName === 'default' ? 'Serie 1' : serieName,
|
|
4328
|
-
dataSource,
|
|
4329
|
-
opacity: opacity,
|
|
4330
|
-
emptyPointSettings: emptyPointSettings
|
|
4331
|
-
// dashArray: dashArray !== undefined ? dashArray : undefined,
|
|
4332
|
-
// width: width !== undefined ? width : undefined,
|
|
4333
|
-
// widthLine: widthLine !== undefined ? widthLine : undefined,
|
|
4334
|
-
};
|
|
4335
|
-
});
|
|
4336
|
-
}
|
|
4337
|
-
else {
|
|
4338
|
-
const dataSource = orderedRawData.map((item) => {
|
|
4339
|
-
let valorFinal = 0;
|
|
4340
|
-
let sizeFinal = 0;
|
|
4341
|
-
// const shouldColorLine = chartoColoredLine;
|
|
4342
|
-
const rawVal = getNestedValue(item, yAxis);
|
|
4343
|
-
// const rawSize = getNestedValue(item, size); // <--- Extraer el valor real
|
|
4344
|
-
if (rawVal !== undefined) {
|
|
4345
|
-
valorFinal = typeof rawVal === 'number' ? rawVal : Number(rawVal) || 0;
|
|
4346
|
-
}
|
|
4347
|
-
// if (rawSize !== undefined) {
|
|
4348
|
-
sizeFinal = Math.abs(valorFinal) !== 0 ? Math.abs(valorFinal) * 0.05 : 0;
|
|
4349
|
-
// }
|
|
4350
|
-
return {
|
|
4351
|
-
x: String(getNestedValue(item, xAxis)),
|
|
4352
|
-
y: valorFinal,
|
|
4353
|
-
size: sizeFinal, // <--- Valor numérico extraído
|
|
4354
|
-
name: String(getNestedValue(item, xAxis)),
|
|
4355
|
-
// ...(shouldColorLine ? { color: getRandomProfessionalHex() } : {})
|
|
4356
|
-
};
|
|
4357
|
-
});
|
|
4358
|
-
series = [
|
|
4359
|
-
{
|
|
4360
|
-
name: xAxis.split(".")[0] && xAxis !== 'default' ? xAxis.split(".")[0] : 'Serie Join',
|
|
4361
|
-
dataSource: dataSource,
|
|
4362
|
-
opacity: opacity,
|
|
4363
|
-
emptyPointSettings: emptyPointSettings
|
|
4364
|
-
// dashArray: dashArray !== undefined ? dashArray : undefined,
|
|
4365
|
-
// width: width !== undefined ? width : undefined,
|
|
4366
|
-
// widthLine: widthLine !== undefined ? widthLine : undefined,
|
|
4367
|
-
}
|
|
4368
|
-
];
|
|
4312
|
+
/*EXAMPLE OF "columnOpts"
|
|
4313
|
+
columnOpts: {
|
|
4314
|
+
breakpointForWindow: true,
|
|
4315
|
+
breakpoints: [
|
|
4316
|
+
{ w: 768, c: 1 },
|
|
4317
|
+
{ w: 992, c: 6 },
|
|
4318
|
+
{ w: 1200, c: this.layoutConfig.columns } // 👈 Usa tu variable para consistencia en Desktop
|
|
4319
|
+
],
|
|
4320
|
+
layout: 'list'
|
|
4369
4321
|
}
|
|
4370
|
-
|
|
4371
|
-
|
|
4322
|
+
*/
|
|
4323
|
+
// Inicializar el canvas
|
|
4324
|
+
this.grid = GridStack.init(options, this.gridContainer.nativeElement);
|
|
4325
|
+
// Cargar los elementos iniciales desde el JSON
|
|
4326
|
+
//this.loadLayoutFromJSON(this.dashboardItems);
|
|
4327
|
+
this.loadLayoutFromJSON(this.dashboardConfig, this.dashboardStyle);
|
|
4328
|
+
//Evaluar Bloqueo de Widgets en Inicializacion
|
|
4329
|
+
if (this.dashboardConfig.lockPositionWidgets) {
|
|
4330
|
+
this.fn_lockPositionWidgets(this.dashboardConfig.lockPositionWidgets);
|
|
4372
4331
|
}
|
|
4332
|
+
// Listener para detectar cambios y actualizar el JSON
|
|
4333
|
+
this.grid.on('change', (event, items) => {
|
|
4334
|
+
this.saveLayoutToJSON();
|
|
4335
|
+
});
|
|
4336
|
+
//Listener para detectar cuando cambia las dimenciones de un widget
|
|
4337
|
+
this.grid.on('resizestop', (event, el) => {
|
|
4338
|
+
// Disparamos el evento nativo del navegador de forma controlada
|
|
4339
|
+
window.dispatchEvent(new Event('resize'));
|
|
4340
|
+
});
|
|
4373
4341
|
}
|
|
4374
|
-
|
|
4375
|
-
|
|
4376
|
-
|
|
4377
|
-
|
|
4342
|
+
//Filtrar Datos por Componente del Widget
|
|
4343
|
+
fn_getDataForWidgetComponent(listTables, prmDashboardData) {
|
|
4344
|
+
let dataresponse = new Map();
|
|
4345
|
+
const ldsize = prmDashboardData.length;
|
|
4346
|
+
const ltsize = listTables.length;
|
|
4347
|
+
if (ltsize > 0) {
|
|
4348
|
+
listTables.forEach((curTableName) => {
|
|
4349
|
+
prmDashboardData.forEach((curTableRef) => {
|
|
4350
|
+
if (curTableName.localeCompare(curTableRef.tableName) == 0) {
|
|
4351
|
+
dataresponse.set(curTableRef.tableName, curTableRef.tableData);
|
|
4352
|
+
}
|
|
4353
|
+
});
|
|
4354
|
+
});
|
|
4378
4355
|
}
|
|
4379
|
-
else
|
|
4380
|
-
|
|
4356
|
+
else {
|
|
4357
|
+
prmDashboardData.forEach((curTableRef) => {
|
|
4358
|
+
dataresponse.set(curTableRef.tableName, curTableRef.tableData);
|
|
4359
|
+
});
|
|
4360
|
+
}
|
|
4361
|
+
const object_base_response = Object.fromEntries(dataresponse);
|
|
4362
|
+
return object_base_response;
|
|
4363
|
+
}
|
|
4364
|
+
fn_getDataForWidgetComponent_back(listTables) {
|
|
4365
|
+
let dataresponse = [];
|
|
4366
|
+
const ldsize = this.dashboardData.length;
|
|
4367
|
+
const ltsize = listTables.length;
|
|
4368
|
+
if (ltsize > 0) {
|
|
4369
|
+
listTables.forEach((curTableName) => {
|
|
4370
|
+
this.dashboardData.forEach((curTableData) => {
|
|
4371
|
+
if (curTableName.localeCompare(curTableData.tableName) == 0) {
|
|
4372
|
+
dataresponse.push(curTableData);
|
|
4373
|
+
}
|
|
4374
|
+
});
|
|
4375
|
+
});
|
|
4381
4376
|
}
|
|
4382
4377
|
else {
|
|
4383
|
-
|
|
4378
|
+
return this.dashboardData;
|
|
4384
4379
|
}
|
|
4385
|
-
|
|
4386
|
-
|
|
4387
|
-
|
|
4388
|
-
|
|
4389
|
-
|
|
4390
|
-
|
|
4391
|
-
|
|
4392
|
-
|
|
4393
|
-
|
|
4394
|
-
|
|
4395
|
-
|
|
4396
|
-
|
|
4397
|
-
const
|
|
4398
|
-
//
|
|
4399
|
-
|
|
4400
|
-
|
|
4380
|
+
return dataresponse;
|
|
4381
|
+
}
|
|
4382
|
+
// Carga elementos desde la configuración JSON
|
|
4383
|
+
//public loadLayoutFromJSON(dashboardItems: YwWidgetLayoutInterface[], ): void {
|
|
4384
|
+
loadLayoutFromJSON(prmDashboardConfig, prmDashboardStyle) {
|
|
4385
|
+
this.grid.removeAll();
|
|
4386
|
+
const widgets = [];
|
|
4387
|
+
this.grid.load(widgets);
|
|
4388
|
+
const lsize = prmDashboardConfig.controlListConfig.length;
|
|
4389
|
+
if (lsize > 0) {
|
|
4390
|
+
prmDashboardConfig.controlListConfig.forEach((widgetConfig) => {
|
|
4391
|
+
//Agregar uno por uno, para poder cargar los parametros internos de los componentes.
|
|
4392
|
+
const controlData = this.fn_getDataForWidgetComponent(widgetConfig.controlTables, this.dashboardData);
|
|
4393
|
+
//Sobre Escribir el ID Correcto en Layaout
|
|
4394
|
+
widgetConfig.layoutConfig.id = widgetConfig.widgetId;
|
|
4395
|
+
//Evaluar Mostrar Eventos
|
|
4396
|
+
if (widgetConfig.showConfigButtons == null || widgetConfig.showConfigButtons == undefined) {
|
|
4397
|
+
widgetConfig.showConfigButtons = prmDashboardConfig.showConfigButtons;
|
|
4401
4398
|
}
|
|
4402
|
-
//
|
|
4403
|
-
|
|
4404
|
-
|
|
4405
|
-
|
|
4406
|
-
|
|
4407
|
-
|
|
4408
|
-
|
|
4409
|
-
name: String(getNestedValue(item, xAxis))
|
|
4410
|
-
// ...(shouldColorLine ? { color: getRandomProfessionalHex() } : {})
|
|
4411
|
-
};
|
|
4399
|
+
//Evalua Asignacion de Estilos
|
|
4400
|
+
if (widgetConfig.widgetStyle == null || widgetConfig.widgetStyle == undefined) {
|
|
4401
|
+
widgetConfig['widgetStyle'] = {};
|
|
4402
|
+
widgetConfig['widgetStyle']['widgetBackgroundColor'] = prmDashboardStyle.widgetBackgroundColor;
|
|
4403
|
+
widgetConfig['widgetStyle']['widgetBorderColor'] = prmDashboardStyle.widgetBorderColor;
|
|
4404
|
+
}
|
|
4405
|
+
this.eventAddWidget(widgetConfig, widgetConfig.controlConfig, controlData, widgetConfig.layoutConfig);
|
|
4412
4406
|
});
|
|
4413
|
-
|
|
4414
|
-
|
|
4415
|
-
|
|
4416
|
-
|
|
4417
|
-
|
|
4418
|
-
|
|
4419
|
-
|
|
4420
|
-
|
|
4421
|
-
|
|
4422
|
-
|
|
4423
|
-
.
|
|
4407
|
+
}
|
|
4408
|
+
}
|
|
4409
|
+
// Guarda los elementos desde la configuración JSON
|
|
4410
|
+
saveLayoutToJSON() {
|
|
4411
|
+
const currentWidgets = this.grid.save(false);
|
|
4412
|
+
this.dashboardItems = currentWidgets.map(w => ({
|
|
4413
|
+
id: w.id,
|
|
4414
|
+
x: w.x || 0,
|
|
4415
|
+
y: w.y || 0,
|
|
4416
|
+
w: w.w || 1,
|
|
4417
|
+
h: w.h || 1,
|
|
4418
|
+
content: w.content,
|
|
4419
|
+
contentData: {}
|
|
4420
|
+
}));
|
|
4421
|
+
console.log('JSON Guardado:', JSON.stringify(this.dashboardItems));
|
|
4422
|
+
return this.dashboardItems;
|
|
4424
4423
|
}
|
|
4425
|
-
|
|
4426
|
-
|
|
4427
|
-
|
|
4428
|
-
|
|
4429
|
-
|
|
4430
|
-
|
|
4431
|
-
|
|
4432
|
-
}
|
|
4433
|
-
|
|
4434
|
-
|
|
4435
|
-
|
|
4436
|
-
|
|
4437
|
-
|
|
4438
|
-
|
|
4439
|
-
|
|
4440
|
-
|
|
4441
|
-
|
|
4442
|
-
|
|
4443
|
-
|
|
4444
|
-
|
|
4445
|
-
|
|
4446
|
-
|
|
4447
|
-
|
|
4448
|
-
|
|
4449
|
-
|
|
4450
|
-
|
|
4451
|
-
|
|
4452
|
-
};
|
|
4453
|
-
};
|
|
4454
|
-
|
|
4455
|
-
class BubbleChartSyncfusionComponent {
|
|
4456
|
-
constructor(elRef, cdr) {
|
|
4457
|
-
this.elRef = elRef;
|
|
4458
|
-
this.cdr = cdr;
|
|
4459
|
-
this.idComponent = '';
|
|
4460
|
-
this.dataChartParse = [];
|
|
4461
|
-
this.currentLabelSize = '';
|
|
4462
|
-
this.currentWidgetWidth = 0; // Valor inicial por defecto
|
|
4424
|
+
/*BUTTON ADD WIDGET*/
|
|
4425
|
+
fn_btn_addWidget() {
|
|
4426
|
+
this.countWidget++;
|
|
4427
|
+
const newWidgetId = 'widget-' + this.countWidget;
|
|
4428
|
+
let newItem = {
|
|
4429
|
+
id: newWidgetId, autoPosition: true, w: 6, h: 3,
|
|
4430
|
+
content: ''
|
|
4431
|
+
};
|
|
4432
|
+
//Datos de Widget y sus Contenidos
|
|
4433
|
+
const widgetConfig = {
|
|
4434
|
+
widgetId: newWidgetId,
|
|
4435
|
+
title: '',
|
|
4436
|
+
typeComponent: 'empty-visual',
|
|
4437
|
+
showConfigButtons: true,
|
|
4438
|
+
widgetStyle: DEFAULT_WIDGET_STYLE,
|
|
4439
|
+
layoutConfig: {
|
|
4440
|
+
id: '',
|
|
4441
|
+
w: 0,
|
|
4442
|
+
h: 0,
|
|
4443
|
+
content: undefined
|
|
4444
|
+
},
|
|
4445
|
+
controlConfig: {},
|
|
4446
|
+
controlTables: []
|
|
4447
|
+
};
|
|
4448
|
+
const controlConfig = {};
|
|
4449
|
+
const controlData = {};
|
|
4450
|
+
this.eventAddWidget(widgetConfig, controlConfig, controlData, newItem);
|
|
4463
4451
|
}
|
|
4464
|
-
|
|
4465
|
-
|
|
4452
|
+
/*BUTTON DELETE WIDGET*/
|
|
4453
|
+
fn_btn_deleteWidget() {
|
|
4454
|
+
const newWidgetId = 'widget-' + this.countWidget;
|
|
4455
|
+
this.eventRemoveWidgetById(newWidgetId);
|
|
4456
|
+
this.countWidget--;
|
|
4466
4457
|
}
|
|
4467
|
-
|
|
4468
|
-
|
|
4469
|
-
|
|
4470
|
-
|
|
4458
|
+
/*BUTTON BLOCK WIDGETS*/
|
|
4459
|
+
fn_btn_lockPositionWidgets() {
|
|
4460
|
+
this.isLocked = !this.isLocked;
|
|
4461
|
+
const shouldLock = !this.allIsLocked();
|
|
4462
|
+
this.allIsLocked.set(shouldLock);
|
|
4463
|
+
this.fn_lockPositionWidgets(shouldLock);
|
|
4464
|
+
console.log(`All widgets have been visually and functionally locked: ${shouldLock}`);
|
|
4471
4465
|
}
|
|
4472
|
-
|
|
4473
|
-
|
|
4466
|
+
fn_lockPositionWidgets(prmAllIsLocked) {
|
|
4467
|
+
const shouldLock = prmAllIsLocked;
|
|
4468
|
+
// 1. Perform the functional Gridstack task on the core grid layout
|
|
4469
|
+
this.grid.movable('.grid-stack-item', !shouldLock);
|
|
4470
|
+
this.grid.resizable('.grid-stack-item', !shouldLock);
|
|
4471
|
+
// 2. Broadcast the state change down to every active dynamic child component
|
|
4472
|
+
this.widgetsActivos.forEach((componentRef) => {
|
|
4473
|
+
componentRef.setInput('isLocked', shouldLock);
|
|
4474
|
+
});
|
|
4475
|
+
console.log(`All widgets have been visually and functionally locked - por TS Config: ${shouldLock}`);
|
|
4474
4476
|
}
|
|
4475
|
-
|
|
4476
|
-
|
|
4477
|
+
/*BUTTON UPDATE WIDGET - CONTROL CONFIG */
|
|
4478
|
+
fn_btn_updateWidgetControlConfig(idWidget) {
|
|
4479
|
+
let newControlConfig = {};
|
|
4480
|
+
/*MODIFICAR METODO PARA CARGAR INFO DEL FORMULARIO*/
|
|
4481
|
+
newControlConfig['provider'] = 'syncfusion';
|
|
4482
|
+
this.eventUpdateWidgetControlConfig(idWidget, newControlConfig);
|
|
4477
4483
|
}
|
|
4478
|
-
|
|
4479
|
-
|
|
4480
|
-
|
|
4481
|
-
|
|
4482
|
-
|
|
4483
|
-
|
|
4484
|
-
|
|
4485
|
-
|
|
4486
|
-
}
|
|
4487
|
-
|
|
4488
|
-
|
|
4489
|
-
|
|
4490
|
-
|
|
4491
|
-
|
|
4492
|
-
}
|
|
4484
|
+
/*BUTTON UPDATE WIDGET - CONTROL CONFIG */
|
|
4485
|
+
fn_btn_updateWidgetControlData(idWidget) {
|
|
4486
|
+
let newControlData = [];
|
|
4487
|
+
/*MODIFICAR METODO PARA CARGAR INFO DEL FORMULARIO*/
|
|
4488
|
+
newControlData = [
|
|
4489
|
+
{ month: 'Ene', sales: 35, expenses: 28 },
|
|
4490
|
+
{ month: 'Feb', sales: 28, expenses: 22 },
|
|
4491
|
+
{ month: 'Mar', sales: 34, expenses: 25 },
|
|
4492
|
+
{ month: 'Abr', sales: 32, expenses: 27 },
|
|
4493
|
+
{ month: 'May', sales: 40, expenses: 30 },
|
|
4494
|
+
{ month: 'Jun', sales: 32, expenses: 26 },
|
|
4495
|
+
{ month: 'Jul', sales: 45, expenses: 32 },
|
|
4496
|
+
{ month: 'Ago', sales: 38, expenses: 29 },
|
|
4497
|
+
{ month: 'Sep', sales: 42, expenses: 31 },
|
|
4498
|
+
{ month: 'Oct', sales: 48, expenses: 35 },
|
|
4499
|
+
{ month: 'Nov', sales: 52, expenses: 38 },
|
|
4500
|
+
{ month: 'Dic', sales: 58, expenses: 42 },
|
|
4501
|
+
];
|
|
4502
|
+
this.eventUpdateWidgetControlData(idWidget, newControlData);
|
|
4503
|
+
}
|
|
4504
|
+
/****************************************************** */
|
|
4505
|
+
/*AGREGAR WIDGET*/
|
|
4506
|
+
eventAddWidget(widgetConfig, controlConfig, controlData, item) {
|
|
4507
|
+
// 1. Agregar el contenedor del widget a Gridstack
|
|
4508
|
+
const el = this.grid.addWidget(item);
|
|
4509
|
+
// 2. Obtener el contenedor interno generado por Gridstack
|
|
4510
|
+
const contentElement = el.querySelector('.grid-stack-item-content');
|
|
4511
|
+
if (contentElement) {
|
|
4512
|
+
// 3. Crear dinámicamente la instancia del componente Angular
|
|
4513
|
+
const componentRef = createComponent(YwDashboardWidgetComponent, {
|
|
4514
|
+
environmentInjector: this.environmentInjector, // Requerido para resolver dependencias
|
|
4515
|
+
hostElement: contentElement // Renderiza directamente aquí dentro
|
|
4516
|
+
});
|
|
4517
|
+
// 4. Pasar las propiedades/Inputs al componente creado
|
|
4518
|
+
//Evaluar Estilos
|
|
4519
|
+
componentRef.setInput('styleWidget', widgetConfig.widgetStyle);
|
|
4520
|
+
//componentRef.instance.configWidget = widgetConfig;
|
|
4521
|
+
componentRef.setInput('configWidget', widgetConfig);
|
|
4522
|
+
componentRef.setInput('controlConfig', controlConfig);
|
|
4523
|
+
componentRef.setInput('controlData', controlData);
|
|
4524
|
+
/* BEGIN - Eventos que provienen desde widget */
|
|
4525
|
+
componentRef.instance.eventDeleteRequest.subscribe((idWidget) => {
|
|
4526
|
+
// Ejecutamos la función de borrado que ya programamos en el paso anterior
|
|
4527
|
+
this.eventRemoveWidgetById(idWidget);
|
|
4528
|
+
});
|
|
4529
|
+
componentRef.instance.eventLockToggleRequest.subscribe((event) => {
|
|
4530
|
+
this.eventToggleLockWidget(event.widgetId, event.shouldLock);
|
|
4531
|
+
});
|
|
4532
|
+
componentRef.instance.eventMaximizeToggleRequest.subscribe((event) => {
|
|
4533
|
+
this.eventToggleMaximizeWidget(event.widgetId, event.shouldMaximize);
|
|
4534
|
+
});
|
|
4535
|
+
//Mostrar
|
|
4536
|
+
componentRef.instance.eventShowConfigFormRequest.subscribe((idWidget) => {
|
|
4537
|
+
this.eventShowFormConfigWidget(idWidget);
|
|
4538
|
+
});
|
|
4539
|
+
/* END - Eventos que provienen desde widget */
|
|
4540
|
+
// 5. Mover los nodos del DOM generados por Angular dentro del DIV del Widget
|
|
4541
|
+
this.appRef.attachView(componentRef.hostView);
|
|
4542
|
+
// Guardar la referencia de Componentes para hacer operaciones con estas.
|
|
4543
|
+
this.widgetsActivos.set(item.id, componentRef);
|
|
4544
|
+
//El componente interno no aparece bien dimensionado, con esto disparamos el evento para que se ajuste a las dimenciones correctas
|
|
4545
|
+
setTimeout(() => {
|
|
4546
|
+
window.dispatchEvent(new Event('resize'));
|
|
4547
|
+
}, 50);
|
|
4493
4548
|
}
|
|
4494
4549
|
}
|
|
4495
|
-
|
|
4496
|
-
|
|
4497
|
-
|
|
4498
|
-
|
|
4499
|
-
|
|
4500
|
-
|
|
4501
|
-
// case 'threshold':
|
|
4502
|
-
// passesRule = yValue >= (configPoint.thresholdValue || 0);
|
|
4503
|
-
// break;
|
|
4504
|
-
// case 'pair':
|
|
4505
|
-
// passesRule = yValue % 2 === 0;
|
|
4506
|
-
// break;
|
|
4507
|
-
// case 'range':
|
|
4508
|
-
// const min = configPoint.minRange || 0;
|
|
4509
|
-
// const max = configPoint.maxRange || 100;
|
|
4510
|
-
// passesRule = yValue >= min && yValue <= max;
|
|
4511
|
-
// break;
|
|
4512
|
-
// default:
|
|
4513
|
-
// passesRule = true;
|
|
4514
|
-
// }
|
|
4515
|
-
// args.fill = passesRule ? (configPoint.trueColor || '#10B981') : (configPoint.falseColor || '#EF4444');
|
|
4516
|
-
// }
|
|
4517
|
-
pointRender(args) {
|
|
4518
|
-
const yValue = Number(args.point.y);
|
|
4519
|
-
// =====================================================
|
|
4520
|
-
// EMPTY POINT / VALOR 0
|
|
4521
|
-
// Tiene prioridad sobre ruleColorPoint
|
|
4522
|
-
// =====================================================
|
|
4523
|
-
if (yValue === 0) {
|
|
4524
|
-
const emptyPoint = this.config.emptyPointSettings;
|
|
4525
|
-
if (emptyPoint && emptyPoint !== '') {
|
|
4526
|
-
args.fill = emptyPoint;
|
|
4527
|
-
}
|
|
4550
|
+
/*UPDATE CONTROLCONFIG WIDGET*/
|
|
4551
|
+
eventUpdateWidgetControlConfig(idWidget, newControlConfig) {
|
|
4552
|
+
//Obtener la referencia del componente almacenada en el Map
|
|
4553
|
+
const componentRef = this.widgetsActivos.get(idWidget);
|
|
4554
|
+
if (!componentRef) {
|
|
4555
|
+
console.warn(`No se encontró un widget activo con el ID: ${idWidget}`);
|
|
4528
4556
|
return;
|
|
4529
4557
|
}
|
|
4530
|
-
//
|
|
4531
|
-
|
|
4532
|
-
//
|
|
4533
|
-
|
|
4534
|
-
|
|
4558
|
+
//Actualizar el Input usando la API oficial setInput
|
|
4559
|
+
componentRef.setInput('controlConfig', newControlConfig);
|
|
4560
|
+
// NOTA: setInput dispara automáticamente la detección de cambios (ChangeDetectionStrategy.OnPush).
|
|
4561
|
+
// Si deseas asegurarte manualmente, puedes forzar un render:
|
|
4562
|
+
// componentRef.changeDetectorRef.detectChanges();
|
|
4563
|
+
}
|
|
4564
|
+
/*UPDATE CONTROL DATA WIDGET*/
|
|
4565
|
+
eventUpdateWidgetControlData(idWidget, newControlData) {
|
|
4566
|
+
//Obtener la referencia del componente almacenada en el Map
|
|
4567
|
+
const componentRef = this.widgetsActivos.get(idWidget);
|
|
4568
|
+
if (!componentRef) {
|
|
4569
|
+
console.warn(`No se encontró un widget activo con el ID: ${idWidget}`);
|
|
4535
4570
|
return;
|
|
4536
4571
|
}
|
|
4537
|
-
|
|
4538
|
-
|
|
4539
|
-
|
|
4540
|
-
|
|
4541
|
-
|
|
4542
|
-
|
|
4543
|
-
|
|
4544
|
-
|
|
4545
|
-
|
|
4546
|
-
|
|
4547
|
-
|
|
4548
|
-
|
|
4549
|
-
|
|
4550
|
-
|
|
4551
|
-
|
|
4552
|
-
|
|
4553
|
-
|
|
4554
|
-
|
|
4572
|
+
//Actualizar el Input usando la API oficial setInput
|
|
4573
|
+
componentRef.setInput('controlData', newControlData);
|
|
4574
|
+
// NOTA: setInput dispara automáticamente la detección de cambios (ChangeDetectionStrategy.OnPush).
|
|
4575
|
+
// Si deseas asegurarte manualmente, puedes forzar un render:
|
|
4576
|
+
componentRef.changeDetectorRef.detectChanges();
|
|
4577
|
+
}
|
|
4578
|
+
/****************************************************** */
|
|
4579
|
+
/* BEGIN - DRAWER */
|
|
4580
|
+
handleShowFormFilterDrawer() {
|
|
4581
|
+
this.drawerfiltervisible = true;
|
|
4582
|
+
}
|
|
4583
|
+
handleCloseFormFilterDrawer() {
|
|
4584
|
+
this.drawerfiltervisible = false;
|
|
4585
|
+
}
|
|
4586
|
+
handleCloseFormDrawer() {
|
|
4587
|
+
this.drawerconfigvisible = false;
|
|
4588
|
+
}
|
|
4589
|
+
fnGetDrawerWidth(prm_percent) {
|
|
4590
|
+
const curWidth = window.innerWidth;
|
|
4591
|
+
let newWidth = curWidth;
|
|
4592
|
+
if (prm_percent) {
|
|
4593
|
+
newWidth = Math.floor(curWidth * prm_percent / 100);
|
|
4555
4594
|
}
|
|
4556
|
-
|
|
4557
|
-
|
|
4558
|
-
|
|
4595
|
+
if (newWidth < 400) {
|
|
4596
|
+
newWidth = curWidth;
|
|
4597
|
+
}
|
|
4598
|
+
return newWidth;
|
|
4559
4599
|
}
|
|
4560
|
-
|
|
4561
|
-
|
|
4562
|
-
|
|
4563
|
-
|
|
4564
|
-
|
|
4565
|
-
|
|
4566
|
-
|
|
4567
|
-
|
|
4568
|
-
|
|
4569
|
-
|
|
4570
|
-
|
|
4571
|
-
|
|
4572
|
-
|
|
4573
|
-
|
|
4600
|
+
onFilterSelectionChange(eventData) {
|
|
4601
|
+
const lsize = this.widgetsActivos.size;
|
|
4602
|
+
//Validar que ya se crearon y renderizaron los componentes graficos.
|
|
4603
|
+
if (lsize > 0) {
|
|
4604
|
+
const currentFilterController = this.dashboardFilterConfig.controlListConfig.find((x) => x.widgetId == eventData['widgetId']);
|
|
4605
|
+
if (currentFilterController) {
|
|
4606
|
+
currentFilterController.controlFilterData = eventData['eventResponse'];
|
|
4607
|
+
this.fnUpdateDataControllerBasedOnFilter(this.dashboardFilterConfig.controlListConfig);
|
|
4608
|
+
}
|
|
4609
|
+
}
|
|
4610
|
+
}
|
|
4611
|
+
fnUpdateDataControllerBasedOnFilter(filterControlListConfig) {
|
|
4612
|
+
let copyDashboardData = structuredClone(this.dashboardData);
|
|
4613
|
+
filterControlListConfig.forEach((item) => {
|
|
4614
|
+
let tableSelected = copyDashboardData.find((x) => x.tableName == item.controlTable);
|
|
4615
|
+
if (item.typeComponent == 'filter-slicer' && tableSelected && item.controlFilterData) {
|
|
4616
|
+
const fieldName = item.configComponent.filterField;
|
|
4617
|
+
if (item.configComponent.dataType == 'date') {
|
|
4618
|
+
const minDate = item.controlFilterData['startDate'];
|
|
4619
|
+
const maxDate = item.controlFilterData['endDate'];
|
|
4620
|
+
if (minDate && maxDate) {
|
|
4621
|
+
const filterData = tableSelected.tableData.filter((y) => (minDate <= y[fieldName] && y[fieldName] <= maxDate));
|
|
4622
|
+
tableSelected.tableData = filterData;
|
|
4574
4623
|
}
|
|
4575
4624
|
}
|
|
4576
|
-
|
|
4577
|
-
|
|
4578
|
-
|
|
4579
|
-
|
|
4580
|
-
|
|
4581
|
-
|
|
4582
|
-
|
|
4583
|
-
? this.config.labelSize
|
|
4584
|
-
: parseFloat(this.config.labelSize);
|
|
4585
|
-
if (!isNaN(parsedSize)) {
|
|
4586
|
-
if (width < 260) {
|
|
4587
|
-
const scale = Math.max(0.65, width / 260);
|
|
4588
|
-
this.currentLabelSize = `${Math.round(parsedSize * scale)}px`;
|
|
4625
|
+
if (item.configComponent.dataType == 'number') {
|
|
4626
|
+
const minNum = Number(item.controlFilterData['minValue']);
|
|
4627
|
+
const maxNum = Number(item.controlFilterData['maxValue']);
|
|
4628
|
+
if (minNum && maxNum) {
|
|
4629
|
+
const filterData = tableSelected.tableData.filter((y) => (minNum <= y[fieldName] && y[fieldName] <= maxNum));
|
|
4630
|
+
tableSelected.tableData = filterData;
|
|
4631
|
+
}
|
|
4589
4632
|
}
|
|
4590
|
-
|
|
4591
|
-
|
|
4633
|
+
}
|
|
4634
|
+
if (item.typeComponent == 'filter-button' && tableSelected && item.controlFilterData) {
|
|
4635
|
+
const fieldName = item.configComponent.filterField;
|
|
4636
|
+
const listValues = item.controlFilterData || [];
|
|
4637
|
+
if (listValues && listValues.length > 0) {
|
|
4638
|
+
const filterData = tableSelected.tableData.filter((y) => (listValues.includes(y[fieldName])));
|
|
4639
|
+
tableSelected.tableData = filterData;
|
|
4592
4640
|
}
|
|
4593
|
-
this.cdr.markForCheck();
|
|
4594
|
-
return;
|
|
4595
4641
|
}
|
|
4596
|
-
|
|
4597
|
-
|
|
4598
|
-
|
|
4599
|
-
|
|
4600
|
-
|
|
4642
|
+
if (item.typeComponent == 'filter-list' && tableSelected && item.controlFilterData) {
|
|
4643
|
+
const fieldName = item.configComponent.filterField;
|
|
4644
|
+
if (item.configComponent.dataType == 'text') {
|
|
4645
|
+
const listValues = item.controlFilterData['ids'] || [];
|
|
4646
|
+
if (listValues && listValues.length > 0) {
|
|
4647
|
+
const listValues1D = listValues;
|
|
4648
|
+
const filterData = tableSelected.tableData.filter((y) => (listValues1D.includes(y[fieldName])));
|
|
4649
|
+
tableSelected.tableData = filterData;
|
|
4650
|
+
}
|
|
4651
|
+
}
|
|
4652
|
+
if (item.configComponent.dataType == 'date') {
|
|
4653
|
+
const minDate = item.controlFilterData['minDate'];
|
|
4654
|
+
const maxDate = item.controlFilterData['maxDate'];
|
|
4655
|
+
if (minDate && maxDate) {
|
|
4656
|
+
const filterData = tableSelected.tableData.filter((y) => (minDate <= y[fieldName] && y[fieldName] <= maxDate));
|
|
4657
|
+
tableSelected.tableData = filterData;
|
|
4658
|
+
}
|
|
4659
|
+
}
|
|
4660
|
+
}
|
|
4661
|
+
});
|
|
4662
|
+
//Actualizacion de Data Componentes Graficos
|
|
4663
|
+
this.dashboardConfig.controlListConfig.forEach((item) => {
|
|
4664
|
+
const controlData = this.fn_getDataForWidgetComponent(item.controlTables, copyDashboardData);
|
|
4665
|
+
this.eventUpdateWidgetControlData(item.widgetId, controlData);
|
|
4666
|
+
});
|
|
4601
4667
|
}
|
|
4602
|
-
|
|
4603
|
-
|
|
4668
|
+
/* END - DRAWER */
|
|
4669
|
+
/* BEGIN - Eventos que provienen desde widget */
|
|
4670
|
+
eventRemoveWidgetById(widgetId) {
|
|
4671
|
+
// 1. Buscar el elemento HTML físico dentro de Gridstack usando su atributo interno [gs-id]
|
|
4672
|
+
const elementoHtml = this.gridContainer.nativeElement.querySelector(`[gs-id="${widgetId}"]`);
|
|
4673
|
+
if (elementoHtml) {
|
|
4674
|
+
// 2. Remover el elemento de Gridstack (esto limpia el HTML y reordena el tablero si float es false)
|
|
4675
|
+
// El parámetro false indica que remueva el nodo del DOM pero no dispare eventos internos destructivos pesados
|
|
4676
|
+
this.grid.removeWidget(elementoHtml, false);
|
|
4677
|
+
}
|
|
4678
|
+
// 3. Buscar y destruir la instancia de Angular en memoria RAM
|
|
4679
|
+
const componentRef = this.widgetsActivos.get(widgetId);
|
|
4680
|
+
if (componentRef) {
|
|
4681
|
+
// Desengancha la vista del ciclo de renderizado global de Angular
|
|
4682
|
+
this.appRef.detachView(componentRef.hostView);
|
|
4683
|
+
// Destruye el componente y libera la memoria RAM
|
|
4684
|
+
componentRef.destroy();
|
|
4685
|
+
// Eliminamos el registro de nuestro Mapa
|
|
4686
|
+
this.widgetsActivos.delete(widgetId);
|
|
4687
|
+
}
|
|
4688
|
+
//console.log(`Widget ${widgetId} eliminado con éxito de Gridstack y Angular.`);
|
|
4604
4689
|
}
|
|
4605
|
-
|
|
4606
|
-
|
|
4607
|
-
|
|
4608
|
-
|
|
4609
|
-
|
|
4610
|
-
|
|
4611
|
-
|
|
4612
|
-
// }
|
|
4613
|
-
// }
|
|
4614
|
-
axisLabelRender(args) {
|
|
4615
|
-
const umbralWidget = 700;
|
|
4616
|
-
if (this.currentWidgetWidth > umbralWidget) {
|
|
4617
|
-
return;
|
|
4690
|
+
eventToggleLockWidget(widgetId, shouldLock) {
|
|
4691
|
+
const elementoHtml = this.gridContainer.nativeElement.querySelector(`[gs-id="${widgetId}"]`);
|
|
4692
|
+
if (elementoHtml) {
|
|
4693
|
+
// La API de Gridstack nos permite congelar un nodo específico pasándole true/false
|
|
4694
|
+
this.grid.movable(elementoHtml, !shouldLock);
|
|
4695
|
+
this.grid.resizable(elementoHtml, !shouldLock);
|
|
4696
|
+
//console.log(`Widget ${widgetId} cambiado a estado bloqueado: ${shouldLock}`);
|
|
4618
4697
|
}
|
|
4619
|
-
|
|
4620
|
-
|
|
4621
|
-
|
|
4622
|
-
|
|
4623
|
-
|
|
4624
|
-
|
|
4625
|
-
|
|
4698
|
+
}
|
|
4699
|
+
eventToggleMaximizeWidget(widgetId, shouldMaximize) {
|
|
4700
|
+
const elementoHtml = this.gridContainer.nativeElement.querySelector(`[gs-id="${widgetId}"]`);
|
|
4701
|
+
if (elementoHtml) {
|
|
4702
|
+
if (shouldMaximize) {
|
|
4703
|
+
// Aplicamos estilos CSS nativos para forzar al contenedor a flotar sobre todo el dashboard
|
|
4704
|
+
elementoHtml.classList.add('widget-maximized');
|
|
4705
|
+
// Deshabilitamos temporalmente que Gridstack intente moverlo mientras está maximizado
|
|
4706
|
+
this.grid.movable(elementoHtml, false);
|
|
4707
|
+
this.grid.resizable(elementoHtml, false);
|
|
4626
4708
|
}
|
|
4627
4709
|
else {
|
|
4628
|
-
|
|
4629
|
-
|
|
4630
|
-
|
|
4710
|
+
elementoHtml.classList.remove('widget-maximized');
|
|
4711
|
+
// Restauramos los permisos normales leyendo si el componente de Angular estaba bloqueado previamente
|
|
4712
|
+
const componentRef = this.widgetsActivos.get(widgetId);
|
|
4713
|
+
const isCurrentlyLocked = componentRef?.instance.isLocked() || false;
|
|
4714
|
+
this.grid.movable(elementoHtml, !isCurrentlyLocked);
|
|
4715
|
+
this.grid.resizable(elementoHtml, !isCurrentlyLocked);
|
|
4631
4716
|
}
|
|
4717
|
+
// Forzamos un evento resize simulado para que los gráficos de Syncfusion recalculen su nuevo tamaño gigante/pequeño
|
|
4718
|
+
setTimeout(() => {
|
|
4719
|
+
window.dispatchEvent(new Event('resize'));
|
|
4720
|
+
}, 50);
|
|
4632
4721
|
}
|
|
4633
4722
|
}
|
|
4634
|
-
|
|
4635
|
-
|
|
4636
|
-
|
|
4637
|
-
LegendService,
|
|
4638
|
-
DateTimeService], viewQueries: [{ propertyName: "chartInstance", first: true, predicate: ["chart"], descendants: true }], usesOnChanges: true, ngImport: i0, template: "<div class=\"control-section\">\r\n\r\n <ejs-chart \r\n #chart \r\n [primaryXAxis]=\"labelData.axisX\" \r\n [primaryYAxis]=\"labelData.axisY\" \r\n [title]=\"labelData.title\" \r\n (pointRender)=\"pointRender($event)\" \r\n height=\"100%\"\r\n width=\"100%\"\r\n [legendSettings]=\"labelData.legendSettings\"\r\n (axisLabelRender)=\"axisLabelRender($event)\"\r\n\r\n [tooltip]=\"labelData.tooltip\">\r\n <e-series-collection>\r\n @for(series of dataChartParse; track $index){\r\n <e-series \r\n [opacity]=\"series.opacity\"\r\n [dataSource]='series.dataSource' \r\n type='Bubble' \r\n xName='x' \r\n yName='y' \r\n size='size' \r\n [name]='series.name'>\r\n </e-series>\r\n\r\n }\r\n </e-series-collection>\r\n</ejs-chart>\r\n</div>", styles: ["@charset \"UTF-8\";:host{display:flex;flex-direction:column;width:100%;height:100%;min-height:260px;box-sizing:border-box;overflow:hidden}.control-section{display:flex;flex-direction:column;width:100%;height:100%;min-height:260px;box-sizing:border-box;overflow:hidden;background:#fff;border-radius:8px}:host ::ng-deep ejs-circulargauge{display:block;width:100%!important;height:100%!important;flex-grow:1}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: ChartModule }, { kind: "component", type: i1.ChartComponent, selector: "ejs-chart", inputs: ["accessibility", "allowExport", "allowMultiSelection", "annotations", "axes", "background", "backgroundImage", "border", "chartArea", "columns", "crosshair", "currencyCode", "dataSource", "description", "enableAnimation", "enableAutoIntervalOnBothAxis", "enableCanvas", "enableExport", "enableHtmlSanitizer", "enablePersistence", "enableRtl", "enableSideBySidePlacement", "focusBorderColor", "focusBorderMargin", "focusBorderWidth", "height", "highlightColor", "highlightMode", "highlightPattern", "indicators", "isMultiSelect", "isTransposed", "legendSettings", "locale", "margin", "palettes", "primaryXAxis", "primaryYAxis", "rangeColorSettings", "rows", "selectedDataIndexes", "selectionMode", "selectionPattern", "series", "subTitle", "subTitleStyle", "tabIndex", "theme", "title", "titleStyle", "tooltip", "useGroupingSeparator", "width", "zoomSettings"], outputs: ["afterExport", "animationComplete", "annotationRender", "axisLabelClick", "axisLabelRender", "axisMultiLabelRender", "axisRangeCalculated", "beforeExport", "beforePrint", "beforeResize", "chartDoubleClick", "chartMouseClick", "chartMouseDown", "chartMouseLeave", "chartMouseMove", "chartMouseUp", "drag", "dragComplete", "dragEnd", "dragStart", "legendClick", "legendRender", "load", "loaded", "multiLevelLabelClick", "onZooming", "pointClick", "pointDoubleClick", "pointMove", "pointRender", "resized", "scrollChanged", "scrollEnd", "scrollStart", "selectionComplete", "seriesRender", "sharedTooltipRender", "textRender", "tooltipRender", "zoomComplete", "dataSourceChange"] }, { kind: "directive", type: i1.SeriesDirective, selector: "e-series-collection>e-series", inputs: ["accessibility", "animation", "bearFillColor", "binInterval", "border", "boxPlotMode", "bullFillColor", "cardinalSplineTension", "close", "colorName", "columnFacet", "columnSpacing", "columnWidth", "columnWidthInPixel", "connector", "cornerRadius", "dashArray", "dataSource", "dragSettings", "drawType", "emptyPointSettings", "enableComplexProperty", "enableSolidCandles", "enableTooltip", "errorBar", "fill", "groupName", "high", "intermediateSumIndexes", "isClosed", "legendImageUrl", "legendShape", "low", "marker", "maxRadius", "minRadius", "name", "negativeFillColor", "noRisers", "nonHighlightStyle", "opacity", "open", "paretoOptions", "pointColorMapping", "query", "segmentAxis", "segments", "selectionStyle", "showMean", "showNormalDistribution", "size", "splineType", "stackingGroup", "step", "sumIndexes", "summaryFillColor", "tooltipFormat", "tooltipMappingName", "trendlines", "type", "unSelectedStyle", "visible", "volume", "width", "xAxisName", "xName", "yAxisName", "yName", "zOrder"] }, { kind: "directive", type: i1.SeriesCollectionDirective, selector: "ej-chart>e-series-collection" }] }); }
|
|
4639
|
-
}
|
|
4640
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.30", ngImport: i0, type: BubbleChartSyncfusionComponent, decorators: [{
|
|
4641
|
-
type: Component,
|
|
4642
|
-
args: [{ selector: 'yw-bubble-chart-syncfusion', standalone: true, imports: [CommonModule, ChartModule], providers: [BubbleSeriesService, CategoryService, CategoryService,
|
|
4643
|
-
TooltipService,
|
|
4644
|
-
LegendService,
|
|
4645
|
-
DateTimeService], template: "<div class=\"control-section\">\r\n\r\n <ejs-chart \r\n #chart \r\n [primaryXAxis]=\"labelData.axisX\" \r\n [primaryYAxis]=\"labelData.axisY\" \r\n [title]=\"labelData.title\" \r\n (pointRender)=\"pointRender($event)\" \r\n height=\"100%\"\r\n width=\"100%\"\r\n [legendSettings]=\"labelData.legendSettings\"\r\n (axisLabelRender)=\"axisLabelRender($event)\"\r\n\r\n [tooltip]=\"labelData.tooltip\">\r\n <e-series-collection>\r\n @for(series of dataChartParse; track $index){\r\n <e-series \r\n [opacity]=\"series.opacity\"\r\n [dataSource]='series.dataSource' \r\n type='Bubble' \r\n xName='x' \r\n yName='y' \r\n size='size' \r\n [name]='series.name'>\r\n </e-series>\r\n\r\n }\r\n </e-series-collection>\r\n</ejs-chart>\r\n</div>", styles: ["@charset \"UTF-8\";:host{display:flex;flex-direction:column;width:100%;height:100%;min-height:260px;box-sizing:border-box;overflow:hidden}.control-section{display:flex;flex-direction:column;width:100%;height:100%;min-height:260px;box-sizing:border-box;overflow:hidden;background:#fff;border-radius:8px}:host ::ng-deep ejs-circulargauge{display:block;width:100%!important;height:100%!important;flex-grow:1}\n"] }]
|
|
4646
|
-
}], ctorParameters: () => [{ type: i0.ElementRef }, { type: i0.ChangeDetectorRef }], propDecorators: { chartInstance: [{
|
|
4647
|
-
type: ViewChild,
|
|
4648
|
-
args: ['chart']
|
|
4649
|
-
}], chartData: [{
|
|
4650
|
-
type: Input,
|
|
4651
|
-
args: ['chartData']
|
|
4652
|
-
}], config: [{
|
|
4653
|
-
type: Input,
|
|
4654
|
-
args: ['config']
|
|
4655
|
-
}], idComponent: [{
|
|
4656
|
-
type: Input,
|
|
4657
|
-
args: ['idComponent']
|
|
4658
|
-
}] } });
|
|
4659
|
-
|
|
4660
|
-
// import { LineChartSyncfusionComponent } from '../../../../../adapters/charts/line-chart/syncfusion/visual/yw-line-chart-syncfusion.component';
|
|
4661
|
-
// import { YwLineMappingConfig } from '../../../../../models/config/chart/yw-line-chart-config.interface';
|
|
4662
|
-
class BubbleChartComponent {
|
|
4663
|
-
constructor() {
|
|
4664
|
-
this.idComponent = '';
|
|
4665
|
-
}
|
|
4666
|
-
ngOnChanges(changes) {
|
|
4667
|
-
if (changes['chartData']) {
|
|
4668
|
-
console.log('change chartData:', changes['chartData'].currentValue);
|
|
4669
|
-
}
|
|
4670
|
-
if (changes['config']) {
|
|
4671
|
-
console.log('change config:', changes['config'].currentValue);
|
|
4672
|
-
}
|
|
4723
|
+
eventShowFormConfigWidget(widgetId) {
|
|
4724
|
+
this.drawerCurrentWidgetObject['widgetId'] = widgetId;
|
|
4725
|
+
this.drawerconfigvisible = true;
|
|
4673
4726
|
}
|
|
4674
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.30", ngImport: i0, type:
|
|
4675
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.30", type: BubbleChartComponent, isStandalone: true, selector: "yw-bubble-chart", inputs: { chartData: "chartData", config: "config", idComponent: "idComponent" }, usesOnChanges: true, ngImport: i0, template: "llegamos\r\n@if(config.provider==='syncfusion'){\r\n <div style=\"position: relative; width: 100%; height: 100%;\">\r\n <yw-bubble-chart-syncfusion \r\n [idComponent]=\"idComponent\"\r\n [chartData]=\"chartData\" \r\n [config]=\"config\" style=\"display: block; width: 100%; height: 100%;\">\r\n </yw-bubble-chart-syncfusion>\r\n</div>\r\n}", styles: [":host{display:block;width:100%;height:100%;min-height:260px;min-width:0;overflow:hidden}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "component", type: BubbleChartSyncfusionComponent, selector: "yw-bubble-chart-syncfusion", inputs: ["chartData", "config", "idComponent"] }] }); }
|
|
4727
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.30", ngImport: i0, type: YwDashboardComponent, deps: [{ token: i0.EnvironmentInjector }, { token: i0.ApplicationRef }], target: i0.ɵɵFactoryTarget.Component }); }
|
|
4728
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.30", type: YwDashboardComponent, isStandalone: true, selector: "yw-dashboard", inputs: { showControls: { classPropertyName: "showControls", publicName: "showControls", isSignal: true, isRequired: false, transformFunction: null }, showFilter: { classPropertyName: "showFilter", publicName: "showFilter", isSignal: true, isRequired: false, transformFunction: null }, dashboardStyle: { classPropertyName: "dashboardStyle", publicName: "dashboardStyle", isSignal: false, isRequired: false, transformFunction: null }, dashboardConfig: { classPropertyName: "dashboardConfig", publicName: "dashboardConfig", isSignal: false, isRequired: false, transformFunction: null }, dashboardData: { classPropertyName: "dashboardData", publicName: "dashboardData", isSignal: false, isRequired: false, transformFunction: null }, dashboardFilterConfig: { classPropertyName: "dashboardFilterConfig", publicName: "dashboardFilterConfig", isSignal: false, isRequired: false, transformFunction: null } }, viewQueries: [{ propertyName: "gridContainer", first: true, predicate: ["gridContainer"], descendants: true, static: true }], usesOnChanges: true, ngImport: i0, template: "<!-- <div class=\"controls\" [hidden]=\"!showControls()\">\r\n <button (click)=\"saveLayoutToJSON()\">Guardar JSON en Consola</button>\r\n <button (click)=\"fn_btn_addWidget()\">add widget</button>\r\n <button (click)=\"fn_btn_lockPositionWidgets()\">Lock widgets</button>\r\n <button (click)=\"handleShowFormFilterDrawer()\" class=\"btn-filtro\">\r\n <svg *ngIf=\"drawerfiltervisible; else filtroInactivo\" \r\n xmlns=\"http://www.w3.org/2000/svg\" \r\n width=\"20\" height=\"20\" \r\n viewBox=\"0 0 24 24\" \r\n fill=\"currentColor\">\r\n <path d=\"M10 18h4v-2h-4v2zM3 6v2h18V6H3zm3 7h12v-2H6v2z\"/>\r\n </svg>\r\n <ng-template #filtroInactivo>\r\n <svg xmlns=\"http://www.w3.org/2000/svg\" \r\n width=\"20\" height=\"20\" \r\n viewBox=\"0 0 24 24\" \r\n fill=\"none\" \r\n stroke=\"currentColor\" \r\n stroke-width=\"2\">\r\n <polygon points=\"22 3 2 3 10 12.46 10 19 14 21 14 12.46 22 3\"/>\r\n </svg>\r\n </ng-template>\r\n </button>\r\n</div> -->\r\n\r\n<div class=\"controls-container\" >\r\n @if ( showControls() ) { \r\n <!-- Botones principales con nz-button y tipos de Ant Design -->\r\n <button nz-button nzType=\"default\" (click)=\"saveLayoutToJSON()\" >\r\n <span nz-icon nz-type=\"code\"></span> Guardar JSON\r\n </button>\r\n\r\n <button nz-button nzType=\"primary\" (click)=\"fn_btn_addWidget()\" >\r\n <span nz-icon nz-type=\"plus\"></span> A\u00F1adir widget\r\n </button>\r\n\r\n <button nz-button [nzType]=\"isLocked ? 'primary' : 'default'\" nzDanger (click)=\"fn_btn_lockPositionWidgets()\" >\r\n <span nz-icon [nzType]=\"isLocked ? 'lock' : 'unlock'\"></span> \r\n {{ isLocked ? 'Bloqueado' : 'Bloquear' }}\r\n </button>\r\n }\r\n @if ( showFilter() ) { \r\n <!-- Bot\u00F3n de filtro con estilo ic\u00F3nico -->\r\n <button nz-button nzType=\"default\" nzShape=\"circle\" (click)=\"handleShowFormFilterDrawer()\" class=\"btn-filtro\" [class.active]=\"drawerfiltervisible\" >\r\n <svg *ngIf=\"drawerfiltervisible; else filtroInactivo\" \r\n xmlns=\"http://www.w3.org/2000/svg\" \r\n width=\"16\" height=\"16\" \r\n viewBox=\"0 0 24 24\" \r\n fill=\"currentColor\">\r\n <path d=\"M10 18h4v-2h-4v2zM3 6v2h18V6H3zm3 7h12v-2H6v2z\"/>\r\n </svg>\r\n <ng-template #filtroInactivo>\r\n <svg xmlns=\"http://www.w3.org/2000/svg\" \r\n width=\"16\" height=\"16\" \r\n viewBox=\"0 0 24 24\" \r\n fill=\"none\" \r\n stroke=\"currentColor\" \r\n stroke-width=\"2\">\r\n <polygon points=\"22 3 2 3 10 12.46 10 19 14 21 14 12.46 22 3\"/>\r\n </svg>\r\n </ng-template>\r\n </button>\r\n }\r\n</div>\r\n<div #gridContainer class=\"grid-stack canvas-container\"\r\n [style.--canvas-bg]=\"dashboardStyle.canvasBackgroundColor\"\r\n></div>\r\n\r\n\r\n\r\n\r\n<!-- DRAWER - FILTER -->\r\n\r\n<nz-drawer\r\n[nzVisible]=\"drawerfiltervisible\"\r\n[nzMaskClosable]=\"false\"\r\nnzPlacement=\"right\"\r\n[nzWidth]=\"fnGetDrawerWidth(50)\"\r\n(nzOnClose)=\"handleCloseFormFilterDrawer()\"\r\n>\r\n<ng-container *nzDrawerContent>\r\n <div class=\"widget-details-info\">\r\n <h6 nz-typography>Filtros</h6>\r\n <yw-dashboard-filter\r\n [dashboardFilterConfig]=\"dashboardFilterConfig\"\r\n [dashboardData]=\"dashboardData\"\r\n (filterSelectionChange)=\"onFilterSelectionChange($event)\"\r\n >\r\n </yw-dashboard-filter>\r\n </div>\r\n\r\n <!--\r\n <nz-tabset nzCentered>\r\n <nz-tab nzTitle=\"Secion de Filtros\">\r\n <div class=\"controls\">\r\n aqui botones de control:\r\n\r\n </div>\r\n <div>\r\n \r\n\r\n </div>\r\n\r\n </nz-tab>\r\n \r\n </nz-tabset>\r\n-->\r\n</ng-container>\r\n</nz-drawer>\r\n\r\n\r\n\r\n<!-- DRAWER - CONFIGURACION -->\r\n<nz-drawer\r\n[nzVisible]=\"drawerconfigvisible\"\r\n[nzMaskClosable]=\"false\"\r\nnzPlacement=\"right\"\r\n[nzWidth]=\"fnGetDrawerWidth(50)\"\r\n(nzOnClose)=\"handleCloseFormDrawer()\"\r\n>\r\n<ng-container *nzDrawerContent>\r\n <div class=\"widget-details-info\">\r\n <h6 nz-typography>{{ drawerCurrentWidgetObject.widgetId }}</h6>\r\n </div>\r\n <nz-tabset nzCentered>\r\n <nz-tab nzTitle=\"{{ drawerCurrentWidgetObject.widgetId }}\">\r\n <div class=\"controls\">\r\n <button (click)=\"fn_btn_updateWidgetControlConfig(drawerCurrentWidgetObject.widgetId)\">Actualiza Configuracion</button>\r\n <button (click)=\"fn_btn_updateWidgetControlData(drawerCurrentWidgetObject.widgetId)\">Actualiza Data</button> \r\n </div>\r\n <div>\r\n bla bla bla\r\n </div>\r\n\r\n </nz-tab>\r\n \r\n </nz-tabset>\r\n</ng-container>\r\n</nz-drawer>", styles: ["@charset \"UTF-8\";:host{display:block;width:100%}.canvas-container{background-color:var(--canvas-bg, #f5f5f5);min-height:500px;padding:10px}::vdeep .card-inner{background:#fff;border:1px solid #ccc;height:100%;display:flex;align-items:center;justify-content:center}:host ::ng-deep .grid-stack-item-content{border-radius:6px;box-shadow:0 2px 5px #0000001a;display:flex;align-items:center;justify-content:center;font-weight:700;overflow:hidden}::ng-deep .grid-stack-item.widget-maximized{position:fixed!important;top:0!important;left:0!important;width:100vw!important;height:100vh!important;z-index:9999!important;transform:none!important;margin:0!important;padding:5px}::ng-deep .grid-stack-item.widget-maximized .grid-stack-item-content{position:absolute!important;inset:0!important;width:100%!important;height:100%!important;margin:0!important;padding:0!important;border:none!important;border-radius:0!important;box-shadow:none!important;background-color:#fff!important;overflow:hidden}::ng-deep .grid-stack>.grid-stack-item>.ui-resizable-handle{opacity:0!important;background-image:none!important}.widget-details-info{padding-top:30px;text-align:center}.widget-details-info h6{font-family:manrope,sans-serif;font-size:20px;font-weight:700;line-height:26px;color:#2d3144}.widget-details-info p{font-family:manrope,sans-serif;font-size:14px;font-weight:400;line-height:21px;color:#4b5064}.controls-container{display:flex;flex-wrap:wrap;align-items:center;gap:12px;padding:12px 16px;background:#fff;border-bottom:1px solid #f0f0f0;box-shadow:0 2px 8px #0000000a;border-radius:6px;margin-bottom:16px;width:100%;box-sizing:border-box;position:sticky;top:0}.controls-container button{white-space:nowrap}.controls-container .btn-filtro{display:inline-flex;align-items:center;justify-content:center;padding:0;width:32px;height:32px;border-radius:50%;transition:all .3s ease}.controls-container .btn-filtro.active{color:#fff;background-color:#1890ff;border-color:#1890ff}.controls-container .btn-filtro.active:hover{background-color:#40a9ff;border-color:#40a9ff}@media(max-width:576px){.controls-container{gap:8px;padding:8px 10px}.controls-container button[nz-button]{font-size:13px;padding:0 10px}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: NzDrawerModule }, { kind: "component", type: i2.NzDrawerComponent, selector: "nz-drawer", inputs: ["nzContent", "nzCloseIcon", "nzClosable", "nzMaskClosable", "nzMask", "nzCloseOnNavigation", "nzNoAnimation", "nzKeyboard", "nzTitle", "nzExtra", "nzFooter", "nzPlacement", "nzSize", "nzMaskStyle", "nzBodyStyle", "nzWrapClassName", "nzWidth", "nzHeight", "nzZIndex", "nzOffsetX", "nzOffsetY", "nzVisible"], outputs: ["nzOnViewInit", "nzOnClose", "nzVisibleChange"], exportAs: ["nzDrawer"] }, { kind: "directive", type: i2.NzDrawerContentDirective, selector: "[nzDrawerContent]", exportAs: ["nzDrawerContent"] }, { kind: "ngmodule", type: NzTabsModule }, { kind: "component", type: i3.NzTabsComponent, selector: "nz-tabs,nz-tabset", inputs: ["nzSelectedIndex", "nzTabPosition", "nzTabBarExtraContent", "nzCanDeactivate", "nzAddIcon", "nzTabBarStyle", "nzType", "nzSize", "nzAnimated", "nzTabBarGutter", "nzHideAdd", "nzCentered", "nzHideAll", "nzLinkRouter", "nzLinkExact", "nzDestroyInactiveTabPane"], outputs: ["nzSelectChange", "nzSelectedIndexChange", "nzTabListScroll", "nzClose", "nzAdd"], exportAs: ["nzTabs"] }, { kind: "component", type: i3.NzTabComponent, selector: "nz-tab", inputs: ["nzTitle", "nzClosable", "nzCloseIcon", "nzDisabled", "nzForceRender"], outputs: ["nzSelect", "nzDeselect", "nzClick", "nzContextmenu"], exportAs: ["nzTab"] }, { kind: "ngmodule", type: NzIconModule }, { kind: "directive", type: i1$3.NzIconDirective, selector: "nz-icon,[nz-icon]", inputs: ["nzSpin", "nzRotate", "nzType", "nzTheme", "nzTwotoneColor", "nzIconfont"], exportAs: ["nzIcon"] }, { kind: "ngmodule", type: NzButtonModule }, { kind: "component", type: i5.NzButtonComponent, selector: "button[nz-button], a[nz-button]", inputs: ["nzBlock", "nzGhost", "nzSearch", "nzLoading", "nzDanger", "disabled", "tabIndex", "nzType", "nzShape", "nzSize"], exportAs: ["nzButton"] }, { kind: "directive", type: i6.ɵNzTransitionPatchDirective, selector: "[nz-button], [nz-icon], nz-icon, [nz-menu-item], [nz-submenu], nz-select-top-control, nz-select-placeholder, nz-input-group", inputs: ["hidden"] }, { kind: "directive", type: i7.NzWaveDirective, selector: "[nz-wave],button[nz-button]:not([nzType=\"link\"]):not([nzType=\"text\"])", inputs: ["nzWaveExtraNode"], exportAs: ["nzWave"] }, { kind: "component", type: YwDashboardFilterComponent, selector: "yw-dashboard-filter", inputs: ["dashboardFilterConfig", "dashboardData"], outputs: ["filterSelectionChange"] }] }); }
|
|
4676
4729
|
}
|
|
4677
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.30", ngImport: i0, type:
|
|
4730
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.30", ngImport: i0, type: YwDashboardComponent, decorators: [{
|
|
4678
4731
|
type: Component,
|
|
4679
|
-
args: [{ selector: 'yw-
|
|
4680
|
-
|
|
4681
|
-
|
|
4682
|
-
|
|
4683
|
-
|
|
4684
|
-
|
|
4685
|
-
|
|
4686
|
-
|
|
4687
|
-
|
|
4688
|
-
|
|
4732
|
+
args: [{ selector: 'yw-dashboard', standalone: true, imports: [CommonModule,
|
|
4733
|
+
YwDashboardWidgetComponent,
|
|
4734
|
+
NzDrawerModule,
|
|
4735
|
+
NzTabsModule,
|
|
4736
|
+
YwBaseSlicerComponent,
|
|
4737
|
+
NzIconModule,
|
|
4738
|
+
NzButtonModule,
|
|
4739
|
+
YwButtonSlicerComponent,
|
|
4740
|
+
YwListSlicerComponent,
|
|
4741
|
+
YwDashboardFilterComponent
|
|
4742
|
+
], template: "<!-- <div class=\"controls\" [hidden]=\"!showControls()\">\r\n <button (click)=\"saveLayoutToJSON()\">Guardar JSON en Consola</button>\r\n <button (click)=\"fn_btn_addWidget()\">add widget</button>\r\n <button (click)=\"fn_btn_lockPositionWidgets()\">Lock widgets</button>\r\n <button (click)=\"handleShowFormFilterDrawer()\" class=\"btn-filtro\">\r\n <svg *ngIf=\"drawerfiltervisible; else filtroInactivo\" \r\n xmlns=\"http://www.w3.org/2000/svg\" \r\n width=\"20\" height=\"20\" \r\n viewBox=\"0 0 24 24\" \r\n fill=\"currentColor\">\r\n <path d=\"M10 18h4v-2h-4v2zM3 6v2h18V6H3zm3 7h12v-2H6v2z\"/>\r\n </svg>\r\n <ng-template #filtroInactivo>\r\n <svg xmlns=\"http://www.w3.org/2000/svg\" \r\n width=\"20\" height=\"20\" \r\n viewBox=\"0 0 24 24\" \r\n fill=\"none\" \r\n stroke=\"currentColor\" \r\n stroke-width=\"2\">\r\n <polygon points=\"22 3 2 3 10 12.46 10 19 14 21 14 12.46 22 3\"/>\r\n </svg>\r\n </ng-template>\r\n </button>\r\n</div> -->\r\n\r\n<div class=\"controls-container\" >\r\n @if ( showControls() ) { \r\n <!-- Botones principales con nz-button y tipos de Ant Design -->\r\n <button nz-button nzType=\"default\" (click)=\"saveLayoutToJSON()\" >\r\n <span nz-icon nz-type=\"code\"></span> Guardar JSON\r\n </button>\r\n\r\n <button nz-button nzType=\"primary\" (click)=\"fn_btn_addWidget()\" >\r\n <span nz-icon nz-type=\"plus\"></span> A\u00F1adir widget\r\n </button>\r\n\r\n <button nz-button [nzType]=\"isLocked ? 'primary' : 'default'\" nzDanger (click)=\"fn_btn_lockPositionWidgets()\" >\r\n <span nz-icon [nzType]=\"isLocked ? 'lock' : 'unlock'\"></span> \r\n {{ isLocked ? 'Bloqueado' : 'Bloquear' }}\r\n </button>\r\n }\r\n @if ( showFilter() ) { \r\n <!-- Bot\u00F3n de filtro con estilo ic\u00F3nico -->\r\n <button nz-button nzType=\"default\" nzShape=\"circle\" (click)=\"handleShowFormFilterDrawer()\" class=\"btn-filtro\" [class.active]=\"drawerfiltervisible\" >\r\n <svg *ngIf=\"drawerfiltervisible; else filtroInactivo\" \r\n xmlns=\"http://www.w3.org/2000/svg\" \r\n width=\"16\" height=\"16\" \r\n viewBox=\"0 0 24 24\" \r\n fill=\"currentColor\">\r\n <path d=\"M10 18h4v-2h-4v2zM3 6v2h18V6H3zm3 7h12v-2H6v2z\"/>\r\n </svg>\r\n <ng-template #filtroInactivo>\r\n <svg xmlns=\"http://www.w3.org/2000/svg\" \r\n width=\"16\" height=\"16\" \r\n viewBox=\"0 0 24 24\" \r\n fill=\"none\" \r\n stroke=\"currentColor\" \r\n stroke-width=\"2\">\r\n <polygon points=\"22 3 2 3 10 12.46 10 19 14 21 14 12.46 22 3\"/>\r\n </svg>\r\n </ng-template>\r\n </button>\r\n }\r\n</div>\r\n<div #gridContainer class=\"grid-stack canvas-container\"\r\n [style.--canvas-bg]=\"dashboardStyle.canvasBackgroundColor\"\r\n></div>\r\n\r\n\r\n\r\n\r\n<!-- DRAWER - FILTER -->\r\n\r\n<nz-drawer\r\n[nzVisible]=\"drawerfiltervisible\"\r\n[nzMaskClosable]=\"false\"\r\nnzPlacement=\"right\"\r\n[nzWidth]=\"fnGetDrawerWidth(50)\"\r\n(nzOnClose)=\"handleCloseFormFilterDrawer()\"\r\n>\r\n<ng-container *nzDrawerContent>\r\n <div class=\"widget-details-info\">\r\n <h6 nz-typography>Filtros</h6>\r\n <yw-dashboard-filter\r\n [dashboardFilterConfig]=\"dashboardFilterConfig\"\r\n [dashboardData]=\"dashboardData\"\r\n (filterSelectionChange)=\"onFilterSelectionChange($event)\"\r\n >\r\n </yw-dashboard-filter>\r\n </div>\r\n\r\n <!--\r\n <nz-tabset nzCentered>\r\n <nz-tab nzTitle=\"Secion de Filtros\">\r\n <div class=\"controls\">\r\n aqui botones de control:\r\n\r\n </div>\r\n <div>\r\n \r\n\r\n </div>\r\n\r\n </nz-tab>\r\n \r\n </nz-tabset>\r\n-->\r\n</ng-container>\r\n</nz-drawer>\r\n\r\n\r\n\r\n<!-- DRAWER - CONFIGURACION -->\r\n<nz-drawer\r\n[nzVisible]=\"drawerconfigvisible\"\r\n[nzMaskClosable]=\"false\"\r\nnzPlacement=\"right\"\r\n[nzWidth]=\"fnGetDrawerWidth(50)\"\r\n(nzOnClose)=\"handleCloseFormDrawer()\"\r\n>\r\n<ng-container *nzDrawerContent>\r\n <div class=\"widget-details-info\">\r\n <h6 nz-typography>{{ drawerCurrentWidgetObject.widgetId }}</h6>\r\n </div>\r\n <nz-tabset nzCentered>\r\n <nz-tab nzTitle=\"{{ drawerCurrentWidgetObject.widgetId }}\">\r\n <div class=\"controls\">\r\n <button (click)=\"fn_btn_updateWidgetControlConfig(drawerCurrentWidgetObject.widgetId)\">Actualiza Configuracion</button>\r\n <button (click)=\"fn_btn_updateWidgetControlData(drawerCurrentWidgetObject.widgetId)\">Actualiza Data</button> \r\n </div>\r\n <div>\r\n bla bla bla\r\n </div>\r\n\r\n </nz-tab>\r\n \r\n </nz-tabset>\r\n</ng-container>\r\n</nz-drawer>", styles: ["@charset \"UTF-8\";:host{display:block;width:100%}.canvas-container{background-color:var(--canvas-bg, #f5f5f5);min-height:500px;padding:10px}::vdeep .card-inner{background:#fff;border:1px solid #ccc;height:100%;display:flex;align-items:center;justify-content:center}:host ::ng-deep .grid-stack-item-content{border-radius:6px;box-shadow:0 2px 5px #0000001a;display:flex;align-items:center;justify-content:center;font-weight:700;overflow:hidden}::ng-deep .grid-stack-item.widget-maximized{position:fixed!important;top:0!important;left:0!important;width:100vw!important;height:100vh!important;z-index:9999!important;transform:none!important;margin:0!important;padding:5px}::ng-deep .grid-stack-item.widget-maximized .grid-stack-item-content{position:absolute!important;inset:0!important;width:100%!important;height:100%!important;margin:0!important;padding:0!important;border:none!important;border-radius:0!important;box-shadow:none!important;background-color:#fff!important;overflow:hidden}::ng-deep .grid-stack>.grid-stack-item>.ui-resizable-handle{opacity:0!important;background-image:none!important}.widget-details-info{padding-top:30px;text-align:center}.widget-details-info h6{font-family:manrope,sans-serif;font-size:20px;font-weight:700;line-height:26px;color:#2d3144}.widget-details-info p{font-family:manrope,sans-serif;font-size:14px;font-weight:400;line-height:21px;color:#4b5064}.controls-container{display:flex;flex-wrap:wrap;align-items:center;gap:12px;padding:12px 16px;background:#fff;border-bottom:1px solid #f0f0f0;box-shadow:0 2px 8px #0000000a;border-radius:6px;margin-bottom:16px;width:100%;box-sizing:border-box;position:sticky;top:0}.controls-container button{white-space:nowrap}.controls-container .btn-filtro{display:inline-flex;align-items:center;justify-content:center;padding:0;width:32px;height:32px;border-radius:50%;transition:all .3s ease}.controls-container .btn-filtro.active{color:#fff;background-color:#1890ff;border-color:#1890ff}.controls-container .btn-filtro.active:hover{background-color:#40a9ff;border-color:#40a9ff}@media(max-width:576px){.controls-container{gap:8px;padding:8px 10px}.controls-container button[nz-button]{font-size:13px;padding:0 10px}}\n"] }]
|
|
4743
|
+
}], ctorParameters: () => [{ type: i0.EnvironmentInjector }, { type: i0.ApplicationRef }], propDecorators: { gridContainer: [{
|
|
4744
|
+
type: ViewChild,
|
|
4745
|
+
args: ['gridContainer', { static: true }]
|
|
4746
|
+
}], showControls: [{ type: i0.Input, args: [{ isSignal: true, alias: "showControls", required: false }] }], showFilter: [{ type: i0.Input, args: [{ isSignal: true, alias: "showFilter", required: false }] }], dashboardStyle: [{
|
|
4747
|
+
type: Input
|
|
4748
|
+
}], dashboardConfig: [{
|
|
4749
|
+
type: Input
|
|
4750
|
+
}], dashboardData: [{
|
|
4751
|
+
type: Input
|
|
4752
|
+
}], dashboardFilterConfig: [{
|
|
4753
|
+
type: Input
|
|
4689
4754
|
}] } });
|
|
4690
4755
|
|
|
4691
4756
|
// Configuraciones especificas de pie chart -> acumulation chart en syncfusion
|