diff --git a/dmp-frontend/src/app/ui/admin/prefilling-source/editor/prefilling-source-editor.component.scss b/dmp-frontend/src/app/ui/admin/prefilling-source/editor/prefilling-source-editor.component.scss
index df9e3a45f..74d11d8d1 100644
--- a/dmp-frontend/src/app/ui/admin/prefilling-source/editor/prefilling-source-editor.component.scss
+++ b/dmp-frontend/src/app/ui/admin/prefilling-source/editor/prefilling-source-editor.component.scss
@@ -40,4 +40,10 @@
color: #FFF;
border: 0px;
}
-}
\ No newline at end of file
+}
+
+::ng-deep .mdc-form-field {
+ label {
+ margin: 0;
+ }
+}
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 f6b272edd..0a57f409e 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
@@ -93,7 +93,7 @@
0. {{'DESCRIPTION-EDITOR.TOC.MAIN-INFO' | translate}} (done)
-
0" [propertiesFormGroup]="formGroup.get('properties')" [descriptionTemplate]="item.descriptionTemplate" *ngIf="formGroup" [links]="links" [boundary]="boundary" [spacer]="spacer" [isActive]="step !== 0" stickyThing (stepFound)="onStepFound($event)" (currentLinks)="getLinks($event)" (entrySelected)="changeStep($event.entry, $event.execute)">
+
0" [formGroup]="formGroup.get('properties')" [descriptionTemplate]="item.descriptionTemplate" *ngIf="formGroup" [links]="links" [boundary]="boundary" [spacer]="spacer" [isActive]="step !== 0" stickyThing (stepFound)="onStepFound($event)" (currentLinks)="getLinks($event)" (entrySelected)="changeStep($event.entry, $event.execute)" [pageToFieldSetMap]="pageToFieldSetMap">
diff --git a/dmp-frontend/src/app/ui/description/editor/description-editor.component.ts b/dmp-frontend/src/app/ui/description/editor/description-editor.component.ts
index 8b2e8b501..00270acaa 100644
--- a/dmp-frontend/src/app/ui/description/editor/description-editor.component.ts
+++ b/dmp-frontend/src/app/ui/description/editor/description-editor.component.ts
@@ -6,7 +6,7 @@ import { DescriptionStatus } from '@app/core/common/enum/description-status';
import { DmpStatus } from '@app/core/common/enum/dmp-status';
import { IsActive } from '@app/core/common/enum/is-active.enum';
import { AppPermission } from '@app/core/common/enum/permission.enum';
-import { Description, DescriptionPersist, DescriptionSectionPermissionResolver, DescriptionStatusPersist } from '@app/core/model/description/description';
+import { Description, DescriptionPersist, DescriptionPropertyDefinitionFieldSet, DescriptionSectionPermissionResolver, DescriptionStatusPersist } from '@app/core/model/description/description';
import { AuthService } from '@app/core/services/auth/auth.service';
import { DescriptionTemplateService } from '@app/core/services/description-template/description-template.service';
import { DescriptionService } from '@app/core/services/description/description.service';
@@ -32,7 +32,7 @@ import { FilterService } from '@common/modules/text-filter/filter-service';
import { Guid } from '@common/types/guid';
import { TranslateService } from '@ngx-translate/core';
import { map, takeUntil } from 'rxjs/operators';
-import { DescriptionEditorModel, DescriptionPropertyDefinitionEditorModel } from './description-editor.model';
+import { DescriptionEditorModel, DescriptionFieldIndicator, DescriptionPropertyDefinitionEditorModel } from './description-editor.model';
import { DescriptionEditorResolver } from './description-editor.resolver';
import { DescriptionEditorService } from './description-editor.service';
import { PrefillDescriptionDialogComponent } from './prefill-description/prefill-description.component';
@@ -44,8 +44,11 @@ import { ConfigurationService } from '@app/core/services/configuration/configura
import { LockTargetType } from '@app/core/common/enum/lock-target-type';
import { FileTransformerService } from '@app/core/services/file-transformer/file-transformer.service';
import { DmpBlueprintDefinitionSection } from '@app/core/model/dmp-blueprint/dmp-blueprint';
-import { DescriptionTemplate } from '@app/core/model/description-template/description-template';
+import { DescriptionTemplate, DescriptionTemplateField, DescriptionTemplateFieldSet, DescriptionTemplatePage, DescriptionTemplateSection } from '@app/core/model/description-template/description-template';
import { DmpDescriptionTemplate } from '@app/core/model/dmp/dmp';
+import { BehaviorSubject } from 'rxjs';
+import { UUID } from 'crypto';
+import { AbstractControl } from '@angular/forms';
@Component({
selector: 'app-description-editor-component',
@@ -67,6 +70,7 @@ export class DescriptionEditorComponent extends BaseEditor = new Map();
constructor(
// BaseFormEditor injected dependencies
@@ -205,8 +209,8 @@ export class DescriptionEditorComponent extends BaseEditor x.sectionId == sectionId && x.descriptionTemplateGroupId == result.descriptionTemplate.groupId);
-
this.prepareForm(result);
+
// this.descriptionModel = this.descriptionModel.fromModel(result);
// this.descriptionModel.dmp = data;
// this.descriptionModel.dmpSectionIndex = this.dmpSectionIndex;
@@ -848,6 +852,10 @@ export class DescriptionEditorComponent extends BaseEditor {
+ const pageToFieldSetMap = new Map();
+
+ descriptionTemplate.definition.pages?.forEach((page: DescriptionTemplatePage) => {
+ page.sections?.forEach((section: DescriptionTemplateSection) => {
+ const fieldsets = this.getFieldsetsFromSection(section);
+ const value = fieldsets?.flatMap((fieldset: DescriptionTemplateFieldSet) =>
+ fieldset.fields?.flatMap((field: DescriptionTemplateField) =>
+ new DescriptionFieldIndicator(page.id, section.id, fieldset.id, field.id, field.data.fieldType, field.data.multipleSelect)
+ // 'properties.fieldSets.' + fieldset.id + '.items.0.fields.' + field.id// + '.textValue'
+ ));
+ pageToFieldSetMap.set(page.id,
+ value
+ );
+ });
+ });
+
+ return pageToFieldSetMap;
+ }
+
+ getFieldsetsFromSection(section: DescriptionTemplateSection): DescriptionTemplateFieldSet[] {
+ if (section.sections) {
+ return section.sections.flatMap((subsection: DescriptionTemplateSection) => this.getFieldsetsFromSection(subsection));
+ }
+
+ else return section.fieldSets;
+ }
+
// // this._listenersSubscription.add(dmpSubscription);
// // this._listenersSubscription.add(profileSubscription);
// // this._listenersSubscription.add(labelSubscription);
diff --git a/dmp-frontend/src/app/ui/description/editor/description-editor.model.ts b/dmp-frontend/src/app/ui/description/editor/description-editor.model.ts
index 4f70e929b..cf75a00f5 100644
--- a/dmp-frontend/src/app/ui/description/editor/description-editor.model.ts
+++ b/dmp-frontend/src/app/ui/description/editor/description-editor.model.ts
@@ -1,5 +1,6 @@
import { FormControl, UntypedFormArray, UntypedFormBuilder, UntypedFormGroup, Validators } from "@angular/forms";
import { DescriptionStatus } from "@app/core/common/enum/description-status";
+import { DescriptionTemplateFieldType } from "@app/core/common/enum/description-template-field-type";
import { IsActive } from "@app/core/common/enum/is-active.enum";
import { DescriptionTemplate, DescriptionTemplateField, DescriptionTemplateFieldSet, DescriptionTemplateSection } from "@app/core/model/description-template/description-template";
import { Description, DescriptionExternalIdentifier, DescriptionExternalIdentifierPersist, DescriptionField, DescriptionFieldPersist, DescriptionPersist, DescriptionPropertyDefinition, DescriptionPropertyDefinitionFieldSet, DescriptionPropertyDefinitionFieldSetItem, DescriptionPropertyDefinitionFieldSetItemPersist, DescriptionPropertyDefinitionFieldSetPersist, DescriptionPropertyDefinitionPersist, DescriptionReference, DescriptionReferencePersist } from "@app/core/model/description/description";
@@ -671,4 +672,60 @@ export class DescriptionReferenceEditorModel implements DescriptionReferencePers
control?.addValidators(context.getValidation(keyField).validators);
});
}
-}
\ No newline at end of file
+}
+
+export class DescriptionFieldIndicator {
+ pageId: string;
+ sectionId: string;
+ fieldSetId: string;
+ fieldId: string;
+ type: string;
+
+ constructor(pageId: string, sectionId: string, fieldSetId: string, fieldId: string, type: DescriptionTemplateFieldType, multipleSelect: boolean = false) {
+ this.pageId = pageId;
+ this.sectionId = sectionId;
+ this.fieldSetId = fieldSetId;
+ this.fieldId = fieldId;
+
+ switch (type) {
+ case DescriptionTemplateFieldType.FREE_TEXT:
+ case DescriptionTemplateFieldType.BOOLEAN_DECISION:
+ case DescriptionTemplateFieldType.CHECK_BOX:
+ case DescriptionTemplateFieldType.RADIO_BOX:
+ case DescriptionTemplateFieldType.TEXT_AREA:
+ case DescriptionTemplateFieldType.UPLOAD:
+ case DescriptionTemplateFieldType.RICH_TEXT_AREA:
+ this.type = "textValue";
+ break;
+ case DescriptionTemplateFieldType.DATASET_IDENTIFIER:
+ case DescriptionTemplateFieldType.VALIDATION:
+ this.type = "externalIdentifier";
+ break;
+ case DescriptionTemplateFieldType.DATE_PICKER:
+ this.type = "dateValue";
+ break;
+ case DescriptionTemplateFieldType.EXTERNAL_DATASETS:
+ this.type = "";
+ break;
+ case DescriptionTemplateFieldType.INTERNAL_ENTRIES_DESCRIPTIONS:
+ if (multipleSelect) this.type = "textListValue";
+ else this.type = "textValue"
+ break;
+ case DescriptionTemplateFieldType.INTERNAL_ENTRIES_DMPS:
+ if (multipleSelect) this.type = "textListValue";
+ else this.type = "textValue";
+ break;
+ case DescriptionTemplateFieldType.REFERENCE_TYPES:
+ if (multipleSelect) this.type = "references";
+ else this.type = "reference";
+ break;
+ case DescriptionTemplateFieldType.SELECT:
+ if (multipleSelect) this.type = "textListValue";
+ else this.type = "textValue";
+ break;
+ case DescriptionTemplateFieldType.TAGS:
+ this.type = "textListValue";
+ break;
+ }
+ }
+}
diff --git a/dmp-frontend/src/app/ui/description/editor/table-of-contents/table-of-contents-internal/table-of-contents-internal.html b/dmp-frontend/src/app/ui/description/editor/table-of-contents/table-of-contents-internal/table-of-contents-internal.html
index 8653b61f4..d5a3845c7 100644
--- a/dmp-frontend/src/app/ui/description/editor/table-of-contents/table-of-contents-internal/table-of-contents-internal.html
+++ b/dmp-frontend/src/app/ui/description/editor/table-of-contents/table-of-contents-internal/table-of-contents-internal.html
@@ -39,6 +39,9 @@
[showErrors]="showErrors"
[hiddenEntries]="hiddenEntries"
[visibilityRulesService]="visibilityRulesService"
+ [propertiesFormGroup]="propertiesFormGroup"
+ [parentId]="entry.id"
+ [parentMap]="updatedMap"
>
diff --git a/dmp-frontend/src/app/ui/description/editor/table-of-contents/table-of-contents-internal/table-of-contents-internal.scss b/dmp-frontend/src/app/ui/description/editor/table-of-contents/table-of-contents-internal/table-of-contents-internal.scss
index 91152786d..c9978f6a4 100644
--- a/dmp-frontend/src/app/ui/description/editor/table-of-contents/table-of-contents-internal/table-of-contents-internal.scss
+++ b/dmp-frontend/src/app/ui/description/editor/table-of-contents/table-of-contents-internal/table-of-contents-internal.scss
@@ -22,8 +22,9 @@
background-color: #ececec;
border-radius: 6px;
}
+
.selected {
- color: #212121 !important;
+ color: #212121;
font-weight: 700 !important;
opacity: 1 !important;
}
diff --git a/dmp-frontend/src/app/ui/description/editor/table-of-contents/table-of-contents-internal/table-of-contents-internal.ts b/dmp-frontend/src/app/ui/description/editor/table-of-contents/table-of-contents-internal/table-of-contents-internal.ts
index 5547ecfa2..4bc9f3c62 100644
--- a/dmp-frontend/src/app/ui/description/editor/table-of-contents/table-of-contents-internal/table-of-contents-internal.ts
+++ b/dmp-frontend/src/app/ui/description/editor/table-of-contents/table-of-contents-internal/table-of-contents-internal.ts
@@ -4,6 +4,7 @@ import { VisibilityRulesService } from '@app/ui/description/editor/description-f
import { Guid } from '@common/types/guid';
import { ToCEntry } from '../models/toc-entry';
import { ToCEntryType } from '../models/toc-entry-type.enum';
+import { DescriptionFieldIndicator } from '../../description-editor.model';
@Component({
selector: 'table-of-contents-internal',
@@ -26,6 +27,10 @@ export class TableOfContentsInternal implements OnInit {
@Input() visibilityRulesService: VisibilityRulesService;
@ViewChildren(TableOfContentsInternal) internalTables: QueryList;
+ @Input() parentId: string;
+ @Input() parentMap: Map = new Map();
+ @Input() updatedMap: Map = new Map();
+
constructor() {
}
ngOnInit(): void {
@@ -42,6 +47,11 @@ export class TableOfContentsInternal implements OnInit {
}
}
}
+
+ if (this.parentMap) {
+ this.updatedMap = this.updateMap(this.tocentries, this.parentMap);
+ console.log(this.updatedMap);
+ }
}
}
@@ -64,6 +74,47 @@ export class TableOfContentsInternal implements OnInit {
// }
}
+ updateMap(entries: ToCEntry[], parentMap:Map): Map {
+ if (this.parentId == null) return parentMap;
+
+ let updatedMap = new Map();
+
+ parentMap.forEach((fields: DescriptionFieldIndicator[], parentId: string) => {
+ if (this.parentId === parentId) {
+ for (let entry of entries) {
+ let entryFields = fields.filter((field: DescriptionFieldIndicator) => field.sectionId === entry.id || field.fieldSetId === entry.id || field.fieldId === entry.id )
+
+ updatedMap.set(entry.id, entryFields);
+ }
+ }
+ });
+
+ return updatedMap;
+ }
+
+ hasErrors(entryId: string): boolean {
+ if (this.updatedMap.size == 0) return true;
+
+ const fields: DescriptionFieldIndicator[] = this.updatedMap.get(entryId);
+
+ for (let field of fields) {
+ let formFieldName: string = `fieldSets.${field.fieldSetId}.items.0.fields.${field.fieldId}.${field.type}`;
+ if (this.isFormFieldValid(formFieldName) === false) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ isFormFieldValid(formFildName: string):boolean {
+ if (this.propertiesFormGroup?.get(formFildName) == null) return true;
+
+ if (this.propertiesFormGroup.get(formFildName).touched === false) return true;
+
+ return this.propertiesFormGroup.get(formFildName).valid;
+ }
+
toggleExpand(index) {
this.expandChildren[index] = !this.expandChildren[index];
// console.log(this.expandChildren);
@@ -113,6 +164,9 @@ export class TableOfContentsInternal implements OnInit {
myClass['section'] = true;
}
+ if(this.hasErrors(entry.id)) {
+ myClass['text-danger'] = true;
+ }
return myClass;
}
diff --git a/dmp-frontend/src/app/ui/description/editor/table-of-contents/table-of-contents.component.html b/dmp-frontend/src/app/ui/description/editor/table-of-contents/table-of-contents.component.html
index 2fb7f2929..62de7a1cb 100644
--- a/dmp-frontend/src/app/ui/description/editor/table-of-contents/table-of-contents.component.html
+++ b/dmp-frontend/src/app/ui/description/editor/table-of-contents/table-of-contents.component.html
@@ -15,7 +15,8 @@
[selected]="tocentrySelected"
[hiddenEntries]="hiddenEntries"
[visibilityRulesService]="visibilityRulesService"
- [propertiesFormGroup]="propertiesFormGroup"
+ [propertiesFormGroup]="formGroup"
+ [parentMap]="pageToFieldSetMap"
>
diff --git a/dmp-frontend/src/app/ui/description/editor/table-of-contents/table-of-contents.component.ts b/dmp-frontend/src/app/ui/description/editor/table-of-contents/table-of-contents.component.ts
index adbcae0ae..a88095d80 100644
--- a/dmp-frontend/src/app/ui/description/editor/table-of-contents/table-of-contents.component.ts
+++ b/dmp-frontend/src/app/ui/description/editor/table-of-contents/table-of-contents.component.ts
@@ -9,6 +9,7 @@ import { debounceTime, distinctUntilChanged, takeUntil } from 'rxjs/operators';
import { ToCEntry } from './models/toc-entry';
import { ToCEntryType } from './models/toc-entry-type.enum';
import { TableOfContentsInternal } from './table-of-contents-internal/table-of-contents-internal';
+import { DescriptionFieldIndicator } from '../description-editor.model';
export interface Link {
/* id of the section*/
@@ -65,12 +66,14 @@ export class TableOfContentsComponent extends BaseComponent implements OnInit, O
this._tocentrySelected = value;
}
- @Input() propertiesFormGroup: UntypedFormGroup;
+ @Input() formGroup: UntypedFormGroup;
@Input() descriptionTemplate: DescriptionTemplate;
@Input() hasFocus: boolean = false;
@Input() visibilityRulesService: VisibilityRulesService;
show: boolean = false;
+ @Input() pageToFieldSetMap: Map;
+
constructor(
@Inject(DOCUMENT) private _document: Document,
// public visibilityRulesService: VisibilityRulesService