diff --git a/README.md b/README.md
index 456f644e13..239d705fe0 100644
--- a/README.md
+++ b/README.md
@@ -66,3 +66,4 @@ All components are supported in the following browsers:
* Due to a [known issue](https://bugzilla.mozilla.org/show_bug.cgi?id=1188880) in Firefox, the Alfresco Upload Component does not currently support folder upload functionality on Firefox.
See the [Browser Support](BROWSER-SUPPORT.md) article for more details.
+
diff --git a/e2e/process-services-cloud/form-field/task-visibility-condition.e2e.ts b/e2e/process-services-cloud/form-field/task-visibility-condition.e2e.ts
index 1f64fc1cd9..a7570d23c9 100644
--- a/e2e/process-services-cloud/form-field/task-visibility-condition.e2e.ts
+++ b/e2e/process-services-cloud/form-field/task-visibility-condition.e2e.ts
@@ -71,7 +71,6 @@ describe('Task cloud visibility', async () => {
await navigationBarPage.navigateToProcessServicesCloudPage();
await appListCloudComponent.checkApsContainer();
await appListCloudComponent.goToApp(simpleApp);
- await tasksCloudDemoPage.taskListCloudComponent().checkTaskListIsLoaded();
});
it('[C315170] Should be able to complete a task with a form with required number widgets', async () => {
diff --git a/lib/process-services-cloud/src/lib/process/process-list/services/process-list-cloud.service.ts b/lib/process-services-cloud/src/lib/process/process-list/services/process-list-cloud.service.ts
index 98bce1c6e8..396f1631c9 100644
--- a/lib/process-services-cloud/src/lib/process/process-list/services/process-list-cloud.service.ts
+++ b/lib/process-services-cloud/src/lib/process/process-list/services/process-list-cloud.service.ts
@@ -66,9 +66,17 @@ export class ProcessListCloudService extends BaseCloudService {
}
}
+ if (!queryParam['status']) {
+ queryParam['status'] = this.buildFilterForAllStatus();
+ }
+
return queryParam;
}
+ private buildFilterForAllStatus() {
+ return ['RUNNING', 'SUSPENDED', 'CANCELLED', 'COMPLETED'];
+ }
+
private isExcludedField(property: string): boolean {
return property === 'appName' || property === 'sorting';
}
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 5c78f2b76f..6c7464dcaf 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
@@ -78,7 +78,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 7dab7f524d..cbf7c288b2 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
@@ -17,7 +17,14 @@
import { SimpleChange, DebugElement } from '@angular/core';
import { async, ComponentFixture, TestBed, fakeAsync, tick } from '@angular/core/testing';
-import { setupTestBed, StorageService, LogService, TranslationService, TranslationMock, FormService } from '@alfresco/adf-core';
+import {
+ setupTestBed,
+ StorageService,
+ LogService,
+ TranslationService,
+ TranslationMock,
+ FormService
+} from '@alfresco/adf-core';
import { of, throwError } from 'rxjs';
import { StartProcessCloudService } from '../services/start-process-cloud.service';
import { FormCloudService } from '../../../form/services/form-cloud.service';
@@ -25,13 +32,25 @@ import { StartProcessCloudComponent } from './start-process-cloud.component';
import { HttpClientModule } from '@angular/common/http';
import { NoopAnimationsModule } from '@angular/platform-browser/animations';
import { TranslateModule, TranslateStore } from '@ngx-translate/core';
-import { MatCardModule, MatOptionModule, MatAutocompleteModule, MatIconModule, MatButtonModule, MatFormFieldModule, MatInputModule, MatRippleModule, MatCommonModule } from '@angular/material';
+import {
+ MatCardModule,
+ MatOptionModule,
+ MatAutocompleteModule,
+ MatIconModule,
+ MatButtonModule,
+ MatFormFieldModule,
+ MatInputModule,
+ MatRippleModule,
+ MatCommonModule
+} from '@angular/material';
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
import { FormCloudModule } from '../../../form/form-cloud.module';
-import { fakeProcessDefinitions, fakeStartForm, fakeStartFormNotValid,
+import {
+ fakeProcessDefinitions, fakeStartForm, fakeStartFormNotValid,
fakeProcessInstance, fakeNoNameProcessDefinitions,
- fakeSingleProcessDefinition, fakeCreatedProcessInstance } from '../mock/start-process.component.mock';
+ fakeSingleProcessDefinition, fakeCreatedProcessInstance
+} from '../mock/start-process.component.mock';
import { By } from '@angular/platform-browser';
import { ProcessPayloadCloud } from '../models/process-payload-cloud.model';
@@ -52,14 +71,14 @@ describe('StartProcessCloudComponent', () => {
selectElement.click();
fixture.detectChanges();
const options: any = fixture.debugElement.queryAll(By.css('.mat-option-text'));
- const currentOption = options.find( (option: DebugElement) => option.nativeElement.innerHTML.trim() === name );
+ const currentOption = options.find((option: DebugElement) => option.nativeElement.innerHTML.trim() === name);
if (currentOption) {
currentOption.nativeElement.click();
}
};
- function typeValueInto(selector: any, value: string ) {
+ function typeValueInto(selector: any, value: string) {
const inputElement = fixture.debugElement.query(By.css(`${selector}`));
inputElement.nativeElement.value = value;
inputElement.nativeElement.dispatchEvent(new Event('input'));
@@ -113,28 +132,26 @@ describe('StartProcessCloudComponent', () => {
describe('start a process without start form', () => {
it('should create a process instance if the selection is valid', fakeAsync(() => {
- component.name = '';
- component.processDefinitionName = '';
+ component.name = 'testFormWithProcess';
+ component.processDefinitionName = 'processwithoutform2';
+ getDefinitionsSpy.and.returnValue(of(fakeSingleProcessDefinition(component.processDefinitionName)));
fixture.detectChanges();
+ formDefinitionSpy = spyOn(formCloudService, 'getForm').and.returnValue(of(fakeStartForm));
const change = new SimpleChange(null, 'MyApp', true);
component.ngOnChanges({ 'appName': change });
fixture.detectChanges();
- tick();
- typeValueInto('#processName', 'OLE');
- typeValueInto('#processDefinitionName', 'processwithoutform2');
- fixture.detectChanges();
tick(450);
fixture.whenStable().then(() => {
fixture.detectChanges();
+ 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(true);
expect(startBtn.disabled).toBe(false);
- expect(component.isProcessFormValid()).toBe(true);
- expect(createProcessSpy).toHaveBeenCalledWith('MyApp', new ProcessPayloadCloud({name: 'OLE',
- processDefinitionKey: fakeProcessDefinitions[1].key}));
- expect(component.currentCreatedProcess.status).toBe('CREATED');
- expect(component.currentCreatedProcess.startDate).toBeNull();
});
}));
@@ -272,7 +289,10 @@ describe('StartProcessCloudComponent', () => {
it('should be able to start a process with a prefilled valid form', fakeAsync(() => {
component.processDefinitionName = 'processwithform';
getDefinitionsSpy.and.returnValue(of(fakeSingleProcessDefinition(component.processDefinitionName)));
- component.values = [{'name': 'firstName', 'value': 'FakeName'}, {'name': 'lastName', 'value': 'FakeLastName'}];
+ component.values = [{ 'name': 'firstName', 'value': 'FakeName' }, {
+ 'name': 'lastName',
+ 'value': 'FakeLastName'
+ }];
fixture.detectChanges();
formDefinitionSpy = spyOn(formCloudService, 'getForm').and.returnValue(of(fakeStartForm));
@@ -303,7 +323,10 @@ describe('StartProcessCloudComponent', () => {
it('should NOT be able to start a process with a prefilled NOT valid form', async(() => {
component.processDefinitionName = 'processwithform';
getDefinitionsSpy.and.returnValue(of(fakeSingleProcessDefinition(component.processDefinitionName)));
- component.values = [{'name': 'firstName', 'value': 'FakeName'}, {'name': 'lastName', 'value': 'FakeLastName'}];
+ component.values = [{ 'name': 'firstName', 'value': 'FakeName' }, {
+ 'name': 'lastName',
+ 'value': 'FakeLastName'
+ }];
fixture.detectChanges();
formDefinitionSpy = spyOn(formCloudService, 'getForm').and.returnValue(of(fakeStartFormNotValid));
@@ -326,7 +349,10 @@ describe('StartProcessCloudComponent', () => {
}));
it('should create a process instance if the selection is valid', fakeAsync(() => {
- component.values = [{'name': 'firstName', 'value': 'FakeName'}, {'name': 'lastName', 'value': 'FakeLastName'}];
+ component.values = [{ 'name': 'firstName', 'value': 'FakeName' }, {
+ 'name': 'lastName',
+ 'value': 'FakeLastName'
+ }];
component.name = 'testFormWithProcess';
component.processDefinitionName = 'processwithoutform2';
getDefinitionsSpy.and.returnValue(of(fakeSingleProcessDefinition(component.processDefinitionName)));
@@ -344,8 +370,10 @@ describe('StartProcessCloudComponent', () => {
expect(startBtn.disabled).toBe(false);
expect(component.formCloud.isValid).toBe(true);
expect(component.isProcessFormValid()).toBe(true);
- expect(createProcessSpy).toHaveBeenCalledWith('MyApp', new ProcessPayloadCloud({name: 'testFormWithProcess',
- processDefinitionKey: fakeProcessDefinitions[1].key}));
+ expect(createProcessSpy).toHaveBeenCalledWith('MyApp', new ProcessPayloadCloud({
+ name: 'testFormWithProcess',
+ processDefinitionKey: fakeProcessDefinitions[1].key
+ }));
expect(component.currentCreatedProcess.status).toBe('CREATED');
expect(component.currentCreatedProcess.startDate).toBeNull();
});
@@ -602,13 +630,13 @@ describe('StartProcessCloudComponent', () => {
component.currentCreatedProcess = fakeProcessInstance;
component.startProcess();
fixture.whenStable().then(() => {
- expect(startProcessSpy).toHaveBeenCalledWith(component.appName, fakeProcessInstance.id);
+ expect(startProcessSpy).toHaveBeenCalledWith(component.appName, fakeProcessInstance.id, component.processPayloadCloud);
});
}));
it('should call service to start process with the variables setted', async(() => {
const inputProcessVariable: Map[] = [];
- inputProcessVariable['name'] = {value: 'Josh'};
+ inputProcessVariable['name'] = { value: 'Josh' };
component.variables = inputProcessVariable;
component.currentCreatedProcess = fakeProcessInstance;
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 41bda8fab4..7499a370bc 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,7 +28,7 @@ import { MatAutocompleteTrigger } from '@angular/material';
import { ProcessPayloadCloud } from '../models/process-payload-cloud.model';
import { debounceTime, takeUntil, switchMap, filter, distinctUntilChanged, tap } from 'rxjs/operators';
import { ProcessDefinitionCloud } from '../models/process-definition-cloud.model';
-import { Subject, Observable, concat } from 'rxjs';
+import { Subject, Observable } from 'rxjs';
import { TaskVariableCloud } from '../../../form/models/task-variable-cloud.model';
@Component({
@@ -100,7 +100,9 @@ export class StartProcessCloudComponent implements OnChanges, OnInit, OnDestroy
isLoading = false;
isFormCloudLoaded = false;
formCloud: FormModel;
- currentCreatedProcess: any;
+ currentCreatedProcess: ProcessInstanceCloud;
+ disableStartButton: boolean = true;
+
protected onDestroy$ = new Subject();
constructor(private startProcessCloudService: StartProcessCloudService,
@@ -118,19 +120,20 @@ export class StartProcessCloudComponent implements OnChanges, OnInit, OnDestroy
.pipe(takeUntil(this.onDestroy$))
.subscribe((processDefinitionName) => {
this.selectProcessDefinitionByProcesDefinitionName(processDefinitionName);
- });
+ });
this.processForm.valueChanges
- .pipe(
- tap(() => this.currentCreatedProcess = undefined),
- debounceTime(400),
- distinctUntilChanged(),
- filter(() => this.isProcessSelectionValid()),
- switchMap(() => this.generateProcessInstance())
- ).pipe(takeUntil(this.onDestroy$))
- .subscribe((res) => {
- this.currentCreatedProcess = res;
- });
+ .pipe(
+ debounceTime(200),
+ tap(() => this.disableStartButton = true),
+ distinctUntilChanged(),
+ filter(() => this.isProcessSelectionValid()),
+ switchMap(() => this.generateProcessInstance())
+ ).pipe(takeUntil(this.onDestroy$))
+ .subscribe((res) => {
+ this.currentCreatedProcess = res;
+ this.disableStartButton = false;
+ });
if (this.processDefinitionName) {
this.processDefinition.setValue(this.processDefinitionName);
@@ -167,12 +170,17 @@ export class StartProcessCloudComponent implements OnChanges, OnInit, OnDestroy
StartProcessCloudComponent.MAX_NAME_LENGTH : this.maxNameLength;
}
- private generateProcessInstance(): Observable {
+ private generateProcessInstance(): Observable {
const createPayload: ProcessPayloadCloud = new ProcessPayloadCloud({
name: this.processInstanceName.value,
processDefinitionKey: this.processPayloadCloud.processDefinitionKey
});
- return this.startProcessCloudService.createProcess(this.appName, createPayload);
+
+ if (this.currentCreatedProcess && this.processPayloadCloud.processDefinitionKey === this.currentCreatedProcess.processDefinitionKey) {
+ return this.startProcessCloudService.updateProcess(this.appName, this.currentCreatedProcess.id, createPayload);
+ } else {
+ return this.startProcessCloudService.createProcess(this.appName, createPayload);
+ }
}
private selectProcessDefinitionByProcesDefinitionName(processDefinitionName: string): void {
@@ -184,8 +192,8 @@ export class StartProcessCloudComponent implements OnChanges, OnInit, OnDestroy
}
setProcessDefinitionOnForm(selectedProcessDefinitionName: string) {
- this.processDefinitionCurrent = this.filteredProcesses.find( (process: ProcessDefinitionCloud) =>
- process.name === selectedProcessDefinitionName || process.key === selectedProcessDefinitionName );
+ this.processDefinitionCurrent = this.filteredProcesses.find((process: ProcessDefinitionCloud) =>
+ process.name === selectedProcessDefinitionName || process.key === selectedProcessDefinitionName);
this.isFormCloudLoaded = false;
this.processPayloadCloud.processDefinitionKey = this.processDefinitionCurrent.key;
@@ -198,7 +206,7 @@ export class StartProcessCloudComponent implements OnChanges, OnInit, OnDestroy
}
private getProcessIfExists(processDefinition: string): ProcessDefinitionCloud {
- let matchedProcess = this.processDefinitionList.find((option) => this.getProcessDefinition(option, processDefinition) );
+ let matchedProcess = this.processDefinitionList.find((option) => this.getProcessDefinition(option, processDefinition));
if (!matchedProcess) {
matchedProcess = new ProcessDefinitionCloud();
}
@@ -227,14 +235,14 @@ export class StartProcessCloudComponent implements OnChanges, OnInit, OnDestroy
this.startProcessCloudService.getProcessDefinitions(this.appName)
.pipe(takeUntil(this.onDestroy$))
.subscribe((processDefinitionRepresentations: ProcessDefinitionCloud[]) => {
- this.processDefinitionList = processDefinitionRepresentations;
- if (processDefinitionRepresentations.length === 1) {
- this.selectDefaultProcessDefinition();
- }
- },
- () => {
- this.errorMessageId = 'ADF_CLOUD_PROCESS_LIST.ADF_CLOUD_START_PROCESS.ERROR.LOAD_PROCESS_DEFS';
- });
+ this.processDefinitionList = processDefinitionRepresentations;
+ if (processDefinitionRepresentations.length === 1) {
+ this.selectDefaultProcessDefinition();
+ }
+ },
+ () => {
+ this.errorMessageId = 'ADF_CLOUD_PROCESS_LIST.ADF_CLOUD_START_PROCESS.ERROR.LOAD_PROCESS_DEFS';
+ });
}
private isValidName(name: string): boolean {
@@ -255,7 +263,7 @@ export class StartProcessCloudComponent implements OnChanges, OnInit, OnDestroy
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()));
+ (option.key && option.key.toLowerCase().includes(processDefinition.toLowerCase()));
}
isProcessDefinitionsEmpty(): boolean {
@@ -276,23 +284,27 @@ export class StartProcessCloudComponent implements OnChanges, OnInit, OnDestroy
startProcess() {
this.isLoading = true;
this.buildProcessCloudPayload();
- concat(
- this.startProcessCloudService.updateProcess(this.appName, this.currentCreatedProcess.id, this.processPayloadCloud),
- this.startProcessCloudService.startCreatedProcess(this.appName, this.currentCreatedProcess.id)
- ).subscribe(
- (res) => {
- this.success.emit(res);
- this.isLoading = false;
- },
- (err) => {
- this.errorMessageId = 'ADF_CLOUD_PROCESS_LIST.ADF_CLOUD_START_PROCESS.ERROR.START';
- this.error.emit(err);
- this.isLoading = false;
- }
- );
+ this.startProcessCloudService.startCreatedProcess(this.appName,
+ this.currentCreatedProcess.id,
+ this.processPayloadCloud)
+ .subscribe(
+ (res) => {
+ this.success.emit(res);
+ this.isLoading = false;
+ },
+ (err) => {
+ this.errorMessageId = 'ADF_CLOUD_PROCESS_LIST.ADF_CLOUD_START_PROCESS.ERROR.START';
+ this.error.emit(err);
+ this.isLoading = false;
+ }
+ );
}
- cancelStartProcess() {
+ async cancelStartProcess() {
+ if (this.currentCreatedProcess) {
+ await this.startProcessCloudService.deleteProcess(this.appName, this.currentCreatedProcess.id);
+ }
+
this.currentCreatedProcess = null;
this.cancel.emit();
}
diff --git a/lib/process-services-cloud/src/lib/process/start-process/services/start-process-cloud.service.spec.ts b/lib/process-services-cloud/src/lib/process/start-process/services/start-process-cloud.service.spec.ts
index 70ec5eedda..49661de320 100755
--- a/lib/process-services-cloud/src/lib/process/start-process/services/start-process-cloud.service.spec.ts
+++ b/lib/process-services-cloud/src/lib/process/start-process/services/start-process-cloud.service.spec.ts
@@ -124,7 +124,7 @@ describe('StartProcessCloudService', () => {
it('should be able to start a created new process instance', (done) => {
spyOn(service, 'startCreatedProcess').and.returnValue(of({ id: 'fake-id', name: 'fake-name', status: 'RUNNING' }));
- service.startCreatedProcess('appName1', 'fake-id')
+ service.startCreatedProcess('appName1', 'fake-id', fakeProcessPayload)
.subscribe(
(res: ProcessInstanceCloud) => {
expect(res).toBeDefined();
diff --git a/lib/process-services-cloud/src/lib/process/start-process/services/start-process-cloud.service.ts b/lib/process-services-cloud/src/lib/process/start-process/services/start-process-cloud.service.ts
index 7e4d4148f3..a7a4da7906 100755
--- a/lib/process-services-cloud/src/lib/process/start-process/services/start-process-cloud.service.ts
+++ b/lib/process-services-cloud/src/lib/process/start-process/services/start-process-cloud.service.ts
@@ -63,7 +63,7 @@ export class StartProcessCloudService extends BaseCloudService {
*/
createProcess(appName: string, payload: ProcessPayloadCloud): Observable {
const url = `${this.getBasePath(appName)}/rb/v1/process-instances/create`;
- payload.payloadType = 'StartProcessPayload';
+ payload.payloadType = 'CreateProcessInstancePayload';
return this.post(url, payload).pipe(
map((result: any) => result.entry),
@@ -76,10 +76,10 @@ export class StartProcessCloudService extends BaseCloudService {
* @param createdProcessInstanceId process instance id of the process previously created
* @returns Details of the process instance just started
*/
- startCreatedProcess(appName: string, createdProcessInstanceId: string): Observable {
+ startCreatedProcess(appName: string, createdProcessInstanceId: string, payload: ProcessPayloadCloud): Observable {
const url = `${this.getBasePath(appName)}/rb/v1/process-instances/${createdProcessInstanceId}/start`;
- return this.post(url).pipe(
+ return this.post(url, payload).pipe(
map((result: any) => result.entry),
map(processInstance => new ProcessInstanceCloud(processInstance.entry))
);
@@ -112,7 +112,20 @@ export class StartProcessCloudService extends BaseCloudService {
payload.payloadType = 'UpdateProcessPayload';
return this.put(url, payload).pipe(
- map(processInstance => new ProcessInstanceCloud(processInstance))
+ map((processInstance: any) => {
+ return new ProcessInstanceCloud(processInstance.entry);
+ })
);
}
+
+ /**
+ * Delete an existing process instance
+ * @param appName name of the Application
+ * @param processInstanceId process instance to update
+ */
+ deleteProcess(appName: string, processInstanceId: string): Observable {
+ const url = `${this.getBasePath(appName)}/rb/v1/process-instances/${processInstanceId}`;
+
+ return this.delete(url);
+ }
}
diff --git a/lib/testing/src/lib/process-services-cloud/pages/start-process-cloud-component.page.ts b/lib/testing/src/lib/process-services-cloud/pages/start-process-cloud-component.page.ts
index 65cb3ed39b..8a99af906f 100644
--- a/lib/testing/src/lib/process-services-cloud/pages/start-process-cloud-component.page.ts
+++ b/lib/testing/src/lib/process-services-cloud/pages/start-process-cloud-component.page.ts
@@ -87,7 +87,7 @@ export class StartProcessCloudPage {
}
async checkStartProcessButtonIsEnabled(): Promise {
- await browser.sleep(1000); // waiting for API response
+ await browser.sleep(2000); // waiting for API response
await BrowserVisibility.waitUntilElementIsVisible(this.startProcessButton);
return this.startProcessButton.isEnabled();
}