[ADF-4409] ADF for Activiti Community - Be able to claim/release/complete task (#4677)

* Be able to claim/release/complete task for community
Be able to start a task/process
Fix unsubscribe on destroy

* Fix the construnctor
This commit is contained in:
Maurizio Vitale
2019-05-02 14:30:38 +02:00
committed by GitHub
parent 9298e6762f
commit e88e0d9b45
12 changed files with 62 additions and 41 deletions

View File

@@ -10,6 +10,7 @@
<adf-cloud-task-list <adf-cloud-task-list
fxFlex fxFlex
class="adf-cloud-layout-overflow" class="adf-cloud-layout-overflow"
[appName]="''"
[processInstanceId]="processInstanceId" [processInstanceId]="processInstanceId"
(rowClick)="onRowClick($event)" (rowClick)="onRowClick($event)"
#taskCloud> #taskCloud>

View File

@@ -1,4 +1,5 @@
<adf-cloud-start-task <adf-cloud-start-task
[appName]="''"
(error)="openSnackMessage($event)" (error)="openSnackMessage($event)"
(success)="onStartTaskSuccess()" (success)="onStartTaskSuccess()"
(cancel)="onCancelStartTask()"> (cancel)="onCancelStartTask()">

View File

@@ -19,7 +19,8 @@ import { SimpleChange, DebugElement, CUSTOM_ELEMENTS_SCHEMA, Component } from '@
import { By } from '@angular/platform-browser'; import { By } from '@angular/platform-browser';
import { ComponentFixture, TestBed } from '@angular/core/testing'; import { ComponentFixture, TestBed } from '@angular/core/testing';
import { Observable, of, throwError } from 'rxjs'; import { Observable, of, throwError } from 'rxjs';
import { FormFieldModel, FormFieldTypes, FormService, FormOutcomeEvent, FormOutcomeModel, LogService, WidgetVisibilityService, setupTestBed } from '@alfresco/adf-core'; import { FormFieldModel, FormFieldTypes, FormService, FormOutcomeEvent, FormOutcomeModel, LogService, WidgetVisibilityService,
setupTestBed, AppConfigService } from '@alfresco/adf-core';
import { ProcessServiceCloudTestingModule } from '../../testing/process-service-cloud.testing.module'; import { ProcessServiceCloudTestingModule } from '../../testing/process-service-cloud.testing.module';
import { FormCloudService } from '../services/form-cloud.service'; import { FormCloudService } from '../services/form-cloud.service';
import { FormCloudComponent } from './form-cloud.component'; import { FormCloudComponent } from './form-cloud.component';
@@ -38,7 +39,7 @@ describe('FormCloudComponent', () => {
logService = new LogService(null); logService = new LogService(null);
visibilityService = new WidgetVisibilityService(null, logService); visibilityService = new WidgetVisibilityService(null, logService);
spyOn(visibilityService, 'refreshVisibility').and.stub(); spyOn(visibilityService, 'refreshVisibility').and.stub();
formCloudService = new FormCloudService(null, null, logService); formCloudService = new FormCloudService(null, new AppConfigService(null), logService);
formService = new FormService(null, null, logService); formService = new FormService(null, null, logService);
formComponent = new FormCloudComponent(formCloudService, formService, null, visibilityService); formComponent = new FormCloudComponent(formCloudService, formService, null, visibilityService);
}); });

View File

