From b2ca28d3fd7fd45b4ec86c4a6fd06a6c7a0df32e Mon Sep 17 00:00:00 2001 From: arditdomi <32884230+arditdomi@users.noreply.github.com> Date: Fri, 29 Nov 2019 16:03:06 +0000 Subject: [PATCH] [ADF-5032] Add delete process directive (#5295) --- .../delete-process.directive.spec.ts | 149 ++++++++++++++++++ .../directives/delete-process.directive.ts | 107 +++++++++++++ .../directives/process-directive.module.ts | 29 ++++ .../src/lib/process/directives/public-api.ts | 20 +++ .../src/lib/process/process-cloud.module.ts | 5 +- .../src/lib/process/public-api.ts | 2 + .../process/services/process-cloud.service.ts | 50 ++++++ 7 files changed, 361 insertions(+), 1 deletion(-) create mode 100644 lib/process-services-cloud/src/lib/process/directives/delete-process.directive.spec.ts create mode 100644 lib/process-services-cloud/src/lib/process/directives/delete-process.directive.ts create mode 100644 lib/process-services-cloud/src/lib/process/directives/process-directive.module.ts create mode 100644 lib/process-services-cloud/src/lib/process/directives/public-api.ts create mode 100644 lib/process-services-cloud/src/lib/process/services/process-cloud.service.ts diff --git a/lib/process-services-cloud/src/lib/process/directives/delete-process.directive.spec.ts b/lib/process-services-cloud/src/lib/process/directives/delete-process.directive.spec.ts new file mode 100644 index 0000000000..ddedde7400 --- /dev/null +++ b/lib/process-services-cloud/src/lib/process/directives/delete-process.directive.spec.ts @@ -0,0 +1,149 @@ +/*! + * @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 { Component, ViewChild } from '@angular/core'; +import { ComponentFixture, TestBed } from '@angular/core/testing'; +import { CoreModule, IdentityUserService, setupTestBed } from '@alfresco/adf-core'; +import { DeleteProcessDirective } from './delete-process.directive'; +import { ProcessCloudService } from '../services/process-cloud.service'; +import { of } from 'rxjs'; + +describe('DeleteProcessDirective', () => { + + @Component({ + selector: 'adf-cloud-delete-process-test-component', + template: '' + }) + class TestComponent { + + processIdMock = 'process-id-mock'; + appNameMock = 'app-mock'; + initiatorMock = 'user-mock'; + + @ViewChild(DeleteProcessDirective) + deleteProcessDirective: DeleteProcessDirective; + } + + let fixture: ComponentFixture; + let processCloudService: ProcessCloudService; + let identityUserService: IdentityUserService; + + setupTestBed({ + imports: [ + CoreModule.forRoot() + ], + declarations: [ + TestComponent, + DeleteProcessDirective + ] + }); + + beforeEach(() => { + processCloudService = TestBed.get(ProcessCloudService); + fixture = TestBed.createComponent(TestComponent); + identityUserService = TestBed.get(IdentityUserService); + spyOn(identityUserService, 'getCurrentUserInfo').and.returnValue({username: 'user-mock'}); + fixture.detectChanges(); + }); + + it('should call delete process service when click', () => { + spyOn(processCloudService, 'deleteProcess').and.returnValue(of({})); + const button = fixture.nativeElement.querySelector('button'); + button.click(); + expect(processCloudService.deleteProcess).toHaveBeenCalled(); + }); + +}); + +describe('Validation Errors', () => { + let fixture; + + @Component({ + template: '' + }) + class DeleteProcessMissingInputsDirectiveComponent { + @ViewChild(DeleteProcessDirective) + deleteProcessDirective: DeleteProcessDirective; + } + + @Component({ + template: '' + }) + class DeleteProcessMissingAppNameDirectiveComponent { + @ViewChild(DeleteProcessDirective) + deleteProcessDirective: DeleteProcessDirective; + + processId = 'id-mock'; + processInitiator = 'user-mock'; + } + + @Component({ + template: '' + }) + class DeleteProcessMissingProcessIdDirectiveComponent { + @ViewChild(DeleteProcessDirective) + deleteProcessDirective: DeleteProcessDirective; + + appName = 'app-mock'; + processInitiator = 'user-mock'; + } + + @Component({ + template: '' + }) + class DeleteProcessMissingProcessInitiatorDirectiveComponent { + @ViewChild(DeleteProcessDirective) + deleteProcessDirective: DeleteProcessDirective; + + appName = 'app-mock'; + processId = 'id-mock'; + } + + setupTestBed({ + imports: [ + CoreModule.forRoot() + ], + declarations: [ + DeleteProcessMissingInputsDirectiveComponent, + DeleteProcessMissingAppNameDirectiveComponent, + DeleteProcessMissingProcessIdDirectiveComponent, + DeleteProcessMissingProcessInitiatorDirectiveComponent, + DeleteProcessDirective + ] + }); + + it('should throw an error when appName processId and processInitiator are undefined', () => { + fixture = TestBed.createComponent(DeleteProcessMissingInputsDirectiveComponent); + expect(() => fixture.detectChanges()).toThrowError('Attribute processId, appName, processInitiator is required'); + }); + + it('should throw an error when appName is missing', () => { + fixture = TestBed.createComponent(DeleteProcessMissingAppNameDirectiveComponent); + expect(() => fixture.detectChanges()).toThrowError('Attribute appName is required'); + }); + + it('should throw an error when processId is missing', () => { + fixture = TestBed.createComponent(DeleteProcessMissingProcessIdDirectiveComponent); + expect(() => fixture.detectChanges()).toThrowError('Attribute processId is required'); + }); + + it('should throw an error when processInitiator is missing', () => { + fixture = TestBed.createComponent(DeleteProcessMissingProcessInitiatorDirectiveComponent); + expect(() => fixture.detectChanges()).toThrowError('Attribute processInitiator is required'); + }); + +}); diff --git a/lib/process-services-cloud/src/lib/process/directives/delete-process.directive.ts b/lib/process-services-cloud/src/lib/process/directives/delete-process.directive.ts new file mode 100644 index 0000000000..b11641a0e7 --- /dev/null +++ b/lib/process-services-cloud/src/lib/process/directives/delete-process.directive.ts @@ -0,0 +1,107 @@ +/*! + * @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 { Directive, Input, HostListener, Output, EventEmitter, OnInit } from '@angular/core'; +import { IdentityUserService } from '@alfresco/adf-core'; +import { ProcessCloudService } from '../services/process-cloud.service'; + +@Directive({ + selector: '[adf-cloud-delete-process]' +}) +export class DeleteProcessDirective implements OnInit { + + /** (Required) The id of the process. */ + @Input() + processId: string; + + /** (Required) The name of the application. */ + @Input() + appName: string; + + /** (Required) The process initiator */ + @Input() + processInitiator: string; + + /** Emitted when the process is deleted. */ + @Output() + success: EventEmitter = new EventEmitter(); + + /** Emitted when the process cannot be deleted. */ + @Output() + error: EventEmitter = new EventEmitter(); + + invalidParams: string[] = []; + + constructor( + private processCloudService: ProcessCloudService, + private identityUserService: IdentityUserService) {} + + ngOnInit() { + this.validateInputs(); + } + + validateInputs() { + + if (!this.isProcessValid()) { + this.invalidParams.push('processId'); + } + if (!this.isAppValid()) { + this.invalidParams.push('appName'); + } + if (!this.isProcessInitiatorValid()) { + this.invalidParams.push('processInitiator'); + } + if (this.invalidParams.length) { + throw new Error(`Attribute ${this.invalidParams.join(', ')} is required`); + } + } + + isProcessValid(): boolean { + return this.processId && this.processId.length > 0; + } + + isAppValid(): boolean { + return (this.appName && this.appName.length > 0); + } + + isProcessInitiatorValid(): boolean { + return (this.processInitiator && this.processInitiator.length > 0); + } + + @HostListener('click') + async onClick() { + try { + this.deleteProcess(); + } catch (error) { + this.error.emit(error); + } + } + + private async deleteProcess() { + const currentUser: string = this.identityUserService.getCurrentUserInfo().username; + if (currentUser === this.processInitiator) { + await this.processCloudService.deleteProcess(this.appName, this.processId) + .subscribe((response) => { + this.success.emit(response); + }, ((error) => { + this.error.emit(error); + })); + } else { + this.error.emit('Permission denied'); + } + + } +} diff --git a/lib/process-services-cloud/src/lib/process/directives/process-directive.module.ts b/lib/process-services-cloud/src/lib/process/directives/process-directive.module.ts new file mode 100644 index 0000000000..d544102f15 --- /dev/null +++ b/lib/process-services-cloud/src/lib/process/directives/process-directive.module.ts @@ -0,0 +1,29 @@ +/*! + * @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 { NgModule } from '@angular/core'; +import { DeleteProcessDirective } from './delete-process.directive'; + +@NgModule({ + declarations: [ + DeleteProcessDirective + ], + exports: [ + DeleteProcessDirective + ] +}) +export class ProcessDirectiveModule { } diff --git a/lib/process-services-cloud/src/lib/process/directives/public-api.ts b/lib/process-services-cloud/src/lib/process/directives/public-api.ts new file mode 100644 index 0000000000..8919c86169 --- /dev/null +++ b/lib/process-services-cloud/src/lib/process/directives/public-api.ts @@ -0,0 +1,20 @@ +/*! + * @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. + */ + +export * from './delete-process.directive'; + +export * from './process-directive.module'; diff --git a/lib/process-services-cloud/src/lib/process/process-cloud.module.ts b/lib/process-services-cloud/src/lib/process/process-cloud.module.ts index ccecbc4a01..5cbeb35ede 100644 --- a/lib/process-services-cloud/src/lib/process/process-cloud.module.ts +++ b/lib/process-services-cloud/src/lib/process/process-cloud.module.ts @@ -21,6 +21,7 @@ import { ProcessListCloudModule } from './process-list/process-list-cloud.module import { StartProcessCloudModule } from './start-process/start-process-cloud.module'; import { CoreModule } from '@alfresco/adf-core'; import { ProcessHeaderCloudModule } from './process-header/process-header-cloud.module'; +import { ProcessDirectiveModule } from './directives/process-directive.module'; @NgModule({ imports: [ @@ -28,13 +29,15 @@ import { ProcessHeaderCloudModule } from './process-header/process-header-cloud. ProcessListCloudModule, StartProcessCloudModule, ProcessHeaderCloudModule, + ProcessDirectiveModule, CoreModule ], exports: [ ProcessFiltersCloudModule, ProcessListCloudModule, StartProcessCloudModule, - ProcessHeaderCloudModule + ProcessHeaderCloudModule, + ProcessDirectiveModule ] }) export class ProcessCloudModule { } diff --git a/lib/process-services-cloud/src/lib/process/public-api.ts b/lib/process-services-cloud/src/lib/process/public-api.ts index 8080aec215..8486bc8819 100644 --- a/lib/process-services-cloud/src/lib/process/public-api.ts +++ b/lib/process-services-cloud/src/lib/process/public-api.ts @@ -19,5 +19,7 @@ export * from './process-list/public-api'; export * from './process-filters/public-api'; export * from './start-process/public-api'; export * from './process-header/public-api'; +export * from './directives/public-api'; +export * from './services/process-cloud.service'; export * from './process-cloud.module'; diff --git a/lib/process-services-cloud/src/lib/process/services/process-cloud.service.ts b/lib/process-services-cloud/src/lib/process/services/process-cloud.service.ts new file mode 100644 index 0000000000..2ffc3d3fc5 --- /dev/null +++ b/lib/process-services-cloud/src/lib/process/services/process-cloud.service.ts @@ -0,0 +1,50 @@ +/*! + * @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 { throwError } from 'rxjs'; +import { BaseCloudService } from '../../services/base-cloud.service'; + +@Injectable({ + providedIn: 'root' +}) +export class ProcessCloudService extends BaseCloudService { + + constructor(apiService: AlfrescoApiService, + appConfigService: AppConfigService, + private logService: LogService) { + super(apiService); + this.contextRoot = appConfigService.get('bpmHost', ''); + } + + /** + * Deletes a process. + * @param appName Name of the app + * @param processId Id of the process to delete + * @returns Operation Information + */ + deleteProcess(appName: string, processId: string) { + if (appName && processId) { + const queryUrl = `${this.getBasePath(appName)}/rb/v1/process-instances/${processId}`; + return this.delete(queryUrl); + } else { + this.logService.error('App name and Process id are mandatory for deleting a process'); + return throwError('App name and process id not configured'); + } + } +}