ngx-dynamic-entity-builder 1.3.0 → 1.5.0
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/README.md +2 -1
- package/fesm2022/ngx-dynamic-entity-builder.mjs +521 -105
- package/fesm2022/ngx-dynamic-entity-builder.mjs.map +1 -1
- package/package.json +7 -7
- package/types/ngx-dynamic-entity-builder.d.ts +582 -0
- package/esm2022/lib/builder-store.service.mjs +0 -1057
- package/esm2022/lib/clone.mjs +0 -14
- package/esm2022/lib/components/entity-builder-canvas.component.mjs +0 -84
- package/esm2022/lib/components/entity-builder-tree-node.component.mjs +0 -192
- package/esm2022/lib/components/entity-reference-config.component.mjs +0 -405
- package/esm2022/lib/components/field-inspector.component.mjs +0 -139
- package/esm2022/lib/components/field-palette.component.mjs +0 -57
- package/esm2022/lib/components/field-rules-list.component.mjs +0 -224
- package/esm2022/lib/components/referenced-field-config.component.mjs +0 -235
- package/esm2022/lib/components/rule-form.component.mjs +0 -201
- package/esm2022/lib/components/tab-manager.component.mjs +0 -354
- package/esm2022/lib/entity-builder.component.mjs +0 -159
- package/esm2022/lib/field-catalog.mjs +0 -6
- package/esm2022/ngx-dynamic-entity-builder.mjs +0 -5
- package/esm2022/public-api.mjs +0 -16
- package/index.d.ts +0 -5
- package/lib/builder-store.service.d.ts +0 -206
- package/lib/clone.d.ts +0 -9
- package/lib/components/entity-builder-canvas.component.d.ts +0 -9
- package/lib/components/entity-builder-tree-node.component.d.ts +0 -17
- package/lib/components/entity-reference-config.component.d.ts +0 -29
- package/lib/components/field-inspector.component.d.ts +0 -33
- package/lib/components/field-palette.component.d.ts +0 -13
- package/lib/components/field-rules-list.component.d.ts +0 -19
- package/lib/components/referenced-field-config.component.d.ts +0 -24
- package/lib/components/rule-form.component.d.ts +0 -16
- package/lib/components/tab-manager.component.d.ts +0 -28
- package/lib/entity-builder.component.d.ts +0 -45
- package/lib/field-catalog.d.ts +0 -5
- package/public-api.d.ts +0 -12
|
@@ -1,235 +0,0 @@
|
|
|
1
|
-
import { ChangeDetectionStrategy, Component, computed, inject } from '@angular/core';
|
|
2
|
-
import { CommonModule } from '@angular/common';
|
|
3
|
-
import { FormsModule } from '@angular/forms';
|
|
4
|
-
import { MatButtonModule } from '@angular/material/button';
|
|
5
|
-
import { MatDividerModule } from '@angular/material/divider';
|
|
6
|
-
import { MatFormFieldModule } from '@angular/material/form-field';
|
|
7
|
-
import { MatIconModule } from '@angular/material/icon';
|
|
8
|
-
import { MatInputModule } from '@angular/material/input';
|
|
9
|
-
import { MatSlideToggleModule } from '@angular/material/slide-toggle';
|
|
10
|
-
import { ConfigSourceService } from 'ngx-dynamic-entity';
|
|
11
|
-
import { BuilderStore } from '../builder-store.service';
|
|
12
|
-
import * as i0 from "@angular/core";
|
|
13
|
-
import * as i1 from "@angular/forms";
|
|
14
|
-
import * as i2 from "@angular/material/button";
|
|
15
|
-
import * as i3 from "@angular/material/form-field";
|
|
16
|
-
import * as i4 from "@angular/material/icon";
|
|
17
|
-
import * as i5 from "@angular/material/input";
|
|
18
|
-
import * as i6 from "@angular/material/slide-toggle";
|
|
19
|
-
export class ReferencedFieldConfigComponent {
|
|
20
|
-
store = inject(BuilderStore);
|
|
21
|
-
configSource = inject(ConfigSourceService, { optional: true });
|
|
22
|
-
field = computed(() => this.store.selectedField());
|
|
23
|
-
toggleReferenced(field, enabled) {
|
|
24
|
-
if (enabled) {
|
|
25
|
-
this.store.updateField(field.id, { isReferenced: true });
|
|
26
|
-
}
|
|
27
|
-
else {
|
|
28
|
-
this.store.unlinkReferencedField(field.id);
|
|
29
|
-
}
|
|
30
|
-
}
|
|
31
|
-
updateEntityKey(field, key) {
|
|
32
|
-
const trimmed = key.trim();
|
|
33
|
-
this.store.updateField(field.id, { referencedEntityKey: trimmed || undefined });
|
|
34
|
-
this.checkDriftForField(field.id);
|
|
35
|
-
}
|
|
36
|
-
updateFieldId(field, fieldId) {
|
|
37
|
-
const trimmed = fieldId.trim();
|
|
38
|
-
this.store.updateField(field.id, { referencedFieldId: trimmed || undefined });
|
|
39
|
-
this.checkDriftForField(field.id);
|
|
40
|
-
}
|
|
41
|
-
async syncWithSource(field) {
|
|
42
|
-
if (!field.referencedEntityKey || !field.referencedFieldId || !this.configSource)
|
|
43
|
-
return;
|
|
44
|
-
const sourceConfig = await this.configSource.getConfig(field.referencedEntityKey);
|
|
45
|
-
if (!sourceConfig)
|
|
46
|
-
return;
|
|
47
|
-
const sourceField = this.findField(sourceConfig.tabs ?? [], field.referencedFieldId);
|
|
48
|
-
if (sourceField) {
|
|
49
|
-
this.store.syncReferencedField(field.id, sourceField);
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
/**
|
|
53
|
-
* Both callers pass the id of the field they just edited. This used to ignore that
|
|
54
|
-
* argument and read `store.selectedField()` instead, so whenever the edited field was not
|
|
55
|
-
* the selected one it checked drift against the wrong field's source entity — or bailed
|
|
56
|
-
* out entirely if nothing was selected.
|
|
57
|
-
*/
|
|
58
|
-
async checkDriftForField(fieldId) {
|
|
59
|
-
const f = this.store.fields().find(field => field.id === fieldId);
|
|
60
|
-
if (!f || !f.isReferenced || !f.referencedEntityKey || !f.referencedFieldId || !this.configSource)
|
|
61
|
-
return;
|
|
62
|
-
const sourceConfig = await this.configSource.getConfig(f.referencedEntityKey);
|
|
63
|
-
if (sourceConfig) {
|
|
64
|
-
this.store.checkDrift({ [f.referencedEntityKey]: sourceConfig });
|
|
65
|
-
}
|
|
66
|
-
}
|
|
67
|
-
findField(tabs, id) {
|
|
68
|
-
for (const t of tabs) {
|
|
69
|
-
for (const f of t.fields ?? []) {
|
|
70
|
-
if (f.id === id)
|
|
71
|
-
return f;
|
|
72
|
-
if (f.children?.length) {
|
|
73
|
-
const res = this.findFieldInList(f.children, id);
|
|
74
|
-
if (res)
|
|
75
|
-
return res;
|
|
76
|
-
}
|
|
77
|
-
}
|
|
78
|
-
}
|
|
79
|
-
return undefined;
|
|
80
|
-
}
|
|
81
|
-
findFieldInList(fields, id) {
|
|
82
|
-
for (const f of fields) {
|
|
83
|
-
if (f.id === id)
|
|
84
|
-
return f;
|
|
85
|
-
if (f.children?.length) {
|
|
86
|
-
const res = this.findFieldInList(f.children, id);
|
|
87
|
-
if (res)
|
|
88
|
-
return res;
|
|
89
|
-
}
|
|
90
|
-
}
|
|
91
|
-
return undefined;
|
|
92
|
-
}
|
|
93
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: ReferencedFieldConfigComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
94
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "17.3.12", type: ReferencedFieldConfigComponent, isStandalone: true, selector: "ngx-referenced-field-config", ngImport: i0, template: `
|
|
95
|
-
@if (field(); as f) {
|
|
96
|
-
<div class="deb-referenced-field" style="margin-top: 16px;">
|
|
97
|
-
<div class="deb-row" style="justify-content: space-between; align-items: center; margin-bottom: 8px;">
|
|
98
|
-
<span class="deb-section-title" style="margin:0;">Referenced Field</span>
|
|
99
|
-
<mat-slide-toggle
|
|
100
|
-
data-testid="toggle-referenced"
|
|
101
|
-
[ngModel]="f.isReferenced ?? false"
|
|
102
|
-
(ngModelChange)="toggleReferenced(f, $event)"
|
|
103
|
-
>
|
|
104
|
-
Link
|
|
105
|
-
</mat-slide-toggle>
|
|
106
|
-
</div>
|
|
107
|
-
|
|
108
|
-
@if (f.isReferenced) {
|
|
109
|
-
<mat-form-field appearance="outline" subscriptSizing="dynamic" class="deb-full" style="margin-bottom: 8px;">
|
|
110
|
-
<mat-label>Source Entity Key</mat-label>
|
|
111
|
-
<input
|
|
112
|
-
matInput
|
|
113
|
-
data-testid="referenced-entity-key"
|
|
114
|
-
[ngModel]="f.referencedEntityKey ?? ''"
|
|
115
|
-
(ngModelChange)="updateEntityKey(f, $event)"
|
|
116
|
-
placeholder="e.g. individuals"
|
|
117
|
-
/>
|
|
118
|
-
</mat-form-field>
|
|
119
|
-
|
|
120
|
-
<mat-form-field appearance="outline" subscriptSizing="dynamic" class="deb-full" style="margin-bottom: 8px;">
|
|
121
|
-
<mat-label>Source Field ID</mat-label>
|
|
122
|
-
<input
|
|
123
|
-
matInput
|
|
124
|
-
data-testid="referenced-field-id"
|
|
125
|
-
[ngModel]="f.referencedFieldId ?? ''"
|
|
126
|
-
(ngModelChange)="updateFieldId(f, $event)"
|
|
127
|
-
placeholder="e.g. firstName"
|
|
128
|
-
/>
|
|
129
|
-
</mat-form-field>
|
|
130
|
-
|
|
131
|
-
@if (f.hasDrift) {
|
|
132
|
-
<div class="deb-drift-banner" data-testid="drift-banner" style="background: #fff3e0; border: 1px solid #ffe0b2; padding: 8px 12px; border-radius: 4px; margin-top: 8px;">
|
|
133
|
-
<div class="deb-row" style="gap: 8px; align-items: center; color: #e65100; font-weight: 500;">
|
|
134
|
-
<mat-icon style="font-size: 18px; width:18px; height:18px;">warning</mat-icon>
|
|
135
|
-
<span>Source field definition has drifted!</span>
|
|
136
|
-
</div>
|
|
137
|
-
<p style="margin: 4px 0 8px 0; font-size: 12px; color: #666;">
|
|
138
|
-
The upstream field configuration in "{{ f.referencedEntityKey }}" has evolved.
|
|
139
|
-
</p>
|
|
140
|
-
<button
|
|
141
|
-
mat-flat-button
|
|
142
|
-
color="warn"
|
|
143
|
-
type="button"
|
|
144
|
-
data-testid="sync-source-btn"
|
|
145
|
-
(click)="syncWithSource(f)"
|
|
146
|
-
>
|
|
147
|
-
Sync with Source
|
|
148
|
-
</button>
|
|
149
|
-
</div>
|
|
150
|
-
}
|
|
151
|
-
}
|
|
152
|
-
</div>
|
|
153
|
-
}
|
|
154
|
-
`, isInline: true, dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i2.MatButton, selector: " button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ", exportAs: ["matButton"] }, { kind: "ngmodule", type: MatDividerModule }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "component", type: i3.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i3.MatLabel, selector: "mat-label" }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i4.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i5.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly"], exportAs: ["matInput"] }, { kind: "ngmodule", type: MatSlideToggleModule }, { kind: "component", type: i6.MatSlideToggle, selector: "mat-slide-toggle", inputs: ["name", "id", "labelPosition", "aria-label", "aria-labelledby", "aria-describedby", "required", "color", "disabled", "disableRipple", "tabIndex", "checked", "hideIcon"], outputs: ["change", "toggleChange"], exportAs: ["matSlideToggle"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
155
|
-
}
|
|
156
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: ReferencedFieldConfigComponent, decorators: [{
|
|
157
|
-
type: Component,
|
|
158
|
-
args: [{
|
|
159
|
-
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
160
|
-
selector: 'ngx-referenced-field-config',
|
|
161
|
-
standalone: true,
|
|
162
|
-
imports: [
|
|
163
|
-
CommonModule,
|
|
164
|
-
FormsModule,
|
|
165
|
-
MatButtonModule,
|
|
166
|
-
MatDividerModule,
|
|
167
|
-
MatFormFieldModule,
|
|
168
|
-
MatIconModule,
|
|
169
|
-
MatInputModule,
|
|
170
|
-
MatSlideToggleModule,
|
|
171
|
-
],
|
|
172
|
-
template: `
|
|
173
|
-
@if (field(); as f) {
|
|
174
|
-
<div class="deb-referenced-field" style="margin-top: 16px;">
|
|
175
|
-
<div class="deb-row" style="justify-content: space-between; align-items: center; margin-bottom: 8px;">
|
|
176
|
-
<span class="deb-section-title" style="margin:0;">Referenced Field</span>
|
|
177
|
-
<mat-slide-toggle
|
|
178
|
-
data-testid="toggle-referenced"
|
|
179
|
-
[ngModel]="f.isReferenced ?? false"
|
|
180
|
-
(ngModelChange)="toggleReferenced(f, $event)"
|
|
181
|
-
>
|
|
182
|
-
Link
|
|
183
|
-
</mat-slide-toggle>
|
|
184
|
-
</div>
|
|
185
|
-
|
|
186
|
-
@if (f.isReferenced) {
|
|
187
|
-
<mat-form-field appearance="outline" subscriptSizing="dynamic" class="deb-full" style="margin-bottom: 8px;">
|
|
188
|
-
<mat-label>Source Entity Key</mat-label>
|
|
189
|
-
<input
|
|
190
|
-
matInput
|
|
191
|
-
data-testid="referenced-entity-key"
|
|
192
|
-
[ngModel]="f.referencedEntityKey ?? ''"
|
|
193
|
-
(ngModelChange)="updateEntityKey(f, $event)"
|
|
194
|
-
placeholder="e.g. individuals"
|
|
195
|
-
/>
|
|
196
|
-
</mat-form-field>
|
|
197
|
-
|
|
198
|
-
<mat-form-field appearance="outline" subscriptSizing="dynamic" class="deb-full" style="margin-bottom: 8px;">
|
|
199
|
-
<mat-label>Source Field ID</mat-label>
|
|
200
|
-
<input
|
|
201
|
-
matInput
|
|
202
|
-
data-testid="referenced-field-id"
|
|
203
|
-
[ngModel]="f.referencedFieldId ?? ''"
|
|
204
|
-
(ngModelChange)="updateFieldId(f, $event)"
|
|
205
|
-
placeholder="e.g. firstName"
|
|
206
|
-
/>
|
|
207
|
-
</mat-form-field>
|
|
208
|
-
|
|
209
|
-
@if (f.hasDrift) {
|
|
210
|
-
<div class="deb-drift-banner" data-testid="drift-banner" style="background: #fff3e0; border: 1px solid #ffe0b2; padding: 8px 12px; border-radius: 4px; margin-top: 8px;">
|
|
211
|
-
<div class="deb-row" style="gap: 8px; align-items: center; color: #e65100; font-weight: 500;">
|
|
212
|
-
<mat-icon style="font-size: 18px; width:18px; height:18px;">warning</mat-icon>
|
|
213
|
-
<span>Source field definition has drifted!</span>
|
|
214
|
-
</div>
|
|
215
|
-
<p style="margin: 4px 0 8px 0; font-size: 12px; color: #666;">
|
|
216
|
-
The upstream field configuration in "{{ f.referencedEntityKey }}" has evolved.
|
|
217
|
-
</p>
|
|
218
|
-
<button
|
|
219
|
-
mat-flat-button
|
|
220
|
-
color="warn"
|
|
221
|
-
type="button"
|
|
222
|
-
data-testid="sync-source-btn"
|
|
223
|
-
(click)="syncWithSource(f)"
|
|
224
|
-
>
|
|
225
|
-
Sync with Source
|
|
226
|
-
</button>
|
|
227
|
-
</div>
|
|
228
|
-
}
|
|
229
|
-
}
|
|
230
|
-
</div>
|
|
231
|
-
}
|
|
232
|
-
`,
|
|
233
|
-
}]
|
|
234
|
-
}] });
|
|
235
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVmZXJlbmNlZC1maWVsZC1jb25maWcuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vc3JjL2xpYi9jb21wb25lbnRzL3JlZmVyZW5jZWQtZmllbGQtY29uZmlnLmNvbXBvbmVudC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsdUJBQXVCLEVBQUUsU0FBUyxFQUFFLFFBQVEsRUFBRSxNQUFNLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDckYsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBQy9DLE9BQU8sRUFBRSxXQUFXLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUM3QyxPQUFPLEVBQUUsZUFBZSxFQUFFLE1BQU0sMEJBQTBCLENBQUM7QUFDM0QsT0FBTyxFQUFFLGdCQUFnQixFQUFFLE1BQU0sMkJBQTJCLENBQUM7QUFDN0QsT0FBTyxFQUFFLGtCQUFrQixFQUFFLE1BQU0sOEJBQThCLENBQUM7QUFDbEUsT0FBTyxFQUFFLGFBQWEsRUFBRSxNQUFNLHdCQUF3QixDQUFDO0FBQ3ZELE9BQU8sRUFBRSxjQUFjLEVBQUUsTUFBTSx5QkFBeUIsQ0FBQztBQUN6RCxPQUFPLEVBQUUsb0JBQW9CLEVBQUUsTUFBTSxnQ0FBZ0MsQ0FBQztBQUN0RSxPQUFPLEVBQUUsbUJBQW1CLEVBQUUsTUFBTSxvQkFBb0IsQ0FBQztBQUV6RCxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0sMEJBQTBCLENBQUM7Ozs7Ozs7O0FBOEV4RCxNQUFNLE9BQU8sOEJBQThCO0lBQ3RCLEtBQUssR0FBRyxNQUFNLENBQUMsWUFBWSxDQUFDLENBQUM7SUFDN0IsWUFBWSxHQUFHLE1BQU0sQ0FBQyxtQkFBbUIsRUFBRSxFQUFFLFFBQVEsRUFBRSxJQUFJLEVBQUUsQ0FBK0IsQ0FBQztJQUM3RixLQUFLLEdBQUcsUUFBUSxDQUFDLEdBQUcsRUFBRSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsYUFB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NEZBZ0VYLDhCQUE4QjtrQkE1RTFDLFNBQVM7bUJBQUM7b0JBQ1QsZUFBZSxFQUFFLHVCQUF1QixDQUFDLE1BQU07b0JBQy9DLFFBQVEsRUFBRSw2QkFBNkI7b0JBQ3ZDLFVBQVUsRUFBRSxJQUFJO29CQUNoQixPQUFPLEVBQUU7d0JBQ1AsWUFBWTt3QkFDWixXQUFXO3dCQUNYLGVBQWU7d0JBQ2YsZ0JBQWdCO3dCQUNoQixrQkFBa0I7d0JBQ2xCLGFBQWE7d0JBQ2IsY0FBYzt3QkFDZCxvQkFBb0I7cUJBQ3JCO29CQUNELFFBQVEsRUFBRTs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBNERUO2lCQUNGIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3ksIENvbXBvbmVudCwgY29tcHV0ZWQsIGluamVjdCB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgQ29tbW9uTW9kdWxlIH0gZnJvbSAnQGFuZ3VsYXIvY29tbW9uJztcbmltcG9ydCB7IEZvcm1zTW9kdWxlIH0gZnJvbSAnQGFuZ3VsYXIvZm9ybXMnO1xuaW1wb3J0IHsgTWF0QnV0dG9uTW9kdWxlIH0gZnJvbSAnQGFuZ3VsYXIvbWF0ZXJpYWwvYnV0dG9uJztcbmltcG9ydCB7IE1hdERpdmlkZXJNb2R1bGUgfSBmcm9tICdAYW5ndWxhci9tYXRlcmlhbC9kaXZpZGVyJztcbmltcG9ydCB7IE1hdEZvcm1GaWVsZE1vZHVsZSB9IGZyb20gJ0Bhbmd1bGFyL21hdGVyaWFsL2Zvcm0tZmllbGQnO1xuaW1wb3J0IHsgTWF0SWNvbk1vZHVsZSB9IGZyb20gJ0Bhbmd1bGFyL21hdGVyaWFsL2ljb24nO1xuaW1wb3J0IHsgTWF0SW5wdXRNb2R1bGUgfSBmcm9tICdAYW5ndWxhci9tYXRlcmlhbC9pbnB1dCc7XG5pbXBvcnQgeyBNYXRTbGlkZVRvZ2dsZU1vZHVsZSB9IGZyb20gJ0Bhbmd1bGFyL21hdGVyaWFsL3NsaWRlLXRvZ2dsZSc7XG5pbXBvcnQgeyBDb25maWdTb3VyY2VTZXJ2aWNlIH0gZnJvbSAnbmd4LWR5bmFtaWMtZW50aXR5JztcbmltcG9ydCB0eXBlIHsgTmVzdGVkRmllbGRDb25maWcgfSBmcm9tICdAZHluYW1pYy1lbnRpdHkvY29yZSc7XG5pbXBvcnQgeyBCdWlsZGVyU3RvcmUgfSBmcm9tICcuLi9idWlsZGVyLXN0b3JlLnNlcnZpY2UnO1xuXG5AQ29tcG9uZW50KHtcbiAgY2hhbmdlRGV0ZWN0aW9uOiBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneS5PblB1c2gsXG4gIHNlbGVjdG9yOiAnbmd4LXJlZmVyZW5jZWQtZmllbGQtY29uZmlnJyxcbiAgc3RhbmRhbG9uZTogdHJ1ZSxcbiAgaW1wb3J0czogW1xuICAgIENvbW1vbk1vZHVsZSxcbiAgICBGb3Jtc01vZHVsZSxcbiAgICBNYXRCdXR0b25Nb2R1bGUsXG4gICAgTWF0RGl2aWRlck1vZHVsZSxcbiAgICBNYXRGb3JtRmllbGRNb2R1bGUsXG4gICAgTWF0SWNvbk1vZHVsZSxcbiAgICBNYXRJbnB1dE1vZHVsZSxcbiAgICBNYXRTbGlkZVRvZ2dsZU1vZHVsZSxcbiAgXSxcbiAgdGVtcGxhdGU6IGBcbiAgICBAaWYgKGZpZWxkKCk7IGFzIGYpIHtcbiAgICAgIDxkaXYgY2xhc3M9XCJkZWItcmVmZXJlbmNlZC1maWVsZFwiIHN0eWxlPVwibWFyZ2luLXRvcDogMTZweDtcIj5cbiAgICAgICAgPGRpdiBjbGFzcz1cImRlYi1yb3dcIiBzdHlsZT1cImp1c3RpZnktY29udGVudDogc3BhY2UtYmV0d2VlbjsgYWxpZ24taXRlbXM6IGNlbnRlcjsgbWFyZ2luLWJvdHRvbTogOHB4O1wiPlxuICAgICAgICAgIDxzcGFuIGNsYXNzPVwiZGViLXNlY3Rpb24tdGl0bGVcIiBzdHlsZT1cIm1hcmdpbjowO1wiPlJlZmVyZW5jZWQgRmllbGQ8L3NwYW4+XG4gICAgICAgICAgPG1hdC1zbGlkZS10b2dnbGVcbiAgICAgICAgICAgIGRhdGEtdGVzdGlkPVwidG9nZ2xlLXJlZmVyZW5jZWRcIlxuICAgICAgICAgICAgW25nTW9kZWxdPVwiZi5pc1JlZmVyZW5jZWQgPz8gZmFsc2VcIlxuICAgICAgICAgICAgKG5nTW9kZWxDaGFuZ2UpPVwidG9nZ2xlUmVmZXJlbmNlZChmLCAkZXZlbnQpXCJcbiAgICAgICAgICA+XG4gICAgICAgICAgICBMaW5rXG4gICAgICAgICAgPC9tYXQtc2xpZGUtdG9nZ2xlPlxuICAgICAgICA8L2Rpdj5cblxuICAgICAgICBAaWYgKGYuaXNSZWZlcmVuY2VkKSB7XG4gICAgICAgICAgPG1hdC1mb3JtLWZpZWxkIGFwcGVhcmFuY2U9XCJvdXRsaW5lXCIgc3Vic2NyaXB0U2l6aW5nPVwiZHluYW1pY1wiIGNsYXNzPVwiZGViLWZ1bGxcIiBzdHlsZT1cIm1hcmdpbi1ib3R0b206IDhweDtcIj5cbiAgICAgICAgICAgIDxtYXQtbGFiZWw+U291cmNlIEVudGl0eSBLZXk8L21hdC1sYWJlbD5cbiAgICAgICAgICAgIDxpbnB1dFxuICAgICAgICAgICAgICBtYXRJbnB1dFxuICAgICAgICAgICAgICBkYXRhLXRlc3RpZD1cInJlZmVyZW5jZWQtZW50aXR5LWtleVwiXG4gICAgICAgICAgICAgIFtuZ01vZGVsXT1cImYucmVmZXJlbmNlZEVudGl0eUtleSA/PyAnJ1wiXG4gICAgICAgICAgICAgIChuZ01vZGVsQ2hhbmdlKT1cInVwZGF0ZUVudGl0eUtleShmLCAkZXZlbnQpXCJcbiAgICAgICAgICAgICAgcGxhY2Vob2xkZXI9XCJlLmcuIGluZGl2aWR1YWxzXCJcbiAgICAgICAgICAgIC8+XG4gICAgICAgICAgPC9tYXQtZm9ybS1maWVsZD5cblxuICAgICAgICAgIDxtYXQtZm9ybS1maWVsZCBhcHBlYXJhbmNlPVwib3V0bGluZVwiIHN1YnNjcmlwdFNpemluZz1cImR5bmFtaWNcIiBjbGFzcz1cImRlYi1mdWxsXCIgc3R5bGU9XCJtYXJnaW4tYm90dG9tOiA4cHg7XCI+XG4gICAgICAgICAgICA8bWF0LWxhYmVsPlNvdXJjZSBGaWVsZCBJRDwvbWF0LWxhYmVsPlxuICAgICAgICAgICAgPGlucHV0XG4gICAgICAgICAgICAgIG1hdElucHV0XG4gICAgICAgICAgICAgIGRhdGEtdGVzdGlkPVwicmVmZXJlbmNlZC1maWVsZC1pZFwiXG4gICAgICAgICAgICAgIFtuZ01vZGVsXT1cImYucmVmZXJlbmNlZEZpZWxkSWQgPz8gJydcIlxuICAgICAgICAgICAgICAobmdNb2RlbENoYW5nZSk9XCJ1cGRhdGVGaWVsZElkKGYsICRldmVudClcIlxuICAgICAgICAgICAgICBwbGFjZWhvbGRlcj1cImUuZy4gZmlyc3ROYW1lXCJcbiAgICAgICAgICAgIC8+XG4gICAgICAgICAgPC9tYXQtZm9ybS1maWVsZD5cblxuICAgICAgICAgIEBpZiAoZi5oYXNEcmlmdCkge1xuICAgICAgICAgICAgPGRpdiBjbGFzcz1cImRlYi1kcmlmdC1iYW5uZXJcIiBkYXRhLXRlc3RpZD1cImRyaWZ0LWJhbm5lclwiIHN0eWxlPVwiYmFja2dyb3VuZDogI2ZmZjNlMDsgYm9yZGVyOiAxcHggc29saWQgI2ZmZTBiMjsgcGFkZGluZzogOHB4IDEycHg7IGJvcmRlci1yYWRpdXM6IDRweDsgbWFyZ2luLXRvcDogOHB4O1wiPlxuICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZGViLXJvd1wiIHN0eWxlPVwiZ2FwOiA4cHg7IGFsaWduLWl0ZW1zOiBjZW50ZXI7IGNvbG9yOiAjZTY1MTAwOyBmb250LXdlaWdodDogNTAwO1wiPlxuICAgICAgICAgICAgICAgIDxtYXQtaWNvbiBzdHlsZT1cImZvbnQtc2l6ZTogMThweDsgd2lkdGg6MThweDsgaGVpZ2h0OjE4cHg7XCI+d2FybmluZzwvbWF0LWljb24+XG4gICAgICAgICAgICAgICAgPHNwYW4+U291cmNlIGZpZWxkIGRlZmluaXRpb24gaGFzIGRyaWZ0ZWQhPC9zcGFuPlxuICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgPHAgc3R5bGU9XCJtYXJnaW46IDRweCAwIDhweCAwOyBmb250LXNpemU6IDEycHg7IGNvbG9yOiAjNjY2O1wiPlxuICAgICAgICAgICAgICAgIFRoZSB1cHN0cmVhbSBmaWVsZCBjb25maWd1cmF0aW9uIGluIFwie3sgZi5yZWZlcmVuY2VkRW50aXR5S2V5IH19XCIgaGFzIGV2b2x2ZWQuXG4gICAgICAgICAgICAgIDwvcD5cbiAgICAgICAgICAgICAgPGJ1dHRvblxuICAgICAgICAgICAgICAgIG1hdC1mbGF0LWJ1dHRvblxuICAgICAgICAgICAgICAgIGNvbG9yPVwid2FyblwiXG4gICAgICAgICAgICAgICAgdHlwZT1cImJ1dHRvblwiXG4gICAgICAgICAgICAgICAgZGF0YS10ZXN0aWQ9XCJzeW5jLXNvdXJjZS1idG5cIlxuICAgICAgICAgICAgICAgIChjbGljayk9XCJzeW5jV2l0aFNvdXJjZShmKVwiXG4gICAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgICBTeW5jIHdpdGggU291cmNlXG4gICAgICAgICAgICAgIDwvYnV0dG9uPlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICA8L2Rpdj5cbiAgICB9XG4gIGAsXG59KVxuZXhwb3J0IGNsYXNzIFJlZmVyZW5jZWRGaWVsZENvbmZpZ0NvbXBvbmVudCB7XG4gIHByb3RlY3RlZCByZWFkb25seSBzdG9yZSA9IGluamVjdChCdWlsZGVyU3RvcmUpO1xuICBwcm90ZWN0ZWQgcmVhZG9ubHkgY29uZmlnU291cmNlID0gaW5qZWN0KENvbmZpZ1NvdXJjZVNlcnZpY2UsIHsgb3B0aW9uYWw6IHRydWUgfSkgYXMgQ29uZmlnU291cmNlU2VydmljZSB8IG51bGw7XG4gIHByb3RlY3RlZCByZWFkb25seSBmaWVsZCA9IGNvbXB1dGVkKCgpID0+IHRoaXMuc3RvcmUuc2VsZWN0ZWRGaWVsZCgpKTtcblxuICBwcm90ZWN0ZWQgdG9nZ2xlUmVmZXJlbmNlZChmaWVsZDogTmVzdGVkRmllbGRDb25maWcsIGVuYWJsZWQ6IGJvb2xlYW4pOiB2b2lkIHtcbiAgICBpZiAoZW5hYmxlZCkge1xuICAgICAgdGhpcy5zdG9yZS51cGRhdGVGaWVsZChmaWVsZC5pZCwgeyBpc1JlZmVyZW5jZWQ6IHRydWUgfSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuc3RvcmUudW5saW5rUmVmZXJlbmNlZEZpZWxkKGZpZWxkLmlkKTtcbiAgICB9XG4gIH1cblxuICBwcm90ZWN0ZWQgdXBkYXRlRW50aXR5S2V5KGZpZWxkOiBOZXN0ZWRGaWVsZENvbmZpZywga2V5OiBzdHJpbmcpOiB2b2lkIHtcbiAgICBjb25zdCB0cmltbWVkID0ga2V5LnRyaW0oKTtcbiAgICB0aGlzLnN0b3JlLnVwZGF0ZUZpZWxkKGZpZWxkLmlkLCB7IHJlZmVyZW5jZWRFbnRpdHlLZXk6IHRyaW1tZWQgfHwgdW5kZWZpbmVkIH0pO1xuICAgIHRoaXMuY2hlY2tEcmlmdEZvckZpZWxkKGZpZWxkLmlkKTtcbiAgfVxuXG4gIHByb3RlY3RlZCB1cGRhdGVGaWVsZElkKGZpZWxkOiBOZXN0ZWRGaWVsZENvbmZpZywgZmllbGRJZDogc3RyaW5nKTogdm9pZCB7XG4gICAgY29uc3QgdHJpbW1lZCA9IGZpZWxkSWQudHJpbSgpO1xuICAgIHRoaXMuc3RvcmUudXBkYXRlRmllbGQoZmllbGQuaWQsIHsgcmVmZXJlbmNlZEZpZWxkSWQ6IHRyaW1tZWQgfHwgdW5kZWZpbmVkIH0pO1xuICAgIHRoaXMuY2hlY2tEcmlmdEZvckZpZWxkKGZpZWxkLmlkKTtcbiAgfVxuXG4gIHByb3RlY3RlZCBhc3luYyBzeW5jV2l0aFNvdXJjZShmaWVsZDogTmVzdGVkRmllbGRDb25maWcpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBpZiAoIWZpZWxkLnJlZmVyZW5jZWRFbnRpdHlLZXkgfHwgIWZpZWxkLnJlZmVyZW5jZWRGaWVsZElkIHx8ICF0aGlzLmNvbmZpZ1NvdXJjZSkgcmV0dXJuO1xuICAgIGNvbnN0IHNvdXJjZUNvbmZpZyA9IGF3YWl0IHRoaXMuY29uZmlnU291cmNlLmdldENvbmZpZyhmaWVsZC5yZWZlcmVuY2VkRW50aXR5S2V5KTtcbiAgICBpZiAoIXNvdXJjZUNvbmZpZykgcmV0dXJuO1xuXG4gICAgY29uc3Qgc291cmNlRmllbGQgPSB0aGlzLmZpbmRGaWVsZChzb3VyY2VDb25maWcudGFicyA/PyBbXSwgZmllbGQucmVmZXJlbmNlZEZpZWxkSWQpO1xuICAgIGlmIChzb3VyY2VGaWVsZCkge1xuICAgICAgdGhpcy5zdG9yZS5zeW5jUmVmZXJlbmNlZEZpZWxkKGZpZWxkLmlkLCBzb3VyY2VGaWVsZCk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIEJvdGggY2FsbGVycyBwYXNzIHRoZSBpZCBvZiB0aGUgZmllbGQgdGhleSBqdXN0IGVkaXRlZC4gVGhpcyB1c2VkIHRvIGlnbm9yZSB0aGF0XG4gICAqIGFyZ3VtZW50IGFuZCByZWFkIGBzdG9yZS5zZWxlY3RlZEZpZWxkKClgIGluc3RlYWQsIHNvIHdoZW5ldmVyIHRoZSBlZGl0ZWQgZmllbGQgd2FzIG5vdFxuICAgKiB0aGUgc2VsZWN0ZWQgb25lIGl0IGNoZWNrZWQgZHJpZnQgYWdhaW5zdCB0aGUgd3JvbmcgZmllbGQncyBzb3VyY2UgZW50aXR5IOKAlCBvciBiYWlsZWRcbiAgICogb3V0IGVudGlyZWx5IGlmIG5vdGhpbmcgd2FzIHNlbGVjdGVkLlxuICAgKi9cbiAgcHJpdmF0ZSBhc3luYyBjaGVja0RyaWZ0Rm9yRmllbGQoZmllbGRJZDogc3RyaW5nKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgY29uc3QgZiA9IHRoaXMuc3RvcmUuZmllbGRzKCkuZmluZChmaWVsZCA9PiBmaWVsZC5pZCA9PT0gZmllbGRJZCk7XG4gICAgaWYgKCFmIHx8ICFmLmlzUmVmZXJlbmNlZCB8fCAhZi5yZWZlcmVuY2VkRW50aXR5S2V5IHx8ICFmLnJlZmVyZW5jZWRGaWVsZElkIHx8ICF0aGlzLmNvbmZpZ1NvdXJjZSkgcmV0dXJuO1xuICAgIGNvbnN0IHNvdXJjZUNvbmZpZyA9IGF3YWl0IHRoaXMuY29uZmlnU291cmNlLmdldENvbmZpZyhmLnJlZmVyZW5jZWRFbnRpdHlLZXkpO1xuICAgIGlmIChzb3VyY2VDb25maWcpIHtcbiAgICAgIHRoaXMuc3RvcmUuY2hlY2tEcmlmdCh7IFtmLnJlZmVyZW5jZWRFbnRpdHlLZXldOiBzb3VyY2VDb25maWcgfSk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBmaW5kRmllbGQodGFiczogYW55W10sIGlkOiBzdHJpbmcpOiBOZXN0ZWRGaWVsZENvbmZpZyB8IHVuZGVmaW5lZCB7XG4gICAgZm9yIChjb25zdCB0IG9mIHRhYnMpIHtcbiAgICAgIGZvciAoY29uc3QgZiBvZiB0LmZpZWxkcyA/PyBbXSkge1xuICAgICAgICBpZiAoZi5pZCA9PT0gaWQpIHJldHVybiBmO1xuICAgICAgICBpZiAoZi5jaGlsZHJlbj8ubGVuZ3RoKSB7XG4gICAgICAgICAgY29uc3QgcmVzID0gdGhpcy5maW5kRmllbGRJbkxpc3QoZi5jaGlsZHJlbiwgaWQpO1xuICAgICAgICAgIGlmIChyZXMpIHJldHVybiByZXM7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgfVxuXG4gIHByaXZhdGUgZmluZEZpZWxkSW5MaXN0KGZpZWxkczogTmVzdGVkRmllbGRDb25maWdbXSwgaWQ6IHN0cmluZyk6IE5lc3RlZEZpZWxkQ29uZmlnIHwgdW5kZWZpbmVkIHtcbiAgICBmb3IgKGNvbnN0IGYgb2YgZmllbGRzKSB7XG4gICAgICBpZiAoZi5pZCA9PT0gaWQpIHJldHVybiBmO1xuICAgICAgaWYgKGYuY2hpbGRyZW4/Lmxlbmd0aCkge1xuICAgICAgICBjb25zdCByZXMgPSB0aGlzLmZpbmRGaWVsZEluTGlzdChmLmNoaWxkcmVuLCBpZCk7XG4gICAgICAgIGlmIChyZXMpIHJldHVybiByZXM7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiB1bmRlZmluZWQ7XG4gIH1cbn1cbiJdfQ==
|
|
@@ -1,201 +0,0 @@
|
|
|
1
|
-
import { ChangeDetectionStrategy, Component, EventEmitter, Input, Output } from '@angular/core';
|
|
2
|
-
import { CommonModule } from '@angular/common';
|
|
3
|
-
import { FormsModule } from '@angular/forms';
|
|
4
|
-
import { MatButtonModule } from '@angular/material/button';
|
|
5
|
-
import { MatFormFieldModule } from '@angular/material/form-field';
|
|
6
|
-
import { MatIconModule } from '@angular/material/icon';
|
|
7
|
-
import { MatInputModule } from '@angular/material/input';
|
|
8
|
-
import { MatSelectModule } from '@angular/material/select';
|
|
9
|
-
import * as i0 from "@angular/core";
|
|
10
|
-
import * as i1 from "@angular/forms";
|
|
11
|
-
import * as i2 from "@angular/material/button";
|
|
12
|
-
import * as i3 from "@angular/material/form-field";
|
|
13
|
-
import * as i4 from "@angular/material/icon";
|
|
14
|
-
import * as i5 from "@angular/material/input";
|
|
15
|
-
import * as i6 from "@angular/material/select";
|
|
16
|
-
import * as i7 from "@angular/material/core";
|
|
17
|
-
/**
|
|
18
|
-
* RuleFormComponent — dialog/panel form for creating or editing a FormRule.
|
|
19
|
-
*/
|
|
20
|
-
export class RuleFormComponent {
|
|
21
|
-
rule = {
|
|
22
|
-
formConfigId: 'form-1',
|
|
23
|
-
fieldId: '',
|
|
24
|
-
conditions: [{ operator: 'EQUAL', compareType: 'value', value: '' }],
|
|
25
|
-
action: { type: 'visibility', value: false },
|
|
26
|
-
targets: [],
|
|
27
|
-
enabled: true,
|
|
28
|
-
priority: 1,
|
|
29
|
-
};
|
|
30
|
-
save = new EventEmitter();
|
|
31
|
-
cancel = new EventEmitter();
|
|
32
|
-
operators = [
|
|
33
|
-
'EQUAL',
|
|
34
|
-
'NOT_EQUAL',
|
|
35
|
-
'CONTAINS',
|
|
36
|
-
'NOT_CONTAINS',
|
|
37
|
-
'STARTS_WITH',
|
|
38
|
-
'ENDS_WITH',
|
|
39
|
-
'IS_EMPTY',
|
|
40
|
-
'IS_NOT_EMPTY',
|
|
41
|
-
'LESS_THAN',
|
|
42
|
-
'MORE_THAN',
|
|
43
|
-
'LESS_THAN_EQUAL',
|
|
44
|
-
'MORE_THAN_EQUAL',
|
|
45
|
-
'DATE_BEFORE',
|
|
46
|
-
'DATE_AFTER',
|
|
47
|
-
'IN',
|
|
48
|
-
'NOT_IN',
|
|
49
|
-
'HAS_ITEMS',
|
|
50
|
-
'VALUE_CHANGED',
|
|
51
|
-
];
|
|
52
|
-
addCondition() {
|
|
53
|
-
this.rule.conditions.push({ operator: 'EQUAL', compareType: 'value', value: '' });
|
|
54
|
-
}
|
|
55
|
-
removeCondition(index) {
|
|
56
|
-
this.rule.conditions.splice(index, 1);
|
|
57
|
-
}
|
|
58
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: RuleFormComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
59
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "17.3.12", type: RuleFormComponent, isStandalone: true, selector: "ngx-rule-form", inputs: { rule: "rule" }, outputs: { save: "save", cancel: "cancel" }, ngImport: i0, template: `
|
|
60
|
-
<div class="deb-rule-form">
|
|
61
|
-
<h3 class="deb-rule-form__title">{{ rule.id ? 'Edit Rule' : 'New Form Rule' }}</h3>
|
|
62
|
-
|
|
63
|
-
<!-- Trigger Field -->
|
|
64
|
-
<mat-form-field appearance="outline" subscriptSizing="dynamic" class="deb-full">
|
|
65
|
-
<mat-label>Trigger Field ID</mat-label>
|
|
66
|
-
<input matInput [(ngModel)]="rule.fieldId" placeholder="e.g. status" />
|
|
67
|
-
</mat-form-field>
|
|
68
|
-
|
|
69
|
-
<!-- Conditions -->
|
|
70
|
-
<div class="deb-rule-section">
|
|
71
|
-
<h4>Conditions</h4>
|
|
72
|
-
@for (cond of rule.conditions; track $index) {
|
|
73
|
-
<div class="deb-rule-row">
|
|
74
|
-
<mat-form-field appearance="outline" subscriptSizing="dynamic">
|
|
75
|
-
<mat-label>Operator</mat-label>
|
|
76
|
-
<mat-select [(ngModel)]="cond.operator">
|
|
77
|
-
@for (op of operators; track op) {
|
|
78
|
-
<mat-option [value]="op">{{ op }}</mat-option>
|
|
79
|
-
}
|
|
80
|
-
</mat-select>
|
|
81
|
-
</mat-form-field>
|
|
82
|
-
<mat-form-field appearance="outline" subscriptSizing="dynamic">
|
|
83
|
-
<mat-label>Value</mat-label>
|
|
84
|
-
<input matInput [(ngModel)]="cond.value" placeholder="Condition value" />
|
|
85
|
-
</mat-form-field>
|
|
86
|
-
<button mat-icon-button color="warn" type="button" (click)="removeCondition($index)">
|
|
87
|
-
<mat-icon>delete</mat-icon>
|
|
88
|
-
</button>
|
|
89
|
-
</div>
|
|
90
|
-
}
|
|
91
|
-
<button mat-stroked-button type="button" (click)="addCondition()">
|
|
92
|
-
<mat-icon>add</mat-icon> Add Condition
|
|
93
|
-
</button>
|
|
94
|
-
</div>
|
|
95
|
-
|
|
96
|
-
<!-- Action -->
|
|
97
|
-
<div class="deb-rule-section">
|
|
98
|
-
<h4>Action</h4>
|
|
99
|
-
<div class="deb-rule-row">
|
|
100
|
-
<mat-form-field appearance="outline" subscriptSizing="dynamic">
|
|
101
|
-
<mat-label>Action Type</mat-label>
|
|
102
|
-
<mat-select [(ngModel)]="rule.action.type">
|
|
103
|
-
<mat-option value="visibility">Visibility (Show/Hide)</mat-option>
|
|
104
|
-
<mat-option value="validation">Validation Message</mat-option>
|
|
105
|
-
<mat-option value="info">Info Banner</mat-option>
|
|
106
|
-
</mat-select>
|
|
107
|
-
</mat-form-field>
|
|
108
|
-
<mat-form-field appearance="outline" subscriptSizing="dynamic">
|
|
109
|
-
<mat-label>Value / Message</mat-label>
|
|
110
|
-
<input matInput [(ngModel)]="rule.action.value" placeholder="false to hide, or message text" />
|
|
111
|
-
</mat-form-field>
|
|
112
|
-
</div>
|
|
113
|
-
</div>
|
|
114
|
-
|
|
115
|
-
<div class="deb-rule-form__actions">
|
|
116
|
-
<button mat-button type="button" (click)="cancel.emit()">Cancel</button>
|
|
117
|
-
<button mat-raised-button color="primary" type="button" (click)="save.emit(rule)">Save Rule</button>
|
|
118
|
-
</div>
|
|
119
|
-
</div>
|
|
120
|
-
`, isInline: true, styles: [".deb-rule-form{display:flex;flex-direction:column;gap:12px;background:#fafafa;border:1px solid #e0e0e0;border-radius:8px;padding:16px}.deb-rule-form__title{margin:0 0 8px;font-size:16px;font-weight:600}.deb-full{width:100%}.deb-rule-section{display:flex;flex-direction:column;gap:8px}.deb-rule-section h4{margin:0;font-size:13px;font-weight:600;color:#555}.deb-rule-row{display:flex;gap:8px;align-items:center}.deb-rule-row>*{flex:1}.deb-rule-form__actions{display:flex;justify-content:flex-end;gap:8px;margin-top:8px}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i2.MatButton, selector: " button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ", exportAs: ["matButton"] }, { kind: "component", type: i2.MatIconButton, selector: "button[mat-icon-button]", exportAs: ["matButton"] }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "component", type: i3.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i3.MatLabel, selector: "mat-label" }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i4.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i5.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly"], exportAs: ["matInput"] }, { kind: "ngmodule", type: MatSelectModule }, { kind: "component", type: i6.MatSelect, selector: "mat-select", inputs: ["aria-describedby", "panelClass", "disabled", "disableRipple", "tabIndex", "hideSingleSelectionIndicator", "placeholder", "required", "multiple", "disableOptionCentering", "compareWith", "value", "aria-label", "aria-labelledby", "errorStateMatcher", "typeaheadDebounceInterval", "sortComparator", "id", "panelWidth"], outputs: ["openedChange", "opened", "closed", "selectionChange", "valueChange"], exportAs: ["matSelect"] }, { kind: "component", type: i7.MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
121
|
-
}
|
|
122
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: RuleFormComponent, decorators: [{
|
|
123
|
-
type: Component,
|
|
124
|
-
args: [{ changeDetection: ChangeDetectionStrategy.OnPush, selector: 'ngx-rule-form', standalone: true, imports: [
|
|
125
|
-
CommonModule,
|
|
126
|
-
FormsModule,
|
|
127
|
-
MatButtonModule,
|
|
128
|
-
MatFormFieldModule,
|
|
129
|
-
MatIconModule,
|
|
130
|
-
MatInputModule,
|
|
131
|
-
MatSelectModule,
|
|
132
|
-
], template: `
|
|
133
|
-
<div class="deb-rule-form">
|
|
134
|
-
<h3 class="deb-rule-form__title">{{ rule.id ? 'Edit Rule' : 'New Form Rule' }}</h3>
|
|
135
|
-
|
|
136
|
-
<!-- Trigger Field -->
|
|
137
|
-
<mat-form-field appearance="outline" subscriptSizing="dynamic" class="deb-full">
|
|
138
|
-
<mat-label>Trigger Field ID</mat-label>
|
|
139
|
-
<input matInput [(ngModel)]="rule.fieldId" placeholder="e.g. status" />
|
|
140
|
-
</mat-form-field>
|
|
141
|
-
|
|
142
|
-
<!-- Conditions -->
|
|
143
|
-
<div class="deb-rule-section">
|
|
144
|
-
<h4>Conditions</h4>
|
|
145
|
-
@for (cond of rule.conditions; track $index) {
|
|
146
|
-
<div class="deb-rule-row">
|
|
147
|
-
<mat-form-field appearance="outline" subscriptSizing="dynamic">
|
|
148
|
-
<mat-label>Operator</mat-label>
|
|
149
|
-
<mat-select [(ngModel)]="cond.operator">
|
|
150
|
-
@for (op of operators; track op) {
|
|
151
|
-
<mat-option [value]="op">{{ op }}</mat-option>
|
|
152
|
-
}
|
|
153
|
-
</mat-select>
|
|
154
|
-
</mat-form-field>
|
|
155
|
-
<mat-form-field appearance="outline" subscriptSizing="dynamic">
|
|
156
|
-
<mat-label>Value</mat-label>
|
|
157
|
-
<input matInput [(ngModel)]="cond.value" placeholder="Condition value" />
|
|
158
|
-
</mat-form-field>
|
|
159
|
-
<button mat-icon-button color="warn" type="button" (click)="removeCondition($index)">
|
|
160
|
-
<mat-icon>delete</mat-icon>
|
|
161
|
-
</button>
|
|
162
|
-
</div>
|
|
163
|
-
}
|
|
164
|
-
<button mat-stroked-button type="button" (click)="addCondition()">
|
|
165
|
-
<mat-icon>add</mat-icon> Add Condition
|
|
166
|
-
</button>
|
|
167
|
-
</div>
|
|
168
|
-
|
|
169
|
-
<!-- Action -->
|
|
170
|
-
<div class="deb-rule-section">
|
|
171
|
-
<h4>Action</h4>
|
|
172
|
-
<div class="deb-rule-row">
|
|
173
|
-
<mat-form-field appearance="outline" subscriptSizing="dynamic">
|
|
174
|
-
<mat-label>Action Type</mat-label>
|
|
175
|
-
<mat-select [(ngModel)]="rule.action.type">
|
|
176
|
-
<mat-option value="visibility">Visibility (Show/Hide)</mat-option>
|
|
177
|
-
<mat-option value="validation">Validation Message</mat-option>
|
|
178
|
-
<mat-option value="info">Info Banner</mat-option>
|
|
179
|
-
</mat-select>
|
|
180
|
-
</mat-form-field>
|
|
181
|
-
<mat-form-field appearance="outline" subscriptSizing="dynamic">
|
|
182
|
-
<mat-label>Value / Message</mat-label>
|
|
183
|
-
<input matInput [(ngModel)]="rule.action.value" placeholder="false to hide, or message text" />
|
|
184
|
-
</mat-form-field>
|
|
185
|
-
</div>
|
|
186
|
-
</div>
|
|
187
|
-
|
|
188
|
-
<div class="deb-rule-form__actions">
|
|
189
|
-
<button mat-button type="button" (click)="cancel.emit()">Cancel</button>
|
|
190
|
-
<button mat-raised-button color="primary" type="button" (click)="save.emit(rule)">Save Rule</button>
|
|
191
|
-
</div>
|
|
192
|
-
</div>
|
|
193
|
-
`, styles: [".deb-rule-form{display:flex;flex-direction:column;gap:12px;background:#fafafa;border:1px solid #e0e0e0;border-radius:8px;padding:16px}.deb-rule-form__title{margin:0 0 8px;font-size:16px;font-weight:600}.deb-full{width:100%}.deb-rule-section{display:flex;flex-direction:column;gap:8px}.deb-rule-section h4{margin:0;font-size:13px;font-weight:600;color:#555}.deb-rule-row{display:flex;gap:8px;align-items:center}.deb-rule-row>*{flex:1}.deb-rule-form__actions{display:flex;justify-content:flex-end;gap:8px;margin-top:8px}\n"] }]
|
|
194
|
-
}], propDecorators: { rule: [{
|
|
195
|
-
type: Input
|
|
196
|
-
}], save: [{
|
|
197
|
-
type: Output
|
|
198
|
-
}], cancel: [{
|
|
199
|
-
type: Output
|
|
200
|
-
}] } });
|
|
201
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicnVsZS1mb3JtLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9saWIvY29tcG9uZW50cy9ydWxlLWZvcm0uY29tcG9uZW50LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSx1QkFBdUIsRUFBRSxTQUFTLEVBQUUsWUFBWSxFQUFFLEtBQUssRUFBRSxNQUFNLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDaEcsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBQy9DLE9BQU8sRUFBRSxXQUFXLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUM3QyxPQUFPLEVBQUUsZUFBZSxFQUFFLE1BQU0sMEJBQTBCLENBQUM7QUFDM0QsT0FBTyxFQUFFLGtCQUFrQixFQUFFLE1BQU0sOEJBQThCLENBQUM7QUFDbEUsT0FBTyxFQUFFLGFBQWEsRUFBRSxNQUFNLHdCQUF3QixDQUFDO0FBQ3ZELE9BQU8sRUFBRSxjQUFjLEVBQUUsTUFBTSx5QkFBeUIsQ0FBQztBQUN6RCxPQUFPLEVBQUUsZUFBZSxFQUFFLE1BQU0sMEJBQTBCLENBQUM7Ozs7Ozs7OztBQUkzRDs7R0FFRztBQTJISCxNQUFNLE9BQU8saUJBQWlCO0lBQ25CLElBQUksR0FBYTtRQUN4QixZQUFZLEVBQUUsUUFBUTtRQUN0QixPQUFPLEVBQUUsRUFBRTtRQUNYLFVBQVUsRUFBRSxDQUFDLEVBQUUsUUFBUSxFQUFFLE9BQU8sRUFBRSxXQUFXLEVBQUUsT0FBTyxFQUFFLEtBQUssRUFBRSxFQUFFLEVBQUUsQ0FBQztRQUNwRSxNQUFNLEVBQUUsRUFBRSxJQUFJLEVBQUUsWUFBWSxFQUFFLEtBQUssRUFBRSxLQUFLLEVBQUU7UUFDNUMsT0FBTyxFQUFFLEVBQUU7UUFDWCxPQUFPLEVBQUUsSUFBSTtRQUNiLFFBQVEsRUFBRSxDQUFDO0tBQ1osQ0FBQztJQUVRLElBQUksR0FBRyxJQUFJLFlBQVksRUFBWSxDQUFDO0lBQ3BDLE1BQU0sR0FBRyxJQUFJLFlBQVksRUFBUSxDQUFDO0lBRW5DLFNBQVMsR0FBbUI7UUFDbkMsT0FBTztRQUNQLFdBQVc7UUFDWCxVQUFVO1FBQ1YsY0FBYztRQUNkLGFBQWE7UUFDYixXQUFXO1FBQ1gsVUFBVTtRQUNWLGNBQWM7UUFDZCxXQUFXO1FBQ1gsV0FBVztRQUNYLGlCQUFpQjtRQUNqQixpQkFBaUI7UUFDakIsYUFBYTtRQUNiLFlBQVk7UUFDWixJQUFJO1FBQ0osUUFBUTtRQUNSLFdBQVc7UUFDWCxlQUFlO0tBQ2hCLENBQUM7SUFFRixZQUFZO1FBQ1YsSUFBSSxDQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsSUFBSSxDQUFDLEVBQUUsUUFBUSxFQUFFLE9BQU8sRUFBRSxXQUFXLEVBQUUsT0FBTyxFQUFFLEtBQUssRUFBRSxFQUFFLEVBQUUsQ0FBQyxDQUFDO0lBQ3BGLENBQUM7SUFFRCxlQUFlLENBQUMsS0FBYTtRQUMzQixJQUFJLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxNQUFNLENBQUMsS0FBSyxFQUFFLENBQUMsQ0FBQyxDQUFDO0lBQ3hDLENBQUM7d0dBekNVLGlCQUFpQjs0RkFBakIsaUJBQWlCLGdKQTdHbEI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7R0E2RFQsaWxCQXJFQyxZQUFZLDhCQUNaLFdBQVcsOG1CQUNYLGVBQWUsd1VBQ2Ysa0JBQWtCLDBTQUNsQixhQUFhLG1MQUNiLGNBQWMsMFdBQ2QsZUFBZTs7NEZBK0dOLGlCQUFpQjtrQkExSDdCLFNBQVM7c0NBQ1MsdUJBQXVCLENBQUMsTUFBTSxZQUNyQyxlQUFlLGNBQ2IsSUFBSSxXQUNQO3dCQUNQLFlBQVk7d0JBQ1osV0FBVzt3QkFDWCxlQUFlO3dCQUNmLGtCQUFrQjt3QkFDbEIsYUFBYTt3QkFDYixjQUFjO3dCQUNkLGVBQWU7cUJBQ2hCLFlBQ1M7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7R0E2RFQ7OEJBaURRLElBQUk7c0JBQVosS0FBSztnQkFVSSxJQUFJO3NCQUFiLE1BQU07Z0JBQ0csTUFBTTtzQkFBZixNQUFNIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3ksIENvbXBvbmVudCwgRXZlbnRFbWl0dGVyLCBJbnB1dCwgT3V0cHV0IH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBDb21tb25Nb2R1bGUgfSBmcm9tICdAYW5ndWxhci9jb21tb24nO1xuaW1wb3J0IHsgRm9ybXNNb2R1bGUgfSBmcm9tICdAYW5ndWxhci9mb3Jtcyc7XG5pbXBvcnQgeyBNYXRCdXR0b25Nb2R1bGUgfSBmcm9tICdAYW5ndWxhci9tYXRlcmlhbC9idXR0b24nO1xuaW1wb3J0IHsgTWF0Rm9ybUZpZWxkTW9kdWxlIH0gZnJvbSAnQGFuZ3VsYXIvbWF0ZXJpYWwvZm9ybS1maWVsZCc7XG5pbXBvcnQgeyBNYXRJY29uTW9kdWxlIH0gZnJvbSAnQGFuZ3VsYXIvbWF0ZXJpYWwvaWNvbic7XG5pbXBvcnQgeyBNYXRJbnB1dE1vZHVsZSB9IGZyb20gJ0Bhbmd1bGFyL21hdGVyaWFsL2lucHV0JztcbmltcG9ydCB7IE1hdFNlbGVjdE1vZHVsZSB9IGZyb20gJ0Bhbmd1bGFyL21hdGVyaWFsL3NlbGVjdCc7XG5cbmltcG9ydCB0eXBlIHsgRm9ybVJ1bGUsIFJ1bGVPcGVyYXRvciB9IGZyb20gJ0BkeW5hbWljLWVudGl0eS9jb3JlJztcblxuLyoqXG4gKiBSdWxlRm9ybUNvbXBvbmVudCDigJQgZGlhbG9nL3BhbmVsIGZvcm0gZm9yIGNyZWF0aW5nIG9yIGVkaXRpbmcgYSBGb3JtUnVsZS5cbiAqL1xuQENvbXBvbmVudCh7XG4gIGNoYW5nZURldGVjdGlvbjogQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3kuT25QdXNoLFxuICBzZWxlY3RvcjogJ25neC1ydWxlLWZvcm0nLFxuICBzdGFuZGFsb25lOiB0cnVlLFxuICBpbXBvcnRzOiBbXG4gICAgQ29tbW9uTW9kdWxlLFxuICAgIEZvcm1zTW9kdWxlLFxuICAgIE1hdEJ1dHRvbk1vZHVsZSxcbiAgICBNYXRGb3JtRmllbGRNb2R1bGUsXG4gICAgTWF0SWNvbk1vZHVsZSxcbiAgICBNYXRJbnB1dE1vZHVsZSxcbiAgICBNYXRTZWxlY3RNb2R1bGUsXG4gIF0sXG4gIHRlbXBsYXRlOiBgXG4gICAgPGRpdiBjbGFzcz1cImRlYi1ydWxlLWZvcm1cIj5cbiAgICAgIDxoMyBjbGFzcz1cImRlYi1ydWxlLWZvcm1fX3RpdGxlXCI+e3sgcnVsZS5pZCA/ICdFZGl0IFJ1bGUnIDogJ05ldyBGb3JtIFJ1bGUnIH19PC9oMz5cblxuICAgICAgPCEtLSBUcmlnZ2VyIEZpZWxkIC0tPlxuICAgICAgPG1hdC1mb3JtLWZpZWxkIGFwcGVhcmFuY2U9XCJvdXRsaW5lXCIgc3Vic2NyaXB0U2l6aW5nPVwiZHluYW1pY1wiIGNsYXNzPVwiZGViLWZ1bGxcIj5cbiAgICAgICAgPG1hdC1sYWJlbD5UcmlnZ2VyIEZpZWxkIElEPC9tYXQtbGFiZWw+XG4gICAgICAgIDxpbnB1dCBtYXRJbnB1dCBbKG5nTW9kZWwpXT1cInJ1bGUuZmllbGRJZFwiIHBsYWNlaG9sZGVyPVwiZS5nLiBzdGF0dXNcIiAvPlxuICAgICAgPC9tYXQtZm9ybS1maWVsZD5cblxuICAgICAgPCEtLSBDb25kaXRpb25zIC0tPlxuICAgICAgPGRpdiBjbGFzcz1cImRlYi1ydWxlLXNlY3Rpb25cIj5cbiAgICAgICAgPGg0PkNvbmRpdGlvbnM8L2g0PlxuICAgICAgICBAZm9yIChjb25kIG9mIHJ1bGUuY29uZGl0aW9uczsgdHJhY2sgJGluZGV4KSB7XG4gICAgICAgICAgPGRpdiBjbGFzcz1cImRlYi1ydWxlLXJvd1wiPlxuICAgICAgICAgICAgPG1hdC1mb3JtLWZpZWxkIGFwcGVhcmFuY2U9XCJvdXRsaW5lXCIgc3Vic2NyaXB0U2l6aW5nPVwiZHluYW1pY1wiPlxuICAgICAgICAgICAgICA8bWF0LWxhYmVsPk9wZXJhdG9yPC9tYXQtbGFiZWw+XG4gICAgICAgICAgICAgIDxtYXQtc2VsZWN0IFsobmdNb2RlbCldPVwiY29uZC5vcGVyYXRvclwiPlxuICAgICAgICAgICAgICAgIEBmb3IgKG9wIG9mIG9wZXJhdG9yczsgdHJhY2sgb3ApIHtcbiAgICAgICAgICAgICAgICAgIDxtYXQtb3B0aW9uIFt2YWx1ZV09XCJvcFwiPnt7IG9wIH19PC9tYXQtb3B0aW9uPlxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgPC9tYXQtc2VsZWN0PlxuICAgICAgICAgICAgPC9tYXQtZm9ybS1maWVsZD5cbiAgICAgICAgICAgIDxtYXQtZm9ybS1maWVsZCBhcHBlYXJhbmNlPVwib3V0bGluZVwiIHN1YnNjcmlwdFNpemluZz1cImR5bmFtaWNcIj5cbiAgICAgICAgICAgICAgPG1hdC1sYWJlbD5WYWx1ZTwvbWF0LWxhYmVsPlxuICAgICAgICAgICAgICA8aW5wdXQgbWF0SW5wdXQgWyhuZ01vZGVsKV09XCJjb25kLnZhbHVlXCIgcGxhY2Vob2xkZXI9XCJDb25kaXRpb24gdmFsdWVcIiAvPlxuICAgICAgICAgICAgPC9tYXQtZm9ybS1maWVsZD5cbiAgICAgICAgICAgIDxidXR0b24gbWF0LWljb24tYnV0dG9uIGNvbG9yPVwid2FyblwiIHR5cGU9XCJidXR0b25cIiAoY2xpY2spPVwicmVtb3ZlQ29uZGl0aW9uKCRpbmRleClcIj5cbiAgICAgICAgICAgICAgPG1hdC1pY29uPmRlbGV0ZTwvbWF0LWljb24+XG4gICAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgfVxuICAgICAgICA8YnV0dG9uIG1hdC1zdHJva2VkLWJ1dHRvbiB0eXBlPVwiYnV0dG9uXCIgKGNsaWNrKT1cImFkZENvbmRpdGlvbigpXCI+XG4gICAgICAgICAgPG1hdC1pY29uPmFkZDwvbWF0LWljb24+IEFkZCBDb25kaXRpb25cbiAgICAgICAgPC9idXR0b24+XG4gICAgICA8L2Rpdj5cblxuICAgICAgPCEtLSBBY3Rpb24gLS0+XG4gICAgICA8ZGl2IGNsYXNzPVwiZGViLXJ1bGUtc2VjdGlvblwiPlxuICAgICAgICA8aDQ+QWN0aW9uPC9oND5cbiAgICAgICAgPGRpdiBjbGFzcz1cImRlYi1ydWxlLXJvd1wiPlxuICAgICAgICAgIDxtYXQtZm9ybS1maWVsZCBhcHBlYXJhbmNlPVwib3V0bGluZVwiIHN1YnNjcmlwdFNpemluZz1cImR5bmFtaWNcIj5cbiAgICAgICAgICAgIDxtYXQtbGFiZWw+QWN0aW9uIFR5cGU8L21hdC1sYWJlbD5cbiAgICAgICAgICAgIDxtYXQtc2VsZWN0IFsobmdNb2RlbCldPVwicnVsZS5hY3Rpb24udHlwZVwiPlxuICAgICAgICAgICAgICA8bWF0LW9wdGlvbiB2YWx1ZT1cInZpc2liaWxpdHlcIj5WaXNpYmlsaXR5IChTaG93L0hpZGUpPC9tYXQtb3B0aW9uPlxuICAgICAgICAgICAgICA8bWF0LW9wdGlvbiB2YWx1ZT1cInZhbGlkYXRpb25cIj5WYWxpZGF0aW9uIE1lc3NhZ2U8L21hdC1vcHRpb24+XG4gICAgICAgICAgICAgIDxtYXQtb3B0aW9uIHZhbHVlPVwiaW5mb1wiPkluZm8gQmFubmVyPC9tYXQtb3B0aW9uPlxuICAgICAgICAgICAgPC9tYXQtc2VsZWN0PlxuICAgICAgICAgIDwvbWF0LWZvcm0tZmllbGQ+XG4gICAgICAgICAgPG1hdC1mb3JtLWZpZWxkIGFwcGVhcmFuY2U9XCJvdXRsaW5lXCIgc3Vic2NyaXB0U2l6aW5nPVwiZHluYW1pY1wiPlxuICAgICAgICAgICAgPG1hdC1sYWJlbD5WYWx1ZSAvIE1lc3NhZ2U8L21hdC1sYWJlbD5cbiAgICAgICAgICAgIDxpbnB1dCBtYXRJbnB1dCBbKG5nTW9kZWwpXT1cInJ1bGUuYWN0aW9uLnZhbHVlXCIgcGxhY2Vob2xkZXI9XCJmYWxzZSB0byBoaWRlLCBvciBtZXNzYWdlIHRleHRcIiAvPlxuICAgICAgICAgIDwvbWF0LWZvcm0tZmllbGQ+XG4gICAgICAgIDwvZGl2PlxuICAgICAgPC9kaXY+XG5cbiAgICAgIDxkaXYgY2xhc3M9XCJkZWItcnVsZS1mb3JtX19hY3Rpb25zXCI+XG4gICAgICAgIDxidXR0b24gbWF0LWJ1dHRvbiB0eXBlPVwiYnV0dG9uXCIgKGNsaWNrKT1cImNhbmNlbC5lbWl0KClcIj5DYW5jZWw8L2J1dHRvbj5cbiAgICAgICAgPGJ1dHRvbiBtYXQtcmFpc2VkLWJ1dHRvbiBjb2xvcj1cInByaW1hcnlcIiB0eXBlPVwiYnV0dG9uXCIgKGNsaWNrKT1cInNhdmUuZW1pdChydWxlKVwiPlNhdmUgUnVsZTwvYnV0dG9uPlxuICAgICAgPC9kaXY+XG4gICAgPC9kaXY+XG4gIGAsXG4gIHN0eWxlczogW1xuICAgIGBcbiAgICAgIC5kZWItcnVsZS1mb3JtIHtcbiAgICAgICAgZGlzcGxheTogZmxleDtcbiAgICAgICAgZmxleC1kaXJlY3Rpb246IGNvbHVtbjtcbiAgICAgICAgZ2FwOiAxMnB4O1xuICAgICAgICBiYWNrZ3JvdW5kOiAjZmFmYWZhO1xuICAgICAgICBib3JkZXI6IDFweCBzb2xpZCAjZTBlMGUwO1xuICAgICAgICBib3JkZXItcmFkaXVzOiA4cHg7XG4gICAgICAgIHBhZGRpbmc6IDE2cHg7XG4gICAgICB9XG4gICAgICAuZGViLXJ1bGUtZm9ybV9fdGl0bGUge1xuICAgICAgICBtYXJnaW46IDAgMCA4cHggMDtcbiAgICAgICAgZm9udC1zaXplOiAxNnB4O1xuICAgICAgICBmb250LXdlaWdodDogNjAwO1xuICAgICAgfVxuICAgICAgLmRlYi1mdWxsIHtcbiAgICAgICAgd2lkdGg6IDEwMCU7XG4gICAgICB9XG4gICAgICAuZGViLXJ1bGUtc2VjdGlvbiB7XG4gICAgICAgIGRpc3BsYXk6IGZsZXg7XG4gICAgICAgIGZsZXgtZGlyZWN0aW9uOiBjb2x1bW47XG4gICAgICAgIGdhcDogOHB4O1xuICAgICAgfVxuICAgICAgLmRlYi1ydWxlLXNlY3Rpb24gaDQge1xuICAgICAgICBtYXJnaW46IDA7XG4gICAgICAgIGZvbnQtc2l6ZTogMTNweDtcbiAgICAgICAgZm9udC13ZWlnaHQ6IDYwMDtcbiAgICAgICAgY29sb3I6ICM1NTU7XG4gICAgICB9XG4gICAgICAuZGViLXJ1bGUtcm93IHtcbiAgICAgICAgZGlzcGxheTogZmxleDtcbiAgICAgICAgZ2FwOiA4cHg7XG4gICAgICAgIGFsaWduLWl0ZW1zOiBjZW50ZXI7XG4gICAgICB9XG4gICAgICAuZGViLXJ1bGUtcm93ID4gKiB7XG4gICAgICAgIGZsZXg6IDE7XG4gICAgICB9XG4gICAgICAuZGViLXJ1bGUtZm9ybV9fYWN0aW9ucyB7XG4gICAgICAgIGRpc3BsYXk6IGZsZXg7XG4gICAgICAgIGp1c3RpZnktY29udGVudDogZmxleC1lbmQ7XG4gICAgICAgIGdhcDogOHB4O1xuICAgICAgICBtYXJnaW4tdG9wOiA4cHg7XG4gICAgICB9XG4gICAgYCxcbiAgXSxcbn0pXG5leHBvcnQgY2xhc3MgUnVsZUZvcm1Db21wb25lbnQge1xuICBASW5wdXQoKSBydWxlOiBGb3JtUnVsZSA9IHtcbiAgICBmb3JtQ29uZmlnSWQ6ICdmb3JtLTEnLFxuICAgIGZpZWxkSWQ6ICcnLFxuICAgIGNvbmRpdGlvbnM6IFt7IG9wZXJhdG9yOiAnRVFVQUwnLCBjb21wYXJlVHlwZTogJ3ZhbHVlJywgdmFsdWU6ICcnIH1dLFxuICAgIGFjdGlvbjogeyB0eXBlOiAndmlzaWJpbGl0eScsIHZhbHVlOiBmYWxzZSB9LFxuICAgIHRhcmdldHM6IFtdLFxuICAgIGVuYWJsZWQ6IHRydWUsXG4gICAgcHJpb3JpdHk6IDEsXG4gIH07XG5cbiAgQE91dHB1dCgpIHNhdmUgPSBuZXcgRXZlbnRFbWl0dGVyPEZvcm1SdWxlPigpO1xuICBAT3V0cHV0KCkgY2FuY2VsID0gbmV3IEV2ZW50RW1pdHRlcjx2b2lkPigpO1xuXG4gIHJlYWRvbmx5IG9wZXJhdG9yczogUnVsZU9wZXJhdG9yW10gPSBbXG4gICAgJ0VRVUFMJyxcbiAgICAnTk9UX0VRVUFMJyxcbiAgICAnQ09OVEFJTlMnLFxuICAgICdOT1RfQ09OVEFJTlMnLFxuICAgICdTVEFSVFNfV0lUSCcsXG4gICAgJ0VORFNfV0lUSCcsXG4gICAgJ0lTX0VNUFRZJyxcbiAgICAnSVNfTk9UX0VNUFRZJyxcbiAgICAnTEVTU19USEFOJyxcbiAgICAnTU9SRV9USEFOJyxcbiAgICAnTEVTU19USEFOX0VRVUFMJyxcbiAgICAnTU9SRV9USEFOX0VRVUFMJyxcbiAgICAnREFURV9CRUZPUkUnLFxuICAgICdEQVRFX0FGVEVSJyxcbiAgICAnSU4nLFxuICAgICdOT1RfSU4nLFxuICAgICdIQVNfSVRFTVMnLFxuICAgICdWQUxVRV9DSEFOR0VEJyxcbiAgXTtcblxuICBhZGRDb25kaXRpb24oKTogdm9pZCB7XG4gICAgdGhpcy5ydWxlLmNvbmRpdGlvbnMucHVzaCh7IG9wZXJhdG9yOiAnRVFVQUwnLCBjb21wYXJlVHlwZTogJ3ZhbHVlJywgdmFsdWU6ICcnIH0pO1xuICB9XG5cbiAgcmVtb3ZlQ29uZGl0aW9uKGluZGV4OiBudW1iZXIpOiB2b2lkIHtcbiAgICB0aGlzLnJ1bGUuY29uZGl0aW9ucy5zcGxpY2UoaW5kZXgsIDEpO1xuICB9XG59XG4iXX0=
|