[AAE-1260] Add changes detection for ProcessHeaderCloud when a process gets cancelled (#5341)

* [AAE-1260] Add changes detection for ProcessHeaderCloud when a process is cancelled

* [AAE-1260] Add service documentation

* [AAE-1260] fix typo

* [AAE-1260] Fix unit tests

* [AAE-1260] delete process header cloud service
This commit is contained in:
arditdomi 2019-12-20 12:17:44 +00:00 committed by Eugenio Romano
parent af51977db4
commit f97cf0f446
9 changed files with 80 additions and 84 deletions

View File

@ -1,13 +1,13 @@
--- ---
Title: Process Header Cloud Service Title: Process Cloud Service
Added: v3.0.0 Added: v3.0.0
Status: Experimental Status: Experimental
Last reviewed: 2019-03-15 Last reviewed: 2019-03-15
--- ---
# [Process Header Cloud Service](../../../lib/process-services-cloud/src/lib/process/process-header/services/process-header-cloud.service.ts "Defined in process-header-cloud.service.ts") # [Process Cloud Service](../../../lib/process-services-cloud/src/lib/process/services/process-cloud.service.ts "Defined in process-cloud.service.ts")
Manages cloud process instances. Manages cloud process instances.
## Class members ## Class members
@ -15,8 +15,8 @@ Manages cloud process instances.
- **getBasePath**(appName: `string`): `string`<br/> - **getBasePath**(appName: `string`): `string`<br/>
- _appName:_ `string` - - _appName:_ `string` -
- **Returns** `string` - - **Returns** `string` -
- **getProcessInstanceById**(appName: `string`, processInstanceId: `string`): [`Observable`](http://reactivex.io/documentation/observable.html)`<`[`ProcessInstanceCloud`](../../../lib/process-services-cloud/src/lib/process/start-process/models/process-instance-cloud.model.ts)`>`<br/> - **getProcessInstanceById**(appName: `string`, processInstanceId: `string`): [`Observable`](http://reactivex.io/documentation/observable.html)`<`[`ProcessInstanceCloud`](../../../lib/process-services-cloud/src/lib/process/start-process/models/process-instance-cloud.model.ts)`>`<br/>
Gets details of a process instance. Gets details of a process instance.
@ -24,6 +24,12 @@ Manages cloud process instances.
- _processInstanceId:_ `string` - ID of the process instance whose details you want - _processInstanceId:_ `string` - ID of the process instance whose details you want
- **Returns** [`Observable`](http://reactivex.io/documentation/observable.html)`<`[`ProcessInstanceCloud`](../../../lib/process-services-cloud/src/lib/process/start-process/models/process-instance-cloud.model.ts)`>` - Process instance details - **Returns** [`Observable`](http://reactivex.io/documentation/observable.html)`<`[`ProcessInstanceCloud`](../../../lib/process-services-cloud/src/lib/process/start-process/models/process-instance-cloud.model.ts)`>` - Process instance details
- **cancelProcess**(appName: `string`, processInstanceId: `string`): [`Observable`](http://reactivex.io/documentation/observable.html)`<`[`ProcessInstanceCloud`](../../../lib/process-services-cloud/src/lib/process/start-process/models/process-instance-cloud.model.ts)`>`<br/>
Cancels a process instance.
- _appName:_ `string` - Name of the app
- _processInstanceId:_ `string` - ID of the process instance whose details you want
- **Returns** [`Observable`](http://reactivex.io/documentation/observable.html)`<`[`ProcessInstanceCloud`](../../../lib/process-services-cloud/src/lib/process/start-process/models/process-instance-cloud.model.ts)`>` - Process instance details
## Details ## Details
The methods work in much the same way as the equivalent methods in the The methods work in much the same way as the equivalent methods in the

View File

@ -61,10 +61,10 @@ describe('DeleteProcessDirective', () => {
}); });
it('should call delete process service when click', () => { it('should call delete process service when click', () => {
spyOn(processCloudService, 'deleteProcess').and.returnValue(of({})); spyOn(processCloudService, 'cancelProcess').and.returnValue(of({}));
const button = fixture.nativeElement.querySelector('button'); const button = fixture.nativeElement.querySelector('button');
button.click(); button.click();
expect(processCloudService.deleteProcess).toHaveBeenCalled(); expect(processCloudService.cancelProcess).toHaveBeenCalled();
}); });
}); });

View File

