Vocabularies contain all the information which can be used in conditions and updated in actions. For example: The form field and the datasource field values we use in conditions, and the form field and page (tabs) enabled and visible properties we can set in actions.
Vocabularies can be generated either for an entire window and everything in it (all the datasources, forms, pages and ribbons) including nested frames, or just a frame with everything in it but not including nested frames so frame vocabularies are much smaller and simpler than window vocabularies which can be very big.
The guidelines for designing rules and the reason for generating both window and frame vocabularies is to split the rules into several small and simple frame rule flows instead of having all the rules in a single big window rule flow.
So rules should and in most cases can be placed in the frame rules unless there are cases where the conditions and actions reference fields from multiple frames or ribbons (ribbons are usually in the widow) etc. which are less common (or if there is only a window and no frames).
In other words, use frames whenever you can and windows when you have to.
At runtime whenever a field is changed or a record is selected etc. it triggers the rule flow execution for the frame and also the rule flow execution for the window (if there are rule flows for the window and frame) incase there are rules in the window that are also effected.
There is currently no need or use case to change the default values when generating a vocabulary.
The Generate Vocabulary window creates a vocabulary file with the same name as the window or frame and the .ecore extension. Currently the file is saved out to the PASOE temp directory. After the vocabulary file is generated, copy the file to your workspace (see file and directory structure).
Note that currently generating vocabularies for big windows can take 5 or more minutes. Generating vocabularies for frames is much faster.
In addition, the layout designer sets the RulesBehaviour and RulesMetadata properties for the window and the frame. These properties contain metadata and advanced options. There's currently no need or use cases to change these properties except when removing a rule flow by deleting or setting an empty JSON object "{}".
There are 4 main rule file types and file extensions -
If you open any of the rule files in a text editor like Notepad++ you can see they are all XML files.
In addition, there are also the generated JavaScript files (minified .js files) used at runtime. The rule files are the only and absolute source of truth for the generated .js files. The .js files should not and cannot be modified manually.
The rules root directory is located in the customer webui/Rules directory (in the frontend project repository).
The root directory contains a Ruleflows directory for all the rule files. The Ruleflows directory is organized into directories by module similar to the frontend and backend source directories. For example: Entscheid, Sendung, Stamm etc. directories.
In addition, the root directory contains directories for every generated window or frame rule flows containing the .js files. These directories are located in the root directory partly because this is the default location in the Corticon Generate Ruleflow dialog-box and it saves developers from changing the directory manually every time.
Currently the .js files are included in the git repository and need to be committed instead of being generated in the build. There is a risk of the rules and .js files not matching in this approach. For example: if the rules were updated and someone forgot to generate the .js files.
Incase the .js files will need to be generated in the build the script files in the akioma corticon-java project can be used to generated the .js files (see the in Corticon integration guide).
There are advantages and disadvantages to separating unrelated rules with unrelated conditions to separate rule sheets or combining them to a single rule sheet.
On the one hand keeping unrelated rules in separate rule sheets allows for the best use of the Check for Conflicts and Check for Completeness features in Corticon but on the other hand having many rule sheets files with just one line rules is also unwanted.
The general best practices from Progress Software is to use separate rule sheets for complex conditions with many combinations and combine simpler rules into a single rule sheet to save on rule sheets files and are also where the Check for Conflicts and Check for Completeness is less needed. In other words, it's a balancing act, just like writing code.
Taking into account that UI rules are mostly made up of many simple rules and how the rules are mostly divided in the specification, the rules should be divided in the following way -
With the exception that complicated rules with many conditions fields and many combinations are put in a separate rule sheets.
Rule tests are the first and best way to debug and track down problems. Every rule sheet should have a rule test with the exception of the fixed rule sheet.
Rule tests are created with a single test sheet (tab). To add another test sheet (tab), open or select a rule test file, open the Ruletest menu, open the Testsheet menu and click the Add Testsheet menu item.
Rule tests also show you the rule statements of the rules that were triggered when running the test sheet to further help debug and understand the output.
You cannot have different tests with different conditions in a single test sheet and they must be separated into separate test sheets. Alternatively, use a single test sheet with conditions that triggers multiple rules.
Rule tests need to be incorporated and run as part of the build and pipeline unit tests.
Remove unused fields that have no conditions when copying entities to the input column, to keep the rule tests simple and readable (keeping in mind that some forms and datasources can have tens or even hundreds of fields).
Note that at runtime Corticon logging can be turned on by setting Corticon.debug = true that will console log the rule triggers, execution, messages (rule statements), payload and result.
Even though the rule sheets have no dependencies by default (except for special cases) and there is no need to connect them, it is still considered a best practice and you should always connect the rule sheets so the order of execution is clear.
Of course, there can be more complicated rule flows but there's currently no need or use case.
There is currently no need or use case to change the defaults when generating the .js files except for setting the Platform to browser.
Corticon creates a directory in the rules root directory with the same name as the rule flow (which is also the name of the window or frame) containing all the required files.
The Corticon runtime looks for the generated .js files in the same directory so there is no need to copy or manually move files.
The window and frame names are unique so there is no risk of conflicts.
Using code should only be used as a last resort and if there is no other choice. Whenever possible backend data should be taken from the business entity. If the data does not exist in the business entity, consider adding the fields or even creating another business entity with the required fields.
To run simple synchronous code like fetching data from the UI, Corticon.js supports JavaScript functions calls in rule sheets. You can create custom properties and set their values with JavaScript functions in the fixed rule sheet.
To run asynchronous code like backend calls, create a regular TypeScript event handler file that sets custom properties in the screen akEvent payload property and then calls the frame or window controller callRules() method to execute the screen rules.
The framework provides several entry points in the Corticon execution process:
The events can be specified from the Corticon 'RulesBehavior' attribute, using properties with the same name as the event.
The event format itself is identical with the other framework events, with 'self' referencing the rules' main window.
The payload is made accessible through the window's akEvent property. (akEvent.rulesExecution.payload)
As of SWAT 21.14, the vocabularies will be generated with a new custom screen properties entity. (_CustomData.CustomScreenProperties)
By default the entity will be empty, it won't contain any properties.
To add screen properties, the 'RulesBehavior' attribute now accepts a new property 'CustomPropertyObjects', which will contain a comma-separated list of MATCHES patterns for repository data fields.
(ex. "field1,field2,fields*", which will match objects 'field1', 'field2' and all objects starting with 'fields')
All matching data field objects will be processed and a corresponding property will be added to the custom screen properties entity.
The role of this new entity is to provide an easy and accessible way to add custom properties to a vocabulary without risk of losing them on regeneration. (as it happens now for manually added ones)
The custom properties can be assigned from the Corticon custom events and to facilitate this, the following helper functions have been made available:
/** * Gets an entity from a given payload * @public * @static * @memberOf Corticon * @param {Object} payload The payload * @param {string} entityName The entity name * @returns {Object} The entity object from the payload or undefined if not found */ Corticon.getCustomScreenPropertiesFromPayload(payload); /** * Gets the 'CustomScreenProperties' entity from a given payload * @public * @static * @memberOf Corticon * @param {Object} payload The payload * @returns {Object} The entity object from the payload or undefined if not found */ Corticon.getEntityFromPayload(payload, entityName); |
Progress tutorials (see link below) -
https://www.progress.com/corticon/corticon-learning-center
Corticon.js Integration Guide for DevOps (see link below) -
For example: generate .js files and run unit tests from the command line)
corticon_js_integration_draft.pdf