@myrmidon/gve-core 6.1.0 → 6.1.2
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.
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
|
-
import { input, output, ChangeDetectionStrategy, Component, inject, DestroyRef, signal, computed, effect, viewChild, model,
|
|
2
|
+
import { input, output, ChangeDetectionStrategy, Component, inject, DestroyRef, signal, computed, effect, viewChild, model, untracked, Injectable, Optional, Inject, CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
|
|
3
3
|
import * as i1 from '@angular/material/core';
|
|
4
4
|
import { MatRippleModule } from '@angular/material/core';
|
|
5
5
|
import * as i2$1 from '@myrmidon/ngx-tools';
|
|
@@ -16,8 +16,8 @@ import * as i5 from '@angular/material/input';
|
|
|
16
16
|
import { MatInputModule } from '@angular/material/input';
|
|
17
17
|
import * as i6 from '@angular/material/tooltip';
|
|
18
18
|
import { MatTooltipModule, MatTooltip } from '@angular/material/tooltip';
|
|
19
|
-
import { Subject, debounceTime, distinctUntilChanged,
|
|
20
|
-
import { takeUntilDestroyed
|
|
19
|
+
import { Subject, debounceTime, distinctUntilChanged, catchError, BehaviorSubject } from 'rxjs';
|
|
20
|
+
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
|
|
21
21
|
import * as i2$3 from '@angular/material/snack-bar';
|
|
22
22
|
import { MatSnackBar, MatSnackBarModule } from '@angular/material/snack-bar';
|
|
23
23
|
import * as i2$2 from '@angular/cdk/clipboard';
|
|
@@ -81,11 +81,15 @@ class BaseTextCharComponent {
|
|
|
81
81
|
/**
|
|
82
82
|
* The character to display.
|
|
83
83
|
*/
|
|
84
|
-
this.char = input(...(ngDevMode ? [undefined, { debugName: "char" }] : []));
|
|
84
|
+
this.char = input(...(ngDevMode ? [undefined, { debugName: "char" }] : /* istanbul ignore next */ []));
|
|
85
85
|
/**
|
|
86
86
|
* Emitted when the character is clicked.
|
|
87
87
|
*/
|
|
88
88
|
this.charPick = output();
|
|
89
|
+
/**
|
|
90
|
+
* Emitted when the character is double-clicked.
|
|
91
|
+
*/
|
|
92
|
+
this.charDblPick = output();
|
|
89
93
|
this.defaultColor = '#D8D8D8';
|
|
90
94
|
this.defaultBorderColor = '#D8D8D8';
|
|
91
95
|
this.defaultEmSize = 1.5;
|
|
@@ -93,13 +97,16 @@ class BaseTextCharComponent {
|
|
|
93
97
|
onCharClick(event) {
|
|
94
98
|
this.charPick.emit({ char: this.char(), event });
|
|
95
99
|
}
|
|
96
|
-
|
|
97
|
-
|
|
100
|
+
onCharDblClick(event) {
|
|
101
|
+
this.charDblPick.emit({ char: this.char(), event });
|
|
102
|
+
}
|
|
103
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.3", ngImport: i0, type: BaseTextCharComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
104
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.3", type: BaseTextCharComponent, isStandalone: true, selector: "gve-base-text-char", inputs: { char: { classPropertyName: "char", publicName: "char", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { charPick: "charPick", charDblPick: "charDblPick" }, ngImport: i0, template: "@if (char()) {\r\n<div matRipple id=\"container\" (click)=\"onCharClick($event)\" (dblclick)=\"onCharDblClick($event)\">\r\n <div\r\n id=\"c-label\"\r\n [style.fontSize]=\"char()!.emSize + 'em'\"\r\n [style.borderColor]=\"char()!.borderColor\"\r\n >\r\n {{ char()!.label }}\r\n </div>\r\n <div\r\n id=\"c-id\"\r\n [style.fontSize]=\"char()!.emSize / 2 + 'em'\"\r\n [style.color]=\"char()!.color | colorToContrast\"\r\n [style.borderColor]=\"char()!.borderColor\"\r\n [style.backgroundColor]=\"char()!.color\"\r\n >\r\n {{ char()!.id }}\r\n </div>\r\n</div>\r\n}\r\n", styles: ["div#container{cursor:pointer;flex-direction:column;align-items:center}div#c-label{border:1px solid silver;border-radius:6px;padding:6px;height:1.5em;align-items:center;justify-content:center;text-align:center}div#c-id{margin-top:4px;margin-bottom:16px;border:1px solid silver;border-radius:6px;padding:6px;align-items:center;justify-content:center;text-align:center}\n"], dependencies: [{ kind: "ngmodule", type: MatRippleModule }, { kind: "directive", type: i1.MatRipple, selector: "[mat-ripple], [matRipple]", inputs: ["matRippleColor", "matRippleUnbounded", "matRippleCentered", "matRippleRadius", "matRippleAnimation", "matRippleDisabled", "matRippleTrigger"], exportAs: ["matRipple"] }, { kind: "pipe", type: ColorToContrastPipe, name: "colorToContrast" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
98
105
|
}
|
|
99
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.
|
|
106
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.3", ngImport: i0, type: BaseTextCharComponent, decorators: [{
|
|
100
107
|
type: Component,
|
|
101
|
-
args: [{ selector: 'gve-base-text-char', imports: [MatRippleModule, ColorToContrastPipe], changeDetection: ChangeDetectionStrategy.OnPush, template: "@if (char()) {\r\n<div matRipple id=\"container\" (click)=\"onCharClick($event)\">\r\n <div\r\n id=\"c-label\"\r\n [style.fontSize]=\"char()!.emSize + 'em'\"\r\n [style.borderColor]=\"char()!.borderColor\"\r\n >\r\n {{ char()!.label }}\r\n </div>\r\n <div\r\n id=\"c-id\"\r\n [style.fontSize]=\"char()!.emSize / 2 + 'em'\"\r\n [style.color]=\"char()!.color | colorToContrast\"\r\n [style.borderColor]=\"char()!.borderColor\"\r\n [style.backgroundColor]=\"char()!.color\"\r\n >\r\n {{ char()!.id }}\r\n </div>\r\n</div>\r\n}\r\n", styles: ["div#container{cursor:pointer;flex-direction:column;align-items:center}div#c-label{border:1px solid silver;border-radius:6px;padding:6px;height:1.5em;align-items:center;justify-content:center;text-align:center}div#c-id{margin-top:4px;margin-bottom:16px;border:1px solid silver;border-radius:6px;padding:6px;align-items:center;justify-content:center;text-align:center}\n"] }]
|
|
102
|
-
}], propDecorators: { char: [{ type: i0.Input, args: [{ isSignal: true, alias: "char", required: false }] }], charPick: [{ type: i0.Output, args: ["charPick"] }] } });
|
|
108
|
+
args: [{ selector: 'gve-base-text-char', imports: [MatRippleModule, ColorToContrastPipe], changeDetection: ChangeDetectionStrategy.OnPush, template: "@if (char()) {\r\n<div matRipple id=\"container\" (click)=\"onCharClick($event)\" (dblclick)=\"onCharDblClick($event)\">\r\n <div\r\n id=\"c-label\"\r\n [style.fontSize]=\"char()!.emSize + 'em'\"\r\n [style.borderColor]=\"char()!.borderColor\"\r\n >\r\n {{ char()!.label }}\r\n </div>\r\n <div\r\n id=\"c-id\"\r\n [style.fontSize]=\"char()!.emSize / 2 + 'em'\"\r\n [style.color]=\"char()!.color | colorToContrast\"\r\n [style.borderColor]=\"char()!.borderColor\"\r\n [style.backgroundColor]=\"char()!.color\"\r\n >\r\n {{ char()!.id }}\r\n </div>\r\n</div>\r\n}\r\n", styles: ["div#container{cursor:pointer;flex-direction:column;align-items:center}div#c-label{border:1px solid silver;border-radius:6px;padding:6px;height:1.5em;align-items:center;justify-content:center;text-align:center}div#c-id{margin-top:4px;margin-bottom:16px;border:1px solid silver;border-radius:6px;padding:6px;align-items:center;justify-content:center;text-align:center}\n"] }]
|
|
109
|
+
}], propDecorators: { char: [{ type: i0.Input, args: [{ isSignal: true, alias: "char", required: false }] }], charPick: [{ type: i0.Output, args: ["charPick"] }], charDblPick: [{ type: i0.Output, args: ["charDblPick"] }] } });
|
|
103
110
|
|
|
104
111
|
/**
|
|
105
112
|
* 🔑 `gve-base-text-view`
|
|
@@ -132,45 +139,45 @@ class BaseTextViewComponent {
|
|
|
132
139
|
/**
|
|
133
140
|
* The default color for the text.
|
|
134
141
|
*/
|
|
135
|
-
this.defaultColor = input('#DBDBDB', ...(ngDevMode ? [{ debugName: "defaultColor" }] : []));
|
|
142
|
+
this.defaultColor = input('#DBDBDB', ...(ngDevMode ? [{ debugName: "defaultColor" }] : /* istanbul ignore next */ []));
|
|
136
143
|
/**
|
|
137
144
|
* The default border color for the text.
|
|
138
145
|
*/
|
|
139
|
-
this.defaultBorderColor = input('#DBDBDB', ...(ngDevMode ? [{ debugName: "defaultBorderColor" }] : []));
|
|
146
|
+
this.defaultBorderColor = input('#DBDBDB', ...(ngDevMode ? [{ debugName: "defaultBorderColor" }] : /* istanbul ignore next */ []));
|
|
140
147
|
/**
|
|
141
148
|
* The color for the selected text.
|
|
142
149
|
*/
|
|
143
|
-
this.selectionColor = input('#3E92CC', ...(ngDevMode ? [{ debugName: "selectionColor" }] : []));
|
|
150
|
+
this.selectionColor = input('#3E92CC', ...(ngDevMode ? [{ debugName: "selectionColor" }] : /* istanbul ignore next */ []));
|
|
144
151
|
/**
|
|
145
152
|
* The color for search match highlights.
|
|
146
153
|
*/
|
|
147
|
-
this.searchHighlightColor = input('#FFD54F', ...(ngDevMode ? [{ debugName: "searchHighlightColor" }] : []));
|
|
154
|
+
this.searchHighlightColor = input('#FFD54F', ...(ngDevMode ? [{ debugName: "searchHighlightColor" }] : /* istanbul ignore next */ []));
|
|
148
155
|
/**
|
|
149
156
|
* True if line numbers should be displayed next to each line.
|
|
150
157
|
*/
|
|
151
|
-
this.hasLineNumber = input(false, ...(ngDevMode ? [{ debugName: "hasLineNumber" }] : []));
|
|
158
|
+
this.hasLineNumber = input(false, ...(ngDevMode ? [{ debugName: "hasLineNumber" }] : /* istanbul ignore next */ []));
|
|
152
159
|
/**
|
|
153
160
|
* The search query entered in the toolbar.
|
|
154
161
|
*/
|
|
155
|
-
this.searchQuery = signal('', ...(ngDevMode ? [{ debugName: "searchQuery" }] : []));
|
|
162
|
+
this.searchQuery = signal('', ...(ngDevMode ? [{ debugName: "searchQuery" }] : /* istanbul ignore next */ []));
|
|
156
163
|
/**
|
|
157
164
|
* The positions of search matches (start and length pairs).
|
|
158
165
|
*/
|
|
159
|
-
this.searchMatches = signal([], ...(ngDevMode ? [{ debugName: "searchMatches" }] : []));
|
|
166
|
+
this.searchMatches = signal([], ...(ngDevMode ? [{ debugName: "searchMatches" }] : /* istanbul ignore next */ []));
|
|
160
167
|
/**
|
|
161
168
|
* The text to display.
|
|
162
169
|
*/
|
|
163
|
-
this.text = input([], ...(ngDevMode ? [{ debugName: "text" }] : []));
|
|
170
|
+
this.text = input([], ...(ngDevMode ? [{ debugName: "text" }] : /* istanbul ignore next */ []));
|
|
164
171
|
/**
|
|
165
172
|
* An optional callback to get the color of a character node.
|
|
166
173
|
* Return null to use the default color.
|
|
167
174
|
*/
|
|
168
|
-
this.colorCallback = input(...(ngDevMode ? [undefined, { debugName: "colorCallback" }] : []));
|
|
175
|
+
this.colorCallback = input(...(ngDevMode ? [undefined, { debugName: "colorCallback" }] : /* istanbul ignore next */ []));
|
|
169
176
|
/**
|
|
170
177
|
* An optional callback to get the color of a character node.
|
|
171
178
|
* Return null to use the default color.
|
|
172
179
|
*/
|
|
173
|
-
this.borderColorCallback = input(...(ngDevMode ? [undefined, { debugName: "borderColorCallback" }] : []));
|
|
180
|
+
this.borderColorCallback = input(...(ngDevMode ? [undefined, { debugName: "borderColorCallback" }] : /* istanbul ignore next */ []));
|
|
174
181
|
/**
|
|
175
182
|
* Emitted when a character is picked.
|
|
176
183
|
*/
|
|
@@ -186,11 +193,11 @@ class BaseTextViewComponent {
|
|
|
186
193
|
*/
|
|
187
194
|
this.baseLines = computed(() => {
|
|
188
195
|
return this.buildLines(this.text(), this.colorCallback(), this.borderColorCallback());
|
|
189
|
-
}, ...(ngDevMode ? [{ debugName: "baseLines" }] : []));
|
|
196
|
+
}, ...(ngDevMode ? [{ debugName: "baseLines" }] : /* istanbul ignore next */ []));
|
|
190
197
|
/**
|
|
191
198
|
* Signal for tracking selected range state.
|
|
192
199
|
*/
|
|
193
|
-
this.selectedRange = signal(null, ...(ngDevMode ? [{ debugName: "selectedRange" }] : []));
|
|
200
|
+
this.selectedRange = signal(null, ...(ngDevMode ? [{ debugName: "selectedRange" }] : /* istanbul ignore next */ []));
|
|
194
201
|
/**
|
|
195
202
|
* The lines with selection or search highlight state applied.
|
|
196
203
|
* Search highlights take priority over selection when present.
|
|
@@ -236,26 +243,30 @@ class BaseTextViewComponent {
|
|
|
236
243
|
}
|
|
237
244
|
return char;
|
|
238
245
|
}));
|
|
239
|
-
}, ...(ngDevMode ? [{ debugName: "lines" }] : []));
|
|
246
|
+
}, ...(ngDevMode ? [{ debugName: "lines" }] : /* istanbul ignore next */ []));
|
|
240
247
|
/**
|
|
241
248
|
* Check if there is an active selection.
|
|
242
249
|
*/
|
|
243
250
|
this.hasSelection = computed(() => {
|
|
244
251
|
return this.selectedRange() !== null;
|
|
245
|
-
}, ...(ngDevMode ? [{ debugName: "hasSelection" }] : []));
|
|
252
|
+
}, ...(ngDevMode ? [{ debugName: "hasSelection" }] : /* istanbul ignore next */ []));
|
|
246
253
|
/**
|
|
247
254
|
* Get the total count of matched characters.
|
|
248
255
|
*/
|
|
249
256
|
this.matchCount = computed(() => {
|
|
250
257
|
const matches = this.searchMatches();
|
|
251
258
|
return matches.reduce((sum, m) => sum + m.length, 0);
|
|
252
|
-
}, ...(ngDevMode ? [{ debugName: "matchCount" }] : []));
|
|
259
|
+
}, ...(ngDevMode ? [{ debugName: "matchCount" }] : /* istanbul ignore next */ []));
|
|
253
260
|
/**
|
|
254
261
|
* Check if a search is active (query is not empty).
|
|
255
262
|
*/
|
|
256
263
|
this.isSearchActive = computed(() => {
|
|
257
264
|
return this.searchQuery().length > 0;
|
|
258
|
-
}, ...(ngDevMode ? [{ debugName: "isSearchActive" }] : []));
|
|
265
|
+
}, ...(ngDevMode ? [{ debugName: "isSearchActive" }] : /* istanbul ignore next */ []));
|
|
266
|
+
/**
|
|
267
|
+
* Space-separated list of character IDs collected via double-click.
|
|
268
|
+
*/
|
|
269
|
+
this.pickedIds = signal('', ...(ngDevMode ? [{ debugName: "pickedIds" }] : /* istanbul ignore next */ []));
|
|
259
270
|
// reset selection when text changes
|
|
260
271
|
effect(() => {
|
|
261
272
|
this.text();
|
|
@@ -595,10 +606,37 @@ class BaseTextViewComponent {
|
|
|
595
606
|
duration: 2000,
|
|
596
607
|
});
|
|
597
608
|
}
|
|
598
|
-
|
|
599
|
-
|
|
609
|
+
/**
|
|
610
|
+
* Append a character's ID to the pickedIds string on double-click.
|
|
611
|
+
*/
|
|
612
|
+
onCharDblPick(event) {
|
|
613
|
+
if (!event?.char) {
|
|
614
|
+
return;
|
|
615
|
+
}
|
|
616
|
+
const current = this.pickedIds();
|
|
617
|
+
this.pickedIds.set(current ? `${current} ${event.char.id}` : `${event.char.id}`);
|
|
618
|
+
}
|
|
619
|
+
/**
|
|
620
|
+
* Clear the collected IDs string.
|
|
621
|
+
*/
|
|
622
|
+
clearPickedIds() {
|
|
623
|
+
this.pickedIds.set('');
|
|
624
|
+
}
|
|
625
|
+
/**
|
|
626
|
+
* Copy the collected IDs string to the clipboard.
|
|
627
|
+
*/
|
|
628
|
+
copyPickedIds() {
|
|
629
|
+
const ids = this.pickedIds();
|
|
630
|
+
if (!ids) {
|
|
631
|
+
return;
|
|
632
|
+
}
|
|
633
|
+
this._clipboard.copy(ids);
|
|
634
|
+
this._snackBar.open('IDs copied', 'OK', { duration: 2000 });
|
|
635
|
+
}
|
|
636
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.3", ngImport: i0, type: BaseTextViewComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
637
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.3", type: BaseTextViewComponent, isStandalone: true, selector: "gve-base-text-view", inputs: { defaultColor: { classPropertyName: "defaultColor", publicName: "defaultColor", isSignal: true, isRequired: false, transformFunction: null }, defaultBorderColor: { classPropertyName: "defaultBorderColor", publicName: "defaultBorderColor", isSignal: true, isRequired: false, transformFunction: null }, selectionColor: { classPropertyName: "selectionColor", publicName: "selectionColor", isSignal: true, isRequired: false, transformFunction: null }, searchHighlightColor: { classPropertyName: "searchHighlightColor", publicName: "searchHighlightColor", isSignal: true, isRequired: false, transformFunction: null }, hasLineNumber: { classPropertyName: "hasLineNumber", publicName: "hasLineNumber", isSignal: true, isRequired: false, transformFunction: null }, text: { classPropertyName: "text", publicName: "text", isSignal: true, isRequired: false, transformFunction: null }, colorCallback: { classPropertyName: "colorCallback", publicName: "colorCallback", isSignal: true, isRequired: false, transformFunction: null }, borderColorCallback: { classPropertyName: "borderColorCallback", publicName: "borderColorCallback", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { charPick: "charPick", rangePick: "rangePick" }, ngImport: i0, template: "<!-- Toolbar -->\r\n<div class=\"toolbar\">\r\n <mat-form-field appearance=\"outline\" class=\"search-field\">\r\n <input\r\n matInput\r\n [ngModel]=\"searchQuery()\"\r\n (ngModelChange)=\"onSearchInput($event)\"\r\n placeholder=\"search\"\r\n />\r\n @if (searchQuery()) {\r\n <button\r\n type=\"button\"\r\n matSuffix\r\n mat-icon-button\r\n matTooltip=\"Clear search\"\r\n (click)=\"clearSearch()\"\r\n >\r\n <mat-icon class=\"mat-warn\">close</mat-icon>\r\n </button>\r\n }\r\n </mat-form-field>\r\n\r\n @if (isSearchActive()) {\r\n <span class=\"match-count\" [class.no-matches]=\"matchCount() === 0\">\r\n {{ matchCount() }}\r\n </span>\r\n }\r\n\r\n <button\r\n type=\"button\"\r\n mat-stroked-button\r\n matTooltip=\"Copy selection text to clipboard\"\r\n [disabled]=\"!hasSelection()\"\r\n (click)=\"copySelection()\"\r\n >\r\n <mat-icon>content_copy</mat-icon>\r\n copy\r\n </button>\r\n\r\n <button\r\n type=\"button\"\r\n mat-stroked-button\r\n matTooltip=\"Copy selection coordinates to clipboard\"\r\n [disabled]=\"!hasSelection()\"\r\n (click)=\"copyCoordinates()\"\r\n >\r\n <mat-icon>pin_drop</mat-icon>\r\n copy coords\r\n </button>\r\n\r\n @if (pickedIds()) {\r\n <span class=\"picked-ids\" matTooltip=\"Double-clicked character IDs\">{{ pickedIds() }}</span>\r\n <button\r\n type=\"button\"\r\n mat-icon-button\r\n matTooltip=\"Clear collected IDs\"\r\n (click)=\"clearPickedIds()\"\r\n >\r\n <mat-icon>clear</mat-icon>\r\n </button>\r\n <button\r\n type=\"button\"\r\n mat-icon-button\r\n matTooltip=\"Copy collected IDs to clipboard\"\r\n (click)=\"copyPickedIds()\"\r\n >\r\n <mat-icon>content_copy</mat-icon>\r\n </button>\r\n }\r\n</div>\r\n\r\n<!-- Text display -->\r\n<div id=\"text\" tabindex=\"0\" (keydown)=\"onKeyDown($event)\">\r\n @for (line of lines(); track $index) {\r\n <div class=\"line\">\r\n @if (hasLineNumber()) {\r\n <div class=\"nr\">\r\n {{ lines().indexOf(line) + 1 }}\r\n </div>\r\n }\r\n @for (c of line; track c.id) {\r\n <gve-base-text-char [char]=\"c\" (charPick)=\"onCharPick($event)\" (charDblPick)=\"onCharDblPick($event)\" />\r\n }\r\n </div>\r\n }\r\n</div>\r\n", styles: [".toolbar{display:flex;align-items:center;gap:8px;margin-bottom:8px;flex-wrap:wrap}.search-field{flex:0 0 auto;min-width:200px;max-width:300px}.match-count{font-weight:700;padding:4px 8px;border-radius:4px;background-color:#e8f5e9;color:#2e7d32}.match-count.no-matches{background-color:#ffebee;color:#c62828}.line{display:flex;gap:8px;align-items:center;flex-wrap:wrap}.line *{flex:0 0 auto}.nr{font-size:.8em;font-weight:700;color:silver;margin:0 4px}.picked-ids{font-family:monospace;font-size:.85em;padding:4px 8px;border-radius:4px;background-color:#e3f2fd;color:#1565c0;border:1px solid #90caf9;max-width:300px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}\n"], dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$1.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$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.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[matButton], a[matButton], button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button], a[mat-button], a[mat-raised-button], a[mat-flat-button], a[mat-stroked-button] ", inputs: ["matButton"], exportAs: ["matButton", "matAnchor"] }, { kind: "component", type: i2.MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { 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.MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { 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", "disabledInteractive"], exportAs: ["matInput"] }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i6.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "component", type: BaseTextCharComponent, selector: "gve-base-text-char", inputs: ["char"], outputs: ["charPick", "charDblPick"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
600
638
|
}
|
|
601
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.
|
|
639
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.3", ngImport: i0, type: BaseTextViewComponent, decorators: [{
|
|
602
640
|
type: Component,
|
|
603
641
|
args: [{ selector: 'gve-base-text-view', imports: [
|
|
604
642
|
FormsModule,
|
|
@@ -608,7 +646,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.0", ngImpor
|
|
|
608
646
|
MatInputModule,
|
|
609
647
|
MatTooltipModule,
|
|
610
648
|
BaseTextCharComponent,
|
|
611
|
-
], changeDetection: ChangeDetectionStrategy.OnPush, template: "<!-- Toolbar -->\r\n<div class=\"toolbar\">\r\n <mat-form-field appearance=\"outline\" class=\"search-field\">\r\n <input\r\n matInput\r\n [ngModel]=\"searchQuery()\"\r\n (ngModelChange)=\"onSearchInput($event)\"\r\n placeholder=\"search\"\r\n />\r\n @if (searchQuery()) {\r\n <button\r\n type=\"button\"\r\n matSuffix\r\n mat-icon-button\r\n matTooltip=\"Clear search\"\r\n (click)=\"clearSearch()\"\r\n >\r\n <mat-icon class=\"mat-warn\">close</mat-icon>\r\n </button>\r\n }\r\n </mat-form-field>\r\n\r\n @if (isSearchActive()) {\r\n <span class=\"match-count\" [class.no-matches]=\"matchCount() === 0\">\r\n {{ matchCount() }}\r\n </span>\r\n }\r\n\r\n <button\r\n type=\"button\"\r\n mat-stroked-button\r\n matTooltip=\"Copy selection text to clipboard\"\r\n [disabled]=\"!hasSelection()\"\r\n (click)=\"copySelection()\"\r\n >\r\n <mat-icon>content_copy</mat-icon>\r\n copy\r\n </button>\r\n\r\n <button\r\n type=\"button\"\r\n mat-stroked-button\r\n matTooltip=\"Copy selection coordinates to clipboard\"\r\n [disabled]=\"!hasSelection()\"\r\n (click)=\"copyCoordinates()\"\r\n >\r\n <mat-icon>pin_drop</mat-icon>\r\n copy coords\r\n </button>\r\n</div>\r\n\r\n<!-- Text display -->\r\n<div id=\"text\" tabindex=\"0\" (keydown)=\"onKeyDown($event)\">\r\n @for (line of lines(); track $index) {\r\n <div class=\"line\">\r\n @if (hasLineNumber()) {\r\n <div class=\"nr\">\r\n {{ lines().indexOf(line) + 1 }}\r\n </div>\r\n }\r\n @for (c of line; track c.id) {\r\n <gve-base-text-char [char]=\"c\" (charPick)=\"onCharPick($event)\" />\r\n }\r\n </div>\r\n }\r\n</div>\r\n", styles: [".toolbar{display:flex;align-items:center;gap:8px;margin-bottom:8px;flex-wrap:wrap}.search-field{flex:0 0 auto;min-width:200px;max-width:300px}.match-count{font-weight:700;padding:4px 8px;border-radius:4px;background-color:#e8f5e9;color:#2e7d32}.match-count.no-matches{background-color:#ffebee;color:#c62828}.line{display:flex;gap:8px;align-items:center;flex-wrap:wrap}.line *{flex:0 0 auto}.nr{font-size:.8em;font-weight:700;color:silver;margin:0 4px}\n"] }]
|
|
649
|
+
], changeDetection: ChangeDetectionStrategy.OnPush, template: "<!-- Toolbar -->\r\n<div class=\"toolbar\">\r\n <mat-form-field appearance=\"outline\" class=\"search-field\">\r\n <input\r\n matInput\r\n [ngModel]=\"searchQuery()\"\r\n (ngModelChange)=\"onSearchInput($event)\"\r\n placeholder=\"search\"\r\n />\r\n @if (searchQuery()) {\r\n <button\r\n type=\"button\"\r\n matSuffix\r\n mat-icon-button\r\n matTooltip=\"Clear search\"\r\n (click)=\"clearSearch()\"\r\n >\r\n <mat-icon class=\"mat-warn\">close</mat-icon>\r\n </button>\r\n }\r\n </mat-form-field>\r\n\r\n @if (isSearchActive()) {\r\n <span class=\"match-count\" [class.no-matches]=\"matchCount() === 0\">\r\n {{ matchCount() }}\r\n </span>\r\n }\r\n\r\n <button\r\n type=\"button\"\r\n mat-stroked-button\r\n matTooltip=\"Copy selection text to clipboard\"\r\n [disabled]=\"!hasSelection()\"\r\n (click)=\"copySelection()\"\r\n >\r\n <mat-icon>content_copy</mat-icon>\r\n copy\r\n </button>\r\n\r\n <button\r\n type=\"button\"\r\n mat-stroked-button\r\n matTooltip=\"Copy selection coordinates to clipboard\"\r\n [disabled]=\"!hasSelection()\"\r\n (click)=\"copyCoordinates()\"\r\n >\r\n <mat-icon>pin_drop</mat-icon>\r\n copy coords\r\n </button>\r\n\r\n @if (pickedIds()) {\r\n <span class=\"picked-ids\" matTooltip=\"Double-clicked character IDs\">{{ pickedIds() }}</span>\r\n <button\r\n type=\"button\"\r\n mat-icon-button\r\n matTooltip=\"Clear collected IDs\"\r\n (click)=\"clearPickedIds()\"\r\n >\r\n <mat-icon>clear</mat-icon>\r\n </button>\r\n <button\r\n type=\"button\"\r\n mat-icon-button\r\n matTooltip=\"Copy collected IDs to clipboard\"\r\n (click)=\"copyPickedIds()\"\r\n >\r\n <mat-icon>content_copy</mat-icon>\r\n </button>\r\n }\r\n</div>\r\n\r\n<!-- Text display -->\r\n<div id=\"text\" tabindex=\"0\" (keydown)=\"onKeyDown($event)\">\r\n @for (line of lines(); track $index) {\r\n <div class=\"line\">\r\n @if (hasLineNumber()) {\r\n <div class=\"nr\">\r\n {{ lines().indexOf(line) + 1 }}\r\n </div>\r\n }\r\n @for (c of line; track c.id) {\r\n <gve-base-text-char [char]=\"c\" (charPick)=\"onCharPick($event)\" (charDblPick)=\"onCharDblPick($event)\" />\r\n }\r\n </div>\r\n }\r\n</div>\r\n", styles: [".toolbar{display:flex;align-items:center;gap:8px;margin-bottom:8px;flex-wrap:wrap}.search-field{flex:0 0 auto;min-width:200px;max-width:300px}.match-count{font-weight:700;padding:4px 8px;border-radius:4px;background-color:#e8f5e9;color:#2e7d32}.match-count.no-matches{background-color:#ffebee;color:#c62828}.line{display:flex;gap:8px;align-items:center;flex-wrap:wrap}.line *{flex:0 0 auto}.nr{font-size:.8em;font-weight:700;color:silver;margin:0 4px}.picked-ids{font-family:monospace;font-size:.85em;padding:4px 8px;border-radius:4px;background-color:#e3f2fd;color:#1565c0;border:1px solid #90caf9;max-width:300px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}\n"] }]
|
|
612
650
|
}], ctorParameters: () => [], propDecorators: { defaultColor: [{ type: i0.Input, args: [{ isSignal: true, alias: "defaultColor", required: false }] }], defaultBorderColor: [{ type: i0.Input, args: [{ isSignal: true, alias: "defaultBorderColor", required: false }] }], selectionColor: [{ type: i0.Input, args: [{ isSignal: true, alias: "selectionColor", required: false }] }], searchHighlightColor: [{ type: i0.Input, args: [{ isSignal: true, alias: "searchHighlightColor", required: false }] }], hasLineNumber: [{ type: i0.Input, args: [{ isSignal: true, alias: "hasLineNumber", required: false }] }], text: [{ type: i0.Input, args: [{ isSignal: true, alias: "text", required: false }] }], colorCallback: [{ type: i0.Input, args: [{ isSignal: true, alias: "colorCallback", required: false }] }], borderColorCallback: [{ type: i0.Input, args: [{ isSignal: true, alias: "borderColorCallback", required: false }] }], charPick: [{ type: i0.Output, args: ["charPick"] }], rangePick: [{ type: i0.Output, args: ["rangePick"] }] } });
|
|
613
651
|
|
|
614
652
|
/**
|
|
@@ -637,39 +675,60 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.0", ngImpor
|
|
|
637
675
|
*/
|
|
638
676
|
class FeatureEditorComponent {
|
|
639
677
|
constructor(formBuilder) {
|
|
640
|
-
this.nameControl = viewChild('nameCtl', ...(ngDevMode ? [{ debugName: "nameControl" }] : []));
|
|
678
|
+
this.nameControl = viewChild('nameCtl', ...(ngDevMode ? [{ debugName: "nameControl" }] : /* istanbul ignore next */ []));
|
|
641
679
|
/**
|
|
642
680
|
* The list of feature names to display in the name selection.
|
|
643
681
|
* This is used when you have a closed list of features.
|
|
644
682
|
*/
|
|
645
|
-
this.featNames = input(...(ngDevMode ? [undefined, { debugName: "featNames" }] : []));
|
|
683
|
+
this.featNames = input(...(ngDevMode ? [undefined, { debugName: "featNames" }] : /* istanbul ignore next */ []));
|
|
646
684
|
/**
|
|
647
685
|
* The feature values map. When specified and the user selects a feature
|
|
648
686
|
* name present in the map keys, the corresponding values will be used
|
|
649
687
|
* to populate the value selection.
|
|
650
688
|
*/
|
|
651
|
-
this.featValues = input(...(ngDevMode ? [undefined, { debugName: "featValues" }] : []));
|
|
689
|
+
this.featValues = input(...(ngDevMode ? [undefined, { debugName: "featValues" }] : /* istanbul ignore next */ []));
|
|
652
690
|
/**
|
|
653
691
|
* The feature to edit.
|
|
654
692
|
*/
|
|
655
|
-
this.feature = model(...(ngDevMode ? [undefined, { debugName: "feature" }] : []));
|
|
693
|
+
this.feature = model(...(ngDevMode ? [undefined, { debugName: "feature" }] : /* istanbul ignore next */ []));
|
|
656
694
|
/**
|
|
657
695
|
* True if the feature is a variant operation feature, which has
|
|
658
696
|
* additional properties like negation, global, and short-lived.
|
|
659
697
|
*/
|
|
660
|
-
this.isVar = input(false, ...(ngDevMode ? [{ debugName: "isVar" }] : []));
|
|
698
|
+
this.isVar = input(false, ...(ngDevMode ? [{ debugName: "isVar" }] : /* istanbul ignore next */ []));
|
|
661
699
|
/**
|
|
662
700
|
* The IDs of the features that are multi-valued. Used to determine
|
|
663
701
|
* if the current feature being edited should display multi-value controls.
|
|
664
702
|
*/
|
|
665
703
|
this.multiValuedFeatureIds = input([
|
|
666
704
|
'r_hints',
|
|
667
|
-
], ...(ngDevMode ? [{ debugName: "multiValuedFeatureIds" }] : []));
|
|
705
|
+
], ...(ngDevMode ? [{ debugName: "multiValuedFeatureIds" }] : /* istanbul ignore next */ []));
|
|
668
706
|
/**
|
|
669
707
|
* Event emitted when the user cancels the feature editing.
|
|
670
708
|
*/
|
|
671
709
|
this.featureCancel = output();
|
|
672
|
-
|
|
710
|
+
/**
|
|
711
|
+
* The allowed value IDs for the currently selected feature name.
|
|
712
|
+
* Set synchronously in updateForm (on feature load) and in the
|
|
713
|
+
* name.valueChanges subscription (on user interaction).
|
|
714
|
+
*/
|
|
715
|
+
this.nameIds = signal(undefined, ...(ngDevMode ? [{ debugName: "nameIds" }] : /* istanbul ignore next */ []));
|
|
716
|
+
/**
|
|
717
|
+
* Tracks the current feature name. Updated synchronously in updateForm
|
|
718
|
+
* and in the name.valueChanges subscription so that isMultiValued stays
|
|
719
|
+
* in sync regardless of whether the change was programmatic or user-driven.
|
|
720
|
+
*/
|
|
721
|
+
this._currentName = signal('', ...(ngDevMode ? [{ debugName: "_currentName" }] : /* istanbul ignore next */ []));
|
|
722
|
+
/**
|
|
723
|
+
* Computed signal that determines if the current feature is multi-valued.
|
|
724
|
+
* Automatically updates when either _currentName or multiValuedFeatureIds
|
|
725
|
+
* changes.
|
|
726
|
+
*/
|
|
727
|
+
this.isMultiValued = computed(() => {
|
|
728
|
+
const ids = this.multiValuedFeatureIds();
|
|
729
|
+
const name = this._currentName();
|
|
730
|
+
return !!ids && !!name && ids.includes(name);
|
|
731
|
+
}, ...(ngDevMode ? [{ debugName: "isMultiValued" }] : /* istanbul ignore next */ []));
|
|
673
732
|
this.name = formBuilder.control('', {
|
|
674
733
|
validators: [Validators.required, Validators.maxLength(50)],
|
|
675
734
|
nonNullable: true,
|
|
@@ -696,41 +755,29 @@ class FeatureEditorComponent {
|
|
|
696
755
|
isGlobal: this.isGlobal,
|
|
697
756
|
isShortLived: this.isShortLived,
|
|
698
757
|
});
|
|
699
|
-
//
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
});
|
|
703
|
-
// Computed signal that automatically tracks dependencies and triggers
|
|
704
|
-
// change detection when either name or multiValuedFeatureIds changes
|
|
705
|
-
this.isMultiValued = computed(() => {
|
|
706
|
-
const ids = this.multiValuedFeatureIds();
|
|
707
|
-
const name = this.nameSignal();
|
|
708
|
-
return !!ids && !!name && ids.includes(name);
|
|
709
|
-
}, ...(ngDevMode ? [{ debugName: "isMultiValued" }] : []));
|
|
710
|
-
// when feature changes, update the form
|
|
758
|
+
// When the feature input changes, repopulate the form atomically.
|
|
759
|
+
// featValues is read via untracked() so changes to it do not retrigger
|
|
760
|
+
// this effect and accidentally overwrite in-progress user edits.
|
|
711
761
|
effect(() => {
|
|
712
762
|
this.updateForm(this.feature());
|
|
713
|
-
setTimeout(() =>
|
|
714
|
-
this.nameControl()?.nativeElement?.focus();
|
|
715
|
-
this.nameIds.set(this.getLabeledIdsFor(this.name.value, this.featValues()));
|
|
716
|
-
}, 500);
|
|
717
|
-
});
|
|
718
|
-
// diagnostic logging for multiValuedFeatureIds
|
|
719
|
-
effect(() => {
|
|
720
|
-
console.log('[FeatureEditor] multiValuedFeatureIds:', this.multiValuedFeatureIds(), 'isMultiValued:', this.isMultiValued());
|
|
763
|
+
setTimeout(() => this.nameControl()?.nativeElement?.focus(), 0);
|
|
721
764
|
});
|
|
722
765
|
}
|
|
723
766
|
ngOnInit() {
|
|
724
|
-
//
|
|
767
|
+
// Respond to user-initiated name changes only.
|
|
768
|
+
// updateForm uses { emitEvent: false } so programmatic loads never
|
|
769
|
+
// reach this subscription, eliminating the race that caused value.reset()
|
|
770
|
+
// to fire after a 300 ms debounce and wipe the just-loaded value.
|
|
725
771
|
this._sub = this.name.valueChanges
|
|
726
772
|
.pipe(debounceTime(300), distinctUntilChanged())
|
|
727
773
|
.subscribe((name) => {
|
|
728
|
-
|
|
774
|
+
this._currentName.set(name);
|
|
775
|
+
this.nameIds.set(this.getLabeledIdsFor(name, this.featValues()));
|
|
776
|
+
// Reset value only when preset names are in use; for free-text names
|
|
777
|
+
// the value is independent and must not be cleared.
|
|
778
|
+
if (this.featNames()?.length) {
|
|
729
779
|
this.value.reset();
|
|
730
|
-
this.nameIds.set(this.getLabeledIdsFor(name, this.featValues()));
|
|
731
780
|
}
|
|
732
|
-
// Note: isMultiValued is now a computed signal that automatically
|
|
733
|
-
// updates when nameSignal or multiValuedFeatureIds changes
|
|
734
781
|
});
|
|
735
782
|
}
|
|
736
783
|
ngOnDestroy() {
|
|
@@ -740,26 +787,32 @@ class FeatureEditorComponent {
|
|
|
740
787
|
if (!id) {
|
|
741
788
|
return undefined;
|
|
742
789
|
}
|
|
743
|
-
console.log('getLabeledIdsFor', id, featValues);
|
|
744
790
|
return featValues ? featValues[id] : undefined;
|
|
745
791
|
}
|
|
746
792
|
updateForm(feature) {
|
|
747
793
|
if (!feature) {
|
|
794
|
+
this._currentName.set('');
|
|
795
|
+
this.nameIds.set(undefined);
|
|
748
796
|
this.form.reset();
|
|
749
|
-
// Note: isMultiValued is a computed signal - it will automatically
|
|
750
|
-
// update to false when name is reset to empty string
|
|
751
797
|
}
|
|
752
798
|
else {
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
799
|
+
// Read featValues outside the reactive context so that changes to
|
|
800
|
+
// featValues alone do not re-trigger the parent effect and overwrite
|
|
801
|
+
// any in-progress user edits.
|
|
802
|
+
const featValues = untracked(() => this.featValues());
|
|
803
|
+
// Update derived signals first so the template can resolve the correct
|
|
804
|
+
// control type (select vs text) before Angular renders.
|
|
805
|
+
this._currentName.set(feature.name);
|
|
806
|
+
this.nameIds.set(this.getLabeledIdsFor(feature.name, featValues));
|
|
807
|
+
// Use emitEvent: false to suppress valueChanges events.
|
|
808
|
+
// This prevents the name.valueChanges subscription (which resets the
|
|
809
|
+
// value control) from firing during a programmatic load.
|
|
810
|
+
this.name.setValue(feature.name, { emitEvent: false });
|
|
811
|
+
this.value.setValue(feature.value, { emitEvent: false });
|
|
756
812
|
this.setPolicy.setValue(feature.setPolicy || FeatureSetPolicy.multiple);
|
|
757
813
|
this.isNegated.setValue(feature.isNegated || false);
|
|
758
814
|
this.isGlobal.setValue(feature.isGlobal || false);
|
|
759
815
|
this.isShortLived.setValue(feature.isShortLived || false);
|
|
760
|
-
// Note: isMultiValued is a computed signal - it will automatically
|
|
761
|
-
// update based on the new name value and multiValuedFeatureIds
|
|
762
|
-
this._frozen = false;
|
|
763
816
|
}
|
|
764
817
|
}
|
|
765
818
|
addValueToComposite() {
|
|
@@ -799,10 +852,10 @@ class FeatureEditorComponent {
|
|
|
799
852
|
setPolicy: this.setPolicy.value,
|
|
800
853
|
});
|
|
801
854
|
}
|
|
802
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.
|
|
803
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.
|
|
855
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.3", ngImport: i0, type: FeatureEditorComponent, deps: [{ token: i1$1.FormBuilder }], target: i0.ɵɵFactoryTarget.Component }); }
|
|
856
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.3", type: FeatureEditorComponent, isStandalone: true, selector: "gve-feature-editor", inputs: { featNames: { classPropertyName: "featNames", publicName: "featNames", isSignal: true, isRequired: false, transformFunction: null }, featValues: { classPropertyName: "featValues", publicName: "featValues", isSignal: true, isRequired: false, transformFunction: null }, feature: { classPropertyName: "feature", publicName: "feature", isSignal: true, isRequired: false, transformFunction: null }, isVar: { classPropertyName: "isVar", publicName: "isVar", isSignal: true, isRequired: false, transformFunction: null }, multiValuedFeatureIds: { classPropertyName: "multiValuedFeatureIds", publicName: "multiValuedFeatureIds", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { feature: "featureChange", featureCancel: "featureCancel" }, viewQueries: [{ propertyName: "nameControl", first: true, predicate: ["nameCtl"], descendants: true, isSignal: true }], ngImport: i0, template: "<form [formGroup]=\"form\" (submit)=\"save()\">\r\n <div class=\"form-row\">\r\n @if (featNames()?.length) {\r\n <!-- name (bound) -->\r\n <mat-form-field>\r\n <mat-label>name</mat-label>\r\n <mat-select #nameCtl [formControl]=\"name\">\r\n @for (i of featNames(); track i) {\r\n <mat-option [value]=\"i.id\">{{ i.label }}</mat-option>\r\n }\r\n </mat-select>\r\n @if ($any(name).errors?.required && (name.dirty || name.touched)) {\r\n <mat-error>name required</mat-error>\r\n }\r\n </mat-form-field>\r\n } @else {\r\n <!-- name (free) -->\r\n <mat-form-field>\r\n <mat-label>name</mat-label>\r\n <input #nameCtl matInput [formControl]=\"name\" />\r\n @if ($any(name).errors?.required && (name.dirty || name.touched)) {\r\n <mat-error>name required</mat-error>\r\n }\r\n @if ($any(name).errors?.maxLength && (name.dirty || name.touched)) {\r\n <mat-error>name too long</mat-error>\r\n }\r\n </mat-form-field>\r\n }\r\n\r\n <!-- value (bound) -->\r\n @if (nameIds()?.length) {\r\n @if (isMultiValued()) {\r\n <!-- multi-valued: select for picking + text for composite -->\r\n <mat-form-field>\r\n <mat-label>select value</mat-label>\r\n <mat-select [formControl]=\"selectedValue\">\r\n @for (e of nameIds(); track e) {\r\n <mat-option [value]=\"e.id\">{{ e.label }}</mat-option>\r\n }\r\n </mat-select>\r\n </mat-form-field>\r\n <button\r\n type=\"button\"\r\n color=\"primary\"\r\n mat-icon-button\r\n matTooltip=\"Add selected value\"\r\n (click)=\"addValueToComposite()\"\r\n [disabled]=\"!selectedValue.value\"\r\n >\r\n <mat-icon class=\"mat-primary\">add</mat-icon>\r\n </button>\r\n <mat-form-field>\r\n <mat-label>composite value</mat-label>\r\n <input matInput [formControl]=\"value\" />\r\n @if (\r\n $any(value).errors?.maxLength && (value.dirty || value.touched)\r\n ) {\r\n <mat-error>value too long</mat-error>\r\n }\r\n </mat-form-field>\r\n } @else {\r\n <!-- single-valued: just select -->\r\n <mat-form-field>\r\n <mat-label>value</mat-label>\r\n <mat-select [formControl]=\"value\">\r\n @for (e of nameIds(); track e) {\r\n <mat-option [value]=\"e.id\">{{ e.label }}</mat-option>\r\n }\r\n </mat-select>\r\n @if ($any(value).errors?.required && (value.dirty || value.touched)) {\r\n <mat-error>value required</mat-error>\r\n }\r\n </mat-form-field>\r\n }\r\n } @else {\r\n <!-- value (free) -->\r\n <mat-form-field>\r\n <mat-label>value</mat-label>\r\n <input matInput [formControl]=\"value\" />\r\n @if ($any(value).errors?.required && (value.dirty || value.touched)) {\r\n <mat-error>value required</mat-error>\r\n }\r\n @if ($any(value).errors?.maxLength && (value.dirty || value.touched)) {\r\n <mat-error>value too long</mat-error>\r\n }\r\n </mat-form-field>\r\n }\r\n\r\n <!-- setPolicy -->\r\n <mat-form-field>\r\n <mat-label>set policy</mat-label>\r\n <mat-select [formControl]=\"setPolicy\">\r\n <mat-option [value]=\"0\">multiple</mat-option>\r\n <mat-option [value]=\"1\">single</mat-option>\r\n <mat-option [value]=\"2\">single first</mat-option>\r\n </mat-select>\r\n </mat-form-field>\r\n </div>\r\n\r\n @if (isVar()) {\r\n <div class=\"form-row\">\r\n <!-- isNegated -->\r\n <mat-checkbox [formControl]=\"isNegated\">negated</mat-checkbox>\r\n\r\n <!-- isShortLived -->\r\n <mat-checkbox [formControl]=\"isShortLived\">short-lived</mat-checkbox>\r\n\r\n <!-- isGlobal -->\r\n <mat-checkbox [formControl]=\"isGlobal\">global</mat-checkbox>\r\n </div>\r\n }\r\n\r\n <!-- buttons -->\r\n <div class=\"form-row\">\r\n <button\r\n type=\"button\"\r\n color=\"warn\"\r\n mat-icon-button\r\n matTooltip=\"Discard changes\"\r\n (click)=\"cancel()\"\r\n >\r\n <mat-icon class=\"mat-warn\">clear</mat-icon>\r\n </button>\r\n <button\r\n type=\"submit\"\r\n color=\"primary\"\r\n mat-icon-button\r\n matTooltip=\"Accept changes\"\r\n [disabled]=\"form.invalid || form.pristine\"\r\n >\r\n <mat-icon class=\"mat-primary\">check_circle</mat-icon>\r\n </button>\r\n </div>\r\n</form>\r\n", styles: [".form-row{display:flex;gap:8px;align-items:center;flex-wrap:wrap}.form-row *{flex:0 0 auto}\n"], dependencies: [{ kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1$1.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$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],[formArray],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$1.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i2.MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "ngmodule", type: MatCheckboxModule }, { kind: "component", type: i3$1.MatCheckbox, selector: "mat-checkbox", inputs: ["aria-label", "aria-labelledby", "aria-describedby", "aria-expanded", "aria-controls", "aria-owns", "id", "required", "labelPosition", "name", "value", "disableRipple", "tabIndex", "color", "disabledInteractive", "checked", "disabled", "indeterminate"], outputs: ["change", "indeterminateChange"], exportAs: ["matCheckbox"] }, { 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: "directive", type: i3.MatError, selector: "mat-error, [matError]", inputs: ["id"] }, { 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", "disabledInteractive"], exportAs: ["matInput"] }, { kind: "ngmodule", type: MatSelectModule }, { kind: "component", type: i7.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", "canSelectNullableOptions"], outputs: ["openedChange", "opened", "closed", "selectionChange", "valueChange"], exportAs: ["matSelect"] }, { kind: "component", type: i7.MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i6.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
804
857
|
}
|
|
805
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.
|
|
858
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.3", ngImport: i0, type: FeatureEditorComponent, decorators: [{
|
|
806
859
|
type: Component,
|
|
807
860
|
args: [{ selector: 'gve-feature-editor', changeDetection: ChangeDetectionStrategy.OnPush, imports: [
|
|
808
861
|
ReactiveFormsModule,
|
|
@@ -848,25 +901,25 @@ class FeatureSetEditorComponent {
|
|
|
848
901
|
* True if the feature is a variant operation feature, which has
|
|
849
902
|
* additional properties like negation, global, and short-lived.
|
|
850
903
|
*/
|
|
851
|
-
this.isVar = input(true, ...(ngDevMode ? [{ debugName: "isVar" }] : []));
|
|
904
|
+
this.isVar = input(true, ...(ngDevMode ? [{ debugName: "isVar" }] : /* istanbul ignore next */ []));
|
|
852
905
|
/**
|
|
853
906
|
* The list of feature names to display in the name selection.
|
|
854
907
|
* This is used when you have a closed list of features.
|
|
855
908
|
*/
|
|
856
|
-
this.featNames = input(...(ngDevMode ? [undefined, { debugName: "featNames" }] : []));
|
|
909
|
+
this.featNames = input(...(ngDevMode ? [undefined, { debugName: "featNames" }] : /* istanbul ignore next */ []));
|
|
857
910
|
/**
|
|
858
911
|
* The feature values map. When specified and the user selects a feature
|
|
859
912
|
* name present in the map keys, the corresponding values will be used
|
|
860
913
|
* to populate the value selection.
|
|
861
914
|
*/
|
|
862
|
-
this.featValues = input(...(ngDevMode ? [undefined, { debugName: "featValues" }] : []));
|
|
915
|
+
this.featValues = input(...(ngDevMode ? [undefined, { debugName: "featValues" }] : /* istanbul ignore next */ []));
|
|
863
916
|
/**
|
|
864
917
|
* The threshold at which the features filter should become visible.
|
|
865
918
|
* If set to 0, the filter is always visible; if set to -1, it is always
|
|
866
919
|
* invisible; otherwise, it gets visible when the number of features
|
|
867
920
|
* is greater than or equal to the threshold. Default is 5.
|
|
868
921
|
*/
|
|
869
|
-
this.filterThreshold = input(5, ...(ngDevMode ? [{ debugName: "filterThreshold" }] : []));
|
|
922
|
+
this.filterThreshold = input(5, ...(ngDevMode ? [{ debugName: "filterThreshold" }] : /* istanbul ignore next */ []));
|
|
870
923
|
/**
|
|
871
924
|
* The IDs of the features that are multi-valued. If a feature being
|
|
872
925
|
* edited is in this list, the feature editor will allow adding multiple
|
|
@@ -874,23 +927,19 @@ class FeatureSetEditorComponent {
|
|
|
874
927
|
*/
|
|
875
928
|
this.multiValuedFeatureIds = input([
|
|
876
929
|
'r_hints',
|
|
877
|
-
], ...(ngDevMode ? [{ debugName: "multiValuedFeatureIds" }] : []));
|
|
930
|
+
], ...(ngDevMode ? [{ debugName: "multiValuedFeatureIds" }] : /* istanbul ignore next */ []));
|
|
878
931
|
/**
|
|
879
932
|
* The features to edit.
|
|
880
933
|
*/
|
|
881
|
-
this.features = model([], ...(ngDevMode ? [{ debugName: "features" }] : []));
|
|
882
|
-
this.editedFeature = signal(undefined, ...(ngDevMode ? [{ debugName: "editedFeature" }] : []));
|
|
883
|
-
this.editedFeatureIndex = signal(-1, ...(ngDevMode ? [{ debugName: "editedFeatureIndex" }] : []));
|
|
884
|
-
this.filteredFeatures = signal([], ...(ngDevMode ? [{ debugName: "filteredFeatures" }] : []));
|
|
934
|
+
this.features = model([], ...(ngDevMode ? [{ debugName: "features" }] : /* istanbul ignore next */ []));
|
|
935
|
+
this.editedFeature = signal(undefined, ...(ngDevMode ? [{ debugName: "editedFeature" }] : /* istanbul ignore next */ []));
|
|
936
|
+
this.editedFeatureIndex = signal(-1, ...(ngDevMode ? [{ debugName: "editedFeatureIndex" }] : /* istanbul ignore next */ []));
|
|
937
|
+
this.filteredFeatures = signal([], ...(ngDevMode ? [{ debugName: "filteredFeatures" }] : /* istanbul ignore next */ []));
|
|
885
938
|
this.filter = formBuilder.control(null);
|
|
886
939
|
// when features change, apply the filter
|
|
887
940
|
effect(() => {
|
|
888
941
|
this.applyFeatureFilter(this.features(), this.filter.value);
|
|
889
942
|
});
|
|
890
|
-
// diagnostic logging for multiValuedFeatureIds
|
|
891
|
-
effect(() => {
|
|
892
|
-
console.log('[FeatureSetEditor] multiValuedFeatureIds:', this.multiValuedFeatureIds());
|
|
893
|
-
});
|
|
894
943
|
}
|
|
895
944
|
applyFeatureFilter(features, name) {
|
|
896
945
|
this.filteredFeatures.set(features.filter((feature) => {
|
|
@@ -961,10 +1010,10 @@ class FeatureSetEditorComponent {
|
|
|
961
1010
|
this.editedFeature.set(undefined);
|
|
962
1011
|
this.editedFeatureIndex.set(-1);
|
|
963
1012
|
}
|
|
964
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.
|
|
965
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.
|
|
1013
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.3", ngImport: i0, type: FeatureSetEditorComponent, deps: [{ token: i1$1.FormBuilder }], target: i0.ɵɵFactoryTarget.Component }); }
|
|
1014
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.3", type: FeatureSetEditorComponent, isStandalone: true, selector: "gve-feature-set-editor", inputs: { isVar: { classPropertyName: "isVar", publicName: "isVar", isSignal: true, isRequired: false, transformFunction: null }, featNames: { classPropertyName: "featNames", publicName: "featNames", isSignal: true, isRequired: false, transformFunction: null }, featValues: { classPropertyName: "featValues", publicName: "featValues", isSignal: true, isRequired: false, transformFunction: null }, filterThreshold: { classPropertyName: "filterThreshold", publicName: "filterThreshold", isSignal: true, isRequired: false, transformFunction: null }, multiValuedFeatureIds: { classPropertyName: "multiValuedFeatureIds", publicName: "multiValuedFeatureIds", isSignal: true, isRequired: false, transformFunction: null }, features: { classPropertyName: "features", publicName: "features", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { features: "featuresChange" }, ngImport: i0, template: "<div>\r\n <div class=\"form-row\">\r\n <!-- filter -->\r\n @if (filterThreshold() === 0 || features().length >= filterThreshold()) {\r\n <mat-form-field>\r\n <input matInput placeholder=\"filter\" [formControl]=\"filter\" />\r\n <button\r\n type=\"button\"\r\n mat-icon-button\r\n matSuffix\r\n (click)=\"filter.reset()\"\r\n [disabled]=\"!filter.value\"\r\n [attr.aria-label]=\"'Reset filter'\"\r\n >\r\n <mat-icon color=\"warn\" class=\"mat-warn\">cancel</mat-icon>\r\n </button>\r\n </mat-form-field>\r\n }\r\n\r\n <!-- add feature button -->\r\n <button\r\n type=\"button\"\r\n color=\"primary\"\r\n class=\"mat-primary\"\r\n mat-flat-button\r\n matTooltip=\"Add a new feature\"\r\n (click)=\"addFeature()\"\r\n [class.in-row-button]=\"\r\n filterThreshold() === 0 || features()!.length >= filterThreshold()\r\n \"\r\n >\r\n <mat-icon>add</mat-icon>\r\n feature\r\n </button>\r\n </div>\r\n\r\n <!-- list -->\r\n @if (features().length) {\r\n <table>\r\n <thead>\r\n <tr>\r\n <th></th>\r\n <th>feature</th>\r\n <th>value</th>\r\n <th>policy</th>\r\n @if (isVar()) {\r\n <th>flags</th>\r\n }\r\n </tr>\r\n </thead>\r\n <tbody>\r\n @for (feature of filteredFeatures(); track $index) {\r\n <tr [class.selected]=\"$index === editedFeatureIndex()\">\r\n <td class=\"fit-width\">\r\n <!-- edit -->\r\n <button\r\n type=\"button\"\r\n color=\"primary\"\r\n mat-icon-button\r\n matTooltip=\"Edit this feature\"\r\n (click)=\"editFeature(feature)\"\r\n >\r\n <mat-icon class=\"mat-primary\">edit</mat-icon>\r\n </button>\r\n <!-- delete -->\r\n <button\r\n type=\"button\"\r\n color=\"warn\"\r\n mat-icon-button\r\n matTooltip=\"Delete this feature\"\r\n (click)=\"deleteFeature(feature)\"\r\n >\r\n <mat-icon class=\"mat-warn\">delete</mat-icon>\r\n </button>\r\n </td>\r\n <td>\r\n @if (featNames()?.length) {\r\n <span>{{\r\n feature.name | flatLookup: featNames() : \"id\" : \"label\"\r\n }}</span>\r\n } @else {\r\n <span>{{ feature.name }}</span>\r\n }\r\n </td>\r\n <td>\r\n @if (featValues()) {\r\n <span>{{\r\n feature.value | flatLookup: featValues()![feature.name]\r\n }}</span>\r\n } @else {\r\n <span>{{ feature.value }}</span>\r\n }\r\n </td>\r\n <td>\r\n <span>{{ POLICIES[feature.setPolicy] }}</span>\r\n </td>\r\n @if (isVar()) {\r\n <td>\r\n @if ($any(feature).isNegated) {\r\n <span class=\"icon\" matTooltip=\"Negated: remove if present\">\r\n <mat-icon class=\"mat-warn\">remove_circle</mat-icon>\r\n </span>\r\n }\r\n @if ($any(feature).isGlobal) {\r\n <span class=\"icon\" matTooltip=\"Global: apply to whole output\">\r\n <mat-icon class=\"mat-primary\">public</mat-icon>\r\n </span>\r\n }\r\n @if ($any(feature).isShortLived) {\r\n <span\r\n class=\"icon\"\r\n matTooltip=\"Short-lived: removed on next operation\"\r\n >\r\n <mat-icon class=\"mat-accent\">timer</mat-icon>\r\n </span>\r\n }\r\n </td>\r\n }\r\n </tr>\r\n }\r\n </tbody>\r\n </table>\r\n }\r\n\r\n <!-- editor -->\r\n @if (editedFeature()) {\r\n <mat-expansion-panel\r\n [disabled]=\"!editedFeature()\"\r\n [expanded]=\"editedFeature()\"\r\n >\r\n <mat-expansion-panel-header>\r\n <mat-panel-title>\r\n <span>{{ editedFeature()?.name || \"feature\" }}</span>\r\n </mat-panel-title>\r\n </mat-expansion-panel-header>\r\n <gve-feature-editor\r\n [isVar]=\"isVar()\"\r\n [multiValuedFeatureIds]=\"multiValuedFeatureIds()\"\r\n [featNames]=\"featNames()\"\r\n [featValues]=\"featValues()\"\r\n [feature]=\"editedFeature()\"\r\n (featureChange)=\"onFeatureChange($event)\"\r\n (featureCancel)=\"onFeatureCancel()\"\r\n />\r\n </mat-expansion-panel>\r\n }\r\n</div>\r\n", styles: [".form-row{display:flex;gap:8px;align-items:center;flex-wrap:wrap}.form-row *{flex:0 0 auto}.in-row-button{margin-top:-16px}table{width:100%;border-collapse:collapse}tbody tr:nth-child(odd){background-color:#e2e2e2}th{text-align:left;font-weight:400;color:silver}td.fit-width{width:1px;white-space:nowrap}tr.selected{background-color:#d0d0d0!important}\n"], dependencies: [{ kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$1.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$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i2.MatButton, selector: " button[matButton], a[matButton], button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button], a[mat-button], a[mat-raised-button], a[mat-flat-button], a[mat-stroked-button] ", inputs: ["matButton"], exportAs: ["matButton", "matAnchor"] }, { kind: "component", type: i2.MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "ngmodule", type: MatExpansionModule }, { kind: "component", type: i7$1.MatExpansionPanel, selector: "mat-expansion-panel", inputs: ["hideToggle", "togglePosition"], outputs: ["afterExpand", "afterCollapse"], exportAs: ["matExpansionPanel"] }, { kind: "component", type: i7$1.MatExpansionPanelHeader, selector: "mat-expansion-panel-header", inputs: ["expandedHeight", "collapsedHeight", "tabIndex"] }, { kind: "directive", type: i7$1.MatExpansionPanelTitle, selector: "mat-panel-title" }, { 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.MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { 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", "disabledInteractive"], exportAs: ["matInput"] }, { kind: "ngmodule", type: MatSelectModule }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i6.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "component", type: FeatureEditorComponent, selector: "gve-feature-editor", inputs: ["featNames", "featValues", "feature", "isVar", "multiValuedFeatureIds"], outputs: ["featureChange", "featureCancel"] }, { kind: "pipe", type: FlatLookupPipe, name: "flatLookup" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
966
1015
|
}
|
|
967
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.
|
|
1016
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.3", ngImport: i0, type: FeatureSetEditorComponent, decorators: [{
|
|
968
1017
|
type: Component,
|
|
969
1018
|
args: [{ selector: 'gve-feature-set-editor', changeDetection: ChangeDetectionStrategy.OnPush, imports: [
|
|
970
1019
|
ReactiveFormsModule,
|
|
@@ -1042,7 +1091,7 @@ class BaseTextEditorComponent {
|
|
|
1042
1091
|
* objects, or undefined. In output this will be an array of `CharNode`
|
|
1043
1092
|
* objects.
|
|
1044
1093
|
*/
|
|
1045
|
-
this.text = input.required({ ...(ngDevMode ? { debugName: "text" } : {}), transform: (value) => {
|
|
1094
|
+
this.text = input.required({ ...(ngDevMode ? { debugName: "text" } : /* istanbul ignore next */ {}), transform: (value) => {
|
|
1046
1095
|
if (value === undefined) {
|
|
1047
1096
|
return undefined;
|
|
1048
1097
|
}
|
|
@@ -1061,14 +1110,14 @@ class BaseTextEditorComponent {
|
|
|
1061
1110
|
*/
|
|
1062
1111
|
this.multiValuedFeatureIds = input([
|
|
1063
1112
|
'r_hints',
|
|
1064
|
-
], ...(ngDevMode ? [{ debugName: "multiValuedFeatureIds" }] : []));
|
|
1113
|
+
], ...(ngDevMode ? [{ debugName: "multiValuedFeatureIds" }] : /* istanbul ignore next */ []));
|
|
1065
1114
|
/**
|
|
1066
1115
|
* Emitted for the edited text as an array of `CharNode`'s whenever it changes.
|
|
1067
1116
|
*/
|
|
1068
1117
|
this.textChange = output();
|
|
1069
|
-
this.selectedChar = signal(undefined, ...(ngDevMode ? [{ debugName: "selectedChar" }] : []));
|
|
1070
|
-
this.selectedCharLabel = signal(undefined, ...(ngDevMode ? [{ debugName: "selectedCharLabel" }] : []));
|
|
1071
|
-
this.textRange = signal(undefined, ...(ngDevMode ? [{ debugName: "textRange" }] : []));
|
|
1118
|
+
this.selectedChar = signal(undefined, ...(ngDevMode ? [{ debugName: "selectedChar" }] : /* istanbul ignore next */ []));
|
|
1119
|
+
this.selectedCharLabel = signal(undefined, ...(ngDevMode ? [{ debugName: "selectedCharLabel" }] : /* istanbul ignore next */ []));
|
|
1120
|
+
this.textRange = signal(undefined, ...(ngDevMode ? [{ debugName: "textRange" }] : /* istanbul ignore next */ []));
|
|
1072
1121
|
this.userText = formBuilder.control('', {
|
|
1073
1122
|
nonNullable: true,
|
|
1074
1123
|
validators: [Validators.required, Validators.maxLength(10000)],
|
|
@@ -1123,10 +1172,10 @@ class BaseTextEditorComponent {
|
|
|
1123
1172
|
}
|
|
1124
1173
|
});
|
|
1125
1174
|
}
|
|
1126
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.
|
|
1127
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.
|
|
1175
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.3", ngImport: i0, type: BaseTextEditorComponent, deps: [{ token: i1$1.FormBuilder }, { token: i4$1.DialogService }], target: i0.ɵɵFactoryTarget.Component }); }
|
|
1176
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.3", type: BaseTextEditorComponent, isStandalone: true, selector: "gve-base-text-editor", inputs: { text: { classPropertyName: "text", publicName: "text", isSignal: true, isRequired: true, transformFunction: null }, multiValuedFeatureIds: { classPropertyName: "multiValuedFeatureIds", publicName: "multiValuedFeatureIds", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { textChange: "textChange" }, ngImport: i0, template: "<form [formGroup]=\"form\" (submit)=\"setTextFromUser()\">\r\n <!-- text -->\r\n <div>\r\n <mat-form-field class=\"full-width\">\r\n <mat-label>text</mat-label>\r\n <textarea matInput [formControl]=\"userText\" rows=\"5\"></textarea>\r\n @if ( $any(userText).errors?.required && (userText.dirty ||\r\n userText.touched) ) {\r\n <mat-error>text required</mat-error>\r\n } @if ( $any(userText).errors?.maxLength && (userText.dirty ||\r\n userText.touched) ) {\r\n <mat-error>text too long</mat-error>\r\n }\r\n </mat-form-field>\r\n </div>\r\n <!-- buttons -->\r\n <div class=\"form-row\">\r\n <!-- set -->\r\n <button\r\n type=\"button\"\r\n mat-flat-button\r\n class=\"mat-warn\"\r\n matTooltip=\"Reset characters to newly entered text\"\r\n [disabled]=\"!userText.value\"\r\n (click)=\"setTextFromUser()\"\r\n >\r\n set\r\n </button>\r\n </div>\r\n\r\n <!-- base text -->\r\n <div id=\"text-view\">\r\n <gve-base-text-view\r\n [text]=\"text() || []\"\r\n (charPick)=\"onSelectedChar($event)\"\r\n (rangePick)=\"textRange.set($event)\"\r\n />\r\n\r\n <!-- text range -->\r\n @if (textRange()) {\r\n <div id=\"text-range\">{{ textRange()!.at }} \u00D7 {{ textRange()!.run }}</div>\r\n }\r\n </div>\r\n\r\n <!-- char features -->\r\n @if (selectedChar()) {\r\n <fieldset>\r\n <legend>features</legend>\r\n <gve-feature-set-editor\r\n [features]=\"selectedChar()!.features || []\"\r\n [multiValuedFeatureIds]=\"multiValuedFeatureIds()\"\r\n (featuresChange)=\"onFeaturesChange($event)\"\r\n />\r\n </fieldset>\r\n }\r\n</form>\r\n", styles: [".full-width{width:100%}#text-view{margin:8px 0}fieldset{border:1px solid #ccc;padding:10px;margin:10px 0;border-radius:5px}legend{color:silver}.form-row{display:flex;gap:8px;align-items:center;flex-wrap:wrap}.form-row *{flex:0 0 auto}\n"], dependencies: [{ kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1$1.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$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],[formArray],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$1.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i2.MatButton, selector: " button[matButton], a[matButton], button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button], a[mat-button], a[mat-raised-button], a[mat-flat-button], a[mat-stroked-button] ", inputs: ["matButton"], exportAs: ["matButton", "matAnchor"] }, { 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: "directive", type: i3.MatError, selector: "mat-error, [matError]", inputs: ["id"] }, { kind: "ngmodule", type: MatIconModule }, { 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", "disabledInteractive"], exportAs: ["matInput"] }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i6.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "component", type: BaseTextViewComponent, selector: "gve-base-text-view", inputs: ["defaultColor", "defaultBorderColor", "selectionColor", "searchHighlightColor", "hasLineNumber", "text", "colorCallback", "borderColorCallback"], outputs: ["charPick", "rangePick"] }, { kind: "component", type: FeatureSetEditorComponent, selector: "gve-feature-set-editor", inputs: ["isVar", "featNames", "featValues", "filterThreshold", "multiValuedFeatureIds", "features"], outputs: ["featuresChange"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
1128
1177
|
}
|
|
1129
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.
|
|
1178
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.3", ngImport: i0, type: BaseTextEditorComponent, decorators: [{
|
|
1130
1179
|
type: Component,
|
|
1131
1180
|
args: [{ selector: 'gve-base-text-editor', imports: [
|
|
1132
1181
|
ReactiveFormsModule,
|
|
@@ -1219,10 +1268,10 @@ class GveApiService {
|
|
|
1219
1268
|
})
|
|
1220
1269
|
.pipe(catchError(this._error.handleError));
|
|
1221
1270
|
}
|
|
1222
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.
|
|
1223
|
-
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.
|
|
1271
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.3", ngImport: i0, type: GveApiService, deps: [{ token: i1$2.HttpClient }, { token: i2$1.ErrorService }, { token: i2$1.EnvService }], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
1272
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.3", ngImport: i0, type: GveApiService, providedIn: 'root' }); }
|
|
1224
1273
|
}
|
|
1225
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.
|
|
1274
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.3", ngImport: i0, type: GveApiService, decorators: [{
|
|
1226
1275
|
type: Injectable,
|
|
1227
1276
|
args: [{
|
|
1228
1277
|
providedIn: 'root',
|
|
@@ -1245,13 +1294,13 @@ class BatchOperationEditorComponent {
|
|
|
1245
1294
|
this._api = _api;
|
|
1246
1295
|
this.dialogRef = dialogRef;
|
|
1247
1296
|
this.data = data;
|
|
1248
|
-
this.busy = signal(false, ...(ngDevMode ? [{ debugName: "busy" }] : []));
|
|
1249
|
-
this.parseError = signal(undefined, ...(ngDevMode ? [{ debugName: "parseError" }] : []));
|
|
1297
|
+
this.busy = signal(false, ...(ngDevMode ? [{ debugName: "busy" }] : /* istanbul ignore next */ []));
|
|
1298
|
+
this.parseError = signal(undefined, ...(ngDevMode ? [{ debugName: "parseError" }] : /* istanbul ignore next */ []));
|
|
1250
1299
|
/**
|
|
1251
1300
|
* The preset text to parse if any. Usually you start with a blank
|
|
1252
1301
|
* text, but sometimes you might want to pre-set it.
|
|
1253
1302
|
*/
|
|
1254
|
-
this.preset = input(...(ngDevMode ? [undefined, { debugName: "preset" }] : []));
|
|
1303
|
+
this.preset = input(...(ngDevMode ? [undefined, { debugName: "preset" }] : /* istanbul ignore next */ []));
|
|
1255
1304
|
/**
|
|
1256
1305
|
* Emitted when operations change.
|
|
1257
1306
|
*/
|
|
@@ -1305,10 +1354,10 @@ class BatchOperationEditorComponent {
|
|
|
1305
1354
|
close() {
|
|
1306
1355
|
this.dialogRef?.close();
|
|
1307
1356
|
}
|
|
1308
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.
|
|
1309
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.
|
|
1357
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.3", ngImport: i0, type: BatchOperationEditorComponent, deps: [{ token: i1$1.FormBuilder }, { token: GveApiService }, { token: i3$2.MatDialogRef, optional: true }, { token: MAT_DIALOG_DATA, optional: true }], target: i0.ɵɵFactoryTarget.Component }); }
|
|
1358
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.3", type: BatchOperationEditorComponent, isStandalone: true, selector: "gve-batch-operation-editor", inputs: { preset: { classPropertyName: "preset", publicName: "preset", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { operationsChange: "operationsChange" }, ngImport: i0, template: "<div [style.padding]=\"dialogRef ? '8px' : '0'\">\r\n @if (dialogRef) {\r\n <div id=\"heading\">\r\n <h2>Add Operations</h2>\r\n </div>\r\n }\r\n <fieldset>\r\n <div id=\"batch-input\">\r\n <div>\r\n <mat-form-field class=\"full-width\">\r\n <mat-label>operations</mat-label>\r\n <textarea\r\n class=\"code\"\r\n matInput\r\n [formControl]=\"text\"\r\n rows=\"8\"\r\n spellcheck=\"false\"\r\n ></textarea>\r\n </mat-form-field>\r\n @if (parseError()) {\r\n <div class=\"error\">{{ parseError() }}</div>\r\n }\r\n </div>\r\n </div>\r\n <div id=\"batch-help\">\r\n <ul>\r\n <li>\r\n <strong>replace</strong>:\r\n <code>ATxRUN<strong>=</strong>\"VALUE\"</code>\r\n </li>\r\n <li>\r\n <strong>delete</strong>:\r\n <code>ATxRUN<strong>-</strong></code>\r\n </li>\r\n <li>\r\n <strong>add-before</strong>:\r\n <code>ATxRUN<strong>+[</strong>\"VALUE\"</code>\r\n </li>\r\n <li>\r\n <strong>add-after</strong>:\r\n <code>ATxRUN<strong>+]</strong>\"VALUE\"</code>\r\n </li>\r\n <li>\r\n <strong>move-before</strong>:\r\n <code>ATxRUN<strong>>[</strong>TO</code>\r\n </li>\r\n <li>\r\n <strong>move-after</strong>:\r\n <code>ATxRUN<strong>>]</strong>TO</code>\r\n </li>\r\n <li>\r\n <strong>swap</strong>:\r\n <code>ATxRUN<strong><></strong>TOxRUN</code>\r\n </li>\r\n <li>\r\n <strong>annotate</strong>:\r\n <code>ATxRUN<strong>:</strong></code>\r\n </li>\r\n </ul>\r\n <p>For all the operations:</p>\r\n <ul>\r\n <li>\r\n prefix <code>(ITAG:OTAG)</code> to define input and/or output tags,\r\n separated by colon.\r\n </li>\r\n <li>\r\n prepend <code>@</code> to AT to use character indexes (0-N)\r\n rather than IDs.\r\n </li>\r\n <li>RUN (where applicable) defaults to 1.</li>\r\n <li>\r\n append features like <code>[NAME OPERATOR VALUE]</code>, separated by\r\n space, where:\r\n </li>\r\n <li>\r\n <ol>\r\n <li>\r\n NAME is an arbitrary string. Prefixes:\r\n <code>*</code>=global features, <code>!</code>=remove feature (no\r\n value). Suffixes: <code>^</code>=short-lived (like\r\n <code>*version^=alpha</code>).\r\n </li>\r\n <li>\r\n OPERATOR is <code>=</code> (multiple), <code>:=</code> (single),\r\n <code>==</code> (first-single).\r\n </li>\r\n <li>\r\n VALUE is a string. If it includes spaces, wrap it in\r\n <code>\"\"</code>.\r\n </li>\r\n </ol>\r\n </li>\r\n </ul>\r\n </div>\r\n <div class=\"form-row-center\">\r\n @if (dialogRef) {\r\n <button\r\n type=\"button\"\r\n class=\"mat-warn\"\r\n mat-flat-button\r\n matTooltip=\"Close dialog\"\r\n (click)=\"close()\"\r\n >\r\n close\r\n </button>\r\n }\r\n <button\r\n type=\"button\"\r\n class=\"mat-primary\"\r\n mat-flat-button\r\n matTooltip=\"Parse text into operations\"\r\n [disabled]=\"!text.value || busy()\"\r\n (click)=\"parseOperations(text.value!)\"\r\n >\r\n batch add\r\n </button>\r\n </div>\r\n </fieldset>\r\n</div>\r\n", styles: [".full-width{width:100%}.error{color:red}.form-row{display:flex;gap:8px;align-items:center;flex-wrap:wrap}.form-row-center{display:flex;gap:8px;align-items:center;justify-content:center;flex-wrap:wrap}.form-row,.form-row-center *{flex:0 0 auto}div#heading{margin:8px;text-align:center}div#batch-help strong{color:#ff8c00}\n"], dependencies: [{ kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$1.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$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i2.MatButton, selector: " button[matButton], a[matButton], button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button], a[mat-button], a[mat-raised-button], a[mat-flat-button], a[mat-stroked-button] ", inputs: ["matButton"], exportAs: ["matButton", "matAnchor"] }, { 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: "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", "disabledInteractive"], exportAs: ["matInput"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
1310
1359
|
}
|
|
1311
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.
|
|
1360
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.3", ngImport: i0, type: BatchOperationEditorComponent, decorators: [{
|
|
1312
1361
|
type: Component,
|
|
1313
1362
|
args: [{ selector: 'gve-batch-operation-editor', changeDetection: ChangeDetectionStrategy.OnPush, imports: [
|
|
1314
1363
|
ReactiveFormsModule,
|
|
@@ -1347,15 +1396,15 @@ class OperationSourceEditorComponent {
|
|
|
1347
1396
|
/**
|
|
1348
1397
|
* The source to edit.
|
|
1349
1398
|
*/
|
|
1350
|
-
this.source = model(...(ngDevMode ? [undefined, { debugName: "source" }] : []));
|
|
1399
|
+
this.source = model(...(ngDevMode ? [undefined, { debugName: "source" }] : /* istanbul ignore next */ []));
|
|
1351
1400
|
/**
|
|
1352
1401
|
* The list of source IDs when it's a closed set.
|
|
1353
1402
|
*/
|
|
1354
|
-
this.ids = input(...(ngDevMode ? [undefined, { debugName: "ids" }] : []));
|
|
1403
|
+
this.ids = input(...(ngDevMode ? [undefined, { debugName: "ids" }] : /* istanbul ignore next */ []));
|
|
1355
1404
|
/**
|
|
1356
1405
|
* The list of source types when it's a closed set.
|
|
1357
1406
|
*/
|
|
1358
|
-
this.types = input(...(ngDevMode ? [undefined, { debugName: "types" }] : []));
|
|
1407
|
+
this.types = input(...(ngDevMode ? [undefined, { debugName: "types" }] : /* istanbul ignore next */ []));
|
|
1359
1408
|
/**
|
|
1360
1409
|
* The event emitted when the edit is canceled.
|
|
1361
1410
|
*/
|
|
@@ -1410,10 +1459,10 @@ class OperationSourceEditorComponent {
|
|
|
1410
1459
|
note: this.note.value || undefined,
|
|
1411
1460
|
});
|
|
1412
1461
|
}
|
|
1413
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.
|
|
1414
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.
|
|
1462
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.3", ngImport: i0, type: OperationSourceEditorComponent, deps: [{ token: i1$1.FormBuilder }], target: i0.ɵɵFactoryTarget.Component }); }
|
|
1463
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.3", type: OperationSourceEditorComponent, isStandalone: true, selector: "gve-operation-source-editor", inputs: { source: { classPropertyName: "source", publicName: "source", isSignal: true, isRequired: false, transformFunction: null }, ids: { classPropertyName: "ids", publicName: "ids", isSignal: true, isRequired: false, transformFunction: null }, types: { classPropertyName: "types", publicName: "types", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { source: "sourceChange", sourceCancel: "sourceCancel" }, ngImport: i0, template: "<form [formGroup]=\"form\" (submit)=\"save()\">\r\n <div class=\"form-row\">\r\n <!-- id -->\r\n <!-- id (bound) -->\r\n @if (ids()?.length) {\r\n <mat-form-field>\r\n <mat-label>id</mat-label>\r\n <mat-select [formControl]=\"id\">\r\n @for (i of ids(); track i.id) {\r\n <mat-option [value]=\"i.id\">{{ i.label }}</mat-option>\r\n }\r\n </mat-select>\r\n @if ($any(id.errors)?.required && (id.dirty || id.touched)) {\r\n <mat-error>ID required</mat-error>\r\n }\r\n </mat-form-field>\r\n } @else {\r\n <!-- id (free) -->\r\n <mat-form-field>\r\n <mat-label>id</mat-label>\r\n <input matInput [formControl]=\"id\" />\r\n @if ($any(id.errors)?.required && (id.dirty || id.touched)) {\r\n <mat-error>ID required</mat-error>\r\n } @if ($any(id.errors)?.maxLength && (id.dirty || id.touched)) {\r\n <mat-error>id too long</mat-error>\r\n }\r\n </mat-form-field>\r\n }\r\n\r\n <!-- type (bound) -->\r\n @if (types()?.length) {\r\n <mat-form-field>\r\n <mat-label>type</mat-label>\r\n <mat-select [formControl]=\"type\">\r\n @for (i of types(); track i.id) {\r\n <mat-option [value]=\"i.id\">{{ i.label }}</mat-option>\r\n }\r\n </mat-select>\r\n @if ($any(type.errors)?.required && (type.dirty || type.touched)) {\r\n <mat-error>type required</mat-error>\r\n }\r\n </mat-form-field>\r\n } @else {\r\n <!-- type (free) -->\r\n <mat-form-field>\r\n <mat-label>type</mat-label>\r\n <input matInput [formControl]=\"type\" />\r\n @if ($any(type.errors)?.required && (type.dirty || type.touched)) {\r\n <mat-error>type required</mat-error>\r\n } @if ($any(type.errors)?.maxLength && (type.dirty || type.touched)) {\r\n <mat-error>type too long</mat-error>\r\n }\r\n </mat-form-field>\r\n }\r\n\r\n <!-- rank -->\r\n <mat-form-field class=\"nr\">\r\n <mat-label>rank</mat-label>\r\n <input matInput [formControl]=\"rank\" type=\"number\" min=\"0\" />\r\n </mat-form-field>\r\n </div>\r\n <!-- note -->\r\n <div>\r\n <mat-form-field class=\"long-text\">\r\n <mat-label>note</mat-label>\r\n <textarea matInput [formControl]=\"note\" class=\"long-text\"></textarea>\r\n </mat-form-field>\r\n </div>\r\n\r\n <!-- buttons -->\r\n <div class=\"form-row\">\r\n <button\r\n type=\"button\"\r\n color=\"warn\"\r\n mat-icon-button\r\n matTooltip=\"Discard changes\"\r\n (click)=\"cancel()\"\r\n >\r\n <mat-icon class=\"mat-warn\">clear</mat-icon>\r\n </button>\r\n <button\r\n type=\"submit\"\r\n color=\"primary\"\r\n mat-icon-button\r\n matTooltip=\"Accept changes\"\r\n [disabled]=\"form.invalid || form.pristine\"\r\n >\r\n <mat-icon class=\"mat-primary\">check_circle</mat-icon>\r\n </button>\r\n </div>\r\n</form>\r\n", styles: [".long-text{width:100%;max-width:800px}.form-row{display:flex;gap:8px;align-items:center;flex-wrap:wrap}.form-row *{flex:0 0 auto}.nr{width:5em}table{width:100%;border-collapse:collapse}th{color:#909090;font-weight:400;text-align:left;background-color:#e1e0e0}th,td{padding:4px;border-bottom:1px solid silver}tbody tr:nth-child(2n){background-color:#e8e8e8}td.fit-width{width:1px;white-space:nowrap}\n"], dependencies: [{ kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1$1.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$1.NumberValueAccessor, selector: "input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]" }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],[formArray],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$1.MinValidator, selector: "input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]", inputs: ["min"] }, { kind: "directive", type: i1$1.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i2.MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { 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: "directive", type: i3.MatError, selector: "mat-error, [matError]", inputs: ["id"] }, { 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", "disabledInteractive"], exportAs: ["matInput"] }, { kind: "ngmodule", type: MatSelectModule }, { kind: "component", type: i7.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", "canSelectNullableOptions"], outputs: ["openedChange", "opened", "closed", "selectionChange", "valueChange"], exportAs: ["matSelect"] }, { kind: "component", type: i7.MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i6.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
1415
1464
|
}
|
|
1416
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.
|
|
1465
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.3", ngImport: i0, type: OperationSourceEditorComponent, decorators: [{
|
|
1417
1466
|
type: Component,
|
|
1418
1467
|
args: [{ selector: 'gve-operation-source-editor', changeDetection: ChangeDetectionStrategy.OnPush, imports: [
|
|
1419
1468
|
ReactiveFormsModule,
|
|
@@ -1642,10 +1691,10 @@ class SettingsService {
|
|
|
1642
1691
|
// for when the cache was not in sync with the local storage
|
|
1643
1692
|
removedKeys.forEach((key) => this._subject.next(key));
|
|
1644
1693
|
}
|
|
1645
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.
|
|
1646
|
-
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.
|
|
1694
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.3", ngImport: i0, type: SettingsService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
1695
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.3", ngImport: i0, type: SettingsService, providedIn: 'root' }); }
|
|
1647
1696
|
}
|
|
1648
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.
|
|
1697
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.3", ngImport: i0, type: SettingsService, decorators: [{
|
|
1649
1698
|
type: Injectable,
|
|
1650
1699
|
args: [{
|
|
1651
1700
|
providedIn: 'root',
|
|
@@ -1711,23 +1760,23 @@ class ChainOperationEditorComponent {
|
|
|
1711
1760
|
/**
|
|
1712
1761
|
* The operation to edit.
|
|
1713
1762
|
*/
|
|
1714
|
-
this.operation = model(...(ngDevMode ? [undefined, { debugName: "operation" }] : []));
|
|
1763
|
+
this.operation = model(...(ngDevMode ? [undefined, { debugName: "operation" }] : /* istanbul ignore next */ []));
|
|
1715
1764
|
/**
|
|
1716
1765
|
* The snapshot the operation refers to.
|
|
1717
1766
|
*/
|
|
1718
|
-
this.snapshot = input(...(ngDevMode ? [undefined, { debugName: "snapshot" }] : []));
|
|
1767
|
+
this.snapshot = input(...(ngDevMode ? [undefined, { debugName: "snapshot" }] : /* istanbul ignore next */ []));
|
|
1719
1768
|
/**
|
|
1720
1769
|
* Whether to hide the preview request button.
|
|
1721
1770
|
*/
|
|
1722
|
-
this.hidePreview = input(...(ngDevMode ? [undefined, { debugName: "hidePreview" }] : []));
|
|
1771
|
+
this.hidePreview = input(...(ngDevMode ? [undefined, { debugName: "hidePreview" }] : /* istanbul ignore next */ []));
|
|
1723
1772
|
/**
|
|
1724
1773
|
* Definitions for features, including names and values.
|
|
1725
1774
|
*/
|
|
1726
|
-
this.featureDefs = input(...(ngDevMode ? [undefined, { debugName: "featureDefs" }] : []));
|
|
1775
|
+
this.featureDefs = input(...(ngDevMode ? [undefined, { debugName: "featureDefs" }] : /* istanbul ignore next */ []));
|
|
1727
1776
|
/**
|
|
1728
1777
|
* Set when the edited operation's text range is to be patched.
|
|
1729
1778
|
*/
|
|
1730
|
-
this.rangePatch = input(...(ngDevMode ? [undefined, { debugName: "rangePatch" }] : []));
|
|
1779
|
+
this.rangePatch = input(...(ngDevMode ? [undefined, { debugName: "rangePatch" }] : /* istanbul ignore next */ []));
|
|
1731
1780
|
/**
|
|
1732
1781
|
* The IDs of the features that are multi-valued. If a feature being
|
|
1733
1782
|
* edited is in this list, the feature editor will allow adding multiple
|
|
@@ -1735,7 +1784,7 @@ class ChainOperationEditorComponent {
|
|
|
1735
1784
|
*/
|
|
1736
1785
|
this.multiValuedFeatureIds = input([
|
|
1737
1786
|
'r_hints',
|
|
1738
|
-
], ...(ngDevMode ? [{ debugName: "multiValuedFeatureIds" }] : []));
|
|
1787
|
+
], ...(ngDevMode ? [{ debugName: "multiValuedFeatureIds" }] : /* istanbul ignore next */ []));
|
|
1739
1788
|
/**
|
|
1740
1789
|
* Emitted when the operation is changed.
|
|
1741
1790
|
*/
|
|
@@ -1748,18 +1797,18 @@ class ChainOperationEditorComponent {
|
|
|
1748
1797
|
* Emitted when operation editing is cancelled.
|
|
1749
1798
|
*/
|
|
1750
1799
|
this.operationCancel = output();
|
|
1751
|
-
this.tabIndex = signal(0, ...(ngDevMode ? [{ debugName: "tabIndex" }] : []));
|
|
1752
|
-
this.id = signal(undefined, ...(ngDevMode ? [{ debugName: "id" }] : []));
|
|
1753
|
-
this.hasTo = signal(false, ...(ngDevMode ? [{ debugName: "hasTo" }] : []));
|
|
1754
|
-
this.hasToRun = signal(false, ...(ngDevMode ? [{ debugName: "hasToRun" }] : []));
|
|
1755
|
-
this.hasValue = signal(false, ...(ngDevMode ? [{ debugName: "hasValue" }] : []));
|
|
1800
|
+
this.tabIndex = signal(0, ...(ngDevMode ? [{ debugName: "tabIndex" }] : /* istanbul ignore next */ []));
|
|
1801
|
+
this.id = signal(undefined, ...(ngDevMode ? [{ debugName: "id" }] : /* istanbul ignore next */ []));
|
|
1802
|
+
this.hasTo = signal(false, ...(ngDevMode ? [{ debugName: "hasTo" }] : /* istanbul ignore next */ []));
|
|
1803
|
+
this.hasToRun = signal(false, ...(ngDevMode ? [{ debugName: "hasToRun" }] : /* istanbul ignore next */ []));
|
|
1804
|
+
this.hasValue = signal(false, ...(ngDevMode ? [{ debugName: "hasValue" }] : /* istanbul ignore next */ []));
|
|
1756
1805
|
// elements parsed from SVG and having an id attribute;
|
|
1757
1806
|
// we can attach features to each of these elements
|
|
1758
|
-
this.elements = signal([], ...(ngDevMode ? [{ debugName: "elements" }] : []));
|
|
1759
|
-
this.editedElementId = signal(undefined, ...(ngDevMode ? [{ debugName: "editedElementId" }] : []));
|
|
1807
|
+
this.elements = signal([], ...(ngDevMode ? [{ debugName: "elements" }] : /* istanbul ignore next */ []));
|
|
1808
|
+
this.editedElementId = signal(undefined, ...(ngDevMode ? [{ debugName: "editedElementId" }] : /* istanbul ignore next */ []));
|
|
1760
1809
|
// source
|
|
1761
|
-
this.editedSource = signal(undefined, ...(ngDevMode ? [{ debugName: "editedSource" }] : []));
|
|
1762
|
-
this.editedSourceIndex = signal(-1, ...(ngDevMode ? [{ debugName: "editedSourceIndex" }] : []));
|
|
1810
|
+
this.editedSource = signal(undefined, ...(ngDevMode ? [{ debugName: "editedSource" }] : /* istanbul ignore next */ []));
|
|
1811
|
+
this.editedSourceIndex = signal(-1, ...(ngDevMode ? [{ debugName: "editedSourceIndex" }] : /* istanbul ignore next */ []));
|
|
1763
1812
|
this._subs = [];
|
|
1764
1813
|
// general
|
|
1765
1814
|
this.rank = formBuilder.control(0, { nonNullable: true });
|
|
@@ -1990,10 +2039,10 @@ class ChainOperationEditorComponent {
|
|
|
1990
2039
|
this.operation.set(this.getOperation());
|
|
1991
2040
|
this.operationChange.emit(this.operation());
|
|
1992
2041
|
}
|
|
1993
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.
|
|
1994
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.0", type: ChainOperationEditorComponent, isStandalone: true, selector: "gve-chain-operation-editor", inputs: { operation: { classPropertyName: "operation", publicName: "operation", isSignal: true, isRequired: false, transformFunction: null }, snapshot: { classPropertyName: "snapshot", publicName: "snapshot", isSignal: true, isRequired: false, transformFunction: null }, hidePreview: { classPropertyName: "hidePreview", publicName: "hidePreview", isSignal: true, isRequired: false, transformFunction: null }, featureDefs: { classPropertyName: "featureDefs", publicName: "featureDefs", isSignal: true, isRequired: false, transformFunction: null }, rangePatch: { classPropertyName: "rangePatch", publicName: "rangePatch", isSignal: true, isRequired: false, transformFunction: null }, multiValuedFeatureIds: { classPropertyName: "multiValuedFeatureIds", publicName: "multiValuedFeatureIds", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { operation: "operationChange", operationChange: "operationChange", operationPreview: "operationPreview", operationCancel: "operationCancel" }, ngImport: i0, template: "<form [formGroup]=\"form\" (submit)=\"save()\">\r\n <!-- tabs -->\r\n <mat-tab-group [selectedIndex]=\"tabIndex()\">\r\n <!-- GENERAL -->\r\n <mat-tab label=\"general\">\r\n <div class=\"form-row\">\r\n <!-- id -->\r\n <div id=\"id\" class=\"muted\">{{ id() }}</div>\r\n\r\n <!-- type -->\r\n <mat-form-field>\r\n <mat-label>type</mat-label>\r\n <mat-select [formControl]=\"type\">\r\n <mat-option [value]=\"0\"\r\n ><mat-icon>layers</mat-icon> replace</mat-option\r\n >\r\n <mat-option [value]=\"1\"\r\n ><mat-icon>close</mat-icon>delete</mat-option\r\n >\r\n <mat-option [value]=\"2\"\r\n ><mat-icon>last_page</mat-icon>add-before</mat-option\r\n >\r\n <mat-option [value]=\"3\"\r\n ><mat-icon>first_page</mat-icon>add-after</mat-option\r\n >\r\n <mat-option [value]=\"4\"\r\n ><mat-icon>login</mat-icon>move-before</mat-option\r\n >\r\n <mat-option [value]=\"5\"\r\n ><mat-icon>logout</mat-icon>move-after</mat-option\r\n >\r\n <mat-option [value]=\"6\"\r\n ><mat-icon>compare_arrows</mat-icon>swap</mat-option\r\n >\r\n <mat-option [value]=\"7\"\r\n ><mat-icon>edit_note</mat-icon>annotate</mat-option\r\n >\r\n </mat-select>\r\n @if ($any(type).errors?.required && (type.dirty || type.touched)) {\r\n <mat-error>type required</mat-error>\r\n }\r\n </mat-form-field>\r\n\r\n <!-- at -->\r\n <mat-form-field class=\"nr\">\r\n <mat-label>at</mat-label>\r\n <input matInput [formControl]=\"at\" type=\"number\" min=\"0\" />\r\n @if ($any(at).errors?.required && (at.dirty || at.touched)) {\r\n <mat-error>at required</mat-error>\r\n }\r\n </mat-form-field>\r\n\r\n <!-- atAsIndex -->\r\n <mat-checkbox [formControl]=\"atAsIndex\">idx</mat-checkbox>\r\n\r\n <!-- run -->\r\n <mat-form-field class=\"nr\">\r\n <mat-label>run</mat-label>\r\n <input matInput [formControl]=\"run\" type=\"number\" min=\"0\" />\r\n @if ($any(run).errors?.required && (run.dirty || run.touched)) {\r\n <mat-error>run required</mat-error>\r\n }\r\n </mat-form-field>\r\n\r\n <!-- to -->\r\n @if (hasTo()) {\r\n <mat-form-field class=\"nr\">\r\n <mat-label>to</mat-label>\r\n <input matInput [formControl]=\"to\" type=\"number\" min=\"0\" />\r\n @if ($any(to).errors?.required && (to.dirty || to.touched)) {\r\n <mat-error>to required</mat-error>\r\n }\r\n </mat-form-field>\r\n\r\n <!-- toAsIndex -->\r\n <mat-checkbox [formControl]=\"toAsIndex\">idx</mat-checkbox>\r\n\r\n <!-- toRun -->\r\n @if (hasToRun()) {\r\n <mat-form-field class=\"nr\">\r\n <mat-label>to run</mat-label>\r\n <input matInput [formControl]=\"toRun\" type=\"number\" min=\"0\" />\r\n @if (\r\n $any(toRun).errors?.required && (toRun.dirty || toRun.touched)\r\n ) {\r\n <mat-error>to run required</mat-error>\r\n }\r\n </mat-form-field>\r\n }\r\n }\r\n\r\n <!-- value -->\r\n @if (hasValue()) {\r\n <mat-form-field>\r\n <mat-label>value</mat-label>\r\n <input matInput [formControl]=\"value\" />\r\n </mat-form-field>\r\n }\r\n </div>\r\n <div class=\"form-row\">\r\n <!-- rank -->\r\n <mat-form-field class=\"nr\">\r\n <mat-label>rank</mat-label>\r\n <input matInput [formControl]=\"rank\" type=\"number\" min=\"0\" />\r\n @if ($any(rank).errors?.required && (rank.dirty || rank.touched)) {\r\n <mat-error>rank required</mat-error>\r\n }\r\n </mat-form-field>\r\n\r\n <!-- groupId -->\r\n <mat-form-field>\r\n <mat-label>group ID</mat-label>\r\n <input matInput [formControl]=\"groupId\" />\r\n @if (\r\n $any(groupId).errors?.required && (groupId.dirty || groupId.touched)\r\n ) {\r\n <mat-error>group ID required</mat-error>\r\n }\r\n </mat-form-field>\r\n\r\n <!-- inputTag -->\r\n <mat-form-field>\r\n <mat-label>input tag</mat-label>\r\n <input matInput [formControl]=\"inputTag\" />\r\n <mat-hint>blank=latest</mat-hint>\r\n </mat-form-field>\r\n\r\n <!-- outputTag -->\r\n <mat-form-field>\r\n <mat-label>output tag</mat-label>\r\n <input matInput [formControl]=\"outputTag\" />\r\n <mat-hint>blank=auto (vN)</mat-hint>\r\n </mat-form-field>\r\n </div>\r\n <div>\r\n <!-- features -->\r\n <fieldset>\r\n <legend>operation features</legend>\r\n <gve-feature-set-editor\r\n [isVar]=\"true\"\r\n [featNames]=\"featureDefs()?.names\"\r\n [featValues]=\"featureDefs()?.values\"\r\n [features]=\"features.value\"\r\n [multiValuedFeatureIds]=\"multiValuedFeatureIds()\"\r\n (featuresChange)=\"onFeaturesChange($event)\"\r\n />\r\n </fieldset>\r\n </div>\r\n </mat-tab>\r\n\r\n <!-- SOURCES -->\r\n <mat-tab label=\"sources\">\r\n <div>\r\n <button\r\n type=\"button\"\r\n mat-flat-button\r\n color=\"primary\"\r\n class=\"mat-primary\"\r\n (click)=\"addSource()\"\r\n >\r\n <mat-icon>add_circle</mat-icon>\r\n source\r\n </button>\r\n </div>\r\n <table>\r\n <thead>\r\n <tr>\r\n <th></th>\r\n <th>type</th>\r\n <th>id</th>\r\n <th>rank</th>\r\n </tr>\r\n </thead>\r\n <tbody>\r\n @for (s of sources.value; track s) {\r\n <tr [class.selected]=\"s === editedSource()\">\r\n <td class=\"fit-width\">\r\n <button\r\n type=\"button\"\r\n mat-icon-button\r\n color=\"primary\"\r\n (click)=\"editSource($index)\"\r\n >\r\n <mat-icon class=\"mat-primary\">edit</mat-icon>\r\n </button>\r\n <button type=\"button\" mat-icon-button color=\"warn\">\r\n <mat-icon class=\"mat-warn\">delete</mat-icon>\r\n </button>\r\n </td>\r\n <td>{{ s.type }}</td>\r\n <td>{{ s.id }}</td>\r\n <td>{{ s.rank }}</td>\r\n </tr>\r\n }\r\n </tbody>\r\n </table>\r\n @if (editedSource()) {\r\n <!-- source editor -->\r\n <mat-expansion-panel\r\n [disabled]=\"!editedSource()\"\r\n [expanded]=\"editedSource()\"\r\n >\r\n <mat-expansion-panel-header>\r\n <mat-panel-title>source</mat-panel-title>\r\n </mat-expansion-panel-header>\r\n <gve-operation-source-editor\r\n [source]=\"editedSource()\"\r\n (sourceChange)=\"onSourceChange($event!)\"\r\n (sourceCancel)=\"closeSource()\"\r\n />\r\n </mat-expansion-panel>\r\n }\r\n </mat-tab>\r\n </mat-tab-group>\r\n\r\n <!-- buttons -->\r\n <div id=\"submit-row\">\r\n <button\r\n type=\"button\"\r\n color=\"warn\"\r\n mat-icon-button\r\n matTooltip=\"Discard operation\"\r\n (click)=\"cancel()\"\r\n >\r\n <mat-icon class=\"mat-warn\">clear</mat-icon>\r\n </button>\r\n @if (!hidePreview()) {\r\n <button\r\n type=\"button\"\r\n color=\"primary\"\r\n mat-icon-button\r\n matTooltip=\"Preview operation\"\r\n (click)=\"requestPreview()\"\r\n >\r\n <mat-icon class=\"mat-primary\">preview</mat-icon>\r\n </button>\r\n }\r\n <button\r\n type=\"submit\"\r\n color=\"primary\"\r\n class=\"mat-primary\"\r\n mat-flat-button\r\n matTooltip=\"Save operation\"\r\n [disabled]=\"form.invalid || form.pristine\"\r\n >\r\n <mat-icon>check_circle</mat-icon>\r\n save\r\n </button>\r\n </div>\r\n</form>\r\n", styles: [".form-row{display:flex;gap:8px;align-items:center;flex-wrap:wrap}.form-row *{flex:0 0 auto}#submit-row{display:flex;gap:8px;align-items:center;justify-content:center;flex-wrap:wrap;margin-top:8px;border-top:1px solid silver}.toolbar-row{display:flex;align-items:center;flex-wrap:wrap}.nr{width:6em}.long-text{width:100%;max-width:800px}#id{border-radius:6px;padding:4px;background-color:#beb9b9;color:#fff;margin-top:-16px}fieldset{border:1px solid silver;border-radius:6px;padding:8px;margin:8px 0}legend{color:silver}table{width:100%;border-collapse:collapse}tbody tr:nth-child(odd){background-color:#e2e2e2}th{text-align:left;font-weight:400;color:silver}td.fit-width{width:1px;white-space:nowrap}tr.selected{background-color:#d0d0d0!important}#btn-save{color:#072d3e}#btn-load{color:#dbd112}#btn-copy{color:#22549f}#btn-preview{color:#095409}#code{height:500px;border:1px solid silver}#monaco{height:100%}#preview{box-sizing:border-box;width:100%;border:1px solid silver;border-radius:4px;padding:8px}.tree-invisible{display:none}.tree ul,.tree li{margin-top:0;margin-bottom:0;list-style-type:none}.selected-node{background-color:#e5e5e5}.child-title{font-weight:700;margin:0;background-color:#ccc;color:#fff;padding:8px}#tree-container{display:grid;grid-template-rows:auto;grid-template-columns:auto 1fr;grid-template-areas:\"nav ed\";gap:0 16px;align-items:stretch}#tree-nav{grid-area:nav;border:1px solid silver;border-radius:6px;margin:8px 0;padding-right:8px}#tree-ed{grid-area:ed;border:1px solid silver;border-radius:6px;margin:8px 0}@media only screen and (max-width:959px){div#container{grid-template-columns:1fr;grid-template-areas:\"nav\" \"ed\";gap:16px 0;align-items:start}}\n"], dependencies: [{ kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1$1.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$1.NumberValueAccessor, selector: "input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]" }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],[formArray],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$1.MinValidator, selector: "input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]", inputs: ["min"] }, { kind: "directive", type: i1$1.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "ngmodule", type: ClipboardModule }, { kind: "ngmodule", type: MatBadgeModule }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i2.MatButton, selector: " button[matButton], a[matButton], button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button], a[mat-button], a[mat-raised-button], a[mat-flat-button], a[mat-stroked-button] ", inputs: ["matButton"], exportAs: ["matButton", "matAnchor"] }, { kind: "component", type: i2.MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "ngmodule", type: MatCheckboxModule }, { kind: "component", type: i3$1.MatCheckbox, selector: "mat-checkbox", inputs: ["aria-label", "aria-labelledby", "aria-describedby", "aria-expanded", "aria-controls", "aria-owns", "id", "required", "labelPosition", "name", "value", "disableRipple", "tabIndex", "color", "disabledInteractive", "checked", "disabled", "indeterminate"], outputs: ["change", "indeterminateChange"], exportAs: ["matCheckbox"] }, { kind: "ngmodule", type: MatExpansionModule }, { kind: "component", type: i7$1.MatExpansionPanel, selector: "mat-expansion-panel", inputs: ["hideToggle", "togglePosition"], outputs: ["afterExpand", "afterCollapse"], exportAs: ["matExpansionPanel"] }, { kind: "component", type: i7$1.MatExpansionPanelHeader, selector: "mat-expansion-panel-header", inputs: ["expandedHeight", "collapsedHeight", "tabIndex"] }, { kind: "directive", type: i7$1.MatExpansionPanelTitle, selector: "mat-panel-title" }, { 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: "directive", type: i3.MatHint, selector: "mat-hint", inputs: ["align", "id"] }, { kind: "directive", type: i3.MatError, selector: "mat-error, [matError]", inputs: ["id"] }, { 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", "disabledInteractive"], exportAs: ["matInput"] }, { kind: "ngmodule", type: MatSelectModule }, { kind: "component", type: i7.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", "canSelectNullableOptions"], outputs: ["openedChange", "opened", "closed", "selectionChange", "valueChange"], exportAs: ["matSelect"] }, { kind: "component", type: i7.MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "ngmodule", type: MatTabsModule }, { kind: "component", type: i10.MatTab, selector: "mat-tab", inputs: ["disabled", "label", "aria-label", "aria-labelledby", "labelClass", "bodyClass", "id"], exportAs: ["matTab"] }, { kind: "component", type: i10.MatTabGroup, selector: "mat-tab-group", inputs: ["color", "fitInkBarToContent", "mat-stretch-tabs", "mat-align-tabs", "dynamicHeight", "selectedIndex", "headerPosition", "animationDuration", "contentTabIndex", "disablePagination", "disableRipple", "preserveContent", "backgroundColor", "aria-label", "aria-labelledby"], outputs: ["selectedIndexChange", "focusChange", "animationDone", "selectedTabChange"], exportAs: ["matTabGroup"] }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i6.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "ngmodule", type: NgeMonacoModule }, { kind: "component", type: FeatureSetEditorComponent, selector: "gve-feature-set-editor", inputs: ["isVar", "featNames", "featValues", "filterThreshold", "multiValuedFeatureIds", "features"], outputs: ["featuresChange"] }, { kind: "component", type: OperationSourceEditorComponent, selector: "gve-operation-source-editor", inputs: ["source", "ids", "types"], outputs: ["sourceChange", "sourceCancel"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
2042
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.3", ngImport: i0, type: ChainOperationEditorComponent, deps: [{ token: i1$1.FormBuilder }, { token: i2$2.Clipboard }, { token: SettingsService }, { token: i4$1.DialogService }], target: i0.ɵɵFactoryTarget.Component }); }
|
|
2043
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.3", type: ChainOperationEditorComponent, isStandalone: true, selector: "gve-chain-operation-editor", inputs: { operation: { classPropertyName: "operation", publicName: "operation", isSignal: true, isRequired: false, transformFunction: null }, snapshot: { classPropertyName: "snapshot", publicName: "snapshot", isSignal: true, isRequired: false, transformFunction: null }, hidePreview: { classPropertyName: "hidePreview", publicName: "hidePreview", isSignal: true, isRequired: false, transformFunction: null }, featureDefs: { classPropertyName: "featureDefs", publicName: "featureDefs", isSignal: true, isRequired: false, transformFunction: null }, rangePatch: { classPropertyName: "rangePatch", publicName: "rangePatch", isSignal: true, isRequired: false, transformFunction: null }, multiValuedFeatureIds: { classPropertyName: "multiValuedFeatureIds", publicName: "multiValuedFeatureIds", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { operation: "operationChange", operationChange: "operationChange", operationPreview: "operationPreview", operationCancel: "operationCancel" }, ngImport: i0, template: "<form [formGroup]=\"form\" (submit)=\"save()\">\r\n <!-- tabs -->\r\n <mat-tab-group [selectedIndex]=\"tabIndex()\">\r\n <!-- GENERAL -->\r\n <mat-tab label=\"general\">\r\n <div class=\"form-row\">\r\n <!-- id -->\r\n <div id=\"id\" class=\"muted\">{{ id() }}</div>\r\n\r\n <!-- type -->\r\n <mat-form-field>\r\n <mat-label>type</mat-label>\r\n <mat-select [formControl]=\"type\">\r\n <mat-option [value]=\"0\"\r\n ><mat-icon>layers</mat-icon> replace</mat-option\r\n >\r\n <mat-option [value]=\"1\"\r\n ><mat-icon>close</mat-icon>delete</mat-option\r\n >\r\n <mat-option [value]=\"2\"\r\n ><mat-icon>last_page</mat-icon>add-before</mat-option\r\n >\r\n <mat-option [value]=\"3\"\r\n ><mat-icon>first_page</mat-icon>add-after</mat-option\r\n >\r\n <mat-option [value]=\"4\"\r\n ><mat-icon>login</mat-icon>move-before</mat-option\r\n >\r\n <mat-option [value]=\"5\"\r\n ><mat-icon>logout</mat-icon>move-after</mat-option\r\n >\r\n <mat-option [value]=\"6\"\r\n ><mat-icon>compare_arrows</mat-icon>swap</mat-option\r\n >\r\n <mat-option [value]=\"7\"\r\n ><mat-icon>edit_note</mat-icon>annotate</mat-option\r\n >\r\n </mat-select>\r\n @if ($any(type).errors?.required && (type.dirty || type.touched)) {\r\n <mat-error>type required</mat-error>\r\n }\r\n </mat-form-field>\r\n\r\n <!-- at -->\r\n <mat-form-field class=\"nr\">\r\n <mat-label>at</mat-label>\r\n <input matInput [formControl]=\"at\" type=\"number\" min=\"0\" />\r\n @if ($any(at).errors?.required && (at.dirty || at.touched)) {\r\n <mat-error>at required</mat-error>\r\n }\r\n </mat-form-field>\r\n\r\n <!-- atAsIndex -->\r\n <mat-checkbox [formControl]=\"atAsIndex\">idx</mat-checkbox>\r\n\r\n <!-- run -->\r\n <mat-form-field class=\"nr\">\r\n <mat-label>run</mat-label>\r\n <input matInput [formControl]=\"run\" type=\"number\" min=\"0\" />\r\n @if ($any(run).errors?.required && (run.dirty || run.touched)) {\r\n <mat-error>run required</mat-error>\r\n }\r\n </mat-form-field>\r\n\r\n <!-- to -->\r\n @if (hasTo()) {\r\n <mat-form-field class=\"nr\">\r\n <mat-label>to</mat-label>\r\n <input matInput [formControl]=\"to\" type=\"number\" min=\"0\" />\r\n @if ($any(to).errors?.required && (to.dirty || to.touched)) {\r\n <mat-error>to required</mat-error>\r\n }\r\n </mat-form-field>\r\n\r\n <!-- toAsIndex -->\r\n <mat-checkbox [formControl]=\"toAsIndex\">idx</mat-checkbox>\r\n\r\n <!-- toRun -->\r\n @if (hasToRun()) {\r\n <mat-form-field class=\"nr\">\r\n <mat-label>to run</mat-label>\r\n <input matInput [formControl]=\"toRun\" type=\"number\" min=\"0\" />\r\n @if (\r\n $any(toRun).errors?.required && (toRun.dirty || toRun.touched)\r\n ) {\r\n <mat-error>to run required</mat-error>\r\n }\r\n </mat-form-field>\r\n }\r\n }\r\n\r\n <!-- value -->\r\n @if (hasValue()) {\r\n <mat-form-field>\r\n <mat-label>value</mat-label>\r\n <input matInput [formControl]=\"value\" />\r\n </mat-form-field>\r\n }\r\n </div>\r\n <div class=\"form-row\">\r\n <!-- rank -->\r\n <mat-form-field class=\"nr\">\r\n <mat-label>rank</mat-label>\r\n <input matInput [formControl]=\"rank\" type=\"number\" min=\"0\" />\r\n @if ($any(rank).errors?.required && (rank.dirty || rank.touched)) {\r\n <mat-error>rank required</mat-error>\r\n }\r\n </mat-form-field>\r\n\r\n <!-- groupId -->\r\n <mat-form-field>\r\n <mat-label>group ID</mat-label>\r\n <input matInput [formControl]=\"groupId\" />\r\n @if (\r\n $any(groupId).errors?.required && (groupId.dirty || groupId.touched)\r\n ) {\r\n <mat-error>group ID required</mat-error>\r\n }\r\n </mat-form-field>\r\n\r\n <!-- inputTag -->\r\n <mat-form-field>\r\n <mat-label>input tag</mat-label>\r\n <input matInput [formControl]=\"inputTag\" />\r\n <mat-hint>blank=latest</mat-hint>\r\n </mat-form-field>\r\n\r\n <!-- outputTag -->\r\n <mat-form-field>\r\n <mat-label>output tag</mat-label>\r\n <input matInput [formControl]=\"outputTag\" />\r\n <mat-hint>blank=auto (vN)</mat-hint>\r\n </mat-form-field>\r\n </div>\r\n <div>\r\n <!-- features -->\r\n <fieldset>\r\n <legend>operation features</legend>\r\n <gve-feature-set-editor\r\n [isVar]=\"true\"\r\n [featNames]=\"featureDefs()?.names\"\r\n [featValues]=\"featureDefs()?.values\"\r\n [features]=\"features.value\"\r\n [multiValuedFeatureIds]=\"multiValuedFeatureIds()\"\r\n (featuresChange)=\"onFeaturesChange($event)\"\r\n />\r\n </fieldset>\r\n </div>\r\n </mat-tab>\r\n\r\n <!-- SOURCES -->\r\n <mat-tab label=\"sources\">\r\n <div>\r\n <button\r\n type=\"button\"\r\n mat-flat-button\r\n color=\"primary\"\r\n class=\"mat-primary\"\r\n (click)=\"addSource()\"\r\n >\r\n <mat-icon>add_circle</mat-icon>\r\n source\r\n </button>\r\n </div>\r\n <table>\r\n <thead>\r\n <tr>\r\n <th></th>\r\n <th>type</th>\r\n <th>id</th>\r\n <th>rank</th>\r\n </tr>\r\n </thead>\r\n <tbody>\r\n @for (s of sources.value; track s) {\r\n <tr [class.selected]=\"s === editedSource()\">\r\n <td class=\"fit-width\">\r\n <button\r\n type=\"button\"\r\n mat-icon-button\r\n color=\"primary\"\r\n (click)=\"editSource($index)\"\r\n >\r\n <mat-icon class=\"mat-primary\">edit</mat-icon>\r\n </button>\r\n <button type=\"button\" mat-icon-button color=\"warn\">\r\n <mat-icon class=\"mat-warn\">delete</mat-icon>\r\n </button>\r\n </td>\r\n <td>{{ s.type }}</td>\r\n <td>{{ s.id }}</td>\r\n <td>{{ s.rank }}</td>\r\n </tr>\r\n }\r\n </tbody>\r\n </table>\r\n @if (editedSource()) {\r\n <!-- source editor -->\r\n <mat-expansion-panel\r\n [disabled]=\"!editedSource()\"\r\n [expanded]=\"editedSource()\"\r\n >\r\n <mat-expansion-panel-header>\r\n <mat-panel-title>source</mat-panel-title>\r\n </mat-expansion-panel-header>\r\n <gve-operation-source-editor\r\n [source]=\"editedSource()\"\r\n (sourceChange)=\"onSourceChange($event!)\"\r\n (sourceCancel)=\"closeSource()\"\r\n />\r\n </mat-expansion-panel>\r\n }\r\n </mat-tab>\r\n </mat-tab-group>\r\n\r\n <!-- buttons -->\r\n <div id=\"submit-row\">\r\n <button\r\n type=\"button\"\r\n color=\"warn\"\r\n mat-icon-button\r\n matTooltip=\"Discard operation\"\r\n (click)=\"cancel()\"\r\n >\r\n <mat-icon class=\"mat-warn\">clear</mat-icon>\r\n </button>\r\n @if (!hidePreview()) {\r\n <button\r\n type=\"button\"\r\n color=\"primary\"\r\n mat-icon-button\r\n matTooltip=\"Preview operation\"\r\n (click)=\"requestPreview()\"\r\n >\r\n <mat-icon class=\"mat-primary\">preview</mat-icon>\r\n </button>\r\n }\r\n <button\r\n type=\"submit\"\r\n color=\"primary\"\r\n class=\"mat-primary\"\r\n mat-flat-button\r\n matTooltip=\"Save operation\"\r\n [disabled]=\"form.invalid || form.pristine\"\r\n >\r\n <mat-icon>check_circle</mat-icon>\r\n save\r\n </button>\r\n </div>\r\n</form>\r\n", styles: [".form-row{display:flex;gap:8px;align-items:center;flex-wrap:wrap}.form-row *{flex:0 0 auto}#submit-row{display:flex;gap:8px;align-items:center;justify-content:center;flex-wrap:wrap;margin-top:8px;border-top:1px solid silver}.toolbar-row{display:flex;align-items:center;flex-wrap:wrap}.nr{width:6em}.long-text{width:100%;max-width:800px}#id{border-radius:6px;padding:4px;background-color:#beb9b9;color:#fff;margin-top:-16px}fieldset{border:1px solid silver;border-radius:6px;padding:8px;margin:8px 0}legend{color:silver}table{width:100%;border-collapse:collapse}tbody tr:nth-child(odd){background-color:#e2e2e2}th{text-align:left;font-weight:400;color:silver}td.fit-width{width:1px;white-space:nowrap}tr.selected{background-color:#d0d0d0!important}#btn-save{color:#072d3e}#btn-load{color:#dbd112}#btn-copy{color:#22549f}#btn-preview{color:#095409}#code{height:500px;border:1px solid silver}#monaco{height:100%}#preview{box-sizing:border-box;width:100%;border:1px solid silver;border-radius:4px;padding:8px}.tree-invisible{display:none}.tree ul,.tree li{margin-top:0;margin-bottom:0;list-style-type:none}.selected-node{background-color:#e5e5e5}.child-title{font-weight:700;margin:0;background-color:#ccc;color:#fff;padding:8px}#tree-container{display:grid;grid-template-rows:auto;grid-template-columns:auto 1fr;grid-template-areas:\"nav ed\";gap:0 16px;align-items:stretch}#tree-nav{grid-area:nav;border:1px solid silver;border-radius:6px;margin:8px 0;padding-right:8px}#tree-ed{grid-area:ed;border:1px solid silver;border-radius:6px;margin:8px 0}@media only screen and (max-width:959px){div#container{grid-template-columns:1fr;grid-template-areas:\"nav\" \"ed\";gap:16px 0;align-items:start}}\n"], dependencies: [{ kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1$1.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$1.NumberValueAccessor, selector: "input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]" }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],[formArray],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$1.MinValidator, selector: "input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]", inputs: ["min"] }, { kind: "directive", type: i1$1.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "ngmodule", type: ClipboardModule }, { kind: "ngmodule", type: MatBadgeModule }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i2.MatButton, selector: " button[matButton], a[matButton], button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button], a[mat-button], a[mat-raised-button], a[mat-flat-button], a[mat-stroked-button] ", inputs: ["matButton"], exportAs: ["matButton", "matAnchor"] }, { kind: "component", type: i2.MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "ngmodule", type: MatCheckboxModule }, { kind: "component", type: i3$1.MatCheckbox, selector: "mat-checkbox", inputs: ["aria-label", "aria-labelledby", "aria-describedby", "aria-expanded", "aria-controls", "aria-owns", "id", "required", "labelPosition", "name", "value", "disableRipple", "tabIndex", "color", "disabledInteractive", "checked", "disabled", "indeterminate"], outputs: ["change", "indeterminateChange"], exportAs: ["matCheckbox"] }, { kind: "ngmodule", type: MatExpansionModule }, { kind: "component", type: i7$1.MatExpansionPanel, selector: "mat-expansion-panel", inputs: ["hideToggle", "togglePosition"], outputs: ["afterExpand", "afterCollapse"], exportAs: ["matExpansionPanel"] }, { kind: "component", type: i7$1.MatExpansionPanelHeader, selector: "mat-expansion-panel-header", inputs: ["expandedHeight", "collapsedHeight", "tabIndex"] }, { kind: "directive", type: i7$1.MatExpansionPanelTitle, selector: "mat-panel-title" }, { 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: "directive", type: i3.MatHint, selector: "mat-hint", inputs: ["align", "id"] }, { kind: "directive", type: i3.MatError, selector: "mat-error, [matError]", inputs: ["id"] }, { 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", "disabledInteractive"], exportAs: ["matInput"] }, { kind: "ngmodule", type: MatSelectModule }, { kind: "component", type: i7.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", "canSelectNullableOptions"], outputs: ["openedChange", "opened", "closed", "selectionChange", "valueChange"], exportAs: ["matSelect"] }, { kind: "component", type: i7.MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "ngmodule", type: MatTabsModule }, { kind: "component", type: i10.MatTab, selector: "mat-tab", inputs: ["disabled", "label", "aria-label", "aria-labelledby", "labelClass", "bodyClass", "id"], exportAs: ["matTab"] }, { kind: "component", type: i10.MatTabGroup, selector: "mat-tab-group", inputs: ["color", "fitInkBarToContent", "mat-stretch-tabs", "mat-align-tabs", "dynamicHeight", "selectedIndex", "headerPosition", "animationDuration", "contentTabIndex", "disablePagination", "disableRipple", "preserveContent", "backgroundColor", "aria-label", "aria-labelledby"], outputs: ["selectedIndexChange", "focusChange", "animationDone", "selectedTabChange"], exportAs: ["matTabGroup"] }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i6.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "ngmodule", type: NgeMonacoModule }, { kind: "component", type: FeatureSetEditorComponent, selector: "gve-feature-set-editor", inputs: ["isVar", "featNames", "featValues", "filterThreshold", "multiValuedFeatureIds", "features"], outputs: ["featuresChange"] }, { kind: "component", type: OperationSourceEditorComponent, selector: "gve-operation-source-editor", inputs: ["source", "ids", "types"], outputs: ["sourceChange", "sourceCancel"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
1995
2044
|
}
|
|
1996
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.
|
|
2045
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.3", ngImport: i0, type: ChainOperationEditorComponent, decorators: [{
|
|
1997
2046
|
type: Component,
|
|
1998
2047
|
args: [{ selector: 'gve-chain-operation-editor', changeDetection: ChangeDetectionStrategy.OnPush, imports: [
|
|
1999
2048
|
ReactiveFormsModule,
|
|
@@ -2036,26 +2085,26 @@ class FeatureSetViewComponent {
|
|
|
2036
2085
|
/**
|
|
2037
2086
|
* The features.
|
|
2038
2087
|
*/
|
|
2039
|
-
this.features = input([], ...(ngDevMode ? [{ debugName: "features" }] : []));
|
|
2088
|
+
this.features = input([], ...(ngDevMode ? [{ debugName: "features" }] : /* istanbul ignore next */ []));
|
|
2040
2089
|
/**
|
|
2041
2090
|
* The list of feature names to display in the name selection.
|
|
2042
2091
|
* This is used when you have a closed list of features.
|
|
2043
2092
|
*/
|
|
2044
|
-
this.featNames = input(...(ngDevMode ? [undefined, { debugName: "featNames" }] : []));
|
|
2093
|
+
this.featNames = input(...(ngDevMode ? [undefined, { debugName: "featNames" }] : /* istanbul ignore next */ []));
|
|
2045
2094
|
/**
|
|
2046
2095
|
* The feature values map. When specified and the user selects a feature
|
|
2047
2096
|
* name present in the map keys, the corresponding values will be used
|
|
2048
2097
|
* to populate the value selection.
|
|
2049
2098
|
*/
|
|
2050
|
-
this.featValues = input(...(ngDevMode ? [undefined, { debugName: "featValues" }] : []));
|
|
2099
|
+
this.featValues = input(...(ngDevMode ? [undefined, { debugName: "featValues" }] : /* istanbul ignore next */ []));
|
|
2051
2100
|
/**
|
|
2052
2101
|
* The threshold at which the features filter should become visible.
|
|
2053
2102
|
* If set to 0, the filter is always visible; if set to -1, it is always
|
|
2054
2103
|
* invisible; otherwise, it gets visible when the number of features
|
|
2055
2104
|
* is greater than the threshold. Default is 5.
|
|
2056
2105
|
*/
|
|
2057
|
-
this.filterThreshold = input(5, ...(ngDevMode ? [{ debugName: "filterThreshold" }] : []));
|
|
2058
|
-
this.filteredFeatures = signal([], ...(ngDevMode ? [{ debugName: "filteredFeatures" }] : []));
|
|
2106
|
+
this.filterThreshold = input(5, ...(ngDevMode ? [{ debugName: "filterThreshold" }] : /* istanbul ignore next */ []));
|
|
2107
|
+
this.filteredFeatures = signal([], ...(ngDevMode ? [{ debugName: "filteredFeatures" }] : /* istanbul ignore next */ []));
|
|
2059
2108
|
this.filter = formBuilder.control(null);
|
|
2060
2109
|
// when features change, reset the filter and apply it
|
|
2061
2110
|
effect(() => {
|
|
@@ -2080,10 +2129,10 @@ class FeatureSetViewComponent {
|
|
|
2080
2129
|
ngOnDestroy() {
|
|
2081
2130
|
this._sub?.unsubscribe();
|
|
2082
2131
|
}
|
|
2083
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.
|
|
2084
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.
|
|
2132
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.3", ngImport: i0, type: FeatureSetViewComponent, deps: [{ token: i1$1.FormBuilder }], target: i0.ɵɵFactoryTarget.Component }); }
|
|
2133
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.3", type: FeatureSetViewComponent, isStandalone: true, selector: "gve-feature-set-view", inputs: { features: { classPropertyName: "features", publicName: "features", isSignal: true, isRequired: false, transformFunction: null }, featNames: { classPropertyName: "featNames", publicName: "featNames", isSignal: true, isRequired: false, transformFunction: null }, featValues: { classPropertyName: "featValues", publicName: "featValues", isSignal: true, isRequired: false, transformFunction: null }, filterThreshold: { classPropertyName: "filterThreshold", publicName: "filterThreshold", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "<div>\r\n <!-- filter -->\r\n <div>\r\n @if (filterThreshold() === 0 || features()!.length > filterThreshold()) {\r\n <div class=\"form-row\">\r\n <mat-form-field id=\"filter\">\r\n <mat-label>filter</mat-label>\r\n <input matInput [formControl]=\"filter\" />\r\n <button\r\n type=\"button\"\r\n mat-icon-button\r\n matSuffix\r\n (click)=\"filter.reset()\"\r\n [disabled]=\"!filter.value\"\r\n [attr.aria-label]=\"'Reset filter'\"\r\n >\r\n <mat-icon color=\"warn\" class=\"mat-warn\">cancel</mat-icon>\r\n </button>\r\n </mat-form-field>\r\n <span id=\"badge\">{{ filteredFeatures().length }}</span>\r\n </div>\r\n }\r\n\r\n <!-- list -->\r\n @if (filteredFeatures().length) {\r\n <table>\r\n <tbody>\r\n @for (feature of filteredFeatures(); track $index) {\r\n <tr>\r\n <th>\r\n @if (featNames()?.length) {\r\n <span>{{\r\n feature.name | flatLookup: featNames() : \"id\" : \"label\"\r\n }}</span>\r\n } @else {\r\n <span>{{ feature.name }}</span>\r\n }\r\n </th>\r\n <td>\r\n @if (featValues()) {\r\n <span>{{\r\n feature.value | flatLookup: featValues()![feature.name]\r\n }}</span>\r\n } @else {\r\n <span>{{ feature.value }}</span>\r\n }\r\n </td>\r\n </tr>\r\n }\r\n </tbody>\r\n </table>\r\n }\r\n </div>\r\n</div>\r\n", styles: [":host{display:block;width:100%;min-width:0}.form-row{display:flex;gap:8px;align-items:center;flex-wrap:wrap}.form-row *{flex:0 0 auto}.in-row-button{margin-top:-16px}table{width:100%;border-collapse:collapse;min-width:0}th{text-align:left;background-color:#c8d9eb;color:#333;font-weight:400}th,td{border:1px solid silver;padding:4px}tr:nth-child(2n){background-color:#dfdfdf}#filter{width:7em}#badge{border:1px solid silver;border-radius:6px;padding:4px;margin-top:-18px}\n"], dependencies: [{ kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$1.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$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i2.MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { 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: "directive", type: i3.MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { 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", "disabledInteractive"], exportAs: ["matInput"] }, { kind: "pipe", type: FlatLookupPipe, name: "flatLookup" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
2085
2134
|
}
|
|
2086
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.
|
|
2135
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.3", ngImport: i0, type: FeatureSetViewComponent, decorators: [{
|
|
2087
2136
|
type: Component,
|
|
2088
2137
|
args: [{ selector: 'gve-feature-set-view', changeDetection: ChangeDetectionStrategy.OnPush, imports: [
|
|
2089
2138
|
ReactiveFormsModule,
|
|
@@ -2117,23 +2166,23 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.0", ngImpor
|
|
|
2117
2166
|
class StepsMapComponent {
|
|
2118
2167
|
constructor() {
|
|
2119
2168
|
// track view initialization
|
|
2120
|
-
this._viewInitialized = signal(false, ...(ngDevMode ? [{ debugName: "_viewInitialized" }] : []));
|
|
2169
|
+
this._viewInitialized = signal(false, ...(ngDevMode ? [{ debugName: "_viewInitialized" }] : /* istanbul ignore next */ []));
|
|
2121
2170
|
// track whether we've processed the steps/selection
|
|
2122
|
-
this._selectionProcessed = signal(false, ...(ngDevMode ? [{ debugName: "_selectionProcessed" }] : []));
|
|
2171
|
+
this._selectionProcessed = signal(false, ...(ngDevMode ? [{ debugName: "_selectionProcessed" }] : /* istanbul ignore next */ []));
|
|
2123
2172
|
// the lines of each version text, keyed under the output tag
|
|
2124
|
-
this.lines = signal({}, ...(ngDevMode ? [{ debugName: "lines" }] : []));
|
|
2173
|
+
this.lines = signal({}, ...(ngDevMode ? [{ debugName: "lines" }] : /* istanbul ignore next */ []));
|
|
2125
2174
|
/**
|
|
2126
2175
|
* The steps to display.
|
|
2127
2176
|
*/
|
|
2128
|
-
this.steps = input([], ...(ngDevMode ? [{ debugName: "steps" }] : []));
|
|
2177
|
+
this.steps = input([], ...(ngDevMode ? [{ debugName: "steps" }] : /* istanbul ignore next */ []));
|
|
2129
2178
|
/**
|
|
2130
2179
|
* The step that is currently selected.
|
|
2131
2180
|
*/
|
|
2132
|
-
this.selectedStep = model(...(ngDevMode ? [undefined, { debugName: "selectedStep" }] : []));
|
|
2181
|
+
this.selectedStep = model(...(ngDevMode ? [undefined, { debugName: "selectedStep" }] : /* istanbul ignore next */ []));
|
|
2133
2182
|
/**
|
|
2134
2183
|
* The font size of the steps text.
|
|
2135
2184
|
*/
|
|
2136
|
-
this.textFontSize = input('0.8em', ...(ngDevMode ? [{ debugName: "textFontSize" }] : []));
|
|
2185
|
+
this.textFontSize = input('0.8em', ...(ngDevMode ? [{ debugName: "textFontSize" }] : /* istanbul ignore next */ []));
|
|
2137
2186
|
// handle steps updates
|
|
2138
2187
|
effect(() => {
|
|
2139
2188
|
const currentSteps = this.steps();
|
|
@@ -2203,10 +2252,10 @@ class StepsMapComponent {
|
|
|
2203
2252
|
onStepClick(step) {
|
|
2204
2253
|
this.selectedStep.set(step);
|
|
2205
2254
|
}
|
|
2206
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.
|
|
2207
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.
|
|
2255
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.3", ngImport: i0, type: StepsMapComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
2256
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.3", type: StepsMapComponent, isStandalone: true, selector: "gve-steps-map", inputs: { steps: { classPropertyName: "steps", publicName: "steps", isSignal: true, isRequired: false, transformFunction: null }, selectedStep: { classPropertyName: "selectedStep", publicName: "selectedStep", isSignal: true, isRequired: false, transformFunction: null }, textFontSize: { classPropertyName: "textFontSize", publicName: "textFontSize", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { selectedStep: "selectedStepChange" }, ngImport: i0, template: "<div>\r\n @if (steps().length) { @for (step of steps(); track step.outputTag) {\r\n <div\r\n matRipple\r\n class=\"step form-row\"\r\n [class.selected]=\"step === selectedStep()\"\r\n (click)=\"onStepClick(step)\"\r\n >\r\n <!-- tag -->\r\n <div class=\"tag\">\r\n <span class=\"muted-tag\">{{ step.inputTag }} ▶ </span>\r\n {{ step.outputTag }}\r\n </div>\r\n <!-- text lines -->\r\n <div class=\"text\" [style.fontSize]=\"textFontSize()\">\r\n @for (line of lines()[step.outputTag]; track $index) {\r\n <div class=\"line\">{{ line }}</div>\r\n }\r\n <div></div>\r\n </div>\r\n </div>\r\n } }\r\n</div>\r\n", styles: [".form-row{display:flex;gap:8px;align-items:start;flex-wrap:wrap}.form-row *{flex:0 0 auto}.selected{background-color:#ffc}.step{border:1px solid rgb(68,114,253);border-radius:6px;margin:8px 0}.tag{background-color:#4472fd;color:#fff;border:1px solid rgb(68,114,253);border-radius:6px;padding:4px;cursor:pointer}.muted-tag{color:silver}.text{font-size:.5em}\n"], dependencies: [{ kind: "ngmodule", type: MatButtonModule }, { kind: "ngmodule", type: MatRippleModule }, { kind: "directive", type: i1.MatRipple, selector: "[mat-ripple], [matRipple]", inputs: ["matRippleColor", "matRippleUnbounded", "matRippleCentered", "matRippleRadius", "matRippleAnimation", "matRippleDisabled", "matRippleTrigger"], exportAs: ["matRipple"] }, { kind: "ngmodule", type: MatTooltipModule }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
2208
2257
|
}
|
|
2209
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.
|
|
2258
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.3", ngImport: i0, type: StepsMapComponent, decorators: [{
|
|
2210
2259
|
type: Component,
|
|
2211
2260
|
args: [{ selector: 'gve-steps-map', imports: [MatButtonModule, MatRippleModule, MatTooltipModule], changeDetection: ChangeDetectionStrategy.OnPush, template: "<div>\r\n @if (steps().length) { @for (step of steps(); track step.outputTag) {\r\n <div\r\n matRipple\r\n class=\"step form-row\"\r\n [class.selected]=\"step === selectedStep()\"\r\n (click)=\"onStepClick(step)\"\r\n >\r\n <!-- tag -->\r\n <div class=\"tag\">\r\n <span class=\"muted-tag\">{{ step.inputTag }} ▶ </span>\r\n {{ step.outputTag }}\r\n </div>\r\n <!-- text lines -->\r\n <div class=\"text\" [style.fontSize]=\"textFontSize()\">\r\n @for (line of lines()[step.outputTag]; track $index) {\r\n <div class=\"line\">{{ line }}</div>\r\n }\r\n <div></div>\r\n </div>\r\n </div>\r\n } }\r\n</div>\r\n", styles: [".form-row{display:flex;gap:8px;align-items:start;flex-wrap:wrap}.form-row *{flex:0 0 auto}.selected{background-color:#ffc}.step{border:1px solid rgb(68,114,253);border-radius:6px;margin:8px 0}.tag{background-color:#4472fd;color:#fff;border:1px solid rgb(68,114,253);border-radius:6px;padding:4px;cursor:pointer}.muted-tag{color:silver}.text{font-size:.5em}\n"] }]
|
|
2212
2261
|
}], ctorParameters: () => [], propDecorators: { steps: [{ type: i0.Input, args: [{ isSignal: true, alias: "steps", required: false }] }], selectedStep: [{ type: i0.Input, args: [{ isSignal: true, alias: "selectedStep", required: false }] }, { type: i0.Output, args: ["selectedStepChange"] }], textFontSize: [{ type: i0.Input, args: [{ isSignal: true, alias: "textFontSize", required: false }] }] } });
|
|
@@ -2227,34 +2276,34 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.0", ngImpor
|
|
|
2227
2276
|
class ChainResultViewComponent {
|
|
2228
2277
|
constructor(formBuilder) {
|
|
2229
2278
|
// track if we've already performed step selection
|
|
2230
|
-
this._stepSelectionDone = signal(false, ...(ngDevMode ? [{ debugName: "_stepSelectionDone" }] : []));
|
|
2279
|
+
this._stepSelectionDone = signal(false, ...(ngDevMode ? [{ debugName: "_stepSelectionDone" }] : /* istanbul ignore next */ []));
|
|
2231
2280
|
// track if component view is initialized
|
|
2232
|
-
this._viewInitialized = signal(false, ...(ngDevMode ? [{ debugName: "_viewInitialized" }] : []));
|
|
2281
|
+
this._viewInitialized = signal(false, ...(ngDevMode ? [{ debugName: "_viewInitialized" }] : /* istanbul ignore next */ []));
|
|
2233
2282
|
/**
|
|
2234
2283
|
* The result to display.
|
|
2235
2284
|
*/
|
|
2236
|
-
this.result = input(...(ngDevMode ? [undefined, { debugName: "result" }] : []));
|
|
2285
|
+
this.result = input(...(ngDevMode ? [undefined, { debugName: "result" }] : /* istanbul ignore next */ []));
|
|
2237
2286
|
/**
|
|
2238
2287
|
* The index of the initial step to display after the result is set.
|
|
2239
2288
|
* If the index is negative, it is counted from the end of the steps.
|
|
2240
2289
|
*/
|
|
2241
|
-
this.initialStepIndex = input(...(ngDevMode ? [undefined, { debugName: "initialStepIndex" }] : []));
|
|
2290
|
+
this.initialStepIndex = input(...(ngDevMode ? [undefined, { debugName: "initialStepIndex" }] : /* istanbul ignore next */ []));
|
|
2242
2291
|
/**
|
|
2243
2292
|
* Emitted when a result's step is picked by the user.
|
|
2244
2293
|
*/
|
|
2245
2294
|
this.stepPick = output();
|
|
2246
|
-
this.versionTags = signal([], ...(ngDevMode ? [{ debugName: "versionTags" }] : []));
|
|
2247
|
-
this.tags = signal([], ...(ngDevMode ? [{ debugName: "tags" }] : []));
|
|
2248
|
-
this.step = signal(undefined, ...(ngDevMode ? [{ debugName: "step" }] : []));
|
|
2249
|
-
this.selection = signal(undefined, ...(ngDevMode ? [{ debugName: "selection" }] : []));
|
|
2250
|
-
this.selectionFeatures = signal([], ...(ngDevMode ? [{ debugName: "selectionFeatures" }] : []));
|
|
2251
|
-
this.selectionRange = signal(undefined, ...(ngDevMode ? [{ debugName: "selectionRange" }] : []));
|
|
2295
|
+
this.versionTags = signal([], ...(ngDevMode ? [{ debugName: "versionTags" }] : /* istanbul ignore next */ []));
|
|
2296
|
+
this.tags = signal([], ...(ngDevMode ? [{ debugName: "tags" }] : /* istanbul ignore next */ []));
|
|
2297
|
+
this.step = signal(undefined, ...(ngDevMode ? [{ debugName: "step" }] : /* istanbul ignore next */ []));
|
|
2298
|
+
this.selection = signal(undefined, ...(ngDevMode ? [{ debugName: "selection" }] : /* istanbul ignore next */ []));
|
|
2299
|
+
this.selectionFeatures = signal([], ...(ngDevMode ? [{ debugName: "selectionFeatures" }] : /* istanbul ignore next */ []));
|
|
2300
|
+
this.selectionRange = signal(undefined, ...(ngDevMode ? [{ debugName: "selectionRange" }] : /* istanbul ignore next */ []));
|
|
2252
2301
|
/**
|
|
2253
2302
|
* True to disable range picking. For instance the snapshot editor,
|
|
2254
2303
|
* which uses rangePick to set the edited operation's range, disables
|
|
2255
2304
|
* this when no operation is being edited.
|
|
2256
2305
|
*/
|
|
2257
|
-
this.disabledRangePick = input(true, ...(ngDevMode ? [{ debugName: "disabledRangePick" }] : []));
|
|
2306
|
+
this.disabledRangePick = input(true, ...(ngDevMode ? [{ debugName: "disabledRangePick" }] : /* istanbul ignore next */ []));
|
|
2258
2307
|
/**
|
|
2259
2308
|
* Emitted when a range is picked.
|
|
2260
2309
|
*/
|
|
@@ -2453,10 +2502,10 @@ class ChainResultViewComponent {
|
|
|
2453
2502
|
this.rangePick.emit(this.selectionRange());
|
|
2454
2503
|
}
|
|
2455
2504
|
}
|
|
2456
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.
|
|
2457
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.
|
|
2505
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.3", ngImport: i0, type: ChainResultViewComponent, deps: [{ token: i1$1.FormBuilder }], target: i0.ɵɵFactoryTarget.Component }); }
|
|
2506
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.3", type: ChainResultViewComponent, isStandalone: true, selector: "gve-chain-result-view", inputs: { result: { classPropertyName: "result", publicName: "result", isSignal: true, isRequired: false, transformFunction: null }, initialStepIndex: { classPropertyName: "initialStepIndex", publicName: "initialStepIndex", isSignal: true, isRequired: false, transformFunction: null }, disabledRangePick: { classPropertyName: "disabledRangePick", publicName: "disabledRangePick", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { stepPick: "stepPick", rangePick: "rangePick" }, ngImport: i0, template: "@if (result()) {\r\n<div id=\"container\">\r\n <div id=\"bar\" class=\"form-row\">\r\n <!-- version -->\r\n @if (versionTags().length) {\r\n <mat-form-field>\r\n <mat-label>stage</mat-label>\r\n <mat-select [formControl]=\"versionTag\">\r\n <mat-option [value]=\"null\">-</mat-option>\r\n @for (t of versionTags(); track t) {\r\n <mat-option [value]=\"t\">{{ t }}</mat-option>\r\n }\r\n </mat-select>\r\n </mat-form-field>\r\n }\r\n <!-- tag -->\r\n @if (tags().length) {\r\n <mat-form-field>\r\n <mat-label>tag</mat-label>\r\n <mat-select [formControl]=\"tag\">\r\n @for (t of tags(); track t) {\r\n <mat-option [value]=\"t\">{{ t }}</mat-option>\r\n }\r\n </mat-select>\r\n </mat-form-field>\r\n }\r\n <!-- range picker -->\r\n @if (selectionRange()) {\r\n <div class=\"range\">\r\n {{ selectionRange()!.at }}\u00D7{{ selectionRange()!.run }}\r\n </div>\r\n @if (!disabledRangePick()) {\r\n <button\r\n type=\"button\"\r\n mat-icon-button\r\n matTooltip=\"Pick this range for the edited operation\"\r\n (click)=\"pickRange()\"\r\n [disabled]=\"disabledRangePick()\"\r\n >\r\n <mat-icon class=\"mat-warn\">file_open</mat-icon>\r\n </button>\r\n } }\r\n </div>\r\n\r\n <!-- step -->\r\n @if (step()) {\r\n <div id=\"step\">\r\n <!-- text -->\r\n <div id=\"text\">\r\n <gve-base-text-view\r\n [text]=\"result()!.taggedNodes[step()!.outputTag]\"\r\n [colorCallback]=\"getCharColor\"\r\n [hasLineNumber]=\"true\"\r\n (charPick)=\"onTextCharPick($event)\"\r\n (rangePick)=\"onTextRangePick($event)\"\r\n />\r\n </div>\r\n <!-- features -->\r\n <div id=\"feats\" class=\"form-row-top\">\r\n <div id=\"g-feats\">\r\n <div class=\"feat-header\">{{ step()!.outputTag }}</div>\r\n <gve-feature-set-view [features]=\"step()!.featureSet.features\" />\r\n </div>\r\n <div id=\"n-feats\">\r\n @if (selectionFeatures().length) {\r\n <div class=\"feat-header\">{{ selection() }}</div>\r\n <gve-feature-set-view [features]=\"selectionFeatures()\" />\r\n }\r\n </div>\r\n </div>\r\n </div>\r\n }\r\n\r\n <!-- steps map -->\r\n <div id=\"map\">\r\n <gve-steps-map\r\n [steps]=\"result()!.steps\"\r\n [selectedStep]=\"step()\"\r\n (selectedStepChange)=\"onStepChange($event)\"\r\n />\r\n </div>\r\n</div>\r\n}\r\n", styles: [".form-row{display:flex;gap:8px;align-items:center;flex-wrap:wrap}.form-row *{flex:0 0 auto}.form-row-top{display:flex;gap:8px;align-items:start;flex-wrap:wrap;width:100%;box-sizing:border-box}.form-row-top>div{flex:1 1 0%;min-width:0}.range{color:silver;border:1px solid silver;border-radius:4px;padding:4px}div#container{display:grid;grid-template-rows:auto 1fr;grid-template-columns:3fr 1fr;grid-template-areas:\"bar map\" \"step map\";gap:8px;height:100%}div#bar{grid-area:bar}div#map{grid-area:map;min-height:0;overflow-y:auto}div#step{grid-area:step;min-height:0;display:grid;grid-template-rows:1fr auto;gap:8px}div#text{min-height:0;overflow-y:auto}div#feats{width:100%}.feat-header{background-color:#3e92cc;color:#fff;text-align:center;border:1px solid #3e92cc;border-top-left-radius:4px;border-top-right-radius:4px}@media only screen and (max-width:959px){div#container{grid-template-columns:1fr;grid-template-areas:\"bar\" \"step\"}#map{display:none}}\n"], dependencies: [{ kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i2.MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { 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: MatSelectModule }, { kind: "component", type: i7.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", "canSelectNullableOptions"], outputs: ["openedChange", "opened", "closed", "selectionChange", "valueChange"], exportAs: ["matSelect"] }, { kind: "component", type: i7.MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "component", type: FeatureSetViewComponent, selector: "gve-feature-set-view", inputs: ["features", "featNames", "featValues", "filterThreshold"] }, { kind: "component", type: StepsMapComponent, selector: "gve-steps-map", inputs: ["steps", "selectedStep", "textFontSize"], outputs: ["selectedStepChange"] }, { kind: "component", type: BaseTextViewComponent, selector: "gve-base-text-view", inputs: ["defaultColor", "defaultBorderColor", "selectionColor", "searchHighlightColor", "hasLineNumber", "text", "colorCallback", "borderColorCallback"], outputs: ["charPick", "rangePick"] }, { kind: "directive", type: MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
2458
2507
|
}
|
|
2459
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.
|
|
2508
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.3", ngImport: i0, type: ChainResultViewComponent, decorators: [{
|
|
2460
2509
|
type: Component,
|
|
2461
2510
|
args: [{ selector: 'gve-chain-result-view', imports: [
|
|
2462
2511
|
ReactiveFormsModule,
|
|
@@ -2487,7 +2536,7 @@ class SnapshotTextEditorComponent {
|
|
|
2487
2536
|
this._snackbar = _snackbar;
|
|
2488
2537
|
this.dialogRef = dialogRef;
|
|
2489
2538
|
this.data = data;
|
|
2490
|
-
this.text = model([], ...(ngDevMode ? [{ debugName: "text" }] : []));
|
|
2539
|
+
this.text = model([], ...(ngDevMode ? [{ debugName: "text" }] : /* istanbul ignore next */ []));
|
|
2491
2540
|
this.userText = formBuilder.control('', {
|
|
2492
2541
|
nonNullable: true,
|
|
2493
2542
|
validators: [Validators.required, Validators.maxLength(5000)],
|
|
@@ -2529,10 +2578,10 @@ class SnapshotTextEditorComponent {
|
|
|
2529
2578
|
this.text.set(GveBaseTextService.stringToBaseChars(this.userText.value));
|
|
2530
2579
|
this.dialogRef?.close(this.text());
|
|
2531
2580
|
}
|
|
2532
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.
|
|
2533
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.
|
|
2581
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.3", ngImport: i0, type: SnapshotTextEditorComponent, deps: [{ token: i1$1.FormBuilder }, { token: i2$3.MatSnackBar }, { token: i3$2.MatDialogRef, optional: true }, { token: MAT_DIALOG_DATA, optional: true }], target: i0.ɵɵFactoryTarget.Component }); }
|
|
2582
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.3", type: SnapshotTextEditorComponent, isStandalone: true, selector: "gve-snapshot-text-editor", inputs: { text: { classPropertyName: "text", publicName: "text", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { text: "textChange" }, ngImport: i0, template: "<div [style.padding]=\"dialogRef ? '8px' : '0'\">\r\n @if (dialogRef) {\r\n <div id=\"heading\">\r\n <h2>Set Base Text</h2>\r\n </div>\r\n }\r\n <form [formGroup]=\"form\" (submit)=\"save()\">\r\n <fieldset>\r\n <div id=\"batch-input\">\r\n <div>\r\n <mat-form-field class=\"full-width\">\r\n <mat-label>base text</mat-label>\r\n <textarea matInput [formControl]=\"userText\" rows=\"8\"></textarea>\r\n @if (\r\n $any(userText).errors?.required &&\r\n (userText.dirty || userText.touched)\r\n ) {\r\n <mat-error>text required</mat-error>\r\n }\r\n @if (\r\n $any(userText).errors?.maxLength &&\r\n (userText.dirty || userText.touched)\r\n ) {\r\n <mat-error>text too long</mat-error>\r\n }\r\n </mat-form-field>\r\n </div>\r\n </div>\r\n <div class=\"form-row-center\">\r\n @if (dialogRef) {\r\n <button\r\n type=\"button\"\r\n class=\"mat-warn\"\r\n mat-flat-button\r\n matTooltip=\"Close dialog\"\r\n (click)=\"close()\"\r\n >\r\n close\r\n </button>\r\n }\r\n <button\r\n type=\"button\"\r\n class=\"mat-primary\"\r\n mat-flat-button\r\n matTooltip=\"Copy JSON to clipboard\"\r\n [disabled]=\"form.invalid\"\r\n (click)=\"copyToClipboard()\"\r\n >\r\n JSON\r\n </button>\r\n <button\r\n type=\"button\"\r\n class=\"mat-primary\"\r\n mat-flat-button\r\n matTooltip=\"Set base text\"\r\n [disabled]=\"form.invalid\"\r\n (click)=\"save()\"\r\n >\r\n set\r\n </button>\r\n </div>\r\n </fieldset>\r\n </form>\r\n</div>\r\n", styles: [".full-width{width:100%}.form-row{display:flex;gap:8px;align-items:center;flex-wrap:wrap}.form-row-center{display:flex;gap:8px;align-items:center;justify-content:center;flex-wrap:wrap}.form-row,.form-row-center *{flex:0 0 auto}div#heading{margin:8px;text-align:center}\n"], dependencies: [{ kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1$1.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$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],[formArray],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$1.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i2.MatButton, selector: " button[matButton], a[matButton], button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button], a[mat-button], a[mat-raised-button], a[mat-flat-button], a[mat-stroked-button] ", inputs: ["matButton"], exportAs: ["matButton", "matAnchor"] }, { 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: "directive", type: i3.MatError, selector: "mat-error, [matError]", inputs: ["id"] }, { kind: "ngmodule", type: MatIconModule }, { 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", "disabledInteractive"], exportAs: ["matInput"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
2534
2583
|
}
|
|
2535
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.
|
|
2584
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.3", ngImport: i0, type: SnapshotTextEditorComponent, decorators: [{
|
|
2536
2585
|
type: Component,
|
|
2537
2586
|
args: [{ selector: 'gve-snapshot-text-editor', changeDetection: ChangeDetectionStrategy.OnPush, imports: [
|
|
2538
2587
|
ReactiveFormsModule,
|
|
@@ -2578,32 +2627,32 @@ class SnapshotEditorComponent {
|
|
|
2578
2627
|
* Using viewChild signal to handle conditionally rendered element -
|
|
2579
2628
|
* the element only exists when result() is truthy.
|
|
2580
2629
|
*/
|
|
2581
|
-
this.renditionRef = viewChild('rendition', ...(ngDevMode ? [{ debugName: "renditionRef" }] : []));
|
|
2630
|
+
this.renditionRef = viewChild('rendition', ...(ngDevMode ? [{ debugName: "renditionRef" }] : /* istanbul ignore next */ []));
|
|
2582
2631
|
/**
|
|
2583
2632
|
* The snapshot to edit.
|
|
2584
2633
|
*/
|
|
2585
|
-
this.snapshot = model(...(ngDevMode ? [undefined, { debugName: "snapshot" }] : []));
|
|
2634
|
+
this.snapshot = model(...(ngDevMode ? [undefined, { debugName: "snapshot" }] : /* istanbul ignore next */ []));
|
|
2586
2635
|
/**
|
|
2587
2636
|
* The batch operations text to set for the editor.
|
|
2588
2637
|
*/
|
|
2589
|
-
this.batchOps = input(...(ngDevMode ? [undefined, { debugName: "batchOps" }] : []));
|
|
2638
|
+
this.batchOps = input(...(ngDevMode ? [undefined, { debugName: "batchOps" }] : /* istanbul ignore next */ []));
|
|
2590
2639
|
/**
|
|
2591
2640
|
* True to disable saving.
|
|
2592
2641
|
*/
|
|
2593
|
-
this.noSave = input(...(ngDevMode ? [undefined, { debugName: "noSave" }] : []));
|
|
2642
|
+
this.noSave = input(...(ngDevMode ? [undefined, { debugName: "noSave" }] : /* istanbul ignore next */ []));
|
|
2594
2643
|
/**
|
|
2595
2644
|
* True to enable debug mode for view rendition.
|
|
2596
2645
|
*/
|
|
2597
|
-
this.debug = input(...(ngDevMode ? [undefined, { debugName: "debug" }] : []));
|
|
2646
|
+
this.debug = input(...(ngDevMode ? [undefined, { debugName: "debug" }] : /* istanbul ignore next */ []));
|
|
2598
2647
|
/**
|
|
2599
2648
|
* True to not show character decoration according to the trace
|
|
2600
2649
|
* features in nodes.
|
|
2601
2650
|
*/
|
|
2602
|
-
this.noDecoration = input(...(ngDevMode ? [undefined, { debugName: "noDecoration" }] : []));
|
|
2651
|
+
this.noDecoration = input(...(ngDevMode ? [undefined, { debugName: "noDecoration" }] : /* istanbul ignore next */ []));
|
|
2603
2652
|
/**
|
|
2604
2653
|
* Definitions for features, including names and values.
|
|
2605
2654
|
*/
|
|
2606
|
-
this.featureDefs = input(...(ngDevMode ? [undefined, { debugName: "featureDefs" }] : []));
|
|
2655
|
+
this.featureDefs = input(...(ngDevMode ? [undefined, { debugName: "featureDefs" }] : /* istanbul ignore next */ []));
|
|
2607
2656
|
/**
|
|
2608
2657
|
* The IDs of the features that are multi-valued. If a feature being
|
|
2609
2658
|
* edited is in this list, the feature editor will allow adding multiple
|
|
@@ -2611,35 +2660,35 @@ class SnapshotEditorComponent {
|
|
|
2611
2660
|
*/
|
|
2612
2661
|
this.multiValuedFeatureIds = input([
|
|
2613
2662
|
'r_hints',
|
|
2614
|
-
], ...(ngDevMode ? [{ debugName: "multiValuedFeatureIds" }] : []));
|
|
2663
|
+
], ...(ngDevMode ? [{ debugName: "multiValuedFeatureIds" }] : /* istanbul ignore next */ []));
|
|
2615
2664
|
/**
|
|
2616
2665
|
* Settings for rendering the snapshot. These are passed to the snapshot rendition
|
|
2617
2666
|
* component.
|
|
2618
2667
|
*/
|
|
2619
|
-
this.renditionSettings = input(DEFAULT_SETTINGS, ...(ngDevMode ? [{ debugName: "renditionSettings" }] : []));
|
|
2668
|
+
this.renditionSettings = input(DEFAULT_SETTINGS, ...(ngDevMode ? [{ debugName: "renditionSettings" }] : /* istanbul ignore next */ []));
|
|
2620
2669
|
/**
|
|
2621
2670
|
* Optional maximum height for the operations list. When set, the operations
|
|
2622
2671
|
* list will have a vertical scrollbar if its content exceeds this height.
|
|
2623
2672
|
* The value should be a valid CSS height value (e.g., '300px', '50vh').
|
|
2624
2673
|
*/
|
|
2625
|
-
this.opListMaxHeight = input(undefined, ...(ngDevMode ? [{ debugName: "opListMaxHeight" }] : []));
|
|
2674
|
+
this.opListMaxHeight = input(undefined, ...(ngDevMode ? [{ debugName: "opListMaxHeight" }] : /* istanbul ignore next */ []));
|
|
2626
2675
|
/**
|
|
2627
2676
|
* Emitted when the user cancels the snapshot editing.
|
|
2628
2677
|
*/
|
|
2629
2678
|
this.snapshotCancel = output();
|
|
2630
2679
|
this.featDetails = new FormControl(false, { nonNullable: true });
|
|
2631
2680
|
this.autoRun = new FormControl(false, { nonNullable: true });
|
|
2632
|
-
this.chain = signal(undefined, ...(ngDevMode ? [{ debugName: "chain" }] : []));
|
|
2681
|
+
this.chain = signal(undefined, ...(ngDevMode ? [{ debugName: "chain" }] : /* istanbul ignore next */ []));
|
|
2633
2682
|
// the currently picked base text range
|
|
2634
|
-
this.textRange = signal(undefined, ...(ngDevMode ? [{ debugName: "textRange" }] : []));
|
|
2683
|
+
this.textRange = signal(undefined, ...(ngDevMode ? [{ debugName: "textRange" }] : /* istanbul ignore next */ []));
|
|
2635
2684
|
// the lines count for the current base text
|
|
2636
|
-
this.lineCount = signal(0, ...(ngDevMode ? [{ debugName: "lineCount" }] : []));
|
|
2685
|
+
this.lineCount = signal(0, ...(ngDevMode ? [{ debugName: "lineCount" }] : /* istanbul ignore next */ []));
|
|
2637
2686
|
// the currently edited operation
|
|
2638
|
-
this.editedOp = signal(undefined, ...(ngDevMode ? [{ debugName: "editedOp" }] : []));
|
|
2639
|
-
this.editedOpIndex = signal(-1, ...(ngDevMode ? [{ debugName: "editedOpIndex" }] : []));
|
|
2687
|
+
this.editedOp = signal(undefined, ...(ngDevMode ? [{ debugName: "editedOp" }] : /* istanbul ignore next */ []));
|
|
2688
|
+
this.editedOpIndex = signal(-1, ...(ngDevMode ? [{ debugName: "editedOpIndex" }] : /* istanbul ignore next */ []));
|
|
2640
2689
|
// the patch to apply to the edited operation's range
|
|
2641
|
-
this.editedOpRangePatch = signal(undefined, ...(ngDevMode ? [{ debugName: "editedOpRangePatch" }] : []));
|
|
2642
|
-
this.busy = signal(false, ...(ngDevMode ? [{ debugName: "busy" }] : []));
|
|
2690
|
+
this.editedOpRangePatch = signal(undefined, ...(ngDevMode ? [{ debugName: "editedOpRangePatch" }] : /* istanbul ignore next */ []));
|
|
2691
|
+
this.busy = signal(false, ...(ngDevMode ? [{ debugName: "busy" }] : /* istanbul ignore next */ []));
|
|
2643
2692
|
this.opTypeMap = {
|
|
2644
2693
|
0: 'replace',
|
|
2645
2694
|
1: 'delete',
|
|
@@ -2651,9 +2700,9 @@ class SnapshotEditorComponent {
|
|
|
2651
2700
|
7: 'annotate',
|
|
2652
2701
|
};
|
|
2653
2702
|
// operations execution result
|
|
2654
|
-
this.result = signal(undefined, ...(ngDevMode ? [{ debugName: "result" }] : []));
|
|
2655
|
-
this.resultOperationId = signal(undefined, ...(ngDevMode ? [{ debugName: "resultOperationId" }] : []));
|
|
2656
|
-
this.initialStepIndex = signal(-1, ...(ngDevMode ? [{ debugName: "initialStepIndex" }] : []));
|
|
2703
|
+
this.result = signal(undefined, ...(ngDevMode ? [{ debugName: "result" }] : /* istanbul ignore next */ []));
|
|
2704
|
+
this.resultOperationId = signal(undefined, ...(ngDevMode ? [{ debugName: "resultOperationId" }] : /* istanbul ignore next */ []));
|
|
2705
|
+
this.initialStepIndex = signal(-1, ...(ngDevMode ? [{ debugName: "initialStepIndex" }] : /* istanbul ignore next */ []));
|
|
2657
2706
|
// base text
|
|
2658
2707
|
this.baseText = new FormControl([], {
|
|
2659
2708
|
nonNullable: true,
|
|
@@ -3265,10 +3314,10 @@ class SnapshotEditorComponent {
|
|
|
3265
3314
|
}
|
|
3266
3315
|
this.snapshot.set(this.getSnapshot());
|
|
3267
3316
|
}
|
|
3268
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.
|
|
3269
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.0", type: SnapshotEditorComponent, isStandalone: true, selector: "gve-snapshot-editor", inputs: { snapshot: { classPropertyName: "snapshot", publicName: "snapshot", isSignal: true, isRequired: false, transformFunction: null }, batchOps: { classPropertyName: "batchOps", publicName: "batchOps", isSignal: true, isRequired: false, transformFunction: null }, noSave: { classPropertyName: "noSave", publicName: "noSave", isSignal: true, isRequired: false, transformFunction: null }, debug: { classPropertyName: "debug", publicName: "debug", isSignal: true, isRequired: false, transformFunction: null }, noDecoration: { classPropertyName: "noDecoration", publicName: "noDecoration", isSignal: true, isRequired: false, transformFunction: null }, featureDefs: { classPropertyName: "featureDefs", publicName: "featureDefs", isSignal: true, isRequired: false, transformFunction: null }, multiValuedFeatureIds: { classPropertyName: "multiValuedFeatureIds", publicName: "multiValuedFeatureIds", isSignal: true, isRequired: false, transformFunction: null }, renditionSettings: { classPropertyName: "renditionSettings", publicName: "renditionSettings", isSignal: true, isRequired: false, transformFunction: null }, opListMaxHeight: { classPropertyName: "opListMaxHeight", publicName: "opListMaxHeight", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { snapshot: "snapshotChange", snapshotCancel: "snapshotCancel" }, viewQueries: [{ propertyName: "renditionRef", first: true, predicate: ["rendition"], descendants: true, isSignal: true }], ngImport: i0, template: "<form [formGroup]=\"form\" (submit)=\"save()\">\r\n <mat-tab-group>\r\n <!-- text -->\r\n <mat-tab>\r\n <ng-template mat-tab-label>\r\n <mat-icon>article</mat-icon> <span class=\"label\">text</span>\r\n </ng-template>\r\n <mat-expansion-panel>\r\n <mat-expansion-panel-header>\r\n <mat-panel-title> base text </mat-panel-title>\r\n </mat-expansion-panel-header>\r\n <!-- base text -->\r\n <div class=\"form-row\">\r\n <button\r\n type=\"button\"\r\n mat-flat-button\r\n color=\"mat-warn\"\r\n matTooltip=\"Enter base text\"\r\n (click)=\"inputBaseText()\"\r\n [disabled]=\"busy()\"\r\n >\r\n <mat-icon>edit</mat-icon> base text\r\n </button>\r\n\r\n @if (textRange()) {\r\n <span id=\"text-range\"\r\n >{{ textRange()!.at }}\u00D7{{ textRange()!.run }}</span\r\n >\r\n }\r\n </div>\r\n\r\n <!-- text characters -->\r\n <gve-base-text-view\r\n [text]=\"baseText.value\"\r\n [hasLineNumber]=\"true\"\r\n (rangePick)=\"onRangePick($event)\"\r\n />\r\n </mat-expansion-panel>\r\n </mat-tab>\r\n\r\n <!-- operations -->\r\n <mat-tab>\r\n <ng-template mat-tab-label>\r\n <mat-icon>edit</mat-icon> <span class=\"label\">operations</span>\r\n </ng-template>\r\n\r\n <div id=\"snapshot-container\">\r\n <div id=\"general\">\r\n <div class=\"form-row\">\r\n <!-- feat details -->\r\n <mat-slide-toggle\r\n [formControl]=\"featDetails\"\r\n matTooltip=\"Toggle feature details\"\r\n >feat. details</mat-slide-toggle\r\n >\r\n <!-- auto run on edit -->\r\n <mat-slide-toggle\r\n [formControl]=\"autoRun\"\r\n matTooltip=\"Auto-run operations on edit\"\r\n >auto-run</mat-slide-toggle\r\n >\r\n\r\n <div class=\"form-row right\">\r\n <!-- copy ops DSL -->\r\n <button\r\n type=\"button\"\r\n mat-icon-button\r\n matTooltip=\"Copy operations as DSL to clipboard\"\r\n [disabled]=\"!operations.value.length || busy()\"\r\n (click)=\"copyOperationsDsl()\"\r\n >\r\n <mat-icon>content_copy</mat-icon>\r\n </button>\r\n\r\n <!-- copy ops JSON -->\r\n <button\r\n type=\"button\"\r\n mat-icon-button\r\n matTooltip=\"Copy operations as JSON to clipboard\"\r\n [disabled]=\"!operations.value.length || busy()\"\r\n (click)=\"copyOperationsJson()\"\r\n >\r\n <mat-icon>copy_all</mat-icon>\r\n </button>\r\n\r\n <!-- remove ops -->\r\n <button\r\n type=\"button\"\r\n class=\"mat-warn\"\r\n mat-flat-button\r\n matTooltip=\"Remove all the operations\"\r\n [disabled]=\"!operations.value.length || busy()\"\r\n (click)=\"clearOperations()\"\r\n >\r\n <mat-icon>delete_forever</mat-icon> clear\r\n </button>\r\n\r\n <!-- batch add ops -->\r\n <button\r\n type=\"button\"\r\n mat-flat-button\r\n matTooltip=\"Add a batch of operations\"\r\n class=\"mat-primary\"\r\n [disabled]=\"busy()\"\r\n (click)=\"parseOperations()\"\r\n >\r\n <mat-icon>post_add</mat-icon> batch\r\n </button>\r\n\r\n <!-- add op -->\r\n <button\r\n type=\"button\"\r\n mat-flat-button\r\n class=\"mat-primary\"\r\n [disabled]=\"!baseText.value\"\r\n (click)=\"editNewOperation()\"\r\n matTooltip=\"Add a new operation\"\r\n >\r\n <mat-icon>add_circle</mat-icon> operation\r\n </button>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <!-- ops -->\r\n <div\r\n id=\"ops\"\r\n [style.max-height]=\"opListMaxHeight()\"\r\n [style.overflow-y]=\"opListMaxHeight() ? 'auto' : null\"\r\n >\r\n <!-- operations list -->\r\n @if (operations.value.length) {\r\n <table id=\"list\">\r\n <thead>\r\n <tr>\r\n <th>nr.</th>\r\n <th></th>\r\n <th>ID</th>\r\n <th>type</th>\r\n <th>at</th>\r\n <th>run</th>\r\n <th>value</th>\r\n <th>itag</th>\r\n <th>otag</th>\r\n <th>gid</th>\r\n <th>feats</th>\r\n </tr>\r\n </thead>\r\n <tbody>\r\n @for (\r\n operation of operations.value;\r\n track operation.id;\r\n let index = $index\r\n ) {\r\n <tr\r\n [class.selected]=\"operation.id === resultOperationId()\"\r\n [class.edited]=\"operation.id === editedOp()?.id\"\r\n >\r\n <td class=\"fit-width\">{{ index + 1 }}.</td>\r\n <td class=\"fit-width\">\r\n <!-- edit -->\r\n <button\r\n type=\"button\"\r\n mat-icon-button\r\n class=\"mat-primary\"\r\n (click)=\"editOperation(index)\"\r\n matTooltip=\"Edit operation\"\r\n >\r\n <mat-icon>edit</mat-icon>\r\n </button>\r\n <!-- delete -->\r\n <button\r\n type=\"button\"\r\n mat-icon-button\r\n class=\"mat-warn\"\r\n (click)=\"deleteOperation(index)\"\r\n matTooltip=\"Delete operation\"\r\n >\r\n <mat-icon class=\"mat-warn\">delete</mat-icon>\r\n </button>\r\n <!-- run to -->\r\n <button\r\n type=\"button\"\r\n mat-icon-button\r\n class=\"mat-accent\"\r\n (click)=\"runTo(index)\"\r\n matTooltip=\"Run to this operation\"\r\n >\r\n <mat-icon class=\"mat-accent\">subscriptions</mat-icon>\r\n </button>\r\n <!-- duplicate -->\r\n <button\r\n type=\"button\"\r\n mat-icon-button\r\n (click)=\"duplicateOperation(index)\"\r\n matTooltip=\"Duplicate operation\"\r\n >\r\n <mat-icon>control_point_duplicate</mat-icon>\r\n </button>\r\n <!-- move up -->\r\n <button\r\n type=\"button\"\r\n mat-icon-button\r\n (click)=\"moveOperationUp(index)\"\r\n matTooltip=\"Move operation up\"\r\n [disabled]=\"index === 0\"\r\n >\r\n <mat-icon>arrow_circle_up</mat-icon>\r\n </button>\r\n <!-- move down -->\r\n <button\r\n type=\"button\"\r\n mat-icon-button\r\n (click)=\"moveOperationDown(index)\"\r\n matTooltip=\"Move operation down\"\r\n [disabled]=\"index === operations.value.length - 1\"\r\n >\r\n <mat-icon>arrow_circle_down</mat-icon>\r\n </button>\r\n </td>\r\n <td>{{ operation.id }}</td>\r\n <td>{{ operation.type | flatLookup: opTypeMap }}</td>\r\n <td>{{ operation.at }}</td>\r\n <td>{{ operation.run }}</td>\r\n <td>{{ operation.value }}</td>\r\n <td>{{ operation.inputTag }}</td>\r\n <td>{{ operation.outputTag }}</td>\r\n <td>{{ operation.groupId }}</td>\r\n <td>\r\n @if (operation.features?.length) {\r\n @if (featDetails.value) {\r\n <div class=\"form-row\">\r\n @for (\r\n feat of operation.features;\r\n track $index;\r\n let i = $index\r\n ) {\r\n <div class=\"feature\">\r\n <span class=\"fname\">{{\r\n feat.name\r\n | flatLookup\r\n : featureDefs()?.names\r\n : \"id\"\r\n : \"label\"\r\n }}</span\r\n >=<span class=\"fvalue\">{{\r\n feat.value\r\n | flatLookup\r\n : featureDefs()?.values?.[feat.name]\r\n : \"id\"\r\n : \"label\"\r\n }}</span>\r\n </div>\r\n }\r\n </div>\r\n } @else {\r\n {{ operation.features?.length }}\r\n }\r\n }\r\n </td>\r\n </tr>\r\n }\r\n </tbody>\r\n </table>\r\n }\r\n\r\n <!-- operation editor -->\r\n @if (editedOp()) {\r\n <mat-expansion-panel\r\n [expanded]=\"editedOp()\"\r\n [disabled]=\"!editedOp()\"\r\n >\r\n <mat-expansion-panel-header>\r\n <mat-panel-title\r\n >operation {{ editedOp()?.id }}</mat-panel-title\r\n >\r\n </mat-expansion-panel-header>\r\n <fieldset>\r\n <gve-chain-operation-editor\r\n [featureDefs]=\"featureDefs()\"\r\n [multiValuedFeatureIds]=\"multiValuedFeatureIds()\"\r\n [hidePreview]=\"editedOpIndex() === -1\"\r\n [operation]=\"editedOp()\"\r\n [rangePatch]=\"editedOpRangePatch()\"\r\n (operationCancel)=\"onOperationCancel()\"\r\n (operationChange)=\"onOperationChange($event)\"\r\n (operationPreview)=\"onOperationPreview($event)\"\r\n />\r\n </fieldset>\r\n </mat-expansion-panel>\r\n }\r\n </div>\r\n </div>\r\n </mat-tab>\r\n </mat-tab-group>\r\n\r\n <!-- progress -->\r\n <div>\r\n @if (busy()) {\r\n <mat-progress-bar mode=\"indeterminate\" />\r\n }\r\n </div>\r\n\r\n <!-- result -->\r\n @if (result()) {\r\n <fieldset id=\"result\">\r\n <legend>result</legend>\r\n <gve-chain-result-view\r\n [result]=\"result()!\"\r\n [initialStepIndex]=\"initialStepIndex()\"\r\n [disabledRangePick]=\"editedOp() ? false : true\"\r\n (stepPick)=\"onStepPick($event)\"\r\n (rangePick)=\"onRangePick($event, true)\"\r\n />\r\n </fieldset>\r\n }\r\n\r\n <!-- snapshot view -->\r\n @if (result()) {\r\n <div id=\"preview\">\r\n <gve-snapshot-rendition #rendition class=\"rendition\">\r\n </gve-snapshot-rendition>\r\n </div>\r\n }\r\n\r\n <!--buttons -->\r\n <div class=\"form-row-center\">\r\n <button\r\n type=\"button\"\r\n class=\"mat-warn\"\r\n mat-flat-button\r\n matTooltip=\"Discard changes\"\r\n (click)=\"close()\"\r\n >\r\n <mat-icon>clear</mat-icon>\r\n close\r\n </button>\r\n @if (!noSave()) {\r\n <button\r\n type=\"submit\"\r\n class=\"mat-primary\"\r\n mat-flat-button\r\n matTooltip=\"Save changes\"\r\n [disabled]=\"form.invalid\"\r\n >\r\n <mat-icon>check_circle</mat-icon>\r\n save\r\n </button>\r\n }\r\n </div>\r\n</form>\r\n", styles: [".form-row{display:flex;gap:8px;align-items:center;flex-wrap:wrap}.form-row-center{display:flex;gap:8px;align-items:center;justify-content:center;flex-wrap:wrap}.form-row,.form-row-center *{flex:0 0 auto}.form-row .right{margin-left:auto}.button-row{display:flex;align-items:center;flex-wrap:wrap}.button-row *{flex:0 0 auto}.long-text{width:100%;max-width:800px}#text-range{margin:8px;border:1px solid silver;border-radius:6px;padding:6px}mat-expansion-panel{margin:8px 0}div#visual-info{font-size:95%;color:#909090;margin:8px}#result{max-height:800px;overflow:auto}#list{margin:8px 0}#opStyle{margin-top:8px}table{width:100%;border-collapse:collapse}th{color:#909090;font-weight:400;text-align:left;background-color:#e1e0e0}th,td{padding:4px;border-bottom:1px solid silver}tbody tr:nth-child(2n){background-color:#e8e8e8}td.fit-width{width:1px;white-space:nowrap}tr.selected{background-color:#c8d9eb}tr.edited{background-color:#f6f6e4}fieldset{border:1px solid silver;border-radius:6px;padding:8px;margin:8px 0}legend{color:#909090}.error{color:red}.input-nr{width:6em}.full-width{width:100%}.code{font-family:Courier New,Courier,monospace}.boxed{border:1px solid silver;border-radius:6px;padding:8px;margin:8px 0}span.label{margin-left:8px}.feature,.fname{color:silver}.fvalue{color:#fff;background-color:#b5bdc9;padding:2px 4px;border-radius:4px}gve-animation-timeline-set{margin:8px 0}div#image{display:grid;gap:8px;grid-template-rows:auto;grid-template-columns:1fr auto;grid-template-areas:\"image-ctl image-view\"}div#image-ctl{grid-area:image-ctl}div#image-view{grid-area:image-view}div#chain-view{margin-bottom:8px}#preview{margin:8px 0}.rendition{display:block;width:100%;min-height:600px;max-height:80vh;border:1px solid #ccc;overflow:auto}@media only screen and (max-width:959px){div#image{grid-template-columns:1fr;grid-template-areas:\"image-ctl\" \"image-view\"}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],[formArray],form:not([ngNoForm]),[ngForm]" }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$1.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i2.MatButton, selector: " button[matButton], a[matButton], button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button], a[mat-button], a[mat-raised-button], a[mat-flat-button], a[mat-stroked-button] ", inputs: ["matButton"], exportAs: ["matButton", "matAnchor"] }, { kind: "component", type: i2.MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "ngmodule", type: MatButtonToggleModule }, { kind: "ngmodule", type: MatCheckboxModule }, { kind: "ngmodule", type: MatExpansionModule }, { kind: "component", type: i7$1.MatExpansionPanel, selector: "mat-expansion-panel", inputs: ["hideToggle", "togglePosition"], outputs: ["afterExpand", "afterCollapse"], exportAs: ["matExpansionPanel"] }, { kind: "component", type: i7$1.MatExpansionPanelHeader, selector: "mat-expansion-panel-header", inputs: ["expandedHeight", "collapsedHeight", "tabIndex"] }, { kind: "directive", type: i7$1.MatExpansionPanelTitle, selector: "mat-panel-title" }, { kind: "ngmodule", type: MatFormFieldModule }, { 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: "ngmodule", type: MatProgressBarModule }, { kind: "component", type: i9.MatProgressBar, selector: "mat-progress-bar", inputs: ["color", "value", "bufferValue", "mode"], outputs: ["animationEnd"], exportAs: ["matProgressBar"] }, { kind: "ngmodule", type: MatSliderModule }, { kind: "component", type: MatSlideToggle, selector: "mat-slide-toggle", inputs: ["name", "id", "labelPosition", "aria-label", "aria-labelledby", "aria-describedby", "required", "color", "disabled", "disableRipple", "tabIndex", "checked", "hideIcon", "disabledInteractive"], outputs: ["change", "toggleChange"], exportAs: ["matSlideToggle"] }, { kind: "ngmodule", type: MatSnackBarModule }, { kind: "ngmodule", type: MatTabsModule }, { kind: "directive", type: i10.MatTabLabel, selector: "[mat-tab-label], [matTabLabel]" }, { kind: "component", type: i10.MatTab, selector: "mat-tab", inputs: ["disabled", "label", "aria-label", "aria-labelledby", "labelClass", "bodyClass", "id"], exportAs: ["matTab"] }, { kind: "component", type: i10.MatTabGroup, selector: "mat-tab-group", inputs: ["color", "fitInkBarToContent", "mat-stretch-tabs", "mat-align-tabs", "dynamicHeight", "selectedIndex", "headerPosition", "animationDuration", "contentTabIndex", "disablePagination", "disableRipple", "preserveContent", "backgroundColor", "aria-label", "aria-labelledby"], outputs: ["selectedIndexChange", "focusChange", "animationDone", "selectedTabChange"], exportAs: ["matTabGroup"] }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i6.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "component", type: ChainOperationEditorComponent, selector: "gve-chain-operation-editor", inputs: ["operation", "snapshot", "hidePreview", "featureDefs", "rangePatch", "multiValuedFeatureIds"], outputs: ["operationChange", "operationPreview", "operationCancel"] }, { kind: "component", type: ChainResultViewComponent, selector: "gve-chain-result-view", inputs: ["result", "initialStepIndex", "disabledRangePick"], outputs: ["stepPick", "rangePick"] }, { kind: "component", type: BaseTextViewComponent, selector: "gve-base-text-view", inputs: ["defaultColor", "defaultBorderColor", "selectionColor", "searchHighlightColor", "hasLineNumber", "text", "colorCallback", "borderColorCallback"], outputs: ["charPick", "rangePick"] }, { kind: "pipe", type: FlatLookupPipe, name: "flatLookup" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
3317
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.3", ngImport: i0, type: SnapshotEditorComponent, deps: [{ token: i1$1.FormBuilder }, { token: GveApiService }, { token: i3$2.MatDialog }, { token: i4$1.DialogService }, { token: i2$3.MatSnackBar }], target: i0.ɵɵFactoryTarget.Component }); }
|
|
3318
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.3", type: SnapshotEditorComponent, isStandalone: true, selector: "gve-snapshot-editor", inputs: { snapshot: { classPropertyName: "snapshot", publicName: "snapshot", isSignal: true, isRequired: false, transformFunction: null }, batchOps: { classPropertyName: "batchOps", publicName: "batchOps", isSignal: true, isRequired: false, transformFunction: null }, noSave: { classPropertyName: "noSave", publicName: "noSave", isSignal: true, isRequired: false, transformFunction: null }, debug: { classPropertyName: "debug", publicName: "debug", isSignal: true, isRequired: false, transformFunction: null }, noDecoration: { classPropertyName: "noDecoration", publicName: "noDecoration", isSignal: true, isRequired: false, transformFunction: null }, featureDefs: { classPropertyName: "featureDefs", publicName: "featureDefs", isSignal: true, isRequired: false, transformFunction: null }, multiValuedFeatureIds: { classPropertyName: "multiValuedFeatureIds", publicName: "multiValuedFeatureIds", isSignal: true, isRequired: false, transformFunction: null }, renditionSettings: { classPropertyName: "renditionSettings", publicName: "renditionSettings", isSignal: true, isRequired: false, transformFunction: null }, opListMaxHeight: { classPropertyName: "opListMaxHeight", publicName: "opListMaxHeight", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { snapshot: "snapshotChange", snapshotCancel: "snapshotCancel" }, viewQueries: [{ propertyName: "renditionRef", first: true, predicate: ["rendition"], descendants: true, isSignal: true }], ngImport: i0, template: "<form [formGroup]=\"form\" (submit)=\"save()\">\r\n <mat-tab-group>\r\n <!-- text -->\r\n <mat-tab>\r\n <ng-template mat-tab-label>\r\n <mat-icon>article</mat-icon> <span class=\"label\">text</span>\r\n </ng-template>\r\n <mat-expansion-panel>\r\n <mat-expansion-panel-header>\r\n <mat-panel-title> base text </mat-panel-title>\r\n </mat-expansion-panel-header>\r\n <!-- base text -->\r\n <div class=\"form-row\">\r\n <button\r\n type=\"button\"\r\n mat-flat-button\r\n color=\"mat-warn\"\r\n matTooltip=\"Enter base text\"\r\n (click)=\"inputBaseText()\"\r\n [disabled]=\"busy()\"\r\n >\r\n <mat-icon>edit</mat-icon> base text\r\n </button>\r\n\r\n @if (textRange()) {\r\n <span id=\"text-range\"\r\n >{{ textRange()!.at }}\u00D7{{ textRange()!.run }}</span\r\n >\r\n }\r\n </div>\r\n\r\n <!-- text characters -->\r\n <gve-base-text-view\r\n [text]=\"baseText.value\"\r\n [hasLineNumber]=\"true\"\r\n (rangePick)=\"onRangePick($event)\"\r\n />\r\n </mat-expansion-panel>\r\n </mat-tab>\r\n\r\n <!-- operations -->\r\n <mat-tab>\r\n <ng-template mat-tab-label>\r\n <mat-icon>edit</mat-icon> <span class=\"label\">operations</span>\r\n </ng-template>\r\n\r\n <div id=\"snapshot-container\">\r\n <div id=\"general\">\r\n <div class=\"form-row\">\r\n <!-- feat details -->\r\n <mat-slide-toggle\r\n [formControl]=\"featDetails\"\r\n matTooltip=\"Toggle feature details\"\r\n >feat. details</mat-slide-toggle\r\n >\r\n <!-- auto run on edit -->\r\n <mat-slide-toggle\r\n [formControl]=\"autoRun\"\r\n matTooltip=\"Auto-run operations on edit\"\r\n >auto-run</mat-slide-toggle\r\n >\r\n\r\n <div class=\"form-row right\">\r\n <!-- copy ops DSL -->\r\n <button\r\n type=\"button\"\r\n mat-icon-button\r\n matTooltip=\"Copy operations as DSL to clipboard\"\r\n [disabled]=\"!operations.value.length || busy()\"\r\n (click)=\"copyOperationsDsl()\"\r\n >\r\n <mat-icon>content_copy</mat-icon>\r\n </button>\r\n\r\n <!-- copy ops JSON -->\r\n <button\r\n type=\"button\"\r\n mat-icon-button\r\n matTooltip=\"Copy operations as JSON to clipboard\"\r\n [disabled]=\"!operations.value.length || busy()\"\r\n (click)=\"copyOperationsJson()\"\r\n >\r\n <mat-icon>copy_all</mat-icon>\r\n </button>\r\n\r\n <!-- remove ops -->\r\n <button\r\n type=\"button\"\r\n class=\"mat-warn\"\r\n mat-flat-button\r\n matTooltip=\"Remove all the operations\"\r\n [disabled]=\"!operations.value.length || busy()\"\r\n (click)=\"clearOperations()\"\r\n >\r\n <mat-icon>delete_forever</mat-icon> clear\r\n </button>\r\n\r\n <!-- batch add ops -->\r\n <button\r\n type=\"button\"\r\n mat-flat-button\r\n matTooltip=\"Add a batch of operations\"\r\n class=\"mat-primary\"\r\n [disabled]=\"busy()\"\r\n (click)=\"parseOperations()\"\r\n >\r\n <mat-icon>post_add</mat-icon> batch\r\n </button>\r\n\r\n <!-- add op -->\r\n <button\r\n type=\"button\"\r\n mat-flat-button\r\n class=\"mat-primary\"\r\n [disabled]=\"!baseText.value\"\r\n (click)=\"editNewOperation()\"\r\n matTooltip=\"Add a new operation\"\r\n >\r\n <mat-icon>add_circle</mat-icon> operation\r\n </button>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <!-- ops -->\r\n <div\r\n id=\"ops\"\r\n [style.max-height]=\"opListMaxHeight()\"\r\n [style.overflow-y]=\"opListMaxHeight() ? 'auto' : null\"\r\n >\r\n <!-- operations list -->\r\n @if (operations.value.length) {\r\n <table id=\"list\">\r\n <thead>\r\n <tr>\r\n <th>nr.</th>\r\n <th></th>\r\n <th>ID</th>\r\n <th>type</th>\r\n <th>at</th>\r\n <th>run</th>\r\n <th>value</th>\r\n <th>itag</th>\r\n <th>otag</th>\r\n <th>gid</th>\r\n <th>feats</th>\r\n </tr>\r\n </thead>\r\n <tbody>\r\n @for (\r\n operation of operations.value;\r\n track operation.id;\r\n let index = $index\r\n ) {\r\n <tr\r\n [class.selected]=\"operation.id === resultOperationId()\"\r\n [class.edited]=\"operation.id === editedOp()?.id\"\r\n >\r\n <td class=\"fit-width\">{{ index + 1 }}.</td>\r\n <td class=\"fit-width\">\r\n <!-- edit -->\r\n <button\r\n type=\"button\"\r\n mat-icon-button\r\n class=\"mat-primary\"\r\n (click)=\"editOperation(index)\"\r\n matTooltip=\"Edit operation\"\r\n >\r\n <mat-icon>edit</mat-icon>\r\n </button>\r\n <!-- delete -->\r\n <button\r\n type=\"button\"\r\n mat-icon-button\r\n class=\"mat-warn\"\r\n (click)=\"deleteOperation(index)\"\r\n matTooltip=\"Delete operation\"\r\n >\r\n <mat-icon class=\"mat-warn\">delete</mat-icon>\r\n </button>\r\n <!-- run to -->\r\n <button\r\n type=\"button\"\r\n mat-icon-button\r\n class=\"mat-accent\"\r\n (click)=\"runTo(index)\"\r\n matTooltip=\"Run to this operation\"\r\n >\r\n <mat-icon class=\"mat-accent\">subscriptions</mat-icon>\r\n </button>\r\n <!-- duplicate -->\r\n <button\r\n type=\"button\"\r\n mat-icon-button\r\n (click)=\"duplicateOperation(index)\"\r\n matTooltip=\"Duplicate operation\"\r\n >\r\n <mat-icon>control_point_duplicate</mat-icon>\r\n </button>\r\n <!-- move up -->\r\n <button\r\n type=\"button\"\r\n mat-icon-button\r\n (click)=\"moveOperationUp(index)\"\r\n matTooltip=\"Move operation up\"\r\n [disabled]=\"index === 0\"\r\n >\r\n <mat-icon>arrow_circle_up</mat-icon>\r\n </button>\r\n <!-- move down -->\r\n <button\r\n type=\"button\"\r\n mat-icon-button\r\n (click)=\"moveOperationDown(index)\"\r\n matTooltip=\"Move operation down\"\r\n [disabled]=\"index === operations.value.length - 1\"\r\n >\r\n <mat-icon>arrow_circle_down</mat-icon>\r\n </button>\r\n </td>\r\n <td>{{ operation.id }}</td>\r\n <td>{{ operation.type | flatLookup: opTypeMap }}</td>\r\n <td>{{ operation.at }}</td>\r\n <td>{{ operation.run }}</td>\r\n <td>{{ operation.value }}</td>\r\n <td>{{ operation.inputTag }}</td>\r\n <td>{{ operation.outputTag }}</td>\r\n <td>{{ operation.groupId }}</td>\r\n <td>\r\n @if (operation.features?.length) {\r\n @if (featDetails.value) {\r\n <div class=\"form-row\">\r\n @for (\r\n feat of operation.features;\r\n track $index;\r\n let i = $index\r\n ) {\r\n <div class=\"feature\">\r\n <span class=\"fname\">{{\r\n feat.name\r\n | flatLookup\r\n : featureDefs()?.names\r\n : \"id\"\r\n : \"label\"\r\n }}</span\r\n >=<span class=\"fvalue\">{{\r\n feat.value\r\n | flatLookup\r\n : featureDefs()?.values?.[feat.name]\r\n : \"id\"\r\n : \"label\"\r\n }}</span>\r\n </div>\r\n }\r\n </div>\r\n } @else {\r\n {{ operation.features?.length }}\r\n }\r\n }\r\n </td>\r\n </tr>\r\n }\r\n </tbody>\r\n </table>\r\n }\r\n\r\n <!-- operation editor -->\r\n @if (editedOp()) {\r\n <mat-expansion-panel\r\n [expanded]=\"editedOp()\"\r\n [disabled]=\"!editedOp()\"\r\n >\r\n <mat-expansion-panel-header>\r\n <mat-panel-title\r\n >operation {{ editedOp()?.id }}</mat-panel-title\r\n >\r\n </mat-expansion-panel-header>\r\n <fieldset>\r\n <gve-chain-operation-editor\r\n [featureDefs]=\"featureDefs()\"\r\n [multiValuedFeatureIds]=\"multiValuedFeatureIds()\"\r\n [hidePreview]=\"editedOpIndex() === -1\"\r\n [operation]=\"editedOp()\"\r\n [rangePatch]=\"editedOpRangePatch()\"\r\n (operationCancel)=\"onOperationCancel()\"\r\n (operationChange)=\"onOperationChange($event)\"\r\n (operationPreview)=\"onOperationPreview($event)\"\r\n />\r\n </fieldset>\r\n </mat-expansion-panel>\r\n }\r\n </div>\r\n </div>\r\n </mat-tab>\r\n </mat-tab-group>\r\n\r\n <!-- progress -->\r\n <div>\r\n @if (busy()) {\r\n <mat-progress-bar mode=\"indeterminate\" />\r\n }\r\n </div>\r\n\r\n <!-- result -->\r\n @if (result()) {\r\n <fieldset id=\"result\">\r\n <legend>result</legend>\r\n <gve-chain-result-view\r\n [result]=\"result()!\"\r\n [initialStepIndex]=\"initialStepIndex()\"\r\n [disabledRangePick]=\"editedOp() ? false : true\"\r\n (stepPick)=\"onStepPick($event)\"\r\n (rangePick)=\"onRangePick($event, true)\"\r\n />\r\n </fieldset>\r\n }\r\n\r\n <!-- snapshot view -->\r\n @if (result()) {\r\n <div id=\"preview\">\r\n <gve-snapshot-rendition #rendition class=\"rendition\">\r\n </gve-snapshot-rendition>\r\n </div>\r\n }\r\n\r\n <!--buttons -->\r\n <div class=\"form-row-center\">\r\n <button\r\n type=\"button\"\r\n class=\"mat-warn\"\r\n mat-flat-button\r\n matTooltip=\"Discard changes\"\r\n (click)=\"close()\"\r\n >\r\n <mat-icon>clear</mat-icon>\r\n close\r\n </button>\r\n @if (!noSave()) {\r\n <button\r\n type=\"submit\"\r\n class=\"mat-primary\"\r\n mat-flat-button\r\n matTooltip=\"Save changes\"\r\n [disabled]=\"form.invalid\"\r\n >\r\n <mat-icon>check_circle</mat-icon>\r\n save\r\n </button>\r\n }\r\n </div>\r\n</form>\r\n", styles: [".form-row{display:flex;gap:8px;align-items:center;flex-wrap:wrap}.form-row-center{display:flex;gap:8px;align-items:center;justify-content:center;flex-wrap:wrap}.form-row,.form-row-center *{flex:0 0 auto}.form-row .right{margin-left:auto}.button-row{display:flex;align-items:center;flex-wrap:wrap}.button-row *{flex:0 0 auto}.long-text{width:100%;max-width:800px}#text-range{margin:8px;border:1px solid silver;border-radius:6px;padding:6px}mat-expansion-panel{margin:8px 0}div#visual-info{font-size:95%;color:#909090;margin:8px}#result{max-height:800px;overflow:auto}#list{margin:8px 0}#opStyle{margin-top:8px}table{width:100%;border-collapse:collapse}th{color:#909090;font-weight:400;text-align:left;background-color:#e1e0e0}th,td{padding:4px;border-bottom:1px solid silver}tbody tr:nth-child(2n){background-color:#e8e8e8}td.fit-width{width:1px;white-space:nowrap}tr.selected{background-color:#c8d9eb}tr.edited{background-color:#f6f6e4}fieldset{border:1px solid silver;border-radius:6px;padding:8px;margin:8px 0}legend{color:#909090}.error{color:red}.input-nr{width:6em}.full-width{width:100%}.code{font-family:Courier New,Courier,monospace}.boxed{border:1px solid silver;border-radius:6px;padding:8px;margin:8px 0}span.label{margin-left:8px}.feature,.fname{color:silver}.fvalue{color:#fff;background-color:#b5bdc9;padding:2px 4px;border-radius:4px}gve-animation-timeline-set{margin:8px 0}div#image{display:grid;gap:8px;grid-template-rows:auto;grid-template-columns:1fr auto;grid-template-areas:\"image-ctl image-view\"}div#image-ctl{grid-area:image-ctl}div#image-view{grid-area:image-view}div#chain-view{margin-bottom:8px}#preview{margin:8px 0}.rendition{display:block;width:100%;min-height:600px;max-height:80vh;border:1px solid #ccc;overflow:auto}@media only screen and (max-width:959px){div#image{grid-template-columns:1fr;grid-template-areas:\"image-ctl\" \"image-view\"}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],[formArray],form:not([ngNoForm]),[ngForm]" }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$1.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i2.MatButton, selector: " button[matButton], a[matButton], button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button], a[mat-button], a[mat-raised-button], a[mat-flat-button], a[mat-stroked-button] ", inputs: ["matButton"], exportAs: ["matButton", "matAnchor"] }, { kind: "component", type: i2.MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "ngmodule", type: MatButtonToggleModule }, { kind: "ngmodule", type: MatCheckboxModule }, { kind: "ngmodule", type: MatExpansionModule }, { kind: "component", type: i7$1.MatExpansionPanel, selector: "mat-expansion-panel", inputs: ["hideToggle", "togglePosition"], outputs: ["afterExpand", "afterCollapse"], exportAs: ["matExpansionPanel"] }, { kind: "component", type: i7$1.MatExpansionPanelHeader, selector: "mat-expansion-panel-header", inputs: ["expandedHeight", "collapsedHeight", "tabIndex"] }, { kind: "directive", type: i7$1.MatExpansionPanelTitle, selector: "mat-panel-title" }, { kind: "ngmodule", type: MatFormFieldModule }, { 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: "ngmodule", type: MatProgressBarModule }, { kind: "component", type: i9.MatProgressBar, selector: "mat-progress-bar", inputs: ["color", "value", "bufferValue", "mode"], outputs: ["animationEnd"], exportAs: ["matProgressBar"] }, { kind: "ngmodule", type: MatSliderModule }, { kind: "component", type: MatSlideToggle, selector: "mat-slide-toggle", inputs: ["name", "id", "labelPosition", "aria-label", "aria-labelledby", "aria-describedby", "required", "color", "disabled", "disableRipple", "tabIndex", "checked", "hideIcon", "disabledInteractive"], outputs: ["change", "toggleChange"], exportAs: ["matSlideToggle"] }, { kind: "ngmodule", type: MatSnackBarModule }, { kind: "ngmodule", type: MatTabsModule }, { kind: "directive", type: i10.MatTabLabel, selector: "[mat-tab-label], [matTabLabel]" }, { kind: "component", type: i10.MatTab, selector: "mat-tab", inputs: ["disabled", "label", "aria-label", "aria-labelledby", "labelClass", "bodyClass", "id"], exportAs: ["matTab"] }, { kind: "component", type: i10.MatTabGroup, selector: "mat-tab-group", inputs: ["color", "fitInkBarToContent", "mat-stretch-tabs", "mat-align-tabs", "dynamicHeight", "selectedIndex", "headerPosition", "animationDuration", "contentTabIndex", "disablePagination", "disableRipple", "preserveContent", "backgroundColor", "aria-label", "aria-labelledby"], outputs: ["selectedIndexChange", "focusChange", "animationDone", "selectedTabChange"], exportAs: ["matTabGroup"] }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i6.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "component", type: ChainOperationEditorComponent, selector: "gve-chain-operation-editor", inputs: ["operation", "snapshot", "hidePreview", "featureDefs", "rangePatch", "multiValuedFeatureIds"], outputs: ["operationChange", "operationPreview", "operationCancel"] }, { kind: "component", type: ChainResultViewComponent, selector: "gve-chain-result-view", inputs: ["result", "initialStepIndex", "disabledRangePick"], outputs: ["stepPick", "rangePick"] }, { kind: "component", type: BaseTextViewComponent, selector: "gve-base-text-view", inputs: ["defaultColor", "defaultBorderColor", "selectionColor", "searchHighlightColor", "hasLineNumber", "text", "colorCallback", "borderColorCallback"], outputs: ["charPick", "rangePick"] }, { kind: "pipe", type: FlatLookupPipe, name: "flatLookup" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
3270
3319
|
}
|
|
3271
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.
|
|
3320
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.3", ngImport: i0, type: SnapshotEditorComponent, decorators: [{
|
|
3272
3321
|
type: Component,
|
|
3273
3322
|
args: [{ selector: 'gve-snapshot-editor', imports: [
|
|
3274
3323
|
CommonModule,
|
|
@@ -3399,10 +3448,10 @@ class GveGraphvizService {
|
|
|
3399
3448
|
sb.push('}');
|
|
3400
3449
|
return sb.join('\n');
|
|
3401
3450
|
}
|
|
3402
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.
|
|
3403
|
-
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.
|
|
3451
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.3", ngImport: i0, type: GveGraphvizService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
3452
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.3", ngImport: i0, type: GveGraphvizService, providedIn: 'root' }); }
|
|
3404
3453
|
}
|
|
3405
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.
|
|
3454
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.3", ngImport: i0, type: GveGraphvizService, decorators: [{
|
|
3406
3455
|
type: Injectable,
|
|
3407
3456
|
args: [{
|
|
3408
3457
|
providedIn: 'root',
|