Commands
Create snippets of code that work across the Jetveo application. Allows for direct data manipulation inside application database.
Testing is also available. See Test
in the upper right of the App Builder screen. See below for more information.
Creating a new a command
General
- Name - name of a command, shown in a list of commands
- Code identifier - code identifier of the command used internally and when logging application errors
- Type - type of a Business command
- Custom command - has it's own input model and it's own page that allows app user to fill it's model values
- Entity command - a command executed on a specific entity record
- Entity batch command - a command executed on a collection of entity records
- Child entity command - a command that needs both entity and it's parent references
- Child entity batch command - a command executed on a collection of entities that has a reference to parent entity
- Result type - result of the command. Allows for creating Data grids or Documents from command results.
UI
- Default title for action button - default label used on a new Action button and on a Custom command page
- Default icon for action button - default icon used in a label of a new Action button and on a Custom command page
Security
- Execution condition - security condition that needs to return true for the command to be executed
Custom Command Input Model
Lets you set up a custom input Model for the command.
First, go to the "Model" tab and define Model's Attributes and References. You can use Inherited aspects. Attribute and reference values can be sent to a command through Parameters (that you set up when creating an Action button), or from command Page accessible to application user.
To set up such page, go to the "View" tab. As with any other view, select a layout and populate it with Data fields and/or Elements.
Using a command
Business commands can be attached to different places or events depending on their type:
Entity commands:
- Entity pages (page Actions)
- Entity page tab (page Actions)
- List page (as a command or batch command)
- Data grid (as a command or batch command)
- Entity events (on created, on deleted, on attribute updated)
Child entity commands:
- Data grid (command, batch command)
- Child Entity events (on child created, on child deleted, on child modified)
Custom commands:
- Entity pages (page Actions)
- Entity page tab (page Actions)
- List page (page Actions)
- Application menu item (they have their own page)
- API endpoint to allow 3rd party integration
- Scheduled events
Command results
Command results let you show or save result of a command.
Data grid result
Custom command with a Data grid report result must return a new Data grid. It shows on a page that opens after the command execution and lets app users to save the result as .XLS file.
In the following example we create a Data grid that lists application users and their emails:
return new ReportResult(new ReportResult.Column[ ] { new ReportResult.Column("Name"), new ReportResult.Column("Email") },
App.Security.Users.Select(u => new ReportResult.Row(u.Name, u.Email)));
Document result
Custom command with Document result must return a new object of type DocumentResult.
In the following example, we use Razor + HTML template to render a new html page and then create a byte stream out of it to allow app users to save it:
var htmlTable = App.Templates.HtmlReport.Render(templateModel);
var tableBytes = Encoding.UTF8.GetBytes(htmlTable);
return new DocumentResult("report.html", tableBytes);
Queued vs Asynchronous commands
Queued commands
The default mode of command execution is queued. This means when the command is invoked, it is placed into the command queue, and executes only after all preceding commands in the queue. This is usually not a problem, as the command queue is usually empty.
Asynchronous commands
Asynchronous commands start executing immediately upon invocation. You can think of it as a second thread, separate from the main command queue. This can be particularly useful if you expect the command execution to last for a long duration, and when the following commands do not depend on the changes made by the current one.
There is no way to lock shared data in an asynchronous commands, so be aware that race conditions can occur.
Invoking Commands in code
Each command has an object accessible in the code: App.Commands.ExampleCommand
. You can invoke a command by calling the InvokeAsync(ExampleCommandModel model)
method on this object, while passing in the command model.
This method immediately invokes the command, and proceeds to the next line. Notably this means the code does not wait for the command to finish executing, and cannot use the command's result. When dealing with synchronous commands, the invoked command begins executing only after the invoker command has finished.
Special case: Deadlock
When an app uses its own command API within a command, the command API must be asynchronous. Otherwise this will result in a deadlock.
Test Command Interface
Commands can be tested directly inside the interface. This allows a code-run loop, with defined input values, where the user can edit on-the-fly for immediate results.
For example, the screenshot below shows code for a test email (left), the Configuration for a test to send the email (upper right), and the results (lower right).
The code needs to include the proper coding to define the logs that are to be generated. The instance and Model needs to be configured. Click “Run” to get the results.