@myrmidon/cadmus-ui 12.0.0 → 12.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,5 +1,5 @@
1
1
  import * as i0 from '@angular/core';
2
- import { input, output, Component, effect, ViewChild, Injectable, Inject, model } from '@angular/core';
2
+ import { input, output, Component, effect, ViewChild, Injectable, Inject, model, computed, inject } from '@angular/core';
3
3
  import { MatButton, MatIconButton, MatAnchor } from '@angular/material/button';
4
4
  import { MatIcon } from '@angular/material/icon';
5
5
  import { SafeHtmlPipe, deepCopy } from '@myrmidon/ngx-tools';
@@ -19,6 +19,7 @@ import { MatInput } from '@angular/material/input';
19
19
  import * as i1$2 from '@myrmidon/cadmus-api';
20
20
  import { NestedTreeControl } from '@angular/cdk/tree';
21
21
  import { MatTreeNestedDataSource, MatTree, MatTreeNodeDef, MatTreeNode, MatTreeNodeToggle, MatNestedTreeNode, MatTreeNodeOutlet } from '@angular/material/tree';
22
+ import { AppRepository } from '@myrmidon/cadmus-state';
22
23
  import * as i1$3 from '@myrmidon/auth-jwt-login';
23
24
 
24
25
  class CloseSaveButtonsComponent {
@@ -28,10 +29,10 @@ class CloseSaveButtonsComponent {
28
29
  close() {
29
30
  this.closeRequest.emit();
30
31
  }
31
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.1.3", ngImport: i0, type: CloseSaveButtonsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
32
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.1.3", type: CloseSaveButtonsComponent, isStandalone: true, selector: "cadmus-close-save-buttons", inputs: { form: { classPropertyName: "form", publicName: "form", isSignal: true, isRequired: false, transformFunction: null }, noSave: { classPropertyName: "noSave", publicName: "noSave", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { closeRequest: "closeRequest" }, ngImport: i0, template: "@if (form()) {\n<div class=\"form-row\">\n <button type=\"button\" mat-flat-button class=\"mat-warn\" (click)=\"close()\">\n <mat-icon>cancel</mat-icon>\n close\n </button>\n @if (!noSave()) {\n <button\n type=\"submit\"\n [disabled]=\"form()?.invalid\"\n mat-flat-button\n class=\"mat-primary\"\n >\n <mat-icon>check_circle</mat-icon>\n save\n </button>\n }\n</div>\n}\n", styles: [".form-row{display:flex;gap:8px;align-items:center;flex-wrap:wrap}.form-row *{flex:0 0 auto}\n"], dependencies: [{ kind: "component", type: MatButton, selector: " button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ", exportAs: ["matButton"] }, { kind: "component", type: MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }] });
32
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.3", ngImport: i0, type: CloseSaveButtonsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
33
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.3", type: CloseSaveButtonsComponent, isStandalone: true, selector: "cadmus-close-save-buttons", inputs: { form: { classPropertyName: "form", publicName: "form", isSignal: true, isRequired: false, transformFunction: null }, noSave: { classPropertyName: "noSave", publicName: "noSave", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { closeRequest: "closeRequest" }, ngImport: i0, template: "@if (form()) {\n<div class=\"form-row\">\n <button type=\"button\" mat-flat-button class=\"mat-warn\" (click)=\"close()\">\n <mat-icon>cancel</mat-icon>\n close\n </button>\n @if (!noSave()) {\n <button\n type=\"submit\"\n [disabled]=\"form()?.invalid\"\n mat-flat-button\n class=\"mat-primary\"\n >\n <mat-icon>check_circle</mat-icon>\n save\n </button>\n }\n</div>\n}\n", styles: [".form-row{display:flex;gap:8px;align-items:center;flex-wrap:wrap}.form-row *{flex:0 0 auto}\n"], dependencies: [{ kind: "component", type: MatButton, selector: " button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ", exportAs: ["matButton"] }, { kind: "component", type: MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }] });
33
34
  }
34
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.3", ngImport: i0, type: CloseSaveButtonsComponent, decorators: [{
35
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.3", ngImport: i0, type: CloseSaveButtonsComponent, decorators: [{
35
36
  type: Component,
36
37
  args: [{ selector: 'cadmus-close-save-buttons', imports: [MatButton, MatIcon], template: "@if (form()) {\n<div class=\"form-row\">\n <button type=\"button\" mat-flat-button class=\"mat-warn\" (click)=\"close()\">\n <mat-icon>cancel</mat-icon>\n close\n </button>\n @if (!noSave()) {\n <button\n type=\"submit\"\n [disabled]=\"form()?.invalid\"\n mat-flat-button\n class=\"mat-primary\"\n >\n <mat-icon>check_circle</mat-icon>\n save\n </button>\n }\n</div>\n}\n", styles: [".form-row{display:flex;gap:8px;align-items:center;flex-wrap:wrap}.form-row *{flex:0 0 auto}\n"] }]
37
38
  }] });
@@ -68,10 +69,10 @@ class DecoratedTokenTextComponent {
68
69
  decorate(text, locations, selectedLocation) {
69
70
  this.text = this._textLayerService.render(text, locations, selectedLocation);
70
71
  }
71
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.1.3", ngImport: i0, type: DecoratedTokenTextComponent, deps: [{ token: i1.TextLayerService }], target: i0.ɵɵFactoryTarget.Component });
72
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "19.1.3", type: DecoratedTokenTextComponent, isStandalone: true, selector: "cadmus-decorated-token-text", inputs: { baseText: { classPropertyName: "baseText", publicName: "baseText", isSignal: true, isRequired: false, transformFunction: null }, locations: { classPropertyName: "locations", publicName: "locations", isSignal: true, isRequired: false, transformFunction: null }, selectedLocation: { classPropertyName: "selectedLocation", publicName: "selectedLocation", isSignal: true, isRequired: false, transformFunction: null } }, viewQueries: [{ propertyName: "_textElement", first: true, predicate: ["textElem"], descendants: true }], ngImport: i0, template: "<div [innerHtml]=\"text | safeHtml : 'html'\" id=\"text\" #textElem></div>\r\n", styles: [":host ::ng-deep div#text{counter-reset:text-y-counter}:host ::ng-deep div#text p:before{content:counter(text-y-counter);counter-increment:text-y-counter;margin-right:6px;color:#a0a0a0}:host ::ng-deep span.fr{background-color:#ff0;border:1px solid silver;border-radius:6px;padding:0 4px}:host ::ng-deep span.fr-sel{background-color:orange;font-weight:700;border:1px solid #404040}\n"], dependencies: [{ kind: "pipe", type: SafeHtmlPipe, name: "safeHtml" }] });
72
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.3", ngImport: i0, type: DecoratedTokenTextComponent, deps: [{ token: i1.TextLayerService }], target: i0.ɵɵFactoryTarget.Component });
73
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "19.2.3", type: DecoratedTokenTextComponent, isStandalone: true, selector: "cadmus-decorated-token-text", inputs: { baseText: { classPropertyName: "baseText", publicName: "baseText", isSignal: true, isRequired: false, transformFunction: null }, locations: { classPropertyName: "locations", publicName: "locations", isSignal: true, isRequired: false, transformFunction: null }, selectedLocation: { classPropertyName: "selectedLocation", publicName: "selectedLocation", isSignal: true, isRequired: false, transformFunction: null } }, viewQueries: [{ propertyName: "_textElement", first: true, predicate: ["textElem"], descendants: true }], ngImport: i0, template: "<div [innerHtml]=\"text | safeHtml : 'html'\" id=\"text\" #textElem></div>\r\n", styles: [":host ::ng-deep div#text{counter-reset:text-y-counter}:host ::ng-deep div#text p:before{content:counter(text-y-counter);counter-increment:text-y-counter;margin-right:6px;color:#a0a0a0}:host ::ng-deep span.fr{background-color:#ff0;border:1px solid silver;border-radius:6px;padding:0 4px}:host ::ng-deep span.fr-sel{background-color:orange;font-weight:700;border:1px solid #404040}\n"], dependencies: [{ kind: "pipe", type: SafeHtmlPipe, name: "safeHtml" }] });
73
74
  }
74
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.3", ngImport: i0, type: DecoratedTokenTextComponent, decorators: [{
75
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.3", ngImport: i0, type: DecoratedTokenTextComponent, decorators: [{
75
76
  type: Component,
76
77
  args: [{ selector: 'cadmus-decorated-token-text', imports: [SafeHtmlPipe], template: "<div [innerHtml]=\"text | safeHtml : 'html'\" id=\"text\" #textElem></div>\r\n", styles: [":host ::ng-deep div#text{counter-reset:text-y-counter}:host ::ng-deep div#text p:before{content:counter(text-y-counter);counter-increment:text-y-counter;margin-right:6px;color:#a0a0a0}:host ::ng-deep span.fr{background-color:#ff0;border:1px solid silver;border-radius:6px;padding:0 4px}:host ::ng-deep span.fr-sel{background-color:orange;font-weight:700;border:1px solid #404040}\n"] }]
77
78
  }], ctorParameters: () => [{ type: i1.TextLayerService }], propDecorators: { _textElement: [{
@@ -81,10 +82,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.3", ngImpor
81
82
 
82
83
  class ErrorListComponent {
83
84
  errors = input();
84
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.1.3", ngImport: i0, type: ErrorListComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
85
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.1.3", type: ErrorListComponent, isStandalone: true, selector: "cadmus-error-list", inputs: { errors: { classPropertyName: "errors", publicName: "errors", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "@if (errors()?.length) {\n <ul>\n @for (error of errors(); track error) {\n <li class=\"error\">{{error}}</li>\n }\n </ul>\n}\n", styles: [".error{color:red}\n"] });
85
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.3", ngImport: i0, type: ErrorListComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
86
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.3", type: ErrorListComponent, isStandalone: true, selector: "cadmus-error-list", inputs: { errors: { classPropertyName: "errors", publicName: "errors", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "@if (errors()?.length) {\n <ul>\n @for (error of errors(); track error) {\n <li class=\"error\">{{error}}</li>\n }\n </ul>\n}\n", styles: [".error{color:red}\n"] });
86
87
  }
87
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.3", ngImport: i0, type: ErrorListComponent, decorators: [{
88
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.3", ngImport: i0, type: ErrorListComponent, decorators: [{
88
89
  type: Component,
89
90
  args: [{ selector: 'cadmus-error-list', template: "@if (errors()?.length) {\n <ul>\n @for (error of errors(); track error) {\n <li class=\"error\">{{error}}</li>\n }\n </ul>\n}\n", styles: [".error{color:red}\n"] }]
90
91
  }] });
@@ -232,10 +233,10 @@ class ColorService {
232
233
  const rgb = this.hslToRgb(h, s, l);
233
234
  return this.rgbToString(rgb.r, rgb.g, rgb.b);
234
235
  }
235
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.1.3", ngImport: i0, type: ColorService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
236
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.1.3", ngImport: i0, type: ColorService, providedIn: 'root' });
236
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.3", ngImport: i0, type: ColorService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
237
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.3", ngImport: i0, type: ColorService, providedIn: 'root' });
237
238
  }
238
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.3", ngImport: i0, type: ColorService, decorators: [{
239
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.3", ngImport: i0, type: ColorService, decorators: [{
239
240
  type: Injectable,
240
241
  args: [{
241
242
  providedIn: 'root',
@@ -318,10 +319,10 @@ class FacetBadgeComponent {
318
319
  this.contrastColor = this._colorService.getContrastColor(this.color);
319
320
  this.tip = this.getFacetTip(data?.facetId || '') ?? undefined;
320
321
  }
321
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.1.3", ngImport: i0, type: FacetBadgeComponent, deps: [{ token: ColorService }], target: i0.ɵɵFactoryTarget.Component });
322
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "19.1.3", type: FacetBadgeComponent, isStandalone: true, selector: "cadmus-facet-badge", inputs: { data: { classPropertyName: "data", publicName: "data", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "<span\r\n class=\"model-type\"\r\n [style.background-color]=\"color\"\r\n [style.color]=\"contrastColor\"\r\n matTooltip=\"{{ tip }}\"\r\n >{{ data().facetId }}\r\n</span>\r\n", styles: ["span.model-type{padding:4px;border-radius:6px}\n"], dependencies: [{ kind: "directive", type: MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }] });
322
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.3", ngImport: i0, type: FacetBadgeComponent, deps: [{ token: ColorService }], target: i0.ɵɵFactoryTarget.Component });
323
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "19.2.3", type: FacetBadgeComponent, isStandalone: true, selector: "cadmus-facet-badge", inputs: { data: { classPropertyName: "data", publicName: "data", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "<span\r\n class=\"model-type\"\r\n [style.background-color]=\"color\"\r\n [style.color]=\"contrastColor\"\r\n matTooltip=\"{{ tip }}\"\r\n >{{ data().facetId }}\r\n</span>\r\n", styles: ["span.model-type{padding:4px;border-radius:6px}\n"], dependencies: [{ kind: "directive", type: MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }] });
323
324
  }
324
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.3", ngImport: i0, type: FacetBadgeComponent, decorators: [{
325
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.3", ngImport: i0, type: FacetBadgeComponent, decorators: [{
325
326
  type: Component,
326
327
  args: [{ selector: 'cadmus-facet-badge', imports: [MatTooltip], template: "<span\r\n class=\"model-type\"\r\n [style.background-color]=\"color\"\r\n [style.color]=\"contrastColor\"\r\n matTooltip=\"{{ tip }}\"\r\n >{{ data().facetId }}\r\n</span>\r\n", styles: ["span.model-type{padding:4px;border-radius:6px}\n"] }]
327
328
  }], ctorParameters: () => [{ type: ColorService }] });
@@ -347,10 +348,10 @@ class FlagsBadgeComponent {
347
348
  return def.id & data.flags;
348
349
  });
349
350
  }
350
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.1.3", ngImport: i0, type: FlagsBadgeComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
351
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.1.3", type: FlagsBadgeComponent, isStandalone: true, selector: "cadmus-flags-badge", inputs: { data: { classPropertyName: "data", publicName: "data", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "<div>\n @for (def of badgeFlags; track def.id) {\n <span\n class=\"badge-flag\"\n [style.color]=\"'#' + def.colorKey\"\n [matTooltip]=\"def.label\"\n >\n @if (def.isAdmin) { &#x25c6; } @else { &#x2b24; }\n </span>\n }\n</div>\n", styles: ["span.badge-flag{font-size:1rem;cursor:default}\n"], dependencies: [{ kind: "directive", type: MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }] });
351
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.3", ngImport: i0, type: FlagsBadgeComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
352
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.3", type: FlagsBadgeComponent, isStandalone: true, selector: "cadmus-flags-badge", inputs: { data: { classPropertyName: "data", publicName: "data", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "<div>\n @for (def of badgeFlags; track def.id) {\n <span\n class=\"badge-flag\"\n [style.color]=\"'#' + def.colorKey\"\n [matTooltip]=\"def.label\"\n >\n @if (def.isAdmin) { &#x25c6; } @else { &#x2b24; }\n </span>\n }\n</div>\n", styles: ["span.badge-flag{font-size:1rem;cursor:default}\n"], dependencies: [{ kind: "directive", type: MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }] });
352
353
  }
353
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.3", ngImport: i0, type: FlagsBadgeComponent, decorators: [{
354
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.3", ngImport: i0, type: FlagsBadgeComponent, decorators: [{
354
355
  type: Component,
355
356
  args: [{ selector: 'cadmus-flags-badge', imports: [MatTooltip], template: "<div>\n @for (def of badgeFlags; track def.id) {\n <span\n class=\"badge-flag\"\n [style.color]=\"'#' + def.colorKey\"\n [matTooltip]=\"def.label\"\n >\n @if (def.isAdmin) { &#x25c6; } @else { &#x2b24; }\n </span>\n }\n</div>\n", styles: ["span.badge-flag{font-size:1rem;cursor:default}\n"] }]
356
357
  }], ctorParameters: () => [] });
@@ -428,10 +429,10 @@ class LayerHintsComponent {
428
429
  }
429
430
  });
430
431
  }
431
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.1.3", ngImport: i0, type: LayerHintsComponent, deps: [{ token: i1$1.FormBuilder }, { token: i2.DialogService }], target: i0.ɵɵFactoryTarget.Component });
432
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.1.3", type: LayerHintsComponent, isStandalone: true, selector: "cadmus-layer-hints", inputs: { hints: { classPropertyName: "hints", publicName: "hints", isSignal: true, isRequired: false, transformFunction: null }, targetLocation: { classPropertyName: "targetLocation", publicName: "targetLocation", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, readonly: { classPropertyName: "readonly", publicName: "readonly", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { requestEdit: "requestEdit", requestDelete: "requestDelete", requestMove: "requestMove", requestPatch: "requestPatch" }, ngImport: i0, template: "@if (hints().length) {\n<form [formGroup]=\"form\" (submit)=\"emitRequestPatch()\">\n <table class=\"patches\">\n <thead>\n <tr>\n <th></th>\n <th>location</th>\n <th>description</th>\n <th>patch</th>\n </tr>\n </thead>\n <tbody>\n @for (hint of hints(); track hint; let i = $index) {\n <tr>\n @if (!readonly()) {\n <td>\n <button\n type=\"button\"\n mat-icon-button\n matTooltip=\"Edit this fragment\"\n [disabled]=\"disabled()\"\n >\n <mat-icon>edit</mat-icon>\n </button>\n <button\n type=\"button\"\n mat-icon-button\n matTooltip=\"Move this fragment to {{ targetLocation() }}\"\n [disabled]=\"\n disabled() || !targetLocation() || targetLocation() === hint.location\n \"\n (click)=\"emitRequestMove(hint)\"\n >\n <mat-icon>arrow_forward</mat-icon>\n </button>\n <button\n type=\"button\"\n mat-icon-button\n matTooltip=\"Delete this fragment\"\n [disabled]=\"disabled()\"\n (click)=\"emitRequestDelete(hint)\"\n >\n <mat-icon class=\"mat-warn\">delete</mat-icon>\n </button>\n </td>\n }\n <td>{{ hint.location }}</td>\n <td>{{ hint.description }}</td>\n <td>\n @if (hint.patchOperation) {\n <mat-checkbox\n matTooltip=\"Apply this patch\"\n [disabled]=\"disabled()\"\n [value]=\"(i + 1).toString()\"\n >\n {{ hint.patchOperation }}\n </mat-checkbox>\n }\n </td>\n </tr>\n }\n </tbody>\n </table>\n @if (targetLocation()) {\n <div>move target: {{ targetLocation() }}</div>\n }\n <button\n type=\"submit\"\n mat-flat-button\n [disabled]=\"readonly() || disabled() || form.invalid\"\n >\n apply patches\n </button>\n</form>\n}\n", styles: ["table.patches th{font-weight:400;color:#bdbdbd}\n"], dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1$1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "component", type: MatIconButton, selector: "button[mat-icon-button]", exportAs: ["matButton"] }, { kind: "directive", type: MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "component", type: MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: MatCheckbox, selector: "mat-checkbox", inputs: ["aria-label", "aria-labelledby", "aria-describedby", "aria-expanded", "aria-controls", "aria-owns", "id", "required", "labelPosition", "name", "value", "disableRipple", "tabIndex", "color", "disabledInteractive", "checked", "disabled", "indeterminate"], outputs: ["change", "indeterminateChange"], exportAs: ["matCheckbox"] }, { kind: "component", type: MatButton, selector: " button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ", exportAs: ["matButton"] }] });
432
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.3", ngImport: i0, type: LayerHintsComponent, deps: [{ token: i1$1.FormBuilder }, { token: i2.DialogService }], target: i0.ɵɵFactoryTarget.Component });
433
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.3", type: LayerHintsComponent, isStandalone: true, selector: "cadmus-layer-hints", inputs: { hints: { classPropertyName: "hints", publicName: "hints", isSignal: true, isRequired: false, transformFunction: null }, targetLocation: { classPropertyName: "targetLocation", publicName: "targetLocation", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, readonly: { classPropertyName: "readonly", publicName: "readonly", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { requestEdit: "requestEdit", requestDelete: "requestDelete", requestMove: "requestMove", requestPatch: "requestPatch" }, ngImport: i0, template: "@if (hints().length) {\n<form [formGroup]=\"form\" (submit)=\"emitRequestPatch()\">\n <table class=\"patches\">\n <thead>\n <tr>\n <th></th>\n <th>location</th>\n <th>description</th>\n <th>patch</th>\n </tr>\n </thead>\n <tbody>\n @for (hint of hints(); track hint; let i = $index) {\n <tr>\n @if (!readonly()) {\n <td>\n <button\n type=\"button\"\n mat-icon-button\n matTooltip=\"Edit this fragment\"\n [disabled]=\"disabled()\"\n >\n <mat-icon>edit</mat-icon>\n </button>\n <button\n type=\"button\"\n mat-icon-button\n matTooltip=\"Move this fragment to {{ targetLocation() }}\"\n [disabled]=\"\n disabled() || !targetLocation() || targetLocation() === hint.location\n \"\n (click)=\"emitRequestMove(hint)\"\n >\n <mat-icon>arrow_forward</mat-icon>\n </button>\n <button\n type=\"button\"\n mat-icon-button\n matTooltip=\"Delete this fragment\"\n [disabled]=\"disabled()\"\n (click)=\"emitRequestDelete(hint)\"\n >\n <mat-icon class=\"mat-warn\">delete</mat-icon>\n </button>\n </td>\n }\n <td>{{ hint.location }}</td>\n <td>{{ hint.description }}</td>\n <td>\n @if (hint.patchOperation) {\n <mat-checkbox\n matTooltip=\"Apply this patch\"\n [disabled]=\"disabled()\"\n [value]=\"(i + 1).toString()\"\n >\n {{ hint.patchOperation }}\n </mat-checkbox>\n }\n </td>\n </tr>\n }\n </tbody>\n </table>\n @if (targetLocation()) {\n <div>move target: {{ targetLocation() }}</div>\n }\n <button\n type=\"submit\"\n mat-flat-button\n [disabled]=\"readonly() || disabled() || form.invalid\"\n >\n apply patches\n </button>\n</form>\n}\n", styles: ["table.patches th{font-weight:400;color:#bdbdbd}\n"], dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1$1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "component", type: MatIconButton, selector: "button[mat-icon-button]", exportAs: ["matButton"] }, { kind: "directive", type: MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "component", type: MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: MatCheckbox, selector: "mat-checkbox", inputs: ["aria-label", "aria-labelledby", "aria-describedby", "aria-expanded", "aria-controls", "aria-owns", "id", "required", "labelPosition", "name", "value", "disableRipple", "tabIndex", "color", "disabledInteractive", "checked", "disabled", "indeterminate"], outputs: ["change", "indeterminateChange"], exportAs: ["matCheckbox"] }, { kind: "component", type: MatButton, selector: " button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ", exportAs: ["matButton"] }] });
433
434
  }
434
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.3", ngImport: i0, type: LayerHintsComponent, decorators: [{
435
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.3", ngImport: i0, type: LayerHintsComponent, decorators: [{
435
436
  type: Component,
