AAE-34135 add confirmation (#10783)

This commit is contained in:
Jonas Wollweber 2025-04-14 06:42:37 +02:00 committed by GitHub
parent 659805ab20
commit baf0e4552e
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 70 additions and 2 deletions

View File

@ -48,9 +48,12 @@ import { TestbedHarnessEnvironment } from '@angular/cdk/testing/testbed';
import { MatAutocompleteHarness } from '@angular/material/autocomplete/testing'; import { MatAutocompleteHarness } from '@angular/material/autocomplete/testing';
import { MatButtonHarness } from '@angular/material/button/testing'; import { MatButtonHarness } from '@angular/material/button/testing';
import { FormCloudDisplayMode } from '../../../services/form-fields.interfaces'; import { FormCloudDisplayMode } from '../../../services/form-fields.interfaces';
import { MatDialogHarness } from '@angular/material/dialog/testing';
import { MatDialog } from '@angular/material/dialog';
describe('StartProcessCloudComponent', () => { describe('StartProcessCloudComponent', () => {
let loader: HarnessLoader; let loader: HarnessLoader;
let documentRootLoader: HarnessLoader;
let component: StartProcessCloudComponent; let component: StartProcessCloudComponent;
let fixture: ComponentFixture<StartProcessCloudComponent>; let fixture: ComponentFixture<StartProcessCloudComponent>;
let processService: StartProcessCloudService; let processService: StartProcessCloudService;
@ -97,6 +100,7 @@ describe('StartProcessCloudComponent', () => {
getStartEventFormStaticValuesMappingSpy = spyOn(processService, 'getStartEventFormStaticValuesMapping').and.returnValue(of([])); getStartEventFormStaticValuesMappingSpy = spyOn(processService, 'getStartEventFormStaticValuesMapping').and.returnValue(of([]));
getStartEventConstantSpy = spyOn(processService, 'getStartEventConstants').and.returnValue(of([])); getStartEventConstantSpy = spyOn(processService, 'getStartEventConstants').and.returnValue(of([]));
loader = TestbedHarnessEnvironment.loader(fixture); loader = TestbedHarnessEnvironment.loader(fixture);
documentRootLoader = TestbedHarnessEnvironment.documentRootLoader(fixture);
}); });
afterEach(() => { afterEach(() => {
@ -919,6 +923,42 @@ describe('StartProcessCloudComponent', () => {
component.startProcess(); component.startProcess();
}); });
it('should open confirmation dialog on start process if confirmMessage.show is true', async () => {
component.formCloud = new FormModel({ confirmMessage: { show: true } });
let dialogs = await documentRootLoader.getAllHarnesses(MatDialogHarness);
expect(dialogs.length).toBe(0);
component.startProcess();
dialogs = await documentRootLoader.getAllHarnesses(MatDialogHarness);
expect(dialogs.length).toBe(1);
});
it('should start process when user confirms', () => {
const matDialog = TestBed.inject(MatDialog);
spyOn(matDialog, 'open').and.returnValue({ afterClosed: () => of(true) } as never);
fixture.detectChanges();
component.formCloud = new FormModel({ confirmMessage: { show: true } });
component.startProcess();
expect(startProcessSpy).toHaveBeenCalled();
});
it('should not start process if user rejects', () => {
const matDialog = TestBed.inject(MatDialog);
spyOn(matDialog, 'open').and.returnValue({ afterClosed: () => of(false) } as never);
fixture.detectChanges();
component.formCloud = new FormModel({ confirmMessage: { show: true } });
component.startProcess();
expect(startProcessSpy).not.toHaveBeenCalled();
});
it('should emit error when process name field is empty', () => { it('should emit error when process name field is empty', () => {
fixture.detectChanges(); fixture.detectChanges();
const processInstanceName = component.processForm.controls['processInstanceName']; const processInstanceName = component.processForm.controls['processInstanceName'];

View File

@ -29,7 +29,14 @@ import {
ViewChild, ViewChild,
ViewEncapsulation ViewEncapsulation
} from '@angular/core'; } from '@angular/core';
import { ContentLinkModel, FormModel, InplaceFormInputComponent, LocalizedDatePipe, TranslationService } from '@alfresco/adf-core'; import {
ConfirmDialogComponent,
ContentLinkModel,
FormModel,
InplaceFormInputComponent,
LocalizedDatePipe,
TranslationService
} from '@alfresco/adf-core';
import { AbstractControl, FormControl, FormGroup, ReactiveFormsModule, ValidatorFn, Validators } from '@angular/forms'; import { AbstractControl, FormControl, FormGroup, ReactiveFormsModule, ValidatorFn, Validators } from '@angular/forms';
import { MatAutocompleteModule, MatAutocompleteTrigger } from '@angular/material/autocomplete'; import { MatAutocompleteModule, MatAutocompleteTrigger } from '@angular/material/autocomplete';
import { catchError, debounceTime, map } from 'rxjs/operators'; import { catchError, debounceTime, map } from 'rxjs/operators';
@ -54,6 +61,7 @@ import { MatOptionModule } from '@angular/material/core';
import { FormCloudComponent } from '../../../form/components/form-cloud.component'; import { FormCloudComponent } from '../../../form/components/form-cloud.component';
import { FormCustomOutcomesComponent } from '../../../form/components/form-cloud-custom-outcomes.component'; import { FormCustomOutcomesComponent } from '../../../form/components/form-cloud-custom-outcomes.component';
import { MatCheckboxChange } from '@angular/material/checkbox'; import { MatCheckboxChange } from '@angular/material/checkbox';
import { MatDialog } from '@angular/material/dialog';
const MAX_NAME_LENGTH: number = 255; const MAX_NAME_LENGTH: number = 255;
const PROCESS_DEFINITION_DEBOUNCE: number = 300; const PROCESS_DEFINITION_DEBOUNCE: number = 300;
@ -197,6 +205,7 @@ export class StartProcessCloudComponent implements OnChanges, OnInit {
private readonly localizedDatePipe = inject(LocalizedDatePipe); private readonly localizedDatePipe = inject(LocalizedDatePipe);
private readonly displayStartSubject = new BehaviorSubject<string>(null); private readonly displayStartSubject = new BehaviorSubject<string>(null);
private readonly hasVisibleOutcomesSubject = new BehaviorSubject<boolean>(false); private readonly hasVisibleOutcomesSubject = new BehaviorSubject<boolean>(false);
private readonly dialog = inject(MatDialog);
get isProcessFormValid(): boolean { get isProcessFormValid(): boolean {
if (this.hasForm && this.isFormCloudLoaded) { if (this.hasForm && this.isFormCloudLoaded) {
@ -422,7 +431,7 @@ export class StartProcessCloudComponent implements OnChanges, OnInit {
this.startProcess(); this.startProcess();
} }
startProcess() { startProcessWithoutConfirmation() {
this.isProcessStarting = true; this.isProcessStarting = true;
const action = this.hasForm const action = this.hasForm
@ -461,6 +470,25 @@ export class StartProcessCloudComponent implements OnChanges, OnInit {
}); });
} }
startProcess() {
if (!this.formCloud?.confirmMessage?.show) {
this.startProcessWithoutConfirmation();
} else {
const dialogRef = this.dialog.open(ConfirmDialogComponent, {
data: {
message: this.formCloud.confirmMessage.message
},
minWidth: '450px'
});
dialogRef.afterClosed().subscribe((result) => {
if (result) {
this.startProcessWithoutConfirmation();
}
});
}
}
private unifyErrorResponse(err: any) { private unifyErrorResponse(err: any) {
if (!err?.response?.body?.entry && err?.response?.body?.message) { if (!err?.response?.body?.entry && err?.response?.body?.message) {
err.response.body = { err.response.body = {