@@ -17,14 +17,14 @@
import { FormCloudService } from '../services/form-cloud.service'; import { FormCloudService } from '../services/form-cloud.service';
import { FormCloud } from './form-cloud.model'; import { FormCloud } from './form-cloud.model';
import { TabModel, FormFieldModel, ContainerModel, FormOutcomeModel, FormFieldTypes } from '@alfresco/adf-core'; import { TabModel, FormFieldModel, ContainerModel, FormOutcomeModel, FormFieldTypes, AppConfigService } from '@alfresco/adf-core';
describe('FormCloud', () => { describe('FormCloud', () => {
let formCloudService: FormCloudService; let formCloudService: FormCloudService;
beforeEach(() => { beforeEach(() => {
formCloudService = new FormCloudService(null, null, null); formCloudService = new FormCloudService(null, new AppConfigService(null), null);
}); });
it('should store original json', () => { it('should store original json', () => {

View File

@@ -23,18 +23,22 @@ import { TaskDetailsCloudModel } from '../../task/start-task/models/task-details
import { SaveFormRepresentation, CompleteFormRepresentation } from '@alfresco/js-api'; import { SaveFormRepresentation, CompleteFormRepresentation } from '@alfresco/js-api';
import { FormCloud } from '../models/form-cloud.model'; import { FormCloud } from '../models/form-cloud.model';
import { TaskVariableCloud } from '../models/task-variable-cloud.model'; import { TaskVariableCloud } from '../models/task-variable-cloud.model';
import { BaseCloudService } from '../../services/base-cloud.service';
@Injectable({ @Injectable({
providedIn: 'root' providedIn: 'root'
}) })
export class FormCloudService { export class FormCloudService extends BaseCloudService {
contentTypes = ['application/json']; accepts = ['application/json']; returnType = Object; contentTypes = ['application/json']; accepts = ['application/json']; returnType = Object;
constructor( constructor(
private apiService: AlfrescoApiService, private apiService: AlfrescoApiService,
private appConfigService: AppConfigService, private appConfigService: AppConfigService,
private logService: LogService private logService: LogService
) {} ) {
super();
this.contextRoot = this.appConfigService.get('bpmHost', '');
}
/** /**
* Gets the form definition of a task. * Gets the form definition of a task.
@@ -245,15 +249,15 @@ export class FormCloudService {
} }
private buildGetTaskUrl(appName: string, taskId: string): string { private buildGetTaskUrl(appName: string, taskId: string): string {
return `${this.appConfigService.get('bpmHost')}/${appName}/query/v1/tasks/${taskId}`; return `${this.getBasePath(appName)}/query/v1/tasks/${taskId}`;
} }
private buildGetFormUrl(appName: string, formId: string): string { private buildGetFormUrl(appName: string, formId: string): string {
return `${this.appConfigService.get('bpmHost')}/${appName}/form/v1/forms/${formId}`; return `${this.getBasePath(appName)}/form/v1/forms/${formId}`;
} }
private buildSaveFormUrl(appName: string, formId: string): string { private buildSaveFormUrl(appName: string, formId: string): string {
return `${this.appConfigService.get('bpmHost')}/${appName}/form/v1/forms/${formId}/save`; return `${this.getBasePath(appName)}/form/v1/forms/${formId}/save`;
} }
private buildUploadUrl(nodeId: string): string { private buildUploadUrl(nodeId: string): string {
@@ -261,15 +265,15 @@ export class FormCloudService {
} }
private buildSubmitFormUrl(appName: string, formId: string): string { private buildSubmitFormUrl(appName: string, formId: string): string {
return `${this.appConfigService.get('bpmHost')}/${appName}/form/v1/forms/${formId}/submit`; return `${this.getBasePath(appName)}/form/v1/forms/${formId}/submit`;
} }
private buildGetTaskVariablesUrl(appName: string, taskId: string): string { private buildGetTaskVariablesUrl(appName: string, taskId: string): string {
return `${this.appConfigService.get('bpmHost')}/${appName}/query/v1/tasks/${taskId}/variables`; return `${this.getBasePath(appName)}/query/v1/tasks/${taskId}/variables`;
} }
private buildFolderTask(appName: string, taskId: string): string { private buildFolderTask(appName: string, taskId: string): string {
return `${this.appConfigService.get('bpmHost')}/${appName}/process-storage/v1/folders/tasks/${taskId}`; return `${this.getBasePath(appName)}/process-storage/v1/folders/tasks/${taskId}`;
} }
private handleError(error: any) { private handleError(error: any) {

View File

@@ -20,13 +20,13 @@ import { AlfrescoApiService, AppConfigService, LogService } from '@alfresco/adf-
import { catchError, map } from 'rxjs/operators'; import { catchError, map } from 'rxjs/operators';
import { FormDefinitionSelectorCloudModel } from '../models/form-definition-selector-cloud.model'; import { FormDefinitionSelectorCloudModel } from '../models/form-definition-selector-cloud.model';
import { from, Observable, throwError } from 'rxjs'; import { from, Observable, throwError } from 'rxjs';
import { BaseCloudService } from '../../services/base-cloud.service';
@Injectable({ @Injectable({
providedIn: 'root' providedIn: 'root'
}) })
export class FormDefinitionSelectorCloudService { export class FormDefinitionSelectorCloudService extends BaseCloudService {
contextRoot: string;
contentTypes = ['application/json']; contentTypes = ['application/json'];
accepts = ['application/json']; accepts = ['application/json'];
returnType = Object; returnType = Object;
@@ -34,6 +34,7 @@ export class FormDefinitionSelectorCloudService {
constructor(private apiService: AlfrescoApiService, constructor(private apiService: AlfrescoApiService,
private appConfigService: AppConfigService, private appConfigService: AppConfigService,
private logService: LogService) { private logService: LogService) {
super();
this.contextRoot = this.appConfigService.get('bpmHost', ''); this.contextRoot = this.appConfigService.get('bpmHost', '');
} }
@@ -65,7 +66,7 @@ export class FormDefinitionSelectorCloudService {
} }
private buildGetFormsUrl(appName: string): any { private buildGetFormsUrl(appName: string): any {
return `${this.appConfigService.get('bpmHost')}/${appName}/form/v1/forms`; return `${this.getBasePath(appName)}/form/v1/forms`;
} }
private handleError(error: any) { private handleError(error: any) {

View File

@@ -67,7 +67,7 @@ export class ClaimTaskDirective implements OnInit {
} }
isAppValid(): boolean { isAppValid(): boolean {
return this.appName && this.appName.length > 0; return (this.appName && this.appName.length > 0) || (this.appName === '');
} }
@HostListener('click') @HostListener('click')

View File

@@ -64,7 +64,7 @@ export class CompleteTaskDirective implements OnInit {
} }
isAppValid(): boolean { isAppValid(): boolean {
return this.appName && this.appName.length > 0; return (this.appName && this.appName.length > 0) || (this.appName === '');
} }
@HostListener('click') @HostListener('click')

View File

@@ -65,7 +65,7 @@ export class UnClaimTaskDirective implements OnInit {
} }
isAppValid(): boolean { isAppValid(): boolean {
return this.appName && this.appName.length > 0; return (this.appName && this.appName.length > 0) || (this.appName === '');
} }
@HostListener('click') @HostListener('click')

View File

@@ -48,6 +48,7 @@ export class TaskCloudService extends BaseCloudService {
* @returns Details of the task that was completed * @returns Details of the task that was completed
*/ */
completeTask(appName: string, taskId: string): Observable<TaskDetailsCloudModel> { completeTask(appName: string, taskId: string): Observable<TaskDetailsCloudModel> {
if ((appName || appName === '') && taskId) {
const queryUrl = this.buildCompleteTaskUrl(appName, taskId); const queryUrl = this.buildCompleteTaskUrl(appName, taskId);
const bodyParam = { 'payloadType': 'CompleteTaskPayload' }; const bodyParam = { 'payloadType': 'CompleteTaskPayload' };
const pathParams = {}, queryParams = {}, headerParams = {}, const pathParams = {}, queryParams = {}, headerParams = {},
@@ -63,6 +64,10 @@ export class TaskCloudService extends BaseCloudService {
).pipe( ).pipe(
catchError((err) => this.handleError(err)) catchError((err) => this.handleError(err))
); );
} else {
this.logService.error('AppName and TaskId are mandatory for complete a task');
return throwError('AppName/TaskId not configured');
}
} }
/** /**
@@ -102,7 +107,7 @@ export class TaskCloudService extends BaseCloudService {
* @returns Details of the claimed task * @returns Details of the claimed task
*/ */
claimTask(appName: string, taskId: string, assignee: string): Observable<TaskDetailsCloudModel> { claimTask(appName: string, taskId: string, assignee: string): Observable<TaskDetailsCloudModel> {
if (appName && taskId) { if ((appName || appName === '') && taskId) {
const queryUrl = `${this.getBasePath(appName)}/rb/v1/tasks/${taskId}/claim?assignee=${assignee}`; const queryUrl = `${this.getBasePath(appName)}/rb/v1/tasks/${taskId}/claim?assignee=${assignee}`;
return from(this.apiService.getInstance() return from(this.apiService.getInstance()
.oauth2Auth.callCustomApi(queryUrl, 'POST', .oauth2Auth.callCustomApi(queryUrl, 'POST',
@@ -129,7 +134,7 @@ export class TaskCloudService extends BaseCloudService {
* @returns Details of the task that was unclaimed * @returns Details of the task that was unclaimed
*/ */
unclaimTask(appName: string, taskId: string): Observable<TaskDetailsCloudModel> { unclaimTask(appName: string, taskId: string): Observable<TaskDetailsCloudModel> {
if (appName && taskId) { if ((appName || appName === '') && taskId) {
const queryUrl = `${this.getBasePath(appName)}/rb/v1/tasks/${taskId}/release`; const queryUrl = `${this.getBasePath(appName)}/rb/v1/tasks/${taskId}/release`;
return from(this.apiService.getInstance() return from(this.apiService.getInstance()
.oauth2Auth.callCustomApi(queryUrl, 'POST', .oauth2Auth.callCustomApi(queryUrl, 'POST',
@@ -184,7 +189,7 @@ export class TaskCloudService extends BaseCloudService {
* @returns Updated task details * @returns Updated task details
*/ */
updateTask(appName: string, taskId: string, updatePayload: any): Observable<TaskDetailsCloudModel> { updateTask(appName: string, taskId: string, updatePayload: any): Observable<TaskDetailsCloudModel> {
if (appName && taskId) { if ((appName || appName === '') && taskId) {
updatePayload.payloadType = 'UpdateTaskPayload'; updatePayload.payloadType = 'UpdateTaskPayload';
const queryUrl = `${this.getBasePath(appName)}/rb/v1/tasks/${taskId}`; const queryUrl = `${this.getBasePath(appName)}/rb/v1/tasks/${taskId}`;

View File

@@ -98,7 +98,7 @@ export class TaskFormCloudComponent implements OnChanges {
ngOnChanges(changes: SimpleChanges) { ngOnChanges(changes: SimpleChanges) {
const appName = changes['appName']; const appName = changes['appName'];
if (appName && appName.currentValue && this.taskId) { if (appName && (appName.currentValue || appName.currentValue === '' ) && this.taskId) {
this.loadTask(); this.loadTask();
return; return;
} }

View File

@@ -15,7 +15,7 @@
* limitations under the License. * limitations under the License.
*/ */
import { Component, Input, OnInit, EventEmitter, Output } from '@angular/core'; import { Component, Input, OnInit, EventEmitter, Output, OnDestroy } from '@angular/core';
import { import {
CardViewDateItemModel, CardViewDateItemModel,
CardViewItem, CardViewItem,
@@ -29,13 +29,14 @@ import {
import { TaskDetailsCloudModel, TaskStatusEnum } from '../../start-task/models/task-details-cloud.model'; import { TaskDetailsCloudModel, TaskStatusEnum } from '../../start-task/models/task-details-cloud.model';
import { Router } from '@angular/router'; import { Router } from '@angular/router';
import { TaskCloudService } from '../../services/task-cloud.service'; import { TaskCloudService } from '../../services/task-cloud.service';
import { Subscription } from 'rxjs';
@Component({ @Component({
selector: 'adf-cloud-task-header', selector: 'adf-cloud-task-header',
templateUrl: './task-header-cloud.component.html', templateUrl: './task-header-cloud.component.html',
styleUrls: ['./task-header-cloud.component.scss'] styleUrls: ['./task-header-cloud.component.scss']
}) })
export class TaskHeaderCloudComponent implements OnInit { export class TaskHeaderCloudComponent implements OnInit, OnDestroy {
/** (Required) The name of the application. */ /** (Required) The name of the application. */
@Input() @Input()
@@ -58,6 +59,8 @@ export class TaskHeaderCloudComponent implements OnInit {
inEdit: boolean = false; inEdit: boolean = false;
parentTaskName: string; parentTaskName: string;
private subscriptions: Subscription[] = [];
constructor( constructor(
private taskCloudService: TaskCloudService, private taskCloudService: TaskCloudService,
private translationService: TranslationService, private translationService: TranslationService,
@@ -71,11 +74,11 @@ export class TaskHeaderCloudComponent implements OnInit {
this.loadTaskDetailsById(this.appName, this.taskId); this.loadTaskDetailsById(this.appName, this.taskId);
} }
this.cardViewUpdateService.itemUpdated$.subscribe(this.updateTaskDetails.bind(this)); this.subscriptions.push(this.cardViewUpdateService.itemUpdated$.subscribe(this.updateTaskDetails.bind(this)));
} }
loadTaskDetailsById(appName: string, taskId: string): any { loadTaskDetailsById(appName: string, taskId: string): any {
this.taskCloudService.getTaskById(appName, taskId).subscribe( this.subscriptions.push(this.taskCloudService.getTaskById(appName, taskId).subscribe(
(taskDetails) => { (taskDetails) => {
this.taskDetails = taskDetails; this.taskDetails = taskDetails;
if (this.taskDetails.parentTaskId) { if (this.taskDetails.parentTaskId) {
@@ -83,7 +86,7 @@ export class TaskHeaderCloudComponent implements OnInit {
} else { } else {
this.refreshData(); this.refreshData();
} }
}); }));
} }
private initDefaultProperties() { private initDefaultProperties() {
@@ -244,4 +247,9 @@ export class TaskHeaderCloudComponent implements OnInit {
onCompletedTask(event: any) { onCompletedTask(event: any) {
this.goBack(); this.goBack();
} }
ngOnDestroy() {
this.subscriptions.forEach((subscription) => subscription.unsubscribe());
this.subscriptions = [];
}
} }