Skip to content

Commit 0ebf6bc

Browse files
author
Andrea Barbasso
committed
[CST-16756] listen to form saves and add errors to live region
1 parent a062db0 commit 0ebf6bc

File tree

7 files changed

+116
-8
lines changed

7 files changed

+116
-8
lines changed

src/app/shared/form/builder/ds-dynamic-form-ui/ds-dynamic-form-control-container.component.spec.ts

Lines changed: 51 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,12 +59,23 @@ import {
5959
DynamicNGBootstrapTextAreaComponent,
6060
DynamicNGBootstrapTimePickerComponent,
6161
} from '@ng-dynamic-forms/ui-ng-bootstrap';
62+
import { Actions } from '@ngrx/effects';
6263
import { Store } from '@ngrx/store';
6364
import { TranslateModule } from '@ngx-translate/core';
6465
import { NgxMaskModule } from 'ngx-mask';
65-
import { of } from 'rxjs';
66+
import {
67+
of,
68+
ReplaySubject,
69+
} from 'rxjs';
6670

6771
import { environment } from '../../../../../environments/environment';
72+
import {
73+
SaveForLaterSubmissionFormErrorAction,
74+
SaveSubmissionFormErrorAction,
75+
SaveSubmissionFormSuccessAction,
76+
SaveSubmissionSectionFormErrorAction,
77+
SaveSubmissionSectionFormSuccessAction,
78+
} from '../../../../submission/objects/submission-objects.actions';
6879
import { SubmissionService } from '../../../../submission/submission.service';
6980
import { SubmissionObjectService } from '../../../../submission/submission-object.service';
7081
import { LiveRegionService } from '../../../live-region/live-region.service';
@@ -208,6 +219,8 @@ describe('DsDynamicFormControlContainerComponent test suite', () => {
208219
const testItem: Item = new Item();
209220
const testWSI: WorkspaceItem = new WorkspaceItem();
210221
testWSI.item = of(createSuccessfulRemoteDataObject(testItem));
222+
const actions$: ReplaySubject<any> = new ReplaySubject<any>(1);
223+
211224
beforeEach(waitForAsync(() => {
212225

213226
TestBed.configureTestingModule({
@@ -241,6 +254,7 @@ describe('DsDynamicFormControlContainerComponent test suite', () => {
241254
{ provide: APP_DATA_SERVICES_MAP, useValue: {} },
242255
{ provide: DYNAMIC_FORM_CONTROL_MAP_FN, useValue: dsDynamicFormControlMapFn },
243256
{ provide: LiveRegionService, useValue: getLiveRegionServiceStub() },
257+
{ provide: Actions, useValue: actions$ },
244258
],
245259
schemas: [CUSTOM_ELEMENTS_SCHEMA],
246260
}).compileComponents().then(() => {
@@ -382,4 +396,40 @@ describe('DsDynamicFormControlContainerComponent test suite', () => {
382396
expect(testFn(formModel[25])).toEqual(DsDynamicFormGroupComponent);
383397
});
384398

399+
describe('store action subscriptions', () => {
400+
beforeEach(() => {
401+
fixture.detectChanges();
402+
});
403+
404+
it('should call announceErrorMessages on SAVE_SUBMISSION_FORM_SUCCESS', () => {
405+
spyOn(component, 'announceErrorMessages');
406+
actions$.next(new SaveSubmissionFormSuccessAction('1234', [] as any));
407+
expect(component.announceErrorMessages).toHaveBeenCalled();
408+
});
409+
410+
it('should call announceErrorMessages on SAVE_SUBMISSION_SECTION_FORM_SUCCESS', () => {
411+
spyOn(component, 'announceErrorMessages');
412+
actions$.next(new SaveSubmissionSectionFormSuccessAction('1234', [] as any));
413+
expect(component.announceErrorMessages).toHaveBeenCalled();
414+
});
415+
416+
it('should call announceErrorMessages on SAVE_SUBMISSION_FORM_ERROR', () => {
417+
spyOn(component, 'announceErrorMessages');
418+
actions$.next(new SaveSubmissionFormErrorAction('1234'));
419+
expect(component.announceErrorMessages).toHaveBeenCalled();
420+
});
421+
422+
it('should call announceErrorMessages on SAVE_FOR_LATER_SUBMISSION_FORM_ERROR', () => {
423+
spyOn(component, 'announceErrorMessages');
424+
actions$.next(new SaveForLaterSubmissionFormErrorAction('1234'));
425+
expect(component.announceErrorMessages).toHaveBeenCalled();
426+
});
427+
428+
it('should call announceErrorMessages on SAVE_SUBMISSION_SECTION_FORM_ERROR', () => {
429+
spyOn(component, 'announceErrorMessages');
430+
actions$.next(new SaveSubmissionSectionFormErrorAction('1234'));
431+
expect(component.announceErrorMessages).toHaveBeenCalled();
432+
});
433+
});
434+
385435
});

src/app/shared/form/builder/ds-dynamic-form-ui/ds-dynamic-form-control-container.component.ts

Lines changed: 29 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,10 @@ import {
9494
DynamicFormValidationService,
9595
DynamicTemplateDirective,
9696
} from '@ng-dynamic-forms/core';
97+
import {
98+
Actions,
99+
ofType,
100+
} from '@ngrx/effects';
97101
import { Store } from '@ngrx/store';
98102
import {
99103
TranslateModule,
@@ -113,6 +117,7 @@ import {
113117
} from 'rxjs/operators';
114118

115119
import { AppState } from '../../../../app.reducer';
120+
import { SubmissionObjectActionTypes } from '../../../../submission/objects/submission-objects.actions';
116121
import { SubmissionService } from '../../../../submission/submission.service';
117122
import { SubmissionObjectService } from '../../../../submission/submission-object.service';
118123
import { LiveRegionService } from '../../../live-region/live-region.service';
@@ -174,6 +179,8 @@ export class DsDynamicFormControlContainerComponent extends DynamicFormControlCo
174179
*/
175180
private subs: Subscription[] = [];
176181

182+
private liveRegionErrorMessagesShownAlready = false;
183+
177184
/* eslint-disable @angular-eslint/no-output-rename */
178185
@Output('dfBlur') blur: EventEmitter<DynamicFormControlEvent> = new EventEmitter<DynamicFormControlEvent>();
179186
@Output('dfChange') change: EventEmitter<DynamicFormControlEvent> = new EventEmitter<DynamicFormControlEvent>();
@@ -215,6 +222,7 @@ export class DsDynamicFormControlContainerComponent extends DynamicFormControlCo
215222
protected metadataService: MetadataService,
216223
@Inject(APP_CONFIG) protected appConfig: AppConfig,
217224
@Inject(DYNAMIC_FORM_CONTROL_MAP_FN) protected dynamicFormControlFn: DynamicFormControlMapFn,
225+
private actions$: Actions,
218226
) {
219227
super(ref, componentFactoryResolver, layoutService, validationService, dynamicFormComponentService, relationService);
220228
this.fetchThumbnail = this.appConfig.browseBy.showThumbnails;
@@ -227,6 +235,18 @@ export class DsDynamicFormControlContainerComponent extends DynamicFormControlCo
227235
this.isRelationship = hasValue(this.model.relationship);
228236
const isWrapperAroundRelationshipList = hasValue(this.model.relationshipConfig);
229237

238+
// Subscribe to specified submission actions to announce error messages
239+
const errorAnnounceActionsSub = this.actions$.pipe(
240+
ofType(
241+
SubmissionObjectActionTypes.SAVE_SUBMISSION_FORM_SUCCESS,
242+
SubmissionObjectActionTypes.SAVE_SUBMISSION_SECTION_FORM_SUCCESS,
243+
SubmissionObjectActionTypes.SAVE_SUBMISSION_FORM_ERROR,
244+
SubmissionObjectActionTypes.SAVE_FOR_LATER_SUBMISSION_FORM_ERROR,
245+
SubmissionObjectActionTypes.SAVE_SUBMISSION_SECTION_FORM_ERROR,
246+
),
247+
).subscribe(() => this.announceErrorMessages());
248+
this.subs.push(errorAnnounceActionsSub);
249+
230250
if (this.isRelationship || isWrapperAroundRelationshipList) {
231251
const config = this.model.relationshipConfig || this.model.relationship;
232252
const relationshipOptions = Object.assign(new RelationshipOptions(), config);
@@ -359,15 +379,20 @@ export class DsDynamicFormControlContainerComponent extends DynamicFormControlCo
359379
* Announce error messages to the user
360380
*/
361381
announceErrorMessages() {
362-
const numberOfInvalidInputs = this.getNumberOfInvalidInputs() ?? 1;
363-
setTimeout(() => {
382+
if (!this.liveRegionErrorMessagesShownAlready) {
383+
this.liveRegionErrorMessagesShownAlready = true;
384+
const numberOfInvalidInputs = this.getNumberOfInvalidInputs() ?? 1;
385+
const timeoutMs = numberOfInvalidInputs * 3500;
364386
this.errorMessages.forEach((errorMsg) => {
365387
// set timer based on the number of the invalid inputs
366-
this.liveRegionService.setMessageTimeOutMs(numberOfInvalidInputs * 3500);
388+
this.liveRegionService.setMessageTimeOutMs(timeoutMs);
367389
const message = this.translateService.instant(errorMsg);
368390
this.liveRegionService.addMessage(message);
369391
});
370-
}, 14000);// wait for the general deposit alert to be announced
392+
setTimeout(() => {
393+
this.liveRegionErrorMessagesShownAlready = false;
394+
}, timeoutMs);
395+
}
371396
}
372397

373398
/**

src/app/shared/form/builder/ds-dynamic-form-ui/models/array-group/dynamic-form-array.component.spec.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,13 +16,17 @@ import {
1616
DynamicFormValidationService,
1717
DynamicInputModel,
1818
} from '@ng-dynamic-forms/core';
19+
import { provideMockActions } from '@ngrx/effects/testing';
1920
import { provideMockStore } from '@ngrx/store/testing';
2021
import {
2122
TranslateModule,
2223
TranslateService,
2324
} from '@ngx-translate/core';
2425
import { NgxMaskModule } from 'ngx-mask';
25-
import { of } from 'rxjs';
26+
import {
27+
Observable,
28+
of,
29+
} from 'rxjs';
2630
import { LiveRegionService } from 'src/app/shared/live-region/live-region.service';
2731

2832
import { environment } from '../../../../../../../environments/environment.test';
@@ -61,6 +65,7 @@ describe('DsDynamicFormArrayComponent', () => {
6165
{ provide: TranslateService, useValue: translateServiceStub },
6266
{ provide: HttpClient, useValue: {} },
6367
{ provide: SubmissionService, useValue: {} },
68+
provideMockActions(() => new Observable<any>()),
6469
{ provide: APP_CONFIG, useValue: environment },
6570
{ provide: DYNAMIC_FORM_CONTROL_MAP_FN, useValue: dsDynamicFormControlMapFn },
6671
{ provide: LiveRegionService, useValue: getLiveRegionServiceStub() },

src/app/shared/form/builder/ds-dynamic-form-ui/models/relation-group/dynamic-relation-group.component.spec.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,10 @@ import {
3535
DynamicFormLayoutService,
3636
DynamicFormValidationService,
3737
} from '@ng-dynamic-forms/core';
38+
import { provideMockActions } from '@ngrx/effects/testing';
3839
import { provideMockStore } from '@ngrx/store/testing';
3940
import { TranslateModule } from '@ngx-translate/core';
41+
import { Observable } from 'rxjs';
4042

4143
import { environment } from '../../../../../../../environments/environment.test';
4244
import { SubmissionService } from '../../../../../../submission/submission.service';
@@ -171,6 +173,7 @@ describe('DsDynamicRelationGroupComponent test suite', () => {
171173
FormComponent,
172174
FormService,
173175
provideMockStore({ initialState }),
176+
provideMockActions(() => new Observable<any>()),
174177
{ provide: VocabularyService, useValue: vocabularyServiceStub },
175178
{ provide: DsDynamicTypeBindRelationService, useClass: DsDynamicTypeBindRelationService },
176179
{ provide: SubmissionObjectService, useValue: {} },
@@ -183,6 +186,11 @@ describe('DsDynamicRelationGroupComponent test suite', () => {
183186
],
184187
schemas: [CUSTOM_ELEMENTS_SCHEMA],
185188
})
189+
.overrideComponent(DsDynamicRelationGroupComponent, {
190+
remove: {
191+
imports: [FormComponent],
192+
},
193+
})
186194
.compileComponents();
187195

188196
}));

src/app/shared/resource-policies/form/resource-policy-form.component.spec.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,11 +44,15 @@ import {
4444
import { isNotEmptyOperator } from '@dspace/shared/utils/empty.util';
4545
import { NgbModule } from '@ng-bootstrap/ng-bootstrap';
4646
import { DYNAMIC_FORM_CONTROL_MAP_FN } from '@ng-dynamic-forms/core';
47+
import { provideMockActions } from '@ngrx/effects/testing';
4748
import { provideMockStore } from '@ngrx/store/testing';
4849
import { TranslateModule } from '@ngx-translate/core';
4950
import { getTestScheduler } from 'jasmine-marbles';
5051
import { NgxMaskModule } from 'ngx-mask';
51-
import { of } from 'rxjs';
52+
import {
53+
Observable,
54+
of,
55+
} from 'rxjs';
5256
import { delay } from 'rxjs/operators';
5357
import { TestScheduler } from 'rxjs/testing';
5458

@@ -237,6 +241,7 @@ describe('ResourcePolicyFormComponent test suite', () => {
237241
{ provide: APP_DATA_SERVICES_MAP, useValue: {} },
238242
{ provide: DYNAMIC_FORM_CONTROL_MAP_FN, useValue: dsDynamicFormControlMapFn },
239243
provideMockStore({}),
244+
provideMockActions(() => new Observable<any>()),
240245
{ provide: LiveRegionService, useValue: getLiveRegionServiceStub() },
241246
],
242247
schemas: [

src/app/submission/sections/accesses/section-accesses.component.spec.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,11 @@ describe('SubmissionSectionAccessesComponent', () => {
130130
provideMockStore({}),
131131
],
132132
})
133+
.overrideComponent(SubmissionSectionAccessesComponent, {
134+
remove: {
135+
imports: [FormComponent],
136+
},
137+
})
133138
.compileComponents();
134139
});
135140

@@ -229,6 +234,11 @@ describe('SubmissionSectionAccessesComponent', () => {
229234

230235
],
231236
})
237+
.overrideComponent(SubmissionSectionAccessesComponent, {
238+
remove: {
239+
imports: [FormComponent],
240+
},
241+
})
232242
.compileComponents();
233243
});
234244

src/app/submission/sections/license/section-license.component.spec.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,10 +40,14 @@ import {
4040
DynamicFormControlEvent,
4141
DynamicFormControlEventType,
4242
} from '@ng-dynamic-forms/core';
43+
import { provideMockActions } from '@ngrx/effects/testing';
4344
import { provideMockStore } from '@ngrx/store/testing';
4445
import { TranslateModule } from '@ngx-translate/core';
4546
import { cold } from 'jasmine-marbles';
46-
import { of } from 'rxjs';
47+
import {
48+
Observable,
49+
of,
50+
} from 'rxjs';
4751
import { take } from 'rxjs/operators';
4852

4953
import { environment } from '../../../../environments/environment.test';
@@ -182,6 +186,7 @@ describe('SubmissionSectionLicenseComponent test suite', () => {
182186
{ provide: 'submissionIdProvider', useValue: submissionId },
183187
ChangeDetectorRef,
184188
provideMockStore({ initialState }),
189+
provideMockActions(() => new Observable<any>()),
185190
FormBuilderService,
186191
{ provide: DsDynamicTypeBindRelationService, useValue: getMockDsDynamicTypeBindRelationService() },
187192
{ provide: APP_CONFIG, useValue: environment },

0 commit comments

Comments
 (0)