# Overview of ELO Flows components

Below, all graphical components are addressed in examples with their corresponding annotations.

Überblick Komponentenaufbau

# ELO Flows component

Each flow is based on components. Components can contain multiple elements. For example, a component provides one or more triggers. These triggers then initiate additional actions in the flow. These actions are realized via services. Services are also provided by components.

Komponenten in der Flows Administration

Definition of the component class (here: CounterComponent):

@Component(version = "0.0.1", namespace = "academy.training", name = "Counter", displayName = "Document counter", description = "Unique allocation of identification numbers")
public class CounterComponent {
}

# Triggers

Triggers are used to call a flow.

If a component in a flow is used as the first component, it automatically provides triggers in the ELO Flows administration area.

Beispiel eines Triggers

Please note

Triggers are always defined in the component class.

@Component(version = "0.0.1", namespace = "academy.training", name = "Counter", displayName = "Document counter", description = "Unique allocation of identification numbers")
public class CounterComponent {
  @Trigger(displayName="Call document counter")
  @WebHook(endpoint="createCounter")
  public CounterTriggerData triggerCounter(@Config CounterTriggerData triggerData) {
    //Implementation
  }
  @Trigger()
  @Scheduled()
  public TriggerData otherTrigger(@Config TriggerData triggerData) {
  //Implementation
  }
}

# Service

Services provide different functions in ELO Flows. If a component is not used as the first component in ELO Flows, then it provides different services for selection. If multiple services are available, they can also be grouped.

Dienst Zähler auswählen

Please note

Services are always defined in the component class.

@Component(version = "0.0.1", namespace = "academy.training", name = "Counter", displayName = "Document counter", description = "Unique allocation of identification numbers")
public class CounterComponent {
  @Service()
  public ServiceOutputData createCounter(SerivceInputData ) {
    //Implementation
  }
}

# Input fields

The input fields are used to capture user data. The fields can have different types and also offer suggestions for input. Data from previous components can also be used via keys via the input fields. The input fields are transferred to a service @Service or trigger@Trigger, where they are used for configuration tasks over the course of the flow.

The following types are possible:

  • String
  • Integer
  • Boolean
  • Object
  • Array

# String input field (text)

The input fields for values of different types also include the configuration tree and a JSONata editor.

Eingabefeld

To implement an input field, a class is declared that provides the fields via the annotation @Property. This class is transferred to a service/trigger method as a parameter. The variable type (String counterName under annotation @Property) determines the type of the field in the editor.

Eingabefeld Editor

CounterInput.java
public class CounterInput {
  @Property(displayName="Counter name" description="Enter postfix and prefix for new counter")
  private String counterName; // Type string in input field editor
  //Implement getter and setter methods
}
CounterComponent.java
@Component(version = "0.0.1", namespace = "academy.training", name = "Counter", displayName = "Document counter", description = "Unique allocation of identification numbers")
public class CounterComponent {
  @Service(name="CreateCounter")
  public CounterOutput createCounter(CounterInput input) {}
}

# Integer input field

To implement an integer type input field, proceed in the same way as for a string input field. The variable type, in our example postfix, is declared by the int type.

Eingabefeld Integer

Eingabefeld Editor Integer

CounterInput.java
public class CounterInput {
  @Property(displayName="Postfix")
  private int postfix; //Type Integer in the input field editor
  //Implement getter and setter methods
}
CounterComponent.java
@Component(version = "0.0.1", namespace = "academy.training",
name = "Counter", displayName = "Document counter",
description = "Unique allocation of identification numbers")
public class CounterComponent {
  @Service(name="CreateCounter")
  public CounterOutput createCounter(CounterInput input) {}
}

# Boolean input field

Eingabefeld Boolean

Eingabefeld Editor Boolean

CounterInput.java
public class CounterInput {
  @Property(displayName="Import counter")
  private boolean importCounter; //Type Boolean in the input field editor
  //Implement getter and setter methods
}
CounterComponent.java
@Component(version = "0.0.1", namespace = "academy.training",
name = "Counter", displayName = "Document counter",
description = "Unique allocation of identification numbers")
public class CounterComponent {
  @Service(name="CreateCounter")
  public CounterOutput createCounter(CounterInput input) {}
  }
}

# Object input field

If you need multiple input lines at once (including of different types), you can implement an Object type input field. This allows you to combine multiple fields into an object.

Eingabefeld Objekt

Eingabefeld Editor Objekt

The example shows implementation of the CounterObject class as an internal class.

