2024-04-18 11:20:05 +02:00
|
|
|
import { Component, Input, OnChanges, OnInit, SimpleChanges } from '@angular/core';
|
2024-04-01 15:05:28 +02:00
|
|
|
import { UntypedFormArray, UntypedFormGroup } from '@angular/forms';
|
|
|
|
import { MatDialog } from '@angular/material/dialog';
|
2024-02-09 21:46:05 +01:00
|
|
|
import { ReferenceType } from '@app/core/model/reference-type/reference-type';
|
2024-01-15 17:47:34 +01:00
|
|
|
import { ReferenceService } from '@app/core/services/reference/reference.service';
|
|
|
|
import { EnumUtils } from '@app/core/services/utilities/enum-utils.service';
|
|
|
|
import { MultipleAutoCompleteConfiguration } from '@app/library/auto-complete/multiple/multiple-auto-complete-configuration';
|
2024-02-21 16:52:50 +01:00
|
|
|
import { SingleAutoCompleteConfiguration } from '@app/library/auto-complete/single/single-auto-complete-configuration';
|
2024-01-15 17:47:34 +01:00
|
|
|
import { BaseComponent } from '@common/base/base.component';
|
2024-04-01 15:05:28 +02:00
|
|
|
import { takeUntil } from 'rxjs/operators';
|
|
|
|
import { ReferenceDialogEditorComponent } from './editor/reference-dialog-editor.component';
|
2024-04-02 10:15:07 +02:00
|
|
|
import { Reference, ReferencePersist } from '@app/core/model/reference/reference';
|
|
|
|
import { ReferenceSearchLookup } from '@app/core/query/reference-search.lookup';
|
|
|
|
import { Guid } from '@common/types/guid';
|
|
|
|
import { nameof } from 'ts-simple-nameof';
|
2024-04-18 11:20:05 +02:00
|
|
|
import { Subscription } from 'rxjs';
|
2023-12-28 16:18:49 +01:00
|
|
|
|
|
|
|
@Component({
|
|
|
|
selector: 'app-reference-field-component',
|
|
|
|
templateUrl: 'reference-field.component.html',
|
|
|
|
styleUrls: ['./reference-field.component.scss']
|
|
|
|
})
|
2024-04-18 11:20:05 +02:00
|
|
|
export class ReferenceFieldComponent extends BaseComponent implements OnInit, OnChanges {
|
2023-12-28 16:18:49 +01:00
|
|
|
|
|
|
|
@Input() referenceType: ReferenceType = null;
|
|
|
|
@Input() form: UntypedFormGroup = null;
|
2024-02-01 13:42:23 +01:00
|
|
|
@Input() label: string = null;
|
2024-02-08 18:48:14 +01:00
|
|
|
@Input() required: boolean = false;
|
|
|
|
@Input() multiple: boolean = true;
|
|
|
|
@Input() hint: string;
|
2024-02-09 21:46:05 +01:00
|
|
|
@Input() placeholder: string;
|
2024-04-16 17:20:43 +02:00
|
|
|
@Input() dependencies: UntypedFormGroup = null;
|
|
|
|
|
2024-04-17 16:17:36 +02:00
|
|
|
referenceToUse: Reference[]= [];
|
2024-04-18 11:20:05 +02:00
|
|
|
|
|
|
|
referenceDepedencyIds: Guid[] = [];
|
2023-12-28 16:18:49 +01:00
|
|
|
|
2024-01-15 17:47:34 +01:00
|
|
|
multipleAutoCompleteSearchConfiguration: MultipleAutoCompleteConfiguration;
|
2024-02-21 16:52:50 +01:00
|
|
|
singleAutoCompleteSearchConfiguration: SingleAutoCompleteConfiguration;
|
2023-12-28 16:18:49 +01:00
|
|
|
|
2024-04-18 11:20:05 +02:00
|
|
|
dependenciesSubscription: Subscription = null;
|
2023-12-28 16:18:49 +01:00
|
|
|
constructor(
|
2024-01-15 17:47:34 +01:00
|
|
|
private referenceService: ReferenceService,
|
|
|
|
public enumUtils: EnumUtils,
|
2024-04-01 15:05:28 +02:00
|
|
|
private dialog: MatDialog,
|
2023-12-28 16:18:49 +01:00
|
|
|
) { super(); }
|
|
|
|
|
|
|
|
ngOnInit() {
|
2024-04-18 11:20:05 +02:00
|
|
|
this.referenceDepedencyIds = this.referenceType.definition.sources.filter(x => x.referenceTypeDependencies).flatMap(x => x.referenceTypeDependencies).filter(x => x).map(x => x.id);
|
|
|
|
if (this.referenceDepedencyIds.length > 0) {
|
|
|
|
this.resolveReferenceDepedency(true);
|
2024-04-17 16:17:36 +02:00
|
|
|
} else {
|
|
|
|
if (this.multiple) {
|
|
|
|
this.multipleAutoCompleteSearchConfiguration = this.referenceService.getMultipleAutoCompleteSearchConfiguration(this.referenceType.id, null);
|
|
|
|
} else {
|
|
|
|
this.singleAutoCompleteSearchConfiguration = this.referenceService.getSingleAutocompleteSearchConfiguration(this.referenceType.id, null);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-04-18 11:20:05 +02:00
|
|
|
ngOnChanges(changes: SimpleChanges) {
|
|
|
|
if ((changes['dependencies'] || changes['referenceType']) && this.dependencies != null && this.referenceType != null) {
|
|
|
|
this.referenceDepedencyIds = this.referenceType.definition.sources.filter(x => x.referenceTypeDependencies).flatMap(x => x.referenceTypeDependencies).filter(x => x).map(x => x.id);
|
|
|
|
if (this.referenceDepedencyIds.length > 0) {
|
|
|
|
if (this.dependenciesSubscription != null) this.dependenciesSubscription.unsubscribe();
|
|
|
|
this.resolveReferenceDepedency(true);
|
|
|
|
this.dependenciesSubscription = this.dependencies.valueChanges.pipe(takeUntil(this._destroyed)).subscribe(changes => {
|
|
|
|
this.resolveReferenceDepedency(false);
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
resolveReferenceDepedency(isInitial: boolean) {
|
2024-04-17 16:17:36 +02:00
|
|
|
const referenceToUse : Reference[]= [];
|
|
|
|
Object.keys(this.dependencies.controls).forEach(controlName => {
|
|
|
|
// (this.dependencies.get(controlName).get('references').value as Reference[]).filter(x=> sourcesWithDependencies.some(y => y.referenceTypeDependencies) x.type.id == this.referenceType.id &&)
|
|
|
|
const foudReferences: any[] = this.dependencies.get(controlName).get('references')?.value;
|
|
|
|
if (foudReferences != null) {
|
|
|
|
for (let i = 0; i < foudReferences.length; i++) {
|
|
|
|
const foudReference = foudReferences[i];
|
2024-04-18 11:20:05 +02:00
|
|
|
if (foudReference?.typeId && this.referenceDepedencyIds.includes(foudReference.typeId)) {
|
2024-04-17 16:17:36 +02:00
|
|
|
const typed = foudReference as ReferencePersist;
|
|
|
|
|
|
|
|
referenceToUse.push({
|
|
|
|
id: typed.id,
|
|
|
|
hash: typed.hash,
|
|
|
|
description: typed.description,
|
|
|
|
reference: typed.reference,
|
|
|
|
abbreviation: typed.abbreviation,
|
|
|
|
source: typed.source,
|
|
|
|
sourceType: typed.sourceType,
|
|
|
|
label: typed.label,
|
|
|
|
definition: typed.definition,
|
|
|
|
type: {
|
|
|
|
id: typed.typeId,
|
|
|
|
}
|
|
|
|
})
|
2024-04-18 11:20:05 +02:00
|
|
|
} else if (foudReference?.type?.id && this.referenceDepedencyIds.includes(foudReference.type.id)) {
|
2024-04-17 16:17:36 +02:00
|
|
|
const typed = foudReference as Reference;
|
|
|
|
if (typed != null) referenceToUse.push(typed);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
});
|
2024-04-18 11:20:05 +02:00
|
|
|
if (!isInitial && (!referenceToUse.map(x => x.reference).every(x => this.referenceToUse.map(y => y.reference).includes(x)) ||
|
2024-04-17 16:17:36 +02:00
|
|
|
!this.referenceToUse.map(x => x.reference).every(x => referenceToUse.map(y => y.reference).includes(x)))) {
|
2024-04-18 11:20:05 +02:00
|
|
|
this.referenceToUse = referenceToUse;
|
|
|
|
this.form.setValue([]);
|
|
|
|
this.form.updateValueAndValidity();
|
|
|
|
} else {
|
|
|
|
this.referenceToUse = referenceToUse;
|
|
|
|
}
|
|
|
|
// if (this.referenceToUseInitialized && (!referenceToUse.map(x => x.reference).every(x => this.referenceToUse.map(y => y.reference).includes(x)) ||
|
|
|
|
// !this.referenceToUse.map(x => x.reference).every(x => referenceToUse.map(y => y.reference).includes(x)))) {
|
|
|
|
// this.form.setValue(null, {onlySelf: true, emitEvent: false});
|
|
|
|
// }
|
2024-04-17 16:17:36 +02:00
|
|
|
|
2024-04-18 11:20:05 +02:00
|
|
|
// this.referenceToUse = referenceToUse;
|
|
|
|
// this.referenceToUseInitialized = true;
|
2024-04-17 16:17:36 +02:00
|
|
|
|
2024-02-21 16:52:50 +01:00
|
|
|
if (this.multiple) {
|
2024-04-17 16:17:36 +02:00
|
|
|
this.multipleAutoCompleteSearchConfiguration = this.referenceService.getMultipleAutoCompleteSearchConfiguration(this.referenceType.id, this.referenceToUse);
|
2024-02-21 16:52:50 +01:00
|
|
|
} else {
|
2024-04-17 16:17:36 +02:00
|
|
|
this.singleAutoCompleteSearchConfiguration = this.referenceService.getSingleAutocompleteSearchConfiguration(this.referenceType.id, this.referenceToUse);
|
2024-02-21 16:52:50 +01:00
|
|
|
}
|
2023-12-28 16:18:49 +01:00
|
|
|
}
|
|
|
|
|
2024-01-18 13:23:20 +01:00
|
|
|
addReference() {
|
2024-04-01 15:05:28 +02:00
|
|
|
|
2024-04-02 10:15:07 +02:00
|
|
|
this.referenceService.searchWithDefinition(this.buildAutocompleteSearchLookup(this.referenceType.id))
|
|
|
|
.pipe(takeUntil(this._destroyed))
|
|
|
|
.subscribe(
|
|
|
|
references => {
|
|
|
|
const dialogRef = this.dialog.open(ReferenceDialogEditorComponent, {
|
|
|
|
width: '500px',
|
|
|
|
restoreFocus: false,
|
|
|
|
data: {
|
|
|
|
referenceTypeId: this.referenceType.id,
|
|
|
|
label: this.label ?? this.referenceType.name,
|
|
|
|
existingReferences: references.map(x => x.reference)
|
|
|
|
},
|
|
|
|
});
|
|
|
|
dialogRef.afterClosed()
|
|
|
|
.pipe(takeUntil(this._destroyed))
|
|
|
|
.subscribe(newResult => {
|
2024-04-17 16:17:36 +02:00
|
|
|
if (!newResult) { return; }
|
2024-04-02 10:15:07 +02:00
|
|
|
let results = this.form.value as ReferencePersist[];
|
|
|
|
if (results == undefined) results = [];
|
|
|
|
results.push(newResult);
|
|
|
|
this.form.setValue(results);
|
|
|
|
});
|
|
|
|
}
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
private buildAutocompleteSearchLookup(typeId: Guid): ReferenceSearchLookup {
|
|
|
|
const lookup: ReferenceSearchLookup = new ReferenceSearchLookup();
|
|
|
|
lookup.page = { size: 100, offset: 0 };
|
|
|
|
lookup.project = {
|
|
|
|
fields: [
|
|
|
|
nameof<Reference>(x => x.reference),
|
|
|
|
]
|
|
|
|
};
|
|
|
|
lookup.typeId = typeId;
|
|
|
|
lookup.order = { items: [nameof<Reference>(x => x.label)] };
|
2024-04-16 17:20:43 +02:00
|
|
|
|
2024-04-02 10:15:07 +02:00
|
|
|
return lookup;
|
2024-01-18 13:23:20 +01:00
|
|
|
}
|
2023-12-28 16:18:49 +01:00
|
|
|
}
|