@myrmidon/cadmus-ui 15.1.3 → 16.0.0
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,35 +1,22 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
|
-
import { input, output, Component, signal, effect, ViewChild, Injectable, Inject,
|
|
3
|
-
import
|
|
4
|
-
import {
|
|
5
|
-
import * as i5 from '@angular/material/icon';
|
|
6
|
-
import { MatIcon, MatIconModule } from '@angular/material/icon';
|
|
2
|
+
import { input, output, Component, signal, effect, ViewChild, Injectable, Inject, computed, model, inject } from '@angular/core';
|
|
3
|
+
import { MatButton, MatIconButton } from '@angular/material/button';
|
|
4
|
+
import { MatIcon } from '@angular/material/icon';
|
|
7
5
|
import { SafeHtmlPipe, ColorToContrastPipe, deepCopy } from '@myrmidon/ngx-tools';
|
|
8
6
|
import * as i1 from '@myrmidon/cadmus-core';
|
|
9
|
-
import
|
|
10
|
-
import { MatTooltip, MatTooltipModule } from '@angular/material/tooltip';
|
|
7
|
+
import { MatTooltip } from '@angular/material/tooltip';
|
|
11
8
|
import * as i1$1 from '@angular/forms';
|
|
12
|
-
import { FormsModule, ReactiveFormsModule,
|
|
13
|
-
import
|
|
14
|
-
import { MatCheckbox, MatCheckboxModule } from '@angular/material/checkbox';
|
|
9
|
+
import { FormsModule, ReactiveFormsModule, PristineChangeEvent } from '@angular/forms';
|
|
10
|
+
import { MatCheckbox } from '@angular/material/checkbox';
|
|
15
11
|
import * as i2 from '@myrmidon/ngx-mat-tools';
|
|
16
12
|
import { AsyncPipe } from '@angular/common';
|
|
17
13
|
import { of, BehaviorSubject, map as map$1, Subject } from 'rxjs';
|
|
18
14
|
import { debounceTime, distinctUntilChanged, switchMap, map, take } from 'rxjs/operators';
|
|
19
15
|
import { MatAutocomplete, MatAutocompleteTrigger } from '@angular/material/autocomplete';
|
|
20
16
|
import { MatOption } from '@angular/material/core';
|
|
21
|
-
import
|
|
22
|
-
import {
|
|
23
|
-
import * as i4$1 from '@angular/material/input';
|
|
24
|
-
import { MatInput, MatInputModule } from '@angular/material/input';
|
|
17
|
+
import { MatFormField } from '@angular/material/form-field';
|
|
18
|
+
import { MatInput } from '@angular/material/input';
|
|
25
19
|
import * as i1$2 from '@myrmidon/cadmus-api';
|
|
26
|
-
import { moveItemInArray, CdkDropList, CdkDrag } from '@angular/cdk/drag-drop';
|
|
27
|
-
import { MatChipListbox, MatChipOption, MatChipRemove } from '@angular/material/chips';
|
|
28
|
-
import { MatExpansionPanel } from '@angular/material/expansion';
|
|
29
|
-
import { MatDialogRef, MAT_DIALOG_DATA, MatDialog } from '@angular/material/dialog';
|
|
30
|
-
import * as i7 from '@angular/material/progress-bar';
|
|
31
|
-
import { MatProgressBarModule } from '@angular/material/progress-bar';
|
|
32
|
-
import { PagedTreeStore, BrowserTreeNodeComponent } from '@myrmidon/paged-data-browsers';
|
|
33
20
|
import { AppRepository } from '@myrmidon/cadmus-state';
|
|
34
21
|
import * as i1$3 from '@myrmidon/auth-jwt-login';
|
|
35
22
|
|
|
@@ -40,10 +27,10 @@ class CloseSaveButtonsComponent {
|
|
|
40
27
|
close() {
|
|
41
28
|
this.closeRequest.emit();
|
|
42
29
|
}
|
|
43
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
44
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "
|
|
30
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: CloseSaveButtonsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
31
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.0", 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[matButton], a[matButton], button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button], a[mat-button], a[mat-raised-button], a[mat-flat-button], a[mat-stroked-button] ", inputs: ["matButton"], exportAs: ["matButton", "matAnchor"] }, { kind: "component", type: MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }] });
|
|
45
32
|
}
|
|
46
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
33
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: CloseSaveButtonsComponent, decorators: [{
|
|
47
34
|
type: Component,
|
|
48
35
|
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"] }]
|
|
49
36
|
}], propDecorators: { form: [{ type: i0.Input, args: [{ isSignal: true, alias: "form", required: false }] }], noSave: [{ type: i0.Input, args: [{ isSignal: true, alias: "noSave", required: false }] }], closeRequest: [{ type: i0.Output, args: ["closeRequest"] }] } });
|
|
@@ -80,10 +67,10 @@ class DecoratedTokenTextComponent {
|
|
|
80
67
|
decorate(text, locations, selectedLocation) {
|
|
81
68
|
this.text.set(this._textLayerService.render(text, locations, selectedLocation));
|
|
82
69
|
}
|
|
83
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
84
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "
|
|
70
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: DecoratedTokenTextComponent, deps: [{ token: i1.TextLayerService }], target: i0.ɵɵFactoryTarget.Component });
|
|
71
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.1.0", 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" }] });
|
|
85
72
|
}
|
|
86
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
73
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: DecoratedTokenTextComponent, decorators: [{
|
|
87
74
|
type: Component,
|
|
88
75
|
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"] }]
|
|
89
76
|
}], ctorParameters: () => [{ type: i1.TextLayerService }], propDecorators: { _textElement: [{
|
|
@@ -93,10 +80,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.7", ngImpor
|
|
|
93
80
|
|
|
94
81
|
class ErrorListComponent {
|
|
95
82
|
errors = input(...(ngDevMode ? [undefined, { debugName: "errors" }] : []));
|
|
96
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
97
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "
|
|
83
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: ErrorListComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
84
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.0", 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"] });
|
|
98
85
|
}
|
|
99
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
86
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: ErrorListComponent, decorators: [{
|
|
100
87
|
type: Component,
|
|
101
88
|
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"] }]
|
|
102
89
|
}], propDecorators: { errors: [{ type: i0.Input, args: [{ isSignal: true, alias: "errors", required: false }] }] } });
|
|
@@ -244,10 +231,10 @@ class ColorService {
|
|
|
244
231
|
const rgb = this.hslToRgb(h, s, l);
|
|
245
232
|
return this.rgbToString(rgb.r, rgb.g, rgb.b);
|
|
246
233
|
}
|
|
247
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
248
|
-
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "
|
|
234
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: ColorService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
235
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: ColorService, providedIn: 'root' });
|
|
249
236
|
}
|
|
250
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
237
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: ColorService, decorators: [{
|
|
251
238
|
type: Injectable,
|
|
252
239
|
args: [{
|
|
253
240
|
providedIn: 'root',
|
|
@@ -328,10 +315,10 @@ class FacetBadgeComponent {
|
|
|
328
315
|
this.contrastColor.set(this._colorService.getContrastColor(this.color()));
|
|
329
316
|
this.tip.set(this.getFacetTip(data?.facetId || '') ?? undefined);
|
|
330
317
|
}
|
|
331
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
332
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "
|
|
318
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: FacetBadgeComponent, deps: [{ token: ColorService }], target: i0.ɵɵFactoryTarget.Component });
|
|
319
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.1.0", 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"] }] });
|
|
333
320
|
}
|
|
334
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
321
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: FacetBadgeComponent, decorators: [{
|
|
335
322
|
type: Component,
|
|
336
323
|
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"] }]
|
|
337
324
|
}], ctorParameters: () => [{ type: ColorService }], propDecorators: { data: [{ type: i0.Input, args: [{ isSignal: true, alias: "data", required: false }] }] } });
|
|
@@ -357,10 +344,10 @@ class FlagsBadgeComponent {
|
|
|
357
344
|
return def.id & data.flags;
|
|
358
345
|
}));
|
|
359
346
|
}
|
|
360
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
361
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "
|
|
347
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: FlagsBadgeComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
348
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.0", type: FlagsBadgeComponent, isStandalone: true, selector: "cadmus-flags-badge", inputs: { data: { classPropertyName: "data", publicName: "data", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "<div>\r\n @for (def of badgeFlags(); track def.id) {\r\n <span\r\n class=\"badge-flag\"\r\n [style.color]=\"'#' + def.colorKey\"\r\n [matTooltip]=\"def.label\"\r\n >\r\n @if (def.isAdmin) { ◆ } @else { ⬤ }\r\n </span>\r\n }\r\n</div>\r\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"] }] });
|
|
362
349
|
}
|
|
363
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
350
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: FlagsBadgeComponent, decorators: [{
|
|
364
351
|
type: Component,
|
|
365
352
|
args: [{ selector: 'cadmus-flags-badge', imports: [MatTooltip], template: "<div>\r\n @for (def of badgeFlags(); track def.id) {\r\n <span\r\n class=\"badge-flag\"\r\n [style.color]=\"'#' + def.colorKey\"\r\n [matTooltip]=\"def.label\"\r\n >\r\n @if (def.isAdmin) { ◆ } @else { ⬤ }\r\n </span>\r\n }\r\n</div>\r\n", styles: ["span.badge-flag{font-size:1rem;cursor:default}\n"] }]
|
|
366
353
|
}], ctorParameters: () => [], propDecorators: { data: [{ type: i0.Input, args: [{ isSignal: true, alias: "data", required: false }] }] } });
|
|
@@ -437,10 +424,10 @@ class LayerHintsComponent {
|
|
|
437
424
|
}
|
|
438
425
|
});
|
|
439
426
|
}
|
|
440
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
441
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "
|
|
427
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: LayerHintsComponent, deps: [{ token: i1$1.FormBuilder }, { token: i2.DialogService }], target: i0.ɵɵFactoryTarget.Component });
|
|
428
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.0", 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) {\r\n<form [formGroup]=\"form\" (submit)=\"emitRequestPatch()\">\r\n <table class=\"patches\">\r\n <thead>\r\n <tr>\r\n <th></th>\r\n <th>location</th>\r\n <th>description</th>\r\n <th>patch</th>\r\n </tr>\r\n </thead>\r\n <tbody>\r\n @for (hint of hints(); track hint; let i = $index) {\r\n <tr>\r\n @if (!readonly()) {\r\n <td>\r\n <button\r\n type=\"button\"\r\n mat-icon-button\r\n matTooltip=\"Edit this fragment\"\r\n [disabled]=\"disabled()\"\r\n >\r\n <mat-icon>edit</mat-icon>\r\n </button>\r\n <button\r\n type=\"button\"\r\n mat-icon-button\r\n matTooltip=\"Move this fragment to {{ targetLocation() }}\"\r\n [disabled]=\"\r\n disabled() ||\r\n !targetLocation() ||\r\n targetLocation() === hint.location\r\n \"\r\n (click)=\"emitRequestMove(hint)\"\r\n >\r\n <mat-icon>arrow_forward</mat-icon>\r\n </button>\r\n <button\r\n type=\"button\"\r\n mat-icon-button\r\n matTooltip=\"Delete this fragment\"\r\n [disabled]=\"disabled()\"\r\n (click)=\"emitRequestDelete(hint)\"\r\n >\r\n <mat-icon class=\"mat-warn\">delete</mat-icon>\r\n </button>\r\n </td>\r\n }\r\n <td>{{ hint.location }}</td>\r\n <td>{{ hint.description }}</td>\r\n <td>\r\n @if (hint.patchOperation) {\r\n <mat-checkbox\r\n matTooltip=\"Apply this patch\"\r\n [formControl]=\"checks.at(i)\"\r\n >\r\n {{ hint.patchOperation }}\r\n </mat-checkbox>\r\n }\r\n </td>\r\n </tr>\r\n }\r\n </tbody>\r\n </table>\r\n @if (targetLocation()) {\r\n <div>move target: {{ targetLocation() }}</div>\r\n }\r\n <button\r\n type=\"submit\"\r\n mat-flat-button\r\n [disabled]=\"readonly() || disabled() || form.invalid\"\r\n >\r\n apply patches\r\n </button>\r\n</form>\r\n}\r\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.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],[formArray],form:not([ngNoForm]),[ngForm]" }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$1.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "component", type: MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { 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[matButton], a[matButton], button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button], a[mat-button], a[mat-raised-button], a[mat-flat-button], a[mat-stroked-button] ", inputs: ["matButton"], exportAs: ["matButton", "matAnchor"] }] });
|
|
442
429
|
}
|
|
443
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
430
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: LayerHintsComponent, decorators: [{
|
|
444
431
|
type: Component,
|
|
445
432
|
args: [{ selector: 'cadmus-layer-hints', imports: [
|
|
446
433
|
FormsModule,
|
|
@@ -577,10 +564,10 @@ class LookupPinComponent {
|
|
|
577
564
|
this.clear();
|
|
578
565
|
}
|
|
579
566
|
}
|
|
580
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
581
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "
|
|
567
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: LookupPinComponent, deps: [{ token: i1$1.UntypedFormBuilder }, { token: i1$2.ItemService }, { token: 'indexLookupDefinitions' }], target: i0.ɵɵFactoryTarget.Component });
|
|
568
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.0", 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\">\r\n <mat-autocomplete #lookupAuto=\"matAutocomplete\" [displayWith]=\"entryToName\">\r\n @for (entry of entries$ | async; track entry) {\r\n <mat-option [value]=\"entry\" (onSelectionChange)=\"pickEntry(entry)\">\r\n {{ entry?.value }}\r\n </mat-option>\r\n }\r\n </mat-autocomplete>\r\n\r\n <mat-form-field>\r\n <input\r\n matInput\r\n type=\"text\"\r\n [placeholder]=\"label()\"\r\n [formControl]=\"lookup\"\r\n [matAutocomplete]=\"lookupAuto\"\r\n />\r\n </mat-form-field>\r\n <button\r\n type=\"button\"\r\n mat-icon-button\r\n (click)=\"clear()\"\r\n [disabled]=\"!entry()\"\r\n matTooltip=\"Clear\"\r\n >\r\n <mat-icon class=\"mat-warn\">clear</mat-icon>\r\n </button>\r\n</form>\r\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],[formArray],form:not([ngNoForm]),[ngForm]" }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$1.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "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], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { 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" }] });
|
|
582
569
|
}
|
|
583
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
570
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: LookupPinComponent, decorators: [{
|
|
584
571
|
type: Component,
|
|
585
572
|
args: [{ selector: 'cadmus-lookup-pin', imports: [
|
|
586
573
|
FormsModule,
|
|
@@ -600,630 +587,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.7", ngImpor
|
|
|
600
587
|
args: ['indexLookupDefinitions']
|
|
601
588
|
}] }], propDecorators: { initialValue: [{ type: i0.Input, args: [{ isSignal: true, alias: "initialValue", required: false }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], limit: [{ type: i0.Input, args: [{ isSignal: true, alias: "limit", required: false }] }], resetOnPick: [{ type: i0.Input, args: [{ isSignal: true, alias: "resetOnPick", required: false }] }], entryChange: [{ type: i0.Output, args: ["entryChange"] }], lookupKey: [{ type: i0.Input, args: [{ isSignal: true, alias: "lookupKey", required: false }] }] } });
|
|
602
589
|
|
|
603
|
-
/**
|
|
604
|
-
* A label rendering function which removes from a label
|
|
605
|
-
* all the characters past the last colon, trimming the result.
|
|
606
|
-
* This is a typical rendering when dealing with hierarchical
|
|
607
|
-
* thesaurus entries, e.g. "furniture: table: color", where
|
|
608
|
-
* we can shorten the label to just "color", as "furniture"
|
|
609
|
-
* and "table" are its ancestors.
|
|
610
|
-
*/
|
|
611
|
-
const renderLabelFromLastColon = (label) => {
|
|
612
|
-
if (!label) {
|
|
613
|
-
return label;
|
|
614
|
-
}
|
|
615
|
-
const i = label.lastIndexOf(':');
|
|
616
|
-
return i > -1 && i + 1 < label.length ? label.substring(i + 1).trim() : label;
|
|
617
|
-
};
|
|
618
|
-
/**
|
|
619
|
-
* A static paged tree store service for thesaurus entries.
|
|
620
|
-
* This builds the tree nodes from the thesaurus entries, assuming
|
|
621
|
-
* that entry IDs are hierarchical and separated by dots (.).
|
|
622
|
-
*/
|
|
623
|
-
class StaticThesPagedTreeStoreService {
|
|
624
|
-
_renderLabel;
|
|
625
|
-
_nodes = [];
|
|
626
|
-
_built = false;
|
|
627
|
-
_entries;
|
|
628
|
-
constructor(entries, _renderLabel) {
|
|
629
|
-
this._renderLabel = _renderLabel;
|
|
630
|
-
// assign a number to each entry for stable IDs
|
|
631
|
-
this._entries = entries.map((entry, index) => ({
|
|
632
|
-
...entry,
|
|
633
|
-
n: index + 1,
|
|
634
|
-
}));
|
|
635
|
-
}
|
|
636
|
-
ensureNodes() {
|
|
637
|
-
// lazily build the nodes only once
|
|
638
|
-
if (this._built) {
|
|
639
|
-
return;
|
|
640
|
-
}
|
|
641
|
-
// map where key is node.id and value is max x value for that parent
|
|
642
|
-
// (0 is used for the virtual root)
|
|
643
|
-
const xMap = new Map();
|
|
644
|
-
for (const entry of this._entries) {
|
|
645
|
-
const hasDot = entry.id.includes('.');
|
|
646
|
-
const keyParts = entry.id.split('.');
|
|
647
|
-
// create the node
|
|
648
|
-
const node = {
|
|
649
|
-
id: entry.n,
|
|
650
|
-
label: hasDot && this._renderLabel
|
|
651
|
-
? this._renderLabel(entry.value)
|
|
652
|
-
: entry.value,
|
|
653
|
-
key: entry.id,
|
|
654
|
-
value: entry.value,
|
|
655
|
-
paging: { pageNumber: 0, pageCount: 0, total: 0 },
|
|
656
|
-
y: hasDot ? keyParts.length : 1,
|
|
657
|
-
x: 0, // will be set later
|
|
658
|
-
parentId: undefined, // will be set later
|
|
659
|
-
hasChildren: false, // will be set later
|
|
660
|
-
};
|
|
661
|
-
// if it has a dot, find its parent and set parentId
|
|
662
|
-
if (hasDot) {
|
|
663
|
-
// build the parent key
|
|
664
|
-
const parentKey = keyParts.slice(0, keyParts.length - 1).join('.');
|
|
665
|
-
// find the parent node with that key
|
|
666
|
-
const parentNode = this._nodes.find((n) => n.key === parentKey);
|
|
667
|
-
// if found, set parentId and x in child and hasChildren in parent
|
|
668
|
-
if (parentNode) {
|
|
669
|
-
node.parentId = parentNode.id;
|
|
670
|
-
parentNode.hasChildren = true;
|
|
671
|
-
if (xMap.has(parentNode.id)) {
|
|
672
|
-
xMap.set(parentNode.id, xMap.get(parentNode.id) + 1);
|
|
673
|
-
}
|
|
674
|
-
else {
|
|
675
|
-
xMap.set(parentNode.id, 1);
|
|
676
|
-
}
|
|
677
|
-
node.x = xMap.get(parentNode.id);
|
|
678
|
-
}
|
|
679
|
-
else {
|
|
680
|
-
// parent not found, treat as root
|
|
681
|
-
if (xMap.has(0)) {
|
|
682
|
-
xMap.set(0, xMap.get(0) + 1);
|
|
683
|
-
}
|
|
684
|
-
else {
|
|
685
|
-
xMap.set(0, 1);
|
|
686
|
-
}
|
|
687
|
-
node.x = xMap.get(0);
|
|
688
|
-
}
|
|
689
|
-
}
|
|
690
|
-
else {
|
|
691
|
-
// else it's a root node
|
|
692
|
-
if (xMap.has(0)) {
|
|
693
|
-
xMap.set(0, xMap.get(0) + 1);
|
|
694
|
-
}
|
|
695
|
-
else {
|
|
696
|
-
xMap.set(0, 1);
|
|
697
|
-
}
|
|
698
|
-
node.x = xMap.get(0);
|
|
699
|
-
}
|
|
700
|
-
this._nodes.push(node);
|
|
701
|
-
}
|
|
702
|
-
this._built = true;
|
|
703
|
-
}
|
|
704
|
-
/**
|
|
705
|
-
* Get the specified page of nodes.
|
|
706
|
-
* @param filter The filter.
|
|
707
|
-
* @param pageNumber The page number.
|
|
708
|
-
* @param pageSize The page size.
|
|
709
|
-
* @param hasMockRoot Whether the root node is a mock node. Not used here.
|
|
710
|
-
*/
|
|
711
|
-
getNodes(filter, pageNumber, pageSize, hasMockRoot) {
|
|
712
|
-
this.ensureNodes();
|
|
713
|
-
// apply filtering
|
|
714
|
-
let nodes = this._nodes.filter((n) => {
|
|
715
|
-
if (filter.parentId !== undefined && filter.parentId !== null) {
|
|
716
|
-
if (n.parentId !== filter.parentId) {
|
|
717
|
-
return false;
|
|
718
|
-
}
|
|
719
|
-
}
|
|
720
|
-
else {
|
|
721
|
-
if (n.parentId) {
|
|
722
|
-
return false;
|
|
723
|
-
}
|
|
724
|
-
}
|
|
725
|
-
if (filter.label) {
|
|
726
|
-
const filterValue = filter.label.toLowerCase();
|
|
727
|
-
if (!n.label.toLowerCase().includes(filterValue)) {
|
|
728
|
-
return false;
|
|
729
|
-
}
|
|
730
|
-
}
|
|
731
|
-
return true;
|
|
732
|
-
});
|
|
733
|
-
// apply paging
|
|
734
|
-
const startIndex = (pageNumber - 1) * pageSize;
|
|
735
|
-
const endIndex = startIndex + pageSize;
|
|
736
|
-
const pagedNodes = nodes.slice(startIndex, endIndex);
|
|
737
|
-
// page and return
|
|
738
|
-
const paged = nodes.slice((pageNumber - 1) * pageSize, pageNumber * pageSize);
|
|
739
|
-
return of({
|
|
740
|
-
items: paged,
|
|
741
|
-
pageNumber: pageNumber,
|
|
742
|
-
pageSize: pageSize,
|
|
743
|
-
pageCount: Math.ceil(nodes.length / pageSize),
|
|
744
|
-
total: nodes.length,
|
|
745
|
-
});
|
|
746
|
-
}
|
|
747
|
-
}
|
|
748
|
-
|
|
749
|
-
/**
|
|
750
|
-
* A filter to be used for thesaurus paged tree browsers.
|
|
751
|
-
*/
|
|
752
|
-
class ThesPagedTreeFilterComponent {
|
|
753
|
-
dialogRef = inject(MatDialogRef, {
|
|
754
|
-
optional: true,
|
|
755
|
-
});
|
|
756
|
-
data = inject(MAT_DIALOG_DATA, { optional: true });
|
|
757
|
-
/**
|
|
758
|
-
* The filter.
|
|
759
|
-
*/
|
|
760
|
-
filter = model(...(ngDevMode ? [undefined, { debugName: "filter" }] : []));
|
|
761
|
-
wrapped = signal(false, ...(ngDevMode ? [{ debugName: "wrapped" }] : []));
|
|
762
|
-
label;
|
|
763
|
-
form;
|
|
764
|
-
constructor() {
|
|
765
|
-
const formBuilder = inject(FormBuilder);
|
|
766
|
-
const data = this.data;
|
|
767
|
-
// form
|
|
768
|
-
this.label = formBuilder.control(null);
|
|
769
|
-
this.form = formBuilder.group({
|
|
770
|
-
label: this.label,
|
|
771
|
-
});
|
|
772
|
-
// bind dialog data if any
|
|
773
|
-
if (this.dialogRef) {
|
|
774
|
-
this.wrapped.set(true);
|
|
775
|
-
if (data) {
|
|
776
|
-
this.filter.set(data.filter);
|
|
777
|
-
}
|
|
778
|
-
}
|
|
779
|
-
else {
|
|
780
|
-
this.wrapped.set(false);
|
|
781
|
-
}
|
|
782
|
-
// update form when filter changes
|
|
783
|
-
effect(() => {
|
|
784
|
-
this.updateForm(this.filter());
|
|
785
|
-
});
|
|
786
|
-
}
|
|
787
|
-
ngOnInit() {
|
|
788
|
-
this.updateForm(this.filter());
|
|
789
|
-
}
|
|
790
|
-
updateForm(filter) {
|
|
791
|
-
if (!filter) {
|
|
792
|
-
this.form.reset();
|
|
793
|
-
return;
|
|
794
|
-
}
|
|
795
|
-
this.label.setValue(filter.label ?? null);
|
|
796
|
-
this.form.markAsPristine();
|
|
797
|
-
}
|
|
798
|
-
getFilter() {
|
|
799
|
-
return {
|
|
800
|
-
label: this.label.value ?? undefined,
|
|
801
|
-
};
|
|
802
|
-
}
|
|
803
|
-
reset() {
|
|
804
|
-
this.form.reset();
|
|
805
|
-
this.filter.set(null);
|
|
806
|
-
this.dialogRef?.close(null);
|
|
807
|
-
}
|
|
808
|
-
apply() {
|
|
809
|
-
this.filter.set(this.getFilter());
|
|
810
|
-
this.dialogRef?.close(this.filter());
|
|
811
|
-
}
|
|
812
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.7", ngImport: i0, type: ThesPagedTreeFilterComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
813
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "20.3.7", type: ThesPagedTreeFilterComponent, isStandalone: true, selector: "cadmus-thes-paged-tree-filter", inputs: { filter: { classPropertyName: "filter", publicName: "filter", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { filter: "filterChange" }, ngImport: i0, template: "<form\r\n [formGroup]=\"form\"\r\n [style.margin.px]=\"wrapped() ? 16 : 0\"\r\n (submit)=\"apply()\"\r\n>\r\n <div class=\"form-row\">\r\n <!-- label -->\r\n <mat-form-field>\r\n <input matInput placeholder=\"label\" [formControl]=\"label\" />\r\n </mat-form-field>\r\n </div>\r\n\r\n <div class=\"form-row\">\r\n <!-- buttons -->\r\n <button type=\"button\" mat-icon-button matTooltip=\"Reset\" (click)=\"reset()\">\r\n <mat-icon class=\"mat-warn\">clear</mat-icon>\r\n </button>\r\n <button\r\n type=\"submit\"\r\n mat-icon-button\r\n matTooltip=\"Apply\"\r\n [disabled]=\"form.invalid\"\r\n >\r\n <mat-icon class=\"mat-primary\">check_circle</mat-icon>\r\n </button>\r\n </div>\r\n</form>\r\n", styles: ["form{margin:16px}.form-row{display:flex;gap:8px;align-items:center;flex-wrap:wrap}.form-row *{flex:0 0 auto}.nr{width:6em}fieldset{border:1px solid silver;border-radius:6px;padding:8px 16px;margin:8px 0}legend{color:silver}th{text-align:left;font-weight:400}#tag-selector{width:8em}.tag-chip{border:2px solid transparent;border-radius:6px}\n"], dependencies: [{ kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1$1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$1.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i2$1.MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "component", type: i4.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i4$1.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly", "disabledInteractive"], exportAs: ["matInput"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i5.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i6.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }] });
|
|
814
|
-
}
|
|
815
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.7", ngImport: i0, type: ThesPagedTreeFilterComponent, decorators: [{
|
|
816
|
-
type: Component,
|
|
817
|
-
args: [{ selector: 'cadmus-thes-paged-tree-filter', imports: [
|
|
818
|
-
ReactiveFormsModule,
|
|
819
|
-
MatButtonModule,
|
|
820
|
-
MatFormFieldModule,
|
|
821
|
-
MatInputModule,
|
|
822
|
-
MatIconModule,
|
|
823
|
-
MatTooltipModule,
|
|
824
|
-
], template: "<form\r\n [formGroup]=\"form\"\r\n [style.margin.px]=\"wrapped() ? 16 : 0\"\r\n (submit)=\"apply()\"\r\n>\r\n <div class=\"form-row\">\r\n <!-- label -->\r\n <mat-form-field>\r\n <input matInput placeholder=\"label\" [formControl]=\"label\" />\r\n </mat-form-field>\r\n </div>\r\n\r\n <div class=\"form-row\">\r\n <!-- buttons -->\r\n <button type=\"button\" mat-icon-button matTooltip=\"Reset\" (click)=\"reset()\">\r\n <mat-icon class=\"mat-warn\">clear</mat-icon>\r\n </button>\r\n <button\r\n type=\"submit\"\r\n mat-icon-button\r\n matTooltip=\"Apply\"\r\n [disabled]=\"form.invalid\"\r\n >\r\n <mat-icon class=\"mat-primary\">check_circle</mat-icon>\r\n </button>\r\n </div>\r\n</form>\r\n", styles: ["form{margin:16px}.form-row{display:flex;gap:8px;align-items:center;flex-wrap:wrap}.form-row *{flex:0 0 auto}.nr{width:6em}fieldset{border:1px solid silver;border-radius:6px;padding:8px 16px;margin:8px 0}legend{color:silver}th{text-align:left;font-weight:400}#tag-selector{width:8em}.tag-chip{border:2px solid transparent;border-radius:6px}\n"] }]
|
|
825
|
-
}], ctorParameters: () => [], propDecorators: { filter: [{ type: i0.Input, args: [{ isSignal: true, alias: "filter", required: false }] }, { type: i0.Output, args: ["filterChange"] }] } });
|
|
826
|
-
|
|
827
|
-
class ThesPagedTreeBrowserComponent {
|
|
828
|
-
_dialog = inject(MatDialog);
|
|
829
|
-
_sub;
|
|
830
|
-
/**
|
|
831
|
-
* The service to use to load the nodes.
|
|
832
|
-
*/
|
|
833
|
-
service = input(new StaticThesPagedTreeStoreService([], renderLabelFromLastColon), ...(ngDevMode ? [{ debugName: "service" }] : []));
|
|
834
|
-
/**
|
|
835
|
-
* Emitted when a node is clicked.
|
|
836
|
-
*/
|
|
837
|
-
nodePick = output();
|
|
838
|
-
/**
|
|
839
|
-
* The store instance, built from the service.
|
|
840
|
-
*/
|
|
841
|
-
store = computed(() => {
|
|
842
|
-
const service = this.service();
|
|
843
|
-
const store = new PagedTreeStore(service);
|
|
844
|
-
this.nodes$ = store.nodes$;
|
|
845
|
-
this.filter$ = store.filter$;
|
|
846
|
-
return store;
|
|
847
|
-
}, ...(ngDevMode ? [{ debugName: "store" }] : []));
|
|
848
|
-
loading = signal(false, ...(ngDevMode ? [{ debugName: "loading" }] : []));
|
|
849
|
-
debug = new FormControl(false, {
|
|
850
|
-
nonNullable: true,
|
|
851
|
-
});
|
|
852
|
-
hideLoc = new FormControl(false, {
|
|
853
|
-
nonNullable: true,
|
|
854
|
-
});
|
|
855
|
-
hideFilter = new FormControl(false, {
|
|
856
|
-
nonNullable: true,
|
|
857
|
-
});
|
|
858
|
-
filter$;
|
|
859
|
-
nodes$;
|
|
860
|
-
label = new FormControl(null);
|
|
861
|
-
form = new FormGroup({
|
|
862
|
-
label: this.label,
|
|
863
|
-
});
|
|
864
|
-
constructor() {
|
|
865
|
-
const store = this.store();
|
|
866
|
-
this.nodes$ = store.nodes$;
|
|
867
|
-
this.filter$ = store.filter$;
|
|
868
|
-
}
|
|
869
|
-
ngOnInit() {
|
|
870
|
-
if (!this.store().getNodes().length) {
|
|
871
|
-
this.loading.set(true);
|
|
872
|
-
this.store()
|
|
873
|
-
.setFilter({})
|
|
874
|
-
.finally(() => {
|
|
875
|
-
this.loading.set(false);
|
|
876
|
-
console.log('nodes loaded', this.store().getNodes());
|
|
877
|
-
});
|
|
878
|
-
}
|
|
879
|
-
}
|
|
880
|
-
ngOnDestroy() {
|
|
881
|
-
this._sub?.unsubscribe();
|
|
882
|
-
}
|
|
883
|
-
reset() {
|
|
884
|
-
this.loading.set(true);
|
|
885
|
-
this.store()
|
|
886
|
-
.reset()
|
|
887
|
-
.finally(() => {
|
|
888
|
-
this.loading.set(false);
|
|
889
|
-
});
|
|
890
|
-
}
|
|
891
|
-
onToggleExpanded(node) {
|
|
892
|
-
this.loading.set(true);
|
|
893
|
-
if (node.expanded) {
|
|
894
|
-
this.store()
|
|
895
|
-
.collapse(node.id)
|
|
896
|
-
.finally(() => {
|
|
897
|
-
this.loading.set(false);
|
|
898
|
-
});
|
|
899
|
-
}
|
|
900
|
-
else {
|
|
901
|
-
this.store()
|
|
902
|
-
.expand(node.id)
|
|
903
|
-
.finally(() => {
|
|
904
|
-
this.loading.set(false);
|
|
905
|
-
});
|
|
906
|
-
}
|
|
907
|
-
}
|
|
908
|
-
onPageChangeRequest(request) {
|
|
909
|
-
this.loading.set(true);
|
|
910
|
-
this.store()
|
|
911
|
-
.changePage(request.node.id, request.paging.pageNumber)
|
|
912
|
-
.finally(() => {
|
|
913
|
-
this.loading.set(false);
|
|
914
|
-
});
|
|
915
|
-
}
|
|
916
|
-
onFilterChange(filter) {
|
|
917
|
-
console.log('filter change', filter);
|
|
918
|
-
this.loading.set(true);
|
|
919
|
-
this.store()
|
|
920
|
-
.setFilter(filter || {})
|
|
921
|
-
.finally(() => {
|
|
922
|
-
this.loading.set(false);
|
|
923
|
-
});
|
|
924
|
-
}
|
|
925
|
-
onEditFilterRequest(node) {
|
|
926
|
-
const dialogRef = this._dialog.open(ThesPagedTreeFilterComponent, {
|
|
927
|
-
data: {
|
|
928
|
-
filter: node.filter,
|
|
929
|
-
},
|
|
930
|
-
});
|
|
931
|
-
dialogRef.afterClosed().subscribe((filter) => {
|
|
932
|
-
// undefined = user dismissed without changes
|
|
933
|
-
if (filter === null) {
|
|
934
|
-
this.store().setNodeFilter(node.id, null);
|
|
935
|
-
}
|
|
936
|
-
else if (filter) {
|
|
937
|
-
this.store().setNodeFilter(node.id, filter);
|
|
938
|
-
}
|
|
939
|
-
});
|
|
940
|
-
}
|
|
941
|
-
expandAll() {
|
|
942
|
-
this.store().expandAll();
|
|
943
|
-
}
|
|
944
|
-
collapseAll() {
|
|
945
|
-
this.store().collapseAll();
|
|
946
|
-
}
|
|
947
|
-
clear() {
|
|
948
|
-
this.store().clear();
|
|
949
|
-
}
|
|
950
|
-
onNodeClick(node) {
|
|
951
|
-
if (!node.hasChildren) {
|
|
952
|
-
this.nodePick.emit(node);
|
|
953
|
-
}
|
|
954
|
-
}
|
|
955
|
-
findLabels() {
|
|
956
|
-
if (!this.label.value) {
|
|
957
|
-
return;
|
|
958
|
-
}
|
|
959
|
-
this.store().findLabels(this.label.value);
|
|
960
|
-
}
|
|
961
|
-
removeHilites() {
|
|
962
|
-
this.store().removeHilites();
|
|
963
|
-
}
|
|
964
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.7", ngImport: i0, type: ThesPagedTreeBrowserComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
965
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.7", type: ThesPagedTreeBrowserComponent, isStandalone: true, selector: "cadmus-thes-paged-tree-browser", inputs: { service: { classPropertyName: "service", publicName: "service", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { nodePick: "nodePick" }, ngImport: i0, template: "<div id=\"container\">\r\n <!-- filters -->\r\n <div id=\"filters\" class=\"form-row\">\r\n <form [formGroup]=\"form\" (submit)=\"findLabels()\" class=\"form-row\">\r\n <mat-form-field>\r\n <mat-label>label</mat-label>\r\n <input matInput [formControl]=\"label\" />\r\n @if ($any(label).errors?.required && (label.dirty || label.touched)) {\r\n <mat-error>label required</mat-error>\r\n }\r\n </mat-form-field>\r\n <button type=\"submit\" mat-icon-button class=\"mat-primary\">\r\n <mat-icon>search</mat-icon>\r\n </button>\r\n <button type=\"button\" mat-icon-button (click)=\"removeHilites()\">\r\n <mat-icon class=\"mat-warn\">clear</mat-icon>\r\n </button>\r\n </form>\r\n <fieldset>\r\n <legend>filter</legend>\r\n <cadmus-thes-paged-tree-filter\r\n [filter]=\"filter$ | async\"\r\n (filterChange)=\"onFilterChange($event)\"\r\n />\r\n </fieldset>\r\n </div>\r\n\r\n <!-- tree -->\r\n <div id=\"tree\">\r\n <!-- progress -->\r\n @if (loading()) {\r\n <div>\r\n <mat-progress-bar mode=\"indeterminate\"></mat-progress-bar>\r\n </div>\r\n }\r\n <!-- nodes -->\r\n @if (nodes$ | async; as nodes) {\r\n <div>\r\n @for (node of nodes; track node.id; let i = $index) {\r\n <div class=\"button-row\" [class.hilite]=\"node.hilite\">\r\n <pdb-browser-tree-node\r\n [node]=\"node\"\r\n [debug]=\"debug.value\"\r\n [paging]=\"\r\n node.expanded &&\r\n i + 1 < nodes.length &&\r\n nodes[i + 1].paging.pageCount > 1\r\n ? nodes[i + 1].paging\r\n : undefined\r\n \"\r\n [hideFilter]=\"hideFilter.value\"\r\n [hideLoc]=\"hideLoc.value\"\r\n (toggleExpandedRequest)=\"onToggleExpanded($any($event))\"\r\n (changePageRequest)=\"onPageChangeRequest($event)\"\r\n (editNodeFilterRequest)=\"onEditFilterRequest($any($event))\"\r\n />\r\n @if (!node.hasChildren) {\r\n <button type=\"button\" mat-icon-button (click)=\"onNodeClick(node)\">\r\n <mat-icon class=\"mat-primary\">check_circle</mat-icon>\r\n </button>\r\n }\r\n </div>\r\n }\r\n </div>\r\n }\r\n <div class=\"form-row\">\r\n <mat-checkbox [formControl]=\"debug\">debug</mat-checkbox>\r\n <mat-checkbox [formControl]=\"hideFilter\">no filter</mat-checkbox>\r\n <mat-checkbox [formControl]=\"hideLoc\">no loc.</mat-checkbox>\r\n <button\r\n type=\"button\"\r\n mat-flat-button\r\n (click)=\"collapseAll()\"\r\n style=\"margin-left: 24px\"\r\n >\r\n collapse\r\n </button>\r\n </div>\r\n </div>\r\n</div>\r\n", styles: ["form{margin:16px}.form-row{display:flex;gap:8px;align-items:center;flex-wrap:wrap}.form-row *{flex:0 0 auto}.nr{width:6em}fieldset{border:1px solid silver;border-radius:6px;padding:8px 16px;margin:8px 0}legend{color:silver}th{text-align:left;font-weight:400}#tag-selector{width:8em}.tag-chip{border:2px solid transparent;border-radius:6px}.button-row{display:flex;align-items:center;flex-wrap:wrap}.button-row *{flex:0 0 auto}.hilite{background-color:#ffffe0;border:2px solid gold;border-radius:6px;padding:2px 4px}\n"], dependencies: [{ kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1$1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$1.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i2$1.MatButton, selector: " button[matButton], a[matButton], button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button], a[mat-button], a[mat-raised-button], a[mat-flat-button], a[mat-stroked-button] ", inputs: ["matButton"], exportAs: ["matButton", "matAnchor"] }, { kind: "component", type: i2$1.MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "ngmodule", type: MatCheckboxModule }, { kind: "component", type: i3.MatCheckbox, selector: "mat-checkbox", inputs: ["aria-label", "aria-labelledby", "aria-describedby", "aria-expanded", "aria-controls", "aria-owns", "id", "required", "labelPosition", "name", "value", "disableRipple", "tabIndex", "color", "disabledInteractive", "checked", "disabled", "indeterminate"], outputs: ["change", "indeterminateChange"], exportAs: ["matCheckbox"] }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "component", type: i4.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i4.MatLabel, selector: "mat-label" }, { kind: "directive", type: i4.MatError, selector: "mat-error, [matError]", inputs: ["id"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i5.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i4$1.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly", "disabledInteractive"], exportAs: ["matInput"] }, { kind: "ngmodule", type: MatProgressBarModule }, { kind: "component", type: i7.MatProgressBar, selector: "mat-progress-bar", inputs: ["color", "value", "bufferValue", "mode"], outputs: ["animationEnd"], exportAs: ["matProgressBar"] }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "component", type: ThesPagedTreeFilterComponent, selector: "cadmus-thes-paged-tree-filter", inputs: ["filter"], outputs: ["filterChange"] }, { kind: "component", type: BrowserTreeNodeComponent, selector: "pdb-browser-tree-node", inputs: ["node", "paging", "debug", "hideLabel", "hideLoc", "hidePaging", "hideFilter", "indentSize", "rangeWidth"], outputs: ["toggleExpandedRequest", "changePageRequest", "editNodeFilterRequest"] }, { kind: "pipe", type: AsyncPipe, name: "async" }] });
|
|
966
|
-
}
|
|
967
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.7", ngImport: i0, type: ThesPagedTreeBrowserComponent, decorators: [{
|
|
968
|
-
type: Component,
|
|
969
|
-
args: [{ selector: 'cadmus-thes-paged-tree-browser', imports: [
|
|
970
|
-
AsyncPipe,
|
|
971
|
-
ReactiveFormsModule,
|
|
972
|
-
MatButtonModule,
|
|
973
|
-
MatCheckboxModule,
|
|
974
|
-
MatFormFieldModule,
|
|
975
|
-
MatIconModule,
|
|
976
|
-
MatInputModule,
|
|
977
|
-
MatProgressBarModule,
|
|
978
|
-
MatTooltipModule,
|
|
979
|
-
ThesPagedTreeFilterComponent,
|
|
980
|
-
BrowserTreeNodeComponent,
|
|
981
|
-
], template: "<div id=\"container\">\r\n <!-- filters -->\r\n <div id=\"filters\" class=\"form-row\">\r\n <form [formGroup]=\"form\" (submit)=\"findLabels()\" class=\"form-row\">\r\n <mat-form-field>\r\n <mat-label>label</mat-label>\r\n <input matInput [formControl]=\"label\" />\r\n @if ($any(label).errors?.required && (label.dirty || label.touched)) {\r\n <mat-error>label required</mat-error>\r\n }\r\n </mat-form-field>\r\n <button type=\"submit\" mat-icon-button class=\"mat-primary\">\r\n <mat-icon>search</mat-icon>\r\n </button>\r\n <button type=\"button\" mat-icon-button (click)=\"removeHilites()\">\r\n <mat-icon class=\"mat-warn\">clear</mat-icon>\r\n </button>\r\n </form>\r\n <fieldset>\r\n <legend>filter</legend>\r\n <cadmus-thes-paged-tree-filter\r\n [filter]=\"filter$ | async\"\r\n (filterChange)=\"onFilterChange($event)\"\r\n />\r\n </fieldset>\r\n </div>\r\n\r\n <!-- tree -->\r\n <div id=\"tree\">\r\n <!-- progress -->\r\n @if (loading()) {\r\n <div>\r\n <mat-progress-bar mode=\"indeterminate\"></mat-progress-bar>\r\n </div>\r\n }\r\n <!-- nodes -->\r\n @if (nodes$ | async; as nodes) {\r\n <div>\r\n @for (node of nodes; track node.id; let i = $index) {\r\n <div class=\"button-row\" [class.hilite]=\"node.hilite\">\r\n <pdb-browser-tree-node\r\n [node]=\"node\"\r\n [debug]=\"debug.value\"\r\n [paging]=\"\r\n node.expanded &&\r\n i + 1 < nodes.length &&\r\n nodes[i + 1].paging.pageCount > 1\r\n ? nodes[i + 1].paging\r\n : undefined\r\n \"\r\n [hideFilter]=\"hideFilter.value\"\r\n [hideLoc]=\"hideLoc.value\"\r\n (toggleExpandedRequest)=\"onToggleExpanded($any($event))\"\r\n (changePageRequest)=\"onPageChangeRequest($event)\"\r\n (editNodeFilterRequest)=\"onEditFilterRequest($any($event))\"\r\n />\r\n @if (!node.hasChildren) {\r\n <button type=\"button\" mat-icon-button (click)=\"onNodeClick(node)\">\r\n <mat-icon class=\"mat-primary\">check_circle</mat-icon>\r\n </button>\r\n }\r\n </div>\r\n }\r\n </div>\r\n }\r\n <div class=\"form-row\">\r\n <mat-checkbox [formControl]=\"debug\">debug</mat-checkbox>\r\n <mat-checkbox [formControl]=\"hideFilter\">no filter</mat-checkbox>\r\n <mat-checkbox [formControl]=\"hideLoc\">no loc.</mat-checkbox>\r\n <button\r\n type=\"button\"\r\n mat-flat-button\r\n (click)=\"collapseAll()\"\r\n style=\"margin-left: 24px\"\r\n >\r\n collapse\r\n </button>\r\n </div>\r\n </div>\r\n</div>\r\n", styles: ["form{margin:16px}.form-row{display:flex;gap:8px;align-items:center;flex-wrap:wrap}.form-row *{flex:0 0 auto}.nr{width:6em}fieldset{border:1px solid silver;border-radius:6px;padding:8px 16px;margin:8px 0}legend{color:silver}th{text-align:left;font-weight:400}#tag-selector{width:8em}.tag-chip{border:2px solid transparent;border-radius:6px}.button-row{display:flex;align-items:center;flex-wrap:wrap}.button-row *{flex:0 0 auto}.hilite{background-color:#ffffe0;border:2px solid gold;border-radius:6px;padding:2px 4px}\n"] }]
|
|
982
|
-
}], ctorParameters: () => [], propDecorators: { service: [{ type: i0.Input, args: [{ isSignal: true, alias: "service", required: false }] }], nodePick: [{ type: i0.Output, args: ["nodePick"] }] } });
|
|
983
|
-
|
|
984
|
-
/**
|
|
985
|
-
* Thesaurus tree component.
|
|
986
|
-
* This component displays a set of hierarchical thesaurus entries
|
|
987
|
-
* in a tree, provided that each entry marks its hierarchy with
|
|
988
|
-
* dots. For instance, say you have the hierarchy "furniture" -
|
|
989
|
-
* "type" - "color". You might have an entry whose ID is
|
|
990
|
-
* "furniture.table.red", with a sibling "furniture.table.green",
|
|
991
|
-
* and a parent "furniture.table". This parent is there only to
|
|
992
|
-
* provide a label to the parent node, but only leaf nodes can be
|
|
993
|
-
* picked by the user. Whenever one is picked, the entryChange
|
|
994
|
-
* event is emitted. Note that even if you specify a label renderer
|
|
995
|
-
* function, the event always emits the original label.
|
|
996
|
-
*/
|
|
997
|
-
class ThesaurusTreeComponent {
|
|
998
|
-
/**
|
|
999
|
-
* The thesaurus entries.
|
|
1000
|
-
*/
|
|
1001
|
-
entries = input(...(ngDevMode ? [undefined, { debugName: "entries" }] : []));
|
|
1002
|
-
/**
|
|
1003
|
-
* The optional node label rendering function.
|
|
1004
|
-
*/
|
|
1005
|
-
renderLabel = input(renderLabelFromLastColon, ...(ngDevMode ? [{ debugName: "renderLabel" }] : []));
|
|
1006
|
-
/**
|
|
1007
|
-
* Fired when a thesaurus entry is selected.
|
|
1008
|
-
*/
|
|
1009
|
-
entryChange = output();
|
|
1010
|
-
/**
|
|
1011
|
-
* The tree store service, dependent on the current entries and renderLabel.
|
|
1012
|
-
*/
|
|
1013
|
-
service = computed(() => {
|
|
1014
|
-
const entries = this.entries();
|
|
1015
|
-
return new StaticThesPagedTreeStoreService(entries || [], this.renderLabel());
|
|
1016
|
-
}, ...(ngDevMode ? [{ debugName: "service" }] : []));
|
|
1017
|
-
/**
|
|
1018
|
-
* The filter component class to use.
|
|
1019
|
-
*/
|
|
1020
|
-
filterComponent = ThesPagedTreeFilterComponent;
|
|
1021
|
-
onNodePick(node) {
|
|
1022
|
-
// only allow selection of leaf nodes (nodes without children)
|
|
1023
|
-
if (!node.hasChildren) {
|
|
1024
|
-
// find the original entry
|
|
1025
|
-
const entry = this.entries()?.find((e) => e.id === node.key);
|
|
1026
|
-
if (entry) {
|
|
1027
|
-
this.entryChange.emit(entry);
|
|
1028
|
-
}
|
|
1029
|
-
}
|
|
1030
|
-
}
|
|
1031
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.7", ngImport: i0, type: ThesaurusTreeComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
1032
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.7", type: ThesaurusTreeComponent, isStandalone: true, selector: "cadmus-thesaurus-tree", inputs: { entries: { classPropertyName: "entries", publicName: "entries", isSignal: true, isRequired: false, transformFunction: null }, renderLabel: { classPropertyName: "renderLabel", publicName: "renderLabel", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { entryChange: "entryChange" }, ngImport: i0, template: "<div>\r\n <!-- tree -->\r\n @if (service() && entries()?.length) {\r\n <div class=\"tree-wrapper\">\r\n <cadmus-thes-paged-tree-browser\r\n [service]=\"service()\"\r\n (nodePick)=\"onNodePick($event)\"\r\n />\r\n </div>\r\n }\r\n</div>\r\n", styles: [".th-tree-progress-bar{margin-left:30px}.th-tree-nested-node{padding-left:30px}mat-tree{margin-left:40px}.mat-tree-node{padding:0;background-color:#fff}.mat-nested-tree-node{top:-24px}ul,li{list-style:none;margin:0;padding:0}li.th-tree-container{border-bottom:0}ul{padding-left:40px}li{padding-left:40px;border:1px dotted grey;border-width:0 0 1px 1px;position:relative;top:-24px}li.mat-tree-node,li div{margin:0;position:relative;top:24px}li ul{border-top:1px dotted grey;margin-left:-40px;padding-left:60px}.mat-nested-tree-node:last-child ul{border-left:1px solid white;margin-left:-41px}.mat-mdc-icon-button{z-index:100}span.found-count{margin:0 4px;padding:2px 4px;color:#fff;background-color:#0cc078;border-radius:6px}span.not-found-count{margin:0 4px;padding:2px 4px;color:#fff;background-color:#fb6962;border-radius:6px}.hilite{background-color:#fdfd96}.filter-field{width:100%;margin-bottom:1rem}.tree-container{border:1px solid #e0e0e0;border-radius:4px;overflow:auto;max-height:500px}.tree-wrapper{border:1px solid #e0e0e0;border-radius:4px;overflow:hidden;background:#fff}.no-entries{text-align:center;padding:2rem;color:#666;font-style:italic;border:1px solid #e0e0e0;border-radius:4px;background:#f9f9f9}.no-entries p{margin:0}\n"], dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "component", type: ThesPagedTreeBrowserComponent, selector: "cadmus-thes-paged-tree-browser", inputs: ["service"], outputs: ["nodePick"] }] });
|
|
1033
|
-
}
|
|
1034
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.7", ngImport: i0, type: ThesaurusTreeComponent, decorators: [{
|
|
1035
|
-
type: Component,
|
|
1036
|
-
args: [{ selector: 'cadmus-thesaurus-tree', imports: [FormsModule, ReactiveFormsModule, ThesPagedTreeBrowserComponent], template: "<div>\r\n <!-- tree -->\r\n @if (service() && entries()?.length) {\r\n <div class=\"tree-wrapper\">\r\n <cadmus-thes-paged-tree-browser\r\n [service]=\"service()\"\r\n (nodePick)=\"onNodePick($event)\"\r\n />\r\n </div>\r\n }\r\n</div>\r\n", styles: [".th-tree-progress-bar{margin-left:30px}.th-tree-nested-node{padding-left:30px}mat-tree{margin-left:40px}.mat-tree-node{padding:0;background-color:#fff}.mat-nested-tree-node{top:-24px}ul,li{list-style:none;margin:0;padding:0}li.th-tree-container{border-bottom:0}ul{padding-left:40px}li{padding-left:40px;border:1px dotted grey;border-width:0 0 1px 1px;position:relative;top:-24px}li.mat-tree-node,li div{margin:0;position:relative;top:24px}li ul{border-top:1px dotted grey;margin-left:-40px;padding-left:60px}.mat-nested-tree-node:last-child ul{border-left:1px solid white;margin-left:-41px}.mat-mdc-icon-button{z-index:100}span.found-count{margin:0 4px;padding:2px 4px;color:#fff;background-color:#0cc078;border-radius:6px}span.not-found-count{margin:0 4px;padding:2px 4px;color:#fff;background-color:#fb6962;border-radius:6px}.hilite{background-color:#fdfd96}.filter-field{width:100%;margin-bottom:1rem}.tree-container{border:1px solid #e0e0e0;border-radius:4px;overflow:auto;max-height:500px}.tree-wrapper{border:1px solid #e0e0e0;border-radius:4px;overflow:hidden;background:#fff}.no-entries{text-align:center;padding:2rem;color:#666;font-style:italic;border:1px solid #e0e0e0;border-radius:4px;background:#f9f9f9}.no-entries p{margin:0}\n"] }]
|
|
1037
|
-
}], propDecorators: { entries: [{ type: i0.Input, args: [{ isSignal: true, alias: "entries", required: false }] }], renderLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "renderLabel", required: false }] }], entryChange: [{ type: i0.Output, args: ["entryChange"] }] } });
|
|
1038
|
-
|
|
1039
|
-
/**
|
|
1040
|
-
* The prefix added to custom entries' IDs.
|
|
1041
|
-
*/
|
|
1042
|
-
const CUSTOM_ENTRY_PREFIX = '$';
|
|
1043
|
-
/**
|
|
1044
|
-
* A picker component for thesaurus entries.
|
|
1045
|
-
* This component allows picking one or more entries from a given thesaurus.
|
|
1046
|
-
* In its collapsed state, it shows the picked entries as chips; when
|
|
1047
|
-
* expanded, it shows the thesaurus tree to pick from. Custom entries
|
|
1048
|
-
* (not in the thesaurus) can be optionally allowed.
|
|
1049
|
-
*/
|
|
1050
|
-
class ThesEntriesPickerComponent {
|
|
1051
|
-
/**
|
|
1052
|
-
* The thesaurus entries to pick from (required).
|
|
1053
|
-
*/
|
|
1054
|
-
availableEntries = input.required(...(ngDevMode ? [{ debugName: "availableEntries" }] : []));
|
|
1055
|
-
/**
|
|
1056
|
-
* The picked entries.
|
|
1057
|
-
*/
|
|
1058
|
-
entries = model([], ...(ngDevMode ? [{ debugName: "entries" }] : []));
|
|
1059
|
-
/**
|
|
1060
|
-
* True to show the entries with labels shortened according to
|
|
1061
|
-
* their hierarchy.
|
|
1062
|
-
*/
|
|
1063
|
-
hierarchicLabels = input(false, ...(ngDevMode ? [{ debugName: "hierarchicLabels" }] : []));
|
|
1064
|
-
/**
|
|
1065
|
-
* True to automatically sort entries (disables drag-and-drop).
|
|
1066
|
-
* When false, entries can be manually reordered via drag-and-drop.
|
|
1067
|
-
*/
|
|
1068
|
-
autoSort = input(false, ...(ngDevMode ? [{ debugName: "autoSort" }] : []));
|
|
1069
|
-
/**
|
|
1070
|
-
* True to allow custom values (not in the entries list).
|
|
1071
|
-
*/
|
|
1072
|
-
allowCustom = input(false, ...(ngDevMode ? [{ debugName: "allowCustom" }] : []));
|
|
1073
|
-
/**
|
|
1074
|
-
* The minimum number of entries to pick.
|
|
1075
|
-
*/
|
|
1076
|
-
minEntries = input(0, ...(ngDevMode ? [{ debugName: "minEntries" }] : []));
|
|
1077
|
-
/**
|
|
1078
|
-
* The maximum number of entries to pick (0=unlimited).
|
|
1079
|
-
*/
|
|
1080
|
-
maxEntries = input(0, ...(ngDevMode ? [{ debugName: "maxEntries" }] : []));
|
|
1081
|
-
/**
|
|
1082
|
-
* True when the picker is expanded (showing the entries list).
|
|
1083
|
-
*/
|
|
1084
|
-
expanded = model(false, ...(ngDevMode ? [{ debugName: "expanded" }] : []));
|
|
1085
|
-
/**
|
|
1086
|
-
* The message to show when there are no picked entries.
|
|
1087
|
-
*/
|
|
1088
|
-
emptyMessage = input('no entries', ...(ngDevMode ? [{ debugName: "emptyMessage" }] : []));
|
|
1089
|
-
/**
|
|
1090
|
-
* The number of remaining entries that can be picked (0=unlimited).
|
|
1091
|
-
* This is displayed only if maxEntries > 1.
|
|
1092
|
-
*/
|
|
1093
|
-
remaining = computed(() => {
|
|
1094
|
-
if (this.maxEntries() > 0) {
|
|
1095
|
-
return this.maxEntries() - this.entries().length;
|
|
1096
|
-
}
|
|
1097
|
-
return 0;
|
|
1098
|
-
}, ...(ngDevMode ? [{ debugName: "remaining" }] : []));
|
|
1099
|
-
id;
|
|
1100
|
-
value;
|
|
1101
|
-
form;
|
|
1102
|
-
constructor(formBuilder) {
|
|
1103
|
-
this.id = formBuilder.control('', {
|
|
1104
|
-
validators: [Validators.required, Validators.maxLength(100)],
|
|
1105
|
-
nonNullable: true,
|
|
1106
|
-
});
|
|
1107
|
-
this.value = formBuilder.control('', {
|
|
1108
|
-
validators: [Validators.required, Validators.maxLength(500)],
|
|
1109
|
-
nonNullable: true,
|
|
1110
|
-
});
|
|
1111
|
-
this.form = formBuilder.group({
|
|
1112
|
-
id: this.id,
|
|
1113
|
-
value: this.value,
|
|
1114
|
-
});
|
|
1115
|
-
// if auto-sort is turned on and we have entries, sort them
|
|
1116
|
-
effect(() => {
|
|
1117
|
-
// only track autoSort() changes, not entries()
|
|
1118
|
-
const shouldSort = this.autoSort();
|
|
1119
|
-
if (shouldSort) {
|
|
1120
|
-
// use untracked to read entries without creating a dependency
|
|
1121
|
-
const currentEntries = untracked(() => this.entries());
|
|
1122
|
-
if (currentEntries.length > 1) {
|
|
1123
|
-
const entries = [...currentEntries];
|
|
1124
|
-
this.sortEntries(entries);
|
|
1125
|
-
this.entries.set(entries);
|
|
1126
|
-
}
|
|
1127
|
-
}
|
|
1128
|
-
});
|
|
1129
|
-
}
|
|
1130
|
-
// need arrow function to use 'this'
|
|
1131
|
-
renderLabel = (label) => {
|
|
1132
|
-
return this.hierarchicLabels() ? renderLabelFromLastColon(label) : label;
|
|
1133
|
-
};
|
|
1134
|
-
sortEntries(entries) {
|
|
1135
|
-
entries.sort((a, b) => {
|
|
1136
|
-
const aIsCustom = a.id?.startsWith(CUSTOM_ENTRY_PREFIX) ?? false;
|
|
1137
|
-
const bIsCustom = b.id?.startsWith(CUSTOM_ENTRY_PREFIX) ?? false;
|
|
1138
|
-
if (aIsCustom !== bIsCustom) {
|
|
1139
|
-
// place custom entries after non-custom ones
|
|
1140
|
-
return aIsCustom ? 1 : -1;
|
|
1141
|
-
}
|
|
1142
|
-
// same kind: sort by label/value
|
|
1143
|
-
return a.value.localeCompare(b.value);
|
|
1144
|
-
});
|
|
1145
|
-
}
|
|
1146
|
-
onEntryChange(entry) {
|
|
1147
|
-
// check if already present
|
|
1148
|
-
if (this.entries().some((e) => e.id === entry.id)) {
|
|
1149
|
-
return;
|
|
1150
|
-
}
|
|
1151
|
-
// check if limit is reached
|
|
1152
|
-
if (this.maxEntries() && this.entries().length >= this.maxEntries()) {
|
|
1153
|
-
return;
|
|
1154
|
-
}
|
|
1155
|
-
const entries = [...this.entries()];
|
|
1156
|
-
entries.push(entry);
|
|
1157
|
-
if (this.autoSort()) {
|
|
1158
|
-
this.sortEntries(entries);
|
|
1159
|
-
}
|
|
1160
|
-
this.entries.set(entries);
|
|
1161
|
-
}
|
|
1162
|
-
addCustomEntry() {
|
|
1163
|
-
if (this.form.invalid) {
|
|
1164
|
-
return;
|
|
1165
|
-
}
|
|
1166
|
-
// create the custom entry
|
|
1167
|
-
const customEntry = {
|
|
1168
|
-
id: CUSTOM_ENTRY_PREFIX + this.id.value,
|
|
1169
|
-
value: this.value.value,
|
|
1170
|
-
};
|
|
1171
|
-
// check if already present
|
|
1172
|
-
if (this.entries().some((e) => e.id === customEntry.id)) {
|
|
1173
|
-
return;
|
|
1174
|
-
}
|
|
1175
|
-
// check if limit is reached
|
|
1176
|
-
if (this.maxEntries() && this.entries().length >= this.maxEntries()) {
|
|
1177
|
-
return;
|
|
1178
|
-
}
|
|
1179
|
-
const entries = [...this.entries()];
|
|
1180
|
-
entries.push(customEntry);
|
|
1181
|
-
if (this.autoSort()) {
|
|
1182
|
-
this.sortEntries(entries);
|
|
1183
|
-
}
|
|
1184
|
-
this.entries.set(entries);
|
|
1185
|
-
this.form.reset();
|
|
1186
|
-
}
|
|
1187
|
-
removeEntry(entry) {
|
|
1188
|
-
const entries = [...this.entries().filter((e) => e.id !== entry.id)];
|
|
1189
|
-
this.entries.set(entries);
|
|
1190
|
-
}
|
|
1191
|
-
clear() {
|
|
1192
|
-
this.entries.set([]);
|
|
1193
|
-
// if min > 0, expand the picker
|
|
1194
|
-
if (this.minEntries() > 0 && !this.expanded()) {
|
|
1195
|
-
setTimeout(() => {
|
|
1196
|
-
this.expanded.set(true);
|
|
1197
|
-
}, 0);
|
|
1198
|
-
}
|
|
1199
|
-
}
|
|
1200
|
-
onDrop(event) {
|
|
1201
|
-
const entries = [...this.entries()];
|
|
1202
|
-
moveItemInArray(entries, event.previousIndex, event.currentIndex);
|
|
1203
|
-
this.entries.set(entries);
|
|
1204
|
-
}
|
|
1205
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.7", ngImport: i0, type: ThesEntriesPickerComponent, deps: [{ token: i1$1.FormBuilder }], target: i0.ɵɵFactoryTarget.Component });
|
|
1206
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.7", type: ThesEntriesPickerComponent, isStandalone: true, selector: "cadmus-thes-entries-picker", inputs: { availableEntries: { classPropertyName: "availableEntries", publicName: "availableEntries", isSignal: true, isRequired: true, transformFunction: null }, entries: { classPropertyName: "entries", publicName: "entries", isSignal: true, isRequired: false, transformFunction: null }, hierarchicLabels: { classPropertyName: "hierarchicLabels", publicName: "hierarchicLabels", isSignal: true, isRequired: false, transformFunction: null }, autoSort: { classPropertyName: "autoSort", publicName: "autoSort", isSignal: true, isRequired: false, transformFunction: null }, allowCustom: { classPropertyName: "allowCustom", publicName: "allowCustom", isSignal: true, isRequired: false, transformFunction: null }, minEntries: { classPropertyName: "minEntries", publicName: "minEntries", isSignal: true, isRequired: false, transformFunction: null }, maxEntries: { classPropertyName: "maxEntries", publicName: "maxEntries", isSignal: true, isRequired: false, transformFunction: null }, expanded: { classPropertyName: "expanded", publicName: "expanded", isSignal: true, isRequired: false, transformFunction: null }, emptyMessage: { classPropertyName: "emptyMessage", publicName: "emptyMessage", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { entries: "entriesChange", expanded: "expandedChange" }, ngImport: i0, template: "<div id=\"container\">\r\n <!-- picked entries -->\r\n <div id=\"picked\" class=\"form-row\">\r\n <!-- count -->\r\n <span class=\"nr\" [class.error]=\"entries().length < minEntries()\">{{\r\n entries().length\r\n }}</span>\r\n <!-- max-->\r\n @if (maxEntries() > 1) {\r\n <span class=\"muted\">/{{ maxEntries() }}</span>\r\n @if (remaining()) {\r\n <span class=\"muted\">: -{{ remaining() }}</span>\r\n } }\r\n <!-- min -->\r\n @if (minEntries()) {\r\n <!-- min with error -->\r\n @if (entries().length < minEntries()) {\r\n <span class=\"error\"> (min {{ minEntries() }})</span>\r\n }\r\n <!-- min without error -->\r\n @else {\r\n <span class=\"muted\"> (min {{ minEntries() }})</span>\r\n } }\r\n <!-- list -->\r\n <mat-chip-listbox\r\n [cdkDropListDisabled]=\"autoSort()\"\r\n cdkDropList\r\n cdkDropListOrientation=\"horizontal\"\r\n (cdkDropListDropped)=\"onDrop($event)\"\r\n class=\"chip-list\"\r\n >\r\n @for (e of entries(); track e.id; let idx = $index) {\r\n <div class=\"chip-wrapper\">\r\n <mat-chip-option\r\n [cdkDragDisabled]=\"autoSort()\"\r\n cdkDrag\r\n [class.error]=\"!allowCustom() && e.id.startsWith('$')\"\r\n >\r\n {{ renderLabel(e.value) }}\r\n <button\r\n type=\"button\"\r\n matChipRemove\r\n (click)=\"removeEntry(e)\"\r\n aria-label=\"Remove entry\"\r\n >\r\n <mat-icon class=\"mat-warn\">cancel</mat-icon>\r\n </button>\r\n </mat-chip-option>\r\n </div>\r\n } @empty {\r\n <span class=\"muted empty-message\">{{ emptyMessage() }}</span>\r\n }\r\n </mat-chip-listbox>\r\n\r\n <!-- clear -->\r\n @if (entries().length > 0) {\r\n <button\r\n type=\"button\"\r\n mat-icon-button\r\n matTooltip=\"Remove all entries\"\r\n (click)=\"clear()\"\r\n [disabled]=\"entries().length === 0\"\r\n >\r\n <mat-icon class=\"mat-warn\">clear</mat-icon>\r\n </button>\r\n }\r\n <!-- toggler -->\r\n <button\r\n type=\"button\"\r\n mat-icon-button\r\n matTooltip=\"Toggle picker\"\r\n (click)=\"expanded.set(!expanded())\"\r\n >\r\n @if (expanded()) {\r\n <mat-icon class=\"mat-primary\">publish</mat-icon>\r\n } @if (!expanded()) {\r\n <mat-icon class=\"mat-primary\">get_app</mat-icon>\r\n }\r\n </button>\r\n </div>\r\n\r\n <!-- entries picker -->\r\n <div id=\"picker\">\r\n <mat-expansion-panel\r\n [expanded]=\"expanded()\"\r\n (expandedChange)=\"expanded.set($event)\"\r\n >\r\n <div>\r\n <fieldset>\r\n <legend>available</legend>\r\n <cadmus-thesaurus-tree\r\n [entries]=\"availableEntries()\"\r\n [renderLabel]=\"renderLabel\"\r\n (entryChange)=\"onEntryChange($event)\"\r\n />\r\n </fieldset>\r\n </div>\r\n @if (allowCustom()) {\r\n <div>\r\n <form [formGroup]=\"form\" (submit)=\"addCustomEntry()\">\r\n <fieldset>\r\n <legend>custom</legend>\r\n <div class=\"form-row\">\r\n <mat-form-field>\r\n <input\r\n matInput\r\n type=\"text\"\r\n [formControl]=\"id\"\r\n placeholder=\"ID\"\r\n />\r\n </mat-form-field>\r\n <mat-form-field>\r\n <input\r\n matInput\r\n type=\"text\"\r\n [formControl]=\"value\"\r\n placeholder=\"label\"\r\n />\r\n </mat-form-field>\r\n <button\r\n type=\"submit\"\r\n mat-icon-button\r\n matTooltip=\"Add custom entry\"\r\n [disabled]=\"\r\n !form.valid ||\r\n (maxEntries() > 0 && entries().length >= maxEntries())\r\n \"\r\n >\r\n <mat-icon class=\"mat-primary\">check_circle</mat-icon>\r\n </button>\r\n </div>\r\n </fieldset>\r\n </form>\r\n </div>\r\n }\r\n </mat-expansion-panel>\r\n </div>\r\n</div>\r\n", styles: ["#container{width:100%}.form-row{display:flex;gap:8px;align-items:center;flex-wrap:wrap}.form-row *{flex:0 0 auto}.error{color:#8b0000}.nr{font-weight:700}.muted{color:gray}fieldset{border:1px solid silver;border-radius:8px;padding:8px 16px}.chip-list{display:flex;flex-wrap:wrap;gap:4px;align-items:center;padding:4px}.chip-wrapper{display:inline-flex;position:relative;margin:2px}.chip-list mat-chip-option:not([cdkDragDisabled]){cursor:grab}.chip-list mat-chip-option:not([cdkDragDisabled]):active{cursor:grabbing}.chip-list mat-chip-option[cdkDragDisabled]{cursor:default}.chip-list .empty-message{margin-left:0}.chip-list mat-chip-option.mat-mdc-chip-selected{background-color:inherit}.chip-list mat-chip-option:not(.error).mat-mdc-chip-selected{background-color:#e0e0e0}mat-chip-option.error{background-color:#ffebee!important;border:1px solid darkred}.cdk-drag-preview{opacity:.95;box-shadow:0 8px 20px #0006;transform:rotate(3deg)}.drag-placeholder{width:4px;background:#1976d2;border-radius:2px;height:36px;box-shadow:0 0 8px #1976d299;animation:pulse .5s ease-in-out infinite}@keyframes pulse{0%,to{opacity:.6;transform:scaleY(1)}50%{opacity:1;transform:scaleY(1.1)}}.chip-list .cdk-drag-placeholder{opacity:0;width:4px;min-width:4px}.chip-wrapper{transition:transform .25s cubic-bezier(0,0,.2,1)}.cdk-drop-list-dragging .chip-wrapper:not(.cdk-drag-placeholder){transition:transform .25s cubic-bezier(0,0,.2,1)}.cdk-drop-list-dragging .chip-wrapper{will-change:transform}\n"], dependencies: [{ kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1$1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$1.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: CdkDropList, selector: "[cdkDropList], cdk-drop-list", inputs: ["cdkDropListConnectedTo", "cdkDropListData", "cdkDropListOrientation", "id", "cdkDropListLockAxis", "cdkDropListDisabled", "cdkDropListSortingDisabled", "cdkDropListEnterPredicate", "cdkDropListSortPredicate", "cdkDropListAutoScrollDisabled", "cdkDropListAutoScrollStep", "cdkDropListElementContainer", "cdkDropListHasAnchor"], outputs: ["cdkDropListDropped", "cdkDropListEntered", "cdkDropListExited", "cdkDropListSorted"], exportAs: ["cdkDropList"] }, { kind: "directive", type: CdkDrag, selector: "[cdkDrag]", inputs: ["cdkDragData", "cdkDragLockAxis", "cdkDragRootElement", "cdkDragBoundary", "cdkDragStartDelay", "cdkDragFreeDragPosition", "cdkDragDisabled", "cdkDragConstrainPosition", "cdkDragPreviewClass", "cdkDragPreviewContainer", "cdkDragScale"], outputs: ["cdkDragStarted", "cdkDragReleased", "cdkDragEnded", "cdkDragEntered", "cdkDragExited", "cdkDragDropped", "cdkDragMoved"], exportAs: ["cdkDrag"] }, { kind: "component", type: MatChipListbox, selector: "mat-chip-listbox", inputs: ["multiple", "aria-orientation", "selectable", "compareWith", "required", "hideSingleSelectionIndicator", "value"], outputs: ["change"] }, { kind: "component", type: MatChipOption, selector: "mat-basic-chip-option, [mat-basic-chip-option], mat-chip-option, [mat-chip-option]", inputs: ["selectable", "selected"], outputs: ["selectionChange"] }, { kind: "directive", type: MatChipRemove, selector: "[matChipRemove]" }, { kind: "component", type: MatExpansionPanel, selector: "mat-expansion-panel", inputs: ["hideToggle", "togglePosition"], outputs: ["afterExpand", "afterCollapse"], exportAs: ["matExpansionPanel"] }, { kind: "component", type: MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "component", type: MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "component", type: MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { 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: MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "component", type: ThesaurusTreeComponent, selector: "cadmus-thesaurus-tree", inputs: ["entries", "renderLabel"], outputs: ["entryChange"] }] });
|
|
1207
|
-
}
|
|
1208
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.7", ngImport: i0, type: ThesEntriesPickerComponent, decorators: [{
|
|
1209
|
-
type: Component,
|
|
1210
|
-
args: [{ selector: 'cadmus-thes-entries-picker', imports: [
|
|
1211
|
-
ReactiveFormsModule,
|
|
1212
|
-
CdkDropList,
|
|
1213
|
-
CdkDrag,
|
|
1214
|
-
MatChipListbox,
|
|
1215
|
-
MatChipOption,
|
|
1216
|
-
MatChipRemove,
|
|
1217
|
-
MatExpansionPanel,
|
|
1218
|
-
MatFormField,
|
|
1219
|
-
MatIconButton,
|
|
1220
|
-
MatIcon,
|
|
1221
|
-
MatInput,
|
|
1222
|
-
MatTooltip,
|
|
1223
|
-
ThesaurusTreeComponent,
|
|
1224
|
-
], template: "<div id=\"container\">\r\n <!-- picked entries -->\r\n <div id=\"picked\" class=\"form-row\">\r\n <!-- count -->\r\n <span class=\"nr\" [class.error]=\"entries().length < minEntries()\">{{\r\n entries().length\r\n }}</span>\r\n <!-- max-->\r\n @if (maxEntries() > 1) {\r\n <span class=\"muted\">/{{ maxEntries() }}</span>\r\n @if (remaining()) {\r\n <span class=\"muted\">: -{{ remaining() }}</span>\r\n } }\r\n <!-- min -->\r\n @if (minEntries()) {\r\n <!-- min with error -->\r\n @if (entries().length < minEntries()) {\r\n <span class=\"error\"> (min {{ minEntries() }})</span>\r\n }\r\n <!-- min without error -->\r\n @else {\r\n <span class=\"muted\"> (min {{ minEntries() }})</span>\r\n } }\r\n <!-- list -->\r\n <mat-chip-listbox\r\n [cdkDropListDisabled]=\"autoSort()\"\r\n cdkDropList\r\n cdkDropListOrientation=\"horizontal\"\r\n (cdkDropListDropped)=\"onDrop($event)\"\r\n class=\"chip-list\"\r\n >\r\n @for (e of entries(); track e.id; let idx = $index) {\r\n <div class=\"chip-wrapper\">\r\n <mat-chip-option\r\n [cdkDragDisabled]=\"autoSort()\"\r\n cdkDrag\r\n [class.error]=\"!allowCustom() && e.id.startsWith('$')\"\r\n >\r\n {{ renderLabel(e.value) }}\r\n <button\r\n type=\"button\"\r\n matChipRemove\r\n (click)=\"removeEntry(e)\"\r\n aria-label=\"Remove entry\"\r\n >\r\n <mat-icon class=\"mat-warn\">cancel</mat-icon>\r\n </button>\r\n </mat-chip-option>\r\n </div>\r\n } @empty {\r\n <span class=\"muted empty-message\">{{ emptyMessage() }}</span>\r\n }\r\n </mat-chip-listbox>\r\n\r\n <!-- clear -->\r\n @if (entries().length > 0) {\r\n <button\r\n type=\"button\"\r\n mat-icon-button\r\n matTooltip=\"Remove all entries\"\r\n (click)=\"clear()\"\r\n [disabled]=\"entries().length === 0\"\r\n >\r\n <mat-icon class=\"mat-warn\">clear</mat-icon>\r\n </button>\r\n }\r\n <!-- toggler -->\r\n <button\r\n type=\"button\"\r\n mat-icon-button\r\n matTooltip=\"Toggle picker\"\r\n (click)=\"expanded.set(!expanded())\"\r\n >\r\n @if (expanded()) {\r\n <mat-icon class=\"mat-primary\">publish</mat-icon>\r\n } @if (!expanded()) {\r\n <mat-icon class=\"mat-primary\">get_app</mat-icon>\r\n }\r\n </button>\r\n </div>\r\n\r\n <!-- entries picker -->\r\n <div id=\"picker\">\r\n <mat-expansion-panel\r\n [expanded]=\"expanded()\"\r\n (expandedChange)=\"expanded.set($event)\"\r\n >\r\n <div>\r\n <fieldset>\r\n <legend>available</legend>\r\n <cadmus-thesaurus-tree\r\n [entries]=\"availableEntries()\"\r\n [renderLabel]=\"renderLabel\"\r\n (entryChange)=\"onEntryChange($event)\"\r\n />\r\n </fieldset>\r\n </div>\r\n @if (allowCustom()) {\r\n <div>\r\n <form [formGroup]=\"form\" (submit)=\"addCustomEntry()\">\r\n <fieldset>\r\n <legend>custom</legend>\r\n <div class=\"form-row\">\r\n <mat-form-field>\r\n <input\r\n matInput\r\n type=\"text\"\r\n [formControl]=\"id\"\r\n placeholder=\"ID\"\r\n />\r\n </mat-form-field>\r\n <mat-form-field>\r\n <input\r\n matInput\r\n type=\"text\"\r\n [formControl]=\"value\"\r\n placeholder=\"label\"\r\n />\r\n </mat-form-field>\r\n <button\r\n type=\"submit\"\r\n mat-icon-button\r\n matTooltip=\"Add custom entry\"\r\n [disabled]=\"\r\n !form.valid ||\r\n (maxEntries() > 0 && entries().length >= maxEntries())\r\n \"\r\n >\r\n <mat-icon class=\"mat-primary\">check_circle</mat-icon>\r\n </button>\r\n </div>\r\n </fieldset>\r\n </form>\r\n </div>\r\n }\r\n </mat-expansion-panel>\r\n </div>\r\n</div>\r\n", styles: ["#container{width:100%}.form-row{display:flex;gap:8px;align-items:center;flex-wrap:wrap}.form-row *{flex:0 0 auto}.error{color:#8b0000}.nr{font-weight:700}.muted{color:gray}fieldset{border:1px solid silver;border-radius:8px;padding:8px 16px}.chip-list{display:flex;flex-wrap:wrap;gap:4px;align-items:center;padding:4px}.chip-wrapper{display:inline-flex;position:relative;margin:2px}.chip-list mat-chip-option:not([cdkDragDisabled]){cursor:grab}.chip-list mat-chip-option:not([cdkDragDisabled]):active{cursor:grabbing}.chip-list mat-chip-option[cdkDragDisabled]{cursor:default}.chip-list .empty-message{margin-left:0}.chip-list mat-chip-option.mat-mdc-chip-selected{background-color:inherit}.chip-list mat-chip-option:not(.error).mat-mdc-chip-selected{background-color:#e0e0e0}mat-chip-option.error{background-color:#ffebee!important;border:1px solid darkred}.cdk-drag-preview{opacity:.95;box-shadow:0 8px 20px #0006;transform:rotate(3deg)}.drag-placeholder{width:4px;background:#1976d2;border-radius:2px;height:36px;box-shadow:0 0 8px #1976d299;animation:pulse .5s ease-in-out infinite}@keyframes pulse{0%,to{opacity:.6;transform:scaleY(1)}50%{opacity:1;transform:scaleY(1.1)}}.chip-list .cdk-drag-placeholder{opacity:0;width:4px;min-width:4px}.chip-wrapper{transition:transform .25s cubic-bezier(0,0,.2,1)}.cdk-drop-list-dragging .chip-wrapper:not(.cdk-drag-placeholder){transition:transform .25s cubic-bezier(0,0,.2,1)}.cdk-drop-list-dragging .chip-wrapper{will-change:transform}\n"] }]
|
|
1225
|
-
}], ctorParameters: () => [{ type: i1$1.FormBuilder }], propDecorators: { availableEntries: [{ type: i0.Input, args: [{ isSignal: true, alias: "availableEntries", required: true }] }], entries: [{ type: i0.Input, args: [{ isSignal: true, alias: "entries", required: false }] }, { type: i0.Output, args: ["entriesChange"] }], hierarchicLabels: [{ type: i0.Input, args: [{ isSignal: true, alias: "hierarchicLabels", required: false }] }], autoSort: [{ type: i0.Input, args: [{ isSignal: true, alias: "autoSort", required: false }] }], allowCustom: [{ type: i0.Input, args: [{ isSignal: true, alias: "allowCustom", required: false }] }], minEntries: [{ type: i0.Input, args: [{ isSignal: true, alias: "minEntries", required: false }] }], maxEntries: [{ type: i0.Input, args: [{ isSignal: true, alias: "maxEntries", required: false }] }], expanded: [{ type: i0.Input, args: [{ isSignal: true, alias: "expanded", required: false }] }, { type: i0.Output, args: ["expandedChange"] }], emptyMessage: [{ type: i0.Input, args: [{ isSignal: true, alias: "emptyMessage", required: false }] }] } });
|
|
1226
|
-
|
|
1227
590
|
var PartBadgeType;
|
|
1228
591
|
(function (PartBadgeType) {
|
|
1229
592
|
PartBadgeType[PartBadgeType["partAndRole"] = 0] = "partAndRole";
|
|
@@ -1368,10 +731,10 @@ class PartBadgeComponent {
|
|
|
1368
731
|
entry = typeThesaurus.entries?.find((e) => e.id === roleId);
|
|
1369
732
|
return entry ? entry.value : roleId;
|
|
1370
733
|
}
|
|
1371
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
1372
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "
|
|
734
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: PartBadgeComponent, deps: [{ token: i1$2.FacetService }], target: i0.ɵɵFactoryTarget.Component });
|
|
735
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.0", 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) {\r\n<span\r\n class=\"part-badge\"\r\n [style.background-color]=\"color()\"\r\n [style.color]=\"color() | colorToContrast\"\r\n [matTooltip]=\"partDefinition()?.description\"\r\n>\r\n {{ typeName() }}\r\n</span>\r\n} @if (badgeType() !== 1 && roleName()) {\r\n<span class=\"role-badge\">\r\n {{ roleName() }}\r\n</span>\r\n}\r\n", styles: [".part-badge{padding:4px;border-radius:6px}.role-badge{padding:4px;border:1px solid silver;border-radius:6px}\n"], dependencies: [{ kind: "directive", type: MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "pipe", type: ColorToContrastPipe, name: "colorToContrast" }] });
|
|
1373
736
|
}
|
|
1374
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
737
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: PartBadgeComponent, decorators: [{
|
|
1375
738
|
type: Component,
|
|
1376
739
|
args: [{ selector: 'cadmus-part-badge', imports: [MatTooltip, ColorToContrastPipe], template: "@if (badgeType() !== 2) {\r\n<span\r\n class=\"part-badge\"\r\n [style.background-color]=\"color()\"\r\n [style.color]=\"color() | colorToContrast\"\r\n [matTooltip]=\"partDefinition()?.description\"\r\n>\r\n {{ typeName() }}\r\n</span>\r\n} @if (badgeType() !== 1 && roleName()) {\r\n<span class=\"role-badge\">\r\n {{ roleName() }}\r\n</span>\r\n}\r\n", styles: [".part-badge{padding:4px;border-radius:6px}.role-badge{padding:4px;border:1px solid silver;border-radius:6px}\n"] }]
|
|
1377
740
|
}], ctorParameters: () => [{ type: i1$2.FacetService }], propDecorators: { badgeType: [{ type: i0.Input, args: [{ isSignal: true, alias: "badgeType", required: false }] }], typeThesaurus: [{ type: i0.Input, args: [{ isSignal: true, alias: "typeThesaurus", required: false }] }], facetDefinition: [{ type: i0.Input, args: [{ isSignal: true, alias: "facetDefinition", required: false }] }], partTypeIds: [{ type: i0.Input, args: [{ isSignal: true, alias: "partTypeIds", required: false }] }] } });
|
|
@@ -1607,10 +970,10 @@ class ModelEditorComponentBase {
|
|
|
1607
970
|
// the form is no more dirty
|
|
1608
971
|
this.form.markAsPristine();
|
|
1609
972
|
}
|
|
1610
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
1611
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "
|
|
973
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: ModelEditorComponentBase, deps: [{ token: i1$3.AuthJwtService }, { token: i1$1.FormBuilder }], target: i0.ɵɵFactoryTarget.Component });
|
|
974
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.1.0", 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 });
|
|
1612
975
|
}
|
|
1613
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
976
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: ModelEditorComponentBase, decorators: [{
|
|
1614
977
|
type: Component,
|
|
1615
978
|
args: [{
|
|
1616
979
|
template: '',
|
|
@@ -1692,10 +1055,10 @@ class UserRefLookupService {
|
|
|
1692
1055
|
getName(item) {
|
|
1693
1056
|
return item?.user?.userName;
|
|
1694
1057
|
}
|
|
1695
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
1696
|
-
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "
|
|
1058
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: UserRefLookupService, deps: [{ token: i1$2.UserService }], target: i0.ɵɵFactoryTarget.Injectable });
|
|
1059
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: UserRefLookupService, providedIn: 'root' });
|
|
1697
1060
|
}
|
|
1698
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
1061
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: UserRefLookupService, decorators: [{
|
|
1699
1062
|
type: Injectable,
|
|
1700
1063
|
args: [{
|
|
1701
1064
|
providedIn: 'root',
|
|
@@ -1759,5 +1122,5 @@ const extractPristineChanges = (control) => {
|
|
|
1759
1122
|
* Generated bundle index. Do not edit.
|
|
1760
1123
|
*/
|
|
1761
1124
|
|
|
1762
|
-
export {
|
|
1125
|
+
export { CloseSaveButtonsComponent, ColorService, CustomValidators, DecoratedTokenTextComponent, ErrorListComponent, FacetBadgeComponent, FlagsBadgeComponent, JsonValidators, LayerHintsComponent, LookupPinComponent, ModelEditorComponentBase, PartBadgeComponent, PartBadgeType, UserRefLookupService, extractPristineChanges, extractTouchedChanges, getPartIdName };
|
|
1763
1126
|
//# sourceMappingURL=myrmidon-cadmus-ui.mjs.map
|