diff --git a/lib/process-services-cloud/src/lib/process/start-process/components/start-process-cloud.component.html b/lib/process-services-cloud/src/lib/process/start-process/components/start-process-cloud.component.html index 625a7be648..9e350e738c 100755 --- a/lib/process-services-cloud/src/lib/process/start-process/components/start-process-cloud.component.html +++ b/lib/process-services-cloud/src/lib/process/start-process/components/start-process-cloud.component.html @@ -48,9 +48,10 @@ - + [showTitle]="false" + (formLoaded)="onFormLoaded($event)"> @@ -64,7 +65,7 @@ - diff --git a/lib/process-services-cloud/src/lib/process/start-process/components/start-process-cloud.component.spec.ts b/lib/process-services-cloud/src/lib/process/start-process/components/start-process-cloud.component.spec.ts index d58830fc57..fdbe4805f6 100755 --- a/lib/process-services-cloud/src/lib/process/start-process/components/start-process-cloud.component.spec.ts +++ b/lib/process-services-cloud/src/lib/process/start-process/components/start-process-cloud.component.spec.ts @@ -25,7 +25,8 @@ import { FormCloudService } from '../../../form/services/form-cloud.service'; import { StartProcessCloudComponent } from './start-process-cloud.component'; import { ProcessServiceCloudTestingModule } from '../../../testing/process-service-cloud.testing.module'; import { ProcessCloudModule } from '../../process-cloud.module'; -import { fakeProcessDefinitions, fakeStartForm, fakeProcessInstance, fakeProcessPayload, fakeNoNameProcessDefinitions } from '../mock/start-process.component.mock'; +import { fakeProcessDefinitions, fakeStartForm, fakeStartFormNotValid, + fakeProcessInstance, fakeProcessPayload, fakeNoNameProcessDefinitions } from '../mock/start-process.component.mock'; describe('StartProcessCloudComponent', () => { @@ -64,7 +65,7 @@ describe('StartProcessCloudComponent', () => { describe('start a process without start form', () => { - it('should enable start button when name and process filled out', async(() => { + it('should be able to start a process with a valid process name and process definition', async(() => { component.name = 'My new process'; component.processDefinitionName = 'processwithoutform2'; fixture.detectChanges(); @@ -116,7 +117,7 @@ describe('StartProcessCloudComponent', () => { component.name = 'My new process with form'; }); - it('should show a form if the process definition has one', async(() => { + it('should be able to start a process with a valid form', async(() => { component.processDefinitionName = 'processwithform'; fixture.detectChanges(); getDefinitionsSpy = spyOn(formCloudService, 'getForm').and.returnValue(of(fakeStartForm)); @@ -131,11 +132,32 @@ describe('StartProcessCloudComponent', () => { const lastNameEl = fixture.nativeElement.querySelector('#lastName'); expect(lastNameEl).toBeDefined(); const startBtn = fixture.nativeElement.querySelector('#button-start'); + expect(component.formCloud.isValid).toBe(true); expect(startBtn.disabled).toBe(false); }); })); - it('should show a prefilled form if the values are passed as input', async(() => { + it('should NOT be able to start a process with a form NOT valid', async(() => { + component.processDefinitionName = 'processwithform'; + fixture.detectChanges(); + getDefinitionsSpy = spyOn(formCloudService, 'getForm').and.returnValue(of(fakeStartFormNotValid)); + + const change = new SimpleChange(null, 'MyApp', true); + component.ngOnChanges({ 'appName': change }); + fixture.detectChanges(); + + fixture.whenStable().then(() => { + const firstNameEl = fixture.nativeElement.querySelector('#firstName'); + expect(firstNameEl).toBeDefined(); + const lastNameEl = fixture.nativeElement.querySelector('#lastName'); + expect(lastNameEl).toBeDefined(); + const startBtn = fixture.nativeElement.querySelector('#button-start'); + expect(component.formCloud.isValid).toBe(false); + expect(startBtn.disabled).toBe(true); + }); + })); + + it('should be able to start a process with a prefilled valid form', async(() => { component.processDefinitionName = 'processwithform'; component.values = [{'name': 'firstName', 'value': 'FakeName'}, {'name': 'lastName', 'value': 'FakeLastName'}]; fixture.detectChanges(); @@ -153,9 +175,33 @@ describe('StartProcessCloudComponent', () => { expect(lastNameEl).toBeDefined(); expect(lastNameEl.value).toEqual('FakeLastName'); const startBtn = fixture.nativeElement.querySelector('#button-start'); + expect(component.formCloud.isValid).toBe(true); expect(startBtn.disabled).toBe(false); }); })); + + it('should NOT be able to start a process with a prefilled NOT valid form', async(() => { + component.processDefinitionName = 'processwithform'; + component.values = [{'name': 'firstName', 'value': 'FakeName'}, {'name': 'lastName', 'value': 'FakeLastName'}]; + fixture.detectChanges(); + getDefinitionsSpy = spyOn(formCloudService, 'getForm').and.returnValue(of(fakeStartFormNotValid)); + + const change = new SimpleChange(null, 'MyApp', true); + component.ngOnChanges({ 'appName': change }); + fixture.detectChanges(); + + fixture.whenStable().then(() => { + const firstNameEl = fixture.nativeElement.querySelector('#firstName'); + expect(firstNameEl).toBeDefined(); + expect(firstNameEl.value).toEqual('FakeName'); + const lastNameEl = fixture.nativeElement.querySelector('#lastName'); + expect(lastNameEl).toBeDefined(); + expect(lastNameEl.value).toEqual('FakeLastName'); + const startBtn = fixture.nativeElement.querySelector('#button-start'); + expect(component.formCloud.isValid).toBe(false); + expect(startBtn.disabled).toBe(true); + }); + })); }); describe('process definitions list', () => { diff --git a/lib/process-services-cloud/src/lib/process/start-process/components/start-process-cloud.component.ts b/lib/process-services-cloud/src/lib/process/start-process/components/start-process-cloud.component.ts index 78052068c5..618c729387 100755 --- a/lib/process-services-cloud/src/lib/process/start-process/components/start-process-cloud.component.ts +++ b/lib/process-services-cloud/src/lib/process/start-process/components/start-process-cloud.component.ts @@ -28,8 +28,8 @@ import { ProcessPayloadCloud } from '../models/process-payload-cloud.model'; import { debounceTime, takeUntil } from 'rxjs/operators'; import { ProcessDefinitionCloud } from '../models/process-definition-cloud.model'; import { Subject } from 'rxjs'; -import { FormCloudComponent } from '../../../form/components/form-cloud.component'; import { TaskVariableCloud } from '../../../form/models/task-variable-cloud.model'; +import { FormCloud } from '../../../form/models/form-cloud.model'; @Component({ selector: 'adf-cloud-start-process', @@ -44,9 +44,6 @@ export class StartProcessCloudComponent implements OnChanges, OnInit, OnDestroy @ViewChild(MatAutocompleteTrigger) inputAutocomplete: MatAutocompleteTrigger; - @ViewChild(FormCloudComponent) - formCloud: FormCloudComponent; - /** (required) Name of the app. */ @Input() appName: string; @@ -94,6 +91,7 @@ export class StartProcessCloudComponent implements OnChanges, OnInit, OnDestroy processPayloadCloud = new ProcessPayloadCloud(); filteredProcesses: ProcessDefinitionCloud[] = []; isLoading = false; + formCloud: FormCloud; protected onDestroy$ = new Subject(); constructor(private startProcessCloudService: StartProcessCloudService, private formBuilder: FormBuilder) { @@ -129,6 +127,10 @@ export class StartProcessCloudComponent implements OnChanges, OnInit, OnDestroy return this.processDefinitionCurrent && !!this.processDefinitionCurrent.formKey; } + onFormLoaded(form: FormCloud) { + this.formCloud = form; + } + private getMaxNameLength(): number { return this.maxNameLength > StartProcessCloudComponent.MAX_NAME_LENGTH ? StartProcessCloudComponent.MAX_NAME_LENGTH : this.maxNameLength; @@ -137,6 +139,7 @@ export class StartProcessCloudComponent implements OnChanges, OnInit, OnDestroy setProcessDefinitionOnForm(processDefinition: string) { this.filteredProcesses = this.getProcessDefinitionList(processDefinition); const selectedProcess = this.getProcessIfExists(processDefinition); + this.processDefinitionCurrent = selectedProcess; this.processPayloadCloud.processDefinitionKey = selectedProcess.key; } @@ -189,6 +192,14 @@ export class StartProcessCloudComponent implements OnChanges, OnInit, OnDestroy return !!name; } + isProcessFormValid(): boolean { + if (this.hasForm()) { + return this.formCloud.isValid || this.isLoading; + } else { + return this.processForm.valid || this.isLoading; + } + } + private getProcessDefinition(option: ProcessDefinitionCloud, processDefinition: string): boolean { return (this.isValidName(option.name) && option.name.toLowerCase().includes(processDefinition.toLowerCase())) || (option.key && option.key.toLowerCase().includes(processDefinition.toLowerCase())); @@ -207,7 +218,7 @@ export class StartProcessCloudComponent implements OnChanges, OnInit, OnDestroy } if (this.hasForm()) { - this.processPayloadCloud.variables = Object.assign(this.processPayloadCloud.variables, this.formCloud.form.values); + this.processPayloadCloud.variables = Object.assign(this.processPayloadCloud.variables, this.formCloud.values); } this.startProcessCloudService.startProcess(this.appName, this.processPayloadCloud).subscribe( diff --git a/lib/process-services-cloud/src/lib/process/start-process/mock/start-process.component.mock.ts b/lib/process-services-cloud/src/lib/process/start-process/mock/start-process.component.mock.ts index 13e7d03f55..5783ccc910 100755 --- a/lib/process-services-cloud/src/lib/process/start-process/mock/start-process.component.mock.ts +++ b/lib/process-services-cloud/src/lib/process/start-process/mock/start-process.component.mock.ts @@ -139,3 +139,63 @@ export let fakeStartForm = { 'metadata': {}, 'variables': [] }; + +export let fakeStartFormNotValid = { + 'id': 'form-a5d50817-5183-4850-802d-17af54b2632f', + 'name': 'simpleform', + 'description': '', + 'version': 0, + 'tabs': [], + 'fields': [ + { + 'type': 'container', + 'id': '5a6b24c1-db2b-45e9-9aff-142395433d23', + 'name': 'Label', + 'tab': null, + 'fields': { + '1': [ + { + 'type': 'text', + 'id': 'firstName', + 'name': 'firstName', + 'colspan': 1, + 'params': { + 'existingColspan': 1, + 'maxColspan': 2 + }, + 'visibilityCondition': null, + 'placeholder': null, + 'value': null, + 'required': true, + 'minLength': 15, + 'maxLength': 0, + 'regexPattern': null + } + ], + '2': [ + { + 'type': 'text', + 'id': 'lastName', + 'name': 'lastName', + 'colspan': 1, + 'params': { + 'existingColspan': 1, + 'maxColspan': 2 + }, + 'visibilityCondition': null, + 'placeholder': null, + 'value': null, + 'required': false, + 'minLength': 0, + 'maxLength': 0, + 'regexPattern': null + } + ] + }, + 'numberOfColumns': 2 + } + ], + 'outcomes': [], + 'metadata': {}, + 'variables': [] +};