# UI Augmentation

Virtuoso allows users to have some control over specific parts of the application interface through the usage of Dynamic Forms.

They are particularly suited to Virtuoso Integrations, allowing their creators to define custom forms with which the other users will interact, either to configure an integration after installing it or to provide extra data after triggering an integration action (see Creating an integration).

# Example

Let's assume we have built an integration for GitHub.

We may want to allow users to create GitHub issues directly from a journey's context menu by defining a title and a description. Additionally, we want those to come pre-filled with information from the journey (see the contextual information section).

With the integrations' interactive menus feature we can place an action at the journey context menu. By associating a dynamic form to that action, we can have the required fields displayed to the user:

Text field


This page will describe how forms can be easily built and is divided in two sections:

# Dynamic Form structure

Dynamic Forms are mainly a way to structure different types of input fields. In this section, we present the formal language that you should use in order define the schema of the form to be rendered by Virtuoso.

A form contains fields or sections; a section is a way to organize group of fields; and a field is a graphical control element intended to enable the user to input some kind of data.

The form shown in the example above can be described by the following code:

{
  "fields": [
    {
      "name": "title",
      "type": "TEXT",
      "label": "Title",
      "defaultValue": "Issue for journey \"{{JOURNEY.name}}\""
    },
    {
      "name": "description",
      "rows": 10,
      "type": "TEXT_AREA",
      "label": "Description",
      "defaultValue": "Project: {{PROJECT.name}}\nGoal: {{GOAL.name}}\nJourney: {{JOURNEY.name}}\n\nIssue description:\n\n"
    },
    {
      "hint": "Check if the issue should be marked as a bug. Leave unchecked otherwise",
      "name": "isBug",
      "type": "SWITCH",
      "label": "Bug"
    }
  ]
}

This manual will now go over the different levels of this code and explain the reason for each one and how it can be configured.

# Form root

At the top level, a form is a very simple object that ties the rest of the elements together.

It has only two optional properties:

  • fields (optional): an array of field objects
  • sections (optional): an array of section objects

Fields added to the fields array will be rendered at the root of the form, with no section label or hint.

Root fields AND sections

Adding elements to both arrays is valid, however sections will take precedence and will cause the elements in the fields array to not render.

Basic form structure example
{
  "fields": [(...)],
  "sections": [(...)]
}

# Form sections

Any combination of fields may be added directly to the form root or further organized into sections, if they make sense as a group and/or require extra information for the user who will interact with them.

Form sections

Sections are configured using the following set of properties:

  • label: the label of the section, presented at the top of the section
  • hint (optional): text meant to help / inform the users about the section's fields and required information, presented next to the label
  • fields (optional): an array of field objects
Basic form section structure example
{
  "label": "User information",
  "hint": "Your personal information. This data will be kept private.",
  "fields": [(...)]
}

# Form fields

Fields are the main visual and functional components of a form. Each field type is better suited to a type of information.

The main field properties, common and required for all types of field are:

  • type: the type of the field (takes a different value for each field type);
  • name: the name of the property that contains the field value when the form is submitted;
  • label: the label of the field, presented above/next to the field itself;

However, the visual aspect and user experience are different for each field, requiring set of properties to fine-tune them. Currently, dynamic forms support the following types of fields (check each of them to learn their specifications):

# Text

Text fields allow users to input single words or short sentences.

Text field

Properties and example

Text fields are configured using the following set of properties:

  • type: the type of the field (TEXT);
  • name: the name of the property that contains the field value when the form is submitted;
  • label: the label of the field, presented above the field itself;
  • hint (optional): text meant to help / inform the users filling the field, presented next to the label:
  • placeholder (optional): text meant to help / inform the users filling the field, presented on the field itself until the user starts typing;
  • defaultValue (optional): prefilled value of the field which can be altered by the user unless field is marked as disabled;
  • disabled (optional): if true, the value of the field cannot be changed (default is false);
  • hidden (optional): if true, the field is included in the form but not shown to the user (default is false);
  • required (optional): if true, the field must be filled before the form can be submitted (default is false);
  • maxLength (optional): maximum number of allowed characters when filling the field (0 or undefined for no limit);

A json example of this field is shown below:

