@myrmidon/cadmus-refs-asserted-ids 9.0.0 → 10.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,36 +1,59 @@
1
1
  import * as i0 from '@angular/core';
2
- import { Injectable, output, Component, Inject, input, model, effect, Input } from '@angular/core';
2
+ import { Injectable, model, input, output, effect, Inject, Component, Input } from '@angular/core';
3
3
  import * as i1$1 from '@angular/forms';
4
4
  import { Validators, FormsModule, ReactiveFormsModule } from '@angular/forms';
5
- import { debounceTime } from 'rxjs/operators';
5
+ import { debounceTime as debounceTime$1 } from 'rxjs/operators';
6
6
  import * as i3 from '@angular/material/button';
7
7
  import { MatButtonModule } from '@angular/material/button';
8
- import * as i4 from '@angular/material/expansion';
8
+ import * as i4$1 from '@angular/material/expansion';
9
9
  import { MatExpansionModule } from '@angular/material/expansion';
10
- import * as i6 from '@angular/material/form-field';
10
+ import * as i6$1 from '@angular/material/form-field';
11
11
  import { MatFormFieldModule } from '@angular/material/form-field';
12
- import * as i8 from '@angular/material/input';
13
- import { MatInputModule } from '@angular/material/input';
14
12
  import * as i7 from '@angular/material/icon';
15
13
  import { MatIconModule } from '@angular/material/icon';
14
+ import * as i8$1 from '@angular/material/input';
15
+ import { MatInputModule } from '@angular/material/input';
16
16
  import * as i9 from '@angular/material/select';
17
17
  import { MatSelectModule } from '@angular/material/select';
18
- import { AssertionComponent } from '@myrmidon/cadmus-refs-assertion';
19
- import { of, map, forkJoin, take, distinctUntilChanged, debounceTime as debounceTime$1 } from 'rxjs';
20
- import { RefLookupComponent, RefLookupSetComponent } from '@myrmidon/cadmus-refs-lookup';
21
- import * as i1 from '@myrmidon/cadmus-api';
22
- import * as i10 from '@angular/material/core';
23
- import { CommonModule } from '@angular/common';
24
- import * as i6$1 from '@angular/material/tooltip';
18
+ import * as i14 from '@angular/material/tooltip';
25
19
  import { MatTooltipModule } from '@angular/material/tooltip';
26
- import * as i2 from '@myrmidon/ngx-mat-tools';
27
- import * as i6$2 from '@angular/cdk/clipboard';
20
+ import { AssertionComponent } from '@myrmidon/cadmus-refs-assertion';
21
+ import { map, of, distinctUntilChanged, debounceTime, forkJoin, take } from 'rxjs';
22
+ import * as i6 from '@angular/cdk/clipboard';
28
23
  import { ClipboardModule } from '@angular/cdk/clipboard';
29
- import * as i8$1 from '@angular/material/checkbox';
24
+ import * as i8 from '@angular/material/checkbox';
30
25
  import { MatCheckboxModule } from '@angular/material/checkbox';
31
26
  import * as i3$1 from '@myrmidon/ngx-tools';
32
27
  import { FlatLookupPipe } from '@myrmidon/ngx-tools';
33
- import * as i4$1 from '@angular/material/snack-bar';
28
+ import { RefLookupComponent, RefLookupSetComponent } from '@myrmidon/cadmus-refs-lookup';
29
+ import * as i1 from '@myrmidon/cadmus-api';
30
+ import * as i4 from '@angular/material/snack-bar';
31
+ import * as i2 from '@myrmidon/ngx-mat-tools';
32
+
33
+ class ItemRefLookupService {
34
+ _itemService;
35
+ constructor(_itemService) {
36
+ this._itemService = _itemService;
37
+ }
38
+ lookup(filter, options) {
39
+ return this._itemService
40
+ .getItems({
41
+ title: filter.text,
42
+ }, 1, filter.limit || 10)
43
+ .pipe(map((page) => page.items));
44
+ }
45
+ getName(item) {
46
+ return item?.title;
47
+ }
48
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.0", ngImport: i0, type: ItemRefLookupService, deps: [{ token: i1.ItemService }], target: i0.ɵɵFactoryTarget.Injectable });
49
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.0.0", ngImport: i0, type: ItemRefLookupService, providedIn: 'root' });
50
+ }
51
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.0", ngImport: i0, type: ItemRefLookupService, decorators: [{
52
+ type: Injectable,
53
+ args: [{
54
+ providedIn: 'root',
55
+ }]
56
+ }], ctorParameters: () => [{ type: i1.ItemService }] });
34
57
 
35
58
  /**
36
59
  * Cadmus pin-based lookup data service. The text being searched here is just
@@ -103,10 +126,10 @@ class PinRefLookupService {
103
126
  }
104
127
  }));
105
128
  }
106
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.5", ngImport: i0, type: PinRefLookupService, deps: [{ token: i1.ItemService }], target: i0.ɵɵFactoryTarget.Injectable });
107
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.0.5", ngImport: i0, type: PinRefLookupService, providedIn: 'root' });
129
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.0", ngImport: i0, type: PinRefLookupService, deps: [{ token: i1.ItemService }], target: i0.ɵɵFactoryTarget.Injectable });
130
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.0.0", ngImport: i0, type: PinRefLookupService, providedIn: 'root' });
108
131
  }
109
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.5", ngImport: i0, type: PinRefLookupService, decorators: [{
132
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.0", ngImport: i0, type: PinRefLookupService, decorators: [{
110
133
  type: Injectable,
111
134
  args: [{
112
135
  providedIn: 'root',
@@ -122,978 +145,1079 @@ const METADATA_PART_ID$1 = 'it.vedph.metadata';
122
145
  * item's metadata part, if any. He can then use these data to build
123
146
  * some EID by variously assembling these components.
124
147
  */
