Documentation Index
Fetch the complete documentation index at: https://docs.activeviam.com/llms.txt
Use this file to discover all available pages before exploring further.
Overview
The UserActionDTO dynamically generates actions on the UI and submits them to the server. The actions can be either form actions or workflow actions.
Form actions relate to product-specific actions, while workflow actions are used to move the workflow. Form actions have UI elements, such as buttons connected to them. For these to be rendered correctly, form actions can’t be removed or added. However, workflow actions are dynamically rendered, so they can be customized. This section refers only to workflow actions.
The UserActionDTO looks as follows:
/**
* <b>UserActionDTO</b>
*
* <p> The DTO used by the UI to receive and process actions submitted from the UI to the server.
*
* @author ActiveViam
*/
@Data
@SuperBuilder(toBuilder = true)
@NoArgsConstructor
@JsonTypeInfo(
use = JsonTypeInfo.Id.NAME,
property = "type")
@JsonSubTypes({
@JsonSubTypes.Type(value = WorkflowTaskActionDTO.class, name = "WORKFLOW"),
@JsonSubTypes.Type(value = FormActionDTO.class, name = "FORM")
})
public class UserActionDTO implements Serializable {
/*
* The name of the action, which will appear as the button
*/
protected String name;
/*
* The type of the action, which can be either a workflow action or a form action.
*/
protected UserActionType type;
/*
* True if the UI component should be enabled, false otherwise.
*/
@Builder.Default protected boolean enabled = true;
/*
* Input fields for workflow action. Used by the UI to generate component on-the-fly.
*/
@Builder.Default
private List<UserActionInputFieldDTO> actionInputFields = new ArrayList<>();
/*
* This method is used to make a copy of the retrieved bean
*
* @return a copy of this object
*/
public UserActionDTO createCopy() {
return toBuilder().build();
}
}
The WorkflowTaskActionDTO inherits all the fields of UserActionDTO and looks as follows:
/**
* <b>WorkflowTaskActionDTO</b>
*
* <p> The DTO used by the UI to receive and submit user actions on workflows.
*
* @author ActiveViam
*/
@Data
@EqualsAndHashCode(callSuper = true)
@SuperBuilder(toBuilder = true)
@NoArgsConstructor
public class WorkflowTaskActionDTO extends UserActionDTO {
/*
* The task key of the custom action. This is used to trigger an action in the backend, and should be unique for each task action in the application.
* */
protected String taskKey;
/*
* An optional consumer to update the DTO (for example to enable the button) that accepts the current {@link UserActionDTO} and a {@link WorkflowTaskActionObject}.
* The {@link WorkflowTaskActionObject} contains the workflow task - in its current state - and process instance ID for which the action is intended to be applied.
*/
@Builder.Default @JsonIgnore
protected transient BiConsumer<UserActionDTO, WorkflowTaskActionObject>
currentTaskConsumer = (wa, taskActionObject) -> {
};
@Override
public UserActionType getType() {
return WORKFLOW;
}
}
The UserActionInputFieldDTO tells the UI which kind of component to render and looks as follows:
/**
* <b>UserActionInputFieldDTO</b>
*
* <p>A DTO to represent the input fields in the UI used by actions.
*
* @author ActiveViam
*/
@Data
@SuperBuilder(toBuilder = true)
@NoArgsConstructor
public class UserActionInputFieldDTO implements Serializable {
/*
* The label of the UI field
*/
protected String label;
/*
* The input type of this field: SELECT for multiple options (a dropdown), TEXT for a text input, LINK for a navigable link, CHECKBOX for a boolean checkbox
*/
protected UserActionInputFieldInputType inputType;
/*
* If this field is required by the UI for form submission
*/
protected boolean required;
/*
* True if the UI input field should be enabled, false otherwise.
*/
@Builder.Default protected boolean enabled = true;
/*
* An optional tooltip to display on the UI input field component
*/
protected String tooltip;
/*
* The list of options for a SELECT field. Will not be used for TEXT fields.
*/
@Builder.Default private List<String> options = new ArrayList<>();
/*
* A default value used to pre-fill the input field.
*/
@JsonSerialize(using = DynamicActionInputValueSerializer.class)
protected Serializable defaultValue;
/*
* The variable used to link this input field with a backend variable
*/
protected String actionVariable;
}
where UserActionInputFieldInputType can be one of:
public enum UserActionInputFieldInputType {
SELECT, // Select multiple options from a dropdown.
TEXT, // Input the option as a text field.
LINK, // Input the option as a navigable link.
CHECKBOX, // input the option as a boolean checkbox
}
We have added lombok builder methods to quickly create instances of this class.
Define the beans
Depending on the type of WorkflowTaskActionDTO supplied to the UI, it will render a button that on clicking will either:
- Execute an action
- Show a popup for submission and then execute an action
1. Execution only action
The simplest instance of a WorkflowTaskActionDTO looks as follows:
@Bean
public WorkflowTaskActionDTO approveTaskButtonWorkflowAction(){
return WorkflowTaskActionDTO.builder()
.name("Approve")
.actionKey("Approve")
.build();
}
In this case, a button will appear on the UI with the label Approve and when clicked, it will submit a response to the server to execute the task specified by the task key “Approve”.
For more information on how the task is executed, see Executing the Java Task.
A more complex instance of a WorkflowTaskActionDTO will specify input fields to be rendered in the UI, updated and submitted to the server.
It can also provide a defaultValue for fields, which will pre-populate the input field in the UI. Example:
@Bean
public WorkflowTaskActionDTO reviewBreachTaskButtonWorkflowAction(){
List<WorkflowTaskActionInputFieldDTO> inputFields = new ArrayList<>();
WorkflowTaskActionInputFieldDTO classificationField = WorkflowTaskActionInputFieldDTO.builder()
.label("Classification")
.taskVariable("classification")
.required(true)
.inputType(SELECT)
.options(List.of("Unclassified","Technical Issue","True Breach","New Trade","Late Trade","Market Moved"))
.defaultValue("Unclassified")
.build();
WorkflowTaskActionInputFieldDTO riskCommentField = WorkflowTaskActionInputFieldDTO.builder()
.label("Risk comment")
.taskVariable("riskComment")
.inputType(TEXT)
.build();
inputFields.add(classificationField);
inputFields.add(riskCommentField);
return WorkflowTaskActionDTO.builder()
.name(REVIEW_NAME)
.actionKey(REVIEW_KEY)
.taskInputFields(inputFields)
.build();
}
In this example, we define two input fields: Classification and Risk Comment, with the following properties:
Classification is required, so the form may not be submitted until its value is filled. Risk Comment is not specified as required, so it defaults to false.
Classification has input type SELECT, so the options listed will be available in a dropdown.
Risk Comment has input type TEXT, so a text field will appear requesting input.
Import the beans
Once defined, the beans can then be imported into the Atoti Sign-Off project. A nice convention is to have one @Configuration file per workflow, and to import these into a parent @Configuration.
Then, this one parent @Configuration can be imported to the project.
For example, the out-of-the-box workflow actions are included in WorkflowTaskActionsConfig:
@Import({
CommonWorkflowActionsConfig.class,
ProcessDefinitionWorkflowActionsConfig.class,
})
public class WorkflowActionsConfig {
}
- and the
ProcessDefinitionWorkflowActionsConfig class contains the actions related to the process definition workflow:
@Configuration
public class ProcessDefinitionWorkflowActionsConfig {
@Bean
public WorkflowTaskActionDTO saveWorkflowAction() {
return WorkflowTaskActionDTO.builder()
.name(SAVE)
.actionKey(SAVE)
.taskInputFields(List.of(getCommentInputField()))
.build();
}
@Bean
public WorkflowTaskActionDTO deleteWorkflowAction() {
return WorkflowTaskActionDTO.builder()
.name(DELETE)
.actionKey(DELETE)
.taskInputFields(List.of(getCommentInputField()))
.build();
}
// ... other beans
protected WorkflowTaskActionInputFieldDTO getCommentInputField() {
return WorkflowTaskActionInputFieldDTO.builder()
.label(COMMENT_NAME)
.taskVariable(COMMENT_VARIABLE)
.inputType(TEXT)
.build();
}
}