{
  "type": "TEXT",
  "name": "searchParameters",
  "label": "Search parameters"
  "hint": "Text that will be used to search for results",
  "placeholder": "Please insert your search parameters here",
  "defaultValue": "",
  "disabled": false,
  "hidden": false,
  "required": true,
  "maxLength": 0        
}

# Text Area

Text area fields are similar to simple text field but are better suited to larger texts.

Text area field

Properties and example

Text area fields are configured using the following set of properties:

  • type: the type of the field (TEXT_AREA);
  • name: the name of the property that contains the field value when the form is submitted;
  • label: the label of the field, presented above the field itself;
  • hint (optional): text meant to help / inform the users filling the field, presented next to the label;
  • placeholder (optional): text meant to help / inform the users filling the field, presented on the field itself until the user starts typing;
  • defaultValue (optional): prefilled value of the field which can be altered by the user unless field is marked as disabled;
  • disabled (optional): if true, the value of the field cannot be changed (default is false);
  • hidden (optional): if true, the field is included in the form but not shown to the user (default is false);
  • required (optional): if true, the field must be filled before the form can be submitted (default is false);
  • maxLength (optional): maximum number of allowed characters when filling the field (0 or undefined for no limit);
  • rows (optional): number of rows (field height) the field will be rendered with. Texts that span over more than this value will be scrollable inside the text area (must be between 1 and 10);

A json example of this field is shown below:

{
  "type": "TEXT_AREA",
  "name": "userComments",
  "label": "Comments",
  "hint": "Your comments are anonymous and can't be traced back to your account",
  "placeholder": "Let us know your opinion",
  "defaultValue": "",
  "disabled": false,
  "hidden": false,
  "required": true,
  "maxLength": 0,
  "rows": 5
}

# URL

URL fields are a variation of the simple text field, better suited to URL values. They offer a separate control to configure the protocol.

URL field

Properties and example

URL fields are configured using the following set of properties:

  • type: the type of the field (URL);
  • name: the name of the property that contains the field value when the form is submitted;
  • label: the label of the field, presented above the field itself;
  • hint (optional): text meant to help / inform the users filling the field, presented next to the label;
  • placeholder (optional): text meant to help / inform the users filling the field, presented on the field itself until the user starts typing;
  • defaultValue (optional): prefilled value of the field which can be altered by the user unless field is marked as disabled;
  • disabled (optional): if true, the value of the field cannot be changed (default is false);
  • hidden (optional): if true, the field is included in the form but not shown to the user (default is false);
  • required (optional): if true, the field must be filled before the form can be submitted (default is false);

A json example of this field is shown below:

{
  "type": "URL",
  "name": "targetPage",
  "label": "Target page",
  "hint": "Address of the webpage to target when searching for results",
  "placeholder": "Target page address",
  "defaultValue": "",
  "disabled": false,
  "hidden": false,
  "required": true
}

Switch

Switch fields are well suited to situations where the user should inform one of two possible values, e.g. yes/no, on/off, enabled/disabled, etc. The submitted value for these fields is either true or false.

Switch field

Switch fields are configured using the following set of properties:

  • type: the type of the field (SWITCH);
  • name: the name of the property that contains the field value when the form is submitted;
  • label: the label of the field, presented next to the field itself;
  • hint (optional): text meant to help / inform the users filling the field, presented next to the label;
  • defaultValue (optional): initial value of the field which can be altered by the user unless field is marked as disabled;
  • disabled (optional): if true, the value of the field cannot be changed (default is false);
  • hidden (optional): if true, the field is included in the form but not shown to the user (default is false);
  • required (optional): if true, the field must be set to true before the form can be submitted (default is false);

A json example of this field is shown below:

{
  "type": "SWITCH",
  "name": "sendNotifications",
  "label": "Send notifications",
  "hint": "Set to true if notifications should be sent to your email",
  "defaultValue": true,
  "disabled": false,
  "hidden": false,
  "required": false
}

Dropdown

Dropdown fields allow users to select a value from a list of multiple options. The submitted value will be the value property associated with the selected dropdown option.

Dropdown field

