mirror of
https://github.com/Alfresco/alfresco-ng2-components.git
synced 2026-09-02 17:53:30 +00:00
AAE-46517 Add onRowCountChange form event for Repeatable Sections (#12062)
* AAE-46517 Add onRowCountChange event for Repeatable Sections * code review fixes for unit test
This commit is contained in:
@@ -16,6 +16,8 @@
|
||||
*/
|
||||
|
||||
import { DateFnsUtils } from '../../../../common';
|
||||
import { FormRulesEvent } from '../../../events/form-rules.event';
|
||||
import { firstValueFrom, map, Subject, take, timeout } from 'rxjs';
|
||||
import { FormFieldTypes } from './form-field-types';
|
||||
import { RequiredFieldValidator } from './form-field-validator';
|
||||
import { FormFieldModel } from './form-field.model';
|
||||
@@ -1541,6 +1543,17 @@ describe('FormFieldModel', () => {
|
||||
});
|
||||
|
||||
describe('add row', () => {
|
||||
const assignFormRulesEventSubject = (): Subject<FormRulesEvent> => {
|
||||
const formRulesEvent = new Subject<FormRulesEvent>();
|
||||
(field.form as any).formService = {
|
||||
formRulesEvent,
|
||||
validateForm: new Subject(),
|
||||
validateFormField: new Subject(),
|
||||
formFieldValueChanged: new Subject()
|
||||
};
|
||||
return formRulesEvent;
|
||||
};
|
||||
|
||||
it('should add row if allowed by limit param', () => {
|
||||
expect(field.rows.length).toBe(2);
|
||||
|
||||
@@ -1568,18 +1581,56 @@ describe('FormFieldModel', () => {
|
||||
expect(field.rows.length).toBe(5);
|
||||
});
|
||||
|
||||
it('should call onRepeatableSectionChanged', () => {
|
||||
spyOn(field.form, 'onRepeatableSectionChanged').and.callThrough();
|
||||
it('should call onRepeatableSectionRowCountChanged', () => {
|
||||
spyOn(field.form, 'onRepeatableSectionRowCountChanged').and.callThrough();
|
||||
|
||||
expect(field.form.onRepeatableSectionChanged).not.toHaveBeenCalled();
|
||||
expect(field.form.onRepeatableSectionRowCountChanged).not.toHaveBeenCalled();
|
||||
|
||||
field.addRow(field.fields, form);
|
||||
|
||||
expect(field.form.onRepeatableSectionChanged).toHaveBeenCalled();
|
||||
expect(field.form.onRepeatableSectionRowCountChanged).toHaveBeenCalledWith(field);
|
||||
});
|
||||
|
||||
it('should emit onRowCountChanged via formService.formRulesEvent', async () => {
|
||||
const formRulesEvent = assignFormRulesEventSubject();
|
||||
const emissionPromise = firstValueFrom(formRulesEvent);
|
||||
|
||||
field.addRow(field.fields, form);
|
||||
|
||||
const emittedEvent = await emissionPromise;
|
||||
expect(emittedEvent.type).toBe('onRowCountChanged');
|
||||
expect(emittedEvent.field).toBe(field);
|
||||
});
|
||||
|
||||
it('should NOT emit onRowCountChanged when add row is not allowed', async () => {
|
||||
const formRulesEvent = assignFormRulesEventSubject();
|
||||
|
||||
field.addRow(field.fields, form);
|
||||
field.addRow(field.fields, form);
|
||||
field.addRow(field.fields, form);
|
||||
expect(field.rows.length).toBe(5);
|
||||
|
||||
const emissionPromise = firstValueFrom(formRulesEvent.pipe(timeout(50)));
|
||||
|
||||
field.addRow(field.fields, form);
|
||||
|
||||
await expectAsync(emissionPromise).toBeRejected();
|
||||
expect(field.rows.length).toBe(5);
|
||||
});
|
||||
});
|
||||
|
||||
describe('remove row', () => {
|
||||
const assignFormRulesEventSubject = (): Subject<FormRulesEvent> => {
|
||||
const formRulesEvent = new Subject<FormRulesEvent>();
|
||||
(field.form as any).formService = {
|
||||
formRulesEvent,
|
||||
validateForm: new Subject(),
|
||||
validateFormField: new Subject(),
|
||||
formFieldValueChanged: new Subject()
|
||||
};
|
||||
return formRulesEvent;
|
||||
};
|
||||
|
||||
it('should remove row if target index exists', () => {
|
||||
expect(field.rows.length).toBe(2);
|
||||
|
||||
@@ -1646,14 +1697,77 @@ describe('FormFieldModel', () => {
|
||||
expect(field.form.onFormFieldChanged).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should call onRepeatableSectionChanged', () => {
|
||||
spyOn(field.form, 'onRepeatableSectionChanged').and.callThrough();
|
||||
it('should call onRepeatableSectionRowCountChanged', () => {
|
||||
spyOn(field.form, 'onRepeatableSectionRowCountChanged').and.callThrough();
|
||||
|
||||
expect(field.form.onRepeatableSectionChanged).not.toHaveBeenCalled();
|
||||
expect(field.form.onRepeatableSectionRowCountChanged).not.toHaveBeenCalled();
|
||||
|
||||
field.removeRow(1);
|
||||
|
||||
expect(field.form.onRepeatableSectionChanged).toHaveBeenCalled();
|
||||
expect(field.form.onRepeatableSectionRowCountChanged).toHaveBeenCalledWith(field);
|
||||
});
|
||||
|
||||
it('should emit onRowCountChanged via formService.formRulesEvent', async () => {
|
||||
const formRulesEvent = assignFormRulesEventSubject();
|
||||
const emissionPromise = firstValueFrom(formRulesEvent);
|
||||
|
||||
field.removeRow(1);
|
||||
|
||||
const emittedEvent = await emissionPromise;
|
||||
expect(emittedEvent.type).toBe('onRowCountChanged');
|
||||
expect(emittedEvent.field).toBe(field);
|
||||
});
|
||||
|
||||
it('should update form values before emitting onRowCountChanged', async () => {
|
||||
const formRulesEvent = assignFormRulesEventSubject();
|
||||
form.values[field.id] = [
|
||||
{
|
||||
Text0wwp7n: 'mock-1',
|
||||
Integer0rzkwq: 1
|
||||
},
|
||||
{
|
||||
Text0wwp7n: 'mock-2',
|
||||
Integer0rzkwq: 2
|
||||
}
|
||||
];
|
||||
|
||||
const valuesLengthAtEmissionPromise = firstValueFrom(
|
||||
formRulesEvent.pipe(
|
||||
take(1),
|
||||
map(() => form.values[field.id].length)
|
||||
)
|
||||
);
|
||||
|
||||
field.removeRow(1);
|
||||
|
||||
const valuesLengthAtEmission = await valuesLengthAtEmissionPromise;
|
||||
expect(valuesLengthAtEmission).toBe(1);
|
||||
expect(form.values[field.id]).toEqual([
|
||||
{
|
||||
Text0wwp7n: 'mock-1',
|
||||
Integer0rzkwq: 1
|
||||
}
|
||||
]);
|
||||
});
|
||||
|
||||
it('should emit onRowCountChanged even when form values do not contain section id', async () => {
|
||||
const formRulesEvent = assignFormRulesEventSubject();
|
||||
form.values = {};
|
||||
const emissionPromise = firstValueFrom(formRulesEvent);
|
||||
|
||||
field.removeRow(1);
|
||||
|
||||
const emittedEvent = await emissionPromise;
|
||||
expect(emittedEvent.type).toBe('onRowCountChanged');
|
||||
});
|
||||
|
||||
it('should NOT emit onRowCountChanged when remove row target index does not exist', async () => {
|
||||
const formRulesEvent = assignFormRulesEventSubject();
|
||||
const emissionPromise = firstValueFrom(formRulesEvent.pipe(timeout(50)));
|
||||
|
||||
field.removeRow(2);
|
||||
|
||||
await expectAsync(emissionPromise).toBeRejected();
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@@ -470,7 +470,7 @@ export class FormFieldModel extends FormWidgetModel {
|
||||
}
|
||||
|
||||
this.rows.push(this.createRow(fields, form, this.rows.length));
|
||||
this.form.onRepeatableSectionChanged();
|
||||
this.form.onRepeatableSectionRowCountChanged(this);
|
||||
}
|
||||
|
||||
private shouldAddRow(): boolean {
|
||||
@@ -484,14 +484,17 @@ export class FormFieldModel extends FormWidgetModel {
|
||||
|
||||
this.rows.splice(index, 1);
|
||||
this.updateChildrenFieldsRowIndex();
|
||||
this.form.onRepeatableSectionChanged();
|
||||
|
||||
if (!this.form.values[this.id]) {
|
||||
return;
|
||||
const hasSectionValues = !!this.form.values[this.id];
|
||||
if (hasSectionValues) {
|
||||
this.form.values[this.id].splice(index, 1);
|
||||
}
|
||||
|
||||
this.form.values[this.id].splice(index, 1);
|
||||
this.form.onFormFieldChanged(this);
|
||||
this.form.onRepeatableSectionRowCountChanged(this);
|
||||
|
||||
if (hasSectionValues) {
|
||||
this.form.onFormFieldChanged(this);
|
||||
}
|
||||
}
|
||||
|
||||
private shouldRemoveRow(index: number): boolean {
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
*/
|
||||
|
||||
import { FormFieldEvent } from '../../../events/form-field.event';
|
||||
import { FormRulesEvent } from '../../../events/form-rules.event';
|
||||
import { ValidateFormFieldEvent } from '../../../events/validate-form-field.event';
|
||||
import { ValidateFormEvent } from '../../../events/validate-form.event';
|
||||
import { ContainerModel } from './container.model';
|
||||
@@ -154,6 +155,11 @@ export class FormModel implements ProcessFormModel {
|
||||
this.fieldsCache = this.getFormFields([], true);
|
||||
}
|
||||
|
||||
onRepeatableSectionRowCountChanged(sectionField: FormFieldModel): void {
|
||||
this.onRepeatableSectionChanged();
|
||||
this.formService?.formRulesEvent?.next(new FormRulesEvent('onRowCountChanged', new FormFieldEvent(this, sectionField)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates entire form and all form fields.
|
||||
*/
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
|
||||
import { Subject } from 'rxjs';
|
||||
import { FormFieldEvent } from '../events/form-field.event';
|
||||
import { FormRulesEvent } from '../events/form-rules.event';
|
||||
import { ValidateFormFieldEvent } from '../events/validate-form-field.event';
|
||||
import { ValidateFormEvent } from '../events/validate-form.event';
|
||||
|
||||
@@ -24,4 +25,5 @@ export interface FormValidationService {
|
||||
formFieldValueChanged: Subject<FormFieldEvent>;
|
||||
validateForm: Subject<ValidateFormEvent>;
|
||||
validateFormField: Subject<ValidateFormFieldEvent>;
|
||||
formRulesEvent?: Subject<FormRulesEvent>;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user