436
437
  args: [{ selector: 'cadmus-layer-hints', imports: [
437
438
  FormsModule,
@@ -568,10 +569,10 @@ class LookupPinComponent {
568
569
  this.clear();
569
570
  }
570
571
  }
571
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.1.3", ngImport: i0, type: LookupPinComponent, deps: [{ token: i1$1.UntypedFormBuilder }, { token: i1$2.ItemService }, { token: 'indexLookupDefinitions' }], target: i0.ɵɵFactoryTarget.Component });
572
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.1.3", type: LookupPinComponent, isStandalone: true, selector: "cadmus-lookup-pin", inputs: { initialValue: { classPropertyName: "initialValue", publicName: "initialValue", isSignal: true, isRequired: false, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, limit: { classPropertyName: "limit", publicName: "limit", isSignal: true, isRequired: false, transformFunction: null }, resetOnPick: { classPropertyName: "resetOnPick", publicName: "resetOnPick", isSignal: true, isRequired: false, transformFunction: null }, lookupKey: { classPropertyName: "lookupKey", publicName: "lookupKey", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { entryChange: "entryChange" }, ngImport: i0, template: "<form [formGroup]=\"form\">\n <mat-autocomplete #lookupAuto=\"matAutocomplete\" [displayWith]=\"entryToName\">\n @for (entry of entries$ | async; track entry) {\n <mat-option [value]=\"entry\" (onSelectionChange)=\"pickEntry(entry)\">\n {{ entry?.value }}\n </mat-option>\n }\n </mat-autocomplete>\n\n <mat-form-field>\n <input\n matInput\n type=\"text\"\n [placeholder]=\"label()\"\n [formControl]=\"lookup\"\n [matAutocomplete]=\"lookupAuto\"\n />\n </mat-form-field>\n <button\n type=\"button\"\n mat-icon-button\n (click)=\"clear()\"\n [disabled]=\"!entry\"\n matTooltip=\"Clear\"\n >\n <mat-icon class=\"mat-warn\">clear</mat-icon>\n </button>\n</form>\n", styles: [""], dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1$1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$1.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "component", type: MatAutocomplete, selector: "mat-autocomplete", inputs: ["aria-label", "aria-labelledby", "displayWith", "autoActiveFirstOption", "autoSelectActiveOption", "requireSelection", "panelWidth", "disableRipple", "class", "hideSingleSelectionIndicator"], outputs: ["optionSelected", "opened", "closed", "optionActivated"], exportAs: ["matAutocomplete"] }, { kind: "component", type: MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "component", type: MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly", "disabledInteractive"], exportAs: ["matInput"] }, { kind: "directive", type: MatAutocompleteTrigger, selector: "input[matAutocomplete], textarea[matAutocomplete]", inputs: ["matAutocomplete", "matAutocompletePosition", "matAutocompleteConnectedTo", "autocomplete", "matAutocompleteDisabled"], exportAs: ["matAutocompleteTrigger"] }, { kind: "component", type: MatIconButton, selector: "button[mat-icon-button]", exportAs: ["matButton"] }, { kind: "directive", type: MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "component", type: MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "pipe", type: AsyncPipe, name: "async" }] });
572
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.3", ngImport: i0, type: LookupPinComponent, deps: [{ token: i1$1.UntypedFormBuilder }, { token: i1$2.ItemService }, { token: 'indexLookupDefinitions' }], target: i0.ɵɵFactoryTarget.Component });
573
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.3", type: LookupPinComponent, isStandalone: true, selector: "cadmus-lookup-pin", inputs: { initialValue: { classPropertyName: "initialValue", publicName: "initialValue", isSignal: true, isRequired: false, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, limit: { classPropertyName: "limit", publicName: "limit", isSignal: true, isRequired: false, transformFunction: null }, resetOnPick: { classPropertyName: "resetOnPick", publicName: "resetOnPick", isSignal: true, isRequired: false, transformFunction: null }, lookupKey: { classPropertyName: "lookupKey", publicName: "lookupKey", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { entryChange: "entryChange" }, ngImport: i0, template: "<form [formGroup]=\"form\">\n <mat-autocomplete #lookupAuto=\"matAutocomplete\" [displayWith]=\"entryToName\">\n @for (entry of entries$ | async; track entry) {\n <mat-option [value]=\"entry\" (onSelectionChange)=\"pickEntry(entry)\">\n {{ entry?.value }}\n </mat-option>\n }\n </mat-autocomplete>\n\n <mat-form-field>\n <input\n matInput\n type=\"text\"\n [placeholder]=\"label()\"\n [formControl]=\"lookup\"\n [matAutocomplete]=\"lookupAuto\"\n />\n </mat-form-field>\n <button\n type=\"button\"\n mat-icon-button\n (click)=\"clear()\"\n [disabled]=\"!entry\"\n matTooltip=\"Clear\"\n >\n <mat-icon class=\"mat-warn\">clear</mat-icon>\n </button>\n</form>\n", styles: [""], dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1$1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$1.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "component", type: MatAutocomplete, selector: "mat-autocomplete", inputs: ["aria-label", "aria-labelledby", "displayWith", "autoActiveFirstOption", "autoSelectActiveOption", "requireSelection", "panelWidth", "disableRipple", "class", "hideSingleSelectionIndicator"], outputs: ["optionSelected", "opened", "closed", "optionActivated"], exportAs: ["matAutocomplete"] }, { kind: "component", type: MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "component", type: MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly", "disabledInteractive"], exportAs: ["matInput"] }, { kind: "directive", type: MatAutocompleteTrigger, selector: "input[matAutocomplete], textarea[matAutocomplete]", inputs: ["matAutocomplete", "matAutocompletePosition", "matAutocompleteConnectedTo", "autocomplete", "matAutocompleteDisabled"], exportAs: ["matAutocompleteTrigger"] }, { kind: "component", type: MatIconButton, selector: "button[mat-icon-button]", exportAs: ["matButton"] }, { kind: "directive", type: MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "component", type: MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "pipe", type: AsyncPipe, name: "async" }] });
573
574
  }
574
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.3", ngImport: i0, type: LookupPinComponent, decorators: [{
575
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.3", ngImport: i0, type: LookupPinComponent, decorators: [{
575
576
  type: Component,
576
577
  args: [{ selector: 'cadmus-lookup-pin', imports: [
577
578
  FormsModule,
@@ -597,6 +598,41 @@ var PartBadgeType;
597
598
  PartBadgeType[PartBadgeType["partOnly"] = 1] = "partOnly";
598
599
  PartBadgeType[PartBadgeType["roleOnly"] = 2] = "roleOnly";
599
600
  })(PartBadgeType || (PartBadgeType = {}));
601
+ /**
602
+ * Function used to get the part's human-friendly name from its ID and role ID.
603
+ * This assumes that thesaurus entries with role ID specified have form
604
+ * partId:roleId.
605
+ * @param typeId The part type ID.
606
+ * @param roleId The optional role ID.
607
+ * @param typeThesaurus The types thesaurus.
608
+ * @param noFallback If true, and no thesaurus is provided, return undefined
609
+ * rather than the type and role IDs.
610
+ * @returns The name.
611
+ */
612
+ function getPartIdName(typeId, roleId, typeThesaurus, noFallback = false) {
613
+ if (!typeThesaurus) {
614
+ if (noFallback) {
615
+ return undefined;
616
+ }
617
+ return roleId ? `${typeId} ${roleId}` : typeId;
618
+ }
619
+ let entry;
620
+ // first find partId:roleId if any
621
+ if (roleId) {
622
+ const suffixedId = `${typeId}:${roleId}`;
623
+ entry = typeThesaurus.entries?.find((e) => e.id === suffixedId);
624
+ if (entry) {
625
+ return entry.value;
626
+ }
627
+ }
628
+ // else find partId alone
629
+ entry = typeThesaurus.entries?.find((e) => e.id === typeId);
630
+ return entry ? entry.value : typeId;
631
+ }
632
+ /**
633
+ * Part badge component. This component displays a badge with the
634
+ * part's type name and role name, if any, and a background color.
635
+ */
600
636
  class PartBadgeComponent {
601
637
  _facetService;
602
638
  _colorService;
@@ -635,28 +671,34 @@ class PartBadgeComponent {
635
671
  }
636
672
  return this._facetService.getPartColor(typeId, roleId, facetDefinition);
637
673
  }
638
- getTypeIdName(typeId, typeThesaurus) {
639
- if (!typeThesaurus) {
640
- return typeId;
641
- }
642
- // strip :suffix if any
643
- const i = typeId.lastIndexOf(':');
644
- if (i > -1) {
645
- typeId = typeId.substring(0, i);
646
- }
647
- const entry = typeThesaurus.entries?.find((e) => e.id === typeId);
648
- return entry ? entry.value : typeId;
649
- }
674
+ /**
675
+ * Get the role's human-friendly name from its ID.
676
+ * @param roleId The role ID.
677
+ * @param typeThesaurus The types thesaurus.
678
+ * @returns The name.?
679
+ */
650
680
  getRoleIdName(roleId, typeThesaurus) {
651
- if (!roleId || !roleId.startsWith('fr.')) {
681
+ if (!roleId || !typeThesaurus) {
652
682
  return roleId;
653
683
  }
654
- return this.getTypeIdName(roleId, typeThesaurus);
684
+ let entry;
685
+ // first find full roleId with optional suffix
686
+ entry = typeThesaurus.entries?.find((e) => e.id === roleId);
687
+ if (entry) {
688
+ return entry.value;
689
+ }
690
+ // else strip :suffix if any and find
691
+ const i = roleId.lastIndexOf(':');
692
+ if (i > -1) {
693
+ roleId = roleId.substring(0, i);
694
+ }
695
+ entry = typeThesaurus.entries?.find((e) => e.id === roleId);
696
+ return entry ? entry.value : roleId;
655
697
  }
656
698
  updateBadge(partTypeIds, typeThesaurus, facetDefinition) {
657
699
  if (partTypeIds) {
658
700
  this.color = this.getPartColor(partTypeIds.typeId, partTypeIds.roleId, facetDefinition);
659
- this.typeName = this.getTypeIdName(partTypeIds.typeId, typeThesaurus);
701
+ this.typeName = getPartIdName(partTypeIds.typeId, partTypeIds.roleId, typeThesaurus);
660
702
  this.roleName = this.getRoleIdName(partTypeIds.roleId, typeThesaurus);
661
703
  }
662
704
  else {
@@ -666,10 +708,10 @@ class PartBadgeComponent {
666
708
  }
667
709
  this.contrastColor = this._colorService.getContrastColor(this.color);
668
710
  }
669
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.1.3", ngImport: i0, type: PartBadgeComponent, deps: [{ token: i1$2.FacetService }, { token: ColorService }], target: i0.ɵɵFactoryTarget.Component });
670
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.1.3", type: PartBadgeComponent, isStandalone: true, selector: "cadmus-part-badge", inputs: { badgeType: { classPropertyName: "badgeType", publicName: "badgeType", isSignal: true, isRequired: false, transformFunction: null }, typeThesaurus: { classPropertyName: "typeThesaurus", publicName: "typeThesaurus", isSignal: true, isRequired: false, transformFunction: null }, facetDefinition: { classPropertyName: "facetDefinition", publicName: "facetDefinition", isSignal: true, isRequired: false, transformFunction: null }, partTypeIds: { classPropertyName: "partTypeIds", publicName: "partTypeIds", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "@if (badgeType() !== 2) {\n<span\n class=\"part-badge\"\n [style.background-color]=\"color\"\n [style.color]=\"contrastColor\"\n>\n {{ typeName }}\n</span>\n} @if (badgeType() !== 1 && roleName) {\n<span class=\"role-badge\">\n {{ roleName }}\n</span>\n}\n", styles: [".part-badge{padding:4px;border-radius:6px}.role-badge{padding:4px;border:1px solid silver;border-radius:6px}\n"] });
711
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.3", ngImport: i0, type: PartBadgeComponent, deps: [{ token: i1$2.FacetService }, { token: ColorService }], target: i0.ɵɵFactoryTarget.Component });
712
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.3", type: PartBadgeComponent, isStandalone: true, selector: "cadmus-part-badge", inputs: { badgeType: { classPropertyName: "badgeType", publicName: "badgeType", isSignal: true, isRequired: false, transformFunction: null }, typeThesaurus: { classPropertyName: "typeThesaurus", publicName: "typeThesaurus", isSignal: true, isRequired: false, transformFunction: null }, facetDefinition: { classPropertyName: "facetDefinition", publicName: "facetDefinition", isSignal: true, isRequired: false, transformFunction: null }, partTypeIds: { classPropertyName: "partTypeIds", publicName: "partTypeIds", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "@if (badgeType() !== 2) {\n<span\n class=\"part-badge\"\n [style.background-color]=\"color\"\n [style.color]=\"contrastColor\"\n>\n {{ typeName }}\n</span>\n} @if (badgeType() !== 1 && roleName) {\n<span class=\"role-badge\">\n {{ roleName }}\n</span>\n}\n", styles: [".part-badge{padding:4px;border-radius:6px}.role-badge{padding:4px;border:1px solid silver;border-radius:6px}\n"] });
671
713
  }
672
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.3", ngImport: i0, type: PartBadgeComponent, decorators: [{
714
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.3", ngImport: i0, type: PartBadgeComponent, decorators: [{
673
715
  type: Component,
674
716
  args: [{ selector: 'cadmus-part-badge', template: "@if (badgeType() !== 2) {\n<span\n class=\"part-badge\"\n [style.background-color]=\"color\"\n [style.color]=\"contrastColor\"\n>\n {{ typeName }}\n</span>\n} @if (badgeType() !== 1 && roleName) {\n<span class=\"role-badge\">\n {{ roleName }}\n</span>\n}\n", styles: [".part-badge{padding:4px;border-radius:6px}.role-badge{padding:4px;border:1px solid silver;border-radius:6px}\n"] }]
675
717
  }], ctorParameters: () => [{ type: i1$2.FacetService }, { type: ColorService }] });
@@ -879,10 +921,10 @@ class ThesaurusTreeComponent {
879
921
  }
880
922
  return this.foundNodes?.length > 0 && this.foundNodes.indexOf(node) > -1;
881
923
  }
882
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.1.3", ngImport: i0, type: ThesaurusTreeComponent, deps: [{ token: i1$1.FormBuilder }], target: i0.ɵɵFactoryTarget.Component });
883
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.1.3", type: ThesaurusTreeComponent, isStandalone: true, selector: "cadmus-thesaurus-tree", inputs: { entries: { classPropertyName: "entries", publicName: "entries", isSignal: true, isRequired: false, transformFunction: null }, rootLabel: { classPropertyName: "rootLabel", publicName: "rootLabel", isSignal: true, isRequired: false, transformFunction: null }, renderLabel: { classPropertyName: "renderLabel", publicName: "renderLabel", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { entryChange: "entryChange" }, ngImport: i0, template: "<form [formGroup]=\"form\" (submit)=\"find()\">\n <button\n type=\"button\"\n mat-icon-button\n matTooltip=\"Expand all\"\n (click)=\"expandAll()\"\n >\n <mat-icon>unfold_more</mat-icon>\n </button>\n <button\n type=\"button\"\n mat-icon-button\n matTooltip=\"Collapse all\"\n (click)=\"collapseAll()\"\n >\n <mat-icon>unfold_less</mat-icon>\n </button>\n <mat-form-field>\n <mat-label>find</mat-label>\n <input matInput [formControl]=\"filter\" />\n <button\n type=\"button\"\n matSuffix\n mat-icon-button\n (click)=\"resetFilter()\"\n >\n <mat-icon class=\"mat-warn\">clear</mat-icon>\n </button>\n </mat-form-field>\n @if (foundNodes) {\n <span\n [ngClass]=\"{\n 'found-count': foundNodes.length,\n 'not-found-count': foundNodes.length === 0\n }\"\n >{{ foundNodes.length }}</span\n >\n }\n</form>\n<mat-tree\n [dataSource]=\"treeDataSource\"\n [treeControl]=\"treeControl\"\n class=\"th-tree\"\n>\n <!-- leaf node -->\n <mat-tree-node *matTreeNodeDef=\"let node\" matTreeNodeToggle>\n <li>\n <div class=\"mat-tree-node\">\n <a\n mat-button\n (click)=\"onTreeNodeClick(node)\"\n [class.hilite]=\"isFoundNode(node)\"\n >\n {{ node.label }}\n </a>\n </div>\n </li>\n </mat-tree-node>\n\n <!-- root node -->\n <mat-nested-tree-node *matTreeNodeDef=\"let node; when: isRoot\">\n <div class=\"mat-tree-node\">\n <button\n type=\"button\"\n mat-icon-button\n matTreeNodeToggle\n [attr.aria-label]=\"'Toggle ' + node.label\"\n >\n <mat-icon>\n {{ treeControl.isExpanded(node) ? \"expand_more\" : \"chevron_right\" }}\n </mat-icon>\n </button>\n {{ node.label }}\n </div>\n <ul class=\"tree-nested-node\">\n @if (treeControl.isExpanded(node)) {\n <div>\n <ng-container matTreeNodeOutlet></ng-container>\n </div>\n }\n </ul>\n </mat-nested-tree-node>\n\n <!-- parent node -->\n <mat-nested-tree-node *matTreeNodeDef=\"let node; when: hasChildren\">\n <li class=\"tree-container\">\n <div class=\"mat-tree-node\">\n <button\n type=\"button\"\n mat-icon-button\n matTreeNodeToggle\n [attr.aria-label]=\"'Toggle ' + node.label\"\n >\n <mat-icon>\n {{ treeControl.isExpanded(node) ? \"expand_more\" : \"chevron_right\" }}\n </mat-icon>\n </button>\n <a mat-button (click)=\"onTreeNodeClick(node)\">\n {{ node.label }}\n </a>\n </div>\n <ul class=\"tree-nested-node\">\n @if (treeControl.isExpanded(node)) {\n <div>\n <ng-container matTreeNodeOutlet></ng-container>\n </div>\n }\n </ul>\n </li>\n </mat-nested-tree-node>\n</mat-tree>\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}\n"], dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1$1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$1.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "component", type: MatIconButton, selector: "button[mat-icon-button]", exportAs: ["matButton"] }, { kind: "directive", type: MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "component", type: MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: MatLabel, selector: "mat-label" }, { kind: "directive", type: MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly", "disabledInteractive"], exportAs: ["matInput"] }, { kind: "directive", type: MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "component", type: MatTree, selector: "mat-tree", exportAs: ["matTree"] }, { kind: "directive", type: MatTreeNodeDef, selector: "[matTreeNodeDef]", inputs: ["matTreeNodeDefWhen", "matTreeNode"] }, { kind: "directive", type: MatTreeNode, selector: "mat-tree-node", inputs: ["tabIndex", "disabled"], outputs: ["activation", "expandedChange"], exportAs: ["matTreeNode"] }, { kind: "directive", type: MatTreeNodeToggle, selector: "[matTreeNodeToggle]", inputs: ["matTreeNodeToggleRecursive"] }, { kind: "component", type: MatAnchor, selector: "a[mat-button], a[mat-raised-button], a[mat-flat-button], a[mat-stroked-button]", exportAs: ["matButton", "matAnchor"] }, { kind: "directive", type: MatNestedTreeNode, selector: "mat-nested-tree-node", inputs: ["matNestedTreeNode", "disabled", "tabIndex"], outputs: ["activation", "expandedChange"], exportAs: ["matNestedTreeNode"] }, { kind: "directive", type: MatTreeNodeOutlet, selector: "[matTreeNodeOutlet]" }] });
924
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.3", ngImport: i0, type: ThesaurusTreeComponent, deps: [{ token: i1$1.FormBuilder }], target: i0.ɵɵFactoryTarget.Component });
925
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.3", type: ThesaurusTreeComponent, isStandalone: true, selector: "cadmus-thesaurus-tree", inputs: { entries: { classPropertyName: "entries", publicName: "entries", isSignal: true, isRequired: false, transformFunction: null }, rootLabel: { classPropertyName: "rootLabel", publicName: "rootLabel", isSignal: true, isRequired: false, transformFunction: null }, renderLabel: { classPropertyName: "renderLabel", publicName: "renderLabel", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { entryChange: "entryChange" }, ngImport: i0, template: "<form [formGroup]=\"form\" (submit)=\"find()\">\n <button\n type=\"button\"\n mat-icon-button\n matTooltip=\"Expand all\"\n (click)=\"expandAll()\"\n >\n <mat-icon>unfold_more</mat-icon>\n </button>\n <button\n type=\"button\"\n mat-icon-button\n matTooltip=\"Collapse all\"\n (click)=\"collapseAll()\"\n >\n <mat-icon>unfold_less</mat-icon>\n </button>\n <mat-form-field>\n <mat-label>find</mat-label>\n <input matInput [formControl]=\"filter\" />\n <button\n type=\"button\"\n matSuffix\n mat-icon-button\n (click)=\"resetFilter()\"\n >\n <mat-icon class=\"mat-warn\">clear</mat-icon>\n </button>\n </mat-form-field>\n @if (foundNodes) {\n <span\n [ngClass]=\"{\n 'found-count': foundNodes.length,\n 'not-found-count': foundNodes.length === 0\n }\"\n >{{ foundNodes.length }}</span\n >\n }\n</form>\n<mat-tree\n [dataSource]=\"treeDataSource\"\n [treeControl]=\"treeControl\"\n class=\"th-tree\"\n>\n <!-- leaf node -->\n <mat-tree-node *matTreeNodeDef=\"let node\" matTreeNodeToggle>\n <li>\n <div class=\"mat-tree-node\">\n <a\n mat-button\n (click)=\"onTreeNodeClick(node)\"\n [class.hilite]=\"isFoundNode(node)\"\n >\n {{ node.label }}\n </a>\n </div>\n </li>\n </mat-tree-node>\n\n <!-- root node -->\n <mat-nested-tree-node *matTreeNodeDef=\"let node; when: isRoot\">\n <div class=\"mat-tree-node\">\n <button\n type=\"button\"\n mat-icon-button\n matTreeNodeToggle\n [attr.aria-label]=\"'Toggle ' + node.label\"\n >\n <mat-icon>\n {{ treeControl.isExpanded(node) ? \"expand_more\" : \"chevron_right\" }}\n </mat-icon>\n </button>\n {{ node.label }}\n </div>\n <ul class=\"tree-nested-node\">\n @if (treeControl.isExpanded(node)) {\n <div>\n <ng-container matTreeNodeOutlet></ng-container>\n </div>\n }\n </ul>\n </mat-nested-tree-node>\n\n <!-- parent node -->\n <mat-nested-tree-node *matTreeNodeDef=\"let node; when: hasChildren\">\n <li class=\"tree-container\">\n <div class=\"mat-tree-node\">\n <button\n type=\"button\"\n mat-icon-button\n matTreeNodeToggle\n [attr.aria-label]=\"'Toggle ' + node.label\"\n >\n <mat-icon>\n {{ treeControl.isExpanded(node) ? \"expand_more\" : \"chevron_right\" }}\n </mat-icon>\n </button>\n <a mat-button (click)=\"onTreeNodeClick(node)\">\n {{ node.label }}\n </a>\n </div>\n <ul class=\"tree-nested-node\">\n @if (treeControl.isExpanded(node)) {\n <div>\n <ng-container matTreeNodeOutlet></ng-container>\n </div>\n }\n </ul>\n </li>\n </mat-nested-tree-node>\n</mat-tree>\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}\n"], dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1$1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$1.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "component", type: MatIconButton, selector: "button[mat-icon-button]", exportAs: ["matButton"] }, { kind: "directive", type: MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "component", type: MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: MatLabel, selector: "mat-label" }, { kind: "directive", type: MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly", "disabledInteractive"], exportAs: ["matInput"] }, { kind: "directive", type: MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "component", type: MatTree, selector: "mat-tree", exportAs: ["matTree"] }, { kind: "directive", type: MatTreeNodeDef, selector: "[matTreeNodeDef]", inputs: ["matTreeNodeDefWhen", "matTreeNode"] }, { kind: "directive", type: MatTreeNode, selector: "mat-tree-node", inputs: ["tabIndex", "disabled"], outputs: ["activation", "expandedChange"], exportAs: ["matTreeNode"] }, { kind: "directive", type: MatTreeNodeToggle, selector: "[matTreeNodeToggle]", inputs: ["matTreeNodeToggleRecursive"] }, { kind: "component", type: MatAnchor, selector: "a[mat-button], a[mat-raised-button], a[mat-flat-button], a[mat-stroked-button]", exportAs: ["matButton", "matAnchor"] }, { kind: "directive", type: MatNestedTreeNode, selector: "mat-nested-tree-node", inputs: ["matNestedTreeNode", "disabled", "tabIndex"], outputs: ["activation", "expandedChange"], exportAs: ["matNestedTreeNode"] }, { kind: "directive", type: MatTreeNodeOutlet, selector: "[matTreeNodeOutlet]" }] });
884
926
  }