They are configured using the following set of properties:

  • type: the type of the field (DROPDOWN);
  • name: the name of the property that contains the field value when the form is submitted;
  • label: the label of the field, presented above the field itself;
  • hint (optional): text meant to help / inform the users filling the field, presented next to the label;
  • placeholder (optional): text meant to help / inform the users filling the field, presented on the field itself until an option is selected;
  • defaultValue (optional): initial value of the field which can be altered by the user unless field is marked as disabled. Should match the value property of one of the dropdown options;
  • disabled (optional): if true, the value of the field cannot be changed (default is false);
  • hidden (optional): if true, the field is included in the form but not shown to the user (default is false);
  • required (optional): if true, the field must have an option selected before the form can be submitted (default is false);
  • options (optional): an array of dropdown option objects that will be presented to the user;

A dropdown option is an object with the following set of properties:

  • value: the value submitted for the dropdown field if the option is selected (may be a string, boolean or numeric value);
  • label: the label that represents the option in the interface;

A json example of this field is shown below:

{
  "type": "DROPDOWN",
  "name": "deviceType",
  "label": "Device",
  "hint": "Select your preferred type of device",
  "placeholder": "Select type of device",
  "defaultValue": 1,
  "disabled": false,
  "hidden": false,
  "required": true,
  "options": [
    {
      "label": "Computer",
      "value": 1
    },
    {
      "label": "Phone",
      "value": 2
    },
    {
      "label": "Tablet",
      "value": 3
    }
  ]
}

# Dynamic Form editor

In different parts of the application you may be required or offered the option to create and edit a Dynamic Form. In those situations you'll be presented with an editor:

Form editor

This editor has some features specially tailored to Dynamic Forms: context placeholders, hints and errors, and actions,

# Context Placeholders

Forms may be rendered in a context, i.e. they may have an associated project, goal, or any other kind of entity used in the application. For interactive menu actions, for example, the form context relates to the menu where the action is included, as shown in the example above.

A user building forms for these situations may want to use values that will be available at the time the form is rendered but not when it is being built. Placeholders solve that limitation.

A placeholder is a sequence of characters that are included in the form description and then automatically replaced by the corresponding contextual value when the form is rendered. They have many useful applications, like showing a project name in a field label, goal id in a field's default value or the current date in a dropdown field options list.

Placeholder format

All placeholders consist of a string with the following format:

{{KEY_EXPRESSION.detailExpression}}

in which KEY_EXPRESSION is an uppercase, underscore _ separated expression and detailExpression is an optional camel case expression. If detailExpression is included, a dot . must separate both parts.

Available placeholders

The placeholders available to each form depend on the context it will be rendered in. This context may be either fixed (and pointed out to the form creator) or configurable at the time of form creation.

Configurable context dynamic forms include:

  • Interactive menu actions (context is controlled by the Virtuoso menu associated with the action)

The following are the available placeholder KEY_EXPRESSION.detailExpression combinations for each context (some placeholders are available in more than one context):