125
- class ScopedPinLookupComponent {
148
+ class PinTargetLookupComponent {
149
+ _presetLookupDefs;
150
+ itemLookupService;
151
+ pinLookupService;
126
152
  _itemService;
127
- lookupService;
128
- lookupDefs;
129
- // lookup
130
- key;
131
- keyForm;
132
- keys;
133
- info;
134
- // builder
135
- id;
136
- idForm;
153
+ _thesService;
154
+ _snackbar;
155
+ _subs = [];
156
+ _noTargetUpdate;
157
+ _noFormUpdate;
158
+ _startWithByTypeMode;
137
159
  /**
138
- * Emitted whenever the user picks an ID.
160
+ * True when the by-type pin lookup mode is active.
161
+ * User can change mode unless modeSwitching is false.
139
162
  */
140
- idPick = output();
141
- constructor(formBuilder, _itemService, lookupService, lookupDefs) {
142
- this._itemService = _itemService;
143
- this.lookupService = lookupService;
144
- this.lookupDefs = lookupDefs;
145
- // lookup
146
- // keys are all the defined lookup searches
147
- this.keys = Object.keys(lookupDefs);
148
- // the selected key defines the lookup scope
149
- this.key = formBuilder.control(null);
150
- this.keyForm = formBuilder.group({
151
- key: this.key,
152
- });
153
- // id
154
- this.id = formBuilder.control(null, [
155
- Validators.required,
156
- Validators.maxLength(300),
157
- ]);
158
- this.idForm = formBuilder.group({
159
- id: this.id,
160
- });
161
- }
162
- ngOnInit() {
163
- // pre-select a unique key
164
- if (this.keys.length === 1) {
165
- this.key.setValue(this.keys[0]);
166
- this.key.markAsDirty();
167
- this.key.updateValueAndValidity();
168
- }
169
- }
170
- onItemChange(item) {
171
- const info = {
172
- pin: item,
173
- };
174
- // lookup item and its metadata part if any
175
- forkJoin({
176
- item: item
177
- ? this._itemService.getItem(item.itemId, false, true)
178
- : of(null),
179
- part: item
180
- ? this._itemService.getPartFromTypeAndRole(item.itemId, METADATA_PART_ID$1, undefined, true)
181
- : of(null),
182
- })
183
- .pipe(take(1))
184
- .subscribe({
185
- next: (result) => {
186
- if (result.item) {
187
- info.item = result.item;
188
- info.part = result.part;
189
- this.info = info;
190
- }
191
- },
192
- error: (error) => {
193
- console.error(error ? JSON.stringify(error) : 'Error loading item/metadata');
194
- },
195
- });
196
- }
197
- appendIdComponent(type, metaIndex = -1) {
198
- let id = this.id.value || '';
199
- switch (type) {
200
- case 'pin':
201
- id += this.info?.pin.value;
202
- break;
203
- case 'itemId':
204
- id += this.info.item?.id || '';
205
- break;
206
- case 'partId':
207
- id += this.info.part?.id || '';
208
- break;
209
- case 'partTypeId':
210
- id += this.info.part?.typeId || '';
211
- break;
212
- case 'partRoleId':
213
- id += this.info.part?.roleId || '';
214
- break;
215
- case 'metadata':
216
- id += this.info.part.metadata[metaIndex].value;
217
- break;
218
- }
219
- this.id.setValue(id);
220
- this.id.markAsDirty();
221
- this.id.updateValueAndValidity();
222
- }
223
- pickId() {
224
- if (this.idForm.invalid) {
225
- return;
226
- }
227
- this.idPick.emit(this.id.value);
228
- this.info = undefined;
229
- }
230
- resetId() {
231
- this.id.reset();
232
- this.id.markAsDirty();
233
- this.id.updateValueAndValidity();
234
- }
235
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.5", ngImport: i0, type: ScopedPinLookupComponent, deps: [{ token: i1$1.FormBuilder }, { token: i1.ItemService }, { token: PinRefLookupService }, { token: 'indexLookupDefinitions' }], target: i0.ɵɵFactoryTarget.Component });
236
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.0.5", type: ScopedPinLookupComponent, isStandalone: true, selector: "cadmus-scoped-pin-lookup", outputs: { idPick: "idPick" }, ngImport: i0, template: "<div>\n <!-- lookup -->\n <div>\n <form [formGroup]=\"keyForm\" class=\"form-row\">\n <!-- key -->\n @if (keys.length > 1) {\n <mat-form-field>\n <mat-label>type</mat-label>\n <mat-select [formControl]=\"key\">\n @for (k of keys; track k) {\n <mat-option [value]=\"k\">{{ k }}</mat-option>\n }\n </mat-select>\n @if ($any(key).errors?.required && (key.dirty || key.touched)) {\n <mat-error>type required</mat-error>\n }\n </mat-form-field>\n }\n <cadmus-ref-lookup\n [service]=\"lookupService\"\n label=\"pin\"\n [options]=\"key.value ? lookupDefs[key.value] : undefined\"\n (itemChange)=\"onItemChange($event)\"\n />\n </form>\n </div>\n\n <!-- builder -->\n @if (info) {\n <mat-expansion-panel [expanded]=\"info\" [disabled]=\"!info\">\n <mat-expansion-panel-header>ID builder</mat-expansion-panel-header>\n <!-- ID -->\n <div>\n <form [formGroup]=\"idForm\" (submit)=\"pickId()\">\n <mat-form-field style=\"width: 100%\">\n <input matInput [formControl]=\"id\" />\n @if ($any(id).errors?.required && (id.dirty || id.touched)) {\n <mat-error>ID required</mat-error>\n } @if ($any(id).errors?.maxLength && (id.dirty || id.touched)) {\n <mat-error>ID too long</mat-error>\n }\n <button\n mat-icon-button\n type=\"button\"\n matSuffix\n (click)=\"resetId()\"\n [disabled]=\"!id.value\"\n >\n <mat-icon class=\"mat-warn\">close</mat-icon>\n </button>\n <button\n mat-icon-button\n type=\"button\"\n matSuffix\n (click)=\"pickId()\"\n [disabled]=\"idForm.invalid\"\n >\n <mat-icon class=\"mat-primary\">check_circle</mat-icon>\n </button>\n </mat-form-field>\n </form>\n </div>\n <!-- table -->\n <table>\n <thead>\n <th></th>\n <th>source</th>\n <th>value</th>\n </thead>\n <tbody>\n <!-- pin -->\n <tr>\n <td>\n <button\n type=\"button\"\n mat-icon-button\n (click)=\"appendIdComponent('pin')\"\n >\n <mat-icon class=\"mat-primary\">add_circle</mat-icon>\n </button>\n </td>\n <td>pin</td>\n <td>{{ info!.pin.value }}</td>\n </tr>\n <!-- item ID -->\n <tr>\n <td>\n <button\n type=\"button\"\n mat-icon-button\n (click)=\"appendIdComponent('itemId')\"\n >\n <mat-icon class=\"mat-primary\">add_circle</mat-icon>\n </button>\n </td>\n <td>item ID</td>\n <td>{{ info!.item?.id }}</td>\n </tr>\n <!-- item title -->\n <tr>\n <td></td>\n <td>item title</td>\n <td>{{ info!.item?.title }}</td>\n </tr>\n <!-- part ID -->\n <tr>\n <td>\n <button\n type=\"button\"\n mat-icon-button\n (click)=\"appendIdComponent('partId')\"\n >\n <mat-icon class=\"mat-primary\">add_circle</mat-icon>\n </button>\n </td>\n <td>part ID</td>\n <td>{{ info!.part?.id }}</td>\n </tr>\n <!-- part type ID -->\n <tr>\n <td>\n <button\n type=\"button\"\n mat-icon-button\n (click)=\"appendIdComponent('partTypeId')\"\n >\n <mat-icon class=\"mat-primary\">add_circle</mat-icon>\n </button>\n </td>\n <td>part type ID</td>\n <td>{{ info!.part?.typeId }}</td>\n </tr>\n <!-- part role ID -->\n <tr>\n <td>\n <button\n type=\"button\"\n mat-icon-button\n (click)=\"appendIdComponent('partRoleId')\"\n >\n <mat-icon class=\"mat-primary\">add_circle</mat-icon>\n </button>\n </td>\n <td>part role ID</td>\n <td>{{ info!.part?.roleId }}</td>\n </tr>\n <!-- part's metadata -->\n @for (m of info!.part?.metadata; track m; let i = $index) {\n <tr>\n <td>\n <button\n type=\"button\"\n mat-icon-button\n (click)=\"appendIdComponent('metadata', i)\"\n >\n <mat-icon class=\"mat-primary\">add_circle</mat-icon>\n </button>\n </td>\n <td class=\"metadata\">{{ m.name }}</td>\n <td class=\"metadata\">{{ m.value }}</td>\n </tr>\n }\n </tbody>\n </table>\n </mat-expansion-panel>\n }\n</div>\n", styles: [".metadata{color:#4a3001}table{border:1px solid silver;border-radius:6px;padding:4px;margin-top:8px}tr:nth-child(odd){background-color:#f0f0f0}th{font-weight:400;text-align:left;color:silver}\n"], dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1$1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$1.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i3.MatIconButton, selector: "button[mat-icon-button]", exportAs: ["matButton"] }, { kind: "ngmodule", type: MatExpansionModule }, { kind: "component", type: i4.MatExpansionPanel, selector: "mat-expansion-panel", inputs: ["hideToggle", "togglePosition"], outputs: ["afterExpand", "afterCollapse"], exportAs: ["matExpansionPanel"] }, { kind: "component", type: i4.MatExpansionPanelHeader, selector: "mat-expansion-panel-header", inputs: ["expandedHeight", "collapsedHeight", "tabIndex"] }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "component", type: i6.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i6.MatLabel, selector: "mat-label" }, { kind: "directive", type: i6.MatError, selector: "mat-error, [matError]", inputs: ["id"] }, { kind: "directive", type: i6.MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i7.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i8.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly", "disabledInteractive"], exportAs: ["matInput"] }, { kind: "ngmodule", type: MatSelectModule }, { kind: "component", type: i9.MatSelect, selector: "mat-select", inputs: ["aria-describedby", "panelClass", "disabled", "disableRipple", "tabIndex", "hideSingleSelectionIndicator", "placeholder", "required", "multiple", "disableOptionCentering", "compareWith", "value", "aria-label", "aria-labelledby", "errorStateMatcher", "typeaheadDebounceInterval", "sortComparator", "id", "panelWidth", "canSelectNullableOptions"], outputs: ["openedChange", "opened", "closed", "selectionChange", "valueChange"], exportAs: ["matSelect"] }, { kind: "component", type: i10.MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "component", type: RefLookupComponent, selector: "cadmus-ref-lookup", inputs: ["label", "limit", "baseFilter", "service", "item", "required", "hasMore", "linkTemplate", "optDialog", "options"], outputs: ["itemChange", "optionsChange", "moreRequest"] }] });
237
- }
238
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.5", ngImport: i0, type: ScopedPinLookupComponent, decorators: [{
239
- type: Component,
240
- args: [{ selector: 'cadmus-scoped-pin-lookup', imports: [
241
- FormsModule,
242
- ReactiveFormsModule,
243
- MatButtonModule,
244
- MatExpansionModule,
245
- MatFormFieldModule,
246
- MatIconModule,
247
- MatInputModule,
248
- MatSelectModule,
249
- RefLookupComponent,
250
- ], template: "<div>\n <!-- lookup -->\n <div>\n <form [formGroup]=\"keyForm\" class=\"form-row\">\n <!-- key -->\n @if (keys.length > 1) {\n <mat-form-field>\n <mat-label>type</mat-label>\n <mat-select [formControl]=\"key\">\n @for (k of keys; track k) {\n <mat-option [value]=\"k\">{{ k }}</mat-option>\n }\n </mat-select>\n @if ($any(key).errors?.required && (key.dirty || key.touched)) {\n <mat-error>type required</mat-error>\n }\n </mat-form-field>\n }\n <cadmus-ref-lookup\n [service]=\"lookupService\"\n label=\"pin\"\n [options]=\"key.value ? lookupDefs[key.value] : undefined\"\n (itemChange)=\"onItemChange($event)\"\n />\n </form>\n </div>\n\n <!-- builder -->\n @if (info) {\n <mat-expansion-panel [expanded]=\"info\" [disabled]=\"!info\">\n <mat-expansion-panel-header>ID builder</mat-expansion-panel-header>\n <!-- ID -->\n <div>\n <form [formGroup]=\"idForm\" (submit)=\"pickId()\">\n <mat-form-field style=\"width: 100%\">\n <input matInput [formControl]=\"id\" />\n @if ($any(id).errors?.required && (id.dirty || id.touched)) {\n <mat-error>ID required</mat-error>\n } @if ($any(id).errors?.maxLength && (id.dirty || id.touched)) {\n <mat-error>ID too long</mat-error>\n }\n <button\n mat-icon-button\n type=\"button\"\n matSuffix\n (click)=\"resetId()\"\n [disabled]=\"!id.value\"\n >\n <mat-icon class=\"mat-warn\">close</mat-icon>\n </button>\n <button\n mat-icon-button\n type=\"button\"\n matSuffix\n (click)=\"pickId()\"\n [disabled]=\"idForm.invalid\"\n >\n <mat-icon class=\"mat-primary\">check_circle</mat-icon>\n </button>\n </mat-form-field>\n </form>\n </div>\n <!-- table -->\n <table>\n <thead>\n <th></th>\n <th>source</th>\n <th>value</th>\n </thead>\n <tbody>\n <!-- pin -->\n <tr>\n <td>\n <button\n type=\"button\"\n mat-icon-button\n (click)=\"appendIdComponent('pin')\"\n >\n <mat-icon class=\"mat-primary\">add_circle</mat-icon>\n </button>\n </td>\n <td>pin</td>\n <td>{{ info!.pin.value }}</td>\n </tr>\n <!-- item ID -->\n <tr>\n <td>\n <button\n type=\"button\"\n mat-icon-button\n (click)=\"appendIdComponent('itemId')\"\n >\n <mat-icon class=\"mat-primary\">add_circle</mat-icon>\n </button>\n </td>\n <td>item ID</td>\n <td>{{ info!.item?.id }}</td>\n </tr>\n <!-- item title -->\n <tr>\n <td></td>\n <td>item title</td>\n <td>{{ info!.item?.title }}</td>\n </tr>\n <!-- part ID -->\n <tr>\n <td>\n <button\n type=\"button\"\n mat-icon-button\n (click)=\"appendIdComponent('partId')\"\n >\n <mat-icon class=\"mat-primary\">add_circle</mat-icon>\n </button>\n </td>\n <td>part ID</td>\n <td>{{ info!.part?.id }}</td>\n </tr>\n <!-- part type ID -->\n <tr>\n <td>\n <button\n type=\"button\"\n mat-icon-button\n (click)=\"appendIdComponent('partTypeId')\"\n >\n <mat-icon class=\"mat-primary\">add_circle</mat-icon>\n </button>\n </td>\n <td>part type ID</td>\n <td>{{ info!.part?.typeId }}</td>\n </tr>\n <!-- part role ID -->\n <tr>\n <td>\n <button\n type=\"button\"\n mat-icon-button\n (click)=\"appendIdComponent('partRoleId')\"\n >\n <mat-icon class=\"mat-primary\">add_circle</mat-icon>\n </button>\n </td>\n <td>part role ID</td>\n <td>{{ info!.part?.roleId }}</td>\n </tr>\n <!-- part's metadata -->\n @for (m of info!.part?.metadata; track m; let i = $index) {\n <tr>\n <td>\n <button\n type=\"button\"\n mat-icon-button\n (click)=\"appendIdComponent('metadata', i)\"\n >\n <mat-icon class=\"mat-primary\">add_circle</mat-icon>\n </button>\n </td>\n <td class=\"metadata\">{{ m.name }}</td>\n <td class=\"metadata\">{{ m.value }}</td>\n </tr>\n }\n </tbody>\n </table>\n </mat-expansion-panel>\n }\n</div>\n", styles: [".metadata{color:#4a3001}table{border:1px solid silver;border-radius:6px;padding:4px;margin-top:8px}tr:nth-child(odd){background-color:#f0f0f0}th{font-weight:400;text-align:left;color:silver}\n"] }]
251
- }], ctorParameters: () => [{ type: i1$1.FormBuilder }, { type: i1.ItemService }, { type: PinRefLookupService }, { type: undefined, decorators: [{
252
- type: Inject,
253
- args: ['indexLookupDefinitions']
254
- }] }] });
255
-
256
- /**
257
- * Asserted ID editor component.
258
- */
259
- class AssertedIdComponent {
260
- lookupService;
261
- lookupDefs;
262
- _sub;
263
- _updatingForm;
264
- tag;
265
- value;
266
- label;
267
- scope;
268
- assertion;
269
- form;
270
- lookupExpanded;
271
- // asserted-id-scopes
272
- idScopeEntries = input();
273
- // asserted-id-tags
274
- idTagEntries = input();
275
- // assertion-tags
276
- assTagEntries = input();
277
- // doc-reference-types
278
- refTypeEntries = input();
279
- // doc-reference-tags
280
- refTagEntries = input();
163
+ pinByTypeMode = model();
281
164
  /**
282
- * The asserted ID being edited.
165
+ * True when the user can switch between by-type and by-item mode.
283
166
  */
284
- id = model();
167
+ canSwitchMode = model();
285
168
  /**
286
- * True to hide the pin-based EID lookup UI.
169
+ * True when the user can edit the target's gid/label for internal
170
+ * targets.
287
171
  */
288
- noEidLookup = input();
172
+ canEditTarget = input();
289
173
  /**
290
- * True to show the submit button.
174
+ * The lookup definitions to be used for the by-type lookup. If
175
+ * not specified, the lookup definitions will be got via injection
176
+ * when available; if the injected definitions are empty, the
177
+ * lookup definitions will be built from the model-types thesaurus;
178
+ * if this is not available either, the by-type lookup will be
179
+ * disabled.
291
180
  */
292
- hasSubmit = input();
181
+ lookupDefinitions = model();
293
182
  /**
294
- * Emitted when the editor is closed.
183
+ * The optional configurations for using external lookup services.
184
+ */
185
+ extLookupConfigs = input([]);
186
+ /**
187
+ * True if when a new target is set it should be internal rather than
188
+ * external by default.
189
+ */
190
+ internalDefault = input();
191
+ /**
192
+ * The target to be edited.
193
+ */
194
+ target = model();
195
+ /**
196
+ * The default value for part type key when the by-type mode is active.
197
+ */
198
+ defaultPartTypeKey = input();
199
+ /**
200
+ * Emitted when user closes the editor.
295
201
  */
296
202
  editorClose = output();
297
- constructor(formBuilder, lookupService, lookupDefs) {
298
- this.lookupService = lookupService;
299
- this.lookupDefs = lookupDefs;
300
- this.tag = formBuilder.control(null, Validators.maxLength(50));
301
- this.value = formBuilder.control(null, [
302
- Validators.required,
303
- Validators.maxLength(500),
304
- ]);
305
- this.label = formBuilder.control(null, Validators.maxLength(500));
306
- this.scope = formBuilder.control(null, Validators.maxLength(500));
307
- this.assertion = formBuilder.control(null);
308
- this.form = formBuilder.group({
309
- tag: this.tag,
310
- value: this.value,
311
- label: this.label,
312
- scope: this.scope,
313
- assertion: this.assertion,
314
- });
315
- this.lookupExpanded = false;
316
- // when id changes, update form
317
- effect(() => {
318
- this.updateForm(this.id());
319
- });
320
- }
321
- ngOnInit() {
322
- this._sub = this.form.valueChanges
323
- .pipe(debounceTime(300))
324
- .subscribe((_) => {
325
- if (!this._updatingForm) {
326
- this.emitIdChange();
203
+ /**
204
+ * Emitted when the user requests more items from an external lookup.
205
+ */
206
+ extMoreRequest = output();
207
+ /**
208
+ * Emitted when the user changes the external lookup configuration.
209
+ */
210
+ extLookupConfigChange = output();
211
+ // by type
212
+ modelEntries;
213
+ partTypeKeys;
214
+ // by item
215
+ itemParts;
216
+ // form - by item
217
+ item;
218
+ itemPart;
219
+ // form - by type
220
+ partTypeKey;
221
+ // form - both
222
+ gid;
223
+ label;
224
+ byTypeMode;
225
+ external;
226
+ form;
227
+ filter;
228
+ pinFilterOptions;
229
+ lookupData;
230
+ constructor(_presetLookupDefs, itemLookupService, pinLookupService, _itemService, _thesService, _snackbar, formBuilder) {
231
+ this._presetLookupDefs = _presetLookupDefs;
232
+ this.itemLookupService = itemLookupService;
233
+ this.pinLookupService = pinLookupService;
234
+ this._itemService = _itemService;
235
+ this._thesService = _thesService;
236
+ this._snackbar = _snackbar;
237
+ this.partTypeKeys = [];
238
+ this.itemParts = [];
239
+ this.modelEntries = [];
240
+ // this is the default filter for the pin lookup, which will
241
+ // be merged with values provided by user here
242
+ this.filter = {
243
+ text: '',
244
+ limit: 10,
245
+ };
246
+ // form
247
+ this.item = formBuilder.control(null);
248
+ this.itemPart = formBuilder.control(null);
249
+ this.partTypeKey = formBuilder.control(null);
250
+ this.gid = formBuilder.control(null, [
251
+ Validators.required,
252
+ Validators.maxLength(300),
253
+ ]);
254
+ this.label = formBuilder.control(null, [
255
+ Validators.required,
256
+ Validators.maxLength(300),
257
+ ]);
258
+ this.byTypeMode = formBuilder.control(false, { nonNullable: true });
259
+ this.external = formBuilder.control(false, { nonNullable: true });
260
+ this.form = formBuilder.group({
261
+ item: this.item,
262
+ itemPart: this.itemPart,
263
+ partTypeKey: this.partTypeKey,
264
+ gid: this.gid,
265
+ label: this.label,
266
+ byTypeMode: this.byTypeMode,
267
+ external: this.external,
268
+ });
269
+ // when pinByTypeMode changes, adjust form
270
+ effect(() => {
271
+ if (!this.byTypeMode) {
272
+ this._startWithByTypeMode = this.pinByTypeMode();
273
+ }
274
+ else {
275
+ this.byTypeMode.setValue(this.pinByTypeMode() || false, {
276
+ emitEvent: false,
277
+ });
278
+ this.byTypeMode.updateValueAndValidity();
279
+ }
280
+ });
281
+ // when target changes, update form
282
+ effect(() => {
283
+ if (this._noFormUpdate) {
284
+ this._noFormUpdate = false;
285
+ return;
286
+ }
287
+ console.log('target changed', this.target());
288
+ this.updateForm(this.target());
289
+ });
290
+ }
291
+ forceByItem() {
292
+ this.pinByTypeMode.set(false);
293
+ this.canSwitchMode.set(false);
294
+ }
295
+ setupKeys() {
296
+ // use DI presets if no lookup definitions
297
+ if (!this.lookupDefinitions()) {
298
+ this.lookupDefinitions.set(this._presetLookupDefs);
299
+ }
300
+ // keys are all the defined lookup searches
301
+ this.partTypeKeys = Object.keys(this.lookupDefinitions());
302
+ // if no keys, get them from thesaurus model-types;
303
+ // if this is not available, just force by item mode.
304
+ if (!this.partTypeKeys.length) {
305
+ if (this.modelEntries?.length) {
306
+ // set lookupDefinitions from thesaurus entries
307
+ const defs = {};
308
+ this.modelEntries.forEach((e) => {
309
+ defs[e.value] = {
310
+ name: e.value,
311
+ typeId: e.id,
312
+ };
313
+ });
314
+ this.lookupDefinitions.set(defs);
315
+ // set type keys from thesaurus entries
316
+ this.partTypeKeys = this.modelEntries.map((e) => e.value);
327
317
  }
318
+ }
319
+ // if still no keys, force by item mode
320
+ if (!this.partTypeKeys.length) {
321
+ this.forceByItem();
322
+ }
323
+ else {
324
+ // set default key
325
+ this.partTypeKey.setValue(this.defaultPartTypeKey() || this.partTypeKeys[0]);
326
+ }
327
+ }
328
+ ngOnInit() {
329
+ // set start mode if required
330
+ if (this._startWithByTypeMode) {
331
+ this.byTypeMode.setValue(true);
332
+ }
333
+ // whenever item changes (by lookup), update item's parts and filter
334
+ this._subs.push(this.item.valueChanges
335
+ .pipe(distinctUntilChanged(), debounceTime(300))
336
+ .subscribe((item) => {
337
+ this.itemPart.setValue(null, { emitEvent: false });
338
+ this.itemParts = item?.parts || [];
339
+ this.filter = {
340
+ ...this.filter,
341
+ itemId: item?.id,
342
+ };
343
+ }));
344
+ // whenever itemPart changes (by user selection), update target and
345
+ // eventually gid
346
+ this._subs.push(this.itemPart.valueChanges
347
+ .pipe(distinctUntilChanged(), debounceTime(300))
348
+ .subscribe((part) => {
349
+ if (!this.gid.value || this.gid.pristine) {
350
+ this.gid.setValue(this.buildGid());
351
+ }
352
+ this.filter = {
353
+ ...this.filter,
354
+ partId: part?.id,
355
+ };
356
+ this.updateTarget(true);
357
+ }));
358
+ // whenever partTypeKey changes, update filter's options
359
+ this._subs.push(this.partTypeKey.valueChanges
360
+ .pipe(distinctUntilChanged(), debounceTime(300))
361
+ .subscribe((key) => {
362
+ this.pinFilterOptions = key
363
+ ? this.lookupDefinitions()[key]
364
+ : undefined;
365
+ }));
366
+ // whenever external changes, set required validator in label
367
+ // (true for external, false for internal)
368
+ this._subs.push(this.external.valueChanges
369
+ .pipe(distinctUntilChanged(), debounceTime(300))
370
+ .subscribe((external) => {
371
+ if (external) {
372
+ this.label.setValidators([
373
+ Validators.required,
374
+ Validators.maxLength(300),
375
+ ]);
376
+ }
377
+ else {
378
+ this.label.setValidators([Validators.maxLength(300)]);
379
+ }
380
+ this.label.updateValueAndValidity();
381
+ }));
382
+ // load model-types thesaurus entries
383
+ this._thesService.getThesaurus('model-types', true).subscribe({
384
+ next: (t) => {
385
+ this.modelEntries = t.entries || [];
386
+ if (this.modelEntries?.length) {
387
+ this.setupKeys();
388
+ }
389
+ else {
390
+ this.forceByItem();
391
+ }
392
+ },
393
+ error: () => {
394
+ this.forceByItem();
395
+ },
328
396
  });
329
397
  }
330
398
  ngOnDestroy() {
331
- this._sub?.unsubscribe();
399
+ for (let i = 0; i < this._subs.length; i++) {
400
+ this._subs[i].unsubscribe();
401
+ }
332
402
  }
333
- onAssertionChange(assertion) {
334
- this.assertion.setValue(assertion || null);
403
+ buildGid() {
404
+ // the GID is the part ID if any, or the item ID, followed by
405
+ // the pin's value (=EID)
406
+ const pin = this.lookupData?.pin;
407
+ if (!pin?.value) {
408
+ return null;
409
+ }
410
+ return pin.partId
411
+ ? `P${pin.partId}/${pin.value}`
412
+ : `I${pin.itemId}/${pin.value}`;
335
413
  }
336
- onIdPick(id) {
337
- this.value.setValue(id);
338
- this.value.markAsDirty();
339
- this.value.updateValueAndValidity();
340
- this.lookupExpanded = false;
414
+ buildLabel() {
415
+ if (!this.lookupData?.pin) {
416
+ return null;
417
+ }
418
+ const sb = [];
419
+ // pin value
420
+ if (this.lookupData.pin.value) {
421
+ sb.push(this.lookupData.pin.value);
422
+ sb.push(' | ');
423
+ }
424
+ // item title
425
+ sb.push(this.lookupData.item?.title || this.lookupData.pin?.itemId);
426
+ // part type and role
427
+ if (this.lookupData.pin.partTypeId) {
428
+ const e = this.modelEntries?.find((e) => e.id === this.lookupData.pin.partTypeId);
429
+ sb.push(' (');
430
+ sb.push(e?.value || this.lookupData.pin.partTypeId);
431
+ if (this.lookupData.pin.roleId) {
432
+ sb.push(`, ${this.lookupData.pin.roleId}`);
433
+ }
434
+ sb.push(')');
435
+ }
436
+ return sb.join('');
437
+ }
438
+ getTarget() {
439
+ if (this.external.value) {
440
+ return {
441
+ gid: this.gid.value || '',
442
+ label: this.label.value || '',
443
+ };
444
+ }
445
+ else {
446
+ const pin = this.lookupData?.pin;
447
+ return {
448
+ gid: this.gid.value || '',
449
+ label: this.label.value || '',
450
+ itemId: pin?.itemId || '',
451
+ partId: pin?.partId || '',
452
+ partTypeId: pin?.partTypeId || '',
453
+ roleId: pin?.roleId || '',
454
+ name: pin?.name || '',
455
+ value: pin?.value || '',
456
+ };
457
+ }
458
+ }
459
+ emitChange() {
460
+ this._noFormUpdate = true;
461
+ this.target.set(this.getTarget());
462
+ }
463
+ updateTarget(noEmit = false) {
464
+ if (this._noTargetUpdate) {
465
+ return;
466
+ }
467
+ if (!this.external.value) {
468
+ this.gid.setValue(this.buildGid());
469
+ this.gid.updateValueAndValidity();
470
+ this.gid.markAsDirty();
471
+ this.label.setValue(this.buildLabel());
472
+ this.label.updateValueAndValidity();
473
+ this.label.markAsDirty();
474
+ }
475
+ if (!noEmit) {
476
+ this.emitChange();
477
+ }
478
+ }
479
+ updateForm(target) {
480
+ // build pin info from target
481
+ if (!target) {
482
+ this.lookupData = undefined;
483
+ this.item.reset();
484
+ this.itemPart.reset();
485
+ this.gid.reset();
486
+ this.label.reset();
487
+ return;
488
+ }
489
+ this._noTargetUpdate = true;
490
+ this.gid.setValue(target.gid || '', { emitEvent: false });
491
+ this.label.setValue(target.label || '', { emitEvent: false });
492
+ this.lookupData = {
493
+ pin: {
494
+ itemId: target.itemId || '',
495
+ partId: target.partId || '',
496
+ partTypeId: target.partTypeId || '',
497
+ roleId: target.roleId || '',
498
+ name: target.name || '',
499
+ value: target.value || '',
500
+ },
501
+ };
502
+ // get item
503
+ if (target.itemId) {
504
+ this._itemService.getItem(target.itemId, true, true).subscribe({
505
+ next: (item) => {
506
+ this.item.setValue(item, { emitEvent: false });
507
+ this.form.markAsPristine();
508
+ this._noTargetUpdate = false;
509
+ this.external.setValue(!target.name, { emitEvent: false });
510
+ this.updateTarget();
511
+ },
512
+ error: (error) => {
513
+ if (error) {
514
+ console.error('Item service error', error);
515
+ }
516
+ this.external.setValue(!target.name, { emitEvent: false });
517
+ this._noTargetUpdate = false;
518
+ },
519
+ });
520
+ }
521
+ else {
522
+ this.external.setValue(!target.name && !this.internalDefault(), {
523
+ emitEvent: false,
524
+ });
525
+ this._noTargetUpdate = false;
526
+ this.updateTarget();
527
+ }
528
+ }
529
+ /**
530
+ * Called when the item lookup changes (item is looked up
531
+ * by its title).
532
+ *
533
+ * @param item The item got from lookup.
534
+ */
535
+ onItemLookupChange(item) {
536
+ if (!item) {
537
+ this.itemPart.setValue(null);
538
+ this.itemParts = [];
539
+ return;
540
+ }
541
+ // load item's parts
542
+ this._itemService.getItem(item.id, true, true).subscribe({
543
+ next: (i) => {
544
+ // setting the item will trigger its parts update
545
+ this.item.setValue(i);
546
+ this.updateTarget(true);
547
+ },
548
+ error: (error) => {
549
+ if (error) {
550
+ console.error('Error getting item', error);
551
+ }
552
+ this.itemPart.setValue(null);
553
+ this.itemParts = [];
554
+ this.updateTarget(true);
555
+ },
556
+ });
557
+ }
558
+ loadItemInfo(pin) {
559
+ if (!pin) {
560
+ return;
561
+ }
562
+ forkJoin({
563
+ item: this._itemService.getItem(pin.itemId, false, true),
564
+ part: this._itemService.getPartFromTypeAndRole(pin.itemId, METADATA_PART_ID$1, undefined, true),
565
+ })
566
+ .pipe(take(1))
567
+ .subscribe({
568
+ next: (result) => {
569
+ this.lookupData = {
570
+ pin: pin,
571
+ item: result.item,
572
+ metaPart: result.part,
573
+ };
574
+ this.updateTarget(true);
575
+ },
576
+ error: (error) => {
577
+ this.lookupData = undefined;
578
+ console.error('Error loading item/metadata', error);
579
+ },
580
+ });
581
+ }
582
+ /**
583
+ * Called when the pin lookup change. A pin is looked up by its
584
+ * name and value (=the filter's text), and optionally by:
585
+ * - its index lookup definition (selected by partTypeKey).
586
+ * - its item (defined by item, in filter).
587
+ * - its part (defined by itemPart, in filter).
588
+ *
589
+ * @param info The pin info from pin lookup.
590
+ */
591
+ onPinLookupChange(info) {
592
+ this.loadItemInfo(info);
341
593
  }
342
- updateForm(value) {
343
- this._updatingForm = true;
344
- if (!value) {
345
- this.form.reset();
346
- }
347
- else {
348
- this.tag.setValue(value.tag || null);
349
- this.value.setValue(value.value);
350
- this.label.setValue(value.label || null);
351
- this.scope.setValue(value.scope);
352
- this.assertion.setValue(value.assertion || null);
353
- this.form.markAsPristine();
594
+ onExtItemChange(event) {
595
+ if (event.item) {
596
+ setTimeout(() => {
597
+ this.gid.setValue(event.itemId);
598
+ this.gid.updateValueAndValidity();
599
+ this.gid.markAsDirty();
600
+ this.label.setValue(event.itemLabel);
601
+ this.label.updateValueAndValidity();
602
+ this.label.markAsDirty();
603
+ });
354
604
  }
355
- this._updatingForm = false;
356
605
  }
357
- getId() {
358
- return {
359
- tag: this.tag.value?.trim(),
360
- value: this.value.value?.trim() || '',
361
- label: this.label.value?.trim() || undefined,
362
- scope: this.scope.value?.trim() || '',
363
- assertion: this.assertion.value || undefined,
364
- };
606
+ onExtMoreRequest(event) {
607
+ this.extMoreRequest.emit(event);
365
608
  }
366
- emitIdChange() {
367
- if (!this.hasSubmit()) {
368
- this.id.set(this.getId());
369
- }
609
+ onCopied() {
610
+ this._snackbar.open('Copied to clipboard', 'OK', {
611
+ duration: 1500,
612
+ });
370
613
  }
371
- cancel() {
614
+ onExtConfigChange(config) {
615
+ this.extLookupConfigChange.emit(config);
616
+ }
617
+ close() {
372
618
  this.editorClose.emit();
373
619
  }
374
620
  save() {
375
- if (this.form.valid) {
376
- this.id.set(this.getId());
621
+ if (this.form.invalid) {
622
+ return;
377
623
  }
624
+ this.target.set(this.getTarget());
625
+ this.emitChange();
378
626
  }
379
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.5", ngImport: i0, type: AssertedIdComponent, deps: [{ token: i1$1.FormBuilder }, { token: PinRefLookupService }, { token: 'indexLookupDefinitions' }], target: i0.ɵɵFactoryTarget.Component });
380
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.0.5", type: AssertedIdComponent, isStandalone: true, selector: "cadmus-refs-asserted-id", inputs: { idScopeEntries: { classPropertyName: "idScopeEntries", publicName: "idScopeEntries", isSignal: true, isRequired: false, transformFunction: null }, idTagEntries: { classPropertyName: "idTagEntries", publicName: "idTagEntries", isSignal: true, isRequired: false, transformFunction: null }, assTagEntries: { classPropertyName: "assTagEntries", publicName: "assTagEntries", isSignal: true, isRequired: false, transformFunction: null }, refTypeEntries: { classPropertyName: "refTypeEntries", publicName: "refTypeEntries", isSignal: true, isRequired: false, transformFunction: null }, refTagEntries: { classPropertyName: "refTagEntries", publicName: "refTagEntries", isSignal: true, isRequired: false, transformFunction: null }, id: { classPropertyName: "id", publicName: "id", isSignal: true, isRequired: false, transformFunction: null }, noEidLookup: { classPropertyName: "noEidLookup", publicName: "noEidLookup", isSignal: true, isRequired: false, transformFunction: null }, hasSubmit: { classPropertyName: "hasSubmit", publicName: "hasSubmit", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { id: "idChange", editorClose: "editorClose" }, ngImport: i0, template: "<form [formGroup]=\"form\" (submit)=\"save()\">\n <div>\n <div class=\"form-row\">\n <!-- tag (bound) -->\n @if (idTagEntries()?.length) {\n <mat-form-field>\n <mat-label>tag</mat-label>\n <mat-select [formControl]=\"tag\">\n @for (e of idTagEntries(); track e) {\n <mat-option [value]=\"e.id\">{{ e.value }}</mat-option>\n }\n </mat-select>\n </mat-form-field>\n }\n <!-- tag (free) -->\n @else {\n <mat-form-field>\n <mat-label>tag</mat-label>\n <input matInput [formControl]=\"tag\" />\n @if ($any(tag.errors)?.maxLength && (tag.dirty || tag.touched)) {\n <mat-error>tag too long</mat-error>\n }\n </mat-form-field>\n }\n\n <!-- scope (bound) -->\n @if (idScopeEntries()?.length) {\n <mat-form-field>\n <mat-label>scope</mat-label>\n <mat-select [formControl]=\"scope\">\n @for (e of idScopeEntries(); track e) {\n <mat-option [value]=\"e.id\">{{ e.value }}</mat-option>\n }\n </mat-select>\n </mat-form-field>\n }\n <!-- scope (free) -->\n @else {\n <mat-form-field>\n <mat-label>scope</mat-label>\n <input matInput [formControl]=\"scope\" />\n @if ($any(scope.errors)?.maxLength && (scope.dirty || scope.touched)) {\n <mat-error>scope too long</mat-error>\n }\n </mat-form-field>\n }\n\n <!-- value -->\n <mat-form-field>\n <mat-label>value</mat-label>\n <input matInput [formControl]=\"value\" />\n @if ($any(value.errors)?.required && (value.dirty || value.touched)) {\n <mat-error>value required</mat-error>\n } @if ($any(value.errors)?.maxLength && (value.dirty || value.touched))\n {\n <mat-error>value too long</mat-error>\n }\n </mat-form-field>\n\n <!-- label -->\n <mat-form-field>\n <mat-label>label</mat-label>\n <input matInput [formControl]=\"label\" />\n @if ($any(label.errors)?.maxLength && (label.dirty || label.touched)) {\n <mat-error>label too long</mat-error>\n }\n </mat-form-field>\n\n <!-- lookup -->\n @if (!noEidLookup()) {\n <div>\n <mat-expansion-panel [(expanded)]=\"lookupExpanded\">\n <mat-expansion-panel-header>lookup</mat-expansion-panel-header>\n <cadmus-scoped-pin-lookup\n (idPick)=\"onIdPick($event)\"\n ></cadmus-scoped-pin-lookup>\n </mat-expansion-panel>\n </div>\n }\n </div>\n\n <!-- assertion -->\n <mat-expansion-panel>\n <mat-expansion-panel-header>assertion</mat-expansion-panel-header>\n <cadmus-refs-assertion\n [assTagEntries]=\"assTagEntries()\"\n [refTypeEntries]=\"refTypeEntries()\"\n [refTagEntries]=\"refTagEntries()\"\n [assertion]=\"assertion.value || undefined\"\n (assertionChange)=\"onAssertionChange($event)\"\n >\n </cadmus-refs-assertion>\n </mat-expansion-panel>\n </div>\n\n <!-- buttons -->\n @if (hasSubmit()) {\n <div>\n <button mat-icon-button type=\"button\" (click)=\"cancel()\">\n <mat-icon class=\"mat-warn\">close</mat-icon>\n </button>\n <button mat-icon-button type=\"submit\" [disabled]=\"form.invalid\">\n <mat-icon class=\"mat-primary\">check_circle</mat-icon>\n </button>\n </div>\n }\n</form>\n", styles: [".form-row{display:flex;gap:8px;align-items:flex-start;flex-wrap:wrap}.form-row *{flex:0 0 auto}.pin-info{font-size:90%;color:silver}fieldset{border:1px solid silver;border-radius:6px;padding:6px}@media only screen and (max-width: 959px){div#container{grid-template-rows:1fr auto;grid-template-columns:1fr;grid-template-areas:\"editor\" \"lookup\"}}\n"], dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1$1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$1.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i3.MatIconButton, selector: "button[mat-icon-button]", exportAs: ["matButton"] }, { kind: "ngmodule", type: MatExpansionModule }, { kind: "component", type: i4.MatExpansionPanel, selector: "mat-expansion-panel", inputs: ["hideToggle", "togglePosition"], outputs: ["afterExpand", "afterCollapse"], exportAs: ["matExpansionPanel"] }, { kind: "component", type: i4.MatExpansionPanelHeader, selector: "mat-expansion-panel-header", inputs: ["expandedHeight", "collapsedHeight", "tabIndex"] }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "component", type: i6.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i6.MatLabel, selector: "mat-label" }, { kind: "directive", type: i6.MatError, selector: "mat-error, [matError]", inputs: ["id"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i7.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i8.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly", "disabledInteractive"], exportAs: ["matInput"] }, { kind: "ngmodule", type: MatSelectModule }, { kind: "component", type: i9.MatSelect, selector: "mat-select", inputs: ["aria-describedby", "panelClass", "disabled", "disableRipple", "tabIndex", "hideSingleSelectionIndicator", "placeholder", "required", "multiple", "disableOptionCentering", "compareWith", "value", "aria-label", "aria-labelledby", "errorStateMatcher", "typeaheadDebounceInterval", "sortComparator", "id", "panelWidth", "canSelectNullableOptions"], outputs: ["openedChange", "opened", "closed", "selectionChange", "valueChange"], exportAs: ["matSelect"] }, { kind: "component", type: i10.MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "component", type: AssertionComponent, selector: "cadmus-refs-assertion", inputs: ["assTagEntries", "refTypeEntries", "refTagEntries", "assertion"], outputs: ["assertionChange"] }, { kind: "component", type: ScopedPinLookupComponent, selector: "cadmus-scoped-pin-lookup", outputs: ["idPick"] }] });
627
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.0", ngImport: i0, type: PinTargetLookupComponent, deps: [{ token: 'indexLookupDefinitions' }, { token: ItemRefLookupService }, { token: PinRefLookupService }, { token: i1.ItemService }, { token: i1.ThesaurusService }, { token: i4.MatSnackBar }, { token: i1$1.FormBuilder }], target: i0.ɵɵFactoryTarget.Component });
628
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.0.0", type: PinTargetLookupComponent, isStandalone: true, selector: "cadmus-pin-target-lookup", inputs: { pinByTypeMode: { classPropertyName: "pinByTypeMode", publicName: "pinByTypeMode", isSignal: true, isRequired: false, transformFunction: null }, canSwitchMode: { classPropertyName: "canSwitchMode", publicName: "canSwitchMode", isSignal: true, isRequired: false, transformFunction: null }, canEditTarget: { classPropertyName: "canEditTarget", publicName: "canEditTarget", isSignal: true, isRequired: false, transformFunction: null }, lookupDefinitions: { classPropertyName: "lookupDefinitions", publicName: "lookupDefinitions", isSignal: true, isRequired: false, transformFunction: null }, extLookupConfigs: { classPropertyName: "extLookupConfigs", publicName: "extLookupConfigs", isSignal: true, isRequired: false, transformFunction: null }, internalDefault: { classPropertyName: "internalDefault", publicName: "internalDefault", isSignal: true, isRequired: false, transformFunction: null }, target: { classPropertyName: "target", publicName: "target", isSignal: true, isRequired: false, transformFunction: null }, defaultPartTypeKey: { classPropertyName: "defaultPartTypeKey", publicName: "defaultPartTypeKey", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { pinByTypeMode: "pinByTypeModeChange", canSwitchMode: "canSwitchModeChange", lookupDefinitions: "lookupDefinitionsChange", target: "targetChange", editorClose: "editorClose", extMoreRequest: "extMoreRequest", extLookupConfigChange: "extLookupConfigChange" }, ngImport: i0, template: "<form [formGroup]=\"form\" (submit)=\"save()\">\r\n <div class=\"form-row\">\r\n <!-- external -->\r\n <mat-checkbox [formControl]=\"external\">external</mat-checkbox>\r\n <!-- mode switcher -->\r\n @if (!external.value) {\r\n <div>\r\n @if (canSwitchMode()) {\r\n <mat-checkbox [formControl]=\"byTypeMode\"> by type</mat-checkbox>\r\n }\r\n </div>\r\n }\r\n </div>\r\n\r\n <div class=\"form-row\">\r\n <!-- label -->\r\n <div>\r\n @if (external.value || canEditTarget()) {\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 } @if ( $any(label).errors?.maxLength && (label.dirty || label.touched)\r\n ) {\r\n <mat-error>label too long</mat-error>\r\n }\r\n </mat-form-field>\r\n } @if (!external.value && !canEditTarget() && label.value) {\r\n <div class=\"info\"><span class=\"label\">label</span>{{ label.value }}</div>\r\n }\r\n </div>\r\n\r\n <!-- gid -->\r\n <div>\r\n @if (external.value || canEditTarget()) {\r\n <mat-form-field>\r\n <mat-label>GID</mat-label>\r\n <input matInput [formControl]=\"gid\" />\r\n @if ($any(gid).errors?.required && (gid.dirty || gid.touched)) {\r\n <mat-error>GID required</mat-error>\r\n } @if ($any(gid).errors?.maxLength && (gid.dirty || gid.touched)) {\r\n <mat-error>GID too long</mat-error>\r\n }\r\n </mat-form-field>\r\n } @if (!external.value && !canEditTarget() && gid.value) {\r\n <div class=\"info\">\r\n <span class=\"label\">GID</span> <span class=\"gid\">{{ gid.value }}</span>\r\n </div>\r\n }\r\n </div>\r\n </div>\r\n\r\n <!-- external lookup set -->\r\n @if (external.value && extLookupConfigs().length) {\r\n <fieldset>\r\n <legend>external lookup</legend>\r\n <cadmus-ref-lookup-set\r\n [configs]=\"extLookupConfigs()\"\r\n (itemChange)=\"onExtItemChange($event)\"\r\n (moreRequest)=\"onExtMoreRequest($event)\"\r\n (configChange)=\"onExtConfigChange($any($event))\"\r\n />\r\n </fieldset>\r\n }\r\n\r\n <!-- BY ITEM -->\r\n @if (!external.value) {\r\n <fieldset>\r\n <legend>internal lookup</legend>\r\n <div class=\"form-row\">\r\n @if (!byTypeMode.value) {\r\n <fieldset class=\"form-row\">\r\n <legend>pin filters</legend>\r\n <!-- item filter -->\r\n <cadmus-ref-lookup\r\n [service]=\"itemLookupService\"\r\n label=\"item\"\r\n (itemChange)=\"onItemLookupChange($event)\"\r\n />\r\n <!-- part filter -->\r\n @if (itemParts.length) {\r\n <mat-form-field>\r\n <mat-label>part</mat-label>\r\n <mat-select [formControl]=\"itemPart\">\r\n <mat-option [value]=\"null\">(any)</mat-option>\r\n @for (p of itemParts; track p) {\r\n <mat-option [value]=\"p\">{{\r\n p.typeId | flatLookup : modelEntries : \"id\" : \"value\"\r\n }}</mat-option>\r\n }\r\n </mat-select>\r\n <mat-hint>parts: {{ itemParts.length }}</mat-hint>\r\n </mat-form-field>\r\n }\r\n </fieldset>\r\n }\r\n <!-- BY TYPE -->\r\n @if (byTypeMode.value) {\r\n <div>\r\n <!-- part type filter -->\r\n @if (partTypeKeys.length) {\r\n <mat-form-field>\r\n <mat-label>part type</mat-label>\r\n <mat-select [formControl]=\"partTypeKey\">\r\n @for (k of partTypeKeys; track k) {\r\n <mat-option [value]=\"k\">{{ k }}</mat-option>\r\n }\r\n </mat-select>\r\n </mat-form-field>\r\n }\r\n </div>\r\n }\r\n <!-- PIN -->\r\n @if (partTypeKey.value) {\r\n <div>\r\n <!-- pin lookup -->\r\n <cadmus-ref-lookup\r\n [service]=\"pinLookupService\"\r\n [baseFilter]=\"filter\"\r\n [options]=\"pinFilterOptions\"\r\n label=\"pin\"\r\n (itemChange)=\"onPinLookupChange($event)\"\r\n />\r\n </div>\r\n }\r\n </div>\r\n <!-- data -->\r\n @if (lookupData?.pin?.name) {\r\n <mat-expansion-panel id=\"data\">\r\n <mat-expansion-panel-header>pin data</mat-expansion-panel-header>\r\n <!-- table -->\r\n <table>\r\n <thead>\r\n <th></th>\r\n <th>source</th>\r\n <th>value</th>\r\n </thead>\r\n <tbody>\r\n <!-- pin -->\r\n @if (lookupData?.pin?.value) {\r\n <tr>\r\n <td class=\"fit-width\">\r\n <button\r\n type=\"button\"\r\n mat-icon-button\r\n matTooltip=\"Copy value\"\r\n [cdkCopyToClipboard]=\"lookupData!.pin!.value\"\r\n (cdkCopyToClipboardCopied)=\"onCopied()\"\r\n >\r\n <mat-icon class=\"mat-primary\">content_copy</mat-icon>\r\n </button>\r\n </td>\r\n <td>pin</td>\r\n <td>{{ lookupData!.pin.value }}</td>\r\n </tr>\r\n }\r\n <!-- item ID -->\r\n @if (lookupData?.pin?.itemId) {\r\n <tr>\r\n <td>\r\n <button\r\n type=\"button\"\r\n mat-icon-button\r\n [cdkCopyToClipboard]=\"lookupData!.pin!.itemId\"\r\n (cdkCopyToClipboardCopied)=\"onCopied()\"\r\n >\r\n <mat-icon class=\"mat-primary\">content_copy</mat-icon>\r\n </button>\r\n </td>\r\n <td>item ID</td>\r\n <td>{{ lookupData!.pin.itemId }}</td>\r\n </tr>\r\n }\r\n <!-- item title -->\r\n @if (lookupData?.item?.title) {\r\n <tr>\r\n <td>\r\n <button\r\n type=\"button\"\r\n mat-icon-button\r\n [cdkCopyToClipboard]=\"lookupData!.item!.title\"\r\n (cdkCopyToClipboardCopied)=\"onCopied()\"\r\n >\r\n <mat-icon class=\"mat-primary\">content_copy</mat-icon>\r\n </button>\r\n </td>\r\n <td>item title</td>\r\n <td>{{ lookupData!.item!.title }}</td>\r\n </tr>\r\n }\r\n <!-- part ID -->\r\n @if (lookupData?.pin?.partId) {\r\n <tr>\r\n <td>\r\n <button\r\n type=\"button\"\r\n mat-icon-button\r\n [cdkCopyToClipboard]=\"lookupData!.pin!.partId\"\r\n (cdkCopyToClipboardCopied)=\"onCopied()\"\r\n >\r\n <mat-icon class=\"mat-primary\">content_copy</mat-icon>\r\n </button>\r\n </td>\r\n <td>part ID</td>\r\n <td>{{ lookupData!.pin.partId }}</td>\r\n </tr>\r\n }\r\n <!-- part type ID -->\r\n @if (lookupData?.pin?.partTypeId) {\r\n <tr>\r\n <td>\r\n <button\r\n type=\"button\"\r\n mat-icon-button\r\n [cdkCopyToClipboard]=\"lookupData!.pin!.partTypeId\"\r\n (cdkCopyToClipboardCopied)=\"onCopied()\"\r\n >\r\n <mat-icon class=\"mat-primary\">content_copy</mat-icon>\r\n </button>\r\n </td>\r\n <td>part type ID</td>\r\n <td>{{ lookupData!.pin!.partTypeId }}</td>\r\n </tr>\r\n }\r\n <!-- part role ID -->\r\n @if (lookupData?.pin?.roleId) {\r\n <tr>\r\n <td>\r\n <button\r\n type=\"button\"\r\n mat-icon-button\r\n [cdkCopyToClipboard]=\"lookupData!.pin!.roleId!\"\r\n (cdkCopyToClipboardCopied)=\"onCopied()\"\r\n >\r\n <mat-icon class=\"mat-primary\">content_copy</mat-icon>\r\n </button>\r\n </td>\r\n <td>part role ID</td>\r\n <td>{{ lookupData!.pin!.roleId }}</td>\r\n </tr>\r\n }\r\n <!-- part's metadata -->\r\n @for ( m of lookupData?.metaPart?.metadata || []; track m; let i =\r\n $index) {\r\n <tr>\r\n <td>\r\n <button\r\n type=\"button\"\r\n mat-icon-button\r\n [cdkCopyToClipboard]=\"m.value\"\r\n (cdkCopyToClipboardCopied)=\"onCopied()\"\r\n >\r\n <mat-icon class=\"mat-primary\">content_copy</mat-icon>\r\n </button>\r\n </td>\r\n <td class=\"metadata\">{{ m.name }}</td>\r\n <td class=\"metadata\">{{ m.value }}</td>\r\n </tr>\r\n }\r\n </tbody>\r\n </table>\r\n </mat-expansion-panel>\r\n }\r\n </fieldset>\r\n }\r\n\r\n <!-- buttons -->\r\n <div class=\"button-row\" id=\"toolbar\">\r\n <button mat-icon-button type=\"button\" (click)=\"close()\">\r\n <mat-icon class=\"mat-warn\">close</mat-icon>\r\n </button>\r\n <button mat-flat-button type=\"submit\" [disabled]=\"form.invalid\">\r\n <mat-icon>check_circle</mat-icon>\r\n target\r\n </button>\r\n </div>\r\n</form>\r\n", styles: [".metadata{color:#4a3001}.info{border:1px solid silver;border-radius:6px;background-color:silver;color:#fff;padding:4px;margin:8px 0}.info .label{background-color:#fff;color:silver;margin:0 6px}#data{margin:8px 0}table{border:1px solid silver;border-radius:6px;padding:4px;margin-top:8px}tr:nth-child(odd){background-color:#f0f0f0}td.fit-width{width:1px;white-space:nowrap}th{font-weight:400;text-align:left;color:silver}.form-row{display:flex;gap:8px;align-items:center;flex-wrap:wrap}.form-row *{flex:0 0 auto}.button-row{display:flex;align-items:center;flex-wrap:wrap}.label{border:1px solid silver;border-radius:6px;padding:4px}fieldset{border:1px solid silver;border-radius:6px;padding:8px;margin-bottom:8px}legend{color:silver}div#toolbar{margin-top:8px}\n"], dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1$1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$1.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "ngmodule", type:
629
+ // material
630
+ ClipboardModule }, { kind: "directive", type: i6.CdkCopyToClipboard, selector: "[cdkCopyToClipboard]", inputs: ["cdkCopyToClipboard", "cdkCopyToClipboardAttempts"], outputs: ["cdkCopyToClipboardCopied"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i3.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: i3.MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "ngmodule", type: MatCheckboxModule }, { kind: "component", type: i8.MatCheckbox, selector: "mat-checkbox", inputs: ["aria-label", "aria-labelledby", "aria-describedby", "aria-expanded", "aria-controls", "aria-owns", "id", "required", "labelPosition", "name", "value", "disableRipple", "tabIndex", "color", "disabledInteractive", "checked", "disabled", "indeterminate"], outputs: ["change", "indeterminateChange"], exportAs: ["matCheckbox"] }, { kind: "ngmodule", type: MatExpansionModule }, { kind: "component", type: i4$1.MatExpansionPanel, selector: "mat-expansion-panel", inputs: ["hideToggle", "togglePosition"], outputs: ["afterExpand", "afterCollapse"], exportAs: ["matExpansionPanel"] }, { kind: "component", type: i4$1.MatExpansionPanelHeader, selector: "mat-expansion-panel-header", inputs: ["expandedHeight", "collapsedHeight", "tabIndex"] }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "component", type: i6$1.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i6$1.MatLabel, selector: "mat-label" }, { kind: "directive", type: i6$1.MatHint, selector: "mat-hint", inputs: ["align", "id"] }, { kind: "directive", type: i6$1.MatError, selector: "mat-error, [matError]", inputs: ["id"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i7.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i8$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: MatSelectModule }, { kind: "component", type: i9.MatSelect, selector: "mat-select", inputs: ["aria-describedby", "panelClass", "disabled", "disableRipple", "tabIndex", "hideSingleSelectionIndicator", "placeholder", "required", "multiple", "disableOptionCentering", "compareWith", "value", "aria-label", "aria-labelledby", "errorStateMatcher", "typeaheadDebounceInterval", "sortComparator", "id", "panelWidth", "canSelectNullableOptions"], outputs: ["openedChange", "opened", "closed", "selectionChange", "valueChange"], exportAs: ["matSelect"] }, { kind: "component", type: i9.MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i14.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "pipe", type:
631
+ // myrmidon
632
+ FlatLookupPipe, name: "flatLookup" }, { kind: "component", type:
633
+ // bricks
634
+ RefLookupComponent, selector: "cadmus-ref-lookup", inputs: ["label", "limit", "baseFilter", "service", "item", "required", "hasMore", "linkTemplate", "optDialog", "options"], outputs: ["itemChange", "optionsChange", "moreRequest"] }, { kind: "component", type: RefLookupSetComponent, selector: "cadmus-ref-lookup-set", inputs: ["configs", "iconSize"], outputs: ["configChange", "itemChange", "moreRequest"] }] });
381
635
  }
382
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.5", ngImport: i0, type: AssertedIdComponent, decorators: [{
636
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.0", ngImport: i0, type: PinTargetLookupComponent, decorators: [{
383
637
  type: Component,
384
- args: [{ selector: 'cadmus-refs-asserted-id', imports: [
638
+ args: [{ selector: 'cadmus-pin-target-lookup', imports: [
385
639
  FormsModule,
386
640
  ReactiveFormsModule,
641
+ // material
642
+ ClipboardModule,
387
643
  MatButtonModule,
644
+ MatCheckboxModule,
388
645
  MatExpansionModule,
389
646
  MatFormFieldModule,
390
647
  MatIconModule,
391
648
  MatInputModule,
392
649
  MatSelectModule,
393
- AssertionComponent,
394
- ScopedPinLookupComponent,
395
- ], template: "<form [formGroup]=\"form\" (submit)=\"save()\">\n <div>\n <div class=\"form-row\">\n <!-- tag (bound) -->\n @if (idTagEntries()?.length) {\n <mat-form-field>\n <mat-label>tag</mat-label>\n <mat-select [formControl]=\"tag\">\n @for (e of idTagEntries(); track e) {\n <mat-option [value]=\"e.id\">{{ e.value }}</mat-option>\n }\n </mat-select>\n </mat-form-field>\n }\n <!-- tag (free) -->\n @else {\n <mat-form-field>\n <mat-label>tag</mat-label>\n <input matInput [formControl]=\"tag\" />\n @if ($any(tag.errors)?.maxLength && (tag.dirty || tag.touched)) {\n <mat-error>tag too long</mat-error>\n }\n </mat-form-field>\n }\n\n <!-- scope (bound) -->\n @if (idScopeEntries()?.length) {\n <mat-form-field>\n <mat-label>scope</mat-label>\n <mat-select [formControl]=\"scope\">\n @for (e of idScopeEntries(); track e) {\n <mat-option [value]=\"e.id\">{{ e.value }}</mat-option>\n }\n </mat-select>\n </mat-form-field>\n }\n <!-- scope (free) -->\n @else {\n <mat-form-field>\n <mat-label>scope</mat-label>\n <input matInput [formControl]=\"scope\" />\n @if ($any(scope.errors)?.maxLength && (scope.dirty || scope.touched)) {\n <mat-error>scope too long</mat-error>\n }\n </mat-form-field>\n }\n\n <!-- value -->\n <mat-form-field>\n <mat-label>value</mat-label>\n <input matInput [formControl]=\"value\" />\n @if ($any(value.errors)?.required && (value.dirty || value.touched)) {\n <mat-error>value required</mat-error>\n } @if ($any(value.errors)?.maxLength && (value.dirty || value.touched))\n {\n <mat-error>value too long</mat-error>\n }\n </mat-form-field>\n\n <!-- label -->\n <mat-form-field>\n <mat-label>label</mat-label>\n <input matInput [formControl]=\"label\" />\n @if ($any(label.errors)?.maxLength && (label.dirty || label.touched)) {\n <mat-error>label too long</mat-error>\n }\n </mat-form-field>\n\n <!-- lookup -->\n @if (!noEidLookup()) {\n <div>\n <mat-expansion-panel [(expanded)]=\"lookupExpanded\">\n <mat-expansion-panel-header>lookup</mat-expansion-panel-header>\n <cadmus-scoped-pin-lookup\n (idPick)=\"onIdPick($event)\"\n ></cadmus-scoped-pin-lookup>\n </mat-expansion-panel>\n </div>\n }\n </div>\n\n <!-- assertion -->\n <mat-expansion-panel>\n <mat-expansion-panel-header>assertion</mat-expansion-panel-header>\n <cadmus-refs-assertion\n [assTagEntries]=\"assTagEntries()\"\n [refTypeEntries]=\"refTypeEntries()\"\n [refTagEntries]=\"refTagEntries()\"\n [assertion]=\"assertion.value || undefined\"\n (assertionChange)=\"onAssertionChange($event)\"\n >\n </cadmus-refs-assertion>\n </mat-expansion-panel>\n </div>\n\n <!-- buttons -->\n @if (hasSubmit()) {\n <div>\n <button mat-icon-button type=\"button\" (click)=\"cancel()\">\n <mat-icon class=\"mat-warn\">close</mat-icon>\n </button>\n <button mat-icon-button type=\"submit\" [disabled]=\"form.invalid\">\n <mat-icon class=\"mat-primary\">check_circle</mat-icon>\n </button>\n </div>\n }\n</form>\n", styles: [".form-row{display:flex;gap:8px;align-items:flex-start;flex-wrap:wrap}.form-row *{flex:0 0 auto}.pin-info{font-size:90%;color:silver}fieldset{border:1px solid silver;border-radius:6px;padding:6px}@media only screen and (max-width: 959px){div#container{grid-template-rows:1fr auto;grid-template-columns:1fr;grid-template-areas:\"editor\" \"lookup\"}}\n"] }]
396
- }], ctorParameters: () => [{ type: i1$1.FormBuilder }, { type: PinRefLookupService }, { type: undefined, decorators: [{
650
+ MatTooltipModule,
651
+ // myrmidon
652
+ FlatLookupPipe,
653
+ // bricks
654
+ RefLookupComponent,
655
+ RefLookupSetComponent,
656
+ ], template: "<form [formGroup]=\"form\" (submit)=\"save()\">\r\n <div class=\"form-row\">\r\n <!-- external -->\r\n <mat-checkbox [formControl]=\"external\">external</mat-checkbox>\r\n <!-- mode switcher -->\r\n @if (!external.value) {\r\n <div>\r\n @if (canSwitchMode()) {\r\n <mat-checkbox [formControl]=\"byTypeMode\"> by type</mat-checkbox>\r\n }\r\n </div>\r\n }\r\n </div>\r\n\r\n <div class=\"form-row\">\r\n <!-- label -->\r\n <div>\r\n @if (external.value || canEditTarget()) {\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 } @if ( $any(label).errors?.maxLength && (label.dirty || label.touched)\r\n ) {\r\n <mat-error>label too long</mat-error>\r\n }\r\n </mat-form-field>\r\n } @if (!external.value && !canEditTarget() && label.value) {\r\n <div class=\"info\"><span class=\"label\">label</span>{{ label.value }}</div>\r\n }\r\n </div>\r\n\r\n <!-- gid -->\r\n <div>\r\n @if (external.value || canEditTarget()) {\r\n <mat-form-field>\r\n <mat-label>GID</mat-label>\r\n <input matInput [formControl]=\"gid\" />\r\n @if ($any(gid).errors?.required && (gid.dirty || gid.touched)) {\r\n <mat-error>GID required</mat-error>\r\n } @if ($any(gid).errors?.maxLength && (gid.dirty || gid.touched)) {\r\n <mat-error>GID too long</mat-error>\r\n }\r\n </mat-form-field>\r\n } @if (!external.value && !canEditTarget() && gid.value) {\r\n <div class=\"info\">\r\n <span class=\"label\">GID</span> <span class=\"gid\">{{ gid.value }}</span>\r\n </div>\r\n }\r\n </div>\r\n </div>\r\n\r\n <!-- external lookup set -->\r\n @if (external.value && extLookupConfigs().length) {\r\n <fieldset>\r\n <legend>external lookup</legend>\r\n <cadmus-ref-lookup-set\r\n [configs]=\"extLookupConfigs()\"\r\n (itemChange)=\"onExtItemChange($event)\"\r\n (moreRequest)=\"onExtMoreRequest($event)\"\r\n (configChange)=\"onExtConfigChange($any($event))\"\r\n />\r\n </fieldset>\r\n }\r\n\r\n <!-- BY ITEM -->\r\n @if (!external.value) {\r\n <fieldset>\r\n <legend>internal lookup</legend>\r\n <div class=\"form-row\">\r\n @if (!byTypeMode.value) {\r\n <fieldset class=\"form-row\">\r\n <legend>pin filters</legend>\r\n <!-- item filter -->\r\n <cadmus-ref-lookup\r\n [service]=\"itemLookupService\"\r\n label=\"item\"\r\n (itemChange)=\"onItemLookupChange($event)\"\r\n />\r\n <!-- part filter -->\r\n @if (itemParts.length) {\r\n <mat-form-field>\r\n <mat-label>part</mat-label>\r\n <mat-select [formControl]=\"itemPart\">\r\n <mat-option [value]=\"null\">(any)</mat-option>\r\n @for (p of itemParts; track p) {\r\n <mat-option [value]=\"p\">{{\r\n p.typeId | flatLookup : modelEntries : \"id\" : \"value\"\r\n }}</mat-option>\r\n }\r\n </mat-select>\r\n <mat-hint>parts: {{ itemParts.length }}</mat-hint>\r\n </mat-form-field>\r\n }\r\n </fieldset>\r\n }\r\n <!-- BY TYPE -->\r\n @if (byTypeMode.value) {\r\n <div>\r\n <!-- part type filter -->\r\n @if (partTypeKeys.length) {\r\n <mat-form-field>\r\n <mat-label>part type</mat-label>\r\n <mat-select [formControl]=\"partTypeKey\">\r\n @for (k of partTypeKeys; track k) {\r\n <mat-option [value]=\"k\">{{ k }}</mat-option>\r\n }\r\n </mat-select>\r\n </mat-form-field>\r\n }\r\n </div>\r\n }\r\n <!-- PIN -->\r\n @if (partTypeKey.value) {\r\n <div>\r\n <!-- pin lookup -->\r\n <cadmus-ref-lookup\r\n [service]=\"pinLookupService\"\r\n [baseFilter]=\"filter\"\r\n [options]=\"pinFilterOptions\"\r\n label=\"pin\"\r\n (itemChange)=\"onPinLookupChange($event)\"\r\n />\r\n </div>\r\n }\r\n </div>\r\n <!-- data -->\r\n @if (lookupData?.pin?.name) {\r\n <mat-expansion-panel id=\"data\">\r\n <mat-expansion-panel-header>pin data</mat-expansion-panel-header>\r\n <!-- table -->\r\n <table>\r\n <thead>\r\n <th></th>\r\n <th>source</th>\r\n <th>value</th>\r\n </thead>\r\n <tbody>\r\n <!-- pin -->\r\n @if (lookupData?.pin?.value) {\r\n <tr>\r\n <td class=\"fit-width\">\r\n <button\r\n type=\"button\"\r\n mat-icon-button\r\n matTooltip=\"Copy value\"\r\n [cdkCopyToClipboard]=\"lookupData!.pin!.value\"\r\n (cdkCopyToClipboardCopied)=\"onCopied()\"\r\n >\r\n <mat-icon class=\"mat-primary\">content_copy</mat-icon>\r\n </button>\r\n </td>\r\n <td>pin</td>\r\n <td>{{ lookupData!.pin.value }}</td>\r\n </tr>\r\n }\r\n <!-- item ID -->\r\n @if (lookupData?.pin?.itemId) {\r\n <tr>\r\n <td>\r\n <button\r\n type=\"button\"\r\n mat-icon-button\r\n [cdkCopyToClipboard]=\"lookupData!.pin!.itemId\"\r\n (cdkCopyToClipboardCopied)=\"onCopied()\"\r\n >\r\n <mat-icon class=\"mat-primary\">content_copy</mat-icon>\r\n </button>\r\n </td>\r\n <td>item ID</td>\r\n <td>{{ lookupData!.pin.itemId }}</td>\r\n </tr>\r\n }\r\n <!-- item title -->\r\n @if (lookupData?.item?.title) {\r\n <tr>\r\n <td>\r\n <button\r\n type=\"button\"\r\n mat-icon-button\r\n [cdkCopyToClipboard]=\"lookupData!.item!.title\"\r\n (cdkCopyToClipboardCopied)=\"onCopied()\"\r\n >\r\n <mat-icon class=\"mat-primary\">content_copy</mat-icon>\r\n </button>\r\n </td>\r\n <td>item title</td>\r\n <td>{{ lookupData!.item!.title }}</td>\r\n </tr>\r\n }\r\n <!-- part ID -->\r\n @if (lookupData?.pin?.partId) {\r\n <tr>\r\n <td>\r\n <button\r\n type=\"button\"\r\n mat-icon-button\r\n [cdkCopyToClipboard]=\"lookupData!.pin!.partId\"\r\n (cdkCopyToClipboardCopied)=\"onCopied()\"\r\n >\r\n <mat-icon class=\"mat-primary\">content_copy</mat-icon>\r\n </button>\r\n </td>\r\n <td>part ID</td>\r\n <td>{{ lookupData!.pin.partId }}</td>\r\n </tr>\r\n }\r\n <!-- part type ID -->\r\n @if (lookupData?.pin?.partTypeId) {\r\n <tr>\r\n <td>\r\n <button\r\n type=\"button\"\r\n mat-icon-button\r\n [cdkCopyToClipboard]=\"lookupData!.pin!.partTypeId\"\r\n (cdkCopyToClipboardCopied)=\"onCopied()\"\r\n >\r\n <mat-icon class=\"mat-primary\">content_copy</mat-icon>\r\n </button>\r\n </td>\r\n <td>part type ID</td>\r\n <td>{{ lookupData!.pin!.partTypeId }}</td>\r\n </tr>\r\n }\r\n <!-- part role ID -->\r\n @if (lookupData?.pin?.roleId) {\r\n <tr>\r\n <td>\r\n <button\r\n type=\"button\"\r\n mat-icon-button\r\n [cdkCopyToClipboard]=\"lookupData!.pin!.roleId!\"\r\n (cdkCopyToClipboardCopied)=\"onCopied()\"\r\n >\r\n <mat-icon class=\"mat-primary\">content_copy</mat-icon>\r\n </button>\r\n </td>\r\n <td>part role ID</td>\r\n <td>{{ lookupData!.pin!.roleId }}</td>\r\n </tr>\r\n }\r\n <!-- part's metadata -->\r\n @for ( m of lookupData?.metaPart?.metadata || []; track m; let i =\r\n $index) {\r\n <tr>\r\n <td>\r\n <button\r\n type=\"button\"\r\n mat-icon-button\r\n [cdkCopyToClipboard]=\"m.value\"\r\n (cdkCopyToClipboardCopied)=\"onCopied()\"\r\n >\r\n <mat-icon class=\"mat-primary\">content_copy</mat-icon>\r\n </button>\r\n </td>\r\n <td class=\"metadata\">{{ m.name }}</td>\r\n <td class=\"metadata\">{{ m.value }}</td>\r\n </tr>\r\n }\r\n </tbody>\r\n </table>\r\n </mat-expansion-panel>\r\n }\r\n </fieldset>\r\n }\r\n\r\n <!-- buttons -->\r\n <div class=\"button-row\" id=\"toolbar\">\r\n <button mat-icon-button type=\"button\" (click)=\"close()\">\r\n <mat-icon class=\"mat-warn\">close</mat-icon>\r\n </button>\r\n <button mat-flat-button type=\"submit\" [disabled]=\"form.invalid\">\r\n <mat-icon>check_circle</mat-icon>\r\n target\r\n </button>\r\n </div>\r\n</form>\r\n", styles: [".metadata{color:#4a3001}.info{border:1px solid silver;border-radius:6px;background-color:silver;color:#fff;padding:4px;margin:8px 0}.info .label{background-color:#fff;color:silver;margin:0 6px}#data{margin:8px 0}table{border:1px solid silver;border-radius:6px;padding:4px;margin-top:8px}tr:nth-child(odd){background-color:#f0f0f0}td.fit-width{width:1px;white-space:nowrap}th{font-weight:400;text-align:left;color:silver}.form-row{display:flex;gap:8px;align-items:center;flex-wrap:wrap}.form-row *{flex:0 0 auto}.button-row{display:flex;align-items:center;flex-wrap:wrap}.label{border:1px solid silver;border-radius:6px;padding:4px}fieldset{border:1px solid silver;border-radius:6px;padding:8px;margin-bottom:8px}legend{color:silver}div#toolbar{margin-top:8px}\n"] }]
657
+ }], ctorParameters: () => [{ type: undefined, decorators: [{
397
658
  type: Inject,
398
659
  args: ['indexLookupDefinitions']
399
- }] }] });
660
+ }] }, { type: ItemRefLookupService }, { type: PinRefLookupService }, { type: i1.ItemService }, { type: i1.ThesaurusService }, { type: i4.MatSnackBar }, { type: i1$1.FormBuilder }] });
400
661
 
401
662
  /**
402
- * Asserted IDs editor.
663
+ * The key to be used to retrieve the external lookup configs from the
664
+ * settings storage. This is equal to the selector of
665
+ * AssertedCompositeIdComponent plus ".configs".
403
666
  */
404
- class AssertedIdsComponent {
405
- _dialogService;
406
- _editedIndex;
407
- edited;
408
- /**
409
- * The asserted IDs.
410
- */
411
- ids = model([]);
667
+ const ASSERTED_COMPOSITE_ID_CONFIGS_KEY = 'cadmus-refs-asserted-composite-id.configs';
668
+ /**
669
+ * An asserted composite ID editor. This allows the user to edit an asserted
670
+ * composite ID, which can be an external ID or a lookup ID.
671
+ */
672
+ class AssertedCompositeIdComponent {
673
+ lookupService;
674
+ lookupDefs;
675
+ _sub;
676
+ _updatingForm;
677
+ extLookupConfigs;
678
+ targetExpanded = false;
679
+ // form
680
+ target;
681
+ scope;
682
+ tag;
683
+ assertion;
684
+ form;
412
685
  // asserted-id-scopes
413
686
  idScopeEntries = input();
414
- // asserted-id-tags
415
- idTagEntries = input();
416
- // assertion-tags
417
- assTagEntries = input();
418
- // doc-reference-types
419
- refTypeEntries = input();
420
- // doc-reference-tags
421
- refTagEntries = input();
422
- entries;
423
- form;
424
- constructor(formBuilder, _dialogService) {
425
- this._dialogService = _dialogService;
426
- this._editedIndex = -1;
427
- this.entries = formBuilder.control([], { nonNullable: true });
428
- // form
429
- this.form = formBuilder.group({
430
- ids: this.entries,
431
- });
432
- // when ids change, update form
433
- effect(() => {
434
- this.updateForm(this.ids());
435
- });
436
- }
437
- updateForm(ids) {
438
- if (!ids?.length) {
439
- this.form.reset();
440
- return;
441
- }
442
- this.entries.setValue(ids, { emitEvent: false });
443
- this.entries.updateValueAndValidity();
444
- this.form.markAsPristine();
445
- }
446
- addId() {
447
- this.editId({
448
- scope: '',
449
- value: '',
450
- }, -1);
451
- }
452
- editId(id, index) {
453
- this._editedIndex = index;
454
- this.edited = id;
455
- }
456
- closeId() {
457
- this._editedIndex = -1;
458
- this.edited = undefined;
459
- }
460
- saveId(entry) {
461
- const entries = [...this.entries.value];
462
- if (this._editedIndex === -1) {
463
- entries.push(entry);
464
- }
465
- else {
466
- entries.splice(this._editedIndex, 1, entry);
467
- }
468
- this.entries.setValue(entries);
469
- this.entries.markAsDirty();
470
- this.entries.updateValueAndValidity();
471
- this.closeId();
472
- }
473
- deleteId(index) {
474
- this._dialogService
475
- .confirm('Confirmation', 'Delete ID?')
476
- .pipe(take(1))
477
- .subscribe((yes) => {
478
- if (yes) {
479
- if (this._editedIndex === index) {
480
- this.closeId();
481
- }
482
- const entries = [...this.entries.value];
483
- entries.splice(index, 1);
484
- this.entries.setValue(entries);
485
- this.entries.markAsDirty();
486
- this.entries.updateValueAndValidity();
487
- this.ids.set(this.entries.value);
488
- }
489
- });
490
- }
491
- moveIdUp(index) {
492
- if (index < 1) {
493
- return;
494
- }
495
- const entry = this.entries.value[index];
496
- const entries = [...this.entries.value];
497
- entries.splice(index, 1);
498
- entries.splice(index - 1, 0, entry);
499
- this.entries.setValue(entries);
500
- this.entries.markAsDirty();
501
- this.entries.updateValueAndValidity();
502
- this.ids.set(this.entries.value);
503
- }
504
- moveIdDown(index) {
505
- if (index + 1 >= this.entries.value.length) {
506
- return;
507
- }
508
- const entry = this.entries.value[index];
509
- const entries = [...this.entries.value];
510
- entries.splice(index, 1);
511
- entries.splice(index + 1, 0, entry);
512
- this.entries.setValue(entries);
513
- this.entries.markAsDirty();
514
- this.entries.updateValueAndValidity();
515
- this.ids.set(this.entries.value);
516
- }
517
- onIdChange(id) {
518
- this.saveId(id);
519
- this.ids.set(this.entries.value);
520
- }
521
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.5", ngImport: i0, type: AssertedIdsComponent, deps: [{ token: i1$1.FormBuilder }, { token: i2.DialogService }], target: i0.ɵɵFactoryTarget.Component });
522
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.0.5", type: AssertedIdsComponent, isStandalone: true, selector: "cadmus-refs-asserted-ids", inputs: { ids: { classPropertyName: "ids", publicName: "ids", isSignal: true, isRequired: false, transformFunction: null }, idScopeEntries: { classPropertyName: "idScopeEntries", publicName: "idScopeEntries", isSignal: true, isRequired: false, transformFunction: null }, idTagEntries: { classPropertyName: "idTagEntries", publicName: "idTagEntries", isSignal: true, isRequired: false, transformFunction: null }, assTagEntries: { classPropertyName: "assTagEntries", publicName: "assTagEntries", isSignal: true, isRequired: false, transformFunction: null }, refTypeEntries: { classPropertyName: "refTypeEntries", publicName: "refTypeEntries", isSignal: true, isRequired: false, transformFunction: null }, refTagEntries: { classPropertyName: "refTagEntries", publicName: "refTagEntries", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { ids: "idsChange" }, ngImport: i0, template: "<form [formGroup]=\"form\">\n <div>\n <button type=\"button\" mat-flat-button class=\"mat-primary\" (click)=\"addId()\">\n <mat-icon>add_circle</mat-icon> ID\n </button>\n </div>\n @if (entries.value.length) {\n <table>\n <thead>\n <tr>\n <th></th>\n <th>scope</th>\n <th>value</th>\n </tr>\n </thead>\n <tbody>\n @for ( entry of entries.value; track entry; let i = $index; let first =\n $first; let last = $last) {\n <tr [class.selected]=\"entry === edited\">\n <td class=\"fit-width\">\n <button\n type=\"button\"\n mat-icon-button\n matTooltip=\"Edit this ID\"\n (click)=\"editId(entry, i)\"\n >\n <mat-icon class=\"mat-primary\">edit</mat-icon>\n </button>\n <button\n type=\"button\"\n mat-icon-button\n matTooltip=\"Move this ID up\"\n [disabled]=\"first\"\n (click)=\"moveIdUp(i)\"\n >\n <mat-icon>arrow_upward</mat-icon>\n </button>\n <button\n type=\"button\"\n mat-icon-button\n matTooltip=\"Move this ID down\"\n [disabled]=\"last\"\n (click)=\"moveIdDown(i)\"\n >\n <mat-icon>arrow_downward</mat-icon>\n </button>\n <button\n type=\"button\"\n mat-icon-button\n matTooltip=\"Delete this ID\"\n (click)=\"deleteId(i)\"\n >\n <mat-icon class=\"mat-warn\">remove_circle</mat-icon>\n </button>\n </td>\n <td>{{ entry.scope }}</td>\n <td>{{ entry.value }}</td>\n </tr>\n }\n </tbody>\n </table>\n }\n\n <mat-expansion-panel [expanded]=\"edited\" [disabled]=\"!edited\">\n <mat-expansion-panel-header\n >ID {{ edited?.value }}</mat-expansion-panel-header\n >\n <cadmus-refs-asserted-id\n [idScopeEntries]=\"idScopeEntries()\"\n [idTagEntries]=\"idTagEntries()\"\n [assTagEntries]=\"assTagEntries()\"\n [refTypeEntries]=\"refTypeEntries()\"\n [refTagEntries]=\"refTagEntries()\"\n [hasSubmit]=\"true\"\n [id]=\"edited\"\n (idChange)=\"onIdChange($event)\"\n (editorClose)=\"closeId()\"\n ></cadmus-refs-asserted-id>\n </mat-expansion-panel>\n</form>\n", styles: ["table{width:100%;border-collapse:collapse}tbody tr:nth-child(odd){background-color:#e2e2e2}th{text-align:left;font-weight:400;color:silver}td.fit-width{width:1px;white-space:nowrap}tr.selected{background-color:#d0d0d0!important}fieldset{border:1px solid silver;border-radius:6px;padding:6px}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1$1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i3.MatButton, selector: " button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ", exportAs: ["matButton"] }, { kind: "component", type: i3.MatIconButton, selector: "button[mat-icon-button]", exportAs: ["matButton"] }, { kind: "ngmodule", type: MatExpansionModule }, { kind: "component", type: i4.MatExpansionPanel, selector: "mat-expansion-panel", inputs: ["hideToggle", "togglePosition"], outputs: ["afterExpand", "afterCollapse"], exportAs: ["matExpansionPanel"] }, { kind: "component", type: i4.MatExpansionPanelHeader, selector: "mat-expansion-panel-header", inputs: ["expandedHeight", "collapsedHeight", "tabIndex"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i7.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i6$1.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "component", type: AssertedIdComponent, selector: "cadmus-refs-asserted-id", inputs: ["idScopeEntries", "idTagEntries", "assTagEntries", "refTypeEntries", "refTagEntries", "id", "noEidLookup", "hasSubmit"], outputs: ["idChange", "editorClose"] }] });
523
- }
524
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.5", ngImport: i0, type: AssertedIdsComponent, decorators: [{
525
- type: Component,
526
- args: [{ selector: 'cadmus-refs-asserted-ids', imports: [
527
- CommonModule,
528
- FormsModule,
529
- ReactiveFormsModule,
530
- MatButtonModule,
531
- MatExpansionModule,
532
- MatIconModule,
533
- MatTooltipModule,
534
- AssertedIdComponent,
535
- ], template: "<form [formGroup]=\"form\">\n <div>\n <button type=\"button\" mat-flat-button class=\"mat-primary\" (click)=\"addId()\">\n <mat-icon>add_circle</mat-icon> ID\n </button>\n </div>\n @if (entries.value.length) {\n <table>\n <thead>\n <tr>\n <th></th>\n <th>scope</th>\n <th>value</th>\n </tr>\n </thead>\n <tbody>\n @for ( entry of entries.value; track entry; let i = $index; let first =\n $first; let last = $last) {\n <tr [class.selected]=\"entry === edited\">\n <td class=\"fit-width\">\n <button\n type=\"button\"\n mat-icon-button\n matTooltip=\"Edit this ID\"\n (click)=\"editId(entry, i)\"\n >\n <mat-icon class=\"mat-primary\">edit</mat-icon>\n </button>\n <button\n type=\"button\"\n mat-icon-button\n matTooltip=\"Move this ID up\"\n [disabled]=\"first\"\n (click)=\"moveIdUp(i)\"\n >\n <mat-icon>arrow_upward</mat-icon>\n </button>\n <button\n type=\"button\"\n mat-icon-button\n matTooltip=\"Move this ID down\"\n [disabled]=\"last\"\n (click)=\"moveIdDown(i)\"\n >\n <mat-icon>arrow_downward</mat-icon>\n </button>\n <button\n type=\"button\"\n mat-icon-button\n matTooltip=\"Delete this ID\"\n (click)=\"deleteId(i)\"\n >\n <mat-icon class=\"mat-warn\">remove_circle</mat-icon>\n </button>\n </td>\n <td>{{ entry.scope }}</td>\n <td>{{ entry.value }}</td>\n </tr>\n }\n </tbody>\n </table>\n }\n\n <mat-expansion-panel [expanded]=\"edited\" [disabled]=\"!edited\">\n <mat-expansion-panel-header\n >ID {{ edited?.value }}</mat-expansion-panel-header\n >\n <cadmus-refs-asserted-id\n [idScopeEntries]=\"idScopeEntries()\"\n [idTagEntries]=\"idTagEntries()\"\n [assTagEntries]=\"assTagEntries()\"\n [refTypeEntries]=\"refTypeEntries()\"\n [refTagEntries]=\"refTagEntries()\"\n [hasSubmit]=\"true\"\n [id]=\"edited\"\n (idChange)=\"onIdChange($event)\"\n (editorClose)=\"closeId()\"\n ></cadmus-refs-asserted-id>\n </mat-expansion-panel>\n</form>\n", styles: ["table{width:100%;border-collapse:collapse}tbody tr:nth-child(odd){background-color:#e2e2e2}th{text-align:left;font-weight:400;color:silver}td.fit-width{width:1px;white-space:nowrap}tr.selected{background-color:#d0d0d0!important}fieldset{border:1px solid silver;border-radius:6px;padding:6px}\n"] }]
536
- }], ctorParameters: () => [{ type: i1$1.FormBuilder }, { type: i2.DialogService }] });
537
-
538
- class ItemRefLookupService {
539
- _itemService;
540
- constructor(_itemService) {
541
- this._itemService = _itemService;
542
- }
543
- lookup(filter, options) {
544
- return this._itemService
545
- .getItems({
546
- title: filter.text,
547
- }, 1, filter.limit || 10)
548
- .pipe(map((page) => page.items));
549
- }
550
- getName(item) {
551
- return item?.title;
552
- }
553
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.5", ngImport: i0, type: ItemRefLookupService, deps: [{ token: i1.ItemService }], target: i0.ɵɵFactoryTarget.Injectable });
554
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.0.5", ngImport: i0, type: ItemRefLookupService, providedIn: 'root' });
555
- }
556
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.5", ngImport: i0, type: ItemRefLookupService, decorators: [{
557
- type: Injectable,
558
- args: [{
559
- providedIn: 'root',
560
- }]
561
- }], ctorParameters: () => [{ type: i1.ItemService }] });
562
-
563
- // from Cadmus general parts
564
- const METADATA_PART_ID = 'it.vedph.metadata';
565
- /*
566
- * Scoped pin-based lookup component. This component provides a list
567
- * of pin-based searches, with a lookup control. Whenever the user
568
- * picks a pin value, he gets the details about its item and part, and
569
- * item's metadata part, if any. He can then use these data to build
570
- * some EID by variously assembling these components.
571
- */
572
- class PinTargetLookupComponent {
573
- _presetLookupDefs;
574
- itemLookupService;
575
- pinLookupService;
576
- _itemService;
577
- _thesService;
578
- _snackbar;
579
- _subs = [];
580
- _noTargetUpdate;
581
- _noFormUpdate;
582
- _startWithByTypeMode;
687
+ // asserted-id-tags
688
+ idTagEntries = input();
689
+ // assertion-tags
690
+ assTagEntries = input();
691
+ // doc-reference-types
692
+ refTypeEntries = input();
693
+ // doc-reference-tags
694
+ refTagEntries = input();
583
695
  /**
584
- * True when the by-type pin lookup mode is active.
585
- * User can change mode unless modeSwitching is false.
696
+ * The ID being edited.
586
697
  */
587
- pinByTypeMode = model();
698
+ id = model();
588
699
  /**
589
- * True when the user can switch between by-type and by-item mode.
700
+ * True if when a new ID is set it should be internal rather than
701
+ * external by default.
590
702
  */
591
- canSwitchMode = model();
703
+ internalDefault = input();
592
704
  /**
593
- * True when the user can edit the target's gid/label for internal
594
- * targets.
705
+ * True if the UI has a submit button.
595
706
  */
596
- canEditTarget = input();
707
+ hasSubmit = input();
597
708
  /**
598
- * The lookup definitions to be used for the by-type lookup. If
599
- * not specified, the lookup definitions will be got via injection
600
- * when available; if the injected definitions are empty, the
601
- * lookup definitions will be built from the model-types thesaurus;
602
- * if this is not available either, the by-type lookup will be
603
- * disabled.
709
+ * True when the internal UI preselected mode should be by type rather than
710
+ * by item. User can change mode unless modeSwitching is false.
604
711
  */
605
- lookupDefinitions = model();
712
+ pinByTypeMode = input();
606
713
  /**
607
- * The optional configurations for using external lookup services.
714
+ * True when the user can switch between by-type and by-item mode in
715
+ * the internal UI.
608
716
  */
609
- extLookupConfigs = input([]);
717
+ canSwitchMode = input();
610
718
  /**
611
- * True if when a new target is set it should be internal rather than
612
- * external by default.
719
+ * True when the user can edit the target's gid/label for internal targets.
613
720
  */
614
- internalDefault = input();
721
+ canEditTarget = input();
615
722
  /**
616
- * The target to be edited.
723
+ * The lookup definitions to be used for the by-type lookup in the internal UI.
724
+ * If not specified, the lookup definitions will be got via injection
725
+ * when available; if the injected definitions are empty, the
726
+ * lookup definitions will be built from the model-types thesaurus;
727
+ * if this is not available either, the by-type lookup will be
728
+ * disabled.
617
729
  */
618
- target = model();
730
+ lookupDefinitions = input();
619
731
  /**
620
- * The default value for part type key when the by-type mode is active.
732
+ * The default part type key to be used.
621
733
  */
622
734
  defaultPartTypeKey = input();
623
735
  /**
624
- * Emitted when user closes the editor.
736
+ * Emitted whenever the user requests to close the editor.
625
737
  */
626
738
  editorClose = output();
627
739
  /**
628
- * Emitted when the user requests more items from an external lookup.
740
+ * Emitted when the user requests more.
629
741
  */
630
742
  extMoreRequest = output();
631
- /**
632
- * Emitted when the user changes the external lookup configuration.
633
- */
634
- extLookupConfigChange = output();
635
- // by type
636
- modelEntries;
637
- partTypeKeys;
638
- // by item
639
- itemParts;
640
- // form - by item
641
- item;
642
- itemPart;
643
- // form - by type
644
- partTypeKey;
645
- // form - both
646
- gid;
647
- label;
648
- byTypeMode;
649
- external;
650
- form;
651
- filter;
652
- pinFilterOptions;
653
- lookupData;
654
- constructor(_presetLookupDefs, itemLookupService, pinLookupService, _itemService, _thesService, _snackbar, formBuilder) {
655
- this._presetLookupDefs = _presetLookupDefs;
656
- this.itemLookupService = itemLookupService;
657
- this.pinLookupService = pinLookupService;
658
- this._itemService = _itemService;
659
- this._thesService = _thesService;
660
- this._snackbar = _snackbar;
661
- this.partTypeKeys = [];
662
- this.itemParts = [];
663
- this.modelEntries = [];
664
- // this is the default filter for the pin lookup, which will
665
- // be merged with values provided by user here
666
- this.filter = {
667
- text: '',
668
- limit: 10,
669
- };
743
+ constructor(formBuilder, lookupService, lookupDefs, settings) {
744
+ this.lookupService = lookupService;
745
+ this.lookupDefs = lookupDefs;
670
746
  // form
671
- this.item = formBuilder.control(null);
672
- this.itemPart = formBuilder.control(null);
673
- this.partTypeKey = formBuilder.control(null);
674
- this.gid = formBuilder.control(null, [
675
- Validators.required,
676
- Validators.maxLength(300),
677
- ]);
678
- this.label = formBuilder.control(null, [
679
- Validators.required,
680
- Validators.maxLength(300),
681
- ]);
682
- this.byTypeMode = formBuilder.control(false, { nonNullable: true });
683
- this.external = formBuilder.control(false, { nonNullable: true });
747
+ this.target = formBuilder.control(null, Validators.required);
748
+ this.scope = formBuilder.control(null, Validators.maxLength(500));
749
+ this.tag = formBuilder.control(null, Validators.maxLength(50));
750
+ this.assertion = formBuilder.control(null);
684
751
  this.form = formBuilder.group({
685
- item: this.item,
686
- itemPart: this.itemPart,
687
- partTypeKey: this.partTypeKey,
688
- gid: this.gid,
689
- label: this.label,
690
- byTypeMode: this.byTypeMode,
691
- external: this.external,
692
- });
693
- // when pinByTypeMode changes, adjust form
694
- effect(() => {
695
- if (!this.byTypeMode) {
696
- this._startWithByTypeMode = this.pinByTypeMode();
697
- }
698
- else {
699
- this.byTypeMode.setValue(this.pinByTypeMode() || false, {
700
- emitEvent: false,
701
- });
702
- this.byTypeMode.updateValueAndValidity();
703
- }
752
+ target: this.target,
753
+ scope: this.scope,
754
+ tag: this.tag,
755
+ assertion: this.assertion,
704
756
  });
705
- // when target changes, update form
757
+ // external lookup configs
758
+ this.extLookupConfigs =
759
+ settings.retrieve(ASSERTED_COMPOSITE_ID_CONFIGS_KEY) ||
760
+ [];
761
+ // when id changes, update form
706
762
  effect(() => {
707
- if (this._noFormUpdate) {
708
- this._noFormUpdate = false;
709
- return;
710
- }
711
- console.log('target changed', this.target());
712
- this.updateForm(this.target());
763
+ this.updateForm(this.id());
713
764
  });
714
765
  }
715
- forceByItem() {
716
- this.pinByTypeMode.set(false);
717
- this.canSwitchMode.set(false);
718
- }
719
- setupKeys() {
720
- // use DI presets if no lookup definitions
721
- if (!this.lookupDefinitions()) {
722
- this.lookupDefinitions.set(this._presetLookupDefs);
723
- }
724
- // keys are all the defined lookup searches
725
- this.partTypeKeys = Object.keys(this.lookupDefinitions());
726
- // if no keys, get them from thesaurus model-types;
727
- // if this is not available, just force by item mode.
728
- if (!this.partTypeKeys.length) {
729
- if (this.modelEntries?.length) {
730
- // set lookupDefinitions from thesaurus entries
731
- const defs = {};
732
- this.modelEntries.forEach((e) => {
733
- defs[e.value] = {
734
- name: e.value,
735
- typeId: e.id,
736
- };
737
- });
738
- this.lookupDefinitions.set(defs);
739
- // set type keys from thesaurus entries
740
- this.partTypeKeys = this.modelEntries.map((e) => e.value);
741
- }
742
- }
743
- // if still no keys, force by item mode
744
- if (!this.partTypeKeys.length) {
745
- this.forceByItem();
746
- }
747
- else {
748
- // set default key
749
- this.partTypeKey.setValue(this.defaultPartTypeKey() || this.partTypeKeys[0]);
750
- }
751
- }
752
766
  ngOnInit() {
753
- // set start mode if required
754
- if (this._startWithByTypeMode) {
755
- this.byTypeMode.setValue(true);
756
- }
757
- // whenever item changes (by lookup), update item's parts and filter
758
- this._subs.push(this.item.valueChanges
759
- .pipe(distinctUntilChanged(), debounceTime$1(300))
760
- .subscribe((item) => {
761
- this.itemPart.setValue(null, { emitEvent: false });
762
- this.itemParts = item?.parts || [];
763
- this.filter = {
764
- ...this.filter,
765
- itemId: item?.id,
766
- };
767
- }));
768
- // whenever itemPart changes (by user selection), update target and
769
- // eventually gid
770
- this._subs.push(this.itemPart.valueChanges
771
- .pipe(distinctUntilChanged(), debounceTime$1(300))
772
- .subscribe((part) => {
773
- if (!this.gid.value || this.gid.pristine) {
774
- this.gid.setValue(this.buildGid());
775
- }
776
- this.filter = {
777
- ...this.filter,
778
- partId: part?.id,
779
- };
780
- this.updateTarget(true);
781
- }));
782
- // whenever partTypeKey changes, update filter's options
783
- this._subs.push(this.partTypeKey.valueChanges
784
- .pipe(distinctUntilChanged(), debounceTime$1(300))
785
- .subscribe((key) => {
786
- this.pinFilterOptions = key
787
- ? this.lookupDefinitions()[key]
788
- : undefined;
789
- }));
790
- // whenever external changes, set required validator in label
791
- // (true for external, false for internal)
792
- this._subs.push(this.external.valueChanges
793
- .pipe(distinctUntilChanged(), debounceTime$1(300))
794
- .subscribe((external) => {
795
- if (external) {
796
- this.label.setValidators([
797
- Validators.required,
798
- Validators.maxLength(300),
799
- ]);
800
- }
801
- else {
802
- this.label.setValidators([Validators.maxLength(300)]);
767
+ this._sub = this.form.valueChanges
768
+ .pipe(debounceTime$1(300))
769
+ .subscribe((_) => {
770
+ if (!this._updatingForm) {
771
+ this.emitIdChange();
803
772
  }
804
- this.label.updateValueAndValidity();
805
- }));
806
- // load model-types thesaurus entries
807
- this._thesService.getThesaurus('model-types', true).subscribe({
808
- next: (t) => {
809
- this.modelEntries = t.entries || [];
810
- if (this.modelEntries?.length) {
811
- this.setupKeys();
812
- }
813
- else {
814
- this.forceByItem();
815
- }
816
- },
817
- error: () => {
818
- this.forceByItem();
819
- },
820
773
  });
821
774
  }
822
775
  ngOnDestroy() {
823
- for (let i = 0; i < this._subs.length; i++) {
824
- this._subs[i].unsubscribe();
776
+ this._sub?.unsubscribe();
777
+ }
778
+ onAssertionChange(assertion) {
779
+ this.assertion.setValue(assertion || null);
780
+ }
781
+ onTargetChange(target) {
782
+ this.target.setValue(target);
783
+ this.target.markAsDirty();
784
+ this.target.updateValueAndValidity();
785
+ if (this.form.valid) {
786
+ this.targetExpanded = false;
825
787
  }
826
788
  }
827
- buildGid() {
828
- // the GID is the part ID if any, or the item ID, followed by
829
- // the pin's value (=EID)
830
- const pin = this.lookupData?.pin;
831
- if (!pin?.value) {
832
- return null;
789
+ updateForm(id) {
790
+ this._updatingForm = true;
791
+ if (!id) {
792
+ this.form.reset();
833
793
  }
834
- return pin.partId
835
- ? `P${pin.partId}/${pin.value}`
836
- : `I${pin.itemId}/${pin.value}`;
794
+ else {
795
+ this.target.setValue(id.target);
796
+ this.scope.setValue(id.scope || null);
797
+ this.tag.setValue(id.tag || null);
798
+ this.assertion.setValue(id.assertion || null);
799
+ this.form.markAsPristine();
800
+ }
801
+ this._updatingForm = false;
837
802
  }
838
- buildLabel() {
839
- if (!this.lookupData?.pin) {
840
- return null;
803
+ getId() {
804
+ const external = !this.target.value?.name;
805
+ const target = this.target.value;
806
+ return {
807
+ target: external
808
+ ? {
809
+ gid: target?.gid || '',
810
+ label: target?.label || target?.gid || '',
811
+ }
812
+ : target,
813
+ scope: this.scope.value?.trim() || '',
814
+ tag: this.tag.value?.trim(),
815
+ assertion: this.assertion.value || undefined,
816
+ };
817
+ }
818
+ emitIdChange() {
819
+ if (!this.hasSubmit()) {
820
+ this.id.set(this.getId());
841
821
  }
842
- const sb = [];
843
- // pin value
844
- if (this.lookupData.pin.value) {
845
- sb.push(this.lookupData.pin.value);
846
- sb.push(' | ');
822
+ }
823
+ onEditorClose() {
824
+ this.targetExpanded = false;
825
+ }
826
+ onExtMoreRequest(event) {
827
+ this.extMoreRequest.emit(event);
828
+ }
829
+ onExtLookupConfigChange(config) {
830
+ if (!this.scope.value ||
831
+ this.extLookupConfigs.some((c) => c.name === this.scope.value)) {
832
+ this.scope.setValue(config.name || null);
833
+ this.scope.markAsDirty();
834
+ this.scope.updateValueAndValidity();
847
835
  }
848
- // item title
849
- sb.push(this.lookupData.item?.title || this.lookupData.pin?.itemId);
850
- // part type and role
851
- if (this.lookupData.pin.partTypeId) {
852
- const e = this.modelEntries?.find((e) => e.id === this.lookupData.pin.partTypeId);
853
- sb.push(' (');
854
- sb.push(e?.value || this.lookupData.pin.partTypeId);
855
- if (this.lookupData.pin.roleId) {
856
- sb.push(`, ${this.lookupData.pin.roleId}`);
857
- }
858
- sb.push(')');
836
+ }
837
+ cancel() {
838
+ this.editorClose.emit();
839
+ }
840
+ save() {
841
+ if (this.form.valid) {
842
+ this.id.set(this.getId());
859
843
  }
860
- return sb.join('');
861
844
  }
862
- getTarget() {
863
- if (this.external.value) {
864
- return {
865
- gid: this.gid.value || '',
866
- label: this.label.value || '',
867
- };
845
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.0", ngImport: i0, type: AssertedCompositeIdComponent, deps: [{ token: i1$1.FormBuilder }, { token: PinRefLookupService }, { token: 'indexLookupDefinitions' }, { token: i3$1.RamStorageService }], target: i0.ɵɵFactoryTarget.Component });
846
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.0.0", type: AssertedCompositeIdComponent, isStandalone: true, selector: "cadmus-refs-asserted-composite-id", inputs: { idScopeEntries: { classPropertyName: "idScopeEntries", publicName: "idScopeEntries", isSignal: true, isRequired: false, transformFunction: null }, idTagEntries: { classPropertyName: "idTagEntries", publicName: "idTagEntries", isSignal: true, isRequired: false, transformFunction: null }, assTagEntries: { classPropertyName: "assTagEntries", publicName: "assTagEntries", isSignal: true, isRequired: false, transformFunction: null }, refTypeEntries: { classPropertyName: "refTypeEntries", publicName: "refTypeEntries", isSignal: true, isRequired: false, transformFunction: null }, refTagEntries: { classPropertyName: "refTagEntries", publicName: "refTagEntries", isSignal: true, isRequired: false, transformFunction: null }, id: { classPropertyName: "id", publicName: "id", isSignal: true, isRequired: false, transformFunction: null }, internalDefault: { classPropertyName: "internalDefault", publicName: "internalDefault", isSignal: true, isRequired: false, transformFunction: null }, hasSubmit: { classPropertyName: "hasSubmit", publicName: "hasSubmit", isSignal: true, isRequired: false, transformFunction: null }, pinByTypeMode: { classPropertyName: "pinByTypeMode", publicName: "pinByTypeMode", isSignal: true, isRequired: false, transformFunction: null }, canSwitchMode: { classPropertyName: "canSwitchMode", publicName: "canSwitchMode", isSignal: true, isRequired: false, transformFunction: null }, canEditTarget: { classPropertyName: "canEditTarget", publicName: "canEditTarget", isSignal: true, isRequired: false, transformFunction: null }, lookupDefinitions: { classPropertyName: "lookupDefinitions", publicName: "lookupDefinitions", isSignal: true, isRequired: false, transformFunction: null }, defaultPartTypeKey: { classPropertyName: "defaultPartTypeKey", publicName: "defaultPartTypeKey", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { id: "idChange", editorClose: "editorClose", extMoreRequest: "extMoreRequest" }, ngImport: i0, template: "<form [formGroup]=\"form\" (submit)=\"save()\">\r\n <div>\r\n <div class=\"form-row\">\r\n <!-- tag (bound) -->\r\n @if (idTagEntries()?.length) {\r\n <mat-form-field class=\"short-text\">\r\n <mat-label>tag</mat-label>\r\n <mat-select [formControl]=\"tag\">\r\n @for (e of idTagEntries(); track e) {\r\n <mat-option [value]=\"e.id\">{{ e.value }}</mat-option>\r\n }\r\n </mat-select>\r\n </mat-form-field>\r\n }\r\n <!-- tag (free) -->\r\n @else {\r\n <mat-form-field class=\"short-text\">\r\n <mat-label>tag</mat-label>\r\n <input matInput [formControl]=\"tag\" />\r\n @if ($any(tag.errors)?.maxLength && (tag.dirty || tag.touched)) {\r\n <mat-error>tag too long</mat-error>\r\n }\r\n </mat-form-field>\r\n }\r\n\r\n <!-- scope (bound) -->\r\n @if (idScopeEntries()?.length) {\r\n <mat-form-field class=\"short-text\">\r\n <mat-label>scope</mat-label>\r\n <mat-select [formControl]=\"scope\">\r\n @for (e of idScopeEntries(); track e) {\r\n <mat-option [value]=\"e.id\">{{ e.value }}</mat-option>\r\n }\r\n </mat-select>\r\n </mat-form-field>\r\n }\r\n <!-- scope (free) -->\r\n @else {\r\n <mat-form-field class=\"short-text\">\r\n <mat-label>scope</mat-label>\r\n <input matInput [formControl]=\"scope\" />\r\n @if ( $any(scope.errors)?.maxLength && (scope.dirty || scope.touched) )\r\n {\r\n <mat-error>scope too long</mat-error>\r\n }\r\n </mat-form-field>\r\n }\r\n\r\n <!-- label and GID -->\r\n @if (target.value?.label) {\r\n <div class=\"info\">\r\n <span class=\"label\">label</span>{{ target.value?.label }}\r\n </div>\r\n } @if (target.value?.gid) {\r\n <div class=\"info\">\r\n <span class=\"label\">GID</span>{{ target.value?.gid }}\r\n </div>\r\n }\r\n </div>\r\n\r\n <!-- target -->\r\n <div class=\"boxed\">\r\n <mat-expansion-panel [(expanded)]=\"targetExpanded\">\r\n <mat-expansion-panel-header>target</mat-expansion-panel-header>\r\n <cadmus-pin-target-lookup\r\n [pinByTypeMode]=\"pinByTypeMode()\"\r\n [canSwitchMode]=\"canSwitchMode()\"\r\n [canEditTarget]=\"canEditTarget()\"\r\n [lookupDefinitions]=\"lookupDefinitions()\"\r\n [defaultPartTypeKey]=\"defaultPartTypeKey()\"\r\n [target]=\"target.value || undefined\"\r\n [internalDefault]=\"internalDefault()\"\r\n [extLookupConfigs]=\"extLookupConfigs\"\r\n (targetChange)=\"onTargetChange($event)\"\r\n (editorClose)=\"onEditorClose()\"\r\n (extMoreRequest)=\"onExtMoreRequest($event)\"\r\n (extLookupConfigChange)=\"onExtLookupConfigChange($event)\"\r\n />\r\n </mat-expansion-panel>\r\n </div>\r\n\r\n <!-- assertion -->\r\n <br />\r\n <div class=\"boxed\">\r\n <mat-expansion-panel>\r\n <mat-expansion-panel-header>assertion</mat-expansion-panel-header>\r\n <cadmus-refs-assertion\r\n [assTagEntries]=\"assTagEntries()\"\r\n [refTypeEntries]=\"refTypeEntries()\"\r\n [refTagEntries]=\"refTagEntries()\"\r\n [assertion]=\"assertion.value || undefined\"\r\n (assertionChange)=\"onAssertionChange($event)\"\r\n />\r\n </mat-expansion-panel>\r\n </div>\r\n </div>\r\n\r\n <!-- buttons -->\r\n @if (hasSubmit()) {\r\n <div>\r\n <button\r\n mat-icon-button\r\n type=\"button\"\r\n (click)=\"cancel()\"\r\n [disabled]=\"!this.target.value?.gid || !this.target.value?.label\"\r\n >\r\n <mat-icon class=\"mat-warn\">close</mat-icon>\r\n </button>\r\n <button mat-icon-button type=\"submit\" [disabled]=\"form.invalid\">\r\n <mat-icon class=\"mat-primary\">check_circle</mat-icon>\r\n </button>\r\n </div>\r\n }\r\n</form>\r\n", styles: [".form-row{display:flex;gap:8px;align-items:center;flex-wrap:wrap}.form-row *{flex:0 0 auto}.boxed{border:1px solid silver;border-radius:6px;padding:6px}.short-text{width:8em}.pin-info{font-size:90%;color:silver}fieldset{border:1px solid silver;border-radius:6px;padding:6px}.info{border:1px solid silver;border-radius:6px;background-color:silver;color:#fff;padding:4px}.info .label{background-color:#fff;color:silver;margin:0 6px}@media only screen and (max-width: 959px){div#container{grid-template-rows:1fr auto;grid-template-columns:1fr;grid-template-areas:\"editor\" \"lookup\"}}\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:
847
+ // material
848
+ MatButtonModule }, { kind: "component", type: i3.MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "ngmodule", type: MatExpansionModule }, { kind: "component", type: i4$1.MatExpansionPanel, selector: "mat-expansion-panel", inputs: ["hideToggle", "togglePosition"], outputs: ["afterExpand", "afterCollapse"], exportAs: ["matExpansionPanel"] }, { kind: "component", type: i4$1.MatExpansionPanelHeader, selector: "mat-expansion-panel-header", inputs: ["expandedHeight", "collapsedHeight", "tabIndex"] }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "component", type: i6$1.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i6$1.MatLabel, selector: "mat-label" }, { kind: "directive", type: i6$1.MatError, selector: "mat-error, [matError]", inputs: ["id"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i7.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i8$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: MatSelectModule }, { kind: "component", type: i9.MatSelect, selector: "mat-select", inputs: ["aria-describedby", "panelClass", "disabled", "disableRipple", "tabIndex", "hideSingleSelectionIndicator", "placeholder", "required", "multiple", "disableOptionCentering", "compareWith", "value", "aria-label", "aria-labelledby", "errorStateMatcher", "typeaheadDebounceInterval", "sortComparator", "id", "panelWidth", "canSelectNullableOptions"], outputs: ["openedChange", "opened", "closed", "selectionChange", "valueChange"], exportAs: ["matSelect"] }, { kind: "component", type: i9.MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "component", type:
849
+ // bricks
850
+ AssertionComponent, selector: "cadmus-refs-assertion", inputs: ["assTagEntries", "refTypeEntries", "refTagEntries", "assertion"], outputs: ["assertionChange"] }, { kind: "component", type:
851
+ // local
852
+ PinTargetLookupComponent, selector: "cadmus-pin-target-lookup", inputs: ["pinByTypeMode", "canSwitchMode", "canEditTarget", "lookupDefinitions", "extLookupConfigs", "internalDefault", "target", "defaultPartTypeKey"], outputs: ["pinByTypeModeChange", "canSwitchModeChange", "lookupDefinitionsChange", "targetChange", "editorClose", "extMoreRequest", "extLookupConfigChange"] }] });
853
+ }
854
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.0", ngImport: i0, type: AssertedCompositeIdComponent, decorators: [{
855
+ type: Component,
856
+ args: [{ selector: 'cadmus-refs-asserted-composite-id', imports: [
857
+ ReactiveFormsModule,
858
+ // material
859
+ MatButtonModule,
860
+ MatExpansionModule,
861
+ MatFormFieldModule,
862
+ MatIconModule,
863
+ MatInputModule,
864
+ MatSelectModule,
865
+ MatTooltipModule,
866
+ // bricks
867
+ AssertionComponent,
868
+ // local
869
+ PinTargetLookupComponent,
870
+ ], template: "<form [formGroup]=\"form\" (submit)=\"save()\">\r\n <div>\r\n <div class=\"form-row\">\r\n <!-- tag (bound) -->\r\n @if (idTagEntries()?.length) {\r\n <mat-form-field class=\"short-text\">\r\n <mat-label>tag</mat-label>\r\n <mat-select [formControl]=\"tag\">\r\n @for (e of idTagEntries(); track e) {\r\n <mat-option [value]=\"e.id\">{{ e.value }}</mat-option>\r\n }\r\n </mat-select>\r\n </mat-form-field>\r\n }\r\n <!-- tag (free) -->\r\n @else {\r\n <mat-form-field class=\"short-text\">\r\n <mat-label>tag</mat-label>\r\n <input matInput [formControl]=\"tag\" />\r\n @if ($any(tag.errors)?.maxLength && (tag.dirty || tag.touched)) {\r\n <mat-error>tag too long</mat-error>\r\n }\r\n </mat-form-field>\r\n }\r\n\r\n <!-- scope (bound) -->\r\n @if (idScopeEntries()?.length) {\r\n <mat-form-field class=\"short-text\">\r\n <mat-label>scope</mat-label>\r\n <mat-select [formControl]=\"scope\">\r\n @for (e of idScopeEntries(); track e) {\r\n <mat-option [value]=\"e.id\">{{ e.value }}</mat-option>\r\n }\r\n </mat-select>\r\n </mat-form-field>\r\n }\r\n <!-- scope (free) -->\r\n @else {\r\n <mat-form-field class=\"short-text\">\r\n <mat-label>scope</mat-label>\r\n <input matInput [formControl]=\"scope\" />\r\n @if ( $any(scope.errors)?.maxLength && (scope.dirty || scope.touched) )\r\n {\r\n <mat-error>scope too long</mat-error>\r\n }\r\n </mat-form-field>\r\n }\r\n\r\n <!-- label and GID -->\r\n @if (target.value?.label) {\r\n <div class=\"info\">\r\n <span class=\"label\">label</span>{{ target.value?.label }}\r\n </div>\r\n } @if (target.value?.gid) {\r\n <div class=\"info\">\r\n <span class=\"label\">GID</span>{{ target.value?.gid }}\r\n </div>\r\n }\r\n </div>\r\n\r\n <!-- target -->\r\n <div class=\"boxed\">\r\n <mat-expansion-panel [(expanded)]=\"targetExpanded\">\r\n <mat-expansion-panel-header>target</mat-expansion-panel-header>\r\n <cadmus-pin-target-lookup\r\n [pinByTypeMode]=\"pinByTypeMode()\"\r\n [canSwitchMode]=\"canSwitchMode()\"\r\n [canEditTarget]=\"canEditTarget()\"\r\n [lookupDefinitions]=\"lookupDefinitions()\"\r\n [defaultPartTypeKey]=\"defaultPartTypeKey()\"\r\n [target]=\"target.value || undefined\"\r\n [internalDefault]=\"internalDefault()\"\r\n [extLookupConfigs]=\"extLookupConfigs\"\r\n (targetChange)=\"onTargetChange($event)\"\r\n (editorClose)=\"onEditorClose()\"\r\n (extMoreRequest)=\"onExtMoreRequest($event)\"\r\n (extLookupConfigChange)=\"onExtLookupConfigChange($event)\"\r\n />\r\n </mat-expansion-panel>\r\n </div>\r\n\r\n <!-- assertion -->\r\n <br />\r\n <div class=\"boxed\">\r\n <mat-expansion-panel>\r\n <mat-expansion-panel-header>assertion</mat-expansion-panel-header>\r\n <cadmus-refs-assertion\r\n [assTagEntries]=\"assTagEntries()\"\r\n [refTypeEntries]=\"refTypeEntries()\"\r\n [refTagEntries]=\"refTagEntries()\"\r\n [assertion]=\"assertion.value || undefined\"\r\n (assertionChange)=\"onAssertionChange($event)\"\r\n />\r\n </mat-expansion-panel>\r\n </div>\r\n </div>\r\n\r\n <!-- buttons -->\r\n @if (hasSubmit()) {\r\n <div>\r\n <button\r\n mat-icon-button\r\n type=\"button\"\r\n (click)=\"cancel()\"\r\n [disabled]=\"!this.target.value?.gid || !this.target.value?.label\"\r\n >\r\n <mat-icon class=\"mat-warn\">close</mat-icon>\r\n </button>\r\n <button mat-icon-button type=\"submit\" [disabled]=\"form.invalid\">\r\n <mat-icon class=\"mat-primary\">check_circle</mat-icon>\r\n </button>\r\n </div>\r\n }\r\n</form>\r\n", styles: [".form-row{display:flex;gap:8px;align-items:center;flex-wrap:wrap}.form-row *{flex:0 0 auto}.boxed{border:1px solid silver;border-radius:6px;padding:6px}.short-text{width:8em}.pin-info{font-size:90%;color:silver}fieldset{border:1px solid silver;border-radius:6px;padding:6px}.info{border:1px solid silver;border-radius:6px;background-color:silver;color:#fff;padding:4px}.info .label{background-color:#fff;color:silver;margin:0 6px}@media only screen and (max-width: 959px){div#container{grid-template-rows:1fr auto;grid-template-columns:1fr;grid-template-areas:\"editor\" \"lookup\"}}\n"] }]
871
+ }], ctorParameters: () => [{ type: i1$1.FormBuilder }, { type: PinRefLookupService }, { type: undefined, decorators: [{
872
+ type: Inject,
873
+ args: ['indexLookupDefinitions']
874
+ }] }, { type: i3$1.RamStorageService }] });
875
+
876
+ /**
877
+ * Asserted composite IDs editor.
878
+ */
879
+ class AssertedCompositeIdsComponent {
880
+ _dialogService;
881
+ _ids;
882
+ _editedIndex;
883
+ edited;
884
+ /**
885
+ * The asserted IDs.
886
+ */
887
+ get ids() {
888
+ return this._ids;
889
+ }
890
+ set ids(value) {
891
+ if (this._ids !== value) {
892
+ this._ids = value || [];
893
+ this.updateForm(value);
894
+ }
895
+ }
896
+ // asserted-id-scopes
897
+ idScopeEntries = input();
898
+ // asserted-id-tags
899
+ idTagEntries = input();
900
+ // assertion-tags
901
+ assTagEntries = input();
902
+ // doc-reference-types
903
+ refTypeEntries = input();
904
+ // doc-reference-tags
905
+ refTagEntries = input();
906
+ /**
907
+ * True when the internal UI preselected mode should be by type rather than
908
+ * by item. User can change mode unless modeSwitching is false.
909
+ */
910
+ pinByTypeMode = input();
911
+ /**
912
+ * True when the user can switch between by-type and by-item mode in
913
+ * the internal UI.
914
+ */
915
+ canSwitchMode = input();
916
+ /**
917
+ * True when the user can edit the target's gid/label for internal targets.
918
+ */
919
+ canEditTarget = input();
920
+ /**
921
+ * The lookup definitions to be used for the by-type lookup in the internal UI.
922
+ * If not specified, the lookup definitions will be got via injection
923
+ * when available; if the injected definitions are empty, the
924
+ * lookup definitions will be built from the model-types thesaurus;
925
+ * if this is not available either, the by-type lookup will be
926
+ * disabled.
927
+ */
928
+ lookupDefinitions = input();
929
+ /**
930
+ * The default part type key.
931
+ */
932
+ defaultPartTypeKey = input();
933
+ /**
934
+ * True if when a new ID is set it should be internal rather than
935
+ * external by default.
936
+ */
937
+ internalDefault = input();
938
+ /**
939
+ * Emitted whenever any ID changes.
940
+ */
941
+ idsChange = output();
942
+ entries;
943
+ form;
944
+ constructor(formBuilder, _dialogService) {
945
+ this._dialogService = _dialogService;
946
+ this._ids = [];
947
+ this._editedIndex = -1;
948
+ this.entries = formBuilder.control([], { nonNullable: true });
949
+ // form
950
+ this.form = formBuilder.group({
951
+ ids: this.entries,
952
+ });
953
+ }
954
+ updateForm(ids) {
955
+ if (!ids?.length) {
956
+ this.form.reset();
957
+ return;
958
+ }
959
+ this.entries.setValue(ids, { emitEvent: false });
960
+ this.entries.updateValueAndValidity();
961
+ this.form.markAsPristine();
962
+ }
963
+ emitIdsChange() {
964
+ this.idsChange.emit(this.entries.value);
965
+ }
966
+ addId() {
967
+ this.editId({
968
+ target: { gid: '', label: '' },
969
+ }, -1);
970
+ }
971
+ editId(id, index) {
972
+ this._editedIndex = index;
973
+ this.edited = id;
974
+ }
975
+ closeId() {
976
+ this._editedIndex = -1;
977
+ this.edited = undefined;
978
+ }
979
+ saveId(entry) {
980
+ const entries = [...this.entries.value];
981
+ if (this._editedIndex === -1) {
982
+ entries.push(entry);
868
983
  }
869
984
  else {
870
- const pin = this.lookupData?.pin;
871
- return {
872
- gid: this.gid.value || '',
873
- label: this.label.value || '',
874
- itemId: pin?.itemId || '',
875
- partId: pin?.partId || '',
876
- partTypeId: pin?.partTypeId || '',
877
- roleId: pin?.roleId || '',
878
- name: pin?.name || '',
879
- value: pin?.value || '',
880
- };
985
+ entries.splice(this._editedIndex, 1, entry);
881
986
  }
987
+ this.entries.setValue(entries);
988
+ this.entries.markAsDirty();
989
+ this.entries.updateValueAndValidity();
990
+ this.closeId();
882
991
  }
883
- emitChange() {
884
- this._noFormUpdate = true;
885
- this.target.set(this.getTarget());
992
+ deleteId(index) {
993
+ this._dialogService
994
+ .confirm('Confirmation', 'Delete ID?')
995
+ .pipe(take(1))
996
+ .subscribe((yes) => {
997
+ if (yes) {
998
+ if (this._editedIndex === index) {
999
+ this.closeId();
1000
+ }
1001
+ const entries = [...this.entries.value];
1002
+ entries.splice(index, 1);
1003
+ this.entries.setValue(entries);
1004
+ this.entries.markAsDirty();
1005
+ this.entries.updateValueAndValidity();
1006
+ this.emitIdsChange();
1007
+ }
1008
+ });
886
1009
  }
887
- updateTarget(noEmit = false) {
888
- if (this._noTargetUpdate) {
1010
+ moveIdUp(index) {
1011
+ if (index < 1) {
889
1012
  return;
890
1013
  }
891
- if (!this.external.value) {
892
- this.gid.setValue(this.buildGid());
893
- this.gid.updateValueAndValidity();
894
- this.gid.markAsDirty();
895
- this.label.setValue(this.buildLabel());
896
- this.label.updateValueAndValidity();
897
- this.label.markAsDirty();
898
- }
899
- if (!noEmit) {
900
- this.emitChange();
901
- }
1014
+ const entry = this.entries.value[index];
1015
+ const entries = [...this.entries.value];
1016
+ entries.splice(index, 1);
1017
+ entries.splice(index - 1, 0, entry);
1018
+ this.entries.setValue(entries);
1019
+ this.entries.markAsDirty();
1020
+ this.entries.updateValueAndValidity();
1021
+ this.emitIdsChange();
902
1022
  }
903
- updateForm(target) {
904
- // build pin info from target
905
- if (!target) {
906
- this.lookupData = undefined;
907
- this.item.reset();
908
- this.itemPart.reset();
909
- this.gid.reset();
910
- this.label.reset();
1023
+ moveIdDown(index) {
1024
+ if (index + 1 >= this.entries.value.length) {
911
1025
  return;
912
1026
  }
913
- this._noTargetUpdate = true;
914
- this.gid.setValue(target.gid || '', { emitEvent: false });
915
- this.label.setValue(target.label || '', { emitEvent: false });
916
- this.lookupData = {
917
- pin: {
918
- itemId: target.itemId || '',
919
- partId: target.partId || '',
920
- partTypeId: target.partTypeId || '',
921
- roleId: target.roleId || '',
922
- name: target.name || '',
923
- value: target.value || '',
924
- },
925
- };
926
- // get item
927
- if (target.itemId) {
928
- this._itemService.getItem(target.itemId, true, true).subscribe({
929
- next: (item) => {
930
- this.item.setValue(item, { emitEvent: false });
931
- this.form.markAsPristine();
932
- this._noTargetUpdate = false;
933
- this.external.setValue(!target.name, { emitEvent: false });
934
- this.updateTarget();
935
- },
936
- error: (error) => {
937
- if (error) {
938
- console.error('Item service error', error);
939
- }
940
- this.external.setValue(!target.name, { emitEvent: false });
941
- this._noTargetUpdate = false;
942
- },
943
- });
944
- }
945
- else {
946
- this.external.setValue(!target.name && !this.internalDefault(), {
947
- emitEvent: false,
948
- });
949
- this._noTargetUpdate = false;
950
- this.updateTarget();
951
- }
1027
+ const entry = this.entries.value[index];
1028
+ const entries = [...this.entries.value];
1029
+ entries.splice(index, 1);
1030
+ entries.splice(index + 1, 0, entry);
1031
+ this.entries.setValue(entries);
1032
+ this.entries.markAsDirty();
1033
+ this.entries.updateValueAndValidity();
1034
+ this.emitIdsChange();
1035
+ }
1036
+ onIdChange(id) {
1037
+ this.saveId(id);
1038
+ this.emitIdsChange();
952
1039
  }
1040
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.0", ngImport: i0, type: AssertedCompositeIdsComponent, deps: [{ token: i1$1.FormBuilder }, { token: i2.DialogService }], target: i0.ɵɵFactoryTarget.Component });
1041
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.0.0", type: AssertedCompositeIdsComponent, isStandalone: true, selector: "cadmus-refs-asserted-composite-ids", inputs: { ids: { classPropertyName: "ids", publicName: "ids", isSignal: false, isRequired: false, transformFunction: null }, idScopeEntries: { classPropertyName: "idScopeEntries", publicName: "idScopeEntries", isSignal: true, isRequired: false, transformFunction: null }, idTagEntries: { classPropertyName: "idTagEntries", publicName: "idTagEntries", isSignal: true, isRequired: false, transformFunction: null }, assTagEntries: { classPropertyName: "assTagEntries", publicName: "assTagEntries", isSignal: true, isRequired: false, transformFunction: null }, refTypeEntries: { classPropertyName: "refTypeEntries", publicName: "refTypeEntries", isSignal: true, isRequired: false, transformFunction: null }, refTagEntries: { classPropertyName: "refTagEntries", publicName: "refTagEntries", isSignal: true, isRequired: false, transformFunction: null }, pinByTypeMode: { classPropertyName: "pinByTypeMode", publicName: "pinByTypeMode", isSignal: true, isRequired: false, transformFunction: null }, canSwitchMode: { classPropertyName: "canSwitchMode", publicName: "canSwitchMode", isSignal: true, isRequired: false, transformFunction: null }, canEditTarget: { classPropertyName: "canEditTarget", publicName: "canEditTarget", isSignal: true, isRequired: false, transformFunction: null }, lookupDefinitions: { classPropertyName: "lookupDefinitions", publicName: "lookupDefinitions", isSignal: true, isRequired: false, transformFunction: null }, defaultPartTypeKey: { classPropertyName: "defaultPartTypeKey", publicName: "defaultPartTypeKey", isSignal: true, isRequired: false, transformFunction: null }, internalDefault: { classPropertyName: "internalDefault", publicName: "internalDefault", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { idsChange: "idsChange" }, ngImport: i0, template: "<form [formGroup]=\"form\">\r\n <!-- buttons -->\r\n <button type=\"button\" class=\"mat-primary\" mat-flat-button (click)=\"addId()\">\r\n <mat-icon>add_circle</mat-icon> ID\r\n </button>\r\n <!-- list -->\r\n @if (entries.value.length) {\r\n <table>\r\n <thead>\r\n <tr>\r\n <th></th>\r\n <th>scope</th>\r\n <th>label</th>\r\n <th>gid</th>\r\n <th>ass.</th>\r\n </tr>\r\n </thead>\r\n <tbody>\r\n @for ( entry of entries.value; track entry; let i = $index; let first =\r\n $first; let last = $last) {\r\n <tr [class.selected]=\"entry === edited\">\r\n <td class=\"fit-width\">\r\n <button\r\n type=\"button\"\r\n mat-icon-button\r\n matTooltip=\"Edit this ID\"\r\n (click)=\"editId(entry, i)\"\r\n >\r\n <mat-icon class=\"mat-primary\">edit</mat-icon>\r\n </button>\r\n <button\r\n type=\"button\"\r\n mat-icon-button\r\n matTooltip=\"Move this ID up\"\r\n [disabled]=\"first\"\r\n (click)=\"moveIdUp(i)\"\r\n >\r\n <mat-icon>arrow_upward</mat-icon>\r\n </button>\r\n <button\r\n type=\"button\"\r\n mat-icon-button\r\n matTooltip=\"Move this ID down\"\r\n [disabled]=\"last\"\r\n (click)=\"moveIdDown(i)\"\r\n >\r\n <mat-icon>arrow_downward</mat-icon>\r\n </button>\r\n <button\r\n type=\"button\"\r\n mat-icon-button\r\n matTooltip=\"Delete this ID\"\r\n (click)=\"deleteId(i)\"\r\n >\r\n <mat-icon class=\"mat-warn\">remove_circle</mat-icon>\r\n </button>\r\n </td>\r\n <td>{{ entry.scope }}</td>\r\n <td>{{ entry?.target?.label }}</td>\r\n <td>{{ entry?.target?.gid }}</td>\r\n <td>{{ entry?.assertion ? \"Y\" : \"N\" }}</td>\r\n </tr>\r\n }\r\n </tbody>\r\n </table>\r\n }\r\n\r\n <!-- editor -->\r\n <mat-expansion-panel [expanded]=\"edited\" [disabled]=\"!edited\">\r\n <mat-expansion-panel-header\r\n >ID {{ edited?.target?.label }}</mat-expansion-panel-header\r\n >\r\n <cadmus-refs-asserted-composite-id\r\n [idScopeEntries]=\"idScopeEntries()\"\r\n [idTagEntries]=\"idTagEntries()\"\r\n [assTagEntries]=\"assTagEntries()\"\r\n [refTypeEntries]=\"refTypeEntries()\"\r\n [refTagEntries]=\"refTagEntries()\"\r\n [hasSubmit]=\"true\"\r\n [pinByTypeMode]=\"pinByTypeMode()\"\r\n [canSwitchMode]=\"canSwitchMode()\"\r\n [canEditTarget]=\"canEditTarget()\"\r\n [lookupDefinitions]=\"lookupDefinitions()\"\r\n [defaultPartTypeKey]=\"defaultPartTypeKey()\"\r\n [internalDefault]=\"internalDefault()\"\r\n [id]=\"edited\"\r\n (idChange)=\"onIdChange($event)\"\r\n (editorClose)=\"closeId()\"\r\n />\r\n </mat-expansion-panel>\r\n</form>\r\n", styles: ["table{width:100%;border-collapse:collapse}tbody tr:nth-child(odd){background-color:#e2e2e2}th{text-align:left;font-weight:400;color:silver}td.fit-width{width:1px;white-space:nowrap}tr.selected{background-color:#d0d0d0!important}fieldset{border:1px solid silver;border-radius:6px;padding:6px}\n"], dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1$1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i3.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: i3.MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "ngmodule", type: MatCheckboxModule }, { kind: "ngmodule", type: MatExpansionModule }, { kind: "component", type: i4$1.MatExpansionPanel, selector: "mat-expansion-panel", inputs: ["hideToggle", "togglePosition"], outputs: ["afterExpand", "afterCollapse"], exportAs: ["matExpansionPanel"] }, { kind: "component", type: i4$1.MatExpansionPanelHeader, selector: "mat-expansion-panel-header", inputs: ["expandedHeight", "collapsedHeight", "tabIndex"] }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i7.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatInputModule }, { kind: "component", type: AssertedCompositeIdComponent, selector: "cadmus-refs-asserted-composite-id", inputs: ["idScopeEntries", "idTagEntries", "assTagEntries", "refTypeEntries", "refTagEntries", "id", "internalDefault", "hasSubmit", "pinByTypeMode", "canSwitchMode", "canEditTarget", "lookupDefinitions", "defaultPartTypeKey"], outputs: ["idChange", "editorClose", "extMoreRequest"] }] });
1042
+ }
1043
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.0", ngImport: i0, type: AssertedCompositeIdsComponent, decorators: [{
1044
+ type: Component,
1045
+ args: [{ selector: 'cadmus-refs-asserted-composite-ids', imports: [
1046
+ FormsModule,
1047
+ ReactiveFormsModule,
1048
+ MatButtonModule,
1049
+ MatCheckboxModule,
1050
+ MatExpansionModule,
1051
+ MatFormFieldModule,
1052
+ MatIconModule,
1053
+ MatInputModule,
1054
+ AssertedCompositeIdComponent,
1055
+ ], template: "<form [formGroup]=\"form\">\r\n <!-- buttons -->\r\n <button type=\"button\" class=\"mat-primary\" mat-flat-button (click)=\"addId()\">\r\n <mat-icon>add_circle</mat-icon> ID\r\n </button>\r\n <!-- list -->\r\n @if (entries.value.length) {\r\n <table>\r\n <thead>\r\n <tr>\r\n <th></th>\r\n <th>scope</th>\r\n <th>label</th>\r\n <th>gid</th>\r\n <th>ass.</th>\r\n </tr>\r\n </thead>\r\n <tbody>\r\n @for ( entry of entries.value; track entry; let i = $index; let first =\r\n $first; let last = $last) {\r\n <tr [class.selected]=\"entry === edited\">\r\n <td class=\"fit-width\">\r\n <button\r\n type=\"button\"\r\n mat-icon-button\r\n matTooltip=\"Edit this ID\"\r\n (click)=\"editId(entry, i)\"\r\n >\r\n <mat-icon class=\"mat-primary\">edit</mat-icon>\r\n </button>\r\n <button\r\n type=\"button\"\r\n mat-icon-button\r\n matTooltip=\"Move this ID up\"\r\n [disabled]=\"first\"\r\n (click)=\"moveIdUp(i)\"\r\n >\r\n <mat-icon>arrow_upward</mat-icon>\r\n </button>\r\n <button\r\n type=\"button\"\r\n mat-icon-button\r\n matTooltip=\"Move this ID down\"\r\n [disabled]=\"last\"\r\n (click)=\"moveIdDown(i)\"\r\n >\r\n <mat-icon>arrow_downward</mat-icon>\r\n </button>\r\n <button\r\n type=\"button\"\r\n mat-icon-button\r\n matTooltip=\"Delete this ID\"\r\n (click)=\"deleteId(i)\"\r\n >\r\n <mat-icon class=\"mat-warn\">remove_circle</mat-icon>\r\n </button>\r\n </td>\r\n <td>{{ entry.scope }}</td>\r\n <td>{{ entry?.target?.label }}</td>\r\n <td>{{ entry?.target?.gid }}</td>\r\n <td>{{ entry?.assertion ? \"Y\" : \"N\" }}</td>\r\n </tr>\r\n }\r\n </tbody>\r\n </table>\r\n }\r\n\r\n <!-- editor -->\r\n <mat-expansion-panel [expanded]=\"edited\" [disabled]=\"!edited\">\r\n <mat-expansion-panel-header\r\n >ID {{ edited?.target?.label }}</mat-expansion-panel-header\r\n >\r\n <cadmus-refs-asserted-composite-id\r\n [idScopeEntries]=\"idScopeEntries()\"\r\n [idTagEntries]=\"idTagEntries()\"\r\n [assTagEntries]=\"assTagEntries()\"\r\n [refTypeEntries]=\"refTypeEntries()\"\r\n [refTagEntries]=\"refTagEntries()\"\r\n [hasSubmit]=\"true\"\r\n [pinByTypeMode]=\"pinByTypeMode()\"\r\n [canSwitchMode]=\"canSwitchMode()\"\r\n [canEditTarget]=\"canEditTarget()\"\r\n [lookupDefinitions]=\"lookupDefinitions()\"\r\n [defaultPartTypeKey]=\"defaultPartTypeKey()\"\r\n [internalDefault]=\"internalDefault()\"\r\n [id]=\"edited\"\r\n (idChange)=\"onIdChange($event)\"\r\n (editorClose)=\"closeId()\"\r\n />\r\n </mat-expansion-panel>\r\n</form>\r\n", styles: ["table{width:100%;border-collapse:collapse}tbody tr:nth-child(odd){background-color:#e2e2e2}th{text-align:left;font-weight:400;color:silver}td.fit-width{width:1px;white-space:nowrap}tr.selected{background-color:#d0d0d0!important}fieldset{border:1px solid silver;border-radius:6px;padding:6px}\n"] }]
1056
+ }], ctorParameters: () => [{ type: i1$1.FormBuilder }, { type: i2.DialogService }], propDecorators: { ids: [{
1057
+ type: Input
1058
+ }] } });
1059
+
1060
+ // from Cadmus general parts
1061
+ const METADATA_PART_ID = 'it.vedph.metadata';
1062
+ /*
1063
+ * Scoped pin-based lookup component. This component provides a list
1064
+ * of pin-based searches, with a lookup control. Whenever the user
1065
+ * picks a pin value, he gets the details about its item and part, and
1066
+ * item's metadata part, if any. He can then use these data to build
1067
+ * some EID by variously assembling these components.
1068
+ */
1069
+ class ScopedPinLookupComponent {
1070
+ _itemService;
1071
+ lookupService;
1072
+ lookupDefs;
1073
+ // lookup
1074
+ key;
1075
+ keyForm;
1076
+ keys;
1077
+ info;
1078
+ // builder
1079
+ id;
1080
+ idForm;
953
1081
  /**
954
- * Called when the item lookup changes (item is looked up
955
- * by its title).
956
- *
957
- * @param item The item got from lookup.
1082
+ * Emitted whenever the user picks an ID.
958
1083
  */
959
- onItemLookupChange(item) {
960
- if (!item) {
961
- return;
962
- }
963
- // load item's parts
964
- this._itemService.getItem(item.id, true, true).subscribe({
965
- next: (i) => {
966
- // setting the item will trigger its parts update
967
- this.item.setValue(i);
968
- this.updateTarget(true);
969
- },
970
- error: (error) => {
971
- if (error) {
972
- console.error('Error getting item', error);
973
- }
974
- this.itemPart.setValue(null);
975
- this.itemParts = [];
976
- this.updateTarget(true);
977
- },
1084
+ idPick = output();
1085
+ constructor(formBuilder, _itemService, lookupService, lookupDefs) {
1086
+ this._itemService = _itemService;
1087
+ this.lookupService = lookupService;
1088
+ this.lookupDefs = lookupDefs;
1089
+ // lookup
1090
+ // keys are all the defined lookup searches
1091
+ this.keys = Object.keys(lookupDefs);
1092
+ // the selected key defines the lookup scope
1093
+ this.key = formBuilder.control(null);
1094
+ this.keyForm = formBuilder.group({
1095
+ key: this.key,
1096
+ });
1097
+ // id
1098
+ this.id = formBuilder.control(null, [
1099
+ Validators.required,
1100
+ Validators.maxLength(300),
1101
+ ]);
1102
+ this.idForm = formBuilder.group({
1103
+ id: this.id,
978
1104
  });
979
1105
  }
980
- loadItemInfo(pin) {
981
- if (!pin) {
982
- return;
1106
+ ngOnInit() {
1107
+ // pre-select a unique key
1108
+ if (this.keys.length === 1) {
1109
+ this.key.setValue(this.keys[0]);
1110
+ this.key.markAsDirty();
1111
+ this.key.updateValueAndValidity();
983
1112
  }
1113
+ }
1114
+ onItemChange(item) {
1115
+ const info = {
1116
+ pin: item,
1117
+ };
1118
+ // lookup item and its metadata part if any
984
1119
  forkJoin({
985
- item: this._itemService.getItem(pin.itemId, false, true),
986
- part: this._itemService.getPartFromTypeAndRole(pin.itemId, METADATA_PART_ID, undefined, true),
1120
+ item: item
1121
+ ? this._itemService.getItem(item.itemId, false, true)
1122
+ : of(null),
1123
+ part: item
1124
+ ? this._itemService.getPartFromTypeAndRole(item.itemId, METADATA_PART_ID, undefined, true)
1125
+ : of(null),
987
1126
  })
988
1127
  .pipe(take(1))
989
1128
  .subscribe({
990
1129
  next: (result) => {
991
- this.lookupData = {
992
- pin: pin,
993
- item: result.item,
994
- metaPart: result.part,
995
- };
996
- this.updateTarget(true);
1130
+ if (result.item) {
1131
+ info.item = result.item;
1132
+ info.part = result.part;
1133
+ this.info = info;
1134
+ }
997
1135
  },
998
1136
  error: (error) => {
999
- this.lookupData = undefined;
1000
- console.error('Error loading item/metadata', error);
1137
+ console.error(error ? JSON.stringify(error) : 'Error loading item/metadata');
1001
1138
  },
1002
1139
  });
1003
1140
  }
1004
- /**
1005
- * Called when the pin lookup change. A pin is looked up by its
1006
- * name and value (=the filter's text), and optionally by:
1007
- * - its index lookup definition (selected by partTypeKey).
1008
- * - its item (defined by item, in filter).
1009
- * - its part (defined by itemPart, in filter).
1010
- *
1011
- * @param info The pin info from pin lookup.
1012
- */
1013
- onPinLookupChange(info) {
1014
- this.loadItemInfo(info);
1015
- }
1016
- onExtItemChange(event) {
1017
- if (event.item) {
1018
- setTimeout(() => {
1019
- this.gid.setValue(event.itemId);
1020
- this.gid.updateValueAndValidity();
1021
- this.gid.markAsDirty();
1022
- this.label.setValue(event.itemLabel);
1023
- this.label.updateValueAndValidity();
1024
- this.label.markAsDirty();
1025
- });
1026
- }
1027
- }
1028
- onExtMoreRequest(event) {
1029
- this.extMoreRequest.emit(event);
1030
- }
1031
- onCopied() {
1032
- this._snackbar.open('Copied to clipboard', 'OK', {
1033
- duration: 1500,
1034
- });
1035
- }
1036
- onExtConfigChange(config) {
1037
- this.extLookupConfigChange.emit(config);
1038
- }
1039
- close() {
1040
- this.editorClose.emit();
1141
+ appendIdComponent(type, metaIndex = -1) {
1142
+ let id = this.id.value || '';
1143
+ switch (type) {
1144
+ case 'pin':
1145
+ id += this.info?.pin.value;
1146
+ break;
1147
+ case 'itemId':
1148
+ id += this.info.item?.id || '';
1149
+ break;
1150
+ case 'partId':
1151
+ id += this.info.part?.id || '';
1152
+ break;
1153
+ case 'partTypeId':
1154
+ id += this.info.part?.typeId || '';
1155
+ break;
1156
+ case 'partRoleId':
1157
+ id += this.info.part?.roleId || '';
1158
+ break;
1159
+ case 'metadata':
1160
+ id += this.info.part.metadata[metaIndex].value;
1161
+ break;
1162
+ }
1163
+ this.id.setValue(id);
1164
+ this.id.markAsDirty();
1165
+ this.id.updateValueAndValidity();
1041
1166
  }
1042
- save() {
1043
- if (this.form.invalid) {
1167
+ pickId() {
1168
+ if (this.idForm.invalid) {
1044
1169
  return;
1045
1170
  }
1046
- this.target.set(this.getTarget());
1047
- this.emitChange();
1171
+ this.idPick.emit(this.id.value);
1172
+ this.info = undefined;
1173
+ }
1174
+ resetId() {
1175
+ this.id.reset();
1176
+ this.id.markAsDirty();
1177
+ this.id.updateValueAndValidity();
1048
1178
  }
1049
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.5", ngImport: i0, type: PinTargetLookupComponent, deps: [{ token: 'indexLookupDefinitions' }, { token: ItemRefLookupService }, { token: PinRefLookupService }, { token: i1.ItemService }, { token: i1.ThesaurusService }, { token: i4$1.MatSnackBar }, { token: i1$1.FormBuilder }], target: i0.ɵɵFactoryTarget.Component });
1050
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.0.5", type: PinTargetLookupComponent, isStandalone: true, selector: "cadmus-pin-target-lookup", inputs: { pinByTypeMode: { classPropertyName: "pinByTypeMode", publicName: "pinByTypeMode", isSignal: true, isRequired: false, transformFunction: null }, canSwitchMode: { classPropertyName: "canSwitchMode", publicName: "canSwitchMode", isSignal: true, isRequired: false, transformFunction: null }, canEditTarget: { classPropertyName: "canEditTarget", publicName: "canEditTarget", isSignal: true, isRequired: false, transformFunction: null }, lookupDefinitions: { classPropertyName: "lookupDefinitions", publicName: "lookupDefinitions", isSignal: true, isRequired: false, transformFunction: null }, extLookupConfigs: { classPropertyName: "extLookupConfigs", publicName: "extLookupConfigs", isSignal: true, isRequired: false, transformFunction: null }, internalDefault: { classPropertyName: "internalDefault", publicName: "internalDefault", isSignal: true, isRequired: false, transformFunction: null }, target: { classPropertyName: "target", publicName: "target", isSignal: true, isRequired: false, transformFunction: null }, defaultPartTypeKey: { classPropertyName: "defaultPartTypeKey", publicName: "defaultPartTypeKey", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { pinByTypeMode: "pinByTypeModeChange", canSwitchMode: "canSwitchModeChange", lookupDefinitions: "lookupDefinitionsChange", target: "targetChange", editorClose: "editorClose", extMoreRequest: "extMoreRequest", extLookupConfigChange: "extLookupConfigChange" }, ngImport: i0, template: "<form [formGroup]=\"form\" (submit)=\"save()\">\r\n <div class=\"form-row\">\r\n <!-- external -->\r\n <mat-checkbox [formControl]=\"external\">external</mat-checkbox>\r\n <!-- mode switcher -->\r\n @if (!external.value) {\r\n <div>\r\n @if (canSwitchMode()) {\r\n <mat-checkbox [formControl]=\"byTypeMode\"> by type</mat-checkbox>\r\n }\r\n </div>\r\n }\r\n </div>\r\n\r\n <div class=\"form-row\">\r\n <!-- label -->\r\n <div>\r\n @if (external.value || canEditTarget()) {\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 } @if ( $any(label).errors?.maxLength && (label.dirty || label.touched)\r\n ) {\r\n <mat-error>label too long</mat-error>\r\n }\r\n </mat-form-field>\r\n } @if (!external.value && !canEditTarget() && label.value) {\r\n <div class=\"info\"><span class=\"label\">label</span>{{ label.value }}</div>\r\n }\r\n </div>\r\n\r\n <!-- gid -->\r\n <div>\r\n @if (external.value || canEditTarget()) {\r\n <mat-form-field>\r\n <mat-label>GID</mat-label>\r\n <input matInput [formControl]=\"gid\" />\r\n @if ($any(gid).errors?.required && (gid.dirty || gid.touched)) {\r\n <mat-error>GID required</mat-error>\r\n } @if ($any(gid).errors?.maxLength && (gid.dirty || gid.touched)) {\r\n <mat-error>GID too long</mat-error>\r\n }\r\n </mat-form-field>\r\n } @if (!external.value && !canEditTarget() && gid.value) {\r\n <div class=\"info\">\r\n <span class=\"label\">GID</span> <span class=\"gid\">{{ gid.value }}</span>\r\n </div>\r\n }\r\n </div>\r\n </div>\r\n\r\n <!-- external lookup set -->\r\n @if (external.value && extLookupConfigs().length) {\r\n <div>\r\n <cadmus-ref-lookup-set\r\n [configs]=\"extLookupConfigs()\"\r\n (itemChange)=\"onExtItemChange($event)\"\r\n (moreRequest)=\"onExtMoreRequest($event)\"\r\n (configChange)=\"onExtConfigChange($any($event))\"\r\n ></cadmus-ref-lookup-set>\r\n </div>\r\n }\r\n\r\n <!-- BY ITEM -->\r\n @if (!external.value) {\r\n <div>\r\n <div class=\"form-row\">\r\n @if (!byTypeMode.value) {\r\n <fieldset class=\"form-row\">\r\n <legend>pin filters</legend>\r\n <!-- item filter -->\r\n <cadmus-ref-lookup\r\n [service]=\"itemLookupService\"\r\n label=\"item\"\r\n (itemChange)=\"onItemLookupChange($event)\"\r\n ></cadmus-ref-lookup>\r\n <!-- part filter -->\r\n @if (itemParts.length) {\r\n <mat-form-field>\r\n <mat-label>part</mat-label>\r\n <mat-select [formControl]=\"itemPart\">\r\n <mat-option [value]=\"null\">(any)</mat-option>\r\n @for (p of itemParts; track p) {\r\n <mat-option [value]=\"p\">{{\r\n p.typeId | flatLookup : modelEntries : \"id\" : \"value\"\r\n }}</mat-option>\r\n }\r\n </mat-select>\r\n </mat-form-field>\r\n }\r\n </fieldset>\r\n }\r\n <!-- BY TYPE -->\r\n @if (byTypeMode.value) {\r\n <div>\r\n <!-- par type filter -->\r\n @if (partTypeKeys.length) {\r\n <mat-form-field>\r\n <mat-label>part type</mat-label>\r\n <mat-select [formControl]=\"partTypeKey\">\r\n @for (k of partTypeKeys; track k) {\r\n <mat-option [value]=\"k\">{{ k }}</mat-option>\r\n }\r\n </mat-select>\r\n </mat-form-field>\r\n }\r\n </div>\r\n }\r\n <!-- PIN -->\r\n @if (partTypeKey.value) {\r\n <div>\r\n <!-- pin lookup -->\r\n <cadmus-ref-lookup\r\n [service]=\"pinLookupService\"\r\n [baseFilter]=\"filter\"\r\n [options]=\"pinFilterOptions\"\r\n label=\"pin\"\r\n (itemChange)=\"onPinLookupChange($event)\"\r\n />\r\n </div>\r\n }\r\n </div>\r\n <!-- data -->\r\n @if (lookupData?.pin?.name) {\r\n <mat-expansion-panel id=\"data\">\r\n <mat-expansion-panel-header>pin data</mat-expansion-panel-header>\r\n <!-- table -->\r\n <table>\r\n <thead>\r\n <th></th>\r\n <th>source</th>\r\n <th>value</th>\r\n </thead>\r\n <tbody>\r\n <!-- pin -->\r\n @if (lookupData?.pin?.value) {\r\n <tr>\r\n <td>\r\n <button\r\n type=\"button\"\r\n mat-icon-button\r\n [cdkCopyToClipboard]=\"lookupData!.pin!.value\"\r\n (cdkCopyToClipboardCopied)=\"onCopied()\"\r\n >\r\n <mat-icon class=\"mat-primary\">content_copy</mat-icon>\r\n </button>\r\n </td>\r\n <td>pin</td>\r\n <td>{{ lookupData!.pin.value }}</td>\r\n </tr>\r\n }\r\n <!-- item ID -->\r\n @if (lookupData?.pin?.itemId) {\r\n <tr>\r\n <td>\r\n <button\r\n type=\"button\"\r\n mat-icon-button\r\n [cdkCopyToClipboard]=\"lookupData!.pin!.itemId\"\r\n (cdkCopyToClipboardCopied)=\"onCopied()\"\r\n >\r\n <mat-icon class=\"mat-primary\">content_copy</mat-icon>\r\n </button>\r\n </td>\r\n <td>item ID</td>\r\n <td>{{ lookupData!.pin.itemId }}</td>\r\n </tr>\r\n }\r\n <!-- item title -->\r\n @if (lookupData?.item?.title) {\r\n <tr>\r\n <td>\r\n <button\r\n type=\"button\"\r\n mat-icon-button\r\n [cdkCopyToClipboard]=\"lookupData!.item!.title\"\r\n (cdkCopyToClipboardCopied)=\"onCopied()\"\r\n >\r\n <mat-icon class=\"mat-primary\">content_copy</mat-icon>\r\n </button>\r\n </td>\r\n <td>item title</td>\r\n <td>{{ lookupData!.item!.title }}</td>\r\n </tr>\r\n }\r\n <!-- part ID -->\r\n @if (lookupData?.pin?.partId) {\r\n <tr>\r\n <td>\r\n <button\r\n type=\"button\"\r\n mat-icon-button\r\n [cdkCopyToClipboard]=\"lookupData!.pin!.partId\"\r\n (cdkCopyToClipboardCopied)=\"onCopied()\"\r\n >\r\n <mat-icon class=\"mat-primary\">content_copy</mat-icon>\r\n </button>\r\n </td>\r\n <td>part ID</td>\r\n <td>{{ lookupData!.pin.partId }}</td>\r\n </tr>\r\n }\r\n <!-- part type ID -->\r\n @if (lookupData?.pin?.partTypeId) {\r\n <tr>\r\n <td>\r\n <button\r\n type=\"button\"\r\n mat-icon-button\r\n [cdkCopyToClipboard]=\"lookupData!.pin!.partTypeId\"\r\n (cdkCopyToClipboardCopied)=\"onCopied()\"\r\n >\r\n <mat-icon class=\"mat-primary\">content_copy</mat-icon>\r\n </button>\r\n </td>\r\n <td>part type ID</td>\r\n <td>{{ lookupData!.pin!.partTypeId }}</td>\r\n </tr>\r\n }\r\n <!-- part role ID -->\r\n @if (lookupData?.pin?.roleId) {\r\n <tr>\r\n <td>\r\n <button\r\n type=\"button\"\r\n mat-icon-button\r\n [cdkCopyToClipboard]=\"lookupData!.pin!.roleId!\"\r\n (cdkCopyToClipboardCopied)=\"onCopied()\"\r\n >\r\n <mat-icon class=\"mat-primary\">content_copy</mat-icon>\r\n </button>\r\n </td>\r\n <td>part role ID</td>\r\n <td>{{ lookupData!.pin!.roleId }}</td>\r\n </tr>\r\n }\r\n <!-- part's metadata -->\r\n @for ( m of lookupData?.metaPart?.metadata || []; track m; let i =\r\n $index) {\r\n <tr>\r\n <td>\r\n <button\r\n type=\"button\"\r\n mat-icon-button\r\n [cdkCopyToClipboard]=\"m.value\"\r\n (cdkCopyToClipboardCopied)=\"onCopied()\"\r\n >\r\n <mat-icon class=\"mat-primary\">content_copy</mat-icon>\r\n </button>\r\n </td>\r\n <td class=\"metadata\">{{ m.name }}</td>\r\n <td class=\"metadata\">{{ m.value }}</td>\r\n </tr>\r\n }\r\n </tbody>\r\n </table>\r\n </mat-expansion-panel>\r\n }\r\n </div>\r\n }\r\n\r\n <!-- buttons -->\r\n <div class=\"button-row\" id=\"toolbar\">\r\n <button mat-icon-button type=\"button\" (click)=\"close()\">\r\n <mat-icon class=\"mat-warn\">close</mat-icon>\r\n </button>\r\n <button mat-flat-button type=\"submit\" [disabled]=\"form.invalid\">\r\n <mat-icon>check_circle</mat-icon>\r\n target\r\n </button>\r\n </div>\r\n</form>\r\n", styles: [".metadata{color:#4a3001}.info{border:1px solid silver;border-radius:6px;background-color:silver;color:#fff;padding:4px;margin:8px 0}.info .label{background-color:#fff;color:silver;margin:0 6px}#data{margin:8px 0}table{border:1px solid silver;border-radius:6px;padding:4px;margin-top:8px}tr:nth-child(odd){background-color:#f0f0f0}th{font-weight:400;text-align:left;color:silver}.form-row{display:flex;gap:8px;align-items:center;flex-wrap:wrap}.form-row *{flex:0 0 auto}.button-row{display:flex;align-items:center;flex-wrap:wrap}.label{border:1px solid silver;border-radius:6px;padding:4px}fieldset{border:1px solid silver;border-radius:6px;padding:8px;margin-bottom:8px}legend{color:silver}div#toolbar{margin-top:8px}\n"], dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1$1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$1.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "ngmodule", type: ClipboardModule }, { kind: "directive", type: i6$2.CdkCopyToClipboard, selector: "[cdkCopyToClipboard]", inputs: ["cdkCopyToClipboard", "cdkCopyToClipboardAttempts"], outputs: ["cdkCopyToClipboardCopied"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i3.MatButton, selector: " button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ", exportAs: ["matButton"] }, { kind: "component", type: i3.MatIconButton, selector: "button[mat-icon-button]", exportAs: ["matButton"] }, { kind: "ngmodule", type: MatCheckboxModule }, { kind: "component", type: i8$1.MatCheckbox, selector: "mat-checkbox", inputs: ["aria-label", "aria-labelledby", "aria-describedby", "aria-expanded", "aria-controls", "aria-owns", "id", "required", "labelPosition", "name", "value", "disableRipple", "tabIndex", "color", "disabledInteractive", "checked", "disabled", "indeterminate"], outputs: ["change", "indeterminateChange"], exportAs: ["matCheckbox"] }, { kind: "ngmodule", type: MatExpansionModule }, { kind: "component", type: i4.MatExpansionPanel, selector: "mat-expansion-panel", inputs: ["hideToggle", "togglePosition"], outputs: ["afterExpand", "afterCollapse"], exportAs: ["matExpansionPanel"] }, { kind: "component", type: i4.MatExpansionPanelHeader, selector: "mat-expansion-panel-header", inputs: ["expandedHeight", "collapsedHeight", "tabIndex"] }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "component", type: i6.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i6.MatLabel, selector: "mat-label" }, { kind: "directive", type: i6.MatError, selector: "mat-error, [matError]", inputs: ["id"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i7.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i8.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly", "disabledInteractive"], exportAs: ["matInput"] }, { kind: "ngmodule", type: MatSelectModule }, { kind: "component", type: i9.MatSelect, selector: "mat-select", inputs: ["aria-describedby", "panelClass", "disabled", "disableRipple", "tabIndex", "hideSingleSelectionIndicator", "placeholder", "required", "multiple", "disableOptionCentering", "compareWith", "value", "aria-label", "aria-labelledby", "errorStateMatcher", "typeaheadDebounceInterval", "sortComparator", "id", "panelWidth", "canSelectNullableOptions"], outputs: ["openedChange", "opened", "closed", "selectionChange", "valueChange"], exportAs: ["matSelect"] }, { kind: "component", type: i10.MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "component", type: RefLookupComponent, selector: "cadmus-ref-lookup", inputs: ["label", "limit", "baseFilter", "service", "item", "required", "hasMore", "linkTemplate", "optDialog", "options"], outputs: ["itemChange", "optionsChange", "moreRequest"] }, { kind: "component", type: RefLookupSetComponent, selector: "cadmus-ref-lookup-set", inputs: ["configs", "iconSize"], outputs: ["configChange", "itemChange", "moreRequest"] }, { kind: "pipe", type: FlatLookupPipe, name: "flatLookup" }] });
1179
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.0", ngImport: i0, type: ScopedPinLookupComponent, deps: [{ token: i1$1.FormBuilder }, { token: i1.ItemService }, { token: PinRefLookupService }, { token: 'indexLookupDefinitions' }], target: i0.ɵɵFactoryTarget.Component });
1180
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.0.0", type: ScopedPinLookupComponent, isStandalone: true, selector: "cadmus-scoped-pin-lookup", outputs: { idPick: "idPick" }, ngImport: i0, template: "<div>\r\n <!-- lookup -->\r\n <div>\r\n <form [formGroup]=\"keyForm\" class=\"form-row\">\r\n <!-- key -->\r\n @if (keys.length > 1) {\r\n <mat-form-field>\r\n <mat-label>type</mat-label>\r\n <mat-select [formControl]=\"key\">\r\n @for (k of keys; track k) {\r\n <mat-option [value]=\"k\">{{ k }}</mat-option>\r\n }\r\n </mat-select>\r\n @if ($any(key).errors?.required && (key.dirty || key.touched)) {\r\n <mat-error>type required</mat-error>\r\n }\r\n </mat-form-field>\r\n }\r\n <cadmus-ref-lookup\r\n [service]=\"lookupService\"\r\n label=\"pin\"\r\n [options]=\"key.value ? lookupDefs[key.value] : undefined\"\r\n (itemChange)=\"onItemChange($event)\"\r\n />\r\n </form>\r\n </div>\r\n\r\n <!-- builder -->\r\n @if (info) {\r\n <mat-expansion-panel [expanded]=\"info\" [disabled]=\"!info\">\r\n <mat-expansion-panel-header>ID builder</mat-expansion-panel-header>\r\n <!-- ID -->\r\n <div>\r\n <form [formGroup]=\"idForm\" (submit)=\"pickId()\">\r\n <mat-form-field style=\"width: 100%\">\r\n <input matInput [formControl]=\"id\" />\r\n @if ($any(id).errors?.required && (id.dirty || id.touched)) {\r\n <mat-error>ID required</mat-error>\r\n } @if ($any(id).errors?.maxLength && (id.dirty || id.touched)) {\r\n <mat-error>ID too long</mat-error>\r\n }\r\n <button\r\n mat-icon-button\r\n type=\"button\"\r\n matSuffix\r\n (click)=\"resetId()\"\r\n [disabled]=\"!id.value\"\r\n >\r\n <mat-icon class=\"mat-warn\">close</mat-icon>\r\n </button>\r\n <button\r\n mat-icon-button\r\n type=\"button\"\r\n matSuffix\r\n (click)=\"pickId()\"\r\n [disabled]=\"idForm.invalid\"\r\n >\r\n <mat-icon class=\"mat-primary\">check_circle</mat-icon>\r\n </button>\r\n </mat-form-field>\r\n </form>\r\n </div>\r\n <!-- table -->\r\n <table>\r\n <thead>\r\n <th></th>\r\n <th>source</th>\r\n <th>value</th>\r\n </thead>\r\n <tbody>\r\n <!-- pin -->\r\n <tr class=\"fit-width\">\r\n <td>\r\n <button\r\n type=\"button\"\r\n mat-icon-button\r\n (click)=\"appendIdComponent('pin')\"\r\n >\r\n <mat-icon class=\"mat-primary\">add_circle</mat-icon>\r\n </button>\r\n </td>\r\n <td>pin</td>\r\n <td>{{ info!.pin.value }}</td>\r\n </tr>\r\n <!-- item ID -->\r\n <tr>\r\n <td>\r\n <button\r\n type=\"button\"\r\n mat-icon-button\r\n (click)=\"appendIdComponent('itemId')\"\r\n >\r\n <mat-icon class=\"mat-primary\">add_circle</mat-icon>\r\n </button>\r\n </td>\r\n <td>item ID</td>\r\n <td>{{ info!.item?.id }}</td>\r\n </tr>\r\n <!-- item title -->\r\n <tr>\r\n <td></td>\r\n <td>item title</td>\r\n <td>{{ info!.item?.title }}</td>\r\n </tr>\r\n <!-- part ID -->\r\n <tr>\r\n <td>\r\n <button\r\n type=\"button\"\r\n mat-icon-button\r\n (click)=\"appendIdComponent('partId')\"\r\n >\r\n <mat-icon class=\"mat-primary\">add_circle</mat-icon>\r\n </button>\r\n </td>\r\n <td>part ID</td>\r\n <td>{{ info!.part?.id }}</td>\r\n </tr>\r\n <!-- part type ID -->\r\n <tr>\r\n <td>\r\n <button\r\n type=\"button\"\r\n mat-icon-button\r\n (click)=\"appendIdComponent('partTypeId')\"\r\n >\r\n <mat-icon class=\"mat-primary\">add_circle</mat-icon>\r\n </button>\r\n </td>\r\n <td>part type ID</td>\r\n <td>{{ info!.part?.typeId }}</td>\r\n </tr>\r\n <!-- part role ID -->\r\n <tr>\r\n <td>\r\n <button\r\n type=\"button\"\r\n mat-icon-button\r\n (click)=\"appendIdComponent('partRoleId')\"\r\n >\r\n <mat-icon class=\"mat-primary\">add_circle</mat-icon>\r\n </button>\r\n </td>\r\n <td>part role ID</td>\r\n <td>{{ info!.part?.roleId }}</td>\r\n </tr>\r\n <!-- part's metadata -->\r\n @for (m of info!.part?.metadata; track m; let i = $index) {\r\n <tr>\r\n <td>\r\n <button\r\n type=\"button\"\r\n mat-icon-button\r\n (click)=\"appendIdComponent('metadata', i)\"\r\n >\r\n <mat-icon class=\"mat-primary\">add_circle</mat-icon>\r\n </button>\r\n </td>\r\n <td class=\"metadata\">{{ m.name }}</td>\r\n <td class=\"metadata\">{{ m.value }}</td>\r\n </tr>\r\n }\r\n </tbody>\r\n </table>\r\n </mat-expansion-panel>\r\n }\r\n</div>\r\n", styles: [".metadata{color:#4a3001}table{border:1px solid silver;border-radius:6px;padding:4px;margin-top:8px}tr:nth-child(odd){background-color:#f0f0f0}th{font-weight:400;text-align:left;color:silver}td.fit-width{width:1px;white-space:nowrap}\n"], dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1$1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$1.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "ngmodule", type:
1181
+ // material
1182
+ MatButtonModule }, { kind: "component", type: i3.MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "ngmodule", type: MatExpansionModule }, { kind: "component", type: i4$1.MatExpansionPanel, selector: "mat-expansion-panel", inputs: ["hideToggle", "togglePosition"], outputs: ["afterExpand", "afterCollapse"], exportAs: ["matExpansionPanel"] }, { kind: "component", type: i4$1.MatExpansionPanelHeader, selector: "mat-expansion-panel-header", inputs: ["expandedHeight", "collapsedHeight", "tabIndex"] }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "component", type: i6$1.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i6$1.MatLabel, selector: "mat-label" }, { kind: "directive", type: i6$1.MatError, selector: "mat-error, [matError]", inputs: ["id"] }, { kind: "directive", type: i6$1.MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i7.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i8$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: MatSelectModule }, { kind: "component", type: i9.MatSelect, selector: "mat-select", inputs: ["aria-describedby", "panelClass", "disabled", "disableRipple", "tabIndex", "hideSingleSelectionIndicator", "placeholder", "required", "multiple", "disableOptionCentering", "compareWith", "value", "aria-label", "aria-labelledby", "errorStateMatcher", "typeaheadDebounceInterval", "sortComparator", "id", "panelWidth", "canSelectNullableOptions"], outputs: ["openedChange", "opened", "closed", "selectionChange", "valueChange"], exportAs: ["matSelect"] }, { kind: "component", type: i9.MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "component", type:
1183
+ // bricks
1184
+ RefLookupComponent, selector: "cadmus-ref-lookup", inputs: ["label", "limit", "baseFilter", "service", "item", "required", "hasMore", "linkTemplate", "optDialog", "options"], outputs: ["itemChange", "optionsChange", "moreRequest"] }] });
1051
1185
  }
1052
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.5", ngImport: i0, type: PinTargetLookupComponent, decorators: [{
1186
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.0", ngImport: i0, type: ScopedPinLookupComponent, decorators: [{
1053
1187
  type: Component,
1054
- args: [{ selector: 'cadmus-pin-target-lookup', imports: [
1188
+ args: [{ selector: 'cadmus-scoped-pin-lookup', imports: [
1055
1189
  FormsModule,
1056
1190
  ReactiveFormsModule,
1057
- ClipboardModule,
1191
+ // material
1058
1192
  MatButtonModule,
1059
- MatCheckboxModule,
1060
1193
  MatExpansionModule,
1061
1194
  MatFormFieldModule,
1062
1195
  MatIconModule,
1063
1196
  MatInputModule,
1064
1197
  MatSelectModule,
1198
+ // bricks
1065
1199
  RefLookupComponent,
1066
- RefLookupSetComponent,
1067
- FlatLookupPipe,
1068
- ], template: "<form [formGroup]=\"form\" (submit)=\"save()\">\r\n <div class=\"form-row\">\r\n <!-- external -->\r\n <mat-checkbox [formControl]=\"external\">external</mat-checkbox>\r\n <!-- mode switcher -->\r\n @if (!external.value) {\r\n <div>\r\n @if (canSwitchMode()) {\r\n <mat-checkbox [formControl]=\"byTypeMode\"> by type</mat-checkbox>\r\n }\r\n </div>\r\n }\r\n </div>\r\n\r\n <div class=\"form-row\">\r\n <!-- label -->\r\n <div>\r\n @if (external.value || canEditTarget()) {\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 } @if ( $any(label).errors?.maxLength && (label.dirty || label.touched)\r\n ) {\r\n <mat-error>label too long</mat-error>\r\n }\r\n </mat-form-field>\r\n } @if (!external.value && !canEditTarget() && label.value) {\r\n <div class=\"info\"><span class=\"label\">label</span>{{ label.value }}</div>\r\n }\r\n </div>\r\n\r\n <!-- gid -->\r\n <div>\r\n @if (external.value || canEditTarget()) {\r\n <mat-form-field>\r\n <mat-label>GID</mat-label>\r\n <input matInput [formControl]=\"gid\" />\r\n @if ($any(gid).errors?.required && (gid.dirty || gid.touched)) {\r\n <mat-error>GID required</mat-error>\r\n } @if ($any(gid).errors?.maxLength && (gid.dirty || gid.touched)) {\r\n <mat-error>GID too long</mat-error>\r\n }\r\n </mat-form-field>\r\n } @if (!external.value && !canEditTarget() && gid.value) {\r\n <div class=\"info\">\r\n <span class=\"label\">GID</span> <span class=\"gid\">{{ gid.value }}</span>\r\n </div>\r\n }\r\n </div>\r\n </div>\r\n\r\n <!-- external lookup set -->\r\n @if (external.value && extLookupConfigs().length) {\r\n <div>\r\n <cadmus-ref-lookup-set\r\n [configs]=\"extLookupConfigs()\"\r\n (itemChange)=\"onExtItemChange($event)\"\r\n (moreRequest)=\"onExtMoreRequest($event)\"\r\n (configChange)=\"onExtConfigChange($any($event))\"\r\n ></cadmus-ref-lookup-set>\r\n </div>\r\n }\r\n\r\n <!-- BY ITEM -->\r\n @if (!external.value) {\r\n <div>\r\n <div class=\"form-row\">\r\n @if (!byTypeMode.value) {\r\n <fieldset class=\"form-row\">\r\n <legend>pin filters</legend>\r\n <!-- item filter -->\r\n <cadmus-ref-lookup\r\n [service]=\"itemLookupService\"\r\n label=\"item\"\r\n (itemChange)=\"onItemLookupChange($event)\"\r\n ></cadmus-ref-lookup>\r\n <!-- part filter -->\r\n @if (itemParts.length) {\r\n <mat-form-field>\r\n <mat-label>part</mat-label>\r\n <mat-select [formControl]=\"itemPart\">\r\n <mat-option [value]=\"null\">(any)</mat-option>\r\n @for (p of itemParts; track p) {\r\n <mat-option [value]=\"p\">{{\r\n p.typeId | flatLookup : modelEntries : \"id\" : \"value\"\r\n }}</mat-option>\r\n }\r\n </mat-select>\r\n </mat-form-field>\r\n }\r\n </fieldset>\r\n }\r\n <!-- BY TYPE -->\r\n @if (byTypeMode.value) {\r\n <div>\r\n <!-- par type filter -->\r\n @if (partTypeKeys.length) {\r\n <mat-form-field>\r\n <mat-label>part type</mat-label>\r\n <mat-select [formControl]=\"partTypeKey\">\r\n @for (k of partTypeKeys; track k) {\r\n <mat-option [value]=\"k\">{{ k }}</mat-option>\r\n }\r\n </mat-select>\r\n </mat-form-field>\r\n }\r\n </div>\r\n }\r\n <!-- PIN -->\r\n @if (partTypeKey.value) {\r\n <div>\r\n <!-- pin lookup -->\r\n <cadmus-ref-lookup\r\n [service]=\"pinLookupService\"\r\n [baseFilter]=\"filter\"\r\n [options]=\"pinFilterOptions\"\r\n label=\"pin\"\r\n (itemChange)=\"onPinLookupChange($event)\"\r\n />\r\n </div>\r\n }\r\n </div>\r\n <!-- data -->\r\n @if (lookupData?.pin?.name) {\r\n <mat-expansion-panel id=\"data\">\r\n <mat-expansion-panel-header>pin data</mat-expansion-panel-header>\r\n <!-- table -->\r\n <table>\r\n <thead>\r\n <th></th>\r\n <th>source</th>\r\n <th>value</th>\r\n </thead>\r\n <tbody>\r\n <!-- pin -->\r\n @if (lookupData?.pin?.value) {\r\n <tr>\r\n <td>\r\n <button\r\n type=\"button\"\r\n mat-icon-button\r\n [cdkCopyToClipboard]=\"lookupData!.pin!.value\"\r\n (cdkCopyToClipboardCopied)=\"onCopied()\"\r\n >\r\n <mat-icon class=\"mat-primary\">content_copy</mat-icon>\r\n </button>\r\n </td>\r\n <td>pin</td>\r\n <td>{{ lookupData!.pin.value }}</td>\r\n </tr>\r\n }\r\n <!-- item ID -->\r\n @if (lookupData?.pin?.itemId) {\r\n <tr>\r\n <td>\r\n <button\r\n type=\"button\"\r\n mat-icon-button\r\n [cdkCopyToClipboard]=\"lookupData!.pin!.itemId\"\r\n (cdkCopyToClipboardCopied)=\"onCopied()\"\r\n >\r\n <mat-icon class=\"mat-primary\">content_copy</mat-icon>\r\n </button>\r\n </td>\r\n <td>item ID</td>\r\n <td>{{ lookupData!.pin.itemId }}</td>\r\n </tr>\r\n }\r\n <!-- item title -->\r\n @if (lookupData?.item?.title) {\r\n <tr>\r\n <td>\r\n <button\r\n type=\"button\"\r\n mat-icon-button\r\n [cdkCopyToClipboard]=\"lookupData!.item!.title\"\r\n (cdkCopyToClipboardCopied)=\"onCopied()\"\r\n >\r\n <mat-icon class=\"mat-primary\">content_copy</mat-icon>\r\n </button>\r\n </td>\r\n <td>item title</td>\r\n <td>{{ lookupData!.item!.title }}</td>\r\n </tr>\r\n }\r\n <!-- part ID -->\r\n @if (lookupData?.pin?.partId) {\r\n <tr>\r\n <td>\r\n <button\r\n type=\"button\"\r\n mat-icon-button\r\n [cdkCopyToClipboard]=\"lookupData!.pin!.partId\"\r\n (cdkCopyToClipboardCopied)=\"onCopied()\"\r\n >\r\n <mat-icon class=\"mat-primary\">content_copy</mat-icon>\r\n </button>\r\n </td>\r\n <td>part ID</td>\r\n <td>{{ lookupData!.pin.partId }}</td>\r\n </tr>\r\n }\r\n <!-- part type ID -->\r\n @if (lookupData?.pin?.partTypeId) {\r\n <tr>\r\n <td>\r\n <button\r\n type=\"button\"\r\n mat-icon-button\r\n [cdkCopyToClipboard]=\"lookupData!.pin!.partTypeId\"\r\n (cdkCopyToClipboardCopied)=\"onCopied()\"\r\n >\r\n <mat-icon class=\"mat-primary\">content_copy</mat-icon>\r\n </button>\r\n </td>\r\n <td>part type ID</td>\r\n <td>{{ lookupData!.pin!.partTypeId }}</td>\r\n </tr>\r\n }\r\n <!-- part role ID -->\r\n @if (lookupData?.pin?.roleId) {\r\n <tr>\r\n <td>\r\n <button\r\n type=\"button\"\r\n mat-icon-button\r\n [cdkCopyToClipboard]=\"lookupData!.pin!.roleId!\"\r\n (cdkCopyToClipboardCopied)=\"onCopied()\"\r\n >\r\n <mat-icon class=\"mat-primary\">content_copy</mat-icon>\r\n </button>\r\n </td>\r\n <td>part role ID</td>\r\n <td>{{ lookupData!.pin!.roleId }}</td>\r\n </tr>\r\n }\r\n <!-- part's metadata -->\r\n @for ( m of lookupData?.metaPart?.metadata || []; track m; let i =\r\n $index) {\r\n <tr>\r\n <td>\r\n <button\r\n type=\"button\"\r\n mat-icon-button\r\n [cdkCopyToClipboard]=\"m.value\"\r\n (cdkCopyToClipboardCopied)=\"onCopied()\"\r\n >\r\n <mat-icon class=\"mat-primary\">content_copy</mat-icon>\r\n </button>\r\n </td>\r\n <td class=\"metadata\">{{ m.name }}</td>\r\n <td class=\"metadata\">{{ m.value }}</td>\r\n </tr>\r\n }\r\n </tbody>\r\n </table>\r\n </mat-expansion-panel>\r\n }\r\n </div>\r\n }\r\n\r\n <!-- buttons -->\r\n <div class=\"button-row\" id=\"toolbar\">\r\n <button mat-icon-button type=\"button\" (click)=\"close()\">\r\n <mat-icon class=\"mat-warn\">close</mat-icon>\r\n </button>\r\n <button mat-flat-button type=\"submit\" [disabled]=\"form.invalid\">\r\n <mat-icon>check_circle</mat-icon>\r\n target\r\n </button>\r\n </div>\r\n</form>\r\n", styles: [".metadata{color:#4a3001}.info{border:1px solid silver;border-radius:6px;background-color:silver;color:#fff;padding:4px;margin:8px 0}.info .label{background-color:#fff;color:silver;margin:0 6px}#data{margin:8px 0}table{border:1px solid silver;border-radius:6px;padding:4px;margin-top:8px}tr:nth-child(odd){background-color:#f0f0f0}th{font-weight:400;text-align:left;color:silver}.form-row{display:flex;gap:8px;align-items:center;flex-wrap:wrap}.form-row *{flex:0 0 auto}.button-row{display:flex;align-items:center;flex-wrap:wrap}.label{border:1px solid silver;border-radius:6px;padding:4px}fieldset{border:1px solid silver;border-radius:6px;padding:8px;margin-bottom:8px}legend{color:silver}div#toolbar{margin-top:8px}\n"] }]
1069
- }], ctorParameters: () => [{ type: undefined, decorators: [{
1200
+ ], template: "<div>\r\n <!-- lookup -->\r\n <div>\r\n <form [formGroup]=\"keyForm\" class=\"form-row\">\r\n <!-- key -->\r\n @if (keys.length > 1) {\r\n <mat-form-field>\r\n <mat-label>type</mat-label>\r\n <mat-select [formControl]=\"key\">\r\n @for (k of keys; track k) {\r\n <mat-option [value]=\"k\">{{ k }}</mat-option>\r\n }\r\n </mat-select>\r\n @if ($any(key).errors?.required && (key.dirty || key.touched)) {\r\n <mat-error>type required</mat-error>\r\n }\r\n </mat-form-field>\r\n }\r\n <cadmus-ref-lookup\r\n [service]=\"lookupService\"\r\n label=\"pin\"\r\n [options]=\"key.value ? lookupDefs[key.value] : undefined\"\r\n (itemChange)=\"onItemChange($event)\"\r\n />\r\n </form>\r\n </div>\r\n\r\n <!-- builder -->\r\n @if (info) {\r\n <mat-expansion-panel [expanded]=\"info\" [disabled]=\"!info\">\r\n <mat-expansion-panel-header>ID builder</mat-expansion-panel-header>\r\n <!-- ID -->\r\n <div>\r\n <form [formGroup]=\"idForm\" (submit)=\"pickId()\">\r\n <mat-form-field style=\"width: 100%\">\r\n <input matInput [formControl]=\"id\" />\r\n @if ($any(id).errors?.required && (id.dirty || id.touched)) {\r\n <mat-error>ID required</mat-error>\r\n } @if ($any(id).errors?.maxLength && (id.dirty || id.touched)) {\r\n <mat-error>ID too long</mat-error>\r\n }\r\n <button\r\n mat-icon-button\r\n type=\"button\"\r\n matSuffix\r\n (click)=\"resetId()\"\r\n [disabled]=\"!id.value\"\r\n >\r\n <mat-icon class=\"mat-warn\">close</mat-icon>\r\n </button>\r\n <button\r\n mat-icon-button\r\n type=\"button\"\r\n matSuffix\r\n (click)=\"pickId()\"\r\n [disabled]=\"idForm.invalid\"\r\n >\r\n <mat-icon class=\"mat-primary\">check_circle</mat-icon>\r\n </button>\r\n </mat-form-field>\r\n </form>\r\n </div>\r\n <!-- table -->\r\n <table>\r\n <thead>\r\n <th></th>\r\n <th>source</th>\r\n <th>value</th>\r\n </thead>\r\n <tbody>\r\n <!-- pin -->\r\n <tr class=\"fit-width\">\r\n <td>\r\n <button\r\n type=\"button\"\r\n mat-icon-button\r\n (click)=\"appendIdComponent('pin')\"\r\n >\r\n <mat-icon class=\"mat-primary\">add_circle</mat-icon>\r\n </button>\r\n </td>\r\n <td>pin</td>\r\n <td>{{ info!.pin.value }}</td>\r\n </tr>\r\n <!-- item ID -->\r\n <tr>\r\n <td>\r\n <button\r\n type=\"button\"\r\n mat-icon-button\r\n (click)=\"appendIdComponent('itemId')\"\r\n >\r\n <mat-icon class=\"mat-primary\">add_circle</mat-icon>\r\n </button>\r\n </td>\r\n <td>item ID</td>\r\n <td>{{ info!.item?.id }}</td>\r\n </tr>\r\n <!-- item title -->\r\n <tr>\r\n <td></td>\r\n <td>item title</td>\r\n <td>{{ info!.item?.title }}</td>\r\n </tr>\r\n <!-- part ID -->\r\n <tr>\r\n <td>\r\n <button\r\n type=\"button\"\r\n mat-icon-button\r\n (click)=\"appendIdComponent('partId')\"\r\n >\r\n <mat-icon class=\"mat-primary\">add_circle</mat-icon>\r\n </button>\r\n </td>\r\n <td>part ID</td>\r\n <td>{{ info!.part?.id }}</td>\r\n </tr>\r\n <!-- part type ID -->\r\n <tr>\r\n <td>\r\n <button\r\n type=\"button\"\r\n mat-icon-button\r\n (click)=\"appendIdComponent('partTypeId')\"\r\n >\r\n <mat-icon class=\"mat-primary\">add_circle</mat-icon>\r\n </button>\r\n </td>\r\n <td>part type ID</td>\r\n <td>{{ info!.part?.typeId }}</td>\r\n </tr>\r\n <!-- part role ID -->\r\n <tr>\r\n <td>\r\n <button\r\n type=\"button\"\r\n mat-icon-button\r\n (click)=\"appendIdComponent('partRoleId')\"\r\n >\r\n <mat-icon class=\"mat-primary\">add_circle</mat-icon>\r\n </button>\r\n </td>\r\n <td>part role ID</td>\r\n <td>{{ info!.part?.roleId }}</td>\r\n </tr>\r\n <!-- part's metadata -->\r\n @for (m of info!.part?.metadata; track m; let i = $index) {\r\n <tr>\r\n <td>\r\n <button\r\n type=\"button\"\r\n mat-icon-button\r\n (click)=\"appendIdComponent('metadata', i)\"\r\n >\r\n <mat-icon class=\"mat-primary\">add_circle</mat-icon>\r\n </button>\r\n </td>\r\n <td class=\"metadata\">{{ m.name }}</td>\r\n <td class=\"metadata\">{{ m.value }}</td>\r\n </tr>\r\n }\r\n </tbody>\r\n </table>\r\n </mat-expansion-panel>\r\n }\r\n</div>\r\n", styles: [".metadata{color:#4a3001}table{border:1px solid silver;border-radius:6px;padding:4px;margin-top:8px}tr:nth-child(odd){background-color:#f0f0f0}th{font-weight:400;text-align:left;color:silver}td.fit-width{width:1px;white-space:nowrap}\n"] }]
1201
+ }], ctorParameters: () => [{ type: i1$1.FormBuilder }, { type: i1.ItemService }, { type: PinRefLookupService }, { type: undefined, decorators: [{
1070
1202
  type: Inject,
1071
1203
  args: ['indexLookupDefinitions']
1072
- }] }, { type: ItemRefLookupService }, { type: PinRefLookupService }, { type: i1.ItemService }, { type: i1.ThesaurusService }, { type: i4$1.MatSnackBar }, { type: i1$1.FormBuilder }] });
1204
+ }] }] });
1073
1205
 
