[ACTIVITI-3234] add processInstanceId to save/submit event, change get folder… (#4833)

* [ACTIVITI-3234] add processId to save/submit event, change get folder rest call api

* Update form-cloud.component.md

* lint fix

* [ACTIVITI-3234] fix tests

* [ACTIVITI-3234] fix tests

* Fix rename processId in processInstanceId
This commit is contained in:
Mario Romano 2019-06-11 14:30:43 +01:00 committed by Eugenio Romano
parent 7b191d37eb
commit fb082cdfdc
7 changed files with 67 additions and 45 deletions

View File

@ -29,7 +29,8 @@ Shows a [`form`](../../../lib/process-services-cloud/src/lib/form/models/form-cl
```html ```html
<adf-cloud-form <adf-cloud-form
[appName]="appName" [appName]="appName"
[taskId]="taskId"> [taskId]="taskId"
[processInstanceId]="processInstanceId">
</adf-cloud-form> </adf-cloud-form>
``` ```
@ -92,6 +93,7 @@ The template defined inside `empty-form` will be shown when no form definition i
| showTitle | `boolean` | true | Toggle rendering of the form title. | | showTitle | `boolean` | true | Toggle rendering of the form title. |
| showValidationIcon | `boolean` | true | Toggle rendering of the validation icon next to the form title. | | showValidationIcon | `boolean` | true | Toggle rendering of the validation icon next to the form title. |
| taskId | `string` | | Task id to fetch corresponding form and values. | | taskId | `string` | | Task id to fetch corresponding form and values. |
| processInstanceId | `string `| | Process instance id to fetch corresponding form and values.|
### Events ### Events
@ -116,6 +118,7 @@ All `formXXX` events receive a [`FormCloudModel`](../../../lib/process-services-
<adf-cloud-form <adf-cloud-form
[appName]="appName" [appName]="appName"
[taskId]="selectedTask?.id" [taskId]="selectedTask?.id"
[processInstanceId]="selectedTask?.processInstanceId"
(formSaved)="onFormSaved($event)"> (formSaved)="onFormSaved($event)">
</adf-cloud-form> </adf-cloud-form>
``` ```
@ -132,12 +135,13 @@ onFormSaved(form: FormCloudModel) {
There are various ways to display a form. The common scenarios are detailed below. There are various ways to display a form. The common scenarios are detailed below.
#### Displaying a form instance by task id #### Displaying a form instance by task id and processInstanceId
```html ```html
<adf-cloud-form <adf-cloud-form
[appName]="appName" [appName]="appName"
[taskId]="selectedTask?.id"> [taskId]="selectedTask?.id"
[processInstanceId]="selectedTask?.processInstanceId">
</adf-cloud-form> </adf-cloud-form>
``` ```
@ -172,6 +176,7 @@ of the form validation before it is submitted.
<adf-cloud-form <adf-cloud-form
[appName]="appName" [appName]="appName"
[taskId]="selectedTask?.id" [taskId]="selectedTask?.id"
[processInstanceId]="selectedTask?.processInstanceId"
executeOutcome="validateForm($event)"> executeOutcome="validateForm($event)">
</adf-cloud-form> </adf-cloud-form>
``` ```

View File

@ -466,6 +466,7 @@ describe('FormCloudComponent', () => {
const taskId = '123-223'; const taskId = '123-223';
const appName = 'test-app'; const appName = 'test-app';
const processInstanceId = '333-444';
const formModel = new FormCloud({ const formModel = new FormCloud({
formRepresentation: { formRepresentation: {
@ -482,10 +483,11 @@ describe('FormCloudComponent', () => {
formComponent.form = formModel; formComponent.form = formModel;
formComponent.taskId = taskId; formComponent.taskId = taskId;
formComponent.appName = appName; formComponent.appName = appName;
formComponent.processInstanceId = processInstanceId;
formComponent.saveTaskForm(); formComponent.saveTaskForm();
expect(formCloudService.saveTaskForm).toHaveBeenCalledWith(appName, formModel.taskId, formModel.id, formModel.values); expect(formCloudService.saveTaskForm).toHaveBeenCalledWith(appName, formModel.taskId, processInstanceId, formModel.id, formModel.values);
expect(saved).toBeTruthy(); expect(saved).toBeTruthy();
expect(savedForm).toEqual(formModel); expect(savedForm).toEqual(formModel);
}); });
@ -567,6 +569,8 @@ describe('FormCloudComponent', () => {
const taskId = '123-223'; const taskId = '123-223';
const appName = 'test-app'; const appName = 'test-app';
const processInstanceId = '333-444';
const formModel = new FormCloud({ const formModel = new FormCloud({
formRepresentation: { formRepresentation: {
id: '23', id: '23',
@ -583,9 +587,10 @@ describe('FormCloudComponent', () => {
formComponent.form = formModel; formComponent.form = formModel;
formComponent.taskId = taskId; formComponent.taskId = taskId;
formComponent.appName = appName; formComponent.appName = appName;
formComponent.processInstanceId = processInstanceId;
formComponent.completeTaskForm(outcome); formComponent.completeTaskForm(outcome);
expect(formCloudService.completeTaskForm).toHaveBeenCalledWith(appName, formModel.taskId, formModel.id, formModel.values, outcome); expect(formCloudService.completeTaskForm).toHaveBeenCalledWith(appName, formModel.taskId, processInstanceId, formModel.id, formModel.values, outcome);
expect(completed).toBeTruthy(); expect(completed).toBeTruthy();
}); });

View File

@ -52,6 +52,10 @@ export class FormCloudComponent extends FormBaseComponent implements OnChanges,
@Input() @Input()
formId: string; formId: string;
/** ProcessInstanceId id to fetch corresponding form and values. */
@Input()
processInstanceId: string;
/** Underlying form model instance. */ /** Underlying form model instance. */
@Input() @Input()
form: FormCloud; form: FormCloud;
@ -110,8 +114,8 @@ export class FormCloudComponent extends FormBaseComponent implements OnChanges,
ngOnChanges(changes: SimpleChanges) { ngOnChanges(changes: SimpleChanges) {
const appName = changes['appName']; const appName = changes['appName'];
if (appName && appName.currentValue) { if (appName && appName.currentValue) {
if (this.taskId) { if (this.taskId && this.processInstanceId) {
this.getFormDefinitionWithFolderTask(this.appName, this.taskId); this.getFormDefinitionWithFolderTask(this.appName, this.taskId, this.processInstanceId);
} else if (this.formId) { } else if (this.formId) {
this.getFormById(appName.currentValue, this.formId); this.getFormById(appName.currentValue, this.formId);
} }
@ -211,22 +215,22 @@ export class FormCloudComponent extends FormBaseComponent implements OnChanges,
); );
} }
getFormDefinitionWithFolderTask(appName: string, taskId: string) { getFormDefinitionWithFolderTask(appName: string, taskId: string, processInstanceId: string) {
this.getFormDefinitionWithFolderByTaskId(appName, taskId); this.getFormDefinitionWithFolder(appName, taskId, processInstanceId);
} }
async getFormDefinitionWithFolderByTaskId(appName: string, taskId: string) { async getFormDefinitionWithFolder(appName: string, taskId: string, processInstanceId: string) {
try { try {
await this.getFormByTaskId(appName, taskId); await this.getFormByTaskId(appName, taskId);
const hasUploadWidget = (<any> this.form).hasUpload; const hasUploadWidget = (<any> this.form).hasUpload;
if (hasUploadWidget) { if (hasUploadWidget) {
try { try {
const processStorageCloudModel = await this.formCloudService.getProcessStorageFolderTask(appName, taskId).toPromise(); const processStorageCloudModel = await this.formCloudService.getProcessStorageFolderTask(appName, taskId, processInstanceId).toPromise();
this.form.nodeId = processStorageCloudModel.nodeId; this.form.nodeId = processStorageCloudModel.nodeId;
this.form.contentHost = processStorageCloudModel.path; this.form.contentHost = processStorageCloudModel.path;
} catch (error) { } catch (error) {
this.notificationService.openSnackMessage('The content repo is not configured'); this.notificationService.openSnackMessage('The content repo is not configured');
} }
} }
@ -239,7 +243,7 @@ export class FormCloudComponent extends FormBaseComponent implements OnChanges,
saveTaskForm() { saveTaskForm() {
if (this.form && this.appName && this.taskId) { if (this.form && this.appName && this.taskId) {
this.formCloudService this.formCloudService
.saveTaskForm(this.appName, this.taskId, this.form.id, this.form.values) .saveTaskForm(this.appName, this.taskId, this.processInstanceId, this.form.id, this.form.values)
.pipe(takeUntil(this.onDestroy$)) .pipe(takeUntil(this.onDestroy$))
.subscribe( .subscribe(
() => { () => {
@ -253,7 +257,7 @@ export class FormCloudComponent extends FormBaseComponent implements OnChanges,
completeTaskForm(outcome?: string) { completeTaskForm(outcome?: string) {
if (this.form && this.appName && this.taskId) { if (this.form && this.appName && this.taskId) {
this.formCloudService this.formCloudService
.completeTaskForm(this.appName, this.taskId, this.form.id, this.form.values, outcome) .completeTaskForm(this.appName, this.taskId, this.processInstanceId, this.form.id, this.form.values, outcome)
.pipe(takeUntil(this.onDestroy$)) .pipe(takeUntil(this.onDestroy$))
.subscribe( .subscribe(
() => { () => {

View File

@ -41,6 +41,7 @@ describe('Form Cloud service', () => {
let apiService: AlfrescoApiService; let apiService: AlfrescoApiService;
const appName = 'app-name'; const appName = 'app-name';
const taskId = 'task-id'; const taskId = 'task-id';
const processInstanceId = 'process-instance-id';
setupTestBed({ setupTestBed({
imports: [ imports: [
@ -167,7 +168,7 @@ describe('Form Cloud service', () => {
oauth2Auth.callCustomApi.and.returnValue(Promise.resolve(responseBody)); oauth2Auth.callCustomApi.and.returnValue(Promise.resolve(responseBody));
const formId = 'form-id'; const formId = 'form-id';
service.saveTaskForm(appName, taskId, formId, {}).subscribe((result: any) => { service.saveTaskForm(appName, taskId, processInstanceId, formId, {}).subscribe((result: any) => {
expect(result).toBeDefined(); expect(result).toBeDefined();
expect(result.id).toBe('id'); expect(result.id).toBe('id');
expect(result.name).toBe('name'); expect(result.name).toBe('name');
@ -182,7 +183,7 @@ describe('Form Cloud service', () => {
oauth2Auth.callCustomApi.and.returnValue(Promise.resolve(responseBody)); oauth2Auth.callCustomApi.and.returnValue(Promise.resolve(responseBody));
const formId = 'form-id'; const formId = 'form-id';
service.completeTaskForm(appName, taskId, formId, {}, '').subscribe((result: any) => { service.completeTaskForm(appName, taskId, processInstanceId, formId, {}, '').subscribe((result: any) => {
expect(result).toBeDefined(); expect(result).toBeDefined();
expect(result.id).toBe('id'); expect(result.id).toBe('id');
expect(result.name).toBe('name'); expect(result.name).toBe('name');

View File

@ -30,7 +30,10 @@ import { BaseCloudService } from '../../services/base-cloud.service';
}) })
export class FormCloudService extends BaseCloudService { 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,
@ -71,9 +74,9 @@ export class FormCloudService extends BaseCloudService {
* @param formValues Form values object * @param formValues Form values object
* @returns Updated task details * @returns Updated task details
*/ */
saveTaskForm(appName: string, taskId: string, formId: string, formValues: FormValues): Observable<TaskDetailsCloudModel> { saveTaskForm(appName: string, taskId: string, processInstanceId: string, formId: string, formValues: FormValues): Observable<TaskDetailsCloudModel> {
const apiUrl = this.buildSaveFormUrl(appName, formId); const apiUrl = this.buildSaveFormUrl(appName, formId);
const saveFormRepresentation = <SaveFormRepresentation> { values: formValues, taskId: taskId }; const saveFormRepresentation = <SaveFormRepresentation> {values: formValues, taskId: taskId, processInstanceId: processInstanceId};
return from(this.apiService return from(this.apiService
.getInstance() .getInstance()
.oauth2Auth.callCustomApi(apiUrl, 'POST', .oauth2Auth.callCustomApi(apiUrl, 'POST',
@ -100,7 +103,7 @@ export class FormCloudService extends BaseCloudService {
'', '',
nodeId, nodeId,
'', '',
{ overwrite: true } {overwrite: true}
)).pipe( )).pipe(
map((res: any) => { map((res: any) => {
return (res.entry); return (res.entry);
@ -118,9 +121,9 @@ export class FormCloudService extends BaseCloudService {
* @param outcome (Optional) Form outcome * @param outcome (Optional) Form outcome
* @returns Updated task details * @returns Updated task details
*/ */
completeTaskForm(appName: string, taskId: string, formId: string, formValues: FormValues, outcome: string): Observable<TaskDetailsCloudModel> { completeTaskForm(appName: string, taskId: string, processInstanceId: string, formId: string, formValues: FormValues, outcome: string): Observable<TaskDetailsCloudModel> {
const apiUrl = this.buildSubmitFormUrl(appName, formId); const apiUrl = this.buildSubmitFormUrl(appName, formId);
const completeFormRepresentation: any = <CompleteFormRepresentation> { values: formValues, taskId: taskId }; const completeFormRepresentation: any = <CompleteFormRepresentation> {values: formValues, taskId: taskId, processInstanceId: processInstanceId};
if (outcome) { if (outcome) {
completeFormRepresentation.outcome = outcome; completeFormRepresentation.outcome = outcome;
} }
@ -163,8 +166,8 @@ export class FormCloudService extends BaseCloudService {
); );
} }
getProcessStorageFolderTask(appName: string, taskId: string): Observable<ProcessStorageCloudModel> { getProcessStorageFolderTask(appName: string, taskId: string, processInstanceId: string): Observable<ProcessStorageCloudModel> {
const apiUrl = this.buildFolderTask(appName, taskId); const apiUrl = this.buildFolderTask(appName, taskId, processInstanceId);
return from(this.apiService return from(this.apiService
.getInstance() .getInstance()
.oauth2Auth.callCustomApi(apiUrl, 'GET', .oauth2Auth.callCustomApi(apiUrl, 'GET',
@ -218,9 +221,9 @@ export class FormCloudService extends BaseCloudService {
this.apiService this.apiService
.getInstance() .getInstance()
.oauth2Auth.callCustomApi( .oauth2Auth.callCustomApi(
apiUrl, 'GET', pathParams, queryParams, apiUrl, 'GET', pathParams, queryParams,
headerParams, formParams, bodyParam, headerParams, formParams, bodyParam,
this.contentTypes, this.accepts, this.returnType, null, null) this.contentTypes, this.accepts, this.returnType, null, null)
).pipe( ).pipe(
catchError((err) => this.handleError(err)) catchError((err) => this.handleError(err))
); );
@ -290,8 +293,8 @@ export class FormCloudService extends BaseCloudService {
return `${this.getBasePath(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, processInstanceId: string): string {
return `${this.getBasePath(appName)}/process-storage/v1/folders/tasks/${taskId}`; return `${this.getBasePath(appName)}/process-storage/v1/folders/${processInstanceId}/${taskId}`;
} }
private handleError(error: any) { private handleError(error: any) {

View File

@ -1,15 +1,16 @@
<div *ngIf="!loading; else loadingTemplate"> <div *ngIf="!loading; else loadingTemplate">
<adf-cloud-form *ngIf="hasForm(); else withoutForm" <adf-cloud-form *ngIf="hasForm(); else withoutForm"
[appName]="appName" [appName]="appName"
[taskId]="taskId" [taskId]="taskId"
[readOnly]="isReadOnly()" [processInstanceId]="taskDetails.processInstanceId"
[showRefreshButton]="showRefreshButton" [readOnly]="isReadOnly()"
[showValidationIcon]="showValidationIcon" [showRefreshButton]="showRefreshButton"
[showCompleteButton]="canCompleteTask()" [showValidationIcon]="showValidationIcon"
[showSaveButton]="canCompleteTask()" [showCompleteButton]="canCompleteTask()"
(formSaved)="onFormSaved($event)" [showSaveButton]="canCompleteTask()"
(formCompleted)="onFormCompleted($event)" (formSaved)="onFormSaved($event)"
(formError)="onError($event)"> (formCompleted)="onFormCompleted($event)"
(formError)="onError($event)">
<adf-cloud-form-custom-outcomes> <adf-cloud-form-custom-outcomes>
<ng-template [ngTemplateOutlet]="taskFormCloudButtons"> <ng-template [ngTemplateOutlet]="taskFormCloudButtons">
</ng-template> </ng-template>
@ -40,7 +41,8 @@
<mat-card-actions class="adf-task-form-actions"> <mat-card-actions class="adf-task-form-actions">
<ng-template [ngTemplateOutlet]="taskFormCloudButtons"> <ng-template [ngTemplateOutlet]="taskFormCloudButtons">
</ng-template> </ng-template>
<button mat-button *ngIf="canCompleteTask()" adf-cloud-complete-task [appName]="appName" [taskId]="taskId" (success)="onCompleteTask()" color="primary"> <button mat-button *ngIf="canCompleteTask()" adf-cloud-complete-task [appName]="appName"
[taskId]="taskId" (success)="onCompleteTask()" color="primary">
{{'ADF_CLOUD_TASK_FORM.EMPTY_FORM.BUTTONS.COMPLETE' | translate}} {{'ADF_CLOUD_TASK_FORM.EMPTY_FORM.BUTTONS.COMPLETE' | translate}}
</button> </button>
</mat-card-actions> </mat-card-actions>
@ -50,10 +52,12 @@
<button mat-button *ngIf="showCancelButton" id="adf-cloud-cancel-task" (click)="onCancelClick()"> <button mat-button *ngIf="showCancelButton" id="adf-cloud-cancel-task" (click)="onCancelClick()">
{{'ADF_CLOUD_TASK_FORM.EMPTY_FORM.BUTTONS.CANCEL' | translate}} {{'ADF_CLOUD_TASK_FORM.EMPTY_FORM.BUTTONS.CANCEL' | translate}}
</button> </button>
<button mat-button *ngIf="canClaimTask()" adf-cloud-claim-task [appName]="appName" [taskId]="taskId" (success)="onClaimTask()"> <button mat-button *ngIf="canClaimTask()" adf-cloud-claim-task [appName]="appName" [taskId]="taskId"
(success)="onClaimTask()">
{{'ADF_CLOUD_TASK_FORM.EMPTY_FORM.BUTTONS.CLAIM' | translate}} {{'ADF_CLOUD_TASK_FORM.EMPTY_FORM.BUTTONS.CLAIM' | translate}}
</button> </button>
<button mat-button *ngIf="canUnclaimTask()" adf-cloud-unclaim-task [appName]="appName" [taskId]="taskId" (success)="onUnclaimTask()"> <button mat-button *ngIf="canUnclaimTask()" adf-cloud-unclaim-task [appName]="appName" [taskId]="taskId"
(success)="onUnclaimTask()">
{{'ADF_CLOUD_TASK_FORM.EMPTY_FORM.BUTTONS.UNCLAIM' | translate}} {{'ADF_CLOUD_TASK_FORM.EMPTY_FORM.BUTTONS.UNCLAIM' | translate}}
</button> </button>
</ng-template> </ng-template>

View File

@ -96,13 +96,13 @@ export class TaskFormCloudComponent implements OnChanges {
constructor( constructor(
private taskCloudService: TaskCloudService, private taskCloudService: TaskCloudService,
private formRenderingService: FormRenderingService) { private formRenderingService: FormRenderingService) {
this.formRenderingService.setComponentTypeResolver('upload', () => UploadCloudWidgetComponent, true); this.formRenderingService.setComponentTypeResolver('upload', () => UploadCloudWidgetComponent, true);
this.formRenderingService.setComponentTypeResolver('dropdown', () => DropdownCloudWidgetComponent, true); this.formRenderingService.setComponentTypeResolver('dropdown', () => DropdownCloudWidgetComponent, true);
} }
ngOnChanges(changes: SimpleChanges) { ngOnChanges(changes: SimpleChanges) {
const appName = changes['appName']; const appName = changes['appName'];
if (appName && (appName.currentValue || appName.currentValue === '' ) && this.taskId) { if (appName && (appName.currentValue || appName.currentValue === '') && this.taskId) {
this.loadTask(); this.loadTask();
return; return;
} }