added progress indication at DMP Editor.
This commit is contained in:
parent
f05d629c14
commit
be9b8df468
|
@ -1,19 +1,16 @@
|
|||
import { Component, EventEmitter, Input, Output } from '@angular/core';
|
||||
import { UntypedFormGroup } from '@angular/forms';
|
||||
import { MatDialog } from '@angular/material/dialog';
|
||||
import { DescriptionStatus } from '@app/core/common/enum/description-status';
|
||||
import { DescriptionTemplateVersionStatus } from '@app/core/common/enum/description-template-version-status';
|
||||
import { IsActive } from '@app/core/common/enum/is-active.enum';
|
||||
import { DescriptionTemplate } from '@app/core/model/description-template/description-template';
|
||||
import { Description } from '@app/core/model/description/description';
|
||||
import { DmpBlueprintDefinitionSection } from '@app/core/model/dmp-blueprint/dmp-blueprint';
|
||||
import { Dmp, DmpDescriptionTemplate } from '@app/core/model/dmp/dmp';
|
||||
import { DescriptionTemplateService } from '@app/core/services/description-template/description-template.service';
|
||||
import { DmpDescriptionTemplate } from '@app/core/model/dmp/dmp';
|
||||
import { DescriptionService } from '@app/core/services/description/description.service';
|
||||
import { DmpBlueprintService } from '@app/core/services/dmp/dmp-blueprint.service';
|
||||
import { BaseComponent } from '@common/base/base.component';
|
||||
import { takeUntil } from 'rxjs/operators';
|
||||
import { DeprecatedDescriptionTemplateDialog } from './dialog-description-template/deprecated-description-template-dialog.component';
|
||||
import { DescriptionTemplateVersionStatus } from '@app/core/common/enum/description-template-version-status';
|
||||
import { DescriptionStatus } from '@app/core/common/enum/description-status';
|
||||
|
||||
@Component({
|
||||
selector: 'app-description-base-fields-editor-component',
|
||||
|
@ -47,6 +44,7 @@ export class DescriptionBaseFieldsEditorComponent extends BaseComponent {
|
|||
const currentVersionsOfDescriptionTemplates = dmpDescriptionTemplates.map(x => x.currentDescriptionTemplate);
|
||||
this.availableDescriptionTemplates.push(...currentVersionsOfDescriptionTemplates);
|
||||
|
||||
if (this.description?.descriptionTemplate != null) {
|
||||
const isPreviousVersion: boolean = this.description.descriptionTemplate.versionStatus === DescriptionTemplateVersionStatus.Previous;
|
||||
if (isPreviousVersion === true) {
|
||||
if (this.description.status === DescriptionStatus.Draft) {
|
||||
|
@ -58,6 +56,7 @@ export class DescriptionBaseFieldsEditorComponent extends BaseComponent {
|
|||
this.availableDescriptionTemplates.push(this.description.descriptionTemplate);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private openDeprecatedDescriptionTemplateDialog(): void {
|
||||
const dialogRef = this.dialog.open(DeprecatedDescriptionTemplateDialog, {
|
||||
|
@ -67,7 +66,7 @@ export class DescriptionBaseFieldsEditorComponent extends BaseComponent {
|
|||
});
|
||||
dialogRef.afterClosed().pipe(takeUntil(this._destroyed)).subscribe(
|
||||
result => {
|
||||
if(result) {
|
||||
if (result) {
|
||||
this.descriptionService.updateDescriptionTemplate({
|
||||
id: this.description.id,
|
||||
hash: this.description.hash
|
||||
|
|
|
@ -111,13 +111,13 @@
|
|||
<span class="material-icons">chevron_left</span>
|
||||
<div>{{'DMP-EDITOR.ACTIONS.PREVIOUS-STEP' | translate}}</div>
|
||||
</div>
|
||||
<div *ngIf="this.step < this.maxStep" mat-raised-button type="button" class="col-auto stepper-btn ml-auto" [ngClass]="{ 'next-disabled': this.step === this.maxStep, 'next': this.step < selectedBlueprint?.definition?.sections?.length, 'description-next': this.step >= selectedBlueprint?.definition?.sections?.length }" (click)="nextStep()">
|
||||
<div *ngIf="this.step < this.maxSteps" mat-raised-button type="button" class="col-auto stepper-btn ml-auto" [ngClass]="{ 'next-disabled': this.step === this.maxSteps, 'next': this.step < selectedBlueprint?.definition?.sections?.length, 'description-next': this.step >= selectedBlueprint?.definition?.sections?.length }" (click)="nextStep()">
|
||||
<div>{{'DMP-EDITOR.ACTIONS.NEXT-STEP' | translate}}</div>
|
||||
<span class="material-icons">chevron_right</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-auto pr-0" *ngIf="this.step !== 0">
|
||||
<!-- <app-form-progress-indication class="col-12" *ngIf="formGroup && !formGroup.disabled && !lockStatus" [formGroup]="formGroup" [isDmpEditor]="true"></app-form-progress-indication> -->
|
||||
<app-dmp-form-progress-indication class="col-12" *ngIf="formGroup && !formGroup.disabled && !lockStatus" [formGroup]="formGroup"></app-dmp-form-progress-indication>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
|
|
@ -88,7 +88,7 @@ export class DmpEditorComponent extends BaseEditor<DmpEditorModel, Dmp> implemen
|
|||
filterFn: (searchQuery: string, data?: any) => this.dmpBlueprintService.query(this.dmpBlueprintService.buildAutocompleteLookup(searchQuery, null, null, [DmpBlueprintStatus.Finalized])).pipe(map(x => x.items)),
|
||||
getSelectedItem: (selectedItem: any) => this.dmpBlueprintService.query(this.dmpBlueprintService.buildAutocompleteLookup(null, null, [selectedItem])).pipe(map(x => x.items[0])),
|
||||
displayFn: (item: DmpBlueprint) => item.label,
|
||||
subtitleFn: (item: DmpBlueprint) => this.language.instant('DMP-EDITOR.FIELDS.DMP-BLUEPRINT-VERSION') + ' '+ item.version,
|
||||
subtitleFn: (item: DmpBlueprint) => this.language.instant('DMP-EDITOR.FIELDS.DMP-BLUEPRINT-VERSION') + ' ' + item.version,
|
||||
titleFn: (item: DmpBlueprint) => item.label,
|
||||
valueAssign: (item: DmpBlueprint) => item.id,
|
||||
};
|
||||
|
@ -174,14 +174,14 @@ export class DmpEditorComponent extends BaseEditor<DmpEditorModel, Dmp> implemen
|
|||
try {
|
||||
this.editorModel = data ? new DmpEditorModel().fromModel(data) : new DmpEditorModel();
|
||||
if (data) {
|
||||
if(data.descriptions){
|
||||
if (data.descriptions) {
|
||||
if (data.status == DmpStatus.Finalized) {
|
||||
data.descriptions = data.descriptions.filter(x => x.isActive === IsActive.Active && x.status === DescriptionStatus.Finalized);
|
||||
} else {
|
||||
data.descriptions = data.descriptions.filter(x => x.isActive === IsActive.Active && x.status !== DescriptionStatus.Canceled);
|
||||
}
|
||||
}
|
||||
if(data.dmpDescriptionTemplates){
|
||||
if (data.dmpDescriptionTemplates) {
|
||||
data.dmpDescriptionTemplates = data.dmpDescriptionTemplates.filter(x => x.isActive === IsActive.Active);
|
||||
}
|
||||
|
||||
|
@ -304,6 +304,11 @@ export class DmpEditorComponent extends BaseEditor<DmpEditorModel, Dmp> implemen
|
|||
// Steps
|
||||
//
|
||||
//
|
||||
|
||||
get maxSteps(): number {
|
||||
return this.item?.blueprint?.definition?.sections?.length ?? 0;
|
||||
}
|
||||
|
||||
changeStep(index: number) {
|
||||
this.step = index;
|
||||
this.resetScroll();
|
||||
|
@ -389,7 +394,8 @@ export class DmpEditorComponent extends BaseEditor<DmpEditorModel, Dmp> implemen
|
|||
DmpEditorModel.reApplyPropertiesValidators(
|
||||
{
|
||||
formGroup: this.formGroup,
|
||||
validationErrorModel: this.editorModel.validationErrorModel
|
||||
validationErrorModel: this.editorModel.validationErrorModel,
|
||||
blueprint: this.item.blueprint
|
||||
}
|
||||
);
|
||||
this.formGroup.get('properties').get('contacts').markAsDirty();
|
||||
|
@ -404,7 +410,8 @@ export class DmpEditorComponent extends BaseEditor<DmpEditorModel, Dmp> implemen
|
|||
DmpEditorModel.reApplyPropertiesValidators(
|
||||
{
|
||||
formGroup: this.formGroup,
|
||||
validationErrorModel: this.editorModel.validationErrorModel
|
||||
validationErrorModel: this.editorModel.validationErrorModel,
|
||||
blueprint: this.item.blueprint
|
||||
}
|
||||
);
|
||||
this.formGroup.get('properties').get('contacts').markAsDirty();
|
||||
|
@ -455,32 +462,32 @@ export class DmpEditorComponent extends BaseEditor<DmpEditorModel, Dmp> implemen
|
|||
});
|
||||
}
|
||||
|
||||
canAddDescription(section: DmpBlueprintDefinitionSection ): boolean{
|
||||
if(section.hasTemplates){
|
||||
if (section.descriptionTemplates?.length > 0){
|
||||
canAddDescription(section: DmpBlueprintDefinitionSection): boolean {
|
||||
if (section.hasTemplates) {
|
||||
if (section.descriptionTemplates?.length > 0) {
|
||||
const descriptions = this.descriptionsInSection(section.id)
|
||||
|
||||
if (this.item.dmpDescriptionTemplates.filter(x => x.sectionId == section.id).length > descriptions.map(x => x.dmpDescriptionTemplate).length){
|
||||
if (this.item.dmpDescriptionTemplates.filter(x => x.sectionId == section.id).length > descriptions.map(x => x.dmpDescriptionTemplate).length) {
|
||||
return true;
|
||||
}
|
||||
|
||||
let multiplicityValidResults :boolean[] = [];
|
||||
let multiplicityValidResults: boolean[] = [];
|
||||
section.descriptionTemplates.forEach(sectionDescriptionTemplate => {
|
||||
if (sectionDescriptionTemplate.maxMultiplicity != null){
|
||||
if (sectionDescriptionTemplate.maxMultiplicity != null) {
|
||||
const count = descriptions.filter(x => x.dmpDescriptionTemplate.descriptionTemplateGroupId == sectionDescriptionTemplate.descriptionTemplateGroupId).length || 0;
|
||||
if (count >= sectionDescriptionTemplate.maxMultiplicity) multiplicityValidResults.push(false);
|
||||
else multiplicityValidResults.push(true);
|
||||
}else{
|
||||
} else {
|
||||
multiplicityValidResults.push(true);
|
||||
}
|
||||
})
|
||||
|
||||
if(multiplicityValidResults.includes(true)) return true
|
||||
if (multiplicityValidResults.includes(true)) return true
|
||||
else return false;
|
||||
}else{
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}else{
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -504,10 +511,10 @@ export class DmpEditorComponent extends BaseEditor<DmpEditorModel, Dmp> implemen
|
|||
dialogRef.afterClosed().pipe(takeUntil(this._destroyed)).subscribe(groupId => {
|
||||
if (groupId) {
|
||||
let data = this.formGroup.get('descriptionTemplates').get(sectionId.toString()).value as Guid[];
|
||||
if (data){
|
||||
if (data) {
|
||||
data.push(groupId);
|
||||
this.formGroup.get('descriptionTemplates').get(sectionId.toString()).patchValue(data);
|
||||
} else{
|
||||
} else {
|
||||
this.formGroup.get('descriptionTemplates').get(sectionId.toString()).patchValue([groupId]);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,11 +1,12 @@
|
|||
import { FormArray, FormControl, UntypedFormArray, UntypedFormBuilder, UntypedFormGroup, Validators } from "@angular/forms";
|
||||
import { FormArray, FormControl, UntypedFormBuilder, UntypedFormGroup, Validators } from "@angular/forms";
|
||||
import { DmpAccessType } from "@app/core/common/enum/dmp-access-type";
|
||||
import { DmpBlueprintFieldCategory } from "@app/core/common/enum/dmp-blueprint-field-category";
|
||||
import { DmpContactType } from "@app/core/common/enum/dmp-contact-type";
|
||||
import { DmpStatus } from "@app/core/common/enum/dmp-status";
|
||||
import { DmpUserRole } from "@app/core/common/enum/dmp-user-role";
|
||||
import { DmpUserType } from "@app/core/common/enum/dmp-user-type";
|
||||
import { IsActive } from "@app/core/common/enum/is-active.enum";
|
||||
import { DmpBlueprint } from "@app/core/model/dmp-blueprint/dmp-blueprint";
|
||||
import { DmpBlueprint, FieldInSection } from "@app/core/model/dmp-blueprint/dmp-blueprint";
|
||||
import { Dmp, DmpBlueprintValue, DmpBlueprintValuePersist, DmpContact, DmpContactPersist, DmpDescriptionTemplate, DmpDescriptionTemplatePersist, DmpPersist, DmpProperties, DmpPropertiesPersist, DmpReferenceDataPersist, DmpReferencePersist, DmpUser, DmpUserPersist } from "@app/core/model/dmp/dmp";
|
||||
import { DmpReference } from "@app/core/model/dmp/dmp-reference";
|
||||
import { ReferencePersist } from "@app/core/model/reference/reference";
|
||||
|
@ -120,13 +121,16 @@ export class DmpEditorModel extends BaseEditorModel implements DmpPersist {
|
|||
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: 'status', validators: [Validators.required, BackendErrorValidator(this.validationErrorModel, 'status')] });
|
||||
baseValidationArray.push({ key: 'properties', validators: [Validators.required, BackendErrorValidator(this.validationErrorModel, 'properties')] });
|
||||
baseValidationArray.push({ key: 'status', validators: [BackendErrorValidator(this.validationErrorModel, 'status')] });
|
||||
baseValidationArray.push({ key: 'properties', validators: [BackendErrorValidator(this.validationErrorModel, 'properties')] });
|
||||
baseValidationArray.push({ key: 'description', validators: [Validators.required, BackendErrorValidator(this.validationErrorModel, 'description')] });
|
||||
baseValidationArray.push({ key: 'language', validators: [BackendErrorValidator(this.validationErrorModel, 'language')] });
|
||||
baseValidationArray.push({ key: 'blueprint', validators: [Validators.required, BackendErrorValidator(this.validationErrorModel, 'blueprint')] });
|
||||
baseValidationArray.push({ key: 'accessType', validators: [BackendErrorValidator(this.validationErrorModel, 'accessType')] });
|
||||
baseValidationArray.push({ key: 'language', validators: [Validators.required, BackendErrorValidator(this.validationErrorModel, 'language')] });
|
||||
baseValidationArray.push({ key: 'blueprint', validators: [BackendErrorValidator(this.validationErrorModel, 'blueprint')] });
|
||||
baseValidationArray.push({ key: 'accessType', validators: [Validators.required, BackendErrorValidator(this.validationErrorModel, 'accessType')] });
|
||||
baseValidationArray.push({ key: 'descriptionTemplates', validators: [Validators.required, BackendErrorValidator(this.validationErrorModel, 'descriptionTemplates')] });
|
||||
|
||||
baseValidationArray.push({ key: 'dmpDescriptionValidator', validators: [] });
|
||||
|
||||
baseValidationArray.push({ key: 'users', validators: [BackendErrorValidator(this.validationErrorModel, `users`)] });
|
||||
baseValidationArray.push({ key: 'hash', validators: [] });
|
||||
|
||||
|
@ -143,6 +147,7 @@ export class DmpEditorModel extends BaseEditorModel implements DmpPersist {
|
|||
static reApplyPropertiesValidators(params: {
|
||||
formGroup: UntypedFormGroup,
|
||||
validationErrorModel: ValidationErrorModel,
|
||||
blueprint: DmpBlueprint
|
||||
}): void {
|
||||
|
||||
const { formGroup, validationErrorModel } = params;
|
||||
|
@ -150,20 +155,36 @@ export class DmpEditorModel extends BaseEditorModel implements DmpPersist {
|
|||
DmpPropertiesEditorModel.reapplyValidators({
|
||||
formGroup: control as UntypedFormGroup,
|
||||
rootPath: `properties.`,
|
||||
validationErrorModel: validationErrorModel
|
||||
validationErrorModel: validationErrorModel,
|
||||
blueprint: params.blueprint
|
||||
});
|
||||
}
|
||||
|
||||
static reApplyDescriptionTemplateValidators(params: {
|
||||
formGroup: UntypedFormGroup,
|
||||
validationErrorModel: ValidationErrorModel,
|
||||
}): void {
|
||||
|
||||
const { formGroup, validationErrorModel } = params;
|
||||
|
||||
const descriptionTemplates = formGroup?.get('descriptionTemplates') as UntypedFormGroup;
|
||||
const keys = Object.keys(descriptionTemplates.value as Object);
|
||||
keys.forEach((key) => {
|
||||
const control = descriptionTemplates?.get(key);
|
||||
DmpBlueprintValueEditorModel.reapplyValidators({
|
||||
DmpDescriptionTemplateEditorModel.reapplyValidators({
|
||||
formGroup: control as UntypedFormGroup,
|
||||
rootPath: `descriptionTemplates[${key}].`,
|
||||
validationErrorModel: validationErrorModel
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
static reApplyUsersValidators(params: {
|
||||
formGroup: UntypedFormGroup,
|
||||
validationErrorModel: ValidationErrorModel,
|
||||
}): void {
|
||||
|
||||
const { formGroup, validationErrorModel } = params;
|
||||
(formGroup.get('users') as FormArray).controls?.forEach(
|
||||
(control, index) => DmpUserEditorModel.reapplyValidators({
|
||||
formGroup: control as UntypedFormGroup,
|
||||
|
@ -189,11 +210,13 @@ export class DmpPropertiesEditorModel implements DmpPropertiesPersist {
|
|||
|
||||
dmpBlueprint.definition.sections.forEach(section => {
|
||||
section.fields?.forEach(field => {
|
||||
if (field.category !== DmpBlueprintFieldCategory.System) {
|
||||
this.dmpBlueprintValues.set(field.id, new DmpBlueprintValueEditorModel(this.validationErrorModel).fromModel(
|
||||
{
|
||||
fieldId: field.id,
|
||||
fieldValue: item?.dmpBlueprintValues?.find(x => x.fieldId == field.id)?.fieldValue,
|
||||
}, dmpReferences));
|
||||
}, dmpReferences, field));
|
||||
}
|
||||
});
|
||||
});
|
||||
if (item?.contacts) { item.contacts.map(x => this.contacts.push(new DmpContactEditorModel(this.validationErrorModel).fromModel(x))); }
|
||||
|
@ -254,7 +277,8 @@ export class DmpPropertiesEditorModel implements DmpPropertiesPersist {
|
|||
static reapplyValidators(params: {
|
||||
formGroup: UntypedFormGroup,
|
||||
validationErrorModel: ValidationErrorModel,
|
||||
rootPath: string
|
||||
rootPath: string,
|
||||
blueprint: DmpBlueprint
|
||||
}): void {
|
||||
|
||||
const { formGroup, rootPath, validationErrorModel } = params;
|
||||
|
@ -266,7 +290,8 @@ export class DmpPropertiesEditorModel implements DmpPropertiesPersist {
|
|||
DmpBlueprintValueEditorModel.reapplyValidators({
|
||||
formGroup: control as UntypedFormGroup,
|
||||
rootPath: `${rootPath}dmpBlueprintValues[${key}].`,
|
||||
validationErrorModel: validationErrorModel
|
||||
validationErrorModel: validationErrorModel,
|
||||
isRequired: params.blueprint.definition.sections.flatMap(x => x.fields).find(x => x.id.toString() == key).required
|
||||
})
|
||||
});
|
||||
|
||||
|
@ -284,6 +309,8 @@ export class DmpBlueprintValueEditorModel implements DmpBlueprintValuePersist {
|
|||
fieldId: Guid;
|
||||
fieldValue: string;
|
||||
references: DmpReferencePersist[] = [];
|
||||
isRequired: boolean = false;
|
||||
category: DmpBlueprintFieldCategory;
|
||||
|
||||
protected formBuilder: UntypedFormBuilder = new UntypedFormBuilder();
|
||||
|
||||
|
@ -291,7 +318,7 @@ export class DmpBlueprintValueEditorModel implements DmpBlueprintValuePersist {
|
|||
public validationErrorModel: ValidationErrorModel = new ValidationErrorModel()
|
||||
) { }
|
||||
|
||||
fromModel(item: DmpBlueprintValue, dmpReferences: DmpReference[]): DmpBlueprintValueEditorModel {
|
||||
fromModel(item: DmpBlueprintValue, dmpReferences: DmpReference[], field: FieldInSection): DmpBlueprintValueEditorModel {
|
||||
this.fieldId = item.fieldId;
|
||||
this.fieldValue = item.fieldValue;
|
||||
this.references = dmpReferences?.filter(x => x.data.blueprintFieldId == this.fieldId && x.isActive == IsActive.Active).map(x => {
|
||||
|
@ -311,6 +338,10 @@ export class DmpBlueprintValueEditorModel implements DmpBlueprintValuePersist {
|
|||
}
|
||||
});
|
||||
|
||||
this.isRequired = field.required;
|
||||
if (this.isRequired) console.log(field);
|
||||
this.category = field.category;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
|
@ -323,28 +354,39 @@ export class DmpBlueprintValueEditorModel implements DmpBlueprintValuePersist {
|
|||
if (context == null) {
|
||||
context = DmpBlueprintValueEditorModel.createValidationContext({
|
||||
validationErrorModel: this.validationErrorModel,
|
||||
rootPath
|
||||
rootPath,
|
||||
isRequired: this.isRequired
|
||||
});
|
||||
}
|
||||
|
||||
return this.formBuilder.group({
|
||||
const formGroup = this.formBuilder.group({
|
||||
fieldId: [{ value: this.fieldId, disabled: disabled }, context.getValidation('fieldId').validators],
|
||||
fieldValue: [{ value: this.fieldValue, disabled: disabled }, context.getValidation('fieldValue').validators],
|
||||
references: [{ value: this.references?.map(x => x.reference), disabled: disabled }, context.getValidation('references').validators],
|
||||
});
|
||||
switch (this.category) {
|
||||
case DmpBlueprintFieldCategory.ReferenceType:
|
||||
formGroup.addControl('references', new FormControl({ value: this.references?.map(x => x.reference), disabled: disabled }, context.getValidation('references').validators));
|
||||
break;
|
||||
case DmpBlueprintFieldCategory.System:
|
||||
case DmpBlueprintFieldCategory.Extra:
|
||||
formGroup.addControl('fieldValue', new FormControl({ value: this.fieldValue, disabled: disabled }, context.getValidation('fieldValue').validators));
|
||||
break;
|
||||
}
|
||||
|
||||
return formGroup;
|
||||
}
|
||||
|
||||
static createValidationContext(params: {
|
||||
rootPath?: string,
|
||||
validationErrorModel: ValidationErrorModel
|
||||
validationErrorModel: ValidationErrorModel,
|
||||
isRequired: boolean,
|
||||
}): ValidationContext {
|
||||
const { rootPath = '', validationErrorModel } = params;
|
||||
|
||||
const baseContext: ValidationContext = new ValidationContext();
|
||||
const baseValidationArray: Validation[] = new Array<Validation>();
|
||||
baseValidationArray.push({ key: 'fieldId', validators: [BackendErrorValidator(validationErrorModel, `${rootPath}fieldId`)] });
|
||||
baseValidationArray.push({ key: 'fieldValue', validators: [BackendErrorValidator(validationErrorModel, `${rootPath}fieldValue`)] });
|
||||
baseValidationArray.push({ key: 'references', validators: [BackendErrorValidator(validationErrorModel, `${rootPath}references`)] });
|
||||
baseValidationArray.push({ key: 'fieldValue', validators: params.isRequired ? [Validators.required, BackendErrorValidator(validationErrorModel, `${rootPath}fieldValue`)] : [BackendErrorValidator(validationErrorModel, `${rootPath}fieldValue`)] });
|
||||
baseValidationArray.push({ key: 'references', validators: params.isRequired ? [Validators.required, BackendErrorValidator(validationErrorModel, `${rootPath}references`)] : [BackendErrorValidator(validationErrorModel, `${rootPath}references`)] });
|
||||
|
||||
baseContext.validation = baseValidationArray;
|
||||
return baseContext;
|
||||
|
@ -353,13 +395,15 @@ export class DmpBlueprintValueEditorModel implements DmpBlueprintValuePersist {
|
|||
static reapplyValidators(params: {
|
||||
formGroup: UntypedFormGroup,
|
||||
validationErrorModel: ValidationErrorModel,
|
||||
rootPath: string
|
||||
rootPath: string,
|
||||
isRequired: boolean
|
||||
}): void {
|
||||
|
||||
const { formGroup, rootPath, validationErrorModel } = params;
|
||||
const context = DmpBlueprintValueEditorModel.createValidationContext({
|
||||
rootPath,
|
||||
validationErrorModel
|
||||
validationErrorModel,
|
||||
isRequired: params.isRequired
|
||||
});
|
||||
|
||||
['fieldId', 'fieldValue', 'references'].forEach(keyField => {
|
||||
|
@ -375,7 +419,7 @@ export class DmpContactEditorModel implements DmpContactPersist {
|
|||
firstName: string;
|
||||
lastName: string;
|
||||
email: string;
|
||||
contactType: DmpContactType= DmpContactType.Internal;
|
||||
contactType: DmpContactType = DmpContactType.Internal;
|
||||
|
||||
protected formBuilder: UntypedFormBuilder = new UntypedFormBuilder();
|
||||
|
||||
|
@ -384,7 +428,7 @@ export class DmpContactEditorModel implements DmpContactPersist {
|
|||
) { }
|
||||
|
||||
fromModel(item: DmpContact): DmpContactEditorModel {
|
||||
if(item?.user?.id) this.userId = item.user.id;
|
||||
if (item?.user?.id) this.userId = item.user.id;
|
||||
this.firstName = item.firstName;
|
||||
this.lastName = item.lastName;
|
||||
this.email = item.email;
|
||||
|
@ -457,7 +501,7 @@ export class DmpUserEditorModel implements DmpUserPersist {
|
|||
user: Guid;
|
||||
role: DmpUserRole;
|
||||
email: string;
|
||||
userType: DmpUserType= DmpUserType.Internal;
|
||||
userType: DmpUserType = DmpUserType.Internal;
|
||||
sectionId: Guid;
|
||||
|
||||
protected formBuilder: UntypedFormBuilder = new UntypedFormBuilder();
|
||||
|
@ -467,7 +511,7 @@ export class DmpUserEditorModel implements DmpUserPersist {
|
|||
) { }
|
||||
|
||||
fromModel(item: DmpUser): DmpUserEditorModel {
|
||||
if(item?.user?.id) this.user = item.user.id;
|
||||
if (item?.user?.id) this.user = item.user.id;
|
||||
this.role = item.role;
|
||||
// TODO this.email = item.email;
|
||||
this.userType = (item == null || this.user != null) ? DmpUserType.Internal : DmpUserType.External;
|
||||
|
@ -623,7 +667,7 @@ export class DmpDescriptionTemplateEditorModel implements DmpDescriptionTemplate
|
|||
if (context == null) {
|
||||
context = DmpDescriptionTemplateEditorModel.createValidationContext({
|
||||
validationErrorModel: this.validationErrorModel,
|
||||
rootPath
|
||||
rootPath: rootPath,
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -635,7 +679,7 @@ export class DmpDescriptionTemplateEditorModel implements DmpDescriptionTemplate
|
|||
|
||||
static createValidationContext(params: {
|
||||
rootPath?: string,
|
||||
validationErrorModel: ValidationErrorModel
|
||||
validationErrorModel: ValidationErrorModel,
|
||||
}): ValidationContext {
|
||||
const { rootPath = '', validationErrorModel } = params;
|
||||
|
||||
|
|
|
@ -1,15 +1,16 @@
|
|||
import { DragDropModule } from '@angular/cdk/drag-drop';
|
||||
import { NgModule } from '@angular/core';
|
||||
import { FormattingModule } from '@app/core/formatting.module';
|
||||
import { AutoCompleteModule } from '@app/library/auto-complete/auto-complete.module';
|
||||
import { RichTextEditorModule } from '@app/library/rich-text-editor/rich-text-editor.module';
|
||||
import { ReferenceFieldModule } from '@app/ui/reference/reference-field/reference-field.module';
|
||||
import { CommonFormsModule } from '@common/forms/common-forms.module';
|
||||
import { ConfirmationDialogModule } from '@common/modules/confirmation-dialog/confirmation-dialog.module';
|
||||
import { CommonUiModule } from '@common/ui/common-ui.module';
|
||||
import { DmpUserFieldModule } from '../dmp-user-field/dmp-user-field.module';
|
||||
import { DmpEditorComponent } from './dmp-editor.component';
|
||||
import { DmpEditorRoutingModule } from './dmp-editor.routing';
|
||||
import { AutoCompleteModule } from '@app/library/auto-complete/auto-complete.module';
|
||||
import { ReferenceFieldModule } from '@app/ui/reference/reference-field/reference-field.module';
|
||||
import { DragDropModule } from '@angular/cdk/drag-drop';
|
||||
import { DmpUserFieldModule } from '../dmp-user-field/dmp-user-field.module';
|
||||
import { DmpFormProgressIndicationModule } from './form-progress-indication/dmp-form-progress-indication.module';
|
||||
|
||||
@NgModule({
|
||||
imports: [
|
||||
|
@ -22,7 +23,8 @@ import { DmpUserFieldModule } from '../dmp-user-field/dmp-user-field.module';
|
|||
AutoCompleteModule,
|
||||
ReferenceFieldModule,
|
||||
DragDropModule,
|
||||
DmpUserFieldModule
|
||||
DmpUserFieldModule,
|
||||
DmpFormProgressIndicationModule
|
||||
],
|
||||
declarations: [
|
||||
DmpEditorComponent,
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
<div class="demo-progress-bar-container">
|
||||
<div class="percentage d-flex justify-content-center">{{progressSoFar}} {{'GENERAL.PREPOSITIONS.OF' | translate}} {{total}}</div>
|
||||
<mat-progress-bar class="form-progress-bar" [ngClass]="{'progress-bar': true}" mode="determinate" [value]="value"></mat-progress-bar>
|
||||
<div class="percentage" [ngStyle]="{'padding-left': value ? value - 10 + '%' : 0 + '%' }">{{value}}%</div>
|
||||
</div>
|
|
@ -0,0 +1,16 @@
|
|||
.percentage {
|
||||
color: #212121;
|
||||
opacity: 0.7;
|
||||
font-weight: 400;
|
||||
font-size: 0.875rem;
|
||||
}
|
||||
|
||||
.progress-bar {
|
||||
border-radius: 20px;
|
||||
height: 11px;
|
||||
|
||||
}
|
||||
|
||||
::ng-deep .mat-progress-bar .mat-progress-bar-fill::after {
|
||||
border-radius: 20px !important;
|
||||
}
|
|
@ -0,0 +1,104 @@
|
|||
import { Component, Input, OnChanges, OnInit, SimpleChanges } from '@angular/core';
|
||||
import { AbstractControl, UntypedFormArray, UntypedFormControl, UntypedFormGroup } 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';
|
||||
|
||||
@Component({
|
||||
selector: 'app-dmp-form-progress-indication',
|
||||
templateUrl: './dmp-form-progress-indication.component.html',
|
||||
styleUrls: ['./dmp-form-progress-indication.component.scss']
|
||||
})
|
||||
export class DmpFormProgressIndicationComponent extends BaseComponent implements OnInit, OnChanges {
|
||||
@Input() formGroup: UntypedFormGroup;
|
||||
|
||||
@Input() public progressValueAccuracy = 2;
|
||||
progressSoFar: number;
|
||||
total: number;
|
||||
percent: number;
|
||||
|
||||
constructor(private visibilityRulesService: VisibilityRulesService) { super(); }
|
||||
|
||||
public value = 0;
|
||||
ngOnInit() {
|
||||
this.init();
|
||||
}
|
||||
|
||||
ngOnChanges(changes: SimpleChanges) {
|
||||
if (changes.formGroup) {
|
||||
this.init();
|
||||
}
|
||||
}
|
||||
|
||||
init() {
|
||||
setTimeout(() => { this.calculateValueForProgressbar(); });
|
||||
this.formGroup
|
||||
.valueChanges
|
||||
.pipe(takeUntil(this._destroyed))
|
||||
.subscribe(control => {
|
||||
setTimeout(() => { this.calculateValueForProgressbar(); });
|
||||
});
|
||||
}
|
||||
|
||||
calculateValueForProgressbar() {
|
||||
this.progressSoFar = this.countFormControlsValidForProgress(this.formGroup);
|
||||
this.total = this.countFormControlsRequiredFieldsForTotal(this.formGroup);
|
||||
this.percent = (this.progressSoFar / this.total) * 100;
|
||||
this.value = Number.parseFloat(this.percent.toPrecision(this.progressValueAccuracy));
|
||||
}
|
||||
|
||||
countFormControlsValidForProgress(formControl: AbstractControl): number {
|
||||
let valueCurrent = 0;
|
||||
if (formControl instanceof UntypedFormControl) {
|
||||
if (this.controlRequired(formControl) && this.controlEnabled(formControl) && formControl.valid) {
|
||||
valueCurrent++;
|
||||
}
|
||||
} else if (formControl instanceof UntypedFormGroup) {
|
||||
Object.keys(formControl.controls).forEach(item => {
|
||||
const control = formControl.get(item);
|
||||
valueCurrent = valueCurrent + this.countFormControlsValidForProgress(control);
|
||||
});
|
||||
} else if (formControl instanceof UntypedFormArray) {
|
||||
formControl.controls.forEach(item => {
|
||||
valueCurrent = valueCurrent + this.countFormControlsValidForProgress(item);
|
||||
});
|
||||
}
|
||||
return valueCurrent;
|
||||
}
|
||||
|
||||
countFormControlsRequiredFieldsForTotal(formControl: AbstractControl, checkVisibility = false): number {
|
||||
let valueCurrent = 0;
|
||||
if (formControl instanceof UntypedFormControl) {
|
||||
if (this.controlRequired(formControl) && this.controlEnabled(formControl)) {
|
||||
valueCurrent++;
|
||||
}
|
||||
} else if (formControl instanceof UntypedFormGroup) {
|
||||
if (!checkVisibility || (!formControl.get('id')?.value || (this.visibilityRulesService.isVisibleMap[formControl.get('id').value] ?? true))) {
|
||||
Object.keys(formControl.controls).forEach(item => {
|
||||
const control = formControl.get(item);
|
||||
valueCurrent = valueCurrent + this.countFormControlsRequiredFieldsForTotal(control, checkVisibility);
|
||||
});
|
||||
}
|
||||
} else if (formControl instanceof UntypedFormArray) {
|
||||
formControl.controls.forEach(item => {
|
||||
valueCurrent = valueCurrent + this.countFormControlsRequiredFieldsForTotal(item, checkVisibility);
|
||||
});
|
||||
}
|
||||
return valueCurrent;
|
||||
}
|
||||
|
||||
controlRequired(formControl: AbstractControl) {
|
||||
if (formControl.validator) {
|
||||
const validator = formControl.validator({} as AbstractControl);
|
||||
if (validator && validator.required) {
|
||||
return true;
|
||||
}
|
||||
} else { return false }
|
||||
}
|
||||
|
||||
controlEnabled(formControl: AbstractControl) {
|
||||
if (formControl.enabled) {
|
||||
return true;
|
||||
} else { return false }
|
||||
}
|
||||
}
|
|
@ -0,0 +1,18 @@
|
|||
import { NgModule } from '@angular/core';
|
||||
import { CommonFormsModule } from '@common/forms/common-forms.module';
|
||||
import { CommonUiModule } from '@common/ui/common-ui.module';
|
||||
import { DmpFormProgressIndicationComponent } from './dmp-form-progress-indication.component';
|
||||
|
||||
@NgModule({
|
||||
imports: [
|
||||
CommonUiModule,
|
||||
CommonFormsModule
|
||||
],
|
||||
declarations: [
|
||||
DmpFormProgressIndicationComponent
|
||||
],
|
||||
exports: [
|
||||
DmpFormProgressIndicationComponent
|
||||
]
|
||||
})
|
||||
export class DmpFormProgressIndicationModule { }
|
|
@ -43,7 +43,7 @@
|
|||
</div>
|
||||
<div class="col-12 col-xl mt-3" *ngIf="user.get('userType').value == dmpUserTypeEnum.Internal">
|
||||
<mat-form-field class="w-100">
|
||||
<mat-label>{{'DMP-EDITOR.FIELDS.USER' | translate}}*</mat-label>
|
||||
<mat-label>{{'DMP-EDITOR.FIELDS.USER' | translate}}</mat-label>
|
||||
<app-single-auto-complete [formControl]="user.get('user')" [hidePlaceholder]="true" [configuration]="userService.singleAutoCompleteDmpAssociatedUserConfiguration"></app-single-auto-complete>
|
||||
<mat-error *ngIf="user.get('user').hasError('backendError')">{{user.get('user').getError('backendError').message}}</mat-error>
|
||||
<mat-error *ngIf="user.get('user').hasError('required')">{{'GENERAL.VALIDATION.REQUIRED' | translate}}</mat-error>
|
||||
|
@ -51,7 +51,7 @@
|
|||
</div>
|
||||
<div class="col-12 col-xl mt-3" *ngIf="user.get('userType').value == dmpUserTypeEnum.External">
|
||||
<mat-form-field class="w-100">
|
||||
<mat-label>{{'DMP-EDITOR.FIELDS.EMAIL' | translate}}*</mat-label>
|
||||
<mat-label>{{'DMP-EDITOR.FIELDS.EMAIL' | translate}}</mat-label>
|
||||
<input matInput type="text" name="email" [formControl]="user.get('email')">
|
||||
<mat-error *ngIf="user.get('email').hasError('backendError')">{{user.get('email').getError('backendError').message}}</mat-error>
|
||||
<mat-error *ngIf="user.get('email').hasError('required')">{{'GENERAL.VALIDATION.REQUIRED' | translate}}</mat-error>
|
||||
|
|
|
@ -57,10 +57,10 @@ export class DmpUserFieldComponent extends BaseComponent implements OnInit {
|
|||
removeUser(userIndex: number): void {
|
||||
(this.form.get('users') as FormArray).removeAt(userIndex);
|
||||
|
||||
DmpEditorModel.reApplyPropertiesValidators(
|
||||
DmpEditorModel.reApplyUsersValidators(
|
||||
{
|
||||
formGroup: this.form,
|
||||
validationErrorModel: this.validationErrorModel
|
||||
validationErrorModel: this.validationErrorModel,
|
||||
}
|
||||
);
|
||||
this.form.get('users').markAsDirty();
|
||||
|
@ -78,7 +78,7 @@ export class DmpUserFieldComponent extends BaseComponent implements OnInit {
|
|||
moveItemInArray(usersFormArray.controls, event.previousIndex, event.currentIndex);
|
||||
usersFormArray.updateValueAndValidity();
|
||||
|
||||
DmpEditorModel.reApplyPropertiesValidators(
|
||||
DmpEditorModel.reApplyUsersValidators(
|
||||
{
|
||||
formGroup: this.form,
|
||||
validationErrorModel: this.validationErrorModel
|
||||
|
|
Loading…
Reference in New Issue