-
Notifications
You must be signed in to change notification settings - Fork 9
Architecture of the ProcessForm Components
The Management System is supposed to provide multiple ways to create and interact with processes inside it. A user should be able to create new processes from scratch, by using an existing template or by importing it from a file. Once a process is created a user should be able to edit its meta data, copy it and select it as a process that is used by a callActivity inside another process.
Since handling all these use cases from inside a single monolithic component would result in a huge, hard to read file it became necessary to split the original ProcessForm into multiple files that were responsible for specific use cases. At the same time we wanted to prevent code duplication as much as possible. Most of the use cases share some functionalities like loading data of existing processes inside the system, committing the final data into the Vuex store or handling the user tasks of a process through different changes.
The ProcessForm provides the base for all other forms. It defines their base layout and some of the form entries all of them need like the process name or description. The other forms can add additional entries or override some of the existing entries using Vue's slots.
The ProcessForm is also responsible for running a validation of the data before committing it to the vuex store and for the commit itself.
The other ProcessForm components function as a wrapper around the base ProcessForm component. Their main purpose is to provide initial data that defines already existing data to use as well as what to do on commit.
By providing a reference to a potentially already existing process the forms can tell the lower level components where to initialize the form data from and by providing a specific id the forms can make sure that the ProcessForm will either create a new Process (Add/Import/Copy) or edit/override an existing process (Edit/Import).
The SubProcessSelection component is used to select other processes for callActivities inside the process editor.
For this use case it will override most of the functionality of the AddProcessForm using it only as a base layout.
The reason we are reusing the AddProcessForm instead of the base ProcessForm is that we want to allow a user to create a new process and directly use it for a callActivity. For this use case the SubProcessSelection will just expose the AddProcessForm and will then use the process information that is emitted by it when a process is created.
The Management System supports three types of processes: Processes, Projects and Templates. Projects require additional data like customer data that is not required for the other two types.
The ProjectProperties Component adds additional form input fields for these properties and handles their initialization from a potentially existing BPMN as well as writing the changed data back into the BPMN on submit.
Processes can contain UserTasks that use additional HTML data by default.
This component is responsible for handling provided HTML data as well as for loading existing HTML data from the store. It will also ensure that references in the BPMN are correct before it is submitted and that missing HTML is added while unused HTML is removed from the store after the process is submitted.
While using the Forms there might be situations that will result in some components making implicit changes, like adding or removing HTML data, or where a user has to decide how to resolve certain conflicts, like importing a process with HTML data to override another process that also provides HTML data.
This component will show warnings and information about these kinds of situations inside the ProcessForm and will allow a user to select an appropriate solution for potential conflicts.
The Proceed dBPMS allows UserTasks to be executed using another Application called 5thIndustry.
To allow a user to opt into this we provide another component that can be used to change if 5thIndustry or HTML should be used and to set some 5thIndustry specific information. This component is responsible for the UI elements allowing this and for writing the necessary information into the BPMN before the commit.
Multiple of the aforementioned components can make changes to the same data or have to react to these kinds of changes. The 5thIndustry Component decides if HTML or 5thIndustry will be used for UserTasks. The UserTask Component has to change the HTML information for the final commit based on this decision. The ProcessFormWarnings component has to consider the changes in the HTML Data for changes it is showing to the user.
Because of this we have to share the state of the form between all components that change what has to be submitted to the store.
We allow this by providing a shared processesData
Object for all components by using Vue's provide/inject functionality.
The highest level Form Components provide the shared Object as well as a function that will allow the components to change this data in a way that other components can react to. They also provide functions with which other components can sign up to be informed when the data has changed.
Since the logic with which this data sharing is set up is reused in all ProcessForms and multiple lower level components we decided to use Vues mixins.
The provider mixin provides the sharing and reactive functionalities.
The injector mixin will make sure that the provided functions and data are usable inside the components using it. It will implicitly register change handlers with the provider component when they are defined in the component using it. These handlers are initProcessData
, initProcessDataFromBPMN
, initFromExistingProcess
, removeBPMNRelatedData
and watchOtherChanges
.
Similar to the ProcessesData Mixins we also wanted to allow lower level components to register callbacks that should be executed before and after data is submitted to the store.
The provider mixin adds the provide functionality to the ProcessForm while the injector mixin allows the components using it to use that functionality to register their callbacks.
They callbacks are once again registered implicitly when the component using the injector mixin has a beforeSubmitValidation
, beforeSubmit
, or afterSubmit
method.