@myrmidon/cadmus-thesaurus-store 0.0.3 → 0.0.4

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
@@ -109,6 +109,10 @@ An editable paged tree browser for thesaurus entries. Editing happens in memory
109
109
 
110
110
  ## History
111
111
 
112
+ ### 0.0.4
113
+
114
+ - 2026-01-31: added logging to thesaurus tree browser to diagnose issues in certain scenarios.
115
+
112
116
  ### 0.0.3
113
117
 
114
118
  - 2026-01-31: fixes to thesaurus browser and editable thesaurus browser. The ThesaurusTreeComponent wasn't updating when data arrived because of an Angular effect timing issue:
@@ -124,7 +128,7 @@ Solution: added ChangeDetectorRef.markForCheck() calls in the subscription callb
124
128
 
125
129
  The fix needed to address:
126
130
 
127
- Signal writes inside effect execution: When subscribing to a BehaviorSubject inside an effect(), the subscription callback executes synchronously (BehaviorSubject emits its current value immediately on subscribe). This means signal writes like this.nodes.set(nodes) occur during the effect's execution, which requires { allowSignalWrites: true }.
131
+ Signal writes inside effect execution: When subscribing to a BehaviorSubject inside an effect(), the subscription callback executes synchronously (BehaviorSubject emits its current value immediately on subscribe). This means signal writes like this.nodes.set(nodes) occur during the effect's execution.
128
132
 
129
133
  Inconsistent markForCheck() calls: The original fix only added markForCheck() in the effect's subscriptions and the initial load's .finally(), but left other async callbacks (expand, collapse, page change, filter change) without it.
130
134
 
@@ -262,8 +262,6 @@ class EditableThesaurusBrowserComponent {
262
262
  label: this.label,
263
263
  });
264
264
  // Use effect to react to service/store changes.
265
- // allowSignalWrites is required because we update signals from subscription callbacks
266
- // that execute synchronously (BehaviorSubject emits immediately on subscribe).
267
265
  effect(() => {
268
266
  const currentStore = this.store();
269
267
  const currentService = this.service();
@@ -301,7 +299,7 @@ class EditableThesaurusBrowserComponent {
301
299
  this._cdr.markForCheck();
302
300
  });
303
301
  }
304
- }, { allowSignalWrites: true });
302
+ });
305
303
  }
306
304
  ngOnDestroy() {
307
305
  this._nodesSub?.unsubscribe();
@@ -725,7 +723,9 @@ class StaticThesaurusPagedTreeStoreService {
725
723
  * @param hasMockRoot Whether the root node is a mock node. Not used here.
726
724
  */
727
725
  getNodes(filter, pageNumber, pageSize, hasMockRoot) {
726
+ console.log('[StaticThesaurusService] getNodes called, entries count:', this._entries.length, 'filter:', filter);
728
727
  this.ensureNodes();
728
+ console.log('[StaticThesaurusService] after ensureNodes, _nodes count:', this._nodes.length);
729
729
  // apply filtering
730
730
  let nodes = this._nodes.filter((n) => {
731
731
  // filter by parentId (required by tree structure)
@@ -750,6 +750,7 @@ class StaticThesaurusPagedTreeStoreService {
750
750
  });
751
751
  // page and return
752
752
  const paged = nodes.slice((pageNumber - 1) * pageSize, pageNumber * pageSize);
753
+ console.log('[StaticThesaurusService] getNodes returning', paged.length, 'items (filtered from', nodes.length, 'total root nodes)');
753
754
  return of({
754
755
  items: paged,
755
756
  pageNumber: pageNumber,
@@ -802,10 +803,9 @@ class ThesaurusBrowserComponent {
802
803
  label: this.label,
803
804
  });
804
805
  // Use effect to react to service/store changes.
805
- // allowSignalWrites is required because we update signals from subscription callbacks
806
- // that execute synchronously (BehaviorSubject emits immediately on subscribe).
807
806
  effect(() => {
808
807
  const currentStore = this.store();
808
+ console.log('[ThesaurusBrowser] effect triggered, store:', currentStore ? 'exists' : 'null');
809
809
  // Unsubscribe from previous store's observables
810
810
  this._nodesSub?.unsubscribe();
811
811
  this._filterSub?.unsubscribe();
@@ -814,22 +814,34 @@ class ThesaurusBrowserComponent {
814
814
  // Angular's reactive context, and some Angular apps use OnPush change
815
815
  // detection or zoneless mode.
816
816
  this._nodesSub = currentStore.nodes$.subscribe((nodes) => {
817
+ console.log('[ThesaurusBrowser] nodes$ emitted, count:', nodes.length, 'nodes:', nodes.map((n) => n.label).slice(0, 3));
817
818
  this.nodes.set(nodes);
819
+ console.log('[ThesaurusBrowser] nodes signal set, calling markForCheck');
818
820
  this._cdr.markForCheck();
819
821
  });
820
822
  this._filterSub = currentStore.filter$.subscribe((filter) => {
823
+ console.log('[ThesaurusBrowser] filter$ emitted:', filter);
821
824
  this.filter.set(filter);
822
825
  this._cdr.markForCheck();
823
826
  });
824
827
  // Load nodes if store is empty
825
- if (!currentStore.getNodes().length) {
828
+ const storeNodes = currentStore.getNodes();
829
+ console.log('[ThesaurusBrowser] store.getNodes() count:', storeNodes.length);
830
+ if (!storeNodes.length) {
831
+ console.log('[ThesaurusBrowser] store is empty, calling setFilter to load');
826
832
  this.loading.set(true);
827
- currentStore.setFilter({}).finally(() => {
833
+ currentStore
834
+ .setFilter({})
835
+ .then(() => {
836
+ console.log('[ThesaurusBrowser] setFilter resolved, store nodes:', currentStore.getNodes().length);
837
+ })
838
+ .finally(() => {
839
+ console.log('[ThesaurusBrowser] setFilter finally, setting loading=false');
828
840
  this.loading.set(false);
829
841
  this._cdr.markForCheck();
830
842
  });
831
843
  }
832
- }, { allowSignalWrites: true });
844
+ });
833
845
  }
834
846
  ngOnDestroy() {
835
847
  this._nodesSub?.unsubscribe();
@@ -973,12 +985,29 @@ class ThesaurusTreeComponent {
973
985
  */
974
986
  this.service = computed(() => {
975
987
  const entries = this.entries();
988
+ console.log('[ThesaurusTree] service computed, entries count:', entries?.length ?? 0);
976
989
  return new StaticThesaurusPagedTreeStoreService(entries || [], this.renderLabel());
977
990
  }, ...(ngDevMode ? [{ debugName: "service" }] : []));
991
+ /**
992
+ * Debug: tracks when the template condition would show the browser.
993
+ */
994
+ this.shouldShowBrowser = computed(() => {
995
+ const svc = this.service();
996
+ const entries = this.entries();
997
+ const result = !!(svc && entries?.length);
998
+ console.log('[ThesaurusTree] shouldShowBrowser computed:', result, '(service:', !!svc, ', entries:', entries?.length ?? 0, ')');
999
+ return result;
1000
+ }, ...(ngDevMode ? [{ debugName: "shouldShowBrowser" }] : []));
978
1001
  /**
979
1002
  * The filter component class to use.
980
1003
  */
981
1004
  this.filterComponent = ThesaurusPagedTreeFilterComponent;
1005
+ // Debug effect to trace when entries input changes
1006
+ effect(() => {
1007
+ const entries = this.entries();
1008
+ const svc = this.service();
1009
+ console.log('[ThesaurusTree] effect: entries changed, count:', entries?.length ?? 0, 'service:', svc ? 'exists' : 'null');
1010
+ });
982
1011
  }
983
1012
  onNodePick(node) {
984
1013
  // only allow selection of leaf nodes (nodes without children)
@@ -991,12 +1020,12 @@ class ThesaurusTreeComponent {
991
1020
  }
992
1021
  }
993
1022
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: ThesaurusTreeComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
994
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.0", type: ThesaurusTreeComponent, isStandalone: true, selector: "cadmus-thesaurus-tree", inputs: { entries: { classPropertyName: "entries", publicName: "entries", isSignal: true, isRequired: false, transformFunction: null }, renderLabel: { classPropertyName: "renderLabel", publicName: "renderLabel", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { entryChange: "entryChange" }, ngImport: i0, template: "<div>\r\n <!-- tree -->\r\n @if (service() && entries()?.length) {\r\n <div class=\"tree-wrapper\">\r\n <cadmus-thesaurus-browser\r\n [service]=\"service()\"\r\n (nodePick)=\"onNodePick($event)\"\r\n />\r\n </div>\r\n }\r\n</div>\r\n", styles: [".th-tree-progress-bar{margin-left:30px}.th-tree-nested-node{padding-left:30px}mat-tree{margin-left:40px}.mat-tree-node{padding:0;background-color:#fff}.mat-nested-tree-node{top:-24px}ul,li{list-style:none;margin:0;padding:0}li.th-tree-container{border-bottom:0}ul{padding-left:40px}li{padding-left:40px;border:1px dotted grey;border-width:0 0 1px 1px;position:relative;top:-24px}li.mat-tree-node,li div{margin:0;position:relative;top:24px}li ul{border-top:1px dotted grey;margin-left:-40px;padding-left:60px}.mat-nested-tree-node:last-child ul{border-left:1px solid white;margin-left:-41px}.mat-mdc-icon-button{z-index:100}span.found-count{margin:0 4px;padding:2px 4px;color:#fff;background-color:#0cc078;border-radius:6px}span.not-found-count{margin:0 4px;padding:2px 4px;color:#fff;background-color:#fb6962;border-radius:6px}.hilite{background-color:#fdfd96}.filter-field{width:100%;margin-bottom:1rem}.tree-container{border:1px solid #e0e0e0;border-radius:4px;overflow:auto;max-height:500px}.tree-wrapper{border:1px solid #e0e0e0;border-radius:4px;overflow:hidden;background:#fff}.no-entries{text-align:center;padding:2rem;color:#666;font-style:italic;border:1px solid #e0e0e0;border-radius:4px;background:#f9f9f9}.no-entries p{margin:0}\n"], dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "component", type: ThesaurusBrowserComponent, selector: "cadmus-thesaurus-browser", inputs: ["service"], outputs: ["nodePick"] }] }); }
1023
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.0", type: ThesaurusTreeComponent, isStandalone: true, selector: "cadmus-thesaurus-tree", inputs: { entries: { classPropertyName: "entries", publicName: "entries", isSignal: true, isRequired: false, transformFunction: null }, renderLabel: { classPropertyName: "renderLabel", publicName: "renderLabel", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { entryChange: "entryChange" }, ngImport: i0, template: "<div>\r\n <!-- tree -->\r\n @if (shouldShowBrowser()) {\r\n <div class=\"tree-wrapper\">\r\n <cadmus-thesaurus-browser\r\n [service]=\"service()\"\r\n (nodePick)=\"onNodePick($event)\"\r\n />\r\n </div>\r\n }\r\n</div>\r\n", styles: [".th-tree-progress-bar{margin-left:30px}.th-tree-nested-node{padding-left:30px}mat-tree{margin-left:40px}.mat-tree-node{padding:0;background-color:#fff}.mat-nested-tree-node{top:-24px}ul,li{list-style:none;margin:0;padding:0}li.th-tree-container{border-bottom:0}ul{padding-left:40px}li{padding-left:40px;border:1px dotted grey;border-width:0 0 1px 1px;position:relative;top:-24px}li.mat-tree-node,li div{margin:0;position:relative;top:24px}li ul{border-top:1px dotted grey;margin-left:-40px;padding-left:60px}.mat-nested-tree-node:last-child ul{border-left:1px solid white;margin-left:-41px}.mat-mdc-icon-button{z-index:100}span.found-count{margin:0 4px;padding:2px 4px;color:#fff;background-color:#0cc078;border-radius:6px}span.not-found-count{margin:0 4px;padding:2px 4px;color:#fff;background-color:#fb6962;border-radius:6px}.hilite{background-color:#fdfd96}.filter-field{width:100%;margin-bottom:1rem}.tree-container{border:1px solid #e0e0e0;border-radius:4px;overflow:auto;max-height:500px}.tree-wrapper{border:1px solid #e0e0e0;border-radius:4px;overflow:hidden;background:#fff}.no-entries{text-align:center;padding:2rem;color:#666;font-style:italic;border:1px solid #e0e0e0;border-radius:4px;background:#f9f9f9}.no-entries p{margin:0}\n"], dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "component", type: ThesaurusBrowserComponent, selector: "cadmus-thesaurus-browser", inputs: ["service"], outputs: ["nodePick"] }] }); }
995
1024
  }
996
1025
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: ThesaurusTreeComponent, decorators: [{
997
1026
  type: Component,
998
- args: [{ selector: 'cadmus-thesaurus-tree', imports: [FormsModule, ReactiveFormsModule, ThesaurusBrowserComponent], template: "<div>\r\n <!-- tree -->\r\n @if (service() && entries()?.length) {\r\n <div class=\"tree-wrapper\">\r\n <cadmus-thesaurus-browser\r\n [service]=\"service()\"\r\n (nodePick)=\"onNodePick($event)\"\r\n />\r\n </div>\r\n }\r\n</div>\r\n", styles: [".th-tree-progress-bar{margin-left:30px}.th-tree-nested-node{padding-left:30px}mat-tree{margin-left:40px}.mat-tree-node{padding:0;background-color:#fff}.mat-nested-tree-node{top:-24px}ul,li{list-style:none;margin:0;padding:0}li.th-tree-container{border-bottom:0}ul{padding-left:40px}li{padding-left:40px;border:1px dotted grey;border-width:0 0 1px 1px;position:relative;top:-24px}li.mat-tree-node,li div{margin:0;position:relative;top:24px}li ul{border-top:1px dotted grey;margin-left:-40px;padding-left:60px}.mat-nested-tree-node:last-child ul{border-left:1px solid white;margin-left:-41px}.mat-mdc-icon-button{z-index:100}span.found-count{margin:0 4px;padding:2px 4px;color:#fff;background-color:#0cc078;border-radius:6px}span.not-found-count{margin:0 4px;padding:2px 4px;color:#fff;background-color:#fb6962;border-radius:6px}.hilite{background-color:#fdfd96}.filter-field{width:100%;margin-bottom:1rem}.tree-container{border:1px solid #e0e0e0;border-radius:4px;overflow:auto;max-height:500px}.tree-wrapper{border:1px solid #e0e0e0;border-radius:4px;overflow:hidden;background:#fff}.no-entries{text-align:center;padding:2rem;color:#666;font-style:italic;border:1px solid #e0e0e0;border-radius:4px;background:#f9f9f9}.no-entries p{margin:0}\n"] }]
999
- }], propDecorators: { entries: [{ type: i0.Input, args: [{ isSignal: true, alias: "entries", required: false }] }], renderLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "renderLabel", required: false }] }], entryChange: [{ type: i0.Output, args: ["entryChange"] }] } });
1027
+ args: [{ selector: 'cadmus-thesaurus-tree', imports: [FormsModule, ReactiveFormsModule, ThesaurusBrowserComponent], template: "<div>\r\n <!-- tree -->\r\n @if (shouldShowBrowser()) {\r\n <div class=\"tree-wrapper\">\r\n <cadmus-thesaurus-browser\r\n [service]=\"service()\"\r\n (nodePick)=\"onNodePick($event)\"\r\n />\r\n </div>\r\n }\r\n</div>\r\n", styles: [".th-tree-progress-bar{margin-left:30px}.th-tree-nested-node{padding-left:30px}mat-tree{margin-left:40px}.mat-tree-node{padding:0;background-color:#fff}.mat-nested-tree-node{top:-24px}ul,li{list-style:none;margin:0;padding:0}li.th-tree-container{border-bottom:0}ul{padding-left:40px}li{padding-left:40px;border:1px dotted grey;border-width:0 0 1px 1px;position:relative;top:-24px}li.mat-tree-node,li div{margin:0;position:relative;top:24px}li ul{border-top:1px dotted grey;margin-left:-40px;padding-left:60px}.mat-nested-tree-node:last-child ul{border-left:1px solid white;margin-left:-41px}.mat-mdc-icon-button{z-index:100}span.found-count{margin:0 4px;padding:2px 4px;color:#fff;background-color:#0cc078;border-radius:6px}span.not-found-count{margin:0 4px;padding:2px 4px;color:#fff;background-color:#fb6962;border-radius:6px}.hilite{background-color:#fdfd96}.filter-field{width:100%;margin-bottom:1rem}.tree-container{border:1px solid #e0e0e0;border-radius:4px;overflow:auto;max-height:500px}.tree-wrapper{border:1px solid #e0e0e0;border-radius:4px;overflow:hidden;background:#fff}.no-entries{text-align:center;padding:2rem;color:#666;font-style:italic;border:1px solid #e0e0e0;border-radius:4px;background:#f9f9f9}.no-entries p{margin:0}\n"] }]
1028
+ }], ctorParameters: () => [], propDecorators: { entries: [{ type: i0.Input, args: [{ isSignal: true, alias: "entries", required: false }] }], renderLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "renderLabel", required: false }] }], entryChange: [{ type: i0.Output, args: ["entryChange"] }] } });
1000
1029
 