885
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.3", ngImport: i0, type: ThesaurusTreeComponent, decorators: [{
927
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.3", ngImport: i0, type: ThesaurusTreeComponent, decorators: [{
886
928
  type: Component,
887
929
  args: [{ selector: 'cadmus-thesaurus-tree', imports: [
888
930
  FormsModule,
@@ -916,6 +958,7 @@ class ModelEditorComponentBase {
916
958
  authService;
917
959
  formBuilder;
918
960
  _mebSubs = [];
961
+ _appRepository;
919
962
  /**
920
963
  * The root form of the editor.
921
964
  */
@@ -954,6 +997,28 @@ class ModelEditorComponentBase {
954
997
  * Emitted when the user requests to close the editor.
955
998
  */
956
999
  editorClose = output();
1000
+ /**
1001
+ * The human-friendly model name. This is computed from the model's
1002
+ * type ID and role ID, if any, using the types thesaurus set provided
1003
+ * by the app repository.
1004
+ */
1005
+ modelName = computed(() => {
1006
+ const identity = this.identity();
1007
+ // layers have no identity but have a layerPart
1008
+ if (!identity) {
1009
+ const layerPart = this.data()?.layerPart;
1010
+ if (layerPart) {
1011
+ return getPartIdName(layerPart.typeId, layerPart.roleId, this._appRepository?.getTypeThesaurus(), true // no fallback so that the part template can use its default name
1012
+ );
1013
+ }
1014
+ return undefined;
1015
+ }
1016
+ if (!identity) {
1017
+ return undefined;
1018
+ }
1019
+ return getPartIdName(identity.typeId, identity.roleId, this._appRepository?.getTypeThesaurus(), true // no fallback so that the part template can use its default name
1020
+ );
1021
+ });
957
1022
  /**
958
1023
  * Create a new instance of the editor.
959
1024
  *
@@ -966,6 +1031,7 @@ class ModelEditorComponentBase {
966
1031
  this.form = formBuilder.group({});
967
1032
  this.userLevel = 0;
968
1033
  this.isDirty$ = new BehaviorSubject(false);
1034
+ this._appRepository = inject(AppRepository);
969
1035
  effect(() => {
970
1036
  this.disableForm(this.disabled());
971
1037
  });
@@ -1112,10 +1178,10 @@ class ModelEditorComponentBase {
1112
1178
  // the form is no more dirty
1113
1179
  this.form.markAsPristine();
1114
1180
  }
1115
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.1.3", ngImport: i0, type: ModelEditorComponentBase, deps: [{ token: i1$3.AuthJwtService }, { token: i1$1.FormBuilder }], target: i0.ɵɵFactoryTarget.Component });
1116
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "19.1.3", type: ModelEditorComponentBase, isStandalone: false, selector: "ng-component", inputs: { identity: { classPropertyName: "identity", publicName: "identity", isSignal: true, isRequired: false, transformFunction: null }, data: { classPropertyName: "data", publicName: "data", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { data: "dataChange", dirtyChange: "dirtyChange", editorClose: "editorClose" }, ngImport: i0, template: '', isInline: true });
1181
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.3", ngImport: i0, type: ModelEditorComponentBase, deps: [{ token: i1$3.AuthJwtService }, { token: i1$1.FormBuilder }], target: i0.ɵɵFactoryTarget.Component });
1182
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "19.2.3", type: ModelEditorComponentBase, isStandalone: false, selector: "ng-component", inputs: { identity: { classPropertyName: "identity", publicName: "identity", isSignal: true, isRequired: false, transformFunction: null }, data: { classPropertyName: "data", publicName: "data", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { data: "dataChange", dirtyChange: "dirtyChange", editorClose: "editorClose" }, ngImport: i0, template: '', isInline: true });
1117
1183
  }
1118
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.3", ngImport: i0, type: ModelEditorComponentBase, decorators: [{
1184
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.3", ngImport: i0, type: ModelEditorComponentBase, decorators: [{
1119
1185
  type: Component,
1120
1186
  args: [{
1121
1187
  template: '',
@@ -1197,10 +1263,10 @@ class UserRefLookupService {
1197
1263
  getName(item) {
1198
1264
  return item?.user?.userName;
1199
1265
  }
1200
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.1.3", ngImport: i0, type: UserRefLookupService, deps: [{ token: i1$2.UserService }], target: i0.ɵɵFactoryTarget.Injectable });
1201
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.1.3", ngImport: i0, type: UserRefLookupService, providedIn: 'root' });
1266
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.3", ngImport: i0, type: UserRefLookupService, deps: [{ token: i1$2.UserService }], target: i0.ɵɵFactoryTarget.Injectable });
1267
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.3", ngImport: i0, type: UserRefLookupService, providedIn: 'root' });
1202
1268
  }
1203
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.3", ngImport: i0, type: UserRefLookupService, decorators: [{
1269
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.3", ngImport: i0, type: UserRefLookupService, decorators: [{
1204
1270
  type: Injectable,
1205
1271
  args: [{
1206
1272
  providedIn: 'root',
@@ -1264,5 +1330,5 @@ const extractPristineChanges = (control) => {
1264
1330
  * Generated bundle index. Do not edit.
1265
1331
  */
1266
1332
 
1267
- export { CloseSaveButtonsComponent, ColorService, CustomValidators, DecoratedTokenTextComponent, ErrorListComponent, FacetBadgeComponent, FlagsBadgeComponent, JsonValidators, LayerHintsComponent, LookupPinComponent, ModelEditorComponentBase, PartBadgeComponent, PartBadgeType, ThesaurusTreeComponent, UserRefLookupService, extractPristineChanges, extractTouchedChanges, renderLabelFromLastColon };
1333
+ export { CloseSaveButtonsComponent, ColorService, CustomValidators, DecoratedTokenTextComponent, ErrorListComponent, FacetBadgeComponent, FlagsBadgeComponent, JsonValidators, LayerHintsComponent, LookupPinComponent, ModelEditorComponentBase, PartBadgeComponent, PartBadgeType, ThesaurusTreeComponent, UserRefLookupService, extractPristineChanges, extractTouchedChanges, getPartIdName, renderLabelFromLastColon };
1268
1334
  //# sourceMappingURL=myrmidon-cadmus-ui.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"myrmidon-cadmus-ui.mjs","sources":["../../../../projects/myrmidon/cadmus-ui/src/lib/components/close-save-buttons/close-save-buttons.component.ts","../../../../projects/myrmidon/cadmus-ui/src/lib/components/close-save-buttons/close-save-buttons.component.html","../../../../projects/myrmidon/cadmus-ui/src/lib/components/decorated-token-text/decorated-token-text.component.ts","../../../../projects/myrmidon/cadmus-ui/src/lib/components/decorated-token-text/decorated-token-text.component.html","../../../../projects/myrmidon/cadmus-ui/src/lib/components/error-list/error-list.component.ts","../../../../projects/myrmidon/cadmus-ui/src/lib/components/error-list/error-list.component.html","../../../../projects/myrmidon/cadmus-ui/src/lib/services/color.service.ts","../../../../projects/myrmidon/cadmus-ui/src/lib/components/facet-badge/facet-badge.component.ts","../../../../projects/myrmidon/cadmus-ui/src/lib/components/facet-badge/facet-badge.component.html","../../../../projects/myrmidon/cadmus-ui/src/lib/components/flags-badge/flags-badge.component.ts","../../../../projects/myrmidon/cadmus-ui/src/lib/components/flags-badge/flags-badge.component.html","../../../../projects/myrmidon/cadmus-ui/src/lib/components/layer-hints/layer-hints.component.ts","../../../../projects/myrmidon/cadmus-ui/src/lib/components/layer-hints/layer-hints.component.html","../../../../projects/myrmidon/cadmus-ui/src/lib/components/lookup-pin/lookup-pin.component.ts","../../../../projects/myrmidon/cadmus-ui/src/lib/components/lookup-pin/lookup-pin.component.html","../../../../projects/myrmidon/cadmus-ui/src/lib/components/part-badge/part-badge.component.ts","../../../../projects/myrmidon/cadmus-ui/src/lib/components/part-badge/part-badge.component.html","../../../../projects/myrmidon/cadmus-ui/src/lib/components/thesaurus-tree/thesaurus-tree.component.ts","../../../../projects/myrmidon/cadmus-ui/src/lib/components/thesaurus-tree/thesaurus-tree.component.html","../../../../projects/myrmidon/cadmus-ui/src/lib/components/model-editor-component-base.ts","../../../../projects/myrmidon/cadmus-ui/src/lib/validators/custom-validators.ts","../../../../projects/myrmidon/cadmus-ui/src/lib/validators/json-validators.ts","../../../../projects/myrmidon/cadmus-ui/src/lib/services/user-ref-lookup.service.ts","../../../../projects/myrmidon/cadmus-ui/src/lib/utils.ts","../../../../projects/myrmidon/cadmus-ui/src/public-api.ts","../../../../projects/myrmidon/cadmus-ui/src/myrmidon-cadmus-ui.ts"],"sourcesContent":["import { Component, input, output } from '@angular/core';\r\nimport { FormGroup, UntypedFormGroup } from '@angular/forms';\r\n\r\nimport { MatButton } from '@angular/material/button';\r\nimport { MatIcon } from '@angular/material/icon';\r\n\r\n@Component({\r\n selector: 'cadmus-close-save-buttons',\r\n templateUrl: './close-save-buttons.component.html',\r\n styleUrls: ['./close-save-buttons.component.css'],\r\n imports: [MatButton, MatIcon],\r\n})\r\nexport class CloseSaveButtonsComponent {\r\n public readonly form = input<FormGroup | UntypedFormGroup>();\r\n\r\n public readonly noSave = input<boolean>();\r\n\r\n public readonly closeRequest = output();\r\n\r\n public close(): void {\r\n this.closeRequest.emit();\r\n }\r\n}\r\n","@if (form()) {\n<div class=\"form-row\">\n <button type=\"button\" mat-flat-button class=\"mat-warn\" (click)=\"close()\">\n <mat-icon>cancel</mat-icon>\n close\n </button>\n @if (!noSave()) {\n <button\n type=\"submit\"\n [disabled]=\"form()?.invalid\"\n mat-flat-button\n class=\"mat-primary\"\n >\n <mat-icon>check_circle</mat-icon>\n save\n </button>\n }\n</div>\n}\n","import {\r\n Component,\r\n OnInit,\r\n ViewChild,\r\n ElementRef,\r\n input,\r\n effect,\r\n} from '@angular/core';\r\n\r\nimport { SafeHtmlPipe } from '@myrmidon/ngx-tools';\r\n\r\nimport { TokenLocation, TextLayerService } from '@myrmidon/cadmus-core';\r\n\r\n/**\r\n * Decorated token-based text visualizer. This is used when editing\r\n * token-based text layers.\r\n */\r\n@Component({\r\n selector: 'cadmus-decorated-token-text',\r\n templateUrl: './decorated-token-text.component.html',\r\n styleUrls: ['./decorated-token-text.component.css'],\r\n imports: [SafeHtmlPipe],\r\n})\r\nexport class DecoratedTokenTextComponent implements OnInit {\r\n @ViewChild('textElem') _textElement?: ElementRef;\r\n\r\n /**\r\n * The base text.\r\n */\r\n public readonly baseText = input<string>('');\r\n\r\n /**\r\n * The token-based locations of all the fragments in the layer.\r\n */\r\n public readonly locations = input<TokenLocation[]>([]);\r\n\r\n /**\r\n * A selected token-based location.\r\n */\r\n public readonly selectedLocation = input<TokenLocation>();\r\n\r\n public text?: string; // rendered HTML text\r\n\r\n constructor(private _textLayerService: TextLayerService) {\r\n effect(() => {\r\n this.decorate(this.baseText(), this.locations(), this.selectedLocation());\r\n });\r\n }\r\n\r\n public ngOnInit(): void {\r\n this.decorate(this.baseText(), this.locations(), this.selectedLocation());\r\n }\r\n\r\n private decorate(\r\n text: string,\r\n locations: TokenLocation[],\r\n selectedLocation?: TokenLocation\r\n ): void {\r\n this.text = this._textLayerService.render(\r\n text,\r\n locations,\r\n selectedLocation\r\n );\r\n }\r\n}\r\n","<div [innerHtml]=\"text | safeHtml : 'html'\" id=\"text\" #textElem></div>\r\n","import { Component, input } from '@angular/core';\r\n\r\n@Component({\r\n selector: 'cadmus-error-list',\r\n templateUrl: './error-list.component.html',\r\n styleUrls: ['./error-list.component.css'],\r\n})\r\nexport class ErrorListComponent {\r\n public readonly errors = input<string[]>();\r\n}\r\n","@if (errors()?.length) {\n <ul>\n @for (error of errors(); track error) {\n <li class=\"error\">{{error}}</li>\n }\n </ul>\n}\n","import { Injectable } from '@angular/core';\r\n\r\n/**\r\n * Colors helper service.\r\n */\r\n@Injectable({\r\n providedIn: 'root',\r\n})\r\nexport class ColorService {\r\n /**\r\n * Get the R,G,B components of the color expressed by the specified\r\n * RGB string (3 or 6 digits format).\r\n *\r\n * @param rgb The RGB color string (3 or 6 digits).\r\n * @returns An array where [0]=R, [1]=G, [2]=B, or null if invalid\r\n * input string.\r\n */\r\n public getRgb(rgb: string): number[] | null {\r\n if (!rgb) {\r\n return null;\r\n }\r\n\r\n // RGB\r\n let m = rgb.match(/^#?([0-9a-f]{3})$/i);\r\n if (m && m[1]) {\r\n // in 3-characters format, each value is multiplied by 0x11 to give an\r\n // even scale from 0x00 to 0xff\r\n return [\r\n parseInt(m[1].charAt(0), 16) * 0x11,\r\n parseInt(m[1].charAt(1), 16) * 0x11,\r\n parseInt(m[1].charAt(2), 16) * 0x11,\r\n ];\r\n }\r\n // RRGGBB\r\n m = rgb.match(/^#?([0-9a-f]{6})$/i);\r\n if (m && m[1]) {\r\n return [\r\n parseInt(m[1].substring(0, 2), 16),\r\n parseInt(m[1].substring(2, 4), 16),\r\n parseInt(m[1].substring(4, 6), 16),\r\n ];\r\n }\r\n return null;\r\n }\r\n\r\n /**\r\n * Get black or white according to which of them has the maximum contrast\r\n * against the specified color.\r\n *\r\n * @param rgb The RGB color string.\r\n * @returns Black or white. If rgb is invalid, always black.\r\n */\r\n public getContrastColor(rgb: string): string {\r\n // https://stackoverflow.com/questions/3942878/how-to-decide-font-color-in-white-or-black-depending-on-background-color\r\n const values = this.getRgb(rgb);\r\n if (!values) {\r\n return 'black';\r\n }\r\n return values[0] * 0.299 + values[1] * 0.587 + values[2] * 0.114 > 186\r\n ? 'black'\r\n : 'white';\r\n }\r\n\r\n /**\r\n * Convert HSL to RGB.\r\n *\r\n * @param h Hue\r\n * @param s Saturation\r\n * @param l Lightness\r\n * @returns Object with r, g, b values.\r\n */\r\n public hslToRgb(\r\n h: number,\r\n s: number,\r\n l: number\r\n ): { r: number; g: number; b: number } {\r\n // https://css-tricks.com/converting-color-spaces-in-javascript/\r\n // must be fractions of 1\r\n s /= 100;\r\n l /= 100;\r\n\r\n let c = (1 - Math.abs(2 * l - 1)) * s,\r\n x = c * (1 - Math.abs(((h / 60) % 2) - 1)),\r\n m = l - c / 2,\r\n r = 0,\r\n g = 0,\r\n b = 0;\r\n if (0 <= h && h < 60) {\r\n r = c;\r\n g = x;\r\n b = 0;\r\n } else if (60 <= h && h < 120) {\r\n r = x;\r\n g = c;\r\n b = 0;\r\n } else if (120 <= h && h < 180) {\r\n r = 0;\r\n g = c;\r\n b = x;\r\n } else if (180 <= h && h < 240) {\r\n r = 0;\r\n g = x;\r\n b = c;\r\n } else if (240 <= h && h < 300) {\r\n r = x;\r\n g = 0;\r\n b = c;\r\n } else if (300 <= h && h < 360) {\r\n r = c;\r\n g = 0;\r\n b = x;\r\n }\r\n r = Math.round((r + m) * 255);\r\n g = Math.round((g + m) * 255);\r\n b = Math.round((b + m) * 255);\r\n\r\n return { r: r, g: g, b: b };\r\n }\r\n\r\n public rgbToString(r: number, g: number, b: number): string {\r\n let rd = r.toString(16);\r\n if (rd.length === 1) {\r\n rd = '0' + rd;\r\n }\r\n let gd = g.toString(16);\r\n if (gd.length === 1) {\r\n gd = '0' + gd;\r\n }\r\n let bd = b.toString(16);\r\n if (bd.length === 1) {\r\n bd = '0' + bd;\r\n }\r\n return rd + gd + bd;\r\n }\r\n\r\n /**\r\n * Get the next color from a palette generated to include\r\n * the specified count of colors.\r\n *\r\n * @param index The index of the next color in the palette.\r\n * @param count The total count of colors in the palette.\r\n * @param blueBoost True to adjust colors for the eye's lack of sensitivity to blue.\r\n * @returns The RRGGBB values string.\r\n */\r\n public nextPaletteColor(\r\n index: number,\r\n count: number,\r\n blueBoost = true\r\n ): string {\r\n // https://stackoverflow.com/questions/43193341/how-to-generate-random-pastel-or-brighter-color-in-javascript\r\n const h = Math.floor((index / count) * 341); // between 0 and 340\r\n let s = 100;\r\n let l = 50;\r\n\r\n if (blueBoost && h > 215 && h < 265) {\r\n const gain = 20;\r\n let blueness = 1 - Math.abs(h - 240) / 25;\r\n let change = Math.floor(gain * blueness);\r\n l += change;\r\n s -= change;\r\n }\r\n const rgb = this.hslToRgb(h, s, l);\r\n return this.rgbToString(rgb.r, rgb.g, rgb.b);\r\n }\r\n}\r\n","import { Component, effect, input, Input } from '@angular/core';\r\nimport { FacetDefinition } from '@myrmidon/cadmus-core';\r\n\r\nimport { MatTooltip } from '@angular/material/tooltip';\r\n\r\nimport { ColorService } from '../../services/color.service';\r\n\r\nexport interface FacetBadgeData {\r\n definitions: FacetDefinition[];\r\n facetId?: string;\r\n}\r\n\r\n@Component({\r\n selector: 'cadmus-facet-badge',\r\n templateUrl: './facet-badge.component.html',\r\n styleUrls: ['./facet-badge.component.css'],\r\n imports: [MatTooltip],\r\n})\r\nexport class FacetBadgeComponent {\r\n private _facetColors: { [key: string]: string };\r\n private _facetTips: { [key: string]: string };\r\n\r\n public color: string;\r\n public contrastColor: string;\r\n public tip?: string;\r\n\r\n /**\r\n * The facet data.\r\n */\r\n public readonly data = input<FacetBadgeData>({\r\n definitions: [],\r\n });\r\n\r\n constructor(private _colorService: ColorService) {\r\n this._facetColors = {};\r\n this._facetTips = {};\r\n this.color = 'transparent';\r\n this.contrastColor = 'black';\r\n\r\n effect(() => {\r\n this.updateBadge(this.data());\r\n });\r\n }\r\n\r\n private getFacetColor(facetId: string): string {\r\n if (this._facetColors[facetId]) {\r\n return this._facetColors[facetId];\r\n }\r\n if (!this.data().definitions?.length) {\r\n return 'transparent';\r\n }\r\n\r\n const facet = this.data().definitions.find((f) => {\r\n return f.id === facetId;\r\n });\r\n if (facet?.colorKey) {\r\n this._facetColors[facetId] = '#' + facet.colorKey;\r\n } else {\r\n this._facetColors[facetId] = 'transparent';\r\n }\r\n return this._facetColors[facetId];\r\n }\r\n\r\n private getFacetTip(facetId: string): string | null {\r\n if (this._facetTips[facetId]) {\r\n return this._facetTips[facetId];\r\n }\r\n\r\n if (!this.data().definitions?.length) {\r\n return null;\r\n }\r\n\r\n const facet = this.data().definitions.find((f) => {\r\n return f.id === facetId;\r\n });\r\n if (!facet) {\r\n this._facetTips[facetId] = facetId;\r\n } else {\r\n const sb: string[] = [];\r\n for (let i = 0; i < facet.partDefinitions.length; i++) {\r\n if (i > 0) {\r\n sb.push(', ');\r\n }\r\n sb.push(facet.partDefinitions[i].name);\r\n if (facet.partDefinitions[i].isRequired) {\r\n sb.push('*');\r\n }\r\n }\r\n this._facetTips[facetId] = sb.join('');\r\n }\r\n return this._facetTips[facetId];\r\n }\r\n\r\n private updateBadge(data?: FacetBadgeData) {\r\n this._facetColors = {};\r\n this._facetTips = {};\r\n this.color = this.getFacetColor(data?.facetId || '');\r\n this.contrastColor = this._colorService.getContrastColor(this.color);\r\n this.tip = this.getFacetTip(data?.facetId || '') ?? undefined;\r\n }\r\n}\r\n","<span\r\n class=\"model-type\"\r\n [style.background-color]=\"color\"\r\n [style.color]=\"contrastColor\"\r\n matTooltip=\"{{ tip }}\"\r\n >{{ data().facetId }}\r\n</span>\r\n","import { Component, effect, input, Input } from '@angular/core';\r\n\r\nimport { MatTooltip } from '@angular/material/tooltip';\r\n\r\nimport { FlagDefinition } from '@myrmidon/cadmus-core';\r\n\r\n/**\r\n * Data for FlagsBadgeComponent, including flags and their definitions.\r\n */\r\nexport interface FlagsBadgeData {\r\n definitions: FlagDefinition[];\r\n flags: number;\r\n}\r\n\r\n/**\r\n * Badge with item's flags. Each flag is represented by a circle filled\r\n * with the flag's color key.\r\n */\r\n@Component({\r\n selector: 'cadmus-flags-badge',\r\n templateUrl: './flags-badge.component.html',\r\n styleUrls: ['./flags-badge.component.css'],\r\n imports: [MatTooltip],\r\n})\r\nexport class FlagsBadgeComponent {\r\n public badgeFlags: FlagDefinition[] = [];\r\n\r\n public readonly data = input<FlagsBadgeData>();\r\n\r\n constructor() {\r\n effect(() => {\r\n this.updateBadge(this.data());\r\n });\r\n }\r\n\r\n private updateBadge(data?: FlagsBadgeData) {\r\n if (!data) {\r\n return;\r\n }\r\n this.badgeFlags = data.definitions.filter((def) => {\r\n // tslint:disable-next-line: no-bitwise\r\n return def.id & data!.flags;\r\n });\r\n }\r\n}\r\n","<div>\n @for (def of badgeFlags; track def.id) {\n <span\n class=\"badge-flag\"\n [style.color]=\"'#' + def.colorKey\"\n [matTooltip]=\"def.label\"\n >\n @if (def.isAdmin) { &#x25c6; } @else { &#x2b24; }\n </span>\n }\n</div>\n","import {\r\n Component,\r\n OnInit,\r\n Input,\r\n Output,\r\n EventEmitter,\r\n output,\r\n input,\r\n effect,\r\n} from '@angular/core';\r\nimport {\r\n FormGroup,\r\n FormArray,\r\n FormBuilder,\r\n FormsModule,\r\n ReactiveFormsModule,\r\n} from '@angular/forms';\r\n\r\nimport { MatIconButton, MatButton } from '@angular/material/button';\r\nimport { MatTooltip } from '@angular/material/tooltip';\r\nimport { MatIcon } from '@angular/material/icon';\r\nimport { MatCheckbox } from '@angular/material/checkbox';\r\n\r\nimport { DialogService } from '@myrmidon/ngx-mat-tools';\r\n\r\nimport { LayerHint } from '@myrmidon/cadmus-core';\r\n\r\n@Component({\r\n selector: 'cadmus-layer-hints',\r\n templateUrl: './layer-hints.component.html',\r\n styleUrls: ['./layer-hints.component.css'],\r\n imports: [\r\n FormsModule,\r\n ReactiveFormsModule,\r\n MatIconButton,\r\n MatTooltip,\r\n MatIcon,\r\n MatCheckbox,\r\n MatButton,\r\n ],\r\n})\r\nexport class LayerHintsComponent {\r\n public readonly hints = input<LayerHint[]>([]);\r\n\r\n public readonly targetLocation = input<string>();\r\n public readonly disabled = input<boolean>();\r\n public readonly readonly = input<boolean>();\r\n\r\n public readonly requestEdit = output<LayerHint>();\r\n public readonly requestDelete = output<LayerHint>();\r\n public readonly requestMove = output<LayerHint>();\r\n public readonly requestPatch = output<string[]>();\r\n\r\n public form: FormGroup;\r\n public checks: FormArray;\r\n\r\n constructor(\r\n private _formBuilder: FormBuilder,\r\n private _dialogService: DialogService\r\n ) {\r\n this.checks = _formBuilder.array([]);\r\n this.form = _formBuilder.group({\r\n checks: this.checks,\r\n });\r\n\r\n effect(() => {\r\n this.updateChecks(this.hints());\r\n });\r\n }\r\n\r\n private updateChecks(hints: LayerHint[]) {\r\n this.checks.controls = [];\r\n for (let i = 0; i < hints.length; i++) {\r\n this.checks.push(this._formBuilder.control(false));\r\n }\r\n }\r\n\r\n public emitRequestEdit(hint: LayerHint) {\r\n this.requestEdit.emit(hint);\r\n }\r\n\r\n public emitRequestDelete(hint: LayerHint) {\r\n this._dialogService\r\n .confirm('Confirm Deletion', `Delete fragment at \"${hint.location}\"?`)\r\n .subscribe((ok: boolean) => {\r\n if (ok) {\r\n this.requestDelete.emit(hint);\r\n }\r\n });\r\n }\r\n\r\n public emitRequestMove(hint: LayerHint) {\r\n if (!this.targetLocation) {\r\n return;\r\n }\r\n this._dialogService\r\n .confirm(\r\n 'Confirm Move',\r\n `Move fragment at ${hint.location} to ${this.targetLocation}?`\r\n )\r\n .subscribe((ok: boolean) => {\r\n if (ok) {\r\n this.requestMove.emit(hint);\r\n }\r\n });\r\n }\r\n\r\n public emitRequestPatch() {\r\n if (this.form.invalid) {\r\n return;\r\n }\r\n this._dialogService\r\n .confirm('Confirm Patch', `Patch the selected fragments?`)\r\n .subscribe((ok: boolean) => {\r\n if (ok) {\r\n const patches: string[] = [];\r\n for (let i = 0; i < this.checks.controls.length; i++) {\r\n const n = this.checks.controls[i].value;\r\n if (n) {\r\n patches.push(this.hints()[n - 1].patchOperation!);\r\n }\r\n }\r\n this.requestPatch.emit(patches);\r\n }\r\n });\r\n }\r\n}\r\n","@if (hints().length) {\n<form [formGroup]=\"form\" (submit)=\"emitRequestPatch()\">\n <table class=\"patches\">\n <thead>\n <tr>\n <th></th>\n <th>location</th>\n <th>description</th>\n <th>patch</th>\n </tr>\n </thead>\n <tbody>\n @for (hint of hints(); track hint; let i = $index) {\n <tr>\n @if (!readonly()) {\n <td>\n <button\n type=\"button\"\n mat-icon-button\n matTooltip=\"Edit this fragment\"\n [disabled]=\"disabled()\"\n >\n <mat-icon>edit</mat-icon>\n </button>\n <button\n type=\"button\"\n mat-icon-button\n matTooltip=\"Move this fragment to {{ targetLocation() }}\"\n [disabled]=\"\n disabled() || !targetLocation() || targetLocation() === hint.location\n \"\n (click)=\"emitRequestMove(hint)\"\n >\n <mat-icon>arrow_forward</mat-icon>\n </button>\n <button\n type=\"button\"\n mat-icon-button\n matTooltip=\"Delete this fragment\"\n [disabled]=\"disabled()\"\n (click)=\"emitRequestDelete(hint)\"\n >\n <mat-icon class=\"mat-warn\">delete</mat-icon>\n </button>\n </td>\n }\n <td>{{ hint.location }}</td>\n <td>{{ hint.description }}</td>\n <td>\n @if (hint.patchOperation) {\n <mat-checkbox\n matTooltip=\"Apply this patch\"\n [disabled]=\"disabled()\"\n [value]=\"(i + 1).toString()\"\n >\n {{ hint.patchOperation }}\n </mat-checkbox>\n }\n </td>\n </tr>\n }\n </tbody>\n </table>\n @if (targetLocation()) {\n <div>move target: {{ targetLocation() }}</div>\n }\n <button\n type=\"submit\"\n mat-flat-button\n [disabled]=\"readonly() || disabled() || form.invalid\"\n >\n apply patches\n </button>\n</form>\n}\n","import {\r\n Component,\r\n effect,\r\n Inject,\r\n input,\r\n OnInit,\r\n output,\r\n} from '@angular/core';\r\nimport { AsyncPipe } from '@angular/common';\r\nimport {\r\n UntypedFormBuilder,\r\n UntypedFormControl,\r\n UntypedFormGroup,\r\n FormsModule,\r\n ReactiveFormsModule,\r\n} from '@angular/forms';\r\nimport { Observable, of } from 'rxjs';\r\nimport {\r\n debounceTime,\r\n distinctUntilChanged,\r\n map,\r\n switchMap,\r\n take,\r\n} from 'rxjs/operators';\r\n\r\nimport {\r\n MatAutocomplete,\r\n MatAutocompleteTrigger,\r\n} from '@angular/material/autocomplete';\r\nimport { MatOption } from '@angular/material/core';\r\nimport { MatFormField } from '@angular/material/form-field';\r\nimport { MatInput } from '@angular/material/input';\r\nimport { MatIconButton } from '@angular/material/button';\r\nimport { MatTooltip } from '@angular/material/tooltip';\r\nimport { MatIcon } from '@angular/material/icon';\r\n\r\nimport { DataPage, ErrorWrapper } from '@myrmidon/ngx-tools';\r\n\r\nimport { DataPinInfo, IndexLookupDefinitions } from '@myrmidon/cadmus-core';\r\nimport { ItemService } from '@myrmidon/cadmus-api';\r\n\r\n/**\r\n * Generic data pin lookup component. This allows users typing a part\r\n * of a pin's value, and get the full pin. For instance, if you have\r\n * a lookup set of colors and type \"gr\", you might get the pins\r\n * corresponding to \"green\" (e.g. id=color, value=green), \"gray\", etc.\r\n * Usage: add a FormControl to hold a DataPinInfo value; in the HTML\r\n * template set the component's lookupKey, label, initialValue, and\r\n * entryChange handler. The initialValue, if any, should be the initial\r\n * DataPinInfo value.\r\n * If you are using this component as a pure lookup device, don't set\r\n * the initialValue and set resetOnPick=true.\r\n */\r\n@Component({\r\n selector: 'cadmus-lookup-pin',\r\n templateUrl: './lookup-pin.component.html',\r\n styleUrls: ['./lookup-pin.component.css'],\r\n imports: [\r\n FormsModule,\r\n ReactiveFormsModule,\r\n MatAutocomplete,\r\n MatOption,\r\n MatFormField,\r\n MatInput,\r\n MatAutocompleteTrigger,\r\n MatIconButton,\r\n MatTooltip,\r\n MatIcon,\r\n AsyncPipe,\r\n ],\r\n})\r\nexport class LookupPinComponent implements OnInit {\r\n /**\r\n * The entry value initially set when the component loads.\r\n */\r\n public readonly initialValue = input<string>();\r\n\r\n /**\r\n * The label to be displayed for this lookup.\r\n */\r\n public readonly label = input<string>('');\r\n\r\n /**\r\n * The maximum count of lookup entries to retrieve.\r\n * Default is 10.\r\n */\r\n public readonly limit = input<number>(10);\r\n\r\n /**\r\n * True to reset the lookup value after it is picked.\r\n * This is typically used when you use this component\r\n * as a pure lookup device, storing the picked value\r\n * elsewhere when handling its entryChange event.\r\n */\r\n public readonly resetOnPick = input<boolean>();\r\n\r\n /**\r\n * Fired whenever an entry is picked. Usually you should\r\n * cast the received argument to a more specific type.\r\n */\r\n public readonly entryChange = output<DataPinInfo | null>();\r\n\r\n public form: UntypedFormGroup;\r\n public lookup: UntypedFormControl;\r\n public entries$: Observable<DataPinInfo[]> | undefined;\r\n public entry: DataPinInfo | undefined;\r\n\r\n constructor(\r\n formBuilder: UntypedFormBuilder,\r\n private _itemService: ItemService,\r\n @Inject('indexLookupDefinitions')\r\n private _lookupDefs: IndexLookupDefinitions\r\n ) {\r\n // form\r\n this.lookup = formBuilder.control(null);\r\n this.form = formBuilder.group({\r\n lookup: this.lookup,\r\n });\r\n\r\n effect(() => {\r\n console.log('lookup pin initial value', this.initialValue());\r\n if (this.lookup) {\r\n this.resetToInitial();\r\n }\r\n });\r\n }\r\n\r\n /**\r\n * The lookup key to be used for this component.\r\n * This should be a key from the injectable indexLookupDefinitions.\r\n */\r\n public readonly lookupKey = input<string>();\r\n\r\n public ngOnInit(): void {\r\n this.entries$ = this.lookup.valueChanges.pipe(\r\n debounceTime(300),\r\n distinctUntilChanged(),\r\n switchMap((value: DataPinInfo | string) => {\r\n // if it's a string it's a filter; else it's the entry got\r\n if (typeof value === 'string') {\r\n return this.lookupEntries(value, this.limit());\r\n } else {\r\n return of([value]);\r\n }\r\n })\r\n );\r\n // setup initial value if its name was specified\r\n if (this.initialValue()) {\r\n this.resetToInitial();\r\n }\r\n }\r\n\r\n private lookupEntries(\r\n filter: string,\r\n limit: number\r\n ): Observable<DataPinInfo[]> {\r\n // get the lookup definition\r\n if (!this.lookupKey() || !filter) {\r\n return of([]);\r\n }\r\n const ld = this._lookupDefs[this.lookupKey()!];\r\n if (!ld) {\r\n return of([]);\r\n }\r\n\r\n // build query\r\n const query = ld.roleId\r\n ? `[partTypeId=${ld.typeId}] AND [roleId=${ld.roleId}] AND [name=${ld.name}] AND [value^=${filter}]`\r\n : `[partTypeId=${ld.typeId}] AND [name=${ld.name}] AND [value^=${filter}]`;\r\n\r\n // search\r\n return this._itemService.searchPins(query, 1, limit).pipe(\r\n map((w: ErrorWrapper<DataPage<DataPinInfo>>) => {\r\n if (w.error) {\r\n return [];\r\n } else {\r\n return w.value?.items || [];\r\n }\r\n })\r\n );\r\n }\r\n\r\n private resetToInitial(): void {\r\n this.lookupEntries(this.initialValue() || '', 1)\r\n .pipe(take(1))\r\n .subscribe((entries) => {\r\n this.lookup.setValue(entries.length ? entries[0] : undefined);\r\n });\r\n }\r\n\r\n public clear(): void {\r\n this.entry = undefined;\r\n this.lookup.setValue(null);\r\n this.entryChange.emit(null);\r\n }\r\n\r\n public entryToName(entry: DataPinInfo): string {\r\n return entry?.value;\r\n }\r\n\r\n public pickEntry(entry: DataPinInfo): void {\r\n this.entry = entry;\r\n this.entryChange.emit(entry);\r\n if (this.resetOnPick()) {\r\n this.clear();\r\n }\r\n }\r\n}\r\n","<form [formGroup]=\"form\">\n <mat-autocomplete #lookupAuto=\"matAutocomplete\" [displayWith]=\"entryToName\">\n @for (entry of entries$ | async; track entry) {\n <mat-option [value]=\"entry\" (onSelectionChange)=\"pickEntry(entry)\">\n {{ entry?.value }}\n </mat-option>\n }\n </mat-autocomplete>\n\n <mat-form-field>\n <input\n matInput\n type=\"text\"\n [placeholder]=\"label()\"\n [formControl]=\"lookup\"\n [matAutocomplete]=\"lookupAuto\"\n />\n </mat-form-field>\n <button\n type=\"button\"\n mat-icon-button\n (click)=\"clear()\"\n [disabled]=\"!entry\"\n matTooltip=\"Clear\"\n >\n <mat-icon class=\"mat-warn\">clear</mat-icon>\n </button>\n</form>\n","import { Component, effect, input } from '@angular/core';\r\n\r\nimport { Thesaurus, FacetDefinition, PartTypeIds } from '@myrmidon/cadmus-core';\r\nimport { FacetService } from '@myrmidon/cadmus-api';\r\n\r\nimport { ColorService } from '../../services/color.service';\r\n\r\nexport enum PartBadgeType {\r\n partAndRole = 0,\r\n partOnly = 1,\r\n roleOnly = 2,\r\n}\r\n\r\n@Component({\r\n selector: 'cadmus-part-badge',\r\n templateUrl: './part-badge.component.html',\r\n styleUrls: ['./part-badge.component.css'],\r\n})\r\nexport class PartBadgeComponent {\r\n public typeName: string | undefined;\r\n public roleName: string | undefined;\r\n public color: string;\r\n public contrastColor: string;\r\n\r\n /**\r\n * The badge type: 0=part and role, 1=part only, 2=role only.\r\n */\r\n public readonly badgeType = input<PartBadgeType>(PartBadgeType.partAndRole);\r\n\r\n /**\r\n * The types thesaurus.\r\n */\r\n public readonly typeThesaurus = input<Thesaurus>();\r\n\r\n /**\r\n * The part's facet definition.\r\n */\r\n public readonly facetDefinition = input<FacetDefinition>();\r\n\r\n /**\r\n * The part type IDs.\r\n */\r\n public readonly partTypeIds = input<PartTypeIds>();\r\n\r\n constructor(\r\n private _facetService: FacetService,\r\n private _colorService: ColorService\r\n ) {\r\n this.color = 'transparent';\r\n this.contrastColor = 'black';\r\n\r\n effect(() => {\r\n this.updateBadge(\r\n this.partTypeIds(),\r\n this.typeThesaurus(),\r\n this.facetDefinition()\r\n );\r\n });\r\n }\r\n\r\n private getPartColor(\r\n typeId: string,\r\n roleId?: string,\r\n facetDefinition?: FacetDefinition\r\n ): string {\r\n if (!facetDefinition) {\r\n return 'transparent';\r\n }\r\n return this._facetService.getPartColor(typeId, roleId, facetDefinition);\r\n }\r\n\r\n private getTypeIdName(typeId: string, typeThesaurus?: Thesaurus): string {\r\n if (!typeThesaurus) {\r\n return typeId;\r\n }\r\n // strip :suffix if any\r\n const i = typeId.lastIndexOf(':');\r\n if (i > -1) {\r\n typeId = typeId.substring(0, i);\r\n }\r\n const entry = typeThesaurus.entries?.find((e) => e.id === typeId);\r\n return entry ? entry.value : typeId;\r\n }\r\n\r\n private getRoleIdName(\r\n roleId?: string,\r\n typeThesaurus?: Thesaurus\r\n ): string | undefined {\r\n if (!roleId || !roleId.startsWith('fr.')) {\r\n return roleId;\r\n }\r\n return this.getTypeIdName(roleId, typeThesaurus);\r\n }\r\n\r\n private updateBadge(\r\n partTypeIds?: PartTypeIds,\r\n typeThesaurus?: Thesaurus,\r\n facetDefinition?: FacetDefinition\r\n ): void {\r\n if (partTypeIds) {\r\n this.color = this.getPartColor(\r\n partTypeIds.typeId,\r\n partTypeIds.roleId,\r\n facetDefinition\r\n );\r\n this.typeName = this.getTypeIdName(partTypeIds.typeId, typeThesaurus);\r\n this.roleName = this.getRoleIdName(partTypeIds.roleId, typeThesaurus);\r\n } else {\r\n this.color = 'transparent';\r\n this.typeName = undefined;\r\n this.roleName = undefined;\r\n }\r\n this.contrastColor = this._colorService.getContrastColor(this.color);\r\n }\r\n}\r\n","@if (badgeType() !== 2) {\n<span\n class=\"part-badge\"\n [style.background-color]=\"color\"\n [style.color]=\"contrastColor\"\n>\n {{ typeName }}\n</span>\n} @if (badgeType() !== 1 && roleName) {\n<span class=\"role-badge\">\n {{ roleName }}\n</span>\n}\n","import { NestedTreeControl } from '@angular/cdk/tree';\r\nimport { Component, effect, input, OnInit, output } from '@angular/core';\r\nimport {\r\n FormBuilder,\r\n FormControl,\r\n FormGroup,\r\n FormsModule,\r\n ReactiveFormsModule,\r\n} from '@angular/forms';\r\nimport { NgClass } from '@angular/common';\r\n\r\nimport {\r\n MatTreeNestedDataSource,\r\n MatTree,\r\n MatTreeNodeDef,\r\n MatTreeNode,\r\n MatTreeNodeToggle,\r\n MatNestedTreeNode,\r\n MatTreeNodeOutlet,\r\n} from '@angular/material/tree';\r\nimport { MatIconButton, MatAnchor } from '@angular/material/button';\r\nimport { MatTooltip } from '@angular/material/tooltip';\r\nimport { MatIcon } from '@angular/material/icon';\r\nimport {\r\n MatFormField,\r\n MatLabel,\r\n MatSuffix,\r\n} from '@angular/material/form-field';\r\nimport { MatInput } from '@angular/material/input';\r\n\r\nimport { ThesaurusEntry } from '@myrmidon/cadmus-core';\r\n\r\ninterface TreeNode {\r\n id: string;\r\n label: string;\r\n originalLabel?: string;\r\n parent?: TreeNode;\r\n children?: TreeNode[];\r\n clickable?: boolean;\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 const 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\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. Note that even if you specify a label renderer\r\n * function, the event always emits the original label.\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: [\r\n FormsModule,\r\n ReactiveFormsModule,\r\n MatIconButton,\r\n MatTooltip,\r\n MatIcon,\r\n MatFormField,\r\n MatLabel,\r\n MatInput,\r\n MatSuffix,\r\n NgClass,\r\n MatTree,\r\n MatTreeNodeDef,\r\n MatTreeNode,\r\n MatTreeNodeToggle,\r\n MatAnchor,\r\n MatNestedTreeNode,\r\n MatTreeNodeOutlet,\r\n ],\r\n})\r\nexport class ThesaurusTreeComponent implements OnInit {\r\n /**\r\n * The thesaurus entries.\r\n */\r\n public readonly entries = input<ThesaurusEntry[]>();\r\n\r\n /**\r\n * The label for the root node.\r\n */\r\n public readonly rootLabel = input<string>('-');\r\n /**\r\n * The optional node label rendering function.\r\n */\r\n public readonly renderLabel = input<(label: string) => string>();\r\n /**\r\n * Fired when a thesaurus entry is selected.\r\n */\r\n public readonly entryChange = output<ThesaurusEntry>();\r\n\r\n public root: TreeNode;\r\n // TODO: use childrenAccessor: https://material.angular.io/cdk/tree/examples\r\n public treeControl: NestedTreeControl<TreeNode>;\r\n public treeDataSource: MatTreeNestedDataSource<TreeNode>;\r\n\r\n public filter: FormControl<string | null>;\r\n public form: FormGroup;\r\n public foundNodes: TreeNode[] | undefined;\r\n\r\n public hasChildren = (index: number, node: TreeNode) => {\r\n return node && node.children && node.children.length > 0;\r\n };\r\n\r\n public isRoot = (index: number, node: TreeNode) => {\r\n return node && node.id === '@root';\r\n };\r\n\r\n constructor(formBuilder: FormBuilder) {\r\n // tree\r\n this.treeControl = new NestedTreeControl<TreeNode>((node) => node.children);\r\n this.treeDataSource = new MatTreeNestedDataSource<TreeNode>();\r\n this.root = { id: '@root', label: '-', children: [] };\r\n // filter\r\n this.filter = formBuilder.control(null);\r\n this.form = formBuilder.group({\r\n filter: this.filter,\r\n });\r\n\r\n effect(() => {\r\n this.initTree(this.entries());\r\n });\r\n }\r\n\r\n public ngOnInit(): void {\r\n this.initTree();\r\n }\r\n\r\n private initTree(entries?: ThesaurusEntry[]): void {\r\n this.foundNodes = undefined;\r\n\r\n this.root = this.buildTreeModel(entries || []);\r\n this.treeDataSource.data = [this.root];\r\n // https://github.com/angular/components/issues/12469\r\n this.treeControl.dataNodes = this.treeDataSource.data;\r\n }\r\n\r\n private getLabel(label: string): string {\r\n const renderer = this.renderLabel();\r\n return renderer ? renderer(label) : label;\r\n }\r\n\r\n private addNode(\r\n entry: ThesaurusEntry,\r\n separator: string,\r\n root: TreeNode\r\n ): void {\r\n const components = entry.id.split(separator);\r\n\r\n // walk the tree up to the last existing component\r\n let i = 0;\r\n let node = root;\r\n const idParts: string[] = [];\r\n\r\n // for each component:\r\n while (i < components.length) {\r\n idParts.push(components[i]);\r\n\r\n // stop walking when the node has no more children\r\n if (!node.children) {\r\n break;\r\n }\r\n // find target among children\r\n const targetId = idParts.join(separator);\r\n const existing = node.children.find((c) => {\r\n return c.id === targetId;\r\n });\r\n if (existing) {\r\n node = existing;\r\n i++;\r\n } else {\r\n break;\r\n }\r\n }\r\n\r\n // node is now the last existing component; use it as the ancestor\r\n // for all the remaining components (starting from i)\r\n while (i < components.length) {\r\n if (!node.children) {\r\n node.children = [];\r\n }\r\n const isLast = i + 1 === components.length;\r\n const label = isLast ? entry.value : components[i];\r\n const child: TreeNode = {\r\n label: isLast ? this.getLabel(label) : label,\r\n id: isLast ? entry.id : idParts.join(separator),\r\n parent: node,\r\n children: [],\r\n };\r\n if (label !== child.label) {\r\n child.originalLabel = label;\r\n }\r\n node.children.push(child);\r\n node = child;\r\n i++;\r\n }\r\n }\r\n\r\n /**\r\n * Build a tree model from a list of name=value pairs,\r\n * where each value can include one or more components separated by\r\n * the specified separator.\r\n * @param entries The entries to add.\r\n * @param separator string The separator string to use for values.\r\n */\r\n public buildTreeModel(entries: ThesaurusEntry[], separator = '.'): TreeNode {\r\n const root: TreeNode = {\r\n id: '@root',\r\n label: this.rootLabel() || '-',\r\n };\r\n if (!entries) {\r\n return root;\r\n }\r\n entries.forEach((entry) => {\r\n this.addNode(entry, separator, root);\r\n });\r\n return root;\r\n }\r\n\r\n public onTreeNodeClick(node: TreeNode): void {\r\n if (node.children && node.children.length > 0) {\r\n return;\r\n }\r\n this.entryChange.emit({\r\n id: node.id,\r\n value: node.originalLabel || node.label,\r\n });\r\n }\r\n\r\n public expandAll(): void {\r\n this.treeControl.expandAll();\r\n }\r\n\r\n public collapseAll(): void {\r\n this.treeControl.collapseAll();\r\n }\r\n\r\n private expandFromNode(node: TreeNode): void {\r\n while (node.parent) {\r\n node = node.parent;\r\n this.treeControl.expand(node);\r\n }\r\n }\r\n\r\n private expandMatchingNodes(\r\n node: TreeNode,\r\n filter: string,\r\n found: TreeNode[]\r\n ): void {\r\n if (node.label.toLowerCase().includes(filter)) {\r\n found.push(node);\r\n this.expandFromNode(node);\r\n }\r\n if (node.children?.length) {\r\n node.children.forEach((child) => {\r\n this.expandMatchingNodes(child, filter, found);\r\n });\r\n }\r\n }\r\n\r\n public find(): void {\r\n if (!this.filter.value?.length) {\r\n return;\r\n }\r\n this.treeControl.collapseAll();\r\n const foundNodes: TreeNode[] = [];\r\n this.expandMatchingNodes(\r\n this.treeDataSource.data[0],\r\n this.filter.value.toLowerCase(),\r\n foundNodes\r\n );\r\n this.foundNodes = foundNodes;\r\n }\r\n\r\n public resetFilter(): void {\r\n this.filter.reset();\r\n this.foundNodes = undefined;\r\n }\r\n\r\n public isFoundNode(node: TreeNode): boolean {\r\n if (!this.foundNodes) {\r\n return false;\r\n }\r\n return this.foundNodes?.length > 0 && this.foundNodes.indexOf(node) > -1;\r\n }\r\n}\r\n","<form [formGroup]=\"form\" (submit)=\"find()\">\n <button\n type=\"button\"\n mat-icon-button\n matTooltip=\"Expand all\"\n (click)=\"expandAll()\"\n >\n <mat-icon>unfold_more</mat-icon>\n </button>\n <button\n type=\"button\"\n mat-icon-button\n matTooltip=\"Collapse all\"\n (click)=\"collapseAll()\"\n >\n <mat-icon>unfold_less</mat-icon>\n </button>\n <mat-form-field>\n <mat-label>find</mat-label>\n <input matInput [formControl]=\"filter\" />\n <button\n type=\"button\"\n matSuffix\n mat-icon-button\n (click)=\"resetFilter()\"\n >\n <mat-icon class=\"mat-warn\">clear</mat-icon>\n </button>\n </mat-form-field>\n @if (foundNodes) {\n <span\n [ngClass]=\"{\n 'found-count': foundNodes.length,\n 'not-found-count': foundNodes.length === 0\n }\"\n >{{ foundNodes.length }}</span\n >\n }\n</form>\n<mat-tree\n [dataSource]=\"treeDataSource\"\n [treeControl]=\"treeControl\"\n class=\"th-tree\"\n>\n <!-- leaf node -->\n <mat-tree-node *matTreeNodeDef=\"let node\" matTreeNodeToggle>\n <li>\n <div class=\"mat-tree-node\">\n <a\n mat-button\n (click)=\"onTreeNodeClick(node)\"\n [class.hilite]=\"isFoundNode(node)\"\n >\n {{ node.label }}\n </a>\n </div>\n </li>\n </mat-tree-node>\n\n <!-- root node -->\n <mat-nested-tree-node *matTreeNodeDef=\"let node; when: isRoot\">\n <div class=\"mat-tree-node\">\n <button\n type=\"button\"\n mat-icon-button\n matTreeNodeToggle\n [attr.aria-label]=\"'Toggle ' + node.label\"\n >\n <mat-icon>\n {{ treeControl.isExpanded(node) ? \"expand_more\" : \"chevron_right\" }}\n </mat-icon>\n </button>\n {{ node.label }}\n </div>\n <ul class=\"tree-nested-node\">\n @if (treeControl.isExpanded(node)) {\n <div>\n <ng-container matTreeNodeOutlet></ng-container>\n </div>\n }\n </ul>\n </mat-nested-tree-node>\n\n <!-- parent node -->\n <mat-nested-tree-node *matTreeNodeDef=\"let node; when: hasChildren\">\n <li class=\"tree-container\">\n <div class=\"mat-tree-node\">\n <button\n type=\"button\"\n mat-icon-button\n matTreeNodeToggle\n [attr.aria-label]=\"'Toggle ' + node.label\"\n >\n <mat-icon>\n {{ treeControl.isExpanded(node) ? \"expand_more\" : \"chevron_right\" }}\n </mat-icon>\n </button>\n <a mat-button (click)=\"onTreeNodeClick(node)\">\n {{ node.label }}\n </a>\n </div>\n <ul class=\"tree-nested-node\">\n @if (treeControl.isExpanded(node)) {\n <div>\n <ng-container matTreeNodeOutlet></ng-container>\n </div>\n }\n </ul>\n </li>\n </mat-nested-tree-node>\n</mat-tree>\n","import {\r\n Component,\r\n OnDestroy,\r\n OnInit,\r\n output,\r\n input,\r\n effect,\r\n model,\r\n} from '@angular/core';\r\nimport {\r\n FormBuilder,\r\n FormGroup,\r\n PristineChangeEvent,\r\n UntypedFormGroup,\r\n} from '@angular/forms';\r\nimport { BehaviorSubject, Subscription } from 'rxjs';\r\n\r\nimport { deepCopy } from '@myrmidon/ngx-tools';\r\nimport { AuthJwtService, User } from '@myrmidon/auth-jwt-login';\r\n\r\nimport {\r\n Fragment,\r\n Part,\r\n TextLayerPart,\r\n ThesauriSet,\r\n} from '@myrmidon/cadmus-core';\r\n\r\n/**\r\n * The identifiers for an edited part.\r\n */\r\nexport interface PartIdentity {\r\n itemId: string;\r\n typeId: string;\r\n partId: string | null;\r\n roleId: string | null;\r\n}\r\n\r\n/**\r\n * The identifiers for an edited fragment.\r\n */\r\nexport interface FragmentIdentity extends PartIdentity {\r\n frTypeId: string;\r\n frRoleId: string | null;\r\n loc: string;\r\n}\r\n\r\n/**\r\n * An edited part or fragment.\r\n */\r\nexport interface EditedObject<T extends Part | Fragment> {\r\n value: T | null;\r\n thesauri: ThesauriSet;\r\n layerPart?: TextLayerPart;\r\n baseText?: string;\r\n}\r\n\r\n/**\r\n * Base class for part/fragment editors dumb components.\r\n * The model type is the templated argument T.\r\n *\r\n * When deriving from this editor, be sure to call super.ngOnInit()\r\n * from the derived editor's ngOnInit handler.\r\n */\r\n@Component({\r\n template: '',\r\n standalone: false,\r\n})\r\nexport abstract class ModelEditorComponentBase<T extends Part | Fragment>\r\n implements OnInit, OnDestroy\r\n{\r\n private readonly _mebSubs: Subscription[] = [];\r\n\r\n /**\r\n * The root form of the editor.\r\n */\r\n public form: FormGroup | UntypedFormGroup;\r\n\r\n /**\r\n * The current user.\r\n */\r\n public user?: User;\r\n\r\n /**\r\n * The user authorization level (0-4).\r\n */\r\n public userLevel: number;\r\n\r\n /**\r\n * An observable with the current dirty state of the editor.\r\n */\r\n public isDirty$: BehaviorSubject<boolean>;\r\n\r\n /**\r\n * The identity of the edited model.\r\n */\r\n public readonly identity = input<PartIdentity | FragmentIdentity>();\r\n\r\n /**\r\n * The data being edited.\r\n */\r\n public readonly data = model<EditedObject<T>>();\r\n\r\n /**\r\n * True to disable the editor.\r\n */\r\n public readonly disabled = input<boolean>();\r\n\r\n /**\r\n * Event emitted when the dirty state has changed.\r\n * This event just reflects changes in isDirty$, and is a facility\r\n * for propagating it to the parent's component.\r\n */\r\n public readonly dirtyChange = output<boolean>();\r\n\r\n /**\r\n * Emitted when the user requests to close the editor.\r\n */\r\n public readonly editorClose = output();\r\n\r\n /**\r\n * Create a new instance of the editor.\r\n *\r\n * @param authService The authentication service.\r\n * @param formBuilder Form builder.\r\n */\r\n constructor(\r\n protected authService: AuthJwtService,\r\n protected formBuilder: FormBuilder\r\n ) {\r\n this.form = formBuilder.group({});\r\n this.userLevel = 0;\r\n this.isDirty$ = new BehaviorSubject<boolean>(false);\r\n\r\n effect(() => {\r\n this.disableForm(this.disabled());\r\n });\r\n effect(() => {\r\n this.onDataSet(this.data());\r\n });\r\n effect(() => {\r\n this.onIdentitySet(this.identity());\r\n });\r\n }\r\n\r\n private disableForm(disabled?: boolean) {\r\n if (disabled) {\r\n this.form.disable();\r\n } else {\r\n this.form.enable();\r\n }\r\n }\r\n\r\n private onIdentitySet(identity?: PartIdentity | FragmentIdentity) {\r\n if (identity?.partId) {\r\n const part = this.data()?.value as Part;\r\n if (part && !part.id) {\r\n console.log('part identity set', identity.partId);\r\n part.id = identity.partId;\r\n }\r\n }\r\n }\r\n\r\n public ngOnInit(): void {\r\n // form\r\n this.form = this.buildForm(this.formBuilder);\r\n\r\n // dirty check on form\r\n this._mebSubs.push(\r\n this.form.events.subscribe((e) => {\r\n if (e instanceof PristineChangeEvent) {\r\n console.log('dirty change: ', !e.pristine);\r\n this.isDirty$.next(!e.pristine);\r\n this.dirtyChange.emit(this.isDirty$.value);\r\n }\r\n })\r\n );\r\n\r\n // auth service\r\n this.userLevel = this.getCurrentUserLevel();\r\n this._mebSubs.push(\r\n this.authService.currentUser$.subscribe((user: User | null) => {\r\n this.updateUserProperties(user);\r\n })\r\n );\r\n }\r\n\r\n public ngOnDestroy(): void {\r\n this._mebSubs.forEach((s) => s.unsubscribe());\r\n }\r\n\r\n /**\r\n * Implement in the derived class to build the root form of this editor.\r\n * The form built will then be attached to the dirty check mechanism\r\n * provided by this base class.\r\n *\r\n * @param formBuilder The form builder.\r\n */\r\n protected abstract buildForm(\r\n formBuilder: FormBuilder\r\n ): FormGroup | UntypedFormGroup;\r\n\r\n /**\r\n * Get the authorization level of the current user if any.\r\n * @returns 4-1 for admin, editor, operator, visitor; else 0.\r\n */\r\n private getCurrentUserLevel(): number {\r\n const user = this.authService.currentUserValue;\r\n if (!user || !user.roles) {\r\n return 0;\r\n }\r\n if (user.roles.indexOf('admin') > -1) {\r\n return 4;\r\n }\r\n if (user.roles.indexOf('editor') > -1) {\r\n return 3;\r\n }\r\n if (user.roles.indexOf('operator') > -1) {\r\n return 2;\r\n }\r\n if (user.roles.indexOf('visitor') > -1) {\r\n return 1;\r\n }\r\n return 0;\r\n }\r\n\r\n private updateUserProperties(user: User | null): void {\r\n if (!user) {\r\n this.user = undefined;\r\n this.userLevel = 0;\r\n } else {\r\n this.user = user;\r\n this.userLevel = this.getCurrentUserLevel();\r\n }\r\n }\r\n\r\n /**\r\n * Update the data value property and emit the corresponding\r\n * modelChange event.\r\n *\r\n * @param value The value.\r\n */\r\n protected updateValue(value: T): void {\r\n this.data.set({ ...(this.data() || { thesauri: {} }), value: value });\r\n }\r\n\r\n /**\r\n * Invoked whenever the model property is set (=data comes from input model\r\n * property), unless setting it via updateModel. Implement to update the form\r\n * controls to reflect the new model data.\r\n *\r\n * @param data The data set, or undefined.\r\n */\r\n protected abstract onDataSet(data?: EditedObject<T>): void;\r\n\r\n /**\r\n * Get a new object from the edited part if any, else as a new part.\r\n *\r\n * @param typeId The part's type ID. This is a constant received\r\n * from the implementor.\r\n * @returns Part object.\r\n */\r\n protected getEditedPart(typeId: string): Part {\r\n const part = deepCopy(this.data()?.value) as Part | null;\r\n return (\r\n part || {\r\n itemId: this.identity()!.itemId || '',\r\n id: '',\r\n typeId: typeId,\r\n roleId: this.identity()!.roleId || undefined,\r\n timeCreated: new Date(),\r\n creatorId: '',\r\n timeModified: new Date(),\r\n userId: '',\r\n }\r\n );\r\n }\r\n\r\n /**\r\n * Get a new object from the edited fragment if any, else a new fragment.\r\n *\r\n * @returns Fragment object.\r\n */\r\n protected getEditedFragment(): Fragment {\r\n const fr = deepCopy(this.data()?.value) as Fragment | null;\r\n return (\r\n fr || {\r\n location: (this.identity() as FragmentIdentity).loc,\r\n }\r\n );\r\n }\r\n\r\n /**\r\n * Implement in derived classes to get the data from form's controls.\r\n * This is used when saving.\r\n */\r\n protected abstract getValue(): T;\r\n\r\n /**\r\n * True if this editor has the thesaurus having the specified key in the\r\n * loaded thesauri set.\r\n */\r\n protected hasThesaurus(key: string): boolean {\r\n return this.data()?.thesauri && this.data()!.thesauri[key] ? true : false;\r\n }\r\n\r\n /**\r\n * Emit a request to close the editor.\r\n */\r\n public close(): void {\r\n this.editorClose.emit();\r\n }\r\n\r\n /**\r\n * Save the edited data if valid.\r\n */\r\n public save(): void {\r\n if (this.form.invalid) {\r\n console.warn('Save invoked with invalid form');\r\n return;\r\n }\r\n const value = this.getValue();\r\n this.updateValue(value);\r\n // the form is no more dirty\r\n this.form.markAsPristine();\r\n }\r\n}\r\n","import {\r\n AbstractControl,\r\n ValidatorFn,\r\n ValidationErrors,\r\n FormGroup,\r\n UntypedFormGroup,\r\n} from '@angular/forms';\r\n\r\n// https://www.tektutorialshub.com/angular/custom-validator-with-parameters-in-angular/\r\n\r\n/**\r\n * General-purpose custom validators.\r\n */\r\n// https://github.com/angular/angular/issues/18867#issuecomment-357484102\r\n// @dynamic\r\nexport class CustomValidators {\r\n /**\r\n * Validates a FormGroup or FormArray control checking if the count of their\r\n * controls with a true value is equal to or greater than the specified\r\n * number.\r\n *\r\n * @param min The minimum number of checked controls.\r\n */\r\n public static minChecked(min = 1): ValidatorFn {\r\n return (control: AbstractControl): ValidationErrors | null => {\r\n // https://trungk18.com/experience/angular-form-array-validate-at-least-one-checkbox-was-selected/\r\n let checked = 0;\r\n\r\n const group = (control as FormGroup) || (control as UntypedFormGroup);\r\n Object.keys(group.controls).forEach((key) => {\r\n const ctl = group.controls[key];\r\n if (ctl.value === true) {\r\n checked++;\r\n }\r\n });\r\n\r\n if (checked < min) {\r\n return {\r\n minChecked: true,\r\n };\r\n }\r\n return null;\r\n };\r\n }\r\n}\r\n","import { AbstractControl } from '@angular/forms';\r\n\r\n/**\r\n * Simple JSON validator.\r\n */\r\nexport class JsonValidators {\r\n public static json(\r\n control: AbstractControl\r\n ): { [key: string]: boolean } | null {\r\n if (!control.value) {\r\n // we allow empty code\r\n return null;\r\n }\r\n try {\r\n JSON.parse(control.value);\r\n } catch (e) {\r\n return { json: true };\r\n }\r\n return null;\r\n }\r\n}\r\n","import { Injectable } from '@angular/core';\nimport { map, Observable } from 'rxjs';\n\nimport { DataPage } from '@myrmidon/ngx-tools';\n\nimport { UserService } from '@myrmidon/cadmus-api';\nimport {\n RefLookupFilter,\n RefLookupService,\n} from '@myrmidon/cadmus-refs-lookup';\n\nexport interface UserWithRoles {\n user: {\n id: string;\n firstName: string;\n lastName: string;\n userName: string;\n email: string;\n };\n roles: string[];\n}\n\n/**\n * Service for users lookup.\n */\n@Injectable({\n providedIn: 'root',\n})\nexport class UserRefLookupService implements RefLookupService {\n constructor(private _userService: UserService) {}\n\n public lookup(\n filter: RefLookupFilter,\n options?: any\n ): Observable<UserWithRoles[]> {\n return this._userService\n .getUsers(\n {\n name: filter.text,\n },\n 1,\n filter.limit\n )\n .pipe(\n map((page: DataPage<UserWithRoles>) => {\n return page.items;\n })\n );\n }\n\n public getName(item: UserWithRoles): string {\n return item?.user?.userName;\n }\n}\n","// https://github.com/angular/angular/issues/10887\r\n\r\nimport { AbstractControl } from '@angular/forms';\r\nimport { Observable, Subject } from 'rxjs';\r\n\r\n/**\r\n * Extract arguments of function\r\n */\r\nexport type ArgumentsType<F> = F extends (...args: infer A) => any ? A : never;\r\n\r\n/**\r\n * Creates an object like O. Optionally provide minimum set of properties P\r\n * which the objects must share to conform.\r\n */\r\ntype ObjectLike<O extends object, P extends keyof O = keyof O> = Pick<O, P>;\r\n\r\n/**\r\n * Extract a touched changed observable from an abstract control.\r\n * Use in component code like:\r\n * this.touchedChanges$ = extractTouchedChanges(this.form);\r\n *\r\n * @param control AbstractControl-like object with markAsTouched method.\r\n */\r\nexport const extractTouchedChanges = (\r\n control: ObjectLike<AbstractControl, 'markAsTouched' | 'markAsUntouched'>\r\n): Observable<boolean> => {\r\n const prevMarkAsTouched = control.markAsTouched;\r\n const prevMarkAsUntouched = control.markAsUntouched;\r\n\r\n const touchedChanges$ = new Subject<boolean>();\r\n\r\n function nextMarkAsTouched(\r\n ...args: ArgumentsType<AbstractControl['markAsTouched']>\r\n ): void {\r\n touchedChanges$.next(true);\r\n prevMarkAsTouched.bind(control)(...args);\r\n }\r\n\r\n function nextMarkAsUntouched(\r\n ...args: ArgumentsType<AbstractControl['markAsUntouched']>\r\n ): void {\r\n touchedChanges$.next(false);\r\n prevMarkAsUntouched.bind(control)(...args);\r\n }\r\n\r\n control.markAsTouched = nextMarkAsTouched;\r\n control.markAsUntouched = nextMarkAsUntouched;\r\n\r\n return touchedChanges$;\r\n};\r\n\r\n/**\r\n * Extract a pristine changed observable from an abstract control.\r\n * Use in component code like:\r\n * this.pristineChanges$ = extractPristineChanges(this.form);\r\n *\r\n * @param control AbstractControl-like object with markAsPristine and markAsDirty\r\n * methods.\r\n */\r\nexport const extractPristineChanges = (\r\n control: ObjectLike<AbstractControl, 'markAsPristine' | 'markAsDirty'>\r\n): Observable<boolean> => {\r\n const prevMarkAsPristine = control.markAsPristine;\r\n const prevMarkAsDirty = control.markAsDirty;\r\n\r\n const pristineChanges$ = new Subject<boolean>();\r\n\r\n function nextMarkAsPristine(\r\n ...args: ArgumentsType<AbstractControl['markAsPristine']>\r\n ): void {\r\n pristineChanges$.next(true);\r\n prevMarkAsPristine.bind(control)(...args);\r\n }\r\n\r\n function nextMarkAsDirty(\r\n ...args: ArgumentsType<AbstractControl['markAsDirty']>\r\n ): void {\r\n pristineChanges$.next(false);\r\n prevMarkAsDirty.bind(control)(...args);\r\n }\r\n\r\n control.markAsPristine = nextMarkAsPristine;\r\n control.markAsDirty = nextMarkAsDirty;\r\n\r\n return pristineChanges$;\r\n};\r\n","/*\r\n * Public API Surface of cadmus-ui\r\n */\r\n\r\nexport * from './lib/components/close-save-buttons/close-save-buttons.component';\r\nexport * from './lib/components/decorated-token-text/decorated-token-text.component';\r\nexport * from './lib/components/error-list/error-list.component';\r\nexport * from './lib/components/facet-badge/facet-badge.component';\r\nexport * from './lib/components/flags-badge/flags-badge.component';\r\nexport * from './lib/components/layer-hints/layer-hints.component';\r\nexport * from './lib/components/lookup-pin/lookup-pin.component';\r\nexport * from './lib/components/part-badge/part-badge.component';\r\nexport * from './lib/components/thesaurus-tree/thesaurus-tree.component';\r\n\r\nexport * from './lib/components/model-editor-component-base';\r\n\r\nexport * from './lib/services/color.service';\r\n\r\nexport * from './lib/validators/custom-validators';\r\nexport * from './lib/validators/json-validators';\r\n\r\nexport * from './lib/services/user-ref-lookup.service';\r\n\r\nexport * from './lib/utils';\r\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":["i1.ColorService","i1","i2.ColorService","i2","map"],"mappings":"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"}
1
+ {"version":3,"file":"myrmidon-cadmus-ui.mjs","sources":["../../../../projects/myrmidon/cadmus-ui/src/lib/components/close-save-buttons/close-save-buttons.component.ts","../../../../projects/myrmidon/cadmus-ui/src/lib/components/close-save-buttons/close-save-buttons.component.html","../../../../projects/myrmidon/cadmus-ui/src/lib/components/decorated-token-text/decorated-token-text.component.ts","../../../../projects/myrmidon/cadmus-ui/src/lib/components/decorated-token-text/decorated-token-text.component.html","../../../../projects/myrmidon/cadmus-ui/src/lib/components/error-list/error-list.component.ts","../../../../projects/myrmidon/cadmus-ui/src/lib/components/error-list/error-list.component.html","../../../../projects/myrmidon/cadmus-ui/src/lib/services/color.service.ts","../../../../projects/myrmidon/cadmus-ui/src/lib/components/facet-badge/facet-badge.component.ts","../../../../projects/myrmidon/cadmus-ui/src/lib/components/facet-badge/facet-badge.component.html","../../../../projects/myrmidon/cadmus-ui/src/lib/components/flags-badge/flags-badge.component.ts","../../../../projects/myrmidon/cadmus-ui/src/lib/components/flags-badge/flags-badge.component.html","../../../../projects/myrmidon/cadmus-ui/src/lib/components/layer-hints/layer-hints.component.ts","../../../../projects/myrmidon/cadmus-ui/src/lib/components/layer-hints/layer-hints.component.html","../../../../projects/myrmidon/cadmus-ui/src/lib/components/lookup-pin/lookup-pin.component.ts","../../../../projects/myrmidon/cadmus-ui/src/lib/components/lookup-pin/lookup-pin.component.html","../../../../projects/myrmidon/cadmus-ui/src/lib/components/part-badge/part-badge.component.ts","../../../../projects/myrmidon/cadmus-ui/src/lib/components/part-badge/part-badge.component.html","../../../../projects/myrmidon/cadmus-ui/src/lib/components/thesaurus-tree/thesaurus-tree.component.ts","../../../../projects/myrmidon/cadmus-ui/src/lib/components/thesaurus-tree/thesaurus-tree.component.html","../../../../projects/myrmidon/cadmus-ui/src/lib/components/model-editor-component-base.ts","../../../../projects/myrmidon/cadmus-ui/src/lib/validators/custom-validators.ts","../../../../projects/myrmidon/cadmus-ui/src/lib/validators/json-validators.ts","../../../../projects/myrmidon/cadmus-ui/src/lib/services/user-ref-lookup.service.ts","../../../../projects/myrmidon/cadmus-ui/src/lib/utils.ts","../../../../projects/myrmidon/cadmus-ui/src/public-api.ts","../../../../projects/myrmidon/cadmus-ui/src/myrmidon-cadmus-ui.ts"],"sourcesContent":["import { Component, input, output } from '@angular/core';\r\nimport { FormGroup, UntypedFormGroup } from '@angular/forms';\r\n\r\nimport { MatButton } from '@angular/material/button';\r\nimport { MatIcon } from '@angular/material/icon';\r\n\r\n@Component({\r\n selector: 'cadmus-close-save-buttons',\r\n templateUrl: './close-save-buttons.component.html',\r\n styleUrls: ['./close-save-buttons.component.css'],\r\n imports: [MatButton, MatIcon],\r\n})\r\nexport class CloseSaveButtonsComponent {\r\n public readonly form = input<FormGroup | UntypedFormGroup>();\r\n\r\n public readonly noSave = input<boolean>();\r\n\r\n public readonly closeRequest = output();\r\n\r\n public close(): void {\r\n this.closeRequest.emit();\r\n }\r\n}\r\n","@if (form()) {\n<div class=\"form-row\">\n <button type=\"button\" mat-flat-button class=\"mat-warn\" (click)=\"close()\">\n <mat-icon>cancel</mat-icon>\n close\n </button>\n @if (!noSave()) {\n <button\n type=\"submit\"\n [disabled]=\"form()?.invalid\"\n mat-flat-button\n class=\"mat-primary\"\n >\n <mat-icon>check_circle</mat-icon>\n save\n </button>\n }\n</div>\n}\n","import {\r\n Component,\r\n OnInit,\r\n ViewChild,\r\n ElementRef,\r\n input,\r\n effect,\r\n} from '@angular/core';\r\n\r\nimport { SafeHtmlPipe } from '@myrmidon/ngx-tools';\r\n\r\nimport { TokenLocation, TextLayerService } from '@myrmidon/cadmus-core';\r\n\r\n/**\r\n * Decorated token-based text visualizer. This is used when editing\r\n * token-based text layers.\r\n */\r\n@Component({\r\n selector: 'cadmus-decorated-token-text',\r\n templateUrl: './decorated-token-text.component.html',\r\n styleUrls: ['./decorated-token-text.component.css'],\r\n imports: [SafeHtmlPipe],\r\n})\r\nexport class DecoratedTokenTextComponent implements OnInit {\r\n @ViewChild('textElem') _textElement?: ElementRef;\r\n\r\n /**\r\n * The base text.\r\n */\r\n public readonly baseText = input<string>('');\r\n\r\n /**\r\n * The token-based locations of all the fragments in the layer.\r\n */\r\n public readonly locations = input<TokenLocation[]>([]);\r\n\r\n /**\r\n * A selected token-based location.\r\n */\r\n public readonly selectedLocation = input<TokenLocation>();\r\n\r\n public text?: string; // rendered HTML text\r\n\r\n constructor(private _textLayerService: TextLayerService) {\r\n effect(() => {\r\n this.decorate(this.baseText(), this.locations(), this.selectedLocation());\r\n });\r\n }\r\n\r\n public ngOnInit(): void {\r\n this.decorate(this.baseText(), this.locations(), this.selectedLocation());\r\n }\r\n\r\n private decorate(\r\n text: string,\r\n locations: TokenLocation[],\r\n selectedLocation?: TokenLocation\r\n ): void {\r\n this.text = this._textLayerService.render(\r\n text,\r\n locations,\r\n selectedLocation\r\n );\r\n }\r\n}\r\n","<div [innerHtml]=\"text | safeHtml : 'html'\" id=\"text\" #textElem></div>\r\n","import { Component, input } from '@angular/core';\r\n\r\n@Component({\r\n selector: 'cadmus-error-list',\r\n templateUrl: './error-list.component.html',\r\n styleUrls: ['./error-list.component.css'],\r\n})\r\nexport class ErrorListComponent {\r\n public readonly errors = input<string[]>();\r\n}\r\n","@if (errors()?.length) {\n <ul>\n @for (error of errors(); track error) {\n <li class=\"error\">{{error}}</li>\n }\n </ul>\n}\n","import { Injectable } from '@angular/core';\r\n\r\n/**\r\n * Colors helper service.\r\n */\r\n@Injectable({\r\n providedIn: 'root',\r\n})\r\nexport class ColorService {\r\n /**\r\n * Get the R,G,B components of the color expressed by the specified\r\n * RGB string (3 or 6 digits format).\r\n *\r\n * @param rgb The RGB color string (3 or 6 digits).\r\n * @returns An array where [0]=R, [1]=G, [2]=B, or null if invalid\r\n * input string.\r\n */\r\n public getRgb(rgb: string): number[] | null {\r\n if (!rgb) {\r\n return null;\r\n }\r\n\r\n // RGB\r\n let m = rgb.match(/^#?([0-9a-f]{3})$/i);\r\n if (m && m[1]) {\r\n // in 3-characters format, each value is multiplied by 0x11 to give an\r\n // even scale from 0x00 to 0xff\r\n return [\r\n parseInt(m[1].charAt(0), 16) * 0x11,\r\n parseInt(m[1].charAt(1), 16) * 0x11,\r\n parseInt(m[1].charAt(2), 16) * 0x11,\r\n ];\r\n }\r\n // RRGGBB\r\n m = rgb.match(/^#?([0-9a-f]{6})$/i);\r\n if (m && m[1]) {\r\n return [\r\n parseInt(m[1].substring(0, 2), 16),\r\n parseInt(m[1].substring(2, 4), 16),\r\n parseInt(m[1].substring(4, 6), 16),\r\n ];\r\n }\r\n return null;\r\n }\r\n\r\n /**\r\n * Get black or white according to which of them has the maximum contrast\r\n * against the specified color.\r\n *\r\n * @param rgb The RGB color string.\r\n * @returns Black or white. If rgb is invalid, always black.\r\n */\r\n public getContrastColor(rgb: string): string {\r\n // https://stackoverflow.com/questions/3942878/how-to-decide-font-color-in-white-or-black-depending-on-background-color\r\n const values = this.getRgb(rgb);\r\n if (!values) {\r\n return 'black';\r\n }\r\n return values[0] * 0.299 + values[1] * 0.587 + values[2] * 0.114 > 186\r\n ? 'black'\r\n : 'white';\r\n }\r\n\r\n /**\r\n * Convert HSL to RGB.\r\n *\r\n * @param h Hue\r\n * @param s Saturation\r\n * @param l Lightness\r\n * @returns Object with r, g, b values.\r\n */\r\n public hslToRgb(\r\n h: number,\r\n s: number,\r\n l: number\r\n ): { r: number; g: number; b: number } {\r\n // https://css-tricks.com/converting-color-spaces-in-javascript/\r\n // must be fractions of 1\r\n s /= 100;\r\n l /= 100;\r\n\r\n let c = (1 - Math.abs(2 * l - 1)) * s,\r\n x = c * (1 - Math.abs(((h / 60) % 2) - 1)),\r\n m = l - c / 2,\r\n r = 0,\r\n g = 0,\r\n b = 0;\r\n if (0 <= h && h < 60) {\r\n r = c;\r\n g = x;\r\n b = 0;\r\n } else if (60 <= h && h < 120) {\r\n r = x;\r\n g = c;\r\n b = 0;\r\n } else if (120 <= h && h < 180) {\r\n r = 0;\r\n g = c;\r\n b = x;\r\n } else if (180 <= h && h < 240) {\r\n r = 0;\r\n g = x;\r\n b = c;\r\n } else if (240 <= h && h < 300) {\r\n r = x;\r\n g = 0;\r\n b = c;\r\n } else if (300 <= h && h < 360) {\r\n r = c;\r\n g = 0;\r\n b = x;\r\n }\r\n r = Math.round((r + m) * 255);\r\n g = Math.round((g + m) * 255);\r\n b = Math.round((b + m) * 255);\r\n\r\n return { r: r, g: g, b: b };\r\n }\r\n\r\n public rgbToString(r: number, g: number, b: number): string {\r\n let rd = r.toString(16);\r\n if (rd.length === 1) {\r\n rd = '0' + rd;\r\n }\r\n let gd = g.toString(16);\r\n if (gd.length === 1) {\r\n gd = '0' + gd;\r\n }\r\n let bd = b.toString(16);\r\n if (bd.length === 1) {\r\n bd = '0' + bd;\r\n }\r\n return rd + gd + bd;\r\n }\r\n\r\n /**\r\n * Get the next color from a palette generated to include\r\n * the specified count of colors.\r\n *\r\n * @param index The index of the next color in the palette.\r\n * @param count The total count of colors in the palette.\r\n * @param blueBoost True to adjust colors for the eye's lack of sensitivity to blue.\r\n * @returns The RRGGBB values string.\r\n */\r\n public nextPaletteColor(\r\n index: number,\r\n count: number,\r\n blueBoost = true\r\n ): string {\r\n // https://stackoverflow.com/questions/43193341/how-to-generate-random-pastel-or-brighter-color-in-javascript\r\n const h = Math.floor((index / count) * 341); // between 0 and 340\r\n let s = 100;\r\n let l = 50;\r\n\r\n if (blueBoost && h > 215 && h < 265) {\r\n const gain = 20;\r\n let blueness = 1 - Math.abs(h - 240) / 25;\r\n let change = Math.floor(gain * blueness);\r\n l += change;\r\n s -= change;\r\n }\r\n const rgb = this.hslToRgb(h, s, l);\r\n return this.rgbToString(rgb.r, rgb.g, rgb.b);\r\n }\r\n}\r\n","import { Component, effect, input, Input } from '@angular/core';\r\nimport { FacetDefinition } from '@myrmidon/cadmus-core';\r\n\r\nimport { MatTooltip } from '@angular/material/tooltip';\r\n\r\nimport { ColorService } from '../../services/color.service';\r\n\r\nexport interface FacetBadgeData {\r\n definitions: FacetDefinition[];\r\n facetId?: string;\r\n}\r\n\r\n@Component({\r\n selector: 'cadmus-facet-badge',\r\n templateUrl: './facet-badge.component.html',\r\n styleUrls: ['./facet-badge.component.css'],\r\n imports: [MatTooltip],\r\n})\r\nexport class FacetBadgeComponent {\r\n private _facetColors: { [key: string]: string };\r\n private _facetTips: { [key: string]: string };\r\n\r\n public color: string;\r\n public contrastColor: string;\r\n public tip?: string;\r\n\r\n /**\r\n * The facet data.\r\n */\r\n public readonly data = input<FacetBadgeData>({\r\n definitions: [],\r\n });\r\n\r\n constructor(private _colorService: ColorService) {\r\n this._facetColors = {};\r\n this._facetTips = {};\r\n this.color = 'transparent';\r\n this.contrastColor = 'black';\r\n\r\n effect(() => {\r\n this.updateBadge(this.data());\r\n });\r\n }\r\n\r\n private getFacetColor(facetId: string): string {\r\n if (this._facetColors[facetId]) {\r\n return this._facetColors[facetId];\r\n }\r\n if (!this.data().definitions?.length) {\r\n return 'transparent';\r\n }\r\n\r\n const facet = this.data().definitions.find((f) => {\r\n return f.id === facetId;\r\n });\r\n if (facet?.colorKey) {\r\n this._facetColors[facetId] = '#' + facet.colorKey;\r\n } else {\r\n this._facetColors[facetId] = 'transparent';\r\n }\r\n return this._facetColors[facetId];\r\n }\r\n\r\n private getFacetTip(facetId: string): string | null {\r\n if (this._facetTips[facetId]) {\r\n return this._facetTips[facetId];\r\n }\r\n\r\n if (!this.data().definitions?.length) {\r\n return null;\r\n }\r\n\r\n const facet = this.data().definitions.find((f) => {\r\n return f.id === facetId;\r\n });\r\n if (!facet) {\r\n this._facetTips[facetId] = facetId;\r\n } else {\r\n const sb: string[] = [];\r\n for (let i = 0; i < facet.partDefinitions.length; i++) {\r\n if (i > 0) {\r\n sb.push(', ');\r\n }\r\n sb.push(facet.partDefinitions[i].name);\r\n if (facet.partDefinitions[i].isRequired) {\r\n sb.push('*');\r\n }\r\n }\r\n this._facetTips[facetId] = sb.join('');\r\n }\r\n return this._facetTips[facetId];\r\n }\r\n\r\n private updateBadge(data?: FacetBadgeData) {\r\n this._facetColors = {};\r\n this._facetTips = {};\r\n this.color = this.getFacetColor(data?.facetId || '');\r\n this.contrastColor = this._colorService.getContrastColor(this.color);\r\n this.tip = this.getFacetTip(data?.facetId || '') ?? undefined;\r\n }\r\n}\r\n","<span\r\n class=\"model-type\"\r\n [style.background-color]=\"color\"\r\n [style.color]=\"contrastColor\"\r\n matTooltip=\"{{ tip }}\"\r\n >{{ data().facetId }}\r\n</span>\r\n","import { Component, effect, input, Input } from '@angular/core';\r\n\r\nimport { MatTooltip } from '@angular/material/tooltip';\r\n\r\nimport { FlagDefinition } from '@myrmidon/cadmus-core';\r\n\r\n/**\r\n * Data for FlagsBadgeComponent, including flags and their definitions.\r\n */\r\nexport interface FlagsBadgeData {\r\n definitions: FlagDefinition[];\r\n flags: number;\r\n}\r\n\r\n/**\r\n * Badge with item's flags. Each flag is represented by a circle filled\r\n * with the flag's color key.\r\n */\r\n@Component({\r\n selector: 'cadmus-flags-badge',\r\n templateUrl: './flags-badge.component.html',\r\n styleUrls: ['./flags-badge.component.css'],\r\n imports: [MatTooltip],\r\n})\r\nexport class FlagsBadgeComponent {\r\n public badgeFlags: FlagDefinition[] = [];\r\n\r\n public readonly data = input<FlagsBadgeData>();\r\n\r\n constructor() {\r\n effect(() => {\r\n this.updateBadge(this.data());\r\n });\r\n }\r\n\r\n private updateBadge(data?: FlagsBadgeData) {\r\n if (!data) {\r\n return;\r\n }\r\n this.badgeFlags = data.definitions.filter((def) => {\r\n // tslint:disable-next-line: no-bitwise\r\n return def.id & data!.flags;\r\n });\r\n }\r\n}\r\n","<div>\n @for (def of badgeFlags; track def.id) {\n <span\n class=\"badge-flag\"\n [style.color]=\"'#' + def.colorKey\"\n [matTooltip]=\"def.label\"\n >\n @if (def.isAdmin) { &#x25c6; } @else { &#x2b24; }\n </span>\n }\n</div>\n","import {\r\n Component,\r\n OnInit,\r\n Input,\r\n Output,\r\n EventEmitter,\r\n output,\r\n input,\r\n effect,\r\n} from '@angular/core';\r\nimport {\r\n FormGroup,\r\n FormArray,\r\n FormBuilder,\r\n FormsModule,\r\n ReactiveFormsModule,\r\n} from '@angular/forms';\r\n\r\nimport { MatIconButton, MatButton } from '@angular/material/button';\r\nimport { MatTooltip } from '@angular/material/tooltip';\r\nimport { MatIcon } from '@angular/material/icon';\r\nimport { MatCheckbox } from '@angular/material/checkbox';\r\n\r\nimport { DialogService } from '@myrmidon/ngx-mat-tools';\r\n\r\nimport { LayerHint } from '@myrmidon/cadmus-core';\r\n\r\n@Component({\r\n selector: 'cadmus-layer-hints',\r\n templateUrl: './layer-hints.component.html',\r\n styleUrls: ['./layer-hints.component.css'],\r\n imports: [\r\n FormsModule,\r\n ReactiveFormsModule,\r\n MatIconButton,\r\n MatTooltip,\r\n MatIcon,\r\n MatCheckbox,\r\n MatButton,\r\n ],\r\n})\r\nexport class LayerHintsComponent {\r\n public readonly hints = input<LayerHint[]>([]);\r\n\r\n public readonly targetLocation = input<string>();\r\n public readonly disabled = input<boolean>();\r\n public readonly readonly = input<boolean>();\r\n\r\n public readonly requestEdit = output<LayerHint>();\r\n public readonly requestDelete = output<LayerHint>();\r\n public readonly requestMove = output<LayerHint>();\r\n public readonly requestPatch = output<string[]>();\r\n\r\n public form: FormGroup;\r\n public checks: FormArray;\r\n\r\n constructor(\r\n private _formBuilder: FormBuilder,\r\n private _dialogService: DialogService\r\n ) {\r\n this.checks = _formBuilder.array([]);\r\n this.form = _formBuilder.group({\r\n checks: this.checks,\r\n });\r\n\r\n effect(() => {\r\n this.updateChecks(this.hints());\r\n });\r\n }\r\n\r\n private updateChecks(hints: LayerHint[]) {\r\n this.checks.controls = [];\r\n for (let i = 0; i < hints.length; i++) {\r\n this.checks.push(this._formBuilder.control(false));\r\n }\r\n }\r\n\r\n public emitRequestEdit(hint: LayerHint) {\r\n this.requestEdit.emit(hint);\r\n }\r\n\r\n public emitRequestDelete(hint: LayerHint) {\r\n this._dialogService\r\n .confirm('Confirm Deletion', `Delete fragment at \"${hint.location}\"?`)\r\n .subscribe((ok: boolean) => {\r\n if (ok) {\r\n this.requestDelete.emit(hint);\r\n }\r\n });\r\n }\r\n\r\n public emitRequestMove(hint: LayerHint) {\r\n if (!this.targetLocation) {\r\n return;\r\n }\r\n this._dialogService\r\n .confirm(\r\n 'Confirm Move',\r\n `Move fragment at ${hint.location} to ${this.targetLocation}?`\r\n )\r\n .subscribe((ok: boolean) => {\r\n if (ok) {\r\n this.requestMove.emit(hint);\r\n }\r\n });\r\n }\r\n\r\n public emitRequestPatch() {\r\n if (this.form.invalid) {\r\n return;\r\n }\r\n this._dialogService\r\n .confirm('Confirm Patch', `Patch the selected fragments?`)\r\n .subscribe((ok: boolean) => {\r\n if (ok) {\r\n const patches: string[] = [];\r\n for (let i = 0; i < this.checks.controls.length; i++) {\r\n const n = this.checks.controls[i].value;\r\n if (n) {\r\n patches.push(this.hints()[n - 1].patchOperation!);\r\n }\r\n }\r\n this.requestPatch.emit(patches);\r\n }\r\n });\r\n }\r\n}\r\n","@if (hints().length) {\n<form [formGroup]=\"form\" (submit)=\"emitRequestPatch()\">\n <table class=\"patches\">\n <thead>\n <tr>\n <th></th>\n <th>location</th>\n <th>description</th>\n <th>patch</th>\n </tr>\n </thead>\n <tbody>\n @for (hint of hints(); track hint; let i = $index) {\n <tr>\n @if (!readonly()) {\n <td>\n <button\n type=\"button\"\n mat-icon-button\n matTooltip=\"Edit this fragment\"\n [disabled]=\"disabled()\"\n >\n <mat-icon>edit</mat-icon>\n </button>\n <button\n type=\"button\"\n mat-icon-button\n matTooltip=\"Move this fragment to {{ targetLocation() }}\"\n [disabled]=\"\n disabled() || !targetLocation() || targetLocation() === hint.location\n \"\n (click)=\"emitRequestMove(hint)\"\n >\n <mat-icon>arrow_forward</mat-icon>\n </button>\n <button\n type=\"button\"\n mat-icon-button\n matTooltip=\"Delete this fragment\"\n [disabled]=\"disabled()\"\n (click)=\"emitRequestDelete(hint)\"\n >\n <mat-icon class=\"mat-warn\">delete</mat-icon>\n </button>\n </td>\n }\n <td>{{ hint.location }}</td>\n <td>{{ hint.description }}</td>\n <td>\n @if (hint.patchOperation) {\n <mat-checkbox\n matTooltip=\"Apply this patch\"\n [disabled]=\"disabled()\"\n [value]=\"(i + 1).toString()\"\n >\n {{ hint.patchOperation }}\n </mat-checkbox>\n }\n </td>\n </tr>\n }\n </tbody>\n </table>\n @if (targetLocation()) {\n <div>move target: {{ targetLocation() }}</div>\n }\n <button\n type=\"submit\"\n mat-flat-button\n [disabled]=\"readonly() || disabled() || form.invalid\"\n >\n apply patches\n </button>\n</form>\n}\n","import {\r\n Component,\r\n effect,\r\n Inject,\r\n input,\r\n OnInit,\r\n output,\r\n} from '@angular/core';\r\nimport { AsyncPipe } from '@angular/common';\r\nimport {\r\n UntypedFormBuilder,\r\n UntypedFormControl,\r\n UntypedFormGroup,\r\n FormsModule,\r\n ReactiveFormsModule,\r\n} from '@angular/forms';\r\nimport { Observable, of } from 'rxjs';\r\nimport {\r\n debounceTime,\r\n distinctUntilChanged,\r\n map,\r\n switchMap,\r\n take,\r\n} from 'rxjs/operators';\r\n\r\nimport {\r\n MatAutocomplete,\r\n MatAutocompleteTrigger,\r\n} from '@angular/material/autocomplete';\r\nimport { MatOption } from '@angular/material/core';\r\nimport { MatFormField } from '@angular/material/form-field';\r\nimport { MatInput } from '@angular/material/input';\r\nimport { MatIconButton } from '@angular/material/button';\r\nimport { MatTooltip } from '@angular/material/tooltip';\r\nimport { MatIcon } from '@angular/material/icon';\r\n\r\nimport { DataPage, ErrorWrapper } from '@myrmidon/ngx-tools';\r\n\r\nimport { DataPinInfo, IndexLookupDefinitions } from '@myrmidon/cadmus-core';\r\nimport { ItemService } from '@myrmidon/cadmus-api';\r\n\r\n/**\r\n * Generic data pin lookup component. This allows users typing a part\r\n * of a pin's value, and get the full pin. For instance, if you have\r\n * a lookup set of colors and type \"gr\", you might get the pins\r\n * corresponding to \"green\" (e.g. id=color, value=green), \"gray\", etc.\r\n * Usage: add a FormControl to hold a DataPinInfo value; in the HTML\r\n * template set the component's lookupKey, label, initialValue, and\r\n * entryChange handler. The initialValue, if any, should be the initial\r\n * DataPinInfo value.\r\n * If you are using this component as a pure lookup device, don't set\r\n * the initialValue and set resetOnPick=true.\r\n */\r\n@Component({\r\n selector: 'cadmus-lookup-pin',\r\n templateUrl: './lookup-pin.component.html',\r\n styleUrls: ['./lookup-pin.component.css'],\r\n imports: [\r\n FormsModule,\r\n ReactiveFormsModule,\r\n MatAutocomplete,\r\n MatOption,\r\n MatFormField,\r\n MatInput,\r\n MatAutocompleteTrigger,\r\n MatIconButton,\r\n MatTooltip,\r\n MatIcon,\r\n AsyncPipe,\r\n ],\r\n})\r\nexport class LookupPinComponent implements OnInit {\r\n /**\r\n * The entry value initially set when the component loads.\r\n */\r\n public readonly initialValue = input<string>();\r\n\r\n /**\r\n * The label to be displayed for this lookup.\r\n */\r\n public readonly label = input<string>('');\r\n\r\n /**\r\n * The maximum count of lookup entries to retrieve.\r\n * Default is 10.\r\n */\r\n public readonly limit = input<number>(10);\r\n\r\n /**\r\n * True to reset the lookup value after it is picked.\r\n * This is typically used when you use this component\r\n * as a pure lookup device, storing the picked value\r\n * elsewhere when handling its entryChange event.\r\n */\r\n public readonly resetOnPick = input<boolean>();\r\n\r\n /**\r\n * Fired whenever an entry is picked. Usually you should\r\n * cast the received argument to a more specific type.\r\n */\r\n public readonly entryChange = output<DataPinInfo | null>();\r\n\r\n public form: UntypedFormGroup;\r\n public lookup: UntypedFormControl;\r\n public entries$: Observable<DataPinInfo[]> | undefined;\r\n public entry: DataPinInfo | undefined;\r\n\r\n constructor(\r\n formBuilder: UntypedFormBuilder,\r\n private _itemService: ItemService,\r\n @Inject('indexLookupDefinitions')\r\n private _lookupDefs: IndexLookupDefinitions\r\n ) {\r\n // form\r\n this.lookup = formBuilder.control(null);\r\n this.form = formBuilder.group({\r\n lookup: this.lookup,\r\n });\r\n\r\n effect(() => {\r\n console.log('lookup pin initial value', this.initialValue());\r\n if (this.lookup) {\r\n this.resetToInitial();\r\n }\r\n });\r\n }\r\n\r\n /**\r\n * The lookup key to be used for this component.\r\n * This should be a key from the injectable indexLookupDefinitions.\r\n */\r\n public readonly lookupKey = input<string>();\r\n\r\n public ngOnInit(): void {\r\n this.entries$ = this.lookup.valueChanges.pipe(\r\n debounceTime(300),\r\n distinctUntilChanged(),\r\n switchMap((value: DataPinInfo | string) => {\r\n // if it's a string it's a filter; else it's the entry got\r\n if (typeof value === 'string') {\r\n return this.lookupEntries(value, this.limit());\r\n } else {\r\n return of([value]);\r\n }\r\n })\r\n );\r\n // setup initial value if its name was specified\r\n if (this.initialValue()) {\r\n this.resetToInitial();\r\n }\r\n }\r\n\r\n private lookupEntries(\r\n filter: string,\r\n limit: number\r\n ): Observable<DataPinInfo[]> {\r\n // get the lookup definition\r\n if (!this.lookupKey() || !filter) {\r\n return of([]);\r\n }\r\n const ld = this._lookupDefs[this.lookupKey()!];\r\n if (!ld) {\r\n return of([]);\r\n }\r\n\r\n // build query\r\n const query = ld.roleId\r\n ? `[partTypeId=${ld.typeId}] AND [roleId=${ld.roleId}] AND [name=${ld.name}] AND [value^=${filter}]`\r\n : `[partTypeId=${ld.typeId}] AND [name=${ld.name}] AND [value^=${filter}]`;\r\n\r\n // search\r\n return this._itemService.searchPins(query, 1, limit).pipe(\r\n map((w: ErrorWrapper<DataPage<DataPinInfo>>) => {\r\n if (w.error) {\r\n return [];\r\n } else {\r\n return w.value?.items || [];\r\n }\r\n })\r\n );\r\n }\r\n\r\n private resetToInitial(): void {\r\n this.lookupEntries(this.initialValue() || '', 1)\r\n .pipe(take(1))\r\n .subscribe((entries) => {\r\n this.lookup.setValue(entries.length ? entries[0] : undefined);\r\n });\r\n }\r\n\r\n public clear(): void {\r\n this.entry = undefined;\r\n this.lookup.setValue(null);\r\n this.entryChange.emit(null);\r\n }\r\n\r\n public entryToName(entry: DataPinInfo): string {\r\n return entry?.value;\r\n }\r\n\r\n public pickEntry(entry: DataPinInfo): void {\r\n this.entry = entry;\r\n this.entryChange.emit(entry);\r\n if (this.resetOnPick()) {\r\n this.clear();\r\n }\r\n }\r\n}\r\n","<form [formGroup]=\"form\">\n <mat-autocomplete #lookupAuto=\"matAutocomplete\" [displayWith]=\"entryToName\">\n @for (entry of entries$ | async; track entry) {\n <mat-option [value]=\"entry\" (onSelectionChange)=\"pickEntry(entry)\">\n {{ entry?.value }}\n </mat-option>\n }\n </mat-autocomplete>\n\n <mat-form-field>\n <input\n matInput\n type=\"text\"\n [placeholder]=\"label()\"\n [formControl]=\"lookup\"\n [matAutocomplete]=\"lookupAuto\"\n />\n </mat-form-field>\n <button\n type=\"button\"\n mat-icon-button\n (click)=\"clear()\"\n [disabled]=\"!entry\"\n matTooltip=\"Clear\"\n >\n <mat-icon class=\"mat-warn\">clear</mat-icon>\n </button>\n</form>\n","import { Component, effect, input } from '@angular/core';\r\n\r\nimport {\r\n Thesaurus,\r\n FacetDefinition,\r\n PartTypeIds,\r\n ThesaurusEntry,\r\n} from '@myrmidon/cadmus-core';\r\nimport { FacetService } from '@myrmidon/cadmus-api';\r\n\r\nimport { ColorService } from '../../services/color.service';\r\n\r\nexport enum PartBadgeType {\r\n partAndRole = 0,\r\n partOnly = 1,\r\n roleOnly = 2,\r\n}\r\n\r\n/**\r\n * Function used to get the part's human-friendly name from its ID and role ID.\r\n * This assumes that thesaurus entries with role ID specified have form\r\n * partId:roleId.\r\n * @param typeId The part type ID.\r\n * @param roleId The optional role ID.\r\n * @param typeThesaurus The types thesaurus.\r\n * @param noFallback If true, and no thesaurus is provided, return undefined\r\n * rather than the type and role IDs.\r\n * @returns The name.\r\n */\r\nexport function getPartIdName(\r\n typeId: string,\r\n roleId?: string | null,\r\n typeThesaurus?: Thesaurus,\r\n noFallback = false\r\n): string | undefined {\r\n if (!typeThesaurus) {\r\n if (noFallback) {\r\n return undefined;\r\n }\r\n return roleId ? `${typeId} ${roleId}` : typeId;\r\n }\r\n let entry: ThesaurusEntry | undefined;\r\n\r\n // first find partId:roleId if any\r\n if (roleId) {\r\n const suffixedId = `${typeId}:${roleId}`;\r\n entry = typeThesaurus.entries?.find((e) => e.id === suffixedId);\r\n if (entry) {\r\n return entry.value;\r\n }\r\n }\r\n // else find partId alone\r\n entry = typeThesaurus.entries?.find((e) => e.id === typeId);\r\n\r\n return entry ? entry.value : typeId;\r\n}\r\n\r\n/**\r\n * Part badge component. This component displays a badge with the\r\n * part's type name and role name, if any, and a background color.\r\n */\r\n@Component({\r\n selector: 'cadmus-part-badge',\r\n templateUrl: './part-badge.component.html',\r\n styleUrls: ['./part-badge.component.css'],\r\n})\r\nexport class PartBadgeComponent {\r\n public typeName: string | undefined;\r\n public roleName: string | undefined;\r\n public color: string;\r\n public contrastColor: string;\r\n\r\n /**\r\n * The badge type: 0=part and role, 1=part only, 2=role only.\r\n */\r\n public readonly badgeType = input<PartBadgeType>(PartBadgeType.partAndRole);\r\n\r\n /**\r\n * The types thesaurus.\r\n */\r\n public readonly typeThesaurus = input<Thesaurus>();\r\n\r\n /**\r\n * The part's facet definition.\r\n */\r\n public readonly facetDefinition = input<FacetDefinition>();\r\n\r\n /**\r\n * The part type IDs.\r\n */\r\n public readonly partTypeIds = input<PartTypeIds>();\r\n\r\n constructor(\r\n private _facetService: FacetService,\r\n private _colorService: ColorService\r\n ) {\r\n this.color = 'transparent';\r\n this.contrastColor = 'black';\r\n\r\n effect(() => {\r\n this.updateBadge(\r\n this.partTypeIds(),\r\n this.typeThesaurus(),\r\n this.facetDefinition()\r\n );\r\n });\r\n }\r\n\r\n private getPartColor(\r\n typeId: string,\r\n roleId?: string,\r\n facetDefinition?: FacetDefinition\r\n ): string {\r\n if (!facetDefinition) {\r\n return 'transparent';\r\n }\r\n return this._facetService.getPartColor(typeId, roleId, facetDefinition);\r\n }\r\n\r\n /**\r\n * Get the role's human-friendly name from its ID.\r\n * @param roleId The role ID.\r\n * @param typeThesaurus The types thesaurus.\r\n * @returns The name.?\r\n */\r\n private getRoleIdName(\r\n roleId?: string,\r\n typeThesaurus?: Thesaurus\r\n ): string | undefined {\r\n if (!roleId || !typeThesaurus) {\r\n return roleId;\r\n }\r\n let entry: ThesaurusEntry | undefined;\r\n\r\n // first find full roleId with optional suffix\r\n entry = typeThesaurus.entries?.find((e) => e.id === roleId);\r\n if (entry) {\r\n return entry.value;\r\n }\r\n\r\n // else strip :suffix if any and find\r\n const i = roleId.lastIndexOf(':');\r\n if (i > -1) {\r\n roleId = roleId.substring(0, i);\r\n }\r\n entry = typeThesaurus.entries?.find((e) => e.id === roleId);\r\n return entry ? entry.value : roleId;\r\n }\r\n\r\n private updateBadge(\r\n partTypeIds?: PartTypeIds,\r\n typeThesaurus?: Thesaurus,\r\n facetDefinition?: FacetDefinition\r\n ): void {\r\n if (partTypeIds) {\r\n this.color = this.getPartColor(\r\n partTypeIds.typeId,\r\n partTypeIds.roleId,\r\n facetDefinition\r\n );\r\n this.typeName = getPartIdName(\r\n partTypeIds.typeId,\r\n partTypeIds.roleId,\r\n typeThesaurus\r\n );\r\n this.roleName = this.getRoleIdName(partTypeIds.roleId, typeThesaurus);\r\n } else {\r\n this.color = 'transparent';\r\n this.typeName = undefined;\r\n this.roleName = undefined;\r\n }\r\n this.contrastColor = this._colorService.getContrastColor(this.color);\r\n }\r\n}\r\n","@if (badgeType() !== 2) {\n<span\n class=\"part-badge\"\n [style.background-color]=\"color\"\n [style.color]=\"contrastColor\"\n>\n {{ typeName }}\n</span>\n} @if (badgeType() !== 1 && roleName) {\n<span class=\"role-badge\">\n {{ roleName }}\n</span>\n}\n","import { NestedTreeControl } from '@angular/cdk/tree';\r\nimport { Component, effect, input, OnInit, output } from '@angular/core';\r\nimport {\r\n FormBuilder,\r\n FormControl,\r\n FormGroup,\r\n FormsModule,\r\n ReactiveFormsModule,\r\n} from '@angular/forms';\r\nimport { NgClass } from '@angular/common';\r\n\r\nimport {\r\n MatTreeNestedDataSource,\r\n MatTree,\r\n MatTreeNodeDef,\r\n MatTreeNode,\r\n MatTreeNodeToggle,\r\n MatNestedTreeNode,\r\n MatTreeNodeOutlet,\r\n} from '@angular/material/tree';\r\nimport { MatIconButton, MatAnchor } from '@angular/material/button';\r\nimport { MatTooltip } from '@angular/material/tooltip';\r\nimport { MatIcon } from '@angular/material/icon';\r\nimport {\r\n MatFormField,\r\n MatLabel,\r\n MatSuffix,\r\n} from '@angular/material/form-field';\r\nimport { MatInput } from '@angular/material/input';\r\n\r\nimport { ThesaurusEntry } from '@myrmidon/cadmus-core';\r\n\r\ninterface TreeNode {\r\n id: string;\r\n label: string;\r\n originalLabel?: string;\r\n parent?: TreeNode;\r\n children?: TreeNode[];\r\n clickable?: boolean;\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 const 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\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. Note that even if you specify a label renderer\r\n * function, the event always emits the original label.\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: [\r\n FormsModule,\r\n ReactiveFormsModule,\r\n MatIconButton,\r\n MatTooltip,\r\n MatIcon,\r\n MatFormField,\r\n MatLabel,\r\n MatInput,\r\n MatSuffix,\r\n NgClass,\r\n MatTree,\r\n MatTreeNodeDef,\r\n MatTreeNode,\r\n MatTreeNodeToggle,\r\n MatAnchor,\r\n MatNestedTreeNode,\r\n MatTreeNodeOutlet,\r\n ],\r\n})\r\nexport class ThesaurusTreeComponent implements OnInit {\r\n /**\r\n * The thesaurus entries.\r\n */\r\n public readonly entries = input<ThesaurusEntry[]>();\r\n\r\n /**\r\n * The label for the root node.\r\n */\r\n public readonly rootLabel = input<string>('-');\r\n /**\r\n * The optional node label rendering function.\r\n */\r\n public readonly renderLabel = input<(label: string) => string>();\r\n /**\r\n * Fired when a thesaurus entry is selected.\r\n */\r\n public readonly entryChange = output<ThesaurusEntry>();\r\n\r\n public root: TreeNode;\r\n // TODO: use childrenAccessor: https://material.angular.io/cdk/tree/examples\r\n public treeControl: NestedTreeControl<TreeNode>;\r\n public treeDataSource: MatTreeNestedDataSource<TreeNode>;\r\n\r\n public filter: FormControl<string | null>;\r\n public form: FormGroup;\r\n public foundNodes: TreeNode[] | undefined;\r\n\r\n public hasChildren = (index: number, node: TreeNode) => {\r\n return node && node.children && node.children.length > 0;\r\n };\r\n\r\n public isRoot = (index: number, node: TreeNode) => {\r\n return node && node.id === '@root';\r\n };\r\n\r\n constructor(formBuilder: FormBuilder) {\r\n // tree\r\n this.treeControl = new NestedTreeControl<TreeNode>((node) => node.children);\r\n this.treeDataSource = new MatTreeNestedDataSource<TreeNode>();\r\n this.root = { id: '@root', label: '-', children: [] };\r\n // filter\r\n this.filter = formBuilder.control(null);\r\n this.form = formBuilder.group({\r\n filter: this.filter,\r\n });\r\n\r\n effect(() => {\r\n this.initTree(this.entries());\r\n });\r\n }\r\n\r\n public ngOnInit(): void {\r\n this.initTree();\r\n }\r\n\r\n private initTree(entries?: ThesaurusEntry[]): void {\r\n this.foundNodes = undefined;\r\n\r\n this.root = this.buildTreeModel(entries || []);\r\n this.treeDataSource.data = [this.root];\r\n // https://github.com/angular/components/issues/12469\r\n this.treeControl.dataNodes = this.treeDataSource.data;\r\n }\r\n\r\n private getLabel(label: string): string {\r\n const renderer = this.renderLabel();\r\n return renderer ? renderer(label) : label;\r\n }\r\n\r\n private addNode(\r\n entry: ThesaurusEntry,\r\n separator: string,\r\n root: TreeNode\r\n ): void {\r\n const components = entry.id.split(separator);\r\n\r\n // walk the tree up to the last existing component\r\n let i = 0;\r\n let node = root;\r\n const idParts: string[] = [];\r\n\r\n // for each component:\r\n while (i < components.length) {\r\n idParts.push(components[i]);\r\n\r\n // stop walking when the node has no more children\r\n if (!node.children) {\r\n break;\r\n }\r\n // find target among children\r\n const targetId = idParts.join(separator);\r\n const existing = node.children.find((c) => {\r\n return c.id === targetId;\r\n });\r\n if (existing) {\r\n node = existing;\r\n i++;\r\n } else {\r\n break;\r\n }\r\n }\r\n\r\n // node is now the last existing component; use it as the ancestor\r\n // for all the remaining components (starting from i)\r\n while (i < components.length) {\r\n if (!node.children) {\r\n node.children = [];\r\n }\r\n const isLast = i + 1 === components.length;\r\n const label = isLast ? entry.value : components[i];\r\n const child: TreeNode = {\r\n label: isLast ? this.getLabel(label) : label,\r\n id: isLast ? entry.id : idParts.join(separator),\r\n parent: node,\r\n children: [],\r\n };\r\n if (label !== child.label) {\r\n child.originalLabel = label;\r\n }\r\n node.children.push(child);\r\n node = child;\r\n i++;\r\n }\r\n }\r\n\r\n /**\r\n * Build a tree model from a list of name=value pairs,\r\n * where each value can include one or more components separated by\r\n * the specified separator.\r\n * @param entries The entries to add.\r\n * @param separator string The separator string to use for values.\r\n */\r\n public buildTreeModel(entries: ThesaurusEntry[], separator = '.'): TreeNode {\r\n const root: TreeNode = {\r\n id: '@root',\r\n label: this.rootLabel() || '-',\r\n };\r\n if (!entries) {\r\n return root;\r\n }\r\n entries.forEach((entry) => {\r\n this.addNode(entry, separator, root);\r\n });\r\n return root;\r\n }\r\n\r\n public onTreeNodeClick(node: TreeNode): void {\r\n if (node.children && node.children.length > 0) {\r\n return;\r\n }\r\n this.entryChange.emit({\r\n id: node.id,\r\n value: node.originalLabel || node.label,\r\n });\r\n }\r\n\r\n public expandAll(): void {\r\n this.treeControl.expandAll();\r\n }\r\n\r\n public collapseAll(): void {\r\n this.treeControl.collapseAll();\r\n }\r\n\r\n private expandFromNode(node: TreeNode): void {\r\n while (node.parent) {\r\n node = node.parent;\r\n this.treeControl.expand(node);\r\n }\r\n }\r\n\r\n private expandMatchingNodes(\r\n node: TreeNode,\r\n filter: string,\r\n found: TreeNode[]\r\n ): void {\r\n if (node.label.toLowerCase().includes(filter)) {\r\n found.push(node);\r\n this.expandFromNode(node);\r\n }\r\n if (node.children?.length) {\r\n node.children.forEach((child) => {\r\n this.expandMatchingNodes(child, filter, found);\r\n });\r\n }\r\n }\r\n\r\n public find(): void {\r\n if (!this.filter.value?.length) {\r\n return;\r\n }\r\n this.treeControl.collapseAll();\r\n const foundNodes: TreeNode[] = [];\r\n this.expandMatchingNodes(\r\n this.treeDataSource.data[0],\r\n this.filter.value.toLowerCase(),\r\n foundNodes\r\n );\r\n this.foundNodes = foundNodes;\r\n }\r\n\r\n public resetFilter(): void {\r\n this.filter.reset();\r\n this.foundNodes = undefined;\r\n }\r\n\r\n public isFoundNode(node: TreeNode): boolean {\r\n if (!this.foundNodes) {\r\n return false;\r\n }\r\n return this.foundNodes?.length > 0 && this.foundNodes.indexOf(node) > -1;\r\n }\r\n}\r\n","<form [formGroup]=\"form\" (submit)=\"find()\">\n <button\n type=\"button\"\n mat-icon-button\n matTooltip=\"Expand all\"\n (click)=\"expandAll()\"\n >\n <mat-icon>unfold_more</mat-icon>\n </button>\n <button\n type=\"button\"\n mat-icon-button\n matTooltip=\"Collapse all\"\n (click)=\"collapseAll()\"\n >\n <mat-icon>unfold_less</mat-icon>\n </button>\n <mat-form-field>\n <mat-label>find</mat-label>\n <input matInput [formControl]=\"filter\" />\n <button\n type=\"button\"\n matSuffix\n mat-icon-button\n (click)=\"resetFilter()\"\n >\n <mat-icon class=\"mat-warn\">clear</mat-icon>\n </button>\n </mat-form-field>\n @if (foundNodes) {\n <span\n [ngClass]=\"{\n 'found-count': foundNodes.length,\n 'not-found-count': foundNodes.length === 0\n }\"\n >{{ foundNodes.length }}</span\n >\n }\n</form>\n<mat-tree\n [dataSource]=\"treeDataSource\"\n [treeControl]=\"treeControl\"\n class=\"th-tree\"\n>\n <!-- leaf node -->\n <mat-tree-node *matTreeNodeDef=\"let node\" matTreeNodeToggle>\n <li>\n <div class=\"mat-tree-node\">\n <a\n mat-button\n (click)=\"onTreeNodeClick(node)\"\n [class.hilite]=\"isFoundNode(node)\"\n >\n {{ node.label }}\n </a>\n </div>\n </li>\n </mat-tree-node>\n\n <!-- root node -->\n <mat-nested-tree-node *matTreeNodeDef=\"let node; when: isRoot\">\n <div class=\"mat-tree-node\">\n <button\n type=\"button\"\n mat-icon-button\n matTreeNodeToggle\n [attr.aria-label]=\"'Toggle ' + node.label\"\n >\n <mat-icon>\n {{ treeControl.isExpanded(node) ? \"expand_more\" : \"chevron_right\" }}\n </mat-icon>\n </button>\n {{ node.label }}\n </div>\n <ul class=\"tree-nested-node\">\n @if (treeControl.isExpanded(node)) {\n <div>\n <ng-container matTreeNodeOutlet></ng-container>\n </div>\n }\n </ul>\n </mat-nested-tree-node>\n\n <!-- parent node -->\n <mat-nested-tree-node *matTreeNodeDef=\"let node; when: hasChildren\">\n <li class=\"tree-container\">\n <div class=\"mat-tree-node\">\n <button\n type=\"button\"\n mat-icon-button\n matTreeNodeToggle\n [attr.aria-label]=\"'Toggle ' + node.label\"\n >\n <mat-icon>\n {{ treeControl.isExpanded(node) ? \"expand_more\" : \"chevron_right\" }}\n </mat-icon>\n </button>\n <a mat-button (click)=\"onTreeNodeClick(node)\">\n {{ node.label }}\n </a>\n </div>\n <ul class=\"tree-nested-node\">\n @if (treeControl.isExpanded(node)) {\n <div>\n <ng-container matTreeNodeOutlet></ng-container>\n </div>\n }\n </ul>\n </li>\n </mat-nested-tree-node>\n</mat-tree>\n","import {\r\n Component,\r\n OnDestroy,\r\n OnInit,\r\n output,\r\n input,\r\n effect,\r\n model,\r\n computed,\r\n inject,\r\n} from '@angular/core';\r\nimport {\r\n FormBuilder,\r\n FormGroup,\r\n PristineChangeEvent,\r\n UntypedFormGroup,\r\n} from '@angular/forms';\r\nimport { BehaviorSubject, Subscription } from 'rxjs';\r\n\r\nimport { deepCopy } from '@myrmidon/ngx-tools';\r\nimport { AuthJwtService, User } from '@myrmidon/auth-jwt-login';\r\n\r\nimport {\r\n Fragment,\r\n Part,\r\n TextLayerPart,\r\n ThesauriSet,\r\n} from '@myrmidon/cadmus-core';\r\nimport { getPartIdName } from './part-badge/part-badge.component';\r\nimport { AppRepository } from '@myrmidon/cadmus-state';\r\n\r\n/**\r\n * The identifiers for an edited part.\r\n */\r\nexport interface PartIdentity {\r\n itemId: string;\r\n typeId: string;\r\n partId: string | null;\r\n roleId: string | null;\r\n}\r\n\r\n/**\r\n * The identifiers for an edited fragment.\r\n */\r\nexport interface FragmentIdentity extends PartIdentity {\r\n frTypeId: string;\r\n frRoleId: string | null;\r\n loc: string;\r\n}\r\n\r\n/**\r\n * An edited part or fragment.\r\n */\r\nexport interface EditedObject<T extends Part | Fragment> {\r\n value: T | null;\r\n thesauri: ThesauriSet;\r\n layerPart?: TextLayerPart;\r\n baseText?: string;\r\n}\r\n\r\n/**\r\n * Base class for part/fragment editors dumb components.\r\n * The model type is the templated argument T.\r\n *\r\n * When deriving from this editor, be sure to call super.ngOnInit()\r\n * from the derived editor's ngOnInit handler.\r\n */\r\n@Component({\r\n template: '',\r\n standalone: false,\r\n})\r\nexport abstract class ModelEditorComponentBase<T extends Part | Fragment>\r\n implements OnInit, OnDestroy\r\n{\r\n private readonly _mebSubs: Subscription[] = [];\r\n private readonly _appRepository?: AppRepository;\r\n\r\n /**\r\n * The root form of the editor.\r\n */\r\n public form: FormGroup | UntypedFormGroup;\r\n\r\n /**\r\n * The current user.\r\n */\r\n public user?: User;\r\n\r\n /**\r\n * The user authorization level (0-4).\r\n */\r\n public userLevel: number;\r\n\r\n /**\r\n * An observable with the current dirty state of the editor.\r\n */\r\n public isDirty$: BehaviorSubject<boolean>;\r\n\r\n /**\r\n * The identity of the edited model.\r\n */\r\n public readonly identity = input<PartIdentity | FragmentIdentity>();\r\n\r\n /**\r\n * The data being edited.\r\n */\r\n public readonly data = model<EditedObject<T>>();\r\n\r\n /**\r\n * True to disable the editor.\r\n */\r\n public readonly disabled = input<boolean>();\r\n\r\n /**\r\n * Event emitted when the dirty state has changed.\r\n * This event just reflects changes in isDirty$, and is a facility\r\n * for propagating it to the parent's component.\r\n */\r\n public readonly dirtyChange = output<boolean>();\r\n\r\n /**\r\n * Emitted when the user requests to close the editor.\r\n */\r\n public readonly editorClose = output();\r\n\r\n /**\r\n * The human-friendly model name. This is computed from the model's\r\n * type ID and role ID, if any, using the types thesaurus set provided\r\n * by the app repository.\r\n */\r\n public readonly modelName = computed<string | undefined>(() => {\r\n const identity = this.identity();\r\n // layers have no identity but have a layerPart\r\n if (!identity) {\r\n const layerPart = this.data()?.layerPart;\r\n if (layerPart) {\r\n return getPartIdName(\r\n layerPart.typeId,\r\n layerPart.roleId,\r\n this._appRepository?.getTypeThesaurus(),\r\n true // no fallback so that the part template can use its default name\r\n );\r\n }\r\n return undefined;\r\n }\r\n if (!identity) {\r\n return undefined;\r\n }\r\n return getPartIdName(\r\n identity.typeId,\r\n identity.roleId,\r\n this._appRepository?.getTypeThesaurus(),\r\n true // no fallback so that the part template can use its default name\r\n );\r\n });\r\n\r\n /**\r\n * Create a new instance of the editor.\r\n *\r\n * @param authService The authentication service.\r\n * @param formBuilder Form builder.\r\n */\r\n constructor(\r\n protected authService: AuthJwtService,\r\n protected formBuilder: FormBuilder\r\n ) {\r\n this.form = formBuilder.group({});\r\n this.userLevel = 0;\r\n this.isDirty$ = new BehaviorSubject<boolean>(false);\r\n this._appRepository = inject(AppRepository);\r\n\r\n effect(() => {\r\n this.disableForm(this.disabled());\r\n });\r\n effect(() => {\r\n this.onDataSet(this.data());\r\n });\r\n effect(() => {\r\n this.onIdentitySet(this.identity());\r\n });\r\n }\r\n\r\n private disableForm(disabled?: boolean) {\r\n if (disabled) {\r\n this.form.disable();\r\n } else {\r\n this.form.enable();\r\n }\r\n }\r\n\r\n private onIdentitySet(identity?: PartIdentity | FragmentIdentity) {\r\n if (identity?.partId) {\r\n const part = this.data()?.value as Part;\r\n if (part && !part.id) {\r\n console.log('part identity set', identity.partId);\r\n part.id = identity.partId;\r\n }\r\n }\r\n }\r\n\r\n public ngOnInit(): void {\r\n // form\r\n this.form = this.buildForm(this.formBuilder);\r\n\r\n // dirty check on form\r\n this._mebSubs.push(\r\n this.form.events.subscribe((e) => {\r\n if (e instanceof PristineChangeEvent) {\r\n console.log('dirty change: ', !e.pristine);\r\n this.isDirty$.next(!e.pristine);\r\n this.dirtyChange.emit(this.isDirty$.value);\r\n }\r\n })\r\n );\r\n\r\n // auth service\r\n this.userLevel = this.getCurrentUserLevel();\r\n this._mebSubs.push(\r\n this.authService.currentUser$.subscribe((user: User | null) => {\r\n this.updateUserProperties(user);\r\n })\r\n );\r\n }\r\n\r\n public ngOnDestroy(): void {\r\n this._mebSubs.forEach((s) => s.unsubscribe());\r\n }\r\n\r\n /**\r\n * Implement in the derived class to build the root form of this editor.\r\n * The form built will then be attached to the dirty check mechanism\r\n * provided by this base class.\r\n *\r\n * @param formBuilder The form builder.\r\n */\r\n protected abstract buildForm(\r\n formBuilder: FormBuilder\r\n ): FormGroup | UntypedFormGroup;\r\n\r\n /**\r\n * Get the authorization level of the current user if any.\r\n * @returns 4-1 for admin, editor, operator, visitor; else 0.\r\n */\r\n private getCurrentUserLevel(): number {\r\n const user = this.authService.currentUserValue;\r\n if (!user || !user.roles) {\r\n return 0;\r\n }\r\n if (user.roles.indexOf('admin') > -1) {\r\n return 4;\r\n }\r\n if (user.roles.indexOf('editor') > -1) {\r\n return 3;\r\n }\r\n if (user.roles.indexOf('operator') > -1) {\r\n return 2;\r\n }\r\n if (user.roles.indexOf('visitor') > -1) {\r\n return 1;\r\n }\r\n return 0;\r\n }\r\n\r\n private updateUserProperties(user: User | null): void {\r\n if (!user) {\r\n this.user = undefined;\r\n this.userLevel = 0;\r\n } else {\r\n this.user = user;\r\n this.userLevel = this.getCurrentUserLevel();\r\n }\r\n }\r\n\r\n /**\r\n * Update the data value property and emit the corresponding\r\n * modelChange event.\r\n *\r\n * @param value The value.\r\n */\r\n protected updateValue(value: T): void {\r\n this.data.set({ ...(this.data() || { thesauri: {} }), value: value });\r\n }\r\n\r\n /**\r\n * Invoked whenever the model property is set (=data comes from input model\r\n * property), unless setting it via updateModel. Implement to update the form\r\n * controls to reflect the new model data.\r\n *\r\n * @param data The data set, or undefined.\r\n */\r\n protected abstract onDataSet(data?: EditedObject<T>): void;\r\n\r\n /**\r\n * Get a new object from the edited part if any, else as a new part.\r\n *\r\n * @param typeId The part's type ID. This is a constant received\r\n * from the implementor.\r\n * @returns Part object.\r\n */\r\n protected getEditedPart(typeId: string): Part {\r\n const part = deepCopy(this.data()?.value) as Part | null;\r\n return (\r\n part || {\r\n itemId: this.identity()!.itemId || '',\r\n id: '',\r\n typeId: typeId,\r\n roleId: this.identity()!.roleId || undefined,\r\n timeCreated: new Date(),\r\n creatorId: '',\r\n timeModified: new Date(),\r\n userId: '',\r\n }\r\n );\r\n }\r\n\r\n /**\r\n * Get a new object from the edited fragment if any, else a new fragment.\r\n *\r\n * @returns Fragment object.\r\n */\r\n protected getEditedFragment(): Fragment {\r\n const fr = deepCopy(this.data()?.value) as Fragment | null;\r\n return (\r\n fr || {\r\n location: (this.identity() as FragmentIdentity).loc,\r\n }\r\n );\r\n }\r\n\r\n /**\r\n * Implement in derived classes to get the data from form's controls.\r\n * This is used when saving.\r\n */\r\n protected abstract getValue(): T;\r\n\r\n /**\r\n * True if this editor has the thesaurus having the specified key in the\r\n * loaded thesauri set.\r\n */\r\n protected hasThesaurus(key: string): boolean {\r\n return this.data()?.thesauri && this.data()!.thesauri[key] ? true : false;\r\n }\r\n\r\n /**\r\n * Emit a request to close the editor.\r\n */\r\n public close(): void {\r\n this.editorClose.emit();\r\n }\r\n\r\n /**\r\n * Save the edited data if valid.\r\n */\r\n public save(): void {\r\n if (this.form.invalid) {\r\n console.warn('Save invoked with invalid form');\r\n return;\r\n }\r\n const value = this.getValue();\r\n this.updateValue(value);\r\n // the form is no more dirty\r\n this.form.markAsPristine();\r\n }\r\n}\r\n","import {\r\n AbstractControl,\r\n ValidatorFn,\r\n ValidationErrors,\r\n FormGroup,\r\n UntypedFormGroup,\r\n} from '@angular/forms';\r\n\r\n// https://www.tektutorialshub.com/angular/custom-validator-with-parameters-in-angular/\r\n\r\n/**\r\n * General-purpose custom validators.\r\n */\r\n// https://github.com/angular/angular/issues/18867#issuecomment-357484102\r\n// @dynamic\r\nexport class CustomValidators {\r\n /**\r\n * Validates a FormGroup or FormArray control checking if the count of their\r\n * controls with a true value is equal to or greater than the specified\r\n * number.\r\n *\r\n * @param min The minimum number of checked controls.\r\n */\r\n public static minChecked(min = 1): ValidatorFn {\r\n return (control: AbstractControl): ValidationErrors | null => {\r\n // https://trungk18.com/experience/angular-form-array-validate-at-least-one-checkbox-was-selected/\r\n let checked = 0;\r\n\r\n const group = (control as FormGroup) || (control as UntypedFormGroup);\r\n Object.keys(group.controls).forEach((key) => {\r\n const ctl = group.controls[key];\r\n if (ctl.value === true) {\r\n checked++;\r\n }\r\n });\r\n\r\n if (checked < min) {\r\n return {\r\n minChecked: true,\r\n };\r\n }\r\n return null;\r\n };\r\n }\r\n}\r\n","import { AbstractControl } from '@angular/forms';\r\n\r\n/**\r\n * Simple JSON validator.\r\n */\r\nexport class JsonValidators {\r\n public static json(\r\n control: AbstractControl\r\n ): { [key: string]: boolean } | null {\r\n if (!control.value) {\r\n // we allow empty code\r\n return null;\r\n }\r\n try {\r\n JSON.parse(control.value);\r\n } catch (e) {\r\n return { json: true };\r\n }\r\n return null;\r\n }\r\n}\r\n","import { Injectable } from '@angular/core';\nimport { map, Observable } from 'rxjs';\n\nimport { DataPage } from '@myrmidon/ngx-tools';\n\nimport { UserService } from '@myrmidon/cadmus-api';\nimport {\n RefLookupFilter,\n RefLookupService,\n} from '@myrmidon/cadmus-refs-lookup';\n\nexport interface UserWithRoles {\n user: {\n id: string;\n firstName: string;\n lastName: string;\n userName: string;\n email: string;\n };\n roles: string[];\n}\n\n/**\n * Service for users lookup.\n */\n@Injectable({\n providedIn: 'root',\n})\nexport class UserRefLookupService implements RefLookupService {\n constructor(private _userService: UserService) {}\n\n public lookup(\n filter: RefLookupFilter,\n options?: any\n ): Observable<UserWithRoles[]> {\n return this._userService\n .getUsers(\n {\n name: filter.text,\n },\n 1,\n filter.limit\n )\n .pipe(\n map((page: DataPage<UserWithRoles>) => {\n return page.items;\n })\n );\n }\n\n public getName(item: UserWithRoles): string {\n return item?.user?.userName;\n }\n}\n","// https://github.com/angular/angular/issues/10887\r\n\r\nimport { AbstractControl } from '@angular/forms';\r\nimport { Observable, Subject } from 'rxjs';\r\n\r\n/**\r\n * Extract arguments of function\r\n */\r\nexport type ArgumentsType<F> = F extends (...args: infer A) => any ? A : never;\r\n\r\n/**\r\n * Creates an object like O. Optionally provide minimum set of properties P\r\n * which the objects must share to conform.\r\n */\r\ntype ObjectLike<O extends object, P extends keyof O = keyof O> = Pick<O, P>;\r\n\r\n/**\r\n * Extract a touched changed observable from an abstract control.\r\n * Use in component code like:\r\n * this.touchedChanges$ = extractTouchedChanges(this.form);\r\n *\r\n * @param control AbstractControl-like object with markAsTouched method.\r\n */\r\nexport const extractTouchedChanges = (\r\n control: ObjectLike<AbstractControl, 'markAsTouched' | 'markAsUntouched'>\r\n): Observable<boolean> => {\r\n const prevMarkAsTouched = control.markAsTouched;\r\n const prevMarkAsUntouched = control.markAsUntouched;\r\n\r\n const touchedChanges$ = new Subject<boolean>();\r\n\r\n function nextMarkAsTouched(\r\n ...args: ArgumentsType<AbstractControl['markAsTouched']>\r\n ): void {\r\n touchedChanges$.next(true);\r\n prevMarkAsTouched.bind(control)(...args);\r\n }\r\n\r\n function nextMarkAsUntouched(\r\n ...args: ArgumentsType<AbstractControl['markAsUntouched']>\r\n ): void {\r\n touchedChanges$.next(false);\r\n prevMarkAsUntouched.bind(control)(...args);\r\n }\r\n\r\n control.markAsTouched = nextMarkAsTouched;\r\n control.markAsUntouched = nextMarkAsUntouched;\r\n\r\n return touchedChanges$;\r\n};\r\n\r\n/**\r\n * Extract a pristine changed observable from an abstract control.\r\n * Use in component code like:\r\n * this.pristineChanges$ = extractPristineChanges(this.form);\r\n *\r\n * @param control AbstractControl-like object with markAsPristine and markAsDirty\r\n * methods.\r\n */\r\nexport const extractPristineChanges = (\r\n control: ObjectLike<AbstractControl, 'markAsPristine' | 'markAsDirty'>\r\n): Observable<boolean> => {\r\n const prevMarkAsPristine = control.markAsPristine;\r\n const prevMarkAsDirty = control.markAsDirty;\r\n\r\n const pristineChanges$ = new Subject<boolean>();\r\n\r\n function nextMarkAsPristine(\r\n ...args: ArgumentsType<AbstractControl['markAsPristine']>\r\n ): void {\r\n pristineChanges$.next(true);\r\n prevMarkAsPristine.bind(control)(...args);\r\n }\r\n\r\n function nextMarkAsDirty(\r\n ...args: ArgumentsType<AbstractControl['markAsDirty']>\r\n ): void {\r\n pristineChanges$.next(false);\r\n prevMarkAsDirty.bind(control)(...args);\r\n }\r\n\r\n control.markAsPristine = nextMarkAsPristine;\r\n control.markAsDirty = nextMarkAsDirty;\r\n\r\n return pristineChanges$;\r\n};\r\n","/*\r\n * Public API Surface of cadmus-ui\r\n */\r\n\r\nexport * from './lib/components/close-save-buttons/close-save-buttons.component';\r\nexport * from './lib/components/decorated-token-text/decorated-token-text.component';\r\nexport * from './lib/components/error-list/error-list.component';\r\nexport * from './lib/components/facet-badge/facet-badge.component';\r\nexport * from './lib/components/flags-badge/flags-badge.component';\r\nexport * from './lib/components/layer-hints/layer-hints.component';\r\nexport * from './lib/components/lookup-pin/lookup-pin.component';\r\nexport * from './lib/components/part-badge/part-badge.component';\r\nexport * from './lib/components/thesaurus-tree/thesaurus-tree.component';\r\n\r\nexport * from './lib/components/model-editor-component-base';\r\n\r\nexport * from './lib/services/color.service';\r\n\r\nexport * from './lib/validators/custom-validators';\r\nexport * from './lib/validators/json-validators';\r\n\r\nexport * from './lib/services/user-ref-lookup.service';\r\n\r\nexport * from './lib/utils';\r\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":["i1.ColorService","i1","i2.ColorService","i2","map"],"mappings":"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"}
@@ -41,6 +41,7 @@ export declare abstract class ModelEditorComponentBase<T extends Part | Fragment
41
41
  protected authService: AuthJwtService;
42
42
  protected formBuilder: FormBuilder;
43
43
  private readonly _mebSubs;
44
+ private readonly _appRepository?;
44
45
  /**
45
46
  * The root form of the editor.
46
47
  */
@@ -79,6 +80,12 @@ export declare abstract class ModelEditorComponentBase<T extends Part | Fragment
79
80
  * Emitted when the user requests to close the editor.
80
81
  */
81
82
  readonly editorClose: import("@angular/core").OutputEmitterRef<void>;
83
+ /**
84
+ * The human-friendly model name. This is computed from the model's
85
+ * type ID and role ID, if any, using the types thesaurus set provided
86
+ * by the app repository.
87
+ */
88
+ readonly modelName: import("@angular/core").Signal<string | undefined>;
82
89
  /**
83
90
  * Create a new instance of the editor.
84
91
  *
@@ -7,6 +7,22 @@ export declare enum PartBadgeType {
7
7
  partOnly = 1,
8
8
  roleOnly = 2
9
9
  }
10
+ /**
11
+ * Function used to get the part's human-friendly name from its ID and role ID.
12
+ * This assumes that thesaurus entries with role ID specified have form
13
+ * partId:roleId.
14
+ * @param typeId The part type ID.
15
+ * @param roleId The optional role ID.
16
+ * @param typeThesaurus The types thesaurus.
17
+ * @param noFallback If true, and no thesaurus is provided, return undefined
18
+ * rather than the type and role IDs.
19
+ * @returns The name.
20
+ */
21
+ export declare function getPartIdName(typeId: string, roleId?: string | null, typeThesaurus?: Thesaurus, noFallback?: boolean): string | undefined;
22
+ /**
23
+ * Part badge component. This component displays a badge with the
24
+ * part's type name and role name, if any, and a background color.
25
+ */
10
26
  export declare class PartBadgeComponent {
11
27
  private _facetService;
12
28
  private _colorService;
@@ -32,7 +48,12 @@ export declare class PartBadgeComponent {
32
48
  readonly partTypeIds: import("@angular/core").InputSignal<PartTypeIds | undefined>;
33
49
  constructor(_facetService: FacetService, _colorService: ColorService);
34
50
  private getPartColor;
35
- private getTypeIdName;
51
+ /**
52
+ * Get the role's human-friendly name from its ID.
53
+ * @param roleId The role ID.
54
+ * @param typeThesaurus The types thesaurus.
55
+ * @returns The name.?
56
+ */
36
57
  private getRoleIdName;
37
58
  private updateBadge;
38
59
  static ɵfac: i0.ɵɵFactoryDeclaration<PartBadgeComponent, never>;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@myrmidon/cadmus-ui",
3
- "version": "12.0.0",
3
+ "version": "12.0.1",
4
4
  "description": "Cadmus - general UI components.",
5
5
  "keywords": [
6
6
  "Cadmus"
@@ -16,8 +16,8 @@
16
16
  "peerDependencies": {
17
17
  "@angular/common": "^19.0.0",
18
18
  "@angular/core": "^19.0.0",
19
- "@myrmidon/ngx-tools": "^1.0.0",
20
- "@myrmidon/cadmus-refs-lookup": "^8.0.0",
19
+ "@myrmidon/ngx-tools": "^1.0.2",
20
+ "@myrmidon/cadmus-refs-lookup": "^8.0.1",
21
21
  "@myrmidon/cadmus-core": "^11.0.0"
22
22
  },
23
23
  "dependencies": {