Function lists

These function lists configure the overall properties of the Workflow. You may only need to implement start().

Functions added to a list are called in reverse order of being defined, breaking as soon as any returns a value.

start(fn)

Called when a new workflow is started. Use this to configure the starting state of the workflow, which otherwise defaults to "START".

EgWorkflow.start(function(M, initial, properties) {
    initial.state = "starting_state";
});

properties is the argument to the create() function which creates the instance.

implementWorkflowService(name, fn)

Defines a service fn that can be called by name on any instance of this workflow. fn takes the instance as the first argument.

By convention name should begin with the workflow name as specified in P.workflow.implement().

If there is more than one implementation for a service name, they will be called in reverse order of registration until one returns something other than undefined (as for all workflow function lists).

Note: This differs from platform services, which are called in order of registration.

EgWorkflow.implementWorkflowService("eg:can_view_workflow", function(M, user) {
    return CanViewApplication(M, user);
});

getActionableBy(fn)

Translate an actionableBy name into a SecurityPrincipal object. If your function cannot find this user, then make sure you return undefined so other functions can try too.

EgWorkflow.getActionableBy(function(M, actionableBy, target) {
    if(actionableBy === "user") {
        return O.user(M.workUnit.data.userEmail);
    }
});

There’s a fallback implementation which provides some very basic actionable by names:

  • "object:creator", the user which created the object associated with the process
  • the API code of any group.

If you implement getActionableBy(), add a hasRole() function which looks up your name.

The entities system provides an implementation which usually does everything you need.

hasRole(fn)

Given a SecurityPrincipal object, test to see if the user has the given role in the instance.

There’s a fallback implementation which tests whether the user is a member of a group, specified by API code, or "object:creator", matching the fallback implementation for getActionableBy.

EgWorkflow.hasRole(function(M, user, role) {
    if(role === "user") {
        return (user.email === M.workUnit.data.userEmail);
    }
});

textInterpolate(fn)

Given a text string, modify it. This is used to replace tokens by specific names, for example, names of the actual users involved.

The entities system implements a useful text interpolation based on the defined entities.

EgWorkflow.textInterpolate(function(M, text) {
    return text.replace(/\#email\#/g, M.workUnit.data.userEmail);
});

This function is slightly unusual in that it must always return a value, and that value is passed through all functions so all interpolations are performed, not just the first matching interpolation.

renderTimelineEntryDeferred(fn)

Render a custom timeline entry.

EgWorkflow.renderTimelineEntryDeferred(function(M, entry) {
});

entry is the timeline entry. Test entry.action to see if it’s something you should render, and if so, return a deferred render using deferredRender() on a template using the properties in M and entry.data.

taskUrl(fn)

Generate the canonical URL of the page representing this instance.

You should not generally need to implement this, as if your workflow is associated with an Object, that page will automatically be used.

EgWorkflow.taskUrl(function(M) {
  return "/do/example/process/"+M.workUnit.id;
});

taskTitle(fn)

Generate the human readable name of this instance, used in links and throughout the UI.

You should not generally need to implement this, as if your workflow is associated with an Object, the title of the object will be used.

EgWorkflow.taskTitle(function(M) {
  return "Process "+M.workUnit.id;
});

modifyFlags(fn)

Features may use this function list to modify the flags. It’s recommended that you avoid the use of this function list if possible.

You can force a recalculation of the cached flags with recalculateFlags().

EgWorkflow.modifyFlags(function(M, flags) {
  flags.xyz = true;
});

modifySendEmail(fn)

Alter any email that is sent. fn takes M and modify, modify is an object containing the property specification, which is an object with the properties described here.

Make changes by modifying the desired property on the modify.specification object.

EgWorkflow.modifySendEmail(function(M, modify) {
    modify.specification.cc = (modify.specification.cc || []).push("researchAdministrator");
});