diff --git a/lib/core/form/components/widgets/core/form.model.ts b/lib/core/form/components/widgets/core/form.model.ts index 8edb5c97f7..7847a5f004 100644 --- a/lib/core/form/components/widgets/core/form.model.ts +++ b/lib/core/form/components/widgets/core/form.model.ts @@ -35,6 +35,10 @@ import { FormValidationService } from '../../../services/form-validation-service import { ProcessFormModel } from './process-form-model.interface'; import { WidgetTypeEnum, WidgetVisibilityModel } from '../../../models/widget-visibility.model'; +export interface ConfirmMessage { + show: boolean; + message: string; +} export interface FormRepresentationModel { [key: string]: any; @@ -55,7 +59,6 @@ export interface FormRepresentationModel { fields?: any[]; }; } - export class FormModel implements ProcessFormModel { static UNSET_TASK_NAME: string = 'Nameless task'; @@ -66,6 +69,7 @@ export class FormModel implements ProcessFormModel { readonly id: string | number; readonly name: string; readonly taskId: string; + readonly confirmMessage: ConfirmMessage; readonly taskName = FormModel.UNSET_TASK_NAME; readonly processDefinitionId: string; readonly selectedOutcome: string; @@ -102,6 +106,7 @@ export class FormModel implements ProcessFormModel { this.variables = json.variables || []; this.processVariables = json.processVariables || []; this.enableFixedSpace = enableFixedSpace ? true : false; + this.confirmMessage = json.confirmMessage || {}; const tabCache: FormWidgetModelCache = {}; diff --git a/lib/process-services-cloud/src/lib/form/components/form-cloud.component.spec.ts b/lib/process-services-cloud/src/lib/form/components/form-cloud.component.spec.ts index 0b4c33e8a5..9980e10525 100644 --- a/lib/process-services-cloud/src/lib/form/components/form-cloud.component.spec.ts +++ b/lib/process-services-cloud/src/lib/form/components/form-cloud.component.spec.ts @@ -55,6 +55,10 @@ import { NoopAnimationsModule } from '@angular/platform-browser/animations'; import { CloudFormRenderingService } from './cloud-form-rendering.service'; import { Node } from '@alfresco/js-api'; import { ESCAPE } from '@angular/cdk/keycodes'; +import { MatDialog } from '@angular/material/dialog'; +import { HarnessLoader } from '@angular/cdk/testing'; +import { TestbedHarnessEnvironment } from '@angular/cdk/testing/testbed'; +import { MatDialogHarness } from '@angular/material/dialog/testing'; const mockOauth2Auth: any = { oauth2Auth: { @@ -68,9 +72,11 @@ describe('FormCloudComponent', () => { let formCloudService: FormCloudService; let fixture: ComponentFixture; let formComponent: FormCloudComponent; + let matDialog: MatDialog; let visibilityService: WidgetVisibilityService; let formRenderingService: CloudFormRenderingService; let translateService: TranslateService; + let documentRootLoader: HarnessLoader; @Component({ selector: 'adf-cloud-custom-widget', @@ -130,12 +136,14 @@ describe('FormCloudComponent', () => { formCloudService = TestBed.inject(FormCloudService); translateService = TestBed.inject(TranslateService); + matDialog = TestBed.inject(MatDialog); visibilityService = TestBed.inject(WidgetVisibilityService); spyOn(visibilityService, 'refreshVisibility').and.callThrough(); fixture = TestBed.createComponent(FormCloudComponent); formComponent = fixture.componentInstance; + documentRootLoader = TestbedHarnessEnvironment.documentRootLoader(fixture); fixture.detectChanges(); }); @@ -737,6 +745,63 @@ describe('FormCloudComponent', () => { expect(completed).toBeTruthy(); }); + it('should open confirmation dialog on complete task', async () => { + formComponent.form = new FormModel({ + confirmMessage: { + show: true, + message: 'Are you sure you want to submit the form?' + } + }); + + formComponent.completeTaskForm(); + let dialogs = await documentRootLoader.getAllHarnesses(MatDialogHarness); + expect(dialogs.length).toBe(1); + + await dialogs[0].close(); + dialogs = await documentRootLoader.getAllHarnesses(MatDialogHarness); + expect(dialogs.length).toBe(0); + }); + + it('should submit form when user confirms', () => { + spyOn(matDialog, 'open').and.returnValue({ afterClosed: () => of(true) }); + fixture.detectChanges(); + + const formModel = new FormModel({ + confirmMessage: { + show: true, + message: 'Are you sure you want to submit the form?' + } + }); + formComponent.form = formModel; + formComponent.taskId = 'id'; + formComponent.appName = 'appName'; + + spyOn(formComponent['formCloudService'], 'completeTaskForm').and.returnValue(of(formModel)); + formComponent.completeTaskForm('complete'); + + expect(formComponent['formCloudService'].completeTaskForm).toHaveBeenCalled(); + }); + + it('should not confirm form if user rejects', () => { + const outcome = 'complete'; + spyOn(matDialog, 'open').and.returnValue({ afterClosed: () => of(false) }); + + const formModel = new FormModel({ + confirmMessage: { + show: true, + message: 'Are you sure you want to submit the form?' + } + }); + + formComponent.form = formModel; + spyOn(formComponent['formCloudService'], 'completeTaskForm'); + + formComponent.completeTaskForm(outcome); + + expect(matDialog.open).toHaveBeenCalled(); + expect(formComponent['formCloudService'].completeTaskForm).not.toHaveBeenCalled(); + }); + it('should require json to parse form', () => { expect(formComponent.parseForm(null)).toBeNull(); }); diff --git a/lib/process-services-cloud/src/lib/form/components/form-cloud.component.ts b/lib/process-services-cloud/src/lib/form/components/form-cloud.component.ts index 315b32d9f9..cd1ca0100f 100644 --- a/lib/process-services-cloud/src/lib/form/components/form-cloud.component.ts +++ b/lib/process-services-cloud/src/lib/form/components/form-cloud.component.ts @@ -38,6 +38,10 @@ import { import { FormCloudService } from '../services/form-cloud.service'; import { TaskVariableCloud } from '../models/task-variable-cloud.model'; import { TaskDetailsCloudModel } from '../../task/start-task/models/task-details-cloud.model'; +import { MatDialog } from '@angular/material/dialog'; +import { + ConfirmDialogComponent +} from '@alfresco/adf-content-services'; @Component({ selector: 'adf-cloud-form', @@ -105,6 +109,7 @@ export class FormCloudComponent extends FormBaseComponent implements OnChanges, constructor(protected formCloudService: FormCloudService, protected formService: FormService, + private dialog: MatDialog, protected visibilityService: WidgetVisibilityService) { super(); @@ -266,6 +271,27 @@ export class FormCloudComponent extends FormBaseComponent implements OnChanges, } completeTaskForm(outcome?: string) { + if (this.form?.confirmMessage?.show === true) { + const dialogRef = this.dialog.open(ConfirmDialogComponent, { + data: { + message: this.form.confirmMessage.message + }, + minWidth: '450px' + }); + + dialogRef.afterClosed() + .subscribe( + (result) => { + if (result === true) { + this.completeForm(outcome); + } + }); + } else { + this.completeForm(outcome); + } + } + + private completeForm(outcome?: string) { if (this.form && this.appName && this.taskId) { this.formCloudService .completeTaskForm(this.appName, this.taskId, this.processInstanceId, `${this.form.id}`, this.form.values, outcome, this.appVersion)