@myrmidon/gve-core 6.0.1 → 6.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.
package/README.md CHANGED
@@ -119,5 +119,4 @@ Operations and timelines are handled by other children components. The snapshot
119
119
 
120
120
  - [@myrmidon/ngx-tools, @myrmidon/ngx-mat-tools](https://github.com/vedph/ngx-tools)
121
121
  - [cisstech/nge](https://github.com/cisstech/nge) for a light Monaco editor wrapper.
122
- - [@svgdotjs/svg.js](https://github.com/svgdotjs/svg.js/) for SVG manipulation.
123
122
  - [gsap](https://gsap.com/) for animations.
@@ -30,7 +30,7 @@ import * as i3$1 from '@angular/material/checkbox';
30
30
  import { MatCheckboxModule } from '@angular/material/checkbox';
31
31
  import * as i4$1 from '@myrmidon/ngx-mat-tools';
32
32
  import * as i3$2 from '@angular/material/dialog';
33
- import { MAT_DIALOG_DATA, MatDialogClose } from '@angular/material/dialog';
33
+ import { MAT_DIALOG_DATA } from '@angular/material/dialog';
34
34
  import * as i1$2 from '@angular/common/http';
35
35
  import { filter, debounceTime as debounceTime$1 } from 'rxjs/operators';
36
36
  import { MatBadgeModule } from '@angular/material/badge';
@@ -661,7 +661,9 @@ class FeatureEditorComponent {
661
661
  * The IDs of the features that are multi-valued. Used to determine
662
662
  * if the current feature being edited should display multi-value controls.
663
663
  */
664
- this.multiValuedFeatureIds = input(...(ngDevMode ? [undefined, { debugName: "multiValuedFeatureIds" }] : []));
664
+ this.multiValuedFeatureIds = input([
665
+ 'r_hints',
666
+ ], ...(ngDevMode ? [{ debugName: "multiValuedFeatureIds" }] : []));
665
667
  /**
666
668
  * Event emitted when the user cancels the feature editing.
667
669
  */
@@ -702,6 +704,10 @@ class FeatureEditorComponent {
702
704
  this.nameIds.set(this.getLabeledIdsFor(this.name.value, this.featValues()));
703
705
  }, 500);
704
706
  });
707
+ // diagnostic logging for multiValuedFeatureIds
708
+ effect(() => {
709
+ console.log('[FeatureEditor] multiValuedFeatureIds:', this.multiValuedFeatureIds(), 'isMultiValued:', this.isMultiValued());
710
+ });
705
711
  }
706
712
  ngOnInit() {
707
713
  // whenever the name changes, update the value selection and multi-valued status
@@ -859,7 +865,9 @@ class FeatureSetEditorComponent {
859
865
  * edited is in this list, the feature editor will allow adding multiple
860
866
  * values to it.
861
867
  */
862
- this.multiValuedFeatureIds = input(...(ngDevMode ? [undefined, { debugName: "multiValuedFeatureIds" }] : []));
868
+ this.multiValuedFeatureIds = input([
869
+ 'r_hints',
870
+ ], ...(ngDevMode ? [{ debugName: "multiValuedFeatureIds" }] : []));
863
871
  /**
864
872
  * The features to edit.
865
873
  */
@@ -872,6 +880,10 @@ class FeatureSetEditorComponent {
872
880
  effect(() => {
873
881
  this.applyFeatureFilter(this.features(), this.filter.value);
874
882
  });
883
+ // diagnostic logging for multiValuedFeatureIds
884
+ effect(() => {
885
+ console.log('[FeatureSetEditor] multiValuedFeatureIds:', this.multiValuedFeatureIds());
886
+ });
875
887
  }
876
888
  applyFeatureFilter(features, name) {
877
889
  this.filteredFeatures.set(features.filter((feature) => {
@@ -1691,7 +1703,9 @@ class ChainOperationEditorComponent {
1691
1703
  * edited is in this list, the feature editor will allow adding multiple
1692
1704
  * values to it. Passed down to feature editors.
1693
1705
  */
1694
- this.multiValuedFeatureIds = input(...(ngDevMode ? [undefined, { debugName: "multiValuedFeatureIds" }] : []));
1706
+ this.multiValuedFeatureIds = input([
1707
+ 'r_hints',
1708
+ ], ...(ngDevMode ? [{ debugName: "multiValuedFeatureIds" }] : []));
1695
1709
  /**
1696
1710
  * Emitted when the operation is changed.
1697
1711
  */
@@ -1777,6 +1791,10 @@ class ChainOperationEditorComponent {
1777
1791
  effect(() => {
1778
1792
  this.updateForm(this.operation());
1779
1793
  });
1794
+ // diagnostic logging for multiValuedFeatureIds
1795
+ effect(() => {
1796
+ console.log('[ChainOperationEditor] multiValuedFeatureIds:', this.multiValuedFeatureIds());
1797
+ });
1780
1798
  // when rangePatch changes, patch operation range (at and run,
1781
1799
  // resetting atAsIndex to false)
1782
1800
  effect(() => {
@@ -2570,7 +2588,9 @@ class SnapshotEditorComponent {
2570
2588
  * edited is in this list, the feature editor will allow adding multiple
2571
2589
  * values to it. Passed down to feature editors.
2572
2590
  */
2573
- this.multiValuedFeatureIds = input(...(ngDevMode ? [undefined, { debugName: "multiValuedFeatureIds" }] : []));
2591
+ this.multiValuedFeatureIds = input([
2592
+ 'r_hints',
2593
+ ], ...(ngDevMode ? [{ debugName: "multiValuedFeatureIds" }] : []));
2574
2594
  /**
2575
2595
  * Settings for rendering the snapshot. These are passed to the snapshot rendition
2576
2596
  * component.
@@ -2628,6 +2648,10 @@ class SnapshotEditorComponent {
2628
2648
  this.runToLast();
2629
2649
  }, 0);
2630
2650
  });
2651
+ // diagnostic logging for multiValuedFeatureIds
2652
+ effect(() => {
2653
+ console.log('[SnapshotEditor] multiValuedFeatureIds:', this.multiValuedFeatureIds());
2654
+ });
2631
2655
  // when rendition element becomes available (conditionally rendered),
2632
2656
  // initialize its settings and event listeners
2633
2657
  effect(() => {
@@ -3216,7 +3240,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.2", ngImpor
3216
3240
  ChainResultViewComponent,
3217
3241
  BaseTextViewComponent,
3218
3242
  FlatLookupPipe,
3219
- MatDialogClose
3220
3243
  ], schemas: [CUSTOM_ELEMENTS_SCHEMA], 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 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>content_copy</mat-icon>\r\n </button>\r\n\r\n <!-- remove ops -->\r\n <button\r\n type=\"button\"\r\n class=\"mat-warn\"\r\n mat-flat-button\r\n matTooltip=\"Remove all the operations\"\r\n [disabled]=\"!operations.value.length || busy()\"\r\n (click)=\"clearOperations()\"\r\n >\r\n <mat-icon>delete_forever</mat-icon> clear\r\n </button>\r\n\r\n <!-- batch add ops -->\r\n <button\r\n type=\"button\"\r\n mat-flat-button\r\n matTooltip=\"Add a batch of operations\"\r\n class=\"mat-primary\"\r\n [disabled]=\"busy()\"\r\n (click)=\"parseOperations()\"\r\n >\r\n <mat-icon>post_add</mat-icon> batch\r\n </button>\r\n\r\n <!-- add op -->\r\n <button\r\n type=\"button\"\r\n mat-flat-button\r\n class=\"mat-primary\"\r\n [disabled]=\"!baseText.value\"\r\n (click)=\"editNewOperation()\"\r\n matTooltip=\"Add a new operation\"\r\n >\r\n <mat-icon>add_circle</mat-icon> operation\r\n </button>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <!-- ops -->\r\n <div id=\"ops\">\r\n <!-- operations list -->\r\n @if (operations.value.length) {\r\n <table id=\"list\">\r\n <thead>\r\n <tr>\r\n <th>nr.</th>\r\n <th></th>\r\n <th>ID</th>\r\n <th>type</th>\r\n <th>at</th>\r\n <th>run</th>\r\n <th>value</th>\r\n <th>itag</th>\r\n <th>otag</th>\r\n <th>gid</th>\r\n <th>feats</th>\r\n </tr>\r\n </thead>\r\n <tbody>\r\n @for (\r\n operation of operations.value;\r\n track operation.id;\r\n let index = $index\r\n ) {\r\n <tr\r\n [class.selected]=\"operation.id === resultOperationId()\"\r\n [class.edited]=\"operation.id === editedOp()?.id\"\r\n >\r\n <td class=\"fit-width\">{{ index + 1 }}.</td>\r\n <td class=\"fit-width\">\r\n <!-- edit -->\r\n <button\r\n type=\"button\"\r\n mat-icon-button\r\n class=\"mat-primary\"\r\n (click)=\"editOperation(index)\"\r\n matTooltip=\"Edit operation\"\r\n >\r\n <mat-icon>edit</mat-icon>\r\n </button>\r\n <!-- delete -->\r\n <button\r\n type=\"button\"\r\n mat-icon-button\r\n class=\"mat-warn\"\r\n (click)=\"deleteOperation(index)\"\r\n matTooltip=\"Delete operation\"\r\n >\r\n <mat-icon class=\"mat-warn\">delete</mat-icon>\r\n </button>\r\n <!-- run to -->\r\n <button\r\n type=\"button\"\r\n mat-icon-button\r\n class=\"mat-accent\"\r\n (click)=\"runTo(index)\"\r\n matTooltip=\"Run to this operation\"\r\n >\r\n <mat-icon class=\"mat-accent\">subscriptions</mat-icon>\r\n </button>\r\n <!-- duplicate -->\r\n <button\r\n type=\"button\"\r\n mat-icon-button\r\n (click)=\"duplicateOperation(index)\"\r\n matTooltip=\"Duplicate operation\"\r\n >\r\n <mat-icon>control_point_duplicate</mat-icon>\r\n </button>\r\n <!-- move up -->\r\n <button\r\n type=\"button\"\r\n mat-icon-button\r\n (click)=\"moveOperationUp(index)\"\r\n matTooltip=\"Move operation up\"\r\n [disabled]=\"index === 0\"\r\n >\r\n <mat-icon>arrow_circle_up</mat-icon>\r\n </button>\r\n <!-- move down -->\r\n <button\r\n type=\"button\"\r\n mat-icon-button\r\n (click)=\"moveOperationDown(index)\"\r\n matTooltip=\"Move operation down\"\r\n [disabled]=\"index === operations.value.length - 1\"\r\n >\r\n <mat-icon>arrow_circle_down</mat-icon>\r\n </button>\r\n </td>\r\n <td>{{ operation.id }}</td>\r\n <td>{{ operation.type | flatLookup: opTypeMap }}</td>\r\n <td>{{ operation.at }}</td>\r\n <td>{{ operation.run }}</td>\r\n <td>{{ operation.value }}</td>\r\n <td>{{ operation.inputTag }}</td>\r\n <td>{{ operation.outputTag }}</td>\r\n <td>{{ operation.groupId }}</td>\r\n <td>\r\n @if (operation.features?.length) {\r\n @if (featDetails.value) {\r\n <div class=\"form-row\">\r\n @for (\r\n feat of operation.features;\r\n track $index;\r\n let i = $index\r\n ) {\r\n <div class=\"feature\">\r\n <span class=\"fname\">{{\r\n feat.name\r\n | flatLookup\r\n : featureDefs()?.names\r\n : \"id\"\r\n : \"label\"\r\n }}</span\r\n >=<span class=\"fvalue\">{{\r\n feat.value\r\n | flatLookup\r\n : featureDefs()?.values?.[feat.name]\r\n : \"id\"\r\n : \"label\"\r\n }}</span>\r\n </div>\r\n }\r\n </div>\r\n } @else {\r\n {{ operation.features?.length }}\r\n }\r\n }\r\n </td>\r\n </tr>\r\n }\r\n </tbody>\r\n </table>\r\n }\r\n\r\n <!-- operation editor -->\r\n @if (editedOp()) {\r\n <mat-expansion-panel\r\n [expanded]=\"editedOp()\"\r\n [disabled]=\"!editedOp()\"\r\n >\r\n <mat-expansion-panel-header>\r\n <mat-panel-title\r\n >operation {{ editedOp()?.id }}</mat-panel-title\r\n >\r\n </mat-expansion-panel-header>\r\n <fieldset>\r\n <gve-chain-operation-editor\r\n [featureDefs]=\"featureDefs()\"\r\n [multiValuedFeatureIds]=\"multiValuedFeatureIds()\"\r\n [hidePreview]=\"editedOpIndex() === -1\"\r\n [operation]=\"editedOp()\"\r\n [rangePatch]=\"editedOpRangePatch()\"\r\n (operationCancel)=\"onOperationCancel()\"\r\n (operationChange)=\"onOperationChange($event)\"\r\n (operationPreview)=\"onOperationPreview($event)\"\r\n />\r\n </fieldset>\r\n </mat-expansion-panel>\r\n }\r\n </div>\r\n </div>\r\n </mat-tab>\r\n </mat-tab-group>\r\n\r\n <!-- progress -->\r\n <div>\r\n @if (busy()) {\r\n <mat-progress-bar mode=\"indeterminate\" />\r\n }\r\n </div>\r\n\r\n <!-- result -->\r\n @if (result()) {\r\n <fieldset id=\"result\">\r\n <legend>result</legend>\r\n <gve-chain-result-view\r\n [result]=\"result()!\"\r\n [initialStepIndex]=\"initialStepIndex()\"\r\n [disabledRangePick]=\"editedOp() ? false : true\"\r\n (stepPick)=\"onStepPick($event)\"\r\n (rangePick)=\"onRangePick($event, true)\"\r\n />\r\n </fieldset>\r\n }\r\n\r\n <!-- snapshot view -->\r\n @if (result()) {\r\n <div id=\"preview\">\r\n <gve-snapshot-rendition #rendition class=\"rendition\">\r\n </gve-snapshot-rendition>\r\n </div>\r\n }\r\n\r\n <!--buttons -->\r\n <div class=\"form-row-center\">\r\n <button\r\n type=\"button\"\r\n class=\"mat-warn\"\r\n mat-flat-button\r\n matTooltip=\"Discard changes\"\r\n (click)=\"close()\"\r\n >\r\n <mat-icon>clear</mat-icon>\r\n close\r\n </button>\r\n @if (!noSave()) {\r\n <button\r\n type=\"submit\"\r\n class=\"mat-primary\"\r\n mat-flat-button\r\n matTooltip=\"Save changes\"\r\n [disabled]=\"form.invalid\"\r\n >\r\n <mat-icon>check_circle</mat-icon>\r\n save\r\n </button>\r\n }\r\n </div>\r\n</form>\r\n", styles: [".form-row{display:flex;gap:8px;align-items:center;flex-wrap:wrap}.form-row-center{display:flex;gap:8px;align-items:center;justify-content:center;flex-wrap:wrap}.form-row,.form-row-center *{flex:0 0 auto}.form-row .right{margin-left:auto}.button-row{display:flex;align-items:center;flex-wrap:wrap}.button-row *{flex:0 0 auto}.long-text{width:100%;max-width:800px}#text-range{margin:8px;border:1px solid silver;border-radius:6px;padding:6px}mat-expansion-panel{margin:8px 0}div#visual-info{font-size:95%;color:#909090;margin:8px}#result{max-height:800px;overflow:auto}#list{margin:8px 0}#opStyle{margin-top:8px}table{width:100%;border-collapse:collapse}th{color:#909090;font-weight:400;text-align:left;background-color:#e1e0e0}th,td{padding:4px;border-bottom:1px solid silver}tbody tr:nth-child(2n){background-color:#e8e8e8}td.fit-width{width:1px;white-space:nowrap}tr.selected{background-color:#c8d9eb}tr.edited{background-color:#f6f6e4}fieldset{border:1px solid silver;border-radius:6px;padding:8px;margin:8px 0}legend{color:#909090}.error{color:red}.input-nr{width:6em}.full-width{width:100%}.code{font-family:Courier New,Courier,monospace}.boxed{border:1px solid silver;border-radius:6px;padding:8px;margin:8px 0}span.label{margin-left:8px}.feature,.fname{color:silver}.fvalue{color:#fff;background-color:#b5bdc9;padding:2px 4px;border-radius:4px}gve-animation-timeline-set{margin:8px 0}div#image{display:grid;gap:8px;grid-template-rows:auto;grid-template-columns:1fr auto;grid-template-areas:\"image-ctl image-view\"}div#image-ctl{grid-area:image-ctl}div#image-view{grid-area:image-view}div#chain-view{margin-bottom:8px}#preview{margin:8px 0}.rendition{display:block;width:100%;min-height:600px;max-height:80vh;border:1px solid #ccc;overflow:auto}@media only screen and (max-width:959px){div#image{grid-template-columns:1fr;grid-template-areas:\"image-ctl\" \"image-view\"}}\n"] }]
3221
3244
  }], 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 }] }], 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 }] }], renditionSettings: [{ type: i0.Input, args: [{ isSignal: true, alias: "renditionSettings", required: false }] }], snapshotCancel: [{ type: i0.Output, args: ["snapshotCancel"] }] } });
3222
3245