Components are written in XML and you can implement desired behavior by writing down its rules, which are if A then B statements.

For example, The requirement is that while inspecting a machine if the user presses the button "Camera", then the device's internal camera starts.

The same rule could be expressed a bit closer to the implementation as:

If we are in the step "inspect_machine" and an event occurs with the command "Camera" then execute action "start_camera".

Structural Frame of a Component

The typical structural frame of a component is as follows:

<workflow [ATTRIBUTES]>
    <context> [...] </context> // Data variables, optional
    <rules> [...] </rules> // If [Expression] then [actions]; optional
    <actions> [...] </actions> // optional
    <steps> 
        <step [ATTRIBUTES]>
            <states>
                <onresume> [...] </onresume> // optional
                <onevent> [...] </onevent> // optional
                [...]
            </states>
            <mapping> [...] </mapping>
        </step>
        [...] 
    </steps>
</workflow>

Before going forward with an example, below is an overview of the XML tags:

  • <context>: Defines variables (data) to work with
  • <rules>: Defines under which condition a set of actions is executed. Consists of an expression and one more action
  • <actions>: Pre-defined actions we want to use in the workflow (e.g., start the device camera).
  • <step>: Screen on the device that contains the data (context) and logic (rules and actions) of the screen and is linked to a user interface template
  • <states>: Determines when a rule will be checked (e.g., When an event occurs, upon entering or leaving a step)
  • <mapping>: Maps the data (context variables) to the user interface (which is defined in a different file)

Example of a Component

To better understand the structure of components, we will use an example of an Image Choice component.

The user selects between the two options "Apple" and "Pear". The same component will be used for this training and will be improved as we go forward.

Download Component

The UI below displays how this component would appear while executing on the Frontline Workplace smart glass application.

The workflow is:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<workflow xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" wfd_version="1.0" reporting="false"
          id="choice" name="choice" descriptor="Choice component" startstep="choose"
          xsi:noNamespaceSchemaLocation="../../../configuration/workflow.xsd">

    <steps>
        <step id="choose" descriptor="the user selects between two options" uitemplate="ChoiceScreen">
            <states>
                <onevent>
                    <rule id="menu_button_selection">
                        <expression>#{event:command} == 'APPLE' || #{event:command} == 'PEAR'</expression>
                        <actions>
                            <finish_workflow id="finish_workflow">
                                <output>
                                    <param name="selected_button" type="string">#{event:command}</param>
                                </output>
                            </finish_workflow>
                        </actions>
                    </rule>
                </onevent>
            </states>
        </step>
    </steps>
</workflow>

Explanation of the workflow

1. The workflow tag contains an attribute startstep="choose". This is used to select which step will be performed first after initializing the component.

2. <step id="choose"... is used to refer to a choice that will be further displayed using uitemplate="ChoiceScreen". ChoiceScreen is a file that defines what is displayed on the screen while we are in this step.

As explained, the behavior of a component is defined using rules. A rule consists of an expression (or condition) and which action to take when that condition is True. Each rule is assigned to one of the states <onenter>,  <onresume><onleave> , <onevent> or  <onpause> . Rules will only be checked when the component is in that state (e.g., onenter - when the component is first started).

3.  The <rule id="menu_button_selection"> is assigned to the <onevent> state. Whenever an event occurs, all rules given to this state will be checked. Here, <expression>#{event:command} == 'APPLE' || #{event:command} == 'PEAR'</expression> checks whether the event contains a specific command. Such an event would be activated when a button with the name "APPLE" or "PEAR" is triggered either by voice command or pressing it on the screen.

4. If a rule expression evaluates to true, the set of actions in the rule's <actions> tag is executed. In this example, the finish_workflow action is used. This immediately leaves the component once the user has chosen one of the two options, and passes on which choice was made in a <output> parameter so that we can create different transitions in the workflow diagram based on that choice.

📌Assignment

Suppose you want to extend our choice component to send a message containing the user's choice back to the Frontline Connector (which could in turn communicate this information to a backend system). Think about the following questions:

  • Which step/s would your component have?
  • Take a look at the ': Which actions would you probably need?

Help and Resources

Actions are the basic building blocks we can use. They range from changing what the user sees (colors, text, notifications,...) to controlling the flow of the program (transition to the next step) by managing data and communicating with the Frontline Connector or external devices.

Solution Notes

First of all, you might argue that communicating with the Frontline Connector is a separate functionality and should have its own component. You would be absolutely right: separating the communication aspect into its own components would make both components more reusable. On the other hand, sometimes you want to simplify the process flow shown in the Frontline Creator Interface for your customer by keeping multiple functionalities together in a single component. For now, let's assume we combine both functionalities in one component.

Which steps could your Component have?

Previously, you were told that steps are equivalent to screens. So why would you have more than one step if the additional functionality is just backend communication?

The answer is maintainability and reusability. Maintainability, because when making changes to the communication aspect, you will only have to look at that step and not read any of the other code. Reusability, because you could also send different messages using the same step if the component becomes even more complex.

In the same way, it would be a good idea to make two separate components of these two functionalities. It is a good idea to at least create separate steps if you combine them into one component. Just make the screen look the same or add a progress notification acknowledgment from the Connector. As such we suggest having 2 steps here, e.g., "choice" and "message_connector".

Which actions would you probably need?

The main purpose of this question is to make you familiar with the 'Actions' catalog. Here are examples of actions you might use in the implementation process:

  • send_commit_message: Communicates with the Frontline Connector
  • ui_progress_notification: Informs the user that we are currently communicating with the backend (in case we wait for acknowledgment)
  • setvar: Used to save an input that can later be returned to both the connector and an output parameter of our component

With this, you have now finished the first lesson. The next lesson will be about scopes and encompass your first practical assignment.