1074
1206
  /**
1075
- * The key to be used to retrieve the external lookup configs from the
1076
- * settings storage. This is equal to the selector of
1077
- * AssertedCompositeIdComponent plus ".configs".
1078
- */
1079
- const ASSERTED_COMPOSITE_ID_CONFIGS_KEY = 'cadmus-refs-asserted-composite-id.configs';
1080
- /**
1081
- * An asserted composite ID editor. This allows the user to edit an asserted
1082
- * composite ID, which can be an external ID or a lookup ID.
1207
+ * Asserted ID editor component.
1083
1208
  */
1084
- class AssertedCompositeIdComponent {
1209
+ class AssertedIdComponent {
1085
1210
  lookupService;
1086
1211
  lookupDefs;
1087
1212
  _sub;
1088
1213
  _updatingForm;
1089
- extLookupConfigs;
1090
- targetExpanded = false;
1091
- // form
1092
- target;
1093
- scope;
1094
1214
  tag;
1215
+ value;
1216
+ label;
1217
+ scope;
1095
1218
  assertion;
1096
1219
  form;
1220
+ lookupExpanded;
1097
1221
  // asserted-id-scopes
1098
1222
  idScopeEntries = input();
1099
1223
  // asserted-id-tags
@@ -1105,71 +1229,40 @@ class AssertedCompositeIdComponent {
1105
1229
  // doc-reference-tags
1106
1230
  refTagEntries = input();
1107
1231
  /**
1108
- * The ID being edited.
1232
+ * The asserted ID being edited.
1109
1233
  */
1110
1234
  id = model();
1111
1235
  /**
1112
- * True if when a new ID is set it should be internal rather than
1113
- * external by default.
1236
+ * True to hide the pin-based EID lookup UI.
1114
1237
  */
1115
- internalDefault = input();
1238
+ noEidLookup = input();
1116
1239
  /**
1117
- * True if the UI has a submit button.
1240
+ * True to show the submit button.
1118
1241
  */
1119
1242
  hasSubmit = input();
1120
1243
  /**
1121
- * True when the internal UI preselected mode should be by type rather than
1122
- * by item. User can change mode unless modeSwitching is false.
1123
- */
1124
- pinByTypeMode = input();
1125
- /**
1126
- * True when the user can switch between by-type and by-item mode in
1127
- * the internal UI.
1128
- */
1129
- canSwitchMode = input();
1130
- /**
1131
- * True when the user can edit the target's gid/label for internal targets.
1132
- */
1133
- canEditTarget = input();
1134
- /**
1135
- * The lookup definitions to be used for the by-type lookup in the internal UI.
1136
- * If not specified, the lookup definitions will be got via injection
1137
- * when available; if the injected definitions are empty, the
1138
- * lookup definitions will be built from the model-types thesaurus;
1139
- * if this is not available either, the by-type lookup will be
1140
- * disabled.
1141
- */
1142
- lookupDefinitions = input();
1143
- /**
1144
- * The default part type key to be used.
1145
- */
1146
- defaultPartTypeKey = input();
1147
- /**
1148
- * Emitted whenever the user requests to close the editor.
1244
+ * Emitted when the editor is closed.
1149
1245
  */
1150
1246
  editorClose = output();
1151
- /**
1152
- * Emitted when the user requests more.
1153
- */
1154
- extMoreRequest = output();
1155
- constructor(formBuilder, lookupService, lookupDefs, settings) {
1247
+ constructor(formBuilder, lookupService, lookupDefs) {
1156
1248
  this.lookupService = lookupService;
1157
1249
  this.lookupDefs = lookupDefs;
1158
- // form
1159
- this.target = formBuilder.control(null, Validators.required);
1160
- this.scope = formBuilder.control(null, Validators.maxLength(500));
1161
1250
  this.tag = formBuilder.control(null, Validators.maxLength(50));
1251
+ this.value = formBuilder.control(null, [
1252
+ Validators.required,
1253
+ Validators.maxLength(500),
1254
+ ]);
1255
+ this.label = formBuilder.control(null, Validators.maxLength(500));
1256
+ this.scope = formBuilder.control(null, Validators.maxLength(500));
1162
1257
  this.assertion = formBuilder.control(null);
1163
1258
  this.form = formBuilder.group({
1164
- target: this.target,
1165
- scope: this.scope,
1166
1259
  tag: this.tag,
1260
+ value: this.value,
1261
+ label: this.label,
1262
+ scope: this.scope,
1167
1263
  assertion: this.assertion,
1168
1264
  });
1169
- // external lookup configs
1170
- this.extLookupConfigs =
1171
- settings.retrieve(ASSERTED_COMPOSITE_ID_CONFIGS_KEY) ||
1172
- [];
1265
+ this.lookupExpanded = false;
1173
1266
  // when id changes, update form
1174
1267
  effect(() => {
1175
1268
  this.updateForm(this.id());
@@ -1177,7 +1270,7 @@ class AssertedCompositeIdComponent {
1177
1270
  }
1178
1271
  ngOnInit() {
1179
1272
  this._sub = this.form.valueChanges
1180
- .pipe(debounceTime(300))
1273
+ .pipe(debounceTime$1(300))
1181
1274
  .subscribe((_) => {
1182
1275
  if (!this._updatingForm) {
1183
1276
  this.emitIdChange();
@@ -1190,40 +1283,33 @@ class AssertedCompositeIdComponent {
1190
1283
  onAssertionChange(assertion) {
1191
1284
  this.assertion.setValue(assertion || null);
1192
1285
  }
1193
- onTargetChange(target) {
1194
- this.target.setValue(target);
1195
- this.target.markAsDirty();
1196
- this.target.updateValueAndValidity();
1197
- if (this.form.valid) {
1198
- this.targetExpanded = false;
1199
- }
1286
+ onIdPick(id) {
1287
+ this.value.setValue(id);
1288
+ this.value.markAsDirty();
1289
+ this.value.updateValueAndValidity();
1290
+ this.lookupExpanded = false;
1200
1291
  }
1201
- updateForm(id) {
1292
+ updateForm(value) {
1202
1293
  this._updatingForm = true;
1203
- if (!id) {
1294
+ if (!value) {
1204
1295
  this.form.reset();
1205
1296
  }
1206
1297
  else {
1207
- this.target.setValue(id.target);
1208
- this.scope.setValue(id.scope || null);
1209
- this.tag.setValue(id.tag || null);
1210
- this.assertion.setValue(id.assertion || null);
1298
+ this.tag.setValue(value.tag || null);
1299
+ this.value.setValue(value.value);
1300
+ this.label.setValue(value.label || null);
1301
+ this.scope.setValue(value.scope);
1302
+ this.assertion.setValue(value.assertion || null);
1211
1303
  this.form.markAsPristine();
1212
1304
  }
1213
1305
  this._updatingForm = false;
1214
1306
  }
1215
1307
  getId() {
1216
- const external = !this.target.value?.name;
1217
- const target = this.target.value;
1218
1308
  return {
1219
- target: external
1220
- ? {
1221
- gid: target?.gid || '',
1222
- label: target?.label || target?.gid || '',
1223
- }
1224
- : target,
1225
- scope: this.scope.value?.trim() || '',
1226
1309
  tag: this.tag.value?.trim(),
1310
+ value: this.value.value?.trim() || '',
1311
+ label: this.label.value?.trim() || undefined,
1312
+ scope: this.scope.value?.trim() || '',
1227
1313
  assertion: this.assertion.value || undefined,
1228
1314
  };
1229
1315
  }
@@ -1232,20 +1318,6 @@ class AssertedCompositeIdComponent {
1232
1318
  this.id.set(this.getId());
1233
1319
  }
1234
1320
  }
1235
- onEditorClose() {
1236
- this.targetExpanded = false;
1237
- }
1238
- onExtMoreRequest(event) {
1239
- this.extMoreRequest.emit(event);
1240
- }
1241
- onExtLookupConfigChange(config) {
1242
- if (!this.scope.value ||
1243
- this.extLookupConfigs.some((c) => c.name === this.scope.value)) {
1244
- this.scope.setValue(config.name || null);
1245
- this.scope.markAsDirty();
1246
- this.scope.updateValueAndValidity();
1247
- }
1248
- }
1249
1321
  cancel() {
1250
1322
  this.editorClose.emit();
1251
1323
  }
@@ -1254,49 +1326,45 @@ class AssertedCompositeIdComponent {
1254
1326
  this.id.set(this.getId());
1255
1327
  }
1256
1328
  }
1257
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.5", ngImport: i0, type: AssertedCompositeIdComponent, deps: [{ token: i1$1.FormBuilder }, { token: PinRefLookupService }, { token: 'indexLookupDefinitions' }, { token: i3$1.RamStorageService }], target: i0.ɵɵFactoryTarget.Component });
1258
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.0.5", type: AssertedCompositeIdComponent, isStandalone: true, selector: "cadmus-refs-asserted-composite-id", inputs: { idScopeEntries: { classPropertyName: "idScopeEntries", publicName: "idScopeEntries", isSignal: true, isRequired: false, transformFunction: null }, idTagEntries: { classPropertyName: "idTagEntries", publicName: "idTagEntries", isSignal: true, isRequired: false, transformFunction: null }, assTagEntries: { classPropertyName: "assTagEntries", publicName: "assTagEntries", isSignal: true, isRequired: false, transformFunction: null }, refTypeEntries: { classPropertyName: "refTypeEntries", publicName: "refTypeEntries", isSignal: true, isRequired: false, transformFunction: null }, refTagEntries: { classPropertyName: "refTagEntries", publicName: "refTagEntries", isSignal: true, isRequired: false, transformFunction: null }, id: { classPropertyName: "id", publicName: "id", isSignal: true, isRequired: false, transformFunction: null }, internalDefault: { classPropertyName: "internalDefault", publicName: "internalDefault", isSignal: true, isRequired: false, transformFunction: null }, hasSubmit: { classPropertyName: "hasSubmit", publicName: "hasSubmit", isSignal: true, isRequired: false, transformFunction: null }, pinByTypeMode: { classPropertyName: "pinByTypeMode", publicName: "pinByTypeMode", isSignal: true, isRequired: false, transformFunction: null }, canSwitchMode: { classPropertyName: "canSwitchMode", publicName: "canSwitchMode", isSignal: true, isRequired: false, transformFunction: null }, canEditTarget: { classPropertyName: "canEditTarget", publicName: "canEditTarget", isSignal: true, isRequired: false, transformFunction: null }, lookupDefinitions: { classPropertyName: "lookupDefinitions", publicName: "lookupDefinitions", isSignal: true, isRequired: false, transformFunction: null }, defaultPartTypeKey: { classPropertyName: "defaultPartTypeKey", publicName: "defaultPartTypeKey", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { id: "idChange", editorClose: "editorClose", extMoreRequest: "extMoreRequest" }, ngImport: i0, template: "<form [formGroup]=\"form\" (submit)=\"save()\">\n <div>\n <div class=\"form-row\">\n <!-- tag (bound) -->\n @if (idTagEntries()?.length) {\n <mat-form-field class=\"short-text\">\n <mat-label>tag</mat-label>\n <mat-select [formControl]=\"tag\">\n @for (e of idTagEntries(); track e) {\n <mat-option [value]=\"e.id\">{{ e.value }}</mat-option>\n }\n </mat-select>\n </mat-form-field>\n }\n <!-- tag (free) -->\n @else {\n <mat-form-field class=\"short-text\">\n <mat-label>tag</mat-label>\n <input matInput [formControl]=\"tag\" />\n @if ($any(tag.errors)?.maxLength && (tag.dirty || tag.touched)) {\n <mat-error>tag too long</mat-error>\n }\n </mat-form-field>\n }\n\n <!-- scope (bound) -->\n @if (idScopeEntries()?.length) {\n <mat-form-field class=\"short-text\">\n <mat-label>scope</mat-label>\n <mat-select [formControl]=\"scope\">\n @for (e of idScopeEntries(); track e) {\n <mat-option [value]=\"e.id\">{{ e.value }}</mat-option>\n }\n </mat-select>\n </mat-form-field>\n }\n <!-- scope (free) -->\n @else {\n <mat-form-field class=\"short-text\">\n <mat-label>scope</mat-label>\n <input matInput [formControl]=\"scope\" />\n @if ( $any(scope.errors)?.maxLength && (scope.dirty || scope.touched) )\n {\n <mat-error>scope too long</mat-error>\n }\n </mat-form-field>\n }\n\n <!-- label and GID -->\n @if (target.value?.label) {\n <div class=\"info\">\n <span class=\"label\">label</span>{{ target.value?.label }}\n </div>\n } @if (target.value?.gid) {\n <div class=\"info\">\n <span class=\"label\">GID</span>{{ target.value?.gid }}\n </div>\n }\n </div>\n\n <!-- target -->\n <div class=\"boxed\">\n <mat-expansion-panel [(expanded)]=\"targetExpanded\">\n <mat-expansion-panel-header>target</mat-expansion-panel-header>\n <cadmus-pin-target-lookup\n [pinByTypeMode]=\"pinByTypeMode()\"\n [canSwitchMode]=\"canSwitchMode()\"\n [canEditTarget]=\"canEditTarget()\"\n [lookupDefinitions]=\"lookupDefinitions()\"\n [defaultPartTypeKey]=\"defaultPartTypeKey()\"\n [target]=\"target.value || undefined\"\n [internalDefault]=\"internalDefault()\"\n [extLookupConfigs]=\"extLookupConfigs\"\n (targetChange)=\"onTargetChange($event)\"\n (editorClose)=\"onEditorClose()\"\n (extMoreRequest)=\"onExtMoreRequest($event)\"\n (extLookupConfigChange)=\"onExtLookupConfigChange($event)\"\n />\n </mat-expansion-panel>\n </div>\n\n <!-- assertion -->\n <br />\n <div class=\"boxed\">\n <mat-expansion-panel>\n <mat-expansion-panel-header>assertion</mat-expansion-panel-header>\n <cadmus-refs-assertion\n [assTagEntries]=\"assTagEntries()\"\n [refTypeEntries]=\"refTypeEntries()\"\n [refTagEntries]=\"refTagEntries()\"\n [assertion]=\"assertion.value || undefined\"\n (assertionChange)=\"onAssertionChange($event)\"\n >\n </cadmus-refs-assertion>\n </mat-expansion-panel>\n </div>\n </div>\n\n <!-- buttons -->\n @if (hasSubmit()) {\n <div>\n <button\n mat-icon-button\n type=\"button\"\n (click)=\"cancel()\"\n [disabled]=\"!this.target.value?.gid || !this.target.value?.label\"\n >\n <mat-icon class=\"mat-warn\">close</mat-icon>\n </button>\n <button mat-icon-button type=\"submit\" [disabled]=\"form.invalid\">\n <mat-icon class=\"mat-primary\">check_circle</mat-icon>\n </button>\n </div>\n }\n</form>\n", styles: [".form-row{display:flex;gap:8px;align-items:center;flex-wrap:wrap}.form-row *{flex:0 0 auto}.boxed{border:1px solid silver;border-radius:6px;padding:6px}.short-text{width:8em}.pin-info{font-size:90%;color:silver}fieldset{border:1px solid silver;border-radius:6px;padding:6px}.info{border:1px solid silver;border-radius:6px;background-color:silver;color:#fff;padding:4px}.info .label{background-color:#fff;color:silver;margin:0 6px}@media only screen and (max-width: 959px){div#container{grid-template-rows:1fr auto;grid-template-columns:1fr;grid-template-areas:\"editor\" \"lookup\"}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { 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: i3.MatIconButton, selector: "button[mat-icon-button]", exportAs: ["matButton"] }, { kind: "ngmodule", type: MatExpansionModule }, { kind: "component", type: i4.MatExpansionPanel, selector: "mat-expansion-panel", inputs: ["hideToggle", "togglePosition"], outputs: ["afterExpand", "afterCollapse"], exportAs: ["matExpansionPanel"] }, { kind: "component", type: i4.MatExpansionPanelHeader, selector: "mat-expansion-panel-header", inputs: ["expandedHeight", "collapsedHeight", "tabIndex"] }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "component", type: i6.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i6.MatLabel, selector: "mat-label" }, { kind: "directive", type: i6.MatError, selector: "mat-error, [matError]", inputs: ["id"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i7.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i8.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly", "disabledInteractive"], exportAs: ["matInput"] }, { kind: "ngmodule", type: MatSelectModule }, { kind: "component", type: i9.MatSelect, selector: "mat-select", inputs: ["aria-describedby", "panelClass", "disabled", "disableRipple", "tabIndex", "hideSingleSelectionIndicator", "placeholder", "required", "multiple", "disableOptionCentering", "compareWith", "value", "aria-label", "aria-labelledby", "errorStateMatcher", "typeaheadDebounceInterval", "sortComparator", "id", "panelWidth", "canSelectNullableOptions"], outputs: ["openedChange", "opened", "closed", "selectionChange", "valueChange"], exportAs: ["matSelect"] }, { kind: "component", type: i10.MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "component", type: AssertionComponent, selector: "cadmus-refs-assertion", inputs: ["assTagEntries", "refTypeEntries", "refTagEntries", "assertion"], outputs: ["assertionChange"] }, { kind: "component", type: PinTargetLookupComponent, selector: "cadmus-pin-target-lookup", inputs: ["pinByTypeMode", "canSwitchMode", "canEditTarget", "lookupDefinitions", "extLookupConfigs", "internalDefault", "target", "defaultPartTypeKey"], outputs: ["pinByTypeModeChange", "canSwitchModeChange", "lookupDefinitionsChange", "targetChange", "editorClose", "extMoreRequest", "extLookupConfigChange"] }] });
1329
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.0", ngImport: i0, type: AssertedIdComponent, deps: [{ token: i1$1.FormBuilder }, { token: PinRefLookupService }, { token: 'indexLookupDefinitions' }], target: i0.ɵɵFactoryTarget.Component });
1330
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.0.0", type: AssertedIdComponent, isStandalone: true, selector: "cadmus-refs-asserted-id", inputs: { idScopeEntries: { classPropertyName: "idScopeEntries", publicName: "idScopeEntries", isSignal: true, isRequired: false, transformFunction: null }, idTagEntries: { classPropertyName: "idTagEntries", publicName: "idTagEntries", isSignal: true, isRequired: false, transformFunction: null }, assTagEntries: { classPropertyName: "assTagEntries", publicName: "assTagEntries", isSignal: true, isRequired: false, transformFunction: null }, refTypeEntries: { classPropertyName: "refTypeEntries", publicName: "refTypeEntries", isSignal: true, isRequired: false, transformFunction: null }, refTagEntries: { classPropertyName: "refTagEntries", publicName: "refTagEntries", isSignal: true, isRequired: false, transformFunction: null }, id: { classPropertyName: "id", publicName: "id", isSignal: true, isRequired: false, transformFunction: null }, noEidLookup: { classPropertyName: "noEidLookup", publicName: "noEidLookup", isSignal: true, isRequired: false, transformFunction: null }, hasSubmit: { classPropertyName: "hasSubmit", publicName: "hasSubmit", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { id: "idChange", editorClose: "editorClose" }, ngImport: i0, template: "<form [formGroup]=\"form\" (submit)=\"save()\">\r\n <div>\r\n <div class=\"form-row\">\r\n <!-- tag (bound) -->\r\n @if (idTagEntries()?.length) {\r\n <mat-form-field>\r\n <mat-label>tag</mat-label>\r\n <mat-select [formControl]=\"tag\">\r\n @for (e of idTagEntries(); track e) {\r\n <mat-option [value]=\"e.id\">{{ e.value }}</mat-option>\r\n }\r\n </mat-select>\r\n </mat-form-field>\r\n }\r\n <!-- tag (free) -->\r\n @else {\r\n <mat-form-field>\r\n <mat-label>tag</mat-label>\r\n <input matInput [formControl]=\"tag\" />\r\n @if ($any(tag.errors)?.maxLength && (tag.dirty || tag.touched)) {\r\n <mat-error>tag too long</mat-error>\r\n }\r\n </mat-form-field>\r\n }\r\n\r\n <!-- scope (bound) -->\r\n @if (idScopeEntries()?.length) {\r\n <mat-form-field>\r\n <mat-label>scope</mat-label>\r\n <mat-select [formControl]=\"scope\">\r\n @for (e of idScopeEntries(); track e) {\r\n <mat-option [value]=\"e.id\">{{ e.value }}</mat-option>\r\n }\r\n </mat-select>\r\n </mat-form-field>\r\n }\r\n <!-- scope (free) -->\r\n @else {\r\n <mat-form-field>\r\n <mat-label>scope</mat-label>\r\n <input matInput [formControl]=\"scope\" />\r\n @if ($any(scope.errors)?.maxLength && (scope.dirty || scope.touched)) {\r\n <mat-error>scope too long</mat-error>\r\n }\r\n </mat-form-field>\r\n }\r\n\r\n <!-- value -->\r\n <mat-form-field>\r\n <mat-label>value</mat-label>\r\n <input matInput [formControl]=\"value\" />\r\n @if ($any(value.errors)?.required && (value.dirty || value.touched)) {\r\n <mat-error>value required</mat-error>\r\n } @if ($any(value.errors)?.maxLength && (value.dirty || value.touched))\r\n {\r\n <mat-error>value too long</mat-error>\r\n }\r\n </mat-form-field>\r\n\r\n <!-- label -->\r\n <mat-form-field>\r\n <mat-label>label</mat-label>\r\n <input matInput [formControl]=\"label\" />\r\n @if ($any(label.errors)?.maxLength && (label.dirty || label.touched)) {\r\n <mat-error>label too long</mat-error>\r\n }\r\n </mat-form-field>\r\n\r\n <!-- lookup -->\r\n @if (!noEidLookup()) {\r\n <div>\r\n <mat-expansion-panel [(expanded)]=\"lookupExpanded\">\r\n <mat-expansion-panel-header>lookup</mat-expansion-panel-header>\r\n <cadmus-scoped-pin-lookup (idPick)=\"onIdPick($event)\" />\r\n </mat-expansion-panel>\r\n </div>\r\n }\r\n </div>\r\n\r\n <!-- assertion -->\r\n <mat-expansion-panel>\r\n <mat-expansion-panel-header>assertion</mat-expansion-panel-header>\r\n <cadmus-refs-assertion\r\n [assTagEntries]=\"assTagEntries()\"\r\n [refTypeEntries]=\"refTypeEntries()\"\r\n [refTagEntries]=\"refTagEntries()\"\r\n [assertion]=\"assertion.value || undefined\"\r\n (assertionChange)=\"onAssertionChange($event)\"\r\n />\r\n </mat-expansion-panel>\r\n </div>\r\n\r\n <!-- buttons -->\r\n @if (hasSubmit()) {\r\n <div>\r\n <button mat-icon-button type=\"button\" (click)=\"cancel()\">\r\n <mat-icon class=\"mat-warn\">close</mat-icon>\r\n </button>\r\n <button mat-icon-button type=\"submit\" [disabled]=\"form.invalid\">\r\n <mat-icon class=\"mat-primary\">check_circle</mat-icon>\r\n </button>\r\n </div>\r\n }\r\n</form>\r\n", styles: [".form-row{display:flex;gap:8px;align-items:flex-start;flex-wrap:wrap}.form-row *{flex:0 0 auto}.pin-info{font-size:90%;color:silver}fieldset{border:1px solid silver;border-radius:6px;padding:6px}@media only screen and (max-width: 959px){div#container{grid-template-rows:1fr auto;grid-template-columns:1fr;grid-template-areas:\"editor\" \"lookup\"}}\n"], dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1$1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$1.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "ngmodule", type:
1331
+ // material
1332
+ MatButtonModule }, { kind: "component", type: i3.MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "ngmodule", type: MatExpansionModule }, { kind: "component", type: i4$1.MatExpansionPanel, selector: "mat-expansion-panel", inputs: ["hideToggle", "togglePosition"], outputs: ["afterExpand", "afterCollapse"], exportAs: ["matExpansionPanel"] }, { kind: "component", type: i4$1.MatExpansionPanelHeader, selector: "mat-expansion-panel-header", inputs: ["expandedHeight", "collapsedHeight", "tabIndex"] }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "component", type: i6$1.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i6$1.MatLabel, selector: "mat-label" }, { kind: "directive", type: i6$1.MatError, selector: "mat-error, [matError]", inputs: ["id"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i7.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i8$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: MatSelectModule }, { kind: "component", type: i9.MatSelect, selector: "mat-select", inputs: ["aria-describedby", "panelClass", "disabled", "disableRipple", "tabIndex", "hideSingleSelectionIndicator", "placeholder", "required", "multiple", "disableOptionCentering", "compareWith", "value", "aria-label", "aria-labelledby", "errorStateMatcher", "typeaheadDebounceInterval", "sortComparator", "id", "panelWidth", "canSelectNullableOptions"], outputs: ["openedChange", "opened", "closed", "selectionChange", "valueChange"], exportAs: ["matSelect"] }, { kind: "component", type: i9.MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "component", type:
1333
+ // bricks
1334
+ AssertionComponent, selector: "cadmus-refs-assertion", inputs: ["assTagEntries", "refTypeEntries", "refTagEntries", "assertion"], outputs: ["assertionChange"] }, { kind: "component", type: ScopedPinLookupComponent, selector: "cadmus-scoped-pin-lookup", outputs: ["idPick"] }] });
1259
1335
  }
1260
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.5", ngImport: i0, type: AssertedCompositeIdComponent, decorators: [{
1336
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.0", ngImport: i0, type: AssertedIdComponent, decorators: [{
1261
1337
  type: Component,
1262
- args: [{ selector: 'cadmus-refs-asserted-composite-id', imports: [
1263
- CommonModule,
1338
+ args: [{ selector: 'cadmus-refs-asserted-id', imports: [
1339
+ FormsModule,
1264
1340
  ReactiveFormsModule,
1341
+ // material
1265
1342
  MatButtonModule,
1266
1343
  MatExpansionModule,
1267
1344
  MatFormFieldModule,
1268
1345
  MatIconModule,
1269
1346
  MatInputModule,
1270
1347
  MatSelectModule,
1271
- MatTooltipModule,
1348
+ // bricks
1272
1349
  AssertionComponent,
1273
- PinTargetLookupComponent,
1274
- ], template: "<form [formGroup]=\"form\" (submit)=\"save()\">\n <div>\n <div class=\"form-row\">\n <!-- tag (bound) -->\n @if (idTagEntries()?.length) {\n <mat-form-field class=\"short-text\">\n <mat-label>tag</mat-label>\n <mat-select [formControl]=\"tag\">\n @for (e of idTagEntries(); track e) {\n <mat-option [value]=\"e.id\">{{ e.value }}</mat-option>\n }\n </mat-select>\n </mat-form-field>\n }\n <!-- tag (free) -->\n @else {\n <mat-form-field class=\"short-text\">\n <mat-label>tag</mat-label>\n <input matInput [formControl]=\"tag\" />\n @if ($any(tag.errors)?.maxLength && (tag.dirty || tag.touched)) {\n <mat-error>tag too long</mat-error>\n }\n </mat-form-field>\n }\n\n <!-- scope (bound) -->\n @if (idScopeEntries()?.length) {\n <mat-form-field class=\"short-text\">\n <mat-label>scope</mat-label>\n <mat-select [formControl]=\"scope\">\n @for (e of idScopeEntries(); track e) {\n <mat-option [value]=\"e.id\">{{ e.value }}</mat-option>\n }\n </mat-select>\n </mat-form-field>\n }\n <!-- scope (free) -->\n @else {\n <mat-form-field class=\"short-text\">\n <mat-label>scope</mat-label>\n <input matInput [formControl]=\"scope\" />\n @if ( $any(scope.errors)?.maxLength && (scope.dirty || scope.touched) )\n {\n <mat-error>scope too long</mat-error>\n }\n </mat-form-field>\n }\n\n <!-- label and GID -->\n @if (target.value?.label) {\n <div class=\"info\">\n <span class=\"label\">label</span>{{ target.value?.label }}\n </div>\n } @if (target.value?.gid) {\n <div class=\"info\">\n <span class=\"label\">GID</span>{{ target.value?.gid }}\n </div>\n }\n </div>\n\n <!-- target -->\n <div class=\"boxed\">\n <mat-expansion-panel [(expanded)]=\"targetExpanded\">\n <mat-expansion-panel-header>target</mat-expansion-panel-header>\n <cadmus-pin-target-lookup\n [pinByTypeMode]=\"pinByTypeMode()\"\n [canSwitchMode]=\"canSwitchMode()\"\n [canEditTarget]=\"canEditTarget()\"\n [lookupDefinitions]=\"lookupDefinitions()\"\n [defaultPartTypeKey]=\"defaultPartTypeKey()\"\n [target]=\"target.value || undefined\"\n [internalDefault]=\"internalDefault()\"\n [extLookupConfigs]=\"extLookupConfigs\"\n (targetChange)=\"onTargetChange($event)\"\n (editorClose)=\"onEditorClose()\"\n (extMoreRequest)=\"onExtMoreRequest($event)\"\n (extLookupConfigChange)=\"onExtLookupConfigChange($event)\"\n />\n </mat-expansion-panel>\n </div>\n\n <!-- assertion -->\n <br />\n <div class=\"boxed\">\n <mat-expansion-panel>\n <mat-expansion-panel-header>assertion</mat-expansion-panel-header>\n <cadmus-refs-assertion\n [assTagEntries]=\"assTagEntries()\"\n [refTypeEntries]=\"refTypeEntries()\"\n [refTagEntries]=\"refTagEntries()\"\n [assertion]=\"assertion.value || undefined\"\n (assertionChange)=\"onAssertionChange($event)\"\n >\n </cadmus-refs-assertion>\n </mat-expansion-panel>\n </div>\n </div>\n\n <!-- buttons -->\n @if (hasSubmit()) {\n <div>\n <button\n mat-icon-button\n type=\"button\"\n (click)=\"cancel()\"\n [disabled]=\"!this.target.value?.gid || !this.target.value?.label\"\n >\n <mat-icon class=\"mat-warn\">close</mat-icon>\n </button>\n <button mat-icon-button type=\"submit\" [disabled]=\"form.invalid\">\n <mat-icon class=\"mat-primary\">check_circle</mat-icon>\n </button>\n </div>\n }\n</form>\n", styles: [".form-row{display:flex;gap:8px;align-items:center;flex-wrap:wrap}.form-row *{flex:0 0 auto}.boxed{border:1px solid silver;border-radius:6px;padding:6px}.short-text{width:8em}.pin-info{font-size:90%;color:silver}fieldset{border:1px solid silver;border-radius:6px;padding:6px}.info{border:1px solid silver;border-radius:6px;background-color:silver;color:#fff;padding:4px}.info .label{background-color:#fff;color:silver;margin:0 6px}@media only screen and (max-width: 959px){div#container{grid-template-rows:1fr auto;grid-template-columns:1fr;grid-template-areas:\"editor\" \"lookup\"}}\n"] }]
1350
+ ScopedPinLookupComponent,
1351
+ ], template: "<form [formGroup]=\"form\" (submit)=\"save()\">\r\n <div>\r\n <div class=\"form-row\">\r\n <!-- tag (bound) -->\r\n @if (idTagEntries()?.length) {\r\n <mat-form-field>\r\n <mat-label>tag</mat-label>\r\n <mat-select [formControl]=\"tag\">\r\n @for (e of idTagEntries(); track e) {\r\n <mat-option [value]=\"e.id\">{{ e.value }}</mat-option>\r\n }\r\n </mat-select>\r\n </mat-form-field>\r\n }\r\n <!-- tag (free) -->\r\n @else {\r\n <mat-form-field>\r\n <mat-label>tag</mat-label>\r\n <input matInput [formControl]=\"tag\" />\r\n @if ($any(tag.errors)?.maxLength && (tag.dirty || tag.touched)) {\r\n <mat-error>tag too long</mat-error>\r\n }\r\n </mat-form-field>\r\n }\r\n\r\n <!-- scope (bound) -->\r\n @if (idScopeEntries()?.length) {\r\n <mat-form-field>\r\n <mat-label>scope</mat-label>\r\n <mat-select [formControl]=\"scope\">\r\n @for (e of idScopeEntries(); track e) {\r\n <mat-option [value]=\"e.id\">{{ e.value }}</mat-option>\r\n }\r\n </mat-select>\r\n </mat-form-field>\r\n }\r\n <!-- scope (free) -->\r\n @else {\r\n <mat-form-field>\r\n <mat-label>scope</mat-label>\r\n <input matInput [formControl]=\"scope\" />\r\n @if ($any(scope.errors)?.maxLength && (scope.dirty || scope.touched)) {\r\n <mat-error>scope too long</mat-error>\r\n }\r\n </mat-form-field>\r\n }\r\n\r\n <!-- value -->\r\n <mat-form-field>\r\n <mat-label>value</mat-label>\r\n <input matInput [formControl]=\"value\" />\r\n @if ($any(value.errors)?.required && (value.dirty || value.touched)) {\r\n <mat-error>value required</mat-error>\r\n } @if ($any(value.errors)?.maxLength && (value.dirty || value.touched))\r\n {\r\n <mat-error>value too long</mat-error>\r\n }\r\n </mat-form-field>\r\n\r\n <!-- label -->\r\n <mat-form-field>\r\n <mat-label>label</mat-label>\r\n <input matInput [formControl]=\"label\" />\r\n @if ($any(label.errors)?.maxLength && (label.dirty || label.touched)) {\r\n <mat-error>label too long</mat-error>\r\n }\r\n </mat-form-field>\r\n\r\n <!-- lookup -->\r\n @if (!noEidLookup()) {\r\n <div>\r\n <mat-expansion-panel [(expanded)]=\"lookupExpanded\">\r\n <mat-expansion-panel-header>lookup</mat-expansion-panel-header>\r\n <cadmus-scoped-pin-lookup (idPick)=\"onIdPick($event)\" />\r\n </mat-expansion-panel>\r\n </div>\r\n }\r\n </div>\r\n\r\n <!-- assertion -->\r\n <mat-expansion-panel>\r\n <mat-expansion-panel-header>assertion</mat-expansion-panel-header>\r\n <cadmus-refs-assertion\r\n [assTagEntries]=\"assTagEntries()\"\r\n [refTypeEntries]=\"refTypeEntries()\"\r\n [refTagEntries]=\"refTagEntries()\"\r\n [assertion]=\"assertion.value || undefined\"\r\n (assertionChange)=\"onAssertionChange($event)\"\r\n />\r\n </mat-expansion-panel>\r\n </div>\r\n\r\n <!-- buttons -->\r\n @if (hasSubmit()) {\r\n <div>\r\n <button mat-icon-button type=\"button\" (click)=\"cancel()\">\r\n <mat-icon class=\"mat-warn\">close</mat-icon>\r\n </button>\r\n <button mat-icon-button type=\"submit\" [disabled]=\"form.invalid\">\r\n <mat-icon class=\"mat-primary\">check_circle</mat-icon>\r\n </button>\r\n </div>\r\n }\r\n</form>\r\n", styles: [".form-row{display:flex;gap:8px;align-items:flex-start;flex-wrap:wrap}.form-row *{flex:0 0 auto}.pin-info{font-size:90%;color:silver}fieldset{border:1px solid silver;border-radius:6px;padding:6px}@media only screen and (max-width: 959px){div#container{grid-template-rows:1fr auto;grid-template-columns:1fr;grid-template-areas:\"editor\" \"lookup\"}}\n"] }]
1275
1352
  }], ctorParameters: () => [{ type: i1$1.FormBuilder }, { type: PinRefLookupService }, { type: undefined, decorators: [{
1276
1353
  type: Inject,
1277
1354
  args: ['indexLookupDefinitions']
1278
- }] }, { type: i3$1.RamStorageService }] });
1355
+ }] }] });
1279
1356
 
