changes desciption editor form field logic to apply validation from form control instead of required html attribute

This commit is contained in:
Diamantis Tziotzios 2024-06-06 20:19:22 +03:00
parent d606cd4058
commit eaa802872a
9 changed files with 194 additions and 108 deletions

View File

@ -76,7 +76,7 @@ export class DescriptionTemplatePreviewDialogComponent extends BaseComponent imp
} }
buildForm() { buildForm() {
this.formGroup = this.editorModel.buildForm(null, true); this.formGroup = this.editorModel.buildForm(null, true, this.visibilityRulesService);
this.previewPropertiesFormGroup = this.editorModel.properties.buildForm() as UntypedFormGroup; this.previewPropertiesFormGroup = this.editorModel.properties.buildForm() as UntypedFormGroup;
this.visibilityRulesService.setContext(this.descriptionTemplate.definition, this.previewPropertiesFormGroup); this.visibilityRulesService.setContext(this.descriptionTemplate.definition, this.previewPropertiesFormGroup);
} }

View File

@ -220,7 +220,7 @@ export class DescriptionEditorComponent extends BaseEditor<DescriptionEditorMode
permissionPerSection => { permissionPerSection => {
this.canEdit = permissionPerSection && permissionPerSection[this.item.dmpDescriptionTemplate.sectionId.toString()] && permissionPerSection[this.item.dmpDescriptionTemplate.sectionId.toString()].some(x => x === AppPermission.EditDescription); this.canEdit = permissionPerSection && permissionPerSection[this.item.dmpDescriptionTemplate.sectionId.toString()] && permissionPerSection[this.item.dmpDescriptionTemplate.sectionId.toString()].some(x => x === AppPermission.EditDescription);
this.canReview = permissionPerSection && permissionPerSection[this.item.dmpDescriptionTemplate.sectionId.toString()] && permissionPerSection[this.item.dmpDescriptionTemplate.sectionId.toString()].some(x => x === AppPermission.ReviewDescription); this.canReview = permissionPerSection && permissionPerSection[this.item.dmpDescriptionTemplate.sectionId.toString()] && permissionPerSection[this.item.dmpDescriptionTemplate.sectionId.toString()].some(x => x === AppPermission.ReviewDescription);
this.formGroup = this.editorModel.buildForm(null, this.isDeleted || !this.canEdit); this.formGroup = this.editorModel.buildForm(null, this.isDeleted || !this.canEdit, this.visibilityRulesService);
if (this.item.descriptionTemplate?.definition) this.visibilityRulesService.setContext(this.item.descriptionTemplate.definition, this.formGroup.get('properties')); if (this.item.descriptionTemplate?.definition) this.visibilityRulesService.setContext(this.item.descriptionTemplate.definition, this.formGroup.get('properties'));
if (this.item.descriptionTemplate?.definition) this.pageToFieldSetMap = this.mapPageToFieldSet(this.item.descriptionTemplate);; if (this.item.descriptionTemplate?.definition) this.pageToFieldSetMap = this.mapPageToFieldSet(this.item.descriptionTemplate);;
@ -681,7 +681,7 @@ export class DescriptionEditorComponent extends BaseEditor<DescriptionEditorMode
this.initialTemplateId = descriptionTemplateId.toString(); this.initialTemplateId = descriptionTemplateId.toString();
this.editorModel.properties = new DescriptionPropertyDefinitionEditorModel(this.editorModel.validationErrorModel).fromModel(null, descriptionTemplate, null); this.editorModel.properties = new DescriptionPropertyDefinitionEditorModel(this.editorModel.validationErrorModel).fromModel(null, descriptionTemplate, null);
this.formGroup.setControl('properties', this.editorModel.buildProperties()); this.formGroup.setControl('properties', this.editorModel.buildProperties(this.visibilityRulesService));
this.item.descriptionTemplate = descriptionTemplate; this.item.descriptionTemplate = descriptionTemplate;
const sectionId = this.item.dmpDescriptionTemplate.sectionId; const sectionId = this.item.dmpDescriptionTemplate.sectionId;
@ -755,6 +755,8 @@ export class DescriptionEditorComponent extends BaseEditor<DescriptionEditorMode
finalize() { finalize() {
this.formService.removeAllBackEndErrors(this.formGroup); this.formService.removeAllBackEndErrors(this.formGroup);
this.formService.touchAllFormFields(this.formGroup); this.formService.touchAllFormFields(this.formGroup);
this.formService.validateAllFormFields(this.formGroup);
this.tocValidationService.validateForm(); this.tocValidationService.validateForm();
if (!this.isFormValid()) { if (!this.isFormValid()) {
this.dialog.open(FormValidationErrorsDialogComponent, { this.dialog.open(FormValidationErrorsDialogComponent, {

View File

@ -1,15 +1,17 @@
import { FormControl, UntypedFormArray, UntypedFormBuilder, UntypedFormGroup, Validators } from "@angular/forms"; import { FormControl, UntypedFormArray, UntypedFormBuilder, UntypedFormGroup, Validators } from "@angular/forms";
import { DescriptionStatus } from "@app/core/common/enum/description-status"; import { DescriptionStatus } from "@app/core/common/enum/description-status";
import { DescriptionTemplateFieldType } from "@app/core/common/enum/description-template-field-type"; import { DescriptionTemplateFieldType } from "@app/core/common/enum/description-template-field-type";
import { DescriptionTemplateFieldValidationType } from "@app/core/common/enum/description-template-field-validation-type";
import { IsActive } from "@app/core/common/enum/is-active.enum"; import { IsActive } from "@app/core/common/enum/is-active.enum";
import { DescriptionTemplate, DescriptionTemplateField, DescriptionTemplateFieldSet, DescriptionTemplateSection } from "@app/core/model/description-template/description-template"; 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"; import { Description, DescriptionExternalIdentifier, DescriptionExternalIdentifierPersist, 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 { ReferencePersist } from "@app/core/model/reference/reference";
import { BaseEditorModel } from "@common/base/base-form-editor-model"; import { BaseEditorModel } from "@common/base/base-form-editor-model";
import { BackendErrorValidator } from '@common/forms/validation/custom-validator'; import { BackendErrorValidator, RequiredWithVisibilityRulesValidator } from '@common/forms/validation/custom-validator';
import { ValidationErrorModel } from '@common/forms/validation/error-model/validation-error-model'; import { ValidationErrorModel } from '@common/forms/validation/error-model/validation-error-model';
import { Validation, ValidationContext } from '@common/forms/validation/validation-context'; import { Validation, ValidationContext } from '@common/forms/validation/validation-context';
import { Guid } from "@common/types/guid"; import { Guid } from "@common/types/guid";
import { VisibilityRulesService } from "./description-form/visibility-rules/visibility-rules.service";
export class DescriptionEditorModel extends BaseEditorModel implements DescriptionPersist { export class DescriptionEditorModel extends BaseEditorModel implements DescriptionPersist {
label: string; label: string;
@ -42,7 +44,7 @@ export class DescriptionEditorModel extends BaseEditorModel implements Descripti
return this; return this;
} }
buildForm(context: ValidationContext = null, disabled: boolean = false): UntypedFormGroup { buildForm(context: ValidationContext = null, disabled: boolean = false, visibilityRulesService: VisibilityRulesService): UntypedFormGroup {
if (context == null) { context = this.createValidationContext(); } if (context == null) { context = this.createValidationContext(); }
return this.formBuilder.group({ return this.formBuilder.group({
@ -54,14 +56,15 @@ export class DescriptionEditorModel extends BaseEditorModel implements Descripti
status: [{ value: this.status, disabled: disabled }, context.getValidation('status').validators], status: [{ value: this.status, disabled: disabled }, context.getValidation('status').validators],
description: [{ value: this.description, disabled: disabled }, context.getValidation('description').validators], description: [{ value: this.description, disabled: disabled }, context.getValidation('description').validators],
tags: [{ value: this.tags, disabled: disabled }, context.getValidation('tags').validators], tags: [{ value: this.tags, disabled: disabled }, context.getValidation('tags').validators],
properties: this.buildProperties(), properties: this.buildProperties(visibilityRulesService),
hash: [{ value: this.hash, disabled: disabled }, context.getValidation('hash').validators] hash: [{ value: this.hash, disabled: disabled }, context.getValidation('hash').validators]
}); });
} }
buildProperties() { buildProperties(visibilityRulesService: VisibilityRulesService) {
return this.properties.buildForm({ return this.properties.buildForm({
rootPath: `properties.` rootPath: `properties.`,
visibilityRulesService: visibilityRulesService
}); });
} }
@ -82,18 +85,37 @@ export class DescriptionEditorModel extends BaseEditorModel implements Descripti
return baseContext; return baseContext;
} }
static reApplyPropertiesValidators(params: { static getFieldValueControlName(fieldType: DescriptionTemplateFieldType, multipleSelect: boolean): string {
formGroup: UntypedFormGroup, switch (fieldType) {
validationErrorModel: ValidationErrorModel, case DescriptionTemplateFieldType.FREE_TEXT:
}): void { case DescriptionTemplateFieldType.TEXT_AREA:
case DescriptionTemplateFieldType.UPLOAD:
const { formGroup, validationErrorModel } = params; case DescriptionTemplateFieldType.RICH_TEXT_AREA:
const control = formGroup?.get('properties'); case DescriptionTemplateFieldType.RADIO_BOX:
DescriptionPropertyDefinitionEditorModel.reapplyValidators({ return 'textValue';
formGroup: control.get('fieldSets') as UntypedFormGroup, case DescriptionTemplateFieldType.DATASET_IDENTIFIER:
rootPath: `properties.`, case DescriptionTemplateFieldType.VALIDATION:
validationErrorModel: validationErrorModel return 'externalIdentifier';
}); case DescriptionTemplateFieldType.DATE_PICKER:
return 'dateValue';
case DescriptionTemplateFieldType.CHECK_BOX:
case DescriptionTemplateFieldType.BOOLEAN_DECISION:
return 'booleanValue';
case DescriptionTemplateFieldType.INTERNAL_ENTRIES_DESCRIPTIONS:
if (multipleSelect) return 'textListValue';
else return 'textValue';
case DescriptionTemplateFieldType.INTERNAL_ENTRIES_DMPS:
if (multipleSelect) return 'textListValue';
else return 'textValue';
case DescriptionTemplateFieldType.REFERENCE_TYPES:
if (multipleSelect) return 'references';
else return 'reference';
case DescriptionTemplateFieldType.SELECT:
if (multipleSelect) return 'textListValue';
else return 'textValue';
case DescriptionTemplateFieldType.TAGS:
return 'tags';
}
} }
} }
@ -113,7 +135,8 @@ export class DescriptionPropertyDefinitionEditorModel implements DescriptionProp
buildForm(params?: { buildForm(params?: {
context?: ValidationContext, context?: ValidationContext,
disabled?: boolean, disabled?: boolean,
rootPath?: string rootPath?: string,
visibilityRulesService: VisibilityRulesService
}): UntypedFormGroup { }): UntypedFormGroup {
let { context = null, disabled = false, rootPath } = params ?? {} let { context = null, disabled = false, rootPath } = params ?? {}
if (context == null) { if (context == null) {
@ -128,7 +151,8 @@ export class DescriptionPropertyDefinitionEditorModel implements DescriptionProp
const fieldSetsFormGroup = this.formBuilder.group({}); const fieldSetsFormGroup = this.formBuilder.group({});
if (this.fieldSets.size > 0) { if (this.fieldSets.size > 0) {
this.fieldSets.forEach((value, key) => fieldSetsFormGroup.addControl(key.toString(), value.buildForm({ this.fieldSets.forEach((value, key) => fieldSetsFormGroup.addControl(key.toString(), value.buildForm({
rootPath: `${rootPath}fieldSets[${key}].` rootPath: `${rootPath}fieldSets[${key}].`,
visibilityRulesService: params.visibilityRulesService
})), context.getValidation('fieldSets')); })), context.getValidation('fieldSets'));
formGroup.addControl('fieldSets', fieldSetsFormGroup); formGroup.addControl('fieldSets', fieldSetsFormGroup);
} }
@ -149,25 +173,6 @@ export class DescriptionPropertyDefinitionEditorModel implements DescriptionProp
return baseContext; return baseContext;
} }
static reapplyValidators(params: {
formGroup: UntypedFormGroup,
validationErrorModel: ValidationErrorModel,
rootPath: string
}): void {
const { formGroup, rootPath, validationErrorModel } = params;
const keys = Object.keys(formGroup.value as Object);
keys.forEach((key) => {
const formArray = formGroup?.get(key);
DescriptionPropertyDefinitionFieldSetEditorModel.reapplyValidators({
formArray: formArray.get('items') as UntypedFormArray,
rootPath: `${rootPath}fieldSets[${key}].`,
validationErrorModel: validationErrorModel
})
});
}
private calculateProperties(item: DescriptionPropertyDefinition, descriptionTemplate: DescriptionTemplate, descriptionReferences: DescriptionReference[]): Map<string, DescriptionPropertyDefinitionFieldSetEditorModel> { private calculateProperties(item: DescriptionPropertyDefinition, descriptionTemplate: DescriptionTemplate, descriptionReferences: DescriptionReference[]): Map<string, DescriptionPropertyDefinitionFieldSetEditorModel> {
let result: Map<string, DescriptionPropertyDefinitionFieldSetEditorModel> = new Map<string, DescriptionPropertyDefinitionFieldSetEditorModel>(); let result: Map<string, DescriptionPropertyDefinitionFieldSetEditorModel> = new Map<string, DescriptionPropertyDefinitionFieldSetEditorModel>();
if (descriptionTemplate) ( if (descriptionTemplate) (
@ -279,7 +284,8 @@ export class DescriptionPropertyDefinitionFieldSetEditorModel implements Descrip
buildForm(params?: { buildForm(params?: {
context?: ValidationContext, context?: ValidationContext,
disabled?: boolean, disabled?: boolean,
rootPath?: string rootPath?: string,
visibilityRulesService: VisibilityRulesService
}): UntypedFormGroup { }): UntypedFormGroup {
let { context = null, disabled = false, rootPath } = params ?? {} let { context = null, disabled = false, rootPath } = params ?? {}
if (context == null) { if (context == null) {
@ -293,7 +299,8 @@ export class DescriptionPropertyDefinitionFieldSetEditorModel implements Descrip
items: this.formBuilder.array( items: this.formBuilder.array(
(this.items ?? []).map( (this.items ?? []).map(
(item, index) => item.buildForm({ (item, index) => item.buildForm({
rootPath: `${rootPath}items[${index}].` rootPath: `${rootPath}items[${index}].`,
visibilityRulesService: params.visibilityRulesService
}) })
), context.getValidation('items').validators ), context.getValidation('items').validators
) )
@ -317,14 +324,18 @@ export class DescriptionPropertyDefinitionFieldSetEditorModel implements Descrip
static reapplyValidators(params: { static reapplyValidators(params: {
formArray: UntypedFormArray, formArray: UntypedFormArray,
validationErrorModel: ValidationErrorModel, validationErrorModel: ValidationErrorModel,
rootPath: string rootPath: string,
fieldSetDefinition: DescriptionTemplateFieldSet,
visibilityRulesService: VisibilityRulesService
}): void { }): void {
const { validationErrorModel, rootPath, formArray } = params; const { validationErrorModel, rootPath, formArray, fieldSetDefinition } = params;
formArray?.controls?.forEach( formArray?.controls?.forEach(
(control, index) => DescriptionPropertyDefinitionFieldSetItemEditorModel.reapplyValidators({ (control, index) => DescriptionPropertyDefinitionFieldSetItemEditorModel.reapplyValidators({
formGroup: control as UntypedFormGroup, formGroup: control as UntypedFormGroup,
rootPath: `${rootPath}items[${index}].`, rootPath: `${rootPath}items[${index}].`,
validationErrorModel: validationErrorModel validationErrorModel: validationErrorModel,
fieldSetDefinition: fieldSetDefinition,
visibilityRulesService: params.visibilityRulesService
}) })
); );
} }
@ -359,7 +370,8 @@ export class DescriptionPropertyDefinitionFieldSetItemEditorModel implements Des
buildForm(params?: { buildForm(params?: {
context?: ValidationContext, context?: ValidationContext,
disabled?: boolean, disabled?: boolean,
rootPath?: string rootPath?: string,
visibilityRulesService: VisibilityRulesService
}): UntypedFormGroup { }): UntypedFormGroup {
let { context = null, disabled = false, rootPath } = params ?? {} let { context = null, disabled = false, rootPath } = params ?? {}
if (context == null) { if (context == null) {
@ -376,7 +388,9 @@ export class DescriptionPropertyDefinitionFieldSetItemEditorModel implements Des
const fieldsFormGroup = this.formBuilder.group({}); const fieldsFormGroup = this.formBuilder.group({});
this.fields.forEach((value, key) => fieldsFormGroup.addControl(key.toString(), value.buildForm({ this.fields.forEach((value, key) => fieldsFormGroup.addControl(key.toString(), value.buildForm({
rootPath: `${rootPath}fields[${key}].` rootPath: `${rootPath}fields[${key}].`,
visibilityRulesService: params.visibilityRulesService,
visibilityRulesKey: key + '_' + formGroup.get('ordinal').value
})), context.getValidation('fields') })), context.getValidation('fields')
) )
formGroup.addControl('fields', fieldsFormGroup); formGroup.addControl('fields', fieldsFormGroup);
@ -403,10 +417,12 @@ export class DescriptionPropertyDefinitionFieldSetItemEditorModel implements Des
static reapplyValidators(params: { static reapplyValidators(params: {
formGroup: UntypedFormGroup, formGroup: UntypedFormGroup,
validationErrorModel: ValidationErrorModel, validationErrorModel: ValidationErrorModel,
rootPath: string rootPath: string,
fieldSetDefinition: DescriptionTemplateFieldSet,
visibilityRulesService: VisibilityRulesService
}): void { }): void {
const { formGroup, rootPath, validationErrorModel } = params; const { formGroup, rootPath, validationErrorModel, fieldSetDefinition } = params;
const context = DescriptionPropertyDefinitionFieldSetItemEditorModel.createValidationContext({ const context = DescriptionPropertyDefinitionFieldSetItemEditorModel.createValidationContext({
rootPath, rootPath,
validationErrorModel validationErrorModel
@ -419,7 +435,10 @@ export class DescriptionPropertyDefinitionFieldSetItemEditorModel implements Des
DescriptionFieldEditorModel.reapplyValidators({ DescriptionFieldEditorModel.reapplyValidators({
formGroup: control as UntypedFormGroup, formGroup: control as UntypedFormGroup,
rootPath: `${rootPath}fields[${key}].`, rootPath: `${rootPath}fields[${key}].`,
validationErrorModel: validationErrorModel validationErrorModel: validationErrorModel,
fieldDefinition: fieldSetDefinition.fields.find(x => x.id == key),
visibilityRulesService: params.visibilityRulesService,
visibilityRulesKey: key + '_' + formGroup.get('ordinal').value
}) })
}); });
@ -442,6 +461,8 @@ export class DescriptionFieldEditorModel implements DescriptionFieldPersist {
tags: string[] = []; tags: string[] = [];
externalIdentifier?: DescriptionExternalIdentifierEditorModel = new DescriptionExternalIdentifierEditorModel(this.validationErrorModel); externalIdentifier?: DescriptionExternalIdentifierEditorModel = new DescriptionExternalIdentifierEditorModel(this.validationErrorModel);
fieldDefinition: DescriptionTemplateField;
protected formBuilder: UntypedFormBuilder = new UntypedFormBuilder(); protected formBuilder: UntypedFormBuilder = new UntypedFormBuilder();
constructor( constructor(
@ -449,6 +470,7 @@ export class DescriptionFieldEditorModel implements DescriptionFieldPersist {
) { } ) { }
public fromModel(item: DescriptionField, descriptionTemplateField: DescriptionTemplateField, descriptionReferences: DescriptionReference[]): DescriptionFieldEditorModel { public fromModel(item: DescriptionField, descriptionTemplateField: DescriptionTemplateField, descriptionReferences: DescriptionReference[]): DescriptionFieldEditorModel {
this.fieldDefinition = descriptionTemplateField;
if (item) { if (item) {
this.textValue = item.textValue; this.textValue = item.textValue;
this.textListValue = item.textListValue; this.textListValue = item.textListValue;
@ -488,46 +510,89 @@ export class DescriptionFieldEditorModel implements DescriptionFieldPersist {
buildForm(params?: { buildForm(params?: {
context?: ValidationContext, context?: ValidationContext,
disabled?: boolean, disabled?: boolean,
rootPath?: string rootPath?: string,
visibilityRulesService: VisibilityRulesService,
visibilityRulesKey: string
}): UntypedFormGroup { }): UntypedFormGroup {
let { context = null, disabled = false, rootPath } = params ?? {} let { context = null, disabled = false, rootPath } = params ?? {}
if (context == null) { if (context == null) {
context = DescriptionFieldEditorModel.createValidationContext({ context = DescriptionFieldEditorModel.createValidationContext({
validationErrorModel: this.validationErrorModel, validationErrorModel: this.validationErrorModel,
rootPath rootPath,
fieldDefinition: this.fieldDefinition,
visibilityRulesService: params.visibilityRulesService,
visibilityRulesKey: params.visibilityRulesKey
}); });
} }
return this.formBuilder.group({ const fieldType = this.fieldDefinition.data.fieldType;
textValue: [{ value: this.textValue, disabled: disabled }, context.getValidation('textValue').validators], const multipleSelect = this.fieldDefinition.data.multipleSelect;
textListValue: [{ value: this.textListValue, disabled: disabled }, context.getValidation('textListValue').validators], const fieldValueControlName = DescriptionEditorModel.getFieldValueControlName(fieldType, multipleSelect);
dateValue: [{ value: this.dateValue, disabled: disabled }, context.getValidation('dateValue').validators], const formGroup = this.formBuilder.group({});
booleanValue: [{ value: this.booleanValue, disabled: disabled }, context.getValidation('booleanValue').validators], switch (fieldType) {
references: [{ value: this.references, disabled: disabled }, context.getValidation('references').validators], case DescriptionTemplateFieldType.FREE_TEXT:
reference: [{ value: this.reference, disabled: disabled }, context.getValidation('reference').validators], case DescriptionTemplateFieldType.TEXT_AREA:
tags: [{ value: this.tags, disabled: disabled }, context.getValidation('tags').validators], case DescriptionTemplateFieldType.UPLOAD:
externalIdentifier: this.externalIdentifier.buildForm({ case DescriptionTemplateFieldType.RICH_TEXT_AREA:
case DescriptionTemplateFieldType.RADIO_BOX:
formGroup.addControl(fieldValueControlName, new FormControl({ value: this.textValue, disabled: disabled }, context.getValidation(fieldValueControlName).validators));
case DescriptionTemplateFieldType.DATASET_IDENTIFIER:
case DescriptionTemplateFieldType.VALIDATION:
formGroup.addControl(fieldValueControlName, this.externalIdentifier.buildForm({
rootPath: `${rootPath}externalIdentifier.` rootPath: `${rootPath}externalIdentifier.`
}), }));
}); case DescriptionTemplateFieldType.DATE_PICKER:
formGroup.addControl(fieldValueControlName, new FormControl({ value: this.dateValue, disabled: disabled }, context.getValidation(fieldValueControlName).validators));
case DescriptionTemplateFieldType.CHECK_BOX:
case DescriptionTemplateFieldType.BOOLEAN_DECISION:
formGroup.addControl(fieldValueControlName, new FormControl({ value: this.booleanValue, disabled: disabled }, context.getValidation(fieldValueControlName).validators));
case DescriptionTemplateFieldType.INTERNAL_ENTRIES_DESCRIPTIONS:
if (multipleSelect) formGroup.addControl(fieldValueControlName, new FormControl({ value: this.textListValue, disabled: disabled }, context.getValidation(fieldValueControlName).validators));
else formGroup.addControl(fieldValueControlName, new FormControl({ value: this.textValue, disabled: disabled }, context.getValidation(fieldValueControlName).validators));
case DescriptionTemplateFieldType.INTERNAL_ENTRIES_DMPS:
if (multipleSelect) formGroup.addControl(fieldValueControlName, new FormControl({ value: this.textListValue, disabled: disabled }, context.getValidation(fieldValueControlName).validators));
else formGroup.addControl(fieldValueControlName, new FormControl({ value: this.textValue, disabled: disabled }, context.getValidation(fieldValueControlName).validators));
case DescriptionTemplateFieldType.REFERENCE_TYPES:
if (multipleSelect) formGroup.addControl(fieldValueControlName, new FormControl({ value: this.references, disabled: disabled }, context.getValidation(fieldValueControlName).validators));
else formGroup.addControl(fieldValueControlName, new FormControl({ value: this.reference, disabled: disabled }, context.getValidation(fieldValueControlName).validators));
case DescriptionTemplateFieldType.SELECT:
if (multipleSelect) formGroup.addControl(fieldValueControlName, new FormControl({ value: this.textListValue, disabled: disabled }, context.getValidation(fieldValueControlName).validators));
else formGroup.addControl(fieldValueControlName, new FormControl({ value: this.textValue, disabled: disabled }, context.getValidation(fieldValueControlName).validators));
case DescriptionTemplateFieldType.TAGS:
formGroup.addControl(fieldValueControlName, new FormControl({ value: this.tags, disabled: disabled }, context.getValidation(fieldValueControlName).validators));
}
return formGroup;
} }
static createValidationContext(params: { static createValidationContext(params: {
rootPath?: string, rootPath?: string,
validationErrorModel: ValidationErrorModel validationErrorModel: ValidationErrorModel,
fieldDefinition: DescriptionTemplateField,
visibilityRulesService: VisibilityRulesService,
visibilityRulesKey: string
}): ValidationContext { }): ValidationContext {
const { rootPath = '', validationErrorModel } = params; const { rootPath = '', validationErrorModel } = params;
const baseContext: ValidationContext = new ValidationContext(); const baseContext: ValidationContext = new ValidationContext();
const baseValidationArray: Validation[] = new Array<Validation>(); const baseValidationArray: Validation[] = new Array<Validation>();
baseValidationArray.push({ key: 'textValue', validators: [BackendErrorValidator(validationErrorModel, `${rootPath}textValue`)] });
baseValidationArray.push({ key: 'textListValue', validators: [BackendErrorValidator(validationErrorModel, `${rootPath}textListValue`)] }); const fieldValueControlName = DescriptionEditorModel.getFieldValueControlName(params.fieldDefinition.data.fieldType, params.fieldDefinition.data.multipleSelect);
baseValidationArray.push({ key: 'dateValue', validators: [BackendErrorValidator(validationErrorModel, `${rootPath}dateValue`)] }); const validators = [];
baseValidationArray.push({ key: 'booleanValue', validators: [BackendErrorValidator(validationErrorModel, `${rootPath}booleanValue`)] }); validators.push(BackendErrorValidator(validationErrorModel, `${rootPath}${fieldValueControlName}`));
baseValidationArray.push({ key: 'references', validators: [BackendErrorValidator(validationErrorModel, `${rootPath}references`)] });
baseValidationArray.push({ key: 'reference', validators: [BackendErrorValidator(validationErrorModel, `${rootPath}references`)] }); params.fieldDefinition.validations.forEach(validation => {
baseValidationArray.push({ key: 'tags', validators: [BackendErrorValidator(validationErrorModel, `${rootPath}tags`)] }); switch (validation) {
baseValidationArray.push({ key: 'externalIdentifier', validators: [BackendErrorValidator(validationErrorModel, `${rootPath}externalIdentifier`)] }); case DescriptionTemplateFieldValidationType.Required:
validators.push(RequiredWithVisibilityRulesValidator(params.visibilityRulesService, params.visibilityRulesKey));
break;
case DescriptionTemplateFieldValidationType.Url:
//TODO
break;
}
});
baseValidationArray.push({ key: fieldValueControlName, validators: validators });
baseContext.validation = baseValidationArray; baseContext.validation = baseValidationArray;
return baseContext; return baseContext;
} }
@ -535,13 +600,20 @@ export class DescriptionFieldEditorModel implements DescriptionFieldPersist {
static reapplyValidators(params: { static reapplyValidators(params: {
formGroup: UntypedFormGroup, formGroup: UntypedFormGroup,
validationErrorModel: ValidationErrorModel, validationErrorModel: ValidationErrorModel,
rootPath: string rootPath: string,
fieldDefinition: DescriptionTemplateField,
visibilityRulesService: VisibilityRulesService,
visibilityRulesKey: string
}): void { }): void {
const { formGroup, rootPath, validationErrorModel } = params; const { formGroup, rootPath, validationErrorModel, fieldDefinition } = params;
const context = DescriptionFieldEditorModel.createValidationContext({ const context = DescriptionFieldEditorModel.createValidationContext({
rootPath, rootPath,
validationErrorModel validationErrorModel,
fieldDefinition: fieldDefinition,
visibilityRulesService: params.visibilityRulesService,
visibilityRulesKey: params.visibilityRulesKey
}); });
['textValue', 'textListValue', 'dateValue', 'booleanValue'].forEach(keyField => { ['textValue', 'textListValue', 'dateValue', 'booleanValue'].forEach(keyField => {

View File

@ -86,7 +86,7 @@ export class DescriptionFormFieldSetComponent extends BaseComponent {
ordinal = Math.max(...properties.items.map(x => x.ordinal).filter(val => !isNaN(val))) + 1; ordinal = Math.max(...properties.items.map(x => x.ordinal).filter(val => !isNaN(val))) + 1;
} }
const item: DescriptionPropertyDefinitionFieldSetEditorModel = new DescriptionPropertyDefinitionEditorModel(this.validationErrorModel).calculateFieldSetProperties(this.fieldSet, ordinal, null, null); const item: DescriptionPropertyDefinitionFieldSetEditorModel = new DescriptionPropertyDefinitionEditorModel(this.validationErrorModel).calculateFieldSetProperties(this.fieldSet, ordinal, null, null);
formArray.push((item.buildForm({ rootPath: `properties.fieldSets[${this.fieldSet.id}].` }).get('items') as UntypedFormArray).at(0)); formArray.push((item.buildForm({ rootPath: `properties.fieldSets[${this.fieldSet.id}].`, visibilityRulesService: this.visibilityRulesService }).get('items') as UntypedFormArray).at(0));
this.visibilityRulesService.reloadVisibility(); this.visibilityRulesService.reloadVisibility();
} }
@ -102,7 +102,9 @@ export class DescriptionFormFieldSetComponent extends BaseComponent {
{ {
formArray: formArray, formArray: formArray,
validationErrorModel: this.validationErrorModel, validationErrorModel: this.validationErrorModel,
rootPath: `properties.fieldSets[${this.fieldSet.id}].` rootPath: `properties.fieldSets[${this.fieldSet.id}].`,
fieldSetDefinition: this.fieldSet,
visibilityRulesService: this.visibilityRulesService
} }
); );
formArray.markAsDirty(); formArray.markAsDirty();

View File

@ -11,7 +11,7 @@
<div class="col-12"> <div class="col-12">
<mat-form-field class="w-100"> <mat-form-field class="w-100">
<mat-label>{{ field.data.label }}</mat-label> <mat-label>{{ field.data.label }}</mat-label>
<input matInput [formControl]="propertiesFormGroup?.get(field.id).get('textValue')" placeholder="{{(field.data.label) + (isRequired? ' *': '')}}" [required]="isRequired"> <input matInput [formControl]="propertiesFormGroup?.get(field.id).get('textValue')" placeholder="{{(field.data.label) + (isRequired? ' *': '')}}" >
<mat-error *ngIf="propertiesFormGroup?.get(field.id).get('textValue').hasError('backendError')">{{propertiesFormGroup?.get(field.id).get('textValue').getError('backendError').message}}</mat-error> <mat-error *ngIf="propertiesFormGroup?.get(field.id).get('textValue').hasError('backendError')">{{propertiesFormGroup?.get(field.id).get('textValue').getError('backendError').message}}</mat-error>
<mat-error *ngIf="propertiesFormGroup?.get(field.id).get('textValue').hasError('required')">{{'GENERAL.VALIDATION.REQUIRED' | translate}}</mat-error> <mat-error *ngIf="propertiesFormGroup?.get(field.id).get('textValue').hasError('required')">{{'GENERAL.VALIDATION.REQUIRED' | translate}}</mat-error>
<mat-error *ngIf="propertiesFormGroup?.get(field.id).get('textValue').hasError('pattern')">{{'GENERAL.VALIDATION.URL.MESSAGE' | translate}}</mat-error> <mat-error *ngIf="propertiesFormGroup?.get(field.id).get('textValue').hasError('pattern')">{{'GENERAL.VALIDATION.URL.MESSAGE' | translate}}</mat-error>
@ -31,14 +31,14 @@
<div class="row"> <div class="row">
<mat-form-field class="col-md-12"> <mat-form-field class="col-md-12">
<ng-container *ngIf="field.data.multipleSelect"> <ng-container *ngIf="field.data.multipleSelect">
<mat-select [formControl]="propertiesFormGroup?.get(field.id).get('textListValue')" placeholder="{{ (field.data.label | translate) + (isRequired? ' *': '') }}" [required]="isRequired" [multiple]="field.data.multipleSelect"> <mat-select [formControl]="propertiesFormGroup?.get(field.id).get('textListValue')" placeholder="{{ (field.data.label | translate) + (isRequired? ' *': '') }}" [multiple]="field.data.multipleSelect">
<mat-option *ngFor="let opt of field.data.options" [value]="opt.value">{{opt.label}}</mat-option> <mat-option *ngFor="let opt of field.data.options" [value]="opt.value">{{opt.label}}</mat-option>
</mat-select> </mat-select>
<mat-error *ngIf="propertiesFormGroup?.get(field.id).get('textListValue').hasError('backendError')">{{propertiesFormGroup?.get(field.id).get('textListValue').getError('backendError').message}}</mat-error> <mat-error *ngIf="propertiesFormGroup?.get(field.id).get('textListValue').hasError('backendError')">{{propertiesFormGroup?.get(field.id).get('textListValue').getError('backendError').message}}</mat-error>
<mat-error *ngIf="propertiesFormGroup?.get(field.id).get('textListValue').hasError('required')">{{'GENERAL.VALIDATION.REQUIRED' | translate}}</mat-error> <mat-error *ngIf="propertiesFormGroup?.get(field.id).get('textListValue').hasError('required')">{{'GENERAL.VALIDATION.REQUIRED' | translate}}</mat-error>
</ng-container> </ng-container>
<ng-container *ngIf="!(field.data.multipleSelect)"> <ng-container *ngIf="!(field.data.multipleSelect)">
<mat-select [formControl]="propertiesFormGroup?.get(field.id).get('textValue')" placeholder="{{ (field.data.label | translate) + (isRequired? ' *': '') }}" [required]="isRequired" [multiple]="field.data.multipleSelect"> <mat-select [formControl]="propertiesFormGroup?.get(field.id).get('textValue')" placeholder="{{ (field.data.label | translate) + (isRequired? ' *': '') }}" [multiple]="field.data.multipleSelect">
<mat-option *ngFor="let opt of field.data.options" [value]="opt.value">{{opt.label}} <mat-option *ngFor="let opt of field.data.options" [value]="opt.value">{{opt.label}}
</mat-option> </mat-option>
</mat-select> </mat-select>
@ -63,7 +63,7 @@
<ng-container *ngIf="!(field.data.multipleSelect)"> <ng-container *ngIf="!(field.data.multipleSelect)">
<mat-form-field class="col-md-12"> <mat-form-field class="col-md-12">
<mat-label>{{ field.data.label }}</mat-label> <mat-label>{{ field.data.label }}</mat-label>
<app-single-auto-complete placeholder="{{ (field.data.label | translate) + (isRequired? ' *': '') }}" [formControl]="propertiesFormGroup?.get(field.id).get('textValue')" [configuration]="descriptionService.singleAutocompleteConfiguration" [required]="isRequired"> <app-single-auto-complete placeholder="{{ (field.data.label | translate) + (isRequired? ' *': '') }}" [formControl]="propertiesFormGroup?.get(field.id).get('textValue')" [configuration]="descriptionService.singleAutocompleteConfiguration" >
</app-single-auto-complete> </app-single-auto-complete>
<mat-error *ngIf="propertiesFormGroup?.get(field.id).get('textValue').hasError('backendError')">{{propertiesFormGroup?.get(field.id).get('textValue').getError('backendError').message}}</mat-error> <mat-error *ngIf="propertiesFormGroup?.get(field.id).get('textValue').hasError('backendError')">{{propertiesFormGroup?.get(field.id).get('textValue').getError('backendError').message}}</mat-error>
<mat-error *ngIf="propertiesFormGroup?.get(field.id).get('textValue').hasError('required')">{{'GENERAL.VALIDATION.REQUIRED' | translate}}</mat-error> <mat-error *ngIf="propertiesFormGroup?.get(field.id).get('textValue').hasError('required')">{{'GENERAL.VALIDATION.REQUIRED' | translate}}</mat-error>
@ -87,7 +87,7 @@
<ng-container *ngIf="!(field.data.multipleSelect)"> <ng-container *ngIf="!(field.data.multipleSelect)">
<mat-form-field class="col-md-12"> <mat-form-field class="col-md-12">
<mat-label>{{ field.data.label }}</mat-label> <mat-label>{{ field.data.label }}</mat-label>
<app-single-auto-complete placeholder="{{ (field.data.label | translate) + (isRequired? ' *': '') }}" [formControl]="propertiesFormGroup?.get(field.id).get('textValue')" [configuration]="dmpService.singleAutocompleteConfiguration" [required]="isRequired"> <app-single-auto-complete placeholder="{{ (field.data.label | translate) + (isRequired? ' *': '') }}" [formControl]="propertiesFormGroup?.get(field.id).get('textValue')" [configuration]="dmpService.singleAutocompleteConfiguration" >
</app-single-auto-complete> </app-single-auto-complete>
<mat-error *ngIf="propertiesFormGroup?.get(field.id).get('textValue').hasError('backendError')">{{propertiesFormGroup?.get(field.id).get('textValue').getError('backendError').message}}</mat-error> <mat-error *ngIf="propertiesFormGroup?.get(field.id).get('textValue').hasError('backendError')">{{propertiesFormGroup?.get(field.id).get('textValue').getError('backendError').message}}</mat-error>
<mat-error *ngIf="propertiesFormGroup?.get(field.id).get('textValue').hasError('required')">{{'GENERAL.VALIDATION.REQUIRED' | translate}}</mat-error> <mat-error *ngIf="propertiesFormGroup?.get(field.id).get('textValue').hasError('required')">{{'GENERAL.VALIDATION.REQUIRED' | translate}}</mat-error>
@ -105,7 +105,7 @@
<div class="col-12"> <div class="col-12">
<mat-form-field *ngSwitchCase="descriptionTemplateFieldTypeEnum.TEXT_AREA" class="w-100"> <mat-form-field *ngSwitchCase="descriptionTemplateFieldTypeEnum.TEXT_AREA" class="w-100">
<mat-label>{{ field.data.label }}</mat-label> <mat-label>{{ field.data.label }}</mat-label>
<textarea matInput class="text-area" [formControl]="propertiesFormGroup?.get(field.id).get('textValue')" matTextareaAutosize matAutosizeMinRows="3" matAutosizeMaxRows="15" [required]="isRequired" placeholder="{{ (field.data.label | translate) + (isRequired? ' *': '') }}"></textarea> <textarea matInput class="text-area" [formControl]="propertiesFormGroup?.get(field.id).get('textValue')" matTextareaAutosize matAutosizeMinRows="3" matAutosizeMaxRows="15" placeholder="{{ (field.data.label | translate) + (isRequired? ' *': '') }}"></textarea>
<button mat-icon-button type="button" *ngIf="!propertiesFormGroup?.get(field.id).get('textValue').disabled && propertiesFormGroup?.get(field.id).get('textValue').value" matSuffix aria-label="Clear" (click)="this.propertiesFormGroup?.get(field.id).get('textValue').patchValue('')"> <button mat-icon-button type="button" *ngIf="!propertiesFormGroup?.get(field.id).get('textValue').disabled && propertiesFormGroup?.get(field.id).get('textValue').value" matSuffix aria-label="Clear" (click)="this.propertiesFormGroup?.get(field.id).get('textValue').patchValue('')">
<mat-icon>close</mat-icon> <mat-icon>close</mat-icon>
</button> </button>
@ -116,7 +116,7 @@
<ng-container *ngSwitchCase="descriptionTemplateFieldTypeEnum.RICH_TEXT_AREA"> <ng-container *ngSwitchCase="descriptionTemplateFieldTypeEnum.RICH_TEXT_AREA">
<div class="col-12"> <div class="col-12">
<rich-text-editor-component [form]="propertiesFormGroup?.get(field.id).get('textValue')" [placeholder]="field.data.label" [required]="isRequired" [wrapperClasses]="'full-width editor ' + <rich-text-editor-component [form]="propertiesFormGroup?.get(field.id).get('textValue')" [placeholder]="field.data.label" [wrapperClasses]="'full-width editor ' +
((isRequired && propertiesFormGroup?.get(field.id).get('textValue').touched && propertiesFormGroup?.get(field.id).get('textValue').hasError('required')) ? 'required' : '')" [editable]="!propertiesFormGroup?.get(field.id).get('textValue').disabled"> ((isRequired && propertiesFormGroup?.get(field.id).get('textValue').touched && propertiesFormGroup?.get(field.id).get('textValue').hasError('required')) ? 'required' : '')" [editable]="!propertiesFormGroup?.get(field.id).get('textValue').disabled">
</rich-text-editor-component> </rich-text-editor-component>
</div> </div>
@ -148,7 +148,7 @@
</div> </div>
</ng-container> </ng-container>
<div *ngSwitchCase="descriptionTemplateFieldTypeEnum.BOOLEAN_DECISION" class="col-12"> <div *ngSwitchCase="descriptionTemplateFieldTypeEnum.BOOLEAN_DECISION" class="col-12">
<mat-radio-group [formControl]="propertiesFormGroup?.get(field.id).get('booleanValue')" [required]="isRequired"> <mat-radio-group [formControl]="propertiesFormGroup?.get(field.id).get('booleanValue')" >
<mat-radio-button class="radio-button-item" [value]="true">{{ "TYPES.DATASET-PROFILE-COMBO-BOX-TYPE.ACTIONS.YES" | translate }}</mat-radio-button> <mat-radio-button class="radio-button-item" [value]="true">{{ "TYPES.DATASET-PROFILE-COMBO-BOX-TYPE.ACTIONS.YES" | translate }}</mat-radio-button>
<mat-radio-button class="radio-button-item" [value]="false">{{ "TYPES.DATASET-PROFILE-COMBO-BOX-TYPE.ACTIONS.NO" | translate }}</mat-radio-button> <mat-radio-button class="radio-button-item" [value]="false">{{ "TYPES.DATASET-PROFILE-COMBO-BOX-TYPE.ACTIONS.NO" | translate }}</mat-radio-button>
<mat-error *ngIf="propertiesFormGroup?.get(field.id).get('booleanValue').hasError('backendError')">{{propertiesFormGroup?.get(field.id).get('booleanValue').getError('backendError').message}}</mat-error> <mat-error *ngIf="propertiesFormGroup?.get(field.id).get('booleanValue').hasError('backendError')">{{propertiesFormGroup?.get(field.id).get('booleanValue').getError('backendError').message}}</mat-error>
@ -159,7 +159,7 @@
</div> </div>
<div *ngSwitchCase="descriptionTemplateFieldTypeEnum.RADIO_BOX" class="col-12"> <div *ngSwitchCase="descriptionTemplateFieldTypeEnum.RADIO_BOX" class="col-12">
<mat-radio-group [formControl]="propertiesFormGroup?.get(field.id).get('textValue')" [required]="isRequired"> <mat-radio-group [formControl]="propertiesFormGroup?.get(field.id).get('textValue')" >
<mat-radio-button *ngFor="let option of field.data.options let index = index" class="radio-button-item" [value]="option.value">{{option.label}}</mat-radio-button> <mat-radio-button *ngFor="let option of field.data.options let index = index" class="radio-button-item" [value]="option.value">{{option.label}}</mat-radio-button>
<mat-error *ngIf="propertiesFormGroup?.get(field.id).get('textValue').hasError('backendError')">{{propertiesFormGroup?.get(field.id).get('textValue').getError('backendError').message}}</mat-error> <mat-error *ngIf="propertiesFormGroup?.get(field.id).get('textValue').hasError('backendError')">{{propertiesFormGroup?.get(field.id).get('textValue').getError('backendError').message}}</mat-error>
</mat-radio-group> </mat-radio-group>
@ -170,7 +170,7 @@
<mat-form-field *ngSwitchCase="descriptionTemplateFieldTypeEnum.DATE_PICKER" class="col-12"> <mat-form-field *ngSwitchCase="descriptionTemplateFieldTypeEnum.DATE_PICKER" class="col-12">
<mat-label>{{ field.data.label }}</mat-label> <mat-label>{{ field.data.label }}</mat-label>
<input matInput placeholder="{{ (field.data.label | translate) + (isRequired? ' *': '') }}" class="table-input" [matDatepicker]="date" [required]="isRequired" [formControl]="propertiesFormGroup?.get(field.id).get('dateValue')"> <input matInput placeholder="{{ (field.data.label | translate) + (isRequired? ' *': '') }}" class="table-input" [matDatepicker]="date" [formControl]="propertiesFormGroup?.get(field.id).get('dateValue')">
<mat-datepicker-toggle matSuffix [for]="date"></mat-datepicker-toggle> <mat-datepicker-toggle matSuffix [for]="date"></mat-datepicker-toggle>
<mat-datepicker #date></mat-datepicker> <mat-datepicker #date></mat-datepicker>
<mat-error *ngIf="propertiesFormGroup?.get(field.id).get('dateValue').hasError('backendError')">{{propertiesFormGroup?.get(field.id).get('dateValue').getError('backendError').message}}</mat-error> <mat-error *ngIf="propertiesFormGroup?.get(field.id).get('dateValue').hasError('backendError')">{{propertiesFormGroup?.get(field.id).get('dateValue').getError('backendError').message}}</mat-error>
@ -185,13 +185,13 @@
<div class="row" *ngIf="datasetIdInitialized"> <div class="row" *ngIf="datasetIdInitialized">
<mat-form-field class="col-md-12"> <mat-form-field class="col-md-12">
<mat-label>{{ field.data.label }}</mat-label> <mat-label>{{ field.data.label }}</mat-label>
<input matInput class="col-md-12" [formControl]="propertiesFormGroup?.get(field.id).get('externalIdentifier')?.get('identifier')" placeholder="{{(field.data.label) + (isRequired? ' *': '')}}" [required]="isRequired" [disabled]="propertiesFormGroup?.get(field.id).get('externalIdentifier')?.get('identifier').disabled"> <input matInput class="col-md-12" [formControl]="propertiesFormGroup?.get(field.id).get('externalIdentifier')?.get('identifier')" placeholder="{{(field.data.label) + (isRequired? ' *': '')}}" [disabled]="propertiesFormGroup?.get(field.id).get('externalIdentifier')?.get('identifier').disabled">
<mat-error *ngIf="propertiesFormGroup?.get(field.id).get('externalIdentifier')?.get('identifier').hasError('backendError')">{{propertiesFormGroup?.get(field.id).get('externalIdentifier')?.get('identifier').getError('backendError').message}}</mat-error> <mat-error *ngIf="propertiesFormGroup?.get(field.id).get('externalIdentifier')?.get('identifier').hasError('backendError')">{{propertiesFormGroup?.get(field.id).get('externalIdentifier')?.get('identifier').getError('backendError').message}}</mat-error>
<mat-error *ngIf="propertiesFormGroup?.get(field.id).get('externalIdentifier')?.get('identifier').hasError('required')">{{'GENERAL.VALIDATION.REQUIRED' | translate}}</mat-error> <mat-error *ngIf="propertiesFormGroup?.get(field.id).get('externalIdentifier')?.get('identifier').hasError('required')">{{'GENERAL.VALIDATION.REQUIRED' | translate}}</mat-error>
</mat-form-field> </mat-form-field>
<mat-form-field class="col-md-12"> <mat-form-field class="col-md-12">
<mat-label>{{ field.data.label }}</mat-label> <mat-label>{{ field.data.label }}</mat-label>
<mat-select class="col-md-12" [formControl]="propertiesFormGroup?.get(field.id).get('externalIdentifier')?.get('type')" [placeholder]="('TYPES.DATASET-PROFILE-IDENTIFIER.IDENTIFIER-TYPE' | translate) + (isRequired? ' *': '')" [required]="isRequired" [disabled]="propertiesFormGroup?.get(field.id).get('externalIdentifier')?.get('type').disabled"> <mat-select class="col-md-12" [formControl]="propertiesFormGroup?.get(field.id).get('externalIdentifier')?.get('type')" [placeholder]="('TYPES.DATASET-PROFILE-IDENTIFIER.IDENTIFIER-TYPE' | translate) + (isRequired? ' *': '')" [disabled]="propertiesFormGroup?.get(field.id).get('externalIdentifier')?.get('type').disabled">
<mat-option *ngFor="let type of datasetIdTypes" [value]="type.value"> <mat-option *ngFor="let type of datasetIdTypes" [value]="type.value">
{{ type.name }} {{ type.name }}
</mat-option> </mat-option>
@ -206,7 +206,7 @@
<div class="row align-items-baseline"> <div class="row align-items-baseline">
<mat-form-field class="col-md-4"> <mat-form-field class="col-md-4">
<mat-label>{{ field.data.label }}</mat-label> <mat-label>{{ field.data.label }}</mat-label>
<input matInput class="col-md-12" [formControl]="propertiesFormGroup?.get(field.id).get('externalIdentifier')?.get('identifier')" placeholder="{{(field.data.label) + (isRequired? ' *': '')}}" [required]="isRequired"> <input matInput class="col-md-12" [formControl]="propertiesFormGroup?.get(field.id).get('externalIdentifier')?.get('identifier')" placeholder="{{(field.data.label) + (isRequired? ' *': '')}}" >
<mat-error *ngIf="propertiesFormGroup?.get(field.id).get('externalIdentifier')?.get('identifier').hasError('backendError')">{{propertiesFormGroup?.get(field.id).get('externalIdentifier')?.get('identifier').getError('backendError').message}}</mat-error> <mat-error *ngIf="propertiesFormGroup?.get(field.id).get('externalIdentifier')?.get('identifier').hasError('backendError')">{{propertiesFormGroup?.get(field.id).get('externalIdentifier')?.get('identifier').getError('backendError').message}}</mat-error>
<mat-error *ngIf="propertiesFormGroup?.get(field.id).get('externalIdentifier')?.get('identifier').hasError('required')">{{'GENERAL.VALIDATION.REQUIRED' | translate}}</mat-error> <mat-error *ngIf="propertiesFormGroup?.get(field.id).get('externalIdentifier')?.get('identifier').hasError('required')">{{'GENERAL.VALIDATION.REQUIRED' | translate}}</mat-error>
</mat-form-field> </mat-form-field>

View File

@ -80,11 +80,12 @@ export class FormProgressIndicationComponent extends BaseComponent implements On
countRequiredFieldsByFieldset(ordinal: number, fieldsFormGroup: UntypedFormGroup, filterValid: boolean = false): number { countRequiredFieldsByFieldset(ordinal: number, fieldsFormGroup: UntypedFormGroup, filterValid: boolean = false): number {
let fieldsCount: number = 0; let fieldsCount: number = 0;
const fieldNames = Object.keys(fieldsFormGroup.controls); const fieldSetNames = Object.keys(fieldsFormGroup.controls);
for(let item of fieldNames) { for(let item of fieldSetNames) {
if (!this.checkVisibility || this.visibilityRulesService.isVisible(item, ordinal)) { if (!this.checkVisibility || this.visibilityRulesService.isVisible(item, ordinal)) {
const fieldControl = fieldsFormGroup.get(item); const fieldControl = fieldsFormGroup.get(item);
for (let fieldType of this.fieldTypes) { const fieldNames = Object.keys((fieldControl as UntypedFormGroup).controls);
for (let fieldType of fieldNames) {
const typedControl = fieldControl.get(fieldType); const typedControl = fieldControl.get(fieldType);
let controlFilter: boolean = this.controlRequired(typedControl) && this.controlEnabled(typedControl); let controlFilter: boolean = this.controlRequired(typedControl) && this.controlEnabled(typedControl);
if (filterValid) controlFilter = controlFilter && typedControl.valid; if (filterValid) controlFilter = controlFilter && typedControl.valid;

View File

@ -4,7 +4,6 @@
<div *ngIf="showItem(groupMenuItem);"> <div *ngIf="showItem(groupMenuItem);">
<hr *ngIf="!firstGroup"> <hr *ngIf="!firstGroup">
<mat-list-item routerLinkActive="active" [isActiveMatchOptions]="{ paths: 'exact', queryParams: 'ignored' }" *ngFor="let groupMenuRoute of groupMenuItem.routes; let first = first" class="nav-item" [ngClass]="{'mt-4': first && firstGroup}"> <mat-list-item routerLinkActive="active" [isActiveMatchOptions]="{ paths: 'exact', queryParams: 'ignored' }" *ngFor="let groupMenuRoute of groupMenuItem.routes; let first = first" class="nav-item" [ngClass]="{'mt-4': first && firstGroup}">
<!-- {{ groupMenuRoute |json }} -->
<a class="new-dmp nav-link nav-row" *ngIf="groupMenuRoute.path !== '/contact-support' && groupMenuRoute.path !== '/co-branding' && groupMenuRoute.path !== '/feedback' && groupMenuRoute.path !== '/descriptions'" [routerLink]="[groupMenuRoute.path]" [ngClass]="{'dmp-tour': groupMenuRoute.path == '/plans'}"> <a class="new-dmp nav-link nav-row" *ngIf="groupMenuRoute.path !== '/contact-support' && groupMenuRoute.path !== '/co-branding' && groupMenuRoute.path !== '/feedback' && groupMenuRoute.path !== '/descriptions'" [routerLink]="[groupMenuRoute.path]" [ngClass]="{'dmp-tour': groupMenuRoute.path == '/plans'}">
<i class="material-symbols-outlined icon">{{ groupMenuRoute.icon }}</i> <i class="material-symbols-outlined icon">{{ groupMenuRoute.icon }}</i>
<i *ngIf="groupMenuRoute.path == '/plans'" class="material-symbols-outlined icon-mask">person</i> <i *ngIf="groupMenuRoute.path == '/plans'" class="material-symbols-outlined icon-mask">person</i>

View File

@ -1,5 +1,3 @@
<!-- {{ userCredentials | async | json }} -->
<div class="profile"> <div class="profile">
<div class="container-fluid"> <div class="container-fluid">
<div *ngIf="user | async as userProfile; else loading" class="user-profile"> <div *ngIf="user | async as userProfile; else loading" class="user-profile">

View File

@ -2,6 +2,7 @@ import { AbstractControl, UntypedFormArray, UntypedFormGroup, ValidatorFn, Valid
import { ValidationErrorModel } from '@common/forms/validation/error-model/validation-error-model'; import { ValidationErrorModel } from '@common/forms/validation/error-model/validation-error-model';
import { isNullOrUndefined } from '@app/utilities/enhancers/utils'; import { isNullOrUndefined } from '@app/utilities/enhancers/utils';
import { DmpBlueprintSystemFieldType } from '@app/core/common/enum/dmp-blueprint-system-field-type'; import { DmpBlueprintSystemFieldType } from '@app/core/common/enum/dmp-blueprint-system-field-type';
import { VisibilityRulesService } from '@app/ui/description/editor/description-form/visibility-rules/visibility-rules.service';
export function BackendErrorValidator(errorModel: ValidationErrorModel, propertyName: string): ValidatorFn { export function BackendErrorValidator(errorModel: ValidationErrorModel, propertyName: string): ValidatorFn {
return (control: AbstractControl): { [key: string]: any } => { return (control: AbstractControl): { [key: string]: any } => {
@ -29,6 +30,17 @@ export function CustomErrorValidator(errorModel: ValidationErrorModel, propertyN
}; };
} }
export function RequiredWithVisibilityRulesValidator(visibilityRulesService: VisibilityRulesService, visibilityRulesKey: string) {
return (control: AbstractControl): { [key: string]: any } => {
if(visibilityRulesService.isVisibleMap[visibilityRulesKey] ?? true) {
return Validators.required(control);
}
control.setErrors(null);
return null;
};
}
export function DateValidator(): ValidatorFn { export function DateValidator(): ValidatorFn {
return (control: AbstractControl): { [key: string]: any } => { return (control: AbstractControl): { [key: string]: any } => {
if (control.value) { if (control.value) {
@ -108,20 +120,20 @@ export function DmpBlueprintSystemFieldRequiredValidator(): ValidatorFn {
let foundAccess = false; let foundAccess = false;
const sectionsFormArray = (control as UntypedFormArray); const sectionsFormArray = (control as UntypedFormArray);
if (sectionsFormArray.controls != null && sectionsFormArray.controls.length > 0 ){ if (sectionsFormArray.controls != null && sectionsFormArray.controls.length > 0) {
sectionsFormArray.controls.forEach((section, index) => { sectionsFormArray.controls.forEach((section, index) => {
const fieldsFormArray = section.get('fields') as UntypedFormArray; const fieldsFormArray = section.get('fields') as UntypedFormArray;
if (fieldsFormArray && fieldsFormArray.length > 0){ if (fieldsFormArray && fieldsFormArray.length > 0) {
if (fieldsFormArray.controls.some(y => (y as UntypedFormGroup).get('systemFieldType')?.value === DmpBlueprintSystemFieldType.Title)){ if (fieldsFormArray.controls.some(y => (y as UntypedFormGroup).get('systemFieldType')?.value === DmpBlueprintSystemFieldType.Title)) {
foundTitle = true; foundTitle = true;
} }
if (fieldsFormArray.controls.some(y => (y as UntypedFormGroup).get('systemFieldType')?.value === DmpBlueprintSystemFieldType.Description)){ if (fieldsFormArray.controls.some(y => (y as UntypedFormGroup).get('systemFieldType')?.value === DmpBlueprintSystemFieldType.Description)) {
foundDescription = true; foundDescription = true;
} }
if (fieldsFormArray.controls.some(y => (y as UntypedFormGroup).get('systemFieldType')?.value === DmpBlueprintSystemFieldType.Language)){ if (fieldsFormArray.controls.some(y => (y as UntypedFormGroup).get('systemFieldType')?.value === DmpBlueprintSystemFieldType.Language)) {
foundLanguage = true; foundLanguage = true;
} }
if (fieldsFormArray.controls.some(y => (y as UntypedFormGroup).get('systemFieldType')?.value === DmpBlueprintSystemFieldType.AccessRights)){ if (fieldsFormArray.controls.some(y => (y as UntypedFormGroup).get('systemFieldType')?.value === DmpBlueprintSystemFieldType.AccessRights)) {
foundAccess = true; foundAccess = true;
} }
} }