Actions – sequences of commands that do the work¶
An action is a named sequence of commands: create or change records, call other systems, send mail, open forms, ask the user. Everything in nexxcite that has to happen in order is an action. This chapter explains how actions are started, how they run, how they are built in the action editor and how to find out what they did. It is intended for administrators who design the logic of an application.
The single commands are described on their own pages; section 11 lists all of them.
1. Actions at a glance¶
An action does not decide when it runs – a button, a business rule, a schedule or another trigger starts it. It decides what happens: its commands run one after another against a record, the current record.
| Part | Meaning |
|---|---|
| Entity | The entity whose records the action runs against. Leave it empty for an action that only talks to the user – it then has no current record. |
| Commands | The steps, in order. Several commands contain further commands (loops, "Switch"). |
| Pre and post commands | Optional commands that run once before and once after the main commands |
| Variables | Values the commands hand to each other, see Action variables |
| Execution condition | An expression that decides whether the action may start at all |
| Settings for operation | Timeouts, loop protection, "Trace Executions" |
Summary¶
- An action runs with the rights of the user it runs for. The read, add, edit and delete limits of the user's roles apply to its commands (section 10).
- An action started by a user in the browser can show forms and ask questions. An action started in the background (schedule, background rule, mailbox listener, REST API) cannot – commands that need a user interface are skipped there.
- There is no transaction across the commands. What a command saved stays saved, even if a later command fails.
- Runs in the background are always recorded in the execution history. Runs a user starts are recorded only when "Trace Executions" is switched on.
Actions are managed under Admin Studio → Automation → Actions, and per entity in the area Entities. See Admin Studio.
2. How actions are started¶
| Trigger | Runs against | Runs | Described in |
|---|---|---|---|
| Button, image, avatar, badge or element in a form | The record of the form | Interactively | Forms |
| Click on a row of a related items grid or an entry of a related items list | The clicked related record | Interactively | Forms |
| Item of an app bar | The record of the form, or the records selected in a grid | Interactively | App bars |
| Badge column of a grid | The record of the row | Interactively | Grids |
| Widget of a dashboard (button, element, image, badge, catalog tile, search field) | The record of the tile, or no record | Interactively | Dashboards |
| "Home Action" of a role | No record | Interactively, after sign-in and on "home" | Roles and permissions |
| Business rule that starts an action in the user interface | The record the rule reacts to | Interactively | Business rules |
| Business rule that starts an action in the background | The saved record | In the background, optionally delayed | Business rules |
| Scheduled action | No record | In the background | Scheduled actions |
| Mailbox listener | The record the mail belongs to, or no record | In the background | Mailbox listeners |
REST API (POST api/v1/actions/{id}/run) |
The record named in the request, or no record | In the background | Run an action |
| Command Execute Action in another action | The current record of the calling action | Like the calling action | This chapter |
| "Execute" in the management view of the actions | The record of the page that is open, if any | Interactively | – |
Where a definition offers an action, you can pick a stored action, write a custom action that belongs only to that place ("Select or create action", tab "Create Custom Action"), or choose a quick action from the drop-down: "Home", "Save", "Refresh", "Discard", "Invalidate Relationships", or navigating to a dashboard or to the results of a query. Prefer a stored action when the same steps are needed in more than one place.
Running against a group of records¶
An action runs once per record in two cases:
- "Runs Against Query" is set: the action runs once for every record the query returns. The record it was started on is ignored. The query is evaluated without a current record. If it returns nothing, the action does nothing.
- An app bar item of a grid starts the action while the user has selected records. This applies when the action belongs to the entity of the grid's query and the grid is not a related items grid in a form.
The pre commands then run once before the first record and the post commands once after the last record, both without a current record. The special variables "Action Iteration" (position of the current record, starting at 0) and "Action Iteration Total Records" tell the commands where they are. If the run for one record ends early or fails, the remaining records are not processed.
Example: "Remind overdue invoices" runs against the query "Invoices overdue". The query returns 40 invoices. The pre commands write the date into a variable, the commands run 40 times – once per invoice – and the post command writes one log entry with the number 40 from "Action Iteration Total Records".
3. Interactive and background runs¶
| Interactive | Background | |
|---|---|---|
| Started by | A user in the browser | Schedule, background business rule, mailbox listener, REST API |
| Runs as | The signed-in user | The identity configured on the trigger, or the user who caused it (background business rules can be set to that), or – for the REST API – the user of the API access |
| Forms, dialogs, popups, navigation | Shown | Skipped – the command does nothing and the action continues |
| Prompts in expressions | Shown to the user | Cannot be answered – the action ends quietly at that command |
| Execution history | Only with "Trace Executions" | Always |
Commands that need a user interface are marked on their pages. An action that has to work from a button and from a schedule must not rely on them. Some commands behave differently without a user interface – for example Go To Record only changes the current record, Delete Entity Record deletes without asking and Open E-Mail Form runs its send action at once with the prefilled mail.
Changes that are not saved: in an interactive run, changes the action made but did not save stay on the form, and the user can save or discard them. In a background run there is nobody to save them – they are lost when the action ends. Save explicitly with Save or with "Save" on the command that changes the record.
4. The current record and context changes¶
Every command works on the current record (also called the context). At the start this is the record the action was started on. Three commands change it for all commands that follow:
| Command | New current record |
|---|---|
| Create Entity Record | The record it created |
| Go To Record | The record it opened |
| Change Context | The record that was current right after an earlier command – or the original record |
For Each Related Record makes each related record the current record inside the loop only. After the loop, the record from before is current again. The other loop commands (JSON, XML, files, file lines) keep the current record and hand each element over in a variable. Execute Action hands the current record to the called action.
The editor shows this: the canvas groups the commands by the entity they work on, with the name and the colour of the entity above each group, and the properties of a command name the entity it starts with and, for a command that changes it, the entity it ends with.
Example: An action on "Order" creates an "Invoice" with Create Entity Record, sets three fields of the invoice with Update Entity Record, saves it and then changes back to the order with Change Context ("Original Context (Order)") to set the order's status to "Invoiced".
When you read an existing action, find the context changes first – a command in the middle of an action works on whatever the last context change left behind, not necessarily on the record the action was started on.
5. The action editor¶
The action editor opens from the management view or the Admin Studio. On the left is the canvas with the flow, on the right the properties of what is selected.
The canvas¶
| Element | Meaning |
|---|---|
| Start symbol | The action itself. Selecting it shows the properties of the action (section 6). |
| Cards | The commands, in the order they run, with their name and their kind. A function symbol marks a command with an execution condition; its text is shown on hover. |
| Arrows | Between two commands. "+" on an arrow ("Insert command here") opens a searchable list of all commands ("Search command") and inserts the chosen one exactly there. |
| Frames with a coloured dot | A group of commands that work on the same entity (section 4) |
| Loop box | The commands inside a loop command, between a loop symbol and an exit symbol |
| Branches | The cases of a "Switch", each labelled with its name, the default case last |
| Flag | The end of the action |
Commands can be dragged to another place, also into and out of loops and cases. Below the canvas are the zoom controls "−", "+" and "Fit"; the editor remembers your zoom.
If "Has Pre Commands" or "Has Post Commands" is on, tabs on the left switch between "Pre", "Commands" and "Post".
The toolbar¶
The menus "Flow", "Data", "Communication", "UI", "AI", "LDAP" and "Files" add a command at the end of the list that contains the selected command (or at the end of the main list if nothing is selected). "Remove Item" removes the selected command – a loop or a switch together with everything inside it. "Clone" copies the selected command.
Properties of a command¶
Every command has on its tab "General":
| Setting | Meaning |
|---|---|
| "Display Name" | Name on the card. New commands are named after their kind; give them a name that says what they do. |
| "Description" | Free text for other administrators |
| "Execution Condition" | Optional logical expression. If it is false, the command is skipped and the action continues with the next command. |
The other settings are on the further tabs (usually "Settings") and described on the page of each command. Expressions in commands can use the fields of the current record and the variables of the action.
Nesting, loops and branches¶
| Construct | Commands | Behaviour |
|---|---|---|
| Branch | Switch | The first case whose condition is true runs; otherwise the default case |
| Loop over related records | For Each Related Record | Runs its commands once per related record |
| Loop over data | Iterate JSON, Iterate XML, Iterate Files, Iterate File Lines | Run their commands once per element |
| Jump | Jump | Continues at another command, depending on a condition |
| Sub-action | Execute Action | Runs another action and waits for it |
Commands inside a loop or a case share the variables of the action. If a command inside ends the action or fails, the loop stops and the whole action ends.
Recommendations: prefer "Switch" over chains of jumps; move a coherent part into its own action and call it with Execute Action; put the guard of the whole action into its execution condition instead of the first command.
Saving the action¶
The action is saved with the buttons of the editor like every other definition. While a sketch is open, the change is collected in the sketch and takes effect when the sketch is published (see Sketches and publishing). Without the permission "Edit Action" the editor opens read-only.
6. Properties of the action¶
Selecting the start symbol shows the properties of the action.
| Tab | Setting | Meaning | Default |
|---|---|---|---|
| "General" | Name, description, tags | Like every definition | – |
| "General" | "Enabled Special Variables" | Special variables the expression editors of this action offer (see Action variables). Only affects the editor – nexxcite sets special variables regardless. | None |
| "Behavior" | "Runs Against Query" | Run once per record of this query (section 2) | Empty |
| "Behavior" | "Execution Condition" | Logical expression, evaluated against the record the action is started on. False: the action does not start. | Empty: always runs |
| "Behavior" | "Execution Condition Error Message" | Text shown to the user when the condition is false | Empty: "Action not allowed to be executed!" |
| "Behavior" | "Has Pre Commands" | Show and run the lane "Pre" | Off |
| "Behavior" | "Has Post Commands" | Show and run the lane "Post" | Off |
| "Behavior" | "UI Interaction Timeout (seconds)" | How long a command waits for the user interface to report that it finished an interaction it started itself, for example loading a form. Also limits how long a popup without buttons may stay open. | Empty: ActionRuntime:UIInteractionTimeoutSeconds (120) |
| "Behavior" | "Max Recursion Depth" | How often this action may start itself again within one chain, directly or through a business rule. 0 forbids it. |
Empty: ActionRuntime:MaxRecursionDepth (5) |
| "Behavior" | "Trace Executions" | Record runs started by users in the execution history (section 9) | Off |
| "Behavior" | "Store Execution Log" | "Inherit (use the next level)", "Never", "On failure or warnings", "Always" – whether the log written during a recorded run is stored with it | Inherit |
| "Variables" | Variables | See Action variables | None |
Pre and post commands¶
Pre commands run once before the main commands, post commands once after them – for every way the action is started, including Execute Action and the REST API.
- In a run on a single record they share that record and the variables with the main commands.
- In a run against a group of records they run once in total and have no current record (section 2).
- If the pre commands end the action or fail, the main commands do not run. If the main commands end the action or fail, the post commands do not run.
The pre and post lanes have their own commands; a Jump cannot go from one lane into another.
The execution condition¶
The condition is checked before anything else. If it is false, the action does not run, and a user in the browser sees the error message in a dialog. For a run against grid-selected records the condition is checked per record and only skips that record. For Execute Action the condition of the called action is checked too; if it is false, the calling action ends.
7. Saving and transactions¶
- Commands that change records keep the changes in memory until the record is saved – by Save, by "Save" on the command itself, by the user, or not at all.
- Saving runs the same validations, calculations and business rules as a user pressing save. A failed save shows the reasons ("Field(s) … must be filled in for …") to a user in the browser. Save and the "Save" option of the update commands then end the action with an error. The "Save" option of the create commands does not – see their pages.
- If business rules that run after the save fail, the record stays saved; the user sees "The record was saved, but a follow-up rule failed" and the action continues.
- There is no rollback. If an action creates an invoice, saves it and then fails at the next command, the invoice stays. Design actions so that a second run can repair or complete the work, or check conditions before the first save.
- Commands that leave the record – Navigate, Go To Record with a form, Create Entity Record with "Show Form" – first ask the user what to do with unsaved changes: "Save", "Discard" or "Cancel". "Cancel" ends the action and keeps the changes.
8. Errors and how an action ends¶
Every command ends in one of four ways:
| Result | Meaning | The action |
|---|---|---|
| Executed | The command did its work | Continues |
| Skipped | Execution condition false, no user interface, or settings incomplete | Continues |
| Ended | The command ended the action on purpose: jump to "(End Action execution)", popup cancelled, user declined a confirmation, record not found | Stops, without an error |
| Failed | An error occurred: a failed save, an exception, a timeout | Stops, with an error |
What the user sees:
- Execution condition not met: the error message in a dialog.
- Failed save: the reasons in a dialog.
- Any other error: usually nothing. The reason is written to the application log and to the protocol of the run. Use "Trace Executions" or the developer console to find it (section 9).
When a command fails inside a loop, a case or a called action, the whole action ends. A run against a group of records stops at the first record that ends or fails.
Loop protection¶
Actions can start each other – directly with Execute Action or indirectly, for example by saving a record whose business rule starts the same action again. nexxcite stops such loops:
| Limit | Default | Set in |
|---|---|---|
| How often the same action may run nested within itself | 5 | "Max Recursion Depth" of the action, ActionRuntime:MaxRecursionDepth |
| How many actions one chain may contain at all | 25 | ActionRuntime:MaxActionCallDepth |
An action that would exceed a limit is not started; the action that tried to start it ends with an error. See Installation and configuration.
9. Execution history and tracing¶
| Run | Recorded under Admin Studio → Monitoring → Background Processes |
|---|---|
| Background business rule, scheduled action, mailbox listener, REST API without waiting | Always |
| Started by a user, REST API with waiting for the result | Only with "Trace Executions" |
| Action called by another action | As part of the run that called it |
A recorded run shows when it ran, for whom, against which record, the result and the protocol of the
action command by command – including the actions it called and those that business rules started
because of its saves. Whether the log written during the run is stored as well is decided by "Store
Execution Log"; the triggering definition (scheduled action, rule, mailbox listener) wins over the
action, the action over the installation default ExecutionHistory:LogCaptureMode.
The result in the history follows the protocol: a run with an error message anywhere in its protocol counts as failed, a run with warnings – for example from commands skipped because of incomplete settings, or from Write Log – as succeeded with warnings.
Switch "Trace Executions" on for an action that fails now and then and nobody can tell why – not for every action: every run becomes an entry. See Monitoring.
The developer console (Admin Studio → Monitoring → Developer Console) shows the actions of another browser session live, also without tracing.
10. Permissions¶
| Permission | Allows |
|---|---|
| "Open Action Manager" | Opening the management view of the actions (and the collection in the Admin Studio) |
| "Add Action" | Creating and cloning actions |
| "Edit Action" | Changing actions. Without it, the editor is read-only. |
| "Delete Action" | Deleting actions |
All four are part of "System Developer". Running an action needs no permission of its own: whoever can click the button can run the action. What the action may do with records is limited by the entity policies of the user it runs for:
| Entity policy | Applies to actions |
|---|---|
| Read limits | Yes – records the user may not read are not found, for example by Go To Record or a query |
| Add limits | Yes – checked when Create Entity Record or Create Related Record creates the record |
| Delete limits | Yes – checked by Delete Entity Record |
| Edit limits | Yes – checked when a command first changes a stored record, for example Update Entity Record. A refused change ends the command with an error. |
The commands that manage user accounts (Create Or Update User, Delete User) are an exception: they check the user permissions "Add User", "Edit User", "Delete User" and "Reset User Password" of the user the action runs for, the same way the user editor does.
Users with "System Developer" are not restricted by add, edit and delete limits. The limits decide about whole records; if a single field must not be changed by a certain group of users, use a field limit, or do not offer them an action that changes it – for example with the execution condition of the action. See Roles and permissions.
11. All commands¶
| Command (menu) | Page | What it does | Needs a user interface |
|---|---|---|---|
| Flow | |||
| Change Context | change-context | Makes an earlier record the current record again | No |
| Execute Action | execute-action | Runs another action and waits for it | No |
| ForEach Related Record | for-each-related-record | Runs commands for every related record | No |
| Iterate JSON | iterate-json | Runs commands for every element of a JSON array | No |
| Iterate XML | iterate-xml | Runs commands for every element of an XML document | No |
| Jump | go-to | Continues at another command, depending on a condition | No |
| Switch | switch | Runs the first case whose condition is true | No |
| Wait | wait | Pauses for some seconds | No |
| Data | |||
| Create Entity Record | create-entity-record | Creates a record and makes it current | Only for "Show Form" |
| Create Related Record | create-related-entity-record | Creates a related record; the current record stays | Only for "Show Form" |
| Create Or Update User | create-or-update-user | Creates a user account or changes one | No |
| Delete Entity Record | delete-entity-record | Deletes the current or a related record | Only for "Confirm in UI" |
| Delete User | delete-user | Deletes a user account | Only for "Confirm in UI" |
| Discard | discard-entity-set-changes | Throws away unsaved changes | No |
| Export Query | export-query | Writes the result of a query as a file into a variable | No |
| Go To Record | go-to-record | Makes a record current and opens its form | Only for the form |
| Invalidate Relationships | invalidate-relationships | Reads related records again | No |
| Link/Unlink Entity Records | link-or-unlink-entity-records | Links or unlinks existing records | Only for "Prompt UI" |
| Refresh | refresh-entity-set | Reads the current record again | No |
| Reset Global User Value | reset-global-user-value | Removes a user's own value of a global value | No |
| Save | save | Saves the current record | No |
| Update Entity Record | update-entity-record | Sets fields of the current record | No |
| Update Global Value | update-global-value | Sets global values | No |
| Update Related Record | update-related-entity-record | Sets fields of one related record | No |
| Update Variable | update-variable | Sets variables | No |
| Write Log | write-log | Writes a line into the log | No |
| Write To File | write-to-file | Writes text into a file | No |
| Communication | |||
| AWS Signed Request | aws-signed-request | Calls an AWS service with a signed request | No |
| HTTP Request | http-request | Calls a web service | No |
| OAuth2 Get Token | oauth2-get-token | Gets an access token for the application | No |
| Run Process | run-process | Starts a program on the server | No |
| Send E-Mail | send-email | Sends a mail | No |
| UI | |||
| Copy to Clipboard | copy-to-clipboard | Puts text into the clipboard of the user | Yes |
| Dispatch UI | dispatch-ui-command | Sends a command to the user interface | Yes |
| Execute JavaScript | execute-js | Runs a script in the browser | Yes |
| Navigate | navigate-to | Opens a dashboard or the results of a query | Yes |
| Navigate to URL | navigate-to-url | Opens an address | Yes |
| OAuth2 User Authorization | oauth2-user-authorization | Gets a token in the name of the signed-in user | Yes |
| Open E-Mail Form | open-email-form | Opens a prefilled mail form | See its page |
| Open Form Dialog | open-form-dialog | Opens a form in a dialog | Yes |
| Show Popup | show-a-popup | Shows a message, optionally with buttons | Yes |
| AI | |||
| AI Assist | ai-assistant | Lets an AI assistant work on a task | See its page |
| AI Predict Value | ai-predict-value | Lets an AI choose a value and store it in variables (an update command writes it into a field) | See its page |
| LDAP | |||
| LDAP Add Group, LDAP Add User To Group, LDAP Add User With Password, LDAP Clear Attribute, LDAP Does Object Exist, LDAP Find Objects, LDAP Get Attribute, LDAP Move User, LDAP Remove Object, LDAP Remove User From Group, LDAP Reset User Password, LDAP Set Attribute | ldap-actions | Read and change a directory | No |
| Files | |||
| Add File | add-file | Stores a file | No |
| Download File | download-file | Hands a file to the user's browser | Yes |
| Get File Data | get-file-data | Reads the content of a stored file | No |
| Get Files | get-files | Lists stored files | No |
| Iterate File Lines | iterate-file-lines | Runs commands for every line or row of a file | No |
| Iterate Files | iterate-files | Runs commands for every file in a folder of the server | No |
| Remove File | remove-file | Removes a stored file | No |
| Not offered in the editor | |||
| Run Background Task | run-background-task | Not carried out – see its page | – |
12. Limitations¶
- There is no transaction across the commands of an action and no rollback (section 7).
- Apart from execution conditions and failed saves, a failing action shows no message to the user.
- The editor does not check whether an action uses commands that need a user interface. An action with such commands still saves and can be attached to a schedule; the commands are then skipped.
- Variables have no type and no default value (see Action variables).
- In the editor, the lanes "Pre" and "Post" always start without an entity, even for an action with an entity. Fields of the record can therefore not be picked there, although a run on a single record has one.
13. Frequently asked questions¶
Does an action run with administrator rights? No. It runs with the rights of the user it runs for: the signed-in user, the identity of the scheduled action, rule or mailbox listener, or the user of the API access.
Can an action that opens a form run from a schedule? Yes, but every command that needs a user interface is skipped. Opening the form does not happen; Go To Record still makes the record current.
An action changed a record, but the changes are gone. Why? The record was not saved. Commands keep their changes in memory until a save. In a background run, unsaved changes are lost when the action ends.
The action fails, but users see nothing. Where is the reason? In the application log and the protocol of the run. Switch on "Trace Executions" and look at the run under Admin Studio → Monitoring → Background Processes.
Can I undo what an action did when a later command fails? No. There is no rollback. Check conditions early, and save as late as possible.
Why is my action not started from a business rule that its own save triggers? Probably the loop protection: the same action may run nested within itself only up to "Max Recursion Depth" times (default 5).