diff --git a/backend/core/src/main/java/org/opencdmp/service/description/DescriptionServiceImpl.java b/backend/core/src/main/java/org/opencdmp/service/description/DescriptionServiceImpl.java index c4d2dfeee..5d34a0964 100644 --- a/backend/core/src/main/java/org/opencdmp/service/description/DescriptionServiceImpl.java +++ b/backend/core/src/main/java/org/opencdmp/service/description/DescriptionServiceImpl.java @@ -847,6 +847,7 @@ public class DescriptionServiceImpl implements DescriptionService { newReference.setId(UUID.randomUUID()); newReference.setDescriptionId(newDescription.getId()); newReference.setReferenceId(descriptionReference.getReferenceId()); + newReference.setData(descriptionReference.getData()); newReference.setCreatedAt(Instant.now()); newReference.setUpdatedAt(Instant.now()); newReference.setIsActive(IsActive.Active); diff --git a/backend/core/src/main/java/org/opencdmp/service/reference/ReferenceService.java b/backend/core/src/main/java/org/opencdmp/service/reference/ReferenceService.java index 7c5916fd0..ac53edf57 100644 --- a/backend/core/src/main/java/org/opencdmp/service/reference/ReferenceService.java +++ b/backend/core/src/main/java/org/opencdmp/service/reference/ReferenceService.java @@ -23,4 +23,6 @@ public interface ReferenceService { void deleteAndSave(UUID id) throws MyForbiddenException, InvalidApplicationException; List searchReferenceData(ReferenceSearchLookup lookup) throws MyNotFoundException, InvalidApplicationException; + + Boolean findReference(String reference, UUID referenceTypeId); } diff --git a/backend/core/src/main/java/org/opencdmp/service/reference/ReferenceServiceImpl.java b/backend/core/src/main/java/org/opencdmp/service/reference/ReferenceServiceImpl.java index 465fd1662..af4820347 100644 --- a/backend/core/src/main/java/org/opencdmp/service/reference/ReferenceServiceImpl.java +++ b/backend/core/src/main/java/org/opencdmp/service/reference/ReferenceServiceImpl.java @@ -159,6 +159,14 @@ public class ReferenceServiceImpl implements ReferenceService { this.deleterFactory.deleter(ReferenceDeleter.class).deleteAndSaveByIds(List.of(id)); } + public Boolean findReference(String reference, UUID referenceTypeId){ + if (this.conventionService.isNullOrEmpty(reference) || !this.conventionService.isValidGuid(referenceTypeId)) return false; + ReferenceQuery query = this.queryFactory.query(ReferenceQuery.class).references(reference).typeIds(referenceTypeId).isActive(IsActive.Active); + + if (query != null && query.count() > 0) return true; + return false; + } + @Override public List searchReferenceData(ReferenceSearchLookup lookup) throws MyNotFoundException, InvalidApplicationException { int initialOffset = 0; diff --git a/backend/web/src/main/java/org/opencdmp/controllers/ReferenceController.java b/backend/web/src/main/java/org/opencdmp/controllers/ReferenceController.java index 786d13eb4..33b9d4a88 100644 --- a/backend/web/src/main/java/org/opencdmp/controllers/ReferenceController.java +++ b/backend/web/src/main/java/org/opencdmp/controllers/ReferenceController.java @@ -105,6 +105,19 @@ public class ReferenceController { return references; } + @GetMapping("find/{referenceTypeId}") + public Boolean findReference(@PathVariable("referenceTypeId") UUID referenceTypeId, @RequestParam("reference") String reference) throws MyNotFoundException { + logger.debug("search with db definition {}", Reference.class.getSimpleName()); + + this.censorFactory.censor(ReferenceCensor.class).censor(null, null); + + Boolean result = this.referenceService.findReference(reference, referenceTypeId); + + this.auditService.track(AuditableAction.Reference_Query, "reference", reference); + + return result; + } + @GetMapping("{id}") public Reference get(@PathVariable("id") UUID id, FieldSet fieldSet) throws MyApplicationException, MyForbiddenException, MyNotFoundException { logger.debug(new MapLogEntry("retrieving" + Reference.class.getSimpleName()).And("id", id).And("fields", fieldSet)); diff --git a/dmp-frontend/src/app/core/services/reference/reference.service.ts b/dmp-frontend/src/app/core/services/reference/reference.service.ts index fcd8d72b7..9468fc5be 100644 --- a/dmp-frontend/src/app/core/services/reference/reference.service.ts +++ b/dmp-frontend/src/app/core/services/reference/reference.service.ts @@ -46,6 +46,14 @@ export class ReferenceService { return this.http.post(url, q).pipe(catchError((error: any) => throwError(error))); } + findReference(reference: string, referenceTypeId: Guid): Observable { + + const url = `${this.apiBase}/find/${referenceTypeId}`; + const options = { params: { reference: reference } }; + + return this.http.get(url, options).pipe(catchError((error: any) => throwError(error))); + } + getSingle(id: Guid, reqFields: string[] = []): Observable { const url = `${this.apiBase}/${id}`; const options = { params: { f: reqFields } }; diff --git a/dmp-frontend/src/app/ui/description/editor/description-editor.component.html b/dmp-frontend/src/app/ui/description/editor/description-editor.component.html index d39232e9a..08bf45631 100644 --- a/dmp-frontend/src/app/ui/description/editor/description-editor.component.html +++ b/dmp-frontend/src/app/ui/description/editor/description-editor.component.html @@ -149,7 +149,7 @@ [hidden]="this.step === 0" [linkToScroll]="linkToScroll" [validationErrorModel]="editorModel.validationErrorModel" - [isNew]="isNew" + [isNew]="isNew || isCopy" (fieldsetFocusChange)="fieldsetIdWithFocus = $event" > diff --git a/dmp-frontend/src/app/ui/reference/reference-field/editor/reference-dialog-editor.component.html b/dmp-frontend/src/app/ui/reference/reference-field/editor/reference-dialog-editor.component.html index 97d2142ce..cb447d916 100644 --- a/dmp-frontend/src/app/ui/reference/reference-field/editor/reference-dialog-editor.component.html +++ b/dmp-frontend/src/app/ui/reference/reference-field/editor/reference-dialog-editor.component.html @@ -11,12 +11,12 @@
- + {{field}} check - clear + clear {{'REFERENCE-FIELD.REFERENCE-DIALOG-EDITOR.IDENTIFIER-EXISTS' | translate}} {{'GENERAL.VALIDATION.REQUIRED' | translate}} @@ -37,7 +37,7 @@
-
+
diff --git a/dmp-frontend/src/app/ui/reference/reference-field/editor/reference-dialog-editor.component.ts b/dmp-frontend/src/app/ui/reference/reference-field/editor/reference-dialog-editor.component.ts index c7298a3df..de40589ef 100644 --- a/dmp-frontend/src/app/ui/reference/reference-field/editor/reference-dialog-editor.component.ts +++ b/dmp-frontend/src/app/ui/reference/reference-field/editor/reference-dialog-editor.component.ts @@ -5,9 +5,10 @@ import { ReferenceSourceType } from '@app/core/common/enum/reference-source-type import { ReferenceType, ReferenceTypeDefinition, ReferenceTypeField } from '@app/core/model/reference-type/reference-type'; import { DefinitionPersist, FieldPersist, ReferencePersist } from '@app/core/model/reference/reference'; import { ReferenceTypeService } from '@app/core/services/reference-type/reference-type.service'; +import { ReferenceService } from '@app/core/services/reference/reference.service'; import { BaseComponent } from '@common/base/base.component'; import { FormService } from '@common/forms/form-service'; -import { takeUntil } from 'rxjs/operators'; +import { debounceTime, takeUntil } from 'rxjs/operators'; import { nameof } from 'ts-simple-nameof'; @Component({ @@ -19,16 +20,11 @@ export class ReferenceDialogEditorComponent extends BaseComponent implements OnI referenceType: ReferenceType; systemFields: string[]; label: string = null - private existingReferences: string[] = []; - - get referenceExists(){ - const reference = this.formGroup.get(this.systemFields[0]).value; - - return this.existingReferences.find((r)=>r === reference) - } + referenceExists: Boolean; constructor( private referenceTypeService: ReferenceTypeService, + private referenceService: ReferenceService, private fb: UntypedFormBuilder, public dialogRef: MatDialogRef, @Inject(MAT_DIALOG_DATA) public data: any, @@ -36,7 +32,6 @@ export class ReferenceDialogEditorComponent extends BaseComponent implements OnI ) { super(); this.label = data.label; - this.existingReferences = data.existingReferences; this.formGroup = this.fb.group({}); } @@ -49,6 +44,21 @@ export class ReferenceDialogEditorComponent extends BaseComponent implements OnI referenceType => { this.referenceType = referenceType; this.buildForm(referenceType.definition?.fields); + this.formGroup.get(this.systemFields[0]).valueChanges + .pipe(takeUntil(this._destroyed), debounceTime(500)) + .subscribe(x => this.findReferenceIfExist()); + + } + ); + } + + findReferenceIfExist(): void { + this.referenceExists = null; + this.referenceService.findReference(this.formGroup.get(this.systemFields[0]).value, this.data.referenceTypeId) + .pipe(takeUntil(this._destroyed)) + .subscribe( + result => { + this.referenceExists = result; } ); } @@ -68,7 +78,7 @@ export class ReferenceDialogEditorComponent extends BaseComponent implements OnI } isFormValid() { - return this.formGroup.valid && !this.referenceExists; + return this.formGroup.valid && this.referenceExists != null && !this.referenceExists; } send() { diff --git a/dmp-frontend/src/app/ui/reference/reference-field/reference-field.component.ts b/dmp-frontend/src/app/ui/reference/reference-field/reference-field.component.ts index ef7efe3c8..cf4782aff 100644 --- a/dmp-frontend/src/app/ui/reference/reference-field/reference-field.component.ts +++ b/dmp-frontend/src/app/ui/reference/reference-field/reference-field.component.ts @@ -132,47 +132,26 @@ export class ReferenceFieldComponent extends BaseComponent implements OnInit, On addReference() { - 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) - }, + const dialogRef = this.dialog.open(ReferenceDialogEditorComponent, { + width: '500px', + restoreFocus: false, + data: { + referenceTypeId: this.referenceType.id, + label: this.label ?? this.referenceType.name, + }, + }); + dialogRef.afterClosed() + .pipe(takeUntil(this._destroyed)) + .subscribe(newResult => { + if (!newResult) { return; } + if (this.multiple) { + let results = this.form.value as ReferencePersist[]; + if (results == undefined) results = []; + results.push(newResult); + this.form.setValue(results); + } else { + this.form.setValue(newResult); + } }); - dialogRef.afterClosed() - .pipe(takeUntil(this._destroyed)) - .subscribe(newResult => { - if (!newResult) { return; } - if (this.multiple) { - let results = this.form.value as ReferencePersist[]; - if (results == undefined) results = []; - results.push(newResult); - this.form.setValue(results); - } else { - this.form.setValue(newResult); - } - }); - } - ); - } - - private buildAutocompleteSearchLookup(typeId: Guid): ReferenceSearchLookup { - const lookup: ReferenceSearchLookup = new ReferenceSearchLookup(); - lookup.page = { size: 100, offset: 0 }; - lookup.project = { - fields: [ - nameof(x => x.reference), - ] - }; - lookup.typeId = typeId; - lookup.order = { items: [nameof(x => x.label)] }; - - return lookup; } }