@ -19,6 +19,7 @@ import { IdentityUserService } from '@alfresco/adf-core';
import { ProcessCloudService } from '../services/process-cloud.service'; import { ProcessCloudService } from '../services/process-cloud.service';
@Directive({ @Directive({
// tslint:disable-next-line: directive-selector
selector: '[adf-cloud-delete-process]' selector: '[adf-cloud-delete-process]'
}) })
export class DeleteProcessDirective implements OnInit { export class DeleteProcessDirective implements OnInit {
@ -93,7 +94,7 @@ export class DeleteProcessDirective implements OnInit {
private async deleteProcess() { private async deleteProcess() {
const currentUser: string = this.identityUserService.getCurrentUserInfo().username; const currentUser: string = this.identityUserService.getCurrentUserInfo().username;
if (currentUser === this.processInitiator) { if (currentUser === this.processInitiator) {
await this.processCloudService.deleteProcess(this.appName, this.processId) await this.processCloudService.cancelProcess(this.appName, this.processId)
.subscribe((response) => { .subscribe((response) => {
this.success.emit(response); this.success.emit(response);
}, ((error) => { }, ((error) => {

View File

@ -22,7 +22,7 @@ import { of } from 'rxjs';
import { ProcessServiceCloudTestingModule } from '../../../testing/process-service-cloud.testing.module'; import { ProcessServiceCloudTestingModule } from '../../../testing/process-service-cloud.testing.module';
import { ProcessHeaderCloudComponent } from './process-header-cloud.component'; import { ProcessHeaderCloudComponent } from './process-header-cloud.component';
import { ProcessHeaderCloudModule } from '../process-header-cloud.module'; import { ProcessHeaderCloudModule } from '../process-header-cloud.module';
import { ProcessHeaderCloudService } from '../services/process-header-cloud.service'; import { ProcessCloudService } from '../../services/process-cloud.service';
const processInstanceDetailsCloudMock = { const processInstanceDetailsCloudMock = {
appName: 'app-form-mau', appName: 'app-form-mau',
@ -39,7 +39,7 @@ const processInstanceDetailsCloudMock = {
describe('ProcessHeaderCloudComponent', () => { describe('ProcessHeaderCloudComponent', () => {
let component: ProcessHeaderCloudComponent; let component: ProcessHeaderCloudComponent;
let fixture: ComponentFixture<ProcessHeaderCloudComponent>; let fixture: ComponentFixture<ProcessHeaderCloudComponent>;
let service: ProcessHeaderCloudService; let service: ProcessCloudService;
let appConfigService: AppConfigService; let appConfigService: AppConfigService;
setupTestBed({ setupTestBed({
@ -52,7 +52,7 @@ describe('ProcessHeaderCloudComponent', () => {
beforeEach(() => { beforeEach(() => {
fixture = TestBed.createComponent(ProcessHeaderCloudComponent); fixture = TestBed.createComponent(ProcessHeaderCloudComponent);
component = fixture.componentInstance; component = fixture.componentInstance;
service = TestBed.get(ProcessHeaderCloudService); service = TestBed.get(ProcessCloudService);
appConfigService = TestBed.get(AppConfigService); appConfigService = TestBed.get(AppConfigService);
spyOn(service, 'getProcessInstanceById').and.returnValue(of(processInstanceDetailsCloudMock)); spyOn(service, 'getProcessInstanceById').and.returnValue(of(processInstanceDetailsCloudMock));
component.appName = 'myApp'; component.appName = 'myApp';

View File

@ -15,10 +15,12 @@
* limitations under the License. * limitations under the License.
*/ */
import { Component, Input, OnChanges } from '@angular/core'; import { Component, Input, OnChanges, OnInit } from '@angular/core';
import { CardViewItem, CardViewTextItemModel, TranslationService, AppConfigService, CardViewDateItemModel, CardViewBaseItemModel } from '@alfresco/adf-core'; import { CardViewItem, CardViewTextItemModel, TranslationService, AppConfigService, CardViewDateItemModel, CardViewBaseItemModel } from '@alfresco/adf-core';
import { ProcessInstanceCloud } from '../../start-process/models/process-instance-cloud.model'; import { ProcessInstanceCloud } from '../../start-process/models/process-instance-cloud.model';
import { ProcessHeaderCloudService } from '../services/process-header-cloud.service'; import { ProcessCloudService } from '../../services/process-cloud.service';
import { takeUntil } from 'rxjs/operators';
import { Subject } from 'rxjs';
@Component({ @Component({
selector: 'adf-cloud-process-header', selector: 'adf-cloud-process-header',
@ -26,7 +28,7 @@ import { ProcessHeaderCloudService } from '../services/process-header-cloud.serv
styleUrls: ['./process-header-cloud.component.scss'] styleUrls: ['./process-header-cloud.component.scss']
}) })
export class ProcessHeaderCloudComponent implements OnChanges { export class ProcessHeaderCloudComponent implements OnChanges, OnInit {
/** (Required) The name of the application. */ /** (Required) The name of the application. */
@Input() @Input()
@ -41,14 +43,25 @@ export class ProcessHeaderCloudComponent implements OnChanges {
dateFormat: string; dateFormat: string;
dateLocale: string; dateLocale: string;
private onDestroy$ = new Subject<boolean>();
constructor( constructor(
private processHeaderCloudService: ProcessHeaderCloudService, private processCloudService: ProcessCloudService,
private translationService: TranslationService, private translationService: TranslationService,
private appConfig: AppConfigService) { private appConfig: AppConfigService) {
this.dateFormat = this.appConfig.get('dateValues.defaultDateFormat'); this.dateFormat = this.appConfig.get('dateValues.defaultDateFormat');
this.dateLocale = this.appConfig.get('dateValues.defaultDateLocale'); this.dateLocale = this.appConfig.get('dateValues.defaultDateLocale');
} }
ngOnInit() {
this.processCloudService.dataChangesDetected
.pipe(takeUntil(this.onDestroy$))
.subscribe((processDetails: ProcessInstanceCloud) => {
this.processInstanceDetails = processDetails;
this.refreshData();
});
}
ngOnChanges() { ngOnChanges() {
if ((this.appName || this.appName === '') && this.processInstanceId) { if ((this.appName || this.appName === '') && this.processInstanceId) {
this.loadProcessInstanceDetails(this.appName, this.processInstanceId); this.loadProcessInstanceDetails(this.appName, this.processInstanceId);
@ -56,7 +69,7 @@ export class ProcessHeaderCloudComponent implements OnChanges {
} }
private loadProcessInstanceDetails(appName: string, processInstanceId: string) { private loadProcessInstanceDetails(appName: string, processInstanceId: string) {
this.processHeaderCloudService.getProcessInstanceById(appName, processInstanceId).subscribe( this.processCloudService.getProcessInstanceById(appName, processInstanceId).subscribe(
(processInstanceDetails) => { (processInstanceDetails) => {
this.processInstanceDetails = processInstanceDetails; this.processInstanceDetails = processInstanceDetails;
this.refreshData(); this.refreshData();
@ -138,4 +151,9 @@ export class ProcessHeaderCloudComponent implements OnChanges {
return filteredProperties ? filteredProperties.indexOf(cardItem.key) >= 0 : true; return filteredProperties ? filteredProperties.indexOf(cardItem.key) >= 0 : true;
} }
ngOnDestroy() {
this.onDestroy$.next(true);
this.onDestroy$.complete();
}
} }

View File

@ -19,7 +19,6 @@ import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common'; import { CommonModule } from '@angular/common';
import { MaterialModule } from '../../material.module'; import { MaterialModule } from '../../material.module';
import { DataTableModule, TemplateModule, CoreModule } from '@alfresco/adf-core'; import { DataTableModule, TemplateModule, CoreModule } from '@alfresco/adf-core';
import { ProcessHeaderCloudService } from '../process-header/services/process-header-cloud.service';
import { ProcessHeaderCloudComponent } from './components/process-header-cloud.component'; import { ProcessHeaderCloudComponent } from './components/process-header-cloud.component';
@NgModule({ @NgModule({
@ -32,7 +31,6 @@ import { ProcessHeaderCloudComponent } from './components/process-header-cloud.c
], ],
declarations: [ProcessHeaderCloudComponent], declarations: [ProcessHeaderCloudComponent],
exports: [ProcessHeaderCloudComponent], exports: [ProcessHeaderCloudComponent]
providers: [ProcessHeaderCloudService]
}) })
export class ProcessHeaderCloudModule { } export class ProcessHeaderCloudModule { }

View File

@ -17,4 +17,3 @@
export * from './process-header-cloud.module'; export * from './process-header-cloud.module';
export * from './components/process-header-cloud.component'; export * from './components/process-header-cloud.component';
export * from './services/process-header-cloud.service';

View File

@ -1,57 +0,0 @@
/*!
* @license
* Copyright 2019 Alfresco Software, Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { AlfrescoApiService, LogService, AppConfigService } from '@alfresco/adf-core';
import { Injectable } from '@angular/core';
import { Observable, throwError } from 'rxjs';
import { map } from 'rxjs/operators';
import { ProcessInstanceCloud } from '../../start-process/models/process-instance-cloud.model';
import { BaseCloudService } from '../../../services/base-cloud.service';
@Injectable({
providedIn: 'root'
})
export class ProcessHeaderCloudService extends BaseCloudService {
constructor(apiService: AlfrescoApiService,
appConfigService: AppConfigService,
private logService: LogService) {
super(apiService);
this.contextRoot = appConfigService.get('bpmHost', '');
}
/**
* Gets details of a process instance.
* @param appName Name of the app
* @param processInstanceId ID of the process instance whose details you want
* @returns Process instance details
*/
getProcessInstanceById(appName: string, processInstanceId: string): Observable<ProcessInstanceCloud> {
if ((appName || appName === '') && processInstanceId) {
const url = `${this.getBasePath(appName)}/query/v1/process-instances/${processInstanceId}`;
return this.get(url).pipe(
map((res: any) => {
return new ProcessInstanceCloud(res.entry);
})
);
} else {
this.logService.error('AppName and ProcessInstanceId are mandatory for querying a task');
return throwError('AppName/ProcessInstanceId not configured');
}
}
}

View File

@ -17,7 +17,9 @@
import { AlfrescoApiService, LogService, AppConfigService } from '@alfresco/adf-core'; import { AlfrescoApiService, LogService, AppConfigService } from '@alfresco/adf-core';
import { Injectable } from '@angular/core'; import { Injectable } from '@angular/core';
import { throwError } from 'rxjs'; import { Observable, Subject, throwError } from 'rxjs';
import { map } from 'rxjs/operators';
import { ProcessInstanceCloud } from '../start-process/models/process-instance-cloud.model';
import { BaseCloudService } from '../../services/base-cloud.service'; import { BaseCloudService } from '../../services/base-cloud.service';
@Injectable({ @Injectable({
@ -25,6 +27,8 @@ import { BaseCloudService } from '../../services/base-cloud.service';
}) })
export class ProcessCloudService extends BaseCloudService { export class ProcessCloudService extends BaseCloudService {
dataChangesDetected = new Subject<ProcessInstanceCloud>();
constructor(apiService: AlfrescoApiService, constructor(apiService: AlfrescoApiService,
appConfigService: AppConfigService, appConfigService: AppConfigService,
private logService: LogService) { private logService: LogService) {
@ -33,15 +37,42 @@ export class ProcessCloudService extends BaseCloudService {
} }
/** /**
* Deletes a process. * Gets details of a process instance.
* @param appName Name of the app * @param appName Name of the app
* @param processId Id of the process to delete * @param processInstanceId ID of the process instance whose details you want
* @returns Process instance details
*/
getProcessInstanceById(appName: string, processInstanceId: string): Observable<ProcessInstanceCloud> {
if (appName && processInstanceId) {
const url = `${this.getBasePath(appName)}/query/v1/process-instances/${processInstanceId}`;
return this.get(url).pipe(
map((res: any) => {
this.dataChangesDetected.next(res.entry);
return new ProcessInstanceCloud(res.entry);
})
);
} else {
this.logService.error('AppName and ProcessInstanceId are mandatory for querying a process');
return throwError('AppName/ProcessInstanceId not configured');
}
}
/**
* Cancels a process.
* @param appName Name of the app
* @param processInstanceId Id of the process to cancel
* @returns Operation Information * @returns Operation Information
*/ */
deleteProcess(appName: string, processId: string) { cancelProcess(appName: string, processInstanceId: string): Observable<ProcessInstanceCloud> {
if (appName && processId) { if (appName && processInstanceId) {
const queryUrl = `${this.getBasePath(appName)}/rb/v1/process-instances/${processId}`; const queryUrl = `${this.getBasePath(appName)}/rb/v1/process-instances/${processInstanceId}`;
return this.delete(queryUrl); return this.delete(queryUrl).pipe(
map((res: any) => {
this.dataChangesDetected.next(res.entry);
return new ProcessInstanceCloud(res.entry);
})
);
} else { } else {
this.logService.error('App name and Process id are mandatory for deleting a process'); this.logService.error('App name and Process id are mandatory for deleting a process');
return throwError('App name and process id not configured'); return throwError('App name and process id not configured');