From c6cd7d6b40973442c38da054f182c940ad6f9cf3 Mon Sep 17 00:00:00 2001 From: Martin Bergljung Date: Thu, 23 Nov 2017 11:31:36 +0000 Subject: [PATCH] [ADF-1586] TaskListService & TaskFilterService documentation update because of 2.0 reorg (#2705) --- docs/task-filter.service.md | 324 ++++++++++++++++++ docs/tasklist.service.md | 650 ++++++++++++++++++++++++++++++++++++ 2 files changed, 974 insertions(+) create mode 100644 docs/task-filter.service.md create mode 100644 docs/tasklist.service.md diff --git a/docs/task-filter.service.md b/docs/task-filter.service.md new file mode 100644 index 0000000000..628c88f3a7 --- /dev/null +++ b/docs/task-filter.service.md @@ -0,0 +1,324 @@ +# Task Filter Service +Manage Task Filters, which are pre-configured Task Instance queries. + +## Importing + +```ts +import { TaskFilterService, FilterRepresentationModel } from '@alfresco/adf-process-services'; + +export class SomePageComponent implements OnInit { + + constructor(private taskFilterService: TaskFilterService) { + } +``` + +## Methods + +#### createDefaultFilters(appId: number): Observable`` +Create and return the default task filters for a Process App: + +```ts +const processAppId = 2; +this.taskFilterService.createDefaultFilters(processAppId).subscribe( (filters: FilterRepresentationModel[]) => { + console.log('Task filters: ', filters); +}, error => { + console.log('Error: ', error); +}); +``` + +The response is an array of `FilterRepresentationModel` objects: + +``` +filters: + 0: { + appId: 2 + filter : { + assignment: "involved" + dueAfter: null + dueBefore: null + name: null + processDefinitionId: null + processDefinitionKey: null + sort: "created-desc" + state: "open" + } + icon: "glyphicon-align-left" + id: null + index: undefined + name: "Involved Tasks" + recent: false + 1: {id: null, appId: 2, name: "My Tasks", recent: false, icon: "glyphicon-inbox", …} + 2: {id: null, appId: 2, name: "Queued Tasks", recent: false, icon: "glyphicon-record", …} + 3: {id: null, appId: 2, name: "Completed Tasks", recent: true, icon: "glyphicon-ok-sign", …} +``` + +These filters can now be used to get matching Task Instances for Process App with ID 2, +such as 'Involved Tasks', 'My Tasks', 'Queued Tasks', and 'Completed Tasks'. + +#### getTaskListFilters(appId?: number): Observable`` +Get all task filters defined for a Process App: + +```ts +const processAppId = 2; +this.taskFilterService.getTaskListFilters(processAppId).subscribe( (filters: FilterRepresentationModel[]) => { + console.log('Task filters: ', filters); +}, error => { + console.log('Error: ', error); +}); +``` + +The response is an array of `FilterRepresentationModel` objects: + +``` +filters: + 0: {id: 10, appId: 2, name: "Involved Tasks", recent: true, icon: "glyphicon-align-left", …} + 1: {id: 9, appId: 2, name: "My Tasks", recent: false, icon: "glyphicon-inbox", …} + 2: {id: 11, appId: 2, name: "Queued Tasks", recent: false, icon: "glyphicon-record", …} + 3: {id: 12, appId: 2, name: "Completed Tasks", recent: false, icon: "glyphicon-ok-sign", …} + 4: {id: 4004, appId: 2, name: "Completed Tasks", recent: false, icon: "glyphicon-ok-sign", …} + 5: {id: 4005, appId: 2, name: "My Tasks", recent: false, icon: "glyphicon-inbox", …} + 6: {id: 4006, appId: 2, name: "Queued Tasks", recent: false, icon: "glyphicon-record", …} + 7: {id: 4007, appId: 2, name: "Involved Tasks", recent: false, icon: "glyphicon-align-left", …} +``` +In this example I had run the `createDefaultFilters` method once, and that created the duplicate of +the default filters. + +These filters can now be used to get matching Task Instances for Process App with ID 2, +such as 'Involved Tasks', 'My Tasks', 'Queued Tasks', and 'Completed Tasks'. + +If you want to return all filters regardless of Process App, and filter out duplicates, +then you can just leave out the Process App number: + +```ts +this.taskFilterService.getTaskListFilters().subscribe( (filters: FilterRepresentationModel[]) => { + console.log('Task filters: ', filters); +}, error => { + console.log('Error: ', error); +}); +``` + +#### getTaskFilterById(filterId: number, appId?: number): Observable`` +Get a specific Task Filter based on its ID, optionally pass in Process App ID to improve performance +when searching for filter: + +```ts +const processAppId = 2; +const taskFilterId = 4007; +this.taskFilterService.getTaskFilterById(taskFilterId, processAppId).subscribe( (filter: FilterRepresentationModel) => { + console.log('Task filter: ', filter); +}, error => { + console.log('Error: ', error); +}); +``` + +The response is a `FilterRepresentationModel` object: + +``` +Task filter: + appId: 2 + filter: + assignment: "involved" + sort: "created-desc" + state: "open" + icon: "glyphicon-align-left" + id: 4007 + name: "Involved Tasks" + recent: false +``` + +The filter can now be used to get 'Involved Tasks' Task Instances for Process App with ID 2. + +#### getTaskFilterByName(taskName: string, appId?: number): Observable`` +Get a specific Task Filter based on its name, optionally pass in Process App ID to improve performance +when searching for filter: + +```ts +const processAppId = 2; +const taskFilterName = 'Completed Tasks'; +this.taskFilterService.getTaskFilterByName(taskFilterName, processAppId).subscribe( (filter: FilterRepresentationModel) => { + console.log('Task filter: ', filter); +}, error => { + console.log('Error: ', error); +}); +``` + +The response is a `FilterRepresentationModel` object: + +``` +appId: 2 +filter: {sort: "created-desc", name: "", state: "completed", assignment: "involved"} +icon: "glyphicon-ok-sign" +id: 12 +name: "Completed Tasks" +recent: false +``` +If there are several filters with the same name for the Process App, then you get back the +first one found matching the name. + +The filter can now be used to get 'Completed Tasks' Task Instances for Process App with ID 2. + +#### addFilter(filter: FilterRepresentationModel): Observable`` +Add a new Task Instance filter: + +```ts +const processAppId = 2; +const filterName = 'InvolvedAsc'; +const filterInvolvedAsc = new FilterRepresentationModel({ + 'name': filterName, + 'appId': processAppId, + 'recent': false, + 'icon': 'glyphicon-align-left', + 'filter': { 'assignment': 'involved', 'sort': 'created-asc', 'state': 'open' } +}); + +this.taskFilterService.addFilter(filterInvolvedAsc).subscribe( (filterResponse: FilterRepresentationModel) => { + console.log('Task filter: ', filterResponse); +}, error => { + console.log('Error: ', error); +}); +``` + +The response is a `FilterRepresentationModel` object: + +``` +appId: 2 +icon: "glyphicon-align-left" +id: 4008 +name: "InvolvedAsc" +recent: false +``` + +The filter can now be used to get 'Involved' Task Instances for +Process App with ID 2 in created date ascending order. + +#### getRunningFilterInstance(appId: number): FilterProcessRepresentationModel +Convenience method to create and return a filter that matches `involved` Task Instances +for passed in Process App ID: + +```ts +const processAppId = 2; +const involvedFilter: FilterRepresentationModel = this.taskFilterService.getInvolvedTasksFilterInstance(processAppId); +console.log('Involved filter', involvedFilter); +``` + +The response is a `FilterRepresentationModel` object: + +``` +appId: 2 +filter: + assignment: "involved" + dueAfter: null + dueBefore: null + name: null + processDefinitionId: null + processDefinitionKey: null + sort: "created-desc" + state: "open" +icon: "glyphicon-align-left" +id: null +index: undefined +name: "Involved Tasks" +recent: false +``` + +Use the `addFilter` to add this filter to a Process App. + +#### getMyTasksFilterInstance(appId: number): FilterProcessRepresentationModel +Convenience method to create and return a filter that matches `My Tasks` Task Instances +for passed in Process App ID: + +```ts +const processAppId = 2; +const myTasksFilter: FilterRepresentationModel = this.taskFilterService.getMyTasksFilterInstance(processAppId); +console.log('My Tasks filter', myTasksFilter); +``` + +The response is a `FilterRepresentationModel` object: + +``` +appId: 2 +filter: + assignment: "assignee" + dueAfter: null + dueBefore: null + name: null + processDefinitionId: null + processDefinitionKey: null + sort: "created-desc" + state: "open" +icon: "glyphicon-inbox" +id: null +index: undefined +name: "My Tasks" +recent: false +``` + +Use the `addFilter` to add this filter to a Process App. + +#### getQueuedTasksFilterInstance(appId: number): FilterProcessRepresentationModel +Convenience method to create and return a filter that matches `Queued Tasks` Task Instances +for passed in Process App ID: + +```ts +const processAppId = 2; +const queuedTasksFilter: FilterRepresentationModel = this.taskFilterService.getQueuedTasksFilterInstance(processAppId); +console.log('Queued Tasks filter', queuedTasksFilter); +``` + +The response is a `FilterRepresentationModel` object: + +``` +appId: 2 +filter: + assignment: "candidate" + dueAfter: null + dueBefore: null + name: null + processDefinitionId: null + processDefinitionKey: null + sort: "created-desc" + state: "open" +icon: "glyphicon-record" +id: null +index: undefined +name: "Queued Tasks" +recent: false +``` + +Use the `addFilter` to add this filter to a Process App. + +#### getCompletedTasksFilterInstance(appId: number): FilterProcessRepresentationModel +Convenience method to create and return a filter that matches `Completed Tasks` Task Instances +for passed in Process App ID: + +```ts +const processAppId = 2; +const completedTasksFilter: FilterRepresentationModel = this.taskFilterService.getCompletedTasksFilterInstance(processAppId); +console.log('Completed Tasks filter', completedTasksFilter); +``` + +The response is a `FilterRepresentationModel` object: + +``` +appId: 2 +filter: + assignment: "involved" + dueAfter: null + dueBefore: null + name: null + processDefinitionId: null + processDefinitionKey: null + sort: "created-desc" + state: "completed" +icon: "glyphicon-ok-sign" +id: null +index: undefined +name: "Completed Tasks" +recent: true +``` + +Use the `addFilter` to add this filter to a Process App. + + + + \ No newline at end of file diff --git a/docs/tasklist.service.md b/docs/tasklist.service.md new file mode 100644 index 0000000000..98885477bf --- /dev/null +++ b/docs/tasklist.service.md @@ -0,0 +1,650 @@ +# Tasklist Service +Manage Task Instances. + +## Importing + +```ts +import { TaskListService, TaskDetailsModel, TaskQueryRequestRepresentationModel, TaskListModel, Form } from '@alfresco/adf-process-services'; +import { TaskUpdateRepresentation } from 'alfresco-js-api'; + +export class SomePageComponent implements OnInit { + + constructor(private tasklistService: TaskListService) { + } +``` + +## Methods + +#### getTaskDetails(taskId: string): Observable`` +Get Task Instance metadata for passed in Task Instance ID: + +```ts +const taskInstanceId = '15303'; +this.tasklistService.getTaskDetails(taskInstanceId).subscribe( (taskInstance: TaskDetailsModel) => { + console.log('TaskInstance: ', taskInstance); +}, error => { + console.log('Error: ', error); +}); +``` + +The `taskInstanceId` refers to a Task Instance identifier in APS. +The returned `taskInstance` object is of type `TaskDetailsModel` and looks like in this sample: + +``` +adhocTaskCanBeReassigned: false +assignee: UserProcessModel {pictureId: null, id: 1, email: "admin@app.activiti.com", firstName: null, lastName: "Administrator"} +category: null +created: Wed Oct 11 2017 09:07:14 GMT+0100 (BST) {} +description: null +dueDate: null +duration: null +endDate: null +executionId: "11337" +formKey: "9" +id: "15303" +initiatorCanCompleteTask: false +involvedPeople: [] +managerOfCandidateGroup: false +memberOfCandidateGroup: false +memberOfCandidateUsers: false +name: "Clarify Invoice - Invoice-20302.pdf" +parentTaskId: null +parentTaskName: null +priority: 50 +processDefinitionCategory: "http://www.activiti.org/processdef" +processDefinitionDeploymentId: "18" +processDefinitionDescription: "This is a simple invoice approval process that allows a person to assign a dedicated approver for the the invoice. It will then be routed to the Accounting department for payment preparation. Once payment is prepared the invoice will be stored in a specific folder and an email notification will be sent." +processDefinitionId: "InvoiceApprovalProcess:2:21" +processDefinitionKey: "InvoiceApprovalProcess" +processDefinitionName: "Invoice Approval Process" +processDefinitionVersion: 2 +processInstanceId: "11337" +processInstanceName: null +processInstanceStartUserId: "1" +taskDefinitionKey: "clarifyInvoice" +``` + +#### getTaskChecklist(id: string): Observable`` +Get all the sub-task instances for a Task Instance, also called the check list: + +```ts +const parentTaskId = '15303'; +this.tasklistService.getTaskChecklist(parentTaskId).subscribe( (subTasks: TaskDetailsModel[]) => { + console.log('Sub Tasks: ', subTasks); +}, error => { + console.log('Error: ', error); +}); +``` + +The response is an array of `TaskDetailsModel` representing the sub-tasks: + +``` +Sub Tasks: + 0: + adhocTaskCanBeReassigned: false + assignee: UserProcessModel {pictureId: null, id: 1, email: "admin@app.activiti.com", firstName: null, lastName: "Administrator"} + category: "2" + created: "2017-10-29T07:29:28.881+0000" + description: null + dueDate: null + duration: null + endDate: null + executionId: null + formKey: null + id: "74745" + initiatorCanCompleteTask: false + involvedPeople: undefined + managerOfCandidateGroup: false + memberOfCandidateGroup: false + memberOfCandidateUsers: false + name: "Double check invoice amount" + parentTaskId: "15303" + parentTaskName: "Clarify Invoice - Invoice-10292.pdf" + priority: 50 + processDefinitionCategory: null + processDefinitionDeploymentId: null + processDefinitionDescription: null + processDefinitionId: null + processDefinitionKey: null + processDefinitionName: null + processDefinitionVersion: 0 + processInstanceId: null + processInstanceName: null + processInstanceStartUserId: null + taskDefinitionKey: null + 1 : + {processDefinitionVersion: 0, id: "74746", name: "Verify with the person that did the purchase", priority: 50, assignee: UserProcessModel, …} +``` + +Looking at the `TaskDetailsModel` for a sub-task we can see that it has a parent task ID that matches what we specified +when calling this method. + +#### getTasks(requestNode: TaskQueryRequestRepresentationModel): Observable`` +Get tasks matching passed in query definition: + +```ts +const taskQuery: TaskQueryRequestRepresentationModel = { + appDefinitionId: '2', + processInstanceId: null, + processDefinitionId: null, + text: null, + assignment: null, + state: 'open', + sort: 'created_asc', + page: 0, + size: 5, + start: null +}; +this.tasklistService.getTasks(taskQuery).subscribe( (taskListModel: TaskListModel) => { + console.log('Task List Model: ', taskListModel); +}, error => { + console.log('Error: ', error); +}); +``` + +In the above example we query for all Task Instances associated with a Process Application with +ID 2. We set `size` to 5, which means that the query will return max 5 task instances. + +We can mix and match the query parameters to narrow down the task list that is returned. +If you are just interested in Task Instances related to a specific Process Instance, +then set the `processInstanceId`. If you want to see all tasks related to a specific type of processes, +then you should set the `processDefinitionId` property. + +You can use the `state` property to define if only `completed` or only `open` tasks should be returned. If you +specify `null` for state then `open` will be assumed. + +The `assignment` property can be used to filter tasks based on how they are assigned (or not assigned yet). +Use `assignee` if you are interested in tasks that are assigned to a user. If you want to see +pooled tasks (i.e. tasks that needs to be claimed by a user), then use `candidate`. + +A `TaskListModel` object is returned for a successful query and the `data` property is an array of +`TaskDetailsModel`: + +``` +data: + 0: {id: "75010", name: "Approve Invoice - Invoice-10202.pdf", description: null, category: null, assignee: {…}, …} + 1: {id: "74746", name: "Verify with the person that did the purchase", description: null, category: "2", assignee: {…}, …} + 2: {id: "74745", name: "Double check invoice amount", description: null, category: "2", assignee: {…}, …} + 3: {id: "20686", name: "Sample checklist task 1", description: null, category: "2", assignee: {…}, …} + 4: {id: "15303", name: "Clarify Invoice - Invoice-20302.pdf", description: null, category: null, assignee: {…}, …} +length: 5 +size: 5 +start: 0 +total: 10 +``` + +We can see that this query resulted in 10 tasks (see `total`), but only 5 were returned as we set `size` to `5`. + +#### getTotalTasks(requestNode: TaskQueryRequestRepresentationModel): Observable`` +Get total number of tasks matching passed in query definition: + +```ts +const taskQuery: TaskQueryRequestRepresentationModel = { + appDefinitionId: '2', + processInstanceId: null, + processDefinitionId: null, + text: null, + assignment: null, + state: 'open', + sort: 'created_asc', + page: 0, + size: 5, + start: null +}; +this.tasklistService.getTotalTasks(taskQuery).subscribe( (response: any) => { + console.log('Total: ', response); +}, error => { + console.log('Error: ', error); +}); +``` + +This is pretty much the same type of query as the `getTasks` method, except that here we just +return how many Task Instances it matched in the `total` property: + +``` +data:[] +size: 0 +start: 0 +total: 10 +``` + +When you call this method it always sets the `size` property to `0`. + +#### findTasksByState(requestNode: TaskQueryRequestRepresentationModel, state?: string): Observable`` +Find and return Task Instances by state `open` or `completed` and query model: + +```ts +const taskState = 'open'; +const taskQuery: TaskQueryRequestRepresentationModel = { + appDefinitionId: '2', + processInstanceId: null, + processDefinitionId: null, + text: null, + assignment: null, + state: 'open', + sort: 'created_asc', + page: 0, + size: 5, + start: null +}; + +this.tasklistService.findTasksByState(taskQuery, taskState).subscribe( (taskList: TaskListModel) => { + console.log('Task list: ', taskList); +}, error => { + console.log('Error: ', error); +}); +``` +The number of tasks that are returned is controlled by the `size` property. + +This is a convenience method on top of the `getTasks` method. It overwrites the `requestNode.state` property +with passed in `state` before making the call to `getTasks`. +For an example of the response see the `getTasks` method. + +#### findAllTaskByState(requestNode: TaskQueryRequestRepresentationModel, state?: string): Observable`` +Find and return all Task Instances by state `open` or `completed` and query model: + +```ts +const taskState = 'open'; +const taskQuery: TaskQueryRequestRepresentationModel = { + appDefinitionId: '2', + processInstanceId: null, + processDefinitionId: null, + text: null, + assignment: null, + state: 'open', + sort: 'created_asc', + page: 0, + size: 5, + start: null +}; + +this.tasklistService.findAllTaskByState(taskQuery, taskState).subscribe( (taskList: TaskListModel) => { + console.log('Task list: ', taskList); +}, error => { + console.log('Error: ', error); +}); +``` + +This is a convenience method on top of the `getTasks` method. It overwrites the `requestNode.state` property with +passed in `state` before making any other calls. Before making the `getTasks` call it will first call the +`getTotalTasks` method to get the total number of tasks that match query and state. It then overwrite the +`requestNode.size` with the total so all matching tasks are returned when finnally making the `getTasks` call. + +**Note** that this can return a lot of data if you are not careful. + +#### findAllTasksWithoutState(requestNode: TaskQueryRequestRepresentationModel): Observable`` +Find and return all Task Instances that matches query model, regardless of state: + +```ts +const taskQuery: TaskQueryRequestRepresentationModel = { + appDefinitionId: '2', + processInstanceId: null, + processDefinitionId: null, + text: null, + assignment: null, + state: null, + sort: 'created_asc', + page: 0, + size: 5, + start: null +}; + +this.tasklistService.findAllTasksWithoutState(taskQuery).subscribe( (taskList: TaskListModel) => { + console.log('Task list: ', taskList); +}, error => { + console.log('Error: ', error); +}); +``` + +This method can be used when you have a task query that should return all tasks regardless of the state they +are in. You cannot achieve this with the `getTasks` method. If you specify a `size` it is overwritten. +Internally it basically calls `findTasksByState(requestNode, 'open')` and +`findAllTaskByState(requestNode, 'completed')`. + +**Note** that this can return a lot of data if you are not careful. + +#### assignTaskByUserId(taskId: string, userId: number): Observable`` +Assign a Task Instance to a user via the User ID: + +```ts +const taskId = '15303'; +const userId = 1; +this.tasklistService.assignTaskByUserId(taskId, userId).subscribe( (taskInstance: TaskDetailsModel) => { + console.log('Task instance: ', taskInstance); +}, error => { + console.log('Error: ', error); +}); +``` + +The user ID identifies a User in APS. + +#### assignTask(taskId: string, requestNode: any): Observable`` +Assign a task to a user via a user object with an `id` property, for example: + +```ts +const taskId = '15303'; +const user = { id: 1, email: 'admin@app.activiti.com', firstName: 'APS', lastName: 'Admin' }; +this.tasklistService.assignTask(taskId, user).subscribe( (taskInstance: TaskDetailsModel) => { + console.log('Task instance: ', taskInstance); +}, error => { + console.log('Error: ', error); +}); +``` + +This method does the same as the `assignTaskByUserId` method, the only difference is that this +method can be used when you have an object where the User ID is contained in an `id` property. + +#### claimTask(taskId: string): Observable`` +Claim a pooled task (i.e. candidate task) as current user so it can be worked on and later on completed: + +```ts +const taskId = '15368'; +this.tasklistService.claimTask(taskId).subscribe( (taskInstance: TaskDetailsModel) => { + console.log('Task instance: ', taskInstance); +}, error => { + console.log('Error: ', error); +}); +``` + +The response will be `null` if the task was claimed successfully. + +The task assignment changes from `candidate` to `assignee`. + +#### unclaimTask(taskId: string): Observable`` +Return a claimed task to the pool (i.e. make it a candidate task): + +```ts +const taskId = '15368'; +this.tasklistService.unclaimTask(taskId).subscribe( (taskInstance: TaskDetailsModel) => { + console.log('Task instance: ', taskInstance); +}, error => { + console.log('Error: ', error); +}); +``` + +The task assignment changes from `assignee` to `candidate`. + +#### completeTask(taskId: string) +Complete a Task Instance as current user and progress Process Instance: + +```ts +const taskId = '15176'; +this.tasklistService.completeTask(taskId); +``` + +This only works if the Task Instance has only one Outcome (i.e. the default `Complete` one). +If the Task Instance has multiple Outcomes, such as Approve and Reject, then this method does not +work, and the Task Instance has to be completed via its associated form. Otherwise you will see an error such as: + +*ERROR Error: Uncaught (in promise): Error: {"message":"Task must be completed using it's form","messageKey":"GENERAL.ERROR.BAD-REQUEST"}* + +#### updateTask(taskId: any, updated): Observable`` +Update name, description, and due date for a Task Instance: + +```ts +const taskId = '80002'; +const updateData: TaskUpdateRepresentation = { + description: 'Updated description', + dueDate: new Date(2018, 1, 10, 11, 0, 0, 0), + name: 'Updated name' +}; +this.tasklistService.updateTask(taskId, updateData).subscribe( (updatedTaskDetails: TaskDetailsModel) => { + console.log('Updated task: ', updatedTaskDetails); +}, error => { + console.log('Error: ', error); +}); +``` +The response is all info about the updated Task Instance, in this example a stand-alone task was updated so there +is no associated process: + +``` +adhocTaskCanBeReassigned: false +assignee: undefined +category: null +created: Mon Nov 13 2017 16:34:49 GMT+0000 (GMT) {} +description: "Updated description" +dueDate: Sat Feb 10 2018 11:00:00 GMT+0000 (GMT) {} +duration: NaN +endDate: null +executionId: null +formKey: "5005" +id: "80002" +initiatorCanCompleteTask: false +managerOfCandidateGroup: false +memberOfCandidateGroup: false +memberOfCandidateUsers: false +name: "Updated name" +parentTaskId: null +parentTaskName: null +priority: 50 +processDefinitionCategory: null +processDefinitionDeploymentId: null +processDefinitionDescription: null +processDefinitionId: null +processDefinitionKey: null +processDefinitionName: null +processDefinitionVersion: 0 +processInstanceId: null +processInstanceName: null +processInstanceStartUserId: null +taskDefinitionKey: null +``` + +#### createNewTask(task: TaskDetailsModel): Observable`` +Create a new stand-alone Task Instance that is not associated with a Process Instance: + +```ts +const taskDetails = new TaskDetailsModel({ + name: 'Some Task', + description: 'A new stand-alone task' +}); + +this.tasklistService.createNewTask(taskDetails).subscribe( (createdTaskDetails: TaskDetailsModel) => { + console.log('Created task details: ', createdTaskDetails); +}, error => { + console.log('Error: ', error); +}); +``` + +In this case we are creating a disconnected Task Instance that is not associated with a form (i.e. `formKey: null`) +and that is not assigned to a user (i.e. `assignee: null`). + +The response looks like this, we can see that an ID was generated for the Task Instance: + +``` +Created task details: + adhocTaskCanBeReassigned: false + assignee: null + category: null + created: Mon Nov 13 2017 16:34:49 GMT+0000 (GMT) {} + description: "A new stand-alone task" + dueDate: null + duration: null + endDate: null + executionId: null + formKey: null + id: "80002" + initiatorCanCompleteTask: false + involvedPeople: undefined + managerOfCandidateGroup: false + memberOfCandidateGroup: false + memberOfCandidateUsers: false + name: "Some Task" + parentTaskId: null + parentTaskName: null + priority: 50 + processDefinitionCategory: null + processDefinitionDeploymentId: null + processDefinitionDescription: null + processDefinitionId: null + processDefinitionKey: null + processDefinitionName: null + processDefinitionVersion: 0 + processInstanceId: null + processInstanceName: null + processInstanceStartUserId: null + taskDefinitionKey: null +``` + +See the `attachFormToATask` method for how to attach a form to the User Task. And see the `assignTaskByUserId` method +for how to assign a user to the new Task Instance. + +#### attachFormToATask(taskId: string, formId: number): Observable`` +Attach a form to a User Task: + +```ts +const taskId = '80002'; +const formId = 5005; +this.tasklistService.attachFormToATask(taskId, formId).subscribe( (response: any) => { + console.log('Assign form response: ', response); +}, error => { + console.log('Error: ', error); +}); +``` + +In this case we need to have a task created and know the ID for it, such as with the `createNewTask` method. +We also need to have a form defined in APS and know the ID for it (you can see the ID for a form in the URL +in APS when you work with it). See the `getFormList` method for how fetch a list of available forms. + +The response will be `null` if form was attached successfully to task. + +#### getFormList(): Observable`
` +Get a list of the available reusable forms: + +```ts +this.tasklistService.getFormList().subscribe( (formList: Form[]) => { + console.log('Available forms: ', formList); +}, error => { + console.log('Error: ', error); +}); +``` + +A successful response looks like this: + +``` +Available forms: + +0: + id: 5005 + name: "Name Info" +1: {name: "cm:folder", id: 3012} +2: {name: "Alfresco Node Form", id: 3011} +3: {name: "Employee", id: 3010} +``` + +The form id property can be used with the `attachFormToATask` method. + +**Note**. Referenced forms that are associated with specific tasks in a process are not included in this list. +Only reusable forms are included. + +#### addTask(task: TaskDetailsModel): Observable`` +Add a Sub-Task (i.e. checklist task) to a parent Task Instance: + +```ts +const parentTaskId = '80002'; +const subTaskDetails = new TaskDetailsModel({ + parentTaskId: parentTaskId, + name: 'Check the invoice amount' +}); +this.tasklistService.addTask(subTaskDetails).subscribe( (updatedTaskDetails: TaskDetailsModel) => { + console.log('Sub-task info: ', updatedTaskDetails); +}, error => { + console.log('Error: ', error); +}); +``` + +The response includes the new sub-task id and also parent task name. +In this example the parent task was just a stand-alone task, so no process information is included: + +``` +adhocTaskCanBeReassigned: false +assignee: null +category: null +created: Tue Nov 14 2017 13:32:41 GMT+0000 (GMT) {} +description: null +dueDate: null +duration: null +endDate: null +executionId: null +formKey: null +id: "80003" +initiatorCanCompleteTask: false +involvedPeople: undefined +managerOfCandidateGroup: false +memberOfCandidateGroup: false +memberOfCandidateUsers: false +name: "Check the invoice amount" +parentTaskId: "80002" +parentTaskName: "Some Task" +priority: 50 +processDefinitionCategory: null +processDefinitionDeploymentId: null +processDefinitionDescription: null +processDefinitionId: null +processDefinitionKey: null +processDefinitionName: null +processDefinitionVersion: 0 +processInstanceId: null +processInstanceName: null +processInstanceStartUserId:null +taskDefinitionKey: null +``` + +#### deleteTask(taskId: string): Observable`` +Delete a Sub-Task (i.e. checklist task): + +```ts +const taskId = '75100'; // Sub-task ID +this.tasklistService.deleteTask(taskId).subscribe( (taskDetails: TaskDetailsModel) => { + console.log('Deleted task info: ', taskDetails); +}, error => { + console.log('Error: ', error); +}); +``` + +**Note**. you can only delete so called checklist tasks with this method. + +#### fetchTaskAuditJsonById(taskId: string): Observable`` +Fetch Task Audit log as JSON for a Task Instance ID: + +```ts +const taskId = '15368'; +this.tasklistService.fetchTaskAuditJsonById(taskId) + .subscribe( auditJson => { + console.log('Task Audit: ', auditJson); + }, error => { + console.log('Error: ', error); + }); +``` + +The response is JSON object with the Task Instance audit log: + +``` +{ + taskId: "15368", + taskName: "Approve by someone in Accounting", + processInstanceId: "15361", + processDefinitionName: "Process With Pooled task", + processDefinitionVersion: 1, + … +} +``` + +#### fetchTaskAuditPdfById(taskId: string): Observable`` +Fetch Task Audit log as JSON for a Task Instance ID: + +```ts +this.tasklistService.fetchTaskAuditPdfById(taskId) + .subscribe( (auditPdf: Blob) => { + console.log('Task Audit: ', auditPdf); + }, error => { + console.log('Error: ', error); + }); +``` + +The response is PDF with the Task Instance audit log. + + + + + \ No newline at end of file