1280
1357
  /**
1281
- * Asserted composite IDs editor.
1358
+ * Asserted IDs editor.
1282
1359
  */
1283
- class AssertedCompositeIdsComponent {
1360
+ class AssertedIdsComponent {
1284
1361
  _dialogService;
1285
- _ids;
1286
1362
  _editedIndex;
1287
1363
  edited;
1288
1364
  /**
1289
1365
  * The asserted IDs.
1290
1366
  */
1291
- get ids() {
1292
- return this._ids;
1293
- }
1294
- set ids(value) {
1295
- if (this._ids !== value) {
1296
- this._ids = value || [];
1297
- this.updateForm(value);
1298
- }
1299
- }
1367
+ ids = model([]);
1300
1368
  // asserted-id-scopes
1301
1369
  idScopeEntries = input();
1302
1370
  // asserted-id-tags
@@ -1307,53 +1375,20 @@ class AssertedCompositeIdsComponent {
1307
1375
  refTypeEntries = input();
1308
1376
  // doc-reference-tags
1309
1377
  refTagEntries = input();
1310
- /**
1311
- * True when the internal UI preselected mode should be by type rather than
1312
- * by item. User can change mode unless modeSwitching is false.
1313
- */
1314
- pinByTypeMode = input();
1315
- /**
1316
- * True when the user can switch between by-type and by-item mode in
1317
- * the internal UI.
1318
- */
1319
- canSwitchMode = input();
1320
- /**
1321
- * True when the user can edit the target's gid/label for internal targets.
1322
- */
1323
- canEditTarget = input();
1324
- /**
1325
- * The lookup definitions to be used for the by-type lookup in the internal UI.
1326
- * If not specified, the lookup definitions will be got via injection
1327
- * when available; if the injected definitions are empty, the
1328
- * lookup definitions will be built from the model-types thesaurus;
1329
- * if this is not available either, the by-type lookup will be
1330
- * disabled.
1331
- */
1332
- lookupDefinitions = input();
1333
- /**
1334
- * The default part type key.
1335
- */
1336
- defaultPartTypeKey = input();
1337
- /**
1338
- * True if when a new ID is set it should be internal rather than
1339
- * external by default.
1340
- */
1341
- internalDefault = input();
1342
- /**
1343
- * Emitted whenever any ID changes.
1344
- */
1345
- idsChange = output();
1346
1378
  entries;
1347
1379
  form;
1348
1380
  constructor(formBuilder, _dialogService) {
1349
1381
  this._dialogService = _dialogService;
1350
- this._ids = [];
1351
1382
  this._editedIndex = -1;
1352
1383
  this.entries = formBuilder.control([], { nonNullable: true });
1353
1384
  // form
1354
1385
  this.form = formBuilder.group({
1355
1386
  ids: this.entries,
1356
1387
  });
1388
+ // when ids change, update form
1389
+ effect(() => {
1390
+ this.updateForm(this.ids());
1391
+ });
1357
1392
  }
1358
1393
  updateForm(ids) {
1359
1394
  if (!ids?.length) {
@@ -1364,12 +1399,10 @@ class AssertedCompositeIdsComponent {
1364
1399
  this.entries.updateValueAndValidity();
1365
1400
  this.form.markAsPristine();
1366
1401
  }
1367
- emitIdsChange() {
1368
- this.idsChange.emit(this.entries.value);
1369
- }
1370
1402
  addId() {
1371
1403
  this.editId({
1372
- target: { gid: '', label: '' },
1404
+ scope: '',
1405
+ value: '',
1373
1406
  }, -1);
1374
1407
  }
1375
1408
  editId(id, index) {
@@ -1407,7 +1440,7 @@ class AssertedCompositeIdsComponent {
1407
1440
  this.entries.setValue(entries);
1408
1441
  this.entries.markAsDirty();
1409
1442
  this.entries.updateValueAndValidity();
1410
- this.emitIdsChange();
1443
+ this.ids.set(this.entries.value);
1411
1444
  }
1412
1445
  });
1413
1446
  }
@@ -1422,7 +1455,7 @@ class AssertedCompositeIdsComponent {
1422
1455
  this.entries.setValue(entries);
1423
1456
  this.entries.markAsDirty();
1424
1457
  this.entries.updateValueAndValidity();
1425
- this.emitIdsChange();
1458
+ this.ids.set(this.entries.value);
1426
1459
  }
1427
1460
  moveIdDown(index) {
1428
1461
  if (index + 1 >= this.entries.value.length) {
@@ -1435,31 +1468,33 @@ class AssertedCompositeIdsComponent {
1435
1468
  this.entries.setValue(entries);
1436
1469
  this.entries.markAsDirty();
1437
1470
  this.entries.updateValueAndValidity();
1438
- this.emitIdsChange();
1471
+ this.ids.set(this.entries.value);
1439
1472
  }
1440
1473
  onIdChange(id) {
1441
1474
  this.saveId(id);
1442
- this.emitIdsChange();
1475
+ this.ids.set(this.entries.value);
1443
1476
  }
1444
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.5", ngImport: i0, type: AssertedCompositeIdsComponent, deps: [{ token: i1$1.FormBuilder }, { token: i2.DialogService }], target: i0.ɵɵFactoryTarget.Component });
1445
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.0.5", type: AssertedCompositeIdsComponent, isStandalone: true, selector: "cadmus-refs-asserted-composite-ids", inputs: { ids: { classPropertyName: "ids", publicName: "ids", isSignal: false, isRequired: false, transformFunction: null }, idScopeEntries: { classPropertyName: "idScopeEntries", publicName: "idScopeEntries", isSignal: true, isRequired: false, transformFunction: null }, idTagEntries: { classPropertyName: "idTagEntries", publicName: "idTagEntries", isSignal: true, isRequired: false, transformFunction: null }, assTagEntries: { classPropertyName: "assTagEntries", publicName: "assTagEntries", isSignal: true, isRequired: false, transformFunction: null }, refTypeEntries: { classPropertyName: "refTypeEntries", publicName: "refTypeEntries", isSignal: true, isRequired: false, transformFunction: null }, refTagEntries: { classPropertyName: "refTagEntries", publicName: "refTagEntries", isSignal: true, isRequired: false, transformFunction: null }, pinByTypeMode: { classPropertyName: "pinByTypeMode", publicName: "pinByTypeMode", isSignal: true, isRequired: false, transformFunction: null }, canSwitchMode: { classPropertyName: "canSwitchMode", publicName: "canSwitchMode", isSignal: true, isRequired: false, transformFunction: null }, canEditTarget: { classPropertyName: "canEditTarget", publicName: "canEditTarget", isSignal: true, isRequired: false, transformFunction: null }, lookupDefinitions: { classPropertyName: "lookupDefinitions", publicName: "lookupDefinitions", isSignal: true, isRequired: false, transformFunction: null }, defaultPartTypeKey: { classPropertyName: "defaultPartTypeKey", publicName: "defaultPartTypeKey", isSignal: true, isRequired: false, transformFunction: null }, internalDefault: { classPropertyName: "internalDefault", publicName: "internalDefault", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { idsChange: "idsChange" }, ngImport: i0, template: "<form [formGroup]=\"form\">\r\n <!-- buttons -->\r\n <button type=\"button\" class=\"mat-primary\" mat-flat-button (click)=\"addId()\">\r\n <mat-icon>add_circle</mat-icon> ID\r\n </button>\r\n <!-- list -->\r\n @if (entries.value.length) {\r\n <table>\r\n <thead>\r\n <tr>\r\n <th></th>\r\n <th>scope</th>\r\n <th>label</th>\r\n <th>gid</th>\r\n <th>ass.</th>\r\n </tr>\r\n </thead>\r\n <tbody>\r\n @for ( entry of entries.value; track entry; let i = $index; let first =\r\n $first; let last = $last) {\r\n <tr [class.selected]=\"entry === edited\">\r\n <td class=\"fit-width\">\r\n <button\r\n type=\"button\"\r\n mat-icon-button\r\n matTooltip=\"Edit this ID\"\r\n (click)=\"editId(entry, i)\"\r\n >\r\n <mat-icon class=\"mat-primary\">edit</mat-icon>\r\n </button>\r\n <button\r\n type=\"button\"\r\n mat-icon-button\r\n matTooltip=\"Move this ID up\"\r\n [disabled]=\"first\"\r\n (click)=\"moveIdUp(i)\"\r\n >\r\n <mat-icon>arrow_upward</mat-icon>\r\n </button>\r\n <button\r\n type=\"button\"\r\n mat-icon-button\r\n matTooltip=\"Move this ID down\"\r\n [disabled]=\"last\"\r\n (click)=\"moveIdDown(i)\"\r\n >\r\n <mat-icon>arrow_downward</mat-icon>\r\n </button>\r\n <button\r\n type=\"button\"\r\n mat-icon-button\r\n matTooltip=\"Delete this ID\"\r\n (click)=\"deleteId(i)\"\r\n >\r\n <mat-icon class=\"mat-warn\">remove_circle</mat-icon>\r\n </button>\r\n </td>\r\n <td>{{ entry.scope }}</td>\r\n <td>{{ entry?.target?.label }}</td>\r\n <td>{{ entry?.target?.gid }}</td>\r\n <td>{{ entry?.assertion ? \"Y\" : \"N\" }}</td>\r\n </tr>\r\n }\r\n </tbody>\r\n </table>\r\n }\r\n\r\n <!-- editor -->\r\n <mat-expansion-panel [expanded]=\"edited\" [disabled]=\"!edited\">\r\n <mat-expansion-panel-header\r\n >ID {{ edited?.target?.label }}</mat-expansion-panel-header\r\n >\r\n <cadmus-refs-asserted-composite-id\r\n [idScopeEntries]=\"idScopeEntries()\"\r\n [idTagEntries]=\"idTagEntries()\"\r\n [assTagEntries]=\"assTagEntries()\"\r\n [refTypeEntries]=\"refTypeEntries()\"\r\n [refTagEntries]=\"refTagEntries()\"\r\n [hasSubmit]=\"true\"\r\n [pinByTypeMode]=\"pinByTypeMode()\"\r\n [canSwitchMode]=\"canSwitchMode()\"\r\n [canEditTarget]=\"canEditTarget()\"\r\n [lookupDefinitions]=\"lookupDefinitions()\"\r\n [defaultPartTypeKey]=\"defaultPartTypeKey()\"\r\n [internalDefault]=\"internalDefault()\"\r\n [id]=\"edited\"\r\n (idChange)=\"onIdChange($event)\"\r\n (editorClose)=\"closeId()\"\r\n />\r\n </mat-expansion-panel>\r\n</form>\r\n", styles: ["table{width:100%;border-collapse:collapse}tbody tr:nth-child(odd){background-color:#e2e2e2}th{text-align:left;font-weight:400;color:silver}td.fit-width{width:1px;white-space:nowrap}tr.selected{background-color:#d0d0d0!important}fieldset{border:1px solid silver;border-radius:6px;padding:6px}\n"], dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1$1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i3.MatButton, selector: " button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ", exportAs: ["matButton"] }, { kind: "component", type: i3.MatIconButton, selector: "button[mat-icon-button]", exportAs: ["matButton"] }, { kind: "ngmodule", type: MatCheckboxModule }, { kind: "ngmodule", type: MatExpansionModule }, { kind: "component", type: i4.MatExpansionPanel, selector: "mat-expansion-panel", inputs: ["hideToggle", "togglePosition"], outputs: ["afterExpand", "afterCollapse"], exportAs: ["matExpansionPanel"] }, { kind: "component", type: i4.MatExpansionPanelHeader, selector: "mat-expansion-panel-header", inputs: ["expandedHeight", "collapsedHeight", "tabIndex"] }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i7.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatInputModule }, { kind: "component", type: AssertedCompositeIdComponent, selector: "cadmus-refs-asserted-composite-id", inputs: ["idScopeEntries", "idTagEntries", "assTagEntries", "refTypeEntries", "refTagEntries", "id", "internalDefault", "hasSubmit", "pinByTypeMode", "canSwitchMode", "canEditTarget", "lookupDefinitions", "defaultPartTypeKey"], outputs: ["idChange", "editorClose", "extMoreRequest"] }] });
1477
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.0", ngImport: i0, type: AssertedIdsComponent, deps: [{ token: i1$1.FormBuilder }, { token: i2.DialogService }], target: i0.ɵɵFactoryTarget.Component });
1478
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.0.0", type: AssertedIdsComponent, isStandalone: true, selector: "cadmus-refs-asserted-ids", inputs: { ids: { classPropertyName: "ids", publicName: "ids", isSignal: true, isRequired: false, transformFunction: null }, idScopeEntries: { classPropertyName: "idScopeEntries", publicName: "idScopeEntries", isSignal: true, isRequired: false, transformFunction: null }, idTagEntries: { classPropertyName: "idTagEntries", publicName: "idTagEntries", isSignal: true, isRequired: false, transformFunction: null }, assTagEntries: { classPropertyName: "assTagEntries", publicName: "assTagEntries", isSignal: true, isRequired: false, transformFunction: null }, refTypeEntries: { classPropertyName: "refTypeEntries", publicName: "refTypeEntries", isSignal: true, isRequired: false, transformFunction: null }, refTagEntries: { classPropertyName: "refTagEntries", publicName: "refTagEntries", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { ids: "idsChange" }, ngImport: i0, template: "<form [formGroup]=\"form\">\r\n <div>\r\n <button type=\"button\" mat-flat-button class=\"mat-primary\" (click)=\"addId()\">\r\n <mat-icon>add_circle</mat-icon> ID\r\n </button>\r\n </div>\r\n @if (entries.value.length) {\r\n <table>\r\n <thead>\r\n <tr>\r\n <th></th>\r\n <th>scope</th>\r\n <th>value</th>\r\n </tr>\r\n </thead>\r\n <tbody>\r\n @for ( entry of entries.value; track entry; let i = $index; let first =\r\n $first; let last = $last) {\r\n <tr [class.selected]=\"entry === edited\">\r\n <td class=\"fit-width\">\r\n <button\r\n type=\"button\"\r\n mat-icon-button\r\n matTooltip=\"Edit this ID\"\r\n (click)=\"editId(entry, i)\"\r\n >\r\n <mat-icon class=\"mat-primary\">edit</mat-icon>\r\n </button>\r\n <button\r\n type=\"button\"\r\n mat-icon-button\r\n matTooltip=\"Move this ID up\"\r\n [disabled]=\"first\"\r\n (click)=\"moveIdUp(i)\"\r\n >\r\n <mat-icon>arrow_upward</mat-icon>\r\n </button>\r\n <button\r\n type=\"button\"\r\n mat-icon-button\r\n matTooltip=\"Move this ID down\"\r\n [disabled]=\"last\"\r\n (click)=\"moveIdDown(i)\"\r\n >\r\n <mat-icon>arrow_downward</mat-icon>\r\n </button>\r\n <button\r\n type=\"button\"\r\n mat-icon-button\r\n matTooltip=\"Delete this ID\"\r\n (click)=\"deleteId(i)\"\r\n >\r\n <mat-icon class=\"mat-warn\">remove_circle</mat-icon>\r\n </button>\r\n </td>\r\n <td>{{ entry.scope }}</td>\r\n <td>{{ entry.value }}</td>\r\n </tr>\r\n }\r\n </tbody>\r\n </table>\r\n }\r\n\r\n <mat-expansion-panel [expanded]=\"edited\" [disabled]=\"!edited\">\r\n <mat-expansion-panel-header\r\n >ID {{ edited?.value }}</mat-expansion-panel-header\r\n >\r\n <cadmus-refs-asserted-id\r\n [idScopeEntries]=\"idScopeEntries()\"\r\n [idTagEntries]=\"idTagEntries()\"\r\n [assTagEntries]=\"assTagEntries()\"\r\n [refTypeEntries]=\"refTypeEntries()\"\r\n [refTagEntries]=\"refTagEntries()\"\r\n [hasSubmit]=\"true\"\r\n [id]=\"edited\"\r\n (idChange)=\"onIdChange($event)\"\r\n (editorClose)=\"closeId()\"\r\n />\r\n </mat-expansion-panel>\r\n</form>\r\n", styles: ["table{width:100%;border-collapse:collapse}tbody tr:nth-child(odd){background-color:#e2e2e2}th{text-align:left;font-weight:400;color:silver}td.fit-width{width:1px;white-space:nowrap}tr.selected{background-color:#d0d0d0!important}fieldset{border:1px solid silver;border-radius:6px;padding:6px}\n"], dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1$1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "ngmodule", type:
1479
+ // material
1480
+ MatButtonModule }, { kind: "component", type: i3.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: i3.MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "ngmodule", type: MatExpansionModule }, { kind: "component", type: i4$1.MatExpansionPanel, selector: "mat-expansion-panel", inputs: ["hideToggle", "togglePosition"], outputs: ["afterExpand", "afterCollapse"], exportAs: ["matExpansionPanel"] }, { kind: "component", type: i4$1.MatExpansionPanelHeader, selector: "mat-expansion-panel-header", inputs: ["expandedHeight", "collapsedHeight", "tabIndex"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i7.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i14.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "component", type:
1481
+ // bricks
1482
+ AssertedIdComponent, selector: "cadmus-refs-asserted-id", inputs: ["idScopeEntries", "idTagEntries", "assTagEntries", "refTypeEntries", "refTagEntries", "id", "noEidLookup", "hasSubmit"], outputs: ["idChange", "editorClose"] }] });
1446
1483
  }
