Tasks
Tasks make collaboration better. Tasks are better than messages when you work together with others. Tasks have a clear status and an assignee. You can go to the Tasks app to claim a task for yourself and start work on it.
Magnolia uses tasks in the publishing workflow: when an editor publishes a page the system creates an approval task and sends it to the publishers group.
See also Custom tasks and User tasks documentation for how to integrate it with jBPM. But please keep in mind, that you can create and work with Tasks without having to deal with jBPM and workflow.
Do not use tasks if you do not have any human activity in your workflow. They are unnecessary for operations that only involve the system itself. |
TasksManager
A task is an object that you create using info.magnolia.task.TasksManager. You can send the task to a list of users or to a list of groups. A recipient can assign the task to themselves. Others can see who owns the task and its status when they go to the Tasks app.
When working with tasks, use the TasksManager
interface to
update fields such as creationDate
, modificationDate
and
status
and to notify the system event bus.
To get TasksManager
in your implementations, use injection:
TasksManager
@Inject
public MyClass(TasksManager tasksManager) {
this.tasksManager = tasksManager;
}
public void createTask() {
Task task = new Task();
...
tasksManager.addTask(task);
}
Be aware that by calling
the task will not be created in the workspace. |
Creating a task
Start by giving the task a name. The name is unique for the type of task you are creating and acts as a reference to the task definition in the registry.
task.setname("getGroceries")
Next, define the possible assignees for the task. You can send a task to
a list of groups
or actors
.
List<String> actorIds = new ArrayList() {{
add("eric");
add("susan");
}};
List<String> groupIds = new ArrayList() {{
add("groceryShoppers");
}};
task.setActorIds(actorIds);
task.setGroupIds(groupIds);
Finally, add content
to your task. The content
should contain the
information the assignee needs to complete the task. For example, in the
default publishing workflow the content
contains information the
publisher needs to review a page and publish it such as the
workspace where the page
resides, a path to the page node, and the version of the page being
published.
Map<String, String> content = new HashMap() {{
put("groceries", "milk, eggs, beer");
put("budget", "15.- CHF");
}};
task.setContent(content);
The |
Claiming a task
When a user assigns a task to themselves they claim it. To claim a
task, set the actorId
:
taskManager.claim(taskId, userId);
This will update the task status
and modificationDate
and notifies
the system event bus.
Magnolia uses
info.magnolia.task.app.actions.ClaimTasksAction
inside the Tasks app for this step.
Reclaiming a task
With appropriate publication rights you can reclaim a task which is
already InProgress
from another user.
Task reclaiming works in the same way as claiming a task, i.e.
taskManager.claim(taskId, userId);
using the
info.magnolia.task.app.actions.ClaimTasksActionDefinition
class but adds notifyPreviousAssignee
, which is set to true
by
default and will trigger sending an i18n-able notification in the Tasks
app to the previous assignee in the publication sequence that the task
has been reclaimed by another user:
messagesManager.sendMessage(task.getActorId(), message)
Please note that notifyPreviousAssignee
is present also in
info.magnolia.task.app.actions.ClaimTasksActionDefinition
.
Resolving a task
To resolve a task assigned to an actor:
Map<String, Object> result = new HashMap<String, Object>();
result.put("budgetSpent", "13.25 CHF");
taskManager.resolve(taskId, result);
A resolved task usually produces some sort of output. You can use the
result
map to pass this output to further processing. TasksManager
will take care of notifying any handlers registered to the system event
bus.
Magnolia uses info.magnolia.task.app.actions.AbortTasksActionDefinition
inside the Tasks app for this step. It allows you to define a decision
inside the configuration which is mainly used for approving or rejecting
a publication.
abort:
class: info.magnolia.task.app.actions.AbortTasksActionDefinition
decision: abort
icon: icon-publish
availability:
multiple: true
rules:
canAbort:
assignee: false
class: info.magnolia.task.app.actions.availability.TaskAvailabilityRuleDefinition
status:
Created: Created
Failed: Failed
InProgress: InProgress
Scheduled: Scheduled
access:
roles:
superuser: superuser
After resolving the task using the ResolveTask
action the result map
contains only one entry with the configured decision.
As with the |
Archiving and removing a task
The TasksManager
provides a method for archiving tasks. The method
removes the task from the Tasks app. You can still retrieve an archived
task later in case you want to re-open it or audit.
While the API allows deleting a task, we strongly discourage doing so unless you know for sure that the deleted task won’t be used any more.
taskManager.archiveTask(taskId);
taskManager.removeTask(taskId);
Status
Every task is bound to a life cycle and goes through several statuses in your process:
-
Created
: The task has been created but is not assigned to any user. -
InProgress
: The task has been assigned to a user. -
Resolved
: The task has been resolved by the assigned user. -
Failed
: Task execution has failed. -
Archived
: The task has been removed from the Tasks app. -
Removed
: The task has been removed from the repository. Removing tasks is supported by the API but should be used carefully. Depending on the use case, a user should be able to reopen a task after it has been resolved.
Changes to task status can be tracked by registering info.magnolia.task.event.TaskEventHandler to the system event bus.
Task definition
Every task type needs a unique name. The name is used to read the task definition from the task registry in your module configuration.
'publish':
'class': 'info.magnolia.module.workflow.jbpm.humantask.definition.PublicationTaskDefinition'
'parameterResolver': 'info.magnolia.livecopy.workflow.jbpm.humantask.DynamicPublicationTaskParameterResolver'
'taskJobFactoryClass': 'info.magnolia.module.workflow.jbpm.humantask.schedule.PublicationTaskJobFactory'
'groups':
'publishers': 'publishers'
'viewMapping':
'default': 'workflow:publish'
'website': 'pages-app:publish'
The simplest info.magnolia.task.definition.TaskDefinition needs the following properties:
All properties below are required. |
|
The node’s name used to look up the configuration for a task. |
|
The i18nable title of the task displayed in the tasks list in the Tasks app. |
|
The view definition used to render the form and action bar in the detail view of the Tasks app. This is a reference to a |
|
The class mapping used for map2bean to initialize the POJO. |
As with any definition used in Magnolia, you can define your own extensions to the task definition and add configurable nodes and properties. |
Task view
While we use the term task view for the detail view of a task, it is technically a message view used to render the form and action bar. |
Use a message view configuration to define which fields of the task
object are displayed to the user. You can use a dot notation such as
content.groceries
to reference fields from the content
or result
map. In the same fashion, you can configure your
actions,
including
availability
and action bar
mappings.
Configuring actions
The abort
, archive
and claim
tasks are configured as
bulk actions.
The decoration file below adds a setting for the abort
action in the task browser and detail (the
definition class is
info.magnolia.task.app.actions.AbortTasksActionDefinition
)
with the travel-demo-publisher
role set to access this action:
subApps:
allTasks:
actions:
abort:
availability:
access:
roles:
- travel-demo-publisher
actions:
abort:
availability:
access:
roles:
- travel-demo-publisher
To allow actions for different users, add their role names from the
list of
default
roles as the properties and values of the roles
subnode.
See Action definition for more details about action properties.