Repository navigation
Basic Workflow: support for "stage" #2256
Description
Related issues
- Basic Workflow: perspective-based UI Basic Workflow: perspective-based UI #3463
- Basic Workflow: backend Relational persistence API to handle stage, action to set stage, function to read stage #4639
Use case
In a small business, anyone with the role employee can submit an expense report by filling out a form. After it has been submitted, the employee who created the expense report can can see but not edit the data (but other employees can't see the data), and anyone with the role manager can either approve or reject it.
New concept: stage
Overview
- What a stage is:
- The set of possible stages a given form can be in is defined by the form author in Form Builder.
- At any given point, a form is one of the stages specified by the form author. For instance, in the above use case, the form author would define the following stage:
started,submitted,approved,rejected, withstartedmarked as the initial stage.
- What the stage influences:
- Different buttons can be shown at the bottom of the form depending on the current stage and the user's permissions (Ability to hide buttons based on permissions #1619). For instance, in the above use case, once submitted, the manager would see two buttons approve and reject.
- Whether fields are read only or visible. For instance, in the above use case, when an expense report has been submitted, all the fields in the expense report would become read only.
- How the stage changes:
- When a form is created, it gets the stage marked by the form author as the initial stage.
- Buttons can change the current stage. For instance, in the above example the approve button will change the state to
approvedand the reject button will change the state torejected.
In Form Builder
Stages
Out of the box, we'll have 2 stages: started (the default), and submitted. Our submit process will change the workflow stage to submitted, which will allow us to make a distinction in the database between form data that has been just saved, but hasn't been submitted yet, and data that has been submitted.
Available to
The Available to section shows in the Operations tab of the Workflow dialog. Its purpose is to allow form authors to whom a given operation is available, e.g. based on the user's authentication role or the workflow stage.
Pre-defined operations
Custom operations
Implementation
- Storage and persistence layer - On relational databases, the stage is stored in a separate column. On eXist, it is stored in the
metadata.xml. For the REST API, the stage is sent off-band through headers, as done currently for say, roles and operations. - Common code for permissions - Common code (proxy or Scala called by all persistence implementations) can determine, based on user's group and permissions, what the requirement on the stage is. Then, the persistence implementation can enforce that constraint, e.g. adding to its
WHEREclause. - New action to change stage - E.g.
change-stage('approved'). fr:stage()- A new XPath function is added that returns the current stage, so the stage can be used in MIPS and in processes where XPath expressions are used.- Redirect to view - If the user goes to
/editand has only the right to view, then she is redirect to/view.








Activity
[-]Basic workflow[/-][+]Workflow: support for "stage"[/+][-]Workflow: support for "stage"[/-][+]Support for "stage"[/+][-]Support for "stage"[/-][+]Basic support for "stage"[/+][-]Basic support for "stage"[/-][+]Support for "stage"[/+]Kevinhebertd commentedon Sep 29, 2015
Looking forward to this. Keep it up
ebruchez commentedon Sep 29, 2015
@Kevinhebertd We are working on it :)
ebruchez commentedon Nov 10, 2015
We have done quite a bit of progress on the UI. Remaining steps:
fix Travis buildOrbeon-Workflow-Stageheadermetadatacolumn /metadata.xmlmetadata.xmlandstagecolumnchange-workflow-stage()action (store alongside mode & version)fr:workflow-stage()functionKevinhebertd commentedon Nov 26, 2015
Do you have an updated release date for 4.11 ?? 😃
ebruchez commentedon Nov 26, 2015
It's not going to be in 2015, that's for sure. Shooting for sometime Q1 2016.
32 remaining items
avernet commentedon Mar 22, 2018
avernet commentedon Apr 3, 2018
Consider the case of an expense report, and say that after an employee submits an expense report, the employee can update it, but not approve it, and a manager can approve it (or reject it), but not update it.
When a persistence API implementation gets a PUT, it doesn't have enough information to discriminate between an update of the initial expense report (only allowed if done by the employee) and an approval or rejection (only allowed if done by the manager). It doesn't have enough information to properly enforce the permissions.
It could reject operations that are clearly forbidden, like a POST by someone other than the employee or the manager. And this is something we could do in the future, but it has two downsides:
(It should be noted that this second point is already a problem right now: a form can implement the above scenario by hiding controls or making them readonly based on the user's role, and persistence API implementation doesn't check that.)
ebruchez commentedon Feb 26, 2019
Summary of how do we handle the workflow UI so far:
object WorkflowTemplatesexposes to the UI templates for repeated content, etc. This is some amount of boilerplate.The idea is that:
In practice, our XForms implementation requires XPath expressions pointing to XML. That is why we do this Scala ↔ XML translation. See also #3455 for similar considerations on how we could improve that.
ebruchez commentedon Feb 26, 2019
I think we can continue along these lines for now. Steps:
avernet commentedon Apr 23, 2019
Next steps:
oxf.fr.detail.button.BUTTON.enabled.*.*property to determine if the button is enabled or disabled).For #2256: upgrade Circe version
For #2256: general-purpose XML ↔ Scala conversion
For #2256: support for stage for MySQL
For #2256: use `Stage` case class instead of `String`
For #2256: first version of new definitions
For #2256: general-purpose XML ↔ Scala conversion
ebruchez commentedon Jan 23, 2020
Supporting native instances would be good, see #3455.
ebruchez commentedon Jan 25, 2020
For reading/writing from/to the form definition:
Converting (option in the Form Builder permissions and/or Workflow dialogs?):
PermissionsXML.parse())WorkflowConfig(PermissionsToWorkflowConfig.convert())instance(fr-form-metadata)/workflow2020.1)Running:
TODO
Q: The "simplified XML" is useful right now for the UI. But should we store the definition to the form in JSON or XML? Right now we don't have a "simplified JSON".
write Form Runner functions usable at runtime:
WorkflowConfigfrom XMLebruchez commentedon Jul 6, 2020
Following discussion with @avernet today, we suggest, for the stage name, to have a localizable label. This is usual for:
avernet commentedon Feb 3, 2025
Status, maybe incomplete, at a very high level: