@myrmidon/gve-core 7.0.1 → 7.0.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.
|
@@ -892,8 +892,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.11", ngImpo
|
|
|
892
892
|
* will allow adding multiple values to it.
|
|
893
893
|
* - ▶️ `isVar`: true if the feature is a variant operation feature, which
|
|
894
894
|
* has additional properties like negation, global, and short-lived.
|
|
895
|
-
* - ▶️ `
|
|
896
|
-
* the
|
|
895
|
+
* - ▶️ `batchMode`: true to enable batch mode, where users edit features
|
|
896
|
+
* without the component firing change events until they click the "Save" button,
|
|
897
|
+
* and close the editor without saving by clicking the "Close" button.
|
|
897
898
|
* - 🔥 `close`: emitted when the user clicks the close button.
|
|
898
899
|
* - 🔥 `featuresChange` (`Feature[]`): emitted when features have changed.
|
|
899
900
|
*/
|
|
@@ -932,10 +933,11 @@ class FeatureSetEditorComponent {
|
|
|
932
933
|
'r_hints',
|
|
933
934
|
], ...(ngDevMode ? [{ debugName: "multiValuedFeatureIds" }] : /* istanbul ignore next */ []));
|
|
934
935
|
/**
|
|
935
|
-
* True
|
|
936
|
-
* without
|
|
936
|
+
* True to enable batch mode, where users edit features
|
|
937
|
+
* without the component firing change events until they click the "Save" button,
|
|
938
|
+
* and close the editor without saving by clicking the "Close" button.
|
|
937
939
|
*/
|
|
938
|
-
this.
|
|
940
|
+
this.batchMode = input(false, ...(ngDevMode ? [{ debugName: "batchMode" }] : /* istanbul ignore next */ []));
|
|
939
941
|
/**
|
|
940
942
|
* Emitted when the user clicks the close button.
|
|
941
943
|
*/
|
|
@@ -947,10 +949,22 @@ class FeatureSetEditorComponent {
|
|
|
947
949
|
this.editedFeature = signal(undefined, ...(ngDevMode ? [{ debugName: "editedFeature" }] : /* istanbul ignore next */ []));
|
|
948
950
|
this.editedFeatureIndex = signal(-1, ...(ngDevMode ? [{ debugName: "editedFeatureIndex" }] : /* istanbul ignore next */ []));
|
|
949
951
|
this.filteredFeatures = signal([], ...(ngDevMode ? [{ debugName: "filteredFeatures" }] : /* istanbul ignore next */ []));
|
|
952
|
+
// In batch mode, mutations accumulate here until the user clicks OK.
|
|
953
|
+
this.draftFeatures = signal([], ...(ngDevMode ? [{ debugName: "draftFeatures" }] : /* istanbul ignore next */ []));
|
|
954
|
+
// Active source: draft in batch mode, model signal otherwise.
|
|
955
|
+
this.workingFeatures = computed(() => (this.batchMode() ? this.draftFeatures() : this.features()), ...(ngDevMode ? [{ debugName: "workingFeatures" }] : /* istanbul ignore next */ []));
|
|
956
|
+
// Show Close/OK buttons only in batch mode.
|
|
957
|
+
this.hasCloseButton = computed(() => this.batchMode(), ...(ngDevMode ? [{ debugName: "hasCloseButton" }] : /* istanbul ignore next */ []));
|
|
950
958
|
this.filter = formBuilder.control(null);
|
|
951
|
-
//
|
|
959
|
+
// Sync draft from the model input whenever features or batchMode changes.
|
|
952
960
|
effect(() => {
|
|
953
|
-
|
|
961
|
+
if (this.batchMode()) {
|
|
962
|
+
this.draftFeatures.set([...this.features()]);
|
|
963
|
+
}
|
|
964
|
+
});
|
|
965
|
+
// When the working list changes, re-apply the filter.
|
|
966
|
+
effect(() => {
|
|
967
|
+
this.applyFeatureFilter(this.workingFeatures(), this.filter.value);
|
|
954
968
|
});
|
|
955
969
|
}
|
|
956
970
|
applyFeatureFilter(features, name) {
|
|
@@ -963,7 +977,7 @@ class FeatureSetEditorComponent {
|
|
|
963
977
|
this._sub = this.filter.valueChanges
|
|
964
978
|
.pipe(distinctUntilChanged(), debounceTime(300))
|
|
965
979
|
.subscribe((value) => {
|
|
966
|
-
this.applyFeatureFilter(this.
|
|
980
|
+
this.applyFeatureFilter(this.workingFeatures(), value);
|
|
967
981
|
});
|
|
968
982
|
}
|
|
969
983
|
ngOnDestroy() {
|
|
@@ -979,16 +993,22 @@ class FeatureSetEditorComponent {
|
|
|
979
993
|
}
|
|
980
994
|
editFeature(feature) {
|
|
981
995
|
this.editedFeature.set(structuredClone(feature));
|
|
982
|
-
this.editedFeatureIndex.set(this.
|
|
996
|
+
this.editedFeatureIndex.set(this.workingFeatures().indexOf(feature));
|
|
983
997
|
}
|
|
984
998
|
deleteFeature(feature) {
|
|
985
|
-
const
|
|
999
|
+
const source = this.workingFeatures();
|
|
1000
|
+
const index = source.indexOf(feature);
|
|
986
1001
|
if (index < 0) {
|
|
987
1002
|
return;
|
|
988
1003
|
}
|
|
989
|
-
const features = [...
|
|
1004
|
+
const features = [...source];
|
|
990
1005
|
features.splice(index, 1);
|
|
991
|
-
this.
|
|
1006
|
+
if (this.batchMode()) {
|
|
1007
|
+
this.draftFeatures.set(features);
|
|
1008
|
+
}
|
|
1009
|
+
else {
|
|
1010
|
+
this.features.set(features);
|
|
1011
|
+
}
|
|
992
1012
|
}
|
|
993
1013
|
isFeatureMultiValued(feature) {
|
|
994
1014
|
if (!feature || !this.multiValuedFeatureIds()) {
|
|
@@ -1000,7 +1020,7 @@ class FeatureSetEditorComponent {
|
|
|
1000
1020
|
if (!feature) {
|
|
1001
1021
|
return;
|
|
1002
1022
|
}
|
|
1003
|
-
const features = [...this.
|
|
1023
|
+
const features = [...this.workingFeatures()];
|
|
1004
1024
|
for (let i = features.length - 1; i >= 0; i--) {
|
|
1005
1025
|
if (features[i].name === feature.name) {
|
|
1006
1026
|
if (feature.setPolicy === FeatureSetPolicy.single ||
|
|
@@ -1016,14 +1036,22 @@ class FeatureSetEditorComponent {
|
|
|
1016
1036
|
features.splice(this.editedFeatureIndex(), 1, feature);
|
|
1017
1037
|
}
|
|
1018
1038
|
this.onFeatureCancel();
|
|
1019
|
-
this.
|
|
1039
|
+
if (this.batchMode()) {
|
|
1040
|
+
this.draftFeatures.set(features);
|
|
1041
|
+
}
|
|
1042
|
+
else {
|
|
1043
|
+
this.features.set(features);
|
|
1044
|
+
}
|
|
1020
1045
|
}
|
|
1021
1046
|
onFeatureCancel() {
|
|
1022
1047
|
this.editedFeature.set(undefined);
|
|
1023
1048
|
this.editedFeatureIndex.set(-1);
|
|
1024
1049
|
}
|
|
1050
|
+
onOk() {
|
|
1051
|
+
this.features.set(this.draftFeatures());
|
|
1052
|
+
}
|
|
1025
1053
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.11", ngImport: i0, type: FeatureSetEditorComponent, deps: [{ token: i1$1.FormBuilder }], target: i0.ɵɵFactoryTarget.Component }); }
|
|
1026
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.11", 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 }, hasCloseButton: { classPropertyName: "hasCloseButton", publicName: "hasCloseButton", isSignal: true, isRequired: false, transformFunction: null }, features: { classPropertyName: "features", publicName: "features", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { close: "close", 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 <label>filter</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 }\r\n\r\n <div class=\"form-row\">\r\n @if (hasCloseButton()) {\r\n <!-- close editor button -->\r\n <button\r\n type=\"button\"\r\n color=\"warn\"\r\n class=\"mat-warn\"\r\n mat-flat-button\r\n matTooltip=\"Close features editor\"\r\n (click)=\"close.emit()\"\r\n >\r\n <mat-icon>close</mat-icon>\r\n close\r\n </button>\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 </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{margin-top:8px;width:100%;border-collapse:collapse;color:var(--mat-sys-on-surface-variant)}tbody tr:nth-child(odd){background-color:var(--mat-sys-surface-container)}th{text-align:left;font-weight:400;color:var(--mat-sys-on-surface-variant)}tbody tr:hover{background-color:var(--mat-sys-surface-container-high)}td.fit-width{width:1px;white-space:nowrap}tbody tr.selected{background-color:var(--mat-sys-secondary-container);color:var(--mat-sys-on-secondary-container)}\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 }); }
|
|
1054
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.11", 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 }, batchMode: { classPropertyName: "batchMode", publicName: "batchMode", isSignal: true, isRequired: false, transformFunction: null }, features: { classPropertyName: "features", publicName: "features", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { close: "close", features: "featuresChange" }, ngImport: i0, template: "<div>\r\n <div class=\"form-row\">\r\n <!-- filter -->\r\n @if (filterThreshold() === 0 || workingFeatures().length >= filterThreshold()) {\r\n <mat-form-field>\r\n <label>filter</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 }\r\n\r\n <div class=\"form-row\">\r\n @if (hasCloseButton()) {\r\n <!-- close editor button -->\r\n <button\r\n type=\"button\"\r\n color=\"warn\"\r\n class=\"mat-warn\"\r\n mat-flat-button\r\n matTooltip=\"Close features editor\"\r\n (click)=\"close.emit()\"\r\n >\r\n <mat-icon>close</mat-icon>\r\n close\r\n </button>\r\n <!-- ok button: commits draft in batch mode -->\r\n <button\r\n type=\"button\"\r\n color=\"primary\"\r\n class=\"mat-primary\"\r\n mat-flat-button\r\n matTooltip=\"Save features\"\r\n (click)=\"onOk()\"\r\n >\r\n <mat-icon>check</mat-icon>\r\n OK\r\n </button>\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 || workingFeatures()!.length >= filterThreshold()\r\n \"\r\n >\r\n <mat-icon>add</mat-icon>\r\n feature\r\n </button>\r\n </div>\r\n </div>\r\n\r\n <!-- list -->\r\n @if (workingFeatures().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{margin-top:8px;width:100%;border-collapse:collapse;color:var(--mat-sys-on-surface-variant)}tbody tr:nth-child(odd){background-color:var(--mat-sys-surface-container)}th{text-align:left;font-weight:400;color:var(--mat-sys-on-surface-variant)}tbody tr:hover{background-color:var(--mat-sys-surface-container-high)}td.fit-width{width:1px;white-space:nowrap}tbody tr.selected{background-color:var(--mat-sys-secondary-container);color:var(--mat-sys-on-secondary-container)}\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 }); }
|
|
1027
1055
|
}
|
|
1028
1056
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.11", ngImport: i0, type: FeatureSetEditorComponent, decorators: [{
|
|
1029
1057
|
type: Component,
|
|
@@ -1038,8 +1066,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.11", ngImpo
|
|
|
1038
1066
|
MatTooltipModule,
|
|
1039
1067
|
FlatLookupPipe,
|
|
1040
1068
|
FeatureEditorComponent,
|
|
1041
|
-
], template: "<div>\r\n <div class=\"form-row\">\r\n <!-- filter -->\r\n @if (filterThreshold() === 0 ||
|
|
1042
|
-
}], ctorParameters: () => [{ type: i1$1.FormBuilder }], propDecorators: { isVar: [{ type: i0.Input, args: [{ isSignal: true, alias: "isVar", required: false }] }], featNames: [{ type: i0.Input, args: [{ isSignal: true, alias: "featNames", required: false }] }], featValues: [{ type: i0.Input, args: [{ isSignal: true, alias: "featValues", required: false }] }], filterThreshold: [{ type: i0.Input, args: [{ isSignal: true, alias: "filterThreshold", required: false }] }], multiValuedFeatureIds: [{ type: i0.Input, args: [{ isSignal: true, alias: "multiValuedFeatureIds", required: false }] }],
|
|
1069
|
+
], template: "<div>\r\n <div class=\"form-row\">\r\n <!-- filter -->\r\n @if (filterThreshold() === 0 || workingFeatures().length >= filterThreshold()) {\r\n <mat-form-field>\r\n <label>filter</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 }\r\n\r\n <div class=\"form-row\">\r\n @if (hasCloseButton()) {\r\n <!-- close editor button -->\r\n <button\r\n type=\"button\"\r\n color=\"warn\"\r\n class=\"mat-warn\"\r\n mat-flat-button\r\n matTooltip=\"Close features editor\"\r\n (click)=\"close.emit()\"\r\n >\r\n <mat-icon>close</mat-icon>\r\n close\r\n </button>\r\n <!-- ok button: commits draft in batch mode -->\r\n <button\r\n type=\"button\"\r\n color=\"primary\"\r\n class=\"mat-primary\"\r\n mat-flat-button\r\n matTooltip=\"Save features\"\r\n (click)=\"onOk()\"\r\n >\r\n <mat-icon>check</mat-icon>\r\n OK\r\n </button>\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 || workingFeatures()!.length >= filterThreshold()\r\n \"\r\n >\r\n <mat-icon>add</mat-icon>\r\n feature\r\n </button>\r\n </div>\r\n </div>\r\n\r\n <!-- list -->\r\n @if (workingFeatures().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{margin-top:8px;width:100%;border-collapse:collapse;color:var(--mat-sys-on-surface-variant)}tbody tr:nth-child(odd){background-color:var(--mat-sys-surface-container)}th{text-align:left;font-weight:400;color:var(--mat-sys-on-surface-variant)}tbody tr:hover{background-color:var(--mat-sys-surface-container-high)}td.fit-width{width:1px;white-space:nowrap}tbody tr.selected{background-color:var(--mat-sys-secondary-container);color:var(--mat-sys-on-secondary-container)}\n"] }]
|
|
1070
|
+
}], ctorParameters: () => [{ type: i1$1.FormBuilder }], propDecorators: { isVar: [{ type: i0.Input, args: [{ isSignal: true, alias: "isVar", required: false }] }], featNames: [{ type: i0.Input, args: [{ isSignal: true, alias: "featNames", required: false }] }], featValues: [{ type: i0.Input, args: [{ isSignal: true, alias: "featValues", required: false }] }], filterThreshold: [{ type: i0.Input, args: [{ isSignal: true, alias: "filterThreshold", required: false }] }], multiValuedFeatureIds: [{ type: i0.Input, args: [{ isSignal: true, alias: "multiValuedFeatureIds", required: false }] }], batchMode: [{ type: i0.Input, args: [{ isSignal: true, alias: "batchMode", required: false }] }], close: [{ type: i0.Output, args: ["close"] }], features: [{ type: i0.Input, args: [{ isSignal: true, alias: "features", required: false }] }, { type: i0.Output, args: ["featuresChange"] }] } });
|
|
1043
1071
|
|
|
1044
1072
|
/**
|
|
1045
1073
|
* Service for base text operations.
|
|
@@ -1189,7 +1217,7 @@ class BaseTextEditorComponent {
|
|
|
1189
1217
|
});
|
|
1190
1218
|
}
|
|
1191
1219
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.11", ngImport: i0, type: BaseTextEditorComponent, deps: [{ token: i1$1.FormBuilder }, { token: i4$1.DialogService }], target: i0.ɵɵFactoryTarget.Component }); }
|
|
1192
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.11", 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?.['v0'] ?? []\"\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{padding:10px;margin:10px 0;border-radius:5px;border:1px solid var(--mat-sys-on-surface-variant)}legend{color:var(--mat-sys-on-surface-variant)}.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", "
|
|
1220
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.11", 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?.['v0'] ?? []\"\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{padding:10px;margin:10px 0;border-radius:5px;border:1px solid var(--mat-sys-on-surface-variant)}legend{color:var(--mat-sys-on-surface-variant)}.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", "batchMode", "features"], outputs: ["close", "featuresChange"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
1193
1221
|
}
|
|
1194
1222
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.11", ngImport: i0, type: BaseTextEditorComponent, decorators: [{
|
|
1195
1223
|
type: Component,
|
|
@@ -2085,7 +2113,7 @@ class ChainOperationEditorComponent {
|
|
|
2085
2113
|
this.operationChange.emit(this.operation());
|
|
2086
2114
|
}
|
|
2087
2115
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.11", ngImport: i0, type: ChainOperationEditorComponent, deps: [{ token: i1$1.FormBuilder }, { token: i2$2.Clipboard }, { token: SettingsService }, { token: i4$1.DialogService }], target: i0.ɵɵFactoryTarget.Component }); }
|
|
2088
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.11", 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 }, sourceIds: { classPropertyName: "sourceIds", publicName: "sourceIds", isSignal: true, isRequired: false, transformFunction: null }, sourceTypes: { classPropertyName: "sourceTypes", publicName: "sourceTypes", 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]=\"7\"\r\n ><mat-icon>edit_note</mat-icon>annotate</mat-option\r\n >\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-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 @if ($any(at).errors?.min && (at.dirty || at.touched)) {\r\n <mat-error>at must be at least 0</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 @if (\r\n $any(value).errors?.required && (value.dirty || value.touched)\r\n ) {\r\n <mat-error>value required</mat-error>\r\n }\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 | flatLookup: sourceTypes() : \"id\" : \"label\" }}</td>\r\n <td>{{ s.id | flatLookup: sourceIds() : \"id\" : \"label\" }}</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 [ids]=\"sourceIds()\"\r\n [types]=\"sourceTypes()\"\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 var(--mat-sys-on-surface-variant)}.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:var(--mat-sys-secondary-container);color:var(--mat-sys-on-secondary-container);margin-top:-16px}fieldset{border:1px solid var(--mat-sys-on-surface-variant);border-radius:6px;padding:8px;margin:8px 0}legend{color:var(--mat-sys-on-surface-variant)}table{width:100%;border-collapse:collapse;color:var(--mat-sys-on-surface-variant)}tbody tr:nth-child(odd){background-color:var(--mat-sys-surface-container)}th{text-align:left;font-weight:400;color:var(--mat-sys-on-surface-variant)}tbody tr:hover{background-color:var(--mat-sys-surface-container-high)}td.fit-width{width:1px;white-space:nowrap}tbody tr.selected{background-color:var(--mat-sys-secondary-container);color:var(--mat-sys-on-secondary-container)}#code{height:500px;border:1px solid var(--mat-sys-on-surface-variant)}#monaco{height:100%}#preview{box-sizing:border-box;width:100%;border:1px solid var(--mat-sys-on-surface-variant);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:var(--mat-sys-secondary-container);color:var(--mat-sys-on-secondary-container)}.child-title{font-weight:700;margin:0;background-color:var(--mat-sys-secondary-container);color:var(--mat-sys-on-secondary-container);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 var(--mat-sys-on-surface-variant);border-radius:6px;margin:8px 0;padding-right:8px}#tree-ed{grid-area:ed;border:1px solid var(--mat-sys-on-surface-variant);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: i12.MatTab, selector: "mat-tab", inputs: ["disabled", "label", "aria-label", "aria-labelledby", "labelClass", "bodyClass", "id"], exportAs: ["matTab"] }, { kind: "component", type: i12.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", "hasCloseButton", "features"], outputs: ["close", "featuresChange"] }, { kind: "component", type: OperationSourceEditorComponent, selector: "gve-operation-source-editor", inputs: ["source", "ids", "types"], outputs: ["sourceChange", "sourceCancel"] }, { kind: "pipe", type: FlatLookupPipe, name: "flatLookup" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
2116
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.11", 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 }, sourceIds: { classPropertyName: "sourceIds", publicName: "sourceIds", isSignal: true, isRequired: false, transformFunction: null }, sourceTypes: { classPropertyName: "sourceTypes", publicName: "sourceTypes", 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]=\"7\"\r\n ><mat-icon>edit_note</mat-icon>annotate</mat-option\r\n >\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-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 @if ($any(at).errors?.min && (at.dirty || at.touched)) {\r\n <mat-error>at must be at least 0</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 @if (\r\n $any(value).errors?.required && (value.dirty || value.touched)\r\n ) {\r\n <mat-error>value required</mat-error>\r\n }\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 | flatLookup: sourceTypes() : \"id\" : \"label\" }}</td>\r\n <td>{{ s.id | flatLookup: sourceIds() : \"id\" : \"label\" }}</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 [ids]=\"sourceIds()\"\r\n [types]=\"sourceTypes()\"\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 var(--mat-sys-on-surface-variant)}.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:var(--mat-sys-secondary-container);color:var(--mat-sys-on-secondary-container);margin-top:-16px}fieldset{border:1px solid var(--mat-sys-on-surface-variant);border-radius:6px;padding:8px;margin:8px 0}legend{color:var(--mat-sys-on-surface-variant)}table{width:100%;border-collapse:collapse;color:var(--mat-sys-on-surface-variant)}tbody tr:nth-child(odd){background-color:var(--mat-sys-surface-container)}th{text-align:left;font-weight:400;color:var(--mat-sys-on-surface-variant)}tbody tr:hover{background-color:var(--mat-sys-surface-container-high)}td.fit-width{width:1px;white-space:nowrap}tbody tr.selected{background-color:var(--mat-sys-secondary-container);color:var(--mat-sys-on-secondary-container)}#code{height:500px;border:1px solid var(--mat-sys-on-surface-variant)}#monaco{height:100%}#preview{box-sizing:border-box;width:100%;border:1px solid var(--mat-sys-on-surface-variant);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:var(--mat-sys-secondary-container);color:var(--mat-sys-on-secondary-container)}.child-title{font-weight:700;margin:0;background-color:var(--mat-sys-secondary-container);color:var(--mat-sys-on-secondary-container);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 var(--mat-sys-on-surface-variant);border-radius:6px;margin:8px 0;padding-right:8px}#tree-ed{grid-area:ed;border:1px solid var(--mat-sys-on-surface-variant);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: i12.MatTab, selector: "mat-tab", inputs: ["disabled", "label", "aria-label", "aria-labelledby", "labelClass", "bodyClass", "id"], exportAs: ["matTab"] }, { kind: "component", type: i12.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", "batchMode", "features"], outputs: ["close", "featuresChange"] }, { kind: "component", type: OperationSourceEditorComponent, selector: "gve-operation-source-editor", inputs: ["source", "ids", "types"], outputs: ["sourceChange", "sourceCancel"] }, { kind: "pipe", type: FlatLookupPipe, name: "flatLookup" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
2089
2117
|
}
|
|
2090
2118
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.11", ngImport: i0, type: ChainOperationEditorComponent, decorators: [{
|
|
2091
2119
|
type: Component,
|
|
@@ -3072,6 +3100,7 @@ class SnapshotEditorComponent {
|
|
|
3072
3100
|
this.operations.setValue(operations);
|
|
3073
3101
|
this.operations.markAsDirty();
|
|
3074
3102
|
this.operations.updateValueAndValidity();
|
|
3103
|
+
this.closeOperationFeats();
|
|
3075
3104
|
}
|
|
3076
3105
|
closeOperationFeats() {
|
|
3077
3106
|
this.featsOpNumbers.set(undefined);
|
|
@@ -3516,7 +3545,7 @@ class SnapshotEditorComponent {
|
|
|
3516
3545
|
this.snapshot.set(this.getSnapshot());
|
|
3517
3546
|
}
|
|
3518
3547
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.11", 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 }); }
|
|
3519
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.11", 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 }, sourceIds: { classPropertyName: "sourceIds", publicName: "sourceIds", isSignal: true, isRequired: false, transformFunction: null }, sourceTypes: { classPropertyName: "sourceTypes", publicName: "sourceTypes", 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 }, { propertyName: "operationEditorPanelRef", first: true, predicate: ["operationEditorPanel"], 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 <!-- edit operations feats -->\r\n <form\r\n (submit)=\"editOperationsFeats()\"\r\n [formGroup]=\"editFeatsForm\"\r\n >\r\n <mat-form-field>\r\n <mat-label>operations (e.g. 2, 5-7, 9)</mat-label>\r\n <input matInput [formControl]=\"editFeatsRange\" />\r\n @if (\r\n $any(editFeatsRange).errors?.required &&\r\n (editFeatsRange.dirty || editFeatsRange.touched)\r\n ) {\r\n <mat-error>range required</mat-error>\r\n }\r\n @if (\r\n $any(editFeatsRange).errors?.pattern &&\r\n (editFeatsRange.dirty || editFeatsRange.touched)\r\n ) {\r\n <mat-error>invalid range (use e.g. 2, 5-7, 9)</mat-error>\r\n }\r\n <button type=\"submit\" matIconButton matSuffix>\r\n <mat-icon>edit_note</mat-icon>\r\n </button>\r\n </mat-form-field>\r\n </form>\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]=\"\r\n busy() || !operations.value.length || !baseText.value\r\n \"\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 <!-- feature set editor -->\r\n @if (featsOpNumbers()?.length) {\r\n <mat-expansion-panel\r\n #featsEditorPanel\r\n [expanded]=\"featsOpNumbers()!.length > 0\"\r\n >\r\n <mat-expansion-panel-header>\r\n <mat-panel-title>\r\n Features of {{ featsRangeLabel() }}\r\n </mat-panel-title>\r\n </mat-expansion-panel-header>\r\n <fieldset>\r\n <gve-feature-set-editor\r\n [hasCloseButton]=\"true\"\r\n [features]=\"operationFeats() || []\"\r\n [featureDefs]=\"featureDefs()\"\r\n [multiValuedFeatureIds]=\"multiValuedFeatureIds()\"\r\n [operations]=\"operations.value\"\r\n [opNumbers]=\"featsOpNumbers()!\"\r\n (close)=\"closeOperationFeats()\"\r\n (featuresChange)=\"saveOperationsFeats($event)\"\r\n />\r\n </fieldset>\r\n </mat-expansion-panel>\r\n }\r\n\r\n <!-- operation editor -->\r\n @if (editedOp()) {\r\n <mat-expansion-panel\r\n #operationEditorPanel\r\n [expanded]=\"editedOp()\"\r\n [disabled]=\"!editedOp()\"\r\n >\r\n <mat-expansion-panel-header>\r\n <mat-panel-title>operation {{ editedOp()?.id }}</mat-panel-title>\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 [sourceIds]=\"sourceIds()\"\r\n [sourceTypes]=\"sourceTypes()\"\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\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 <th>src</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 === editedOp()?.id\"\r\n [class.feat-editing]=\"featsOpNumbers()?.includes(index + 1)\"\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 <!-- version badge -->\r\n @if (\r\n operation.features?.some(f => f.name === 'version')\r\n ) {\r\n <span\r\n matBadge=\"{{ operation.features?.find(f => f.name === 'version')?.value }}\"\r\n matBadgeOverlap=\"false\"\r\n >{{ operation.features?.length }}</span>\r\n }\r\n }\r\n }\r\n </td>\r\n <td>{{ operation.sources?.length || \"\" }}</td>\r\n </tr>\r\n }\r\n </tbody>\r\n </table>\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 class=\"margin-bottom\">\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}.margin-bottom{margin-bottom:8px}#text-range{margin:8px;border:1px solid var(--mat-sys-on-surface-variant);border-radius:6px;padding:6px}mat-expansion-panel{margin:8px 0}div#visual-info{font-size:95%;color:var(--mat-sys-on-surface-variant);margin:8px}#result{max-height:800px;overflow:auto}#snapshot-container{margin-top:6px}#list{margin:8px 0}#opStyle{margin-top:8px}table{width:100%;border-collapse:collapse;color:var(--mat-sys-on-surface-variant)}tbody tr:nth-child(odd){background-color:var(--mat-sys-surface-container)}th{text-align:left;font-weight:400;color:var(--mat-sys-on-surface-variant)}tbody tr:hover{background-color:var(--mat-sys-surface-container-high)}td.fit-width{width:1px;white-space:nowrap}tbody tr.feat-editing{background-color:var(--mat-sys-tertiary-container);color:var(--mat-sys-on-tertiary-container)}tbody tr.selected{background-color:var(--mat-sys-secondary-container);color:var(--mat-sys-on-secondary-container)}fieldset{border:1px solid var(--mat-sys-on-surface-variant);border-radius:6px;padding:8px;margin:8px 0}legend{color:var(--mat-sys-on-surface-variant)}.error{color:var(--mat-sys-error)}.input-nr{width:6em}.full-width{width:100%}.code{font-family:Courier New,Courier,monospace}.boxed{border:1px solid var(--mat-sys-on-surface-variant);border-radius:6px;padding:8px;margin:8px 0}span.label{margin-left:8px}.feature{color:var(--mat-sys-on-surface-variant)}.fname{font-size:.9em;color:var(--mat-sys-on-surface-variant)}.fvalue{font-size:.9em;color:var(--mat-sys-on-surface-variant);background-color:var(--mat-sys-surface-container);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 var(--mat-sys-on-surface-variant);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.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: "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: "directive", type: MatBadge, selector: "[matBadge]", inputs: ["matBadgeColor", "matBadgeOverlap", "matBadgeDisabled", "matBadgePosition", "matBadge", "matBadgeDescription", "matBadgeSize", "matBadgeHidden"] }, { 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: "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: "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: MatProgressBarModule }, { kind: "component", type: i11.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: i12.MatTabLabel, selector: "[mat-tab-label], [matTabLabel]" }, { kind: "component", type: i12.MatTab, selector: "mat-tab", inputs: ["disabled", "label", "aria-label", "aria-labelledby", "labelClass", "bodyClass", "id"], exportAs: ["matTab"] }, { kind: "component", type: i12.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", "sourceIds", "sourceTypes"], 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: "component", type: FeatureSetEditorComponent, selector: "gve-feature-set-editor", inputs: ["isVar", "featNames", "featValues", "filterThreshold", "multiValuedFeatureIds", "hasCloseButton", "features"], outputs: ["close", "featuresChange"] }, { kind: "pipe", type: FlatLookupPipe, name: "flatLookup" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
3548
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.11", 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 }, sourceIds: { classPropertyName: "sourceIds", publicName: "sourceIds", isSignal: true, isRequired: false, transformFunction: null }, sourceTypes: { classPropertyName: "sourceTypes", publicName: "sourceTypes", 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 }, { propertyName: "operationEditorPanelRef", first: true, predicate: ["operationEditorPanel"], 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 <!-- edit operations feats -->\r\n <form\r\n (submit)=\"editOperationsFeats()\"\r\n [formGroup]=\"editFeatsForm\"\r\n >\r\n <mat-form-field>\r\n <mat-label>operations (e.g. 2, 5-7, 9)</mat-label>\r\n <input matInput [formControl]=\"editFeatsRange\" />\r\n @if (\r\n $any(editFeatsRange).errors?.required &&\r\n (editFeatsRange.dirty || editFeatsRange.touched)\r\n ) {\r\n <mat-error>range required</mat-error>\r\n }\r\n @if (\r\n $any(editFeatsRange).errors?.pattern &&\r\n (editFeatsRange.dirty || editFeatsRange.touched)\r\n ) {\r\n <mat-error>invalid range (use e.g. 2, 5-7, 9)</mat-error>\r\n }\r\n <button type=\"submit\" matIconButton matSuffix>\r\n <mat-icon>edit_note</mat-icon>\r\n </button>\r\n </mat-form-field>\r\n </form>\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]=\"\r\n busy() || !operations.value.length || !baseText.value\r\n \"\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 <!-- feature set editor -->\r\n @if (featsOpNumbers()?.length) {\r\n <mat-expansion-panel\r\n #featsEditorPanel\r\n [expanded]=\"featsOpNumbers()!.length > 0\"\r\n >\r\n <mat-expansion-panel-header>\r\n <mat-panel-title>\r\n Features of {{ featsRangeLabel() }}\r\n </mat-panel-title>\r\n </mat-expansion-panel-header>\r\n <fieldset>\r\n <gve-feature-set-editor\r\n [batchMode]=\"true\"\r\n [features]=\"operationFeats() || []\"\r\n [isVar]=\"true\"\r\n [featNames]=\"featureDefs()?.names\"\r\n [featValues]=\"featureDefs()?.values\"\r\n [multiValuedFeatureIds]=\"multiValuedFeatureIds()\"\r\n (close)=\"closeOperationFeats()\"\r\n (featuresChange)=\"saveOperationsFeats($event)\"\r\n />\r\n </fieldset>\r\n </mat-expansion-panel>\r\n }\r\n\r\n <!-- operation editor -->\r\n @if (editedOp()) {\r\n <mat-expansion-panel\r\n #operationEditorPanel\r\n [expanded]=\"editedOp()\"\r\n [disabled]=\"!editedOp()\"\r\n >\r\n <mat-expansion-panel-header>\r\n <mat-panel-title>operation {{ editedOp()?.id }}</mat-panel-title>\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 [sourceIds]=\"sourceIds()\"\r\n [sourceTypes]=\"sourceTypes()\"\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\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 <th>src</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 === editedOp()?.id\"\r\n [class.feat-editing]=\"featsOpNumbers()?.includes(index + 1)\"\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 <!-- version badge -->\r\n @if (\r\n operation.features?.some(f => f.name === 'version')\r\n ) {\r\n <span\r\n matBadge=\"{{ operation.features?.find(f => f.name === 'version')?.value }}\"\r\n matBadgeOverlap=\"false\"\r\n >{{ operation.features?.length }}</span\r\n >\r\n }\r\n }\r\n }\r\n </td>\r\n <td>{{ operation.sources?.length || \"\" }}</td>\r\n </tr>\r\n }\r\n </tbody>\r\n </table>\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 class=\"margin-bottom\">\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}.margin-bottom{margin-bottom:8px}#text-range{margin:8px;border:1px solid var(--mat-sys-on-surface-variant);border-radius:6px;padding:6px}mat-expansion-panel{margin:8px 0}div#visual-info{font-size:95%;color:var(--mat-sys-on-surface-variant);margin:8px}#result{max-height:800px;overflow:auto}#snapshot-container{margin-top:6px}#list{margin:8px 0}#opStyle{margin-top:8px}table{width:100%;border-collapse:collapse;color:var(--mat-sys-on-surface-variant)}tbody tr:nth-child(odd){background-color:var(--mat-sys-surface-container)}th{text-align:left;font-weight:400;color:var(--mat-sys-on-surface-variant)}tbody tr:hover{background-color:var(--mat-sys-surface-container-high)}td.fit-width{width:1px;white-space:nowrap}tbody tr.feat-editing{background-color:var(--mat-sys-tertiary-container);color:var(--mat-sys-on-tertiary-container)}tbody tr.selected{background-color:var(--mat-sys-secondary-container);color:var(--mat-sys-on-secondary-container)}fieldset{border:1px solid var(--mat-sys-on-surface-variant);border-radius:6px;padding:8px;margin:8px 0}legend{color:var(--mat-sys-on-surface-variant)}.error{color:var(--mat-sys-error)}.input-nr{width:6em}.full-width{width:100%}.code{font-family:Courier New,Courier,monospace}.boxed{border:1px solid var(--mat-sys-on-surface-variant);border-radius:6px;padding:8px;margin:8px 0}span.label{margin-left:8px}.feature{color:var(--mat-sys-on-surface-variant)}.fname{font-size:.9em;color:var(--mat-sys-on-surface-variant)}.fvalue{font-size:.9em;color:var(--mat-sys-on-surface-variant);background-color:var(--mat-sys-surface-container);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 var(--mat-sys-on-surface-variant);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.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: "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: "directive", type: MatBadge, selector: "[matBadge]", inputs: ["matBadgeColor", "matBadgeOverlap", "matBadgeDisabled", "matBadgePosition", "matBadge", "matBadgeDescription", "matBadgeSize", "matBadgeHidden"] }, { 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: "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: "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: MatProgressBarModule }, { kind: "component", type: i11.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: i12.MatTabLabel, selector: "[mat-tab-label], [matTabLabel]" }, { kind: "component", type: i12.MatTab, selector: "mat-tab", inputs: ["disabled", "label", "aria-label", "aria-labelledby", "labelClass", "bodyClass", "id"], exportAs: ["matTab"] }, { kind: "component", type: i12.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", "sourceIds", "sourceTypes"], 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: "component", type: FeatureSetEditorComponent, selector: "gve-feature-set-editor", inputs: ["isVar", "featNames", "featValues", "filterThreshold", "multiValuedFeatureIds", "batchMode", "features"], outputs: ["close", "featuresChange"] }, { kind: "pipe", type: FlatLookupPipe, name: "flatLookup" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
3520
3549
|
}
|
|
3521
3550
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.11", ngImport: i0, type: SnapshotEditorComponent, decorators: [{
|
|
3522
3551
|
type: Component,
|
|
@@ -3543,7 +3572,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.11", ngImpo
|
|
|
3543
3572
|
BaseTextViewComponent,
|
|
3544
3573
|
FeatureSetEditorComponent,
|
|
3545
3574
|
FlatLookupPipe,
|
|
3546
|
-
], schemas: [CUSTOM_ELEMENTS_SCHEMA], changeDetection: ChangeDetectionStrategy.OnPush, 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 <!-- edit operations feats -->\r\n <form\r\n (submit)=\"editOperationsFeats()\"\r\n [formGroup]=\"editFeatsForm\"\r\n >\r\n <mat-form-field>\r\n <mat-label>operations (e.g. 2, 5-7, 9)</mat-label>\r\n <input matInput [formControl]=\"editFeatsRange\" />\r\n @if (\r\n $any(editFeatsRange).errors?.required &&\r\n (editFeatsRange.dirty || editFeatsRange.touched)\r\n ) {\r\n <mat-error>range required</mat-error>\r\n }\r\n @if (\r\n $any(editFeatsRange).errors?.pattern &&\r\n (editFeatsRange.dirty || editFeatsRange.touched)\r\n ) {\r\n <mat-error>invalid range (use e.g. 2, 5-7, 9)</mat-error>\r\n }\r\n <button type=\"submit\" matIconButton matSuffix>\r\n <mat-icon>edit_note</mat-icon>\r\n </button>\r\n </mat-form-field>\r\n </form>\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]=\"\r\n busy() || !operations.value.length || !baseText.value\r\n \"\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 <!-- feature set editor -->\r\n @if (featsOpNumbers()?.length) {\r\n <mat-expansion-panel\r\n #featsEditorPanel\r\n [expanded]=\"featsOpNumbers()!.length > 0\"\r\n >\r\n <mat-expansion-panel-header>\r\n <mat-panel-title>\r\n Features of {{ featsRangeLabel() }}\r\n </mat-panel-title>\r\n </mat-expansion-panel-header>\r\n <fieldset>\r\n <gve-feature-set-editor\r\n [hasCloseButton]=\"true\"\r\n [features]=\"operationFeats() || []\"\r\n [featureDefs]=\"featureDefs()\"\r\n [multiValuedFeatureIds]=\"multiValuedFeatureIds()\"\r\n [operations]=\"operations.value\"\r\n [opNumbers]=\"featsOpNumbers()!\"\r\n (close)=\"closeOperationFeats()\"\r\n (featuresChange)=\"saveOperationsFeats($event)\"\r\n />\r\n </fieldset>\r\n </mat-expansion-panel>\r\n }\r\n\r\n <!-- operation editor -->\r\n @if (editedOp()) {\r\n <mat-expansion-panel\r\n #operationEditorPanel\r\n [expanded]=\"editedOp()\"\r\n [disabled]=\"!editedOp()\"\r\n >\r\n <mat-expansion-panel-header>\r\n <mat-panel-title>operation {{ editedOp()?.id }}</mat-panel-title>\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 [sourceIds]=\"sourceIds()\"\r\n [sourceTypes]=\"sourceTypes()\"\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\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 <th>src</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 === editedOp()?.id\"\r\n [class.feat-editing]=\"featsOpNumbers()?.includes(index + 1)\"\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 <!-- version badge -->\r\n @if (\r\n operation.features?.some(f => f.name === 'version')\r\n ) {\r\n <span\r\n matBadge=\"{{ operation.features?.find(f => f.name === 'version')?.value }}\"\r\n matBadgeOverlap=\"false\"\r\n >{{ operation.features?.length }}</span>\r\n }\r\n }\r\n }\r\n </td>\r\n <td>{{ operation.sources?.length || \"\" }}</td>\r\n </tr>\r\n }\r\n </tbody>\r\n </table>\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 class=\"margin-bottom\">\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}.margin-bottom{margin-bottom:8px}#text-range{margin:8px;border:1px solid var(--mat-sys-on-surface-variant);border-radius:6px;padding:6px}mat-expansion-panel{margin:8px 0}div#visual-info{font-size:95%;color:var(--mat-sys-on-surface-variant);margin:8px}#result{max-height:800px;overflow:auto}#snapshot-container{margin-top:6px}#list{margin:8px 0}#opStyle{margin-top:8px}table{width:100%;border-collapse:collapse;color:var(--mat-sys-on-surface-variant)}tbody tr:nth-child(odd){background-color:var(--mat-sys-surface-container)}th{text-align:left;font-weight:400;color:var(--mat-sys-on-surface-variant)}tbody tr:hover{background-color:var(--mat-sys-surface-container-high)}td.fit-width{width:1px;white-space:nowrap}tbody tr.feat-editing{background-color:var(--mat-sys-tertiary-container);color:var(--mat-sys-on-tertiary-container)}tbody tr.selected{background-color:var(--mat-sys-secondary-container);color:var(--mat-sys-on-secondary-container)}fieldset{border:1px solid var(--mat-sys-on-surface-variant);border-radius:6px;padding:8px;margin:8px 0}legend{color:var(--mat-sys-on-surface-variant)}.error{color:var(--mat-sys-error)}.input-nr{width:6em}.full-width{width:100%}.code{font-family:Courier New,Courier,monospace}.boxed{border:1px solid var(--mat-sys-on-surface-variant);border-radius:6px;padding:8px;margin:8px 0}span.label{margin-left:8px}.feature{color:var(--mat-sys-on-surface-variant)}.fname{font-size:.9em;color:var(--mat-sys-on-surface-variant)}.fvalue{font-size:.9em;color:var(--mat-sys-on-surface-variant);background-color:var(--mat-sys-surface-container);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 var(--mat-sys-on-surface-variant);overflow:auto}@media only screen and (max-width:959px){div#image{grid-template-columns:1fr;grid-template-areas:\"image-ctl\" \"image-view\"}}\n"] }]
|
|
3575
|
+
], schemas: [CUSTOM_ELEMENTS_SCHEMA], changeDetection: ChangeDetectionStrategy.OnPush, 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 <!-- edit operations feats -->\r\n <form\r\n (submit)=\"editOperationsFeats()\"\r\n [formGroup]=\"editFeatsForm\"\r\n >\r\n <mat-form-field>\r\n <mat-label>operations (e.g. 2, 5-7, 9)</mat-label>\r\n <input matInput [formControl]=\"editFeatsRange\" />\r\n @if (\r\n $any(editFeatsRange).errors?.required &&\r\n (editFeatsRange.dirty || editFeatsRange.touched)\r\n ) {\r\n <mat-error>range required</mat-error>\r\n }\r\n @if (\r\n $any(editFeatsRange).errors?.pattern &&\r\n (editFeatsRange.dirty || editFeatsRange.touched)\r\n ) {\r\n <mat-error>invalid range (use e.g. 2, 5-7, 9)</mat-error>\r\n }\r\n <button type=\"submit\" matIconButton matSuffix>\r\n <mat-icon>edit_note</mat-icon>\r\n </button>\r\n </mat-form-field>\r\n </form>\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]=\"\r\n busy() || !operations.value.length || !baseText.value\r\n \"\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 <!-- feature set editor -->\r\n @if (featsOpNumbers()?.length) {\r\n <mat-expansion-panel\r\n #featsEditorPanel\r\n [expanded]=\"featsOpNumbers()!.length > 0\"\r\n >\r\n <mat-expansion-panel-header>\r\n <mat-panel-title>\r\n Features of {{ featsRangeLabel() }}\r\n </mat-panel-title>\r\n </mat-expansion-panel-header>\r\n <fieldset>\r\n <gve-feature-set-editor\r\n [batchMode]=\"true\"\r\n [features]=\"operationFeats() || []\"\r\n [isVar]=\"true\"\r\n [featNames]=\"featureDefs()?.names\"\r\n [featValues]=\"featureDefs()?.values\"\r\n [multiValuedFeatureIds]=\"multiValuedFeatureIds()\"\r\n (close)=\"closeOperationFeats()\"\r\n (featuresChange)=\"saveOperationsFeats($event)\"\r\n />\r\n </fieldset>\r\n </mat-expansion-panel>\r\n }\r\n\r\n <!-- operation editor -->\r\n @if (editedOp()) {\r\n <mat-expansion-panel\r\n #operationEditorPanel\r\n [expanded]=\"editedOp()\"\r\n [disabled]=\"!editedOp()\"\r\n >\r\n <mat-expansion-panel-header>\r\n <mat-panel-title>operation {{ editedOp()?.id }}</mat-panel-title>\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 [sourceIds]=\"sourceIds()\"\r\n [sourceTypes]=\"sourceTypes()\"\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\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 <th>src</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 === editedOp()?.id\"\r\n [class.feat-editing]=\"featsOpNumbers()?.includes(index + 1)\"\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 <!-- version badge -->\r\n @if (\r\n operation.features?.some(f => f.name === 'version')\r\n ) {\r\n <span\r\n matBadge=\"{{ operation.features?.find(f => f.name === 'version')?.value }}\"\r\n matBadgeOverlap=\"false\"\r\n >{{ operation.features?.length }}</span\r\n >\r\n }\r\n }\r\n }\r\n </td>\r\n <td>{{ operation.sources?.length || \"\" }}</td>\r\n </tr>\r\n }\r\n </tbody>\r\n </table>\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 class=\"margin-bottom\">\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}.margin-bottom{margin-bottom:8px}#text-range{margin:8px;border:1px solid var(--mat-sys-on-surface-variant);border-radius:6px;padding:6px}mat-expansion-panel{margin:8px 0}div#visual-info{font-size:95%;color:var(--mat-sys-on-surface-variant);margin:8px}#result{max-height:800px;overflow:auto}#snapshot-container{margin-top:6px}#list{margin:8px 0}#opStyle{margin-top:8px}table{width:100%;border-collapse:collapse;color:var(--mat-sys-on-surface-variant)}tbody tr:nth-child(odd){background-color:var(--mat-sys-surface-container)}th{text-align:left;font-weight:400;color:var(--mat-sys-on-surface-variant)}tbody tr:hover{background-color:var(--mat-sys-surface-container-high)}td.fit-width{width:1px;white-space:nowrap}tbody tr.feat-editing{background-color:var(--mat-sys-tertiary-container);color:var(--mat-sys-on-tertiary-container)}tbody tr.selected{background-color:var(--mat-sys-secondary-container);color:var(--mat-sys-on-secondary-container)}fieldset{border:1px solid var(--mat-sys-on-surface-variant);border-radius:6px;padding:8px;margin:8px 0}legend{color:var(--mat-sys-on-surface-variant)}.error{color:var(--mat-sys-error)}.input-nr{width:6em}.full-width{width:100%}.code{font-family:Courier New,Courier,monospace}.boxed{border:1px solid var(--mat-sys-on-surface-variant);border-radius:6px;padding:8px;margin:8px 0}span.label{margin-left:8px}.feature{color:var(--mat-sys-on-surface-variant)}.fname{font-size:.9em;color:var(--mat-sys-on-surface-variant)}.fvalue{font-size:.9em;color:var(--mat-sys-on-surface-variant);background-color:var(--mat-sys-surface-container);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 var(--mat-sys-on-surface-variant);overflow:auto}@media only screen and (max-width:959px){div#image{grid-template-columns:1fr;grid-template-areas:\"image-ctl\" \"image-view\"}}\n"] }]
|
|
3547
3576
|
}], ctorParameters: () => [{ type: i1$1.FormBuilder }, { type: GveApiService }, { type: i3$2.MatDialog }, { type: i4$1.DialogService }, { type: i2$3.MatSnackBar }], propDecorators: { renditionRef: [{ type: i0.ViewChild, args: ['rendition', { isSignal: true }] }], operationEditorPanelRef: [{ type: i0.ViewChild, args: ['operationEditorPanel', { isSignal: true }] }], snapshot: [{ type: i0.Input, args: [{ isSignal: true, alias: "snapshot", required: false }] }, { type: i0.Output, args: ["snapshotChange"] }], batchOps: [{ type: i0.Input, args: [{ isSignal: true, alias: "batchOps", required: false }] }], noSave: [{ type: i0.Input, args: [{ isSignal: true, alias: "noSave", required: false }] }], debug: [{ type: i0.Input, args: [{ isSignal: true, alias: "debug", required: false }] }], noDecoration: [{ type: i0.Input, args: [{ isSignal: true, alias: "noDecoration", required: false }] }], featureDefs: [{ type: i0.Input, args: [{ isSignal: true, alias: "featureDefs", required: false }] }], multiValuedFeatureIds: [{ type: i0.Input, args: [{ isSignal: true, alias: "multiValuedFeatureIds", required: false }] }], sourceIds: [{ type: i0.Input, args: [{ isSignal: true, alias: "sourceIds", required: false }] }], sourceTypes: [{ type: i0.Input, args: [{ isSignal: true, alias: "sourceTypes", required: false }] }], renditionSettings: [{ type: i0.Input, args: [{ isSignal: true, alias: "renditionSettings", required: false }] }], opListMaxHeight: [{ type: i0.Input, args: [{ isSignal: true, alias: "opListMaxHeight", required: false }] }], snapshotCancel: [{ type: i0.Output, args: ["snapshotCancel"] }] } });
|
|
3548
3577
|
|
|
3549
3578
|
class GveGraphvizService {
|