Magnolia 5.7 reached extended end of life on May 31, 2022. Support for this branch is limited, see End-of-life policy. Please note that to cover the extra maintenance effort, this EEoL period is a paid extension in the life of the branch. Customers who opt for the extended maintenance will need a new license key to run future versions of Magnolia 5.7. If you have any questions or to subscribe to the extended maintenance, please get in touch with your local contact at Magnolia.
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 Pulse 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.
TasksManager
A task is an object that you create using the TasksManager. You can send the task to a list of users or to a list of groups. The recipient can assign the task to himself. Other recipients can see who owns the task and its status when they go to the Pulse.
When working with tasks, use the TasksManager
class which takes care of updating fields such as creationDate
, modificationDate
and status
and notifies the system event bus.
To get TasksManager
in your implementations, use injection:
@Inject public MyClass(TasksManager tasksManager) { this.tasksManager = tasksManager; } public void createTask() { Task task = new Task(); ... tasksManager.addTask(task); }
Be aware that by calling
task.setId(String);
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 content
map is stored to JCR using OCM and allows storing any <String, Object>
map where Object
is a simple type. The data inside the content map is usually only used for displaying information in the Pulse.
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.ui.admincentral.shellapp.pulse.task.action.ClaimTaskAction
inside the Pulse 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.ui.admincentral.shellapp.pulse.task.action.ClaimTaskActionDefinition
class but adds notifyPreviousAssignee
, which is set to true
by default and will trigger sending an i18n-able notification in the Pulse 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.ui.admincentral.shellapp.pulse.task.action.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.ui.admincentral.shellapp.pulse.task.action.ResolveTaskAction
inside Pulse for this step. It allows you to define a decision inside the configuration which is mainly used for approving or rejecting a publication.
Node name | Value |
---|---|
messageViews | |
publish | |
form | |
actions | |
approve | |
availability | |
class | info.magnolia.ui.admincentral.shellapp.pulse.task.action.ResolveTaskActionDefinition |
decision | approve |
icon | icon-publish |
After resolving the task using the ResolveTask
action the result map contains only one entry with the configured decision.
As with the content
map, the result
map is stored to JCR using OCM and allows storing any <String, Object>
map where Object
is a simple type.
Archiving and removing a task
The TasksManager
provides a method for archiving tasks. The method removes the task from Pulse. 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 transitions back and forth between statuses as it proceeds in your process:
Created
: The Task has been created but is not assigned to any actor.InProgress
: The task has been assigned to a userResolved
: The task has been resolved by the assigned actor.Failed
: The execution of the task has failed.Archived
: The task has been removed from the Pulse.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 re-open a task after it has been resolved.
Changes to task status can be tracked by registering a 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.
Node name | Value |
---|---|
my-module | |
tasks | |
getGroceries | |
class | info.magnolia.task.definition.TaskDefinition |
taskView | my-module:groceries |
title | Groceries |
The simplest TaskDefinition needs the following properties:
<task name> | required The node's name used to look up the configuration for a task. |
| required The i18nable title of the task displayed in the tasks list in The Pulse. |
| required The view definition used to render the form and action bar in the detail view of The Pulse. This is a reference to a |
| required The class mapping used for node2bean 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. This is especially useful in combination with a custom task presenter for putting together the detail view.
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.
Node name | Value |
---|---|
my-module | |
messageViews | |
groceries | |
form | |
tabs | |
groceries | |
fields | |
actorIds | |
content.groceries | |
class | info.magnolia.ui.form.field.definition.TextFieldDefinition |
content.budget | |
comment | |
actions | |
actionbar |
Task presenter
A task presenter is started when a user opens a task to see its details. The presenter builds the form and action bar which are displayed to the user in the browser. Magnolia provides a DefaultTaskDetailPresenter. See Task view for its functionality.
Most likely the task data you want to display in the Pulse can be rendered with the DefaultTaskDetailPresenter
. But in case the default presenter is not sufficient you can implement your own presenter and have it render whatever view is needed.
To implement a custom presenter, extend or use TaskUiDefinition instead of TaskDefinition and add a presenterClass
property with a custom implementation of the TaskDetailPresenter interface to the configuration.
Node name | Value |
---|---|
tasks | |
getGroceries | |
class | info.magnolia.ui.admincentral.shellapp.pulse.task.definition.TaskUiDefinition |
presenterClass | info.my-company.ui.GroceryTaskPresenter |
taskView | my-module:groceries |
title | Groceries |
In your implementation, you can access the task object as well as its definition using injection:
@Inject public GroceryTaskPresenter(GroceryView view, TaskUiDefinition definition, Task task) { ... }
Configuring bulk actions
The abort
, archive
and claim
tasks can be configured as bulk-actions as per default user roles. Specify the user roles for the tasks via the bulkActions
node in the configuration of the ui-admincentral
module.
The tree below shows the default setting for the archive
action (the definition class is info.magnolia.ui.admincentral.shellapp.pulse.task.action.ArchiveTasksActionDefinition
) with the superuser
role set to access this action:
Node name | Value |
---|---|
bulkActions | |
archive | |
availability | |
access | |
roles | |
superuser | superuser |
rules | |
CanArchiveTaskRule | |
status | |
Created | Created |
Failed | Failed |
InProgress | InProgress |
Resolved | Resolved |
Scheduled | Scheduled |
assignee | false |
class | info.magnolia.ui.admincentral.shellapp.pulse.task.action.availability.TaskAvailabilityRuleDefinition |
multiple | true |
class | info.magnolia.ui.admincentral.shellapp.pulse.task.action.ArchiveTasksActionDefinition |
icon | icon-delete |
To allow bulk actions for other 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.