diff --git a/dmp-frontend/src/app/ui/dmp/dmp-editor-blueprint/dmp-editor.component.html b/dmp-frontend/src/app/ui/dmp/dmp-editor-blueprint/dmp-editor.component.html
index cd72b90c6..b92da98a1 100644
--- a/dmp-frontend/src/app/ui/dmp/dmp-editor-blueprint/dmp-editor.component.html
+++ b/dmp-frontend/src/app/ui/dmp/dmp-editor-blueprint/dmp-editor.component.html
@@ -85,7 +85,7 @@
-
{{section.label}}
+
{{section.label}}
-
@@ -318,3 +318,4 @@
+
diff --git a/dmp-frontend/src/app/ui/dmp/dmp-editor-blueprint/dmp-editor.component.ts b/dmp-frontend/src/app/ui/dmp/dmp-editor-blueprint/dmp-editor.component.ts
index 2d09eb1af..7f9618d8d 100644
--- a/dmp-frontend/src/app/ui/dmp/dmp-editor-blueprint/dmp-editor.component.ts
+++ b/dmp-frontend/src/app/ui/dmp/dmp-editor-blueprint/dmp-editor.component.ts
@@ -47,7 +47,7 @@ import { Guid } from '@common/types/guid';
import { TranslateService } from '@ngx-translate/core';
import { Observable, interval, of } from 'rxjs';
import { map, takeUntil } from 'rxjs/operators';
-import { DmpEditorModel } from './dmp-editor.model';
+import { DmpEditorModel, DmpFieldIndicator } from './dmp-editor.model';
import { DmpEditorResolver } from './dmp-editor.resolver';
import { DmpEditorService } from './dmp-editor.service';
import { DescriptionTemplatePreviewDialogComponent } from '@app/ui/admin/description-template/description-template-preview/description-template-preview-dialog.component';
@@ -93,6 +93,8 @@ export class DmpEditorComponent extends BaseEditor implemen
valueAssign: (item: DmpBlueprint) => item.id,
};
+ sectionToFieldsMap: Map = new Map();
+
protected get canDelete(): boolean {
return !this.isDeleted && !this.isNew && (this.hasPermission(this.authService.permissionEnum.DeleteDmp) || this.item?.authorizationFlags?.some(x => x === AppPermission.DeleteDmp));
}
@@ -222,11 +224,25 @@ export class DmpEditorComponent extends BaseEditor implemen
const canedit = this.isNew ? this.authService.hasPermission(AppPermission.NewDmp) : this.item.authorizationFlags?.some(x => x === AppPermission.EditDmp) || this.authService.hasPermission(AppPermission.EditDmp);
this.formGroup = this.editorModel.buildForm(null, this.isDeleted || !canedit);
+ this.sectionToFieldsMap = this.prepareErrorIndication();
+
if (this.editorModel.status == DmpStatus.Finalized || this.isDeleted) {
this.formGroup.disable();
}
}
+ prepareErrorIndication(): Map {
+ if (this.selectedBlueprint?.definition == null) return;
+
+ const sectionToFieldsMap: Map = new Map();
+ this.selectedBlueprint.definition.sections.forEach((section: DmpBlueprintDefinitionSection) => {
+ let value: DmpFieldIndicator = new DmpFieldIndicator(section);
+ sectionToFieldsMap.set(section.id.toString(), value);
+ });
+
+ return sectionToFieldsMap;
+ }
+
refreshData(): void {
this.getItem(this.editorModel.id, (data: Dmp) => this.prepareForm(data));
}
@@ -365,6 +381,26 @@ export class DmpEditorComponent extends BaseEditor implemen
this.resetScroll();
}
+ hasErrors(sectionId: string): boolean {
+ const formControlBySection = this.sectionToFieldsMap?.get(sectionId);
+ if (formControlBySection == null || this.formGroup == null) return false;
+
+ for (let controlName of formControlBySection.fieldControlNames) {
+ if (this.isFormControlValid(controlName) === false ) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ isFormControlValid(controlName: string): boolean {
+ if (!this.formGroup?.get(controlName)) return true;
+ if (!this.formGroup.get(controlName).touched) return true;
+
+ return this.formGroup.get(controlName).valid;
+ }
+
private resetScroll() {
if (document.getElementById('editor-form') != null) document.getElementById('editor-form').scrollTop = 0;
}
diff --git a/dmp-frontend/src/app/ui/dmp/dmp-editor-blueprint/dmp-editor.model.ts b/dmp-frontend/src/app/ui/dmp/dmp-editor-blueprint/dmp-editor.model.ts
index acf2a226e..7035e0a32 100644
--- a/dmp-frontend/src/app/ui/dmp/dmp-editor-blueprint/dmp-editor.model.ts
+++ b/dmp-frontend/src/app/ui/dmp/dmp-editor-blueprint/dmp-editor.model.ts
@@ -1,12 +1,13 @@
import { FormArray, FormControl, UntypedFormBuilder, UntypedFormGroup, Validators } from "@angular/forms";
import { DmpAccessType } from "@app/core/common/enum/dmp-access-type";
import { DmpBlueprintFieldCategory } from "@app/core/common/enum/dmp-blueprint-field-category";
+import { DmpBlueprintSystemFieldType } from "@app/core/common/enum/dmp-blueprint-system-field-type";
import { DmpContactType } from "@app/core/common/enum/dmp-contact-type";
import { DmpStatus } from "@app/core/common/enum/dmp-status";
import { DmpUserRole } from "@app/core/common/enum/dmp-user-role";
import { DmpUserType } from "@app/core/common/enum/dmp-user-type";
import { IsActive } from "@app/core/common/enum/is-active.enum";
-import { DmpBlueprint, FieldInSection, ReferenceTypeFieldInSection } from "@app/core/model/dmp-blueprint/dmp-blueprint";
+import { DmpBlueprint, DmpBlueprintDefinitionSection, ExtraFieldInSection, FieldInSection, ReferenceTypeFieldInSection, SystemFieldInSection } from "@app/core/model/dmp-blueprint/dmp-blueprint";
import { Dmp, DmpBlueprintValue, DmpBlueprintValuePersist, DmpContact, DmpContactPersist, DmpDescriptionTemplate, DmpDescriptionTemplatePersist, DmpPersist, DmpProperties, DmpPropertiesPersist, DmpReferenceDataPersist, DmpReferencePersist, DmpUser, DmpUserPersist } from "@app/core/model/dmp/dmp";
import { DmpReference } from "@app/core/model/dmp/dmp-reference";
import { ReferencePersist } from "@app/core/model/reference/reference";
@@ -731,3 +732,69 @@ export class DmpDescriptionTemplateEditorModel implements DmpDescriptionTemplate
})
}
}
+
+export class DmpFieldIndicator {
+
+ private _fieldControlNames;
+
+ get fieldControlNames(): string[] {
+ return this._fieldControlNames;
+ }
+
+ constructor(section: DmpBlueprintDefinitionSection) {
+ this._fieldControlNames = [];
+
+ if (section.hasTemplates) {
+ this._fieldControlNames.push(`descriptionTemplates.${section.id}`);
+ } else {
+ section.fields.forEach((field: FieldInSection) => {
+ switch (field.category) {
+ case DmpBlueprintFieldCategory.System:
+ this.buildSystemField(field as SystemFieldInSection);
+ break;
+ case DmpBlueprintFieldCategory.ReferenceType:
+ this.buildReferenceTypeField(field as ReferenceTypeFieldInSection);
+ break;
+ case DmpBlueprintFieldCategory.Extra:
+ this.buildExtraField(field as ExtraFieldInSection);
+ break;
+ }
+ });
+ }
+ }
+
+ buildSystemField(field: SystemFieldInSection): void {
+ switch (field.systemFieldType) {
+ case DmpBlueprintSystemFieldType.Title:
+ this._fieldControlNames.push("label");
+ break;
+ case DmpBlueprintSystemFieldType.Description:
+ this._fieldControlNames.push("description");
+ break;
+ case DmpBlueprintSystemFieldType.Language:
+ this._fieldControlNames.push("language");
+ break;
+ case DmpBlueprintSystemFieldType.Contact:
+ this._fieldControlNames.push("properties.contacts");
+ break;
+ case DmpBlueprintSystemFieldType.AccessRights:
+ this._fieldControlNames.push("accessType");
+ break;
+ case DmpBlueprintSystemFieldType.User:
+ this._fieldControlNames.push("users");
+ break;
+ }
+ }
+
+ buildReferenceTypeField(field: ReferenceTypeFieldInSection): void {
+ if (field.multipleSelect) {
+ this._fieldControlNames.push(`properties.dmpBlueprintValues.${field.id}.references`);
+ } else {
+ this._fieldControlNames.push(`properties.dmpBlueprintValues.${field.id}.reference`);
+ }
+ }
+
+ buildExtraField(field: ExtraFieldInSection): void {
+ this._fieldControlNames.push(`properties.dmpBlueprintValues.${field.id}.fieldValue`);
+ }
+}