From acc754823fb6e0332c3d008c7ec17bd6563929f4 Mon Sep 17 00:00:00 2001 From: Diamantis Tziotzios Date: Fri, 2 Feb 2024 10:29:38 +0200 Subject: [PATCH] description editor frontend changes --- .../app/core/model/description/description.ts | 52 ++-- .../description-template-editor.resolver.ts | 1 - ...escription-base-fields-editor.component.ts | 4 +- .../editor/description-editor.component.html | 5 +- .../editor/description-editor.component.ts | 129 ++++++---- .../editor/description-editor.model.ts | 243 +++++++++++++++--- .../editor/description-editor.resolver.ts | 88 +++++-- .../editor/description-editor.routing.ts | 27 +- .../form-field-set.component.html | 4 +- .../form-field/form-field.component.html | 174 ++++++------- .../form-field/form-field.component.ts | 91 +++---- .../form-section/form-section.component.html | 2 +- .../form-section/form-section.component.ts | 14 +- .../table-of-contents.component.ts | 6 + .../dmp-editor.component.html | 4 +- 15 files changed, 553 insertions(+), 291 deletions(-) diff --git a/dmp-frontend/src/app/core/model/description/description.ts b/dmp-frontend/src/app/core/model/description/description.ts index 1dc6a8b6f..03db906ec 100644 --- a/dmp-frontend/src/app/core/model/description/description.ts +++ b/dmp-frontend/src/app/core/model/description/description.ts @@ -8,28 +8,37 @@ import { Tag } from "../tag/tag"; import { User } from "../user/user"; export interface Description extends BaseEntity { - label: string; - properties: PropertyDefinition; - status: DescriptionStatus; + label?: string; + properties?: DescriptionPropertyDefinition; + status?: DescriptionStatus; description?: string; - createdBy: User; - finalizedAt: Date; - descriptionReferences: DescriptionReference[]; - descriptionTags: DescriptionTag[]; - descriptionTemplate: DescriptionTemplate; - dmpDescriptionTemplate: DmpDescriptionTemplate; - dmp: Dmp; + createdBy?: User; + finalizedAt?: Date; + descriptionReferences?: DescriptionReference[]; + descriptionTags?: DescriptionTag[]; + descriptionTemplate?: DescriptionTemplate; + dmpDescriptionTemplate?: DmpDescriptionTemplate; + dmp?: Dmp; } export interface PublicDescription extends BaseEntity { } -export interface PropertyDefinition { - fields?: DescriptionField[]; +export interface DescriptionPropertyDefinition { + fieldSets: Map; +} + +export interface DescriptionPropertyDefinitionFieldSet { + items?: DescriptionPropertyDefinitionFieldSetItem[]; +} + +export interface DescriptionPropertyDefinitionFieldSetItem { + fields?: Map; + comment?: string; + ordinal?: number; } export interface DescriptionField { - key?: string; value: string; } @@ -53,17 +62,26 @@ export interface DescriptionPersist extends BaseEntityPersist { descriptionTemplateId: Guid; status: DescriptionStatus; description: string; - properties: PropertyDefinitionPersist; + properties: DescriptionPropertyDefinitionPersist; tags: string[]; references: DescriptionReferencePersist[]; } -export interface PropertyDefinitionPersist { - fields: DescriptionFieldPersist[]; +export interface DescriptionPropertyDefinitionPersist { + fieldSets: Map; +} + +export interface DescriptionPropertyDefinitionFieldSetPersist { + items?: DescriptionPropertyDefinitionFieldSetItemPersist[]; +} + +export interface DescriptionPropertyDefinitionFieldSetItemPersist { + fields?: Map; + comment?: string; + ordinal?: number; } export interface DescriptionFieldPersist { - key?: string; value: string; } diff --git a/dmp-frontend/src/app/ui/admin/description-template/editor/description-template-editor.resolver.ts b/dmp-frontend/src/app/ui/admin/description-template/editor/description-template-editor.resolver.ts index 16711c2ae..3914bdda2 100644 --- a/dmp-frontend/src/app/ui/admin/description-template/editor/description-template-editor.resolver.ts +++ b/dmp-frontend/src/app/ui/admin/description-template/editor/description-template-editor.resolver.ts @@ -59,7 +59,6 @@ export class DescriptionTemplateEditorResolver extends BaseEditorResolver { [nameof(x => x.definition), nameof(x => x.pages), nameof(x => x.sections), nameof(x => x.fieldSets), nameof(x => x.fields), nameof(x => x.numbering)].join('.'), [nameof(x => x.definition), nameof(x => x.pages), nameof(x => x.sections), nameof(x => x.fieldSets), nameof(x => x.fields), nameof(x => x.schematics)].join('.'), [nameof(x => x.definition), nameof(x => x.pages), nameof(x => x.sections), nameof(x => x.fieldSets), nameof(x => x.fields), nameof(x => x.defaultValue)].join('.'), - [nameof(x => x.definition), nameof(x => x.pages), nameof(x => x.sections), nameof(x => x.fieldSets), nameof(x => x.fields), nameof(x => x.defaultValue)].join('.'), // [nameof(x => x.definition), nameof(x => x.sections), nameof(x => x.fieldSets), nameof(x => x.fields), nameof(x => x.fieldType)].join('.'), [nameof(x => x.definition), nameof(x => x.pages), nameof(x => x.sections), nameof(x => x.fieldSets), nameof(x => x.fields), nameof(x => x.includeInExport)].join('.'), [nameof(x => x.definition), nameof(x => x.pages), nameof(x => x.sections), nameof(x => x.fieldSets), nameof(x => x.fields), nameof(x => x.validations)].join('.'), diff --git a/dmp-frontend/src/app/ui/description/editor/description-base-fields-editor/description-base-fields-editor.component.ts b/dmp-frontend/src/app/ui/description/editor/description-base-fields-editor/description-base-fields-editor.component.ts index f1c56520a..688135832 100644 --- a/dmp-frontend/src/app/ui/description/editor/description-base-fields-editor/description-base-fields-editor.component.ts +++ b/dmp-frontend/src/app/ui/description/editor/description-base-fields-editor/description-base-fields-editor.component.ts @@ -26,10 +26,10 @@ export class DescriptionBaseFieldsEditorComponent extends BaseComponent { ) { super(); } ngOnInit() { - const dmpDescriptionTemplates: DmpDescriptionTemplate[] = this.description.dmp.dmpDescriptionTemplates.filter(x => x.sectionId === this.description.dmpDescriptionTemplate.sectionId); + const dmpDescriptionTemplates: DmpDescriptionTemplate[] = this.description.dmp.dmpDescriptionTemplates.filter(x => x.sectionId == this.description.dmpDescriptionTemplate.sectionId); const currentVersionsOfDescriptionTemplates = dmpDescriptionTemplates.map(x => x.currentDescriptionTemplate); //Check if the used tempalte in included in the current list. If not add it. - if (currentVersionsOfDescriptionTemplates.find(x => x.id === this.description.descriptionTemplate.id) == null) { + if (currentVersionsOfDescriptionTemplates.find(x => x.id == this.description?.descriptionTemplate?.id) != null) { this.availableDescriptionTemplates.push(this.description.descriptionTemplate) } this.availableDescriptionTemplates.push(...currentVersionsOfDescriptionTemplates); 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 f50349bc3..d5d8aac67 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 @@ -15,9 +15,9 @@
{{'DESCRIPTION-EDITOR.TITLE-PREVIEW-DESCRIPTION' | translate}}
-
+
{{'DESCRIPTION-EDITOR.TO-DMP' | translate}}
-
: {{ item.dmp.label }}
+
: {{ item?.dmp?.label }}
+ {{formGroup?.value | json}}
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 fdbb79efd..3359d4881 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 @@ -33,13 +33,15 @@ 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 } from './description-editor.model'; +import { DescriptionEditorModel, DescriptionPropertyDefinitionEditorModel } from './description-editor.model'; import { DescriptionEditorResolver } from './description-editor.resolver'; import { DescriptionEditorService } from './description-editor.service'; import { ToCEntry } from './table-of-contents/models/toc-entry'; import { TableOfContentsComponent } from './table-of-contents/table-of-contents.component'; import { ToCEntryType } from './table-of-contents/models/toc-entry-type.enum'; import { DmpService } from '@app/core/services/dmp/dmp.service'; +import { DescriptionTemplateSection } from '@app/core/model/description-template/description-template'; +import { DescriptionTemplateService } from '@app/core/services/description-template/description-template.service'; @Component({ selector: 'app-description-editor-component', @@ -112,6 +114,7 @@ export class DescriptionEditorComponent extends BaseEditor { @@ -561,13 +569,15 @@ export class DescriptionEditorComponent extends BaseEditor { - // this.dmpValueChanged(x); - // }); - // // const profileSubscription = - // this.formGroup.get('profile').valueChanges - // .pipe(takeUntil(this._destroyed)) - // .subscribe(x => { - // if (x) { - // this.showtocentriesErrors = false; - // this.descriptionProfileValueChanged(x.id); - // this.formChanged(); - // } - // }); - // // const labelSubscription = - // this.formGroup.get('label').valueChanges - // .pipe(takeUntil(this._destroyed)) - // .subscribe(x => { - // this.formChanged(); - // }); - // // const descriptionSubscription = - // this.formGroup.get('description').valueChanges - // .pipe(takeUntil(this._destroyed)) - // .subscribe(x => { - // this.formChanged(); - // }); - // // const uriSubscription = - // this.formGroup.get('uri').valueChanges - // .pipe(takeUntil(this._destroyed)) - // .subscribe(x => { - // this.formChanged(); - // }); - // // const tagsSubscription = - // this.formGroup.get('tags').valueChanges - // .pipe(takeUntil(this._destroyed)) - // .subscribe(x => { - // this.formChanged(); - // }); - // if (this.formGroup.get('descriptionProfileDefinition')) { - // // const descriptionProfileDefinitionSubscription = - // this.formGroup.get('descriptionProfileDefinition').valueChanges - // .pipe(takeUntil(this._destroyed)) - // .subscribe(x => { - // this.formChanged(); - // }); - // // this._listenersSubscription.add(descriptionProfileDefinitionSubscription); - // } + registerFormListeners() { + // // const dmpSubscription = + // this.formGroup.get('dmp').valueChanges + // .pipe(takeUntil(this._destroyed)) + // .subscribe(x => { + // this.dmpValueChanged(x); + // }); + // // const profileSubscription = + this.formGroup.get('descriptionTemplateId').valueChanges + .pipe(takeUntil(this._destroyed)) + .subscribe(descriptionTemplateId => { + if (descriptionTemplateId) { + // this.showtocentriesErrors = false; + this.descriptionTemplateValueChanged(descriptionTemplateId); + // this.formChanged(); + } + }); + // // const labelSubscription = + // this.formGroup.get('label').valueChanges + // .pipe(takeUntil(this._destroyed)) + // .subscribe(x => { + // this.formChanged(); + // }); + // // const descriptionSubscription = + // this.formGroup.get('description').valueChanges + // .pipe(takeUntil(this._destroyed)) + // .subscribe(x => { + // this.formChanged(); + // }); + // // const uriSubscription = + // this.formGroup.get('uri').valueChanges + // .pipe(takeUntil(this._destroyed)) + // .subscribe(x => { + // this.formChanged(); + // }); + // // const tagsSubscription = + // this.formGroup.get('tags').valueChanges + // .pipe(takeUntil(this._destroyed)) + // .subscribe(x => { + // this.formChanged(); + // }); + // if (this.formGroup.get('descriptionProfileDefinition')) { + // // const descriptionProfileDefinitionSubscription = + // this.formGroup.get('descriptionProfileDefinition').valueChanges + // .pipe(takeUntil(this._destroyed)) + // .subscribe(x => { + // this.formChanged(); + // }); + // // this._listenersSubscription.add(descriptionProfileDefinitionSubscription); + } + + descriptionTemplateValueChanged(descriptionTemplateId: Guid) { + if (descriptionTemplateId != null) { + + this.descriptionTemplateService.getSingle(descriptionTemplateId, DescriptionEditorResolver.descriptionTemplateLookupFields()).pipe(takeUntil(this._destroyed)).subscribe(descriptionTemplate => { + + this.editorModel.properties = new DescriptionPropertyDefinitionEditorModel().fromModel(null, descriptionTemplate); + this.formGroup.removeControl('properties'); + this.formGroup.addControl('properties', this.editorModel.buildProperties()); + this.item.descriptionTemplate = descriptionTemplate; + }); + // this.formGroup.removeControl('descriptionProfileDefinition'); + // this.getDefinition(profiledId); + } + } // // this._listenersSubscription.add(dmpSubscription); // // this._listenersSubscription.add(profileSubscription); 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 93b90925c..d18e1c0ea 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,7 +1,7 @@ -import { UntypedFormBuilder, UntypedFormGroup, Validators } from "@angular/forms"; +import { FormControl, UntypedFormBuilder, UntypedFormGroup, Validators } from "@angular/forms"; import { DescriptionStatus } from "@app/core/common/enum/description-status"; -import { DescriptionTemplate } from "@app/core/model/description-template/description-template"; -import { Description, DescriptionField, DescriptionFieldPersist, DescriptionPersist, DescriptionReference, DescriptionReferencePersist, PropertyDefinition, PropertyDefinitionPersist } from "@app/core/model/description/description"; +import { DescriptionTemplate, DescriptionTemplateFieldSet, DescriptionTemplateSection } from "@app/core/model/description-template/description-template"; +import { Description, DescriptionField, DescriptionFieldPersist, DescriptionPersist, DescriptionPropertyDefinition, DescriptionPropertyDefinitionFieldSet, DescriptionPropertyDefinitionFieldSetItem, DescriptionPropertyDefinitionFieldSetItemPersist, DescriptionPropertyDefinitionFieldSetPersist, DescriptionPropertyDefinitionPersist, DescriptionReference, DescriptionReferencePersist } from "@app/core/model/description/description"; import { ReferencePersist } from "@app/core/model/reference/reference"; import { BaseEditorModel } from "@common/base/base-form-editor-model"; import { BackendErrorValidator } from '@common/forms/validation/custom-validator'; @@ -36,7 +36,7 @@ export class DescriptionEditorModel extends BaseEditorModel implements Descripti this.status = item.status; this.description = item.description; this.tags = item.descriptionTags?.map(x => x.tag?.label); - this.properties = new DescriptionPropertyDefinitionEditorModel().fromModel(item.properties); + this.properties = new DescriptionPropertyDefinitionEditorModel().fromModel(item.properties, descriptionTemplate); //if (item.references) { item.references.map(x => this.references.push(new DescriptionReferenceEditorModel().fromModel(x))); } } return this; @@ -54,13 +54,17 @@ export class DescriptionEditorModel extends BaseEditorModel implements Descripti status: [{ value: this.status, disabled: disabled }, context.getValidation('status').validators], description: [{ value: this.description, disabled: disabled }, context.getValidation('description').validators], tags: [{ value: this.tags, disabled: disabled }, context.getValidation('tags').validators], - properties: this.properties.buildForm({ - rootPath: `properties.` - }), + properties: this.buildProperties(), hash: [{ value: this.hash, disabled: disabled }, context.getValidation('hash').validators] }); } + buildProperties() { + return this.properties.buildForm({ + rootPath: `properties.` + }); + } + createValidationContext(): ValidationContext { const baseContext: ValidationContext = new ValidationContext(); const baseValidationArray: Validation[] = new Array(); @@ -79,18 +83,16 @@ export class DescriptionEditorModel extends BaseEditorModel implements Descripti } } -export class DescriptionPropertyDefinitionEditorModel implements PropertyDefinitionPersist { - fields: DescriptionFieldEditorModel[] = []; +export class DescriptionPropertyDefinitionEditorModel implements DescriptionPropertyDefinitionPersist { + fieldSets: Map = new Map; protected formBuilder: UntypedFormBuilder = new UntypedFormBuilder(); constructor( public validationErrorModel: ValidationErrorModel = new ValidationErrorModel() ) { } - public fromModel(item: PropertyDefinition): DescriptionPropertyDefinitionEditorModel { - if (item) { - if (item.fields) { item.fields.map(x => this.fields.push(new DescriptionFieldEditorModel().fromModel(x))); } - } + public fromModel(item: DescriptionPropertyDefinition, descriptionTemplate: DescriptionTemplate): DescriptionPropertyDefinitionEditorModel { + this.fieldSets = this.calculateProperties(item, descriptionTemplate); return this; } @@ -107,27 +109,198 @@ export class DescriptionPropertyDefinitionEditorModel implements PropertyDefinit }); } + const formGroup = this.formBuilder.group({}); - (this.fields ?? []).map( - (item, index) => formGroup.addControl(item.key, new DescriptionFieldEditorModel( - this.validationErrorModel - ).fromModel(item).buildForm({ - rootPath: `${rootPath}fields[${index}].` - })), context.getValidation('fields') - ) + const fieldSetsFormGroup = this.formBuilder.group({}); + if (this.fieldSets.size > 0) { + this.fieldSets.forEach((value, key) => fieldSetsFormGroup.addControl(key.toString(), value.buildForm({ + rootPath: `${rootPath}fieldSets[${key}].` + })), context.getValidation('fieldSets')); + formGroup.addControl('fieldSets', fieldSetsFormGroup); + } + return formGroup; + } + + static createValidationContext(params: { + rootPath?: string, + validationErrorModel: ValidationErrorModel + }): ValidationContext { + const { rootPath = '', validationErrorModel } = params; + + const baseContext: ValidationContext = new ValidationContext(); + const baseValidationArray: Validation[] = new Array(); + baseValidationArray.push({ key: 'fieldSets', validators: [BackendErrorValidator(validationErrorModel, `${rootPath}fieldSets`)] }); + + baseContext.validation = baseValidationArray; + return baseContext; + } + + private calculateProperties(item: DescriptionPropertyDefinition, descriptionTemplate: DescriptionTemplate,): Map { + let result: Map = new Map(); + if (descriptionTemplate) ( + descriptionTemplate.definition.pages.forEach(definitionPage => { + + definitionPage.sections.forEach(definitionSection => { + + const sectionResult = this.calculateSectionProperties(definitionSection, item); + if (sectionResult != null) { + result = new Map([...result, ...sectionResult]); + } + }) + }) + ) + return result; + } + + private calculateSectionProperties(definitionSection: DescriptionTemplateSection, item: DescriptionPropertyDefinition): Map { + if (definitionSection == null) return null; + let result: Map = new Map(); + + definitionSection?.fieldSets?.forEach(definitionFieldSet => { + const fieldSetResult = this.calculateFieldSetProperties(definitionFieldSet, item); + if (fieldSetResult != null) { + result = new Map([...result, ...fieldSetResult]); + } + }); + + if (definitionSection.sections != null && definitionSection.sections?.length > 0) { + definitionSection.sections.forEach(nestedDefinitionSection => { + const nestedSectionResult = this.calculateSectionProperties(nestedDefinitionSection, item); + if (nestedSectionResult != null) { + result = new Map([...result, ...nestedSectionResult]); + } + }); + } + + return result; + } + + private calculateFieldSetProperties(definitionFieldSet: DescriptionTemplateFieldSet, item: DescriptionPropertyDefinition): Map { + if (definitionFieldSet == null) return null; + const result: Map = new Map(); + + // current saved values + const fieldSetValue: DescriptionPropertyDefinitionFieldSet = item?.fieldSets[definitionFieldSet.id] ?? {}; + + // new item case, where we need to add controls for all the containing fields. + if (fieldSetValue.items == null || fieldSetValue.items?.length == 0) { + + const fields = new Map(); + definitionFieldSet.fields.forEach(definitionField => { + fields.set(definitionField.id, { value: undefined }); + }) + fieldSetValue.items = [{ + fields: fields + } as DescriptionPropertyDefinitionFieldSetItem] + } + + result.set(definitionFieldSet.id, new DescriptionPropertyDefinitionFieldSetEditorModel().fromModel(fieldSetValue)); + + return result; + } + +} + +export class DescriptionPropertyDefinitionFieldSetEditorModel implements DescriptionPropertyDefinitionFieldSetPersist { + items?: DescriptionPropertyDefinitionFieldSetItemEditorModel[] = []; + protected formBuilder: UntypedFormBuilder = new UntypedFormBuilder(); + + constructor( + public validationErrorModel: ValidationErrorModel = new ValidationErrorModel() + ) { } + + public fromModel(item: DescriptionPropertyDefinitionFieldSet): DescriptionPropertyDefinitionFieldSetEditorModel { + if (item) { + if (item.items) { item.items.map(x => this.items.push(new DescriptionPropertyDefinitionFieldSetItemEditorModel().fromModel(x))); } + } + return this; + } + + buildForm(params?: { + context?: ValidationContext, + disabled?: boolean, + rootPath?: string + }): UntypedFormGroup { + let { context = null, disabled = false, rootPath } = params ?? {} + if (context == null) { + context = DescriptionPropertyDefinitionFieldSetEditorModel.createValidationContext({ + validationErrorModel: this.validationErrorModel, + rootPath + }); + } + + return this.formBuilder.group({ + items: this.formBuilder.array( + (this.items ?? []).map( + (item, index) => item.buildForm({ + rootPath: `${rootPath}items[${index}].` + }) + ), context.getValidation('items') + ) + }); + } + + static createValidationContext(params: { + rootPath?: string, + validationErrorModel: ValidationErrorModel + }): ValidationContext { + const { rootPath = '', validationErrorModel } = params; + + const baseContext: ValidationContext = new ValidationContext(); + const baseValidationArray: Validation[] = new Array(); + baseValidationArray.push({ key: 'items', validators: [BackendErrorValidator(validationErrorModel, `${rootPath}items`)] }); + + baseContext.validation = baseValidationArray; + return baseContext; + } + +} + +export class DescriptionPropertyDefinitionFieldSetItemEditorModel implements DescriptionPropertyDefinitionFieldSetItemPersist { + fields: Map = new Map; + comment?: string; + ordinal?: number; + protected formBuilder: UntypedFormBuilder = new UntypedFormBuilder(); + + constructor( + public validationErrorModel: ValidationErrorModel = new ValidationErrorModel() + ) { } + + public fromModel(item: DescriptionPropertyDefinitionFieldSetItem): DescriptionPropertyDefinitionFieldSetItemEditorModel { + if (item) { + this.comment = item.comment; + this.ordinal = item.ordinal; + if (item.fields) { item.fields?.forEach((value, key) => this.fields.set(key, new DescriptionFieldEditorModel().fromModel(value))); } + } + return this; + } + + buildForm(params?: { + context?: ValidationContext, + disabled?: boolean, + rootPath?: string + }): UntypedFormGroup { + let { context = null, disabled = false, rootPath } = params ?? {} + if (context == null) { + context = DescriptionPropertyDefinitionFieldSetItemEditorModel.createValidationContext({ + validationErrorModel: this.validationErrorModel, + rootPath + }); + } + + const formGroup = this.formBuilder.group({}); + formGroup.addControl('comment', new FormControl({ value: this.comment, disabled: disabled }, context.getValidation('comment').validators)); + formGroup.addControl('ordinal', new FormControl({ value: this.ordinal, disabled: disabled }, context.getValidation('ordinal').validators)); + + + const fieldsFormGroup = this.formBuilder.group({}); + this.fields.forEach((value, key) => fieldsFormGroup.addControl(key.toString(), value.buildForm({ + rootPath: `${rootPath}fields[${key}].` + })), context.getValidation('fields') + ) + formGroup.addControl('fields', fieldsFormGroup); + return formGroup; - - // return this.formBuilder.group({ - // fields: this.formBuilder.array( - // (this.fields ?? []).map( - // (item, index) => new DescriptionFieldEditorModel( - // this.validationErrorModel - // ).fromModel(item).buildForm({ - // rootPath: `${rootPath}fields[${index}].` - // }), context.getValidation('fields') - // ) - // ) - // }); } static createValidationContext(params: { @@ -139,6 +312,8 @@ export class DescriptionPropertyDefinitionEditorModel implements PropertyDefinit const baseContext: ValidationContext = new ValidationContext(); const baseValidationArray: Validation[] = new Array(); baseValidationArray.push({ key: 'fields', validators: [BackendErrorValidator(validationErrorModel, `${rootPath}fields`)] }); + baseValidationArray.push({ key: 'comment', validators: [BackendErrorValidator(validationErrorModel, `${rootPath}comment`)] }); + baseValidationArray.push({ key: 'ordinal', validators: [BackendErrorValidator(validationErrorModel, `${rootPath}ordinal`)] }); baseContext.validation = baseValidationArray; return baseContext; @@ -147,7 +322,6 @@ export class DescriptionPropertyDefinitionEditorModel implements PropertyDefinit } export class DescriptionFieldEditorModel implements DescriptionFieldPersist { - key?: string; value: string; protected formBuilder: UntypedFormBuilder = new UntypedFormBuilder(); @@ -158,7 +332,6 @@ export class DescriptionFieldEditorModel implements DescriptionFieldPersist { public fromModel(item: DescriptionField): DescriptionFieldEditorModel { if (item) { - this.key = item.key; this.value = item.value; } return this; @@ -178,7 +351,6 @@ export class DescriptionFieldEditorModel implements DescriptionFieldPersist { } return this.formBuilder.group({ - key: [{ value: this.key, disabled: disabled }, context.getValidation('key').validators], value: [{ value: this.value, disabled: disabled }, context.getValidation('value').validators] }); } @@ -191,7 +363,6 @@ export class DescriptionFieldEditorModel implements DescriptionFieldPersist { const baseContext: ValidationContext = new ValidationContext(); const baseValidationArray: Validation[] = new Array(); - baseValidationArray.push({ key: 'key', validators: [BackendErrorValidator(validationErrorModel, `${rootPath}key`)] }); baseValidationArray.push({ key: 'value', validators: [Validators.required, BackendErrorValidator(validationErrorModel, `${rootPath}value`)] }); baseContext.validation = baseValidationArray; return baseContext; diff --git a/dmp-frontend/src/app/ui/description/editor/description-editor.resolver.ts b/dmp-frontend/src/app/ui/description/editor/description-editor.resolver.ts index c649a02c1..5fd007673 100644 --- a/dmp-frontend/src/app/ui/description/editor/description-editor.resolver.ts +++ b/dmp-frontend/src/app/ui/description/editor/description-editor.resolver.ts @@ -1,22 +1,27 @@ import { Injectable } from '@angular/core'; import { ActivatedRouteSnapshot, RouterStateSnapshot } from '@angular/router'; -import { DescriptionTemplate, DescriptionTemplateBaseFieldData, DescriptionTemplateSelectOption, DescriptionTemplateDefinition, DescriptionTemplateField, DescriptionTemplateFieldSet, DescriptionTemplatePage, DescriptionTemplateRule, DescriptionTemplateSection, DescriptionTemplateSelectData } from '@app/core/model/description-template/description-template'; -import { Description, DescriptionField, DescriptionReference, DescriptionTag, PropertyDefinition } from '@app/core/model/description/description'; +import { DescriptionTemplate, DescriptionTemplateBaseFieldData, DescriptionTemplateDefinition, DescriptionTemplateExternalDatasetData, DescriptionTemplateField, DescriptionTemplateFieldSet, DescriptionTemplateMultiplicity, DescriptionTemplatePage, DescriptionTemplateRule, DescriptionTemplateSection, DescriptionTemplateSelectData, DescriptionTemplateSelectOption, DescriptionTemplateUploadData, DescriptionTemplateUploadOption } from '@app/core/model/description-template/description-template'; +import { Description, DescriptionField, DescriptionPropertyDefinition, DescriptionPropertyDefinitionFieldSet, DescriptionPropertyDefinitionFieldSetItem, DescriptionReference, DescriptionTag } from '@app/core/model/description/description'; import { DescriptionTemplatesInSection, DmpBlueprint, DmpBlueprintDefinition, DmpBlueprintDefinitionSection } from '@app/core/model/dmp-blueprint/dmp-blueprint'; import { Dmp, DmpDescriptionTemplate } from '@app/core/model/dmp/dmp'; import { Reference } from '@app/core/model/reference/reference'; import { Tag } from '@app/core/model/tag/tag'; import { DescriptionService } from '@app/core/services/description/description.service'; +import { DmpService } from '@app/core/services/dmp/dmp.service'; import { BreadcrumbService } from '@app/ui/misc/breadcrumb/breadcrumb.service'; import { BaseEditorResolver } from '@common/base/base-editor.resolver'; import { Guid } from '@common/types/guid'; -import { takeUntil, tap } from 'rxjs/operators'; +import { map, takeUntil, tap } from 'rxjs/operators'; import { nameof } from 'ts-simple-nameof'; @Injectable() export class DescriptionEditorResolver extends BaseEditorResolver { - constructor(private descriptionService: DescriptionService, private breadcrumbService: BreadcrumbService) { + constructor( + private descriptionService: DescriptionService, + private breadcrumbService: BreadcrumbService, + private dmpService: DmpService + ) { super(); } @@ -28,35 +33,17 @@ export class DescriptionEditorResolver extends BaseEditorResolver { nameof(x => x.status), nameof(x => x.description), nameof(x => x.status), - [nameof(x => x.dmp), nameof(x => x.id)].join('.'), - [nameof(x => x.dmp), nameof(x => x.label)].join('.'), - - [nameof(x => x.dmp), nameof(x => x.blueprint), nameof(x => x.id)].join('.'), - [nameof(x => x.dmp), nameof(x => x.blueprint), nameof(x => x.definition)].join('.'), - [nameof(x => x.dmp), nameof(x => x.blueprint), nameof(x => x.definition), nameof(x => x.sections), nameof(x => x.id)].join('.'), - [nameof(x => x.dmp), nameof(x => x.blueprint), nameof(x => x.definition), nameof(x => x.sections), nameof(x => x.label)].join('.'), - [nameof(x => x.dmp), nameof(x => x.blueprint), nameof(x => x.definition), nameof(x => x.sections), nameof(x => x.ordinal)].join('.'), - [nameof(x => x.dmp), nameof(x => x.blueprint), nameof(x => x.definition), nameof(x => x.sections), nameof(x => x.hasTemplates)].join('.'), - // [nameof(x => x.dmp), nameof(x => x.blueprint), nameof(x => x.definition), nameof(x => x.sections), nameof(x => x.descriptionTemplates), nameof(x => x.id)].join('.'), - [nameof(x => x.dmp), nameof(x => x.blueprint), nameof(x => x.definition), nameof(x => x.sections), nameof(x => x.descriptionTemplates), nameof(x => x.descriptionTemplateGroupId)].join('.'), - // [nameof(x => x.dmp), nameof(x => x.blueprint), nameof(x => x.definition), nameof(x => x.sections), nameof(x => x.descriptionTemplates), nameof(x => x.label)].join('.'), - // [nameof(x => x.dmp), nameof(x => x.blueprint), nameof(x => x.definition), nameof(x => x.sections), nameof(x => x.descriptionTemplates), nameof(x => x.minMultiplicity)].join('.'), - // [nameof(x => x.dmp), nameof(x => x.blueprint), nameof(x => x.definition), nameof(x => x.sections), nameof(x => x.descriptionTemplates), nameof(x => x.maxMultiplicity)].join('.'), - - [nameof(x => x.dmp), nameof(x => x.dmpDescriptionTemplates), nameof(x => x.sectionId)].join('.'), - [nameof(x => x.dmp), nameof(x => x.dmpDescriptionTemplates), nameof(x => x.descriptionTemplateGroupId)].join('.'), - [nameof(x => x.dmp), nameof(x => x.dmpDescriptionTemplates), nameof(x => x.currentDescriptionTemplate), nameof(x => x.id)].join('.'), - [nameof(x => x.dmp), nameof(x => x.dmpDescriptionTemplates), nameof(x => x.currentDescriptionTemplate), nameof(x => x.label)].join('.'), - [nameof(x => x.dmp), nameof(x => x.dmpDescriptionTemplates), nameof(x => x.currentDescriptionTemplate), nameof(x => x.version)].join('.'), + ...DescriptionEditorResolver.dmpLookupFields(nameof(x => x.dmp)), [nameof(x => x.dmpDescriptionTemplate), nameof(x => x.id)].join('.'), [nameof(x => x.dmpDescriptionTemplate), nameof(x => x.sectionId)].join('.'), ...DescriptionEditorResolver.descriptionTemplateLookupFields(nameof(x => x.descriptionTemplate)), - [nameof(x => x.properties), nameof(x => x.fields), nameof(x => x.key)].join('.'), - [nameof(x => x.properties), nameof(x => x.fields), nameof(x => x.value)].join('.'), + [nameof(x => x.properties), nameof(x => x.fieldSets), nameof(x => x.items), nameof(x => x.comment)].join('.'), + [nameof(x => x.properties), nameof(x => x.fieldSets), nameof(x => x.items), nameof(x => x.ordinal)].join('.'), + [nameof(x => x.properties), nameof(x => x.fieldSets), nameof(x => x.items), nameof(x => x.fields), nameof(x => x.value)].join('.'), [nameof(x => x.descriptionTags), nameof(x => x.id),].join('.'), [nameof(x => x.descriptionTags), nameof(x => x.tag), nameof(x => x.label)].join('.'), @@ -84,6 +71,7 @@ export class DescriptionEditorResolver extends BaseEditorResolver { (prefix ? prefix + '.' : '') + [nameof(x => x.definition), nameof(x => x.pages), nameof(x => x.sections), nameof(x => x.ordinal)].join('.'), (prefix ? prefix + '.' : '') + [nameof(x => x.definition), nameof(x => x.pages), nameof(x => x.sections), nameof(x => x.title)].join('.'), (prefix ? prefix + '.' : '') + [nameof(x => x.definition), nameof(x => x.pages), nameof(x => x.sections), nameof(x => x.description)].join('.'), + (prefix ? prefix + '.' : '') + [nameof(x => x.definition), nameof(x => x.pages), nameof(x => x.sections), nameof(x => x.sections)].join('.'), (prefix ? prefix + '.' : '') + [nameof(x => x.definition), nameof(x => x.pages), nameof(x => x.sections), nameof(x => x.fieldSets), nameof(x => x.id)].join('.'), (prefix ? prefix + '.' : '') + [nameof(x => x.definition), nameof(x => x.pages), nameof(x => x.sections), nameof(x => x.fieldSets), nameof(x => x.ordinal)].join('.'), (prefix ? prefix + '.' : '') + [nameof(x => x.definition), nameof(x => x.pages), nameof(x => x.sections), nameof(x => x.fieldSets), nameof(x => x.title)].join('.'), @@ -91,6 +79,10 @@ export class DescriptionEditorResolver extends BaseEditorResolver { (prefix ? prefix + '.' : '') + [nameof(x => x.definition), nameof(x => x.pages), nameof(x => x.sections), nameof(x => x.fieldSets), nameof(x => x.extendedDescription)].join('.'), (prefix ? prefix + '.' : '') + [nameof(x => x.definition), nameof(x => x.pages), nameof(x => x.sections), nameof(x => x.fieldSets), nameof(x => x.additionalInformation)].join('.'), (prefix ? prefix + '.' : '') + [nameof(x => x.definition), nameof(x => x.pages), nameof(x => x.sections), nameof(x => x.fieldSets), nameof(x => x.hasCommentField)].join('.'), + (prefix ? prefix + '.' : '') + [nameof(x => x.definition), nameof(x => x.pages), nameof(x => x.sections), nameof(x => x.fieldSets), nameof(x => x.multiplicity), nameof(x => x.min)].join('.'), + (prefix ? prefix + '.' : '') + [nameof(x => x.definition), nameof(x => x.pages), nameof(x => x.sections), nameof(x => x.fieldSets), nameof(x => x.multiplicity), nameof(x => x.max)].join('.'), + (prefix ? prefix + '.' : '') + [nameof(x => x.definition), nameof(x => x.pages), nameof(x => x.sections), nameof(x => x.fieldSets), nameof(x => x.multiplicity), nameof(x => x.placeholder)].join('.'), + (prefix ? prefix + '.' : '') + [nameof(x => x.definition), nameof(x => x.pages), nameof(x => x.sections), nameof(x => x.fieldSets), nameof(x => x.multiplicity), nameof(x => x.tableView)].join('.'), (prefix ? prefix + '.' : '') + [nameof(x => x.definition), nameof(x => x.pages), nameof(x => x.sections), nameof(x => x.fieldSets), nameof(x => x.fields), nameof(x => x.id)].join('.'), (prefix ? prefix + '.' : '') + [nameof(x => x.definition), nameof(x => x.pages), nameof(x => x.sections), nameof(x => x.fieldSets), nameof(x => x.fields), nameof(x => x.defaultValue)].join('.'), (prefix ? prefix + '.' : '') + [nameof(x => x.definition), nameof(x => x.pages), nameof(x => x.sections), nameof(x => x.fieldSets), nameof(x => x.fields), nameof(x => x.validations)].join('.'), @@ -98,10 +90,38 @@ export class DescriptionEditorResolver extends BaseEditorResolver { (prefix ? prefix + '.' : '') + [nameof(x => x.definition), nameof(x => x.pages), nameof(x => x.sections), nameof(x => x.fieldSets), nameof(x => x.fields), nameof(x => x.visibilityRules), nameof(x => x.value)].join('.'), (prefix ? prefix + '.' : '') + [nameof(x => x.definition), nameof(x => x.pages), nameof(x => x.sections), nameof(x => x.fieldSets), nameof(x => x.fields), nameof(x => x.data), nameof(x => x.label)].join('.'), (prefix ? prefix + '.' : '') + [nameof(x => x.definition), nameof(x => x.pages), nameof(x => x.sections), nameof(x => x.fieldSets), nameof(x => x.fields), nameof(x => x.data), nameof(x => x.fieldType)].join('.'), - (prefix ? prefix + '.' : '') + [nameof(x => x.definition), nameof(x => x.pages), nameof(x => x.sections), nameof(x => x.fieldSets), nameof(x => x.fields), nameof(x => x.data), nameof(x => x.options)].join('.'), (prefix ? prefix + '.' : '') + [nameof(x => x.definition), nameof(x => x.pages), nameof(x => x.sections), nameof(x => x.fieldSets), nameof(x => x.fields), nameof(x => x.data), nameof(x => x.options), nameof(x => x.label)].join('.'), (prefix ? prefix + '.' : '') + [nameof(x => x.definition), nameof(x => x.pages), nameof(x => x.sections), nameof(x => x.fieldSets), nameof(x => x.fields), nameof(x => x.data), nameof(x => x.options), nameof(x => x.value)].join('.'), (prefix ? prefix + '.' : '') + [nameof(x => x.definition), nameof(x => x.pages), nameof(x => x.sections), nameof(x => x.fieldSets), nameof(x => x.fields), nameof(x => x.data), nameof(x => x.multipleSelect)].join('.'), + (prefix ? prefix + '.' : '') + [nameof(x => x.definition), nameof(x => x.pages), nameof(x => x.sections), nameof(x => x.fieldSets), nameof(x => x.fields), nameof(x => x.data), nameof(x => x.type)].join('.'), + (prefix ? prefix + '.' : '') + [nameof(x => x.definition), nameof(x => x.pages), nameof(x => x.sections), nameof(x => x.fieldSets), nameof(x => x.fields), nameof(x => x.data), nameof(x => x.maxFileSizeInMB)].join('.'), + (prefix ? prefix + '.' : '') + [nameof(x => x.definition), nameof(x => x.pages), nameof(x => x.sections), nameof(x => x.fieldSets), nameof(x => x.fields), nameof(x => x.data), nameof(x => x.types), nameof(x => x.label)].join('.'), + (prefix ? prefix + '.' : '') + [nameof(x => x.definition), nameof(x => x.pages), nameof(x => x.sections), nameof(x => x.fieldSets), nameof(x => x.fields), nameof(x => x.data), nameof(x => x.types), nameof(x => x.value)].join('.'), + ] + } + + public static dmpLookupFields(prefix?: string): string[] { + return [ + (prefix ? prefix + '.' : '') + [nameof(x => x.id)].join('.'), + (prefix ? prefix + '.' : '') + [nameof(x => x.label)].join('.'), + + (prefix ? prefix + '.' : '') + [nameof(x => x.blueprint), nameof(x => x.id)].join('.'), + (prefix ? prefix + '.' : '') + [nameof(x => x.blueprint), nameof(x => x.definition)].join('.'), + (prefix ? prefix + '.' : '') + [nameof(x => x.blueprint), nameof(x => x.definition), nameof(x => x.sections), nameof(x => x.id)].join('.'), + (prefix ? prefix + '.' : '') + [nameof(x => x.blueprint), nameof(x => x.definition), nameof(x => x.sections), nameof(x => x.label)].join('.'), + (prefix ? prefix + '.' : '') + [nameof(x => x.blueprint), nameof(x => x.definition), nameof(x => x.sections), nameof(x => x.ordinal)].join('.'), + (prefix ? prefix + '.' : '') + [nameof(x => x.blueprint), nameof(x => x.definition), nameof(x => x.sections), nameof(x => x.hasTemplates)].join('.'), + // (prefix ? prefix + '.' : '') + [nameof(x => x.blueprint), nameof(x => x.definition), nameof(x => x.sections), nameof(x => x.descriptionTemplates), nameof(x => x.id)].join('.'), + (prefix ? prefix + '.' : '') + [nameof(x => x.blueprint), nameof(x => x.definition), nameof(x => x.sections), nameof(x => x.descriptionTemplates), nameof(x => x.descriptionTemplateGroupId)].join('.'), + // (prefix ? prefix + '.' : '') + [nameof(x => x.blueprint), nameof(x => x.definition), nameof(x => x.sections), nameof(x => x.descriptionTemplates), nameof(x => x.label)].join('.'), + // (prefix ? prefix + '.' : '') + [nameof(x => x.blueprint), nameof(x => x.definition), nameof(x => x.sections), nameof(x => x.descriptionTemplates), nameof(x => x.minMultiplicity)].join('.'), + // (prefix ? prefix + '.' : '') + [nameof(x => x.blueprint), nameof(x => x.definition), nameof(x => x.sections), nameof(x => x.descriptionTemplates), nameof(x => x.maxMultiplicity)].join('.'), + + (prefix ? prefix + '.' : '') + [nameof(x => x.dmpDescriptionTemplates), nameof(x => x.sectionId)].join('.'), + (prefix ? prefix + '.' : '') + [nameof(x => x.dmpDescriptionTemplates), nameof(x => x.descriptionTemplateGroupId)].join('.'), + (prefix ? prefix + '.' : '') + [nameof(x => x.dmpDescriptionTemplates), nameof(x => x.currentDescriptionTemplate), nameof(x => x.id)].join('.'), + (prefix ? prefix + '.' : '') + [nameof(x => x.dmpDescriptionTemplates), nameof(x => x.currentDescriptionTemplate), nameof(x => x.label)].join('.'), + (prefix ? prefix + '.' : '') + [nameof(x => x.dmpDescriptionTemplates), nameof(x => x.currentDescriptionTemplate), nameof(x => x.version)].join('.'), ] } @@ -111,9 +131,21 @@ export class DescriptionEditorResolver extends BaseEditorResolver { ...DescriptionEditorResolver.lookupFields() ]; const id = route.paramMap.get('id'); + const dmpId = route.paramMap.get('dmpId'); + const dmpSectionId = route.paramMap.get('dmpSectionId'); // const cloneid = route.paramMap.get('cloneid'); if (id != null) { - return this.descriptionService.getSingle(Guid.parse(id), fields).pipe(tap(x => this.breadcrumbService.addIdResolvedValue(x.id?.toString(), x.label)), takeUntil(this._destroyed)); + return this.descriptionService.getSingle(Guid.parse(id), fields) + } else if (dmpId != null && dmpSectionId != null) { + return this.dmpService.getSingle(Guid.parse(dmpId), DescriptionEditorResolver.dmpLookupFields()).pipe(tap(x => this.breadcrumbService.addIdResolvedValue(x.id?.toString(), x.label)), takeUntil(this._destroyed), map(dmp => { + + const description: Description = {}; + description.dmp = dmp; + description.dmpDescriptionTemplate = { + sectionId: Guid.parse(dmpSectionId) + } + return description; + })); } //TODO: check this // else if (cloneid != null) { diff --git a/dmp-frontend/src/app/ui/description/editor/description-editor.routing.ts b/dmp-frontend/src/app/ui/description/editor/description-editor.routing.ts index 7a513afba..75d6ed43c 100644 --- a/dmp-frontend/src/app/ui/description/editor/description-editor.routing.ts +++ b/dmp-frontend/src/app/ui/description/editor/description-editor.routing.ts @@ -27,16 +27,23 @@ const routes: Routes = [ } } }, - // { - // path: 'new/:dmpId/:dmpSectionIndex', - // component: DescriptionWizardComponent, - // canActivate: [AuthGuard], - // data: { - // breadcrumb: true, - // title: 'GENERAL.TITLES.DATASET-NEW' - // }, - // canDeactivate:[CanDeactivateGuard] - // }, + { + path: ':dmpId/:dmpSectionId', + canActivate: [AuthGuard], + component: DescriptionEditorComponent, + canDeactivate: [PendingChangesGuard], + resolve: { + 'entity': DescriptionEditorResolver + }, + data: { + ...BreadcrumbService.generateRouteDataConfiguration({ + title: 'BREADCRUMBS.EDIT-DESCRIPTION' + }), + authContext: { + permissions: [AppPermission.EditDescription] + } + } + }, // { // path: 'edit/:id/finalize', diff --git a/dmp-frontend/src/app/ui/description/editor/description-form/components/form-field-set/form-field-set.component.html b/dmp-frontend/src/app/ui/description/editor/description-form/components/form-field-set/form-field-set.component.html index b7e3ee410..1cc9e460a 100644 --- a/dmp-frontend/src/app/ui/description/editor/description-form/components/form-field-set/form-field-set.component.html +++ b/dmp-frontend/src/app/ui/description/editor/description-form/components/form-field-set/form-field-set.component.html @@ -45,8 +45,8 @@ -
- +
+
diff --git a/dmp-frontend/src/app/ui/description/editor/description-form/components/form-field/form-field.component.html b/dmp-frontend/src/app/ui/description/editor/description-form/components/form-field/form-field.component.html index 6cbafb962..181e79786 100644 --- a/dmp-frontend/src/app/ui/description/editor/description-form/components/form-field/form-field.component.html +++ b/dmp-frontend/src/app/ui/description/editor/description-form/components/form-field/form-field.component.html @@ -11,25 +11,25 @@ {{fieldSet.extendedDescription}} - - {{'GENERAL.VALIDATION.REQUIRED' | translate}} - {{'GENERAL.VALIDATION.URL.MESSAGE' | translate}} + + {{'GENERAL.VALIDATION.REQUIRED' | translate}} + {{'GENERAL.VALIDATION.URL.MESSAGE' | translate}}
- - - {{'GENERAL.VALIDATION.REQUIRED' | translate}} + {{'GENERAL.VALIDATION.REQUIRED' | translate}} {{ "TYPES.DATASET-PROFILE-COMBO-BOX-TYPE.EXTERNAL-SOURCE-HINT" | translate }} @@ -38,11 +38,11 @@
- + {{opt.label}} - {{'GENERAL.VALIDATION.REQUIRED' | translate}} + {{'GENERAL.VALIDATION.REQUIRED' | translate}}
@@ -51,16 +51,16 @@
- - - {{'GENERAL.VALIDATION.REQUIRED' | translate}} + {{'GENERAL.VALIDATION.REQUIRED' | translate}} {{ "TYPES.DATASET-PROFILE-COMBO-BOX-TYPE.EXTERNAL-SOURCE-HINT" | translate }} @@ -70,16 +70,16 @@
- - - {{'GENERAL.VALIDATION.REQUIRED' | translate}} + {{'GENERAL.VALIDATION.REQUIRED' | translate}} {{ "TYPES.DATASET-PROFILE-COMBO-BOX-TYPE.EXTERNAL-SOURCE-HINT" | translate }} @@ -89,97 +89,97 @@
- - - {{'GENERAL.VALIDATION.REQUIRED' | translate}} + {{'GENERAL.VALIDATION.REQUIRED' | translate}} {{ "TYPES.DATASET-PROFILE-COMBO-BOX-TYPE.EXTERNAL-SOURCE-HINT" | translate }}
- + {{field.data.label}}
- - - {{'GENERAL.VALIDATION.REQUIRED' | translate}} + {{'GENERAL.VALIDATION.REQUIRED' | translate}} + ((isRequired && propertiesFormGroup?.get(field.id).get('value').touched && propertiesFormGroup?.get(field.id).get('value').hasError('required')) ? 'required' : '')" + [editable]="!propertiesFormGroup?.get(field.id).get('value').disabled"> -
+
- {{'GENERAL.VALIDATION.REQUIRED' | translate}} + {{'GENERAL.VALIDATION.REQUIRED' | translate}}
- + - {{ propertiesFormGroup.get(field.id).get('value').value.name }} + {{ propertiesFormGroup?.get(field.id).get('value').value.name }}
- -
- - {{ "TYPES.DATASET-PROFILE-COMBO-BOX-TYPE.ACTIONS.YES" | translate }} - {{ "TYPES.DATASET-PROFILE-COMBO-BOX-TYPE.ACTIONS.NO" | translate }} + + {{ "TYPES.DATASET-PROFILE-COMBO-BOX-TYPE.ACTIONS.YES" | translate }} + {{ "TYPES.DATASET-PROFILE-COMBO-BOX-TYPE.ACTIONS.NO" | translate }} - {{'GENERAL.VALIDATION.REQUIRED' | translate}} + {{'GENERAL.VALIDATION.REQUIRED' | translate}} - {{'GENERAL.VALIDATION.REQUIRED' | translate}} + {{'GENERAL.VALIDATION.REQUIRED' | translate}}
- + {{option.label}} - {{'GENERAL.VALIDATION.REQUIRED' | translate}} + {{'GENERAL.VALIDATION.REQUIRED' | translate}} - {{'GENERAL.VALIDATION.REQUIRED' | translate}} * + {{'GENERAL.VALIDATION.REQUIRED' | translate}} *
+ [formControl]="propertiesFormGroup?.get(field.id).get('value')"> - + {{'GENERAL.VALIDATION.REQUIRED' | translate}} @@ -188,16 +188,16 @@
- - - {{'GENERAL.VALIDATION.REQUIRED' | translate}} + {{'GENERAL.VALIDATION.REQUIRED' | translate}} {{ "TYPES.DATASET-PROFILE-COMBO-BOX-TYPE.EXTERNAL-SOURCE-HINT" | translate }} @@ -208,16 +208,16 @@
- - - {{'GENERAL.VALIDATION.REQUIRED' | translate}} + {{'GENERAL.VALIDATION.REQUIRED' | translate}} {{ "TYPES.DATASET-PROFILE-COMBO-BOX-TYPE.EXTERNAL-SOURCE-HINT" | translate }} @@ -227,16 +227,16 @@
- - - {{'GENERAL.VALIDATION.REQUIRED' | translate}} + {{'GENERAL.VALIDATION.REQUIRED' | translate}} {{ "TYPES.DATASET-PROFILE-COMBO-BOX-TYPE.EXTERNAL-SOURCE-HINT" | translate }} @@ -246,16 +246,16 @@
- - - {{'GENERAL.VALIDATION.REQUIRED' | translate}} + {{'GENERAL.VALIDATION.REQUIRED' | translate}} {{ "TYPES.DATASET-PROFILE-COMBO-BOX-TYPE.EXTERNAL-SOURCE-HINT" | translate }} @@ -266,16 +266,16 @@
- - - {{'GENERAL.VALIDATION.REQUIRED' | translate}} + {{'GENERAL.VALIDATION.REQUIRED' | translate}} {{ "TYPES.DATASET-PROFILE-COMBO-BOX-TYPE.EXTERNAL-SOURCE-HINT" | translate }} @@ -286,16 +286,16 @@
- - - {{'GENERAL.VALIDATION.REQUIRED' | translate}} + {{'GENERAL.VALIDATION.REQUIRED' | translate}} {{ "TYPES.DATASET-PROFILE-COMBO-BOX-TYPE.EXTERNAL-SOURCE-HINT" | translate }} @@ -306,16 +306,16 @@
- - - {{'GENERAL.VALIDATION.REQUIRED' | translate}} + {{'GENERAL.VALIDATION.REQUIRED' | translate}} {{ "TYPES.DATASET-PROFILE-COMBO-BOX-TYPE.EXTERNAL-SOURCE-HINT" | translate }} @@ -326,16 +326,16 @@
- - - {{'GENERAL.VALIDATION.REQUIRED' | translate}} + {{'GENERAL.VALIDATION.REQUIRED' | translate}} {{ "TYPES.DATASET-PROFILE-COMBO-BOX-TYPE.EXTERNAL-SOURCE-HINT" | translate }} @@ -346,16 +346,16 @@
- - - {{'GENERAL.VALIDATION.REQUIRED' | translate}} + {{'GENERAL.VALIDATION.REQUIRED' | translate}} {{ "TYPES.DATASET-PROFILE-COMBO-BOX-TYPE.EXTERNAL-SOURCE-HINT" | translate }} @@ -365,7 +365,7 @@
- +
@@ -374,16 +374,16 @@
- - - {{'GENERAL.VALIDATION.REQUIRED' | translate}} + {{'GENERAL.VALIDATION.REQUIRED' | translate}} {{ "TYPES.DATASET-PROFILE-COMBO-BOX-TYPE.EXTERNAL-SOURCE-HINT" | translate }} @@ -394,15 +394,15 @@
- - - {{'GENERAL.VALIDATION.REQUIRED' | translate}} + {{'GENERAL.VALIDATION.REQUIRED' | translate}} @@ -415,18 +415,18 @@
- {{'GENERAL.VALIDATION.REQUIRED' | translate}} + [required]="isRequired" [disabled]="propertiesFormGroup?.get(field.id).get('value').disabled"> + {{'GENERAL.VALIDATION.REQUIRED' | translate}} + [disabled]="propertiesFormGroup?.get(field.id).get('value').disabled"> {{ type.name }} - {{'GENERAL.VALIDATION.REQUIRED' | translate}} + {{'GENERAL.VALIDATION.REQUIRED' | translate}}
@@ -435,10 +435,10 @@
- - {{'GENERAL.VALIDATION.REQUIRED' | translate}} + {{'GENERAL.VALIDATION.REQUIRED' | translate}}
@@ -448,7 +448,7 @@
- {{'GENERAL.VALIDATION.REQUIRED' | translate}} + {{'GENERAL.VALIDATION.REQUIRED' | translate}} @@ -457,12 +457,12 @@ {{ type.name }} - {{'GENERAL.VALIDATION.REQUIRED' | translate}} + {{'GENERAL.VALIDATION.REQUIRED' | translate}}
- - {{'GENERAL.VALIDATION.REQUIRED' | translate}} + + {{'GENERAL.VALIDATION.REQUIRED' | translate}}
diff --git a/dmp-frontend/src/app/ui/description/editor/description-form/components/form-field/form-field.component.ts b/dmp-frontend/src/app/ui/description/editor/description-form/components/form-field/form-field.component.ts index 11749fefb..2d22b2bed 100644 --- a/dmp-frontend/src/app/ui/description/editor/description-form/components/form-field/form-field.component.ts +++ b/dmp-frontend/src/app/ui/description/editor/description-form/components/form-field/form-field.component.ts @@ -123,36 +123,37 @@ export class DescriptionFormFieldComponent extends BaseComponent implements OnIn }); //TODO: validate that this logic is correct. Validation contenxt path might need to be fixed. - if (this.propertiesFormGroup.get(this.field.id).get('value') == null) { - const item: DescriptionFieldEditorModel = new DescriptionFieldEditorModel(); - item.key = this.field.id; - this.propertiesFormGroup.addControl(this.field.id, item.buildForm()); - } + // if (this.propertiesFormGroup.get(this.field.id).get('value') == null) { + // const item: DescriptionFieldEditorModel = new DescriptionFieldEditorModel(); + // item.key = this.field.id; + // this.propertiesFormGroup.addControl(this.field.id, item.buildForm()); + // } - if (this.propertiesFormGroup.get(this.field.id).get('value').value) { - this.visibilityRulesService.updateValueAndVisibility(this.field?.id, this.propertiesFormGroup.get(this.field.id).get('value').value); - } + // if (this.propertiesFormGroup.get(this.field.id).get('value').value) { + // this.visibilityRulesService.updateValueAndVisibility(this.field?.id, this.propertiesFormGroup.get(this.field.id).get('value').value); + // } this.isRequired = this.field.validations?.includes(DescriptionTemplateFieldValidationType.Required); - if (this.field?.data?.fieldType === DescriptionTemplateFieldType.SELECT) { - if ((this.field.data as DescriptionTemplateSelectData).multipleSelect) { - const originalValue = this.propertiesFormGroup.get(this.field.id).get('value').value; - if (originalValue !== null && typeof originalValue === 'string') { - let values = (this.propertiesFormGroup.get(this.field.id).get('value').value).slice(1, -1).split(', ').filter((value) => !value.includes('"')); - let specialValue = (this.propertiesFormGroup.get(this.field.id).get('value').value).split('"').filter((value) => !value.startsWith('[') && !value.endsWith(']') && !values.includes(value) && value !== ', '); - specialValue.forEach(value => values.push(value)); - if (!originalValue.startsWith('[') && !originalValue.endsWith(']')) { - values = undefined; - values = [originalValue]; - } - this.propertiesFormGroup.get(this.field.id).get('value').patchValue(values); - values.forEach(element => { - this.visibilityRulesService.updateValueAndVisibility(this.field?.id, element); - }); - } - } - } + //TODO: refactor + // if (this.field?.data?.fieldType === DescriptionTemplateFieldType.SELECT) { + // if ((this.field.data as DescriptionTemplateSelectData).multipleSelect) { + // const originalValue = this.propertiesFormGroup.get(this.field.id).get('value').value; + // if (originalValue !== null && typeof originalValue === 'string') { + // let values = (this.propertiesFormGroup.get(this.field.id).get('value').value).slice(1, -1).split(', ').filter((value) => !value.includes('"')); + // let specialValue = (this.propertiesFormGroup.get(this.field.id).get('value').value).split('"').filter((value) => !value.startsWith('[') && !value.endsWith(']') && !values.includes(value) && value !== ', '); + // specialValue.forEach(value => values.push(value)); + // if (!originalValue.startsWith('[') && !originalValue.endsWith(']')) { + // values = undefined; + // values = [originalValue]; + // } + // this.propertiesFormGroup.get(this.field.id).get('value').patchValue(values); + // values.forEach(element => { + // this.visibilityRulesService.updateValueAndVisibility(this.field?.id, element); + // }); + // } + // } + // } // Setup autocomplete configuration if needed if (this.field?.data?.fieldType === DescriptionTemplateFieldType.EXTERNAL_SELECT) { @@ -303,8 +304,8 @@ export class DescriptionFormFieldComponent extends BaseComponent implements OnIn }; break; case DescriptionTemplateFieldType.DATASET_IDENTIFIER: - const value = this.propertiesFormGroup.get(this.field.id).get('value').value; - const disabled = this.propertiesFormGroup.get(this.field.id).disabled; + // const value = this.propertiesFormGroup.get(this.field.id).get('value').value; + // const disabled = this.propertiesFormGroup.get(this.field.id).disabled; //TODO: Refactor this. // this.form.removeControl('value'); // this.form.addControl('value', new DatasetIdModel(value).buildForm()); @@ -323,8 +324,8 @@ export class DescriptionFormFieldComponent extends BaseComponent implements OnIn }; break; case DescriptionTemplateFieldType.VALIDATION: - const value1 = this.propertiesFormGroup.get(this.field.id).get('value').value; - const disabled1 = this.propertiesFormGroup.get(this.field.id).disabled; + // const value1 = this.propertiesFormGroup.get(this.field.id).get('value').value; + // const disabled1 = this.propertiesFormGroup.get(this.field.id).disabled; //TODO: Refactor this. // this.form.removeControl('value'); // this.form.addControl('value', new DatasetIdModel(value1).buildForm()); @@ -344,21 +345,23 @@ export class DescriptionFormFieldComponent extends BaseComponent implements OnIn } // this.form = this.visibilityRulesService.getFormGroup(this.field.id); - this.propertiesFormGroup.get(this.field.id).get('value').valueChanges - .pipe( - takeUntil(this._destroyed), - distinctUntilChanged() - ) - .subscribe(item => { - // if (this.field?.data?.fieldType === DescriptionTemplateFieldType.ComboBox && this.form.get('data').value.type === DatasetProfileComboBoxType.Select && this.form.get('data').value.multipleSelect) { - // item.forEach(element => { - // this.visibilityRulesService.updateValueAndVisibility(this.field?.id, element); - // }); + + //TODO: refactor + // this.propertiesFormGroup.get(this.field.id).get('value').valueChanges + // .pipe( + // takeUntil(this._destroyed), + // distinctUntilChanged() + // ) + // .subscribe(item => { + // // if (this.field?.data?.fieldType === DescriptionTemplateFieldType.ComboBox && this.form.get('data').value.type === DatasetProfileComboBoxType.Select && this.form.get('data').value.multipleSelect) { + // // item.forEach(element => { + // // this.visibilityRulesService.updateValueAndVisibility(this.field?.id, element); + // // }); - // } else { - this.visibilityRulesService.updateValueAndVisibility(this.field?.id, item); - // } - }); + // // } else { + // this.visibilityRulesService.updateValueAndVisibility(this.field?.id, item); + // // } + // }); } // _optionRemove(event) { diff --git a/dmp-frontend/src/app/ui/description/editor/description-form/components/form-section/form-section.component.html b/dmp-frontend/src/app/ui/description/editor/description-form/components/form-section/form-section.component.html index d5fc9a951..54c6b7cb9 100644 --- a/dmp-frontend/src/app/ui/description/editor/description-form/components/form-section/form-section.component.html +++ b/dmp-frontend/src/app/ui/description/editor/description-form/components/form-section/form-section.component.html @@ -16,7 +16,7 @@
- +
diff --git a/dmp-frontend/src/app/ui/description/editor/description-form/components/form-section/form-section.component.ts b/dmp-frontend/src/app/ui/description/editor/description-form/components/form-section/form-section.component.ts index 7efec3364..c7edca706 100644 --- a/dmp-frontend/src/app/ui/description/editor/description-form/components/form-section/form-section.component.ts +++ b/dmp-frontend/src/app/ui/description/editor/description-form/components/form-section/form-section.component.ts @@ -57,13 +57,13 @@ export class DescriptionFormSectionComponent extends BaseComponent implements On // this.changeDetector.markForCheck(); // }); // Set comment fields to properties - this.section.fieldSets.forEach(fieldSet => { - if (fieldSet.hasCommentField && !this.propertiesFormGroup.contains('commentFieldValue' + fieldSet.id)) { - const item: DescriptionFieldEditorModel = new DescriptionFieldEditorModel(); - item.key = 'commentFieldValue' + fieldSet.id; - this.propertiesFormGroup.addControl('commentFieldValue' + fieldSet.id, item.buildForm()); - } - }); + // this.section.fieldSets.forEach(fieldSet => { + // if (fieldSet.hasCommentField && !this.propertiesFormGroup.contains('commentFieldValue' + fieldSet.id)) { + // const item: DescriptionFieldEditorModel = new DescriptionFieldEditorModel(); + // item.key = 'commentFieldValue' + fieldSet.id; + // this.propertiesFormGroup.addControl('commentFieldValue' + fieldSet.id, item.buildForm()); + // } + // }); //TODO uncomment // if (this.tocentry) {//maybe not needed as well 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 17b7ff55f..619d7b364 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 @@ -199,6 +199,12 @@ export class TableOfContentsComponent extends BaseComponent implements OnInit, O this._resetObserver(); } + if (changes['descriptionTemplate'] && changes.descriptionTemplate != null) { + this.tocentries = this.getTocEntries(this.descriptionTemplate); + if (this.visibilityRulesService) { + this.hiddenEntries = this._findHiddenEntries(this.tocentries); + } + } if ('visibilityRulesService') { if (this._visibilityRulesSubscription) { 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 fd0a30ec6..ed45c212a 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 @@ -95,9 +95,9 @@
-