diff --git a/demo-shell/src/app/components/app-layout/cloud/task-details-cloud-demo.component.html b/demo-shell/src/app/components/app-layout/cloud/task-details-cloud-demo.component.html
index cfebffe344..3ed80ff5f4 100644
--- a/demo-shell/src/app/components/app-layout/cloud/task-details-cloud-demo.component.html
+++ b/demo-shell/src/app/components/app-layout/cloud/task-details-cloud-demo.component.html
@@ -4,3 +4,9 @@
Simple page to show the taskId: {{ taskId }} of the app: {{ applicationName }}
+
+
+
diff --git a/demo-shell/src/app/components/app-layout/cloud/task-details-cloud-demo.component.ts b/demo-shell/src/app/components/app-layout/cloud/task-details-cloud-demo.component.ts
index a3746998c6..96a328e79a 100644
--- a/demo-shell/src/app/components/app-layout/cloud/task-details-cloud-demo.component.ts
+++ b/demo-shell/src/app/components/app-layout/cloud/task-details-cloud-demo.component.ts
@@ -26,6 +26,7 @@ export class TaskDetailsCloudDemoComponent {
taskId: string;
applicationName: string;
+ readOnly = false;
constructor(private route: ActivatedRoute, private router: Router) {
this.route.params.subscribe((params) => {
diff --git a/demo-shell/src/app/components/task-list-cloud/task-list-cloud-demo.component.html b/demo-shell/src/app/components/task-list-cloud/task-list-cloud-demo.component.html
index b2740609f8..f06de51bcf 100644
--- a/demo-shell/src/app/components/task-list-cloud/task-list-cloud-demo.component.html
+++ b/demo-shell/src/app/components/task-list-cloud/task-list-cloud-demo.component.html
@@ -74,13 +74,6 @@
-
- Select First Row
-
diff --git a/demo-shell/src/app/components/task-list-cloud/task-list-cloud-demo.component.ts b/demo-shell/src/app/components/task-list-cloud/task-list-cloud-demo.component.ts
index 33b3809777..c5c3ee02d7 100644
--- a/demo-shell/src/app/components/task-list-cloud/task-list-cloud-demo.component.ts
+++ b/demo-shell/src/app/components/task-list-cloud/task-list-cloud-demo.component.ts
@@ -43,7 +43,6 @@ export class TaskListCloudDemoComponent implements OnInit {
createdDate: string;
dueDate: string;
selectionMode: string;
- selectFirstRow: boolean = false;
multiSelection: boolean = false;
statusOptions = [
@@ -153,10 +152,6 @@ export class TaskListCloudDemoComponent implements OnInit {
this.multiSelection = !this.multiSelection;
}
- toggleSelectFirstRow() {
- this.selectFirstRow = !this.selectFirstRow;
- }
-
showSelectedRows(rows: any) {
const selectedRows = rows.map((row) => {
diff --git a/docs/process-services-cloud/task-header-cloud.component.md b/docs/process-services-cloud/task-header-cloud.component.md
new file mode 100644
index 0000000000..43b1768fb2
--- /dev/null
+++ b/docs/process-services-cloud/task-header-cloud.component.md
@@ -0,0 +1,52 @@
+# [Task Header component](../../lib/process-services-cloud/task-header/components/task-header-cloud.component.ts "Defined in task-header.component.ts")
+
+Shows all the information related to 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. |
+| readOnly | `boolean` | false | Flag to set the component in Read Only Mode. This mode makes all the cells not clickable and not editable. |
+
+### Events
+
+| Name | Type | Description |
+| ---- | ---- | ----------- |
+| claim | [`EventEmitter`](https://angular.io/api/core/EventEmitter)`` | Emitted when the task is claimed. |
+| unclaim | [`EventEmitter`](https://angular.io/api/core/EventEmitter)`` | Emitted when the task is unclaimed (ie, requeued). |
+
+## Details
+
+The component populates an internal array of
+[CardViewModel](../core/card-view.component.md) with the information that we want to display.
+
+By default all properties are displayed:
+
+**_assignee_**, **_status_**, **_priority_**, **_dueDate_**, **_category_**, **_parentName_**, **_created_**, **_id_**, **_description_**, **_formName_**.
+
+However, you can also choose which properties to show using a configuration in `app.config.json`:
+
+```json
+ "adf-cloud-task-header": {
+ "presets": {
+ "properties" : [ "assignee", "status", "priority", "parentName"]
+ }
+ }
+```
+
+With this configuration, only the four listed properties will be shown.
diff --git a/docs/process-services-cloud/task-list-cloud.component.md b/docs/process-services-cloud/task-list-cloud.component.md
index fac2cdf087..7772851452 100644
--- a/docs/process-services-cloud/task-list-cloud.component.md
+++ b/docs/process-services-cloud/task-list-cloud.component.md
@@ -62,7 +62,6 @@ when the task list is empty:
| parentTaskId | `string` | "" | Filter the tasks. Display only tasks with parentTaskId equal to the supplied value. |
| processDefinitionId | `string` | "" | Filter the tasks. Display only tasks with processDefinitionId equal to the supplied value. |
| processInstanceId | `string` | "" | Filter the tasks. Display only tasks with processInstanceId equal to the supplied value. |
-| selectFirstRow | `boolean` | true | Toggles default selection of the first row. |
| selectionMode | `string` | "single" | Row selection mode. Can be none, `single` or `multiple`. For `multiple` mode, you can use the Cmd (macOS) or Ctrl (Win) modifier key to toggle selection for multiple rows. |
| sorting | [`TaskListCloudSortingModel`](../../lib/process-services-cloud/src/lib/task/task-list/models/task-list-sorting.model.ts)`[]` | | Specifies how the table should be sorted. The parameters are for BE sorting. |
| status | `string` | "" | Filter the tasks. Display only tasks with status equal to the supplied value. |
diff --git a/lib/process-services-cloud/src/lib/i18n/en.json b/lib/process-services-cloud/src/lib/i18n/en.json
index ce16e8c87c..eb0e3a9d9f 100644
--- a/lib/process-services-cloud/src/lib/i18n/en.json
+++ b/lib/process-services-cloud/src/lib/i18n/en.json
@@ -151,5 +151,36 @@
"ERROR": {
"NOT_FOUND": "No group found with the name {{groupName}}"
}
+ },
+ "ADF_CLOUD_TASK_HEADER": {
+ "BUTTON": {
+ "CLAIM": "Claim",
+ "UNCLAIM": "Requeue"
+ },
+ "PROPERTIES": {
+ "TASK_NAME": "Task",
+ "THUMBNAIL": "Thumbnail",
+ "DURATION": "Duration",
+ "PARENT_TASK_ID": "Parent task id",
+ "NAME": "Name",
+ "ASSIGNEE": "Assignee",
+ "ASSIGNEE_DEFAULT": "No assignee",
+ "PRIORITY": "Priority",
+ "DUE_DATE": "Due Date",
+ "DUE_DATE_DEFAULT": "No date",
+ "STATUS": "Status",
+ "CATEGORY": "Category",
+ "CATEGORY_DEFAULT": "No category",
+ "PARENT_NAME": "Parent name",
+ "PARENT_NAME_DEFAULT": "No parent",
+ "CREATED_BY": "Created By",
+ "CREATED": "Created",
+ "END_DATE": "End date",
+ "ID": "ID",
+ "DESCRIPTION": "Description",
+ "DESCRIPTION_DEFAULT": "No description",
+ "FORM_NAME": "Form Name",
+ "FORM_NAME_DEFAULT": "No form"
+ }
}
}
diff --git a/lib/process-services-cloud/src/lib/task/public-api.ts b/lib/process-services-cloud/src/lib/task/public-api.ts
index c15ea586a2..008d567778 100644
--- a/lib/process-services-cloud/src/lib/task/public-api.ts
+++ b/lib/process-services-cloud/src/lib/task/public-api.ts
@@ -18,4 +18,6 @@
export * from './task-list/public-api';
export * from './task-filters/public-api';
export * from './start-task/public-api';
+export * from './task-header/public-api';
+
export * from './task-cloud.module';
diff --git a/lib/process-services-cloud/src/lib/task/start-task/models/task-details-cloud.model.ts b/lib/process-services-cloud/src/lib/task/start-task/models/task-details-cloud.model.ts
index 6fdc98bd63..bd56601794 100644
--- a/lib/process-services-cloud/src/lib/task/start-task/models/task-details-cloud.model.ts
+++ b/lib/process-services-cloud/src/lib/task/start-task/models/task-details-cloud.model.ts
@@ -42,37 +42,43 @@ export class TaskDetailsCloudModel {
serviceName: string;
serviceFullName: string;
serviceVersion: string;
+ managerOfCandidateGroup: boolean;
+ memberOfCandidateGroup: boolean;
+ memberOfCandidateUsers: boolean;
- constructor(obj?: any) {
- if (obj) {
- this.id = obj.id || null;
- this.name = obj.name || null;
- this.appName = obj.appName || null;
- this.assignee = obj.assignee || null;
- this.appVersion = obj.appVersion || null;
- this.createdDate = obj.createdDate || null;
- this.claimedDate = obj.claimedDate || null;
- this.formKey = obj.formKey || null;
- this.description = obj.description || null;
- this.dueDate = obj.dueDate || null;
- this.lastModified = obj.lastModified || null;
- this.lastModifiedTo = obj.lastModifiedTo || null;
- this.lastModifiedFrom = obj.lastModifiedFrom || null;
- this.owner = obj.owner || null;
- this.parentTaskId = obj.parentTaskId || null;
- this.priority = obj.priority || null;
- this.processDefinitionId = obj.processDefinitionId || null;
- this.processInstanceId = obj.processInstanceId || null;
- this.serviceType = obj.serviceType || null;
- this.status = obj.status || null;
- this.standAlone = obj.standAlone || null;
- this.serviceName = obj.serviceName || null;
- this.serviceName = obj.serviceName || null;
- this.serviceFullName = obj.serviceFullName || null;
- this.serviceVersion = obj.serviceVersion || null;
- }
+ constructor(obj?: any) {
+ if (obj) {
+ this.id = obj.id || null;
+ this.name = obj.name || null;
+ this.appName = obj.appName || null;
+ this.assignee = obj.assignee || null;
+ this.appVersion = obj.appVersion || null;
+ this.createdDate = obj.createdDate || null;
+ this.claimedDate = obj.claimedDate || null;
+ this.formKey = obj.formKey || null;
+ this.description = obj.description || null;
+ this.dueDate = obj.dueDate || null;
+ this.lastModified = obj.lastModified || null;
+ this.lastModifiedTo = obj.lastModifiedTo || null;
+ this.lastModifiedFrom = obj.lastModifiedFrom || null;
+ this.owner = obj.owner || null;
+ this.parentTaskId = obj.parentTaskId || null;
+ this.priority = obj.priority || null;
+ this.processDefinitionId = obj.processDefinitionId || null;
+ this.processInstanceId = obj.processInstanceId || null;
+ this.serviceType = obj.serviceType || null;
+ this.status = obj.status || null;
+ this.standAlone = obj.standAlone || null;
+ this.serviceName = obj.serviceName || null;
+ this.serviceName = obj.serviceName || null;
+ this.serviceFullName = obj.serviceFullName || null;
+ this.serviceVersion = obj.serviceVersion || null;
+ this.managerOfCandidateGroup = obj.managerOfCandidateGroup || null;
+ this.memberOfCandidateGroup = obj.memberOfCandidateGroup || null;
+ this.memberOfCandidateUsers = obj.memberOfCandidateUsers || null;
}
- }
+ }
+}
export interface StartTaskCloudResponseModel {
entry: TaskDetailsCloudModel;
diff --git a/lib/process-services-cloud/src/lib/task/task-cloud.module.ts b/lib/process-services-cloud/src/lib/task/task-cloud.module.ts
index ccab6a2b0b..f378f5e36d 100644
--- a/lib/process-services-cloud/src/lib/task/task-cloud.module.ts
+++ b/lib/process-services-cloud/src/lib/task/task-cloud.module.ts
@@ -19,17 +19,20 @@ import { NgModule } from '@angular/core';
import { TaskListCloudModule } from './task-list/task-list-cloud.module';
import { TaskFiltersCloudModule } from './task-filters/task-filters-cloud.module';
import { StartTaskCloudModule } from './start-task/start-task-cloud.module';
+import { TaskHeaderCloudModule } from './task-header/task-header-cloud.module';
@NgModule({
imports: [
TaskListCloudModule,
TaskFiltersCloudModule,
- StartTaskCloudModule
+ StartTaskCloudModule,
+ TaskHeaderCloudModule
],
exports: [
TaskListCloudModule,
TaskFiltersCloudModule,
- StartTaskCloudModule
+ StartTaskCloudModule,
+ TaskHeaderCloudModule
]
})
export class TaskCloudModule { }
diff --git a/lib/process-services-cloud/src/lib/task/task-header/components/task-header-cloud.component.html b/lib/process-services-cloud/src/lib/task/task-header/components/task-header-cloud.component.html
new file mode 100644
index 0000000000..0bd14053ad
--- /dev/null
+++ b/lib/process-services-cloud/src/lib/task/task-header/components/task-header-cloud.component.html
@@ -0,0 +1,15 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/lib/process-services-cloud/src/lib/task/task-header/components/task-header-cloud.component.scss b/lib/process-services-cloud/src/lib/task/task-header/components/task-header-cloud.component.scss
new file mode 100644
index 0000000000..c59023f992
--- /dev/null
+++ b/lib/process-services-cloud/src/lib/task/task-header/components/task-header-cloud.component.scss
@@ -0,0 +1,40 @@
+@mixin adf-task-list-header-theme($theme) {
+ $primary: map-get($theme, primary);
+
+ .adf {
+ &-controls {
+ display: flex;
+ justify-content: space-between;
+ }
+
+ &-edit-controls {
+ display: flex;
+ justify-content: flex-end;
+ margin-left: auto;
+ }
+
+ &-switch-to-edit-mode,
+ &-save-edit-mode {
+ color: mat-color($primary);
+ }
+
+ &-cancel-edit-mode,
+ &-claim-controls {
+ color: rgb(131, 131, 131);
+ }
+
+ &-card-container {
+ font-family: inherit;
+ }
+
+ }
+
+ @media screen and ($mat-small) {
+ adf-card-view .adf-property-value {
+ text-overflow: ellipsis;
+ overflow: hidden;
+ white-space: nowrap;
+ }
+ }
+
+}
diff --git a/lib/process-services-cloud/src/lib/task/task-header/components/task-header-cloud.component.spec.ts b/lib/process-services-cloud/src/lib/task/task-header/components/task-header-cloud.component.spec.ts
new file mode 100644
index 0000000000..f3445840dd
--- /dev/null
+++ b/lib/process-services-cloud/src/lib/task/task-header/components/task-header-cloud.component.spec.ts
@@ -0,0 +1,155 @@
+/*!
+ * @license
+ * Copyright 2016 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 { async, ComponentFixture, TestBed } from '@angular/core/testing';
+import { setupTestBed, AppConfigService } from '@alfresco/adf-core';
+import { TaskHeaderCloudComponent } from './task-header-cloud.component';
+import { taskDetailsCloudMock } from '../mocks/task-details-cloud.mock';
+import { TaskHeaderCloudModule } from '../task-header-cloud.module';
+import { By } from '@angular/platform-browser';
+import { TaskHeaderCloudService } from '../services/task-header-cloud.service';
+import { of } from 'rxjs';
+import { ProcessServiceCloudTestingModule } from '../../../testing/process-service-cloud.testing.module';
+
+describe('TaskHeaderComponent', () => {
+ let component: TaskHeaderCloudComponent;
+ let fixture: ComponentFixture;
+ let service: TaskHeaderCloudService;
+ let appConfigService: AppConfigService;
+
+ setupTestBed({
+ imports: [
+ ProcessServiceCloudTestingModule,
+ TaskHeaderCloudModule
+ ]
+ });
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(TaskHeaderCloudComponent);
+ component = fixture.componentInstance;
+ component.appName = 'myApp';
+ component.taskId = taskDetailsCloudMock.id;
+ service = TestBed.get(TaskHeaderCloudService);
+ appConfigService = TestBed.get(AppConfigService);
+ spyOn(service, 'getTaskById').and.returnValue(of(taskDetailsCloudMock));
+ });
+
+ it('should render empty component if no task details provided', async(() => {
+ component.appName = undefined;
+ component.taskId = undefined;
+ fixture.detectChanges();
+ expect(fixture.debugElement.children.length).toBe(0);
+ }));
+
+ it('should display assignee', async(() => {
+ component.ngOnInit();
+ fixture.detectChanges();
+
+ fixture.whenStable().then(() => {
+ let formNameEl = fixture.debugElement.query(By.css('[data-automation-id="card-textitem-value-assignee"] span'));
+ expect(formNameEl.nativeElement.innerText).toBe('Wilbur Adams');
+ });
+ }));
+
+ it('should display placeholder if no assignee', async(() => {
+ component.ngOnInit();
+ component.taskDetails.assignee = null;
+ fixture.detectChanges();
+
+ fixture.whenStable().then(() => {
+ let valueEl = fixture.debugElement.query(By.css('[data-automation-id="card-textitem-value-assignee"] span'));
+ expect(valueEl.nativeElement.innerText).toBe('ADF_CLOUD_TASK_HEADER.PROPERTIES.ASSIGNEE_DEFAULT');
+ });
+
+ }));
+
+ it('should display priority', async(() => {
+ component.ngOnInit();
+ fixture.detectChanges();
+
+ fixture.whenStable().then(() => {
+ let formNameEl = fixture.debugElement.query(By.css('[data-automation-id="card-textitem-value-priority"]'));
+ expect(formNameEl.nativeElement.innerText).toBe('5');
+ });
+ }));
+
+ it('should display due date', async(() => {
+ component.ngOnInit();
+ fixture.detectChanges();
+
+ fixture.whenStable().then(() => {
+ let valueEl = fixture.debugElement.query(By.css('[data-automation-id="header-dueDate"] .adf-property-value'));
+ expect(valueEl.nativeElement.innerText.trim()).toBe('Dec 18 2018');
+ });
+ }));
+
+ it('should display placeholder if no due date', async(() => {
+ component.ngOnInit();
+ component.taskDetails.dueDate = null;
+ fixture.detectChanges();
+
+ fixture.whenStable().then(() => {
+ let valueEl = fixture.debugElement.query(By.css('[data-automation-id="header-dueDate"] .adf-property-value'));
+ expect(valueEl.nativeElement.innerText.trim()).toBe('ADF_CLOUD_TASK_HEADER.PROPERTIES.DUE_DATE_DEFAULT');
+ });
+ }));
+
+ it('should display the default parent value if is undefined', async(() => {
+ component.ngOnInit();
+ component.taskDetails.processInstanceId = null;
+ fixture.detectChanges();
+
+ fixture.whenStable().then(() => {
+ let valueEl = fixture.debugElement.query(By.css('[data-automation-id="header-parentName"] .adf-property-value'));
+ expect(valueEl.nativeElement.innerText.trim()).toEqual('ADF_CLOUD_TASK_HEADER.PROPERTIES.PARENT_NAME_DEFAULT');
+ });
+ }));
+
+ describe('Config Filtering', () => {
+
+ it('should show only the properties from the configuration file', async(() => {
+ spyOn(appConfigService, 'get').and.returnValue(['assignee', 'status']);
+ component.ngOnInit();
+ fixture.detectChanges();
+ let propertyList = fixture.debugElement.queryAll(By.css('.adf-property-list .adf-property'));
+
+ fixture.whenStable().then(() => {
+ expect(propertyList).toBeDefined();
+ expect(propertyList).not.toBeNull();
+ expect(propertyList.length).toBe(2);
+ expect(propertyList[0].nativeElement.textContent).toContain('ADF_CLOUD_TASK_HEADER.PROPERTIES.ASSIGNEE');
+ expect(propertyList[1].nativeElement.textContent).toContain('ADF_CLOUD_TASK_HEADER.PROPERTIES.STATUS');
+ });
+ }));
+
+ it('should show all the default properties if there is no configuration', async(() => {
+ spyOn(appConfigService, 'get').and.returnValue(null);
+ component.ngOnInit();
+ fixture.detectChanges();
+ fixture.detectChanges();
+
+ fixture.whenStable().then(() => {
+ let propertyList = fixture.debugElement.queryAll(By.css('.adf-property-list .adf-property'));
+ expect(propertyList).toBeDefined();
+ expect(propertyList).not.toBeNull();
+ expect(propertyList.length).toBe(component.properties.length);
+ expect(propertyList[0].nativeElement.textContent).toContain('ADF_CLOUD_TASK_HEADER.PROPERTIES.ASSIGNEE');
+ expect(propertyList[1].nativeElement.textContent).toContain('ADF_CLOUD_TASK_HEADER.PROPERTIES.STATUS');
+ });
+ }));
+ });
+});
diff --git a/lib/process-services-cloud/src/lib/task/task-header/components/task-header-cloud.component.ts b/lib/process-services-cloud/src/lib/task/task-header/components/task-header-cloud.component.ts
new file mode 100644
index 0000000000..33fa3ba60a
--- /dev/null
+++ b/lib/process-services-cloud/src/lib/task/task-header/components/task-header-cloud.component.ts
@@ -0,0 +1,273 @@
+/*!
+ * @license
+ * Copyright 2016 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, Input, OnInit, EventEmitter, Output } from '@angular/core';
+import {
+ CardViewDateItemModel,
+ CardViewItem,
+ CardViewTextItemModel,
+ CardViewBaseItemModel,
+ TranslationService,
+ AppConfigService,
+ CardViewMapItemModel,
+ UpdateNotification,
+ CardViewUpdateService,
+ StorageService
+} from '@alfresco/adf-core';
+import { TaskHeaderCloudService } from '../services/task-header-cloud.service';
+import { TaskDetailsCloudModel } from '../../start-task/models/task-details-cloud.model';
+
+@Component({
+ selector: 'adf-cloud-task-header',
+ templateUrl: './task-header-cloud.component.html',
+ styleUrls: ['./task-header-cloud.component.scss']
+})
+export class TaskHeaderCloudComponent implements OnInit {
+
+ /** (Required) The appName */
+ @Input()
+ appName: string;
+
+ /** (Required) The id of the task. */
+ @Input()
+ taskId: string;
+
+ /** The id of the task. */
+ @Input()
+ readOnly: boolean = false;
+
+ /** Emitted when the task is claimed. */
+ @Output()
+ claim: EventEmitter = new EventEmitter();
+
+ /** Emitted when the task is unclaimed (ie, requeued). */
+ @Output()
+ unclaim: EventEmitter = new EventEmitter();
+
+ taskDetails: TaskDetailsCloudModel = new TaskDetailsCloudModel();
+ properties: CardViewItem [];
+ inEdit: boolean = false;
+ private currentUser: string;
+
+ constructor(private taskHeaderCloudService: TaskHeaderCloudService,
+ private translationService: TranslationService,
+ private appConfig: AppConfigService,
+ private cardViewUpdateService: CardViewUpdateService,
+ private storage: StorageService) {
+ }
+
+ ngOnInit() {
+ this.loadCurrentBpmUserId();
+ if (this.appName && this.taskId) {
+ this.loadTaskDetailsById(this.appName, this.taskId);
+ }
+
+ this.cardViewUpdateService.itemUpdated$.subscribe(this.updateTaskDetails.bind(this));
+ }
+ loadCurrentBpmUserId(): any {
+ this.currentUser = this.storage.getItem('USERNAME');
+ }
+
+ loadTaskDetailsById(appName: string, taskId: string): any {
+ this.taskHeaderCloudService.getTaskById(appName, taskId).subscribe(
+ (taskDetails) => {
+ this.taskDetails = taskDetails;
+ this.refreshData();
+ });
+ }
+
+ private initDefaultProperties(parentInfoMap) {
+ return [
+ new CardViewTextItemModel(
+ {
+ label: 'ADF_CLOUD_TASK_HEADER.PROPERTIES.ASSIGNEE',
+ value: this.taskDetails.assignee,
+ key: 'assignee',
+ default: this.translationService.instant('ADF_CLOUD_TASK_HEADER.PROPERTIES.ASSIGNEE_DEFAULT'),
+ icon: 'create'
+ }
+ ),
+ new CardViewTextItemModel(
+ {
+ label: 'ADF_CLOUD_TASK_HEADER.PROPERTIES.STATUS',
+ value: this.taskDetails.status,
+ key: 'status'
+ }
+ ),
+ new CardViewTextItemModel(
+ {
+ label: 'ADF_CLOUD_TASK_HEADER.PROPERTIES.PRIORITY',
+ value: this.taskDetails.priority,
+ key: 'priority',
+ editable: this.isReadOnlyMode()
+ }
+ ),
+ new CardViewDateItemModel(
+ {
+ label: 'ADF_CLOUD_TASK_HEADER.PROPERTIES.DUE_DATE',
+ value: this.taskDetails.dueDate,
+ key: 'dueDate',
+ default: this.translationService.instant('ADF_CLOUD_TASK_HEADER.PROPERTIES.DUE_DATE_DEFAULT'),
+ editable: this.isReadOnlyMode()
+ }
+ ),
+ new CardViewTextItemModel(
+ {
+ label: 'ADF_CLOUD_TASK_HEADER.PROPERTIES.CATEGORY',
+ value: this.taskDetails.category,
+ key: 'category',
+ default: this.translationService.instant('ADF_CLOUD_TASK_HEADER.PROPERTIES.CATEGORY_DEFAULT')
+ }
+ ),
+ new CardViewDateItemModel(
+ {
+ label: 'ADF_CLOUD_TASK_HEADER.PROPERTIES.CREATED',
+ value: this.taskDetails.createdDate,
+ key: 'created'
+ }
+ ),
+ new CardViewMapItemModel(
+ {
+ label: 'ADF_CLOUD_TASK_HEADER.PROPERTIES.PARENT_NAME',
+ value: parentInfoMap,
+ key: 'parentName',
+ default: this.translationService.instant('ADF_CLOUD_TASK_HEADER.PROPERTIES.PARENT_NAME_DEFAULT'),
+ clickable: this.isReadOnlyMode()
+ }
+ ),
+ new CardViewTextItemModel(
+ {
+ label: 'ADF_CLOUD_TASK_HEADER.PROPERTIES.PARENT_TASK_ID',
+ value: this.taskDetails.parentTaskId,
+ key: 'parentTaskId'
+ }
+ ),
+ new CardViewDateItemModel(
+ {
+ label: 'ADF_CLOUD_TASK_HEADER.PROPERTIES.END_DATE',
+ value: this.taskDetails.claimedDate,
+ key: 'endDate'
+ }
+ ),
+ new CardViewTextItemModel(
+ {
+ label: 'ADF_CLOUD_TASK_HEADER.PROPERTIES.ID',
+ value: this.taskDetails.id,
+ key: 'id'
+ }
+ ),
+ new CardViewTextItemModel(
+ {
+ label: 'ADF_CLOUD_TASK_HEADER.PROPERTIES.DESCRIPTION',
+ value: this.taskDetails.description,
+ key: 'description',
+ default: this.translationService.instant('ADF_CLOUD_TASK_HEADER.PROPERTIES.DESCRIPTION_DEFAULT'),
+ multiline: true,
+ editable: this.isReadOnlyMode()
+ }
+ )
+ ];
+ }
+
+ /**
+ * Refresh the card data
+ */
+ refreshData() {
+ if (this.taskDetails) {
+ const defaultProperties = this.initDefaultProperties(this.getParentInfo());
+ const filteredProperties: string[] = this.appConfig.get('adf-cloud-task-header.presets.properties');
+ this.properties = defaultProperties.filter((cardItem) => this.isValidSelection(filteredProperties, cardItem));
+ }
+ }
+
+ /**
+ * Save a task detail and update it after a successful response
+ *
+ * @param updateNotification
+ */
+ private updateTaskDetails(updateNotification: UpdateNotification) {
+ this.taskHeaderCloudService.updateTask(this.appName, this.taskId, updateNotification.changed)
+ .subscribe(
+ (taskDetails) => {
+ this.taskDetails = taskDetails;
+ this.refreshData();
+ }
+ );
+ }
+
+ getParentInfo() {
+ if (this.taskDetails.processInstanceId && this.taskDetails.processDefinitionId) {
+ return new Map([[this.taskDetails.processInstanceId, this.taskDetails.processDefinitionId]]);
+ }
+ }
+
+ isCompleted() {
+ return this.taskDetails && this.taskDetails.status === 'completed';
+ }
+
+ isTaskClaimable(): boolean {
+ return !this.hasAssignee() && this.isCandidateMember();
+ }
+
+ hasAssignee(): boolean {
+ return !!this.taskDetails.assignee ? true : false;
+ }
+
+ isCandidateMember() {
+ return this.taskDetails.managerOfCandidateGroup || this.taskDetails.memberOfCandidateGroup || this.taskDetails.memberOfCandidateUsers;
+ }
+
+ isTaskClaimedByCandidateMember(): boolean {
+ return this.isCandidateMember() && this.isAssignedToCurrentUser() && !this.isCompleted();
+ }
+
+ isAssignedToCurrentUser(): boolean {
+ return this.hasAssignee() && this.isAssignedTo(this.currentUser);
+ }
+
+ isAssignedTo(userName): boolean {
+ return this.hasAssignee() ? this.taskDetails.assignee === userName : false;
+ }
+
+ isTaskValid() {
+ return this.appName && this.taskId;
+ }
+
+ isReadOnlyMode() {
+ return !this.readOnly;
+ }
+
+ claimTask() {
+ this.taskHeaderCloudService.claimTask(this.appName, this.taskId, this.currentUser).subscribe(
+ (res: any) => {
+ this.loadTaskDetailsById(this.appName, this.taskId);
+ this.claim.emit(this.taskId);
+ });
+ }
+
+ unclaimTask() {
+ this.taskHeaderCloudService.unclaimTask(this.appName, this.taskId).subscribe(
+ () => {
+ this.loadTaskDetailsById(this.appName, this.taskId);
+ this.unclaim.emit(this.taskId);
+ });
+ }
+
+ private isValidSelection(filteredProperties: string[], cardItem: CardViewBaseItemModel): boolean {
+ return filteredProperties ? filteredProperties.indexOf(cardItem.key) >= 0 : true;
+ }
+}
diff --git a/lib/process-services-cloud/src/lib/task/task-header/mocks/fake-task-details-response.mock.ts b/lib/process-services-cloud/src/lib/task/task-header/mocks/fake-task-details-response.mock.ts
new file mode 100644
index 0000000000..38c84b7280
--- /dev/null
+++ b/lib/process-services-cloud/src/lib/task/task-header/mocks/fake-task-details-response.mock.ts
@@ -0,0 +1,46 @@
+/*!
+ * @license
+ * Copyright 2016 Alfresco Software, Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+export const fakeTaskDetailsCloud = {
+ 'entry': {
+ 'serviceName': 'task-app-rb',
+ 'serviceFullName': 'task-app-rb',
+ 'serviceVersion': '',
+ 'appName': 'task-app',
+ 'appVersion': '',
+ 'serviceType': null,
+ 'id': '68d54a8f',
+ 'assignee': 'Phil Woods',
+ 'name': 'This is a new task ',
+ 'description': 'This is the description ',
+ 'createdDate': 1545048055900,
+ 'dueDate': 1545091200000,
+ 'claimedDate': 1545140162601,
+ 'priority': 0,
+ 'category': null,
+ 'processDefinitionId': null,
+ 'processInstanceId': null,
+ 'status': 'ASSIGNED',
+ 'owner': 'Phil Woods',
+ 'parentTaskId': null,
+ 'formKey': null,
+ 'lastModified': 1545140162601,
+ 'lastModifiedTo': null,
+ 'lastModifiedFrom': null,
+ 'standAlone': true
+ }
+};
diff --git a/lib/process-services-cloud/src/lib/task/task-header/mocks/task-details-cloud.mock.ts b/lib/process-services-cloud/src/lib/task/task-header/mocks/task-details-cloud.mock.ts
new file mode 100644
index 0000000000..4ed01973db
--- /dev/null
+++ b/lib/process-services-cloud/src/lib/task/task-header/mocks/task-details-cloud.mock.ts
@@ -0,0 +1,48 @@
+/*!
+ * @license
+ * Copyright 2016 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 { TaskDetailsCloudModel } from '../../start-task/models/task-details-cloud.model';
+
+export const taskDetailsCloudMock = new TaskDetailsCloudModel(
+ {
+ 'serviceName': 'task-app-rb',
+ 'serviceFullName': 'task-app-rb',
+ 'serviceVersion': '',
+ 'appName': 'task-app',
+ 'appVersion': '',
+ 'serviceType': null,
+ 'id': '68d54a8f-01f3-11e9-8e36-0a58646002ad',
+ 'assignee': 'Wilbur Adams',
+ 'name': 'This is a new task ',
+ 'description': 'This is the description ',
+ 'createdDate': 1545048055900,
+ 'dueDate': 1545091200000,
+ 'claimedDate': null,
+ 'priority': 5,
+ 'category': null,
+ 'processDefinitionId': null,
+ 'processInstanceId': null,
+ 'status': 'ASSIGNED',
+ 'owner': 'superadminuser',
+ 'parentTaskId': null,
+ 'formKey': null,
+ 'lastModified': 1545048055900,
+ 'lastModifiedTo': null,
+ 'lastModifiedFrom': null,
+ 'standAlone': true
+ }
+);
diff --git a/lib/process-services-cloud/src/lib/task/task-header/public-api.ts b/lib/process-services-cloud/src/lib/task/task-header/public-api.ts
new file mode 100644
index 0000000000..cdb2a35f47
--- /dev/null
+++ b/lib/process-services-cloud/src/lib/task/task-header/public-api.ts
@@ -0,0 +1,20 @@
+/*!
+ * @license
+ * Copyright 2016 Alfresco Software, Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+export * from './components/task-header-cloud.component';
+
+export * from './task-header-cloud.module';
diff --git a/lib/process-services-cloud/src/lib/task/task-header/services/task-header-cloud.service.spec.ts b/lib/process-services-cloud/src/lib/task/task-header/services/task-header-cloud.service.spec.ts
new file mode 100644
index 0000000000..ec7bd20829
--- /dev/null
+++ b/lib/process-services-cloud/src/lib/task/task-header/services/task-header-cloud.service.spec.ts
@@ -0,0 +1,245 @@
+/*!
+ * @license
+ * Copyright 2016 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 { async } from '@angular/core/testing';
+import { setupTestBed } from '@alfresco/adf-core';
+import { AlfrescoApiServiceMock, LogService, AppConfigService, StorageService, CoreModule } from '@alfresco/adf-core';
+import { fakeTaskDetailsCloud } from '../mocks/fake-task-details-response.mock';
+import { TaskHeaderCloudService } from './task-header-cloud.service';
+
+describe('Task Header Cloud Service', () => {
+
+ let service: TaskHeaderCloudService;
+ let alfrescoApiMock: AlfrescoApiServiceMock;
+
+ function returnFakeTaskDetailsResults() {
+ return {
+ oauth2Auth: {
+ callCustomApi : () => {
+ return Promise.resolve(fakeTaskDetailsCloud);
+ }
+ }
+ };
+ }
+
+ setupTestBed({
+ imports: [
+ CoreModule.forRoot()
+ ]
+ });
+
+ beforeEach(async(() => {
+ alfrescoApiMock = new AlfrescoApiServiceMock(new AppConfigService(null), new StorageService() );
+ service = new TaskHeaderCloudService(alfrescoApiMock,
+ new AppConfigService(null),
+ new LogService(new AppConfigService(null)));
+ }));
+
+ it('should return the task details when querying by id', (done) => {
+ const appName = 'taskp-app';
+ const taskId = '68d54a8f';
+ spyOn(alfrescoApiMock, 'getInstance').and.callFake(returnFakeTaskDetailsResults);
+ service.getTaskById(appName, taskId).subscribe((res: any) => {
+ expect(res).toBeDefined();
+ expect(res).not.toBeNull();
+ expect(res.appName).toBe('task-app');
+ expect(res.id).toBe('68d54a8f');
+ done();
+ });
+ });
+
+ it('should throw error if appName is not defined when querying by id', (done) => {
+ const appName = null;
+ const taskId = '68d54a8f';
+ spyOn(alfrescoApiMock, 'getInstance').and.callFake(returnFakeTaskDetailsResults);
+ service.getTaskById(appName, taskId).subscribe(
+ () => { },
+ (error) => {
+ expect(error).toBe('AppName/TaskId not configured');
+ done();
+ });
+ });
+
+ it('should throw error if taskId is not defined when querying by id', (done) => {
+ const appName = 'task-app';
+ const taskId = null;
+ spyOn(alfrescoApiMock, 'getInstance').and.callFake(returnFakeTaskDetailsResults);
+ service.getTaskById(appName, taskId).subscribe(
+ () => { },
+ (error) => {
+ expect(error).toBe('AppName/TaskId not configured');
+ done();
+ });
+ });
+
+ it('should return the task details when updating a task', (done) => {
+ const appName = 'taskp-app';
+ const taskId = '68d54a8f';
+ const updatePayload = { description: 'New description' };
+ spyOn(alfrescoApiMock, 'getInstance').and.callFake(returnFakeTaskDetailsResults);
+ service.updateTask(appName, taskId, updatePayload).subscribe((res: any) => {
+ expect(res).toBeDefined();
+ expect(res).not.toBeNull();
+ expect(res.appName).toBe('task-app');
+ expect(res.id).toBe('68d54a8f');
+ done();
+ });
+ });
+
+ it('should throw error if appName is not defined when updating a task', (done) => {
+ const appName = null;
+ const taskId = '68d54a8f';
+ const updatePayload = { description: 'New description' };
+ spyOn(alfrescoApiMock, 'getInstance').and.callFake(returnFakeTaskDetailsResults);
+ service.updateTask(appName, taskId, updatePayload).subscribe(
+ () => { },
+ (error) => {
+ expect(error).toBe('AppName/TaskId not configured');
+ done();
+ });
+ });
+
+ it('should throw error if taskId is not defined when updating a task', (done) => {
+ const appName = 'task-app';
+ const taskId = null;
+ const updatePayload = { description: 'New description' };
+ spyOn(alfrescoApiMock, 'getInstance').and.callFake(returnFakeTaskDetailsResults);
+ service.updateTask(appName, taskId, updatePayload).subscribe(
+ () => { },
+ (error) => {
+ expect(error).toBe('AppName/TaskId not configured');
+ done();
+ });
+ });
+
+ it('should return the task details when updating a task', (done) => {
+ const appName = 'taskp-app';
+ const taskId = '68d54a8f';
+ const updatePayload = { description: 'New description' };
+ spyOn(alfrescoApiMock, 'getInstance').and.callFake(returnFakeTaskDetailsResults);
+ service.updateTask(appName, taskId, updatePayload).subscribe((res: any) => {
+ expect(res).toBeDefined();
+ expect(res).not.toBeNull();
+ expect(res.appName).toBe('task-app');
+ expect(res.id).toBe('68d54a8f');
+ done();
+ });
+ });
+
+ it('should throw error if appName is not defined when querying by id', (done) => {
+ const appName = null;
+ const taskId = '68d54a8f';
+ const updatePayload = { description: 'New description' };
+ spyOn(alfrescoApiMock, 'getInstance').and.callFake(returnFakeTaskDetailsResults);
+ service.updateTask(appName, taskId, updatePayload).subscribe(
+ () => { },
+ (error) => {
+ expect(error).toBe('AppName/TaskId not configured');
+ done();
+ });
+ });
+
+ it('should throw error if taskId is not defined updating a task', (done) => {
+ const appName = 'task-app';
+ const taskId = null;
+ const updatePayload = { description: 'New description' };
+ spyOn(alfrescoApiMock, 'getInstance').and.callFake(returnFakeTaskDetailsResults);
+ service.updateTask(appName, taskId, updatePayload).subscribe(
+ () => { },
+ (error) => {
+ expect(error).toBe('AppName/TaskId not configured');
+ done();
+ });
+ });
+
+ it('should return the task details when claiming a task', (done) => {
+ const appName = 'taskp-app';
+ const assignee = 'user12';
+ const taskId = '68d54a8f';
+ spyOn(alfrescoApiMock, 'getInstance').and.callFake(returnFakeTaskDetailsResults);
+ service.claimTask(appName, taskId, assignee).subscribe((res: any) => {
+ expect(res).toBeDefined();
+ expect(res).not.toBeNull();
+ expect(res.appName).toBe('task-app');
+ expect(res.id).toBe('68d54a8f');
+ done();
+ });
+ });
+
+ it('should throw error if appName is not defined when claiming a task', (done) => {
+ const appName = null;
+ const taskId = '68d54a8f';
+ const assignee = 'user12';
+ spyOn(alfrescoApiMock, 'getInstance').and.callFake(returnFakeTaskDetailsResults);
+ service.claimTask(appName, taskId, assignee).subscribe(
+ () => { },
+ (error) => {
+ expect(error).toBe('AppName/TaskId not configured');
+ done();
+ });
+ });
+
+ it('should throw error if taskId is not defined when claiming a task', (done) => {
+ const appName = 'task-app';
+ const taskId = null;
+ const assignee = 'user12';
+ spyOn(alfrescoApiMock, 'getInstance').and.callFake(returnFakeTaskDetailsResults);
+ service.claimTask(appName, taskId, assignee).subscribe(
+ () => { },
+ (error) => {
+ expect(error).toBe('AppName/TaskId not configured');
+ done();
+ });
+ });
+
+ it('should return the task details when unclaiming a task', (done) => {
+ const appName = 'taskp-app';
+ const taskId = '68d54a8f';
+ spyOn(alfrescoApiMock, 'getInstance').and.callFake(returnFakeTaskDetailsResults);
+ service.unclaimTask(appName, taskId).subscribe((res: any) => {
+ expect(res).toBeDefined();
+ expect(res).not.toBeNull();
+ expect(res.appName).toBe('task-app');
+ expect(res.id).toBe('68d54a8f');
+ done();
+ });
+ });
+
+ it('should throw error if appName is not defined when unclaiming a task', (done) => {
+ const appName = null;
+ const taskId = '68d54a8f';
+ spyOn(alfrescoApiMock, 'getInstance').and.callFake(returnFakeTaskDetailsResults);
+ service.unclaimTask(appName, taskId).subscribe(
+ () => { },
+ (error) => {
+ expect(error).toBe('AppName/TaskId not configured');
+ done();
+ });
+ });
+
+ it('should throw error if taskId is not defined when unclaiming a task', (done) => {
+ const appName = 'task-app';
+ const taskId = null;
+ spyOn(alfrescoApiMock, 'getInstance').and.callFake(returnFakeTaskDetailsResults);
+ service.unclaimTask(appName, taskId).subscribe(
+ () => { },
+ (error) => {
+ expect(error).toBe('AppName/TaskId not configured');
+ done();
+ });
+ });
+});
diff --git a/lib/process-services-cloud/src/lib/task/task-header/services/task-header-cloud.service.ts b/lib/process-services-cloud/src/lib/task/task-header/services/task-header-cloud.service.ts
new file mode 100644
index 0000000000..77c72bd4ea
--- /dev/null
+++ b/lib/process-services-cloud/src/lib/task/task-header/services/task-header-cloud.service.ts
@@ -0,0 +1,134 @@
+/*!
+ * @license
+ * Copyright 2016 Alfresco Software, Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import { AlfrescoApiService, LogService, AppConfigService } from '@alfresco/adf-core';
+import { Injectable } from '@angular/core';
+import { Observable, from, throwError } from 'rxjs';
+import { catchError, map } from 'rxjs/operators';
+import { TaskDetailsCloudModel } from '../../start-task/models/task-details-cloud.model';
+
+@Injectable({
+ providedIn: 'root'
+})
+export class TaskHeaderCloudService {
+ contextRoot: string;
+ contentTypes = ['application/json'];
+ accepts = ['application/json'];
+ returnType = Object;
+
+ constructor(private alfrescoApiService: AlfrescoApiService,
+ private appConfigService: AppConfigService,
+ private logService: LogService) {
+ this.contextRoot = this.appConfigService.get('bpmHost', '');
+ }
+
+ getTaskById(appName: string, taskId: string): Observable {
+ if (appName && taskId) {
+
+ let queryUrl = `${this.contextRoot}/${appName}-query/v1/tasks/${taskId}`;
+ return from(this.alfrescoApiService.getInstance()
+ .oauth2Auth.callCustomApi(queryUrl, 'GET',
+ null, null, null,
+ null, null,
+ this.contentTypes, this.accepts,
+ this.returnType, null, null)
+ ).pipe(
+ map((res: any) => {
+ return new TaskDetailsCloudModel(res.entry);
+ }),
+ catchError((err) => this.handleError(err))
+ );
+ } else {
+ this.logService.error('AppName and TaskId are mandatory for querying a task');
+ return throwError('AppName/TaskId not configured');
+ }
+ }
+
+ updateTask(appName: string, taskId: string, updatePayload: any): any {
+ if (appName && taskId) {
+
+ updatePayload.payloadType = 'UpdateTaskPayload';
+
+ let queryUrl = `${this.contextRoot}/${appName}-rb/v1/tasks/${taskId}`;
+ return from(this.alfrescoApiService.getInstance()
+ .oauth2Auth.callCustomApi(queryUrl, 'PUT',
+ null, null, null,
+ null, updatePayload,
+ this.contentTypes, this.accepts,
+ this.returnType, null, null)
+ ).pipe(
+ map((res: any) => {
+ return new TaskDetailsCloudModel(res.entry);
+ }),
+ catchError((err) => this.handleError(err))
+ );
+ } else {
+ this.logService.error('AppName and TaskId are mandatory for querying a task');
+ return throwError('AppName/TaskId not configured');
+ }
+ }
+
+ claimTask(appName: string, taskId: string, assignee: string): any {
+ if (appName && taskId) {
+
+ let queryUrl = `${this.contextRoot}/${appName}-rb/v1/tasks/${taskId}/claim?assignee=${assignee}`;
+ return from(this.alfrescoApiService.getInstance()
+ .oauth2Auth.callCustomApi(queryUrl, 'POST',
+ null, null, null,
+ null, null,
+ this.contentTypes, this.accepts,
+ this.returnType, null, null)
+ ).pipe(
+ map((res: any) => {
+ return new TaskDetailsCloudModel(res.entry);
+ }),
+ catchError((err) => this.handleError(err))
+ );
+ } else {
+ this.logService.error('AppName and TaskId are mandatory for querying a task');
+ return throwError('AppName/TaskId not configured');
+ }
+ }
+
+ unclaimTask(appName: string, taskId: string): any {
+ if (appName && taskId) {
+
+ let queryUrl = `${this.contextRoot}/${appName}-rb/v1/tasks/${taskId}/release`;
+ return from(this.alfrescoApiService.getInstance()
+ .oauth2Auth.callCustomApi(queryUrl, 'POST',
+ null, null, null,
+ null, null,
+ this.contentTypes, this.accepts,
+ this.returnType, null, null)
+ ).pipe(
+ map((res: any) => {
+ return new TaskDetailsCloudModel(res.entry);
+ }),
+ catchError((err) => this.handleError(err))
+ );
+ } else {
+ this.logService.error('AppName and TaskId are mandatory for querying a task');
+ return throwError('AppName/TaskId not configured');
+ }
+ }
+
+ private handleError(error: any) {
+ this.logService.error(error);
+ return throwError(error || 'Server error');
+ }
+
+}
diff --git a/lib/process-services-cloud/src/lib/task/task-header/task-header-cloud.module.spec.ts b/lib/process-services-cloud/src/lib/task/task-header/task-header-cloud.module.spec.ts
new file mode 100644
index 0000000000..209c424646
--- /dev/null
+++ b/lib/process-services-cloud/src/lib/task/task-header/task-header-cloud.module.spec.ts
@@ -0,0 +1,30 @@
+/*!
+ * @license
+ * Copyright 2016 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 { TaskHeaderCloudModule } from './task-header-cloud.module';
+
+describe('TaskCloudModule', () => {
+ let taskHeaderCloudModule: TaskHeaderCloudModule;
+
+ beforeEach(() => {
+ taskHeaderCloudModule = new TaskHeaderCloudModule();
+ });
+
+ it('should create an instance', () => {
+ expect(taskHeaderCloudModule).toBeTruthy();
+ });
+});
diff --git a/lib/process-services-cloud/src/lib/task/task-header/task-header-cloud.module.ts b/lib/process-services-cloud/src/lib/task/task-header/task-header-cloud.module.ts
new file mode 100644
index 0000000000..a2bec75020
--- /dev/null
+++ b/lib/process-services-cloud/src/lib/task/task-header/task-header-cloud.module.ts
@@ -0,0 +1,50 @@
+/*!
+ * @license
+ * Copyright 2016 Alfresco Software, Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import { NgModule } from '@angular/core';
+import { CommonModule } from '@angular/common';
+import { MaterialModule } from '../../material.module';
+import { TranslateModule, TranslateLoader } from '@ngx-translate/core';
+import { TranslateLoaderService, DataTableModule, TemplateModule, CardViewModule } from '@alfresco/adf-core';
+import { TaskHeaderCloudComponent } from './components/task-header-cloud.component';
+import { TaskHeaderCloudService } from './services/task-header-cloud.service';
+
+@NgModule({
+ imports: [
+ CommonModule,
+ TranslateModule.forRoot({
+ loader: {
+ provide: TranslateLoader,
+ useClass: TranslateLoaderService
+ }
+ }),
+ MaterialModule,
+ DataTableModule,
+ TemplateModule,
+ CardViewModule
+ ],
+ declarations: [
+ TaskHeaderCloudComponent
+ ],
+ exports: [
+ TaskHeaderCloudComponent
+ ],
+ providers: [
+ TaskHeaderCloudService
+ ]
+})
+export class TaskHeaderCloudModule { }
diff --git a/lib/process-services-cloud/src/lib/task/task-list/components/task-list-cloud.component.ts b/lib/process-services-cloud/src/lib/task/task-list/components/task-list-cloud.component.ts
index 03e8360f85..18d56037a1 100644
--- a/lib/process-services-cloud/src/lib/task/task-list/components/task-list-cloud.component.ts
+++ b/lib/process-services-cloud/src/lib/task/task-list/components/task-list-cloud.component.ts
@@ -85,10 +85,6 @@ export class TaskListCloudComponent extends DataTableSchema implements OnChanges
@Input()
status: string = '';
- /** Toggles default selection of the first row. */
- @Input()
- selectFirstRow: boolean = true;
-
/**
* Define which task id should be selected after reloading. If the task id doesn't
* exist or nothing is passed then the first task will be selected.
@@ -220,9 +216,6 @@ export class TaskListCloudComponent extends DataTableSchema implements OnChanges
return currentRow.entry.id === taskIdSelected;
});
}
- if (!dataRow && this.selectFirstRow) {
- dataRow = this.rows[0];
- }
if (dataRow) {
dataRow.isSelected = true;
this.currentInstanceId = dataRow.entry.id;
diff --git a/scripts/affected-libs.sh b/scripts/affected-libs.sh
index 80542dacd7..aac1fbb015 100755
--- a/scripts/affected-libs.sh
+++ b/scripts/affected-libs.sh
@@ -40,7 +40,7 @@ if [ ! -d "$DIRECTORY" ]; then
fi
if [ ! -f $DIRECTORY/deps.txt ]; then
- npm run affected:libs -- $HEAD_SHA_BRANCH "HEAD" > $DIRECTORY/deps.txt
+ npm run affected:libs -- $HEAD_SHA_BRANCH "HEAD" > $DIRECTORY/deps.txt || ( echo "This PR needs to be rebased"; exit 1 )
fi
cat $DIRECTORY/deps.txt