mirror of
https://github.com/Alfresco/alfresco-ng2-components.git
synced 2025-05-12 17:04:57 +00:00
[ACA-3416] Add Claim/Release actions on adf task form (#5753)
* [ACA-3255] FE - Claim a task * * Added unit tests * * Added unit tests * Changed cloud directive names * * Added/Updated documents * * Added showReleaseClaim button flag * Add unit test too * * Used claim/release directive in task-header component. * * Fixed unit test * * Fixed one comment * * After rebase * * Fixed comments
This commit is contained in:
parent
77bbecea8e
commit
ea62b1e3bd
BIN
docs/docassets/images/form-custom-outcomes.component.png
Normal file
BIN
docs/docassets/images/form-custom-outcomes.component.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 13 KiB |
@ -1,18 +1,18 @@
|
|||||||
---
|
---
|
||||||
Title: Claim Task Directive
|
Title: Claim Task Cloud Directive
|
||||||
Added: v3.1.0
|
Added: v3.9.0
|
||||||
Status: Experimental
|
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
|
Claims a task
|
||||||
|
|
||||||
## Basic Usage
|
## Basic Usage
|
||||||
|
|
||||||
```html
|
```html
|
||||||
<button adf-claim-task [appName]="appName" [taskId]="taskId" (success)="onTaskClaimed()">Complete</button>
|
<button adf-cloud-claim-task [appName]="appName" [taskId]="taskId" (success)="onTaskClaimed()">Claim</button>
|
||||||
```
|
```
|
||||||
|
|
||||||
## Class members
|
## Class members
|
||||||
@ -22,7 +22,7 @@ Claims a task
|
|||||||
| Name | Type | Default value | Description |
|
| Name | Type | Default value | Description |
|
||||||
| ---- | ---- | ------------- | ----------- |
|
| ---- | ---- | ------------- | ----------- |
|
||||||
| appName | `string` | "" | (Required) The name of the application. |
|
| 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
|
### Events
|
||||||
|
|
@ -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
|
||||||
|
<button adf-cloud-unclaim-task [appName]="appName" [taskId]="taskId" (success)="onTaskUnclaimed()">Unclaim</button>
|
||||||
|
```
|
||||||
|
|
||||||
|
## 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)`<any>` | Emitted when the task cannot be completed. |
|
||||||
|
| success | [`EventEmitter`](https://angular.io/api/core/EventEmitter)`<any>` | Emitted when the task is completed. |
|
@ -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).
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
## Basic Usage
|
||||||
|
|
||||||
|
```html
|
||||||
|
<adf-form>
|
||||||
|
<adf-form-custom-outcomes>
|
||||||
|
<button mat-button (click)="onCustomOutcome1()">
|
||||||
|
Custom-outcome-1
|
||||||
|
</button>
|
||||||
|
<button mat-button (click)="onCustomOutcome2()">
|
||||||
|
Custom-outcome-2
|
||||||
|
</button>
|
||||||
|
<button mat-button (click)="onCustomOutcome3()">
|
||||||
|
Custom-outcome-3
|
||||||
|
</button>
|
||||||
|
</adf-form-custom-outcomes>
|
||||||
|
</adf-form>
|
||||||
|
```
|
||||||
|
|
||||||
|
## See Also
|
||||||
|
|
||||||
|
- [Form component](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. |
|
| 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. |
|
| 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)`<void>` | Emitted when the form associated with the form task is attached. |
|
| showAttachForm | [`EventEmitter`](https://angular.io/api/core/EventEmitter)`<void>` | Emitted when the form associated with the form task is attached. |
|
||||||
|
| taskClaimed | [`EventEmitter`](https://angular.io/api/core/EventEmitter)`<string>` | Emitted when the task is claimed. |
|
||||||
|
| taskUnclaimed | [`EventEmitter`](https://angular.io/api/core/EventEmitter)`<string>` | Emitted when the task is unclaimed (ie, requeued). |
|
||||||
|
|
||||||
## See also
|
## See also
|
||||||
|
|
||||||
|
@ -27,6 +27,7 @@ Shows all the information related to a task.
|
|||||||
| ---- | ---- | ------------- | ----------- |
|
| ---- | ---- | ------------- | ----------- |
|
||||||
| formName | `string` | null | The name of the form. |
|
| 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. |
|
| 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
|
### Events
|
||||||
|
|
||||||
|
31
docs/process-services/directives/claim-task.directive.md
Normal file
31
docs/process-services/directives/claim-task.directive.md
Normal file
@ -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
|
||||||
|
<button adf-claim-task [taskId]="taskId" (success)="onTaskClaimed()">Claim</button>
|
||||||
|
```
|
||||||
|
|
||||||
|
## 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)`<any>` | Emitted when the task cannot be completed. |
|
||||||
|
| success | [`EventEmitter`](https://angular.io/api/core/EventEmitter)`<any>` | Emitted when the task is completed. |
|
@ -1,18 +1,18 @@
|
|||||||
---
|
---
|
||||||
Title: Unclaim Task Directive
|
Title: Unclaim Task Directive
|
||||||
Added: v3.1.0
|
Added: v3.9.0
|
||||||
Status: Experimental
|
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
|
Unclaims a task
|
||||||
|
|
||||||
## Basic Usage
|
## Basic Usage
|
||||||
|
|
||||||
```html
|
```html
|
||||||
<button adf-unclaim-task [appName]="appName" [taskId]="taskId" (success)="onTaskUnclaimed()">Complete</button>
|
<button adf-unclaim-task [appName]="appName" [taskId]="taskId" (success)="onTaskUnclaimed()">Unclaim</button>
|
||||||
```
|
```
|
||||||
|
|
||||||
## Class members
|
## Class members
|
||||||
@ -21,8 +21,7 @@ Unclaims a task
|
|||||||
|
|
||||||
| Name | Type | Default value | Description |
|
| 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
|
### Events
|
||||||
|
|
@ -19,12 +19,12 @@ import { ComponentFixture, TestBed } from '@angular/core/testing';
|
|||||||
import { setupTestBed } from '@alfresco/adf-core';
|
import { setupTestBed } from '@alfresco/adf-core';
|
||||||
import { TaskCloudService } from '../services/task-cloud.service';
|
import { TaskCloudService } from '../services/task-cloud.service';
|
||||||
import { of } from 'rxjs';
|
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 { taskClaimCloudMock } from '../task-header/mocks/fake-claim-task.mock';
|
||||||
import { ProcessServiceCloudTestingModule } from '../../testing/process-service-cloud.testing.module';
|
import { ProcessServiceCloudTestingModule } from '../../testing/process-service-cloud.testing.module';
|
||||||
import { TranslateModule } from '@ngx-translate/core';
|
import { TranslateModule } from '@ngx-translate/core';
|
||||||
|
|
||||||
describe('ClaimTaskDirective', () => {
|
describe('ClaimTaskCloudDirective', () => {
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'adf-cloud-claim-test-component',
|
selector: 'adf-cloud-claim-test-component',
|
||||||
@ -35,8 +35,8 @@ describe('ClaimTaskDirective', () => {
|
|||||||
taskMock = 'test1234';
|
taskMock = 'test1234';
|
||||||
appNameMock = 'simple-app';
|
appNameMock = 'simple-app';
|
||||||
|
|
||||||
@ViewChild(ClaimTaskDirective)
|
@ViewChild(ClaimTaskCloudDirective)
|
||||||
claimTaskDirective: ClaimTaskDirective;
|
claimTaskDirective: ClaimTaskCloudDirective;
|
||||||
}
|
}
|
||||||
|
|
||||||
let fixture: ComponentFixture<TestComponent>;
|
let fixture: ComponentFixture<TestComponent>;
|
||||||
@ -78,8 +78,8 @@ describe('Claim Task Directive validation errors', () => {
|
|||||||
appNameUndefined = undefined;
|
appNameUndefined = undefined;
|
||||||
appNameNull = null;
|
appNameNull = null;
|
||||||
|
|
||||||
@ContentChildren(ClaimTaskDirective)
|
@ContentChildren(ClaimTaskCloudDirective)
|
||||||
claimTaskValidationDirective: ClaimTaskDirective;
|
claimTaskValidationDirective: ClaimTaskCloudDirective;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
@ -90,8 +90,8 @@ describe('Claim Task Directive validation errors', () => {
|
|||||||
|
|
||||||
appName = 'simple-app';
|
appName = 'simple-app';
|
||||||
|
|
||||||
@ContentChildren(ClaimTaskDirective)
|
@ContentChildren(ClaimTaskCloudDirective)
|
||||||
claimTaskValidationDirective: ClaimTaskDirective;
|
claimTaskValidationDirective: ClaimTaskCloudDirective;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
@ -103,8 +103,8 @@ describe('Claim Task Directive validation errors', () => {
|
|||||||
appNameUndefined = undefined;
|
appNameUndefined = undefined;
|
||||||
taskMock = 'test1234';
|
taskMock = 'test1234';
|
||||||
|
|
||||||
@ContentChildren(ClaimTaskDirective)
|
@ContentChildren(ClaimTaskCloudDirective)
|
||||||
claimTaskValidationDirective: ClaimTaskDirective;
|
claimTaskValidationDirective: ClaimTaskCloudDirective;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
@ -116,8 +116,8 @@ describe('Claim Task Directive validation errors', () => {
|
|||||||
appNameNull = null;
|
appNameNull = null;
|
||||||
taskMock = 'test1234';
|
taskMock = 'test1234';
|
||||||
|
|
||||||
@ViewChild(ClaimTaskDirective)
|
@ViewChild(ClaimTaskCloudDirective)
|
||||||
claimTaskValidationDirective: ClaimTaskDirective;
|
claimTaskValidationDirective: ClaimTaskCloudDirective;
|
||||||
}
|
}
|
||||||
|
|
||||||
let fixture: ComponentFixture<any>;
|
let fixture: ComponentFixture<any>;
|
@ -22,7 +22,7 @@ import { TaskCloudService } from '../services/task-cloud.service';
|
|||||||
// tslint:disable-next-line: directive-selector
|
// tslint:disable-next-line: directive-selector
|
||||||
selector: '[adf-cloud-claim-task]'
|
selector: '[adf-cloud-claim-task]'
|
||||||
})
|
})
|
||||||
export class ClaimTaskDirective implements OnInit {
|
export class ClaimTaskCloudDirective implements OnInit {
|
||||||
|
|
||||||
/** (Required) The id of the task. */
|
/** (Required) The id of the task. */
|
||||||
@Input()
|
@Input()
|
@ -15,8 +15,8 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
export * from './claim-task.directive';
|
export * from './claim-task-cloud.directive';
|
||||||
export * from './unclaim-task.directive';
|
export * from './unclaim-task-cloud.directive';
|
||||||
export * from './complete-task.directive';
|
export * from './complete-task.directive';
|
||||||
|
|
||||||
export * from './task-directive.module';
|
export * from './task-directive.module';
|
||||||
|
@ -17,19 +17,19 @@
|
|||||||
|
|
||||||
import { NgModule } from '@angular/core';
|
import { NgModule } from '@angular/core';
|
||||||
import { CompleteTaskDirective } from './complete-task.directive';
|
import { CompleteTaskDirective } from './complete-task.directive';
|
||||||
import { ClaimTaskDirective } from './claim-task.directive';
|
import { ClaimTaskCloudDirective } from './claim-task-cloud.directive';
|
||||||
import { UnClaimTaskDirective } from './unclaim-task.directive';
|
import { UnClaimTaskCloudDirective } from './unclaim-task-cloud.directive';
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
declarations: [
|
declarations: [
|
||||||
CompleteTaskDirective,
|
CompleteTaskDirective,
|
||||||
ClaimTaskDirective,
|
ClaimTaskCloudDirective,
|
||||||
UnClaimTaskDirective
|
UnClaimTaskCloudDirective
|
||||||
],
|
],
|
||||||
exports: [
|
exports: [
|
||||||
CompleteTaskDirective,
|
CompleteTaskDirective,
|
||||||
ClaimTaskDirective,
|
ClaimTaskCloudDirective,
|
||||||
UnClaimTaskDirective
|
UnClaimTaskCloudDirective
|
||||||
]
|
]
|
||||||
})
|
})
|
||||||
export class TaskDirectiveModule { }
|
export class TaskDirectiveModule { }
|
||||||
|
@ -19,12 +19,12 @@ import { ComponentFixture, TestBed } from '@angular/core/testing';
|
|||||||
import { setupTestBed } from '@alfresco/adf-core';
|
import { setupTestBed } from '@alfresco/adf-core';
|
||||||
import { TaskCloudService } from '../services/task-cloud.service';
|
import { TaskCloudService } from '../services/task-cloud.service';
|
||||||
import { of } from 'rxjs';
|
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 { taskClaimCloudMock } from '../task-header/mocks/fake-claim-task.mock';
|
||||||
import { ProcessServiceCloudTestingModule } from '../../testing/process-service-cloud.testing.module';
|
import { ProcessServiceCloudTestingModule } from '../../testing/process-service-cloud.testing.module';
|
||||||
import { TranslateModule } from '@ngx-translate/core';
|
import { TranslateModule } from '@ngx-translate/core';
|
||||||
|
|
||||||
describe('UnClaimTaskDirective', () => {
|
describe('UnClaimTaskCloudDirective', () => {
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'adf-cloud-test-component',
|
selector: 'adf-cloud-test-component',
|
||||||
@ -35,8 +35,8 @@ describe('UnClaimTaskDirective', () => {
|
|||||||
appName = 'simple-app';
|
appName = 'simple-app';
|
||||||
taskIdMock = '1234';
|
taskIdMock = '1234';
|
||||||
|
|
||||||
@ContentChildren(UnClaimTaskDirective)
|
@ContentChildren(UnClaimTaskCloudDirective)
|
||||||
unclaimTaskDirective: UnClaimTaskDirective;
|
unclaimTaskDirective: UnClaimTaskCloudDirective;
|
||||||
}
|
}
|
||||||
|
|
||||||
let fixture: ComponentFixture<TestComponent>;
|
let fixture: ComponentFixture<TestComponent>;
|
||||||
@ -78,8 +78,8 @@ describe('UnClaim Task Directive validation errors', () => {
|
|||||||
appNameUndefined = undefined;
|
appNameUndefined = undefined;
|
||||||
appNameNull = null;
|
appNameNull = null;
|
||||||
|
|
||||||
@ContentChildren(UnClaimTaskDirective)
|
@ContentChildren(UnClaimTaskCloudDirective)
|
||||||
claimTaskValidationDirective: UnClaimTaskDirective;
|
claimTaskValidationDirective: UnClaimTaskCloudDirective;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
@ -90,8 +90,8 @@ describe('UnClaim Task Directive validation errors', () => {
|
|||||||
|
|
||||||
appName = 'simple-app';
|
appName = 'simple-app';
|
||||||
|
|
||||||
@ContentChildren(UnClaimTaskDirective)
|
@ContentChildren(UnClaimTaskCloudDirective)
|
||||||
claimTaskValidationDirective: UnClaimTaskDirective;
|
claimTaskValidationDirective: UnClaimTaskCloudDirective;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
@ -103,8 +103,8 @@ describe('UnClaim Task Directive validation errors', () => {
|
|||||||
appNameUndefined = undefined;
|
appNameUndefined = undefined;
|
||||||
taskMock = 'test1234';
|
taskMock = 'test1234';
|
||||||
|
|
||||||
@ContentChildren(UnClaimTaskDirective)
|
@ContentChildren(UnClaimTaskCloudDirective)
|
||||||
claimTaskValidationDirective: UnClaimTaskDirective;
|
claimTaskValidationDirective: UnClaimTaskCloudDirective;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
@ -116,8 +116,8 @@ describe('UnClaim Task Directive validation errors', () => {
|
|||||||
appNameNull = null;
|
appNameNull = null;
|
||||||
taskMock = 'test1234';
|
taskMock = 'test1234';
|
||||||
|
|
||||||
@ViewChild(UnClaimTaskDirective)
|
@ViewChild(UnClaimTaskCloudDirective)
|
||||||
claimTaskValidationDirective: UnClaimTaskDirective;
|
claimTaskValidationDirective: UnClaimTaskCloudDirective;
|
||||||
}
|
}
|
||||||
|
|
||||||
let fixture: ComponentFixture<any>;
|
let fixture: ComponentFixture<any>;
|
@ -21,7 +21,7 @@ import { TaskCloudService } from '../services/task-cloud.service';
|
|||||||
// tslint:disable-next-line: directive-selector
|
// tslint:disable-next-line: directive-selector
|
||||||
selector: '[adf-cloud-unclaim-task]'
|
selector: '[adf-cloud-unclaim-task]'
|
||||||
})
|
})
|
||||||
export class UnClaimTaskDirective implements OnInit {
|
export class UnClaimTaskCloudDirective implements OnInit {
|
||||||
|
|
||||||
/** (Required) The id of the task. */
|
/** (Required) The id of the task. */
|
||||||
@Input()
|
@Input()
|
@ -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: '<ng-content></ng-content>'
|
||||||
|
})
|
||||||
|
export class FormCustomOutcomesComponent {}
|
@ -34,6 +34,7 @@
|
|||||||
</adf-form-renderer>
|
</adf-form-renderer>
|
||||||
</mat-card-content>
|
</mat-card-content>
|
||||||
<mat-card-actions *ngIf="form.hasOutcomes()" class="adf-form-mat-card-actions">
|
<mat-card-actions *ngIf="form.hasOutcomes()" class="adf-form-mat-card-actions">
|
||||||
|
<ng-content select="adf-form-custom-outcomes"></ng-content>
|
||||||
<button [id]="'adf-form-'+ outcome.name | formatSpace" *ngFor="let outcome of form.outcomes"
|
<button [id]="'adf-form-'+ outcome.name | formatSpace" *ngFor="let outcome of form.outcomes"
|
||||||
[color]="getColorForOutcome(outcome.name)" mat-button [disabled]="!isOutcomeButtonEnabled(outcome)"
|
[color]="getColorForOutcome(outcome.name)" mat-button [disabled]="!isOutcomeButtonEnabled(outcome)"
|
||||||
[class.adf-form-hide-button]="!isOutcomeButtonVisible(outcome, form.readOnly)"
|
[class.adf-form-hide-button]="!isOutcomeButtonVisible(outcome, form.readOnly)"
|
||||||
|
@ -15,7 +15,8 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { SimpleChange, ComponentFactoryResolver, Injector, NgModule, Component } from '@angular/core';
|
import { SimpleChange, ComponentFactoryResolver, Injector, NgModule, Component, ViewChild, DebugElement } from '@angular/core';
|
||||||
|
import { By } from '@angular/platform-browser';
|
||||||
import { TestBed, ComponentFixture } from '@angular/core/testing';
|
import { TestBed, ComponentFixture } from '@angular/core/testing';
|
||||||
import { Observable, of, throwError } from 'rxjs';
|
import { Observable, of, throwError } from 'rxjs';
|
||||||
import { FormFieldModel, FormFieldTypes, FormModel, FormOutcomeEvent, FormOutcomeModel,
|
import { FormFieldModel, FormFieldTypes, FormModel, FormOutcomeEvent, FormOutcomeModel,
|
||||||
@ -1013,3 +1014,79 @@ describe('FormComponent', () => {
|
|||||||
expect(radioFieldById.value).toBe('option_3');
|
expect(radioFieldById.value).toBe('option_3');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'adf-form-with-custom-outcomes',
|
||||||
|
template: `
|
||||||
|
<adf-form #adfForm>
|
||||||
|
<adf-form-custom-outcomes>
|
||||||
|
<button mat-button id="adf-custom-outcome-1" (click)="onCustomButtonOneClick()">
|
||||||
|
CUSTOM-BUTTON-1
|
||||||
|
</button>
|
||||||
|
<button mat-button id="adf-custom-outcome-2" (click)="onCustomButtonTwoClick()">
|
||||||
|
CUSTOM-BUTTON-2
|
||||||
|
</button>
|
||||||
|
</adf-form-custom-outcomes>
|
||||||
|
</adf-form>`
|
||||||
|
})
|
||||||
|
|
||||||
|
class FormWithCustomOutComesComponent {
|
||||||
|
|
||||||
|
@ViewChild('adfForm')
|
||||||
|
adfForm: FormComponent;
|
||||||
|
|
||||||
|
onCustomButtonOneClick() { }
|
||||||
|
onCustomButtonTwoClick() { }
|
||||||
|
}
|
||||||
|
|
||||||
|
describe('FormWithCustomOutComesComponent', () => {
|
||||||
|
|
||||||
|
let fixture: ComponentFixture<FormWithCustomOutComesComponent>;
|
||||||
|
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');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
@ -20,6 +20,7 @@ import { MaterialModule } from '../material.module';
|
|||||||
import { CoreModule } from '@alfresco/adf-core';
|
import { CoreModule } from '@alfresco/adf-core';
|
||||||
import { FormComponent } from './form.component';
|
import { FormComponent } from './form.component';
|
||||||
import { StartFormComponent } from './start-form.component';
|
import { StartFormComponent } from './start-form.component';
|
||||||
|
import { FormCustomOutcomesComponent } from './form-custom-outcomes.component';
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
imports: [
|
imports: [
|
||||||
@ -28,11 +29,13 @@ import { StartFormComponent } from './start-form.component';
|
|||||||
],
|
],
|
||||||
declarations: [
|
declarations: [
|
||||||
FormComponent,
|
FormComponent,
|
||||||
StartFormComponent
|
StartFormComponent,
|
||||||
|
FormCustomOutcomesComponent
|
||||||
],
|
],
|
||||||
exports: [
|
exports: [
|
||||||
FormComponent,
|
FormComponent,
|
||||||
StartFormComponent
|
StartFormComponent,
|
||||||
|
FormCustomOutcomesComponent
|
||||||
]
|
]
|
||||||
})
|
})
|
||||||
export class FormModule {}
|
export class FormModule {}
|
||||||
|
@ -18,4 +18,5 @@
|
|||||||
export * from './form.component';
|
export * from './form.component';
|
||||||
export * from './start-form.component';
|
export * from './start-form.component';
|
||||||
export * from './process-form-rendering.service';
|
export * from './process-form-rendering.service';
|
||||||
|
export * from './form-custom-outcomes.component';
|
||||||
export * from './form.module';
|
export * from './form.module';
|
||||||
|
@ -35,6 +35,8 @@
|
|||||||
(completed)="onComplete()"
|
(completed)="onComplete()"
|
||||||
(showAttachForm)="onShowAttachForm()"
|
(showAttachForm)="onShowAttachForm()"
|
||||||
(executeOutcome)='onFormExecuteOutcome($event)'
|
(executeOutcome)='onFormExecuteOutcome($event)'
|
||||||
|
(taskClaimed)="onClaimAction($event)"
|
||||||
|
(taskUnclaimed)="onUnclaimAction($event)"
|
||||||
(error)="onFormError($event)" #activitiTaskForm>
|
(error)="onFormError($event)" #activitiTaskForm>
|
||||||
</adf-task-form>
|
</adf-task-form>
|
||||||
<adf-attach-form *ngIf="isShowAttachForm()"
|
<adf-attach-form *ngIf="isShowAttachForm()"
|
||||||
|
@ -0,0 +1,122 @@
|
|||||||
|
/*!
|
||||||
|
* @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('ClaimTaskDirective', () => {
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'adf-claim-test-component',
|
||||||
|
template: '<button adf-claim-task [taskId]="taskId" (success)="onClaim($event)">Claim</button>'
|
||||||
|
})
|
||||||
|
class TestComponent {
|
||||||
|
taskId = 'test1234';
|
||||||
|
@Output()
|
||||||
|
claim: EventEmitter<any> = new EventEmitter<any>();
|
||||||
|
|
||||||
|
onClaim(event) {
|
||||||
|
this.claim.emit(event);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let fixture: ComponentFixture<TestComponent>;
|
||||||
|
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: '<button adf-claim-task></button>'
|
||||||
|
})
|
||||||
|
class ClaimTestMissingInputDirectiveComponent { }
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'adf-claim-no-taskid-validation-component',
|
||||||
|
template: '<button adf-claim-task [taskId]=""></button>'
|
||||||
|
})
|
||||||
|
class ClaimTestMissingTaskIdDirectiveComponent { }
|
||||||
|
|
||||||
|
let fixture: ComponentFixture<any>;
|
||||||
|
|
||||||
|
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');
|
||||||
|
});
|
||||||
|
});
|
@ -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<any> = new EventEmitter<any>();
|
||||||
|
|
||||||
|
/** Emitted when the task cannot be claimed. */
|
||||||
|
@Output()
|
||||||
|
error: EventEmitter<any> = new EventEmitter<any>();
|
||||||
|
|
||||||
|
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)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
@ -16,6 +16,10 @@
|
|||||||
(formError)='onFormError($event)'
|
(formError)='onFormError($event)'
|
||||||
(error)='onError($event)'
|
(error)='onError($event)'
|
||||||
(executeOutcome)='onFormExecuteOutcome($event)'>
|
(executeOutcome)='onFormExecuteOutcome($event)'>
|
||||||
|
<adf-form-custom-outcomes>
|
||||||
|
<ng-template [ngTemplateOutlet]="taskFormButtons">
|
||||||
|
</ng-template>
|
||||||
|
</adf-form-custom-outcomes>
|
||||||
</adf-form>
|
</adf-form>
|
||||||
<ng-template #withoutForm>
|
<ng-template #withoutForm>
|
||||||
<adf-task-standalone *ngIf="isStandaloneTask(); else emptyFormMessage"
|
<adf-task-standalone *ngIf="isStandaloneTask(); else emptyFormMessage"
|
||||||
@ -56,6 +60,7 @@
|
|||||||
</ng-template>
|
</ng-template>
|
||||||
</mat-card-content>
|
</mat-card-content>
|
||||||
<mat-card-actions class="adf-task-form-actions">
|
<mat-card-actions class="adf-task-form-actions">
|
||||||
|
<ng-template [ngTemplateOutlet]="taskFormButtons"></ng-template>
|
||||||
<button id="adf-no-form-cancel-button" mat-button *ngIf="showCancelButton" (click)="onCancel()">
|
<button id="adf-no-form-cancel-button" mat-button *ngIf="showCancelButton" (click)="onCancel()">
|
||||||
{{'ADF_TASK_FORM.EMPTY_FORM.BUTTONS.CANCEL' | translate}}
|
{{'ADF_TASK_FORM.EMPTY_FORM.BUTTONS.CANCEL' | translate}}
|
||||||
</button>
|
</button>
|
||||||
@ -66,6 +71,23 @@
|
|||||||
</mat-card>
|
</mat-card>
|
||||||
</ng-template>
|
</ng-template>
|
||||||
</ng-template>
|
</ng-template>
|
||||||
|
|
||||||
|
<ng-template #taskFormButtons>
|
||||||
|
<button mat-button data-automation-id="adf-task-form-claim-button"
|
||||||
|
*ngIf="isTaskClaimable()"
|
||||||
|
adf-claim-task
|
||||||
|
[taskId]="taskId"
|
||||||
|
(success)="onClaimTask($event)">
|
||||||
|
{{ 'ADF_TASK_LIST.DETAILS.BUTTON.CLAIM' | translate }}
|
||||||
|
</button>
|
||||||
|
<button mat-button data-automation-id="adf-task-form-unclaim-button"
|
||||||
|
*ngIf="isTaskClaimedByCandidateMember()"
|
||||||
|
adf-unclaim-task
|
||||||
|
[taskId]="taskId"
|
||||||
|
(success)="onUnclaimTask($event)">
|
||||||
|
{{ 'ADF_TASK_LIST.DETAILS.BUTTON.UNCLAIM' | translate }}
|
||||||
|
</button>
|
||||||
|
</ng-template>
|
||||||
</ng-container>
|
</ng-container>
|
||||||
<ng-template #loadingTemplate>
|
<ng-template #loadingTemplate>
|
||||||
<div fxLayout="row" fxLayoutAlign="center stretch">
|
<div fxLayout="row" fxLayoutAlign="center stretch">
|
||||||
|
@ -37,11 +37,15 @@ import {
|
|||||||
standaloneTaskWithoutForm,
|
standaloneTaskWithoutForm,
|
||||||
completedStandaloneTaskWithoutForm,
|
completedStandaloneTaskWithoutForm,
|
||||||
claimableTaskDetailsMock,
|
claimableTaskDetailsMock,
|
||||||
initiatorCanCompleteTaskDetailsMock
|
initiatorCanCompleteTaskDetailsMock,
|
||||||
|
taskDetailsWithOutCandidateGroup,
|
||||||
|
claimedTaskDetailsMock,
|
||||||
|
claimedByGroupMemberMock
|
||||||
} from '../../../mock/task/task-details.mock';
|
} from '../../../mock/task/task-details.mock';
|
||||||
import { TaskDetailsModel } from '../../models/task-details.model';
|
import { TaskDetailsModel } from '../../models/task-details.model';
|
||||||
import { ProcessTestingModule } from '../../../testing/process.testing.module';
|
import { ProcessTestingModule } from '../../../testing/process.testing.module';
|
||||||
import { TranslateModule } from '@ngx-translate/core';
|
import { TranslateModule } from '@ngx-translate/core';
|
||||||
|
import { By } from '@angular/platform-browser';
|
||||||
|
|
||||||
describe('TaskFormComponent', () => {
|
describe('TaskFormComponent', () => {
|
||||||
let component: TaskFormComponent;
|
let component: TaskFormComponent;
|
||||||
@ -495,4 +499,125 @@ describe('TaskFormComponent', () => {
|
|||||||
expect(validationForm.textContent).toBe('check_circle');
|
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();
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
@ -117,6 +117,14 @@ export class TaskFormComponent implements OnInit {
|
|||||||
@Output()
|
@Output()
|
||||||
cancel = new EventEmitter<void>();
|
cancel = new EventEmitter<void>();
|
||||||
|
|
||||||
|
/** Emitted when the task is claimed. */
|
||||||
|
@Output()
|
||||||
|
taskClaimed = new EventEmitter<string>();
|
||||||
|
|
||||||
|
/** Emitted when the task is unclaimed (ie, requeued).. */
|
||||||
|
@Output()
|
||||||
|
taskUnclaimed = new EventEmitter<string>();
|
||||||
|
|
||||||
taskDetails: TaskDetailsModel;
|
taskDetails: TaskDetailsModel;
|
||||||
currentLoggedUser: UserRepresentation;
|
currentLoggedUser: UserRepresentation;
|
||||||
loading: boolean = false;
|
loading: boolean = false;
|
||||||
@ -278,4 +286,28 @@ export class TaskFormComponent implements OnInit {
|
|||||||
getCompletedTaskTranslatedMessage(): Observable<string> {
|
getCompletedTaskTranslatedMessage(): Observable<string> {
|
||||||
return this.translationService.get('ADF_TASK_FORM.COMPLETED_TASK.TITLE', { taskName: this.taskDetails.name });
|
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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -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: '<button adf-unclaim-task [taskId]="taskId" (success)="onUnclaim($event)">Unclaim</button>'
|
||||||
|
})
|
||||||
|
class TestComponent {
|
||||||
|
taskId = 'test1234';
|
||||||
|
@Output()
|
||||||
|
unclaim: EventEmitter<any> = new EventEmitter<any>();
|
||||||
|
|
||||||
|
onUnclaim(event) {
|
||||||
|
this.unclaim.emit(event);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let fixture: ComponentFixture<TestComponent>;
|
||||||
|
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: '<button adf-unclaim-task></button>'
|
||||||
|
})
|
||||||
|
class ClaimTestMissingInputDirectiveComponent {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'adf-claim-no-taskid-validation-component',
|
||||||
|
template: '<button adf-unclaim-task [taskId]=""></button>'
|
||||||
|
})
|
||||||
|
class ClaimTestMissingTaskIdDirectiveComponent {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
let fixture: ComponentFixture<any>;
|
||||||
|
|
||||||
|
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');
|
||||||
|
});
|
||||||
|
});
|
@ -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<any> = new EventEmitter<any>();
|
||||||
|
|
||||||
|
/** Emitted when the task cannot be released. */
|
||||||
|
@Output()
|
||||||
|
error: EventEmitter<any> = new EventEmitter<any>();
|
||||||
|
|
||||||
|
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)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
@ -3,10 +3,26 @@
|
|||||||
<adf-card-view [properties]="properties" [editable]="!isCompleted()" [displayClearAction]="displayDateClearAction"></adf-card-view>
|
<adf-card-view [properties]="properties" [editable]="!isCompleted()" [displayClearAction]="displayDateClearAction"></adf-card-view>
|
||||||
</mat-card-content>
|
</mat-card-content>
|
||||||
|
|
||||||
<mat-card-actions class="adf-controls">
|
<mat-card-actions class="adf-controls" *ngIf="showClaimRelease">
|
||||||
<button *ngIf="isTaskClaimedByCandidateMember()" mat-button data-automation-id="header-unclaim-button" id="unclaim-task" (click)="unclaimTask(taskDetails.id)" class="adf-claim-controls">{{ 'ADF_TASK_LIST.DETAILS.BUTTON.UNCLAIM' | translate }}
|
<button *ngIf="isTaskClaimedByCandidateMember()"
|
||||||
|
mat-button
|
||||||
|
data-automation-id="header-unclaim-button"
|
||||||
|
id="unclaim-task"
|
||||||
|
class="adf-claim-controls"
|
||||||
|
adf-unclaim-task
|
||||||
|
[taskId]="taskDetails.id"
|
||||||
|
(success)="onUnclaimTask($event)">
|
||||||
|
{{ 'ADF_TASK_LIST.DETAILS.BUTTON.UNCLAIM' | translate }}
|
||||||
</button>
|
</button>
|
||||||
<button *ngIf="isTaskClaimable()" mat-button data-automation-id="header-claim-button" id="claim-task" (click)="claimTask(taskDetails.id)" class="adf-claim-controls">{{ 'ADF_TASK_LIST.DETAILS.BUTTON.CLAIM' | translate }}
|
<button *ngIf="isTaskClaimable()"
|
||||||
|
mat-button
|
||||||
|
data-automation-id="header-claim-button"
|
||||||
|
id="claim-task"
|
||||||
|
class="adf-claim-controls"
|
||||||
|
adf-claim-task
|
||||||
|
[taskId]="taskDetails.id"
|
||||||
|
(success)="onClaimTask($event)">
|
||||||
|
{{ 'ADF_TASK_LIST.DETAILS.BUTTON.CLAIM' | translate }}
|
||||||
</button>
|
</button>
|
||||||
</mat-card-actions>
|
</mat-card-actions>
|
||||||
</mat-card>
|
</mat-card>
|
||||||
|
@ -136,6 +136,30 @@ describe('TaskHeaderComponent', () => {
|
|||||||
|
|
||||||
describe('Claiming', () => {
|
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(() => {
|
it('should display the claim button if no assignee', async(() => {
|
||||||
component.taskDetails = new TaskDetailsModel(claimableTaskDetailsMock);
|
component.taskDetails = new TaskDetailsModel(claimableTaskDetailsMock);
|
||||||
|
|
||||||
@ -227,38 +251,37 @@ describe('TaskHeaderComponent', () => {
|
|||||||
});
|
});
|
||||||
}));
|
}));
|
||||||
|
|
||||||
it('should call the service unclaim method on un-claiming', async(() => {
|
it('should emit claim event when task is claimed', (done) => {
|
||||||
spyOn(service, 'unclaimTask').and.returnValue(of(true));
|
spyOn(service, 'claimTask').and.returnValue(of({}));
|
||||||
component.taskDetails = new TaskDetailsModel(claimedTaskDetailsMock);
|
component.taskDetails = claimableTaskDetailsMock;
|
||||||
component.refreshData();
|
|
||||||
|
component.claim.subscribe((taskId) => {
|
||||||
|
expect(taskId).toEqual(component.taskDetails.id);
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
|
||||||
|
component.ngOnInit();
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
|
|
||||||
fixture.whenStable().then(() => {
|
const claimBtn = fixture.debugElement.query(By.css('[adf-claim-task]'));
|
||||||
const unclaimButton = fixture.debugElement.query(By.css('[data-automation-id="header-unclaim-button"]'));
|
claimBtn.nativeElement.click();
|
||||||
unclaimButton.triggerEventHandler('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(() => {
|
component.ngOnInit();
|
||||||
let unclaimed: boolean = false;
|
|
||||||
spyOn(service, 'unclaimTask').and.returnValue(of(true));
|
|
||||||
component.taskDetails = new TaskDetailsModel(claimedTaskDetailsMock);
|
|
||||||
component.refreshData();
|
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
|
|
||||||
fixture.whenStable().then(() => {
|
const unclaimBtn = fixture.debugElement.query(By.css('[adf-unclaim-task]'));
|
||||||
component.unclaim.subscribe(() => {
|
unclaimBtn.nativeElement.click();
|
||||||
unclaimed = true;
|
});
|
||||||
});
|
|
||||||
|
|
||||||
const unclaimButton = fixture.debugElement.query(By.css('[data-automation-id="header-unclaim-button"]'));
|
|
||||||
unclaimButton.triggerEventHandler('click', {});
|
|
||||||
|
|
||||||
expect(unclaimed).toBeTruthy();
|
|
||||||
});
|
|
||||||
}));
|
|
||||||
|
|
||||||
it('should display due date', async(() => {
|
it('should display due date', async(() => {
|
||||||
component.taskDetails.dueDate = new Date('2016-11-03');
|
component.taskDetails.dueDate = new Date('2016-11-03');
|
||||||
|
@ -23,12 +23,10 @@ import {
|
|||||||
CardViewMapItemModel,
|
CardViewMapItemModel,
|
||||||
CardViewTextItemModel,
|
CardViewTextItemModel,
|
||||||
CardViewBaseItemModel,
|
CardViewBaseItemModel,
|
||||||
LogService,
|
|
||||||
TranslationService,
|
TranslationService,
|
||||||
AppConfigService
|
AppConfigService
|
||||||
} from '@alfresco/adf-core';
|
} from '@alfresco/adf-core';
|
||||||
import { TaskDetailsModel } from '../models/task-details.model';
|
import { TaskDetailsModel } from '../models/task-details.model';
|
||||||
import { TaskListService } from './../services/tasklist.service';
|
|
||||||
import { TaskDescriptionValidator } from '../validators/task-description.validator';
|
import { TaskDescriptionValidator } from '../validators/task-description.validator';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
@ -46,6 +44,10 @@ export class TaskHeaderComponent implements OnChanges, OnInit {
|
|||||||
@Input()
|
@Input()
|
||||||
taskDetails: TaskDetailsModel;
|
taskDetails: TaskDetailsModel;
|
||||||
|
|
||||||
|
/** Toggles display of the claim/release button. */
|
||||||
|
@Input()
|
||||||
|
showClaimRelease = true;
|
||||||
|
|
||||||
/** Emitted when the task is claimed. */
|
/** Emitted when the task is claimed. */
|
||||||
@Output()
|
@Output()
|
||||||
claim: EventEmitter<any> = new EventEmitter<any>();
|
claim: EventEmitter<any> = new EventEmitter<any>();
|
||||||
@ -62,10 +64,8 @@ export class TaskHeaderComponent implements OnChanges, OnInit {
|
|||||||
dateFormat: string;
|
dateFormat: string;
|
||||||
dateLocale: string;
|
dateLocale: string;
|
||||||
|
|
||||||
constructor(private activitiTaskService: TaskListService,
|
constructor(private bpmUserService: BpmUserService,
|
||||||
private bpmUserService: BpmUserService,
|
|
||||||
private translationService: TranslationService,
|
private translationService: TranslationService,
|
||||||
private logService: LogService,
|
|
||||||
private appConfig: AppConfigService) {
|
private appConfig: AppConfigService) {
|
||||||
this.dateFormat = this.appConfig.get('dateValues.defaultDateFormat');
|
this.dateFormat = this.appConfig.get('dateValues.defaultDateFormat');
|
||||||
this.dateLocale = this.appConfig.get('dateValues.defaultDateLocale');
|
this.dateLocale = this.appConfig.get('dateValues.defaultDateLocale');
|
||||||
@ -281,28 +281,12 @@ export class TaskHeaderComponent implements OnChanges, OnInit {
|
|||||||
return (this.taskDetails && this.taskDetails.isCompleted()) ? 'Completed' : 'Running';
|
return (this.taskDetails && this.taskDetails.isCompleted()) ? 'Completed' : 'Running';
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
onClaimTask(taskId: string) {
|
||||||
* Claim task
|
this.claim.emit(taskId);
|
||||||
*
|
|
||||||
* @param taskId
|
|
||||||
*/
|
|
||||||
claimTask(taskId: string) {
|
|
||||||
this.activitiTaskService.claimTask(taskId).subscribe(() => {
|
|
||||||
this.logService.info('Task claimed');
|
|
||||||
this.claim.emit(taskId);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
onUnclaimTask(taskId: string) {
|
||||||
* Unclaim task
|
this.unclaim.emit(taskId);
|
||||||
*
|
|
||||||
* @param taskId
|
|
||||||
*/
|
|
||||||
unclaimTask(taskId: string) {
|
|
||||||
this.activitiTaskService.unclaimTask(taskId).subscribe(() => {
|
|
||||||
this.logService.info('Task unclaimed');
|
|
||||||
this.unclaim.emit(taskId);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -21,6 +21,8 @@ export * from './components/task-header.component';
|
|||||||
export * from './components/no-task-detail-template.directive';
|
export * from './components/no-task-detail-template.directive';
|
||||||
export * from './components/task-filters.component';
|
export * from './components/task-filters.component';
|
||||||
export * from './components/task-form/task-form.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-details.component';
|
||||||
export * from './components/task-audit.directive';
|
export * from './components/task-audit.directive';
|
||||||
export * from './components/start-task.component';
|
export * from './components/start-task.component';
|
||||||
|
@ -38,6 +38,8 @@ import { TaskListComponent } from './components/task-list.component';
|
|||||||
import { TaskStandaloneComponent } from './components/task-standalone.component';
|
import { TaskStandaloneComponent } from './components/task-standalone.component';
|
||||||
import { AttachFormComponent } from './components/attach-form.component';
|
import { AttachFormComponent } from './components/attach-form.component';
|
||||||
import { FormModule } from '../form/form.module';
|
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({
|
@NgModule({
|
||||||
imports: [
|
imports: [
|
||||||
@ -63,7 +65,9 @@ import { FormModule } from '../form/form.module';
|
|||||||
TaskHeaderComponent,
|
TaskHeaderComponent,
|
||||||
StartTaskComponent,
|
StartTaskComponent,
|
||||||
TaskStandaloneComponent,
|
TaskStandaloneComponent,
|
||||||
AttachFormComponent
|
AttachFormComponent,
|
||||||
|
ClaimTaskDirective,
|
||||||
|
UnclaimTaskDirective
|
||||||
],
|
],
|
||||||
exports: [
|
exports: [
|
||||||
NoTaskDetailsTemplateDirective,
|
NoTaskDetailsTemplateDirective,
|
||||||
@ -76,7 +80,9 @@ import { FormModule } from '../form/form.module';
|
|||||||
TaskHeaderComponent,
|
TaskHeaderComponent,
|
||||||
StartTaskComponent,
|
StartTaskComponent,
|
||||||
TaskStandaloneComponent,
|
TaskStandaloneComponent,
|
||||||
AttachFormComponent
|
AttachFormComponent,
|
||||||
|
ClaimTaskDirective,
|
||||||
|
UnclaimTaskDirective
|
||||||
]
|
]
|
||||||
})
|
})
|
||||||
export class TaskListModule {
|
export class TaskListModule {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user