AAE-32255 Start Process button in start event is showing and failing for form with custom outcomes (#10697)

* [AAE-32255] check if form has visible outcomes

* [AAE-32255] readded ?

* [AAE-32255] use pipe and observable

* [AAE-32255] check if exists
This commit is contained in:
Michaela
2025-03-11 17:21:55 +01:00
committed by GitHub
parent 08fd1f3d12
commit a74388513e
5 changed files with 69 additions and 19 deletions

View File

@@ -73,6 +73,7 @@
<ng-container *ngIf="hasForm else taskFormCloudButtons">
<adf-cloud-form
#startForm
[appName]="appName"
[appVersion]="processDefinitionCurrent.appVersion"
[data]="resolvedValues"
@@ -108,7 +109,7 @@
{{ cancelButtonLabel }}
</button>
<button
*ngIf="showStartProcessButton"
*ngIf="showStartProcessButton$ | async"
color="primary"
mat-raised-button
[disabled]="disableStartButton || !isProcessFormValid"

View File

@@ -31,7 +31,8 @@ import {
fakeNoNameProcessDefinitions,
fakeSingleProcessDefinition,
fakeSingleProcessDefinitionWithoutForm,
fakeFormModelJson
fakeFormModelJson,
fakeStartFormWithOutcomes
} from '../mock/start-process.component.mock';
import { By } from '@angular/platform-browser';
import { ProcessPayloadCloud } from '../models/process-payload-cloud.model';
@@ -69,6 +70,8 @@ describe('StartProcessCloudComponent', () => {
const panel = await loader.getHarness(MatAutocompleteHarness);
await panel.selectOption({ text: name });
fixture.detectChanges();
await fixture.whenStable();
};
const typeValueInto = (selector: any, value: string) => {
@@ -185,8 +188,6 @@ describe('StartProcessCloudComponent', () => {
component.name = 'My new process';
component.processDefinitionName = 'process';
await selectOptionByName('processwithoutform2');
fixture.detectChanges();
await fixture.whenStable();
expect(component.processDefinitionCurrent.name).toBe(JSON.parse(JSON.stringify(fakeProcessDefinitions[1])).name);
const startBtn = fixture.nativeElement.querySelector('#button-start');
@@ -537,8 +538,6 @@ describe('StartProcessCloudComponent', () => {
await fixture.whenStable();
await selectOptionByName('processwithform');
fixture.detectChanges();
await fixture.whenStable();
component.processDefinitionName = fakeProcessDefinitions[2].name;
component.setProcessDefinitionOnForm(fakeProcessDefinitions[2].name);
@@ -570,9 +569,6 @@ describe('StartProcessCloudComponent', () => {
component.ngOnChanges({});
await selectOptionByName('process');
fixture.detectChanges();
await fixture.whenStable();
expect(component.processDefinitionCurrent.name).toBe(JSON.parse(JSON.stringify(fakeProcessDefinitions[3])).name);
expect(component.processDefinitionCurrent.key).toBe(JSON.parse(JSON.stringify(fakeProcessDefinitions[3])).key);
});
@@ -701,16 +697,38 @@ describe('StartProcessCloudComponent', () => {
fixture.detectChanges();
});
it('should see start button', async () => {
it('should show start button', () => {
component.ngOnChanges({ appName: firstChange });
fixture.detectChanges();
await fixture.whenStable();
const startButton = fixture.debugElement.query(By.css('#button-start'));
expect(startButton).toBeDefined();
expect(startButton).not.toBeNull();
});
it('should show start button when start process has form without outcomes', async () => {
formDefinitionSpy.and.returnValue(of(fakeStartForm));
component.ngOnChanges({ appName: firstChange });
fixture.detectChanges();
await selectOptionByName('processwithform');
const startButton = fixture.debugElement.query(By.css('#button-start'));
expect(startButton).toBeDefined();
expect(startButton).not.toBeNull();
});
it('should NOT see start button when start process has form with outcomes', async () => {
formDefinitionSpy.and.returnValue(of(fakeStartFormWithOutcomes));
component.ngOnChanges({ appName: firstChange });
fixture.detectChanges();
await selectOptionByName('processwithform');
const startButton = fixture.debugElement.query(By.css('#button-start'));
expect(startButton).toBeNull();
});
it('should call service with the correct parameters when button is clicked and variables are defined and formCloud is undefined', async () => {
component.ngOnChanges({ appName: firstChange });
component.processForm.controls['processInstanceName'].setValue('My Process 1');
@@ -820,8 +838,6 @@ describe('StartProcessCloudComponent', () => {
await fixture.whenStable();
await selectOptionByName('processwithform');
fixture.detectChanges();
await fixture.whenStable();
component.processDefinitionName = fakeProcessDefinitions[2].name;
component.setProcessDefinitionOnForm(fakeProcessDefinitions[2].name);
@@ -941,8 +957,6 @@ describe('StartProcessCloudComponent', () => {
await fixture.whenStable();
component.processDefinitionName = 'processwithoutform1';
await selectOptionByName(fakeProcessDefinitions[0].name);
fixture.detectChanges();
await fixture.whenStable();
expect(emitSpy).toHaveBeenCalledOnceWith(fakeProcessDefinitions[0]);
});

View File

@@ -32,12 +32,12 @@ import {
import { ContentLinkModel, FormModel, InplaceFormInputComponent, LocalizedDatePipe, TranslationService } from '@alfresco/adf-core';
import { AbstractControl, FormControl, FormGroup, ReactiveFormsModule, ValidatorFn, Validators } from '@angular/forms';
import { MatAutocompleteModule, MatAutocompleteTrigger } from '@angular/material/autocomplete';
import { catchError, debounceTime } from 'rxjs/operators';
import { catchError, debounceTime, map } from 'rxjs/operators';
import { ProcessInstanceCloud } from '../models/process-instance-cloud.model';
import { ProcessPayloadCloud } from '../models/process-payload-cloud.model';
import { ProcessWithFormPayloadCloud } from '../models/process-with-form-payload-cloud.model';
import { StartProcessCloudService } from '../services/start-process-cloud.service';
import { forkJoin, of } from 'rxjs';
import { BehaviorSubject, forkJoin, Observable, of, combineLatest } from 'rxjs';
import { ProcessDefinitionCloud } from '../../../models/process-definition-cloud.model';
import { TaskVariableCloud } from '../../../form/models/task-variable-cloud.model';
import { FormCloudDisplayModeConfiguration } from '../../../services/form-fields.interfaces';
@@ -86,6 +86,8 @@ export class StartProcessCloudComponent implements OnChanges, OnInit {
@ViewChild(MatAutocompleteTrigger)
inputAutocomplete: MatAutocompleteTrigger;
@ViewChild('startForm') startForm: FormCloudComponent;
/** (required) Name of the app. */
@Input()
appName: string = '';
@@ -163,7 +165,7 @@ export class StartProcessCloudComponent implements OnChanges, OnInit {
isFormCloudLoading = false;
processDefinitionLoaded = false;
showStartProcessButton = true;
showStartProcessButton$: Observable<boolean>;
startProcessButtonLabel: string;
cancelButtonLabel: string;
@@ -180,6 +182,8 @@ export class StartProcessCloudComponent implements OnChanges, OnInit {
private readonly destroyRef = inject(DestroyRef);
private readonly startProcessCloudService = inject(StartProcessCloudService);
private readonly localizedDatePipe = inject(LocalizedDatePipe);
private readonly displayStartSubject = new BehaviorSubject<string>(null);
private readonly hasVisibleOutcomesSubject = new BehaviorSubject<boolean>(false);
get isProcessFormValid(): boolean {
if (this.hasForm && this.isFormCloudLoaded) {
@@ -230,6 +234,9 @@ export class StartProcessCloudComponent implements OnChanges, OnInit {
.subscribe((processDefinitionName) => {
this.selectProcessDefinitionByProcessDefinitionName(processDefinitionName);
});
this.showStartProcessButton$ = combineLatest([this.displayStartSubject, this.hasVisibleOutcomesSubject]).pipe(
map(([displayStart, hasVisibleOutcomes]) => (displayStart !== null ? displayStart === 'true' : !hasVisibleOutcomes))
);
}
ngOnChanges(changes: SimpleChanges) {
@@ -254,6 +261,10 @@ export class StartProcessCloudComponent implements OnChanges, OnInit {
onFormLoaded(form: FormModel) {
this.isFormCloudLoaded = true;
this.formCloud = form;
if (this.startForm) {
this.hasVisibleOutcomesSubject.next(this.startForm.hasVisibleOutcomes);
}
}
private getMaxNameLength(): number {
@@ -294,7 +305,7 @@ export class StartProcessCloudComponent implements OnChanges, OnInit {
const cancelLabel = constants?.find((constant) => constant.name === 'cancelLabel');
if (displayStart) {
this.showStartProcessButton = displayStart?.value === 'true';
this.displayStartSubject.next(displayStart?.value);
}
if (startLabel) {
this.startProcessButtonLabel = startLabel?.value?.trim()?.length > 0 ? startLabel.value.trim() : this.defaultStartProcessButtonLabel;

View File

@@ -199,6 +199,26 @@ export const fakeStartForm = {
}
};
export const fakeStartFormWithOutcomes = {
formRepresentation: {
...fakeStartForm.formRepresentation,
formDefinition: {
...fakeStartForm.formRepresentation.formDefinition,
outcomes: [
{
id: 'c5676ca7-8ad4-421c-9538-aaf8560bd5fc',
name: 'Option 1',
visibilityCondition: null
},
{
id: '48e9c1f8-50b9-4d2f-998c-7836c132986f',
name: 'Option 2',
visibilityCondition: null
}
]
}
}
};
export const fakeStartFormNotValid = {
formRepresentation: {
id: 'form-a5d50817-5183-4850-802d-17af54b2632f',