public class CounterInput {
  @Property(displayName="Define counter", description="Define a counter. Name and initial value")
  private CounterObject counterObj;//Type CounterObject in the input field editor
  class CounterObject {
    @Property(displayName="Initial value", description="The initial value is optional. The default value is 1"
    @DisplayOptions(order = 2, suggestValue = true)
    private int value = 1;
    @Property(displayName="Counter name", description="Enter the counter name"
    @DisplayOptions(order = 1)
    private String counterName;
    //Implement getter and setter methods
  }
}
@Component(version = "0.0.1", namespace = "academy.training", name = "Counter", displayName = "Document counter", description = "Unique allocation of identification numbers")
public class CounterComponent {
  @Service(name="CreateCounter")
  public CounterOutput createCounter(CounterInput input) {}
}

# Array input field

If multiple fields of one type (string, Boolean, integer, or object) are required, they can be combined into an array. In the example below, multiple object input fields are grouped.

Eingabefeld Array

Eingabefeld Editor Array

public class CounterInput {
  @Property(displayName="Define counter", description="Define a counter with name and initial value")
  private CounterObject[] counterObjects;//Type CounterObject[] in the input field editor
  class CounterObject {
    //See object input field
  }
}

# Mandatory fields

All input fields can be marked as mandatory. The field name is then marked with an asterisk (*). This prevents the user from leaving the input screen if these entries are missing.

Eingabefeld als Pflichtfeld

Setting the attribute required to true in the Property annotation marks the field as mandatory.

@Property(displayName="Counter name" description="Enter postfix and prefix
for new counter", required=true)
private String counterName; // Type string in input field editor

# Order, default field values

The fields can also be configured via the @DisplayOptions annotation. You can configure value suggestions (suggestValue) or the order (order) of the fields here.

Eingabefeld Konfiguration

@Property(displayName="Postfix")
@DisplayOptions(order=2, suggestValue=true)
private int postfix = 6;
@Property(displayName="Prefix")
@DisplayOptions(order=1, size=2)
private String prefix = "Invoice";

# 'Suggestions' tab

In all input fields, suggestion lists can be filled via the annotations @Lookup and @LookupProvider. The function with the annotation @LookupProvider must be implemented in the main component class @Component.

Eingabefeld Vorschläge

public class CounterInput {
  @Property(displayName = "Counter name", required=true)
  @Lookup("getCounters")
  private String counterName;
}
@Component(version = "0.0.1", namespace = "academy.training", name = "Counter", displayName = "Document counter", description = "Unique allocation of identification numbers")
public class CounterComponent {
  @LookupProvider("getCounters")
  public Map<String,String> getCounters() throws CounterException {
  HashMap<String,String> map = new HashMap<>();
    //Implementation
    return map;
  }
}

# Field groups

The input fields can be combined into groups by topics. In the figure, the fields Prefix and Postfix are combined into the group New counter.

Eingabefelder Gruppe

Eingabefelder Gruppe Beispiel

To group input fields, the annotations @PropertyGroups and @PropertyGroup are added to the class declaration. The annotation @PropertyGroupRef is also added to the fields that are combined into a group with the corresponding group name.

@PropertyGroups(@PropertyGroup(displayName="New counter", name="counterGroup"))
public class CounterInput {
  @Property(displayName = "Counter name", required = true, description = "Select a counter name")
  @Lookup("getCounters")
  private String counterName;
  @Property(displayName = "Prefix", description = "Only in combination with counter name")
  @PropertyGroupRef("countergroup")
  @DisplayOptions(order = 1)
  private String prefix;
  @Property(displayName = "Postfix", description = "Only in combination with counter name")
  @PropertyGroupRef("countergroup")
  @DisplayOptions(order = 2, suggestValue = true)
  private int postfix = 6;
}

# Service groups

Different services, see also the ELO objects and metadata component, can be combined into groups.

Dienstgruppen

To group the services, the services are implemented in individual classes. The annotation @ComponentServices is added to these classes. For the groups to be shown, at least two groups have to be defined (i.e. two classes with @ComponentServices and contained @Services). The annotation @ComponentServices must always refer to the main component class (in our case CounterComponent) via the component attribute.

@Component(version = "0.0.1", namespace = "academy.training", name = "Counter", displayName = "Document counter", description = "Unique allocation of identification numbers")
public class CounterComponent {
}
@ComponentServices(component = CounterComponent.class, name = "CounterServices", displayName = "Manage counters")
public class CounterServices {
  @Service(name="CreateCounter")
  public CounterOutput createCounter(CounterInput input) {}
  @Service(name="ChooseCounter")
  public CounterOutput chooseCounter(CounterInput input) {}
}
@ComponentServices(component = CounterComponent.class, name = "CounterServices", displayName = "Import counters")
public class CounterServicesImportGroup {
  @Service(name="ImportCounter")
  public CounterImportOutput importCounter(CounterImportInput input) {}
  @Service(name="FindImportCounter")
  public CounterImportOutput findImportCounter(CounterImportInput input) {}
}

# Indexserver connection

The connection to the ELO Indexserver can be established automatically via the annotation @Connection and @ConnectionRequired. The connection to the ELOix is declared via the annotation @Connection in the IXConnection type variable and can be used in all methods via the annotation @ConnectionRequired.

public class CounterComponent {
  @Connection
  IXConnection ixConnect;
  @LookupProvider("getCounters")
  @ConnectionRequired
  public Map<String,String> getCounters() {
    HashMap<String,String> map = new HashMap<>();
    //Implementation
    return map;
  }
}

# Component information

The documentation can be integrated in different positions, such as the service or component description, via the annotation @Guide. First, you will have to file the relevant markdown file in the corresponding project structure, which is then referenced later in the solution implementation.

Please note

The markdown files are filed to the intended project structure (see figure). Otherwise, the documentation cannot be read or shown.

Dokumentation in der Projektstruktur

The following combinations with other annotations are possible:

  1. Information on a component (@Component and @Guide). Visible in both the service and the trigger selection view.

    Weitere Informationen Komponenten

    Informationen Komponente

    Weitere Informationen Komponente Trigger

    Informationen Komponente Trigger

  2. Information on a service (@Service and @Guide).

    Weitere Informationen Dienst

    Informationen Dienst

  3. Information on a trigger (@Trigger and @Guide)

    Weitere Informationen Trigger

    Informationen Trigger

Last updated: May 4, 2022 at 8:40 AM