@yuuvis/client-framework 2.4.0 → 2.4.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/fesm2022/yuuvis-client-framework-forms.mjs +124 -109
- package/fesm2022/yuuvis-client-framework-forms.mjs.map +1 -1
- package/fesm2022/yuuvis-client-framework-list.mjs +38 -6
- package/fesm2022/yuuvis-client-framework-list.mjs.map +1 -1
- package/fesm2022/yuuvis-client-framework-metadata-form-defaults.mjs +1 -1
- package/fesm2022/yuuvis-client-framework-metadata-form-defaults.mjs.map +1 -1
- package/fesm2022/yuuvis-client-framework-object-relationship.mjs +72 -50
- package/fesm2022/yuuvis-client-framework-object-relationship.mjs.map +1 -1
- package/fesm2022/yuuvis-client-framework-renderer.mjs +81 -6
- package/fesm2022/yuuvis-client-framework-renderer.mjs.map +1 -1
- package/fesm2022/yuuvis-client-framework-tile-list.mjs +137 -177
- package/fesm2022/yuuvis-client-framework-tile-list.mjs.map +1 -1
- package/forms/lib/elements/data-grid/data-grid/data-grid.component.d.ts +2 -2
- package/forms/lib/elements/organization/organization.component.d.ts +6 -11
- package/forms/lib/elements/organization-set/organization-set.component.d.ts +3 -5
- package/lib/assets/i18n/de.json +2 -0
- package/lib/assets/i18n/en.json +2 -0
- package/list/index.d.ts +1 -0
- package/list/lib/list-tile/list-tile.component.d.ts +14 -0
- package/list/lib/list.component.d.ts +1 -0
- package/list/lib/list.module.d.ts +2 -1
- package/object-relationship/lib/actions/add-relationship/add-relationship.component.d.ts +3 -1
- package/object-relationship/lib/object-relationship.component.d.ts +2 -0
- package/object-relationship/lib/object-relationship.const.d.ts +4 -0
- package/package.json +12 -12
- package/renderer/lib/property-renderer/organization.renderer.d.ts +4 -1
- package/tile-list/index.d.ts +1 -1
- package/tile-list/lib/tile-actions-menu/tile-actions-menu.component.d.ts +11 -0
- package/tile-list/lib/tile-list/tile-list.component.d.ts +18 -24
- package/tile-list/lib/tile/tile.component.d.ts +0 -22
|
@@ -32,20 +32,25 @@ import { SnackBarService } from '@yuuvis/client-framework';
|
|
|
32
32
|
const ROOT_NODE_SETTINGS = {
|
|
33
33
|
size: 30,
|
|
34
34
|
borderWidth: 4,
|
|
35
|
-
borderWidthSelected: 6
|
|
35
|
+
borderWidthSelected: 6
|
|
36
36
|
};
|
|
37
37
|
const ROOT_NODE_FONT_SETTINGS = {
|
|
38
|
-
size: 14
|
|
38
|
+
size: 14
|
|
39
39
|
};
|
|
40
40
|
const NODE_SETTINGS = {
|
|
41
|
-
borderWidthSelected: 2
|
|
41
|
+
borderWidthSelected: 2
|
|
42
42
|
};
|
|
43
43
|
const NODE_FONT_SETTINGS = {
|
|
44
|
-
size: 12
|
|
44
|
+
size: 12
|
|
45
45
|
};
|
|
46
46
|
const EDGE_SETTINGS = {};
|
|
47
47
|
const EDGE_FONT_SETTINGS = {
|
|
48
|
-
size: 10
|
|
48
|
+
size: 10
|
|
49
|
+
};
|
|
50
|
+
// add relationship dialog settings
|
|
51
|
+
const ADD_RELATIONSHIP_DIALOG_OPTIONS = {
|
|
52
|
+
width: '500px',
|
|
53
|
+
maxWidth: '90vw'
|
|
49
54
|
};
|
|
50
55
|
|
|
51
56
|
class ObjectRelationshipService {
|
|
@@ -86,6 +91,7 @@ class ObjectRelationshipService {
|
|
|
86
91
|
this.busy.set(true);
|
|
87
92
|
// search for relations that have this object as source or target
|
|
88
93
|
const query = `SELECT * FROM ${SystemType.RELATIONSHIP} WHERE ${RelationshipTypeField.SOURCE_ID} = '${originId}' OR ${RelationshipTypeField.TARGET_ID} = '${originId}'`;
|
|
94
|
+
// TODO: What about multi-page results?
|
|
89
95
|
return this.#search
|
|
90
96
|
.searchCmis(query)
|
|
91
97
|
.pipe(switchMap((resRelations) => {
|
|
@@ -100,7 +106,9 @@ class ObjectRelationshipService {
|
|
|
100
106
|
const ids = Object.keys(o)
|
|
101
107
|
.map((id) => `'${id}'`)
|
|
102
108
|
.join(',');
|
|
103
|
-
|
|
109
|
+
// having no relations would end up in an empty IN () statement which is invalid
|
|
110
|
+
// but as we need to fetch the origin objects anyway we can add it manually
|
|
111
|
+
const q = `SELECT * FROM system:object WHERE ${BaseObjectTypeField.OBJECT_ID} IN (${ids.length > 0 ? ids : `'${originId}'`})`;
|
|
104
112
|
return this.#search.searchCmis(q).pipe(map((resObjects) => ({
|
|
105
113
|
relations: resRelations,
|
|
106
114
|
objects: resObjects
|
|
@@ -131,6 +139,7 @@ class ObjectRelationshipService {
|
|
|
131
139
|
this.busy.set(false);
|
|
132
140
|
if (success) {
|
|
133
141
|
this.#eventService.trigger(YuvEventType.RELATIONSHIP_DELETED, { relationId });
|
|
142
|
+
// TODO: trigger the event will reload the resource anyway (see constructor)
|
|
134
143
|
if (reloadResource) {
|
|
135
144
|
this.#relationsResource.reload();
|
|
136
145
|
}
|
|
@@ -170,7 +179,6 @@ class NodeSummaryComponent {
|
|
|
170
179
|
#system;
|
|
171
180
|
#router;
|
|
172
181
|
openObject(link) {
|
|
173
|
-
console.log('Navigating to link:', link);
|
|
174
182
|
this.#router.navigateByUrl(link);
|
|
175
183
|
}
|
|
176
184
|
#propertyToRendererInput(propertyName, object) {
|
|
@@ -300,7 +308,7 @@ class RelationshipTargetSearchComponent {
|
|
|
300
308
|
useExisting: forwardRef(() => RelationshipTargetSearchComponent),
|
|
301
309
|
multi: true
|
|
302
310
|
}
|
|
303
|
-
], ngImport: i0, template: "<mat-form-field>\n <mat-label>{{ 'yuv.object-relationship.add-relationship.target-search.label' | translate }}</mat-label>\n\n <yuv-autocomplete\n [required]=\"true\"\n [busy]=\"busy()\"\n [formControl]=\"acFormControl\"\n [autocompleteValues]=\"autocompleteRes\"\n [forceSelection]=\"true\"\n (autocompleteFnc)=\"autocompleteFn($event)\"\n [multiple]=\"true\"\n [maxItems]=\"1\"\n >\n <!-- template for chip -->\n <ng-template #chipTemplate let-item>\n <div class=\"label\">{{ item.label }}</div>\n <!-- <div class=\"meta\">{{ item.value[metaFieldProperty] }}</div> -->\n </ng-template>\n </yuv-autocomplete>\n</mat-form-field>\n", styles: [""], dependencies: [{ kind: "ngmodule", type: YuvAutocompleteModule }, { kind: "component", type: i1$1.AutocompleteComponent, selector: "yuv-autocomplete", inputs: ["ariaLabel", "busy", "multiple", "distinctValues", "addOnBlur", "minLength", "maxItems", "forceSelection", "autocompleteValues"], outputs: ["autocompleteFnc", "acBlur"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$2.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i1$2.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "ngmodule", type: TranslateModule }, { kind: "pipe", type: i3.TranslatePipe, name: "translate" }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "component", type: i3$1.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i3$1.MatLabel, selector: "mat-label" }] }); }
|
|
311
|
+
], ngImport: i0, template: "<mat-form-field>\n <mat-label>{{ 'yuv.object-relationship.add-relationship.target-search.label' | translate }}</mat-label>\n\n <yuv-autocomplete\n [required]=\"true\"\n [busy]=\"busy()\"\n [formControl]=\"acFormControl\"\n [autocompleteValues]=\"autocompleteRes\"\n [forceSelection]=\"true\"\n (autocompleteFnc)=\"autocompleteFn($event)\"\n [multiple]=\"true\"\n [maxItems]=\"1\"\n >\n <!-- template for chip -->\n <ng-template #chipTemplate let-item>\n <div class=\"label\">{{ item.label }}</div>\n <!-- <div class=\"meta\">{{ item.value[metaFieldProperty] }}</div> -->\n </ng-template>\n </yuv-autocomplete>\n</mat-form-field>\n", styles: [":host mat-form-field{width:100%}\n"], dependencies: [{ kind: "ngmodule", type: YuvAutocompleteModule }, { kind: "component", type: i1$1.AutocompleteComponent, selector: "yuv-autocomplete", inputs: ["ariaLabel", "busy", "multiple", "distinctValues", "addOnBlur", "minLength", "maxItems", "forceSelection", "autocompleteValues"], outputs: ["autocompleteFnc", "acBlur"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$2.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i1$2.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "ngmodule", type: TranslateModule }, { kind: "pipe", type: i3.TranslatePipe, name: "translate" }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "component", type: i3$1.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i3$1.MatLabel, selector: "mat-label" }] }); }
|
|
304
312
|
}
|
|
305
313
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.15", ngImport: i0, type: RelationshipTargetSearchComponent, decorators: [{
|
|
306
314
|
type: Component,
|
|
@@ -310,7 +318,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.15", ngImpo
|
|
|
310
318
|
useExisting: forwardRef(() => RelationshipTargetSearchComponent),
|
|
311
319
|
multi: true
|
|
312
320
|
}
|
|
313
|
-
], template: "<mat-form-field>\n <mat-label>{{ 'yuv.object-relationship.add-relationship.target-search.label' | translate }}</mat-label>\n\n <yuv-autocomplete\n [required]=\"true\"\n [busy]=\"busy()\"\n [formControl]=\"acFormControl\"\n [autocompleteValues]=\"autocompleteRes\"\n [forceSelection]=\"true\"\n (autocompleteFnc)=\"autocompleteFn($event)\"\n [multiple]=\"true\"\n [maxItems]=\"1\"\n >\n <!-- template for chip -->\n <ng-template #chipTemplate let-item>\n <div class=\"label\">{{ item.label }}</div>\n <!-- <div class=\"meta\">{{ item.value[metaFieldProperty] }}</div> -->\n </ng-template>\n </yuv-autocomplete>\n</mat-form-field>\n" }]
|
|
321
|
+
], template: "<mat-form-field>\n <mat-label>{{ 'yuv.object-relationship.add-relationship.target-search.label' | translate }}</mat-label>\n\n <yuv-autocomplete\n [required]=\"true\"\n [busy]=\"busy()\"\n [formControl]=\"acFormControl\"\n [autocompleteValues]=\"autocompleteRes\"\n [forceSelection]=\"true\"\n (autocompleteFnc)=\"autocompleteFn($event)\"\n [multiple]=\"true\"\n [maxItems]=\"1\"\n >\n <!-- template for chip -->\n <ng-template #chipTemplate let-item>\n <div class=\"label\">{{ item.label }}</div>\n <!-- <div class=\"meta\">{{ item.value[metaFieldProperty] }}</div> -->\n </ng-template>\n </yuv-autocomplete>\n</mat-form-field>\n", styles: [":host mat-form-field{width:100%}\n"] }]
|
|
314
322
|
}], ctorParameters: () => [] });
|
|
315
323
|
|
|
316
324
|
class AddRelationshipComponent {
|
|
@@ -320,6 +328,7 @@ class AddRelationshipComponent {
|
|
|
320
328
|
this.#dialogRef = inject((MatDialogRef));
|
|
321
329
|
this.#dmsService = inject(DmsService);
|
|
322
330
|
this.#eventService = inject(EventService);
|
|
331
|
+
this.translate = inject(TranslateService);
|
|
323
332
|
this.object = input(this.#dialogData.object);
|
|
324
333
|
this.config = input(this.#dialogData.config);
|
|
325
334
|
this.supportedRelationships = computed(() => {
|
|
@@ -358,6 +367,7 @@ class AddRelationshipComponent {
|
|
|
358
367
|
targetObject: new FormControl(null, { nonNullable: true, validators: [Validators.required] })
|
|
359
368
|
}, { validators: this.#relationMatchesTargetObjectValidator });
|
|
360
369
|
this.busy = signal(false);
|
|
370
|
+
this.error = signal(null);
|
|
361
371
|
}
|
|
362
372
|
#system;
|
|
363
373
|
#dialogData;
|
|
@@ -369,10 +379,16 @@ class AddRelationshipComponent {
|
|
|
369
379
|
return o1?.id === o2?.id;
|
|
370
380
|
}
|
|
371
381
|
submit() {
|
|
382
|
+
this.error.set(null);
|
|
383
|
+
this.busy.set(true);
|
|
372
384
|
this.#addRelationship(this.form.value.relation.id, this.form.value.targetObject).subscribe({
|
|
373
|
-
next: () =>
|
|
385
|
+
next: () => {
|
|
386
|
+
this.busy.set(false);
|
|
387
|
+
this.close();
|
|
388
|
+
},
|
|
374
389
|
error: () => {
|
|
375
|
-
|
|
390
|
+
this.error.set(this.translate.instant('yuv.object-relationship.add-relation.error-message'));
|
|
391
|
+
this.busy.set(false);
|
|
376
392
|
}
|
|
377
393
|
});
|
|
378
394
|
}
|
|
@@ -389,7 +405,7 @@ class AddRelationshipComponent {
|
|
|
389
405
|
this.#dialogRef.close();
|
|
390
406
|
}
|
|
391
407
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.15", ngImport: i0, type: AddRelationshipComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
392
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.15", type: AddRelationshipComponent, isStandalone: true, selector: "yuv-add-relationship", inputs: { object: { classPropertyName: "object", publicName: "object", isSignal: true, isRequired: false, transformFunction: null }, config: { classPropertyName: "config", publicName: "config", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "<yuv-dialog class=\"not-separated\" [headertitel]=\"'yuv.object-relationship.add-relationship.headline' | translate\">\n <main [yuvBusyOverlay]=\"busy()\">\n <form [formGroup]=\"form\" (ngSubmit)=\"submit()\">\n @let sn = sourceNode();\n @if (sn) {\n <div class=\"source\">\n {{ sn.title }}\n @if (sn.description) {\n <em>{{ sn.description }}</em>\n }\n </div>\n <div class=\"line\"></div>\n }\n <mat-form-field>\n <mat-label>{{ 'cm.app.cases.action.add-link.search.relation.label' | translate }}</mat-label>\n <mat-select formControlName=\"relation\" [compareWith]=\"optionCompareWith\">\n @for (r of supportedRelationships(); track r.id) {\n <mat-option [value]=\"r\">{{ r.label }}</mat-option>\n }\n </mat-select>\n </mat-form-field>\n\n <div class=\"line\"></div>\n\n <yuv-relationship-target-search formControlName=\"targetObject\"\n [config]=\"config()\"\n [availableTargetTypes]=\"availableTargetTypes()\"\n [supportedRelationships]=\"supportedRelationships()\"\n ></yuv-relationship-target-search>\n\n @if (form.hasError('invalidRelationTargetCombination') && (form.touched || form.dirty)) {\n <mat-error class=\"error\">{{ 'yuv.object-relationship.add-relationship.error.invalidRelationTargetCombination' | translate }}</mat-error>\n }\n </form>\n </main>\n\n <footer>\n <button ymtButton=\"secondary\" type=\"button\" (click)=\"close()\" [disabled]=\"busy()\">\n {{ 'yuv.object-relationship.add-relationship.action.cancel' | translate }}\n </button>\n <button ymtButton=\"primary\" type=\"button\" (click)=\"submit()\" [disabled]=\"form.invalid || busy()\">\n {{ 'yuv.object-relationship.add-relationship.action.submit' | translate }}\n </button>\n </footer>\n</yuv-dialog>\n", styles: [":host main form{padding:var(--ymt-spacing-m);display:flex;flex-direction:column;gap:var(--ymt-spacing-xs);align-items:center}:host main form .source{border:2px solid var(--ymt-outline);border-radius:var(--ymt-corner-s);padding:var(--ymt-spacing-xs);display:flex;flex-direction:column}:host main form .source em{font-style:normal;font:var(--ymt-font-body-subtle);color:var(--ymt-text-color-subtle)}:host main form .line{width:2px;background-color:var(--ymt-outline);min-height:2em;position:relative}:host main form .line:before{content:\"\";position:absolute;transform:rotate(135deg);width:8px;inset-block-end:0;translate:-3px 2px;height:8px;border:4px solid transparent;border-block-start-color:var(--ymt-outline);border-inline-end-color:var(--ymt-outline)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$2.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1$2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$2.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$2.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$2.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "ngmodule", type: TranslateModule }, { kind: "pipe", type: i3.TranslatePipe, name: "translate" }, { kind: "component", type: DialogComponent, selector: "yuv-dialog", inputs: ["headertitel"] }, { kind: "ngmodule", type: MatSelectModule }, { kind: "component", type: i3$1.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i3$1.MatLabel, selector: "mat-label" }, { kind: "directive", type: i3$1.MatError, selector: "mat-error, [matError]", inputs: ["id"] }, { kind: "component", type: i4.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: i4.MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "directive", type: YmtButtonDirective, selector: "button[ymtButton], a[ymtButton]", inputs: ["ymtButton", "disabled", "aria-disabled", "disableRipple", "disabledInteractive", "button-size"] }, { kind: "component", type: RelationshipTargetSearchComponent, selector: "yuv-relationship-target-search", inputs: ["supportedRelationships", "availableTargetTypes", "config"] }, { kind: "directive", type: BusyOverlayDirective, selector: "[yuvBusyOverlay]", inputs: ["yuvBusyOverlay", "yuvBusyOverlayConfig"] }] }); }
|
|
408
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.15", type: AddRelationshipComponent, isStandalone: true, selector: "yuv-add-relationship", inputs: { object: { classPropertyName: "object", publicName: "object", isSignal: true, isRequired: false, transformFunction: null }, config: { classPropertyName: "config", publicName: "config", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "<yuv-dialog class=\"not-separated\" [headertitel]=\"'yuv.object-relationship.add-relationship.headline' | translate\">\n <main [yuvBusyOverlay]=\"busy()\">\n <form [formGroup]=\"form\" (ngSubmit)=\"submit()\">\n @let sn = sourceNode();\n @if (sn) {\n <div class=\"source\">\n {{ sn.title }}\n @if (sn.description) {\n <em>{{ sn.description }}</em>\n }\n </div>\n <div class=\"line\"></div>\n }\n <mat-form-field>\n <mat-label>{{ 'cm.app.cases.action.add-link.search.relation.label' | translate }}</mat-label>\n <mat-select formControlName=\"relation\" [compareWith]=\"optionCompareWith\">\n @for (r of supportedRelationships(); track r.id) {\n <mat-option [value]=\"r\">{{ r.label }}</mat-option>\n }\n </mat-select>\n </mat-form-field>\n\n <div class=\"line\"></div>\n\n <yuv-relationship-target-search formControlName=\"targetObject\"\n [config]=\"config()\"\n [availableTargetTypes]=\"availableTargetTypes()\"\n [supportedRelationships]=\"supportedRelationships()\"\n ></yuv-relationship-target-search>\n\n @if (form.hasError('invalidRelationTargetCombination') && (form.touched || form.dirty)) {\n <mat-error class=\"error\">{{ 'yuv.object-relationship.add-relationship.error.invalidRelationTargetCombination' | translate }}</mat-error>\n }\n \n @if (error()) {\n <div class=\"error\">{{ error() }}</div>\n }\n </form>\n </main>\n\n <footer>\n <button ymtButton=\"secondary\" type=\"button\" (click)=\"close()\" [disabled]=\"busy()\">\n {{ 'yuv.object-relationship.add-relationship.action.cancel' | translate }}\n </button>\n <button ymtButton=\"primary\" type=\"button\" (click)=\"submit()\" [disabled]=\"form.invalid || busy()\">\n {{ 'yuv.object-relationship.add-relationship.action.submit' | translate }}\n </button>\n </footer>\n</yuv-dialog>\n", styles: [":host .error{background-color:var(--ymt-danger-container);color:var(--ymt-on-danger-container);width:100%;padding:var(--ymt-spacing-m);border-radius:var(--ymt-spacing-xs)}:host main form{padding:var(--ymt-spacing-m);display:flex;flex-direction:column;gap:var(--ymt-spacing-xs);align-items:center}:host main form .source{border:2px solid var(--ymt-outline);border-radius:var(--ymt-corner-s);padding:var(--ymt-spacing-xs);display:flex;flex-direction:column}:host main form .source em{font-style:normal;font:var(--ymt-font-body-subtle);color:var(--ymt-text-color-subtle)}:host main form yuv-relationship-target-search,:host main form mat-form-field{width:100%}:host main form .line{width:2px;background-color:var(--ymt-outline);min-height:2em;position:relative}:host main form .line:before{content:\"\";position:absolute;transform:rotate(135deg);width:8px;inset-block-end:0;translate:-3px 2px;height:8px;border:4px solid transparent;border-block-start-color:var(--ymt-outline);border-inline-end-color:var(--ymt-outline)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$2.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1$2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$2.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$2.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$2.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "ngmodule", type: TranslateModule }, { kind: "pipe", type: i3.TranslatePipe, name: "translate" }, { kind: "component", type: DialogComponent, selector: "yuv-dialog", inputs: ["headertitel"] }, { kind: "ngmodule", type: MatSelectModule }, { kind: "component", type: i3$1.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i3$1.MatLabel, selector: "mat-label" }, { kind: "directive", type: i3$1.MatError, selector: "mat-error, [matError]", inputs: ["id"] }, { kind: "component", type: i4.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: i4.MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "directive", type: YmtButtonDirective, selector: "button[ymtButton], a[ymtButton]", inputs: ["ymtButton", "disabled", "aria-disabled", "disableRipple", "disabledInteractive", "button-size"] }, { kind: "component", type: RelationshipTargetSearchComponent, selector: "yuv-relationship-target-search", inputs: ["supportedRelationships", "availableTargetTypes", "config"] }, { kind: "directive", type: BusyOverlayDirective, selector: "[yuvBusyOverlay]", inputs: ["yuvBusyOverlay", "yuvBusyOverlayConfig"] }] }); }
|
|
393
409
|
}
|
|
394
410
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.15", ngImport: i0, type: AddRelationshipComponent, decorators: [{
|
|
395
411
|
type: Component,
|
|
@@ -404,7 +420,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.15", ngImpo
|
|
|
404
420
|
YmtButtonDirective,
|
|
405
421
|
RelationshipTargetSearchComponent,
|
|
406
422
|
BusyOverlayDirective
|
|
407
|
-
], template: "<yuv-dialog class=\"not-separated\" [headertitel]=\"'yuv.object-relationship.add-relationship.headline' | translate\">\n <main [yuvBusyOverlay]=\"busy()\">\n <form [formGroup]=\"form\" (ngSubmit)=\"submit()\">\n @let sn = sourceNode();\n @if (sn) {\n <div class=\"source\">\n {{ sn.title }}\n @if (sn.description) {\n <em>{{ sn.description }}</em>\n }\n </div>\n <div class=\"line\"></div>\n }\n <mat-form-field>\n <mat-label>{{ 'cm.app.cases.action.add-link.search.relation.label' | translate }}</mat-label>\n <mat-select formControlName=\"relation\" [compareWith]=\"optionCompareWith\">\n @for (r of supportedRelationships(); track r.id) {\n <mat-option [value]=\"r\">{{ r.label }}</mat-option>\n }\n </mat-select>\n </mat-form-field>\n\n <div class=\"line\"></div>\n\n <yuv-relationship-target-search formControlName=\"targetObject\"\n [config]=\"config()\"\n [availableTargetTypes]=\"availableTargetTypes()\"\n [supportedRelationships]=\"supportedRelationships()\"\n ></yuv-relationship-target-search>\n\n @if (form.hasError('invalidRelationTargetCombination') && (form.touched || form.dirty)) {\n <mat-error class=\"error\">{{ 'yuv.object-relationship.add-relationship.error.invalidRelationTargetCombination' | translate }}</mat-error>\n }\n </form>\n </main>\n\n <footer>\n <button ymtButton=\"secondary\" type=\"button\" (click)=\"close()\" [disabled]=\"busy()\">\n {{ 'yuv.object-relationship.add-relationship.action.cancel' | translate }}\n </button>\n <button ymtButton=\"primary\" type=\"button\" (click)=\"submit()\" [disabled]=\"form.invalid || busy()\">\n {{ 'yuv.object-relationship.add-relationship.action.submit' | translate }}\n </button>\n </footer>\n</yuv-dialog>\n", styles: [":host main form{padding:var(--ymt-spacing-m);display:flex;flex-direction:column;gap:var(--ymt-spacing-xs);align-items:center}:host main form .source{border:2px solid var(--ymt-outline);border-radius:var(--ymt-corner-s);padding:var(--ymt-spacing-xs);display:flex;flex-direction:column}:host main form .source em{font-style:normal;font:var(--ymt-font-body-subtle);color:var(--ymt-text-color-subtle)}:host main form .line{width:2px;background-color:var(--ymt-outline);min-height:2em;position:relative}:host main form .line:before{content:\"\";position:absolute;transform:rotate(135deg);width:8px;inset-block-end:0;translate:-3px 2px;height:8px;border:4px solid transparent;border-block-start-color:var(--ymt-outline);border-inline-end-color:var(--ymt-outline)}\n"] }]
|
|
423
|
+
], template: "<yuv-dialog class=\"not-separated\" [headertitel]=\"'yuv.object-relationship.add-relationship.headline' | translate\">\n <main [yuvBusyOverlay]=\"busy()\">\n <form [formGroup]=\"form\" (ngSubmit)=\"submit()\">\n @let sn = sourceNode();\n @if (sn) {\n <div class=\"source\">\n {{ sn.title }}\n @if (sn.description) {\n <em>{{ sn.description }}</em>\n }\n </div>\n <div class=\"line\"></div>\n }\n <mat-form-field>\n <mat-label>{{ 'cm.app.cases.action.add-link.search.relation.label' | translate }}</mat-label>\n <mat-select formControlName=\"relation\" [compareWith]=\"optionCompareWith\">\n @for (r of supportedRelationships(); track r.id) {\n <mat-option [value]=\"r\">{{ r.label }}</mat-option>\n }\n </mat-select>\n </mat-form-field>\n\n <div class=\"line\"></div>\n\n <yuv-relationship-target-search formControlName=\"targetObject\"\n [config]=\"config()\"\n [availableTargetTypes]=\"availableTargetTypes()\"\n [supportedRelationships]=\"supportedRelationships()\"\n ></yuv-relationship-target-search>\n\n @if (form.hasError('invalidRelationTargetCombination') && (form.touched || form.dirty)) {\n <mat-error class=\"error\">{{ 'yuv.object-relationship.add-relationship.error.invalidRelationTargetCombination' | translate }}</mat-error>\n }\n \n @if (error()) {\n <div class=\"error\">{{ error() }}</div>\n }\n </form>\n </main>\n\n <footer>\n <button ymtButton=\"secondary\" type=\"button\" (click)=\"close()\" [disabled]=\"busy()\">\n {{ 'yuv.object-relationship.add-relationship.action.cancel' | translate }}\n </button>\n <button ymtButton=\"primary\" type=\"button\" (click)=\"submit()\" [disabled]=\"form.invalid || busy()\">\n {{ 'yuv.object-relationship.add-relationship.action.submit' | translate }}\n </button>\n </footer>\n</yuv-dialog>\n", styles: [":host .error{background-color:var(--ymt-danger-container);color:var(--ymt-on-danger-container);width:100%;padding:var(--ymt-spacing-m);border-radius:var(--ymt-spacing-xs)}:host main form{padding:var(--ymt-spacing-m);display:flex;flex-direction:column;gap:var(--ymt-spacing-xs);align-items:center}:host main form .source{border:2px solid var(--ymt-outline);border-radius:var(--ymt-corner-s);padding:var(--ymt-spacing-xs);display:flex;flex-direction:column}:host main form .source em{font-style:normal;font:var(--ymt-font-body-subtle);color:var(--ymt-text-color-subtle)}:host main form yuv-relationship-target-search,:host main form mat-form-field{width:100%}:host main form .line{width:2px;background-color:var(--ymt-outline);min-height:2em;position:relative}:host main form .line:before{content:\"\";position:absolute;transform:rotate(135deg);width:8px;inset-block-end:0;translate:-3px 2px;height:8px;border:4px solid transparent;border-block-start-color:var(--ymt-outline);border-inline-end-color:var(--ymt-outline)}\n"] }]
|
|
408
424
|
}] });
|
|
409
425
|
|
|
410
426
|
class ObjectRelationshipGraphComponent {
|
|
@@ -435,7 +451,6 @@ class ObjectRelationshipGraphComponent {
|
|
|
435
451
|
const rel = this.#relations();
|
|
436
452
|
if (!rel)
|
|
437
453
|
return;
|
|
438
|
-
// this.#outerObjectNodeIds = rel.objects.items.map((i) => i.fields.get(BaseObjectTypeField.OBJECT_ID) as string);
|
|
439
454
|
this.#_updateGraph(rel.originId, rel.relations, rel.objects);
|
|
440
455
|
});
|
|
441
456
|
/**
|
|
@@ -494,6 +509,7 @@ class ObjectRelationshipGraphComponent {
|
|
|
494
509
|
addRelationship() {
|
|
495
510
|
this.#dialog
|
|
496
511
|
.open(AddRelationshipComponent, {
|
|
512
|
+
...ADD_RELATIONSHIP_DIALOG_OPTIONS,
|
|
497
513
|
data: {
|
|
498
514
|
object: this.selectedObject(),
|
|
499
515
|
config: this.config()
|
|
@@ -507,7 +523,21 @@ class ObjectRelationshipGraphComponent {
|
|
|
507
523
|
deleteRelationship() {
|
|
508
524
|
this.#objectRelationshipService.deleteRelationship(this.selectedRelation().id, false).subscribe((success) => {
|
|
509
525
|
if (success) {
|
|
526
|
+
const deletedEdge = this.#edges.get(this.selectedRelation().id);
|
|
527
|
+
if (!deletedEdge)
|
|
528
|
+
return;
|
|
529
|
+
const sourceNodeId = deletedEdge.from;
|
|
530
|
+
const targetNodeId = deletedEdge.to;
|
|
510
531
|
this.#edges.remove(this.selectedRelation().id);
|
|
532
|
+
// check if the source/target node of the deleted edge has other connections to another node in the current graph
|
|
533
|
+
const otherEdgesForSource = this.#edges.get().filter((edge) => edge.from === sourceNodeId || edge.to === sourceNodeId);
|
|
534
|
+
const otherEdgesForTarget = this.#edges.get().filter((edge) => edge.from === targetNodeId || edge.to === targetNodeId);
|
|
535
|
+
if (sourceNodeId && otherEdgesForSource.length === 0) {
|
|
536
|
+
this.#nodes.remove(sourceNodeId);
|
|
537
|
+
}
|
|
538
|
+
if (targetNodeId && otherEdgesForTarget.length === 0) {
|
|
539
|
+
this.#nodes.remove(targetNodeId);
|
|
540
|
+
}
|
|
511
541
|
}
|
|
512
542
|
else {
|
|
513
543
|
this.#snack.danger(this.translate.instant('yuv.object-relationship.delete-relation.error-message'));
|
|
@@ -548,7 +578,7 @@ class ObjectRelationshipGraphComponent {
|
|
|
548
578
|
const incoming = relations.items.filter((item) => item.fields.get(RelationshipTypeField.TARGET_ID) === originId);
|
|
549
579
|
const outgoing = relations.items.filter((item) => item.fields.get(RelationshipTypeField.SOURCE_ID) === originId);
|
|
550
580
|
const rootNode = this.#toNode(originId);
|
|
551
|
-
const _nodes = originId === this.#relations()?.originId
|
|
581
|
+
const _nodes = originId === this.#relations()?.originId && this.#nodes.get([originId]).length === 0
|
|
552
582
|
? [
|
|
553
583
|
{
|
|
554
584
|
...rootNode,
|
|
@@ -565,7 +595,7 @@ class ObjectRelationshipGraphComponent {
|
|
|
565
595
|
outgoing.forEach((item) => {
|
|
566
596
|
const relatedObjectId = item.fields.get(RelationshipTypeField.TARGET_ID);
|
|
567
597
|
const n = this.#toNode(relatedObjectId);
|
|
568
|
-
const e = this.#toEdge(item, originId, relatedObjectId, '
|
|
598
|
+
const e = this.#toEdge(item, originId, relatedObjectId, 'to');
|
|
569
599
|
if (n) {
|
|
570
600
|
// check if the node is already in the rendered graph
|
|
571
601
|
const nodeExists = _nodes.some((node) => node.id === n.id) || this.#nodes.get([n.id]).length > 0;
|
|
@@ -580,7 +610,7 @@ class ObjectRelationshipGraphComponent {
|
|
|
580
610
|
incoming.forEach((item) => {
|
|
581
611
|
const relatedObjectId = item.fields.get(RelationshipTypeField.SOURCE_ID);
|
|
582
612
|
const n = this.#toNode(relatedObjectId);
|
|
583
|
-
const e = this.#toEdge(item, relatedObjectId, originId, '
|
|
613
|
+
const e = this.#toEdge(item, relatedObjectId, originId, 'from');
|
|
584
614
|
if (n) {
|
|
585
615
|
// check if the node is already in the rendered graph
|
|
586
616
|
const nodeExists = _nodes.some((node) => node.id === n.id) || this.#nodes.get([n.id]).length > 0;
|
|
@@ -714,7 +744,7 @@ class ObjectRelationshipGraphComponent {
|
|
|
714
744
|
forceAtlas2Based: {
|
|
715
745
|
// gravitationalConstant: -50,
|
|
716
746
|
// centralGravity: 0.01,
|
|
717
|
-
springLength: 200
|
|
747
|
+
springLength: 200
|
|
718
748
|
}
|
|
719
749
|
},
|
|
720
750
|
nodes: {
|
|
@@ -727,36 +757,20 @@ class ObjectRelationshipGraphComponent {
|
|
|
727
757
|
nodes: this.#nodes,
|
|
728
758
|
edges: this.#edges
|
|
729
759
|
}, options);
|
|
730
|
-
this.#network.on('selectNode', (params) =>
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
this.#network.on('
|
|
735
|
-
|
|
736
|
-
});
|
|
737
|
-
this.#network.on('dragEnd', (params) => {
|
|
738
|
-
const selectedNodeId = params.nodes[0];
|
|
739
|
-
this.selectedObject.set(this.#objectQA[selectedNodeId]);
|
|
740
|
-
});
|
|
741
|
-
this.#network.on('selectEdge', (params) => {
|
|
742
|
-
const selectedEdgeId = params.edges[0];
|
|
743
|
-
const nodesSelected = params.nodes.length > 0;
|
|
744
|
-
this.selectedRelation.set(params.edges.length === 1 && !nodesSelected ? this.#relationQA[selectedEdgeId] : null);
|
|
745
|
-
});
|
|
746
|
-
this.#network.on('deselectEdge', (params) => {
|
|
747
|
-
const selectedEdgeId = params.edges[0];
|
|
748
|
-
const nodesSelected = params.nodes.length > 0;
|
|
749
|
-
this.selectedRelation.set(params.edges.length === 1 && !nodesSelected ? this.#relationQA[selectedEdgeId] : null);
|
|
750
|
-
});
|
|
751
|
-
this.#network.on('click', (params) => {
|
|
752
|
-
const selectedNodeId = params.nodes[0];
|
|
753
|
-
this.selectedObject.set(this.#objectQA[selectedNodeId]);
|
|
754
|
-
});
|
|
760
|
+
this.#network.on('selectNode', (params) => this.#setSelection(params));
|
|
761
|
+
this.#network.on('deselectNode', (params) => this.#setSelection(params));
|
|
762
|
+
this.#network.on('dragEnd', (params) => this.#setSelection(params));
|
|
763
|
+
this.#network.on('selectEdge', (params) => this.#setSelection(params));
|
|
764
|
+
this.#network.on('deselectEdge', (params) => this.#setSelection(params));
|
|
765
|
+
this.#network.on('click', (params) => this.#setSelection(params));
|
|
755
766
|
this.#network.on('doubleClick', (params) => {
|
|
756
|
-
|
|
757
|
-
this.#expand(selectedNodeId);
|
|
767
|
+
this.#expand(params.nodes[0]);
|
|
758
768
|
});
|
|
759
769
|
}
|
|
770
|
+
#setSelection(params) {
|
|
771
|
+
this.selectedObject.set(params.nodes.length === 1 ? this.#objectQA[params.nodes[0]] : null);
|
|
772
|
+
this.selectedRelation.set(params.edges.length === 1 && params.nodes.length === 0 ? this.#relationQA[params.edges[0]] : null);
|
|
773
|
+
}
|
|
760
774
|
ngOnDestroy() {
|
|
761
775
|
if (this.#network) {
|
|
762
776
|
this.#network.destroy();
|
|
@@ -832,7 +846,7 @@ class ObjectRelationshipListComponent {
|
|
|
832
846
|
#createLists(objectId, relations, objects) {
|
|
833
847
|
const incoming = relations.items.filter((item) => item.fields.get(RelationshipTypeField.TARGET_ID) === objectId);
|
|
834
848
|
const outgoing = relations.items.filter((item) => item.fields.get(RelationshipTypeField.SOURCE_ID) === objectId);
|
|
835
|
-
objects
|
|
849
|
+
objects?.items.forEach((item) => {
|
|
836
850
|
const id = item.fields.get(BaseObjectTypeField.OBJECT_ID);
|
|
837
851
|
this.#objectQA[id] = new DmsObject(item);
|
|
838
852
|
});
|
|
@@ -897,6 +911,10 @@ class ObjectRelationshipComponent {
|
|
|
897
911
|
this.#dialog = inject(MatDialog);
|
|
898
912
|
this.#DEFAULT_MODE = 'graph';
|
|
899
913
|
this.mode = signal(this.#DEFAULT_MODE);
|
|
914
|
+
this.empty = computed(() => {
|
|
915
|
+
const rel = this.#relations();
|
|
916
|
+
return rel && rel.relations.totalNumItems === 0;
|
|
917
|
+
});
|
|
900
918
|
/**
|
|
901
919
|
* ID of the object to display relations for.
|
|
902
920
|
*/
|
|
@@ -915,6 +933,7 @@ class ObjectRelationshipComponent {
|
|
|
915
933
|
const obj = this.originObject();
|
|
916
934
|
return obj ? this.#system.getSupportedRelationships(obj) : [];
|
|
917
935
|
});
|
|
936
|
+
this.busy = this.#objectRelationshipService.busy;
|
|
918
937
|
this.#relations = this.#objectRelationshipService.relations;
|
|
919
938
|
this.#relationsEffect = effect(() => {
|
|
920
939
|
const rel = this.#relations();
|
|
@@ -923,7 +942,8 @@ class ObjectRelationshipComponent {
|
|
|
923
942
|
return;
|
|
924
943
|
}
|
|
925
944
|
const originId = rel.originId;
|
|
926
|
-
const originItem = rel.objects
|
|
945
|
+
const originItem = rel.objects?.items.find((item) => item.fields.get(BaseObjectTypeField.OBJECT_ID) === originId);
|
|
946
|
+
// TODO: use linked signal instead
|
|
927
947
|
this.originObject.set(originItem ? new DmsObject(originItem) : null);
|
|
928
948
|
});
|
|
929
949
|
this.relationActions = input(null);
|
|
@@ -941,6 +961,7 @@ class ObjectRelationshipComponent {
|
|
|
941
961
|
}
|
|
942
962
|
addRelationship() {
|
|
943
963
|
this.#dialog.open(AddRelationshipComponent, {
|
|
964
|
+
...ADD_RELATIONSHIP_DIALOG_OPTIONS,
|
|
944
965
|
data: {
|
|
945
966
|
object: this.originObject(),
|
|
946
967
|
config: this.config()
|
|
@@ -948,7 +969,7 @@ class ObjectRelationshipComponent {
|
|
|
948
969
|
});
|
|
949
970
|
}
|
|
950
971
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.15", ngImport: i0, type: ObjectRelationshipComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
951
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.15", type: ObjectRelationshipComponent, isStandalone: true, selector: "yuv-object-relationship", inputs: { objectId: { classPropertyName: "objectId", publicName: "objectId", isSignal: true, isRequired: true, transformFunction: null }, config: { classPropertyName: "config", publicName: "config", isSignal: true, isRequired: true, transformFunction: null }, relationActions: { classPropertyName: "relationActions", publicName: "relationActions", isSignal: true, isRequired: false, transformFunction: null } }, providers: [ObjectRelationshipService], ngImport: i0, template: "<ymt-pane [plain]=\"true\" [topBarActions]=\"topBarActions\">\n <ymt-pane-body>\n @switch (mode()) {\n @case ('graph') {\n <yuv-object-relationship-graph [config]=\"config()\"></yuv-object-relationship-graph>\n }\n @case ('list') {\n <yuv-object-relationship-list [config]=\"config()\"> </yuv-object-relationship-list>\n }\n }\n </ymt-pane-body>\n</ymt-pane>\n\n<ng-template #topBarActions>\n @if (supportedRelationships().length > 0) {\n <button ymt-icon-button icon-button-size=\"small\" [matTooltip]=\"'yuv.object-relationship.add.tooltip' | translate\" (click)=\"addRelationship()\">\n <mat-icon>add</mat-icon>\n </button>\n }\n <button\n ymt-icon-button\n icon-button-size=\"small\"\n [matTooltip]=\"mode() === 'list' ? ('yuv.object-relationship.mode.graph.tooltip' | translate) : ('yuv.object-relationship.mode.list.tooltip' | translate)\"\n (click)=\"toggleMode()\"\n >\n <mat-icon>{{ mode() === 'list' ? 'graph_3' : 'list' }}</mat-icon>\n </button>\n</ng-template>\n", styles: [":host{display:block;position:relative;height:100%;background-color:var(--ymt-surface)}:host .toggle{position:absolute;inset-block-start:var(--ymt-spacing-s);inset-inline-end:var(--ymt-spacing-s);z-index:10;background-color:var(--ymt-surface);padding:var(--ymt-spacing-xs);border-radius:var(--ymt-corner-full)}:host yuv-object-relationship-list,:host yuv-object-relationship-graph{height:100%}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i1$3.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i2.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "ngmodule", type: TranslateModule }, { kind: "pipe", type: i3.TranslatePipe, name: "translate" }, { kind: "ngmodule", type: MatButtonToggleModule }, { kind: "ngmodule", type: YmtPanesModule }, { kind: "component", type: i4$1.YmtPaneComponent, selector: "ymt-pane", inputs: ["topBarActions", "plain", "mode", "modeAlign"], outputs: ["paneToggled", "navigationClicked"] }, { kind: "component", type: i4$1.YmtPaneBodyComponent, selector: "ymt-pane-body" }, { kind: "directive", type: YmtIconButtonDirective, selector: "button[ymtIconButton],button[ymt-icon-button],a[ymtIconButton],a[ymt-icon-button]", inputs: ["disabled", "disableRipple", "aria-disabled", "disabledInteractive", "icon-button-size"] }, { kind: "component", type: ObjectRelationshipGraphComponent, selector: "yuv-object-relationship-graph", inputs: ["config"], outputs: ["objectSelected", "relationSelected"] }, { kind: "component", type: ObjectRelationshipListComponent, selector: "yuv-object-relationship-list", inputs: ["config"] }] }); }
|
|
972
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.15", type: ObjectRelationshipComponent, isStandalone: true, selector: "yuv-object-relationship", inputs: { objectId: { classPropertyName: "objectId", publicName: "objectId", isSignal: true, isRequired: true, transformFunction: null }, config: { classPropertyName: "config", publicName: "config", isSignal: true, isRequired: true, transformFunction: null }, relationActions: { classPropertyName: "relationActions", publicName: "relationActions", isSignal: true, isRequired: false, transformFunction: null } }, providers: [ObjectRelationshipService], ngImport: i0, template: "<ymt-pane [plain]=\"true\" [topBarActions]=\"topBarActions\">\n <ymt-pane-body [yuvBusyOverlay]=\"busy()\">\n @if (empty()) {\n <div class=\"no-relations\" inert>\n <mat-icon>link_off</mat-icon>\n <p>{{ 'yuv.object-relationship.no-relations' | translate }}</p>\n </div>\n }\n @switch (mode()) {\n @case ('graph') {\n <yuv-object-relationship-graph [config]=\"config()\"></yuv-object-relationship-graph>\n }\n @case ('list') {\n <yuv-object-relationship-list [config]=\"config()\"> </yuv-object-relationship-list>\n }\n }\n </ymt-pane-body>\n</ymt-pane>\n\n<ng-template #topBarActions>\n @if (supportedRelationships().length > 0) {\n <button ymt-icon-button icon-button-size=\"small\" [matTooltip]=\"'yuv.object-relationship.add.tooltip' | translate\" (click)=\"addRelationship()\">\n <mat-icon>add</mat-icon>\n </button>\n }\n <button\n ymt-icon-button\n icon-button-size=\"small\"\n [matTooltip]=\"mode() === 'list' ? ('yuv.object-relationship.mode.graph.tooltip' | translate) : ('yuv.object-relationship.mode.list.tooltip' | translate)\"\n (click)=\"toggleMode()\"\n >\n <mat-icon>{{ mode() === 'list' ? 'graph_3' : 'list' }}</mat-icon>\n </button>\n</ng-template>\n", styles: [":host{display:block;position:relative;height:100%;background-color:var(--ymt-surface)}:host .toggle{position:absolute;inset-block-start:var(--ymt-spacing-s);inset-inline-end:var(--ymt-spacing-s);z-index:10;background-color:var(--ymt-surface);padding:var(--ymt-spacing-xs);border-radius:var(--ymt-corner-full)}:host yuv-object-relationship-list,:host yuv-object-relationship-graph{height:100%}:host .no-relations{position:absolute;inset:0;display:flex;flex-direction:column;justify-content:center;align-items:center;text-align:center;padding:var(--ymt-spacing-l);gap:var(--ymt-spacing-m);overflow:hidden}:host .no-relations mat-icon{scale:4;color:var(--ymt-text-color-subtle);opacity:.5;transform:translateY(-.5em)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i1$3.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i2.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "ngmodule", type: TranslateModule }, { kind: "pipe", type: i3.TranslatePipe, name: "translate" }, { kind: "ngmodule", type: MatButtonToggleModule }, { kind: "ngmodule", type: YmtPanesModule }, { kind: "component", type: i4$1.YmtPaneComponent, selector: "ymt-pane", inputs: ["topBarActions", "plain", "mode", "modeAlign"], outputs: ["paneToggled", "navigationClicked"] }, { kind: "component", type: i4$1.YmtPaneBodyComponent, selector: "ymt-pane-body" }, { kind: "directive", type: YmtIconButtonDirective, selector: "button[ymtIconButton],button[ymt-icon-button],a[ymtIconButton],a[ymt-icon-button]", inputs: ["disabled", "disableRipple", "aria-disabled", "disabledInteractive", "icon-button-size"] }, { kind: "component", type: ObjectRelationshipGraphComponent, selector: "yuv-object-relationship-graph", inputs: ["config"], outputs: ["objectSelected", "relationSelected"] }, { kind: "component", type: ObjectRelationshipListComponent, selector: "yuv-object-relationship-list", inputs: ["config"] }, { kind: "directive", type: BusyOverlayDirective, selector: "[yuvBusyOverlay]", inputs: ["yuvBusyOverlay", "yuvBusyOverlayConfig"] }] }); }
|
|
952
973
|
}
|
|
953
974
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.15", ngImport: i0, type: ObjectRelationshipComponent, decorators: [{
|
|
954
975
|
type: Component,
|
|
@@ -962,8 +983,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.15", ngImpo
|
|
|
962
983
|
YmtIconButtonDirective,
|
|
963
984
|
ObjectRelationshipGraphComponent,
|
|
964
985
|
ObjectRelationshipListComponent,
|
|
965
|
-
YmtIconButtonDirective
|
|
966
|
-
|
|
986
|
+
YmtIconButtonDirective,
|
|
987
|
+
BusyOverlayDirective
|
|
988
|
+
], providers: [ObjectRelationshipService], template: "<ymt-pane [plain]=\"true\" [topBarActions]=\"topBarActions\">\n <ymt-pane-body [yuvBusyOverlay]=\"busy()\">\n @if (empty()) {\n <div class=\"no-relations\" inert>\n <mat-icon>link_off</mat-icon>\n <p>{{ 'yuv.object-relationship.no-relations' | translate }}</p>\n </div>\n }\n @switch (mode()) {\n @case ('graph') {\n <yuv-object-relationship-graph [config]=\"config()\"></yuv-object-relationship-graph>\n }\n @case ('list') {\n <yuv-object-relationship-list [config]=\"config()\"> </yuv-object-relationship-list>\n }\n }\n </ymt-pane-body>\n</ymt-pane>\n\n<ng-template #topBarActions>\n @if (supportedRelationships().length > 0) {\n <button ymt-icon-button icon-button-size=\"small\" [matTooltip]=\"'yuv.object-relationship.add.tooltip' | translate\" (click)=\"addRelationship()\">\n <mat-icon>add</mat-icon>\n </button>\n }\n <button\n ymt-icon-button\n icon-button-size=\"small\"\n [matTooltip]=\"mode() === 'list' ? ('yuv.object-relationship.mode.graph.tooltip' | translate) : ('yuv.object-relationship.mode.list.tooltip' | translate)\"\n (click)=\"toggleMode()\"\n >\n <mat-icon>{{ mode() === 'list' ? 'graph_3' : 'list' }}</mat-icon>\n </button>\n</ng-template>\n", styles: [":host{display:block;position:relative;height:100%;background-color:var(--ymt-surface)}:host .toggle{position:absolute;inset-block-start:var(--ymt-spacing-s);inset-inline-end:var(--ymt-spacing-s);z-index:10;background-color:var(--ymt-surface);padding:var(--ymt-spacing-xs);border-radius:var(--ymt-corner-full)}:host yuv-object-relationship-list,:host yuv-object-relationship-graph{height:100%}:host .no-relations{position:absolute;inset:0;display:flex;flex-direction:column;justify-content:center;align-items:center;text-align:center;padding:var(--ymt-spacing-l);gap:var(--ymt-spacing-m);overflow:hidden}:host .no-relations mat-icon{scale:4;color:var(--ymt-text-color-subtle);opacity:.5;transform:translateY(-.5em)}\n"] }]
|
|
967
989
|
}] });
|
|
968
990
|
|
|
969
991
|
const cmp = [ObjectRelationshipComponent];
|