diff --git a/docs/docassets/images/form-custom-outcomes.component.png b/docs/docassets/images/form-custom-outcomes.component.png new file mode 100644 index 0000000000..196445c22c Binary files /dev/null and b/docs/docassets/images/form-custom-outcomes.component.png differ diff --git a/docs/process-services-cloud/directives/claim-task.directive.md b/docs/process-services-cloud/directives/claim-task-cloud.directive.md similarity index 58% rename from docs/process-services-cloud/directives/claim-task.directive.md rename to docs/process-services-cloud/directives/claim-task-cloud.directive.md index c1a8dba857..b0e2ac335e 100644 --- a/docs/process-services-cloud/directives/claim-task.directive.md +++ b/docs/process-services-cloud/directives/claim-task-cloud.directive.md @@ -1,18 +1,18 @@ --- -Title: Claim Task Directive -Added: v3.1.0 +Title: Claim Task Cloud Directive +Added: v3.9.0 Status: Experimental -Last reviewed: 2019-03-25 +Last reviewed: 2020-06-09 --- -# [Claim task directive](../../../lib/process-services-cloud/src/lib/task/directives/claim-task.directive.ts "Defined in claim-task.directive.ts") +# [Claim task Cloud directive](../../../lib/process-services-cloud/src/lib/task/directives/claim-task-cloud.directive.ts "Defined in claim-task-cloud.directive.ts") Claims a task ## Basic Usage ```html - + ``` ## Class members @@ -22,7 +22,7 @@ Claims a task | Name | Type | Default value | Description | | ---- | ---- | ------------- | ----------- | | appName | `string` | "" | (Required) The name of the application. | -| taskId | `string` | | (Required) The id of the task. | +| taskId | `string` | "" | (Required) The id of the task. | ### Events diff --git a/docs/process-services-cloud/directives/unclaim-task-cloud.directive.md b/docs/process-services-cloud/directives/unclaim-task-cloud.directive.md new file mode 100644 index 0000000000..7c32de34c2 --- /dev/null +++ b/docs/process-services-cloud/directives/unclaim-task-cloud.directive.md @@ -0,0 +1,32 @@ +--- +Title: Unclaim Task Cloud Directive +Added: v3.9.0 +Status: Experimental +Last reviewed: 2020-06-09 +--- + +# [Unclaim Task Cloud directive](../../../lib/process-services-cloud/src/lib/task/directives/unclaim-task-cloud.directive.ts "Defined in unclaim-task-cloud.directive.ts") + +Unclaims a task + +## Basic Usage + +```html + +``` + +## Class members + +### Properties + +| Name | Type | Default value | Description | +| ---- | ---- | ------------- | ----------- | +| appName | `string` | "" | (Required) The name of the application. | +| taskId | `string` | "" | (Required) The id of the task. | + +### Events + +| Name | Type | Description | +| ---- | ---- | ----------- | +| error | [`EventEmitter`](https://angular.io/api/core/EventEmitter)`` | Emitted when the task cannot be completed. | +| success | [`EventEmitter`](https://angular.io/api/core/EventEmitter)`` | Emitted when the task is completed. | diff --git a/docs/process-services/components/form-custom-outcome.component.md b/docs/process-services/components/form-custom-outcome.component.md new file mode 100644 index 0000000000..b7a7e867bf --- /dev/null +++ b/docs/process-services/components/form-custom-outcome.component.md @@ -0,0 +1,34 @@ +--- +Title: Form custom outcomes component +Added: v3.9.0 +Status: Active +Last reviewed: 2020-06-09 +--- + +# [Form custom outcomes component](../../../lib/process-services/src/lib/form/form-custom-outcomes.component.ts "Defined in form-custom-outcomes.component.ts") + +Supplies custom outcome buttons to be included in [Form component](form.component.md). + +![](../../docassets/images/form-custom-outcomes.component.png) + +## Basic Usage + +```html + + + + + + + +``` + +## See Also + +- [Form component](form.component.md) diff --git a/docs/process-services/components/task-form.component.md b/docs/process-services/components/task-form.component.md index 099bc1f2d0..8f1fe3c599 100644 --- a/docs/process-services/components/task-form.component.md +++ b/docs/process-services/components/task-form.component.md @@ -47,6 +47,8 @@ Shows a [`form`](../../../lib/process-services/src/lib/task-list/models/form.mod | formLoaded | [`EventEmitter`](https://angular.io/api/core/EventEmitter)`<`[`FormModel`](../../../lib/core/form/components/widgets/core/form.model.ts)`>` | Emitted when the form is loaded or reloaded. | | formSaved | [`EventEmitter`](https://angular.io/api/core/EventEmitter)`<`[`FormModel`](../../../lib/core/form/components/widgets/core/form.model.ts)`>` | Emitted when the form is submitted with the `Save` or custom outcomes. | | showAttachForm | [`EventEmitter`](https://angular.io/api/core/EventEmitter)`` | Emitted when the form associated with the form task is attached. | +| taskClaimed | [`EventEmitter`](https://angular.io/api/core/EventEmitter)`` | Emitted when the task is claimed. | +| taskUnclaimed | [`EventEmitter`](https://angular.io/api/core/EventEmitter)`` | Emitted when the task is unclaimed (ie, requeued). | ## See also diff --git a/docs/process-services/components/task-header.component.md b/docs/process-services/components/task-header.component.md index 59fcdb44f6..f8927caadb 100644 --- a/docs/process-services/components/task-header.component.md +++ b/docs/process-services/components/task-header.component.md @@ -27,6 +27,7 @@ Shows all the information related to a task. | ---- | ---- | ------------- | ----------- | | formName | `string` | null | The name of the form. | | taskDetails | [`TaskDetailsModel`](../../../lib/process-services/src/lib/task-list/models/task-details.model.ts) | | (required) Details related to the task. | +| showClaimRelease | `boolean` | true | Toggles display of the claim/release button. | ### Events diff --git a/docs/process-services/directives/claim-task.directive.md b/docs/process-services/directives/claim-task.directive.md new file mode 100644 index 0000000000..c6ca70f042 --- /dev/null +++ b/docs/process-services/directives/claim-task.directive.md @@ -0,0 +1,31 @@ +--- +Title: Claim Task Directive +Added: v3.9.0 +Status: Experimental +Last reviewed: 2020-06-09 +--- + +# [Claim task directive](../../../lib/process-services/src/lib/task-list/components/task-form/claim-task.directive.ts "Defined in claim-task.directive.ts") + +Claims a task + +## Basic Usage + +```html + +``` + +## Class members + +### Properties + +| Name | Type | Default value | Description | +| ---- | ---- | ------------- | ----------- | +| taskId | `string` | "" | (Required) The id of the task. | + +### Events + +| Name | Type | Description | +| ---- | ---- | ----------- | +| error | [`EventEmitter`](https://angular.io/api/core/EventEmitter)`` | Emitted when the task cannot be completed. | +| success | [`EventEmitter`](https://angular.io/api/core/EventEmitter)`` | Emitted when the task is completed. | diff --git a/docs/process-services-cloud/directives/unclaim-task.directive.md b/docs/process-services/directives/unclaim-task.directive.md similarity index 62% rename from docs/process-services-cloud/directives/unclaim-task.directive.md rename to docs/process-services/directives/unclaim-task.directive.md index 75d0c576f6..d6ba50ebb1 100644 --- a/docs/process-services-cloud/directives/unclaim-task.directive.md +++ b/docs/process-services/directives/unclaim-task.directive.md @@ -1,18 +1,18 @@ --- Title: Unclaim Task Directive -Added: v3.1.0 +Added: v3.9.0 Status: Experimental -Last reviewed: 2019-03-25 +Last reviewed: 2020-06-09 --- -# [Unclaim task directive](../../../lib/process-services-cloud/src/lib/task/directives/unclaim-task.directive.ts "Defined in unclaim-task.directive.ts") +# [Unclaim Task directive](../../../lib/process-services/src/lib/task-list/components/task-form/unclaim-task.directive.ts "Defined in unclaim-task.directive.ts") Unclaims a task ## Basic Usage ```html - + ``` ## Class members @@ -21,8 +21,7 @@ Unclaims a task | Name | Type | Default value | Description | | ---- | ---- | ------------- | ----------- | -| appName | `string` | "" | (Required) The name of the application. | -| taskId | `string` | | (Required) The id of the task. | +| taskId | `string` | "" | (Required) The id of the task. | ### Events diff --git a/lib/process-services-cloud/src/lib/task/directives/claim-task.directive.spec.ts b/lib/process-services-cloud/src/lib/task/directives/claim-task-cloud.directive.spec.ts similarity index 88% rename from lib/process-services-cloud/src/lib/task/directives/claim-task.directive.spec.ts rename to lib/process-services-cloud/src/lib/task/directives/claim-task-cloud.directive.spec.ts index a02d7b522a..70414451e1 100644 --- a/lib/process-services-cloud/src/lib/task/directives/claim-task.directive.spec.ts +++ b/lib/process-services-cloud/src/lib/task/directives/claim-task-cloud.directive.spec.ts @@ -19,12 +19,12 @@ import { ComponentFixture, TestBed } from '@angular/core/testing'; import { setupTestBed } from '@alfresco/adf-core'; import { TaskCloudService } from '../services/task-cloud.service'; import { of } from 'rxjs'; -import { ClaimTaskDirective } from './claim-task.directive'; +import { ClaimTaskCloudDirective } from './claim-task-cloud.directive'; import { taskClaimCloudMock } from '../task-header/mocks/fake-claim-task.mock'; import { ProcessServiceCloudTestingModule } from '../../testing/process-service-cloud.testing.module'; import { TranslateModule } from '@ngx-translate/core'; -describe('ClaimTaskDirective', () => { +describe('ClaimTaskCloudDirective', () => { @Component({ selector: 'adf-cloud-claim-test-component', @@ -35,8 +35,8 @@ describe('ClaimTaskDirective', () => { taskMock = 'test1234'; appNameMock = 'simple-app'; - @ViewChild(ClaimTaskDirective) - claimTaskDirective: ClaimTaskDirective; + @ViewChild(ClaimTaskCloudDirective) + claimTaskDirective: ClaimTaskCloudDirective; } let fixture: ComponentFixture; @@ -78,8 +78,8 @@ describe('Claim Task Directive validation errors', () => { appNameUndefined = undefined; appNameNull = null; - @ContentChildren(ClaimTaskDirective) - claimTaskValidationDirective: ClaimTaskDirective; + @ContentChildren(ClaimTaskCloudDirective) + claimTaskValidationDirective: ClaimTaskCloudDirective; } @Component({ @@ -90,8 +90,8 @@ describe('Claim Task Directive validation errors', () => { appName = 'simple-app'; - @ContentChildren(ClaimTaskDirective) - claimTaskValidationDirective: ClaimTaskDirective; + @ContentChildren(ClaimTaskCloudDirective) + claimTaskValidationDirective: ClaimTaskCloudDirective; } @Component({ @@ -103,8 +103,8 @@ describe('Claim Task Directive validation errors', () => { appNameUndefined = undefined; taskMock = 'test1234'; - @ContentChildren(ClaimTaskDirective) - claimTaskValidationDirective: ClaimTaskDirective; + @ContentChildren(ClaimTaskCloudDirective) + claimTaskValidationDirective: ClaimTaskCloudDirective; } @Component({ @@ -116,8 +116,8 @@ describe('Claim Task Directive validation errors', () => { appNameNull = null; taskMock = 'test1234'; - @ViewChild(ClaimTaskDirective) - claimTaskValidationDirective: ClaimTaskDirective; + @ViewChild(ClaimTaskCloudDirective) + claimTaskValidationDirective: ClaimTaskCloudDirective; } let fixture: ComponentFixture; diff --git a/lib/process-services-cloud/src/lib/task/directives/claim-task.directive.ts b/lib/process-services-cloud/src/lib/task/directives/claim-task-cloud.directive.ts similarity index 97% rename from lib/process-services-cloud/src/lib/task/directives/claim-task.directive.ts rename to lib/process-services-cloud/src/lib/task/directives/claim-task-cloud.directive.ts index c106285f7c..1fc45e062c 100644 --- a/lib/process-services-cloud/src/lib/task/directives/claim-task.directive.ts +++ b/lib/process-services-cloud/src/lib/task/directives/claim-task-cloud.directive.ts @@ -22,7 +22,7 @@ import { TaskCloudService } from '../services/task-cloud.service'; // tslint:disable-next-line: directive-selector selector: '[adf-cloud-claim-task]' }) -export class ClaimTaskDirective implements OnInit { +export class ClaimTaskCloudDirective implements OnInit { /** (Required) The id of the task. */ @Input() diff --git a/lib/process-services-cloud/src/lib/task/directives/public-api.ts b/lib/process-services-cloud/src/lib/task/directives/public-api.ts index 86f452a53e..bbf339e8d6 100644 --- a/lib/process-services-cloud/src/lib/task/directives/public-api.ts +++ b/lib/process-services-cloud/src/lib/task/directives/public-api.ts @@ -15,8 +15,8 @@ * limitations under the License. */ -export * from './claim-task.directive'; -export * from './unclaim-task.directive'; +export * from './claim-task-cloud.directive'; +export * from './unclaim-task-cloud.directive'; export * from './complete-task.directive'; export * from './task-directive.module'; diff --git a/lib/process-services-cloud/src/lib/task/directives/task-directive.module.ts b/lib/process-services-cloud/src/lib/task/directives/task-directive.module.ts index 50aad9c624..632774f6a5 100644 --- a/lib/process-services-cloud/src/lib/task/directives/task-directive.module.ts +++ b/lib/process-services-cloud/src/lib/task/directives/task-directive.module.ts @@ -17,19 +17,19 @@ import { NgModule } from '@angular/core'; import { CompleteTaskDirective } from './complete-task.directive'; -import { ClaimTaskDirective } from './claim-task.directive'; -import { UnClaimTaskDirective } from './unclaim-task.directive'; +import { ClaimTaskCloudDirective } from './claim-task-cloud.directive'; +import { UnClaimTaskCloudDirective } from './unclaim-task-cloud.directive'; @NgModule({ declarations: [ CompleteTaskDirective, - ClaimTaskDirective, - UnClaimTaskDirective + ClaimTaskCloudDirective, + UnClaimTaskCloudDirective ], exports: [ CompleteTaskDirective, - ClaimTaskDirective, - UnClaimTaskDirective + ClaimTaskCloudDirective, + UnClaimTaskCloudDirective ] }) export class TaskDirectiveModule { } diff --git a/lib/process-services-cloud/src/lib/task/directives/unclaim-tast.directive.spec.ts b/lib/process-services-cloud/src/lib/task/directives/unclaim-task-cloud.directive.spec.ts similarity index 87% rename from lib/process-services-cloud/src/lib/task/directives/unclaim-tast.directive.spec.ts rename to lib/process-services-cloud/src/lib/task/directives/unclaim-task-cloud.directive.spec.ts index c47eff2d9c..1ce43ac148 100644 --- a/lib/process-services-cloud/src/lib/task/directives/unclaim-tast.directive.spec.ts +++ b/lib/process-services-cloud/src/lib/task/directives/unclaim-task-cloud.directive.spec.ts @@ -19,12 +19,12 @@ import { ComponentFixture, TestBed } from '@angular/core/testing'; import { setupTestBed } from '@alfresco/adf-core'; import { TaskCloudService } from '../services/task-cloud.service'; import { of } from 'rxjs'; -import { UnClaimTaskDirective } from './unclaim-task.directive'; +import { UnClaimTaskCloudDirective } from './unclaim-task-cloud.directive'; import { taskClaimCloudMock } from '../task-header/mocks/fake-claim-task.mock'; import { ProcessServiceCloudTestingModule } from '../../testing/process-service-cloud.testing.module'; import { TranslateModule } from '@ngx-translate/core'; -describe('UnClaimTaskDirective', () => { +describe('UnClaimTaskCloudDirective', () => { @Component({ selector: 'adf-cloud-test-component', @@ -35,8 +35,8 @@ describe('UnClaimTaskDirective', () => { appName = 'simple-app'; taskIdMock = '1234'; - @ContentChildren(UnClaimTaskDirective) - unclaimTaskDirective: UnClaimTaskDirective; + @ContentChildren(UnClaimTaskCloudDirective) + unclaimTaskDirective: UnClaimTaskCloudDirective; } let fixture: ComponentFixture; @@ -78,8 +78,8 @@ describe('UnClaim Task Directive validation errors', () => { appNameUndefined = undefined; appNameNull = null; - @ContentChildren(UnClaimTaskDirective) - claimTaskValidationDirective: UnClaimTaskDirective; + @ContentChildren(UnClaimTaskCloudDirective) + claimTaskValidationDirective: UnClaimTaskCloudDirective; } @Component({ @@ -90,8 +90,8 @@ describe('UnClaim Task Directive validation errors', () => { appName = 'simple-app'; - @ContentChildren(UnClaimTaskDirective) - claimTaskValidationDirective: UnClaimTaskDirective; + @ContentChildren(UnClaimTaskCloudDirective) + claimTaskValidationDirective: UnClaimTaskCloudDirective; } @Component({ @@ -103,8 +103,8 @@ describe('UnClaim Task Directive validation errors', () => { appNameUndefined = undefined; taskMock = 'test1234'; - @ContentChildren(UnClaimTaskDirective) - claimTaskValidationDirective: UnClaimTaskDirective; + @ContentChildren(UnClaimTaskCloudDirective) + claimTaskValidationDirective: UnClaimTaskCloudDirective; } @Component({ @@ -116,8 +116,8 @@ describe('UnClaim Task Directive validation errors', () => { appNameNull = null; taskMock = 'test1234'; - @ViewChild(UnClaimTaskDirective) - claimTaskValidationDirective: UnClaimTaskDirective; + @ViewChild(UnClaimTaskCloudDirective) + claimTaskValidationDirective: UnClaimTaskCloudDirective; } let fixture: ComponentFixture; diff --git a/lib/process-services-cloud/src/lib/task/directives/unclaim-task.directive.ts b/lib/process-services-cloud/src/lib/task/directives/unclaim-task-cloud.directive.ts similarity index 97% rename from lib/process-services-cloud/src/lib/task/directives/unclaim-task.directive.ts rename to lib/process-services-cloud/src/lib/task/directives/unclaim-task-cloud.directive.ts index 0e5ffc68f4..8897122541 100644 --- a/lib/process-services-cloud/src/lib/task/directives/unclaim-task.directive.ts +++ b/lib/process-services-cloud/src/lib/task/directives/unclaim-task-cloud.directive.ts @@ -21,7 +21,7 @@ import { TaskCloudService } from '../services/task-cloud.service'; // tslint:disable-next-line: directive-selector selector: '[adf-cloud-unclaim-task]' }) -export class UnClaimTaskDirective implements OnInit { +export class UnClaimTaskCloudDirective implements OnInit { /** (Required) The id of the task. */ @Input() diff --git a/lib/process-services/src/lib/form/form-custom-outcomes.component.ts b/lib/process-services/src/lib/form/form-custom-outcomes.component.ts new file mode 100644 index 0000000000..0af452b08d --- /dev/null +++ b/lib/process-services/src/lib/form/form-custom-outcomes.component.ts @@ -0,0 +1,24 @@ +/*! + * @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 } from '@angular/core'; + +@Component({ + selector: 'adf-form-custom-outcomes', + template: '' +}) +export class FormCustomOutcomesComponent {} diff --git a/lib/process-services/src/lib/form/form.component.html b/lib/process-services/src/lib/form/form.component.html index 5088c2c255..a0a27660c2 100644 --- a/lib/process-services/src/lib/form/form.component.html +++ b/lib/process-services/src/lib/form/form.component.html @@ -34,6 +34,7 @@ + + + + ` +}) + +class FormWithCustomOutComesComponent { + + @ViewChild('adfForm') + adfForm: FormComponent; + + onCustomButtonOneClick() { } + onCustomButtonTwoClick() { } +} + +describe('FormWithCustomOutComesComponent', () => { + + let fixture: ComponentFixture; + let customComponent: FormWithCustomOutComesComponent; + let debugElement: DebugElement; + + setupTestBed({ + imports: [ + TranslateModule.forRoot(), + ProcessTestingModule + ], + declarations: [FormWithCustomOutComesComponent] + }); + + beforeEach(() => { + fixture = TestBed.createComponent(FormWithCustomOutComesComponent); + customComponent = fixture.componentInstance; + debugElement = fixture.debugElement; + const formRepresentation = { + fields: [ + { id: 'container1' } + ], + outcomes: [ + { id: 'outcome-1', name: 'outcome 1' } + ] + }; + + const form = new FormModel(formRepresentation); + customComponent.adfForm.form = form; + fixture.detectChanges(); + }); + + afterEach(() => { + fixture.destroy(); + }); + + it('should be able to inject custom outcomes and click on custom outcomes', () => { + const onCustomButtonOneSpy = spyOn(customComponent, 'onCustomButtonOneClick').and.callThrough(); + const buttonOneBtn = debugElement.query(By.css('#adf-custom-outcome-1')); + const buttonTwoBtn = debugElement.query(By.css('#adf-custom-outcome-2')); + + expect(buttonOneBtn).not.toBeNull(); + expect(buttonTwoBtn).not.toBeNull(); + + buttonOneBtn.nativeElement.click(); + + expect(onCustomButtonOneSpy).toHaveBeenCalled(); + expect(buttonOneBtn.nativeElement.innerText).toBe('CUSTOM-BUTTON-1'); + expect(buttonTwoBtn.nativeElement.innerText).toBe('CUSTOM-BUTTON-2'); + }); +}); diff --git a/lib/process-services/src/lib/form/form.module.ts b/lib/process-services/src/lib/form/form.module.ts index ac1d490143..17e7bf49cb 100644 --- a/lib/process-services/src/lib/form/form.module.ts +++ b/lib/process-services/src/lib/form/form.module.ts @@ -20,6 +20,7 @@ import { MaterialModule } from '../material.module'; import { CoreModule } from '@alfresco/adf-core'; import { FormComponent } from './form.component'; import { StartFormComponent } from './start-form.component'; +import { FormCustomOutcomesComponent } from './form-custom-outcomes.component'; @NgModule({ imports: [ @@ -28,11 +29,13 @@ import { StartFormComponent } from './start-form.component'; ], declarations: [ FormComponent, - StartFormComponent + StartFormComponent, + FormCustomOutcomesComponent ], exports: [ FormComponent, - StartFormComponent + StartFormComponent, + FormCustomOutcomesComponent ] }) export class FormModule {} diff --git a/lib/process-services/src/lib/form/public-api.ts b/lib/process-services/src/lib/form/public-api.ts index 58d4813277..d16c7c3488 100644 --- a/lib/process-services/src/lib/form/public-api.ts +++ b/lib/process-services/src/lib/form/public-api.ts @@ -18,4 +18,5 @@ export * from './form.component'; export * from './start-form.component'; export * from './process-form-rendering.service'; +export * from './form-custom-outcomes.component'; export * from './form.module'; diff --git a/lib/process-services/src/lib/task-list/components/task-details.component.html b/lib/process-services/src/lib/task-list/components/task-details.component.html index a8c352a037..42a187fd61 100644 --- a/lib/process-services/src/lib/task-list/components/task-details.component.html +++ b/lib/process-services/src/lib/task-list/components/task-details.component.html @@ -35,6 +35,8 @@ (completed)="onComplete()" (showAttachForm)="onShowAttachForm()" (executeOutcome)='onFormExecuteOutcome($event)' + (taskClaimed)="onClaimAction($event)" + (taskUnclaimed)="onUnclaimAction($event)" (error)="onFormError($event)" #activitiTaskForm> { + + @Component({ + selector: 'adf-claim-test-component', + template: '' + }) + class TestComponent { + taskId = 'test1234'; + @Output() + claim: EventEmitter = new EventEmitter(); + + onClaim(event) { + this.claim.emit(event); + } + } + + let fixture: ComponentFixture; + let taskListService: TaskListService; + + setupTestBed({ + imports: [ + ProcessTestingModule + ], + declarations: [ + TestComponent + ] + }); + + beforeEach(() => { + taskListService = TestBed.get(TaskListService); + fixture = TestBed.createComponent(TestComponent); + fixture.detectChanges(); + }); + + it('Should be able to call claim task service', () => { + const claimTaskSpy = spyOn(taskListService, 'claimTask').and.returnValue(of({})); + + const button = fixture.nativeElement.querySelector('button'); + button.click(); + + expect(claimTaskSpy).toHaveBeenCalledWith(fixture.componentInstance.taskId); + }); + + it('Should be able to catch success event on click of claim button', async() => { + spyOn(taskListService, 'claimTask').and.returnValue(of({})); + const unclaimSpy = spyOn(fixture.componentInstance.claim, 'emit'); + + const button = fixture.nativeElement.querySelector('button'); + button.click(); + fixture.detectChanges(); + await fixture.whenStable(); + + expect(unclaimSpy).toHaveBeenCalledWith(fixture.componentInstance.taskId); + }); +}); + +describe('Claim Task Directive validation errors', () => { + + @Component({ + selector: 'adf-claim-no-fields-validation-component', + template: '' + }) + class ClaimTestMissingInputDirectiveComponent { } + + @Component({ + selector: 'adf-claim-no-taskid-validation-component', + template: '' + }) + class ClaimTestMissingTaskIdDirectiveComponent { } + + let fixture: ComponentFixture; + + setupTestBed({ + imports: [ + ProcessTestingModule + ], + declarations: [ + ClaimTestMissingTaskIdDirectiveComponent, + ClaimTestMissingInputDirectiveComponent + ] + }); + + beforeEach(() => { + fixture = TestBed.createComponent(ClaimTestMissingInputDirectiveComponent); + }); + + it('should throw error when missing input', () => { + fixture = TestBed.createComponent(ClaimTestMissingInputDirectiveComponent); + + expect(() => fixture.detectChanges()).toThrowError(); + }); + + it('should throw error when taskId is not set', () => { + fixture = TestBed.createComponent(ClaimTestMissingTaskIdDirectiveComponent); + + expect( () => fixture.detectChanges()).toThrowError('Attribute taskId is required'); + }); +}); diff --git a/lib/process-services/src/lib/task-list/components/task-form/claim-task.directive.ts b/lib/process-services/src/lib/task-list/components/task-form/claim-task.directive.ts new file mode 100644 index 0000000000..d2bdcd7ffa --- /dev/null +++ b/lib/process-services/src/lib/task-list/components/task-form/claim-task.directive.ts @@ -0,0 +1,89 @@ +/*! + * @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, + Output, + EventEmitter, + HostListener +} from '@angular/core'; +import { TaskListService } from '../../services/tasklist.service'; +import { LogService } from '@alfresco/adf-core'; + +@Directive({ + // tslint:disable-next-line: directive-selector + selector: '[adf-claim-task]' +}) +export class ClaimTaskDirective { + /** (Required) The id of the task. */ + @Input() + taskId: string; + + /** Emitted when the task is claimed. */ + @Output() + success: EventEmitter = new EventEmitter(); + + /** Emitted when the task cannot be claimed. */ + @Output() + error: EventEmitter = new EventEmitter(); + + invalidParams: string[] = []; + + constructor( + private taskListService: TaskListService, + private logService: LogService) {} + + ngOnInit() { + this.validateInputs(); + } + + validateInputs() { + if (!this.isTaskValid()) { + this.invalidParams.push('taskId'); + } + + if (this.invalidParams.length) { + throw new Error( + `Attribute ${this.invalidParams.join(', ')} is required` + ); + } + } + + isTaskValid(): boolean { + return this.taskId && this.taskId.length > 0; + } + + @HostListener('click') + async onClick() { + try { + this.claimTask(); + } catch (error) { + this.error.emit(error); + } + } + + private async claimTask() { + await this.taskListService.claimTask(this.taskId).subscribe( + () => { + this.logService.info('Task claimed'); + this.success.emit(this.taskId); + }, + error => this.error.emit(error) + ); + } +} diff --git a/lib/process-services/src/lib/task-list/components/task-form/task-form.component.html b/lib/process-services/src/lib/task-list/components/task-form/task-form.component.html index b51dec7261..3ba824ba04 100644 --- a/lib/process-services/src/lib/task-list/components/task-form/task-form.component.html +++ b/lib/process-services/src/lib/task-list/components/task-form/task-form.component.html @@ -16,6 +16,10 @@ (formError)='onFormError($event)' (error)='onError($event)' (executeOutcome)='onFormExecuteOutcome($event)'> + + + + + @@ -66,6 +71,23 @@ + + + + +
diff --git a/lib/process-services/src/lib/task-list/components/task-form/task-form.component.spec.ts b/lib/process-services/src/lib/task-list/components/task-form/task-form.component.spec.ts index d109016e1a..a14c149544 100644 --- a/lib/process-services/src/lib/task-list/components/task-form/task-form.component.spec.ts +++ b/lib/process-services/src/lib/task-list/components/task-form/task-form.component.spec.ts @@ -37,11 +37,15 @@ import { standaloneTaskWithoutForm, completedStandaloneTaskWithoutForm, claimableTaskDetailsMock, - initiatorCanCompleteTaskDetailsMock + initiatorCanCompleteTaskDetailsMock, + taskDetailsWithOutCandidateGroup, + claimedTaskDetailsMock, + claimedByGroupMemberMock } from '../../../mock/task/task-details.mock'; import { TaskDetailsModel } from '../../models/task-details.model'; import { ProcessTestingModule } from '../../../testing/process.testing.module'; import { TranslateModule } from '@ngx-translate/core'; +import { By } from '@angular/platform-browser'; describe('TaskFormComponent', () => { let component: TaskFormComponent; @@ -495,4 +499,125 @@ describe('TaskFormComponent', () => { expect(validationForm.textContent).toBe('check_circle'); }); }); + + describe('Claim/Unclaim buttons', () => { + + it('should display the claim button if no assignee', async() => { + getTaskDetailsSpy.and.returnValue(of(claimableTaskDetailsMock)); + + component.taskId = 'mock-task-id'; + fixture.detectChanges(); + await fixture.whenStable(); + + const claimButton = fixture.debugElement.query(By.css('[data-automation-id="adf-task-form-claim-button"]')); + expect(claimButton.nativeElement.innerText).toBe('ADF_TASK_LIST.DETAILS.BUTTON.CLAIM'); + }); + + it('should not display the claim/requeue button if the task is not claimable ', async() => { + getTaskDetailsSpy.and.returnValue(of(taskDetailsWithOutCandidateGroup)); + + component.taskId = 'mock-task-id'; + fixture.detectChanges(); + + await fixture.whenStable(); + const claimButton = fixture.debugElement.query(By.css('[data-automation-id="adf-task-form-claim-button"]')); + const unclaimButton = fixture.debugElement.query(By.css('[data-automation-id="adf-task-form-unclaim-button"]')); + + expect(component.isTaskClaimable()).toBe(false); + expect(component.isTaskClaimedByCandidateMember()).toBe(false); + expect(unclaimButton).toBeNull(); + expect(claimButton).toBeNull(); + }); + + it('should display the claim button if the task is claimable', async() => { + getTaskDetailsSpy.and.returnValue(of(claimableTaskDetailsMock)); + + component.taskId = 'mock-task-id'; + fixture.detectChanges(); + await fixture.whenStable(); + + const claimButton = fixture.debugElement.query(By.css('[data-automation-id="adf-task-form-claim-button"]')); + + expect(component.isTaskClaimable()).toBe(true); + expect(claimButton.nativeElement.innerText).toBe('ADF_TASK_LIST.DETAILS.BUTTON.CLAIM'); + }); + + it('should display the release button if task is claimed by the current logged-in user', async() => { + getBpmLoggedUserSpy.and.returnValue(of(claimedTaskDetailsMock.assignee)); + getTaskDetailsSpy.and.returnValue(of(claimedTaskDetailsMock)); + + component.taskId = 'mock-task-id'; + fixture.detectChanges(); + await fixture.whenStable(); + + const unclaimButton = fixture.debugElement.query(By.css('[data-automation-id="adf-task-form-unclaim-button"]')); + + expect(component.isTaskClaimedByCandidateMember()).toBe(true); + expect(unclaimButton.nativeElement.innerText).toBe('ADF_TASK_LIST.DETAILS.BUTTON.UNCLAIM'); + }); + + it('should not display the release button to logged in user if task is claimed by other candidate member', async() => { + getTaskDetailsSpy.and.returnValue(of(claimedByGroupMemberMock)); + + component.taskId = 'mock-task-id'; + fixture.detectChanges(); + await fixture.whenStable(); + + const unclaimButton = fixture.debugElement.query(By.css('[data-automation-id="adf-task-form-unclaim-button"]')); + + expect(component.isTaskClaimedByCandidateMember()).toBe(false); + expect(unclaimButton).toBeNull(); + }); + + it('should not display the release button if the task is completed', async() => { + getTaskDetailsSpy.and.returnValue(of(completedTaskDetailsMock)); + + component.taskId = 'mock-task-id'; + fixture.detectChanges(); + await fixture.whenStable(); + + const claimButton = fixture.debugElement.query(By.css('[data-automation-id="adf-task-form-claim-button"]')); + const unclaimButton = fixture.debugElement.query(By.css('[data-automation-id="adf-task-form-unclaim-button"]')); + + expect(claimButton).toBeNull(); + expect(unclaimButton).toBeNull(); + }); + + it('should emit taskClaimed when task is claimed', (done) => { + spyOn(taskListService, 'claimTask').and.returnValue(of({})); + getTaskDetailsSpy.and.returnValue(of(claimableTaskDetailsMock)); + + component.taskId = 'mock-task-id'; + + component.taskClaimed.subscribe((taskId) => { + expect(taskId).toEqual(component.taskId); + done(); + }); + + component.ngOnInit(); + fixture.detectChanges(); + + const claimBtn = fixture.debugElement.query(By.css('[adf-claim-task]')); + claimBtn.nativeElement.click(); + }); + + it('should emit taskUnClaimed when task is unclaimed', (done) => { + spyOn(taskListService, 'unclaimTask').and.returnValue(of({})); + getBpmLoggedUserSpy.and.returnValue(of(claimedTaskDetailsMock.assignee)); + getTaskDetailsSpy.and.returnValue(of(claimedTaskDetailsMock)); + + component.taskId = 'mock-task-id'; + + component.taskUnclaimed.subscribe((taskId: string) => { + expect(taskId).toEqual(component.taskId); + done(); + }); + + component.ngOnInit(); + fixture.detectChanges(); + + const unclaimBtn = fixture.debugElement.query(By.css('[adf-unclaim-task]')); + unclaimBtn.nativeElement.click(); + }); + }); }); diff --git a/lib/process-services/src/lib/task-list/components/task-form/task-form.component.ts b/lib/process-services/src/lib/task-list/components/task-form/task-form.component.ts index b53caf4ee3..77dca180fc 100644 --- a/lib/process-services/src/lib/task-list/components/task-form/task-form.component.ts +++ b/lib/process-services/src/lib/task-list/components/task-form/task-form.component.ts @@ -117,6 +117,14 @@ export class TaskFormComponent implements OnInit { @Output() cancel = new EventEmitter(); + /** Emitted when the task is claimed. */ + @Output() + taskClaimed = new EventEmitter(); + + /** Emitted when the task is unclaimed (ie, requeued).. */ + @Output() + taskUnclaimed = new EventEmitter(); + taskDetails: TaskDetailsModel; currentLoggedUser: UserRepresentation; loading: boolean = false; @@ -278,4 +286,28 @@ export class TaskFormComponent implements OnInit { getCompletedTaskTranslatedMessage(): Observable { return this.translationService.get('ADF_TASK_FORM.COMPLETED_TASK.TITLE', { taskName: this.taskDetails.name }); } + + isCandidateMember(): boolean { + return this.taskDetails.managerOfCandidateGroup || this.taskDetails.memberOfCandidateGroup || this.taskDetails.memberOfCandidateUsers; + } + + isTaskClaimable(): boolean { + return this.isCandidateMember() && !this.isAssigned(); + } + + isTaskClaimedByCandidateMember(): boolean { + return this.isCandidateMember() && this.isAssignedToMe() && !this.isCompletedTask(); + } + + reloadTask() { + this.loadTask(this.taskId); + } + + onClaimTask(taskId: string) { + this.taskClaimed.emit(taskId); + } + + onUnclaimTask(taskId: string) { + this.taskUnclaimed.emit(taskId); + } } diff --git a/lib/process-services/src/lib/task-list/components/task-form/unclaim-task.directive.spec.ts b/lib/process-services/src/lib/task-list/components/task-form/unclaim-task.directive.spec.ts new file mode 100644 index 0000000000..43bd1d48df --- /dev/null +++ b/lib/process-services/src/lib/task-list/components/task-form/unclaim-task.directive.spec.ts @@ -0,0 +1,126 @@ +/*! + * @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, Output, EventEmitter } from '@angular/core'; +import { ComponentFixture, TestBed } from '@angular/core/testing'; +import { setupTestBed } from '@alfresco/adf-core'; +import { of } from 'rxjs'; +import { TaskListService } from '../../services/tasklist.service'; +import { ProcessTestingModule } from '../../../testing/process.testing.module'; + +describe('UnclaimTaskDirective', () => { + + @Component({ + selector: 'adf-unclaim-test-component', + template: '' + }) + class TestComponent { + taskId = 'test1234'; + @Output() + unclaim: EventEmitter = new EventEmitter(); + + onUnclaim(event) { + this.unclaim.emit(event); + } + } + + let fixture: ComponentFixture; + let taskListService: TaskListService; + + setupTestBed({ + imports: [ + ProcessTestingModule + ], + declarations: [ + TestComponent + ] + }); + + beforeEach(() => { + taskListService = TestBed.get(TaskListService); + fixture = TestBed.createComponent(TestComponent); + fixture.detectChanges(); + }); + + it('Should be able to call unclaim task service', () => { + const claimTaskSpy = spyOn(taskListService, 'unclaimTask').and.returnValue(of({})); + + const button = fixture.nativeElement.querySelector('button'); + button.click(); + + expect(claimTaskSpy).toHaveBeenCalledWith(fixture.componentInstance.taskId); + }); + + it('Should be able to catch success event on click of unclaim button', async() => { + spyOn(taskListService, 'unclaimTask').and.returnValue(of({})); + const unclaimSpy = spyOn(fixture.componentInstance.unclaim, 'emit'); + + const button = fixture.nativeElement.querySelector('button'); + button.click(); + fixture.detectChanges(); + await fixture.whenStable(); + + expect(unclaimSpy).toHaveBeenCalledWith(fixture.componentInstance.taskId); + }); +}); + +describe('Claim Task Directive validation errors', () => { + + @Component({ + selector: 'adf-unclaim-no-fields-validation-component', + template: '' + }) + class ClaimTestMissingInputDirectiveComponent { + + } + + @Component({ + selector: 'adf-claim-no-taskid-validation-component', + template: '' + }) + class ClaimTestMissingTaskIdDirectiveComponent { + + } + + let fixture: ComponentFixture; + + setupTestBed({ + imports: [ + ProcessTestingModule + ], + declarations: [ + ClaimTestMissingTaskIdDirectiveComponent, + ClaimTestMissingInputDirectiveComponent + ] + }); + + beforeEach(() => { + fixture = TestBed.createComponent(ClaimTestMissingInputDirectiveComponent); + }); + + it('should throw error when missing input', () => { + fixture = TestBed.createComponent(ClaimTestMissingInputDirectiveComponent); + + expect(() => fixture.detectChanges()).toThrowError(); + }); + + it('should throw error when taskId is not set', () => { + fixture = TestBed.createComponent(ClaimTestMissingTaskIdDirectiveComponent); + + expect( () => fixture.detectChanges()).toThrowError('Attribute taskId is required'); + }); +}); diff --git a/lib/process-services/src/lib/task-list/components/task-form/unclaim-task.directive.ts b/lib/process-services/src/lib/task-list/components/task-form/unclaim-task.directive.ts new file mode 100644 index 0000000000..57f1812c0b --- /dev/null +++ b/lib/process-services/src/lib/task-list/components/task-form/unclaim-task.directive.ts @@ -0,0 +1,88 @@ +/*! + * @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, + HostListener, + Input, + Output, + EventEmitter +} from '@angular/core'; +import { TaskListService } from '../../services/tasklist.service'; +import { LogService } from '@alfresco/adf-core'; + +@Directive({ + // tslint:disable-next-line: directive-selector + selector: '[adf-unclaim-task]' +}) +export class UnclaimTaskDirective { + /** (Required) The id of the task. */ + @Input() + taskId: string; + + /** Emitted when the task is released. */ + @Output() + success: EventEmitter = new EventEmitter(); + + /** Emitted when the task cannot be released. */ + @Output() + error: EventEmitter = new EventEmitter(); + + invalidParams: string[] = []; + + constructor( + private taskListService: TaskListService, + private logService: LogService) {} + + ngOnInit() { + this.validateInputs(); + } + + validateInputs() { + if (!this.isTaskValid()) { + this.invalidParams.push('taskId'); + } + if (this.invalidParams.length) { + throw new Error( + `Attribute ${this.invalidParams.join(', ')} is required` + ); + } + } + + isTaskValid(): boolean { + return this.taskId && this.taskId.length > 0; + } + + @HostListener('click') + async onClick() { + try { + this.unclaimTask(); + } catch (error) { + this.error.emit(error); + } + } + + private async unclaimTask() { + await this.taskListService.unclaimTask(this.taskId).subscribe( + () => { + this.logService.info('Task unclaimed'); + this.success.emit(this.taskId); + }, + error => this.error.emit(error) + ); + } +} diff --git a/lib/process-services/src/lib/task-list/components/task-header.component.html b/lib/process-services/src/lib/task-list/components/task-header.component.html index 4246928719..d6c2879caf 100644 --- a/lib/process-services/src/lib/task-list/components/task-header.component.html +++ b/lib/process-services/src/lib/task-list/components/task-header.component.html @@ -3,10 +3,26 @@ - - - diff --git a/lib/process-services/src/lib/task-list/components/task-header.component.spec.ts b/lib/process-services/src/lib/task-list/components/task-header.component.spec.ts index fc5186dda7..e401bb3caa 100644 --- a/lib/process-services/src/lib/task-list/components/task-header.component.spec.ts +++ b/lib/process-services/src/lib/task-list/components/task-header.component.spec.ts @@ -136,6 +136,30 @@ describe('TaskHeaderComponent', () => { describe('Claiming', () => { + it('should be able display the claim/release button if showClaimRelease set to true', async(() => { + component.taskDetails = new TaskDetailsModel(claimableTaskDetailsMock); + component.showClaimRelease = true; + component.refreshData(); + fixture.detectChanges(); + + fixture.whenStable().then(() => { + const claimButton = fixture.debugElement.query(By.css('[data-automation-id="header-claim-button"]')); + expect(claimButton.nativeElement.innerText).toBe('ADF_TASK_LIST.DETAILS.BUTTON.CLAIM'); + }); + })); + + it('should not be able display the claim/release button if showClaimRelease set to false', async(() => { + component.taskDetails = new TaskDetailsModel(claimableTaskDetailsMock); + component.showClaimRelease = false; + component.refreshData(); + fixture.detectChanges(); + + fixture.whenStable().then(() => { + const claimButton = fixture.debugElement.query(By.css('[data-automation-id="header-claim-button"]')); + expect(claimButton).toBeNull(); + }); + })); + it('should display the claim button if no assignee', async(() => { component.taskDetails = new TaskDetailsModel(claimableTaskDetailsMock); @@ -227,38 +251,37 @@ describe('TaskHeaderComponent', () => { }); })); - it('should call the service unclaim method on un-claiming', async(() => { - spyOn(service, 'unclaimTask').and.returnValue(of(true)); - component.taskDetails = new TaskDetailsModel(claimedTaskDetailsMock); - component.refreshData(); + it('should emit claim event when task is claimed', (done) => { + spyOn(service, 'claimTask').and.returnValue(of({})); + component.taskDetails = claimableTaskDetailsMock; + + component.claim.subscribe((taskId) => { + expect(taskId).toEqual(component.taskDetails.id); + done(); + }); + + component.ngOnInit(); fixture.detectChanges(); - fixture.whenStable().then(() => { - const unclaimButton = fixture.debugElement.query(By.css('[data-automation-id="header-unclaim-button"]')); - unclaimButton.triggerEventHandler('click', {}); + const claimBtn = fixture.debugElement.query(By.css('[adf-claim-task]')); + claimBtn.nativeElement.click(); + }); - expect(service.unclaimTask).toHaveBeenCalledWith('91'); + it('should emit unclaim event when task is unclaimed', (done) => { + spyOn(service, 'unclaimTask').and.returnValue(of({})); + component.taskDetails = claimedTaskDetailsMock; + + component.unclaim.subscribe((taskId: string) => { + expect(taskId).toEqual(component.taskDetails.id); + done(); }); - })); - it('should trigger the unclaim event on successful un-claiming', async(() => { - let unclaimed: boolean = false; - spyOn(service, 'unclaimTask').and.returnValue(of(true)); - component.taskDetails = new TaskDetailsModel(claimedTaskDetailsMock); - component.refreshData(); + component.ngOnInit(); fixture.detectChanges(); - fixture.whenStable().then(() => { - component.unclaim.subscribe(() => { - unclaimed = true; - }); - - const unclaimButton = fixture.debugElement.query(By.css('[data-automation-id="header-unclaim-button"]')); - unclaimButton.triggerEventHandler('click', {}); - - expect(unclaimed).toBeTruthy(); - }); - })); + const unclaimBtn = fixture.debugElement.query(By.css('[adf-unclaim-task]')); + unclaimBtn.nativeElement.click(); + }); it('should display due date', async(() => { component.taskDetails.dueDate = new Date('2016-11-03'); diff --git a/lib/process-services/src/lib/task-list/components/task-header.component.ts b/lib/process-services/src/lib/task-list/components/task-header.component.ts index 15202a428f..d9b3aed822 100644 --- a/lib/process-services/src/lib/task-list/components/task-header.component.ts +++ b/lib/process-services/src/lib/task-list/components/task-header.component.ts @@ -23,12 +23,10 @@ import { CardViewMapItemModel, CardViewTextItemModel, CardViewBaseItemModel, - LogService, TranslationService, AppConfigService } from '@alfresco/adf-core'; import { TaskDetailsModel } from '../models/task-details.model'; -import { TaskListService } from './../services/tasklist.service'; import { TaskDescriptionValidator } from '../validators/task-description.validator'; @Component({ @@ -46,6 +44,10 @@ export class TaskHeaderComponent implements OnChanges, OnInit { @Input() taskDetails: TaskDetailsModel; + /** Toggles display of the claim/release button. */ + @Input() + showClaimRelease = true; + /** Emitted when the task is claimed. */ @Output() claim: EventEmitter = new EventEmitter(); @@ -62,10 +64,8 @@ export class TaskHeaderComponent implements OnChanges, OnInit { dateFormat: string; dateLocale: string; - constructor(private activitiTaskService: TaskListService, - private bpmUserService: BpmUserService, + constructor(private bpmUserService: BpmUserService, private translationService: TranslationService, - private logService: LogService, private appConfig: AppConfigService) { this.dateFormat = this.appConfig.get('dateValues.defaultDateFormat'); this.dateLocale = this.appConfig.get('dateValues.defaultDateLocale'); @@ -281,28 +281,12 @@ export class TaskHeaderComponent implements OnChanges, OnInit { return (this.taskDetails && this.taskDetails.isCompleted()) ? 'Completed' : 'Running'; } - /** - * Claim task - * - * @param taskId - */ - claimTask(taskId: string) { - this.activitiTaskService.claimTask(taskId).subscribe(() => { - this.logService.info('Task claimed'); - this.claim.emit(taskId); - }); + onClaimTask(taskId: string) { + this.claim.emit(taskId); } - /** - * Unclaim task - * - * @param taskId - */ - unclaimTask(taskId: string) { - this.activitiTaskService.unclaimTask(taskId).subscribe(() => { - this.logService.info('Task unclaimed'); - this.unclaim.emit(taskId); - }); + onUnclaimTask(taskId: string) { + this.unclaim.emit(taskId); } /** diff --git a/lib/process-services/src/lib/task-list/public-api.ts b/lib/process-services/src/lib/task-list/public-api.ts index a921856032..997b6f79f3 100644 --- a/lib/process-services/src/lib/task-list/public-api.ts +++ b/lib/process-services/src/lib/task-list/public-api.ts @@ -21,6 +21,8 @@ export * from './components/task-header.component'; export * from './components/no-task-detail-template.directive'; export * from './components/task-filters.component'; export * from './components/task-form/task-form.component'; +export * from './components/task-form/claim-task.directive'; +export * from './components/task-form/unclaim-task.directive'; export * from './components/task-details.component'; export * from './components/task-audit.directive'; export * from './components/start-task.component'; diff --git a/lib/process-services/src/lib/task-list/task-list.module.ts b/lib/process-services/src/lib/task-list/task-list.module.ts index 76eaae9156..c9ba630ba2 100644 --- a/lib/process-services/src/lib/task-list/task-list.module.ts +++ b/lib/process-services/src/lib/task-list/task-list.module.ts @@ -38,6 +38,8 @@ import { TaskListComponent } from './components/task-list.component'; import { TaskStandaloneComponent } from './components/task-standalone.component'; import { AttachFormComponent } from './components/attach-form.component'; import { FormModule } from '../form/form.module'; +import { ClaimTaskDirective } from './components/task-form/claim-task.directive'; +import { UnclaimTaskDirective } from './components/task-form/unclaim-task.directive'; @NgModule({ imports: [ @@ -63,7 +65,9 @@ import { FormModule } from '../form/form.module'; TaskHeaderComponent, StartTaskComponent, TaskStandaloneComponent, - AttachFormComponent + AttachFormComponent, + ClaimTaskDirective, + UnclaimTaskDirective ], exports: [ NoTaskDetailsTemplateDirective, @@ -76,7 +80,9 @@ import { FormModule } from '../form/form.module'; TaskHeaderComponent, StartTaskComponent, TaskStandaloneComponent, - AttachFormComponent + AttachFormComponent, + ClaimTaskDirective, + UnclaimTaskDirective ] }) export class TaskListModule {