1001
1030
  /**
1002
1031
  * The prefix added to custom entries' IDs.
@@ -1 +1 @@
1
- {"version":3,"file":"myrmidon-cadmus-thesaurus-store.mjs","sources":["../../../../projects/myrmidon/cadmus-thesaurus-store/src/lib/components/thesaurus-paged-tree-filter/thesaurus-paged-tree-filter.component.ts","../../../../projects/myrmidon/cadmus-thesaurus-store/src/lib/components/thesaurus-paged-tree-filter/thesaurus-paged-tree-filter.component.html","../../../../projects/myrmidon/cadmus-thesaurus-store/src/lib/components/thesaurus-entry-editor/thesaurus-entry-editor.component.ts","../../../../projects/myrmidon/cadmus-thesaurus-store/src/lib/components/thesaurus-entry-editor/thesaurus-entry-editor.component.html","../../../../projects/myrmidon/cadmus-thesaurus-store/src/lib/components/editable-thesaurus-browser/editable-thesaurus-browser.component.ts","../../../../projects/myrmidon/cadmus-thesaurus-store/src/lib/components/editable-thesaurus-browser/editable-thesaurus-browser.component.html","../../../../projects/myrmidon/cadmus-thesaurus-store/src/lib/services/static-thesaurus-paged-tree-store.service.ts","../../../../projects/myrmidon/cadmus-thesaurus-store/src/lib/components/thesaurus-browser/thesaurus-browser.component.ts","../../../../projects/myrmidon/cadmus-thesaurus-store/src/lib/components/thesaurus-browser/thesaurus-browser.component.html","../../../../projects/myrmidon/cadmus-thesaurus-store/src/lib/components/thesaurus-tree/thesaurus-tree.component.ts","../../../../projects/myrmidon/cadmus-thesaurus-store/src/lib/components/thesaurus-tree/thesaurus-tree.component.html","../../../../projects/myrmidon/cadmus-thesaurus-store/src/lib/components/thesaurus-entries-picker/thesaurus-entries-picker.component.ts","../../../../projects/myrmidon/cadmus-thesaurus-store/src/lib/components/thesaurus-entries-picker/thesaurus-entries-picker.component.html","../../../../projects/myrmidon/cadmus-thesaurus-store/src/lib/services/editable-static-thesaurus-paged-tree-store.service.ts","../../../../projects/myrmidon/cadmus-thesaurus-store/src/public-api.ts","../../../../projects/myrmidon/cadmus-thesaurus-store/src/myrmidon-cadmus-thesaurus-store.ts"],"sourcesContent":["import {\r\n Component,\r\n effect,\r\n inject,\r\n model,\r\n OnInit,\r\n signal,\r\n} from '@angular/core';\r\nimport {\r\n FormBuilder,\r\n FormControl,\r\n FormGroup,\r\n ReactiveFormsModule,\r\n} from '@angular/forms';\r\nimport { MatButtonModule } from '@angular/material/button';\r\nimport { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog';\r\nimport { MatFormFieldModule } from '@angular/material/form-field';\r\nimport { MatIconModule } from '@angular/material/icon';\r\nimport { MatInputModule } from '@angular/material/input';\r\nimport { MatTooltipModule } from '@angular/material/tooltip';\r\n\r\nimport { ThesaurusEntryNodeFilter } from '../../services/static-thesaurus-paged-tree-store.service';\r\n\r\n/**\r\n * A filter to be used for thesaurus paged tree browsers.\r\n */\r\n@Component({\r\n selector: 'cadmus-thesaurus-paged-tree-filter',\r\n imports: [\r\n ReactiveFormsModule,\r\n MatButtonModule,\r\n MatFormFieldModule,\r\n MatInputModule,\r\n MatIconModule,\r\n MatTooltipModule,\r\n ],\r\n templateUrl: './thesaurus-paged-tree-filter.component.html',\r\n styleUrl: './thesaurus-paged-tree-filter.component.css',\r\n})\r\nexport class ThesaurusPagedTreeFilterComponent implements OnInit {\r\n public readonly dialogRef = inject<\r\n MatDialogRef<ThesaurusPagedTreeFilterComponent>\r\n >(MatDialogRef, {\r\n optional: true,\r\n });\r\n public readonly data = inject(MAT_DIALOG_DATA, { optional: true });\r\n\r\n /**\r\n * The filter.\r\n */\r\n public readonly filter = model<ThesaurusEntryNodeFilter | null | undefined>();\r\n\r\n public readonly wrapped = signal<boolean>(false);\r\n\r\n public label: FormControl<string | null>;\r\n public form: FormGroup;\r\n\r\n constructor() {\r\n const formBuilder = inject(FormBuilder);\r\n const data = this.data;\r\n\r\n // form\r\n this.label = formBuilder.control<string | null>(null);\r\n this.form = formBuilder.group({\r\n label: this.label,\r\n });\r\n // bind dialog data if any\r\n if (this.dialogRef) {\r\n this.wrapped.set(true);\r\n if (data) {\r\n this.filter.set(data.filter);\r\n }\r\n } else {\r\n this.wrapped.set(false);\r\n }\r\n\r\n // update form when filter changes\r\n effect(() => {\r\n this.updateForm(this.filter());\r\n });\r\n }\r\n\r\n public ngOnInit(): void {\r\n this.updateForm(this.filter());\r\n }\r\n\r\n private updateForm(filter?: ThesaurusEntryNodeFilter | null): void {\r\n if (!filter) {\r\n this.form.reset();\r\n return;\r\n }\r\n this.label.setValue(filter.label ?? null);\r\n this.form.markAsPristine();\r\n }\r\n\r\n private getFilter(): ThesaurusEntryNodeFilter {\r\n return {\r\n label: this.label.value ?? undefined,\r\n };\r\n }\r\n\r\n public reset(): void {\r\n this.form.reset();\r\n this.filter.set(null);\r\n this.dialogRef?.close(null);\r\n }\r\n\r\n public apply(): void {\r\n const filter = this.getFilter();\r\n this.filter.set(filter);\r\n this.dialogRef?.close(filter);\r\n }\r\n}\r\n","<form\r\n [formGroup]=\"form\"\r\n [style.margin.px]=\"wrapped() ? 16 : 0\"\r\n (submit)=\"apply()\"\r\n>\r\n <div class=\"form-row\">\r\n <!-- label -->\r\n <mat-form-field>\r\n <input matInput placeholder=\"label\" [formControl]=\"label\" />\r\n </mat-form-field>\r\n\r\n <!-- buttons -->\r\n <div class=\"button-row\">\r\n <button\r\n type=\"button\"\r\n mat-icon-button\r\n matTooltip=\"Reset\"\r\n (click)=\"reset()\"\r\n >\r\n <mat-icon class=\"mat-warn\">clear</mat-icon>\r\n </button>\r\n <button\r\n type=\"submit\"\r\n mat-icon-button\r\n matTooltip=\"Apply\"\r\n [disabled]=\"form.invalid\"\r\n >\r\n <mat-icon class=\"mat-primary\">check_circle</mat-icon>\r\n </button>\r\n </div>\r\n </div>\r\n</form>\r\n","import { Component, Inject, input, model, Optional } from '@angular/core';\r\nimport {\r\n FormBuilder,\r\n FormControl,\r\n FormGroup,\r\n ReactiveFormsModule,\r\n Validators,\r\n AbstractControl,\r\n ValidationErrors,\r\n} from '@angular/forms';\r\nimport { MatButtonModule } from '@angular/material/button';\r\nimport {\r\n MatDialogRef,\r\n MAT_DIALOG_DATA,\r\n MatDialogConfig,\r\n} from '@angular/material/dialog';\r\nimport { MatFormFieldModule } from '@angular/material/form-field';\r\nimport { MatIconModule } from '@angular/material/icon';\r\nimport { MatInputModule } from '@angular/material/input';\r\nimport { MatTooltipModule } from '@angular/material/tooltip';\r\n\r\n/**\r\n * An edited thesaurus entry.\r\n */\r\nexport interface EditedThesEntry {\r\n id: string;\r\n value: string;\r\n /**\r\n * True if this entry belongs to a hierarchical thesaurus. When this is true,\r\n * and parentId is set, the parentId field will be used as the prefix for the\r\n * id field when creating a new entry.\r\n */\r\n hierarchical?: boolean;\r\n /**\r\n * The ID of the parent entry, if any.\r\n */\r\n parentId?: string;\r\n /**\r\n * If true, the id field is read-only. This is used when editing an existing\r\n * entry so you cannot change its ID.\r\n */\r\n idLocked?: boolean;\r\n /**\r\n * Function used to check if the given ID exists. This is used when\r\n * creating a new entry to ensure it does not duplicate an existing ID.\r\n * @param id The ID to check.\r\n * @returns True if exists.\r\n */\r\n idExists?: (id: string) => boolean;\r\n}\r\n\r\nexport interface PayloadMatDialogConfig<T> extends MatDialogConfig {\r\n payload?: T;\r\n}\r\n\r\n/**\r\n * A dialog component to edit a thesaurus entry.\r\n */\r\n@Component({\r\n selector: 'cadmus-thesaurus-entry-editor',\r\n imports: [\r\n ReactiveFormsModule,\r\n MatButtonModule,\r\n MatFormFieldModule,\r\n MatIconModule,\r\n MatInputModule,\r\n MatTooltipModule,\r\n ],\r\n templateUrl: './thesaurus-entry-editor.component.html',\r\n styleUrl: './thesaurus-entry-editor.component.scss',\r\n})\r\nexport class ThesEntryEditorComponent {\r\n public readonly entry = model<EditedThesEntry | undefined>();\r\n public wrapped = false;\r\n\r\n public id: FormControl<string>;\r\n public value: FormControl<string>;\r\n public form: FormGroup;\r\n\r\n constructor(\r\n @Optional()\r\n public dialogRef: MatDialogRef<ThesEntryEditorComponent>,\r\n @Optional()\r\n @Inject(MAT_DIALOG_DATA)\r\n public data: PayloadMatDialogConfig<EditedThesEntry>,\r\n formBuilder: FormBuilder\r\n ) {\r\n // bind to data properties if any\r\n if (data) {\r\n this.entry.set(data as EditedThesEntry);\r\n this.wrapped = true;\r\n }\r\n\r\n // custom validator for ID existence\r\n const idExistsValidator = (\r\n control: AbstractControl\r\n ): ValidationErrors | null => {\r\n const entry = this.entry();\r\n if (!entry || entry.idLocked || !entry.idExists) {\r\n return null;\r\n }\r\n const id = control.value?.trim();\r\n if (!id) {\r\n return null;\r\n }\r\n // if editing, allow the current id (do not check against itself)\r\n if (entry.id === id) {\r\n return null;\r\n }\r\n return entry.idExists(id) ? { idExists: true } : null;\r\n };\r\n\r\n // custom validator for hierarchical ID prefix\r\n const hierarchicalIdValidator = (\r\n control: AbstractControl\r\n ): ValidationErrors | null => {\r\n const entry = this.entry();\r\n if (!entry || entry.idLocked || !entry.hierarchical || !entry.parentId) {\r\n return null;\r\n }\r\n const id = control.value?.trim();\r\n if (!id) {\r\n return null;\r\n }\r\n const prefix = entry.parentId + '.';\r\n if (!id.startsWith(prefix) || id.length <= prefix.length) {\r\n return { hierarchicalPrefix: { requiredPrefix: prefix } };\r\n }\r\n return null;\r\n };\r\n\r\n // form controls\r\n this.id = new FormControl<string>((data as EditedThesEntry)?.id || '', {\r\n nonNullable: true,\r\n validators: [\r\n Validators.required,\r\n Validators.maxLength(300),\r\n idExistsValidator,\r\n hierarchicalIdValidator,\r\n ],\r\n });\r\n this.value = new FormControl<string>(\r\n (data as EditedThesEntry)?.value || '',\r\n {\r\n nonNullable: true,\r\n validators: [Validators.required, Validators.maxLength(500)],\r\n }\r\n );\r\n this.form = formBuilder.group({\r\n id: this.id,\r\n value: this.value,\r\n });\r\n }\r\n\r\n cancel(): void {\r\n this.dialogRef?.close();\r\n }\r\n\r\n save(): void {\r\n if (this.form.invalid) {\r\n return;\r\n }\r\n const old = this.entry()!;\r\n\r\n // save data and close the dialog\r\n this.dialogRef?.close({\r\n id: old.idLocked ? old.id : this.id.value?.trim(),\r\n value: this.value.value?.trim(),\r\n } as EditedThesEntry);\r\n }\r\n}\r\n","<form [formGroup]=\"form\" (submit)=\"save()\" [class.wrapped]=\"wrapped\">\r\n <fieldset>\r\n <legend>entry</legend>\r\n <div class=\"form-row\">\r\n <!-- id -->\r\n @if (entry()!.idLocked) {\r\n <span class=\"readonly\">{{ entry()!.id }}</span>\r\n } @else {\r\n <mat-form-field>\r\n <mat-label>ID</mat-label>\r\n <input matInput [formControl]=\"id\" />\r\n @if ($any(id).errors?.required && (id.dirty || id.touched)) {\r\n <mat-error>ID required</mat-error>\r\n } @if ($any(id).errors?.maxLength && (id.dirty || id.touched)) {\r\n <mat-error>ID too long</mat-error>\r\n } @if ($any(id).errors?.idExists && (id.dirty || id.touched)) {\r\n <mat-error>ID already exists</mat-error>\r\n } @if ($any(id).errors?.requiredPrefix && (id.dirty || id.touched)) {\r\n <mat-error>ID must start with \"{{ entry()!.parentId }}.\"</mat-error>\r\n }\r\n <!-- hint -->\r\n @if (entry()?.parentId) {\r\n <mat-hint>parent: {{ entry()!.parentId }}</mat-hint>\r\n }\r\n </mat-form-field>\r\n }\r\n <!-- value -->\r\n <mat-form-field>\r\n <mat-label>value</mat-label>\r\n <input matInput [formControl]=\"value\" />\r\n @if ($any(value).errors?.required && (value.dirty || value.touched)) {\r\n <mat-error>value required</mat-error>\r\n } @if ($any(value).errors?.maxLength && (value.dirty || value.touched))\r\n {\r\n <mat-error>value too long</mat-error>\r\n }\r\n </mat-form-field>\r\n </div>\r\n <!-- buttons -->\r\n <div>\r\n <button\r\n type=\"button\"\r\n mat-icon-button\r\n matTooltip=\"Discard changes\"\r\n (click)=\"cancel()\"\r\n >\r\n <mat-icon class=\"mat-warn\">clear</mat-icon>\r\n </button>\r\n <button\r\n type=\"submit\"\r\n mat-icon-button\r\n matTooltip=\"Accept changes\"\r\n [disabled]=\"form.invalid || form.pristine\"\r\n >\r\n <mat-icon class=\"mat-primary\">check_circle</mat-icon>\r\n </button>\r\n </div>\r\n </fieldset>\r\n</form>\r\n","import {\r\n ChangeDetectorRef,\r\n Component,\r\n OnDestroy,\r\n computed,\r\n effect,\r\n inject,\r\n input,\r\n output,\r\n signal,\r\n} from '@angular/core';\r\nimport { FormControl, FormGroup, ReactiveFormsModule } from '@angular/forms';\r\nimport { Subscription } from 'rxjs';\r\n\r\nimport { MatDialog } from '@angular/material/dialog';\r\nimport { MatProgressBarModule } from '@angular/material/progress-bar';\r\nimport { MatButtonModule } from '@angular/material/button';\r\nimport { MatCheckboxModule } from '@angular/material/checkbox';\r\nimport { MatIconModule } from '@angular/material/icon';\r\nimport { MatTooltipModule } from '@angular/material/tooltip';\r\nimport { MatInputModule } from '@angular/material/input';\r\nimport { MatFormFieldModule } from '@angular/material/form-field';\r\nimport { MatMenuModule } from '@angular/material/menu';\r\nimport { MatSnackBar } from '@angular/material/snack-bar';\r\n\r\nimport { DialogService } from '@myrmidon/ngx-mat-tools';\r\nimport {\r\n BrowserTreeNodeComponent,\r\n PagedTreeStore,\r\n PageChangeRequest,\r\n} from '@myrmidon/paged-data-browsers';\r\n\r\nimport { ThesaurusPagedTreeFilterComponent } from '../thesaurus-paged-tree-filter/thesaurus-paged-tree-filter.component';\r\nimport {\r\n ThesaurusEntryNodeFilter,\r\n ThesaurusEntryPagedTreeNode,\r\n} from '../../services/static-thesaurus-paged-tree-store.service';\r\nimport {\r\n EditedThesEntry,\r\n ThesEntryEditorComponent,\r\n} from '../thesaurus-entry-editor/thesaurus-entry-editor.component';\r\nimport { EditableStaticThesaurusPagedTreeStoreService } from '../../services/editable-static-thesaurus-paged-tree-store.service';\r\n\r\n/**\r\n * An editable paged tree browser for thesaurus entries. Editing happens in memory\r\n * and when complete, the changes can be committed to the underlying data store\r\n * via the EditableStaticThesaurusPagedTreeStoreService.\r\n */\r\n@Component({\r\n selector: 'cadmus-editable-thesaurus-browser',\r\n imports: [\r\n ReactiveFormsModule,\r\n MatButtonModule,\r\n MatCheckboxModule,\r\n MatFormFieldModule,\r\n MatIconModule,\r\n MatInputModule,\r\n MatMenuModule,\r\n MatProgressBarModule,\r\n MatTooltipModule,\r\n ThesaurusPagedTreeFilterComponent,\r\n BrowserTreeNodeComponent,\r\n ],\r\n templateUrl: './editable-thesaurus-browser.component.html',\r\n styleUrls: ['./editable-thesaurus-browser.component.scss'],\r\n})\r\nexport class EditableThesaurusBrowserComponent implements OnDestroy {\r\n private _dialog = inject(MatDialog);\r\n private _snackBar = inject(MatSnackBar);\r\n private _dialogService = inject(DialogService);\r\n private _cdr = inject(ChangeDetectorRef);\r\n private _nodesSub?: Subscription;\r\n private _filterSub?: Subscription;\r\n private _changesSub?: Subscription;\r\n\r\n /**\r\n * The editable service to use to load the nodes.\r\n */\r\n public readonly service =\r\n input<EditableStaticThesaurusPagedTreeStoreService>();\r\n\r\n /**\r\n * True to show the tree root nodes filter.\r\n */\r\n public readonly hasRootFilter = input<boolean>(false);\r\n\r\n /**\r\n * Emitted when a node is clicked.\r\n */\r\n public readonly nodePick = output<ThesaurusEntryPagedTreeNode>();\r\n\r\n /**\r\n * Emitted when the changes state changes.\r\n */\r\n public readonly changesStateChange = output<boolean>();\r\n\r\n /**\r\n * The store instance, built from the service.\r\n */\r\n public readonly store = computed(() => {\r\n const service = this.service();\r\n if (!service) {\r\n return null;\r\n }\r\n return new PagedTreeStore<\r\n ThesaurusEntryPagedTreeNode,\r\n ThesaurusEntryNodeFilter\r\n >(service);\r\n });\r\n\r\n public readonly loading = signal<boolean>(false);\r\n public readonly selectedNode = signal<ThesaurusEntryPagedTreeNode | null>(\r\n null,\r\n );\r\n\r\n // Signals for reactive data binding (replacing observables with async pipe)\r\n public readonly nodes = signal<readonly ThesaurusEntryPagedTreeNode[]>([]);\r\n public readonly filter = signal<Readonly<ThesaurusEntryNodeFilter>>({});\r\n\r\n public debug: FormControl<boolean> = new FormControl(false, {\r\n nonNullable: true,\r\n });\r\n public hideLoc: FormControl<boolean> = new FormControl(false, {\r\n nonNullable: true,\r\n });\r\n public hideFilter: FormControl<boolean> = new FormControl(false, {\r\n nonNullable: true,\r\n });\r\n\r\n public label: FormControl<string | null> = new FormControl(null);\r\n public form = new FormGroup({\r\n label: this.label,\r\n });\r\n\r\n constructor() {\r\n // Use effect to react to service/store changes.\r\n // allowSignalWrites is required because we update signals from subscription callbacks\r\n // that execute synchronously (BehaviorSubject emits immediately on subscribe).\r\n effect(\r\n () => {\r\n const currentStore = this.store();\r\n const currentService = this.service();\r\n\r\n // Cleanup previous subscriptions\r\n this._nodesSub?.unsubscribe();\r\n this._filterSub?.unsubscribe();\r\n this._changesSub?.unsubscribe();\r\n\r\n if (!currentStore || !currentService) {\r\n this.nodes.set([]);\r\n this.filter.set({});\r\n return;\r\n }\r\n\r\n // Subscribe to store's observables and update signals.\r\n // markForCheck() is required because subscription callbacks run outside\r\n // Angular's reactive context, and some Angular apps use OnPush change\r\n // detection or zoneless mode.\r\n this._nodesSub = currentStore.nodes$.subscribe((nodes) => {\r\n this.nodes.set(nodes);\r\n this._cdr.markForCheck();\r\n });\r\n this._filterSub = currentStore.filter$.subscribe((filter) => {\r\n this.filter.set(filter);\r\n this._cdr.markForCheck();\r\n });\r\n\r\n // Subscribe to changes state\r\n this._changesSub = currentService.hasChanges$.subscribe((hasChanges) => {\r\n this.changesStateChange.emit(hasChanges);\r\n this._cdr.markForCheck();\r\n });\r\n\r\n // Load nodes if store is empty\r\n if (!currentStore.getNodes().length) {\r\n this.loading.set(true);\r\n currentStore.setFilter({}).finally(() => {\r\n this.loading.set(false);\r\n this._cdr.markForCheck();\r\n });\r\n }\r\n },\r\n { allowSignalWrites: true }\r\n );\r\n }\r\n\r\n public ngOnDestroy(): void {\r\n this._nodesSub?.unsubscribe();\r\n this._filterSub?.unsubscribe();\r\n this._changesSub?.unsubscribe();\r\n }\r\n\r\n public reset(): void {\r\n const store = this.store();\r\n if (!store) return;\r\n\r\n this.loading.set(true);\r\n store.reset().finally(() => {\r\n this.loading.set(false);\r\n this._cdr.markForCheck();\r\n });\r\n }\r\n\r\n public onToggleExpanded(node: ThesaurusEntryPagedTreeNode): void {\r\n const store = this.store();\r\n if (!store) return;\r\n\r\n this.loading.set(true);\r\n if (node.expanded) {\r\n store.collapse(node.id).finally(() => {\r\n this.loading.set(false);\r\n this._cdr.markForCheck();\r\n });\r\n } else {\r\n store.expand(node.id).finally(() => {\r\n this.loading.set(false);\r\n this._cdr.markForCheck();\r\n });\r\n }\r\n }\r\n\r\n public onPageChangeRequest(request: PageChangeRequest): void {\r\n const store = this.store();\r\n if (!store) return;\r\n\r\n this.loading.set(true);\r\n store.changePage(request.node.id, request.paging.pageNumber).finally(() => {\r\n this.loading.set(false);\r\n this._cdr.markForCheck();\r\n });\r\n }\r\n\r\n public onFilterChange(\r\n filter: ThesaurusEntryNodeFilter | null | undefined,\r\n ): void {\r\n const store = this.store();\r\n if (!store) return;\r\n\r\n console.log('filter change', filter);\r\n this.loading.set(true);\r\n store.setFilter(filter || {}).finally(() => {\r\n this.loading.set(false);\r\n this._cdr.markForCheck();\r\n });\r\n }\r\n\r\n public onEditFilterRequest(node: ThesaurusEntryPagedTreeNode): void {\r\n const store = this.store();\r\n if (!store) return;\r\n\r\n const dialogRef = this._dialog.open(ThesaurusPagedTreeFilterComponent, {\r\n data: {\r\n filter: node.filter,\r\n },\r\n });\r\n dialogRef.afterClosed().subscribe((filter) => {\r\n if (filter === null) {\r\n store.setNodeFilter(node.id, null);\r\n } else if (filter) {\r\n store.setNodeFilter(node.id, filter);\r\n }\r\n });\r\n }\r\n\r\n public expandAll(): void {\r\n const store = this.store();\r\n if (!store) return;\r\n store.expandAll();\r\n }\r\n\r\n public collapseAll(): void {\r\n const store = this.store();\r\n if (!store) return;\r\n store.collapseAll();\r\n }\r\n\r\n public clear(): void {\r\n const store = this.store();\r\n if (!store) return;\r\n store.clear();\r\n }\r\n\r\n public onNodeClick(node: ThesaurusEntryPagedTreeNode): void {\r\n this.selectedNode.set(node);\r\n if (!node.hasChildren) {\r\n this.nodePick.emit(node);\r\n }\r\n }\r\n\r\n public findLabels(): void {\r\n const store = this.store();\r\n if (!store || !this.label.value) return;\r\n store.findLabels(this.label.value);\r\n }\r\n\r\n public removeHilites(): void {\r\n const store = this.store();\r\n if (!store) return;\r\n store.removeHilites();\r\n }\r\n\r\n // editing operations\r\n private editEntry(entry: EditedThesEntry): Promise<EditedThesEntry | null> {\r\n return new Promise((resolve) => {\r\n const dialogRef = this._dialog.open(ThesEntryEditorComponent, {\r\n data: entry,\r\n });\r\n\r\n dialogRef.afterClosed().subscribe((result) => {\r\n resolve(result);\r\n });\r\n });\r\n }\r\n\r\n public async addChild(): Promise<void> {\r\n const store = this.store();\r\n const selected = this.selectedNode();\r\n if (!store || !selected) {\r\n this._snackBar.open('Please select a node first', 'Close', {\r\n duration: 2000,\r\n });\r\n return;\r\n }\r\n\r\n // get the current entries to check for duplicates\r\n const currentService = this.service();\r\n if (!currentService) return;\r\n\r\n // determine the parent ID for the new child\r\n const parentKey = selected.key; // original entry ID\r\n\r\n // edit the new entry\r\n const newEntry = await this.editEntry({\r\n id: '',\r\n value: '',\r\n hierarchical: true,\r\n parentId: parentKey,\r\n idExists: (id: string) =>\r\n currentService.getCurrentEntries().some((e) => e.id === id),\r\n });\r\n if (!newEntry) {\r\n return;\r\n }\r\n\r\n store\r\n .addChild(selected.id, {\r\n label: newEntry.value,\r\n y: 0, // will be calculated by the store\r\n x: 0, // will be calculated by the store\r\n tag: selected.tag,\r\n })\r\n .then((result) => {\r\n if (result) {\r\n // update the temporary node with the user-provided ID,\r\n // this will be handled in the service's nodeToEntry method\r\n (result as any)._userProvidedId = newEntry.id;\r\n this._snackBar.open('Child added successfully', 'Close', {\r\n duration: 2000,\r\n });\r\n }\r\n });\r\n }\r\n\r\n public async addSibling(): Promise<void> {\r\n const store = this.store();\r\n const selected = this.selectedNode();\r\n if (!store || !selected) {\r\n this._snackBar.open('Please select a node first', 'Close', {\r\n duration: 2000,\r\n });\r\n return;\r\n }\r\n\r\n // get the current entries to check for duplicates\r\n const currentService = this.service();\r\n if (!currentService) return;\r\n\r\n const selectedKey = (selected as any).key; // original entry ID\r\n\r\n // determine the parent ID for the new sibling\r\n const selectedParts = selectedKey.split('.');\r\n const parentKey =\r\n selectedParts.length > 1 ? selectedParts.slice(0, -1).join('.') : '';\r\n\r\n const newEntry = await this.editEntry({\r\n id: '',\r\n value: '',\r\n hierarchical: true,\r\n parentId: parentKey,\r\n idExists: (id: string) =>\r\n currentService.getCurrentEntries().some((e) => e.id === id),\r\n });\r\n if (!newEntry) {\r\n return;\r\n }\r\n\r\n // check that the new ID has the same depth\r\n if (newEntry.id.split('.').length !== selectedParts.length) {\r\n this._snackBar.open(\r\n `Sibling must have same depth as \"${selectedKey}\"`,\r\n 'Close',\r\n { duration: 3000 },\r\n );\r\n return;\r\n }\r\n\r\n store\r\n .addSibling(selected.id, {\r\n label: newEntry.value,\r\n tag: selected.tag,\r\n })\r\n .then((result) => {\r\n if (result) {\r\n // update the temporary node with the user-provided ID\r\n (result as any)._userProvidedId = newEntry.id;\r\n this._snackBar.open('Sibling added successfully', 'Close', {\r\n duration: 2000,\r\n });\r\n }\r\n });\r\n }\r\n\r\n public removeNode(): void {\r\n const store = this.store();\r\n const selected = this.selectedNode();\r\n if (!store || !selected) {\r\n this._snackBar.open('Please select a node first', 'Close', {\r\n duration: 2000,\r\n });\r\n return;\r\n }\r\n\r\n const selectedKey = (selected as any).key || `temp_${selected.id}`;\r\n this._dialogService\r\n .confirm(\r\n 'Confirm Deletion',\r\n `Delete \"${selectedKey}\" (${selected.label}) and all its descendants?`,\r\n )\r\n .subscribe((result) => {\r\n if (!result) {\r\n return;\r\n }\r\n store.removeNode(selected.id).then((result) => {\r\n if (result) {\r\n this.selectedNode.set(null);\r\n this._snackBar.open('Node removed successfully', 'Close', {\r\n duration: 2000,\r\n });\r\n }\r\n });\r\n });\r\n }\r\n\r\n public async editNode(): Promise<void> {\r\n const currentService = this.service();\r\n if (!currentService) return;\r\n\r\n const store = this.store();\r\n const selected = this.selectedNode();\r\n if (!store || !selected) {\r\n this._snackBar.open('Please select a node first', 'Close', {\r\n duration: 2000,\r\n });\r\n return;\r\n }\r\n\r\n const selectedKey = selected.key;\r\n const isNewNode = selected.id < 0; // temporary ID means it's a new node\r\n\r\n const newEntry = await this.editEntry({\r\n id: selectedKey || '',\r\n value: selected.label,\r\n idLocked: !isNewNode,\r\n idExists: (id: string) =>\r\n currentService.getCurrentEntries().some((entry) => entry.id === id),\r\n });\r\n if (!newEntry) return;\r\n\r\n store\r\n .replaceNode(selected.id, {\r\n label: newEntry.value,\r\n tag: selected.tag,\r\n })\r\n .then((result) => {\r\n if (result) {\r\n // update the temporary node with the user-provided ID if it's a new node\r\n if (isNewNode) {\r\n (result as any)._userProvidedId = newEntry.id;\r\n }\r\n this._snackBar.open('Node updated successfully', 'Close', {\r\n duration: 2000,\r\n });\r\n }\r\n });\r\n }\r\n}\r\n","<div id=\"container\">\r\n <!-- filters -->\r\n <div id=\"filters\" class=\"form-row\">\r\n <form [formGroup]=\"form\" (submit)=\"findLabels()\">\r\n <fieldset>\r\n <legend>finder</legend>\r\n <div class=\"form-row\">\r\n <mat-form-field>\r\n <mat-label>label</mat-label>\r\n <input matInput [formControl]=\"label\" />\r\n @if ($any(label).errors?.required && (label.dirty || label.touched))\r\n {\r\n <mat-error>label required</mat-error>\r\n }\r\n </mat-form-field>\r\n <div class=\"form-row\" style=\"gap: 0\">\r\n <button type=\"submit\" mat-icon-button class=\"mat-primary\">\r\n <mat-icon>search</mat-icon>\r\n </button>\r\n <button\r\n type=\"button\"\r\n mat-icon-button\r\n (click)=\"removeHilites()\"\r\n class=\"mat-warn\"\r\n >\r\n <mat-icon>clear</mat-icon>\r\n </button>\r\n </div>\r\n </div>\r\n </fieldset>\r\n </form>\r\n @if (hasRootFilter()) {\r\n <fieldset>\r\n <legend>global filter</legend>\r\n <cadmus-thesaurus-paged-tree-filter\r\n [filter]=\"filter()\"\r\n (filterChange)=\"onFilterChange($event)\"\r\n />\r\n </fieldset>\r\n }\r\n </div>\r\n\r\n <!-- editing actions -->\r\n <div class=\"editing-actions\">\r\n <button\r\n type=\"button\"\r\n mat-raised-button\r\n color=\"primary\"\r\n [disabled]=\"!selectedNode()\"\r\n [matMenuTriggerFor]=\"addMenu\"\r\n >\r\n <mat-icon>add</mat-icon>\r\n add\r\n </button>\r\n\r\n <mat-menu #addMenu=\"matMenu\">\r\n <button type=\"button\" mat-menu-item (click)=\"addChild()\">\r\n <mat-icon>subdirectory_arrow_right</mat-icon>\r\n add child\r\n </button>\r\n <button type=\"button\" mat-menu-item (click)=\"addSibling()\">\r\n <mat-icon>arrow_right_alt</mat-icon>\r\n add sibling\r\n </button>\r\n </mat-menu>\r\n\r\n <button\r\n type=\"button\"\r\n mat-stroked-button\r\n color=\"accent\"\r\n [disabled]=\"!selectedNode()\"\r\n (click)=\"editNode()\"\r\n >\r\n <mat-icon>edit</mat-icon>\r\n edit\r\n </button>\r\n\r\n <button\r\n type=\"button\"\r\n mat-stroked-button\r\n color=\"warn\"\r\n [disabled]=\"!selectedNode()\"\r\n (click)=\"removeNode()\"\r\n >\r\n <mat-icon>delete</mat-icon>\r\n remove\r\n </button>\r\n\r\n @if (selectedNode()) {\r\n <span class=\"selected-info\"> selected: {{ selectedNode()!.label }} </span>\r\n }\r\n </div>\r\n\r\n <!-- tree -->\r\n <div id=\"tree\">\r\n <!-- progress -->\r\n @if (loading()) {\r\n <div>\r\n <mat-progress-bar mode=\"indeterminate\"></mat-progress-bar>\r\n </div>\r\n }\r\n <!-- nodes -->\r\n @if (nodes(); as nodeList) {\r\n <div>\r\n @for (node of nodeList; track node.id; let i = $index) {\r\n <div\r\n class=\"button-row\"\r\n [class.hilite]=\"node.hilite\"\r\n [class.selected]=\"selectedNode()?.id === node.id\"\r\n (click)=\"onNodeClick(node)\"\r\n >\r\n <pdb-browser-tree-node\r\n [node]=\"node\"\r\n [debug]=\"debug.value\"\r\n [paging]=\"\r\n node.expanded &&\r\n i + 1 < nodeList.length &&\r\n nodeList[i + 1].paging.pageCount > 1\r\n ? nodeList[i + 1].paging\r\n : undefined\r\n \"\r\n [hideFilter]=\"hideFilter.value\"\r\n [hideLoc]=\"hideLoc.value\"\r\n (toggleExpandedRequest)=\"onToggleExpanded($any($event))\"\r\n (changePageRequest)=\"onPageChangeRequest($event)\"\r\n (editNodeFilterRequest)=\"onEditFilterRequest($any($event))\"\r\n />\r\n </div>\r\n }\r\n </div>\r\n }\r\n <div class=\"form-row\">\r\n <mat-checkbox [formControl]=\"debug\">debug</mat-checkbox>\r\n <mat-checkbox [formControl]=\"hideFilter\">no filter</mat-checkbox>\r\n <mat-checkbox [formControl]=\"hideLoc\">no loc.</mat-checkbox>\r\n <button\r\n type=\"button\"\r\n mat-flat-button\r\n (click)=\"collapseAll()\"\r\n style=\"margin-left: 24px\"\r\n >\r\n collapse\r\n </button>\r\n </div>\r\n </div>\r\n</div>\r\n","import { Observable, of } from 'rxjs';\r\n\r\nimport { DataPage } from '@myrmidon/ngx-tools';\r\nimport {\r\n PagedTreeNode,\r\n PagedTreeStoreService,\r\n TreeNodeFilter,\r\n} from '@myrmidon/paged-data-browsers';\r\nimport { ThesaurusEntry } from '@myrmidon/cadmus-core';\r\n\r\n/**\r\n * The filter for thesaurus entry nodes. The only filtered property is\r\n * the node's label.\r\n */\r\nexport interface ThesaurusEntryNodeFilter extends TreeNodeFilter {\r\n label?: string;\r\n}\r\n\r\n/**\r\n * The tree node for thesaurus entries in a paging tree node.\r\n */\r\nexport interface ThesaurusEntryPagedTreeNode extends PagedTreeNode<ThesaurusEntryNodeFilter> {\r\n key: string; // entry.id\r\n value: string; // entry.value (not rendered; the rendered value is in label)\r\n}\r\n\r\n/**\r\n * A label rendering function which removes from a label\r\n * all the characters past the last colon, trimming the result.\r\n * This is a typical rendering when dealing with hierarchical\r\n * thesaurus entries, e.g. \"furniture: table: color\", where\r\n * we can shorten the label to just \"color\", as \"furniture\"\r\n * and \"table\" are its ancestors.\r\n */\r\nexport function renderLabelFromLastColon(label: string): string {\r\n if (!label) {\r\n return label;\r\n }\r\n const i = label.lastIndexOf(':');\r\n return i > -1 && i + 1 < label.length ? label.substring(i + 1).trim() : label;\r\n}\r\n\r\ninterface NumberedEntry extends ThesaurusEntry {\r\n n: number;\r\n}\r\n\r\n/**\r\n * A static paged tree store service for thesaurus entries.\r\n * This builds tree nodes from all the thesaurus entries from a specific\r\n * thesaurus, assuming that entry IDs are hierarchical and\r\n * separated by dots (.).\r\n * Nodes are received all at once for a thesaurus, so this is essentially\r\n * an adapter to the paged tree store service interface.\r\n * The entries are a flat list where hierarchy is implied by the IDs:\r\n * for instance, \"animal.mammal.dog\" is a child of \"animal.mammal\"\r\n * which is a child of \"animal\". Numeric IDs are added to each node\r\n * based on the order of entries to ensure stable IDs.\r\n * The label of each node can be rendered as-is from the entry value,\r\n * or a custom rendering function can be provided to the constructor.\r\n */\r\nexport class StaticThesaurusPagedTreeStoreService implements PagedTreeStoreService<ThesaurusEntryNodeFilter> {\r\n private _nodes: ThesaurusEntryPagedTreeNode[] = [];\r\n private _built = false;\r\n private readonly _entries: NumberedEntry[];\r\n\r\n /**\r\n * Constructor.\r\n * @param entries The thesaurus entries.\r\n * @param _renderLabel An optional function to render the label\r\n * of each node.\r\n */\r\n constructor(\r\n entries: ThesaurusEntry[],\r\n private _renderLabel?: (label: string) => string,\r\n ) {\r\n // assign a number to each entry for stable IDs\r\n this._entries = entries.map((entry, index) => ({\r\n ...entry,\r\n n: index + 1,\r\n }));\r\n }\r\n\r\n /**\r\n * Ensure that nodes have been built from entries.\r\n */\r\n private ensureNodes(): void {\r\n // lazily build the nodes only once\r\n if (this._built) {\r\n return;\r\n }\r\n\r\n // create a map of sibling numbers (x) where:\r\n // - key=node.id (0 is used for the virtual root);\r\n // - value=max x value for that parent.\r\n const xMap = new Map<number, number>();\r\n\r\n // build nodes from entries\r\n for (const entry of this._entries) {\r\n const hasDot = entry.id.includes('.');\r\n const keyParts = entry.id.split('.');\r\n\r\n // create the node\r\n const node: ThesaurusEntryPagedTreeNode = {\r\n id: entry.n,\r\n label:\r\n hasDot && this._renderLabel\r\n ? this._renderLabel(entry.value)\r\n : entry.value,\r\n key: entry.id,\r\n value: entry.value,\r\n paging: { pageNumber: 0, pageCount: 0, total: 0 },\r\n y: hasDot ? keyParts.length : 1,\r\n x: 0, // will be set later\r\n parentId: undefined, // will be set later\r\n hasChildren: false, // will be set later\r\n };\r\n\r\n // if it has a dot, find its parent and set parentId\r\n if (hasDot) {\r\n // build the parent key\r\n const parentKey = keyParts.slice(0, keyParts.length - 1).join('.');\r\n // find the parent node with that key\r\n const parentNode = this._nodes.find((n) => n.key === parentKey);\r\n // if found, set parentId and x in child and hasChildren in parent\r\n if (parentNode) {\r\n node.parentId = parentNode.id;\r\n parentNode.hasChildren = true;\r\n if (xMap.has(parentNode.id)) {\r\n xMap.set(parentNode.id, xMap.get(parentNode.id)! + 1);\r\n } else {\r\n xMap.set(parentNode.id, 1);\r\n }\r\n node.x = xMap.get(parentNode.id)!;\r\n } else {\r\n // parent not found, treat as root\r\n if (xMap.has(0)) {\r\n xMap.set(0, xMap.get(0)! + 1);\r\n } else {\r\n xMap.set(0, 1);\r\n }\r\n node.x = xMap.get(0)!;\r\n }\r\n } else {\r\n // else it's a root node\r\n if (xMap.has(0)) {\r\n xMap.set(0, xMap.get(0)! + 1);\r\n } else {\r\n xMap.set(0, 1);\r\n }\r\n node.x = xMap.get(0)!;\r\n }\r\n\r\n this._nodes.push(node);\r\n }\r\n\r\n this._built = true;\r\n }\r\n\r\n /**\r\n * Get the specified page of nodes.\r\n * @param filter The filter.\r\n * @param pageNumber The page number.\r\n * @param pageSize The page size.\r\n * @param hasMockRoot Whether the root node is a mock node. Not used here.\r\n */\r\n public getNodes(\r\n filter: ThesaurusEntryNodeFilter,\r\n pageNumber: number,\r\n pageSize: number,\r\n hasMockRoot?: boolean,\r\n ): Observable<DataPage<ThesaurusEntryPagedTreeNode>> {\r\n this.ensureNodes();\r\n\r\n // apply filtering\r\n let nodes = this._nodes.filter((n) => {\r\n // filter by parentId (required by tree structure)\r\n if (filter.parentId !== undefined && filter.parentId !== null) {\r\n if (n.parentId !== filter.parentId) {\r\n return false;\r\n }\r\n } else {\r\n if (n.parentId) {\r\n return false;\r\n }\r\n }\r\n\r\n // filter by label\r\n if (filter.label) {\r\n const filterValue = filter.label.toLowerCase();\r\n if (!n.label.toLowerCase().includes(filterValue)) {\r\n return false;\r\n }\r\n }\r\n return true;\r\n });\r\n\r\n // page and return\r\n const paged = nodes.slice(\r\n (pageNumber - 1) * pageSize,\r\n pageNumber * pageSize,\r\n );\r\n return of({\r\n items: paged,\r\n pageNumber: pageNumber,\r\n pageSize: pageSize,\r\n pageCount: Math.ceil(nodes.length / pageSize),\r\n total: nodes.length,\r\n });\r\n }\r\n}\r\n","import {\r\n ChangeDetectorRef,\r\n Component,\r\n OnDestroy,\r\n computed,\r\n effect,\r\n inject,\r\n input,\r\n output,\r\n signal,\r\n} from '@angular/core';\r\nimport { FormControl, FormGroup, ReactiveFormsModule } from '@angular/forms';\r\nimport { Subscription } from 'rxjs';\r\n\r\nimport { MatDialog } from '@angular/material/dialog';\r\nimport { MatProgressBarModule } from '@angular/material/progress-bar';\r\nimport { MatButtonModule } from '@angular/material/button';\r\nimport { MatCheckboxModule } from '@angular/material/checkbox';\r\nimport { MatIconModule } from '@angular/material/icon';\r\nimport { MatTooltipModule } from '@angular/material/tooltip';\r\nimport { MatInputModule } from '@angular/material/input';\r\nimport { MatFormFieldModule } from '@angular/material/form-field';\r\n\r\nimport {\r\n BrowserTreeNodeComponent,\r\n PagedTreeStore,\r\n PageChangeRequest,\r\n} from '@myrmidon/paged-data-browsers';\r\n\r\nimport {\r\n renderLabelFromLastColon,\r\n StaticThesaurusPagedTreeStoreService,\r\n ThesaurusEntryNodeFilter,\r\n ThesaurusEntryPagedTreeNode,\r\n} from '../../services/static-thesaurus-paged-tree-store.service';\r\nimport { ThesaurusPagedTreeFilterComponent }\r\n from '../thesaurus-paged-tree-filter/thesaurus-paged-tree-filter.component';\r\n\r\n/**\r\n * A readonly paged tree browser for thesaurus entries. This is a lower-level component\r\n * used as an adapter between the generic paged tree browser and the thesaurus entries\r\n * data model.\r\n */\r\n@Component({\r\n selector: 'cadmus-thesaurus-browser',\r\n imports: [\r\n ReactiveFormsModule,\r\n MatButtonModule,\r\n MatCheckboxModule,\r\n MatFormFieldModule,\r\n MatIconModule,\r\n MatInputModule,\r\n MatProgressBarModule,\r\n MatTooltipModule,\r\n ThesaurusPagedTreeFilterComponent,\r\n BrowserTreeNodeComponent,\r\n ],\r\n templateUrl: './thesaurus-browser.component.html',\r\n styleUrl: './thesaurus-browser.component.scss',\r\n})\r\nexport class ThesaurusBrowserComponent implements OnDestroy {\r\n private _dialog = inject(MatDialog);\r\n private _cdr = inject(ChangeDetectorRef);\r\n private _nodesSub?: Subscription;\r\n private _filterSub?: Subscription;\r\n\r\n /**\r\n * The service to use to load the nodes.\r\n */\r\n public readonly service = input<StaticThesaurusPagedTreeStoreService>(\r\n new StaticThesaurusPagedTreeStoreService([], renderLabelFromLastColon)\r\n );\r\n\r\n /**\r\n * Emitted when a node is clicked.\r\n */\r\n public readonly nodePick = output<ThesaurusEntryPagedTreeNode>();\r\n\r\n /**\r\n * The store instance, built from the service.\r\n */\r\n public readonly store = computed(() => {\r\n const service = this.service();\r\n return new PagedTreeStore<\r\n ThesaurusEntryPagedTreeNode,\r\n ThesaurusEntryNodeFilter\r\n >(service);\r\n });\r\n\r\n public readonly loading = signal<boolean>(false);\r\n\r\n // Signals for reactive data binding (replacing observables with async pipe)\r\n public readonly nodes = signal<readonly ThesaurusEntryPagedTreeNode[]>([]);\r\n public readonly filter = signal<Readonly<ThesaurusEntryNodeFilter>>({});\r\n\r\n public debug: FormControl<boolean> = new FormControl(false, {\r\n nonNullable: true,\r\n });\r\n public hideLoc: FormControl<boolean> = new FormControl(false, {\r\n nonNullable: true,\r\n });\r\n public hideFilter: FormControl<boolean> = new FormControl(false, {\r\n nonNullable: true,\r\n });\r\n\r\n public label: FormControl<string | null> = new FormControl(null);\r\n public form = new FormGroup({\r\n label: this.label,\r\n });\r\n\r\n constructor() {\r\n // Use effect to react to service/store changes.\r\n // allowSignalWrites is required because we update signals from subscription callbacks\r\n // that execute synchronously (BehaviorSubject emits immediately on subscribe).\r\n effect(\r\n () => {\r\n const currentStore = this.store();\r\n\r\n // Unsubscribe from previous store's observables\r\n this._nodesSub?.unsubscribe();\r\n this._filterSub?.unsubscribe();\r\n\r\n // Subscribe to new store's observables and update signals.\r\n // markForCheck() is required because subscription callbacks run outside\r\n // Angular's reactive context, and some Angular apps use OnPush change\r\n // detection or zoneless mode.\r\n this._nodesSub = currentStore.nodes$.subscribe((nodes) => {\r\n this.nodes.set(nodes);\r\n this._cdr.markForCheck();\r\n });\r\n this._filterSub = currentStore.filter$.subscribe((filter) => {\r\n this.filter.set(filter);\r\n this._cdr.markForCheck();\r\n });\r\n\r\n // Load nodes if store is empty\r\n if (!currentStore.getNodes().length) {\r\n this.loading.set(true);\r\n currentStore.setFilter({}).finally(() => {\r\n this.loading.set(false);\r\n this._cdr.markForCheck();\r\n });\r\n }\r\n },\r\n { allowSignalWrites: true }\r\n );\r\n }\r\n\r\n public ngOnDestroy(): void {\r\n this._nodesSub?.unsubscribe();\r\n this._filterSub?.unsubscribe();\r\n }\r\n\r\n public reset(): void {\r\n this.loading.set(true);\r\n this.store()\r\n .reset()\r\n .finally(() => {\r\n this.loading.set(false);\r\n this._cdr.markForCheck();\r\n });\r\n }\r\n\r\n public onToggleExpanded(node: ThesaurusEntryPagedTreeNode): void {\r\n this.loading.set(true);\r\n if (node.expanded) {\r\n this.store()\r\n .collapse(node.id)\r\n .finally(() => {\r\n this.loading.set(false);\r\n this._cdr.markForCheck();\r\n });\r\n } else {\r\n this.store()\r\n .expand(node.id)\r\n .finally(() => {\r\n this.loading.set(false);\r\n this._cdr.markForCheck();\r\n });\r\n }\r\n }\r\n\r\n public onPageChangeRequest(request: PageChangeRequest): void {\r\n this.loading.set(true);\r\n this.store()\r\n .changePage(request.node.id, request.paging.pageNumber)\r\n .finally(() => {\r\n this.loading.set(false);\r\n this._cdr.markForCheck();\r\n });\r\n }\r\n\r\n public onFilterChange(filter: ThesaurusEntryNodeFilter | null | undefined): void {\r\n console.log('filter change', filter);\r\n this.loading.set(true);\r\n this.store()\r\n .setFilter(filter || {})\r\n .finally(() => {\r\n this.loading.set(false);\r\n this._cdr.markForCheck();\r\n });\r\n }\r\n\r\n public onEditFilterRequest(node: ThesaurusEntryPagedTreeNode): void {\r\n const dialogRef = this._dialog.open(ThesaurusPagedTreeFilterComponent, {\r\n data: {\r\n filter: node.filter,\r\n },\r\n });\r\n dialogRef.afterClosed().subscribe((filter) => {\r\n // undefined = user dismissed without changes\r\n if (filter === null) {\r\n this.store().setNodeFilter(node.id, null);\r\n } else if (filter) {\r\n this.store().setNodeFilter(node.id, filter);\r\n }\r\n });\r\n }\r\n\r\n public expandAll(): void {\r\n this.store().expandAll();\r\n }\r\n\r\n public collapseAll(): void {\r\n this.store().collapseAll();\r\n }\r\n\r\n public clear(): void {\r\n this.store().clear();\r\n }\r\n\r\n public onNodeClick(node: ThesaurusEntryPagedTreeNode): void {\r\n if (!node.hasChildren) {\r\n this.nodePick.emit(node);\r\n }\r\n }\r\n\r\n public findLabels(): void {\r\n if (!this.label.value) {\r\n return;\r\n }\r\n this.store().findLabels(this.label.value);\r\n }\r\n\r\n public removeHilites(): void {\r\n this.store().removeHilites();\r\n }\r\n}\r\n","<div id=\"container\">\r\n <!-- filters -->\r\n <div id=\"filters\" class=\"form-row\">\r\n <form [formGroup]=\"form\" (submit)=\"findLabels()\" class=\"form-row\">\r\n <mat-form-field>\r\n <mat-label>label</mat-label>\r\n <input matInput [formControl]=\"label\" />\r\n @if ($any(label).errors?.required && (label.dirty || label.touched)) {\r\n <mat-error>label required</mat-error>\r\n }\r\n </mat-form-field>\r\n <button type=\"submit\" mat-icon-button class=\"mat-primary\">\r\n <mat-icon>search</mat-icon>\r\n </button>\r\n <button\r\n type=\"button\"\r\n mat-icon-button\r\n (click)=\"removeHilites()\"\r\n class=\"mat-warn\"\r\n >\r\n <mat-icon>clear</mat-icon>\r\n </button>\r\n </form>\r\n <fieldset>\r\n <legend>filter</legend>\r\n <cadmus-thesaurus-paged-tree-filter\r\n [filter]=\"filter()\"\r\n (filterChange)=\"onFilterChange($event)\"\r\n />\r\n </fieldset>\r\n </div>\r\n\r\n <!-- tree -->\r\n <div id=\"tree\">\r\n <!-- progress -->\r\n @if (loading()) {\r\n <div>\r\n <mat-progress-bar mode=\"indeterminate\"></mat-progress-bar>\r\n </div>\r\n }\r\n <!-- nodes -->\r\n @if (nodes(); as nodeList) {\r\n <div>\r\n @for (node of nodeList; track node.id; let i = $index) {\r\n <div class=\"button-row\" [class.hilite]=\"node.hilite\">\r\n <pdb-browser-tree-node\r\n [node]=\"node\"\r\n [debug]=\"debug.value\"\r\n [paging]=\"\r\n node.expanded &&\r\n i + 1 < nodeList.length &&\r\n nodeList[i + 1].paging.pageCount > 1\r\n ? nodeList[i + 1].paging\r\n : undefined\r\n \"\r\n [hideFilter]=\"hideFilter.value\"\r\n [hideLoc]=\"hideLoc.value\"\r\n (toggleExpandedRequest)=\"onToggleExpanded($any($event))\"\r\n (changePageRequest)=\"onPageChangeRequest($event)\"\r\n (editNodeFilterRequest)=\"onEditFilterRequest($any($event))\"\r\n />\r\n @if (!node.hasChildren) {\r\n <button type=\"button\" mat-icon-button (click)=\"onNodeClick(node)\">\r\n <mat-icon class=\"mat-primary\">check_circle</mat-icon>\r\n </button>\r\n }\r\n </div>\r\n }\r\n </div>\r\n }\r\n <div class=\"form-row\">\r\n <mat-checkbox [formControl]=\"debug\">debug</mat-checkbox>\r\n <mat-checkbox [formControl]=\"hideFilter\">no filter</mat-checkbox>\r\n <mat-checkbox [formControl]=\"hideLoc\">no loc.</mat-checkbox>\r\n <button\r\n type=\"button\"\r\n mat-flat-button\r\n (click)=\"collapseAll()\"\r\n style=\"margin-left: 24px\"\r\n >\r\n collapse\r\n </button>\r\n </div>\r\n </div>\r\n</div>\r\n","import { Component, computed, input, output, Type } from '@angular/core';\r\nimport { FormsModule, ReactiveFormsModule } from '@angular/forms';\r\nimport { ThesaurusEntry } from '@myrmidon/cadmus-core';\r\n\r\nimport { ThesaurusPagedTreeFilterComponent } from '../thesaurus-paged-tree-filter/thesaurus-paged-tree-filter.component';\r\nimport {\r\n renderLabelFromLastColon,\r\n StaticThesaurusPagedTreeStoreService,\r\n ThesaurusEntryPagedTreeNode,\r\n} from '../../services/static-thesaurus-paged-tree-store.service';\r\nimport { ThesaurusBrowserComponent } from '../thesaurus-browser/thesaurus-browser.component';\r\n\r\n/**\r\n * Thesaurus tree component.\r\n * This component displays a set of hierarchical thesaurus entries\r\n * in a tree, provided that each entry marks its hierarchy with\r\n * dots. For instance, say you have the hierarchy \"furniture\" -\r\n * \"type\" - \"color\". You might have an entry whose ID is\r\n * \"furniture.table.red\", with a sibling \"furniture.table.green\",\r\n * and a parent \"furniture.table\". This parent is there only to\r\n * provide a label to the parent node, but only leaf nodes can be\r\n * picked by the user. Whenever one is picked, the entryChange\r\n * event is emitted.\r\n */\r\n@Component({\r\n selector: 'cadmus-thesaurus-tree',\r\n templateUrl: './thesaurus-tree.component.html',\r\n styleUrls: ['./thesaurus-tree.component.css'],\r\n imports: [FormsModule, ReactiveFormsModule, ThesaurusBrowserComponent],\r\n})\r\nexport class ThesaurusTreeComponent {\r\n /**\r\n * The thesaurus entries.\r\n */\r\n public readonly entries = input<ThesaurusEntry[]>();\r\n\r\n /**\r\n * The optional node label rendering function. Note that even if you\r\n * specify a label renderer function, the entryChange event always\r\n * emits the original label.\r\n */\r\n public readonly renderLabel = input<(label: string) => string>(\r\n renderLabelFromLastColon,\r\n );\r\n\r\n /**\r\n * Fired when a thesaurus entry is selected.\r\n */\r\n public readonly entryChange = output<ThesaurusEntry>();\r\n\r\n /**\r\n * The tree store service, dependent on the current entries and renderLabel.\r\n */\r\n public readonly service = computed<StaticThesaurusPagedTreeStoreService>(() => {\r\n const entries = this.entries();\r\n return new StaticThesaurusPagedTreeStoreService(\r\n entries || [],\r\n this.renderLabel(),\r\n );\r\n });\r\n\r\n /**\r\n * The filter component class to use.\r\n */\r\n public readonly filterComponent: Type<ThesaurusPagedTreeFilterComponent> =\r\n ThesaurusPagedTreeFilterComponent;\r\n\r\n public onNodePick(node: ThesaurusEntryPagedTreeNode): void {\r\n // only allow selection of leaf nodes (nodes without children)\r\n if (!node.hasChildren) {\r\n // find the original entry\r\n const entry = this.entries()?.find((e) => e.id === node.key);\r\n if (entry) {\r\n this.entryChange.emit(entry);\r\n }\r\n }\r\n }\r\n}\r\n","<div>\r\n <!-- tree -->\r\n @if (service() && entries()?.length) {\r\n <div class=\"tree-wrapper\">\r\n <cadmus-thesaurus-browser\r\n [service]=\"service()\"\r\n (nodePick)=\"onNodePick($event)\"\r\n />\r\n </div>\r\n }\r\n</div>\r\n","import {\r\n Component,\r\n computed,\r\n effect,\r\n input,\r\n model,\r\n untracked,\r\n} from '@angular/core';\r\nimport { ThesaurusEntry } from '@myrmidon/cadmus-core';\r\nimport {\r\n FormBuilder,\r\n FormControl,\r\n FormGroup,\r\n ReactiveFormsModule,\r\n Validators,\r\n} from '@angular/forms';\r\n\r\nimport {\r\n CdkDragDrop,\r\n CdkDropList,\r\n CdkDrag,\r\n moveItemInArray,\r\n} from '@angular/cdk/drag-drop';\r\nimport {\r\n MatChipListbox,\r\n MatChipOption,\r\n MatChipRemove,\r\n} from '@angular/material/chips';\r\nimport { MatExpansionPanel } from '@angular/material/expansion';\r\nimport { MatFormField } from '@angular/material/form-field';\r\nimport { MatIcon } from '@angular/material/icon';\r\nimport { MatIconButton } from '@angular/material/button';\r\nimport { MatInput } from '@angular/material/input';\r\nimport { MatTooltip } from '@angular/material/tooltip';\r\n\r\nimport { renderLabelFromLastColon } from '../../services/static-thesaurus-paged-tree-store.service';\r\nimport { ThesaurusTreeComponent } from '../thesaurus-tree/thesaurus-tree.component';\r\n\r\n/**\r\n * The prefix added to custom entries' IDs.\r\n */\r\nexport const CUSTOM_ENTRY_PREFIX = '$';\r\n\r\n/**\r\n * A picker component for thesaurus entries.\r\n * This component allows picking one or more entries from a given thesaurus.\r\n * In its collapsed state, it shows the picked entries as chips; when\r\n * expanded, it shows the thesaurus tree to pick from. Custom entries\r\n * (not in the thesaurus) can be optionally allowed.\r\n */\r\n@Component({\r\n selector: 'cadmus-thesaurus-entries-picker',\r\n imports: [\r\n ReactiveFormsModule,\r\n CdkDropList,\r\n CdkDrag,\r\n MatChipListbox,\r\n MatChipOption,\r\n MatChipRemove,\r\n MatExpansionPanel,\r\n MatFormField,\r\n MatIconButton,\r\n MatIcon,\r\n MatInput,\r\n MatTooltip,\r\n ThesaurusTreeComponent,\r\n ],\r\n templateUrl: './thesaurus-entries-picker.component.html',\r\n styleUrl: './thesaurus-entries-picker.component.css',\r\n})\r\nexport class ThesaurusEntriesPickerComponent {\r\n /**\r\n * The thesaurus entries to pick from (required).\r\n */\r\n public readonly availableEntries = input.required<ThesaurusEntry[]>();\r\n\r\n /**\r\n * The picked entries.\r\n */\r\n public readonly entries = model<ThesaurusEntry[]>([]);\r\n\r\n /**\r\n * True to show the entries with labels shortened according to\r\n * their hierarchy.\r\n */\r\n public readonly hierarchicLabels = input<boolean>(false);\r\n\r\n /**\r\n * True to automatically sort the picked entries (disables drag-and-drop).\r\n * When false, entries can be manually reordered via drag-and-drop.\r\n */\r\n public readonly autoSort = input<boolean>(false);\r\n\r\n /**\r\n * True to allow custom values (not in the entries list).\r\n */\r\n public readonly allowCustom = input<boolean>(false);\r\n\r\n /**\r\n * The minimum number of entries to pick.\r\n */\r\n public readonly minEntries = input<number>(0);\r\n\r\n /**\r\n * The maximum number of entries to pick (0=unlimited).\r\n */\r\n public readonly maxEntries = input<number>(0);\r\n\r\n /**\r\n * True when the picker is expanded (showing the entries list).\r\n */\r\n public readonly expanded = model<boolean>(false);\r\n\r\n /**\r\n * The message to show when there are no picked entries.\r\n */\r\n public readonly emptyMessage = input<string>('no entries');\r\n\r\n /**\r\n * The number of remaining entries that can be picked (0=unlimited).\r\n * This is displayed only if maxEntries > 1.\r\n */\r\n public readonly remaining = computed(() => {\r\n if (this.maxEntries() > 0) {\r\n return this.maxEntries() - this.entries().length;\r\n }\r\n return 0;\r\n });\r\n\r\n public id: FormControl<string>;\r\n public value: FormControl<string>;\r\n public form: FormGroup;\r\n\r\n constructor(formBuilder: FormBuilder) {\r\n this.id = formBuilder.control<string>('', {\r\n validators: [Validators.required, Validators.maxLength(100)],\r\n nonNullable: true,\r\n });\r\n this.value = formBuilder.control<string>('', {\r\n validators: [Validators.required, Validators.maxLength(500)],\r\n nonNullable: true,\r\n });\r\n this.form = formBuilder.group({\r\n id: this.id,\r\n value: this.value,\r\n });\r\n // if auto-sort is turned on and we have entries, sort them\r\n effect(() => {\r\n // only track autoSort() changes, not entries()\r\n const shouldSort = this.autoSort();\r\n\r\n if (shouldSort) {\r\n // use untracked to read entries without creating a dependency\r\n const currentEntries = untracked(() => this.entries());\r\n if (currentEntries.length > 1) {\r\n const entries = [...currentEntries];\r\n this.sortEntries(entries);\r\n this.entries.set(entries);\r\n }\r\n }\r\n });\r\n }\r\n\r\n // need arrow function to use 'this'\r\n public renderLabel = (label: string): string => {\r\n return this.hierarchicLabels() ? renderLabelFromLastColon(label) : label;\r\n };\r\n\r\n private sortEntries(entries: ThesaurusEntry[]) {\r\n entries.sort((a: ThesaurusEntry, b: ThesaurusEntry) => {\r\n const aIsCustom = a.id?.startsWith(CUSTOM_ENTRY_PREFIX) ?? false;\r\n const bIsCustom = b.id?.startsWith(CUSTOM_ENTRY_PREFIX) ?? false;\r\n if (aIsCustom !== bIsCustom) {\r\n // place custom entries after non-custom ones\r\n return aIsCustom ? 1 : -1;\r\n }\r\n // same kind: sort by label/value\r\n return a.value.localeCompare(b.value);\r\n });\r\n }\r\n\r\n public onEntryChange(entry: ThesaurusEntry): void {\r\n // check if already present\r\n if (this.entries().some((e: ThesaurusEntry) => e.id === entry.id)) {\r\n return;\r\n }\r\n // check if limit is reached\r\n if (this.maxEntries() && this.entries().length >= this.maxEntries()) {\r\n return;\r\n }\r\n\r\n const entries = [...this.entries()];\r\n entries.push(entry);\r\n if (this.autoSort()) {\r\n this.sortEntries(entries);\r\n }\r\n this.entries.set(entries);\r\n }\r\n\r\n public addCustomEntry(): void {\r\n if (this.form.invalid) {\r\n return;\r\n }\r\n\r\n // create the custom entry\r\n const customEntry: ThesaurusEntry = {\r\n id: CUSTOM_ENTRY_PREFIX + this.id.value,\r\n value: this.value.value,\r\n };\r\n\r\n // check if already present\r\n if (this.entries().some((e: ThesaurusEntry) => e.id === customEntry.id)) {\r\n return;\r\n }\r\n // check if limit is reached\r\n if (this.maxEntries() && this.entries().length >= this.maxEntries()) {\r\n return;\r\n }\r\n const entries = [...this.entries()];\r\n entries.push(customEntry);\r\n if (this.autoSort()) {\r\n this.sortEntries(entries);\r\n }\r\n this.entries.set(entries);\r\n this.form.reset();\r\n }\r\n\r\n public removeEntry(entry: ThesaurusEntry): void {\r\n const entries = [...this.entries().filter((e) => e.id !== entry.id)];\r\n this.entries.set(entries);\r\n }\r\n\r\n public clear(): void {\r\n this.entries.set([]);\r\n // if min > 0, expand the picker\r\n if (this.minEntries() > 0 && !this.expanded()) {\r\n setTimeout(() => {\r\n this.expanded.set(true);\r\n }, 0);\r\n }\r\n }\r\n\r\n public onDrop(event: CdkDragDrop<ThesaurusEntry[]>): void {\r\n const entries = [...this.entries()];\r\n moveItemInArray(entries, event.previousIndex, event.currentIndex);\r\n this.entries.set(entries);\r\n }\r\n}\r\n","<div id=\"container\">\r\n <!-- picked entries -->\r\n <div id=\"picked\" class=\"form-row\">\r\n <!-- count -->\r\n <span class=\"nr\" [class.error]=\"entries().length < minEntries()\">{{\r\n entries().length\r\n }}</span>\r\n <!-- max-->\r\n @if (maxEntries() > 1) {\r\n <span class=\"muted\">/{{ maxEntries() }}</span>\r\n @if (remaining()) {\r\n <span class=\"muted\">: -{{ remaining() }}</span>\r\n } }\r\n <!-- min -->\r\n @if (minEntries()) {\r\n <!-- min with error -->\r\n @if (entries().length < minEntries()) {\r\n <span class=\"error\"> (min {{ minEntries() }})</span>\r\n }\r\n <!-- min without error -->\r\n @else {\r\n <span class=\"muted\"> (min {{ minEntries() }})</span>\r\n } }\r\n <!-- list -->\r\n <mat-chip-listbox\r\n [cdkDropListDisabled]=\"autoSort()\"\r\n cdkDropList\r\n cdkDropListOrientation=\"horizontal\"\r\n (cdkDropListDropped)=\"onDrop($event)\"\r\n class=\"chip-list\"\r\n >\r\n @for (e of entries(); track e.id; let idx = $index) {\r\n <div class=\"chip-wrapper\">\r\n <mat-chip-option\r\n [cdkDragDisabled]=\"autoSort()\"\r\n cdkDrag\r\n [class.error]=\"!allowCustom() && e.id.startsWith('$')\"\r\n >\r\n {{ renderLabel(e.value) }}\r\n <button\r\n type=\"button\"\r\n matChipRemove\r\n (click)=\"removeEntry(e)\"\r\n aria-label=\"Remove entry\"\r\n >\r\n <mat-icon class=\"mat-warn\">cancel</mat-icon>\r\n </button>\r\n </mat-chip-option>\r\n </div>\r\n } @empty {\r\n <span class=\"muted empty-message\">{{ emptyMessage() }}</span>\r\n }\r\n </mat-chip-listbox>\r\n\r\n <!-- clear -->\r\n @if (entries().length > 0) {\r\n <button\r\n type=\"button\"\r\n mat-icon-button\r\n matTooltip=\"Remove all entries\"\r\n (click)=\"clear()\"\r\n [disabled]=\"entries().length === 0\"\r\n >\r\n <mat-icon class=\"mat-warn\">clear</mat-icon>\r\n </button>\r\n }\r\n <!-- toggler -->\r\n <button\r\n type=\"button\"\r\n mat-icon-button\r\n matTooltip=\"Toggle picker\"\r\n (click)=\"expanded.set(!expanded())\"\r\n >\r\n @if (expanded()) {\r\n <mat-icon class=\"mat-primary\">publish</mat-icon>\r\n } @if (!expanded()) {\r\n <mat-icon class=\"mat-primary\">get_app</mat-icon>\r\n }\r\n </button>\r\n </div>\r\n\r\n <!-- entries picker -->\r\n <div id=\"picker\">\r\n <mat-expansion-panel\r\n [expanded]=\"expanded()\"\r\n (expandedChange)=\"expanded.set($event)\"\r\n >\r\n <div>\r\n <fieldset>\r\n <legend>available</legend>\r\n <cadmus-thesaurus-tree\r\n [entries]=\"availableEntries()\"\r\n [renderLabel]=\"renderLabel\"\r\n (entryChange)=\"onEntryChange($event)\"\r\n />\r\n </fieldset>\r\n </div>\r\n @if (allowCustom()) {\r\n <div>\r\n <form [formGroup]=\"form\" (submit)=\"addCustomEntry()\">\r\n <fieldset>\r\n <legend>custom</legend>\r\n <div class=\"form-row\">\r\n <mat-form-field>\r\n <input\r\n matInput\r\n type=\"text\"\r\n [formControl]=\"id\"\r\n placeholder=\"ID\"\r\n />\r\n </mat-form-field>\r\n <mat-form-field>\r\n <input\r\n matInput\r\n type=\"text\"\r\n [formControl]=\"value\"\r\n placeholder=\"label\"\r\n />\r\n </mat-form-field>\r\n <button\r\n type=\"submit\"\r\n mat-icon-button\r\n matTooltip=\"Add custom entry\"\r\n [disabled]=\"\r\n !form.valid ||\r\n (maxEntries() > 0 && entries().length >= maxEntries())\r\n \"\r\n >\r\n <mat-icon class=\"mat-primary\">check_circle</mat-icon>\r\n </button>\r\n </div>\r\n </fieldset>\r\n </form>\r\n </div>\r\n }\r\n </mat-expansion-panel>\r\n </div>\r\n</div>\r\n","import { Observable, of } from 'rxjs';\r\n\r\nimport { DataPage } from '@myrmidon/ngx-tools';\r\n\r\nimport {\r\n EditablePagedTreeStoreServiceBase,\r\n ChangeOperation,\r\n ChangeOperationType,\r\n TreeNode,\r\n} from '@myrmidon/paged-data-browsers';\r\nimport { ThesaurusEntry } from '@myrmidon/cadmus-core';\r\n\r\nimport {\r\n StaticThesaurusPagedTreeStoreService,\r\n ThesaurusEntryNodeFilter,\r\n ThesaurusEntryPagedTreeNode,\r\n} from './static-thesaurus-paged-tree-store.service';\r\n\r\n/**\r\n * Editable version of the static thesaurus paged tree store service.\r\n * This service allows editing operations on the flat ThesaurusEntry list\r\n * while maintaining the tree structure implied by the hierarchical IDs.\r\n */\r\nexport class EditableStaticThesaurusPagedTreeStoreService\r\n extends EditablePagedTreeStoreServiceBase<ThesaurusEntryNodeFilter> {\r\n private _entries: ThesaurusEntry[];\r\n private _staticService: StaticThesaurusPagedTreeStoreService;\r\n private _renderLabel?: (label: string) => string;\r\n\r\n constructor(\r\n entries: ThesaurusEntry[],\r\n renderLabel?: (label: string) => string,\r\n ) {\r\n super();\r\n this._entries = [...entries];\r\n this._renderLabel = renderLabel;\r\n this._staticService = new StaticThesaurusPagedTreeStoreService(\r\n this._entries,\r\n renderLabel,\r\n );\r\n }\r\n\r\n protected override fetchNodes(\r\n filter: ThesaurusEntryNodeFilter,\r\n pageNumber: number,\r\n pageSize: number,\r\n hasMockRoot?: boolean,\r\n ): Observable<DataPage<TreeNode>> {\r\n // update the static service with current entries and delegate,\r\n // preserving the renderLabel function\r\n this._staticService = new StaticThesaurusPagedTreeStoreService(\r\n this._entries,\r\n this._renderLabel,\r\n );\r\n return this._staticService.getNodes(\r\n filter,\r\n pageNumber,\r\n pageSize,\r\n hasMockRoot,\r\n );\r\n }\r\n\r\n protected override persistChanges(\r\n changes: ChangeOperation[],\r\n ): Observable<Map<number, number>> {\r\n console.log('=== SAVING CHANGES ===');\r\n console.log('Changes to persist:', changes);\r\n\r\n const idMap = new Map<number, number>();\r\n\r\n // process changes to update the flat entries list\r\n for (const change of changes) {\r\n switch (change.type) {\r\n case ChangeOperationType.ADD:\r\n if (change.node) {\r\n const newEntry = this.nodeToEntry(change.node);\r\n if (newEntry) {\r\n const existingIndex = this._entries.findIndex(\r\n (e) => e.id === newEntry.id,\r\n );\r\n if (existingIndex === -1) {\r\n this._entries.push(newEntry);\r\n\r\n // map temporary ID to the new permanent ID (array index + 1)\r\n if (change.node.id < 0) {\r\n const permanentId = this._entries.length;\r\n idMap.set(change.node.id, permanentId);\r\n }\r\n console.log('Added entry:', newEntry);\r\n } else {\r\n console.log('Entry already exists, skipping:', newEntry.id);\r\n }\r\n }\r\n }\r\n break;\r\n\r\n case ChangeOperationType.REMOVE:\r\n if (change.originalNode) {\r\n // use the 'key' property which contains the ThesaurusEntry string ID\r\n const nodeWithKey =\r\n change.originalNode as ThesaurusEntryPagedTreeNode;\r\n const entryKey = nodeWithKey.key;\r\n\r\n if (entryKey) {\r\n this.removeEntryAndDescendants(entryKey);\r\n console.log('Removed entry and descendants:', entryKey);\r\n } else {\r\n console.warn('Node missing key property:', change.originalNode);\r\n }\r\n } else if (change.id < 0) {\r\n console.log(\r\n 'Removed temporary node that was never persisted:',\r\n change.id,\r\n );\r\n } else {\r\n console.warn(\r\n 'Remove operation missing originalNode for ID:',\r\n change.id,\r\n );\r\n }\r\n break;\r\n\r\n case ChangeOperationType.UPDATE:\r\n if (change.node && change.originalNode) {\r\n const nodeWithKey =\r\n change.originalNode as ThesaurusEntryPagedTreeNode;\r\n const entryKey = nodeWithKey.key;\r\n\r\n if (entryKey) {\r\n const entryToUpdate = this._entries.find(\r\n (e) => e.id === entryKey,\r\n );\r\n\r\n if (entryToUpdate) {\r\n const updatedEntry = this.nodeToEntry(change.node);\r\n if (updatedEntry) {\r\n // preserve the original hierarchical ID\r\n updatedEntry.id = entryToUpdate.id;\r\n const index = this._entries.findIndex(\r\n (e) => e.id === entryToUpdate.id,\r\n );\r\n if (index !== -1) {\r\n this._entries[index] = updatedEntry;\r\n console.log('Updated entry:', updatedEntry);\r\n }\r\n }\r\n } else {\r\n console.warn(\r\n 'Could not find entry to update with key:',\r\n entryKey,\r\n );\r\n }\r\n } else {\r\n console.warn(\r\n 'Update node missing key property:',\r\n change.originalNode,\r\n );\r\n }\r\n } else if (change.id < 0) {\r\n console.log('Updated temporary node:', change.id);\r\n }\r\n break;\r\n }\r\n }\r\n\r\n // Validate no duplicate IDs\r\n const ids = this._entries.map((e) => e.id);\r\n const duplicates = ids.filter((id, index) => ids.indexOf(id) !== index);\r\n if (duplicates.length > 0) {\r\n console.error('Duplicate IDs found:', duplicates);\r\n }\r\n\r\n console.log('Final entries after changes:', this._entries);\r\n console.log('ID mappings:', idMap);\r\n console.log('=== END SAVING CHANGES ===');\r\n\r\n return of(idMap);\r\n }\r\n\r\n /**\r\n * Convert a TreeNode back to a ThesaurusEntry.\r\n */\r\n private nodeToEntry(node: TreeNode): ThesaurusEntry | null {\r\n // For nodes with the key property, use it directly\r\n const nodeWithKey = node as any;\r\n if (nodeWithKey.key) {\r\n return {\r\n id: nodeWithKey.key,\r\n value: node.label,\r\n };\r\n }\r\n\r\n // For temporary nodes (negative IDs), construct a hierarchical ID\r\n if (node.id < 0) {\r\n // Check for user-provided ID\r\n const userProvidedId = nodeWithKey._userProvidedId;\r\n\r\n if (userProvidedId) {\r\n return {\r\n id: userProvidedId,\r\n value: node.label,\r\n };\r\n }\r\n\r\n // Find parent to construct the ID\r\n if (node.parentId) {\r\n const parentNode = this._nodes.get(node.parentId) as any;\r\n const parentKey = parentNode?.key;\r\n if (parentKey) {\r\n return {\r\n id: `${parentKey}.temp${Math.abs(node.id)}`,\r\n value: node.label,\r\n };\r\n }\r\n }\r\n\r\n // No parent, create a root-level temporary entry\r\n return {\r\n id: `temp${Math.abs(node.id)}`,\r\n value: node.label,\r\n };\r\n }\r\n\r\n console.warn('Could not convert node to entry:', node);\r\n return null;\r\n }\r\n\r\n /**\r\n * Remove an entry and all its descendants from the entries list.\r\n */\r\n private removeEntryAndDescendants(entryId: string): void {\r\n const toRemove: string[] = [];\r\n\r\n // find the entry and all its descendants\r\n for (const entry of this._entries) {\r\n if (entry.id === entryId || entry.id.startsWith(entryId + '.')) {\r\n toRemove.push(entry.id);\r\n }\r\n }\r\n\r\n // remove them from the list\r\n for (const id of toRemove) {\r\n const index = this._entries.findIndex((e) => e.id === id);\r\n if (index !== -1) {\r\n this._entries.splice(index, 1);\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Get current entries (for demonstration purposes).\r\n */\r\n public getCurrentEntries(): ThesaurusEntry[] {\r\n return [...this._entries];\r\n }\r\n}\r\n","/*\r\n * Public API Surface of cadmus-thesaurus-store\r\n */\r\n\r\nexport * from './lib/components/editable-thesaurus-browser/editable-thesaurus-browser.component';\r\nexport * from './lib/components/thesaurus-entries-picker/thesaurus-entries-picker.component';\r\nexport * from './lib/components/thesaurus-entry-editor/thesaurus-entry-editor.component';\r\nexport * from './lib/components/thesaurus-browser/thesaurus-browser.component';\r\nexport * from './lib/components/thesaurus-paged-tree-filter/thesaurus-paged-tree-filter.component';\r\nexport * from './lib/components/thesaurus-tree/thesaurus-tree.component';\r\n\r\nexport * from './lib/services/editable-static-thesaurus-paged-tree-store.service';\r\nexport * from './lib/services/static-thesaurus-paged-tree-store.service';\r\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":["i3","i4","i6","i2","i7"],"mappings":"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"}
1
+ {"version":3,"file":"myrmidon-cadmus-thesaurus-store.mjs","sources":["../../../../projects/myrmidon/cadmus-thesaurus-store/src/lib/components/thesaurus-paged-tree-filter/thesaurus-paged-tree-filter.component.ts","../../../../projects/myrmidon/cadmus-thesaurus-store/src/lib/components/thesaurus-paged-tree-filter/thesaurus-paged-tree-filter.component.html","../../../../projects/myrmidon/cadmus-thesaurus-store/src/lib/components/thesaurus-entry-editor/thesaurus-entry-editor.component.ts","../../../../projects/myrmidon/cadmus-thesaurus-store/src/lib/components/thesaurus-entry-editor/thesaurus-entry-editor.component.html","../../../../projects/myrmidon/cadmus-thesaurus-store/src/lib/components/editable-thesaurus-browser/editable-thesaurus-browser.component.ts","../../../../projects/myrmidon/cadmus-thesaurus-store/src/lib/components/editable-thesaurus-browser/editable-thesaurus-browser.component.html","../../../../projects/myrmidon/cadmus-thesaurus-store/src/lib/services/static-thesaurus-paged-tree-store.service.ts","../../../../projects/myrmidon/cadmus-thesaurus-store/src/lib/components/thesaurus-browser/thesaurus-browser.component.ts","../../../../projects/myrmidon/cadmus-thesaurus-store/src/lib/components/thesaurus-browser/thesaurus-browser.component.html","../../../../projects/myrmidon/cadmus-thesaurus-store/src/lib/components/thesaurus-tree/thesaurus-tree.component.ts","../../../../projects/myrmidon/cadmus-thesaurus-store/src/lib/components/thesaurus-tree/thesaurus-tree.component.html","../../../../projects/myrmidon/cadmus-thesaurus-store/src/lib/components/thesaurus-entries-picker/thesaurus-entries-picker.component.ts","../../../../projects/myrmidon/cadmus-thesaurus-store/src/lib/components/thesaurus-entries-picker/thesaurus-entries-picker.component.html","../../../../projects/myrmidon/cadmus-thesaurus-store/src/lib/services/editable-static-thesaurus-paged-tree-store.service.ts","../../../../projects/myrmidon/cadmus-thesaurus-store/src/public-api.ts","../../../../projects/myrmidon/cadmus-thesaurus-store/src/myrmidon-cadmus-thesaurus-store.ts"],"sourcesContent":["import {\r\n Component,\r\n effect,\r\n inject,\r\n model,\r\n OnInit,\r\n signal,\r\n} from '@angular/core';\r\nimport {\r\n FormBuilder,\r\n FormControl,\r\n FormGroup,\r\n ReactiveFormsModule,\r\n} from '@angular/forms';\r\nimport { MatButtonModule } from '@angular/material/button';\r\nimport { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog';\r\nimport { MatFormFieldModule } from '@angular/material/form-field';\r\nimport { MatIconModule } from '@angular/material/icon';\r\nimport { MatInputModule } from '@angular/material/input';\r\nimport { MatTooltipModule } from '@angular/material/tooltip';\r\n\r\nimport { ThesaurusEntryNodeFilter } from '../../services/static-thesaurus-paged-tree-store.service';\r\n\r\n/**\r\n * A filter to be used for thesaurus paged tree browsers.\r\n */\r\n@Component({\r\n selector: 'cadmus-thesaurus-paged-tree-filter',\r\n imports: [\r\n ReactiveFormsModule,\r\n MatButtonModule,\r\n MatFormFieldModule,\r\n MatInputModule,\r\n MatIconModule,\r\n MatTooltipModule,\r\n ],\r\n templateUrl: './thesaurus-paged-tree-filter.component.html',\r\n styleUrl: './thesaurus-paged-tree-filter.component.css',\r\n})\r\nexport class ThesaurusPagedTreeFilterComponent implements OnInit {\r\n public readonly dialogRef = inject<\r\n MatDialogRef<ThesaurusPagedTreeFilterComponent>\r\n >(MatDialogRef, {\r\n optional: true,\r\n });\r\n public readonly data = inject(MAT_DIALOG_DATA, { optional: true });\r\n\r\n /**\r\n * The filter.\r\n */\r\n public readonly filter = model<ThesaurusEntryNodeFilter | null | undefined>();\r\n\r\n public readonly wrapped = signal<boolean>(false);\r\n\r\n public label: FormControl<string | null>;\r\n public form: FormGroup;\r\n\r\n constructor() {\r\n const formBuilder = inject(FormBuilder);\r\n const data = this.data;\r\n\r\n // form\r\n this.label = formBuilder.control<string | null>(null);\r\n this.form = formBuilder.group({\r\n label: this.label,\r\n });\r\n // bind dialog data if any\r\n if (this.dialogRef) {\r\n this.wrapped.set(true);\r\n if (data) {\r\n this.filter.set(data.filter);\r\n }\r\n } else {\r\n this.wrapped.set(false);\r\n }\r\n\r\n // update form when filter changes\r\n effect(() => {\r\n this.updateForm(this.filter());\r\n });\r\n }\r\n\r\n public ngOnInit(): void {\r\n this.updateForm(this.filter());\r\n }\r\n\r\n private updateForm(filter?: ThesaurusEntryNodeFilter | null): void {\r\n if (!filter) {\r\n this.form.reset();\r\n return;\r\n }\r\n this.label.setValue(filter.label ?? null);\r\n this.form.markAsPristine();\r\n }\r\n\r\n private getFilter(): ThesaurusEntryNodeFilter {\r\n return {\r\n label: this.label.value ?? undefined,\r\n };\r\n }\r\n\r\n public reset(): void {\r\n this.form.reset();\r\n this.filter.set(null);\r\n this.dialogRef?.close(null);\r\n }\r\n\r\n public apply(): void {\r\n const filter = this.getFilter();\r\n this.filter.set(filter);\r\n this.dialogRef?.close(filter);\r\n }\r\n}\r\n","<form\r\n [formGroup]=\"form\"\r\n [style.margin.px]=\"wrapped() ? 16 : 0\"\r\n (submit)=\"apply()\"\r\n>\r\n <div class=\"form-row\">\r\n <!-- label -->\r\n <mat-form-field>\r\n <input matInput placeholder=\"label\" [formControl]=\"label\" />\r\n </mat-form-field>\r\n\r\n <!-- buttons -->\r\n <div class=\"button-row\">\r\n <button\r\n type=\"button\"\r\n mat-icon-button\r\n matTooltip=\"Reset\"\r\n (click)=\"reset()\"\r\n >\r\n <mat-icon class=\"mat-warn\">clear</mat-icon>\r\n </button>\r\n <button\r\n type=\"submit\"\r\n mat-icon-button\r\n matTooltip=\"Apply\"\r\n [disabled]=\"form.invalid\"\r\n >\r\n <mat-icon class=\"mat-primary\">check_circle</mat-icon>\r\n </button>\r\n </div>\r\n </div>\r\n</form>\r\n","import { Component, Inject, input, model, Optional } from '@angular/core';\r\nimport {\r\n FormBuilder,\r\n FormControl,\r\n FormGroup,\r\n ReactiveFormsModule,\r\n Validators,\r\n AbstractControl,\r\n ValidationErrors,\r\n} from '@angular/forms';\r\nimport { MatButtonModule } from '@angular/material/button';\r\nimport {\r\n MatDialogRef,\r\n MAT_DIALOG_DATA,\r\n MatDialogConfig,\r\n} from '@angular/material/dialog';\r\nimport { MatFormFieldModule } from '@angular/material/form-field';\r\nimport { MatIconModule } from '@angular/material/icon';\r\nimport { MatInputModule } from '@angular/material/input';\r\nimport { MatTooltipModule } from '@angular/material/tooltip';\r\n\r\n/**\r\n * An edited thesaurus entry.\r\n */\r\nexport interface EditedThesEntry {\r\n id: string;\r\n value: string;\r\n /**\r\n * True if this entry belongs to a hierarchical thesaurus. When this is true,\r\n * and parentId is set, the parentId field will be used as the prefix for the\r\n * id field when creating a new entry.\r\n */\r\n hierarchical?: boolean;\r\n /**\r\n * The ID of the parent entry, if any.\r\n */\r\n parentId?: string;\r\n /**\r\n * If true, the id field is read-only. This is used when editing an existing\r\n * entry so you cannot change its ID.\r\n */\r\n idLocked?: boolean;\r\n /**\r\n * Function used to check if the given ID exists. This is used when\r\n * creating a new entry to ensure it does not duplicate an existing ID.\r\n * @param id The ID to check.\r\n * @returns True if exists.\r\n */\r\n idExists?: (id: string) => boolean;\r\n}\r\n\r\nexport interface PayloadMatDialogConfig<T> extends MatDialogConfig {\r\n payload?: T;\r\n}\r\n\r\n/**\r\n * A dialog component to edit a thesaurus entry.\r\n */\r\n@Component({\r\n selector: 'cadmus-thesaurus-entry-editor',\r\n imports: [\r\n ReactiveFormsModule,\r\n MatButtonModule,\r\n MatFormFieldModule,\r\n MatIconModule,\r\n MatInputModule,\r\n MatTooltipModule,\r\n ],\r\n templateUrl: './thesaurus-entry-editor.component.html',\r\n styleUrl: './thesaurus-entry-editor.component.scss',\r\n})\r\nexport class ThesEntryEditorComponent {\r\n public readonly entry = model<EditedThesEntry | undefined>();\r\n public wrapped = false;\r\n\r\n public id: FormControl<string>;\r\n public value: FormControl<string>;\r\n public form: FormGroup;\r\n\r\n constructor(\r\n @Optional()\r\n public dialogRef: MatDialogRef<ThesEntryEditorComponent>,\r\n @Optional()\r\n @Inject(MAT_DIALOG_DATA)\r\n public data: PayloadMatDialogConfig<EditedThesEntry>,\r\n formBuilder: FormBuilder\r\n ) {\r\n // bind to data properties if any\r\n if (data) {\r\n this.entry.set(data as EditedThesEntry);\r\n this.wrapped = true;\r\n }\r\n\r\n // custom validator for ID existence\r\n const idExistsValidator = (\r\n control: AbstractControl\r\n ): ValidationErrors | null => {\r\n const entry = this.entry();\r\n if (!entry || entry.idLocked || !entry.idExists) {\r\n return null;\r\n }\r\n const id = control.value?.trim();\r\n if (!id) {\r\n return null;\r\n }\r\n // if editing, allow the current id (do not check against itself)\r\n if (entry.id === id) {\r\n return null;\r\n }\r\n return entry.idExists(id) ? { idExists: true } : null;\r\n };\r\n\r\n // custom validator for hierarchical ID prefix\r\n const hierarchicalIdValidator = (\r\n control: AbstractControl\r\n ): ValidationErrors | null => {\r\n const entry = this.entry();\r\n if (!entry || entry.idLocked || !entry.hierarchical || !entry.parentId) {\r\n return null;\r\n }\r\n const id = control.value?.trim();\r\n if (!id) {\r\n return null;\r\n }\r\n const prefix = entry.parentId + '.';\r\n if (!id.startsWith(prefix) || id.length <= prefix.length) {\r\n return { hierarchicalPrefix: { requiredPrefix: prefix } };\r\n }\r\n return null;\r\n };\r\n\r\n // form controls\r\n this.id = new FormControl<string>((data as EditedThesEntry)?.id || '', {\r\n nonNullable: true,\r\n validators: [\r\n Validators.required,\r\n Validators.maxLength(300),\r\n idExistsValidator,\r\n hierarchicalIdValidator,\r\n ],\r\n });\r\n this.value = new FormControl<string>(\r\n (data as EditedThesEntry)?.value || '',\r\n {\r\n nonNullable: true,\r\n validators: [Validators.required, Validators.maxLength(500)],\r\n }\r\n );\r\n this.form = formBuilder.group({\r\n id: this.id,\r\n value: this.value,\r\n });\r\n }\r\n\r\n cancel(): void {\r\n this.dialogRef?.close();\r\n }\r\n\r\n save(): void {\r\n if (this.form.invalid) {\r\n return;\r\n }\r\n const old = this.entry()!;\r\n\r\n // save data and close the dialog\r\n this.dialogRef?.close({\r\n id: old.idLocked ? old.id : this.id.value?.trim(),\r\n value: this.value.value?.trim(),\r\n } as EditedThesEntry);\r\n }\r\n}\r\n","<form [formGroup]=\"form\" (submit)=\"save()\" [class.wrapped]=\"wrapped\">\r\n <fieldset>\r\n <legend>entry</legend>\r\n <div class=\"form-row\">\r\n <!-- id -->\r\n @if (entry()!.idLocked) {\r\n <span class=\"readonly\">{{ entry()!.id }}</span>\r\n } @else {\r\n <mat-form-field>\r\n <mat-label>ID</mat-label>\r\n <input matInput [formControl]=\"id\" />\r\n @if ($any(id).errors?.required && (id.dirty || id.touched)) {\r\n <mat-error>ID required</mat-error>\r\n } @if ($any(id).errors?.maxLength && (id.dirty || id.touched)) {\r\n <mat-error>ID too long</mat-error>\r\n } @if ($any(id).errors?.idExists && (id.dirty || id.touched)) {\r\n <mat-error>ID already exists</mat-error>\r\n } @if ($any(id).errors?.requiredPrefix && (id.dirty || id.touched)) {\r\n <mat-error>ID must start with \"{{ entry()!.parentId }}.\"</mat-error>\r\n }\r\n <!-- hint -->\r\n @if (entry()?.parentId) {\r\n <mat-hint>parent: {{ entry()!.parentId }}</mat-hint>\r\n }\r\n </mat-form-field>\r\n }\r\n <!-- value -->\r\n <mat-form-field>\r\n <mat-label>value</mat-label>\r\n <input matInput [formControl]=\"value\" />\r\n @if ($any(value).errors?.required && (value.dirty || value.touched)) {\r\n <mat-error>value required</mat-error>\r\n } @if ($any(value).errors?.maxLength && (value.dirty || value.touched))\r\n {\r\n <mat-error>value too long</mat-error>\r\n }\r\n </mat-form-field>\r\n </div>\r\n <!-- buttons -->\r\n <div>\r\n <button\r\n type=\"button\"\r\n mat-icon-button\r\n matTooltip=\"Discard changes\"\r\n (click)=\"cancel()\"\r\n >\r\n <mat-icon class=\"mat-warn\">clear</mat-icon>\r\n </button>\r\n <button\r\n type=\"submit\"\r\n mat-icon-button\r\n matTooltip=\"Accept changes\"\r\n [disabled]=\"form.invalid || form.pristine\"\r\n >\r\n <mat-icon class=\"mat-primary\">check_circle</mat-icon>\r\n </button>\r\n </div>\r\n </fieldset>\r\n</form>\r\n","import {\r\n ChangeDetectorRef,\r\n Component,\r\n OnDestroy,\r\n computed,\r\n effect,\r\n inject,\r\n input,\r\n output,\r\n signal,\r\n} from '@angular/core';\r\nimport { FormControl, FormGroup, ReactiveFormsModule } from '@angular/forms';\r\nimport { Subscription } from 'rxjs';\r\n\r\nimport { MatDialog } from '@angular/material/dialog';\r\nimport { MatProgressBarModule } from '@angular/material/progress-bar';\r\nimport { MatButtonModule } from '@angular/material/button';\r\nimport { MatCheckboxModule } from '@angular/material/checkbox';\r\nimport { MatIconModule } from '@angular/material/icon';\r\nimport { MatTooltipModule } from '@angular/material/tooltip';\r\nimport { MatInputModule } from '@angular/material/input';\r\nimport { MatFormFieldModule } from '@angular/material/form-field';\r\nimport { MatMenuModule } from '@angular/material/menu';\r\nimport { MatSnackBar } from '@angular/material/snack-bar';\r\n\r\nimport { DialogService } from '@myrmidon/ngx-mat-tools';\r\nimport {\r\n BrowserTreeNodeComponent,\r\n PagedTreeStore,\r\n PageChangeRequest,\r\n} from '@myrmidon/paged-data-browsers';\r\n\r\nimport { ThesaurusPagedTreeFilterComponent } from '../thesaurus-paged-tree-filter/thesaurus-paged-tree-filter.component';\r\nimport {\r\n ThesaurusEntryNodeFilter,\r\n ThesaurusEntryPagedTreeNode,\r\n} from '../../services/static-thesaurus-paged-tree-store.service';\r\nimport {\r\n EditedThesEntry,\r\n ThesEntryEditorComponent,\r\n} from '../thesaurus-entry-editor/thesaurus-entry-editor.component';\r\nimport { EditableStaticThesaurusPagedTreeStoreService } from '../../services/editable-static-thesaurus-paged-tree-store.service';\r\n\r\n/**\r\n * An editable paged tree browser for thesaurus entries. Editing happens in memory\r\n * and when complete, the changes can be committed to the underlying data store\r\n * via the EditableStaticThesaurusPagedTreeStoreService.\r\n */\r\n@Component({\r\n selector: 'cadmus-editable-thesaurus-browser',\r\n imports: [\r\n ReactiveFormsModule,\r\n MatButtonModule,\r\n MatCheckboxModule,\r\n MatFormFieldModule,\r\n MatIconModule,\r\n MatInputModule,\r\n MatMenuModule,\r\n MatProgressBarModule,\r\n MatTooltipModule,\r\n ThesaurusPagedTreeFilterComponent,\r\n BrowserTreeNodeComponent,\r\n ],\r\n templateUrl: './editable-thesaurus-browser.component.html',\r\n styleUrls: ['./editable-thesaurus-browser.component.scss'],\r\n})\r\nexport class EditableThesaurusBrowserComponent implements OnDestroy {\r\n private _dialog = inject(MatDialog);\r\n private _snackBar = inject(MatSnackBar);\r\n private _dialogService = inject(DialogService);\r\n private _cdr = inject(ChangeDetectorRef);\r\n private _nodesSub?: Subscription;\r\n private _filterSub?: Subscription;\r\n private _changesSub?: Subscription;\r\n\r\n /**\r\n * The editable service to use to load the nodes.\r\n */\r\n public readonly service =\r\n input<EditableStaticThesaurusPagedTreeStoreService>();\r\n\r\n /**\r\n * True to show the tree root nodes filter.\r\n */\r\n public readonly hasRootFilter = input<boolean>(false);\r\n\r\n /**\r\n * Emitted when a node is clicked.\r\n */\r\n public readonly nodePick = output<ThesaurusEntryPagedTreeNode>();\r\n\r\n /**\r\n * Emitted when the changes state changes.\r\n */\r\n public readonly changesStateChange = output<boolean>();\r\n\r\n /**\r\n * The store instance, built from the service.\r\n */\r\n public readonly store = computed(() => {\r\n const service = this.service();\r\n if (!service) {\r\n return null;\r\n }\r\n return new PagedTreeStore<\r\n ThesaurusEntryPagedTreeNode,\r\n ThesaurusEntryNodeFilter\r\n >(service);\r\n });\r\n\r\n public readonly loading = signal<boolean>(false);\r\n public readonly selectedNode = signal<ThesaurusEntryPagedTreeNode | null>(\r\n null,\r\n );\r\n\r\n // Signals for reactive data binding (replacing observables with async pipe)\r\n public readonly nodes = signal<readonly ThesaurusEntryPagedTreeNode[]>([]);\r\n public readonly filter = signal<Readonly<ThesaurusEntryNodeFilter>>({});\r\n\r\n public debug: FormControl<boolean> = new FormControl(false, {\r\n nonNullable: true,\r\n });\r\n public hideLoc: FormControl<boolean> = new FormControl(false, {\r\n nonNullable: true,\r\n });\r\n public hideFilter: FormControl<boolean> = new FormControl(false, {\r\n nonNullable: true,\r\n });\r\n\r\n public label: FormControl<string | null> = new FormControl(null);\r\n public form = new FormGroup({\r\n label: this.label,\r\n });\r\n\r\n constructor() {\r\n // Use effect to react to service/store changes.\r\n effect(() => {\r\n const currentStore = this.store();\r\n const currentService = this.service();\r\n\r\n // Cleanup previous subscriptions\r\n this._nodesSub?.unsubscribe();\r\n this._filterSub?.unsubscribe();\r\n this._changesSub?.unsubscribe();\r\n\r\n if (!currentStore || !currentService) {\r\n this.nodes.set([]);\r\n this.filter.set({});\r\n return;\r\n }\r\n\r\n // Subscribe to store's observables and update signals.\r\n // markForCheck() is required because subscription callbacks run outside\r\n // Angular's reactive context, and some Angular apps use OnPush change\r\n // detection or zoneless mode.\r\n this._nodesSub = currentStore.nodes$.subscribe((nodes) => {\r\n this.nodes.set(nodes);\r\n this._cdr.markForCheck();\r\n });\r\n this._filterSub = currentStore.filter$.subscribe((filter) => {\r\n this.filter.set(filter);\r\n this._cdr.markForCheck();\r\n });\r\n\r\n // Subscribe to changes state\r\n this._changesSub = currentService.hasChanges$.subscribe((hasChanges) => {\r\n this.changesStateChange.emit(hasChanges);\r\n this._cdr.markForCheck();\r\n });\r\n\r\n // Load nodes if store is empty\r\n if (!currentStore.getNodes().length) {\r\n this.loading.set(true);\r\n currentStore.setFilter({}).finally(() => {\r\n this.loading.set(false);\r\n this._cdr.markForCheck();\r\n });\r\n }\r\n });\r\n }\r\n\r\n public ngOnDestroy(): void {\r\n this._nodesSub?.unsubscribe();\r\n this._filterSub?.unsubscribe();\r\n this._changesSub?.unsubscribe();\r\n }\r\n\r\n public reset(): void {\r\n const store = this.store();\r\n if (!store) return;\r\n\r\n this.loading.set(true);\r\n store.reset().finally(() => {\r\n this.loading.set(false);\r\n this._cdr.markForCheck();\r\n });\r\n }\r\n\r\n public onToggleExpanded(node: ThesaurusEntryPagedTreeNode): void {\r\n const store = this.store();\r\n if (!store) return;\r\n\r\n this.loading.set(true);\r\n if (node.expanded) {\r\n store.collapse(node.id).finally(() => {\r\n this.loading.set(false);\r\n this._cdr.markForCheck();\r\n });\r\n } else {\r\n store.expand(node.id).finally(() => {\r\n this.loading.set(false);\r\n this._cdr.markForCheck();\r\n });\r\n }\r\n }\r\n\r\n public onPageChangeRequest(request: PageChangeRequest): void {\r\n const store = this.store();\r\n if (!store) return;\r\n\r\n this.loading.set(true);\r\n store.changePage(request.node.id, request.paging.pageNumber).finally(() => {\r\n this.loading.set(false);\r\n this._cdr.markForCheck();\r\n });\r\n }\r\n\r\n public onFilterChange(\r\n filter: ThesaurusEntryNodeFilter | null | undefined,\r\n ): void {\r\n const store = this.store();\r\n if (!store) return;\r\n\r\n console.log('filter change', filter);\r\n this.loading.set(true);\r\n store.setFilter(filter || {}).finally(() => {\r\n this.loading.set(false);\r\n this._cdr.markForCheck();\r\n });\r\n }\r\n\r\n public onEditFilterRequest(node: ThesaurusEntryPagedTreeNode): void {\r\n const store = this.store();\r\n if (!store) return;\r\n\r\n const dialogRef = this._dialog.open(ThesaurusPagedTreeFilterComponent, {\r\n data: {\r\n filter: node.filter,\r\n },\r\n });\r\n dialogRef.afterClosed().subscribe((filter) => {\r\n if (filter === null) {\r\n store.setNodeFilter(node.id, null);\r\n } else if (filter) {\r\n store.setNodeFilter(node.id, filter);\r\n }\r\n });\r\n }\r\n\r\n public expandAll(): void {\r\n const store = this.store();\r\n if (!store) return;\r\n store.expandAll();\r\n }\r\n\r\n public collapseAll(): void {\r\n const store = this.store();\r\n if (!store) return;\r\n store.collapseAll();\r\n }\r\n\r\n public clear(): void {\r\n const store = this.store();\r\n if (!store) return;\r\n store.clear();\r\n }\r\n\r\n public onNodeClick(node: ThesaurusEntryPagedTreeNode): void {\r\n this.selectedNode.set(node);\r\n if (!node.hasChildren) {\r\n this.nodePick.emit(node);\r\n }\r\n }\r\n\r\n public findLabels(): void {\r\n const store = this.store();\r\n if (!store || !this.label.value) return;\r\n store.findLabels(this.label.value);\r\n }\r\n\r\n public removeHilites(): void {\r\n const store = this.store();\r\n if (!store) return;\r\n store.removeHilites();\r\n }\r\n\r\n // editing operations\r\n private editEntry(entry: EditedThesEntry): Promise<EditedThesEntry | null> {\r\n return new Promise((resolve) => {\r\n const dialogRef = this._dialog.open(ThesEntryEditorComponent, {\r\n data: entry,\r\n });\r\n\r\n dialogRef.afterClosed().subscribe((result) => {\r\n resolve(result);\r\n });\r\n });\r\n }\r\n\r\n public async addChild(): Promise<void> {\r\n const store = this.store();\r\n const selected = this.selectedNode();\r\n if (!store || !selected) {\r\n this._snackBar.open('Please select a node first', 'Close', {\r\n duration: 2000,\r\n });\r\n return;\r\n }\r\n\r\n // get the current entries to check for duplicates\r\n const currentService = this.service();\r\n if (!currentService) return;\r\n\r\n // determine the parent ID for the new child\r\n const parentKey = selected.key; // original entry ID\r\n\r\n // edit the new entry\r\n const newEntry = await this.editEntry({\r\n id: '',\r\n value: '',\r\n hierarchical: true,\r\n parentId: parentKey,\r\n idExists: (id: string) =>\r\n currentService.getCurrentEntries().some((e) => e.id === id),\r\n });\r\n if (!newEntry) {\r\n return;\r\n }\r\n\r\n store\r\n .addChild(selected.id, {\r\n label: newEntry.value,\r\n y: 0, // will be calculated by the store\r\n x: 0, // will be calculated by the store\r\n tag: selected.tag,\r\n })\r\n .then((result) => {\r\n if (result) {\r\n // update the temporary node with the user-provided ID,\r\n // this will be handled in the service's nodeToEntry method\r\n (result as any)._userProvidedId = newEntry.id;\r\n this._snackBar.open('Child added successfully', 'Close', {\r\n duration: 2000,\r\n });\r\n }\r\n });\r\n }\r\n\r\n public async addSibling(): Promise<void> {\r\n const store = this.store();\r\n const selected = this.selectedNode();\r\n if (!store || !selected) {\r\n this._snackBar.open('Please select a node first', 'Close', {\r\n duration: 2000,\r\n });\r\n return;\r\n }\r\n\r\n // get the current entries to check for duplicates\r\n const currentService = this.service();\r\n if (!currentService) return;\r\n\r\n const selectedKey = (selected as any).key; // original entry ID\r\n\r\n // determine the parent ID for the new sibling\r\n const selectedParts = selectedKey.split('.');\r\n const parentKey =\r\n selectedParts.length > 1 ? selectedParts.slice(0, -1).join('.') : '';\r\n\r\n const newEntry = await this.editEntry({\r\n id: '',\r\n value: '',\r\n hierarchical: true,\r\n parentId: parentKey,\r\n idExists: (id: string) =>\r\n currentService.getCurrentEntries().some((e) => e.id === id),\r\n });\r\n if (!newEntry) {\r\n return;\r\n }\r\n\r\n // check that the new ID has the same depth\r\n if (newEntry.id.split('.').length !== selectedParts.length) {\r\n this._snackBar.open(\r\n `Sibling must have same depth as \"${selectedKey}\"`,\r\n 'Close',\r\n { duration: 3000 },\r\n );\r\n return;\r\n }\r\n\r\n store\r\n .addSibling(selected.id, {\r\n label: newEntry.value,\r\n tag: selected.tag,\r\n })\r\n .then((result) => {\r\n if (result) {\r\n // update the temporary node with the user-provided ID\r\n (result as any)._userProvidedId = newEntry.id;\r\n this._snackBar.open('Sibling added successfully', 'Close', {\r\n duration: 2000,\r\n });\r\n }\r\n });\r\n }\r\n\r\n public removeNode(): void {\r\n const store = this.store();\r\n const selected = this.selectedNode();\r\n if (!store || !selected) {\r\n this._snackBar.open('Please select a node first', 'Close', {\r\n duration: 2000,\r\n });\r\n return;\r\n }\r\n\r\n const selectedKey = (selected as any).key || `temp_${selected.id}`;\r\n this._dialogService\r\n .confirm(\r\n 'Confirm Deletion',\r\n `Delete \"${selectedKey}\" (${selected.label}) and all its descendants?`,\r\n )\r\n .subscribe((result) => {\r\n if (!result) {\r\n return;\r\n }\r\n store.removeNode(selected.id).then((result) => {\r\n if (result) {\r\n this.selectedNode.set(null);\r\n this._snackBar.open('Node removed successfully', 'Close', {\r\n duration: 2000,\r\n });\r\n }\r\n });\r\n });\r\n }\r\n\r\n public async editNode(): Promise<void> {\r\n const currentService = this.service();\r\n if (!currentService) return;\r\n\r\n const store = this.store();\r\n const selected = this.selectedNode();\r\n if (!store || !selected) {\r\n this._snackBar.open('Please select a node first', 'Close', {\r\n duration: 2000,\r\n });\r\n return;\r\n }\r\n\r\n const selectedKey = selected.key;\r\n const isNewNode = selected.id < 0; // temporary ID means it's a new node\r\n\r\n const newEntry = await this.editEntry({\r\n id: selectedKey || '',\r\n value: selected.label,\r\n idLocked: !isNewNode,\r\n idExists: (id: string) =>\r\n currentService.getCurrentEntries().some((entry) => entry.id === id),\r\n });\r\n if (!newEntry) return;\r\n\r\n store\r\n .replaceNode(selected.id, {\r\n label: newEntry.value,\r\n tag: selected.tag,\r\n })\r\n .then((result) => {\r\n if (result) {\r\n // update the temporary node with the user-provided ID if it's a new node\r\n if (isNewNode) {\r\n (result as any)._userProvidedId = newEntry.id;\r\n }\r\n this._snackBar.open('Node updated successfully', 'Close', {\r\n duration: 2000,\r\n });\r\n }\r\n });\r\n }\r\n}\r\n","<div id=\"container\">\r\n <!-- filters -->\r\n <div id=\"filters\" class=\"form-row\">\r\n <form [formGroup]=\"form\" (submit)=\"findLabels()\">\r\n <fieldset>\r\n <legend>finder</legend>\r\n <div class=\"form-row\">\r\n <mat-form-field>\r\n <mat-label>label</mat-label>\r\n <input matInput [formControl]=\"label\" />\r\n @if ($any(label).errors?.required && (label.dirty || label.touched))\r\n {\r\n <mat-error>label required</mat-error>\r\n }\r\n </mat-form-field>\r\n <div class=\"form-row\" style=\"gap: 0\">\r\n <button type=\"submit\" mat-icon-button class=\"mat-primary\">\r\n <mat-icon>search</mat-icon>\r\n </button>\r\n <button\r\n type=\"button\"\r\n mat-icon-button\r\n (click)=\"removeHilites()\"\r\n class=\"mat-warn\"\r\n >\r\n <mat-icon>clear</mat-icon>\r\n </button>\r\n </div>\r\n </div>\r\n </fieldset>\r\n </form>\r\n @if (hasRootFilter()) {\r\n <fieldset>\r\n <legend>global filter</legend>\r\n <cadmus-thesaurus-paged-tree-filter\r\n [filter]=\"filter()\"\r\n (filterChange)=\"onFilterChange($event)\"\r\n />\r\n </fieldset>\r\n }\r\n </div>\r\n\r\n <!-- editing actions -->\r\n <div class=\"editing-actions\">\r\n <button\r\n type=\"button\"\r\n mat-raised-button\r\n color=\"primary\"\r\n [disabled]=\"!selectedNode()\"\r\n [matMenuTriggerFor]=\"addMenu\"\r\n >\r\n <mat-icon>add</mat-icon>\r\n add\r\n </button>\r\n\r\n <mat-menu #addMenu=\"matMenu\">\r\n <button type=\"button\" mat-menu-item (click)=\"addChild()\">\r\n <mat-icon>subdirectory_arrow_right</mat-icon>\r\n add child\r\n </button>\r\n <button type=\"button\" mat-menu-item (click)=\"addSibling()\">\r\n <mat-icon>arrow_right_alt</mat-icon>\r\n add sibling\r\n </button>\r\n </mat-menu>\r\n\r\n <button\r\n type=\"button\"\r\n mat-stroked-button\r\n color=\"accent\"\r\n [disabled]=\"!selectedNode()\"\r\n (click)=\"editNode()\"\r\n >\r\n <mat-icon>edit</mat-icon>\r\n edit\r\n </button>\r\n\r\n <button\r\n type=\"button\"\r\n mat-stroked-button\r\n color=\"warn\"\r\n [disabled]=\"!selectedNode()\"\r\n (click)=\"removeNode()\"\r\n >\r\n <mat-icon>delete</mat-icon>\r\n remove\r\n </button>\r\n\r\n @if (selectedNode()) {\r\n <span class=\"selected-info\"> selected: {{ selectedNode()!.label }} </span>\r\n }\r\n </div>\r\n\r\n <!-- tree -->\r\n <div id=\"tree\">\r\n <!-- progress -->\r\n @if (loading()) {\r\n <div>\r\n <mat-progress-bar mode=\"indeterminate\"></mat-progress-bar>\r\n </div>\r\n }\r\n <!-- nodes -->\r\n @if (nodes(); as nodeList) {\r\n <div>\r\n @for (node of nodeList; track node.id; let i = $index) {\r\n <div\r\n class=\"button-row\"\r\n [class.hilite]=\"node.hilite\"\r\n [class.selected]=\"selectedNode()?.id === node.id\"\r\n (click)=\"onNodeClick(node)\"\r\n >\r\n <pdb-browser-tree-node\r\n [node]=\"node\"\r\n [debug]=\"debug.value\"\r\n [paging]=\"\r\n node.expanded &&\r\n i + 1 < nodeList.length &&\r\n nodeList[i + 1].paging.pageCount > 1\r\n ? nodeList[i + 1].paging\r\n : undefined\r\n \"\r\n [hideFilter]=\"hideFilter.value\"\r\n [hideLoc]=\"hideLoc.value\"\r\n (toggleExpandedRequest)=\"onToggleExpanded($any($event))\"\r\n (changePageRequest)=\"onPageChangeRequest($event)\"\r\n (editNodeFilterRequest)=\"onEditFilterRequest($any($event))\"\r\n />\r\n </div>\r\n }\r\n </div>\r\n }\r\n <div class=\"form-row\">\r\n <mat-checkbox [formControl]=\"debug\">debug</mat-checkbox>\r\n <mat-checkbox [formControl]=\"hideFilter\">no filter</mat-checkbox>\r\n <mat-checkbox [formControl]=\"hideLoc\">no loc.</mat-checkbox>\r\n <button\r\n type=\"button\"\r\n mat-flat-button\r\n (click)=\"collapseAll()\"\r\n style=\"margin-left: 24px\"\r\n >\r\n collapse\r\n </button>\r\n </div>\r\n </div>\r\n</div>\r\n","import { Observable, of } from 'rxjs';\r\n\r\nimport { DataPage } from '@myrmidon/ngx-tools';\r\nimport {\r\n PagedTreeNode,\r\n PagedTreeStoreService,\r\n TreeNodeFilter,\r\n} from '@myrmidon/paged-data-browsers';\r\nimport { ThesaurusEntry } from '@myrmidon/cadmus-core';\r\n\r\n/**\r\n * The filter for thesaurus entry nodes. The only filtered property is\r\n * the node's label.\r\n */\r\nexport interface ThesaurusEntryNodeFilter extends TreeNodeFilter {\r\n label?: string;\r\n}\r\n\r\n/**\r\n * The tree node for thesaurus entries in a paging tree node.\r\n */\r\nexport interface ThesaurusEntryPagedTreeNode extends PagedTreeNode<ThesaurusEntryNodeFilter> {\r\n key: string; // entry.id\r\n value: string; // entry.value (not rendered; the rendered value is in label)\r\n}\r\n\r\n/**\r\n * A label rendering function which removes from a label\r\n * all the characters past the last colon, trimming the result.\r\n * This is a typical rendering when dealing with hierarchical\r\n * thesaurus entries, e.g. \"furniture: table: color\", where\r\n * we can shorten the label to just \"color\", as \"furniture\"\r\n * and \"table\" are its ancestors.\r\n */\r\nexport function renderLabelFromLastColon(label: string): string {\r\n if (!label) {\r\n return label;\r\n }\r\n const i = label.lastIndexOf(':');\r\n return i > -1 && i + 1 < label.length ? label.substring(i + 1).trim() : label;\r\n}\r\n\r\ninterface NumberedEntry extends ThesaurusEntry {\r\n n: number;\r\n}\r\n\r\n/**\r\n * A static paged tree store service for thesaurus entries.\r\n * This builds tree nodes from all the thesaurus entries from a specific\r\n * thesaurus, assuming that entry IDs are hierarchical and\r\n * separated by dots (.).\r\n * Nodes are received all at once for a thesaurus, so this is essentially\r\n * an adapter to the paged tree store service interface.\r\n * The entries are a flat list where hierarchy is implied by the IDs:\r\n * for instance, \"animal.mammal.dog\" is a child of \"animal.mammal\"\r\n * which is a child of \"animal\". Numeric IDs are added to each node\r\n * based on the order of entries to ensure stable IDs.\r\n * The label of each node can be rendered as-is from the entry value,\r\n * or a custom rendering function can be provided to the constructor.\r\n */\r\nexport class StaticThesaurusPagedTreeStoreService implements PagedTreeStoreService<ThesaurusEntryNodeFilter> {\r\n private _nodes: ThesaurusEntryPagedTreeNode[] = [];\r\n private _built = false;\r\n private readonly _entries: NumberedEntry[];\r\n\r\n /**\r\n * Constructor.\r\n * @param entries The thesaurus entries.\r\n * @param _renderLabel An optional function to render the label\r\n * of each node.\r\n */\r\n constructor(\r\n entries: ThesaurusEntry[],\r\n private _renderLabel?: (label: string) => string,\r\n ) {\r\n // assign a number to each entry for stable IDs\r\n this._entries = entries.map((entry, index) => ({\r\n ...entry,\r\n n: index + 1,\r\n }));\r\n }\r\n\r\n /**\r\n * Ensure that nodes have been built from entries.\r\n */\r\n private ensureNodes(): void {\r\n // lazily build the nodes only once\r\n if (this._built) {\r\n return;\r\n }\r\n\r\n // create a map of sibling numbers (x) where:\r\n // - key=node.id (0 is used for the virtual root);\r\n // - value=max x value for that parent.\r\n const xMap = new Map<number, number>();\r\n\r\n // build nodes from entries\r\n for (const entry of this._entries) {\r\n const hasDot = entry.id.includes('.');\r\n const keyParts = entry.id.split('.');\r\n\r\n // create the node\r\n const node: ThesaurusEntryPagedTreeNode = {\r\n id: entry.n,\r\n label:\r\n hasDot && this._renderLabel\r\n ? this._renderLabel(entry.value)\r\n : entry.value,\r\n key: entry.id,\r\n value: entry.value,\r\n paging: { pageNumber: 0, pageCount: 0, total: 0 },\r\n y: hasDot ? keyParts.length : 1,\r\n x: 0, // will be set later\r\n parentId: undefined, // will be set later\r\n hasChildren: false, // will be set later\r\n };\r\n\r\n // if it has a dot, find its parent and set parentId\r\n if (hasDot) {\r\n // build the parent key\r\n const parentKey = keyParts.slice(0, keyParts.length - 1).join('.');\r\n // find the parent node with that key\r\n const parentNode = this._nodes.find((n) => n.key === parentKey);\r\n // if found, set parentId and x in child and hasChildren in parent\r\n if (parentNode) {\r\n node.parentId = parentNode.id;\r\n parentNode.hasChildren = true;\r\n if (xMap.has(parentNode.id)) {\r\n xMap.set(parentNode.id, xMap.get(parentNode.id)! + 1);\r\n } else {\r\n xMap.set(parentNode.id, 1);\r\n }\r\n node.x = xMap.get(parentNode.id)!;\r\n } else {\r\n // parent not found, treat as root\r\n if (xMap.has(0)) {\r\n xMap.set(0, xMap.get(0)! + 1);\r\n } else {\r\n xMap.set(0, 1);\r\n }\r\n node.x = xMap.get(0)!;\r\n }\r\n } else {\r\n // else it's a root node\r\n if (xMap.has(0)) {\r\n xMap.set(0, xMap.get(0)! + 1);\r\n } else {\r\n xMap.set(0, 1);\r\n }\r\n node.x = xMap.get(0)!;\r\n }\r\n\r\n this._nodes.push(node);\r\n }\r\n\r\n this._built = true;\r\n }\r\n\r\n /**\r\n * Get the specified page of nodes.\r\n * @param filter The filter.\r\n * @param pageNumber The page number.\r\n * @param pageSize The page size.\r\n * @param hasMockRoot Whether the root node is a mock node. Not used here.\r\n */\r\n public getNodes(\r\n filter: ThesaurusEntryNodeFilter,\r\n pageNumber: number,\r\n pageSize: number,\r\n hasMockRoot?: boolean,\r\n ): Observable<DataPage<ThesaurusEntryPagedTreeNode>> {\r\n console.log('[StaticThesaurusService] getNodes called, entries count:', this._entries.length, 'filter:', filter);\r\n this.ensureNodes();\r\n console.log('[StaticThesaurusService] after ensureNodes, _nodes count:', this._nodes.length);\r\n\r\n // apply filtering\r\n let nodes = this._nodes.filter((n) => {\r\n // filter by parentId (required by tree structure)\r\n if (filter.parentId !== undefined && filter.parentId !== null) {\r\n if (n.parentId !== filter.parentId) {\r\n return false;\r\n }\r\n } else {\r\n if (n.parentId) {\r\n return false;\r\n }\r\n }\r\n\r\n // filter by label\r\n if (filter.label) {\r\n const filterValue = filter.label.toLowerCase();\r\n if (!n.label.toLowerCase().includes(filterValue)) {\r\n return false;\r\n }\r\n }\r\n return true;\r\n });\r\n\r\n // page and return\r\n const paged = nodes.slice(\r\n (pageNumber - 1) * pageSize,\r\n pageNumber * pageSize,\r\n );\r\n console.log('[StaticThesaurusService] getNodes returning', paged.length, 'items (filtered from', nodes.length, 'total root nodes)');\r\n return of({\r\n items: paged,\r\n pageNumber: pageNumber,\r\n pageSize: pageSize,\r\n pageCount: Math.ceil(nodes.length / pageSize),\r\n total: nodes.length,\r\n });\r\n }\r\n}\r\n","import {\r\n ChangeDetectorRef,\r\n Component,\r\n OnDestroy,\r\n computed,\r\n effect,\r\n inject,\r\n input,\r\n output,\r\n signal,\r\n} from '@angular/core';\r\nimport { FormControl, FormGroup, ReactiveFormsModule } from '@angular/forms';\r\nimport { Subscription } from 'rxjs';\r\n\r\nimport { MatDialog } from '@angular/material/dialog';\r\nimport { MatProgressBarModule } from '@angular/material/progress-bar';\r\nimport { MatButtonModule } from '@angular/material/button';\r\nimport { MatCheckboxModule } from '@angular/material/checkbox';\r\nimport { MatIconModule } from '@angular/material/icon';\r\nimport { MatTooltipModule } from '@angular/material/tooltip';\r\nimport { MatInputModule } from '@angular/material/input';\r\nimport { MatFormFieldModule } from '@angular/material/form-field';\r\n\r\nimport {\r\n BrowserTreeNodeComponent,\r\n PagedTreeStore,\r\n PageChangeRequest,\r\n} from '@myrmidon/paged-data-browsers';\r\n\r\nimport {\r\n renderLabelFromLastColon,\r\n StaticThesaurusPagedTreeStoreService,\r\n ThesaurusEntryNodeFilter,\r\n ThesaurusEntryPagedTreeNode,\r\n} from '../../services/static-thesaurus-paged-tree-store.service';\r\nimport { ThesaurusPagedTreeFilterComponent } from '../thesaurus-paged-tree-filter/thesaurus-paged-tree-filter.component';\r\n\r\n/**\r\n * A readonly paged tree browser for thesaurus entries. This is a lower-level component\r\n * used as an adapter between the generic paged tree browser and the thesaurus entries\r\n * data model.\r\n */\r\n@Component({\r\n selector: 'cadmus-thesaurus-browser',\r\n imports: [\r\n ReactiveFormsModule,\r\n MatButtonModule,\r\n MatCheckboxModule,\r\n MatFormFieldModule,\r\n MatIconModule,\r\n MatInputModule,\r\n MatProgressBarModule,\r\n MatTooltipModule,\r\n ThesaurusPagedTreeFilterComponent,\r\n BrowserTreeNodeComponent,\r\n ],\r\n templateUrl: './thesaurus-browser.component.html',\r\n styleUrl: './thesaurus-browser.component.scss',\r\n})\r\nexport class ThesaurusBrowserComponent implements OnDestroy {\r\n private _dialog = inject(MatDialog);\r\n private _cdr = inject(ChangeDetectorRef);\r\n private _nodesSub?: Subscription;\r\n private _filterSub?: Subscription;\r\n\r\n /**\r\n * The service to use to load the nodes.\r\n */\r\n public readonly service = input<StaticThesaurusPagedTreeStoreService>(\r\n new StaticThesaurusPagedTreeStoreService([], renderLabelFromLastColon),\r\n );\r\n\r\n /**\r\n * Emitted when a node is clicked.\r\n */\r\n public readonly nodePick = output<ThesaurusEntryPagedTreeNode>();\r\n\r\n /**\r\n * The store instance, built from the service.\r\n */\r\n public readonly store = computed(() => {\r\n const service = this.service();\r\n return new PagedTreeStore<\r\n ThesaurusEntryPagedTreeNode,\r\n ThesaurusEntryNodeFilter\r\n >(service);\r\n });\r\n\r\n public readonly loading = signal<boolean>(false);\r\n\r\n // Signals for reactive data binding (replacing observables with async pipe)\r\n public readonly nodes = signal<readonly ThesaurusEntryPagedTreeNode[]>([]);\r\n public readonly filter = signal<Readonly<ThesaurusEntryNodeFilter>>({});\r\n\r\n public debug: FormControl<boolean> = new FormControl(false, {\r\n nonNullable: true,\r\n });\r\n public hideLoc: FormControl<boolean> = new FormControl(false, {\r\n nonNullable: true,\r\n });\r\n public hideFilter: FormControl<boolean> = new FormControl(false, {\r\n nonNullable: true,\r\n });\r\n\r\n public label: FormControl<string | null> = new FormControl(null);\r\n public form = new FormGroup({\r\n label: this.label,\r\n });\r\n\r\n constructor() {\r\n // Use effect to react to service/store changes.\r\n effect(() => {\r\n const currentStore = this.store();\r\n console.log(\r\n '[ThesaurusBrowser] effect triggered, store:',\r\n currentStore ? 'exists' : 'null',\r\n );\r\n\r\n // Unsubscribe from previous store's observables\r\n this._nodesSub?.unsubscribe();\r\n this._filterSub?.unsubscribe();\r\n\r\n // Subscribe to new store's observables and update signals.\r\n // markForCheck() is required because subscription callbacks run outside\r\n // Angular's reactive context, and some Angular apps use OnPush change\r\n // detection or zoneless mode.\r\n this._nodesSub = currentStore.nodes$.subscribe((nodes) => {\r\n console.log(\r\n '[ThesaurusBrowser] nodes$ emitted, count:',\r\n nodes.length,\r\n 'nodes:',\r\n nodes.map((n) => n.label).slice(0, 3),\r\n );\r\n this.nodes.set(nodes);\r\n console.log(\r\n '[ThesaurusBrowser] nodes signal set, calling markForCheck',\r\n );\r\n this._cdr.markForCheck();\r\n });\r\n this._filterSub = currentStore.filter$.subscribe((filter) => {\r\n console.log('[ThesaurusBrowser] filter$ emitted:', filter);\r\n this.filter.set(filter);\r\n this._cdr.markForCheck();\r\n });\r\n\r\n // Load nodes if store is empty\r\n const storeNodes = currentStore.getNodes();\r\n console.log(\r\n '[ThesaurusBrowser] store.getNodes() count:',\r\n storeNodes.length,\r\n );\r\n if (!storeNodes.length) {\r\n console.log(\r\n '[ThesaurusBrowser] store is empty, calling setFilter to load',\r\n );\r\n this.loading.set(true);\r\n currentStore\r\n .setFilter({})\r\n .then(() => {\r\n console.log(\r\n '[ThesaurusBrowser] setFilter resolved, store nodes:',\r\n currentStore.getNodes().length,\r\n );\r\n })\r\n .finally(() => {\r\n console.log(\r\n '[ThesaurusBrowser] setFilter finally, setting loading=false',\r\n );\r\n this.loading.set(false);\r\n this._cdr.markForCheck();\r\n });\r\n }\r\n });\r\n }\r\n\r\n public ngOnDestroy(): void {\r\n this._nodesSub?.unsubscribe();\r\n this._filterSub?.unsubscribe();\r\n }\r\n\r\n public reset(): void {\r\n this.loading.set(true);\r\n this.store()\r\n .reset()\r\n .finally(() => {\r\n this.loading.set(false);\r\n this._cdr.markForCheck();\r\n });\r\n }\r\n\r\n public onToggleExpanded(node: ThesaurusEntryPagedTreeNode): void {\r\n this.loading.set(true);\r\n if (node.expanded) {\r\n this.store()\r\n .collapse(node.id)\r\n .finally(() => {\r\n this.loading.set(false);\r\n this._cdr.markForCheck();\r\n });\r\n } else {\r\n this.store()\r\n .expand(node.id)\r\n .finally(() => {\r\n this.loading.set(false);\r\n this._cdr.markForCheck();\r\n });\r\n }\r\n }\r\n\r\n public onPageChangeRequest(request: PageChangeRequest): void {\r\n this.loading.set(true);\r\n this.store()\r\n .changePage(request.node.id, request.paging.pageNumber)\r\n .finally(() => {\r\n this.loading.set(false);\r\n this._cdr.markForCheck();\r\n });\r\n }\r\n\r\n public onFilterChange(\r\n filter: ThesaurusEntryNodeFilter | null | undefined,\r\n ): void {\r\n console.log('filter change', filter);\r\n this.loading.set(true);\r\n this.store()\r\n .setFilter(filter || {})\r\n .finally(() => {\r\n this.loading.set(false);\r\n this._cdr.markForCheck();\r\n });\r\n }\r\n\r\n public onEditFilterRequest(node: ThesaurusEntryPagedTreeNode): void {\r\n const dialogRef = this._dialog.open(ThesaurusPagedTreeFilterComponent, {\r\n data: {\r\n filter: node.filter,\r\n },\r\n });\r\n dialogRef.afterClosed().subscribe((filter) => {\r\n // undefined = user dismissed without changes\r\n if (filter === null) {\r\n this.store().setNodeFilter(node.id, null);\r\n } else if (filter) {\r\n this.store().setNodeFilter(node.id, filter);\r\n }\r\n });\r\n }\r\n\r\n public expandAll(): void {\r\n this.store().expandAll();\r\n }\r\n\r\n public collapseAll(): void {\r\n this.store().collapseAll();\r\n }\r\n\r\n public clear(): void {\r\n this.store().clear();\r\n }\r\n\r\n public onNodeClick(node: ThesaurusEntryPagedTreeNode): void {\r\n if (!node.hasChildren) {\r\n this.nodePick.emit(node);\r\n }\r\n }\r\n\r\n public findLabels(): void {\r\n if (!this.label.value) {\r\n return;\r\n }\r\n this.store().findLabels(this.label.value);\r\n }\r\n\r\n public removeHilites(): void {\r\n this.store().removeHilites();\r\n }\r\n}\r\n","<div id=\"container\">\r\n <!-- filters -->\r\n <div id=\"filters\" class=\"form-row\">\r\n <form [formGroup]=\"form\" (submit)=\"findLabels()\" class=\"form-row\">\r\n <mat-form-field>\r\n <mat-label>label</mat-label>\r\n <input matInput [formControl]=\"label\" />\r\n @if ($any(label).errors?.required && (label.dirty || label.touched)) {\r\n <mat-error>label required</mat-error>\r\n }\r\n </mat-form-field>\r\n <button type=\"submit\" mat-icon-button class=\"mat-primary\">\r\n <mat-icon>search</mat-icon>\r\n </button>\r\n <button\r\n type=\"button\"\r\n mat-icon-button\r\n (click)=\"removeHilites()\"\r\n class=\"mat-warn\"\r\n >\r\n <mat-icon>clear</mat-icon>\r\n </button>\r\n </form>\r\n <fieldset>\r\n <legend>filter</legend>\r\n <cadmus-thesaurus-paged-tree-filter\r\n [filter]=\"filter()\"\r\n (filterChange)=\"onFilterChange($event)\"\r\n />\r\n </fieldset>\r\n </div>\r\n\r\n <!-- tree -->\r\n <div id=\"tree\">\r\n <!-- progress -->\r\n @if (loading()) {\r\n <div>\r\n <mat-progress-bar mode=\"indeterminate\"></mat-progress-bar>\r\n </div>\r\n }\r\n <!-- nodes -->\r\n @if (nodes(); as nodeList) {\r\n <div>\r\n @for (node of nodeList; track node.id; let i = $index) {\r\n <div class=\"button-row\" [class.hilite]=\"node.hilite\">\r\n <pdb-browser-tree-node\r\n [node]=\"node\"\r\n [debug]=\"debug.value\"\r\n [paging]=\"\r\n node.expanded &&\r\n i + 1 < nodeList.length &&\r\n nodeList[i + 1].paging.pageCount > 1\r\n ? nodeList[i + 1].paging\r\n : undefined\r\n \"\r\n [hideFilter]=\"hideFilter.value\"\r\n [hideLoc]=\"hideLoc.value\"\r\n (toggleExpandedRequest)=\"onToggleExpanded($any($event))\"\r\n (changePageRequest)=\"onPageChangeRequest($event)\"\r\n (editNodeFilterRequest)=\"onEditFilterRequest($any($event))\"\r\n />\r\n @if (!node.hasChildren) {\r\n <button type=\"button\" mat-icon-button (click)=\"onNodeClick(node)\">\r\n <mat-icon class=\"mat-primary\">check_circle</mat-icon>\r\n </button>\r\n }\r\n </div>\r\n }\r\n </div>\r\n }\r\n <div class=\"form-row\">\r\n <mat-checkbox [formControl]=\"debug\">debug</mat-checkbox>\r\n <mat-checkbox [formControl]=\"hideFilter\">no filter</mat-checkbox>\r\n <mat-checkbox [formControl]=\"hideLoc\">no loc.</mat-checkbox>\r\n <button\r\n type=\"button\"\r\n mat-flat-button\r\n (click)=\"collapseAll()\"\r\n style=\"margin-left: 24px\"\r\n >\r\n collapse\r\n </button>\r\n </div>\r\n </div>\r\n</div>\r\n","import { Component, computed, effect, input, output, Type } from '@angular/core';\r\nimport { FormsModule, ReactiveFormsModule } from '@angular/forms';\r\nimport { ThesaurusEntry } from '@myrmidon/cadmus-core';\r\n\r\nimport { ThesaurusPagedTreeFilterComponent } from '../thesaurus-paged-tree-filter/thesaurus-paged-tree-filter.component';\r\nimport {\r\n renderLabelFromLastColon,\r\n StaticThesaurusPagedTreeStoreService,\r\n ThesaurusEntryPagedTreeNode,\r\n} from '../../services/static-thesaurus-paged-tree-store.service';\r\nimport { ThesaurusBrowserComponent } from '../thesaurus-browser/thesaurus-browser.component';\r\n\r\n/**\r\n * Thesaurus tree component.\r\n * This component displays a set of hierarchical thesaurus entries\r\n * in a tree, provided that each entry marks its hierarchy with\r\n * dots. For instance, say you have the hierarchy \"furniture\" -\r\n * \"type\" - \"color\". You might have an entry whose ID is\r\n * \"furniture.table.red\", with a sibling \"furniture.table.green\",\r\n * and a parent \"furniture.table\". This parent is there only to\r\n * provide a label to the parent node, but only leaf nodes can be\r\n * picked by the user. Whenever one is picked, the entryChange\r\n * event is emitted.\r\n */\r\n@Component({\r\n selector: 'cadmus-thesaurus-tree',\r\n templateUrl: './thesaurus-tree.component.html',\r\n styleUrls: ['./thesaurus-tree.component.css'],\r\n imports: [FormsModule, ReactiveFormsModule, ThesaurusBrowserComponent],\r\n})\r\nexport class ThesaurusTreeComponent {\r\n /**\r\n * The thesaurus entries.\r\n */\r\n public readonly entries = input<ThesaurusEntry[]>();\r\n\r\n /**\r\n * The optional node label rendering function. Note that even if you\r\n * specify a label renderer function, the entryChange event always\r\n * emits the original label.\r\n */\r\n public readonly renderLabel = input<(label: string) => string>(\r\n renderLabelFromLastColon,\r\n );\r\n\r\n /**\r\n * Fired when a thesaurus entry is selected.\r\n */\r\n public readonly entryChange = output<ThesaurusEntry>();\r\n\r\n /**\r\n * The tree store service, dependent on the current entries and renderLabel.\r\n */\r\n public readonly service = computed<StaticThesaurusPagedTreeStoreService>(() => {\r\n const entries = this.entries();\r\n console.log('[ThesaurusTree] service computed, entries count:', entries?.length ?? 0);\r\n return new StaticThesaurusPagedTreeStoreService(\r\n entries || [],\r\n this.renderLabel(),\r\n );\r\n });\r\n\r\n /**\r\n * Debug: tracks when the template condition would show the browser.\r\n */\r\n public readonly shouldShowBrowser = computed(() => {\r\n const svc = this.service();\r\n const entries = this.entries();\r\n const result = !!(svc && entries?.length);\r\n console.log('[ThesaurusTree] shouldShowBrowser computed:', result, '(service:', !!svc, ', entries:', entries?.length ?? 0, ')');\r\n return result;\r\n });\r\n\r\n constructor() {\r\n // Debug effect to trace when entries input changes\r\n effect(() => {\r\n const entries = this.entries();\r\n const svc = this.service();\r\n console.log('[ThesaurusTree] effect: entries changed, count:', entries?.length ?? 0, 'service:', svc ? 'exists' : 'null');\r\n });\r\n }\r\n\r\n /**\r\n * The filter component class to use.\r\n */\r\n public readonly filterComponent: Type<ThesaurusPagedTreeFilterComponent> =\r\n ThesaurusPagedTreeFilterComponent;\r\n\r\n public onNodePick(node: ThesaurusEntryPagedTreeNode): void {\r\n // only allow selection of leaf nodes (nodes without children)\r\n if (!node.hasChildren) {\r\n // find the original entry\r\n const entry = this.entries()?.find((e) => e.id === node.key);\r\n if (entry) {\r\n this.entryChange.emit(entry);\r\n }\r\n }\r\n }\r\n}\r\n","<div>\r\n <!-- tree -->\r\n @if (shouldShowBrowser()) {\r\n <div class=\"tree-wrapper\">\r\n <cadmus-thesaurus-browser\r\n [service]=\"service()\"\r\n (nodePick)=\"onNodePick($event)\"\r\n />\r\n </div>\r\n }\r\n</div>\r\n","import {\r\n Component,\r\n computed,\r\n effect,\r\n input,\r\n model,\r\n untracked,\r\n} from '@angular/core';\r\nimport { ThesaurusEntry } from '@myrmidon/cadmus-core';\r\nimport {\r\n FormBuilder,\r\n FormControl,\r\n FormGroup,\r\n ReactiveFormsModule,\r\n Validators,\r\n} from '@angular/forms';\r\n\r\nimport {\r\n CdkDragDrop,\r\n CdkDropList,\r\n CdkDrag,\r\n moveItemInArray,\r\n} from '@angular/cdk/drag-drop';\r\nimport {\r\n MatChipListbox,\r\n MatChipOption,\r\n MatChipRemove,\r\n} from '@angular/material/chips';\r\nimport { MatExpansionPanel } from '@angular/material/expansion';\r\nimport { MatFormField } from '@angular/material/form-field';\r\nimport { MatIcon } from '@angular/material/icon';\r\nimport { MatIconButton } from '@angular/material/button';\r\nimport { MatInput } from '@angular/material/input';\r\nimport { MatTooltip } from '@angular/material/tooltip';\r\n\r\nimport { renderLabelFromLastColon } from '../../services/static-thesaurus-paged-tree-store.service';\r\nimport { ThesaurusTreeComponent } from '../thesaurus-tree/thesaurus-tree.component';\r\n\r\n/**\r\n * The prefix added to custom entries' IDs.\r\n */\r\nexport const CUSTOM_ENTRY_PREFIX = '$';\r\n\r\n/**\r\n * A picker component for thesaurus entries.\r\n * This component allows picking one or more entries from a given thesaurus.\r\n * In its collapsed state, it shows the picked entries as chips; when\r\n * expanded, it shows the thesaurus tree to pick from. Custom entries\r\n * (not in the thesaurus) can be optionally allowed.\r\n */\r\n@Component({\r\n selector: 'cadmus-thesaurus-entries-picker',\r\n imports: [\r\n ReactiveFormsModule,\r\n CdkDropList,\r\n CdkDrag,\r\n MatChipListbox,\r\n MatChipOption,\r\n MatChipRemove,\r\n MatExpansionPanel,\r\n MatFormField,\r\n MatIconButton,\r\n MatIcon,\r\n MatInput,\r\n MatTooltip,\r\n ThesaurusTreeComponent,\r\n ],\r\n templateUrl: './thesaurus-entries-picker.component.html',\r\n styleUrl: './thesaurus-entries-picker.component.css',\r\n})\r\nexport class ThesaurusEntriesPickerComponent {\r\n /**\r\n * The thesaurus entries to pick from (required).\r\n */\r\n public readonly availableEntries = input.required<ThesaurusEntry[]>();\r\n\r\n /**\r\n * The picked entries.\r\n */\r\n public readonly entries = model<ThesaurusEntry[]>([]);\r\n\r\n /**\r\n * True to show the entries with labels shortened according to\r\n * their hierarchy.\r\n */\r\n public readonly hierarchicLabels = input<boolean>(false);\r\n\r\n /**\r\n * True to automatically sort the picked entries (disables drag-and-drop).\r\n * When false, entries can be manually reordered via drag-and-drop.\r\n */\r\n public readonly autoSort = input<boolean>(false);\r\n\r\n /**\r\n * True to allow custom values (not in the entries list).\r\n */\r\n public readonly allowCustom = input<boolean>(false);\r\n\r\n /**\r\n * The minimum number of entries to pick.\r\n */\r\n public readonly minEntries = input<number>(0);\r\n\r\n /**\r\n * The maximum number of entries to pick (0=unlimited).\r\n */\r\n public readonly maxEntries = input<number>(0);\r\n\r\n /**\r\n * True when the picker is expanded (showing the entries list).\r\n */\r\n public readonly expanded = model<boolean>(false);\r\n\r\n /**\r\n * The message to show when there are no picked entries.\r\n */\r\n public readonly emptyMessage = input<string>('no entries');\r\n\r\n /**\r\n * The number of remaining entries that can be picked (0=unlimited).\r\n * This is displayed only if maxEntries > 1.\r\n */\r\n public readonly remaining = computed(() => {\r\n if (this.maxEntries() > 0) {\r\n return this.maxEntries() - this.entries().length;\r\n }\r\n return 0;\r\n });\r\n\r\n public id: FormControl<string>;\r\n public value: FormControl<string>;\r\n public form: FormGroup;\r\n\r\n constructor(formBuilder: FormBuilder) {\r\n this.id = formBuilder.control<string>('', {\r\n validators: [Validators.required, Validators.maxLength(100)],\r\n nonNullable: true,\r\n });\r\n this.value = formBuilder.control<string>('', {\r\n validators: [Validators.required, Validators.maxLength(500)],\r\n nonNullable: true,\r\n });\r\n this.form = formBuilder.group({\r\n id: this.id,\r\n value: this.value,\r\n });\r\n // if auto-sort is turned on and we have entries, sort them\r\n effect(() => {\r\n // only track autoSort() changes, not entries()\r\n const shouldSort = this.autoSort();\r\n\r\n if (shouldSort) {\r\n // use untracked to read entries without creating a dependency\r\n const currentEntries = untracked(() => this.entries());\r\n if (currentEntries.length > 1) {\r\n const entries = [...currentEntries];\r\n this.sortEntries(entries);\r\n this.entries.set(entries);\r\n }\r\n }\r\n });\r\n }\r\n\r\n // need arrow function to use 'this'\r\n public renderLabel = (label: string): string => {\r\n return this.hierarchicLabels() ? renderLabelFromLastColon(label) : label;\r\n };\r\n\r\n private sortEntries(entries: ThesaurusEntry[]) {\r\n entries.sort((a: ThesaurusEntry, b: ThesaurusEntry) => {\r\n const aIsCustom = a.id?.startsWith(CUSTOM_ENTRY_PREFIX) ?? false;\r\n const bIsCustom = b.id?.startsWith(CUSTOM_ENTRY_PREFIX) ?? false;\r\n if (aIsCustom !== bIsCustom) {\r\n // place custom entries after non-custom ones\r\n return aIsCustom ? 1 : -1;\r\n }\r\n // same kind: sort by label/value\r\n return a.value.localeCompare(b.value);\r\n });\r\n }\r\n\r\n public onEntryChange(entry: ThesaurusEntry): void {\r\n // check if already present\r\n if (this.entries().some((e: ThesaurusEntry) => e.id === entry.id)) {\r\n return;\r\n }\r\n // check if limit is reached\r\n if (this.maxEntries() && this.entries().length >= this.maxEntries()) {\r\n return;\r\n }\r\n\r\n const entries = [...this.entries()];\r\n entries.push(entry);\r\n if (this.autoSort()) {\r\n this.sortEntries(entries);\r\n }\r\n this.entries.set(entries);\r\n }\r\n\r\n public addCustomEntry(): void {\r\n if (this.form.invalid) {\r\n return;\r\n }\r\n\r\n // create the custom entry\r\n const customEntry: ThesaurusEntry = {\r\n id: CUSTOM_ENTRY_PREFIX + this.id.value,\r\n value: this.value.value,\r\n };\r\n\r\n // check if already present\r\n if (this.entries().some((e: ThesaurusEntry) => e.id === customEntry.id)) {\r\n return;\r\n }\r\n // check if limit is reached\r\n if (this.maxEntries() && this.entries().length >= this.maxEntries()) {\r\n return;\r\n }\r\n const entries = [...this.entries()];\r\n entries.push(customEntry);\r\n if (this.autoSort()) {\r\n this.sortEntries(entries);\r\n }\r\n this.entries.set(entries);\r\n this.form.reset();\r\n }\r\n\r\n public removeEntry(entry: ThesaurusEntry): void {\r\n const entries = [...this.entries().filter((e) => e.id !== entry.id)];\r\n this.entries.set(entries);\r\n }\r\n\r\n public clear(): void {\r\n this.entries.set([]);\r\n // if min > 0, expand the picker\r\n if (this.minEntries() > 0 && !this.expanded()) {\r\n setTimeout(() => {\r\n this.expanded.set(true);\r\n }, 0);\r\n }\r\n }\r\n\r\n public onDrop(event: CdkDragDrop<ThesaurusEntry[]>): void {\r\n const entries = [...this.entries()];\r\n moveItemInArray(entries, event.previousIndex, event.currentIndex);\r\n this.entries.set(entries);\r\n }\r\n}\r\n","<div id=\"container\">\r\n <!-- picked entries -->\r\n <div id=\"picked\" class=\"form-row\">\r\n <!-- count -->\r\n <span class=\"nr\" [class.error]=\"entries().length < minEntries()\">{{\r\n entries().length\r\n }}</span>\r\n <!-- max-->\r\n @if (maxEntries() > 1) {\r\n <span class=\"muted\">/{{ maxEntries() }}</span>\r\n @if (remaining()) {\r\n <span class=\"muted\">: -{{ remaining() }}</span>\r\n } }\r\n <!-- min -->\r\n @if (minEntries()) {\r\n <!-- min with error -->\r\n @if (entries().length < minEntries()) {\r\n <span class=\"error\"> (min {{ minEntries() }})</span>\r\n }\r\n <!-- min without error -->\r\n @else {\r\n <span class=\"muted\"> (min {{ minEntries() }})</span>\r\n } }\r\n <!-- list -->\r\n <mat-chip-listbox\r\n [cdkDropListDisabled]=\"autoSort()\"\r\n cdkDropList\r\n cdkDropListOrientation=\"horizontal\"\r\n (cdkDropListDropped)=\"onDrop($event)\"\r\n class=\"chip-list\"\r\n >\r\n @for (e of entries(); track e.id; let idx = $index) {\r\n <div class=\"chip-wrapper\">\r\n <mat-chip-option\r\n [cdkDragDisabled]=\"autoSort()\"\r\n cdkDrag\r\n [class.error]=\"!allowCustom() && e.id.startsWith('$')\"\r\n >\r\n {{ renderLabel(e.value) }}\r\n <button\r\n type=\"button\"\r\n matChipRemove\r\n (click)=\"removeEntry(e)\"\r\n aria-label=\"Remove entry\"\r\n >\r\n <mat-icon class=\"mat-warn\">cancel</mat-icon>\r\n </button>\r\n </mat-chip-option>\r\n </div>\r\n } @empty {\r\n <span class=\"muted empty-message\">{{ emptyMessage() }}</span>\r\n }\r\n </mat-chip-listbox>\r\n\r\n <!-- clear -->\r\n @if (entries().length > 0) {\r\n <button\r\n type=\"button\"\r\n mat-icon-button\r\n matTooltip=\"Remove all entries\"\r\n (click)=\"clear()\"\r\n [disabled]=\"entries().length === 0\"\r\n >\r\n <mat-icon class=\"mat-warn\">clear</mat-icon>\r\n </button>\r\n }\r\n <!-- toggler -->\r\n <button\r\n type=\"button\"\r\n mat-icon-button\r\n matTooltip=\"Toggle picker\"\r\n (click)=\"expanded.set(!expanded())\"\r\n >\r\n @if (expanded()) {\r\n <mat-icon class=\"mat-primary\">publish</mat-icon>\r\n } @if (!expanded()) {\r\n <mat-icon class=\"mat-primary\">get_app</mat-icon>\r\n }\r\n </button>\r\n </div>\r\n\r\n <!-- entries picker -->\r\n <div id=\"picker\">\r\n <mat-expansion-panel\r\n [expanded]=\"expanded()\"\r\n (expandedChange)=\"expanded.set($event)\"\r\n >\r\n <div>\r\n <fieldset>\r\n <legend>available</legend>\r\n <cadmus-thesaurus-tree\r\n [entries]=\"availableEntries()\"\r\n [renderLabel]=\"renderLabel\"\r\n (entryChange)=\"onEntryChange($event)\"\r\n />\r\n </fieldset>\r\n </div>\r\n @if (allowCustom()) {\r\n <div>\r\n <form [formGroup]=\"form\" (submit)=\"addCustomEntry()\">\r\n <fieldset>\r\n <legend>custom</legend>\r\n <div class=\"form-row\">\r\n <mat-form-field>\r\n <input\r\n matInput\r\n type=\"text\"\r\n [formControl]=\"id\"\r\n placeholder=\"ID\"\r\n />\r\n </mat-form-field>\r\n <mat-form-field>\r\n <input\r\n matInput\r\n type=\"text\"\r\n [formControl]=\"value\"\r\n placeholder=\"label\"\r\n />\r\n </mat-form-field>\r\n <button\r\n type=\"submit\"\r\n mat-icon-button\r\n matTooltip=\"Add custom entry\"\r\n [disabled]=\"\r\n !form.valid ||\r\n (maxEntries() > 0 && entries().length >= maxEntries())\r\n \"\r\n >\r\n <mat-icon class=\"mat-primary\">check_circle</mat-icon>\r\n </button>\r\n </div>\r\n </fieldset>\r\n </form>\r\n </div>\r\n }\r\n </mat-expansion-panel>\r\n </div>\r\n</div>\r\n","import { Observable, of } from 'rxjs';\r\n\r\nimport { DataPage } from '@myrmidon/ngx-tools';\r\n\r\nimport {\r\n EditablePagedTreeStoreServiceBase,\r\n ChangeOperation,\r\n ChangeOperationType,\r\n TreeNode,\r\n} from '@myrmidon/paged-data-browsers';\r\nimport { ThesaurusEntry } from '@myrmidon/cadmus-core';\r\n\r\nimport {\r\n StaticThesaurusPagedTreeStoreService,\r\n ThesaurusEntryNodeFilter,\r\n ThesaurusEntryPagedTreeNode,\r\n} from './static-thesaurus-paged-tree-store.service';\r\n\r\n/**\r\n * Editable version of the static thesaurus paged tree store service.\r\n * This service allows editing operations on the flat ThesaurusEntry list\r\n * while maintaining the tree structure implied by the hierarchical IDs.\r\n */\r\nexport class EditableStaticThesaurusPagedTreeStoreService\r\n extends EditablePagedTreeStoreServiceBase<ThesaurusEntryNodeFilter> {\r\n private _entries: ThesaurusEntry[];\r\n private _staticService: StaticThesaurusPagedTreeStoreService;\r\n private _renderLabel?: (label: string) => string;\r\n\r\n constructor(\r\n entries: ThesaurusEntry[],\r\n renderLabel?: (label: string) => string,\r\n ) {\r\n super();\r\n this._entries = [...entries];\r\n this._renderLabel = renderLabel;\r\n this._staticService = new StaticThesaurusPagedTreeStoreService(\r\n this._entries,\r\n renderLabel,\r\n );\r\n }\r\n\r\n protected override fetchNodes(\r\n filter: ThesaurusEntryNodeFilter,\r\n pageNumber: number,\r\n pageSize: number,\r\n hasMockRoot?: boolean,\r\n ): Observable<DataPage<TreeNode>> {\r\n // update the static service with current entries and delegate,\r\n // preserving the renderLabel function\r\n this._staticService = new StaticThesaurusPagedTreeStoreService(\r\n this._entries,\r\n this._renderLabel,\r\n );\r\n return this._staticService.getNodes(\r\n filter,\r\n pageNumber,\r\n pageSize,\r\n hasMockRoot,\r\n );\r\n }\r\n\r\n protected override persistChanges(\r\n changes: ChangeOperation[],\r\n ): Observable<Map<number, number>> {\r\n console.log('=== SAVING CHANGES ===');\r\n console.log('Changes to persist:', changes);\r\n\r\n const idMap = new Map<number, number>();\r\n\r\n // process changes to update the flat entries list\r\n for (const change of changes) {\r\n switch (change.type) {\r\n case ChangeOperationType.ADD:\r\n if (change.node) {\r\n const newEntry = this.nodeToEntry(change.node);\r\n if (newEntry) {\r\n const existingIndex = this._entries.findIndex(\r\n (e) => e.id === newEntry.id,\r\n );\r\n if (existingIndex === -1) {\r\n this._entries.push(newEntry);\r\n\r\n // map temporary ID to the new permanent ID (array index + 1)\r\n if (change.node.id < 0) {\r\n const permanentId = this._entries.length;\r\n idMap.set(change.node.id, permanentId);\r\n }\r\n console.log('Added entry:', newEntry);\r\n } else {\r\n console.log('Entry already exists, skipping:', newEntry.id);\r\n }\r\n }\r\n }\r\n break;\r\n\r\n case ChangeOperationType.REMOVE:\r\n if (change.originalNode) {\r\n // use the 'key' property which contains the ThesaurusEntry string ID\r\n const nodeWithKey =\r\n change.originalNode as ThesaurusEntryPagedTreeNode;\r\n const entryKey = nodeWithKey.key;\r\n\r\n if (entryKey) {\r\n this.removeEntryAndDescendants(entryKey);\r\n console.log('Removed entry and descendants:', entryKey);\r\n } else {\r\n console.warn('Node missing key property:', change.originalNode);\r\n }\r\n } else if (change.id < 0) {\r\n console.log(\r\n 'Removed temporary node that was never persisted:',\r\n change.id,\r\n );\r\n } else {\r\n console.warn(\r\n 'Remove operation missing originalNode for ID:',\r\n change.id,\r\n );\r\n }\r\n break;\r\n\r\n case ChangeOperationType.UPDATE:\r\n if (change.node && change.originalNode) {\r\n const nodeWithKey =\r\n change.originalNode as ThesaurusEntryPagedTreeNode;\r\n const entryKey = nodeWithKey.key;\r\n\r\n if (entryKey) {\r\n const entryToUpdate = this._entries.find(\r\n (e) => e.id === entryKey,\r\n );\r\n\r\n if (entryToUpdate) {\r\n const updatedEntry = this.nodeToEntry(change.node);\r\n if (updatedEntry) {\r\n // preserve the original hierarchical ID\r\n updatedEntry.id = entryToUpdate.id;\r\n const index = this._entries.findIndex(\r\n (e) => e.id === entryToUpdate.id,\r\n );\r\n if (index !== -1) {\r\n this._entries[index] = updatedEntry;\r\n console.log('Updated entry:', updatedEntry);\r\n }\r\n }\r\n } else {\r\n console.warn(\r\n 'Could not find entry to update with key:',\r\n entryKey,\r\n );\r\n }\r\n } else {\r\n console.warn(\r\n 'Update node missing key property:',\r\n change.originalNode,\r\n );\r\n }\r\n } else if (change.id < 0) {\r\n console.log('Updated temporary node:', change.id);\r\n }\r\n break;\r\n }\r\n }\r\n\r\n // Validate no duplicate IDs\r\n const ids = this._entries.map((e) => e.id);\r\n const duplicates = ids.filter((id, index) => ids.indexOf(id) !== index);\r\n if (duplicates.length > 0) {\r\n console.error('Duplicate IDs found:', duplicates);\r\n }\r\n\r\n console.log('Final entries after changes:', this._entries);\r\n console.log('ID mappings:', idMap);\r\n console.log('=== END SAVING CHANGES ===');\r\n\r\n return of(idMap);\r\n }\r\n\r\n /**\r\n * Convert a TreeNode back to a ThesaurusEntry.\r\n */\r\n private nodeToEntry(node: TreeNode): ThesaurusEntry | null {\r\n // For nodes with the key property, use it directly\r\n const nodeWithKey = node as any;\r\n if (nodeWithKey.key) {\r\n return {\r\n id: nodeWithKey.key,\r\n value: node.label,\r\n };\r\n }\r\n\r\n // For temporary nodes (negative IDs), construct a hierarchical ID\r\n if (node.id < 0) {\r\n // Check for user-provided ID\r\n const userProvidedId = nodeWithKey._userProvidedId;\r\n\r\n if (userProvidedId) {\r\n return {\r\n id: userProvidedId,\r\n value: node.label,\r\n };\r\n }\r\n\r\n // Find parent to construct the ID\r\n if (node.parentId) {\r\n const parentNode = this._nodes.get(node.parentId) as any;\r\n const parentKey = parentNode?.key;\r\n if (parentKey) {\r\n return {\r\n id: `${parentKey}.temp${Math.abs(node.id)}`,\r\n value: node.label,\r\n };\r\n }\r\n }\r\n\r\n // No parent, create a root-level temporary entry\r\n return {\r\n id: `temp${Math.abs(node.id)}`,\r\n value: node.label,\r\n };\r\n }\r\n\r\n console.warn('Could not convert node to entry:', node);\r\n return null;\r\n }\r\n\r\n /**\r\n * Remove an entry and all its descendants from the entries list.\r\n */\r\n private removeEntryAndDescendants(entryId: string): void {\r\n const toRemove: string[] = [];\r\n\r\n // find the entry and all its descendants\r\n for (const entry of this._entries) {\r\n if (entry.id === entryId || entry.id.startsWith(entryId + '.')) {\r\n toRemove.push(entry.id);\r\n }\r\n }\r\n\r\n // remove them from the list\r\n for (const id of toRemove) {\r\n const index = this._entries.findIndex((e) => e.id === id);\r\n if (index !== -1) {\r\n this._entries.splice(index, 1);\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Get current entries (for demonstration purposes).\r\n */\r\n public getCurrentEntries(): ThesaurusEntry[] {\r\n return [...this._entries];\r\n }\r\n}\r\n","/*\r\n * Public API Surface of cadmus-thesaurus-store\r\n */\r\n\r\nexport * from './lib/components/editable-thesaurus-browser/editable-thesaurus-browser.component';\r\nexport * from './lib/components/thesaurus-entries-picker/thesaurus-entries-picker.component';\r\nexport * from './lib/components/thesaurus-entry-editor/thesaurus-entry-editor.component';\r\nexport * from './lib/components/thesaurus-browser/thesaurus-browser.component';\r\nexport * from './lib/components/thesaurus-paged-tree-filter/thesaurus-paged-tree-filter.component';\r\nexport * from './lib/components/thesaurus-tree/thesaurus-tree.component';\r\n\r\nexport * from './lib/services/editable-static-thesaurus-paged-tree-store.service';\r\nexport * from './lib/services/static-thesaurus-paged-tree-store.service';\r\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":["i3","i4","i6","i2","i7"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@myrmidon/cadmus-thesaurus-store",
3
- "version": "0.0.3",
3
+ "version": "0.0.4",
4
4
  "description": "Cadmus thesauri store components.",
5
5
  "keywords": [
6
6
  "Cadmus"
@@ -386,6 +386,11 @@ declare class ThesaurusTreeComponent {
386
386
  * The tree store service, dependent on the current entries and renderLabel.
387
387
  */
388
388
  readonly service: _angular_core.Signal<StaticThesaurusPagedTreeStoreService>;
389
+ /**
390
+ * Debug: tracks when the template condition would show the browser.
391
+ */
392
+ readonly shouldShowBrowser: _angular_core.Signal<boolean>;
393
+ constructor();
389
394
  /**
390
395
  * The filter component class to use.
391
396
  */