@c80/ui 1.0.32 → 1.0.34
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/esm2022/lib/card-level/card-level.component.mjs +34 -5
- package/esm2022/lib/table/index.mjs +7 -1
- package/esm2022/lib/table/table-column-visibility.service.mjs +156 -0
- package/esm2022/lib/table/table-crud-state.service.mjs +165 -0
- package/esm2022/lib/table/table-data-converter.service.mjs +149 -0
- package/esm2022/lib/table/table-data-utils.service.mjs +166 -0
- package/esm2022/lib/table/table-selection.service.mjs +151 -0
- package/esm2022/lib/table/table.component.mjs +59 -500
- package/esm2022/lib/table/table.types.mjs +5 -0
- package/lib/card-level/card-level.component.d.ts +4 -0
- package/lib/table/index.d.ts +6 -0
- package/lib/table/table-column-visibility.service.d.ts +71 -0
- package/lib/table/table-crud-state.service.d.ts +44 -0
- package/lib/table/table-data-converter.service.d.ts +50 -0
- package/lib/table/table-data-utils.service.d.ts +70 -0
- package/lib/table/table-selection.service.d.ts +39 -0
- package/lib/table/table.component.d.ts +14 -99
- package/lib/table/table.types.d.ts +16 -0
- package/package.json +1 -1
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Component, input } from '@angular/core';
|
|
1
|
+
import { Component, input, computed } from '@angular/core';
|
|
2
2
|
import { CommonModule } from '@angular/common';
|
|
3
3
|
import * as i0 from "@angular/core";
|
|
4
4
|
export class CardLevelComponent {
|
|
@@ -7,7 +7,7 @@ export class CardLevelComponent {
|
|
|
7
7
|
_generatedId;
|
|
8
8
|
get generatedId() {
|
|
9
9
|
if (!this._generatedId) {
|
|
10
|
-
const label = this.cardLevelData().label.toLowerCase().
|
|
10
|
+
const label = this.cardLevelData().label.toLowerCase().replaceAll(/\s+/g, '-');
|
|
11
11
|
const randomNum = Math.floor(Math.random() * 10000);
|
|
12
12
|
this._generatedId = `${label}-${randomNum}`;
|
|
13
13
|
}
|
|
@@ -18,11 +18,40 @@ export class CardLevelComponent {
|
|
|
18
18
|
const calculatedWidth = baseWidth * this.size();
|
|
19
19
|
return `${calculatedWidth}px`;
|
|
20
20
|
}
|
|
21
|
+
// Detecta si el rango es bidireccional (min negativo, max positivo)
|
|
22
|
+
isBidirectional = computed(() => {
|
|
23
|
+
const data = this.cardLevelData();
|
|
24
|
+
return data.min < 0 && data.max > 0;
|
|
25
|
+
});
|
|
26
|
+
// Calcula el porcentaje de fill para barras bidireccionales
|
|
27
|
+
bidirectionalFillPercent = computed(() => {
|
|
28
|
+
const data = this.cardLevelData();
|
|
29
|
+
const totalRange = data.max - data.min;
|
|
30
|
+
return Math.abs(data.value / totalRange) * 100;
|
|
31
|
+
});
|
|
32
|
+
// Determina la dirección del fill (left/right)
|
|
33
|
+
fillDirection = computed(() => {
|
|
34
|
+
return this.cardLevelData().value >= 0 ? 'right' : 'left';
|
|
35
|
+
});
|
|
36
|
+
// Color según el valor y umbrales
|
|
37
|
+
fillColor = computed(() => {
|
|
38
|
+
const data = this.cardLevelData();
|
|
39
|
+
const absValue = Math.abs(data.value);
|
|
40
|
+
const absHigh = Math.abs(data.high);
|
|
41
|
+
const absLow = Math.abs(data.low);
|
|
42
|
+
if (absValue >= absHigh) {
|
|
43
|
+
return 'var(--color-danger)';
|
|
44
|
+
}
|
|
45
|
+
if (absValue >= absLow) {
|
|
46
|
+
return 'var(--color-warning)';
|
|
47
|
+
}
|
|
48
|
+
return 'var(--color-success)';
|
|
49
|
+
});
|
|
21
50
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: CardLevelComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
22
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.
|
|
51
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.13", type: CardLevelComponent, isStandalone: true, selector: "c80-card-level", inputs: { cardLevelData: { classPropertyName: "cardLevelData", publicName: "cardLevelData", isSignal: true, isRequired: true, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "<div class=\"card-level-container\" [style.width]=\"cardWidth\">\r\n <label [for]=\"generatedId\">\r\n <strong>{{ cardLevelData().label }}</strong>\r\n\r\n <span class=\"value-display\">\r\n @if (isBidirectional()) {\r\n <!-- Barra bidireccional desde el centro -->\r\n <div class=\"bidirectional-meter\">\r\n <div class=\"meter-track\">\r\n <div class=\"center-line\"></div>\r\n <div class=\"meter-fill\" [class.fill-left]=\"fillDirection() === 'left'\" [class.fill-right]=\"fillDirection() === 'right'\" [style.width.%]=\"bidirectionalFillPercent()\" [style.background]=\"fillColor()\">\r\n </div>\r\n </div>\r\n </div>\r\n } @else {\r\n <!-- Meter est\u00E1ndar para rangos unidireccionales -->\r\n <meter [id]=\"generatedId\" [optimum]=\"cardLevelData().optimum\" [min]=\"cardLevelData().min\" [max]=\"cardLevelData().max\" [low]=\"cardLevelData().low\" [high]=\"cardLevelData().high\" [value]=\"cardLevelData().value\">\r\n </meter>\r\n }\r\n\r\n {{ cardLevelData().value }}{{ cardLevelData().unit }}\r\n </span>\r\n </label>\r\n</div>", styles: [".card-level-container{background:#fff;border-radius:5px;padding:8px;margin:4px;box-shadow:0 4px 6px #0000001a,0 1px 3px #00000014;min-width:100px;flex:1}.card-level-container label{display:flex;flex-direction:column;margin:0}.card-level-container label strong{font-size:12px;font-weight:600;color:#2d3748;text-transform:uppercase;letter-spacing:.5px;margin-bottom:4px}.card-level-container label .value-display{font-size:12px;font-weight:600;color:#1a202c;text-align:center;padding:0 5px;background:#4299e11a;border-radius:5px}.card-level-container label .bidirectional-meter{width:100%;margin-bottom:4px}.card-level-container label .bidirectional-meter .meter-track{position:relative;width:100%;height:10px;background:#e2e8f0;border-radius:12px;box-shadow:inset 0 2px 4px #0000001a;overflow:hidden}.card-level-container label .bidirectional-meter .meter-track .center-line{position:absolute;left:50%;top:0;bottom:0;width:4px;background:#4a5568;transform:translate(-50%);z-index:1}.card-level-container label .bidirectional-meter .meter-track .meter-fill{position:absolute;top:0;bottom:0;border-radius:5px}.card-level-container label .bidirectional-meter .meter-track .meter-fill.fill-right{left:50%}.card-level-container label .bidirectional-meter .meter-track .meter-fill.fill-left{right:50%}.card-level-container label meter{width:100%;border-radius:12px;border:none;background:#e2e8f0;margin-bottom:4px}.card-level-container label meter::-webkit-meter-bar{background:#e2e8f0;border-radius:12px;box-shadow:inset 0 2px 4px #0000001a}.card-level-container label meter::-webkit-meter-optimum-value{background:linear-gradient(90deg,#48bb78,#38a169);border-radius:12px}.card-level-container label meter::-webkit-meter-suboptimum-value{background:linear-gradient(90deg,#ed8936,#dd6b20);border-radius:12px}.card-level-container label meter::-webkit-meter-even-less-good-value{background:linear-gradient(90deg,#f56565,#e53e3e);border-radius:12px}.card-level-container label meter::-moz-meter-bar{background:linear-gradient(90deg,#48bb78,#38a169);border-radius:12px}:host{--color-success: linear-gradient(90deg, #48bb78, #38a169);--color-warning: linear-gradient(90deg, #ed8936, #dd6b20);--color-danger: linear-gradient(90deg, #f56565, #e53e3e)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }] });
|
|
23
52
|
}
|
|
24
53
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: CardLevelComponent, decorators: [{
|
|
25
54
|
type: Component,
|
|
26
|
-
args: [{ selector: 'c80-card-level', standalone: true, imports: [CommonModule], template: "<div class=\"card-level-container\" [style.width]=\"cardWidth\">\r\n
|
|
55
|
+
args: [{ selector: 'c80-card-level', standalone: true, imports: [CommonModule], template: "<div class=\"card-level-container\" [style.width]=\"cardWidth\">\r\n <label [for]=\"generatedId\">\r\n <strong>{{ cardLevelData().label }}</strong>\r\n\r\n <span class=\"value-display\">\r\n @if (isBidirectional()) {\r\n <!-- Barra bidireccional desde el centro -->\r\n <div class=\"bidirectional-meter\">\r\n <div class=\"meter-track\">\r\n <div class=\"center-line\"></div>\r\n <div class=\"meter-fill\" [class.fill-left]=\"fillDirection() === 'left'\" [class.fill-right]=\"fillDirection() === 'right'\" [style.width.%]=\"bidirectionalFillPercent()\" [style.background]=\"fillColor()\">\r\n </div>\r\n </div>\r\n </div>\r\n } @else {\r\n <!-- Meter est\u00E1ndar para rangos unidireccionales -->\r\n <meter [id]=\"generatedId\" [optimum]=\"cardLevelData().optimum\" [min]=\"cardLevelData().min\" [max]=\"cardLevelData().max\" [low]=\"cardLevelData().low\" [high]=\"cardLevelData().high\" [value]=\"cardLevelData().value\">\r\n </meter>\r\n }\r\n\r\n {{ cardLevelData().value }}{{ cardLevelData().unit }}\r\n </span>\r\n </label>\r\n</div>", styles: [".card-level-container{background:#fff;border-radius:5px;padding:8px;margin:4px;box-shadow:0 4px 6px #0000001a,0 1px 3px #00000014;min-width:100px;flex:1}.card-level-container label{display:flex;flex-direction:column;margin:0}.card-level-container label strong{font-size:12px;font-weight:600;color:#2d3748;text-transform:uppercase;letter-spacing:.5px;margin-bottom:4px}.card-level-container label .value-display{font-size:12px;font-weight:600;color:#1a202c;text-align:center;padding:0 5px;background:#4299e11a;border-radius:5px}.card-level-container label .bidirectional-meter{width:100%;margin-bottom:4px}.card-level-container label .bidirectional-meter .meter-track{position:relative;width:100%;height:10px;background:#e2e8f0;border-radius:12px;box-shadow:inset 0 2px 4px #0000001a;overflow:hidden}.card-level-container label .bidirectional-meter .meter-track .center-line{position:absolute;left:50%;top:0;bottom:0;width:4px;background:#4a5568;transform:translate(-50%);z-index:1}.card-level-container label .bidirectional-meter .meter-track .meter-fill{position:absolute;top:0;bottom:0;border-radius:5px}.card-level-container label .bidirectional-meter .meter-track .meter-fill.fill-right{left:50%}.card-level-container label .bidirectional-meter .meter-track .meter-fill.fill-left{right:50%}.card-level-container label meter{width:100%;border-radius:12px;border:none;background:#e2e8f0;margin-bottom:4px}.card-level-container label meter::-webkit-meter-bar{background:#e2e8f0;border-radius:12px;box-shadow:inset 0 2px 4px #0000001a}.card-level-container label meter::-webkit-meter-optimum-value{background:linear-gradient(90deg,#48bb78,#38a169);border-radius:12px}.card-level-container label meter::-webkit-meter-suboptimum-value{background:linear-gradient(90deg,#ed8936,#dd6b20);border-radius:12px}.card-level-container label meter::-webkit-meter-even-less-good-value{background:linear-gradient(90deg,#f56565,#e53e3e);border-radius:12px}.card-level-container label meter::-moz-meter-bar{background:linear-gradient(90deg,#48bb78,#38a169);border-radius:12px}:host{--color-success: linear-gradient(90deg, #48bb78, #38a169);--color-warning: linear-gradient(90deg, #ed8936, #dd6b20);--color-danger: linear-gradient(90deg, #f56565, #e53e3e)}\n"] }]
|
|
27
56
|
}] });
|
|
28
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
57
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2FyZC1sZXZlbC5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi9saWJzL3VpL3NyYy9saWIvY2FyZC1sZXZlbC9jYXJkLWxldmVsLmNvbXBvbmVudC50cyIsIi4uLy4uLy4uLy4uLy4uL2xpYnMvdWkvc3JjL2xpYi9jYXJkLWxldmVsL2NhcmQtbGV2ZWwuY29tcG9uZW50Lmh0bWwiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFNBQVMsRUFBRSxLQUFLLEVBQUUsUUFBUSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQzNELE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQzs7QUFXL0MsTUFBTSxPQUFPLGtCQUFrQjtJQUM3QixhQUFhLEdBQUcsS0FBSyxDQUFDLFFBQVEsRUFBaUIsQ0FBQztJQUNoRCxJQUFJLEdBQUcsS0FBSyxDQUFTLENBQUMsQ0FBQyxDQUFDLENBQUMsd0NBQXdDO0lBRXpELFlBQVksQ0FBVTtJQUU5QixJQUFJLFdBQVc7UUFDYixJQUFJLENBQUMsSUFBSSxDQUFDLFlBQVksRUFBRSxDQUFDO1lBQ3ZCLE1BQU0sS0FBSyxHQUFHLElBQUksQ0FBQyxhQUFhLEVBQUUsQ0FBQyxLQUFLLENBQUMsV0FBVyxFQUFFLENBQUMsVUFBVSxDQUFDLE1BQU0sRUFBRSxHQUFHLENBQUMsQ0FBQztZQUMvRSxNQUFNLFNBQVMsR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxNQUFNLEVBQUUsR0FBRyxLQUFLLENBQUMsQ0FBQztZQUNwRCxJQUFJLENBQUMsWUFBWSxHQUFHLEdBQUcsS0FBSyxJQUFJLFNBQVMsRUFBRSxDQUFDO1FBQzlDLENBQUM7UUFDRCxPQUFPLElBQUksQ0FBQyxZQUFZLENBQUM7SUFDM0IsQ0FBQztJQUVELElBQUksU0FBUztRQUNYLE1BQU0sU0FBUyxHQUFHLEdBQUcsQ0FBQztRQUN0QixNQUFNLGVBQWUsR0FBRyxTQUFTLEdBQUcsSUFBSSxDQUFDLElBQUksRUFBRSxDQUFDO1FBQ2hELE9BQU8sR0FBRyxlQUFlLElBQUksQ0FBQztJQUNoQyxDQUFDO0lBRUQsb0VBQW9FO0lBQ3BFLGVBQWUsR0FBRyxRQUFRLENBQUMsR0FBRyxFQUFFO1FBQzlCLE1BQU0sSUFBSSxHQUFHLElBQUksQ0FBQyxhQUFhLEVBQUUsQ0FBQztRQUNsQyxPQUFPLElBQUksQ0FBQyxHQUFHLEdBQUcsQ0FBQyxJQUFJLElBQUksQ0FBQyxHQUFHLEdBQUcsQ0FBQyxDQUFDO0lBQ3RDLENBQUMsQ0FBQyxDQUFDO0lBRUgsNERBQTREO0lBQzVELHdCQUF3QixHQUFHLFFBQVEsQ0FBQyxHQUFHLEVBQUU7UUFDdkMsTUFBTSxJQUFJLEdBQUcsSUFBSSxDQUFDLGFBQWEsRUFBRSxDQUFDO1FBQ2xDLE1BQU0sVUFBVSxHQUFHLElBQUksQ0FBQyxHQUFHLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQztRQUN2QyxPQUFPLElBQUksQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLEtBQUssR0FBRyxVQUFVLENBQUMsR0FBRyxHQUFHLENBQUM7SUFDakQsQ0FBQyxDQUFDLENBQUM7SUFFSCwrQ0FBK0M7SUFDL0MsYUFBYSxHQUFHLFFBQVEsQ0FBQyxHQUFHLEVBQUU7UUFDNUIsT0FBTyxJQUFJLENBQUMsYUFBYSxFQUFFLENBQUMsS0FBSyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUM7SUFDNUQsQ0FBQyxDQUFDLENBQUM7SUFFSCxrQ0FBa0M7SUFDbEMsU0FBUyxHQUFHLFFBQVEsQ0FBQyxHQUFHLEVBQUU7UUFDeEIsTUFBTSxJQUFJLEdBQUcsSUFBSSxDQUFDLGFBQWEsRUFBRSxDQUFDO1FBQ2xDLE1BQU0sUUFBUSxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDO1FBQ3RDLE1BQU0sT0FBTyxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDO1FBQ3BDLE1BQU0sTUFBTSxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDO1FBRWxDLElBQUksUUFBUSxJQUFJLE9BQU8sRUFBRSxDQUFDO1lBQ3hCLE9BQU8scUJBQXFCLENBQUM7UUFDL0IsQ0FBQztRQUNELElBQUksUUFBUSxJQUFJLE1BQU0sRUFBRSxDQUFDO1lBQ3ZCLE9BQU8sc0JBQXNCLENBQUM7UUFDaEMsQ0FBQztRQUNELE9BQU8sc0JBQXNCLENBQUM7SUFDaEMsQ0FBQyxDQUFDLENBQUM7d0dBckRRLGtCQUFrQjs0RkFBbEIsa0JBQWtCLDBWQ1ovQix3bkNBdUJNLDB2RURmTSxZQUFZOzs0RkFJWCxrQkFBa0I7a0JBUjlCLFNBQVM7K0JBRUUsZ0JBQWdCLGNBQ2QsSUFBSSxXQUNQLENBQUMsWUFBWSxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQ29tcG9uZW50LCBpbnB1dCwgY29tcHV0ZWQgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcclxuaW1wb3J0IHsgQ29tbW9uTW9kdWxlIH0gZnJvbSAnQGFuZ3VsYXIvY29tbW9uJztcclxuaW1wb3J0IHsgQ2FyZExldmVsRGF0YSB9IGZyb20gJy4vY2FyZC1sZXZlbC5pbnRlcmZhY2UnO1xyXG5cclxuQENvbXBvbmVudCh7XHJcbiAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEBhbmd1bGFyLWVzbGludC9jb21wb25lbnQtc2VsZWN0b3JcclxuICBzZWxlY3RvcjogJ2M4MC1jYXJkLWxldmVsJyxcclxuICBzdGFuZGFsb25lOiB0cnVlLFxyXG4gIGltcG9ydHM6IFtDb21tb25Nb2R1bGVdLFxyXG4gIHRlbXBsYXRlVXJsOiAnLi9jYXJkLWxldmVsLmNvbXBvbmVudC5odG1sJyxcclxuICBzdHlsZVVybDogJy4vY2FyZC1sZXZlbC5jb21wb25lbnQuc2NzcydcclxufSlcclxuZXhwb3J0IGNsYXNzIENhcmRMZXZlbENvbXBvbmVudCB7XHJcbiAgY2FyZExldmVsRGF0YSA9IGlucHV0LnJlcXVpcmVkPENhcmRMZXZlbERhdGE+KCk7XHJcbiAgc2l6ZSA9IGlucHV0PG51bWJlcj4oMSk7IC8vIE11bHRpcGxpY2Fkb3IgZGVsIHRhbWHDsW8gYmFzZSAoMjIwcHgpXHJcblxyXG4gIHByaXZhdGUgX2dlbmVyYXRlZElkPzogc3RyaW5nO1xyXG5cclxuICBnZXQgZ2VuZXJhdGVkSWQoKTogc3RyaW5nIHtcclxuICAgIGlmICghdGhpcy5fZ2VuZXJhdGVkSWQpIHtcclxuICAgICAgY29uc3QgbGFiZWwgPSB0aGlzLmNhcmRMZXZlbERhdGEoKS5sYWJlbC50b0xvd2VyQ2FzZSgpLnJlcGxhY2VBbGwoL1xccysvZywgJy0nKTtcclxuICAgICAgY29uc3QgcmFuZG9tTnVtID0gTWF0aC5mbG9vcihNYXRoLnJhbmRvbSgpICogMTAwMDApO1xyXG4gICAgICB0aGlzLl9nZW5lcmF0ZWRJZCA9IGAke2xhYmVsfS0ke3JhbmRvbU51bX1gO1xyXG4gICAgfVxyXG4gICAgcmV0dXJuIHRoaXMuX2dlbmVyYXRlZElkO1xyXG4gIH1cclxuXHJcbiAgZ2V0IGNhcmRXaWR0aCgpOiBzdHJpbmcge1xyXG4gICAgY29uc3QgYmFzZVdpZHRoID0gMTQwO1xyXG4gICAgY29uc3QgY2FsY3VsYXRlZFdpZHRoID0gYmFzZVdpZHRoICogdGhpcy5zaXplKCk7XHJcbiAgICByZXR1cm4gYCR7Y2FsY3VsYXRlZFdpZHRofXB4YDtcclxuICB9XHJcblxyXG4gIC8vIERldGVjdGEgc2kgZWwgcmFuZ28gZXMgYmlkaXJlY2Npb25hbCAobWluIG5lZ2F0aXZvLCBtYXggcG9zaXRpdm8pXHJcbiAgaXNCaWRpcmVjdGlvbmFsID0gY29tcHV0ZWQoKCkgPT4ge1xyXG4gICAgY29uc3QgZGF0YSA9IHRoaXMuY2FyZExldmVsRGF0YSgpO1xyXG4gICAgcmV0dXJuIGRhdGEubWluIDwgMCAmJiBkYXRhLm1heCA+IDA7XHJcbiAgfSk7XHJcblxyXG4gIC8vIENhbGN1bGEgZWwgcG9yY2VudGFqZSBkZSBmaWxsIHBhcmEgYmFycmFzIGJpZGlyZWNjaW9uYWxlc1xyXG4gIGJpZGlyZWN0aW9uYWxGaWxsUGVyY2VudCA9IGNvbXB1dGVkKCgpID0+IHtcclxuICAgIGNvbnN0IGRhdGEgPSB0aGlzLmNhcmRMZXZlbERhdGEoKTtcclxuICAgIGNvbnN0IHRvdGFsUmFuZ2UgPSBkYXRhLm1heCAtIGRhdGEubWluO1xyXG4gICAgcmV0dXJuIE1hdGguYWJzKGRhdGEudmFsdWUgLyB0b3RhbFJhbmdlKSAqIDEwMDtcclxuICB9KTtcclxuXHJcbiAgLy8gRGV0ZXJtaW5hIGxhIGRpcmVjY2nDs24gZGVsIGZpbGwgKGxlZnQvcmlnaHQpXHJcbiAgZmlsbERpcmVjdGlvbiA9IGNvbXB1dGVkKCgpID0+IHtcclxuICAgIHJldHVybiB0aGlzLmNhcmRMZXZlbERhdGEoKS52YWx1ZSA+PSAwID8gJ3JpZ2h0JyA6ICdsZWZ0JztcclxuICB9KTtcclxuXHJcbiAgLy8gQ29sb3Igc2Vnw7puIGVsIHZhbG9yIHkgdW1icmFsZXNcclxuICBmaWxsQ29sb3IgPSBjb21wdXRlZCgoKSA9PiB7XHJcbiAgICBjb25zdCBkYXRhID0gdGhpcy5jYXJkTGV2ZWxEYXRhKCk7XHJcbiAgICBjb25zdCBhYnNWYWx1ZSA9IE1hdGguYWJzKGRhdGEudmFsdWUpO1xyXG4gICAgY29uc3QgYWJzSGlnaCA9IE1hdGguYWJzKGRhdGEuaGlnaCk7XHJcbiAgICBjb25zdCBhYnNMb3cgPSBNYXRoLmFicyhkYXRhLmxvdyk7XHJcblxyXG4gICAgaWYgKGFic1ZhbHVlID49IGFic0hpZ2gpIHtcclxuICAgICAgcmV0dXJuICd2YXIoLS1jb2xvci1kYW5nZXIpJztcclxuICAgIH1cclxuICAgIGlmIChhYnNWYWx1ZSA+PSBhYnNMb3cpIHtcclxuICAgICAgcmV0dXJuICd2YXIoLS1jb2xvci13YXJuaW5nKSc7XHJcbiAgICB9XHJcbiAgICByZXR1cm4gJ3ZhcigtLWNvbG9yLXN1Y2Nlc3MpJztcclxuICB9KTtcclxufVxyXG4iLCI8ZGl2IGNsYXNzPVwiY2FyZC1sZXZlbC1jb250YWluZXJcIiBbc3R5bGUud2lkdGhdPVwiY2FyZFdpZHRoXCI+XHJcbiAgPGxhYmVsIFtmb3JdPVwiZ2VuZXJhdGVkSWRcIj5cclxuICAgIDxzdHJvbmc+e3sgY2FyZExldmVsRGF0YSgpLmxhYmVsIH19PC9zdHJvbmc+XHJcblxyXG4gICAgPHNwYW4gY2xhc3M9XCJ2YWx1ZS1kaXNwbGF5XCI+XHJcbiAgICAgIEBpZiAoaXNCaWRpcmVjdGlvbmFsKCkpIHtcclxuICAgICAgPCEtLSBCYXJyYSBiaWRpcmVjY2lvbmFsIGRlc2RlIGVsIGNlbnRybyAtLT5cclxuICAgICAgPGRpdiBjbGFzcz1cImJpZGlyZWN0aW9uYWwtbWV0ZXJcIj5cclxuICAgICAgICA8ZGl2IGNsYXNzPVwibWV0ZXItdHJhY2tcIj5cclxuICAgICAgICAgIDxkaXYgY2xhc3M9XCJjZW50ZXItbGluZVwiPjwvZGl2PlxyXG4gICAgICAgICAgPGRpdiBjbGFzcz1cIm1ldGVyLWZpbGxcIiBbY2xhc3MuZmlsbC1sZWZ0XT1cImZpbGxEaXJlY3Rpb24oKSA9PT0gJ2xlZnQnXCIgW2NsYXNzLmZpbGwtcmlnaHRdPVwiZmlsbERpcmVjdGlvbigpID09PSAncmlnaHQnXCIgW3N0eWxlLndpZHRoLiVdPVwiYmlkaXJlY3Rpb25hbEZpbGxQZXJjZW50KClcIiBbc3R5bGUuYmFja2dyb3VuZF09XCJmaWxsQ29sb3IoKVwiPlxyXG4gICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgPC9kaXY+XHJcbiAgICAgIDwvZGl2PlxyXG4gICAgICB9IEBlbHNlIHtcclxuICAgICAgPCEtLSBNZXRlciBlc3TDoW5kYXIgcGFyYSByYW5nb3MgdW5pZGlyZWNjaW9uYWxlcyAtLT5cclxuICAgICAgPG1ldGVyIFtpZF09XCJnZW5lcmF0ZWRJZFwiIFtvcHRpbXVtXT1cImNhcmRMZXZlbERhdGEoKS5vcHRpbXVtXCIgW21pbl09XCJjYXJkTGV2ZWxEYXRhKCkubWluXCIgW21heF09XCJjYXJkTGV2ZWxEYXRhKCkubWF4XCIgW2xvd109XCJjYXJkTGV2ZWxEYXRhKCkubG93XCIgW2hpZ2hdPVwiY2FyZExldmVsRGF0YSgpLmhpZ2hcIiBbdmFsdWVdPVwiY2FyZExldmVsRGF0YSgpLnZhbHVlXCI+XHJcbiAgICAgIDwvbWV0ZXI+XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIHt7IGNhcmRMZXZlbERhdGEoKS52YWx1ZSB9fXt7IGNhcmRMZXZlbERhdGEoKS51bml0IH19XHJcbiAgICA8L3NwYW4+XHJcbiAgPC9sYWJlbD5cclxuPC9kaXY+Il19
|
|
@@ -1,2 +1,8 @@
|
|
|
1
|
+
export * from './table.types';
|
|
1
2
|
export * from './table.component';
|
|
2
|
-
|
|
3
|
+
export * from './table-data-converter.service';
|
|
4
|
+
export * from './table-column-visibility.service';
|
|
5
|
+
export * from './table-data-utils.service';
|
|
6
|
+
export * from './table-selection.service';
|
|
7
|
+
export * from './table-crud-state.service';
|
|
8
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi9saWJzL3VpL3NyYy9saWIvdGFibGUvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsY0FBYyxlQUFlLENBQUM7QUFDOUIsY0FBYyxtQkFBbUIsQ0FBQztBQUNsQyxjQUFjLGdDQUFnQyxDQUFDO0FBQy9DLGNBQWMsbUNBQW1DLENBQUM7QUFDbEQsY0FBYyw0QkFBNEIsQ0FBQztBQUMzQyxjQUFjLDJCQUEyQixDQUFDO0FBQzFDLGNBQWMsNEJBQTRCLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJleHBvcnQgKiBmcm9tICcuL3RhYmxlLnR5cGVzJztcbmV4cG9ydCAqIGZyb20gJy4vdGFibGUuY29tcG9uZW50JztcbmV4cG9ydCAqIGZyb20gJy4vdGFibGUtZGF0YS1jb252ZXJ0ZXIuc2VydmljZSc7XG5leHBvcnQgKiBmcm9tICcuL3RhYmxlLWNvbHVtbi12aXNpYmlsaXR5LnNlcnZpY2UnO1xuZXhwb3J0ICogZnJvbSAnLi90YWJsZS1kYXRhLXV0aWxzLnNlcnZpY2UnO1xuZXhwb3J0ICogZnJvbSAnLi90YWJsZS1zZWxlY3Rpb24uc2VydmljZSc7XG5leHBvcnQgKiBmcm9tICcuL3RhYmxlLWNydWQtc3RhdGUuc2VydmljZSc7XG4iXX0=
|
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
import { Injectable, inject } from '@angular/core';
|
|
2
|
+
import { TableDataConverterService } from './table-data-converter.service';
|
|
3
|
+
import * as i0 from "@angular/core";
|
|
4
|
+
/**
|
|
5
|
+
* Servicio para gestionar la lógica de visibilidad de columnas en tablas C80
|
|
6
|
+
*
|
|
7
|
+
* Maneja las reglas complejas de visibilidad basadas en:
|
|
8
|
+
* - Configuración explícita (visible: false)
|
|
9
|
+
* - Ocultación automática (hideIfAllValuesAreNull)
|
|
10
|
+
* - Estado de creación y edición
|
|
11
|
+
*/
|
|
12
|
+
export class TableColumnVisibilityService {
|
|
13
|
+
dataConverter = inject(TableDataConverterService);
|
|
14
|
+
/**
|
|
15
|
+
* Actualiza las keys de columnas visibles basándose en el estado actual
|
|
16
|
+
* @param columns - Definiciones de columnas
|
|
17
|
+
* @param data - Datos actuales de la tabla
|
|
18
|
+
* @param creating - Si está en modo creación
|
|
19
|
+
* @param editing - ID de fila en edición (null si no hay edición)
|
|
20
|
+
* @returns Array de accessors de columnas visibles
|
|
21
|
+
*/
|
|
22
|
+
updateVisibleKeys(columns, data, creating, editing) {
|
|
23
|
+
const visibleColumns = columns.filter(col => this.isColumnVisibleInHeader(col, data, creating, editing));
|
|
24
|
+
return visibleColumns.map(col => col.accessor);
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Determina si una columna debe ser visible basándose en su configuración y datos
|
|
28
|
+
* @param column - La definición de la columna
|
|
29
|
+
* @param data - Datos actuales de la tabla
|
|
30
|
+
* @param forceShowInCreation - Si es true, ignora hideIfAllValuesAreNull (usado en modo creación)
|
|
31
|
+
* @returns true si la columna debe ser visible
|
|
32
|
+
*/
|
|
33
|
+
isColumnVisible(column, data, forceShowInCreation = false) {
|
|
34
|
+
// PRIORIDAD 1: Si visible está explícitamente establecido en false, SIEMPRE ocultar
|
|
35
|
+
if (column.visible === false) {
|
|
36
|
+
return false;
|
|
37
|
+
}
|
|
38
|
+
// PRIORIDAD 2: Si hideIfAllValuesAreNull es true y todos los valores están vacíos, ocultar
|
|
39
|
+
// EXCEPCIÓN: En modo creación, mostramos estas columnas para permitir entrada de datos
|
|
40
|
+
if (column.hideIfAllValuesAreNull === true && !forceShowInCreation && this.areAllColumnValuesEmpty(column, data)) {
|
|
41
|
+
return false;
|
|
42
|
+
}
|
|
43
|
+
// Por defecto: mostrar
|
|
44
|
+
return true;
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Determina si una columna debe ser visible en los headers
|
|
48
|
+
* @param column - La definición de la columna
|
|
49
|
+
* @param data - Datos actuales de la tabla
|
|
50
|
+
* @param creating - Si está en modo creación
|
|
51
|
+
* @param editing - ID de fila en edición (null si no hay edición)
|
|
52
|
+
* @returns true si el header debe ser visible
|
|
53
|
+
*/
|
|
54
|
+
isColumnVisibleInHeader(column, data, creating, editing) {
|
|
55
|
+
// PRIORIDAD 1: Si visible está explícitamente establecido en false, SIEMPRE ocultar
|
|
56
|
+
if (column.visible === false) {
|
|
57
|
+
return false;
|
|
58
|
+
}
|
|
59
|
+
// Si estamos en modo creación, mostrar columnas con hideIfAllValuesAreNull
|
|
60
|
+
if (creating && column.hideIfAllValuesAreNull === true) {
|
|
61
|
+
return true;
|
|
62
|
+
}
|
|
63
|
+
// Si hay una fila en modo edición y la columna tiene hideIfAllValuesAreNull
|
|
64
|
+
if (editing !== null && column.hideIfAllValuesAreNull === true) {
|
|
65
|
+
// Buscar la fila que se está editando
|
|
66
|
+
const editingRow = data.find(row => row['id'] === editing);
|
|
67
|
+
if (editingRow) {
|
|
68
|
+
// Solo mostrar el header si la fila en edición tiene valor en esta columna
|
|
69
|
+
const cellValue = this.getCellValue(editingRow, column.accessor);
|
|
70
|
+
return !this.dataConverter.isValueEmpty(cellValue);
|
|
71
|
+
}
|
|
72
|
+
// Si no se encuentra la fila, no mostrar el header
|
|
73
|
+
return false;
|
|
74
|
+
}
|
|
75
|
+
// Si hideIfAllValuesAreNull es true y todos los valores están vacíos, ocultar
|
|
76
|
+
if (column.hideIfAllValuesAreNull === true && this.areAllColumnValuesEmpty(column, data)) {
|
|
77
|
+
return false;
|
|
78
|
+
}
|
|
79
|
+
// Por defecto: mostrar
|
|
80
|
+
return true;
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Determina si una columna debe ser visible en una fila específica considerando el modo edición
|
|
84
|
+
* @param column - La definición de la columna
|
|
85
|
+
* @param row - La fila actual
|
|
86
|
+
* @param data - Datos actuales de la tabla
|
|
87
|
+
* @param editing - ID de fila en edición (null si no hay edición)
|
|
88
|
+
* @returns true si la columna debe ser visible para esta fila
|
|
89
|
+
*/
|
|
90
|
+
isColumnVisibleForRow(column, row, data, editing) {
|
|
91
|
+
// PRIORIDAD 1: Si visible está explícitamente establecido en false, SIEMPRE ocultar
|
|
92
|
+
if (column.visible === false) {
|
|
93
|
+
return false;
|
|
94
|
+
}
|
|
95
|
+
// PRIORIDAD 2: Si esta fila específica está en modo edición y la columna tiene hideIfAllValuesAreNull
|
|
96
|
+
const isEditingThisRow = editing === row['id'];
|
|
97
|
+
if (isEditingThisRow && column.hideIfAllValuesAreNull === true) {
|
|
98
|
+
// En edición, solo mostrar si esta fila específica tiene valor en esta columna
|
|
99
|
+
const cellValue = this.getCellValue(row, column.accessor);
|
|
100
|
+
return !this.dataConverter.isValueEmpty(cellValue);
|
|
101
|
+
}
|
|
102
|
+
// PRIORIDAD 3: Si hideIfAllValuesAreNull es true y todos los valores están vacíos, ocultar
|
|
103
|
+
if (column.hideIfAllValuesAreNull === true && this.areAllColumnValuesEmpty(column, data)) {
|
|
104
|
+
return false;
|
|
105
|
+
}
|
|
106
|
+
// Por defecto: mostrar
|
|
107
|
+
return true;
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* Verifica si todos los valores de una columna están vacíos/nulos
|
|
111
|
+
* @param column - La definición de la columna
|
|
112
|
+
* @param data - Datos actuales de la tabla
|
|
113
|
+
* @returns true si todos los valores están vacíos
|
|
114
|
+
*/
|
|
115
|
+
areAllColumnValuesEmpty(column, data) {
|
|
116
|
+
if (data.length === 0) {
|
|
117
|
+
return true; // Si no hay datos, consideramos la columna como vacía
|
|
118
|
+
}
|
|
119
|
+
return data.every(row => {
|
|
120
|
+
const value = this.getCellValue(row, column.accessor);
|
|
121
|
+
return this.dataConverter.isValueEmpty(value);
|
|
122
|
+
});
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* Obtiene el valor de una celda usando el accessor, soportando notación de punto para propiedades anidadas
|
|
126
|
+
* @param row - La fila de datos
|
|
127
|
+
* @param accessor - El accessor de la columna
|
|
128
|
+
* @returns El valor de la celda
|
|
129
|
+
*/
|
|
130
|
+
getCellValue(row, accessor) {
|
|
131
|
+
if (accessor.includes('.')) {
|
|
132
|
+
return this.getNestedValue(row, accessor);
|
|
133
|
+
}
|
|
134
|
+
return row[accessor];
|
|
135
|
+
}
|
|
136
|
+
/**
|
|
137
|
+
* Obtiene el valor de un objeto usando notación de punto (ej: 'task.name')
|
|
138
|
+
* @param obj - Objeto del cual obtener el valor
|
|
139
|
+
* @param accessor - Ruta de acceso usando notación de punto
|
|
140
|
+
* @returns El valor anidado o undefined
|
|
141
|
+
*/
|
|
142
|
+
getNestedValue(obj, accessor) {
|
|
143
|
+
return accessor.split('.').reduce((current, key) => {
|
|
144
|
+
return current && typeof current === 'object' ? current[key] : undefined;
|
|
145
|
+
}, obj);
|
|
146
|
+
}
|
|
147
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: TableColumnVisibilityService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
148
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: TableColumnVisibilityService, providedIn: 'root' });
|
|
149
|
+
}
|
|
150
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: TableColumnVisibilityService, decorators: [{
|
|
151
|
+
type: Injectable,
|
|
152
|
+
args: [{
|
|
153
|
+
providedIn: 'root'
|
|
154
|
+
}]
|
|
155
|
+
}] });
|
|
156
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGFibGUtY29sdW1uLXZpc2liaWxpdHkuc2VydmljZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL2xpYnMvdWkvc3JjL2xpYi90YWJsZS90YWJsZS1jb2x1bW4tdmlzaWJpbGl0eS5zZXJ2aWNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBRW5ELE9BQU8sRUFBRSx5QkFBeUIsRUFBRSxNQUFNLGdDQUFnQyxDQUFDOztBQUUzRTs7Ozs7OztHQU9HO0FBSUgsTUFBTSxPQUFPLDRCQUE0QjtJQUVwQixhQUFhLEdBQUcsTUFBTSxDQUFDLHlCQUF5QixDQUFDLENBQUM7SUFFbkU7Ozs7Ozs7T0FPRztJQUNILGlCQUFpQixDQUNiLE9BQXlCLEVBQ3pCLElBQVMsRUFDVCxRQUFpQixFQUNqQixPQUFrQjtRQUVsQixNQUFNLGNBQWMsR0FBRyxPQUFPLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQ3hDLElBQUksQ0FBQyx1QkFBdUIsQ0FBQyxHQUFHLEVBQUUsSUFBSSxFQUFFLFFBQVEsRUFBRSxPQUFPLENBQUMsQ0FDN0QsQ0FBQztRQUNGLE9BQU8sY0FBYyxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsQ0FBQyxRQUFRLENBQUMsQ0FBQztJQUNuRCxDQUFDO0lBRUQ7Ozs7OztPQU1HO0lBQ0gsZUFBZSxDQUNYLE1BQXNCLEVBQ3RCLElBQVMsRUFDVCxtQkFBbUIsR0FBRyxLQUFLO1FBRTNCLG9GQUFvRjtRQUNwRixJQUFJLE1BQU0sQ0FBQyxPQUFPLEtBQUssS0FBSyxFQUFFLENBQUM7WUFDM0IsT0FBTyxLQUFLLENBQUM7UUFDakIsQ0FBQztRQUVELDJGQUEyRjtRQUMzRix1RkFBdUY7UUFDdkYsSUFBSSxNQUFNLENBQUMsc0JBQXNCLEtBQUssSUFBSSxJQUFJLENBQUMsbUJBQW1CLElBQUks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S0FBSyxDQUFDLEdBQUcsQ0FBQyxFQUFFO1lBQ3BCLE1BQU0sS0FBSyxHQUFHLElBQUksQ0FBQyxZQUFZLENBQUMsR0FBRyxFQUFFLE1BQU0sQ0FBQyxRQUFRLENBQUMsQ0FBQztZQUN0RCxPQUFPLElBQUksQ0FBQyxhQUFhLENBQUMsWUFBWSxDQUFDLEtBQUssQ0FBQyxDQUFDO1FBQ2xELENBQUMsQ0FBQyxDQUFDO0lBQ1AsQ0FBQztJQUVEOzs7OztPQUtHO0lBQ0ssWUFBWSxDQUFvQyxHQUFNLEVBQUUsUUFBZ0I7UUFDNUUsSUFBSSxRQUFRLENBQUMsUUFBUSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUM7WUFDekIsT0FBTyxJQUFJLENBQUMsY0FBYyxDQUFDLEdBQUcsRUFBRSxRQUFRLENBQUMsQ0FBQztRQUM5QyxDQUFDO1FBQ0QsT0FBUSxHQUErQixDQUFDLFFBQVEsQ0FBQyxDQUFDO0lBQ3RELENBQUM7SUFFRDs7Ozs7T0FLRztJQUNLLGNBQWMsQ0FBQyxHQUFRLEVBQUUsUUFBZ0I7UUFDN0MsT0FBTyxRQUFRLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxDQUFDLE9BQU8sRUFBRSxHQUFHLEVBQUUsRUFBRTtZQUMvQyxPQUFPLE9BQU8sSUFBSSxPQUFPLE9BQU8sS0FBSyxRQUFRLENBQUMsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsU0FBUyxDQUFDO1FBQzdFLENBQUMsRUFBRSxHQUFHLENBQUMsQ0FBQztJQUNaLENBQUM7d0dBbExRLDRCQUE0Qjs0R0FBNUIsNEJBQTRCLGNBRnpCLE1BQU07OzRGQUVULDRCQUE0QjtrQkFIeEMsVUFBVTttQkFBQztvQkFDUixVQUFVLEVBQUUsTUFBTTtpQkFDckIiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBJbmplY3RhYmxlLCBpbmplY3QgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IEM4MFRhYmxlQ29sRGVmLCBJRCB9IGZyb20gJy4vdGFibGUudHlwZXMnO1xuaW1wb3J0IHsgVGFibGVEYXRhQ29udmVydGVyU2VydmljZSB9IGZyb20gJy4vdGFibGUtZGF0YS1jb252ZXJ0ZXIuc2VydmljZSc7XG5cbi8qKlxuICogU2VydmljaW8gcGFyYSBnZXN0aW9uYXIgbGEgbMOzZ2ljYSBkZSB2aXNpYmlsaWRhZCBkZSBjb2x1bW5hcyBlbiB0YWJsYXMgQzgwXG4gKlxuICogTWFuZWphIGxhcyByZWdsYXMgY29tcGxlamFzIGRlIHZpc2liaWxpZGFkIGJhc2FkYXMgZW46XG4gKiAtIENvbmZpZ3VyYWNpw7NuIGV4cGzDrWNpdGEgKHZpc2libGU6IGZhbHNlKVxuICogLSBPY3VsdGFjacOzbiBhdXRvbcOhdGljYSAoaGlkZUlmQWxsVmFsdWVzQXJlTnVsbClcbiAqIC0gRXN0YWRvIGRlIGNyZWFjacOzbiB5IGVkaWNpw7NuXG4gKi9cbkBJbmplY3RhYmxlKHtcbiAgICBwcm92aWRlZEluOiAncm9vdCdcbn0pXG5leHBvcnQgY2xhc3MgVGFibGVDb2x1bW5WaXNpYmlsaXR5U2VydmljZSB7XG5cbiAgICBwcml2YXRlIHJlYWRvbmx5IGRhdGFDb252ZXJ0ZXIgPSBpbmplY3QoVGFibGVEYXRhQ29udmVydGVyU2VydmljZSk7XG5cbiAgICAvKipcbiAgICAgKiBBY3R1YWxpemEgbGFzIGtleXMgZGUgY29sdW1uYXMgdmlzaWJsZXMgYmFzw6FuZG9zZSBlbiBlbCBlc3RhZG8gYWN0dWFsXG4gICAgICogQHBhcmFtIGNvbHVtbnMgLSBEZWZpbmljaW9uZXMgZGUgY29sdW1uYXNcbiAgICAgKiBAcGFyYW0gZGF0YSAtIERhdG9zIGFjdHVhbGVzIGRlIGxhIHRhYmxhXG4gICAgICogQHBhcmFtIGNyZWF0aW5nIC0gU2kgZXN0w6EgZW4gbW9kbyBjcmVhY2nDs25cbiAgICAgKiBAcGFyYW0gZWRpdGluZyAtIElEIGRlIGZpbGEgZW4gZWRpY2nDs24gKG51bGwgc2kgbm8gaGF5IGVkaWNpw7NuKVxuICAgICAqIEByZXR1cm5zIEFycmF5IGRlIGFjY2Vzc29ycyBkZSBjb2x1bW5hcyB2aXNpYmxlc1xuICAgICAqL1xuICAgIHVwZGF0ZVZpc2libGVLZXlzPFQgZXh0ZW5kcyBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPj4oXG4gICAgICAgIGNvbHVtbnM6IEM4MFRhYmxlQ29sRGVmW10sXG4gICAgICAgIGRhdGE6IFRbXSxcbiAgICAgICAgY3JlYXRpbmc6IGJvb2xlYW4sXG4gICAgICAgIGVkaXRpbmc6IElEIHwgbnVsbFxuICAgICk6IHN0cmluZ1tdIHtcbiAgICAgICAgY29uc3QgdmlzaWJsZUNvbHVtbnMgPSBjb2x1bW5zLmZpbHRlcihjb2wgPT5cbiAgICAgICAgICAgIHRoaXMuaXNDb2x1bW5WaXNpYmxlSW5IZWFkZXIoY29sLCBkYXRhLCBjcmVhdGluZywgZWRpdGluZylcbiAgICAgICAgKTtcbiAgICAgICAgcmV0dXJuIHZpc2libGVDb2x1bW5zLm1hcChjb2wgPT4gY29sLmFjY2Vzc29yKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBEZXRlcm1pbmEgc2kgdW5hIGNvbHVtbmEgZGViZSBzZXIgdmlzaWJsZSBiYXPDoW5kb3NlIGVuIHN1IGNvbmZpZ3VyYWNpw7NuIHkgZGF0b3NcbiAgICAgKiBAcGFyYW0gY29sdW1uIC0gTGEgZGVmaW5pY2nDs24gZGUgbGEgY29sdW1uYVxuICAgICAqIEBwYXJhbSBkYXRhIC0gRGF0b3MgYWN0dWFsZXMgZGUgbGEgdGFibGFcbiAgICAgKiBAcGFyYW0gZm9yY2VTaG93SW5DcmVhdGlvbiAtIFNpIGVzIHRydWUsIGlnbm9yYSBoaWRlSWZBbGxWYWx1ZXNBcmVOdWxsICh1c2FkbyBlbiBtb2RvIGNyZWFjacOzbilcbiAgICAgKiBAcmV0dXJucyB0cnVlIHNpIGxhIGNvbHVtbmEgZGViZSBzZXIgdmlzaWJsZVxuICAgICAqL1xuICAgIGlzQ29sdW1uVmlzaWJsZTxUIGV4dGVuZHMgUmVjb3JkPHN0cmluZywgdW5rbm93bj4+KFxuICAgICAgICBjb2x1bW46IEM4MFRhYmxlQ29sRGVmLFxuICAgICAgICBkYXRhOiBUW10sXG4gICAgICAgIGZvcmNlU2hvd0luQ3JlYXRpb24gPSBmYWxzZVxuICAgICk6IGJvb2xlYW4ge1xuICAgICAgICAvLyBQUklPUklEQUQgMTogU2kgdmlzaWJsZSBlc3TDoSBleHBsw61jaXRhbWVudGUgZXN0YWJsZWNpZG8gZW4gZmFsc2UsIFNJRU1QUkUgb2N1bHRhclxuICAgICAgICBpZiAoY29sdW1uLnZpc2libGUgPT09IGZhbHNlKSB7XG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBQUklPUklEQUQgMjogU2kgaGlkZUlmQWxsVmFsdWVzQXJlTnVsbCBlcyB0cnVlIHkgdG9kb3MgbG9zIHZhbG9yZXMgZXN0w6FuIHZhY8Otb3MsIG9jdWx0YXJcbiAgICAgICAgLy8gRVhDRVBDScOTTjogRW4gbW9kbyBjcmVhY2nDs24sIG1vc3RyYW1vcyBlc3RhcyBjb2x1bW5hcyBwYXJhIHBlcm1pdGlyIGVudHJhZGEgZGUgZGF0b3NcbiAgICAgICAgaWYgKGNvbHVtbi5oaWRlSWZBbGxWYWx1ZXNBcmVOdWxsID09PSB0cnVlICYmICFmb3JjZVNob3dJbkNyZWF0aW9uICYmIHRoaXMuYXJlQWxsQ29sdW1uVmFsdWVzRW1wdHkoY29sdW1uLCBkYXRhKSkge1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gUG9yIGRlZmVjdG86IG1vc3RyYXJcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogRGV0ZXJtaW5hIHNpIHVuYSBjb2x1bW5hIGRlYmUgc2VyIHZpc2libGUgZW4gbG9zIGhlYWRlcnNcbiAgICAgKiBAcGFyYW0gY29sdW1uIC0gTGEgZGVmaW5pY2nDs24gZGUgbGEgY29sdW1uYVxuICAgICAqIEBwYXJhbSBkYXRhIC0gRGF0b3MgYWN0dWFsZXMgZGUgbGEgdGFibGFcbiAgICAgKiBAcGFyYW0gY3JlYXRpbmcgLSBTaSBlc3TDoSBlbiBtb2RvIGNyZWFjacOzblxuICAgICAqIEBwYXJhbSBlZGl0aW5nIC0gSUQgZGUgZmlsYSBlbiBlZGljacOzbiAobnVsbCBzaSBubyBoYXkgZWRpY2nDs24pXG4gICAgICogQHJldHVybnMgdHJ1ZSBzaSBlbCBoZWFkZXIgZGViZSBzZXIgdmlzaWJsZVxuICAgICAqL1xuICAgIGlzQ29sdW1uVmlzaWJsZUluSGVhZGVyPFQgZXh0ZW5kcyBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPj4oXG4gICAgICAgIGNvbHVtbjogQzgwVGFibGVDb2xEZWYsXG4gICAgICAgIGRhdGE6IFRbXSxcbiAgICAgICAgY3JlYXRpbmc6IGJvb2xlYW4sXG4gICAgICAgIGVkaXRpbmc6IElEIHwgbnVsbFxuICAgICk6IGJvb2xlYW4ge1xuICAgICAgICAvLyBQUklPUklEQUQgMTogU2kgdmlzaWJsZSBlc3TDoSBleHBsw61jaXRhbWVudGUgZXN0YWJsZWNpZG8gZW4gZmFsc2UsIFNJRU1QUkUgb2N1bHRhclxuICAgICAgICBpZiAoY29sdW1uLnZpc2libGUgPT09IGZhbHNlKSB7XG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBTaSBlc3RhbW9zIGVuIG1vZG8gY3JlYWNpw7NuLCBtb3N0cmFyIGNvbHVtbmFzIGNvbiBoaWRlSWZBbGxWYWx1ZXNBcmVOdWxsXG4gICAgICAgIGlmIChjcmVhdGluZyAmJiBjb2x1bW4uaGlkZUlmQWxsVmFsdWVzQXJlTnVsbCA9PT0gdHJ1ZSkge1xuICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBTaSBoYXkgdW5hIGZpbGEgZW4gbW9kbyBlZGljacOzbiB5IGxhIGNvbHVtbmEgdGllbmUgaGlkZUlmQWxsVmFsdWVzQXJlTnVsbFxuICAgICAgICBpZiAoZWRpdGluZyAhPT0gbnVsbCAmJiBjb2x1bW4uaGlkZUlmQWxsVmFsdWVzQXJlTnVsbCA9PT0gdHJ1ZSkge1xuICAgICAgICAgICAgLy8gQnVzY2FyIGxhIGZpbGEgcXVlIHNlIGVzdMOhIGVkaXRhbmRvXG4gICAgICAgICAgICBjb25zdCBlZGl0aW5nUm93ID0gZGF0YS5maW5kKHJvdyA9PiByb3dbJ2lkJ10gPT09IGVkaXRpbmcpO1xuXG4gICAgICAgICAgICBpZiAoZWRpdGluZ1Jvdykge1xuICAgICAgICAgICAgICAgIC8vIFNvbG8gbW9zdHJhciBlbCBoZWFkZXIgc2kgbGEgZmlsYSBlbiBlZGljacOzbiB0aWVuZSB2YWxvciBlbiBlc3RhIGNvbHVtbmFcbiAgICAgICAgICAgICAgICBjb25zdCBjZWxsVmFsdWUgPSB0aGlzLmdldENlbGxWYWx1ZShlZGl0aW5nUm93LCBjb2x1bW4uYWNjZXNzb3IpO1xuICAgICAgICAgICAgICAgIHJldHVybiAhdGhpcy5kYXRhQ29udmVydGVyLmlzVmFsdWVFbXB0eShjZWxsVmFsdWUpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAvLyBTaSBubyBzZSBlbmN1ZW50cmEgbGEgZmlsYSwgbm8gbW9zdHJhciBlbCBoZWFkZXJcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIFNpIGhpZGVJZkFsbFZhbHVlc0FyZU51bGwgZXMgdHJ1ZSB5IHRvZG9zIGxvcyB2YWxvcmVzIGVzdMOhbiB2YWPDrW9zLCBvY3VsdGFyXG4gICAgICAgIGlmIChjb2x1bW4uaGlkZUlmQWxsVmFsdWVzQXJlTnVsbCA9PT0gdHJ1ZSAmJiB0aGlzLmFyZUFsbENvbHVtblZhbHVlc0VtcHR5KGNvbHVtbiwgZGF0YSkpIHtcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIFBvciBkZWZlY3RvOiBtb3N0cmFyXG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIERldGVybWluYSBzaSB1bmEgY29sdW1uYSBkZWJlIHNlciB2aXNpYmxlIGVuIHVuYSBmaWxhIGVzcGVjw61maWNhIGNvbnNpZGVyYW5kbyBlbCBtb2RvIGVkaWNpw7NuXG4gICAgICogQHBhcmFtIGNvbHVtbiAtIExhIGRlZmluaWNpw7NuIGRlIGxhIGNvbHVtbmFcbiAgICAgKiBAcGFyYW0gcm93IC0gTGEgZmlsYSBhY3R1YWxcbiAgICAgKiBAcGFyYW0gZGF0YSAtIERhdG9zIGFjdHVhbGVzIGRlIGxhIHRhYmxhXG4gICAgICogQHBhcmFtIGVkaXRpbmcgLSBJRCBkZSBmaWxhIGVuIGVkaWNpw7NuIChudWxsIHNpIG5vIGhheSBlZGljacOzbilcbiAgICAgKiBAcmV0dXJucyB0cnVlIHNpIGxhIGNvbHVtbmEgZGViZSBzZXIgdmlzaWJsZSBwYXJhIGVzdGEgZmlsYVxuICAgICAqL1xuICAgIGlzQ29sdW1uVmlzaWJsZUZvclJvdzxUIGV4dGVuZHMgUmVjb3JkPHN0cmluZywgdW5rbm93bj4+KFxuICAgICAgICBjb2x1bW46IEM4MFRhYmxlQ29sRGVmLFxuICAgICAgICByb3c6IFQsXG4gICAgICAgIGRhdGE6IFRbXSxcbiAgICAgICAgZWRpdGluZzogSUQgfCBudWxsXG4gICAgKTogYm9vbGVhbiB7XG4gICAgICAgIC8vIFBSSU9SSURBRCAxOiBTaSB2aXNpYmxlIGVzdMOhIGV4cGzDrWNpdGFtZW50ZSBlc3RhYmxlY2lkbyBlbiBmYWxzZSwgU0lFTVBSRSBvY3VsdGFyXG4gICAgICAgIGlmIChjb2x1bW4udmlzaWJsZSA9PT0gZmFsc2UpIHtcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIFBSSU9SSURBRCAyOiBTaSBlc3RhIGZpbGEgZXNwZWPDrWZpY2EgZXN0w6EgZW4gbW9kbyBlZGljacOzbiB5IGxhIGNvbHVtbmEgdGllbmUgaGlkZUlmQWxsVmFsdWVzQXJlTnVsbFxuICAgICAgICBjb25zdCBpc0VkaXRpbmdUaGlzUm93ID0gZWRpdGluZyA9PT0gcm93WydpZCddO1xuICAgICAgICBpZiAoaXNFZGl0aW5nVGhpc1JvdyAmJiBjb2x1bW4uaGlkZUlmQWxsVmFsdWVzQXJlTnVsbCA9PT0gdHJ1ZSkge1xuICAgICAgICAgICAgLy8gRW4gZWRpY2nDs24sIHNvbG8gbW9zdHJhciBzaSBlc3RhIGZpbGEgZXNwZWPDrWZpY2EgdGllbmUgdmFsb3IgZW4gZXN0YSBjb2x1bW5hXG4gICAgICAgICAgICBjb25zdCBjZWxsVmFsdWUgPSB0aGlzLmdldENlbGxWYWx1ZShyb3csIGNvbHVtbi5hY2Nlc3Nvcik7XG4gICAgICAgICAgICByZXR1cm4gIXRoaXMuZGF0YUNvbnZlcnRlci5pc1ZhbHVlRW1wdHkoY2VsbFZhbHVlKTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIFBSSU9SSURBRCAzOiBTaSBoaWRlSWZBbGxWYWx1ZXNBcmVOdWxsIGVzIHRydWUgeSB0b2RvcyBsb3MgdmFsb3JlcyBlc3TDoW4gdmFjw61vcywgb2N1bHRhclxuICAgICAgICBpZiAoY29sdW1uLmhpZGVJZkFsbFZhbHVlc0FyZU51bGwgPT09IHRydWUgJiYgdGhpcy5hcmVBbGxDb2x1bW5WYWx1ZXNFbXB0eShjb2x1bW4sIGRhdGEpKSB7XG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBQb3IgZGVmZWN0bzogbW9zdHJhclxuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBWZXJpZmljYSBzaSB0b2RvcyBsb3MgdmFsb3JlcyBkZSB1bmEgY29sdW1uYSBlc3TDoW4gdmFjw61vcy9udWxvc1xuICAgICAqIEBwYXJhbSBjb2x1bW4gLSBMYSBkZWZpbmljacOzbiBkZSBsYSBjb2x1bW5hXG4gICAgICogQHBhcmFtIGRhdGEgLSBEYXRvcyBhY3R1YWxlcyBkZSBsYSB0YWJsYVxuICAgICAqIEByZXR1cm5zIHRydWUgc2kgdG9kb3MgbG9zIHZhbG9yZXMgZXN0w6FuIHZhY8Otb3NcbiAgICAgKi9cbiAgICBhcmVBbGxDb2x1bW5WYWx1ZXNFbXB0eTxUIGV4dGVuZHMgUmVjb3JkPHN0cmluZywgdW5rbm93bj4+KFxuICAgICAgICBjb2x1bW46IEM4MFRhYmxlQ29sRGVmLFxuICAgICAgICBkYXRhOiBUW11cbiAgICApOiBib29sZWFuIHtcbiAgICAgICAgaWYgKGRhdGEubGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgICByZXR1cm4gdHJ1ZTsgLy8gU2kgbm8gaGF5IGRhdG9zLCBjb25zaWRlcmFtb3MgbGEgY29sdW1uYSBjb21vIHZhY8OtYVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIGRhdGEuZXZlcnkocm93ID0+IHtcbiAgICAgICAgICAgIGNvbnN0IHZhbHVlID0gdGhpcy5nZXRDZWxsVmFsdWUocm93LCBjb2x1bW4uYWNjZXNzb3IpO1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuZGF0YUNvbnZlcnRlci5pc1ZhbHVlRW1wdHkodmFsdWUpO1xuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBPYnRpZW5lIGVsIHZhbG9yIGRlIHVuYSBjZWxkYSB1c2FuZG8gZWwgYWNjZXNzb3IsIHNvcG9ydGFuZG8gbm90YWNpw7NuIGRlIHB1bnRvIHBhcmEgcHJvcGllZGFkZXMgYW5pZGFkYXNcbiAgICAgKiBAcGFyYW0gcm93IC0gTGEgZmlsYSBkZSBkYXRvc1xuICAgICAqIEBwYXJhbSBhY2Nlc3NvciAtIEVsIGFjY2Vzc29yIGRlIGxhIGNvbHVtbmFcbiAgICAgKiBAcmV0dXJucyBFbCB2YWxvciBkZSBsYSBjZWxkYVxuICAgICAqL1xuICAgIHByaXZhdGUgZ2V0Q2VsbFZhbHVlPFQgZXh0ZW5kcyBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPj4ocm93OiBULCBhY2Nlc3Nvcjogc3RyaW5nKTogdW5rbm93biB7XG4gICAgICAgIGlmIChhY2Nlc3Nvci5pbmNsdWRlcygnLicpKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5nZXROZXN0ZWRWYWx1ZShyb3csIGFjY2Vzc29yKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gKHJvdyBhcyBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPilbYWNjZXNzb3JdO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIE9idGllbmUgZWwgdmFsb3IgZGUgdW4gb2JqZXRvIHVzYW5kbyBub3RhY2nDs24gZGUgcHVudG8gKGVqOiAndGFzay5uYW1lJylcbiAgICAgKiBAcGFyYW0gb2JqIC0gT2JqZXRvIGRlbCBjdWFsIG9idGVuZXIgZWwgdmFsb3JcbiAgICAgKiBAcGFyYW0gYWNjZXNzb3IgLSBSdXRhIGRlIGFjY2VzbyB1c2FuZG8gbm90YWNpw7NuIGRlIHB1bnRvXG4gICAgICogQHJldHVybnMgRWwgdmFsb3IgYW5pZGFkbyBvIHVuZGVmaW5lZFxuICAgICAqL1xuICAgIHByaXZhdGUgZ2V0TmVzdGVkVmFsdWUob2JqOiBhbnksIGFjY2Vzc29yOiBzdHJpbmcpOiB1bmtub3duIHtcbiAgICAgICAgcmV0dXJuIGFjY2Vzc29yLnNwbGl0KCcuJykucmVkdWNlKChjdXJyZW50LCBrZXkpID0+IHtcbiAgICAgICAgICAgIHJldHVybiBjdXJyZW50ICYmIHR5cGVvZiBjdXJyZW50ID09PSAnb2JqZWN0JyA/IGN1cnJlbnRba2V5XSA6IHVuZGVmaW5lZDtcbiAgICAgICAgfSwgb2JqKTtcbiAgICB9XG59XG4iXX0=
|
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
import { Injectable, signal, inject } from '@angular/core';
|
|
2
|
+
import { TableColumnVisibilityService } from './table-column-visibility.service';
|
|
3
|
+
import { TableDataConverterService } from './table-data-converter.service';
|
|
4
|
+
import * as i0 from "@angular/core";
|
|
5
|
+
/**
|
|
6
|
+
* Servicio para gestionar el estado CRUD (Crear, Leer, Actualizar, Eliminar) en tablas C80
|
|
7
|
+
*
|
|
8
|
+
* Maneja:
|
|
9
|
+
* - Estado de creación y edición
|
|
10
|
+
* - Gestión de datos temporales (newRow, editRow)
|
|
11
|
+
* - Aplicación de valores dinámicos
|
|
12
|
+
* - Validación y conversión de datos antes de emisión de eventos
|
|
13
|
+
*/
|
|
14
|
+
export class TableCrudStateService {
|
|
15
|
+
visibilityService = inject(TableColumnVisibilityService);
|
|
16
|
+
dataConverter = inject(TableDataConverterService);
|
|
17
|
+
/**
|
|
18
|
+
* Inicializa el estado CRUD para una nueva tabla
|
|
19
|
+
* @returns Objeto con signals y métodos para gestión CRUD
|
|
20
|
+
*/
|
|
21
|
+
createCrudState() {
|
|
22
|
+
const creating = signal(false);
|
|
23
|
+
const newRow = signal(null);
|
|
24
|
+
const editing = signal(null);
|
|
25
|
+
const editRow = signal(null);
|
|
26
|
+
const startCreate = (columns, data) => {
|
|
27
|
+
creating.set(true);
|
|
28
|
+
// Inicializar newRow solo con columnas visibles y no readOnly
|
|
29
|
+
// En modo creación, mostramos columnas con hideIfAllValuesAreNull para permitir entrada de datos
|
|
30
|
+
const row = {};
|
|
31
|
+
columns
|
|
32
|
+
.filter((col) => this.visibilityService.isColumnVisible(col, data, true) && !col.readOnly)
|
|
33
|
+
.forEach((col) => {
|
|
34
|
+
// Si la columna tiene un valor por defecto, usarlo; si no, usar cadena vacía
|
|
35
|
+
const defaultValue = col.default !== undefined ? col.default : '';
|
|
36
|
+
row[col.accessor] = defaultValue;
|
|
37
|
+
});
|
|
38
|
+
newRow.set(row);
|
|
39
|
+
};
|
|
40
|
+
const cancelCreate = () => {
|
|
41
|
+
creating.set(false);
|
|
42
|
+
newRow.set(null);
|
|
43
|
+
};
|
|
44
|
+
const updateNewRow = (key, value) => {
|
|
45
|
+
const current = newRow();
|
|
46
|
+
if (!current)
|
|
47
|
+
return;
|
|
48
|
+
newRow.set({ ...current, [key]: value });
|
|
49
|
+
};
|
|
50
|
+
const saveCreate = (columns, data, createEmitter) => {
|
|
51
|
+
const row = newRow();
|
|
52
|
+
if (!row)
|
|
53
|
+
return;
|
|
54
|
+
// Validar campos requeridos antes de crear - solo columnas visibles y no readOnly
|
|
55
|
+
// En modo creación, incluimos columnas con hideIfAllValuesAreNull
|
|
56
|
+
const visibleColumns = columns.filter((col) => this.visibilityService.isColumnVisible(col, data, true) && !col.readOnly);
|
|
57
|
+
const converted = visibleColumns.reduce((acc, col) => {
|
|
58
|
+
const sampleValue = data.length > 0
|
|
59
|
+
? this.visibilityService['getCellValue'](data[0], col.accessor)
|
|
60
|
+
: undefined;
|
|
61
|
+
acc[col.accessor] = this.dataConverter.convertCellValue(row[col.accessor], col, sampleValue);
|
|
62
|
+
return acc;
|
|
63
|
+
}, {});
|
|
64
|
+
createEmitter.emit({
|
|
65
|
+
row: converted,
|
|
66
|
+
done: (success) => {
|
|
67
|
+
if (success) {
|
|
68
|
+
cancelCreate();
|
|
69
|
+
}
|
|
70
|
+
},
|
|
71
|
+
});
|
|
72
|
+
};
|
|
73
|
+
const startEdit = (row, columns, data) => {
|
|
74
|
+
editing.set(row['id']);
|
|
75
|
+
const edit = {};
|
|
76
|
+
columns
|
|
77
|
+
.filter((col) => this.visibilityService.isColumnVisible(col, data, true) && !col.readOnly)
|
|
78
|
+
.forEach((col) => {
|
|
79
|
+
const value = this.visibilityService['getCellValue'](row, col.accessor);
|
|
80
|
+
edit[col.accessor] = value;
|
|
81
|
+
});
|
|
82
|
+
editRow.set(edit);
|
|
83
|
+
};
|
|
84
|
+
const cancelEdit = () => {
|
|
85
|
+
editing.set(null);
|
|
86
|
+
editRow.set(null);
|
|
87
|
+
};
|
|
88
|
+
const updateEditRow = (key, value) => {
|
|
89
|
+
const current = editRow();
|
|
90
|
+
if (!current)
|
|
91
|
+
return;
|
|
92
|
+
editRow.set({ ...current, [key]: value });
|
|
93
|
+
};
|
|
94
|
+
const saveEdit = (rowId, columns, data, updateEmitter) => {
|
|
95
|
+
const currentEditRow = editRow();
|
|
96
|
+
if (!currentEditRow)
|
|
97
|
+
return;
|
|
98
|
+
const visibleColumns = columns.filter((col) => this.visibilityService.isColumnVisible(col, data, true) && !col.readOnly);
|
|
99
|
+
const converted = visibleColumns.reduce((acc, col) => {
|
|
100
|
+
const sampleValue = data.length > 0
|
|
101
|
+
? this.visibilityService['getCellValue'](data[0], col.accessor)
|
|
102
|
+
: undefined;
|
|
103
|
+
acc[col.accessor] = this.dataConverter.convertCellValue(currentEditRow[col.accessor], col, sampleValue);
|
|
104
|
+
return acc;
|
|
105
|
+
}, {});
|
|
106
|
+
updateEmitter.emit({
|
|
107
|
+
id: rowId,
|
|
108
|
+
changes: converted,
|
|
109
|
+
done: (success) => {
|
|
110
|
+
if (success) {
|
|
111
|
+
cancelEdit();
|
|
112
|
+
}
|
|
113
|
+
},
|
|
114
|
+
});
|
|
115
|
+
};
|
|
116
|
+
const applyInputValues = (partialValues) => {
|
|
117
|
+
// Solo aplicar valores si estamos en modo creación o edición
|
|
118
|
+
if (!creating() && editing() === null) {
|
|
119
|
+
return;
|
|
120
|
+
}
|
|
121
|
+
// Aplicar valores en modo creación
|
|
122
|
+
if (creating()) {
|
|
123
|
+
const currentRow = newRow();
|
|
124
|
+
if (currentRow) {
|
|
125
|
+
const updatedRow = { ...currentRow, ...partialValues };
|
|
126
|
+
newRow.set(updatedRow);
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
// Aplicar valores en modo edición
|
|
130
|
+
if (editing() !== null) {
|
|
131
|
+
const currentEditRow = editRow();
|
|
132
|
+
if (currentEditRow) {
|
|
133
|
+
const updatedEditRow = { ...currentEditRow, ...partialValues };
|
|
134
|
+
editRow.set(updatedEditRow);
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
};
|
|
138
|
+
return {
|
|
139
|
+
// Signals de solo lectura
|
|
140
|
+
creating: creating.asReadonly(),
|
|
141
|
+
newRow: newRow.asReadonly(),
|
|
142
|
+
editing: editing.asReadonly(),
|
|
143
|
+
editRow: editRow.asReadonly(),
|
|
144
|
+
// Métodos
|
|
145
|
+
startCreate,
|
|
146
|
+
cancelCreate,
|
|
147
|
+
updateNewRow,
|
|
148
|
+
saveCreate,
|
|
149
|
+
startEdit,
|
|
150
|
+
cancelEdit,
|
|
151
|
+
updateEditRow,
|
|
152
|
+
saveEdit,
|
|
153
|
+
applyInputValues,
|
|
154
|
+
};
|
|
155
|
+
}
|
|
156
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: TableCrudStateService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
157
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: TableCrudStateService, providedIn: 'root' });
|
|
158
|
+
}
|
|
159
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: TableCrudStateService, decorators: [{
|
|
160
|
+
type: Injectable,
|
|
161
|
+
args: [{
|
|
162
|
+
providedIn: 'root'
|
|
163
|
+
}]
|
|
164
|
+
}] });
|
|
165
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGFibGUtY3J1ZC1zdGF0ZS5zZXJ2aWNlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vbGlicy91aS9zcmMvbGliL3RhYmxlL3RhYmxlLWNydWQtc3RhdGUuc2VydmljZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sRUFBZ0IsTUFBTSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBRXpFLE9BQU8sRUFBRSw0QkFBNEIsRUFBRSxNQUFNLG1DQUFtQyxDQUFDO0FBQ2pGLE9BQU8sRUFBRSx5QkFBeUIsRUFBRSxNQUFNLGdDQUFnQyxDQUFDOztBQUUzRTs7Ozs7Ozs7R0FRRztBQUlILE1BQU0sT0FBTyxxQkFBcUI7SUFFYixpQkFBaUIsR0FBRyxNQUFNLENBQUMsNEJBQTRCLENBQUMsQ0FBQztJQUN6RCxhQUFhLEdBQUcsTUFBTSxDQUFDLHlCQUF5QixDQUFDLENBQUM7SUFFbkU7OztPQUdHO0lBQ0gsZUFBZTtRQUNYLE1BQU0sUUFBUSxHQUFHLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUMvQixNQUFNLE1BQU0sR0FBRyxNQUFNLENBQW9CLElBQUksQ0FBQyxDQUFDO1FBQy9DLE1BQU0sT0FBTyxHQUFHLE1BQU0sQ0FBWSxJQUFJLENBQUMsQ0FBQztRQUN4QyxNQUFNLE9BQU8sR0FBRyxNQUFNLENBQW9CLElBQUksQ0FBQyxDQUFDO1FBRWhELE1BQU0sV0FBVyxHQUFHLENBQUMsT0FBeUIsRUFBRSxJQUFTLEVBQVEsRUFBRTtZQUMvRCxRQUFRLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxDQUFDO1lBRW5CLDhEQUE4RDtZQUM5RCxpR0FBaUc7WUFDakcsTUFBTSxHQUFHLEdBQWUsRUFBRSxDQUFDO1lBQzNCLE9BQU87aUJBQ0YsTUFBTSxDQUFDLENBQUMsR0FBRyxFQUFFLEVBQUUsQ0FBQyxJQUFJLENBQUMsaUJBQWlCLENBQUMsZUFBZSxDQUFDLEdBQUcsRUFBRSxJQUFJLEVBQUUsSUFBSSxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsUUFBUSxDQUFDO2lCQUN6RixPQUFPLENBQUMsQ0FBQyxHQUFHLEVBQUUsRUFBRTtnQkFDYiw2RUFBNkU7Z0JBQzdFLE1BQU0sWUFBWSxHQUFHLEdBQUcsQ0FBQyxPQUFPLEtBQUssU0FBUyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUM7Z0JBQ2pFLEdBQStCLENBQUMsR0FBRyxDQUFDLFFBQVEsQ0FBQyxHQUFHLFlBQVksQ0FBQztZQUNsRSxDQUFDLENBQUMsQ0FBQztZQUNQLE1BQU0sQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUM7UUFDcEIsQ0FBQyxDQUFDO1FBRUYsTUFBTSxZQUFZLEdBQUcsR0FBUyxFQUFFO1lBQzVCLFFBQVEsQ0FBQyxHQUFHLENBQUMsS0FBSyxDQUFDLENBQUM7WUFDcEIsTUFBTSxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUNyQixDQUFDLENBQUM7UUFFRixNQUFNLFlBQVksR0FBRyxDQUFDLEdBQVcsRUFBRSxLQUFjLEVBQVEsRUFBRTtZQUN2RCxNQUFNLE9BQU8sR0FBRyxNQUFNLEVBQUUsQ0FBQztZQUN6QixJQUFJLENBQUMsT0FBTztnQkFBRSxPQUFPO1lBQ3JCLE1BQU0sQ0FBQyxHQUFHLENBQUMsRUFBRSxHQUFHLE9BQU8sRUFBRSxDQUFDLEdBQUcsQ0FBQyxFQUFFLEtBQUssRUFBRSxDQUFDLENBQUM7UUFDN0MsQ0FBQyxDQUFDO1FBRUYsTUFBTSxVQUFVLEdBQUcsQ0FDZixPQUF5QixFQUN6QixJQUFTLEVBQ1QsYUFBa0YsRUFDOUUsRUFBRTtZQUNOLE1BQU0sR0FBRyxHQUFHLE1BQU0sRUFBRSxDQUFDO1lBQ3JCLElBQUksQ0FBQyxHQUFHO2dCQUFFLE9BQU87WUFFakIsa0ZBQWtGO1lBQ2xGLGtFQUFrRTtZQUNsRSxNQUFNLGNBQWMsR0FBRyxPQUFPLENBQUMsTUFBTSxDQUFDLENBQUMsR0FBRyxFQUFFLEVBQUUsQ0FDMUMsSUFBSSxDQUFDLGlCQUFpQixDQUFDLGVBQWUsQ0FBQyxHQUFHLEVBQUUsSUFBSSxFQUFFLElBQUksQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLFFBQVEsQ0FDM0UsQ0FBQztZQUVGLE1BQU0sU0FBUyxHQUFHLGNBQWMsQ0FBQyxNQUFNLENBQUMsQ0FBQyxHQUFHLEVBQUUsR0FBRyxFQUFFLEVBQUU7Z0JBQ2pELE1BQU0sV0FBVyxHQUFHLElBQUksQ0FBQyxNQUFNLEdBQUcsQ0FBQztvQkFDL0IsQ0FBQyxDQUFDLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxjQUFjLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLEVBQUUsR0FBRyxDQUFDLFFBQVEsQ0FBQztvQkFDL0QsQ0FBQyxDQUFDLFNBQVMsQ0FBQztnQkFDaEIsR0FBRyxDQUFDLEdBQUcsQ0FBQyxRQUFRLENBQUMsR0FBRyxJQUFJLENBQUMsYUFBYSxDQUFDLGdCQUFnQixDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsUUFBUSxDQUFDLEVBQUUsR0FBRyxFQUFFLFdBQVcsQ0FBQyxDQUFDO2dCQUM3RixPQUFPLEdBQUcsQ0FBQztZQUNmLENBQUMsRUFBRSxFQUE2QixDQUFlLENBQUM7WUFFaEQsYUFBYSxDQUFDLElBQUksQ0FBQztnQkFDZixHQUFHLEVBQUUsU0FBUztnQkFDZCxJQUFJLEVBQUUsQ0FBQyxPQUFnQixFQUFFLEVBQUU7b0JBQ3ZCLElBQUksT0FBTyxFQUFFLENBQUM7d0JBQ1YsWUFBWSxFQUFFLENBQUM7b0JBQ25CLENBQUM7Z0JBQ0wsQ0FBQzthQUNKLENBQUMsQ0FBQztRQUNQLENBQUMsQ0FBQztRQUVGLE1BQU0sU0FBUyxHQUFHLENBQUMsR0FBTSxFQUFFLE9BQXlCLEVBQUUsSUFBUyxFQUFRLEVBQUU7WUFDckUsT0FBTyxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFPLENBQUMsQ0FBQztZQUU3QixNQUFNLElBQUksR0FBZSxFQUFFLENBQUM7WUFDNUIsT0FBTztpQkFDRixNQUFNLENBQUMsQ0FBQyxHQUFHLEVBQUUsRUFBRSxDQUFDLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxlQUFlLENBQUMsR0FBRyxFQUFFLElBQUksRUFBRSxJQUFJLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxRQUFRLENBQUM7aUJBQ3pGLE9BQU8sQ0FBQyxDQUFDLEdBQUcsRUFBRSxFQUFFO2dCQUNiLE1BQU0sS0FBSyxHQUFHLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxjQUFjLENBQUMsQ0FBQyxHQUFHLEVBQUUsR0FBRyxDQUFDLFFBQVEsQ0FBQyxDQUFDO2dCQUN2RSxJQUFnQyxDQUFDLEdBQUcsQ0FBQyxRQUFRLENBQUMsR0FBRyxLQUFLLENBQUM7WUFDNUQsQ0FBQyxDQUFDLENBQUM7WUFDUCxPQUFPLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxDQUFDO1FBQ3RCLENBQUMsQ0FBQztRQUVGLE1BQU0sVUFBVSxHQUFHLEdBQVMsRUFBRTtZQUMxQixPQUFPLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxDQUFDO1lBQ2xCLE9BQU8sQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLENBQUM7UUFDdEIsQ0FBQyxDQUFDO1FBRUYsTUFBTSxhQUFhLEdBQUcsQ0FBQyxHQUFXLEVBQUUsS0FBYyxFQUFRLEVBQUU7WUFDeEQsTUFBTSxPQUFPLEdBQUcsT0FBTyxFQUFFLENBQUM7WUFDMUIsSUFBSSxDQUFDLE9BQU87Z0JBQUUsT0FBTztZQUNyQixPQUFPLENBQUMsR0FBRyxDQUFDLEVBQUUsR0FBRyxPQUFPLEVBQUUsQ0FBQyxHQUFHLENBQUMsRUFBRSxLQUFLLEVBQUUsQ0FBQyxDQUFDO1FBQzlDLENBQUMsQ0FBQztRQUVGLE1BQU0sUUFBUSxHQUFHLENBQ2IsS0FBUyxFQUNULE9BQXlCLEVBQ3pCLElBQVMsRUFDVCxhQUE4RixFQUMxRixFQUFFO1lBQ04sTUFBTSxjQUFjLEdBQUcsT0FBTyxFQUFFLENBQUM7WUFDakMsSUFBSSxDQUFDLGNBQWM7Z0JBQUUsT0FBTztZQUU1QixNQUFNLGNBQWMsR0FBRyxPQUFPLENBQUMsTUFBTSxDQUNqQyxDQUFDLEdBQUcsRUFBRSxFQUFFLENBQUMsSUFBSSxDQUFDLGlCQUFpQixDQUFDLGVBQWUsQ0FBQyxHQUFHLEVBQUUsSUFBSSxFQUFFLElBQUksQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLFFBQVEsQ0FDcEYsQ0FBQztZQUVGLE1BQU0sU0FBUyxHQUFHLGNBQWMsQ0FBQyxNQUFNLENBQUMsQ0FBQyxHQUFHLEVBQUUsR0FBRyxFQUFFLEVBQUU7Z0JBQ2pELE1BQU0sV0FBVyxHQUFHLElBQUksQ0FBQyxNQUFNLEdBQUcsQ0FBQztvQkFDL0IsQ0FBQyxDQUFDLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxjQUFjLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLEVBQUUsR0FBRyxDQUFDLFFBQVEsQ0FBQztvQkFDL0QsQ0FBQyxDQUFDLFNBQVMsQ0FBQztnQkFDaEIsR0FBRyxDQUFDLEdBQUcsQ0FBQyxRQUFRLENBQUMsR0FBRyxJQUFJLENBQUMsYUFBYSxDQUFDLGdCQUFnQixDQUNuRCxjQUFjLENBQUMsR0FBRyxDQUFDLFFBQVEsQ0FBQyxFQUM1QixHQUFHLEVBQ0gsV0FBVyxDQUNkLENBQUM7Z0JBQ0YsT0FBTyxHQUFHLENBQUM7WUFDZixDQUFDLEVBQUUsRUFBNkIsQ0FBZSxDQUFDO1lBRWhELGFBQWEsQ0FBQyxJQUFJLENBQUM7Z0JBQ2YsRUFBRSxFQUFFLEtBQUs7Z0JBQ1QsT0FBTyxFQUFFLFNBQVM7Z0JBQ2xCLElBQUksRUFBRSxDQUFDLE9BQWdCLEVBQUUsRUFBRTtvQkFDdkIsSUFBSSxPQUFPLEVBQUUsQ0FBQzt3QkFDVixVQUFVLEVBQUUsQ0FBQztvQkFDakIsQ0FBQztnQkFDTCxDQUFDO2FBQ0osQ0FBQyxDQUFDO1FBQ1AsQ0FBQyxDQUFDO1FBRUYsTUFBTSxnQkFBZ0IsR0FBRyxDQUFDLGFBQXlCLEVBQVEsRUFBRTtZQUN6RCw2REFBNkQ7WUFDN0QsSUFBSSxDQUFDLFFBQVEsRUFBRSxJQUFJLE9BQU8sRUFBRSxLQUFLLElBQUksRUFBRSxDQUFDO2dCQUNwQyxPQUFPO1lBQ1gsQ0FBQztZQUVELG1DQUFtQztZQUNuQyxJQUFJLFFBQVEsRUFBRSxFQUFFLENBQUM7Z0JBQ2IsTUFBTSxVQUFVLEdBQUcsTUFBTSxFQUFFLENBQUM7Z0JBQzVCLElBQUksVUFBVSxFQUFFLENBQUM7b0JBQ2IsTUFBTSxVQUFVLEdBQUcsRUFBRSxHQUFHLFVBQVUsRUFBRSxHQUFHLGFBQWEsRUFBRSxDQUFDO29CQUN2RCxNQUFNLENBQUMsR0FBRyxDQUFDLFVBQVUsQ0FBQyxDQUFDO2dCQUMzQixDQUFDO1lBQ0wsQ0FBQztZQUVELGtDQUFrQztZQUNsQyxJQUFJLE9BQU8sRUFBRSxLQUFLLElBQUksRUFBRSxDQUFDO2dCQUNyQixNQUFNLGNBQWMsR0FBRyxPQUFPLEVBQUUsQ0FBQztnQkFDakMsSUFBSSxjQUFjLEVBQUUsQ0FBQztvQkFDakIsTUFBTSxjQUFjLEdBQUcsRUFBRSxHQUFHLGNBQWMsRUFBRSxHQUFHLGFBQWEsRUFBRSxDQUFDO29CQUMvRCxPQUFPLENBQUMsR0FBRyxDQUFDLGNBQWMsQ0FBQyxDQUFDO2dCQUNoQyxDQUFDO1lBQ0wsQ0FBQztRQUNMLENBQUMsQ0FBQztRQUVGLE9BQU87WUFDSCwwQkFBMEI7WUFDMUIsUUFBUSxFQUFFLFFBQVEsQ0FBQyxVQUFVLEVBQUU7WUFDL0IsTUFBTSxFQUFFLE1BQU0sQ0FBQyxVQUFVLEVBQUU7WUFDM0IsT0FBTyxFQUFFLE9BQU8sQ0FBQyxVQUFVLEVBQUU7WUFDN0IsT0FBTyxFQUFFLE9BQU8sQ0FBQyxVQUFVLEVBQUU7WUFFN0IsVUFBVTtZQUNWLFdBQVc7WUFDWCxZQUFZO1lBQ1osWUFBWTtZQUNaLFVBQVU7WUFDVixTQUFTO1lBQ1QsVUFBVTtZQUNWLGFBQWE7WUFDYixRQUFRO1lBQ1IsZ0JBQWdCO1NBQ25CLENBQUM7SUFDTixDQUFDO3dHQWpMUSxxQkFBcUI7NEdBQXJCLHFCQUFxQixjQUZsQixNQUFNOzs0RkFFVCxxQkFBcUI7a0JBSGpDLFVBQVU7bUJBQUM7b0JBQ1IsVUFBVSxFQUFFLE1BQU07aUJBQ3JCIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgSW5qZWN0YWJsZSwgc2lnbmFsLCBFdmVudEVtaXR0ZXIsIGluamVjdCB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgQzgwVGFibGVDb2xEZWYsIElEIH0gZnJvbSAnLi90YWJsZS50eXBlcyc7XG5pbXBvcnQgeyBUYWJsZUNvbHVtblZpc2liaWxpdHlTZXJ2aWNlIH0gZnJvbSAnLi90YWJsZS1jb2x1bW4tdmlzaWJpbGl0eS5zZXJ2aWNlJztcbmltcG9ydCB7IFRhYmxlRGF0YUNvbnZlcnRlclNlcnZpY2UgfSBmcm9tICcuL3RhYmxlLWRhdGEtY29udmVydGVyLnNlcnZpY2UnO1xuXG4vKipcbiAqIFNlcnZpY2lvIHBhcmEgZ2VzdGlvbmFyIGVsIGVzdGFkbyBDUlVEIChDcmVhciwgTGVlciwgQWN0dWFsaXphciwgRWxpbWluYXIpIGVuIHRhYmxhcyBDODBcbiAqXG4gKiBNYW5lamE6XG4gKiAtIEVzdGFkbyBkZSBjcmVhY2nDs24geSBlZGljacOzblxuICogLSBHZXN0acOzbiBkZSBkYXRvcyB0ZW1wb3JhbGVzIChuZXdSb3csIGVkaXRSb3cpXG4gKiAtIEFwbGljYWNpw7NuIGRlIHZhbG9yZXMgZGluw6FtaWNvc1xuICogLSBWYWxpZGFjacOzbiB5IGNvbnZlcnNpw7NuIGRlIGRhdG9zIGFudGVzIGRlIGVtaXNpw7NuIGRlIGV2ZW50b3NcbiAqL1xuQEluamVjdGFibGUoe1xuICAgIHByb3ZpZGVkSW46ICdyb290J1xufSlcbmV4cG9ydCBjbGFzcyBUYWJsZUNydWRTdGF0ZVNlcnZpY2Uge1xuXG4gICAgcHJpdmF0ZSByZWFkb25seSB2aXNpYmlsaXR5U2VydmljZSA9IGluamVjdChUYWJsZUNvbHVtblZpc2liaWxpdHlTZXJ2aWNlKTtcbiAgICBwcml2YXRlIHJlYWRvbmx5IGRhdGFDb252ZXJ0ZXIgPSBpbmplY3QoVGFibGVEYXRhQ29udmVydGVyU2VydmljZSk7XG5cbiAgICAvKipcbiAgICAgKiBJbmljaWFsaXphIGVsIGVzdGFkbyBDUlVEIHBhcmEgdW5hIG51ZXZhIHRhYmxhXG4gICAgICogQHJldHVybnMgT2JqZXRvIGNvbiBzaWduYWxzIHkgbcOpdG9kb3MgcGFyYSBnZXN0acOzbiBDUlVEXG4gICAgICovXG4gICAgY3JlYXRlQ3J1ZFN0YXRlPFQgZXh0ZW5kcyBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPj4oKSB7XG4gICAgICAgIGNvbnN0IGNyZWF0aW5nID0gc2lnbmFsKGZhbHNlKTtcbiAgICAgICAgY29uc3QgbmV3Um93ID0gc2lnbmFsPFBhcnRpYWw8VD4gfCBudWxsPihudWxsKTtcbiAgICAgICAgY29uc3QgZWRpdGluZyA9IHNpZ25hbDxJRCB8IG51bGw+KG51bGwpO1xuICAgICAgICBjb25zdCBlZGl0Um93ID0gc2lnbmFsPFBhcnRpYWw8VD4gfCBudWxsPihudWxsKTtcblxuICAgICAgICBjb25zdCBzdGFydENyZWF0ZSA9IChjb2x1bW5zOiBDODBUYWJsZUNvbERlZltdLCBkYXRhOiBUW10pOiB2b2lkID0+IHtcbiAgICAgICAgICAgIGNyZWF0aW5nLnNldCh0cnVlKTtcblxuICAgICAgICAgICAgLy8gSW5pY2lhbGl6YXIgbmV3Um93IHNvbG8gY29uIGNvbHVtbmFzIHZpc2libGVzIHkgbm8gcmVhZE9ubHlcbiAgICAgICAgICAgIC8vIEVuIG1vZG8gY3JlYWNpw7NuLCBtb3N0cmFtb3MgY29sdW1uYXMgY29uIGhpZGVJZkFsbFZhbHVlc0FyZU51bGwgcGFyYSBwZXJtaXRpciBlbnRyYWRhIGRlIGRhdG9zXG4gICAgICAgICAgICBjb25zdCByb3c6IFBhcnRpYWw8VD4gPSB7fTtcbiAgICAgICAgICAgIGNvbHVtbnNcbiAgICAgICAgICAgICAgICAuZmlsdGVyKChjb2wpID0+IHRoaXMudmlzaWJpbGl0eVNlcnZpY2UuaXNDb2x1bW5WaXNpYmxlKGNvbCwgZGF0YSwgdHJ1ZSkgJiYgIWNvbC5yZWFkT25seSlcbiAgICAgICAgICAgICAgICAuZm9yRWFjaCgoY29sKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIC8vIFNpIGxhIGNvbHVtbmEgdGllbmUgdW4gdmFsb3IgcG9yIGRlZmVjdG8sIHVzYXJsbzsgc2kgbm8sIHVzYXIgY2FkZW5hIHZhY8OtYVxuICAgICAgICAgICAgICAgICAgICBjb25zdCBkZWZhdWx0VmFsdWUgPSBjb2wuZGVmYXVsdCAhPT0gdW5kZWZpbmVkID8gY29sLmRlZmF1bHQgOiAnJztcbiAgICAgICAgICAgICAgICAgICAgKHJvdyBhcyBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPilbY29sLmFjY2Vzc29yXSA9IGRlZmF1bHRWYWx1ZTtcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIG5ld1Jvdy5zZXQocm93KTtcbiAgICAgICAgfTtcblxuICAgICAgICBjb25zdCBjYW5jZWxDcmVhdGUgPSAoKTogdm9pZCA9PiB7XG4gICAgICAgICAgICBjcmVhdGluZy5zZXQoZmFsc2UpO1xuICAgICAgICAgICAgbmV3Um93LnNldChudWxsKTtcbiAgICAgICAgfTtcblxuICAgICAgICBjb25zdCB1cGRhdGVOZXdSb3cgPSAoa2V5OiBzdHJpbmcsIHZhbHVlOiB1bmtub3duKTogdm9pZCA9PiB7XG4gICAgICAgICAgICBjb25zdCBjdXJyZW50ID0gbmV3Um93KCk7XG4gICAgICAgICAgICBpZiAoIWN1cnJlbnQpIHJldHVybjtcbiAgICAgICAgICAgIG5ld1Jvdy5zZXQoeyAuLi5jdXJyZW50LCBba2V5XTogdmFsdWUgfSk7XG4gICAgICAgIH07XG5cbiAgICAgICAgY29uc3Qgc2F2ZUNyZWF0ZSA9IChcbiAgICAgICAgICAgIGNvbHVtbnM6IEM4MFRhYmxlQ29sRGVmW10sXG4gICAgICAgICAgICBkYXRhOiBUW10sXG4gICAgICAgICAgICBjcmVhdGVFbWl0dGVyOiBFdmVudEVtaXR0ZXI8eyByb3c6IFBhcnRpYWw8VD47IGRvbmU6IChyZXN1bHQ6IGJvb2xlYW4pID0+IHZvaWQ7IH0+XG4gICAgICAgICk6IHZvaWQgPT4ge1xuICAgICAgICAgICAgY29uc3Qgcm93ID0gbmV3Um93KCk7XG4gICAgICAgICAgICBpZiAoIXJvdykgcmV0dXJuO1xuXG4gICAgICAgICAgICAvLyBWYWxpZGFyIGNhbXBvcyByZXF1ZXJpZG9zIGFudGVzIGRlIGNyZWFyIC0gc29sbyBjb2x1bW5hcyB2aXNpYmxlcyB5IG5vIHJlYWRPbmx5XG4gICAgICAgICAgICAvLyBFbiBtb2RvIGNyZWFjacOzbiwgaW5jbHVpbW9zIGNvbHVtbmFzIGNvbiBoaWRlSWZBbGxWYWx1ZXNBcmVOdWxsXG4gICAgICAgICAgICBjb25zdCB2aXNpYmxlQ29sdW1ucyA9IGNvbHVtbnMuZmlsdGVyKChjb2wpID0+XG4gICAgICAgICAgICAgICAgdGhpcy52aXNpYmlsaXR5U2VydmljZS5pc0NvbHVtblZpc2libGUoY29sLCBkYXRhLCB0cnVlKSAmJiAhY29sLnJlYWRPbmx5XG4gICAgICAgICAgICApO1xuXG4gICAgICAgICAgICBjb25zdCBjb252ZXJ0ZWQgPSB2aXNpYmxlQ29sdW1ucy5yZWR1Y2UoKGFjYywgY29sKSA9PiB7XG4gICAgICAgICAgICAgICAgY29uc3Qgc2FtcGxlVmFsdWUgPSBkYXRhLmxlbmd0aCA+IDBcbiAgICAgICAgICAgICAgICAgICAgPyB0aGlzLnZpc2liaWxpdHlTZXJ2aWNlWydnZXRDZWxsVmFsdWUnXShkYXRhWzBdLCBjb2wuYWNjZXNzb3IpXG4gICAgICAgICAgICAgICAgICAgIDogdW5kZWZpbmVkO1xuICAgICAgICAgICAgICAgIGFjY1tjb2wuYWNjZXNzb3JdID0gdGhpcy5kYXRhQ29udmVydGVyLmNvbnZlcnRDZWxsVmFsdWUocm93W2NvbC5hY2Nlc3Nvcl0sIGNvbCwgc2FtcGxlVmFsdWUpO1xuICAgICAgICAgICAgICAgIHJldHVybiBhY2M7XG4gICAgICAgICAgICB9LCB7fSBhcyBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPikgYXMgUGFydGlhbDxUPjtcblxuICAgICAgICAgICAgY3JlYXRlRW1pdHRlci5lbWl0KHtcbiAgICAgICAgICAgICAgICByb3c6IGNvbnZlcnRlZCxcbiAgICAgICAgICAgICAgICBkb25lOiAoc3VjY2VzczogYm9vbGVhbikgPT4ge1xuICAgICAgICAgICAgICAgICAgICBpZiAoc3VjY2Vzcykge1xuICAgICAgICAgICAgICAgICAgICAgICAgY2FuY2VsQ3JlYXRlKCk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH07XG5cbiAgICAgICAgY29uc3Qgc3RhcnRFZGl0ID0gKHJvdzogVCwgY29sdW1uczogQzgwVGFibGVDb2xEZWZbXSwgZGF0YTogVFtdKTogdm9pZCA9PiB7XG4gICAgICAgICAgICBlZGl0aW5nLnNldChyb3dbJ2lkJ10gYXMgSUQpO1xuXG4gICAgICAgICAgICBjb25zdCBlZGl0OiBQYXJ0aWFsPFQ+ID0ge307XG4gICAgICAgICAgICBjb2x1bW5zXG4gICAgICAgICAgICAgICAgLmZpbHRlcigoY29sKSA9PiB0aGlzLnZpc2liaWxpdHlTZXJ2aWNlLmlzQ29sdW1uVmlzaWJsZShjb2wsIGRhdGEsIHRydWUpICYmICFjb2wucmVhZE9ubHkpXG4gICAgICAgICAgICAgICAgLmZvckVhY2goKGNvbCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCB2YWx1ZSA9IHRoaXMudmlzaWJpbGl0eVNlcnZpY2VbJ2dldENlbGxWYWx1ZSddKHJvdywgY29sLmFjY2Vzc29yKTtcbiAgICAgICAgICAgICAgICAgICAgKGVkaXQgYXMgUmVjb3JkPHN0cmluZywgdW5rbm93bj4pW2NvbC5hY2Nlc3Nvcl0gPSB2YWx1ZTtcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIGVkaXRSb3cuc2V0KGVkaXQpO1xuICAgICAgICB9O1xuXG4gICAgICAgIGNvbnN0IGNhbmNlbEVkaXQgPSAoKTogdm9pZCA9PiB7XG4gICAgICAgICAgICBlZGl0aW5nLnNldChudWxsKTtcbiAgICAgICAgICAgIGVkaXRSb3cuc2V0KG51bGwpO1xuICAgICAgICB9O1xuXG4gICAgICAgIGNvbnN0IHVwZGF0ZUVkaXRSb3cgPSAoa2V5OiBzdHJpbmcsIHZhbHVlOiB1bmtub3duKTogdm9pZCA9PiB7XG4gICAgICAgICAgICBjb25zdCBjdXJyZW50ID0gZWRpdFJvdygpO1xuICAgICAgICAgICAgaWYgKCFjdXJyZW50KSByZXR1cm47XG4gICAgICAgICAgICBlZGl0Um93LnNldCh7IC4uLmN1cnJlbnQsIFtrZXldOiB2YWx1ZSB9KTtcbiAgICAgICAgfTtcblxuICAgICAgICBjb25zdCBzYXZlRWRpdCA9IChcbiAgICAgICAgICAgIHJvd0lkOiBJRCxcbiAgICAgICAgICAgIGNvbHVtbnM6IEM4MFRhYmxlQ29sRGVmW10sXG4gICAgICAgICAgICBkYXRhOiBUW10sXG4gICAgICAgICAgICB1cGRhdGVFbWl0dGVyOiBFdmVudEVtaXR0ZXI8eyBpZDogSUQ7IGNoYW5nZXM6IFBhcnRpYWw8VD47IGRvbmU6IChyZXN1bHQ6IGJvb2xlYW4pID0+IHZvaWQ7IH0+XG4gICAgICAgICk6IHZvaWQgPT4ge1xuICAgICAgICAgICAgY29uc3QgY3VycmVudEVkaXRSb3cgPSBlZGl0Um93KCk7XG4gICAgICAgICAgICBpZiAoIWN1cnJlbnRFZGl0Um93KSByZXR1cm47XG5cbiAgICAgICAgICAgIGNvbnN0IHZpc2libGVDb2x1bW5zID0gY29sdW1ucy5maWx0ZXIoXG4gICAgICAgICAgICAgICAgKGNvbCkgPT4gdGhpcy52aXNpYmlsaXR5U2VydmljZS5pc0NvbHVtblZpc2libGUoY29sLCBkYXRhLCB0cnVlKSAmJiAhY29sLnJlYWRPbmx5XG4gICAgICAgICAgICApO1xuXG4gICAgICAgICAgICBjb25zdCBjb252ZXJ0ZWQgPSB2aXNpYmxlQ29sdW1ucy5yZWR1Y2UoKGFjYywgY29sKSA9PiB7XG4gICAgICAgICAgICAgICAgY29uc3Qgc2FtcGxlVmFsdWUgPSBkYXRhLmxlbmd0aCA+IDBcbiAgICAgICAgICAgICAgICAgICAgPyB0aGlzLnZpc2liaWxpdHlTZXJ2aWNlWydnZXRDZWxsVmFsdWUnXShkYXRhWzBdLCBjb2wuYWNjZXNzb3IpXG4gICAgICAgICAgICAgICAgICAgIDogdW5kZWZpbmVkO1xuICAgICAgICAgICAgICAgIGFjY1tjb2wuYWNjZXNzb3JdID0gdGhpcy5kYXRhQ29udmVydGVyLmNvbnZlcnRDZWxsVmFsdWUoXG4gICAgICAgICAgICAgICAgICAgIGN1cnJlbnRFZGl0Um93W2NvbC5hY2Nlc3Nvcl0sXG4gICAgICAgICAgICAgICAgICAgIGNvbCxcbiAgICAgICAgICAgICAgICAgICAgc2FtcGxlVmFsdWVcbiAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgIHJldHVybiBhY2M7XG4gICAgICAgICAgICB9LCB7fSBhcyBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPikgYXMgUGFydGlhbDxUPjtcblxuICAgICAgICAgICAgdXBkYXRlRW1pdHRlci5lbWl0KHtcbiAgICAgICAgICAgICAgICBpZDogcm93SWQsXG4gICAgICAgICAgICAgICAgY2hhbmdlczogY29udmVydGVkLFxuICAgICAgICAgICAgICAgIGRvbmU6IChzdWNjZXNzOiBib29sZWFuKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChzdWNjZXNzKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjYW5jZWxFZGl0KCk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH07XG5cbiAgICAgICAgY29uc3QgYXBwbHlJbnB1dFZhbHVlcyA9IChwYXJ0aWFsVmFsdWVzOiBQYXJ0aWFsPFQ+KTogdm9pZCA9PiB7XG4gICAgICAgICAgICAvLyBTb2xvIGFwbGljYXIgdmFsb3JlcyBzaSBlc3RhbW9zIGVuIG1vZG8gY3JlYWNpw7NuIG8gZWRpY2nDs25cbiAgICAgICAgICAgIGlmICghY3JlYXRpbmcoKSAmJiBlZGl0aW5nKCkgPT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8vIEFwbGljYXIgdmFsb3JlcyBlbiBtb2RvIGNyZWFjacOzblxuICAgICAgICAgICAgaWYgKGNyZWF0aW5nKCkpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBjdXJyZW50Um93ID0gbmV3Um93KCk7XG4gICAgICAgICAgICAgICAgaWYgKGN1cnJlbnRSb3cpIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgdXBkYXRlZFJvdyA9IHsgLi4uY3VycmVudFJvdywgLi4ucGFydGlhbFZhbHVlcyB9O1xuICAgICAgICAgICAgICAgICAgICBuZXdSb3cuc2V0KHVwZGF0ZWRSb3cpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgLy8gQXBsaWNhciB2YWxvcmVzIGVuIG1vZG8gZWRpY2nDs25cbiAgICAgICAgICAgIGlmIChlZGl0aW5nKCkgIT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBjdXJyZW50RWRpdFJvdyA9IGVkaXRSb3coKTtcbiAgICAgICAgICAgICAgICBpZiAoY3VycmVudEVkaXRSb3cpIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgdXBkYXRlZEVkaXRSb3cgPSB7IC4uLmN1cnJlbnRFZGl0Um93LCAuLi5wYXJ0aWFsVmFsdWVzIH07XG4gICAgICAgICAgICAgICAgICAgIGVkaXRSb3cuc2V0KHVwZGF0ZWRFZGl0Um93KTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH07XG5cbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIC8vIFNpZ25hbHMgZGUgc29sbyBsZWN0dXJhXG4gICAgICAgICAgICBjcmVhdGluZzogY3JlYXRpbmcuYXNSZWFkb25seSgpLFxuICAgICAgICAgICAgbmV3Um93OiBuZXdSb3cuYXNSZWFkb25seSgpLFxuICAgICAgICAgICAgZWRpdGluZzogZWRpdGluZy5hc1JlYWRvbmx5KCksXG4gICAgICAgICAgICBlZGl0Um93OiBlZGl0Um93LmFzUmVhZG9ubHkoKSxcblxuICAgICAgICAgICAgLy8gTcOpdG9kb3NcbiAgICAgICAgICAgIHN0YXJ0Q3JlYXRlLFxuICAgICAgICAgICAgY2FuY2VsQ3JlYXRlLFxuICAgICAgICAgICAgdXBkYXRlTmV3Um93LFxuICAgICAgICAgICAgc2F2ZUNyZWF0ZSxcbiAgICAgICAgICAgIHN0YXJ0RWRpdCxcbiAgICAgICAgICAgIGNhbmNlbEVkaXQsXG4gICAgICAgICAgICB1cGRhdGVFZGl0Um93LFxuICAgICAgICAgICAgc2F2ZUVkaXQsXG4gICAgICAgICAgICBhcHBseUlucHV0VmFsdWVzLFxuICAgICAgICB9O1xuICAgIH1cbn1cbiJdfQ==
|