bug fix on description-editor progress-count

This commit is contained in:
Sofia Papacharalampous 2024-06-14 17:48:47 +03:00
parent 4253727f8e
commit e6f053a62a
4 changed files with 41 additions and 13 deletions
dmp-frontend/src
app/ui/description/editor
common/forms/validation

View File

@ -7,7 +7,7 @@ import { DescriptionTemplate, DescriptionTemplateField, DescriptionTemplateField
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 { BaseEditorModel } from "@common/base/base-form-editor-model";
import { BackendErrorValidator, RequiredWithVisibilityRulesValidator, UrlValidator } from '@common/forms/validation/custom-validator';
import { BackendErrorValidator, CustomValidators, RequiredWithVisibilityRulesValidator, UrlValidator } from '@common/forms/validation/custom-validator';
import { ValidationErrorModel } from '@common/forms/validation/error-model/validation-error-model';
import { Validation, ValidationContext } from '@common/forms/validation/validation-context';
import { Guid } from "@common/types/guid";
@ -72,11 +72,11 @@ export class DescriptionEditorModel extends BaseEditorModel implements Descripti
const baseContext: ValidationContext = new ValidationContext();
const baseValidationArray: Validation[] = new Array<Validation>();
baseValidationArray.push({ key: 'id', validators: [BackendErrorValidator(this.validationErrorModel, 'id')] });
baseValidationArray.push({ key: 'label', validators: [Validators.required, BackendErrorValidator(this.validationErrorModel, 'label')] });
baseValidationArray.push({ key: 'dmpId', validators: [Validators.required, BackendErrorValidator(this.validationErrorModel, 'dmpId')] });
baseValidationArray.push({ key: 'dmpDescriptionTemplateId', validators: [Validators.required, BackendErrorValidator(this.validationErrorModel, 'dmpDescriptionTemplateId')] });
baseValidationArray.push({ key: 'descriptionTemplateId', validators: [Validators.required, BackendErrorValidator(this.validationErrorModel, 'descriptionTemplateId')] });
baseValidationArray.push({ key: 'status', validators: [Validators.required, BackendErrorValidator(this.validationErrorModel, 'status')] });
baseValidationArray.push({ key: 'label', validators: [CustomValidators.required(), BackendErrorValidator(this.validationErrorModel, 'label')] });
baseValidationArray.push({ key: 'dmpId', validators: [CustomValidators.required(), BackendErrorValidator(this.validationErrorModel, 'dmpId')] });
baseValidationArray.push({ key: 'dmpDescriptionTemplateId', validators: [CustomValidators.required(), BackendErrorValidator(this.validationErrorModel, 'dmpDescriptionTemplateId')] });
baseValidationArray.push({ key: 'descriptionTemplateId', validators: [CustomValidators.required(), BackendErrorValidator(this.validationErrorModel, 'descriptionTemplateId')] });
baseValidationArray.push({ key: 'status', validators: [CustomValidators.required(), BackendErrorValidator(this.validationErrorModel, 'status')] });
baseValidationArray.push({ key: 'description', validators: [BackendErrorValidator(this.validationErrorModel, 'description')] });
baseValidationArray.push({ key: 'tags', validators: [BackendErrorValidator(this.validationErrorModel, 'tags')] });
baseValidationArray.push({ key: 'hash', validators: [] });
@ -602,7 +602,7 @@ export class DescriptionFieldEditorModel implements DescriptionFieldPersist {
params.fieldDefinition.validations.forEach(validation => {
switch (validation) {
case DescriptionTemplateFieldValidationType.Required:
validators.push(RequiredWithVisibilityRulesValidator(params.visibilityRulesService, params.visibilityRulesKey));
validators.push(CustomValidators.RequiredWithVisibilityRulesValidator(params.visibilityRulesService, params.visibilityRulesKey));
break;
case DescriptionTemplateFieldValidationType.Url:
validators.push(UrlValidator());

View File

@ -1,10 +1,11 @@
import {ChangeDetectorRef, Component, ElementRef, Input, OnChanges, OnInit, SimpleChanges} from '@angular/core';
import { AbstractControl, UntypedFormArray, UntypedFormControl, UntypedFormGroup } from '@angular/forms';
import { AbstractControl, FormControl, UntypedFormArray, UntypedFormControl, UntypedFormGroup, Validators } from '@angular/forms';
import { VisibilityRulesService } from '@app/ui/description/editor/description-form/visibility-rules/visibility-rules.service';
import { BaseComponent } from '@common/base/base.component';
import { takeUntil } from 'rxjs/operators';
import { DescriptionEditorModel } from '../description-editor.model';
import { nameof } from 'ts-simple-nameof';
import { BackendErrorValidator, MarkedValidatorFn } from '@common/forms/validation/custom-validator';
@Component({
selector: 'app-form-progress-indication',
@ -216,10 +217,8 @@ export class FormProgressIndicationComponent extends BaseComponent implements On
controlRequired(formControl: AbstractControl) {
if (formControl.validator) {
const validator = formControl.validator({} as AbstractControl);
if (validator && validator.required) {
return true;
}
const validators = (formControl as AbstractControl & { _rawValidators: MarkedValidatorFn[] })._rawValidators;
return validators.some(validator => validator.type === 'RequiredWithVisibilityRulesValidator');
}
return false;

View File

@ -141,7 +141,7 @@ export class TableOfContentsComponent extends BaseComponent implements OnInit, O
takeUntil(this._destroyed),
mergeMap((entries: IntersectionObserverEntry[]) => entries),
filter(entry => entry.isIntersecting),
debounceTime(600),
debounceTime(300),
distinctUntilChanged(),
).subscribe(x => {
if (x.isIntersecting) {

View File

@ -5,6 +5,35 @@ import { DmpBlueprintSystemFieldType } from '@app/core/common/enum/dmp-blueprint
import { VisibilityRulesService } from '@app/ui/description/editor/description-form/visibility-rules/visibility-rules.service';
import { FormService } from '../form-service';
export type MarkedValidatorFn = ValidatorFn & { type: string, metadata: unknown };
// **Workaround for Angular limitation:**
// Angular's 'hasValidator' method has a limitation https://v17.angular.io/api/forms/AbstractControl#hasValidator
// when counting different controls of the same validator
// To address this we followed the approach discussed here https://github.com/angular/angular/issues/54305
export class CustomValidators {
static extendValidatorWithMetadata(validatorFn: ValidatorFn, type: string, metadata?: unknown): MarkedValidatorFn {
const fn = validatorFn as MarkedValidatorFn;
fn.type = type;
fn.metadata = metadata;
return fn;
}
static required = (): MarkedValidatorFn => this.extendValidatorWithMetadata(Validators.required, 'required');
static RequiredWithVisibilityRulesValidator(visibilityRulesService: VisibilityRulesService, visibilityRulesKey: string) {
return this.extendValidatorWithMetadata((control: UntypedFormControl): { [key: string]: any } => {
if (visibilityRulesService.isVisibleMap[visibilityRulesKey] ?? true) {
return Validators.required(control) ;
}
FormService.removeError(control, 'required');
return null;
}, 'RequiredWithVisibilityRulesValidator');
}
}
export function BackendErrorValidator(errorModel: ValidationErrorModel, propertyName: string): ValidatorFn {
return (control: AbstractControl): { [key: string]: any } => {
const error: string = errorModel.getError(propertyName);