mirror of
https://github.com/Alfresco/alfresco-ng2-components.git
synced 2026-09-09 18:03:21 +00:00
AAE-49862 Fix Form Rule Does Not Update Hidden Status of Outcomes on First Run (#12168)
This commit is contained in:
@@ -16,6 +16,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import { Subject } from 'rxjs';
|
import { Subject } from 'rxjs';
|
||||||
|
import { FormEvent } from '../events/form.event';
|
||||||
import { FormFieldEvent } from '../events/form-field.event';
|
import { FormFieldEvent } from '../events/form-field.event';
|
||||||
import { FormRulesEvent } from '../events/form-rules.event';
|
import { FormRulesEvent } from '../events/form-rules.event';
|
||||||
import { ValidateFormFieldEvent } from '../events/validate-form-field.event';
|
import { ValidateFormFieldEvent } from '../events/validate-form-field.event';
|
||||||
@@ -26,4 +27,5 @@ export interface FormValidationService {
|
|||||||
validateForm: Subject<ValidateFormEvent>;
|
validateForm: Subject<ValidateFormEvent>;
|
||||||
validateFormField: Subject<ValidateFormFieldEvent>;
|
validateFormField: Subject<ValidateFormFieldEvent>;
|
||||||
formRulesEvent?: Subject<FormRulesEvent>;
|
formRulesEvent?: Subject<FormRulesEvent>;
|
||||||
|
formVisibilityRefreshed?: Subject<FormEvent>;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -62,6 +62,12 @@ export class FormService implements FormValidationService {
|
|||||||
|
|
||||||
formRulesEvent = new Subject<FormRulesEvent>();
|
formRulesEvent = new Subject<FormRulesEvent>();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Emitted after form field/outcome visibility has been re-evaluated via WidgetVisibilityService.refreshVisibility.
|
||||||
|
* Internal ADF form-rendering event — not part of the FormValidationService contract.
|
||||||
|
*/
|
||||||
|
formVisibilityRefreshed = new Subject<FormEvent>();
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
const injectedFieldValidators = inject(FORM_SERVICE_FIELD_VALIDATORS_TOKEN, { optional: true });
|
const injectedFieldValidators = inject(FORM_SERVICE_FIELD_VALIDATORS_TOKEN, { optional: true });
|
||||||
|
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ import { TestBed } from '@angular/core/testing';
|
|||||||
import { ContainerModel, FormFieldModel, FormFieldTypes, FormModel, TabModel } from '../components/widgets/core';
|
import { ContainerModel, FormFieldModel, FormFieldTypes, FormModel, TabModel } from '../components/widgets/core';
|
||||||
import { WidgetVisibilityModel } from '../models/widget-visibility.model';
|
import { WidgetVisibilityModel } from '../models/widget-visibility.model';
|
||||||
import { WidgetVisibilityService } from './widget-visibility.service';
|
import { WidgetVisibilityService } from './widget-visibility.service';
|
||||||
|
import { FormService } from './form.service';
|
||||||
import {
|
import {
|
||||||
fakeFormJson,
|
fakeFormJson,
|
||||||
formTest,
|
formTest,
|
||||||
@@ -50,6 +51,30 @@ describe('WidgetVisibilityService', () => {
|
|||||||
service = TestBed.inject(WidgetVisibilityService);
|
service = TestBed.inject(WidgetVisibilityService);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should emit formVisibilityRefreshed when visibility is refreshed', () => {
|
||||||
|
const formService = TestBed.inject(FormService);
|
||||||
|
let emittedForm: FormModel | undefined;
|
||||||
|
|
||||||
|
formService.formVisibilityRefreshed.subscribe((event) => {
|
||||||
|
emittedForm = event.form;
|
||||||
|
});
|
||||||
|
|
||||||
|
service.refreshVisibility(stubFormWithFields);
|
||||||
|
|
||||||
|
expect(emittedForm).toBe(stubFormWithFields);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should not emit formVisibilityRefreshed when form is null', () => {
|
||||||
|
const formService = TestBed.inject(FormService);
|
||||||
|
let emitCount = 0;
|
||||||
|
|
||||||
|
formService.formVisibilityRefreshed.subscribe(() => emitCount++);
|
||||||
|
|
||||||
|
service.refreshVisibility(null);
|
||||||
|
|
||||||
|
expect(emitCount).toBe(0);
|
||||||
|
});
|
||||||
|
|
||||||
describe('should be able to evaluate next condition operations', () => {
|
describe('should be able to evaluate next condition operations', () => {
|
||||||
it('using == and return true', () => {
|
it('using == and return true', () => {
|
||||||
const resultsArray = evaluateConditions(
|
const resultsArray = evaluateConditions(
|
||||||
|
|||||||
@@ -15,16 +15,20 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { Injectable } from '@angular/core';
|
import { inject, Injectable } from '@angular/core';
|
||||||
import { FormFieldModel, FormModel, TabModel, ContainerModel, FormOutcomeModel } from '../components/widgets/core';
|
import { FormFieldModel, FormModel, TabModel, ContainerModel, FormOutcomeModel } from '../components/widgets/core';
|
||||||
|
import { FormEvent } from '../events/form.event';
|
||||||
import { TaskProcessVariableModel } from '../models/task-process-variable.model';
|
import { TaskProcessVariableModel } from '../models/task-process-variable.model';
|
||||||
import { WidgetVisibilityModel, WidgetTypeEnum } from '../models/widget-visibility.model';
|
import { WidgetVisibilityModel, WidgetTypeEnum } from '../models/widget-visibility.model';
|
||||||
import { format, isValid, parse } from 'date-fns';
|
import { format, isValid, parse } from 'date-fns';
|
||||||
|
import { FormService } from './form.service';
|
||||||
|
|
||||||
@Injectable({
|
@Injectable({
|
||||||
providedIn: 'root'
|
providedIn: 'root'
|
||||||
})
|
})
|
||||||
export class WidgetVisibilityService {
|
export class WidgetVisibilityService {
|
||||||
|
private readonly formService = inject(FormService);
|
||||||
|
|
||||||
private processVarList: TaskProcessVariableModel[];
|
private processVarList: TaskProcessVariableModel[];
|
||||||
private form: FormModel;
|
private form: FormModel;
|
||||||
|
|
||||||
@@ -45,6 +49,8 @@ export class WidgetVisibilityService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
form.getFormFields().map((field) => this.refreshEntityVisibility(field));
|
form.getFormFields().map((field) => this.refreshEntityVisibility(field));
|
||||||
|
|
||||||
|
this.formService.formVisibilityRefreshed.next(new FormEvent(form));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -32,6 +32,8 @@ import {
|
|||||||
provideTranslations,
|
provideTranslations,
|
||||||
AuthModule,
|
AuthModule,
|
||||||
FormFieldEvent,
|
FormFieldEvent,
|
||||||
|
FormEvent,
|
||||||
|
FormRulesEvent,
|
||||||
NoopTranslateModule,
|
NoopTranslateModule,
|
||||||
NoopAuthModule,
|
NoopAuthModule,
|
||||||
FORM_FIELD_VALIDATORS
|
FORM_FIELD_VALIDATORS
|
||||||
@@ -1299,6 +1301,38 @@ describe('FormCloudComponent', () => {
|
|||||||
expect(formComponent.visibleOutcomes).toEqual([]);
|
expect(formComponent.visibleOutcomes).toEqual([]);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should recompute visibleOutcomes when form visibility is refreshed', () => {
|
||||||
|
formComponent.showCompleteButton = true;
|
||||||
|
const formModel = new FormModel(cloudFormMock);
|
||||||
|
formComponent.form = formModel;
|
||||||
|
|
||||||
|
expect(formComponent.visibleOutcomes.length).toBeGreaterThan(0);
|
||||||
|
|
||||||
|
formModel.outcomes.forEach((outcome) => {
|
||||||
|
outcome.isVisible = false;
|
||||||
|
});
|
||||||
|
|
||||||
|
TestBed.inject(FormService).formVisibilityRefreshed.next(new FormEvent(formModel));
|
||||||
|
|
||||||
|
expect(formComponent.visibleOutcomes).toEqual([]);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should recompute visibleOutcomes when fieldValueChanged rule event fires', () => {
|
||||||
|
formComponent.showCompleteButton = true;
|
||||||
|
const formModel = new FormModel(cloudFormMock);
|
||||||
|
formComponent.form = formModel;
|
||||||
|
|
||||||
|
expect(formComponent.visibleOutcomes.length).toBeGreaterThan(0);
|
||||||
|
|
||||||
|
formModel.outcomes.forEach((outcome) => {
|
||||||
|
outcome.isVisible = false;
|
||||||
|
});
|
||||||
|
|
||||||
|
TestBed.inject(FormService).formRulesEvent.next(new FormRulesEvent('fieldValueChanged', new FormEvent(formModel)));
|
||||||
|
|
||||||
|
expect(formComponent.visibleOutcomes).toEqual([]);
|
||||||
|
});
|
||||||
|
|
||||||
it('should raise [executeOutcome] event for formService', async () => {
|
it('should raise [executeOutcome] event for formService', async () => {
|
||||||
spyOn(formComponent.executeOutcome, 'emit');
|
spyOn(formComponent.executeOutcome, 'emit');
|
||||||
|
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ import {
|
|||||||
SimpleChanges,
|
SimpleChanges,
|
||||||
ViewChild
|
ViewChild
|
||||||
} from '@angular/core';
|
} from '@angular/core';
|
||||||
import { forkJoin, isObservable, Observable, of, Subscription } from 'rxjs';
|
import { forkJoin, isObservable, merge, Observable, of, Subscription } from 'rxjs';
|
||||||
import { filter, map, switchMap } from 'rxjs/operators';
|
import { filter, map, switchMap } from 'rxjs/operators';
|
||||||
import {
|
import {
|
||||||
ConfirmDialogComponent,
|
ConfirmDialogComponent,
|
||||||
@@ -306,11 +306,11 @@ export class FormCloudComponent extends FormBaseComponent implements OnChanges,
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
this.formService.formRulesEvent
|
merge(
|
||||||
.pipe(
|
this.formService.formVisibilityRefreshed.pipe(filter((event) => event.form?.id === this.form?.id)),
|
||||||
filter((event) => event?.type === 'fieldValueChanged' && event.form?.id === this.form?.id),
|
this.formService.formRulesEvent.pipe(filter((event) => event?.type === 'fieldValueChanged' && event.form?.id === this.form?.id))
|
||||||
takeUntilDestroyed()
|
)
|
||||||
)
|
.pipe(takeUntilDestroyed())
|
||||||
.subscribe(() => this.recomputeVisibleOutcomes());
|
.subscribe(() => this.recomputeVisibleOutcomes());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -595,7 +595,6 @@ export class FormCloudComponent extends FormBaseComponent implements OnChanges,
|
|||||||
checkVisibility(field: FormFieldModel) {
|
checkVisibility(field: FormFieldModel) {
|
||||||
if (field?.form) {
|
if (field?.form) {
|
||||||
this.visibilityService.refreshVisibility(field.form);
|
this.visibilityService.refreshVisibility(field.form);
|
||||||
this.recomputeVisibleOutcomes();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -613,7 +612,6 @@ export class FormCloudComponent extends FormBaseComponent implements OnChanges,
|
|||||||
this.setCheckParentVisibilityForValidationOnFields();
|
this.setCheckParentVisibilityForValidationOnFields();
|
||||||
this.visibilityService.refreshVisibility(this.form);
|
this.visibilityService.refreshVisibility(this.form);
|
||||||
this.form.validateForm();
|
this.form.validateForm();
|
||||||
this.recomputeVisibleOutcomes();
|
|
||||||
this.onFormLoaded(this.form);
|
this.onFormLoaded(this.form);
|
||||||
this.formService.formRulesEvent.next(new FormRulesEvent('dataRefreshed', new FormEvent(this.form)));
|
this.formService.formRulesEvent.next(new FormRulesEvent('dataRefreshed', new FormEvent(this.form)));
|
||||||
this.onFormDataRefreshed(this.form);
|
this.onFormDataRefreshed(this.form);
|
||||||
|
|||||||
Reference in New Issue
Block a user