1447
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.5", ngImport: i0, type: AssertedCompositeIdsComponent, decorators: [{
1484
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.0", ngImport: i0, type: AssertedIdsComponent, decorators: [{
1448
1485
  type: Component,
1449
- args: [{ selector: 'cadmus-refs-asserted-composite-ids', imports: [
1486
+ args: [{ selector: 'cadmus-refs-asserted-ids', imports: [
1450
1487
  FormsModule,
1451
1488
  ReactiveFormsModule,
1489
+ // material
1452
1490
  MatButtonModule,
1453
- MatCheckboxModule,
1454
1491
  MatExpansionModule,
1455
- MatFormFieldModule,
1456
1492
  MatIconModule,
1457
- MatInputModule,
1458
- AssertedCompositeIdComponent,
1459
- ], template: "<form [formGroup]=\"form\">\r\n <!-- buttons -->\r\n <button type=\"button\" class=\"mat-primary\" mat-flat-button (click)=\"addId()\">\r\n <mat-icon>add_circle</mat-icon> ID\r\n </button>\r\n <!-- list -->\r\n @if (entries.value.length) {\r\n <table>\r\n <thead>\r\n <tr>\r\n <th></th>\r\n <th>scope</th>\r\n <th>label</th>\r\n <th>gid</th>\r\n <th>ass.</th>\r\n </tr>\r\n </thead>\r\n <tbody>\r\n @for ( entry of entries.value; track entry; let i = $index; let first =\r\n $first; let last = $last) {\r\n <tr [class.selected]=\"entry === edited\">\r\n <td class=\"fit-width\">\r\n <button\r\n type=\"button\"\r\n mat-icon-button\r\n matTooltip=\"Edit this ID\"\r\n (click)=\"editId(entry, i)\"\r\n >\r\n <mat-icon class=\"mat-primary\">edit</mat-icon>\r\n </button>\r\n <button\r\n type=\"button\"\r\n mat-icon-button\r\n matTooltip=\"Move this ID up\"\r\n [disabled]=\"first\"\r\n (click)=\"moveIdUp(i)\"\r\n >\r\n <mat-icon>arrow_upward</mat-icon>\r\n </button>\r\n <button\r\n type=\"button\"\r\n mat-icon-button\r\n matTooltip=\"Move this ID down\"\r\n [disabled]=\"last\"\r\n (click)=\"moveIdDown(i)\"\r\n >\r\n <mat-icon>arrow_downward</mat-icon>\r\n </button>\r\n <button\r\n type=\"button\"\r\n mat-icon-button\r\n matTooltip=\"Delete this ID\"\r\n (click)=\"deleteId(i)\"\r\n >\r\n <mat-icon class=\"mat-warn\">remove_circle</mat-icon>\r\n </button>\r\n </td>\r\n <td>{{ entry.scope }}</td>\r\n <td>{{ entry?.target?.label }}</td>\r\n <td>{{ entry?.target?.gid }}</td>\r\n <td>{{ entry?.assertion ? \"Y\" : \"N\" }}</td>\r\n </tr>\r\n }\r\n </tbody>\r\n </table>\r\n }\r\n\r\n <!-- editor -->\r\n <mat-expansion-panel [expanded]=\"edited\" [disabled]=\"!edited\">\r\n <mat-expansion-panel-header\r\n >ID {{ edited?.target?.label }}</mat-expansion-panel-header\r\n >\r\n <cadmus-refs-asserted-composite-id\r\n [idScopeEntries]=\"idScopeEntries()\"\r\n [idTagEntries]=\"idTagEntries()\"\r\n [assTagEntries]=\"assTagEntries()\"\r\n [refTypeEntries]=\"refTypeEntries()\"\r\n [refTagEntries]=\"refTagEntries()\"\r\n [hasSubmit]=\"true\"\r\n [pinByTypeMode]=\"pinByTypeMode()\"\r\n [canSwitchMode]=\"canSwitchMode()\"\r\n [canEditTarget]=\"canEditTarget()\"\r\n [lookupDefinitions]=\"lookupDefinitions()\"\r\n [defaultPartTypeKey]=\"defaultPartTypeKey()\"\r\n [internalDefault]=\"internalDefault()\"\r\n [id]=\"edited\"\r\n (idChange)=\"onIdChange($event)\"\r\n (editorClose)=\"closeId()\"\r\n />\r\n </mat-expansion-panel>\r\n</form>\r\n", styles: ["table{width:100%;border-collapse:collapse}tbody tr:nth-child(odd){background-color:#e2e2e2}th{text-align:left;font-weight:400;color:silver}td.fit-width{width:1px;white-space:nowrap}tr.selected{background-color:#d0d0d0!important}fieldset{border:1px solid silver;border-radius:6px;padding:6px}\n"] }]
1460
- }], ctorParameters: () => [{ type: i1$1.FormBuilder }, { type: i2.DialogService }], propDecorators: { ids: [{
1461
- type: Input
1462
- }] } });
1493
+ MatTooltipModule,
1494
+ // bricks
1495
+ AssertedIdComponent
1496
+ ], template: "<form [formGroup]=\"form\">\r\n <div>\r\n <button type=\"button\" mat-flat-button class=\"mat-primary\" (click)=\"addId()\">\r\n <mat-icon>add_circle</mat-icon> ID\r\n </button>\r\n </div>\r\n @if (entries.value.length) {\r\n <table>\r\n <thead>\r\n <tr>\r\n <th></th>\r\n <th>scope</th>\r\n <th>value</th>\r\n </tr>\r\n </thead>\r\n <tbody>\r\n @for ( entry of entries.value; track entry; let i = $index; let first =\r\n $first; let last = $last) {\r\n <tr [class.selected]=\"entry === edited\">\r\n <td class=\"fit-width\">\r\n <button\r\n type=\"button\"\r\n mat-icon-button\r\n matTooltip=\"Edit this ID\"\r\n (click)=\"editId(entry, i)\"\r\n >\r\n <mat-icon class=\"mat-primary\">edit</mat-icon>\r\n </button>\r\n <button\r\n type=\"button\"\r\n mat-icon-button\r\n matTooltip=\"Move this ID up\"\r\n [disabled]=\"first\"\r\n (click)=\"moveIdUp(i)\"\r\n >\r\n <mat-icon>arrow_upward</mat-icon>\r\n </button>\r\n <button\r\n type=\"button\"\r\n mat-icon-button\r\n matTooltip=\"Move this ID down\"\r\n [disabled]=\"last\"\r\n (click)=\"moveIdDown(i)\"\r\n >\r\n <mat-icon>arrow_downward</mat-icon>\r\n </button>\r\n <button\r\n type=\"button\"\r\n mat-icon-button\r\n matTooltip=\"Delete this ID\"\r\n (click)=\"deleteId(i)\"\r\n >\r\n <mat-icon class=\"mat-warn\">remove_circle</mat-icon>\r\n </button>\r\n </td>\r\n <td>{{ entry.scope }}</td>\r\n <td>{{ entry.value }}</td>\r\n </tr>\r\n }\r\n </tbody>\r\n </table>\r\n }\r\n\r\n <mat-expansion-panel [expanded]=\"edited\" [disabled]=\"!edited\">\r\n <mat-expansion-panel-header\r\n >ID {{ edited?.value }}</mat-expansion-panel-header\r\n >\r\n <cadmus-refs-asserted-id\r\n [idScopeEntries]=\"idScopeEntries()\"\r\n [idTagEntries]=\"idTagEntries()\"\r\n [assTagEntries]=\"assTagEntries()\"\r\n [refTypeEntries]=\"refTypeEntries()\"\r\n [refTagEntries]=\"refTagEntries()\"\r\n [hasSubmit]=\"true\"\r\n [id]=\"edited\"\r\n (idChange)=\"onIdChange($event)\"\r\n (editorClose)=\"closeId()\"\r\n />\r\n </mat-expansion-panel>\r\n</form>\r\n", styles: ["table{width:100%;border-collapse:collapse}tbody tr:nth-child(odd){background-color:#e2e2e2}th{text-align:left;font-weight:400;color:silver}td.fit-width{width:1px;white-space:nowrap}tr.selected{background-color:#d0d0d0!important}fieldset{border:1px solid silver;border-radius:6px;padding:6px}\n"] }]
1497
+ }], ctorParameters: () => [{ type: i1$1.FormBuilder }, { type: i2.DialogService }] });
1463
1498
 
1464
1499
  /*
1465
1500
  * Public API Surface of cadmus-refs-asserted-ids