diff --git a/demo-shell-ng2/app/components/activiti/activiti-demo.component.html b/demo-shell-ng2/app/components/activiti/activiti-demo.component.html index 3faac514e3..f7b4a74c04 100644 --- a/demo-shell-ng2/app/components/activiti/activiti-demo.component.html +++ b/demo-shell-ng2/app/components/activiti/activiti-demo.component.html @@ -36,6 +36,7 @@ [state]="taskFilter.filter.state" [sort]="taskFilter.filter.sort" [data]="dataTasks" + [landingTaskId]="currentTaskId" (rowClick)="onTaskRowClick($event)" (onSuccess)="onSuccessTaskList($event)" #activititasklist> @@ -43,6 +44,7 @@
Task Details

diff --git a/demo-shell-ng2/app/components/activiti/activiti-demo.component.ts b/demo-shell-ng2/app/components/activiti/activiti-demo.component.ts index 2ac2458a4b..c7daf6051c 100644 --- a/demo-shell-ng2/app/components/activiti/activiti-demo.component.ts +++ b/demo-shell-ng2/app/components/activiti/activiti-demo.component.ts @@ -216,6 +216,11 @@ export class ActivitiDemoComponent implements AfterViewInit { this.currentTaskId = null; } + onTaskCreated(data: any) { + this.currentTaskId = data.parentTaskId; + this.activititasklist.reload(); + } + ngAfterViewInit() { // workaround for MDL issues with dynamic components if (componentHandler) { diff --git a/ng2-components/ng2-activiti-tasklist/README.md b/ng2-components/ng2-activiti-tasklist/README.md index 8c36a53110..11aacfe5cf 100644 --- a/ng2-components/ng2-activiti-tasklist/README.md +++ b/ng2-components/ng2-activiti-tasklist/README.md @@ -218,17 +218,13 @@ platformBrowserDynamic().bootstrapModule(AppModule); | Name | Description | | --- | --- | -|`appId`| { appId } The id of the app. | -|`processDefinitionKey`| { processDefinitionKey } The processDefinitionKey of the process. | -|`assignment`| { assignment } The assignment of the process. -Possible values are: -assignee : where the current user is the assignee -candidate: where the current user is a task candidate -group_x: where the task is assigned to a group where the current user is a member of. The groups can be fetched through the profile REST endpoint -no value: where the current user is involved | -|`state`| { state } Define state of the processes. Possible values are: completed, active | -|`sort`| { sort } Define the sort of the processes. Possible values are created-desc, created-asc, due-desc, due-asc | -| `schemaColumn` | { any[] } optional) JSON object that represent the number and the type of the columns that you want show | +|`appId`| { string } The id of the app. | +|`processDefinitionKey`| { string } The processDefinitionKey of the process. | +|`assignment`| { string } The assignment of the process. | +|`state`| { string } Define state of the processes. Possible values are: completed, active | +|`landingTaskId`| { string } Define which task id should be selected after the reloading. If the task id doesn't exist or nothing is passed it will select the first task | +|`sort`| { string } Define the sort of the processes. Possible values are : created-desc, created-asc, due-desc, due-asc | +| `data` | { DataTableAdapter } (optional) JSON object that represent the number and the type of the columns that you want show | Example: @@ -256,6 +252,7 @@ The component shows the details of the task id passed in input | `formLoaded` | Invoked when form is loaded or reloaded. | | `formSaved` | Invoked when form is submitted with `Save` or custom outcomes. | | `formCompleted` | Invoked when form is submitted with `Complete` outcome. | +| `taskCreated` | Invoked when a checklist task is created. | | `executeOutcome` | Invoked when any outcome is executed, default behaviour can be prevented via `event.preventDefault()` | | `onError` | Invoked at any error | diff --git a/ng2-components/ng2-activiti-tasklist/src/components/activiti-checklist.component.spec.ts b/ng2-components/ng2-activiti-tasklist/src/components/activiti-checklist.component.spec.ts index 88a0374771..6e4de16d10 100644 --- a/ng2-components/ng2-activiti-tasklist/src/components/activiti-checklist.component.spec.ts +++ b/ng2-components/ng2-activiti-tasklist/src/components/activiti-checklist.component.spec.ts @@ -51,7 +51,9 @@ describe('ActivitiChecklist', () => { }).compileComponents().then(() => { let translateService = TestBed.get(AlfrescoTranslateService); spyOn(translateService, 'addTranslationFolder').and.stub(); - spyOn(translateService, 'get').and.callFake((key) => { return Observable.of(key); }); + spyOn(translateService, 'get').and.callFake((key) => { + return Observable.of(key); + }); fixture = TestBed.createComponent(ActivitiChecklist); checklistComponent = fixture.componentInstance; @@ -129,7 +131,7 @@ describe('ActivitiChecklist', () => { jasmine.Ajax.requests.mostRecent().respondWith({ status: 200, contentType: 'json', - responseText: {id: 'fake-check-added-id', name: 'fake-check-added-name'} + responseText: { id: 'fake-check-added-id', name: 'fake-check-added-name' } }); fixture.whenStable().then(() => { fixture.detectChanges(); @@ -149,7 +151,7 @@ describe('ActivitiChecklist', () => { jasmine.Ajax.requests.mostRecent().respondWith({ status: 200, contentType: 'json', - responseText: {data: [{id: 'fake-check-changed-id', name: 'fake-check-changed-name'}]} + responseText: { data: [{ id: 'fake-check-changed-id', name: 'fake-check-changed-name' }] } }); fixture.whenStable().then(() => { fixture.detectChanges(); @@ -173,6 +175,25 @@ describe('ActivitiChecklist', () => { expect(element.querySelector('#checklist-none-message').textContent).toContain('TASK_DETAILS.CHECKLIST.NONE'); }); })); + + it('should emit checklist task created event when the checklist is successfully added', (done) => { + checklistComponent.checklistTaskCreated.subscribe((taskAdded: TaskDetailsModel) => { + fixture.detectChanges(); + expect(taskAdded.id).toEqual('fake-check-added-id'); + expect(taskAdded.name).toEqual('fake-check-added-name'); + expect(element.querySelector('#check-fake-check-added-id')).not.toBeNull(); + expect(element.querySelector('#check-fake-check-added-id').textContent).toContain('fake-check-added-name'); + done(); + }); + showChecklistDialog.click(); + let addButtonDialog = element.querySelector('#add-check'); + addButtonDialog.click(); + jasmine.Ajax.requests.mostRecent().respondWith({ + status: 200, + contentType: 'json', + responseText: { id: 'fake-check-added-id', name: 'fake-check-added-name' } + }); + }); }); }); diff --git a/ng2-components/ng2-activiti-tasklist/src/components/activiti-checklist.component.ts b/ng2-components/ng2-activiti-tasklist/src/components/activiti-checklist.component.ts index c0aced73f9..57dcfb8793 100644 --- a/ng2-components/ng2-activiti-tasklist/src/components/activiti-checklist.component.ts +++ b/ng2-components/ng2-activiti-tasklist/src/components/activiti-checklist.component.ts @@ -15,11 +15,11 @@ * limitations under the License. */ -import { Component, Input, OnInit, ViewChild, OnChanges, SimpleChanges } from '@angular/core'; -import { Observer, Observable } from 'rxjs/Rx'; +import { Component, Input, OnInit, ViewChild, OnChanges, SimpleChanges, EventEmitter, Output } from '@angular/core'; import { AlfrescoTranslateService, LogService } from 'ng2-alfresco-core'; import { ActivitiTaskListService } from './../services/activiti-tasklist.service'; import { TaskDetailsModel } from '../models/task-details.model'; +import { Observer, Observable } from 'rxjs/Rx'; declare let dialogPolyfill: any; @@ -41,6 +41,9 @@ export class ActivitiChecklist implements OnInit, OnChanges { @Input() assignee: string; + @Output() + checklistTaskCreated: EventEmitter = new EventEmitter(); + @ViewChild('dialog') dialog: any; @@ -116,6 +119,7 @@ export class ActivitiChecklist implements OnInit, OnChanges { this.activitiTaskList.addTask(newTask).subscribe( (res: TaskDetailsModel) => { this.checklist.push(res); + this.checklistTaskCreated.emit(res); }, (err) => { this.logService.error(err); diff --git a/ng2-components/ng2-activiti-tasklist/src/components/activiti-task-details.component.html b/ng2-components/ng2-activiti-tasklist/src/components/activiti-task-details.component.html index e65cce9585..7d1d86a2b3 100644 --- a/ng2-components/ng2-activiti-tasklist/src/components/activiti-task-details.component.html +++ b/ng2-components/ng2-activiti-tasklist/src/components/activiti-task-details.component.html @@ -24,7 +24,7 @@
+ (checklistTaskCreated)="onChecklistTaskCreated($event)" #activitichecklist>
diff --git a/ng2-components/ng2-activiti-tasklist/src/components/activiti-task-details.component.spec.ts b/ng2-components/ng2-activiti-tasklist/src/components/activiti-task-details.component.spec.ts index effa712aaf..ef67877cdf 100644 --- a/ng2-components/ng2-activiti-tasklist/src/components/activiti-task-details.component.spec.ts +++ b/ng2-components/ng2-activiti-tasklist/src/components/activiti-task-details.component.spec.ts @@ -27,6 +27,7 @@ import { ActivitiTaskDetails } from './activiti-task-details.component'; import { ActivitiTaskListService } from './../services/activiti-tasklist.service'; import { ActivitiPeopleService } from './../services/activiti-people.service'; import { taskDetailsMock, taskFormMock, tasksMock, noDataMock } from './../assets/task-details.mock'; +import { TaskDetailsModel } from '../models/task-details.model'; describe('ActivitiTaskDetails', () => { @@ -246,6 +247,13 @@ describe('ActivitiTaskDetails', () => { expect(closeSpy).toHaveBeenCalled(); }); + it('should emit a task created event when checklist task is created', () => { + let emitSpy: jasmine.Spy = spyOn(component.taskCreated, 'emit'); + let mockTask = new TaskDetailsModel(taskDetailsMock); + component.onChecklistTaskCreated(mockTask); + expect(emitSpy).toHaveBeenCalled(); + }); + }); }); diff --git a/ng2-components/ng2-activiti-tasklist/src/components/activiti-task-details.component.ts b/ng2-components/ng2-activiti-tasklist/src/components/activiti-task-details.component.ts index d8fd6f3729..3ccc99870c 100644 --- a/ng2-components/ng2-activiti-tasklist/src/components/activiti-task-details.component.ts +++ b/ng2-components/ng2-activiti-tasklist/src/components/activiti-task-details.component.ts @@ -70,6 +70,9 @@ export class ActivitiTaskDetails implements OnInit, OnChanges { @Output() formLoaded: EventEmitter = new EventEmitter(); + @Output() + taskCreated: EventEmitter = new EventEmitter(); + @Output() onError: EventEmitter = new EventEmitter(); @@ -224,6 +227,10 @@ export class ActivitiTaskDetails implements OnInit, OnChanges { this.formLoaded.emit(form); } + onChecklistTaskCreated(task: TaskDetailsModel) { + this.taskCreated.emit(task); + } + onFormError(error: any) { this.errorDialog.nativeElement.showModal(); this.onError.emit(error); diff --git a/ng2-components/ng2-activiti-tasklist/src/components/activiti-tasklist.component.spec.ts b/ng2-components/ng2-activiti-tasklist/src/components/activiti-tasklist.component.spec.ts index 8ca3823570..fc4b02eb59 100644 --- a/ng2-components/ng2-activiti-tasklist/src/components/activiti-tasklist.component.spec.ts +++ b/ng2-components/ng2-activiti-tasklist/src/components/activiti-tasklist.component.spec.ts @@ -161,7 +161,7 @@ describe('ActivitiTaskList', () => { }); it('should return a currentId null when the taskList is empty', () => { - component.selectFirst(); + component.selectTask(null); expect(component.getCurrentId()).toBeNull(); }); diff --git a/ng2-components/ng2-activiti-tasklist/src/components/activiti-tasklist.component.ts b/ng2-components/ng2-activiti-tasklist/src/components/activiti-tasklist.component.ts index d5aee51d73..db9ae4d8c0 100644 --- a/ng2-components/ng2-activiti-tasklist/src/components/activiti-tasklist.component.ts +++ b/ng2-components/ng2-activiti-tasklist/src/components/activiti-tasklist.component.ts @@ -49,6 +49,9 @@ export class ActivitiTaskList implements OnInit, OnChanges { @Input() name: string; + @Input() + landingTaskId: string; + requestNode: TaskQueryRequestRepresentationModel; @Input() @@ -142,7 +145,7 @@ export class ActivitiTaskList implements OnInit, OnChanges { (response) => { let instancesRow = this.createDataRow(response); this.renderInstances(instancesRow); - this.selectFirst(); + this.selectTask(requestNode.landingTaskId); this.onSuccess.emit(response); }, (error) => { this.logService.error(error); @@ -182,16 +185,24 @@ export class ActivitiTaskList implements OnInit, OnChanges { } /** - * Select the first instance of a list if present + * Select the task given in input if present */ - selectFirst() { + selectTask(taskIdToSelect: string) { if (!this.isListEmpty()) { - this.currentInstanceId = this.data.getRows()[0].getValue('id'); + let dataRow = this.data.getRows().find(row => row.getValue('id') === taskIdToSelect); + this.currentInstanceId = dataRow ? dataRow.getValue('id') : this.selectFirst(); } else { this.currentInstanceId = null; } } + /** + * Select the first instance of a list if present + */ + selectFirst() { + return this.data.getRows()[0].getValue('id'); + } + /** * Return the current id * @returns {string} @@ -239,7 +250,8 @@ export class ActivitiTaskList implements OnInit, OnChanges { text: this.name, assignment: this.assignment, state: this.state, - sort: this.sort + sort: this.sort, + landingTaskId: this.landingTaskId }; return new TaskQueryRequestRepresentationModel(requestNode); } diff --git a/ng2-components/ng2-activiti-tasklist/src/models/filter.model.ts b/ng2-components/ng2-activiti-tasklist/src/models/filter.model.ts index 09a8c88256..fb23c2f2f2 100644 --- a/ng2-components/ng2-activiti-tasklist/src/models/filter.model.ts +++ b/ng2-components/ng2-activiti-tasklist/src/models/filter.model.ts @@ -116,6 +116,7 @@ export class TaskQueryRequestRepresentationModel { sort: string; page: number; size: number; + landingTaskId: string; constructor(obj?: any) { this.appDefinitionId = obj && obj.appDefinitionId || null; @@ -128,5 +129,6 @@ export class TaskQueryRequestRepresentationModel { this.sort = obj && obj.sort || null; this.page = obj && obj.page || 0; this.size = obj && obj.size || 25; + this.landingTaskId = obj && obj.landingTaskId || ''; } }