valtech-components 4.0.938 → 4.0.940

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.
@@ -0,0 +1,97 @@
1
+ import { CommonModule } from '@angular/common';
2
+ import { Component, EventEmitter, Input, Output, inject } from '@angular/core';
3
+ import { IonSelect, IonSelectOption } from '@ionic/angular/standalone';
4
+ import { GroupsService } from '../../../services/groups/groups.service';
5
+ import * as i0 from "@angular/core";
6
+ /**
7
+ * val-group-picker — elegir el grupo dueño de un recurso (ADR-083).
8
+ *
9
+ * Se auto-carga: pide sus propios grupos a `GroupsService` en vez de esperar
10
+ * que el consumer se los pase. Es la razón por la que existe como componente y
11
+ * no como un `<select>` armado a mano en cada app — "una línea, una etiqueta
12
+ * i18n" (ver ADR-083 §"Qué se construye una sola vez").
13
+ *
14
+ * Sin texto hardcodeado: los labels llegan por `@Input` (lib i18n-agnostic).
15
+ * Cada app pone su palabra ("Equipo", "Sucursal", "Refugio").
16
+ */
17
+ export class GroupPickerComponent {
18
+ constructor() {
19
+ this.label = '';
20
+ this.placeholder = '';
21
+ this.noGroupLabel = '';
22
+ this.value = null;
23
+ this.disabled = false;
24
+ this.valueChange = new EventEmitter();
25
+ this.groupsSvc = inject(GroupsService);
26
+ this.groups = [];
27
+ }
28
+ ngOnInit() {
29
+ this.groupsSvc.listGroups().subscribe({
30
+ next: (g) => (this.groups = g),
31
+ // Best-effort: si la lectura falla, el picker queda con la opción "sin
32
+ // grupo" únicamente. No es un error bloqueante — crear el recurso sin
33
+ // asignar sigue siendo válido.
34
+ error: () => (this.groups = []),
35
+ });
36
+ }
37
+ onChange(v) {
38
+ this.value = v || null;
39
+ this.valueChange.emit(this.value);
40
+ }
41
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: GroupPickerComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
42
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.14", type: GroupPickerComponent, isStandalone: true, selector: "val-group-picker", inputs: { label: "label", placeholder: "placeholder", noGroupLabel: "noGroupLabel", value: "value", disabled: "disabled" }, outputs: { valueChange: "valueChange" }, ngImport: i0, template: `
43
+ <ion-select
44
+ [label]="label"
45
+ [placeholder]="placeholder"
46
+ [value]="value ?? ''"
47
+ [disabled]="disabled"
48
+ interface="popover"
49
+ (ionChange)="onChange($event.detail.value)"
50
+ >
51
+ <!-- Opción vacía SIEMPRE disponible: un recurso sin grupo es visible para
52
+ toda la organización (ADR-083, decisión 3), no un estado inválido. -->
53
+ <ion-select-option value="">{{ noGroupLabel }}</ion-select-option>
54
+ @for (g of groups; track g.id) {
55
+ <ion-select-option [value]="g.id">{{ g.name }}</ion-select-option>
56
+ }
57
+ </ion-select>
58
+ `, isInline: true, dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "component", type: IonSelect, selector: "ion-select", inputs: ["cancelText", "color", "compareWith", "disabled", "errorText", "expandedIcon", "fill", "helperText", "interface", "interfaceOptions", "justify", "label", "labelPlacement", "mode", "multiple", "name", "okText", "placeholder", "selectedText", "shape", "toggleIcon", "value"] }, { kind: "component", type: IonSelectOption, selector: "ion-select-option", inputs: ["disabled", "value"] }] }); }
59
+ }
60
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: GroupPickerComponent, decorators: [{
61
+ type: Component,
62
+ args: [{
63
+ selector: 'val-group-picker',
64
+ standalone: true,
65
+ imports: [CommonModule, IonSelect, IonSelectOption],
66
+ template: `
67
+ <ion-select
68
+ [label]="label"
69
+ [placeholder]="placeholder"
70
+ [value]="value ?? ''"
71
+ [disabled]="disabled"
72
+ interface="popover"
73
+ (ionChange)="onChange($event.detail.value)"
74
+ >
75
+ <!-- Opción vacía SIEMPRE disponible: un recurso sin grupo es visible para
76
+ toda la organización (ADR-083, decisión 3), no un estado inválido. -->
77
+ <ion-select-option value="">{{ noGroupLabel }}</ion-select-option>
78
+ @for (g of groups; track g.id) {
79
+ <ion-select-option [value]="g.id">{{ g.name }}</ion-select-option>
80
+ }
81
+ </ion-select>
82
+ `,
83
+ }]
84
+ }], propDecorators: { label: [{
85
+ type: Input
86
+ }], placeholder: [{
87
+ type: Input
88
+ }], noGroupLabel: [{
89
+ type: Input
90
+ }], value: [{
91
+ type: Input
92
+ }], disabled: [{
93
+ type: Input
94
+ }], valueChange: [{
95
+ type: Output
96
+ }] } });
97
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZ3JvdXAtcGlja2VyLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uLy4uL3NyYy9saWIvY29tcG9uZW50cy9tb2xlY3VsZXMvZ3JvdXAtcGlja2VyL2dyb3VwLXBpY2tlci5jb21wb25lbnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBQy9DLE9BQU8sRUFBRSxTQUFTLEVBQUUsWUFBWSxFQUFFLEtBQUssRUFBVSxNQUFNLEVBQUUsTUFBTSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQ3ZGLE9BQU8sRUFBRSxTQUFTLEVBQUUsZUFBZSxFQUFFLE1BQU0sMkJBQTJCLENBQUM7QUFDdkUsT0FBTyxFQUFFLGFBQWEsRUFBRSxNQUFNLHlDQUF5QyxDQUFDOztBQUd4RTs7Ozs7Ozs7OztHQVVHO0FBdUJILE1BQU0sT0FBTyxvQkFBb0I7SUF0QmpDO1FBdUJXLFVBQUssR0FBRyxFQUFFLENBQUM7UUFDWCxnQkFBVyxHQUFHLEVBQUUsQ0FBQztRQUNqQixpQkFBWSxHQUFHLEVBQUUsQ0FBQztRQUNsQixVQUFLLEdBQWtCLElBQUksQ0FBQztRQUM1QixhQUFRLEdBQUcsS0FBSyxDQUFDO1FBQ2hCLGdCQUFXLEdBQUcsSUFBSSxZQUFZLEVBQWlCLENBQUM7UUFFekMsY0FBUyxHQUFHLE1BQU0sQ0FBQyxhQUFhLENBQUMsQ0FBQztRQUNuRCxXQUFNLEdBQWUsRUFBRSxDQUFDO0tBZ0J6QjtJQWRDLFFBQVE7UUFDTixJQUFJLENBQUMsU0FBUyxDQUFDLFVBQVUsRUFBRSxDQUFDLFNBQVMsQ0FBQztZQUNwQyxJQUFJLEVBQUUsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUMsSUFBSSxDQUFDLE1BQU0sR0FBRyxDQUFDLENBQUM7WUFDOUIsdUVBQXVFO1lBQ3ZFLHNFQUFzRTtZQUN0RSwrQkFBK0I7WUFDL0IsS0FBSyxFQUFFLEdBQUcsRUFBRSxDQUFDLENBQUMsSUFBSSxDQUFDLE1BQU0sR0FBRyxFQUFFLENBQUM7U0FDaEMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQztJQUVELFFBQVEsQ0FBQyxDQUFTO1FBQ2hCLElBQUksQ0FBQyxLQUFLLEdBQUcsQ0FBQyxJQUFJLElBQUksQ0FBQztRQUN2QixJQUFJLENBQUMsV0FBVyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUM7SUFDcEMsQ0FBQzsrR0F4QlUsb0JBQW9CO21HQUFwQixvQkFBb0IsaVBBbEJyQjs7Ozs7Ozs7Ozs7Ozs7OztHQWdCVCwyREFqQlMsWUFBWSwrQkFBRSxTQUFTLGtWQUFFLGVBQWU7OzRGQW1CdkMsb0JBQW9CO2tCQXRCaEMsU0FBUzttQkFBQztvQkFDVCxRQUFRLEVBQUUsa0JBQWtCO29CQUM1QixVQUFVLEVBQUUsSUFBSTtvQkFDaEIsT0FBTyxFQUFFLENBQUMsWUFBWSxFQUFFLFNBQVMsRUFBRSxlQUFlLENBQUM7b0JBQ25ELFFBQVEsRUFBRTs7Ozs7Ozs7Ozs7Ozs7OztHQWdCVDtpQkFDRjs4QkFFVSxLQUFLO3NCQUFiLEtBQUs7Z0JBQ0csV0FBVztzQkFBbkIsS0FBSztnQkFDRyxZQUFZO3NCQUFwQixLQUFLO2dCQUNHLEtBQUs7c0JBQWIsS0FBSztnQkFDRyxRQUFRO3NCQUFoQixLQUFLO2dCQUNJLFdBQVc7c0JBQXBCLE1BQU0iLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBDb21tb25Nb2R1bGUgfSBmcm9tICdAYW5ndWxhci9jb21tb24nO1xuaW1wb3J0IHsgQ29tcG9uZW50LCBFdmVudEVtaXR0ZXIsIElucHV0LCBPbkluaXQsIE91dHB1dCwgaW5qZWN0IH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBJb25TZWxlY3QsIElvblNlbGVjdE9wdGlvbiB9IGZyb20gJ0Bpb25pYy9hbmd1bGFyL3N0YW5kYWxvbmUnO1xuaW1wb3J0IHsgR3JvdXBzU2VydmljZSB9IGZyb20gJy4uLy4uLy4uL3NlcnZpY2VzL2dyb3Vwcy9ncm91cHMuc2VydmljZSc7XG5pbXBvcnQgeyBWYWxHcm91cCB9IGZyb20gJy4uLy4uLy4uL3NlcnZpY2VzL2dyb3Vwcy90eXBlcyc7XG5cbi8qKlxuICogdmFsLWdyb3VwLXBpY2tlciDigJQgZWxlZ2lyIGVsIGdydXBvIGR1ZcOxbyBkZSB1biByZWN1cnNvIChBRFItMDgzKS5cbiAqXG4gKiBTZSBhdXRvLWNhcmdhOiBwaWRlIHN1cyBwcm9waW9zIGdydXBvcyBhIGBHcm91cHNTZXJ2aWNlYCBlbiB2ZXogZGUgZXNwZXJhclxuICogcXVlIGVsIGNvbnN1bWVyIHNlIGxvcyBwYXNlLiBFcyBsYSByYXrDs24gcG9yIGxhIHF1ZSBleGlzdGUgY29tbyBjb21wb25lbnRlIHlcbiAqIG5vIGNvbW8gdW4gYDxzZWxlY3Q+YCBhcm1hZG8gYSBtYW5vIGVuIGNhZGEgYXBwIOKAlCBcInVuYSBsw61uZWEsIHVuYSBldGlxdWV0YVxuICogaTE4blwiICh2ZXIgQURSLTA4MyDCp1wiUXXDqSBzZSBjb25zdHJ1eWUgdW5hIHNvbGEgdmV6XCIpLlxuICpcbiAqIFNpbiB0ZXh0byBoYXJkY29kZWFkbzogbG9zIGxhYmVscyBsbGVnYW4gcG9yIGBASW5wdXRgIChsaWIgaTE4bi1hZ25vc3RpYykuXG4gKiBDYWRhIGFwcCBwb25lIHN1IHBhbGFicmEgKFwiRXF1aXBvXCIsIFwiU3VjdXJzYWxcIiwgXCJSZWZ1Z2lvXCIpLlxuICovXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICd2YWwtZ3JvdXAtcGlja2VyJyxcbiAgc3RhbmRhbG9uZTogdHJ1ZSxcbiAgaW1wb3J0czogW0NvbW1vbk1vZHVsZSwgSW9uU2VsZWN0LCBJb25TZWxlY3RPcHRpb25dLFxuICB0ZW1wbGF0ZTogYFxuICAgIDxpb24tc2VsZWN0XG4gICAgICBbbGFiZWxdPVwibGFiZWxcIlxuICAgICAgW3BsYWNlaG9sZGVyXT1cInBsYWNlaG9sZGVyXCJcbiAgICAgIFt2YWx1ZV09XCJ2YWx1ZSA/PyAnJ1wiXG4gICAgICBbZGlzYWJsZWRdPVwiZGlzYWJsZWRcIlxuICAgICAgaW50ZXJmYWNlPVwicG9wb3ZlclwiXG4gICAgICAoaW9uQ2hhbmdlKT1cIm9uQ2hhbmdlKCRldmVudC5kZXRhaWwudmFsdWUpXCJcbiAgICA+XG4gICAgICA8IS0tIE9wY2nDs24gdmFjw61hIFNJRU1QUkUgZGlzcG9uaWJsZTogdW4gcmVjdXJzbyBzaW4gZ3J1cG8gZXMgdmlzaWJsZSBwYXJhXG4gICAgICAgICAgIHRvZGEgbGEgb3JnYW5pemFjacOzbiAoQURSLTA4MywgZGVjaXNpw7NuIDMpLCBubyB1biBlc3RhZG8gaW52w6FsaWRvLiAtLT5cbiAgICAgIDxpb24tc2VsZWN0LW9wdGlvbiB2YWx1ZT1cIlwiPnt7IG5vR3JvdXBMYWJlbCB9fTwvaW9uLXNlbGVjdC1vcHRpb24+XG4gICAgICBAZm9yIChnIG9mIGdyb3VwczsgdHJhY2sgZy5pZCkge1xuICAgICAgICA8aW9uLXNlbGVjdC1vcHRpb24gW3ZhbHVlXT1cImcuaWRcIj57eyBnLm5hbWUgfX08L2lvbi1zZWxlY3Qtb3B0aW9uPlxuICAgICAgfVxuICAgIDwvaW9uLXNlbGVjdD5cbiAgYCxcbn0pXG5leHBvcnQgY2xhc3MgR3JvdXBQaWNrZXJDb21wb25lbnQgaW1wbGVtZW50cyBPbkluaXQge1xuICBASW5wdXQoKSBsYWJlbCA9ICcnO1xuICBASW5wdXQoKSBwbGFjZWhvbGRlciA9ICcnO1xuICBASW5wdXQoKSBub0dyb3VwTGFiZWwgPSAnJztcbiAgQElucHV0KCkgdmFsdWU6IHN0cmluZyB8IG51bGwgPSBudWxsO1xuICBASW5wdXQoKSBkaXNhYmxlZCA9IGZhbHNlO1xuICBAT3V0cHV0KCkgdmFsdWVDaGFuZ2UgPSBuZXcgRXZlbnRFbWl0dGVyPHN0cmluZyB8IG51bGw+KCk7XG5cbiAgcHJpdmF0ZSByZWFkb25seSBncm91cHNTdmMgPSBpbmplY3QoR3JvdXBzU2VydmljZSk7XG4gIGdyb3VwczogVmFsR3JvdXBbXSA9IFtdO1xuXG4gIG5nT25Jbml0KCk6IHZvaWQge1xuICAgIHRoaXMuZ3JvdXBzU3ZjLmxpc3RHcm91cHMoKS5zdWJzY3JpYmUoe1xuICAgICAgbmV4dDogKGcpID0+ICh0aGlzLmdyb3VwcyA9IGcpLFxuICAgICAgLy8gQmVzdC1lZmZvcnQ6IHNpIGxhIGxlY3R1cmEgZmFsbGEsIGVsIHBpY2tlciBxdWVkYSBjb24gbGEgb3BjacOzbiBcInNpblxuICAgICAgLy8gZ3J1cG9cIiDDum5pY2FtZW50ZS4gTm8gZXMgdW4gZXJyb3IgYmxvcXVlYW50ZSDigJQgY3JlYXIgZWwgcmVjdXJzbyBzaW5cbiAgICAgIC8vIGFzaWduYXIgc2lndWUgc2llbmRvIHbDoWxpZG8uXG4gICAgICBlcnJvcjogKCkgPT4gKHRoaXMuZ3JvdXBzID0gW10pLFxuICAgIH0pO1xuICB9XG5cbiAgb25DaGFuZ2Uodjogc3RyaW5nKTogdm9pZCB7XG4gICAgdGhpcy52YWx1ZSA9IHYgfHwgbnVsbDtcbiAgICB0aGlzLnZhbHVlQ2hhbmdlLmVtaXQodGhpcy52YWx1ZSk7XG4gIH1cbn1cbiJdfQ==
@@ -0,0 +1,178 @@
1
+ import { CommonModule } from '@angular/common';
2
+ import { Component, EventEmitter, Input, Output, inject } from '@angular/core';
3
+ import { IonIcon, IonSelect, IonSelectOption } from '@ionic/angular/standalone';
4
+ import { ButtonComponent } from '../../atoms/button/button.component';
5
+ import { ComponentStates } from '../../types';
6
+ import { GroupsService } from '../../../services/groups/groups.service';
7
+ import * as i0 from "@angular/core";
8
+ /**
9
+ * val-group-members — administrar la membresía de UN grupo (ADR-083).
10
+ *
11
+ * Deliberadamente NO trae su propio selector de personas: la fuente de
12
+ * "quiénes son los miembros elegibles de la organización" varía por app (org
13
+ * members, invitados, etc.), así que se recibe por `@Input candidates` en vez
14
+ * de que este organismo importe un servicio de organización que no le
15
+ * corresponde. Sin candidatos, igual funciona: solo lista y quita.
16
+ *
17
+ * Sin texto hardcodeado (lib i18n-agnostic): los labels llegan por `@Input`.
18
+ */
19
+ export class GroupMembersComponent {
20
+ constructor() {
21
+ /** Personas elegibles para agregar. Vacío = el organismo solo lista/quita. */
22
+ this.candidates = [];
23
+ this.addPlaceholder = '';
24
+ this.emptyLabel = '';
25
+ this.removeLabel = '';
26
+ this.membersChange = new EventEmitter();
27
+ this.groupsSvc = inject(GroupsService);
28
+ this.members = [];
29
+ this.busy = false;
30
+ }
31
+ get removeButtonProps() {
32
+ return {
33
+ text: this.removeLabel,
34
+ color: 'dark',
35
+ fill: 'clear',
36
+ size: 'small',
37
+ shape: 'round',
38
+ type: 'button',
39
+ state: this.busy ? ComponentStates.DISABLED : ComponentStates.ENABLED,
40
+ };
41
+ }
42
+ ngOnChanges(changes) {
43
+ if (changes['groupId'] && this.groupId) {
44
+ this.reload();
45
+ }
46
+ }
47
+ reload() {
48
+ this.groupsSvc.listMembers(this.groupId).subscribe({
49
+ next: (m) => (this.members = m),
50
+ error: () => (this.members = []),
51
+ });
52
+ }
53
+ /** Candidatos que todavía no están en el grupo — evita ofrecer un alta duplicada. */
54
+ eligible() {
55
+ const current = new Set(this.members.map((m) => m.userId));
56
+ return this.candidates.filter((c) => !current.has(c.userId));
57
+ }
58
+ nameFor(userId) {
59
+ const c = this.candidates.find((x) => x.userId === userId);
60
+ return c?.name || c?.email || userId;
61
+ }
62
+ add(userId) {
63
+ if (!userId || this.busy)
64
+ return;
65
+ this.busy = true;
66
+ this.groupsSvc.addMember(this.groupId, { userId }).subscribe({
67
+ next: (members) => {
68
+ this.members = members;
69
+ this.busy = false;
70
+ this.membersChange.emit(members);
71
+ },
72
+ error: () => (this.busy = false),
73
+ });
74
+ }
75
+ remove(userId) {
76
+ if (this.busy)
77
+ return;
78
+ this.busy = true;
79
+ this.groupsSvc.removeMember(this.groupId, userId).subscribe({
80
+ next: (members) => {
81
+ this.members = members;
82
+ this.busy = false;
83
+ this.membersChange.emit(members);
84
+ },
85
+ error: () => (this.busy = false),
86
+ });
87
+ }
88
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: GroupMembersComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
89
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.14", type: GroupMembersComponent, isStandalone: true, selector: "val-group-members", inputs: { groupId: "groupId", candidates: "candidates", addPlaceholder: "addPlaceholder", emptyLabel: "emptyLabel", removeLabel: "removeLabel" }, outputs: { membersChange: "membersChange" }, usesOnChanges: true, ngImport: i0, template: `
90
+ <div class="group-members">
91
+ @if (candidates.length > 0) {
92
+ <div class="group-members__add">
93
+ <ion-select
94
+ [placeholder]="addPlaceholder"
95
+ interface="popover"
96
+ [disabled]="busy"
97
+ (ionChange)="add($event.detail.value)"
98
+ >
99
+ @for (c of eligible(); track c.userId) {
100
+ <ion-select-option [value]="c.userId">
101
+ {{ c.name || c.email || c.userId }}
102
+ </ion-select-option>
103
+ }
104
+ </ion-select>
105
+ </div>
106
+ }
107
+
108
+ @if (members.length === 0) {
109
+ <p class="group-members__empty">{{ emptyLabel }}</p>
110
+ } @else {
111
+ <ul class="group-members__list">
112
+ @for (m of members; track m.userId) {
113
+ <li class="group-members__row">
114
+ <span class="group-members__name">{{ nameFor(m.userId) }}</span>
115
+ <val-button
116
+ [props]="removeButtonProps"
117
+ (onClick)="remove(m.userId)"
118
+ />
119
+ </li>
120
+ }
121
+ </ul>
122
+ }
123
+ </div>
124
+ `, isInline: true, styles: [".group-members{display:flex;flex-direction:column;gap:12px}.group-members__empty{font-size:.875rem;color:var(--ion-color-medium, #92949c);margin:0}.group-members__list{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:4px}.group-members__row{display:flex;align-items:center;justify-content:space-between;padding:8px 12px;border-radius:10px;background:var(--ion-color-light, #f4f5f8)}.group-members__name{font-size:.9375rem;color:var(--ion-text-color, #000)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "component", type: IonSelect, selector: "ion-select", inputs: ["cancelText", "color", "compareWith", "disabled", "errorText", "expandedIcon", "fill", "helperText", "interface", "interfaceOptions", "justify", "label", "labelPlacement", "mode", "multiple", "name", "okText", "placeholder", "selectedText", "shape", "toggleIcon", "value"] }, { kind: "component", type: IonSelectOption, selector: "ion-select-option", inputs: ["disabled", "value"] }, { kind: "component", type: ButtonComponent, selector: "val-button", inputs: ["preset", "props"], outputs: ["onClick"] }] }); }
125
+ }
126
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: GroupMembersComponent, decorators: [{
127
+ type: Component,
128
+ args: [{ selector: 'val-group-members', standalone: true, imports: [CommonModule, IonIcon, IonSelect, IonSelectOption, ButtonComponent], template: `
129
+ <div class="group-members">
130
+ @if (candidates.length > 0) {
131
+ <div class="group-members__add">
132
+ <ion-select
133
+ [placeholder]="addPlaceholder"
134
+ interface="popover"
135
+ [disabled]="busy"
136
+ (ionChange)="add($event.detail.value)"
137
+ >
138
+ @for (c of eligible(); track c.userId) {
139
+ <ion-select-option [value]="c.userId">
140
+ {{ c.name || c.email || c.userId }}
141
+ </ion-select-option>
142
+ }
143
+ </ion-select>
144
+ </div>
145
+ }
146
+
147
+ @if (members.length === 0) {
148
+ <p class="group-members__empty">{{ emptyLabel }}</p>
149
+ } @else {
150
+ <ul class="group-members__list">
151
+ @for (m of members; track m.userId) {
152
+ <li class="group-members__row">
153
+ <span class="group-members__name">{{ nameFor(m.userId) }}</span>
154
+ <val-button
155
+ [props]="removeButtonProps"
156
+ (onClick)="remove(m.userId)"
157
+ />
158
+ </li>
159
+ }
160
+ </ul>
161
+ }
162
+ </div>
163
+ `, styles: [".group-members{display:flex;flex-direction:column;gap:12px}.group-members__empty{font-size:.875rem;color:var(--ion-color-medium, #92949c);margin:0}.group-members__list{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:4px}.group-members__row{display:flex;align-items:center;justify-content:space-between;padding:8px 12px;border-radius:10px;background:var(--ion-color-light, #f4f5f8)}.group-members__name{font-size:.9375rem;color:var(--ion-text-color, #000)}\n"] }]
164
+ }], propDecorators: { groupId: [{
165
+ type: Input,
166
+ args: [{ required: true }]
167
+ }], candidates: [{
168
+ type: Input
169
+ }], addPlaceholder: [{
170
+ type: Input
171
+ }], emptyLabel: [{
172
+ type: Input
173
+ }], removeLabel: [{
174
+ type: Input
175
+ }], membersChange: [{
176
+ type: Output
177
+ }] } });
178
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZ3JvdXAtbWVtYmVycy5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi9zcmMvbGliL2NvbXBvbmVudHMvb3JnYW5pc21zL2dyb3VwLW1lbWJlcnMvZ3JvdXAtbWVtYmVycy5jb21wb25lbnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBQy9DLE9BQU8sRUFBRSxTQUFTLEVBQUUsWUFBWSxFQUFFLEtBQUssRUFBYSxNQUFNLEVBQWlCLE1BQU0sRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUN6RyxPQUFPLEVBQUUsT0FBTyxFQUFFLFNBQVMsRUFBRSxlQUFlLEVBQUUsTUFBTSwyQkFBMkIsQ0FBQztBQUNoRixPQUFPLEVBQUUsZUFBZSxFQUFFLE1BQU0scUNBQXFDLENBQUM7QUFDdEUsT0FBTyxFQUFFLGVBQWUsRUFBa0IsTUFBTSxhQUFhLENBQUM7QUFDOUQsT0FBTyxFQUFFLGFBQWEsRUFBRSxNQUFNLHlDQUF5QyxDQUFDOztBQVV4RTs7Ozs7Ozs7OztHQVVHO0FBMkNILE1BQU0sT0FBTyxxQkFBcUI7SUExQ2xDO1FBNENFLDhFQUE4RTtRQUNyRSxlQUFVLEdBQTJCLEVBQUUsQ0FBQztRQUN4QyxtQkFBYyxHQUFHLEVBQUUsQ0FBQztRQUNwQixlQUFVLEdBQUcsRUFBRSxDQUFDO1FBQ2hCLGdCQUFXLEdBQUcsRUFBRSxDQUFDO1FBQ2hCLGtCQUFhLEdBQUcsSUFBSSxZQUFZLEVBQW9CLENBQUM7UUFFOUMsY0FBUyxHQUFHLE1BQU0sQ0FBQyxhQUFhLENBQUMsQ0FBQztRQUNuRCxZQUFPLEdBQXFCLEVBQUUsQ0FBQztRQUMvQixTQUFJLEdBQUcsS0FBSyxDQUFDO0tBK0RkO0lBN0RDLElBQUksaUJBQWlCO1FBQ25CLE9BQU87WUFDTCxJQUFJLEVBQUUsSUFBSSxDQUFDLFdBQVc7WUFDdEIsS0FBSyxFQUFFLE1BQU07WUFD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SUFBSSxDQUFDLGFBQWEsQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLENBQUM7WUFDbkMsQ0FBQztZQUNELEtBQUssRUFBRSxHQUFHLEVBQUUsQ0FBQyxDQUFDLElBQUksQ0FBQyxJQUFJLEdBQUcsS0FBSyxDQUFDO1NBQ2pDLENBQUMsQ0FBQztJQUNMLENBQUM7K0dBekVVLHFCQUFxQjttR0FBckIscUJBQXFCLGlTQXRDdEI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBbUNULDRpQkFwQ1MsWUFBWSwrQkFBVyxTQUFTLGtWQUFFLGVBQWUsNkZBQUUsZUFBZTs7NEZBdUNqRSxxQkFBcUI7a0JBMUNqQyxTQUFTOytCQUNFLG1CQUFtQixjQUNqQixJQUFJLFdBQ1AsQ0FBQyxZQUFZLEVBQUUsT0FBTyxFQUFFLFNBQVMsRUFBRSxlQUFlLEVBQUUsZUFBZSxDQUFDLFlBQ25FOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQW1DVDs4QkFJMEIsT0FBTztzQkFBakMsS0FBSzt1QkFBQyxFQUFFLFFBQVEsRUFBRSxJQUFJLEVBQUU7Z0JBRWhCLFVBQVU7c0JBQWxCLEtBQUs7Z0JBQ0csY0FBYztzQkFBdEIsS0FBSztnQkFDRyxVQUFVO3NCQUFsQixLQUFLO2dCQUNHLFdBQVc7c0JBQW5CLEtBQUs7Z0JBQ0ksYUFBYTtzQkFBdEIsTUFBTSIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IENvbW1vbk1vZHVsZSB9IGZyb20gJ0Bhbmd1bGFyL2NvbW1vbic7XG5pbXBvcnQgeyBDb21wb25lbnQsIEV2ZW50RW1pdHRlciwgSW5wdXQsIE9uQ2hhbmdlcywgT3V0cHV0LCBTaW1wbGVDaGFuZ2VzLCBpbmplY3QgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IElvbkljb24sIElvblNlbGVjdCwgSW9uU2VsZWN0T3B0aW9uIH0gZnJvbSAnQGlvbmljL2FuZ3VsYXIvc3RhbmRhbG9uZSc7XG5pbXBvcnQgeyBCdXR0b25Db21wb25lbnQgfSBmcm9tICcuLi8uLi9hdG9tcy9idXR0b24vYnV0dG9uLmNvbXBvbmVudCc7XG5pbXBvcnQgeyBDb21wb25lbnRTdGF0ZXMsIEJ1dHRvbk1ldGFkYXRhIH0gZnJvbSAnLi4vLi4vdHlwZXMnO1xuaW1wb3J0IHsgR3JvdXBzU2VydmljZSB9IGZyb20gJy4uLy4uLy4uL3NlcnZpY2VzL2dyb3Vwcy9ncm91cHMuc2VydmljZSc7XG5pbXBvcnQgeyBWYWxHcm91cE1lbWJlciB9IGZyb20gJy4uLy4uLy4uL3NlcnZpY2VzL2dyb3Vwcy90eXBlcyc7XG5cbi8qKiBQZXJzb25hIGVsZWdpYmxlIHBhcmEgYWdyZWdhciBhbCBncnVwbyAodMOtcGljYW1lbnRlIHVuIGBPcmdNZW1iZXJgKS4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgR3JvdXBNZW1iZXJDYW5kaWRhdGUge1xuICB1c2VySWQ6IHN0cmluZztcbiAgbmFtZT86IHN0cmluZztcbiAgZW1haWw/OiBzdHJpbmc7XG59XG5cbi8qKlxuICogdmFsLWdyb3VwLW1lbWJlcnMg4oCUIGFkbWluaXN0cmFyIGxhIG1lbWJyZXPDrWEgZGUgVU4gZ3J1cG8gKEFEUi0wODMpLlxuICpcbiAqIERlbGliZXJhZGFtZW50ZSBOTyB0cmFlIHN1IHByb3BpbyBzZWxlY3RvciBkZSBwZXJzb25hczogbGEgZnVlbnRlIGRlXG4gKiBcInF1acOpbmVzIHNvbiBsb3MgbWllbWJyb3MgZWxlZ2libGVzIGRlIGxhIG9yZ2FuaXphY2nDs25cIiB2YXLDrWEgcG9yIGFwcCAob3JnXG4gKiBtZW1iZXJzLCBpbnZpdGFkb3MsIGV0Yy4pLCBhc8OtIHF1ZSBzZSByZWNpYmUgcG9yIGBASW5wdXQgY2FuZGlkYXRlc2AgZW4gdmV6XG4gKiBkZSBxdWUgZXN0ZSBvcmdhbmlzbW8gaW1wb3J0ZSB1biBzZXJ2aWNpbyBkZSBvcmdhbml6YWNpw7NuIHF1ZSBubyBsZVxuICogY29ycmVzcG9uZGUuIFNpbiBjYW5kaWRhdG9zLCBpZ3VhbCBmdW5jaW9uYTogc29sbyBsaXN0YSB5IHF1aXRhLlxuICpcbiAqIFNpbiB0ZXh0byBoYXJkY29kZWFkbyAobGliIGkxOG4tYWdub3N0aWMpOiBsb3MgbGFiZWxzIGxsZWdhbiBwb3IgYEBJbnB1dGAuXG4gKi9cbkBDb21wb25lbnQoe1xuICBzZWxlY3RvcjogJ3ZhbC1ncm91cC1tZW1iZXJzJyxcbiAgc3RhbmRhbG9uZTogdHJ1ZSxcbiAgaW1wb3J0czogW0NvbW1vbk1vZHVsZSwgSW9uSWNvbiwgSW9uU2VsZWN0LCBJb25TZWxlY3RPcHRpb24sIEJ1dHRvbkNvbXBvbmVudF0sXG4gIHRlbXBsYXRlOiBgXG4gICAgPGRpdiBjbGFzcz1cImdyb3VwLW1lbWJlcnNcIj5cbiAgICAgIEBpZiAoY2FuZGlkYXRlcy5sZW5ndGggPiAwKSB7XG4gICAgICAgIDxkaXYgY2xhc3M9XCJncm91cC1tZW1iZXJzX19hZGRcIj5cbiAgICAgICAgICA8aW9uLXNlbGVjdFxuICAgICAgICAgICAgW3BsYWNlaG9sZGVyXT1cImFkZFBsYWNlaG9sZGVyXCJcbiAgICAgICAgICAgIGludGVyZmFjZT1cInBvcG92ZXJcIlxuICAgICAgICAgICAgW2Rpc2FibGVkXT1cImJ1c3lcIlxuICAgICAgICAgICAgKGlvbkNoYW5nZSk9XCJhZGQoJGV2ZW50LmRldGFpbC52YWx1ZSlcIlxuICAgICAgICAgID5cbiAgICAgICAgICAgIEBmb3IgKGMgb2YgZWxpZ2libGUoKTsgdHJhY2sgYy51c2VySWQpIHtcbiAgICAgICAgICAgICAgPGlvbi1zZWxlY3Qtb3B0aW9uIFt2YWx1ZV09XCJjLnVzZXJJZFwiPlxuICAgICAgICAgICAgICAgIHt7IGMubmFtZSB8fCBjLmVtYWlsIHx8IGMudXNlcklkIH19XG4gICAgICAgICAgICAgIDwvaW9uLXNlbGVjdC1vcHRpb24+XG4gICAgICAgICAgICB9XG4gICAgICAgICAgPC9pb24tc2VsZWN0PlxuICAgICAgICA8L2Rpdj5cbiAgICAgIH1cblxuICAgICAgQGlmIChtZW1iZXJzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICA8cCBjbGFzcz1cImdyb3VwLW1lbWJlcnNfX2VtcHR5XCI+e3sgZW1wdHlMYWJlbCB9fTwvcD5cbiAgICAgIH0gQGVsc2Uge1xuICAgICAgICA8dWwgY2xhc3M9XCJncm91cC1tZW1iZXJzX19saXN0XCI+XG4gICAgICAgICAgQGZvciAobSBvZiBtZW1iZXJzOyB0cmFjayBtLnVzZXJJZCkge1xuICAgICAgICAgICAgPGxpIGNsYXNzPVwiZ3JvdXAtbWVtYmVyc19fcm93XCI+XG4gICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwiZ3JvdXAtbWVtYmVyc19fbmFtZVwiPnt7IG5hbWVGb3IobS51c2VySWQpIH19PC9zcGFuPlxuICAgICAgICAgICAgICA8dmFsLWJ1dHRvblxuICAgICAgICAgICAgICAgIFtwcm9wc109XCJyZW1vdmVCdXR0b25Qcm9wc1wiXG4gICAgICAgICAgICAgICAgKG9uQ2xpY2spPVwicmVtb3ZlKG0udXNlcklkKVwiXG4gICAgICAgICAgICAgIC8+XG4gICAgICAgICAgICA8L2xpPlxuICAgICAgICAgIH1cbiAgICAgICAgPC91bD5cbiAgICAgIH1cbiAgICA8L2Rpdj5cbiAgYCxcbiAgc3R5bGVVcmxzOiBbJy4vZ3JvdXAtbWVtYmVycy5jb21wb25lbnQuc2NzcyddLFxufSlcbmV4cG9ydCBjbGFzcyBHcm91cE1lbWJlcnNDb21wb25lbnQgaW1wbGVtZW50cyBPbkNoYW5nZXMge1xuICBASW5wdXQoeyByZXF1aXJlZDogdHJ1ZSB9KSBncm91cElkITogc3RyaW5nO1xuICAvKiogUGVyc29uYXMgZWxlZ2libGVzIHBhcmEgYWdyZWdhci4gVmFjw61vID0gZWwgb3JnYW5pc21vIHNvbG8gbGlzdGEvcXVpdGEuICovXG4gIEBJbnB1dCgpIGNhbmRpZGF0ZXM6IEdyb3VwTWVtYmVyQ2FuZGlkYXRlW10gPSBbXTtcbiAgQElucHV0KCkgYWRkUGxhY2Vob2xkZXIgPSAnJztcbiAgQElucHV0KCkgZW1wdHlMYWJlbCA9ICcnO1xuICBASW5wdXQoKSByZW1vdmVMYWJlbCA9ICcnO1xuICBAT3V0cHV0KCkgbWVtYmVyc0NoYW5nZSA9IG5ldyBFdmVudEVtaXR0ZXI8VmFsR3JvdXBNZW1iZXJbXT4oKTtcblxuICBwcml2YXRlIHJlYWRvbmx5IGdyb3Vwc1N2YyA9IGluamVjdChHcm91cHNTZXJ2aWNlKTtcbiAgbWVtYmVyczogVmFsR3JvdXBNZW1iZXJbXSA9IFtdO1xuICBidXN5ID0gZmFsc2U7XG5cbiAgZ2V0IHJlbW92ZUJ1dHRvblByb3BzKCk6IEJ1dHRvbk1ldGFkYXRhIHtcbiAgICByZXR1cm4ge1xuICAgICAgdGV4dDogdGhpcy5yZW1vdmVMYWJlbCxcbiAgICAgIGNvbG9yOiAnZGFyaycsXG4gICAgICBmaWxsOiAnY2xlYXInLFxuICAgICAgc2l6ZTogJ3NtYWxsJyxcbiAgICAgIHNoYXBlOiAncm91bmQnLFxuICAgICAgdHlwZTogJ2J1dHRvbicsXG4gICAgICBzdGF0ZTogdGhpcy5idXN5ID8gQ29tcG9uZW50U3RhdGVzLkRJU0FCTEVEIDogQ29tcG9uZW50U3RhdGVzLkVOQUJMRUQsXG4gICAgfTtcbiAgfVxuXG4gIG5nT25DaGFuZ2VzKGNoYW5nZXM6IFNpbXBsZUNoYW5nZXMpOiB2b2lkIHtcbiAgICBpZiAoY2hhbmdlc1snZ3JvdXBJZCddICYmIHRoaXMuZ3JvdXBJZCkge1xuICAgICAgdGhpcy5yZWxvYWQoKTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIHJlbG9hZCgpOiB2b2lkIHtcbiAgICB0aGlzLmdyb3Vwc1N2Yy5saXN0TWVtYmVycyh0aGlzLmdyb3VwSWQpLnN1YnNjcmliZSh7XG4gICAgICBuZXh0OiAobSkgPT4gKHRoaXMubWVtYmVycyA9IG0pLFxuICAgICAgZXJyb3I6ICgpID0+ICh0aGlzLm1lbWJlcnMgPSBbXSksXG4gICAgfSk7XG4gIH1cblxuICAvKiogQ2FuZGlkYXRvcyBxdWUgdG9kYXbDrWEgbm8gZXN0w6FuIGVuIGVsIGdydXBvIOKAlCBldml0YSBvZnJlY2VyIHVuIGFsdGEgZHVwbGljYWRhLiAqL1xuICBlbGlnaWJsZSgpOiBHcm91cE1lbWJlckNhbmRpZGF0ZVtdIHtcbiAgICBjb25zdCBjdXJyZW50ID0gbmV3IFNldCh0aGlzLm1lbWJlcnMubWFwKChtKSA9PiBtLnVzZXJJZCkpO1xuICAgIHJldHVybiB0aGlzLmNhbmRpZGF0ZXMuZmlsdGVyKChjKSA9PiAhY3VycmVudC5oYXMoYy51c2VySWQpKTtcbiAgfVxuXG4gIG5hbWVGb3IodXNlcklkOiBzdHJpbmcpOiBzdHJpbmcge1xuICAgIGNvbnN0IGMgPSB0aGlzLmNhbmRpZGF0ZXMuZmluZCgoeCkgPT4geC51c2VySWQgPT09IHVzZXJJZCk7XG4gICAgcmV0dXJuIGM/Lm5hbWUgfHwgYz8uZW1haWwgfHwgdXNlcklkO1xuICB9XG5cbiAgYWRkKHVzZXJJZDogc3RyaW5nKTogdm9pZCB7XG4gICAgaWYgKCF1c2VySWQgfHwgdGhpcy5idXN5KSByZXR1cm47XG4gICAgdGhpcy5idXN5ID0gdHJ1ZTtcbiAgICB0aGlzLmdyb3Vwc1N2Yy5hZGRNZW1iZXIodGhpcy5ncm91cElkLCB7IHVzZXJJZCB9KS5zdWJzY3JpYmUoe1xuICAgICAgbmV4dDogKG1lbWJlcnMpID0+IHtcbiAgICAgICAgdGhpcy5tZW1iZXJzID0gbWVtYmVycztcbiAgICAgICAgdGhpcy5idXN5ID0gZmFsc2U7XG4gICAgICAgIHRoaXMubWVtYmVyc0NoYW5nZS5lbWl0KG1lbWJlcnMpO1xuICAgICAgfSxcbiAgICAgIGVycm9yOiAoKSA9PiAodGhpcy5idXN5ID0gZmFsc2UpLFxuICAgIH0pO1xuICB9XG5cbiAgcmVtb3ZlKHVzZXJJZDogc3RyaW5nKTogdm9pZCB7XG4gICAgaWYgKHRoaXMuYnVzeSkgcmV0dXJuO1xuICAgIHRoaXMuYnVzeSA9IHRydWU7XG4gICAgdGhpcy5ncm91cHNTdmMucmVtb3ZlTWVtYmVyKHRoaXMuZ3JvdXBJZCwgdXNlcklkKS5zdWJzY3JpYmUoe1xuICAgICAgbmV4dDogKG1lbWJlcnMpID0+IHtcbiAgICAgICAgdGhpcy5tZW1iZXJzID0gbWVtYmVycztcbiAgICAgICAgdGhpcy5idXN5ID0gZmFsc2U7XG4gICAgICAgIHRoaXMubWVtYmVyc0NoYW5nZS5lbWl0KG1lbWJlcnMpO1xuICAgICAgfSxcbiAgICAgIGVycm9yOiAoKSA9PiAodGhpcy5idXN5ID0gZmFsc2UpLFxuICAgIH0pO1xuICB9XG59XG4iXX0=
@@ -0,0 +1,48 @@
1
+ import { Directive, Input } from '@angular/core';
2
+ import * as i0 from "@angular/core";
3
+ import * as i1 from "../services/feature-control.service";
4
+ /**
5
+ * Structural directive to hide elements when a feature is disabled.
6
+ *
7
+ * Usage: <button *valFeatureGuard="'oauth_facebook'">Sign in with Facebook</button>
8
+ * If oauth_facebook is disabled, the button is not rendered.
9
+ */
10
+ export class FeatureGuardDirective {
11
+ set valFeatureGuard(featureKey) {
12
+ this.featureKey = featureKey;
13
+ this.updateVisibility();
14
+ }
15
+ constructor(templateRef, viewContainer, featureControl) {
16
+ this.templateRef = templateRef;
17
+ this.viewContainer = viewContainer;
18
+ this.featureControl = featureControl;
19
+ this.featureKey = '';
20
+ }
21
+ ngOnInit() {
22
+ this.updateVisibility();
23
+ }
24
+ updateVisibility() {
25
+ if (!this.featureKey) {
26
+ return;
27
+ }
28
+ const isEnabled = this.featureControl.isEnabled(this.featureKey);
29
+ if (isEnabled) {
30
+ this.viewContainer.createEmbeddedView(this.templateRef);
31
+ }
32
+ else {
33
+ this.viewContainer.clear();
34
+ }
35
+ }
36
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: FeatureGuardDirective, deps: [{ token: i0.TemplateRef }, { token: i0.ViewContainerRef }, { token: i1.FeatureControlService }], target: i0.ɵɵFactoryTarget.Directive }); }
37
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "18.2.14", type: FeatureGuardDirective, isStandalone: true, selector: "[valFeatureGuard]", inputs: { valFeatureGuard: "valFeatureGuard" }, ngImport: i0 }); }
38
+ }
39
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: FeatureGuardDirective, decorators: [{
40
+ type: Directive,
41
+ args: [{
42
+ selector: '[valFeatureGuard]',
43
+ standalone: true,
44
+ }]
45
+ }], ctorParameters: () => [{ type: i0.TemplateRef }, { type: i0.ViewContainerRef }, { type: i1.FeatureControlService }], propDecorators: { valFeatureGuard: [{
46
+ type: Input
47
+ }] } });
48
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZmVhdHVyZS1ndWFyZC5kaXJlY3RpdmUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi9zcmMvbGliL2RpcmVjdGl2ZXMvZmVhdHVyZS1ndWFyZC5kaXJlY3RpdmUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFNBQVMsRUFBRSxLQUFLLEVBQXlDLE1BQU0sZUFBZSxDQUFDOzs7QUFHeEY7Ozs7O0dBS0c7QUFLSCxNQUFNLE9BQU8scUJBQXFCO0lBQ2hDLElBQWEsZUFBZSxDQUFDLFVBQWtCO1FBQzdDLElBQUksQ0FBQyxVQUFVLEdBQUcsVUFBVSxDQUFDO1FBQzdCLElBQUksQ0FBQyxnQkFBZ0IsRUFBRSxDQUFDO0lBQzFCLENBQUM7SUFJRCxZQUNVLFdBQTZCLEVBQzdCLGFBQStCLEVBQy9CLGNBQXFDO1FBRnJDLGdCQUFXLEdBQVgsV0FBVyxDQUFrQjtRQUM3QixrQkFBYSxHQUFiLGFBQWEsQ0FBa0I7UUFDL0IsbUJBQWMsR0FBZCxjQUFjLENBQXVCO1FBTHZDLGVBQVUsR0FBVyxFQUFFLENBQUM7SUFNN0IsQ0FBQztJQUVKLFFBQVE7UUFDTixJQUFJLENBQUMsZ0JBQWdCLEVBQUUsQ0FBQztJQUMxQixDQUFDO0lBRU8sZ0JBQWdCO1FBQ3RCLElBQUksQ0FBQyxJQUFJLENBQUMsVUFBVSxFQUFFLENBQUM7WUFDckIsT0FBTztRQUNULENBQUM7UUFFRCxNQUFNLFNBQVMsR0FBRyxJQUFJLENBQUMsY0FBYyxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLENBQUM7UUFDakUsSUFBSSxTQUFTLEVBQUUsQ0FBQztZQUNkLElBQUksQ0FBQyxhQUFhLENBQUMsa0JBQWtCLENBQUMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxDQUFDO1FBQzFELENBQUM7YUFBTSxDQUFDO1lBQ04sSUFBSSxDQUFDLGFBQWEsQ0FBQyxLQUFLLEVBQUUsQ0FBQztRQUM3QixDQUFDO0lBQ0gsQ0FBQzsrR0E3QlUscUJBQXFCO21HQUFyQixxQkFBcUI7OzRGQUFyQixxQkFBcUI7a0JBSmpDLFNBQVM7bUJBQUM7b0JBQ1QsUUFBUSxFQUFFLG1CQUFtQjtvQkFDN0IsVUFBVSxFQUFFLElBQUk7aUJBQ2pCO21KQUVjLGVBQWU7c0JBQTNCLEtBQUsiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBEaXJlY3RpdmUsIElucHV0LCBUZW1wbGF0ZVJlZiwgVmlld0NvbnRhaW5lclJlZiwgT25Jbml0IH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBGZWF0dXJlQ29udHJvbFNlcnZpY2UgfSBmcm9tICcuLi9zZXJ2aWNlcy9mZWF0dXJlLWNvbnRyb2wuc2VydmljZSc7XG5cbi8qKlxuICogU3RydWN0dXJhbCBkaXJlY3RpdmUgdG8gaGlkZSBlbGVtZW50cyB3aGVuIGEgZmVhdHVyZSBpcyBkaXNhYmxlZC5cbiAqXG4gKiBVc2FnZTogPGJ1dHRvbiAqdmFsRmVhdHVyZUd1YXJkPVwiJ29hdXRoX2ZhY2Vib29rJ1wiPlNpZ24gaW4gd2l0aCBGYWNlYm9vazwvYnV0dG9uPlxuICogSWYgb2F1dGhfZmFjZWJvb2sgaXMgZGlzYWJsZWQsIHRoZSBidXR0b24gaXMgbm90IHJlbmRlcmVkLlxuICovXG5ARGlyZWN0aXZlKHtcbiAgc2VsZWN0b3I6ICdbdmFsRmVhdHVyZUd1YXJkXScsXG4gIHN0YW5kYWxvbmU6IHRydWUsXG59KVxuZXhwb3J0IGNsYXNzIEZlYXR1cmVHdWFyZERpcmVjdGl2ZSBpbXBsZW1lbnRzIE9uSW5pdCB7XG4gIEBJbnB1dCgpIHNldCB2YWxGZWF0dXJlR3VhcmQoZmVhdHVyZUtleTogc3RyaW5nKSB7XG4gICAgdGhpcy5mZWF0dXJlS2V5ID0gZmVhdHVyZUtleTtcbiAgICB0aGlzLnVwZGF0ZVZpc2liaWxpdHkoKTtcbiAgfVxuXG4gIHByaXZhdGUgZmVhdHVyZUtleTogc3RyaW5nID0gJyc7XG5cbiAgY29uc3RydWN0b3IoXG4gICAgcHJpdmF0ZSB0ZW1wbGF0ZVJlZjogVGVtcGxhdGVSZWY8YW55PixcbiAgICBwcml2YXRlIHZpZXdDb250YWluZXI6IFZpZXdDb250YWluZXJSZWYsXG4gICAgcHJpdmF0ZSBmZWF0dXJlQ29udHJvbDogRmVhdHVyZUNvbnRyb2xTZXJ2aWNlXG4gICkge31cblxuICBuZ09uSW5pdCgpIHtcbiAgICB0aGlzLnVwZGF0ZVZpc2liaWxpdHkoKTtcbiAgfVxuXG4gIHByaXZhdGUgdXBkYXRlVmlzaWJpbGl0eSgpIHtcbiAgICBpZiAoIXRoaXMuZmVhdHVyZUtleSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGNvbnN0IGlzRW5hYmxlZCA9IHRoaXMuZmVhdHVyZUNvbnRyb2wuaXNFbmFibGVkKHRoaXMuZmVhdHVyZUtleSk7XG4gICAgaWYgKGlzRW5hYmxlZCkge1xuICAgICAgdGhpcy52aWV3Q29udGFpbmVyLmNyZWF0ZUVtYmVkZGVkVmlldyh0aGlzLnRlbXBsYXRlUmVmKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy52aWV3Q29udGFpbmVyLmNsZWFyKCk7XG4gICAgfVxuICB9XG59XG4iXX0=
@@ -0,0 +1,117 @@
1
+ import { Injectable, signal, Optional } from '@angular/core';
2
+ import { firstValueFrom } from 'rxjs';
3
+ import * as i0 from "@angular/core";
4
+ import * as i1 from "@angular/common/http";
5
+ import * as i2 from "./firebase/analytics.service";
6
+ export class FeatureControlService {
7
+ constructor(http, analytics) {
8
+ this.http = http;
9
+ this.analytics = analytics;
10
+ this.features = signal(new Map());
11
+ this.isLoaded = signal(false);
12
+ this.previousState = new Map();
13
+ }
14
+ logFeatureEvent(key, enabled, previousEnabled) {
15
+ if (!this.analytics)
16
+ return;
17
+ try {
18
+ if (previousEnabled === null) {
19
+ // Carga inicial
20
+ this.analytics.logEvent('feature_loaded', {
21
+ feature_key: key,
22
+ feature_enabled: enabled,
23
+ });
24
+ }
25
+ else if (previousEnabled !== enabled) {
26
+ // Transición de estado
27
+ this.analytics.logEvent('feature_changed', {
28
+ feature_key: key,
29
+ previous_state: previousEnabled ? 'enabled' : 'disabled',
30
+ current_state: enabled ? 'enabled' : 'disabled',
31
+ });
32
+ }
33
+ }
34
+ catch (err) {
35
+ console.warn(`Failed to log feature event for ${key}:`, err);
36
+ }
37
+ }
38
+ /**
39
+ * Load user features from backend.
40
+ * Call this during app initialization (AppComponent ctor or effect).
41
+ * Logs feature state changes to Firebase Analytics.
42
+ */
43
+ async loadUserFeatures() {
44
+ try {
45
+ const response = await firstValueFrom(this.http.get('/v2/user/features'));
46
+ const map = new Map();
47
+ response.forEach(f => {
48
+ const previousEnabled = this.previousState.get(f.key) ?? null;
49
+ this.logFeatureEvent(f.key, f.enabled, previousEnabled);
50
+ this.previousState.set(f.key, f.enabled);
51
+ map.set(f.key, f.enabled);
52
+ });
53
+ this.features.set(map);
54
+ this.isLoaded.set(true);
55
+ }
56
+ catch (error) {
57
+ console.error('Failed to load feature control:', error);
58
+ // Fallback: assume all features enabled on error (optimistic)
59
+ this.isLoaded.set(true);
60
+ }
61
+ }
62
+ /**
63
+ * Check if a feature is enabled for the current user.
64
+ * Returns true if feature is not found (optimistic default).
65
+ * If rollout percentage is set, uses consistent hashing for canary rollouts.
66
+ */
67
+ isEnabled(featureKey) {
68
+ const featuresMap = this.features();
69
+ const feature = featuresMap.get(featureKey);
70
+ // Not in map: default to enabled (optimistic)
71
+ if (feature === undefined)
72
+ return true;
73
+ // Not enabled: return false
74
+ if (!feature)
75
+ return false;
76
+ // TODO: Implement rollout percentage check with hash
77
+ // For now, if enabled and no rollout, it's enabled for everyone
78
+ return true;
79
+ }
80
+ /**
81
+ * Get a computed signal for a feature.
82
+ * Use in templates: *ngIf="featureEnabled('oauth_facebook')()"
83
+ * Or in component: featureEnabled('payment_settings').
84
+ */
85
+ featureEnabled(featureKey) {
86
+ return () => this.isEnabled(featureKey);
87
+ }
88
+ /**
89
+ * Get all features for debugging (admin only).
90
+ */
91
+ getAllFeatures() {
92
+ return this.features();
93
+ }
94
+ /**
95
+ * Check if features have been loaded.
96
+ */
97
+ isReady() {
98
+ return this.isLoaded();
99
+ }
100
+ /**
101
+ * Watch for feature changes (for testing/demo purposes).
102
+ */
103
+ watchFeatures() {
104
+ return this.features;
105
+ }
106
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: FeatureControlService, deps: [{ token: i1.HttpClient }, { token: i2.AnalyticsService, optional: true }], target: i0.ɵɵFactoryTarget.Injectable }); }
107
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: FeatureControlService, providedIn: 'root' }); }
108
+ }
109
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: FeatureControlService, decorators: [{
110
+ type: Injectable,
111
+ args: [{
112
+ providedIn: 'root',
113
+ }]
114
+ }], ctorParameters: () => [{ type: i1.HttpClient }, { type: i2.AnalyticsService, decorators: [{
115
+ type: Optional
116
+ }] }] });
117
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZmVhdHVyZS1jb250cm9sLnNlcnZpY2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi9zcmMvbGliL3NlcnZpY2VzL2ZlYXR1cmUtY29udHJvbC5zZXJ2aWNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSxFQUFFLFFBQVEsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUU3RCxPQUFPLEVBQUUsY0FBYyxFQUFFLE1BQU0sTUFBTSxDQUFDOzs7O0FBYXRDLE1BQU0sT0FBTyxxQkFBcUI7SUFLaEMsWUFDVSxJQUFnQixFQUNKLFNBQTRCO1FBRHhDLFNBQUksR0FBSixJQUFJLENBQVk7UUFDSixjQUFTLEdBQVQsU0FBUyxDQUFtQjtRQU4xQyxhQUFRLEdBQUcsTUFBTSxDQUF1QixJQUFJLEdBQUcsRUFBRSxDQUFDLENBQUM7UUFDbkQsYUFBUSxHQUFHLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUN6QixrQkFBYSxHQUFHLElBQUksR0FBRyxFQUFtQixDQUFDO0lBS2hELENBQUM7SUFFSSxlQUFlLENBQUMsR0FBVyxFQUFFLE9BQWdCLEVBQUUsZUFBK0I7UUFDcEYsSUFBSSxDQUFDLElBQUksQ0FBQyxTQUFTO1lBQUUsT0FBTztRQUU1QixJQUFJLENBQUM7WUFDSCxJQUFJLGVBQWUsS0FBSyxJQUFJLEVBQUUsQ0FBQztnQkFDN0IsZ0JBQWdCO2dCQUNoQixJQUFJLENBQUMsU0FBUyxDQUFDLFFBQVEsQ0FBQyxnQkFBZ0IsRUFBRTtvQkFDeEMsV0FBVyxFQUFFLEdBQUc7b0JBQ2hCLGVBQWUsRUFBRSxPQUFPO2lCQUN6QixDQUFDLENBQUM7WUFDTCxDQUFDO2lCQUFNLElBQUksZUFBZSxLQUFLLE9BQU8sRUFBRSxDQUFDO2dCQUN2Qyx1QkFBdUI7Z0JBQ3ZCLElBQUksQ0FBQyxTQUFTLENBQUMsUUFBUSxDQUFDLGlCQUFpQixFQUFFO29CQUN6QyxXQUFXLEVBQUUsR0FBRztv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QUUsTUFBTTtpQkFDbkI7OzBCQVFJLFFBQVEiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBJbmplY3RhYmxlLCBzaWduYWwsIE9wdGlvbmFsIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBIdHRwQ2xpZW50IH0gZnJvbSAnQGFuZ3VsYXIvY29tbW9uL2h0dHAnO1xuaW1wb3J0IHsgZmlyc3RWYWx1ZUZyb20gfSBmcm9tICdyeGpzJztcbmltcG9ydCB7IEFuYWx5dGljc1NlcnZpY2UgfSBmcm9tICcuL2ZpcmViYXNlL2FuYWx5dGljcy5zZXJ2aWNlJztcblxuZXhwb3J0IGludGVyZmFjZSBVc2VyRmVhdHVyZSB7XG4gIGtleTogc3RyaW5nO1xuICBlbmFibGVkOiBib29sZWFuO1xuICByb2xsb3V0UGVyY2VudGFnZT86IG51bWJlcjsgLy8gMC0xMDA6IHBlcmNlbnRhZ2Ugb2YgdXNlcnMgd2hvIGdldCB0aGlzIGZlYXR1cmVcbiAgcm9sbG91dEhhc2g/OiBzdHJpbmc7IC8vIEhhc2ggdXNlZCBmb3IgY29uc2lzdGVudCByb2xsb3V0IChlLmcuLCB1c2VyIElEIGhhc2gpXG59XG5cbkBJbmplY3RhYmxlKHtcbiAgcHJvdmlkZWRJbjogJ3Jvb3QnLFxufSlcbmV4cG9ydCBjbGFzcyBGZWF0dXJlQ29udHJvbFNlcnZpY2Uge1xuICBwcml2YXRlIGZlYXR1cmVzID0gc2lnbmFsPE1hcDxzdHJpbmcsIGJvb2xlYW4+PihuZXcgTWFwKCkpO1xuICBwcml2YXRlIGlzTG9hZGVkID0gc2lnbmFsKGZhbHNlKTtcbiAgcHJpdmF0ZSBwcmV2aW91c1N0YXRlID0gbmV3IE1hcDxzdHJpbmcsIGJvb2xlYW4+KCk7XG5cbiAgY29uc3RydWN0b3IoXG4gICAgcHJpdmF0ZSBodHRwOiBIdHRwQ2xpZW50LFxuICAgIEBPcHRpb25hbCgpIHByaXZhdGUgYW5hbHl0aWNzPzogQW5hbHl0aWNzU2VydmljZVxuICApIHt9XG5cbiAgcHJpdmF0ZSBsb2dGZWF0dXJlRXZlbnQoa2V5OiBzdHJpbmcsIGVuYWJsZWQ6IGJvb2xlYW4sIHByZXZpb3VzRW5hYmxlZDogYm9vbGVhbiB8IG51bGwpOiB2b2lkIHtcbiAgICBpZiAoIXRoaXMuYW5hbHl0aWNzKSByZXR1cm47XG5cbiAgICB0cnkge1xuICAgICAgaWYgKHByZXZpb3VzRW5hYmxlZCA9PT0gbnVsbCkge1xuICAgICAgICAvLyBDYXJnYSBpbmljaWFsXG4gICAgICAgIHRoaXMuYW5hbHl0aWNzLmxvZ0V2ZW50KCdmZWF0dXJlX2xvYWRlZCcsIHtcbiAgICAgICAgICBmZWF0dXJlX2tleToga2V5LFxuICAgICAgICAgIGZlYXR1cmVfZW5hYmxlZDogZW5hYmxlZCxcbiAgICAgICAgfSk7XG4gICAgICB9IGVsc2UgaWYgKHByZXZpb3VzRW5hYmxlZCAhPT0gZW5hYmxlZCkge1xuICAgICAgICAvLyBUcmFuc2ljacOzbiBkZSBlc3RhZG9cbiAgICAgICAgdGhpcy5hbmFseXRpY3MubG9nRXZlbnQoJ2ZlYXR1cmVfY2hhbmdlZCcsIHtcbiAgICAgICAgICBmZWF0dXJlX2tleToga2V5LFxuICAgICAgICAgIHByZXZpb3VzX3N0YXRlOiBwcmV2aW91c0VuYWJsZWQgPyAnZW5hYmxlZCcgOiAnZGlzYWJsZWQnLFxuICAgICAgICAgIGN1cnJlbnRfc3RhdGU6IGVuYWJsZWQgPyAnZW5hYmxlZCcgOiAnZGlzYWJsZWQnLFxuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgIGNvbnNvbGUud2FybihgRmFpbGVkIHRvIGxvZyBmZWF0dXJlIGV2ZW50IGZvciAke2tleX06YCwgZXJyKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogTG9hZCB1c2VyIGZlYXR1cmVzIGZyb20gYmFja2VuZC5cbiAgICogQ2FsbCB0aGlzIGR1cmluZyBhcHAgaW5pdGlhbGl6YXRpb24gKEFwcENvbXBvbmVudCBjdG9yIG9yIGVmZmVjdCkuXG4gICAqIExvZ3MgZmVhdHVyZSBzdGF0ZSBjaGFuZ2VzIHRvIEZpcmViYXNlIEFuYWx5dGljcy5cbiAgICovXG4gIGFzeW5jIGxvYWRVc2VyRmVhdHVyZXMoKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgZmlyc3RWYWx1ZUZyb20odGhpcy5odHRwLmdldDxVc2VyRmVhdHVyZVtdPignL3YyL3VzZXIvZmVhdHVyZXMnKSk7XG4gICAgICBjb25zdCBtYXAgPSBuZXcgTWFwPHN0cmluZywgYm9vbGVhbj4oKTtcblxuICAgICAgcmVzcG9uc2UuZm9yRWFjaChmID0+IHtcbiAgICAgICAgY29uc3QgcHJldmlvdXNFbmFibGVkID0gdGhpcy5wcmV2aW91c1N0YXRlLmdldChmLmtleSkgPz8gbnVsbDtcbiAgICAgICAgdGhpcy5sb2dGZWF0dXJlRXZlbnQoZi5rZXksIGYuZW5hYmxlZCwgcHJldmlvdXNFbmFibGVkKTtcbiAgICAgICAgdGhpcy5wcmV2aW91c1N0YXRlLnNldChmLmtleSwgZi5lbmFibGVkKTtcbiAgICAgICAgbWFwLnNldChmLmtleSwgZi5lbmFibGVkKTtcbiAgICAgIH0pO1xuXG4gICAgICB0aGlzLmZlYXR1cmVzLnNldChtYXApO1xuICAgICAgdGhpcy5pc0xvYWRlZC5zZXQodHJ1ZSk7XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIGNvbnNvbGUuZXJyb3IoJ0ZhaWxlZCB0byBsb2FkIGZlYXR1cmUgY29udHJvbDonLCBlcnJvcik7XG4gICAgICAvLyBGYWxsYmFjazogYXNzdW1lIGFsbCBmZWF0dXJlcyBlbmFibGVkIG9uIGVycm9yIChvcHRpbWlzdGljKVxuICAgICAgdGhpcy5pc0xvYWRlZC5zZXQodHJ1ZSk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIENoZWNrIGlmIGEgZmVhdHVyZSBpcyBlbmFibGVkIGZvciB0aGUgY3VycmVudCB1c2VyLlxuICAgKiBSZXR1cm5zIHRydWUgaWYgZmVhdHVyZSBpcyBub3QgZm91bmQgKG9wdGltaXN0aWMgZGVmYXVsdCkuXG4gICAqIElmIHJvbGxvdXQgcGVyY2VudGFnZSBpcyBzZXQsIHVzZXMgY29uc2lzdGVudCBoYXNoaW5nIGZvciBjYW5hcnkgcm9sbG91dHMuXG4gICAqL1xuICBpc0VuYWJsZWQoZmVhdHVyZUtleTogc3RyaW5nKTogYm9vbGVhbiB7XG4gICAgY29uc3QgZmVhdHVyZXNNYXAgPSB0aGlzLmZlYXR1cmVzKCk7XG4gICAgY29uc3QgZmVhdHVyZSA9IGZlYXR1cmVzTWFwLmdldChmZWF0dXJlS2V5KTtcblxuICAgIC8vIE5vdCBpbiBtYXA6IGRlZmF1bHQgdG8gZW5hYmxlZCAob3B0aW1pc3RpYylcbiAgICBpZiAoZmVhdHVyZSA9PT0gdW5kZWZpbmVkKSByZXR1cm4gdHJ1ZTtcblxuICAgIC8vIE5vdCBlbmFibGVkOiByZXR1cm4gZmFsc2VcbiAgICBpZiAoIWZlYXR1cmUpIHJldHVybiBmYWxzZTtcblxuICAgIC8vIFRPRE86IEltcGxlbWVudCByb2xsb3V0IHBlcmNlbnRhZ2UgY2hlY2sgd2l0aCBoYXNoXG4gICAgLy8gRm9yIG5vdywgaWYgZW5hYmxlZCBhbmQgbm8gcm9sbG91dCwgaXQncyBlbmFibGVkIGZvciBldmVyeW9uZVxuICAgIHJldHVybiB0cnVlO1xuICB9XG5cbiAgLyoqXG4gICAqIEdldCBhIGNvbXB1dGVkIHNpZ25hbCBmb3IgYSBmZWF0dXJlLlxuICAgKiBVc2UgaW4gdGVtcGxhdGVzOiAqbmdJZj1cImZlYXR1cmVFbmFibGVkKCdvYXV0aF9mYWNlYm9vaycpKClcIlxuICAgKiBPciBpbiBjb21wb25lbnQ6IGZlYXR1cmVFbmFibGVkKCdwYXltZW50X3NldHRpbmdzJykuXG4gICAqL1xuICBmZWF0dXJlRW5hYmxlZChmZWF0dXJlS2V5OiBzdHJpbmcpIHtcbiAgICByZXR1cm4gKCkgPT4gdGhpcy5pc0VuYWJsZWQoZmVhdHVyZUtleSk7XG4gIH1cblxuICAvKipcbiAgICogR2V0IGFsbCBmZWF0dXJlcyBmb3IgZGVidWdnaW5nIChhZG1pbiBvbmx5KS5cbiAgICovXG4gIGdldEFsbEZlYXR1cmVzKCk6IE1hcDxzdHJpbmcsIGJvb2xlYW4+IHtcbiAgICByZXR1cm4gdGhpcy5mZWF0dXJlcygpO1xuICB9XG5cbiAgLyoqXG4gICAqIENoZWNrIGlmIGZlYXR1cmVzIGhhdmUgYmVlbiBsb2FkZWQuXG4gICAqL1xuICBpc1JlYWR5KCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0aGlzLmlzTG9hZGVkKCk7XG4gIH1cblxuICAvKipcbiAgICogV2F0Y2ggZm9yIGZlYXR1cmUgY2hhbmdlcyAoZm9yIHRlc3RpbmcvZGVtbyBwdXJwb3NlcykuXG4gICAqL1xuICB3YXRjaEZlYXR1cmVzKCkge1xuICAgIHJldHVybiB0aGlzLmZlYXR1cmVzO1xuICB9XG59XG4iXX0=
@@ -0,0 +1,92 @@
1
+ import { Injectable, Inject } from '@angular/core';
2
+ import { map } from 'rxjs/operators';
3
+ import { VALTECH_AUTH_CONFIG } from '../auth/config';
4
+ import * as i0 from "@angular/core";
5
+ import * as i1 from "@angular/common/http";
6
+ /**
7
+ * Cliente de `/v2/groups/*` (ADR-083). Servicio de PLATAFORMA: no sabe qué es
8
+ * un blueprint ni un refugio, solo agrupa recursos y personas. Cada app lo
9
+ * consume igual — es lo que evita reescribir esta capa por producto.
10
+ */
11
+ export class GroupsService {
12
+ constructor(config, http) {
13
+ this.config = config;
14
+ this.http = http;
15
+ }
16
+ get baseUrl() {
17
+ return `${this.config.apiUrl}/v2/groups`;
18
+ }
19
+ /** Grupos activos de la organización (filtrados por app en el backend). */
20
+ listGroups() {
21
+ return this.http
22
+ .get(this.baseUrl)
23
+ .pipe(map((r) => r.groups ?? []));
24
+ }
25
+ /** Incluye archivados: para la pantalla de administración. */
26
+ listAllGroups() {
27
+ return this.http
28
+ .get(`${this.baseUrl}/all`)
29
+ .pipe(map((r) => r.groups ?? []));
30
+ }
31
+ getGroup(id) {
32
+ return this.http
33
+ .get(`${this.baseUrl}/${id}`)
34
+ .pipe(map((r) => r.group));
35
+ }
36
+ createGroup(req) {
37
+ return this.http
38
+ .post(this.baseUrl, req)
39
+ .pipe(map((r) => r.group));
40
+ }
41
+ updateGroup(id, req) {
42
+ return this.http
43
+ .put(`${this.baseUrl}/${id}`, req)
44
+ .pipe(map((r) => r.group));
45
+ }
46
+ /**
47
+ * No hay `deleteGroup`: el ADR-083 decidió que un servicio de plataforma no
48
+ * puede saber si un vertical todavía apunta al grupo, y como "sin grupo"
49
+ * significa visible para toda la organización, borrarlo publicaría sus
50
+ * recursos a la planta entera. `archiveGroup`/`restoreGroup` cubren la
51
+ * necesidad real sin ese riesgo.
52
+ */
53
+ archiveGroup(id) {
54
+ return this.http
55
+ .post(`${this.baseUrl}/${id}/archive`, {})
56
+ .pipe(map((r) => r.group));
57
+ }
58
+ restoreGroup(id) {
59
+ return this.http
60
+ .post(`${this.baseUrl}/${id}/restore`, {})
61
+ .pipe(map((r) => r.group));
62
+ }
63
+ listMembers(groupId) {
64
+ return this.http
65
+ .get(`${this.baseUrl}/${groupId}/members`)
66
+ .pipe(map((r) => r.members ?? []));
67
+ }
68
+ addMember(groupId, req) {
69
+ return this.http
70
+ .post(`${this.baseUrl}/${groupId}/members`, req)
71
+ .pipe(map((r) => r.members ?? []));
72
+ }
73
+ removeMember(groupId, userId) {
74
+ return this.http
75
+ .delete(`${this.baseUrl}/${groupId}/members/${userId}`)
76
+ .pipe(map((r) => r.members ?? []));
77
+ }
78
+ /** Los grupos del usuario actual. Referencial: el filtrado real corre en el backend. */
79
+ myGroups() {
80
+ return this.http.get(`${this.baseUrl}/mine`);
81
+ }
82
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: GroupsService, deps: [{ token: VALTECH_AUTH_CONFIG }, { token: i1.HttpClient }], target: i0.ɵɵFactoryTarget.Injectable }); }
83
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: GroupsService, providedIn: 'root' }); }
84
+ }
85
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: GroupsService, decorators: [{
86
+ type: Injectable,
87
+ args: [{ providedIn: 'root' }]
88
+ }], ctorParameters: () => [{ type: undefined, decorators: [{
89
+ type: Inject,
90
+ args: [VALTECH_AUTH_CONFIG]
91
+ }] }, { type: i1.HttpClient }] });
92
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZ3JvdXBzLnNlcnZpY2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9zcmMvbGliL3NlcnZpY2VzL2dyb3Vwcy9ncm91cHMuc2VydmljZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUduRCxPQUFPLEVBQUUsR0FBRyxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFFckMsT0FBTyxFQUFFLG1CQUFtQixFQUFFLE1BQU0sZ0JBQWdCLENBQUM7OztBQWNyRDs7OztHQUlHO0FBRUgsTUFBTSxPQUFPLGFBQWE7SUFDeEIsWUFDdUMsTUFBeUIsRUFDdEQsSUFBZ0I7UUFEYSxXQUFNLEdBQU4sTUFBTSxDQUFtQjtRQUN0RCxTQUFJLEdBQUosSUFBSSxDQUFZO0lBQ3ZCLENBQUM7SUFFSixJQUFZLE9BQU87UUFDakIsT0FBTyxHQUFHLElBQUksQ0FBQyxNQUFNLENBQUMsTUFBTSxZQUFZLENBQUM7SUFDM0MsQ0FBQztJQUVELDJFQUEyRTtJQUMzRSxVQUFVO1FBQ1IsT0FBTyxJQUFJLENBQUMsSUFBSTthQUNiLEdBQUcsQ0FBcUIsSUFBSSxDQUFDLE9BQU8sQ0FBQzthQUNyQyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsTUFBTSxJQUFJLEVBQUUsQ0FBQyxDQUFDLENBQUM7SUFDdEMsQ0FBQztJQUVELDhEQUE4RDtJQUM5RCxhQUFhO1FBQ1gsT0FBTyxJQUFJLENBQUMsSUFBSTthQUNiLEdBQUcsQ0FBcUIsR0FBRyxJQUFJLENBQUMsT0FBTyxNQUFNLENBQUM7YUFDOUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDLE1BQU0sSUFBSSxFQUFFLENBQUMsQ0FBQyxDQUFDO0lBQ3RDLENBQUM7SUFFRCxRQUFRLENBQUMsRUFBVTtR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LE1BQU07OzRGQUNuQixhQUFhO2tCQUR6QixVQUFVO21CQUFDLEVBQUUsVUFBVSxFQUFFLE1BQU0sRUFBRTs7MEJBRzdCLE1BQU07MkJBQUMsbUJBQW1CIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgSW5qZWN0YWJsZSwgSW5qZWN0IH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBIdHRwQ2xpZW50IH0gZnJvbSAnQGFuZ3VsYXIvY29tbW9uL2h0dHAnO1xuaW1wb3J0IHsgT2JzZXJ2YWJsZSB9IGZyb20gJ3J4anMnO1xuaW1wb3J0IHsgbWFwIH0gZnJvbSAncnhqcy9vcGVyYXRvcnMnO1xuXG5pbXBvcnQgeyBWQUxURUNIX0FVVEhfQ09ORklHIH0gZnJvbSAnLi4vYXV0aC9jb25maWcnO1xuaW1wb3J0IHsgVmFsdGVjaEF1dGhDb25maWcgfSBmcm9tICcuLi9hdXRoL3R5cGVzJztcbmltcG9ydCB7XG4gIFZhbEdyb3VwLFxuICBWYWxHcm91cE1lbWJlcixcbiAgQ3JlYXRlR3JvdXBSZXF1ZXN0LFxuICBVcGRhdGVHcm91cFJlcXVlc3QsXG4gIEFkZEdyb3VwTWVtYmVyUmVxdWVzdCxcbiAgR3JvdXBSZXNwb25zZSxcbiAgTGlzdEdyb3Vwc1Jlc3BvbnNlLFxuICBMaXN0R3JvdXBNZW1iZXJzUmVzcG9uc2UsXG4gIE15R3JvdXBzUmVzcG9uc2UsXG59IGZyb20gJy4vdHlwZXMnO1xuXG4vKipcbiAqIENsaWVudGUgZGUgYC92Mi9ncm91cHMvKmAgKEFEUi0wODMpLiBTZXJ2aWNpbyBkZSBQTEFUQUZPUk1BOiBubyBzYWJlIHF1w6kgZXNcbiAqIHVuIGJsdWVwcmludCBuaSB1biByZWZ1Z2lvLCBzb2xvIGFncnVwYSByZWN1cnNvcyB5IHBlcnNvbmFzLiBDYWRhIGFwcCBsb1xuICogY29uc3VtZSBpZ3VhbCDigJQgZXMgbG8gcXVlIGV2aXRhIHJlZXNjcmliaXIgZXN0YSBjYXBhIHBvciBwcm9kdWN0by5cbiAqL1xuQEluamVjdGFibGUoeyBwcm92aWRlZEluOiAncm9vdCcgfSlcbmV4cG9ydCBjbGFzcyBHcm91cHNTZXJ2aWNlIHtcbiAgY29uc3RydWN0b3IoXG4gICAgQEluamVjdChWQUxURUNIX0FVVEhfQ09ORklHKSBwcml2YXRlIGNvbmZpZzogVmFsdGVjaEF1dGhDb25maWcsXG4gICAgcHJpdmF0ZSBodHRwOiBIdHRwQ2xpZW50XG4gICkge31cblxuICBwcml2YXRlIGdldCBiYXNlVXJsKCk6IHN0cmluZyB7XG4gICAgcmV0dXJuIGAke3RoaXMuY29uZmlnLmFwaVVybH0vdjIvZ3JvdXBzYDtcbiAgfVxuXG4gIC8qKiBHcnVwb3MgYWN0aXZvcyBkZSBsYSBvcmdhbml6YWNpw7NuIChmaWx0cmFkb3MgcG9yIGFwcCBlbiBlbCBiYWNrZW5kKS4gKi9cbiAgbGlzdEdyb3VwcygpOiBPYnNlcnZhYmxlPFZhbEdyb3VwW10+IHtcbiAgICByZXR1cm4gdGhpcy5odHRwXG4gICAgICAuZ2V0PExpc3RHcm91cHNSZXNwb25zZT4odGhpcy5iYXNlVXJsKVxuICAgICAgLnBpcGUobWFwKChyKSA9PiByLmdyb3VwcyA/PyBbXSkpO1xuICB9XG5cbiAgLyoqIEluY2x1eWUgYXJjaGl2YWRvczogcGFyYSBsYSBwYW50YWxsYSBkZSBhZG1pbmlzdHJhY2nDs24uICovXG4gIGxpc3RBbGxHcm91cHMoKTogT2JzZXJ2YWJsZTxWYWxHcm91cFtdPiB7XG4gICAgcmV0dXJuIHRoaXMuaHR0cFxuICAgICAgLmdldDxMaXN0R3JvdXBzUmVzcG9uc2U+KGAke3RoaXMuYmFzZVVybH0vYWxsYClcbiAgICAgIC5waXBlKG1hcCgocikgPT4gci5ncm91cHMgPz8gW10pKTtcbiAgfVxuXG4gIGdldEdyb3VwKGlkOiBzdHJpbmcpOiBPYnNlcnZhYmxlPFZhbEdyb3VwPiB7XG4gICAgcmV0dXJuIHRoaXMuaHR0cFxuICAgICAgLmdldDxHcm91cFJlc3BvbnNlPihgJHt0aGlzLmJhc2VVcmx9LyR7aWR9YClcbiAgICAgIC5waXBlKG1hcCgocikgPT4gci5ncm91cCkpO1xuICB9XG5cbiAgY3JlYXRlR3JvdXAocmVxOiBDcmVhdGVHcm91cFJlcXVlc3QpOiBPYnNlcnZhYmxlPFZhbEdyb3VwPiB7XG4gICAgcmV0dXJuIHRoaXMuaHR0cFxuICAgICAgLnBvc3Q8R3JvdXBSZXNwb25zZT4odGhpcy5iYXNlVXJsLCByZXEpXG4gICAgICAucGlwZShtYXAoKHIpID0+IHIuZ3JvdXApKTtcbiAgfVxuXG4gIHVwZGF0ZUdyb3VwKGlkOiBzdHJpbmcsIHJlcTogVXBkYXRlR3JvdXBSZXF1ZXN0KTogT2JzZXJ2YWJsZTxWYWxHcm91cD4ge1xuICAgIHJldHVybiB0aGlzLmh0dHBcbiAgICAgIC5wdXQ8R3JvdXBSZXNwb25zZT4oYCR7dGhpcy5iYXNlVXJsfS8ke2lkfWAsIHJlcSlcbiAgICAgIC5waXBlKG1hcCgocikgPT4gci5ncm91cCkpO1xuICB9XG5cbiAgLyoqXG4gICAqIE5vIGhheSBgZGVsZXRlR3JvdXBgOiBlbCBBRFItMDgzIGRlY2lkacOzIHF1ZSB1biBzZXJ2aWNpbyBkZSBwbGF0YWZvcm1hIG5vXG4gICAqIHB1ZWRlIHNhYmVyIHNpIHVuIHZlcnRpY2FsIHRvZGF2w61hIGFwdW50YSBhbCBncnVwbywgeSBjb21vIFwic2luIGdydXBvXCJcbiAgICogc2lnbmlmaWNhIHZpc2libGUgcGFyYSB0b2RhIGxhIG9yZ2FuaXphY2nDs24sIGJvcnJhcmxvIHB1YmxpY2Fyw61hIHN1c1xuICAgKiByZWN1cnNvcyBhIGxhIHBsYW50YSBlbnRlcmEuIGBhcmNoaXZlR3JvdXBgL2ByZXN0b3JlR3JvdXBgIGN1YnJlbiBsYVxuICAgKiBuZWNlc2lkYWQgcmVhbCBzaW4gZXNlIHJpZXNnby5cbiAgICovXG4gIGFyY2hpdmVHcm91cChpZDogc3RyaW5nKTogT2JzZXJ2YWJsZTxWYWxHcm91cD4ge1xuICAgIHJldHVybiB0aGlzLmh0dHBcbiAgICAgIC5wb3N0PEdyb3VwUmVzcG9uc2U+KGAke3RoaXMuYmFzZVVybH0vJHtpZH0vYXJjaGl2ZWAsIHt9KVxuICAgICAgLnBpcGUobWFwKChyKSA9PiByLmdyb3VwKSk7XG4gIH1cblxuICByZXN0b3JlR3JvdXAoaWQ6IHN0cmluZyk6IE9ic2VydmFibGU8VmFsR3JvdXA+IHtcbiAgICByZXR1cm4gdGhpcy5odHRwXG4gICAgICAucG9zdDxHcm91cFJlc3BvbnNlPihgJHt0aGlzLmJhc2VVcmx9LyR7aWR9L3Jlc3RvcmVgLCB7fSlcbiAgICAgIC5waXBlKG1hcCgocikgPT4gci5ncm91cCkpO1xuICB9XG5cbiAgbGlzdE1lbWJlcnMoZ3JvdXBJZDogc3RyaW5nKTogT2JzZXJ2YWJsZTxWYWxHcm91cE1lbWJlcltdPiB7XG4gICAgcmV0dXJuIHRoaXMuaHR0cFxuICAgICAgLmdldDxMaXN0R3JvdXBNZW1iZXJzUmVzcG9uc2U+KGAke3RoaXMuYmFzZVVybH0vJHtncm91cElkfS9tZW1iZXJzYClcbiAgICAgIC5waXBlKG1hcCgocikgPT4gci5tZW1iZXJzID8/IFtdKSk7XG4gIH1cblxuICBhZGRNZW1iZXIoZ3JvdXBJZDogc3RyaW5nLCByZXE6IEFkZEdyb3VwTWVtYmVyUmVxdWVzdCk6IE9ic2VydmFibGU8VmFsR3JvdXBNZW1iZXJbXT4ge1xuICAgIHJldHVybiB0aGlzLmh0dHBcbiAgICAgIC5wb3N0PExpc3RHcm91cE1lbWJlcnNSZXNwb25zZT4oYCR7dGhpcy5iYXNlVXJsfS8ke2dyb3VwSWR9L21lbWJlcnNgLCByZXEpXG4gICAgICAucGlwZShtYXAoKHIpID0+IHIubWVtYmVycyA/PyBbXSkpO1xuICB9XG5cbiAgcmVtb3ZlTWVtYmVyKGdyb3VwSWQ6IHN0cmluZywgdXNlcklkOiBzdHJpbmcpOiBPYnNlcnZhYmxlPFZhbEdyb3VwTWVtYmVyW10+IHtcbiAgICByZXR1cm4gdGhpcy5odHRwXG4gICAgICAuZGVsZXRlPExpc3RHcm91cE1lbWJlcnNSZXNwb25zZT4oYCR7dGhpcy5iYXNlVXJsfS8ke2dyb3VwSWR9L21lbWJlcnMvJHt1c2VySWR9YClcbiAgICAgIC5waXBlKG1hcCgocikgPT4gci5tZW1iZXJzID8/IFtdKSk7XG4gIH1cblxuICAvKiogTG9zIGdydXBvcyBkZWwgdXN1YXJpbyBhY3R1YWwuIFJlZmVyZW5jaWFsOiBlbCBmaWx0cmFkbyByZWFsIGNvcnJlIGVuIGVsIGJhY2tlbmQuICovXG4gIG15R3JvdXBzKCk6IE9ic2VydmFibGU8TXlHcm91cHNSZXNwb25zZT4ge1xuICAgIHJldHVybiB0aGlzLmh0dHAuZ2V0PE15R3JvdXBzUmVzcG9uc2U+KGAke3RoaXMuYmFzZVVybH0vbWluZWApO1xuICB9XG59XG4iXX0=
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHlwZXMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9zcmMvbGliL3NlcnZpY2VzL2dyb3Vwcy90eXBlcy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBHcnVwb3MgKEFEUi0wODMpIOKAlCBzdWJkaXZpc2nDs24gZGUgdW5hIG9yZ2FuaXphY2nDs24gcXVlIGFncnVwYSBSRUNVUlNPUyB5XG4gKiBQRVJTT05BUyBhIGxhIHZlei4gU2VydmljaW8gZGUgcGxhdGFmb3JtYSwgYWduw7NzdGljbyBkZSBkb21pbmlvOiBlbCBtaXNtb1xuICogY29udHJhdG8gc2lydmUgYSBsYSBsw61uZWEgZGUgcHJvZHVjY2nDs24gZGUgTWVyb3R6LCBhbCByZWZ1Z2lvIGRlIENoZXNlZCBvIGFsXG4gKiBldmVudG8gZGUgQmluZ28uIENhZGEgYXBwIGxlIHBvbmUgc3UgZXRpcXVldGEgKFwiRXF1aXBvXCIsIFwiU3VjdXJzYWxcIikgdsOtYSBpMThuXG4gKiDigJQgZWwgbW9kZWxvIG5vIGxhIHNhYmUuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgVmFsR3JvdXAge1xuICBpZDogc3RyaW5nO1xuICBvcmdJZDogc3RyaW5nO1xuICBhcHBJZDogc3RyaW5nO1xuICAvKiogRXRpcXVldGEgZGUgZG9taW5pbyBxdWUgZGVjbGFyYSBsYSBhcHA6IFwibWFjaGluZVwiLCBcInNoZWx0ZXJcIiwgXCJldmVudFwiLiAqL1xuICBraW5kPzogc3RyaW5nO1xuICAvKiogVGV4dG8gZGVsIENMSUVOVEUgKFwiTMOtbmVhIDNcIik6IG5vIHNlIHRyYWR1Y2UuICovXG4gIG5hbWU6IHN0cmluZztcbiAgcGFyZW50SWQ/OiBzdHJpbmc7XG4gIGFyY2hpdmVkOiBib29sZWFuO1xuICBjcmVhdGVkQXQ6IHN0cmluZztcbiAgY3JlYXRlZEJ5Pzogc3RyaW5nO1xuICB1cGRhdGVkQXQ6IHN0cmluZztcbn1cblxuZXhwb3J0IGludGVyZmFjZSBWYWxHcm91cE1lbWJlciB7XG4gIGdyb3VwSWQ6IHN0cmluZztcbiAgb3JnSWQ6IHN0cmluZztcbiAgdXNlcklkOiBzdHJpbmc7XG4gIGdyb3VwTmFtZT86IHN0cmluZztcbiAgYWRkZWRBdDogc3RyaW5nO1xuICBhZGRlZEJ5Pzogc3RyaW5nO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIENyZWF0ZUdyb3VwUmVxdWVzdCB7XG4gIG5hbWU6IHN0cmluZztcbiAga2luZD86IHN0cmluZztcbn1cblxuZXhwb3J0IGludGVyZmFjZSBVcGRhdGVHcm91cFJlcXVlc3Qge1xuICBuYW1lOiBzdHJpbmc7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgQWRkR3JvdXBNZW1iZXJSZXF1ZXN0IHtcbiAgdXNlcklkOiBzdHJpbmc7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgR3JvdXBSZXNwb25zZSB7XG4gIG9wZXJhdGlvbklkOiBzdHJpbmc7XG4gIGdyb3VwOiBWYWxHcm91cDtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBMaXN0R3JvdXBzUmVzcG9uc2Uge1xuICBvcGVyYXRpb25JZDogc3RyaW5nO1xuICBncm91cHM6IFZhbEdyb3VwW107XG4gIGNvdW50OiBudW1iZXI7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgTGlzdEdyb3VwTWVtYmVyc1Jlc3BvbnNlIHtcbiAgb3BlcmF0aW9uSWQ6IHN0cmluZztcbiAgbWVtYmVyczogVmFsR3JvdXBNZW1iZXJbXTtcbiAgY291bnQ6IG51bWJlcjtcbn1cblxuLyoqXG4gKiBSZXNwdWVzdGEgZGUgXCJtaXMgZ3J1cG9zXCI6IGxvIHF1ZSBhbGltZW50YSBlbCBmaWx0cmFkbyBkZWwgbGFkbyBkZWwgY2xpZW50ZVxuICogY3VhbmRvIGhhY2UgZmFsdGEgbW9zdHJhciBjb250ZXh0byAocC5lai4gcXXDqSBncnVwbyBlbGlnacOzIGVsIHVzdWFyaW8gcG9yXG4gKiBkZWZhdWx0KSwgYXVucXVlIGVsIGZpbHRyYWRvIHJlYWwgc2llbXByZSBjb3JyZSBlbiBlbCBiYWNrZW5kLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIE15R3JvdXBzUmVzcG9uc2Uge1xuICBvcGVyYXRpb25JZDogc3RyaW5nO1xuICBncm91cElkczogc3RyaW5nW107XG4gIC8qKlxuICAgKiBFbCB1c3VhcmlvIHZlIFRPRE9TIGxvcyBncnVwb3Mgc2luIGltcG9ydGFyIG1lbWJyZXPDrWEgKHBlcm1pc29cbiAgICogYGdyb3VwczphbGxgKS4gU2luIGBvbWl0ZW1wdHlgIGRlbCBsYWRvIGRlbCBiYWNrZW5kIGEgcHJvcMOzc2l0bzogdW5cbiAgICogYGZhbHNlYCBhdXNlbnRlIHNlcsOtYSBpbmRpc3Rpbmd1aWJsZSBkZSB1bmEgcmVzcHVlc3RhIHZpZWphLlxuICAgKi9cbiAgYWxsR3JvdXBzOiBib29sZWFuO1xuICBncm91cHM6IFZhbEdyb3VwTWVtYmVyW107XG59XG4iXX0=