[835] Auto-save in new Item Submission form breaks the form

Store additions:
1. Form AdditionalData: contains the list of the touched metadata
2. Submission metadata: contains the list of the metadata ids assignable for each section

We keep also track whether a section ha focused fields or not.
This commit is contained in:
Alessandro Martelli
2020-11-19 15:47:03 +01:00
parent 82b7b8aa6f
commit 8111bdd3ce
10 changed files with 299 additions and 28 deletions

View File

@@ -20,7 +20,7 @@ import { FormComponent } from '../../../shared/form/form.component';
import { FormService } from '../../../shared/form/form.service';
import { SectionModelComponent } from '../models/section.model';
import { SubmissionFormsConfigService } from '../../../core/config/submission-forms-config.service';
import { hasNoValue, hasValue, isNotEmpty, isUndefined } from '../../../shared/empty.util';
import { hasNoValue, hasValue, isEmpty, isNotEmpty, isUndefined } from '../../../shared/empty.util';
import { JsonPatchOperationPathCombiner } from '../../../core/json-patch/builder/json-patch-operation-path-combiner';
import { SubmissionFormsModel } from '../../../core/config/models/config-submission-forms.model';
import {
@@ -101,6 +101,18 @@ export class SubmissionSectionformComponent extends SectionModelComponent {
*/
protected formData: any = Object.create({});
/**
* Store the current form additional data
* @protected
*/
protected formAdditionalData: any = Object.create({});
/**
* Store the
* @protected
*/
protected sectionMetadata: string[];
/**
* The [JsonPatchOperationPathCombiner] object
* @type {JsonPatchOperationPathCombiner}
@@ -125,6 +137,12 @@ export class SubmissionSectionformComponent extends SectionModelComponent {
*/
@ViewChild('formRef', {static: false}) private formRef: FormComponent;
/**
* Keep track whether the section is focused or not.
* @protected
*/
protected isFocused = false;
/**
* Initialize instance variables
*
@@ -230,16 +248,24 @@ export class SubmissionSectionformComponent extends SectionModelComponent {
* the section data retrieved from the server
*/
hasMetadataEnrichment(sectionData: WorkspaceitemSectionFormObject): boolean {
const sectionDataToCheck = {};
Object.keys(sectionData).forEach((key) => {
if (this.sectionMetadata.includes(key)) {
sectionDataToCheck[key] = sectionData[key];
}
})
const diffResult = [];
// compare current form data state with section data retrieved from store
const diffObj = difference(sectionData, this.formData);
const diffObj = difference(sectionDataToCheck, this.formData);
// iterate over differences to check whether they are actually different
Object.keys(diffObj)
.forEach((key) => {
diffObj[key].forEach((value) => {
if (value.hasOwnProperty('value')) {
if (value.hasOwnProperty('value') && !isEmpty(value.value)) {
diffResult.push(value);
}
});
@@ -262,6 +288,9 @@ export class SubmissionSectionformComponent extends SectionModelComponent {
sectionData,
this.submissionService.getSubmissionScope()
);
this.formBuilderService.enrichWithAdditionalData(this.formModel, this.formAdditionalData);
this.sectionMetadata = this.sectionService.computeSectionConfiguredMetadata(this.formConfig);
} catch (e) {
const msg: string = this.translate.instant('error.submission.sections.init-form-error') + e.toString();
const sectionError: SubmissionSectionError = {
@@ -283,15 +312,19 @@ export class SubmissionSectionformComponent extends SectionModelComponent {
*/
updateForm(sectionData: WorkspaceitemSectionFormObject, errors: SubmissionSectionError[]): void {
if (hasValue(sectionData) && !isEqual(sectionData, this.sectionData.data)) {
if (isNotEmpty(sectionData) && !isEqual(sectionData, this.sectionData.data)) {
this.sectionData.data = sectionData;
this.isUpdating = true;
this.formModel = null;
this.cdr.detectChanges();
this.initForm(sectionData);
this.checksForErrors(errors);
this.isUpdating = false;
this.cdr.detectChanges();
if (this.hasMetadataEnrichment(sectionData)) {
this.isUpdating = true;
this.formModel = null;
this.cdr.detectChanges();
this.initForm(sectionData);
this.checksForErrors(errors);
this.isUpdating = false;
this.cdr.detectChanges();
} else if (isNotEmpty(errors) || isNotEmpty(this.sectionData.errors)) {
this.checksForErrors(errors);
}
} else if (isNotEmpty(errors) || isNotEmpty(this.sectionData.errors)) {
this.checksForErrors(errors);
}
@@ -308,6 +341,9 @@ export class SubmissionSectionformComponent extends SectionModelComponent {
this.formService.isFormInitialized(this.formId).pipe(
find((status: boolean) => status === true && !this.isUpdating))
.subscribe(() => {
// TODO: filter these errors to only those that had been touched
this.sectionService.checkSectionErrors(this.submissionId, this.sectionData.id, this.formId, errors, this.sectionData.errors);
this.sectionData.errors = errors;
this.cdr.detectChanges();
@@ -328,6 +364,12 @@ export class SubmissionSectionformComponent extends SectionModelComponent {
this.formData = formData;
}),
this.formService.getFormAdditionalData(this.formId).pipe(
distinctUntilChanged())
.subscribe((formAdditional) => {
this.formAdditionalData = formAdditional;
}),
/**
* Subscribe to section state
*/
@@ -375,6 +417,7 @@ export class SubmissionSectionformComponent extends SectionModelComponent {
* the [[DynamicFormControlEvent]] emitted
*/
onFocus(event: DynamicFormControlEvent): void {
this.isFocused = true;
const value = this.formOperationsService.getFieldValueFromChangeEvent(event);
const path = this.formBuilderService.getPath(event.model);
if (this.formBuilderService.hasMappedGroupValue(event.model)) {
@@ -386,6 +429,17 @@ export class SubmissionSectionformComponent extends SectionModelComponent {
}
}
/**
* Method called when a form dfBlur event is fired.
*
* @param event
* the [[DynamicFormControlEvent]] emitted
*/
onBlur(event: DynamicFormControlEvent): void {
this.isFocused = false;
}
/**
* Method called when a form remove event is fired.
* Dispatch form operations based on changes.