mirror of
https://github.com/DSpace/dspace-angular.git
synced 2025-10-10 11:33:04 +00:00
Fixed an issue with showing form error in FormSectionComponent and added comments
This commit is contained in:
@@ -318,6 +318,23 @@ describe('FormSectionComponent test suite', () => {
|
||||
|
||||
});
|
||||
|
||||
it('should update form error properly', () => {
|
||||
spyOn(comp, 'initForm');
|
||||
spyOn(comp, 'checksForErrors');
|
||||
const sectionData: any = {
|
||||
'dc.title': [new FormFieldMetadataValueObject('test')]
|
||||
};
|
||||
comp.sectionData.data = {};
|
||||
comp.sectionData.errors = [];
|
||||
compAsAny.formData = sectionData;
|
||||
|
||||
comp.updateForm(sectionData, parsedSectionErrors);
|
||||
|
||||
expect(comp.initForm).not.toHaveBeenCalled();
|
||||
expect(comp.checksForErrors).toHaveBeenCalled();
|
||||
expect(comp.sectionData.data).toEqual(sectionData);
|
||||
});
|
||||
|
||||
it('should update form error properly', () => {
|
||||
spyOn(comp, 'initForm');
|
||||
spyOn(comp, 'checksForErrors');
|
||||
|
@@ -17,7 +17,6 @@ import { JsonPatchOperationPathCombiner } from '../../../core/json-patch/builder
|
||||
import { SubmissionFormsModel } from '../../../core/config/models/config-submission-forms.model';
|
||||
import { SubmissionSectionError, SubmissionSectionObject } from '../../objects/submission-objects.reducer';
|
||||
import { FormFieldPreviousValueObject } from '../../../shared/form/builder/models/form-field-previous-value-object';
|
||||
import { WorkspaceitemSectionDataType } from '../../../core/submission/models/workspaceitem-sections.model';
|
||||
import { GLOBAL_CONFIG } from '../../../../config';
|
||||
import { GlobalConfig } from '../../../../config/global-config.interface';
|
||||
import { SectionDataObject } from '../models/section-data.model';
|
||||
@@ -28,7 +27,11 @@ import { SectionFormOperationsService } from './section-form-operations.service'
|
||||
import { NotificationsService } from '../../../shared/notifications/notifications.service';
|
||||
import { SectionsService } from '../sections.service';
|
||||
import { difference } from '../../../shared/object.util';
|
||||
import { WorkspaceitemSectionFormObject } from '../../../core/submission/models/workspaceitem-section-form.model';
|
||||
|
||||
/**
|
||||
* This component represents a section that contains a Form.
|
||||
*/
|
||||
@Component({
|
||||
selector: 'ds-submission-section-form',
|
||||
styleUrls: ['./section-form.component.scss'],
|
||||
@@ -37,19 +40,72 @@ import { difference } from '../../../shared/object.util';
|
||||
@renderSectionFor(SectionsType.SubmissionForm)
|
||||
export class FormSectionComponent extends SectionModelComponent {
|
||||
|
||||
/**
|
||||
* The form id
|
||||
*/
|
||||
public formId;
|
||||
|
||||
/**
|
||||
* The form model
|
||||
*/
|
||||
public formModel: DynamicFormControlModel[];
|
||||
|
||||
/**
|
||||
* A boolean representing if this section is updating
|
||||
*/
|
||||
public isUpdating = false;
|
||||
|
||||
/**
|
||||
* A boolean representing if this section is loading
|
||||
*/
|
||||
public isLoading = true;
|
||||
|
||||
/**
|
||||
* The form config
|
||||
*/
|
||||
protected formConfig: SubmissionFormsModel;
|
||||
|
||||
/**
|
||||
* The form data
|
||||
*/
|
||||
protected formData: any = Object.create({});
|
||||
|
||||
/**
|
||||
* The [JsonPatchOperationPathCombiner] object
|
||||
*/
|
||||
protected pathCombiner: JsonPatchOperationPathCombiner;
|
||||
|
||||
/**
|
||||
* The [FormFieldPreviousValueObject] object
|
||||
*/
|
||||
protected previousValue: FormFieldPreviousValueObject = new FormFieldPreviousValueObject();
|
||||
|
||||
/**
|
||||
* The list of Subscription
|
||||
*/
|
||||
protected subs: Subscription[] = [];
|
||||
|
||||
/**
|
||||
* The FormComponent reference
|
||||
*/
|
||||
@ViewChild('formRef') private formRef: FormComponent;
|
||||
|
||||
/**
|
||||
* Initialize instance variables
|
||||
* @param {ChangeDetectorRef} cdr
|
||||
* @param {FormBuilderService} formBuilderService
|
||||
* @param {SectionFormOperationsService} formOperationsService
|
||||
* @param {FormService} formService
|
||||
* @param {SubmissionFormsConfigService} formConfigService
|
||||
* @param {NotificationsService} notificationsService
|
||||
* @param {SectionsService} sectionService
|
||||
* @param {SubmissionService} submissionService
|
||||
* @param {TranslateService} translate
|
||||
* @param {GlobalConfig} EnvConfig
|
||||
* @param {string} injectedCollectionId
|
||||
* @param {SectionDataObject} injectedSectionData
|
||||
* @param {string} injectedSubmissionId
|
||||
*/
|
||||
constructor(protected cdr: ChangeDetectorRef,
|
||||
protected formBuilderService: FormBuilderService,
|
||||
protected formOperationsService: SectionFormOperationsService,
|
||||
@@ -66,6 +122,9 @@ export class FormSectionComponent extends SectionModelComponent {
|
||||
super(injectedCollectionId, injectedSectionData, injectedSubmissionId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize all instance variables and retrieve form configuration
|
||||
*/
|
||||
onSectionInit() {
|
||||
this.pathCombiner = new JsonPatchOperationPathCombiner('sections', this.sectionData.id);
|
||||
this.formId = this.formService.getUniqueId(this.sectionData.id);
|
||||
@@ -75,7 +134,7 @@ export class FormSectionComponent extends SectionModelComponent {
|
||||
tap((config: SubmissionFormsModel) => this.formConfig = config),
|
||||
flatMap(() => this.sectionService.getSectionData(this.submissionId, this.sectionData.id)),
|
||||
take(1))
|
||||
.subscribe((sectionData: WorkspaceitemSectionDataType) => {
|
||||
.subscribe((sectionData: WorkspaceitemSectionFormObject) => {
|
||||
if (isUndefined(this.formModel)) {
|
||||
this.sectionData.errors = [];
|
||||
// Is the first loading so init form
|
||||
@@ -88,17 +147,29 @@ export class FormSectionComponent extends SectionModelComponent {
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* Unsubscribe from all subscriptions
|
||||
*/
|
||||
onSectionDestroy() {
|
||||
this.subs
|
||||
.filter((subscription) => hasValue(subscription))
|
||||
.forEach((subscription) => subscription.unsubscribe());
|
||||
}
|
||||
|
||||
/**
|
||||
* Get section status
|
||||
*/
|
||||
protected getSectionStatus(): Observable<boolean> {
|
||||
return this.formService.isValid(this.formId);
|
||||
}
|
||||
|
||||
hasMetadataEnrichment(sectionData): boolean {
|
||||
/**
|
||||
* Check if the section data has been enriched by the server
|
||||
*
|
||||
* @param sectionData
|
||||
* the section data retrieved from the server
|
||||
*/
|
||||
hasMetadataEnrichment(sectionData: WorkspaceitemSectionFormObject): boolean {
|
||||
const diffResult = [];
|
||||
|
||||
// compare current form data state with section data retrieved from store
|
||||
@@ -116,7 +187,13 @@ export class FormSectionComponent extends SectionModelComponent {
|
||||
return isNotEmpty(diffResult);
|
||||
}
|
||||
|
||||
initForm(sectionData: WorkspaceitemSectionDataType) {
|
||||
/**
|
||||
* Initialize form model
|
||||
*
|
||||
* @param sectionData
|
||||
* the section data retrieved from the server
|
||||
*/
|
||||
initForm(sectionData: WorkspaceitemSectionFormObject): void {
|
||||
try {
|
||||
this.formModel = this.formBuilderService.modelFromConfiguration(
|
||||
this.formConfig,
|
||||
@@ -124,28 +201,32 @@ export class FormSectionComponent extends SectionModelComponent {
|
||||
sectionData,
|
||||
this.submissionService.getSubmissionScope());
|
||||
} catch (e) {
|
||||
this.translate.get('error.submission.sections.init-form-error')
|
||||
.subscribe((msg) => {
|
||||
const msg = this.translate.instant('error.submission.sections.init-form-error');
|
||||
const sectionError: SubmissionSectionError = {
|
||||
message: msg + e.toString(),
|
||||
path: '/sections/' + this.sectionData.id
|
||||
};
|
||||
this.sectionService.setSectionError(this.submissionId, this.sectionData.id, sectionError);
|
||||
})
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
updateForm(sectionData: WorkspaceitemSectionDataType, errors: SubmissionSectionError[]) {
|
||||
/**
|
||||
* Update form model
|
||||
*
|
||||
* @param sectionData
|
||||
* the section data retrieved from the server
|
||||
* @param errors
|
||||
* the section errors retrieved from the server
|
||||
*/
|
||||
updateForm(sectionData: WorkspaceitemSectionFormObject, errors: SubmissionSectionError[]): void {
|
||||
|
||||
if (isNotEmpty(sectionData) && !isEqual(sectionData, this.sectionData.data)) {
|
||||
this.sectionData.data = sectionData;
|
||||
if (this.hasMetadataEnrichment(sectionData)) {
|
||||
this.translate.get('submission.sections.general.metadata-extracted', { sectionId: this.sectionData.id })
|
||||
.pipe(take(1))
|
||||
.subscribe((m) => {
|
||||
this.notificationsService.info(null, m, null, true);
|
||||
});
|
||||
const msg = this.translate.instant(
|
||||
'submission.sections.general.metadata-extracted',
|
||||
{ sectionId: this.sectionData.id });
|
||||
this.notificationsService.info(null, msg, null, true);
|
||||
this.isUpdating = true;
|
||||
this.formModel = null;
|
||||
this.cdr.detectChanges();
|
||||
@@ -153,6 +234,8 @@ export class FormSectionComponent extends SectionModelComponent {
|
||||
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);
|
||||
@@ -160,7 +243,13 @@ export class FormSectionComponent extends SectionModelComponent {
|
||||
|
||||
}
|
||||
|
||||
checksForErrors(errors: SubmissionSectionError[]) {
|
||||
/**
|
||||
* Check if there are form validation error retrieved from server
|
||||
*
|
||||
* @param errors
|
||||
* the section errors retrieved from the server
|
||||
*/
|
||||
checksForErrors(errors: SubmissionSectionError[]): void {
|
||||
this.formService.isFormInitialized(this.formId).pipe(
|
||||
find((status: boolean) => status === true && !this.isUpdating))
|
||||
.subscribe(() => {
|
||||
@@ -170,9 +259,11 @@ export class FormSectionComponent extends SectionModelComponent {
|
||||
});
|
||||
}
|
||||
|
||||
subscriptions() {
|
||||
/**
|
||||
* Initialize all subscriptions
|
||||
*/
|
||||
subscriptions(): void {
|
||||
this.subs.push(
|
||||
|
||||
/**
|
||||
* Subscribe to form's data
|
||||
*/
|
||||
@@ -181,6 +272,7 @@ export class FormSectionComponent extends SectionModelComponent {
|
||||
.subscribe((formData) => {
|
||||
this.formData = formData;
|
||||
}),
|
||||
|
||||
/**
|
||||
* Subscribe to section state
|
||||
*/
|
||||
@@ -190,12 +282,16 @@ export class FormSectionComponent extends SectionModelComponent {
|
||||
}),
|
||||
distinctUntilChanged())
|
||||
.subscribe((sectionState: SubmissionSectionObject) => {
|
||||
this.updateForm(sectionState.data, sectionState.errors);
|
||||
this.updateForm(sectionState.data as WorkspaceitemSectionFormObject, sectionState.errors);
|
||||
})
|
||||
)
|
||||
}
|
||||
|
||||
onChange(event: DynamicFormControlEvent) {
|
||||
/**
|
||||
* Method called when a form dfChange event is fired.
|
||||
* Dispatch form operations based on changes.
|
||||
*/
|
||||
onChange(event: DynamicFormControlEvent): void {
|
||||
this.formOperationsService.dispatchOperationsFromEvent(
|
||||
this.pathCombiner,
|
||||
event,
|
||||
@@ -209,7 +305,11 @@ export class FormSectionComponent extends SectionModelComponent {
|
||||
}
|
||||
}
|
||||
|
||||
onFocus(event: DynamicFormControlEvent) {
|
||||
/**
|
||||
* Method called when a form dfFocus event is fired.
|
||||
* Initialize [FormFieldPreviousValueObject] instance.
|
||||
*/
|
||||
onFocus(event: DynamicFormControlEvent): void {
|
||||
const value = this.formOperationsService.getFieldValueFromChangeEvent(event);
|
||||
const path = this.formBuilderService.getPath(event.model);
|
||||
if (this.formBuilderService.hasMappedGroupValue(event.model)) {
|
||||
@@ -221,7 +321,11 @@ export class FormSectionComponent extends SectionModelComponent {
|
||||
}
|
||||
}
|
||||
|
||||
onRemove(event: DynamicFormControlEvent) {
|
||||
/**
|
||||
* Method called when a form remove event is fired.
|
||||
* Dispatch form operations based on changes.
|
||||
*/
|
||||
onRemove(event: DynamicFormControlEvent): void {
|
||||
this.formOperationsService.dispatchOperationsFromEvent(
|
||||
this.pathCombiner,
|
||||
event,
|
||||
@@ -229,7 +333,15 @@ export class FormSectionComponent extends SectionModelComponent {
|
||||
this.hasStoredValue(this.formBuilderService.getId(event.model), this.formOperationsService.getArrayIndexFromEvent(event)));
|
||||
}
|
||||
|
||||
hasStoredValue(fieldId, index) {
|
||||
/**
|
||||
* Check if the specified form field has already a value stored
|
||||
*
|
||||
* @param fieldId
|
||||
* the section data retrieved from the serverù
|
||||
* @param index
|
||||
* the section data retrieved from the server
|
||||
*/
|
||||
hasStoredValue(fieldId, index): boolean {
|
||||
if (isNotEmpty(this.sectionData.data)) {
|
||||
return this.sectionData.data.hasOwnProperty(fieldId) && isNotEmpty(this.sectionData.data[fieldId][index]);
|
||||
} else {
|
||||
|
Reference in New Issue
Block a user