Common placeholders (available independently of form context)
Key Detail Description Replacement example
NOW The instant the form is displayed to the user, presented as in ISO 8601 format 2020-06-26T13:10:05.664Z
Project placeholders
Key Detail Description Replacement example
NOW The instant the form is displayed to the user, presented as in ISO 8601 format 2020-06-26T13:10:05.664Z
PROJECT id The identifier of the project 1234
PROJECT name The name of the project Shopping Cart page test
Goal placeholders
Key Detail Description Replacement example
NOW The instant the form is displayed to the user, presented as in ISO 8601 format 2020-06-26T13:10:05.664Z
PROJECT id The identifier of the project associated with the goal 1234
PROJECT name The name of the project associated with the goal Shopping Cart page test
GOAL id The identifier of the goal 1234
GOAL name The name of the goal Desktop test
GOAL url The URL associated with the goal https://my.web.application.com
GOAL snapshotId The identifier of the goal's snapshot 1234
Journey placeholders
Key Detail Description Replacement example
NOW The instant the form is displayed to the user, presented as in ISO 8601 format 2020-06-26T13:10:05.664Z
PROJECT id The identifier of the project associated with the journey 1234
PROJECT name The name of the project associated with the journey Shopping Cart page test
GOAL id The identifier of the goal associated with the journey 1234
GOAL name The name of the goal associated with the journey Desktop test
GOAL url The URL of the goal associated with the journey https://my.web.application.com
GOAL snapshotId The identifier of the goal's snapshot, associated with the journey 1234
JOURNEY id The identifier of the journey 1234
JOURNEY name The name of the journey Test Shopping Cart item features
JOURNEY canonicalId The UUIDv4 identifier of the journey 11bf5b37-e0b8-42e0-8dcf-dc8c4aefc000
JOURNEY snapshotId The identifier of the journey's snapshot 1234
Checkpoint placeholders
Key Detail Description Replacement example
NOW The instant the form is displayed to the user, presented as in ISO 8601 format 2020-06-26T13:10:05.664Z
PROJECT id The identifier of the project associated with the checkpoint 1234
PROJECT name The name of the project associated with the checkpoint Shopping Cart page test
GOAL id The identifier of the goal associated with the checkpoint 1234
GOAL name The name of the goal associated with the checkpoint Desktop test
GOAL url The URL of the goal associated with the checkpoint https://my.web.application.com
GOAL snapshotId The identifier of the goal's snapshot, associated with the checkpoint 1234
JOURNEY id The identifier of the journey associated with the checkpoint 1234
JOURNEY name The name of the journey associated with the checkpoint Test Shopping Cart item features
JOURNEY canonicalId The UUIDv4 identifier of the journey associated with the checkpoint 11bf5b37-e0b8-42e0-8dcf-dc8c4aefc000
JOURNEY snapshotId The identifier of the journey's snapshot, associated with the checkpoint 1234
CHECKPOINT id The identifier of the checkpoint 1234
CHECKPOINT name The title of the checkpoint preceded by its number Checkpoint 23 - Shopping Cart item is removed
CHECKPOINT title The title of the checkpoint Shopping Cart item is removed
CHECKPOINT canonicalId The UUIDv4 identifier of the checkpoint 11bf5b37-e0b8-42e0-8dcf-dc8c4aefc000
Extension placeholders
Key Detail Description Replacement example
NOW The instant the form is displayed to the user, presented as in ISO 8601 format 2020-06-26T13:10:05.664Z
PROJECT id The identifier of the project associated with the extension 1234
PROJECT name The name of the project associated with the extension Shopping Cart page test
EXTENSION id The identifier of the extension 1234
EXTENSION name The name of the extension requestShoppingCartItems

Organization extensions

Extensions can be created at project or organization level. Project level extensions will have an associated project but organization level ones will not. This means that if the form is rendered in an organization level context, the project related placeholders will not be replaced. Keep this in mind when creating your dynamic forms.

Test Data Table placeholders
Key Detail Description Replacement example
NOW The instant the form is displayed to the user, presented as in ISO 8601 format 2020-06-26T13:10:05.664Z
PROJECT id The identifier of the project associated with the extension 1234
PROJECT name The name of the project associated with the extension Shopping Cart page test
TEST_DATA_TABLE id The identifier of the test data table 1234
TEST_DATA_TABLE name The name of the test data table Items test data
TEST_DATA_TABLE description The description of the test data table This table contains data for multiple shopping cart items

While editing a form description, if the user starts typing { on a string property value, the editor will present a list of all available placeholders in that context. To accept just press Enter or Tab. Placeholder usage example

In a goal context, this field would render similar to: Placeholder render

# Editor Hints and Errors

The editor will guide you through creating a form description. It can do this in two ways: hints and errors.

Hints will be provided when you hover a part of the code with the mouse cursor, and disappear when you move it away. They can include the name of the part you're editing (whether it is the form root, a section or a particular type of field), extended descriptions on any of these parts, and tips about required properties or their accepted values. Form hint - information Form hint - warning

Errors will be shown below the editor area and will point only the faults int the form structure, missing required properties or invalid property values. Form error

Forms with errors

While the editor identifies errors in the form description, its value cannot be saved and the editor actions cannot be used.

# Editor Actions

At the top of the editor there are three action buttons:

# Re-indent form description

Clicking this button will re-indent the code, with individual properties being separated into different lines. Bear in mind that code style does not affect the rendered form; only the form description content does.

# Copy form description to clipboard

Clicking this button will copy to clipboard the current code on the editor.

# Reset form description to its default state

Clicking this button will revert the form to its most simple and valid state, i.e. an empty fields array. This is equivalent to not defining any form since nothing will be rendered.

Last Updated: 7/2/2020, 1:32:40 PM