Workflow Handlers

Workflow Handlers layer behaviour on top of the basic ‘flowchart’ defined by the states.

These functions are called on the Definition object, and all take two arguments, a Selector and a function which will be called at the appropriate moment when the instance is selected by the Selector.

The handler function’s first argument is always M, the workflow instance.

Returning a value (which isn’t undefined) stops the handler chain.

observeEnter(selector, fn)

Called when a state is entered.

EgWorkflow.observeEnter({}, function(M, transition, previousState) {
});

transition is the transition which caused the move to this state, and previousState is the previous state. The current state, if not implied by the Selector, is in M.state.

observeExit(selector, fn)

Called when the process exits a state.

EgWorkflow.observeExit({}, function(M, transition) {
});

transition is the transition which caused the move from this state.

observeExit handlers are called before the workflow instance is committed to the database, so you can modify the underlying workunit and set timeline entry data. You may prefer to use transitionComplete to avoid race conditions when performing actions as a result of a completed transition.

observeFinish(selector, fn)

Called when the process enters a finish state and the workflow is complete.

EgWorkflow.observeFinish({}, function(M) {
});

transitionComplete(selector, fn)

Called when a transition is complete and all changes to the workflow instance have been committed to the database.

EgWorkflow.transitionComplete({},
  function(M, transition, previousState) {
  }
);

Note that the list of handlers is chosen using the selectors at the beginning of the transition, but the functions are called at the end of the transition with the new state of the workflow instance. This avoids having to select on all the possible destination states.

resolveTransitionDestination(selector, fn)

Called to choose which of the allowed destinations in the state definition will be taken. It’s called even if there is a single destination,.

EgWorkflow.resolveTransitionDestination({},
    function(M, transition, destinations, target) {
    }
);

transition is the transition name.

destinations is an array containing all the allowed destinations, in the order specified in the state definition.

Return a state name to choose a specific destination state. The state you choose is checked to make sure it’s in the allowed list.

filterTransition(selector, fn)

Called after resolveTransitionDestination() to filter out allowed transitions from a state. Your state definition must define all possible transitions, but they may not all be allowed in every instance of the process. This handler allows you to filter the transitions to the permitted set.

EgWorkflow.filterTransition({}, function(M, transition) {
});

transition is the name of the transition.

Return false to remove this transition. Return true to allow this transition regardless of any other handler functions. Return undefined to express no opinion on the matter, and allow other handlers to called.

If all handler functions return undefined, the transition will be allowed.

resolveDispatchDestination(selector, fn)

Called on entry to a dispatch state to immediately forward the workflow to another state. Your state definition must define all possible destination states. Return the name of the destination state to transition to.

EgWorkflow.resolveDispatchDestination({},
	function(M, transition, destination, target, possibleDestinations) {
	}
);

Using this handler and dispatch states may be simpler for workflows with complex routing logic than using multiple sets of resolveTransitionDestination and filterTransition.

actionPanel(selector, fn)

Called to populate the action panel which displays the status of the workflow, links to the transition UI, and any other useful information such as forms.

You should probably not return anything from this handler, as it would prevent all the UI from being added.

EgWorkflow.actionPanel({}, function(M, builder) {
});

builder is a PanelBuilder object.

There are two special purpose action panel handlers, actionPanelStatusUI() and actionPanelTransitionUI(), which can be overridden to adjust the default behaviour. They’re separate to allow that part of the UI to be overridden.

actionPanelStatusUI(selector, fn)

Similar to actionPanel(), but for adding the headline status display at the top of the action panel. Override this handler to change the default UI.

actionPanelTransitionUI(selector, fn)

Similar to actionPanel(), but for adding the links to the built-in transition UI. Override this handler if you need to use a different UI.

panelHeading(priority, title)

Called to set the title of a set of action panel elements with a given priority.

No title is rendered if there are no elements for the given priority.

renderWork(selector, fn)

Called to render the work unit.

EgWorkflow.renderWork({}, function(M, W) {
});

W is a PluginWorkUnitRenderer.

renderWorkList(selector, fn)

Called to render the work unit in the task list.

EgWorkflow.renderWork({}, function(M, W) {
});

W is a PluginWorkUnitRenderer.

workListFullInfo(selector, fn)

Update the PluginWorkUnitRenderer view when rendering the work unit in the task list to set the “full info” link and label.

EgWorkflow.workListFullInfo({}, function(M, W, view) {
});

W is a PluginWorkUnitRenderer, view is the view which will be passed to render().

The handler should modify the properties of the view as described in the render() documentation.

notification(selector, fn)

Alter the view for the email notification sent to the user when the work unit becomes actionable by them.

It’s usually easier to use the Text system to set the text for the email than use this handler.

EgWorkflow.notification({}, function(M, notificationView) {
});

notificationView is the notification view object.

Return false to prevent the notification from being sent.

notificationModifySendEmail(selector, fn)

Alter the email notification sent when a work unit is assigned to a user. This is called after the notification handler, if defined, is used to modify the view. It is called before modifySendEmail.

fn takes M and specification, where specification is an object containing the properties:

  • template, set by default to the generic notification template provided by the platform
  • view, the notification view object that may have been modified by the notification handler
  • to, by default set to the work unit actionableBy
  • cc, by default an empty array
  • except, by default an empty array
  • toExternal, by default an empty array
  • ccExternal, by default an empty array

transitionUI(selector, fn)

Control the built-in transition UI.

EgWorkflow.transitionUI({}, function(M, E, ui) {
});

E is the Exchange object.

ui is a TransitionUI object, on which you should call functions to modify the UI.

transitionFormSubmitted(selector, fn)

Called when the built-in transition UI form is submitted, but before the workflow UI is fully committed to the transition.

EgWorkflow.transitionFormSubmitted({}, function(M, E, ui) {
});

E is the Exchange object.

ui is a TransitionUI object. Call preventTransition() and redirect() to stop the transition and send the user somewhere else.

transitionFormPreTransition(selector, fn)

Called when the built-in transition UI form is submitted, after the workflow UI is fully committed to the transition.

EgWorkflow.transitionFormPreTransition({}, function(M, E, ui) {
});

E is the Exchange object.

ui is a TransitionUI object. Call redirect() send the user somewhere else.

transitionUIPostTransitionRedirectForActionableUser(selector, fn)

Called when the built-in transition UI has completed a transition, and the new actionable user is still the current user. Return a URL to override the default redirect to the workflow’s url.

Note the selector applies to the workflow after the transition has taken place.

EgWorkflow.transitionUIPostTransitionRedirectForActionableUser({},
    function(M, ui) {
    }
);

ui is a TransitionUI object.

preWorkUnitSave(selector, fn)

Called just before save() is called on on the underlying WorkUnit. It’s especially handy for updating WorkUnit tags.

EgWorkflow.preWorkUnitSave({}, function(M) {
});

You can modify the WorkUnit, available as the M.workUnit property. But be careful.

setWorkUnitProperties(selector, fn)

Called after the workflow process is committed to a transition to give the workflow a chance to update the WorkUnit.

EgWorkflow.setWorkUnitProperties({}, function(M, transition) {
});

transition is the name of the transition.

You can modify the WorkUnit, available as the M.workUnit property. But be careful.