05 May 2016

1. Components

This chapter describes the built in features of TVC Helium. Some of them may be configurable and some may not be enabled by default.

1.1. Helium

The main configuration of the application is performed in a file named Helium.xml which is located in WEB-INF/classes/.

This file is responsible for the following.

  • The name of the application

  • The login page of the application

  • What pages should be accessible and to which users

  • What the application topbar should contain

1.1.1. Configuration

The root element of the Helium.xml is <Application> and it supports the following child elements.

Name Description Example

Name

The name of the application. May be visible in the TopBar.

<Name>ACME</Name>

LoginPage

Describes the LoginPage

<LoginPage>
    <!-- LoginPage attribute, see login page chapter -->
</LoginPage>

Sidepanel

Describes the PageSidepanel

<Sidepanel>
    <!-- PageSidepanel attribute, see page sidepanel chapter -->
</Sidepanel>

DateFormat

How should dates be formatted on the client. All moment.js formats is supported but each format must contain month, day and year. If the element is omitted YYYY-MM-DD will be used.

<DateFormat>MMM DD, YYYY</DateFormat>

DateTimeFormat

How should dates with time (used in some places like the history widget) be formatted on the client. All moment.js formats is supported. If the element is omitted YYYY-MM-DD hh:mm:ss will be used.

<DateTimeFormat>MMMM Do YYYY, h:mm:ss a</DateTimeFormat>

StartPage

Specifies which page the user should be redirected to after a successful login (if no other page is requested).

<StartPage>
    <Page namespace="helium">
        Page.xml
    </Page>
</StartPage>

TopBar

Specifies what the TopBar should contain.

<TopBar>
    <!-- TopBar definition, see TopBar chapter -->
</TopBar>

PageMapping

Specifies the PageMapping. What pages are accessible given object type and what roles the user has.

<PageMapping>
   <!-- PageMapping definition, see PageMapping chapter -->
</PageMapping>
Login page

The <LoginPage> element is responsible for customization of the login page and it supports the following child elements.

Name Description Example

Path

The path to the login page.

<Path>
    helium/login.jsp
</Path>

Title

The title of the login page

<Title>
    Login to Helium
</Title>

FormTitle

Specifies what title the login form should have.

<FormTitle>
    Welcome to Helium
</FormTitle>

FormSubTitle

Specifies what sub title the login form should have.

<FormSubTitle>
    Please enter your credentials
</FormSubTitle>
LoginPage example
<LoginPage>
    <Path>/helium/login.jsp</Path>
    <Title>Login to Helium</Title>
    <FormTitle>Welcome to Helium</FormTitle>
    <FormSubTitle>Please enter your credentials</FormSubTitle>
</LoginPage>
TopBar

The TopBar is placed in a fixed, always-visible container in the top of the page, and it holds common actions and menus for the entire application.

image
Figure 1. Top Bar

The <TopBar> element supports the following child elements.

Name Description Example

ShowAppName

Whether the application name should be visible or not. Valid values: true or false (default).

If you would like to display image instead of name (e.g. company logo), see Using image as logo
<ShowAppName>false</ShowAppName>

TooltipSettings

Optional settings as given in Semantic Popup Settings can be passed for tooltip.

Tooltip will only be shown when commands are configured with <Alt>
<TooltipSettings>
  <![CDATA[{
    "variation": "inverted",
    "hoverable": "true",
    "position":"bottom center"
     }]]>
</TooltipSettings>

Left

Child elements to the <Left> element will be left aligned. See Menu/Commands section.

<Left>
    <!-- child elements -->
</Left>

Middle

Child elements that are aligned in the middle of the available remaining space between <Left> and <Right> sections. Currently this section can exclusively hold a <Search inline="true"> command, rendering an inline search field.

<Middle>
  <Search inline="true">tvc:search:hex:common/TopBarSearchV2.xml</Search>
</Middle>

Right

Child elements to the <Right> element will be right aligned. See the Menu/Commands section.

<Right>
    <!-- child elements -->
</Right>

ShowBreadcrumb

Whether the breadcrumb navigation should be visible or not. Valid values: true or false (default). See Breadcrumb section.

<ShowBreadcrumb>true</ShowBreadcrumb>

A breadcrumb trail on a page indicates the page’s position in the application hierarchy. A user can navigate all the way up in the application hierarchy, one level at a time, by starting from the last breadcrumb in the breadcrumb trail. It has maximum length of 5 elements.

For breadcrumb trail to work properly, pages need Title element.

It is a fixed container below topbar of the and is configurable with ShowBreadcrumb setting in TopBar.

image
Figure 2. Breadcrumb

It is responsive by design. Once breadcrumb container exceeds device display width, it will get collapsed and an ellipsis icon will be shown to left of breadcrumb. One can expand it again by clicking on ellipsis icon.

Mobile Breadcrumb

The <Left> and <Right> elements mentioned above can have the following child elements.

Depending on their parent element, they will either be left or right aligned in the TopBar

It is recommended to group commands in menus to avoid spill over of commands in topbar.
Name Description Example

Separator

Will render a horizontal separator

<Separator />

Menu

Will render a dropdown menu containing commands. The menu is defined in the xml referenced inside of the element.

<Menu>
    tvc:menu:helium/MyDashboards.xml
</Menu>

Command

Will render a command. The command is defined in the xml reference from inside of the element.

<Command>
    tvc:command:helium/ResetDashboards.xml
</Command>
Dynamic Menu

Normally, a menu holds a list of pre-configured commands and/ or menus. As opposed to this, a dynamically defined menu allows different content. A dynamic menu is still configured as a regular menu, but has some extra settings which when configured allows developer to get control when the menu is activated. This means, it’s also possible to have a dynamic menu that has a mix of predefined commands as well as dynamically added ones.

An example of such a menu is Recently Viewed objects.

Options
Name Description Required Example

dynamicmenu

Defines a menu as a dynamic menu

true

</Menu>
	<Setting name="dynamicmenu" value="true" />
</Menu>

href

Ajax endpoint to fetch JSON data for dynamic content

true

<Menu>
    <Setting name="href" value="tvc-action/heliumDataTable?config=tvc:tableconfig:helium/RecentlyViewed.xml&amp;reload=true&amp;bindKey=foo" />
</Menu>

id

Unique identifier for the dynamic menu. Can be used, for e.g. to get hold of the menu from JavaScript.

false

<Menu>
    <Setting name="id" value="recent-objects" />
</Menu>

template

Reference to Handlebars template to render content on client

false*

<Menu>
    <Setting name="template" value="helium/templates/recentobject/recentobjectcommand" />
</Menu>

onActivate

JavaScript callback to handle menu when activated. If defined, it’s this callbacks' responsibility to configure dynamic menu content.

onActivate and/ or template should be provided.

false*

<Menu>
    <Setting name="onActivate" value="App.RecentObjects.render" />
</Menu>

A JavaScript API, App.Topbar.dynamicMenus.getById(menuId) can be used to get access to the dynamic menu.

Dynamic menus are currently available only in Topbar.
Example
<Menu xmlns="http://technia.com/TVC/Menu" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://technia.com/TVC/Menu http://products.technia.com/tvc/schema/latest/Menu.xsd">
	<Label>recent.title</Label>
	<Setting name="dynamicmenu" value="true" />
	<Setting name="id" value="recent-objects" />
	<Setting name="template" value="helium/templates/recentobject/recentobjectcommand" />
	<Setting name="onClick" value="App.routing.open" />
	<Setting name="onActivate" value="App.RecentObjects.render" />
	<Setting name="href" value="tvc-action/heliumDataTable?config=tvc:tableconfig:helium:recentobject/RecentlyViewed.xml&amp;reload=true&amp;bindKey=foo" />
</Menu>
Recently Viewed objects

"Recently Viewed" objects is a built-in dynamic menu which when configured shows a list of objects that the user has recently visited. The built-in menu uses TableConfig for defining and retrieving its data and a handlebars template to display the data. Both of them can be overridden if needed, for e.g. to fetch and display information in a different way.

image
Figure 3. Recent Objects Menu

To enable it, add following in the Topbar definition in Helium.xml.

...
<TopBar>
    <Right>
        <Menu>tvc:menu:helium:recentobject/RecentlyViewed.xml</Menu>
    </Right>
</TopBar>
...
Looking to configure recent objects in a widget instead? See Recent Object Widget Configuration for more information.
Themes

"Themes" is a built-in dynamic menu which when configured gives user capability to switch between themes in real time. The built-in menu uses tvc.helium.themes property for retrieving the list of themes. Default value of this property is flat and light as tvc.helium.themes=flat|light.

image
Figure 4. Themes Menu

To enable it, add following in the Topbar definition in Helium.xml.

...
<TopBar>
    <Right>
        <Menu>tvc:menu:helium:theme/ChangeTheme.xml</Menu>
    </Right>
</TopBar>
...
TopBar example
<TopBar>
    <ShowAppName>true</ShowAppName>
    <Left>
        <Separator />
        <Menu>tvc:menu:helium/MyDashboards.xml</Menu>
        <Command>tvc:command:helium/ResetDashboards.xml</Command>
        <Command>tvc:command:helium/Create.xml</Command>
    </Left>
    <Right>
        <Myspace />
        <Search />
        <Logout />
    </Right>
</TopBar>
PageMapping

The <PageMapping> element controls which type of objects should be mapped to which pages. It is possible to control the page mapping based on object type, object state and which access role the user belongs to.

This is done by creating a tree of Page elements with different rules. Given the following example:

<PageMapping>
   <!-- Evaluate the 'PartPage' if the type of the current object is a part
       and the state of the object is 'Released' and the current user belongs
       to the 'SeniorDesignEngineer' or 'ManufacturingDesignEngineer' roles,
       otherwise try the next page. -->
    <Page namespace="helium" name="PartPage.xml">
        <Type is="type_Part" and="current == Released">
            <Access>
                <Role>role_SeniorDesignEngineer</Role>
                <Role>role_ManufacturingDesignEngineer</Role>
            </Access>
        </Type>
    </Page>

    <!-- If the above rule evaluates to false and the current object is of the 'Part'
         type, evaluate 'OtherPartPage.xml' -->
    <Page namespace="helium" name="OtherPartPage.xml">
        <Type is="type_Part" />
    </Page>

    <!-- If the type of the page is ECR, evaluate the 'ECR.xml' page -->
    <Page namespace="helium" name="ECR.xml">
        <Type is="type_ECR" />
    </Page>

    <!-- If none of the above are true, evaluate the DefaultPage.xml -->
    <FallbackPage namespace="helium" name="DefaultPage.xml" />
</PageMapping>

The framework will try to evaluate the different pages from top to bottom until one of the criteria is met. If no criteria is met, the <FallbackPage> will be evaluated.

The <PageMapping> element supports the following child elements.

Name Description Example

Page

Specifies the current Page to evaluate via the namespace and name attributes.

Only evaluate the page if the rules given via the child elements <Type> and <Access> evaluate to true, otherwise try the next page.

<!-- Evaluate the 'PartPage.xml'... -->
<Page namespace="helium" name="PartPage.xml">
        <!-- ...if the current object type is 'Part'
        and current state is 'Released'... -->
        <Type is="type_Part" and="current == Released">
        <!-- ...and if the current user belongs to the roles below -->
        <Access>
           <Role>role_SeniorDesignEngineer</Role>
           <Role>role_ManufacturingDesignEngineer</Role>
        </Access>
    </Type>
</Page>

FallbackPage

The page to fall back to if none of the above rules have been applied. Supports the namespace and name attributes.

<FallbackPage namespace="helium" name="DefaultPage.xml" />

1.1.2. Example

<?xml version="1.0" encoding="UTF-8"?>
<Application xmlns="http://technia.com/helium/Application">

    <Name>ACME</Name>

    <LoginPage>
        <Path>/helium/login.jsp</Path>
        <Title>Login to Helium</Title>
        <FormTitle>Welcome to Helium</FormTitle>
        <FormSubTitle>Please enter your credentials</FormSubTitle>
    </LoginPage>

    <StartPage>
        <Page namespace="helium">Page.xml</Page>
    </StartPage>

    <TopBar>
        <ShowAppName>true</ShowAppName>
        <Left>
            <Separator />
            <Menu>tvc:menu:helium/MyDashboards.xml</Menu>
            <Command>tvc:command:helium/ResetDashboards.xml</Command>
            <Command>tvc:command:helium/Create.xml</Command>
        </Left>
        <Right>
            <Myspace />
            <Search />
            <Logout />
        </Right>
    </TopBar>

    <PageMapping>
        <Page namespace="helium" name="PartPage.xml">
            <Type is="type_Part" and="current == Released">
                <Access>
                    <Role>role_SeniorDesignEngineer</Role>
                    <Role>role_ManufacturingDesignEngineer</Role>
                </Access>
            </Type>
        </Page>

        <Page namespace="helium" name="PartPage.xml">
            <Type is="type_Part" />
        </Page>

        <Page namespace="helium" name="ECO.xml">
            <Type is="type_ECO" />
        </Page>

        <Page namespace="helium" name="ECR.xml">
            <Type is="type_ECR" />
        </Page>

        <FallbackPage namespace="helium" name="DefaultPage.xml" />
    </PageMapping>

    <!--
    <Sidepanel>
	    <Label>Collaboration</Label>
	    <OnInit>App.Collaboration.Panel.instance</OnInit>
	</Sidepanel>
    -->

</Application>

1.2. Page

The page component contains Dashboards and/or Tabs. Each Dashboard holds references to one or more widgets and the Tabs element holds references to other Dashboards.

Pages are used when configuring start pages in the application. They are also used in the page mappings.

image
Figure 5. Page

1.2.1. Configuration

The <Page> element supports the following child elements.

Name Description Example

Title

Optional. Page Title will be seen in browser window, and in Breadcrumb if enabled. Context object pages can use macros to resolve dynamic page titles.

<Title>${TYPE}, ${NAME}:${REVISION}</Title>

Dashboard

Points to a reference to a Dashboard instance.

<Dashboard ns="helium" name="TopPanel.xml" />

Tabs

Configures a list of Tabs

<Tabs>
    <!-- Tab definitions -->
</Tabs>

Sidepanel

Configures sidepanel Sidepanel

<Sidepanel>
	    <Label>Collaboration</Label>
	    <OnInit>App.Collaboration.Panel.instance</OnInit>
    	<OnInitOption name="option" value="value" />
</Sidepanel>

Settings

Simple key value pairs of settings that are passed to the page. If a setting named class is provided, the value will be added to the Page’s DOM element. This can be used, for e.g. to style individual pages. On client, App.page.getSettings() JavaScript API can be used to retrieve these settings. See example.

<Settings>
	<Setting name="class" value="products-page" />
</Settings>

Access

Defines access rules.

1.2.2. Example configuration

<?xml version="1.0" encoding="UTF-8"?>
<Page>
    <Title>${TYPE}, ${NAME}:${REVISION}</Title>
    <Dashboard ns="helium" name="TopPanel.xml" />
    <Tabs>
        <Tab>
            <Label>Dashboard</Label>
            <CacheBehaviour>disabled</CacheBehaviour>
            <Dashboard ns="helium" name="Dashboard.xml" />
        </Tab>
        <Tab>
            <Label>Tab2</Label>
            <CacheBehaviour>preload</CacheBehaviour>
            <Dashboard ns="helium" name="Tab2.xml" />
        </Tab>
        <Tab>
            <Label>Tab3</Label>
            <CacheBehaviour>cache</CacheBehaviour>
            <Dashboard ns="helium" name="Tab3.xml" />
        </Tab>
    </Tabs>
</Page>

1.3. Page Sidepanel

A sidepanel is a container component where additional content can be placed. It can be either built-in components like (Collaboration) or custom component with own rendering. The visibility of this sidepanel container is toggled by clicking it.

Each page supports defining a sidepanel which can be revealed (slided in) from the right side. When the page is first loaded, the initial state of the sidepanel can be controlled from the component’s status method. Ex: "expand", "hidden", "disabled" or "enabled"

The <Sidepanel> element supports the following child elements.

Name Description Example

Label

The label of the sidepanel. If omitted no label will be rendered. If the value is an existing i18n key internationalisation will be performed

<Label>Sidepanel</Label>

OnInit

Javascript function that creates the widget.

<OnInit>
    App.Collaboration.Panel.instance
</OnInit>

OnInitOption

Additional options that is to be passed to the OnInit function.

<OnInitOption name="key"
    value="value" />

1.3.1. Javascript API

The sidepanel can be expanded, collapsed and disabled via javascript using the following syntax:

var sidepanel = App.page.sidepanel;
sidepanel.expand() // expands sidepanel
sidepanel.collapse() // collapses sidepanel
sidepanel.enable() // enables sidepanel
sidepanel.disable() // disables sidepanel
sidepanel.hide() // hides sidepanel

1.3.2. Custom Sidepanel Component

An Example Sidepanel component class with required methods in ES2016

    function ExampleSidepanel($container, objectId, options) {
        this.$container = $container;
        this.objectId = objectId;
        this.options = options;
    }

    ExampleSidepanel.prototype = {

        constructor: ExampleSidepanel,

        label: function() {
            return {
                label : 'custom.labels.example',
                iconClass: 'fa-comments-o'
            };
        },

        status: function() {
           return 'expand'; /* 'hidden', 'enabled', 'disabled' */
        },

        load: function() {
            this.$container.html('<div> Any html Content </div>');
        },

        unload: function() {
            this.$container.html('');
        }
    };

    ExampleSidepanel.instance = function($container, objectId, options) {
        return new ExampleSidepanel($container, objectId, options);
    };

    App.Example = { Sidepanel : ExampleSidepanel };

1.3.3. Example

<Sidepanel>
	<Label>Collaboration</Label>
    <!--   <OnInit>App.Example.Sidepanel.instance</OnInit> -->
	<OnInit>App.Collaboration.Panel.instance</OnInit>
    <OnInitOption name="option" value="value" />
</Sidepanel>
image
Figure 6. Page Sidepanel

1.4. Tabs

The <Tabs> element renders a list of tabs, where each <Tab> element holds a reference to a Dashboard or another set of <Tabs> that will be rendered beneath the current tab (multi-level tabs). It is possible to configure different cache behavior for each tab that holds a dashboard.

image

1.4.1. Tabs configuration

The <Tabs> Element supports the <Tab> child element which supports the following child elements.

Name Description Example

Label

The text that should be rendered in the tab

<Label>Tab 1</Label>

Tabs

A new Tabs element that creates a new row of child tabs.

<Tabs>...</Tabs>

CacheBehaviour

Describes how this tab should be cached. The cache behavior will only affect tabs that holds a dashboard. Valid values are:

disabled

the tab will not be cached

preload

the tab will be preloaded, even if the tab is not initially visible to the user

cache

the tab will be fetched from the server on the first access, but subsequent clicks on the tab will reuse a cached version of the tab

<CacheBehaviour>
    preload
</CacheBehaviour>

Dashboard

Holds a reference to a dashboard that will be rendered in this tab.

<Dashboard ns="helium" name="Tab3.xml" />

Badge

This element can be used to render a small "badge" on the side of the tab label that shows a status description (typically a number or other characters).

See Tab Badge chapter for configuration syntax

See Tab Badge section for example

Access

Defines access rules.

CustomClass

Adds one or more HTML classes on the tab DOM element. This can be used for applying custom styling

<CustomClass>
    wide yellow
</CustomClass>

IconClass

Adds an HTML class that represents a font icon. The icon will be rendered in front of the label

<IconClass>
    fa fa-cog
</IconClass>

Fixed

Prevents users from hiding/moving the tab

<Fixed>true</Fixed>

Visible

Initially have the tab hidden or visible

<Visible>false</Visible>

Settings

Settings to control the behavior of this instance of tabs

See Tab Settings section for details.

1.4.2. Tab Settings

The Settings element is used to control the behavior of the tabs. Some settings can be set as TVC properties to change the default values.

It supports the following child elements:

Name Description Example

Theme

Control the visual style of the tabs. Valid values are:

classic

Classic tabs (default)

material

Material design style

menu

Menu/Toolbar look and feel

<Theme>material</Theme>

IconTheme

Control the visual style of all built in tabs icons. Valid values are:

black

Black icons, no colors (default)

material

Material design style (color)

<IconTheme>material</IconTheme>

Orientation

Control the rendering of the tabs (vertical/horizontal)

horizontal

Horizontal orientation (default)

vertical

Vertical orientation

<Orientation>vertical</Orientation>

TabDrop

Feature that automatically "hides" tabs that does not fit on one row (default true)

<TabDrop>true</TabDrop>
tvc.properties

tvc.core.gui.tabPage.enableTabDrop=true

UserReset

Ability for users to reset the customization (default true)

<UserReset>true</UserReset>
tvc.properties

tvc.core.gui.tabPage.enableReset=true

UserRearrange

Ability for users to change tab order (default true)

<UserRearrange>true</UserRearrange>
tvc.properties

tvc.core.gui.tabPage.enableTabCfg=true

UserOrientationSwitch

Ability for users to toggle between horizontal and vertical orientation (default true)

<UserOrientationSwitch>true</UserOrientationSwitch>
tvc.properties

tvc.core.gui.tabPage.enableOrientationSwitch=true

UserHide

Ability for users to hide tabs (default true).

If you arrive to the page with a deeplink to a hidden tab it will still appear
<UserHide>true</UserHide>
tvc.properties

tvc.core.gui.tabPage.enableCloseButton=true

RememberUserSelection

Enable the feature to automatically save the last selected tab (default true)

<RememberUserSelection>true</RememberUserSelection>
tvc.properties

tvc.core.gui.tabPage.rememberSelection=true

1.4.3. Tab Customization

A user can customize tabs using the icon to the right. Depending on the settings: Visibility, order and orientation of tabs can be changed. Remembering the last visited tab can also be configured. All customization options are on by default but can be turned off by properties or settings.

If there are performance concerns the max size of the customizations can be controlled by the property:

tvc.core.customization.maxContentSize

default value: 100000 Characters

1.4.4. Tab Badge

The Badge element is used to render a small "badge" on the side of the tab label that shows a status description (typically a number or other characters).

image

It supports the following child elements:

Name Description Example

Label

A simple text that should be rendered in the badge

<Label></Label>

Position

Badge position relative to the tab label. Valid values are:

right

Rendered to the right side of the tab label (default)

left

Rendered to the left side of the tablabel

<Position>left</Position>

Provider

A provider can be used instead of a Label if the text is not static. Valid providers are:

mqlcount

Will count the number of returned objects from an mql temp query. If in context of an object it can also be used to count the number of returned objects from an mql expansion.

java

You can write your own java provider that implements the interface: com.technia.helium.core.ui.badge.provider.BadgeProvider

<Provider>mqlcount:temp query bus 'Part' * * where 'owner == context.user'</Provider>
<Provider>mqlcount:expand bus ${OBJECTID} from rel EBOM'</Provider>
<Provider>java:com.company.providers.MyProvider</Provider>

1.4.5. Deeplinking to tab

If an id attribute is appended to the <Tab> element it will be possible to link to that specific tab.

Example: Configure the tab with an id attribute, i.e <Tab id="documents"> and the following link will be accessible http://example.com/tvc/goto#documents.

Currently it is only possible to deeplink to a root (top level) tab, i.e. child tabs are not supported for deeplinking.
It is possible to deeplink to a tab even if the user have hidden it.

1.4.6. Example

This is placed within an Page element.

<Tabs>
    <Tab id="dashboard">
        <Label>Dashboard</Label>
        <CacheBehaviour>disabled</CacheBehaviour>
        <Dashboard ns="helium" name="Dashboard.xml" />
        <Badge>
            <Provider>mqlcount:temp query bus 'Part' * * where 'owner == context.user'</Provider>
        </Badge>
    </Tab>
    <Tab>
        <Label>Tab2</Label>
        <CacheBehaviour>preload</CacheBehaviour>
        <Dashboard ns="helium" name="Tab2.xml" />
    </Tab>
    <Tab>
        <Label>Tab3</Label>
        <CacheBehaviour>cache</CacheBehaviour>
        <Dashboard ns="helium" name="Tab3.xml" />
        <Badge>
            <Label>New!</Label>
            <Position>left</Position>
        </Badge>
    </Tab>
</Tabs>

Example with child tabs:

<Tabs>
    <Tab id="ebom">
        <Label>EBOM</Label>
        <CacheBehaviour>disabled</CacheBehaviour>
        <Dashboard ns="helium" name="PartEBOM.xml" />
    </Tab>
    <Tab id="documents">
        <Label>Documents</Label>
        <Tabs>
            <Tab>
                <Label>Child 1</Label>
                <Tabs>
                    <Tab>
                        <Label>Suppliers</Label>
                        <CacheBehaviour>cache</CacheBehaviour>
                        <Dashboard ns="helium" name="PartEBOM.xml" />
                    </Tab>
                    <Tab>
                        <Label>Where used</Label>
                        <CacheBehaviour>cache</CacheBehaviour>
                        <Dashboard ns="helium" name="Tab2.xml" />
                    </Tab>
                </Tabs>
            </Tab>
            <Tab>
                <Label>Child 2</Label>
                <CacheBehaviour>cache</CacheBehaviour>
                <Dashboard ns="helium" name="Tab2.xml" />
            </Tab>
        </Tabs>
    </Tab>
</Tabs>

1.5. Toolbar

Each widget supports an additional toolbar that may contain preconfigured actions. The toolbar can either be rendered in horizontal mode or in vertical mode. In vertical mode the toolbar will be placed to the left of the widget.

image
Figure 7. example horizontal toolbar
If widget size is small and toolbar items are more than helium by default shows only icons corresponding to toolbar items. Hence, its always recommended to configure icon for toolbar items.

1.5.1. Toolbar configuration

The <Toolbar> element supports the following attributes.

actionHandler

Java class that points to an implementation of an action handler. See custom action handler

vertical

Whether the toolbar should be configured to be rendered in vertical mode. Valid values true or false. Defaults to false.

showUipToolbar

Whether to render uip-toolbar or default helium toolbar. Valid values true or false. Default is false.

isCustomizable

Signifies if the end user is allowed to customize the toolbar or not.If enabled the user hide and reorder the commands or rotate the toolbar. Valid values are true or false. Defaults to false.

The toolbar element supports the following child elements.

Name Description Example

Menu

Creates a dropdown menu in the toolbar. The toolbar can have zero or multiple menus

See specific Menu configuration below

Command

Creates a command in the toolbar

See specific Command configuration below

Toolbar menu

The <Menu> element renders a dropdown menu in the toolbar

The menu element supports the following child elements.

Name Description Example

Label

The name of the dropdown for instance 'Actions'

<Label>Actions</Label>

FontIcon

What icon should be rendered next to the label.

<FontIcon>
    he-pencil
</FontIcon>

Image

What image should be rendered next to the label

<Image>${ROOT_DIR}/tvc/core/images/list-add.png</Image>

RegisteredSuite

Defines the registered suite. This will be used to resolve macros

<RegisteredSuite>EngineeringCentral</RegisteredSuite>

Command

Creates a command in the toolbar

See specific Command configuration below

Menu

If UIP Toolbar is configured, we can configure sub menus by configuring Menu inside.

This feature is only available for uip-toolbar.

<Menu>
    .... // configuration for menu
</Menu>

Alt

Tooltips can be configured for menu by adding <Alt>

This feature is only available for uip-toolbar.

<Alt>Text for tooltip</Alt>
Toolbar command

The <Command> element renders a command in either the toolbar itself, or in an toolbar menu. A command describes a user action.

The <Command> element supports the following child elements.

Name Description Example

Label

Name of the command, for example 'Promote'. By default, the content of it will be shown inside the tooltip. The tooltip is shown after a short interval after the mouse is over a "box".

<Label>
    Delete
</Label>

Alt

Option for configuring tooltip other than label

<Alt>
    Alternative tooltip
</Alt>

FontIcon

What icon should be rendered next to the label.

<FontIcon>
    he-pencil
</FontIcon>

Image

What image should be rendered next to the label

<Image>${ROOT_DIR}/tvc/core/images/list-add.png</Image>

RegisteredSuite

Defines the registered suite. This will be used to resolve macros

<RegisteredSuite>EngineeringCentral</RegisteredSuite>

OnClick

What javascript function should be executed when the user clicks the command, for example: App.custom.delete.

Depending on the content of the widget this inside of the function can refer to the actual content.

For example if the content of the widget is a datatable, this will be set to the table. Which means that is possible to interact with the table using for example this.selectedRows()

<OnClick>
   App.custom.delete
</OnClick>

OnClickParams

Additional parameters to send to the javascript function. Usually a javascript object.

selectionCriteria

To enable/disable command based on row selection. Valid values are
single : only enable when one row is selected,
multi : enable when at least one row is selected
many : only enable when at least two rows are selected.

<OnClickParams>{
    "options": {foo: "bar"},
    "selectionCriteria" : "many"
}</OnClickParams>

ValidFor

Defines the command is valid for which rows in datatable

 <ValidFor>
        <Types>
            <Type>type_Part</Type>
            <Type>type_AnotherType</Type>
        </Types>
        <States policy="policy_DevelopmentPart">
            <State>state_Create</State>
            <State>state_AnotherState</State>
        </States>
        <States policy="policy_ECPart">
            <State>state_Preliminary</State>
        </States>
    </ValidFor>
Custom action handler

The <Toolbar> element supports the actionHandler attribute. The actionHandler attribute value should point to an implementation of a custom action handler. The action handler can implement custom actions.

One actionHandler that ships with Helium is com.technia.helium.table.config.action.TableActionHandler which provides special actions that is intended to be used with a DataTable.

If the com.technia.helium.table.config.action.TableActionHandler is used, it is possible to add the following elements to the toolbar.

Name Description Example

Search

Whether the toolbar should have a search field.

If the element is left out no search field will be rendered.

If show parents is true than the parent rows of the matching rows will also be rendered in structure tables.

It can also be defined using global setting tvc.helium.widget.search.showParents in tvc.properties or web xml init param. Default value is false.

<Search showParents="true"/>

default value of showparents is false

ExpandAll

Whether the toolbar should have a button to fully expand all nodes in structure table.

<ExpandAll />

ExportExcel

Preconfigured command that exports the rows of the table to Excel format.

<ExportExcel />

ExportPDF

Preconfigured command that exports the rows of the table to PDF format.

<ExportPDF />

ExportCSV

Preconfigured command that exports the rows of the table to CSV format.

<ExportCSV />

Collection

Adds a collection menu with below commands to manage businessobjects in Clipboard and Collection.

  1. Add to Clipboard

    • On selecting table row and clicking this command, table row objects will be added to clipboard and built-in clipboard widget will be opened in side-panel. if there is a clipboard widget defined in the dashboard, it will be refreshed to show updated data. See…​ for details on how to configure clipboard widget.

  2. View Clipboard

    • If clicked on this command it will open a clipboard widget in side panel if user has not defined their own clipboard widget.

  3. Add to Collection

    • This command allows the user to add objects to a new collection or to an existing collection.

  4. View Collection

    • This command lists all the existing collections and toolbar commands to manage each collection objects.

Refer Customize Collection section for customizations

<Collection />

Expand all nodes in structure table
Example of a table widget with a toolbar
<DataTable>
    <Title>First Level</Title>
    <TableConfig namespace="helium">EBOMConfig.xml</TableConfig>
    <Toolbar actionHandler="com.technia.helium.table.config.action.TableActionHandler">
        <Search />
        <ExpandAll />
        <Menu>
            <Label>Actions</Label>
            <FontIcon>fa-bars</FontIcon>

            <Command>
                <Label>Promote</Label>
                <FontIcon>fa-forward</FontIcon>
                <OnClick>App.table.action.promote</OnClick>
            </Command>
            <Command>
                <Label>Demote</Label>
                <FontIcon>fa-backward</FontIcon>
                <OnClick>App.table.action.demote</OnClick>
            </Command>
            <Command>
                <Label>Edit</Label>
                <FontIcon>fa-edit</FontIcon>
                <OnClick>App.form.edit</OnClick>
                <OnClickParams>{"formConfigName": "tvc:form:helium/Form1.xml", "fullscreen": true}</OnClickParams>
            </Command>
        </Menu>

        <Menu>
            <Label>Export</Label>
            <FontIcon>fa-share</FontIcon>
            <ExportExcel />
            <ExportPDF />
            <ExportCSV />
        </Menu>
    </Toolbar>
</DataTable>
Example of a form with a vertical toolbar
<FormWidget>
    <FormConfig namespace="helium">Form1.xml</FormConfig>
    <ResolveContextId>page</ResolveContextId>
    <FormMode>view</FormMode>
    <ShowToggleButton>false</ShowToggleButton>

    <Toolbar vertical="true">
        <Command>
            <Label>Toggle Edit Mode</Label>
            <FontIcon>he-pencil</FontIcon>
            <OnClick>App.custom.toggleEditMode</OnClick>
        </Command>
        <Command>
            <Label>Some action</Label>
            <FontIcon>he-chevron-right</FontIcon>
            <OnClick>App.custom.toggleEditMode</OnClick>
        </Command>
    </Toolbar>

</FormWidget>

1.5.2. Invoke Service

Like TVC Classic, 3DExperince services can be reused and called from Helium toolbar. This will allow leveraging existing 3DExperince in Helium table and perform actions like create change order, change request and other actions.

Built-in javascript function App.dataTable.invokeServiceAndCreateObject can be used to launch 3DExperince services, which can be configured using parameter config. Invoke service requires that the result from the 3DExperience service is in form of objectId/physicalid that can be used with configured refreshBehavior.

	<Command>
		<Label>Invoke Service</Label>
		<FontIcon>icon ti-c ti-plus</FontIcon>
		<OnClick>App.dataTable.invokeServiceAndCreateObject</OnClick>
		<OnClickParams>{
			"config": "tvc:service:ups:classic:18x/CreatePartV5.xml",
			"resultExpression": "id",
			"from": "true",
			"selection": "single",
			"refreshBehavior": "add"
		}</OnClickParams>
	</Command>

Following on click params can be used to invoke service / javascript function App.dataTable.invokeServiceAndCreateObject

Parameter Description Required Example

config

Name of the service configuration. It is used to configure the path to the service config.
For more details check link:here

Yes

    <OnClickParams>{
		"config": "tvc:service:ups:classic:18x/CreatePartV5.xml"
	}</OnClickParams>

resultExpression

An expression that will be applied to the result from the service invoke.
Supported values are id or objectId

Yes

    <OnClickParams>{
		"resultExpression": "id"
	}</OnClickParams>

from

Direction to add the new object to table.

Yes

    <OnClickParams>{
		"from": "true"
	}</OnClickParams>

selection

It defines how many object can be selected to perform this action.
Supported values are single, multiple and none.

Default is multiple

No

    <OnClickParams>{
		"selection": "single"
	}</OnClickParams>

refreshBehavior

It defines how a new node would be added from the result to the table.
Supported values are insert,add or expand.

Default is add.

No

    <OnClickParams>{
		"from": "true"
	}</OnClickParams>

1.6. Service Toolbar

Like TVC Classic, we can also call OOTB service directly from client side. It will provide more flexibility and configuration support like allowing user to take input with the associated form and also it gives us possibility to perform multi selection and the chaining of the services. To call OOTB services, we need to predefined it in an XML configuration file. The services are then accessed from an ordinary service command, which contains the reference to the XML file that defines/configures the service.

Built-in javascript function App.dataTable.invokeServiceCall can be used to launch 3DExperience services, which can be configured using JSON config.

1.6.1. Service Command

ServiceCommand will be used to configure an OOTB service. XML configure is shown as below.

XML Definition

The example below illustrates how to define a service inside service command with xml.

<ServiceCommand>
    <Label>Unreserve</Label>
    <Setting name="OnClick" value="App.invokeServiceCallbacks.invokeService" />
    <Setting name="OnClickParams">{
		"url":
		"resources/v1/collabServices/reservation/op/unreserve?tenant=OnPremise&amp;isMultiSel=0&amp;select=physicalid",
		"header":{"content-type": "application/json"},
		"addSecurityContext": "false",
		"method":"POST",
		"body":{"urls": ["{{model//{{physicalid}}}}"]},
		"macro":"true",
		"macroElements":"physicalid",
		"selectionCriteria": "multiple"
		}</Setting>
</ServiceCommand>

We can also use the reference of this command.

<DataTable>
    ...
    <Toolbar>
        ...
        <Menu>
            <Label>Service Actions</Label>
            <ServiceCommand ref="tvc:servicecommand:hex:engineering:homepage/ReserveProduct.xml" />
            <ServiceCommand ref="tvc:servicecommand:hex:engineering:homepage/UnreserveProduct.xml" />
            <ServiceCommand ref="tvc:servicecommand:hex:engineering:homepage/MultiServiceChaining.xml" />
        </Menu>
        ...
    </Toolbar>
</DataTable>
Child elements of OnClickParams
Parameter Description Required Example

url

This element defines the URL of intial service.

Yes

"url": "resources/v1/collabServices/reservation/op/unreserve…​"

header

The header of the initial service call.

No

"header":{"content-type": "application/json"}

body

The body of the service call. It supports injecting macro statments

No

"body":{"urls": ["model//{{physicalid}}"]}

If row selection type is multiple, we need to define macroelements inside {{}}.

example: "body":{"urls": ["{{model//{{physicalid}}}}"]}

macro

If we have any macros defined in Body, then this setting needs to be true

No

"macro":"true"

macroElements

If we have any macros defined in Body, then that macro elements should be defined in this tag. It requires macro tag to be true.

No

"macroElements":"physicalid"

addCsrfToken

This setting can be configured as true to put 3dspace csrf token in service request header.

No

"addCsrfToken": "false"

addSecurityContext

This setting can be configured as true to put security context in service request header.

No

"addSecurityContext": "false"

refreshRows

It defines how the table rows will be refreshed after the processing is done. If this setting is enabled, only rows selected will be refreshed.

No

"refreshRows": "true"

preRequestCallback

Users can specify a reference to a javascript function that will be executed before service call. The function itself needs to be included in a javascript resource. The function needs to receive four parameter, which will be the payload of the service being modified or updated, second parameter is the response of macros, third and fourth parameter are resolve and reject respectively, which will be called at the end to resolve payload.

No

"preRequestCallback": "App.invokeServiceCallbacks.initialRequestCallback",

initialRequestCallback: function(options,response, resolve, reject) {
    // Here options are payload of the service being modified/updated
    // response, is the resolved value of the macros
    // resolve and rejects are the Promise callback functions
    console.log('In initial service callback');
    resolve(options);
}

responseCallback

Users can specify a reference to a javascript function that will be executed after service call. The function itself needs to be included in a javascript resource. The function needs to receive one parameter, which will be the response of the service being modified or updated.

No

"responseCallback":"App.invokeServiceCallbacks.initialResponseCallback"

initialResponseCallback: function(response) {
    console.log('in first response payloadCallback callback' + response);
}

successMessage

User can specify, success messge in translation file (default.json) and use it’s key.

No

"successMessage": "invokeservice.messages.service.reserveSuccess"

resolverPaths

Service chaining can be configured using resolverPaths. Each service is configured as a array element in resolverPath. For more details check here

No

"resolverPaths":[{
    "order":1,
    "preRequestCallback": "App.invokeServiceCallbacks.firstResolverPathCallback",
    "url": "data[0].dataelements.ticketURL",
    "header":{"content-type": "application/json"},
    "body":{"__fcs__jobTicket":"{{data[0].dataelements.ticket}}"},
    "method":"POST",
    "bodyResolver": "data[0].dataelements.ticket",
    "responseCallback": "App.invokeServiceCallbacks.firstResolverResponseCallback"
    }]
Resolver-Paths Configuration

ResolverPaths configuration supports following elements/settings.

Element Description Required Example

url

This element defines the URL which we want to call after receiving the response of initial service. This can be resolved from response of intial service or can be configured separately.

Yes

"url": "data[0].dataelements.ticketURL",

Here, data[0].dataelements.ticketURL is the part of response object where we get the URL of next service call

OR

"url": "resources/v1/collabServices/reservation/op/unreserve?tenant=OnPremise&amp;isMultiSel=0&amp;select=physicalid"

order

A number value used to define in which order service will be executed. The lowest order number will get executed first.

Yes

"order":1

header

The header of the next service call can be configured for service request.

No

"header":{"content-type": "application/json"}

body

The body of the service call. It supports injecting macro statments

No

` "body":{"fcsjobTicket":"{{data[0].dataelements.ticket}}"}`

Here, data[0].dataelements.ticket is the part of response object where we get the value of fcsjobTicket

bodyResolver

It is used to resolve macro statement mentioned inside the Body tag. Here multiple macros can be specified, using comma as delimeter.

No

"bodyResolver": "data[0].dataelements.ticket" Here, data[0].dataelements.ticket is the macro element which we define in the body tag.

addCsrfToken

This setting can be configured as true to put 3dspace csrf token in service request header.

No

"addCsrfToken": "false",

addSecurityContext

This setting can be configured as true to put security context in service request header.

No

"addSecurityContext": "false",

method

HTTP method/verb that should be used to invoke the next service. Valid values are:

GET

POST

PUT

PATCH

DELETE

By default it is GET.

No

"method":"POST",

preRequestCallback

Users can specify a reference to a javascript function that will be executed before service call. The function itself needs to be included in a javascript resource. The function needs to receive four parameter, which will be the payload of the service being modified or updated, second parameter is the resolved value of the macros, third and fourth parameters are resolve and reject respectively, which will be called at the end to resolve payload.

No

"preRequestCallback": "App.invokeServiceCallbacks.firstResolverPathCallback"

firstResolverPathCallback: function(options,response, resolve, reject) {
    // Here options are payload of the service being modified/updated
    // response, is the resolved value of the macros
    // resolve and rejects are the Promise callback functions
    console.log('In initial service callback');
    resolve(options);
}

responseCallback

Users can specify a reference to a javascript function that will be executed after service call. The function itself needs to be included in a javascript resource. The function needs to receive one parameter, which will be the response of the service being modified or updated.

No

"responseCallback": "App.invokeServiceCallbacks.firstResolverResponseCallback"

firstResolverResponseCallback: function(response) {
    console.log('in first response payloadCallback callback' + response);
}
XML Definition

Below is the example of uploading a document for a VPMReference object using 3DExperience services. In the 3DExperience we see multiple requests. Initially it calls CheckinTicket and from its response object it will receive URL for the next service call and fcsjobTicket which it will pass in the body of next service. Then, it calls checkin service to upload the document. Below is the example illustrates how to configure this type of service chaining inside TVC Service command with xml.

<ServiceCommand>
    <Label>Add New Document</Label>
    <Setting name="OnClick" value="App.dataTable.invokeServiceCall" />
	<Setting name="OnClickParams">{
		"url":"resources/v1/modeler/documents/files/CheckinTicket?tenant=OnPremise&amp;e6w-lang=en&amp;e6w-timezone=-330",
		"headers":{"content-type": "application/json"},
		"addSecurityContext": true,
		"method":"PUT",
		"body":{"urls": ["model//{{physicalid}}"]},
		"macro":true,
		"macroElements":"physicalid",
		"preRequestCallback": "App.invokeServiceCallbacks.initialRequestCallback",
		"responseCallback":"App.invokeServiceCallbacks.initialResponseCallback",
		"successMessage":"invokeservice.messages.service.documentSuccess",
		"resolverPaths":[{
		            "order":1,
		            "preRequestCallback": "App.invokeServiceCallbacks.firstResolverPathCallback",
		            "url": "data[0].dataelements.ticketURL",
		            "header":{"content-type": "application/json"},
		            "body":{"__fcs__jobTicket":"{{data[0].dataelements.ticket}}"},
		            "method":"POST",
		            "bodyResolver": "data[0].dataelements.ticket",
		            "responseCallback": "App.invokeServiceCallbacks.firstResolverResponseCallback"
		       },
		       {
		            "order":2,
		            "url": "resources/v1/modeler/documents/?tenant=OnPremise&amp;e6w-lang=en&amp;e6w-timezone=-330&amp;xrequestedwith=xmlhttprequest",
		            "method":"POST",
		            "addSecurityContext": true,
		            "header":{"content-type": "application/json"},
		            "body": {"csrf":{"name":"{{csrfName}}","value":"{{csrfValue}}"},"data":[{"dataelements":{"title":"{{fileName}}","parentId":"{{parentId}}","parentRelName":"PLMDocConnection","parentDirection":"from"},"relateddata":{"files":[{"dataelements":{"title":"{{fileName}}","receipt":"{{text}}"}}]},"tempId":"{{tempId}}"}]},
		            "bodyResolver": "csrfName,csrfValue,fileName,parentId,fileName,text,tempId",
		            "responseCallback":"App.invokeServiceCallbacks.secondResolverResponseCallback"
		       }
		    ]
		}</Setting>
</ServiceCommand>

Here, at the begining, intial service will get call, the subsequent service call we define inside the tag of resolverPaths. The subsequents service will be executed in the defined order.

Below, is the definition of callback used for the above configuration.

(function(window, App, $) {

    var invokeServiceCallbacks = {

        // callbacks for creating doc element

        initialRequestCallback: function(options, payload, resolve, reject) {
            console.log('In initial service callback');
            this.serviceOptions.parentId = payload[0];
            var inputElement = document.createElement("input");
            inputElement.type = "file";
            inputElement.accept = window.accept;
            inputElement.dispatchEvent(new MouseEvent("click"));
        	inputElement.addEventListener('change', (event) => {
                event.preventDefault();
                event.stopImmediatePropagation();
                let files = event.target.files.length>0 ? event.target.files :event.dataTransfer.files; // FileList object
                for (var index = 0; index < files.length; index++) {
                  const file = files[index];
                  var documentInfo = {
                    title: file.name,
                    fileInfo: {
                      comments: '',
                      file: file
                    },
                    relInfo: {
                      parentId: this.serviceOptions.parentId,
                      parentRelName: 'PLMDocConnection',
                      parentDirection: 'from'
                    }
                  };
                  this.serviceOptions.documentInfo = documentInfo;
                  this.serviceOptions.documentInfo.fileInfo = documentInfo.fileInfo;
                }
                resolve(options);
            });
        },

        initialResponseCallback: function(response) {
            console.log('In Initial Service Response Callback' + response);
            this.serviceOptions.csrfTokenName = response.csrf.name;
            this.serviceOptions.csrfTokenValue = response.csrf.value;
        },

        firstResolverPathCallback: function(payload, response,resolve, reject) {
            console.log('In first pre request service callback');
            var fileInfo = this.serviceOptions.fileInfo || (this.serviceOptions.documentInfo && this.serviceOptions.documentInfo.fileInfo);
            var file = fileInfo && fileInfo.file;
            var fileName = file && fileInfo.file.name; //case of overwritten file name
            var formData = new FormData();
            formData.append(
                    Object.keys(payload.body)[0],
                    Object.values(payload.body)[0]
                );
            formData.append('file_0', file, fileName);
            payload.data = formData;
            payload = {
                method: payload.method,
                url: payload.url,
                data: payload.data,
                contentType: false,
                processData: false
            };
            resolve(payload);
        },

        firstResolverResponseCallback: function(response) {
            response.text = encodeURI(response.text);
            response.csrfName = this.serviceOptions.csrfTokenName;
            response.csrfValue = this.serviceOptions.csrfTokenValue;
            response.parentId= this.serviceOptions.parentId;
            var fileInfo = this.serviceOptions.fileInfo || (this.serviceOptions.documentInfo && this.serviceOptions.documentInfo.fileInfo);
            var file = fileInfo && fileInfo.file;
            var fileName = file && fileInfo.file.name;
            response.fileName = fileName;
            var d = new Date();
            var g = d.getTime();
            response.tempId = "temp_" + g;
            console.log('In first Service Response Callback' + response);
        },

        secondResolverPathCallback: function(options, payload,resolve, reject) {
            console.log('In second pre request service callback');
            resolve(options);
        },
        secondResolverResponseCallback: function(response) {
            console.log('In second pre response service callback');
        },
        formResponseCallback:function(formInput){
        	 console.log('In form response service callback');
        }
    };

    App.invokeServiceCallbacks = $.extend({}, App.invokeServiceCallbacks || {}, invokeServiceCallbacks);
})(window, App, jQuery);

1.6.2. Input Based Service

It is possible to call OOTB service and include the OOTB service response value in the Form for further processing. Also, it allows to open a form and prepare OOTB service body with the user input. First, form can be invoked to take user input and on submit it will process the OOTB service.

Form Configuration

Form configuration supports following elements/settings.

Element Description Required Example

url

This is the URL of service which will be called on the submission of the Form. This can be resolved from the response object of initial service or can be configured separately.

Yes

"url":"resources/v1/engineeringItem/setPartNumber?tenant=OnPremise&amp;_=1613402130670&amp;xrequestedwith=xmlhttprequest",

options

This element defines Helium’s Form options setting which will looks for config file

Yes

"options":{
        "formConfigName": "tvc:form:hex:engineering/Form1.xml",
        "fullscreen":true,
        "modal":{
        "position":{"top":"30%","bottom":"20%","left":"40%","right":"10%"},
        "controls":{"dock":true,"expand":true,"close":true}
    }

header

This setting can be configured to add addition values in the service request header which will be called on the submission of the form.

No

"header":{"content-type": "application/json"}

contentType

This setting can be configured to add content type in service request header which will be called on the submission of the form. By default it is application\json

No

"contentType": "application/json"

body

The body of the service which will be called on the submission of the form. It supports injecting macro statments

No

"body":{
    "references": [{
	    "physicalid": "{{references[0].physicalid}}",
	    "partNumber": "{{partNumber.values[0].value}}"}
    ]},

Here, references[0].physicalid is the response object which we will retrieve from the initial service call and partNumber is the field id from which we take input from the user defined in the Helium Form.

bodyResolver

It is used to resolve macro statement mentioned inside the Body tag. Here multiple mcaros can be specified, using comma as delimeter.

No

bodyResolver": "references[0].physicalid,partNumber.values[0].value"

addCsrfToken

This setting can be configured as true to put csrf token in service request header.

No

addCsrfToken: true

addSecurityContext

This setting can be configured as true to put security context in service request header.

No

addSecurityContext": true

method

HTTP method/verb that should be used to invoke the service. Valid values are:

GET

POST

PUT

PATCH

DELETE

No

"method":"PUT

formCallback

Users can specify a reference to a javascript function that will be executed after service call. The function itself needs to be included in a javascript resource. The function needs to receive one parameter, which will be the form input of the form being modified or updated.

No

"formCallback": "App.invokeServiceCallbacks.formResponseCallback"

formResponseCallback: function(formInput) {
    console.log('in first response payloadCallback callback' + formInput);
}
XML Definition

The example below illustrates how to define a form based service inside service command with xml. Below is the example of updating a part number for a VPMReference object using 3DExperience service. In the 3DExperience we see multiple requests, initially it will call retrievePartNumber and from its response object it will open a form where it shows Old Part Number and take input from the form to set new part number and call setPartNumber service on submission of the form. This example illustrates how to configure this type of service chaining inside TVC Service command with xml.

Here, inside the OnClickParams tag we defined the initial service call configuration. For example, retrievePartNumber and then inside form tag we will define next service call inside the url tag, which will call on the submission of the form eg. setPartNumber. Inside Form’s Body tag, macros are defined like physicalid and partNumber (It is the field id defined in the form using which we take user inputs).

<ServiceCommand>
    <Label>Retrieve And Set Part Number</Label>
    <Setting name="OnClick" value="App.dataTable.invokeServiceCall" />
    <Setting name="OnClickParams">{
		"url":"resources/v1/engineeringItem/retrievePartNumber?tenant=OnPremise&amp;xrequestedwith=xmlhttprequest&amp;_=1611277466036",
		"header":{"content-type": "application/json"},
		"addSecurityContext": true,
		"method":"POST",
		"body":{"references": [{"physicalid": "{{physicalid}}"}]},
		"macro":true,
		"macroElements":"physicalid",
		"selectionCriteria": "single",
		"form":{
		     "options":{
		                 "formConfigName": "tvc:form:hex:engineering/Form1.xml",
		                  "fullscreen":true,
		                 "modal":{
		                          "position":{"top":"30%","bottom":"20%","left":"40%","right":"10%"},
		                          "controls":{"dock":true,"expand":true,"close":true}
		                    }
		        },
		     "url":"resources/v1/engineeringItem/setPartNumber?tenant=OnPremise&amp;_=1613402130670&amp;xrequestedwith=xmlhttprequest",
		     "header":{"content-type": "application/json"},
		     "body":{"references": [{"physicalid": "{{references[0].physicalid}}", "partNumber": "{{partNumber.values[0].value}}"}]},
		     "method":"PUT",
		     "addSecurityContext": true,
		     "bodyResolver": "references[0].physicalid,partNumber.values[0].value",
		     "formCallback": "App.invokeServiceCallbacks.formResponseCallback"
		}
		}</Setting>
</ServiceCommand>
XML Definition for Helium Form

Below is the defination of Helium form, It will be as usual. If we want to show the response of first service inside the form field, then we need to define Setting to map the response object to that field. In the below configuration in the Old Part Number field we want to show the value retrieved from the response of retrievePartNumber service call. For this we mapped it with the response object. Here, references[0].partNumber is the response object of retrievePartNumber service call.

<Form>
    <Title>Set Part</Title>
    <Layout>
        <Columns>1</Columns>
    </Layout>
    <Section>
        <Field>
            <Label>Old Part Number</Label>
            <Setting name="options">{"mapping":"references[0].partNumber"}</Setting>
            <Editable>false</Editable>
            <FieldType>text</FieldType>
        </Field>
        <Field id="partNumber">
            <Label>Part Number</Label>
            <Editable>true</Editable>
            <FieldType>text</FieldType>
        </Field>
	</Section>
</Form>
XML Definition

The example below illustrates how to take user input and pass it to the OOTB service.

<ServiceCommand>
    <Label>Set Part Number</Label>
    <Setting name="OnClick" value="App.dataTable.invokeServiceCall" />
    <Setting name="OnClickParams">{
		"macro":"true",
		"macroElements":"physicalid",
		"selectionCriteria": "single",
		"form":{
		     "options":{
		                 "formConfigName": "tvc:form:hex:engineering/Form1.xml",
		                  "fullscreen":true,
		                 "modal":{
		                          "position":{"top":"30%","bottom":"20%","left":"40%","right":"10%"},
		                          "controls":{"dock":true,"expand":true,"close":true}
		                          }
		      },
		     "url": "resources/v1/engineeringItem/setPartNumber?tenant=OnPremise&amp;_=1613402130670&amp;xrequestedwith=xmlhttprequest",
		     "body":{"references": [{"physicalid": "{{physicalid}}", "partNumber": "{{partNumber.values[0].value}}"}]},
		     "method":"PUT",
		     "addSecurityContext": true,
		     "bodyResolver": "physicalid,partNumber.values[0].value",
		     "formCallback": "App.invokeServiceCallbacks.formResponseCallback"
		}
		}</Setting>
</ServiceCommand>

1.7. Dashboard

The main responsibility of the Dashboard is to hold references to different widgets.

image
Figure 8. Dashboard with multiple widgets

1.7.1. Configuration

The <Dashboard> element supports the following child elements.

Name Description Example

Locked

Whether the dashboard should be locked or not. A locked dashboard can not be customized. Valid values true or false.

<Locked>true</Locked>

DisableCustomization

Dashboard customization can be disabled for dashboard. Valid values true or false. Default is false

<DisableCustomization>true</DisableCustomization>

Floating

Whether the dashboard should be floating to the top of the page or not. Valid values true or false.

<Floating>true</Floating>

ResizableHandles

Configure different options i.e any combination of comma seperated valid value, to enable resize widget from different positions like right, left, bottom, left bottom or right bottom. Valid values are e, se, s, sw, w. Default value is se.

  • e - Right

  • w - Left

  • s - Bottom

  • se - Bottom-Right

  • sw - Bottom-Left

<ResizableHandles>e, se, s, sw, w</ResizableHandles>

Widgets

Specifies what Widgets this dashboard should contain.

<Widgets>
    <!-- Widget definitions -->
</Widgets>

1.7.2. Dashboard Customization

A user can customize a dashboard by changing size and position of widgets.

Customization is enabled by default but can be turned off with a property:

tvc.helium.dashboard.customization.enabled=false

or by configuring a dashboard or widget as locked.

Customization actions

For customizable dashboards, a small UI element is automatically appended on the right hand side*, and it slides in to expand when the user focuses on the element. From this menu, the end user can create and manage multiple dashboard views via a sidepanel and easily reset any customization they have done on that particular dashboard view, or re-add a previously removed widget.

Resetting of end user widget which was added dynamically with reset dashboard customization can be enabled with a property:

tvc.helium.dashboard.customization.resetEnduserWidget=true.
image
Figure 9. Customizable Dashboard, showing the customizations menu

(*) If the dashboard is presented in stacked mode, for instance if the user is on a mobile device in portrait mode, the menu is hidden. Customizations only apply to normal dashboard mode.

Dashboard Views

The end user can create and manage multiple dashboard views within a single dashboard, allowing the user to create customized dashboards to better fit their workflow.

From the dashboard menu, the end user can open a sidepanel where it is possible to create and manage multiple dashboard views and easily copy, delete or reset any customization they have done on a dashboard view.

Customization maximum cap

If there are performance concerns, the max size of the customizations object can be controlled by the property:

tvc.core.customization.maxContentSize

default value: 100000 Characters

Widget

The <Widget> element references widget instance via the ref attribute. For example <Widget ref="tvc:widget:helium/MaterialCategoryWidget.xml"/>

It also specifies where an widget should be rendered on the dashboard and what size the widget should have.

For sizes and placements of widgets, keep in mind that TVC Helium is based on a so called grid system, where a dashboard is generally divided into 12 columns. A Widget that should cover the entire browser window width should therefore specify its width to 12, two widgets side-by-side should each specify 6, and so on.

The <Widget> element supports the following child elements.

Name Description Example

Id

The identifier of the widget. Should be unique.

At the moment there is no uniqueness check for widget ID’s. Multiple widgets with the same Id can cause unexpected behaviour.

<Id>materialcategory</Id>

Locked

Whether the widget should be locked or not. A locked widget can not be customized. Valid values true or false.

<Locked>true</Locked>

Width

The width of the widget. Valid value: Positive integer between 1 and 12. It supports the following attributes:

minWidth

Specifies minimum width upto which Widget size can be shrink.

maxWidth

Specifies maximum width upto which Widget size can be expand.

These attributes are optional.
<Width>3</Width>

<Width minWidth="3">6</Width>

<Width maxWidth="8">6</Width>

<Width minWidth="3" maxWidth="8">6</Width>

Height

The height of the widget. Valid value: Positive integer. It supports the following attributes:

adjustHeight

Specifies whether the widget should adjust the height to fit the content (and vertical toolbar if defined) or fill the available space when there is single widget.Valid values are :

true - Widget should adjust the height to fit the content

false - Widget should not adjust the height to fit the content

fill - Fill the available space for a single widget..

The widget needs to have a default height even if adjustHeight is set to true.
Manual Expand/Shrink of Widget will not work when adjustHeight is set to true.
minHeight

Specifies minimum height upto which Widget size can be shrink. This can be set globally in tvc.properties tvc.helium.dashboard.widget.defaultMinHeight = 5. Default value is 5.

maxHeight

Specifies maximum height upto which Widget size can be expand. This can be set globally in tvc.properties tvc.helium.dashboard.widget.defaultMaxHeight = 15. Default value is 18.

minHeight and maxHeight attributes are optional.
<Height adjustHeight="true">
    4
</Height>

<Height minHeight="3">6</Height>

<Height maxHeight="8">6</Height>

<Height minHeight="3" maxHeight="8">6</Height>

<Height adjustHeight="fill"></Height>

X

Specifies where on the X axis the widget should be placed. Valid value: Positive integer.

<X>0</X>

Y

Specifies where on the Y axis the widget should be placed. Valid value: Positive integer.

<Y>1</Y>

Template

Specifies which template the widget should be rendered with. If omitted a default template will be used. Useful if you would like to design your own widget frame template with full path from project root, or render a widget without a header. The latter is accomplished by setting the element text to headerless. Default directory path used for searching template is helium\templates\widget.

<Template>
    headerless
</Template>

or

<Template>helium/custom/templates/headerless</Template>

Badge

This element is used to render a small badge in widget header on right side of the widget title that shows total object count in the widget. In case of history widget it shows number of rows. Valid value is true or false. Default value is false.

<Badge>true</Badge>

1.7.3. Example

<?xml version="1.0" encoding="UTF-8"?>
<Dashboard xmlns="http://technia.com/helium/Dashboard">
    <Locked>false</Locked>
    <Floating>true</Floating>
    <Widgets>
        <Widget id="dt1" width="6" height="10" x="0" y="0" locked="false"
            badge="true" ref="tvc:widget:helium/TableWidget.xml" />

        <Widget ref="tvc:widget:helium/MaterialCategoryWidget.xml">
            <Id>materialcategory</Id>
            <Width minWidth="2" maxWidth="5">3</Width>
            <Height>5</Height>
            <X>6</X>
            <Y>0</Y>
            <Badge>true</Badge>
        </Widget>

        <Widget ref="tvc:widget:helium/RevisionLineWidget.xml">
            <Id>revision-line</Id>
            <Width>3</Width>
            <Height minHeight="3" maxHeight="7">5</Height>
            <X>9</X>
            <Y>0</Y>
        </Widget>

        <Widget ref="tvc:widget:helium/StateWidget.xml">
            <Id>state</Id>
            <Width minWidth="2" maxWidth="5">3</Width>
            <Height minHeight="3" maxHeight="7">5</Height>
            <X>6</X>
            <Y>5</Y>
        </Widget>

        <Widget ref="tvc:widget:helium/RevisionDonutWidget.xml">
            <Id>revision-donut</Id>
            <Width>3</Width>
            <Height>5</Height>
            <X>9</X>
            <Y>5</Y>
        </Widget>
    </Widgets>
</Dashboard>

1.7.4. Widget Customization

Just like for dashboards, an end user can do certain customizations on widget level. Exact customizations available will depend on the type of widget. For example, in a Table widget the end user can customize the pagination size, column visibilities, etc.

Customization on widget level is enabled by default, for dashboards where customization is enabled.

Customization actions

For the normal widget template, a Reset icon is available in the widget header. The user can reset widget level customizations from there. If you use your custom widget template, you can still use the JavaScript API .resetCustomizations(). After deleting a widget customization, the widget will refresh.

image
Figure 10. Resetting widget customizations

1.7.5. Open in Sidepanel

JavaScript API, App.page.sidepanel.openDashboard() can be used to open a dashboard in page’s sidepanel, e.g. App.page.sidepanel.openDashboard("tvc:dashboard:hex:engineering/PartInfoSidePanel.xml", "1.2.3.4");

This could be used for e.g. to quickly see contextual information about an object without navigating back and forth.

image
Figure 11. Dashboard in Sidepanel

JavaScript API, .updateWidgets() is added to Dashboard instance. This API can be used to reload related widgets within the dashboard with different context ids. If the widget is initially hidden, it’ll be made visible.

You need to have access to the dashboard instance to invoke this method. If you instead have access to Widget instance, see this

For an implementation example, refer PartDetailActions.xml Column and Menu definitions available as part of HEX distribution.

image
Figure 12. Load Related Widgets

1.7.7. Widget lock unlock icon

The lock unlock icons can be configured for two different scenarios as given below:

Widget lock and unlock icon reflecting the action available to user. For ex :

  • If widget is locked it would show unlock icon.

  • If widget is unlocked it would show lock icon.

This is the default behaviour.

Widget lock and unlock icon reflecting the current state of widget.For ex :

  • If widget is locked, show lock icon.

  • If widget is unlocked, show unlock icon.

This can be enabled globally as init param tvc.helium.widget.lock.showAlternateIcon = true

1.8. Widget

All widgets (DataTable, Form, Charts) or any custom widget as described in the widget tutorial, share the following configuration options.

1.8.1. Configuration

Name Description Example

Title

The title of the widget. Supports macros if a context object exists, e.g. ${oid}, ${name}, and ${type}.

<Title>Title of the widget</Title>

OnInit

Javascript function that creates the widget.

This is usually implemented in the specific widget definition, for instance the <DataTable> widget provides its own implementation.
<OnInit>
    App.custom.functionThatCreatesMyWidget
</OnInit>

OnInitOption

Additional options that is to be passed to the OnInit function.

<OnInitOption name="formConfigName"
    value="tvc:form:helium/Form.xml" />

PostRender

A javascript function that will be executed when the content of the widget has been rendered.

It is up to the widget implementation to execute the PostRender function after the rendering is complete.
<PostRender>
    App.custom.postRender
</PostRender>

HeaderActions

By providing a reference to a menu XML file, it is possible to add custom actions to the widget header.

<HeaderActions ref="tvc:menu:helium/MyHeaderActions.xml" />

ShowActionTooltip

Whether the header actions tooltip should be visible or not. Default value is true.

<ShowActionTooltip>false<ShowActionTooltip/>

Html

HTML that should be rendered inside of the widget container

<Html>
    <![CDATA[ <h1>This is html</h1>]]>
</Html>

Toolbar

Describes the toolbar of the widget. For more information, see the Toolbar chapter.

<Toolbar>
    <!-- toolbar definition -->
</Toolbar>

Sidepanel

Describes an optional sidepanel in the widget. For more information see the Sidepanel chapter

 <Sidepanel position="left" width="200">
    <!-- sidepanel definition -->
 </Sidepanel>
 ```

Access

Defines access rules.

Replace/Toggle widgets

To toggle/replace a widget with another (switching views) you can do the following.

  1. Create the initial widget as described in the Dashboard chapter.

  2. Also add the other widget (that you want to toggle to) in the same Dashboard but add the element: <Hidden>true</Hidden>. Make sure the X, Y, Width and Height elements have the same values as the initial widget.

    <ToggleWidget>
        <Label>Label for the command</Label>
        <FontIcon>he-some-font-icon</FontIcon>
        <To>the-id-of-the-widget-to-toggle-to</To>
        <Access>access-rules-for-this-action</Access>
    </ToggleWidget>

    The <To> element must point to the id of the widget to toggle to. To toggle back to the initial widget create the same command as above but change the <Id> to point to the initial widget. This means that the relationships will most likely be symmetrical in your configurations.

    For <Access> definition, see Access Control

1.8.2. Conditionally evaluate dataset on drilldown

In some cases, the user might want to evaluate a different dataset for a widget on a drilldown dashboard. This is possible by configuring the widget you want to evaluate with:

<OnInitOption name="evaluateWithDataSet" value="true" />

Example widget configuration:

<ChartWidget>
    <Title>Multi Series Stacked Bar Chart</Title>
    <OnInitOption name="evaluateWithDataSet" value="true" />
    <ChartConfig namespace="hex:engineering">EBOMMultiSeriesStackedBarChart.xml</ChartConfig>
</ChartWidget>

JavaScript API, .loadRelatedWidgets() is added to Widget instance. This API can be used to reload related widgets within the dashboard with different context ids. If any related widget is initially hidden, it’ll be made visible.

You need to have access to the widget instance to invoke this method. If you instead have access to Dashboard instance, see this

1.9. Widget Sidepanel

A sidepanel is a container element where additional content within a widget can be placed. It can be either any HTML content, or a menu containing commands. The visibility of this sidepanel container is toggled by clicking it.

Each widget supports defining a sidepanel which can be revealed (slided in) either from the left or the right side. When the widget is first loaded, the initial state of the sidepanel will be closed.

The <Sidepanel> element supports the position and width attribute. Valid values for position is "left" or "right". Valid value for width is a positive integer.

Currently widgets only supports one sidepanel each, either to the right or to the left.

The <Sidepanel> element supports the following child elements.

Name Description Example

Label

The label of the sidepanel. If omitted no label will be rendered. If the value is an existing i18n key internationalisation will be performed

<Label>Sidepanel</Label>

Html

Custom html to be rendered in the widget

<Html><![CDATA[
    <div>some html</div>
]]></Html>

Closable

Whether sidepanel will be closed when clicking inside the same widget. Default is false.

<Closable>false</Closable>

Toolbar

A Toolbar definition. It is encouraged to supply the toolbar definition with the vertical="true" attribute

If both a toolbar and a html element is provided only the toolbar will be visible.
<Toolbar vertical="true">
    ...
</Toolbar>

1.9.1. Javascript API

The sidepanel can be opened, closed and toggled via javascript using the following syntax:

var widget = App.page.getWidgetById('widget-id');
widget.openSidepanel() // opens sidepanel
widget.closeSidepanel() // close sidepanel
widget.toggleSidepanel() // toggles the sidepanel visibility state

1.9.2. Example

<Sidepanel width="100" position="left">
    <Label>Sidepanel</Label>
    <!--<Html><![CDATA[<div>test</div>]]></Html>-->
    <Toolbar vertical="true">
        <Command>
            <Label>Toggle Edit Mode</Label>
            <FontIcon>he-pencil</FontIcon>
            <OnClick>App.custom.toggleEditMode</OnClick>
            <OnClickParams>{"foo": "bar"}</OnClickParams>
        </Command>
    </Toolbar>
</Sidepanel>

Helium comes with basic search functionality, configurable in a number of ways. Search can be configured to appear in the global topbar by pointing out a search configuration file in Helium.xml: <Search>tvc:search:helium/TopBarSearch.xml</Search> This will render a magnifying glass icon on which you click to launch the search GUI overlay.

You can also choose to render an input field inside the topbar, so that you can type a query directly into it. The configuration is similar to that of the Topbar Icon <Search> command. A full example can be found in the TopBar chapter.

Please note that for topbar inline search, only <Search version="2"> search configuration is supported, and that you will initiate the search by either hitting enter key or clicking the icon.

image
Figure 13. Top Bar

1.10.1. Search

The <Search> format supports the following child elements.

Name Description Example

Limit

The maximum number of search results returned.

<Limit>100</Limit>

Types

Show only results of the listed types.

<Types>
	<Type>type_Part</Type>
	<Type>type_Document</Type>
</Types>

Selects

The statements listed within this element are fetched and returned to the browser for client-side use (for example, to show them in the search result template). NOTE: By default search result provide type, name, revision and description.

<Selects>
	<Select>current</Select>
	<Select><![CDATA[$<attribute[attribute_Originator]>]]></Select>
</Selects>

Where

A Where clause, following MQL syntax. Use %s to indicate where to inject the criteria entered by the user performing the search.

<Where>name ~~ '*%s*'</Where>

HitOnClick

Name of a JavaScript function to execute when clicking on a search result item. The argument passed will be the object ID.

<HitOnClick>App.routing.open</HitOnClick>

HitTemplate

Customize design of search result by either specifying a template formatting the layout of single search result. Currently it’s only possible to specify templates which are located within the helium/template folder.

<HitTemplate>search/result-hit-test</HitTemplate>

ResultRenderCallback

Customize complete search result. Great flexibility but requires custom implementation to handle onclick events, responsiveness etc.

<ResultRenderCallback>App.custom.renderSearchResult</ResultRenderCallback>

SearchProvider

Search Provider to be used for this search config. If none is specified global Search Provider will used as default.

Custom Search Provider should extend Helium class com.technia.helium.search.SearchProvider
<SearchProvider>com.acme.search.PartSearchProvider</SearchProvider>

1.10.2. Example

<?xml version="1.0" encoding="UTF-8"?>
<Search>
	<Limit>100</Limit>

	<!-- Restrict to only search object of specified types -->
	<Types>
		<Type>type_Part</Type>
		<Type>type_Document</Type>
	</Types>

	<!-- Fetch additional select statements which can be used for rendering -->
	<Selects>
		<Select>current</Select>
		<Select><![CDATA[$<attribute[attribute_Originator]>]]></Select>
	</Selects>

	<!-- Where clause. Use %s to indicate where to inject the criteria entered by the user -->
	<!-- <Where>name ~~ '*%s*'</Where> -->

	<!-- Javascript callback when clicking search hits -->
	<!-- <HitOnClick>App.custom.openSearchHit</HitOnClick> -->

	<!-- Customize design of search result by either specifying a template formatting the layout of single search result. Currently it's only possible to specify templates which are located within the helium/template folder. -->
	<!-- <HitTemplate>search/result-hit-test</HitTemplate> -->

	<!-- Customize complete search result. Great flexibility but requires custom implementation to handle onclick events, responsiveness etc -->
	<!-- <ResultRenderCallback>App.custom.renderSearchResult</ResultRenderCallback> -->
	<!-- Custom Search Provider for this search config, if none is specified global Search Provider will used -->
	<!-- <SearchProvider>com.acme.search.PartSearchProvider</SearchProvider> -->
</Search>

1.11. New Search Experience

1.11.1. Quick Search

The quick search allows users a way to easily find objects of interest. It can be used for various use cases, for example by clicking the magnifying glass in the topbar or when locating a person when editing a Part.

When the quick search is launched it opens as an overlay and the user enters a search term. The search result matching the term is presented and by clicking the search hits the user can open the corresponding object.

In more advanced use cases a search form, displayed on the left hand side, is used to further filter down the search result. The user can for instance specify that only Parts in state Released is of interest.

Quick search supports usage of Search Providers. This means that ENOVIA, EXALEAD or other data source can be used to find relevant information.

image
Figure 14. Quick Search
image
Figure 15. With Search Form
Configuration Format
To use this configuration format the version must be set to 2. This is done by setting the version attribute on the Search element to 2. Example: <Search version="2">

Quick search can be configured in two ways, by using specialized Search element or generic Command element.

Search has predefined configurations with default icon, label and javascript callback function to load search.

Sample configuration using Search

<Search version="2">tvc:search:hex:common/TopBarSearchV2.xml</Search>
Using Command

Command gives flexibility of define icon, label and javascript callback function within the URL element.

Sample configuration using Command

<Command>
    <Label>Search</Label>
    <FontIcon>ti-f ti-finder-f</FontIcon>
    <URL href="javascript:App.searchV2.startSearch({options: {'config': 'tvc:search:hex:common/TopBarSearchV2.xml'}});" />
</Command>

The quick search configuration files are placed in the folder search.

The root element of the configuration is <Search> and the following child elements are supported:

Name Description Example

Limit

The maximum number of search results returned.

<Limit>100</Limit>

upperSearchLimitValue

The maximum number of search results allowed to be displayed.

upperSearchLimitValue can be used to limit the maximum search results. Default value is set as 1000. Limit can be only between 1 and the upperSearchLimitValue.
For Index based searches like Exalead, search limit becomes page size and hence this upper search limit will become maximum page size.
<Settings>
	<Setting name="upperSearchLimitValue" value="1000" />
</Settings>

DataFields

The data to include for the search result. For example, type, name, revision and current state.

<DataFields>
    <DataField>type</DataField>
    <DataField>name</DataField>
    <DataField>${attribute[attribute_MaterialCategory]}</DataField>
</DataFields>

Sections

The search result is divided into sections. For example, parts is displayed in one section, documents in another and so on.

See Sections for more details.

SearchForm

Search form which allows the user to further filter down the search result.

See Search Form for more details.

<SearchForm ref="tvc:searchformv2:acme/PartConnectSearchForm.xml" />

InitialHitsCount

The number of hits to display in each section. A "Show more" link is supplied to view more hits.

<InitialHitsCount>15</InitialHitsCount>

ShowMoreHitsCount

The number of additional hits to add to the result when "show more" is clicked.

<ShowMoreHitsCount>50</ShowMoreHitsCount>

SearchOnCriteriaUpdate

Controls if the search is submitted when the search criteria is updated.

For example, after the user has selected state "Released" in the search form or search for "00230" in the term field a search is submitted and the search result is displayed.

This setting is useful when using indexing engine as search provider. The search is throttled to 400ms.

<SearchOnCriteriaUpdate>true</SearchOnCriteriaUpdate>

Settings

Additional settings for the search. These settings are accessible in SearchProvider and can be used while performing search.

<Settings>
    <Setting name="name-of-setting" value="the-value" />
    <Setting name="another-setting" value="another-value" />
</Settings>

Server

Triggers executed server-side at different steps during the life-cycle of a search operation.

See Server-Side Triggers for more details

<Server
    preSearch="com.acme.MyPreSearchHandler"
    postSearch="com.acme.MyPostSearchHandler" />

Client

Callbacks triggered on the client at specific points.

See Client-Side Callbacks for more details.

Example how to register a callback executed when the search is rendered and ready:

<Client ready="MyApp.globalSearchReady" />

UIs

It defines UI elements for rendering search result in a section. See Section UIs for more details.

<UIs>
    <UI id="id0" default="true">
        <Type>tile</Type>
        <TileHitTemplate>helium/templates/search/v2/primaryimage-result-hit</TileHitTemplate>
        <ResultTemplate>helium/templates/search/v2/primaryimage-result</ResultTemplate>
        <Icon>ti-f ti-menu-f</Icon>
        <Settings>
            <Setting name="title" value="Primary Image" />
        </Settings>
    </UI>
</UIs>

OpenOnLoad

Controls if the search panel should be opened by default on load. Default value is false.

When user opens or closes search panel, it will be remembered. Based on last user action, search panel will either be opened or closed.
<OpenOnLoad>true</OpenOnLoad>

Specify the search provider to use in the attribute provider on the <Search> element. See Search Providers for more details and a list of available providers. Example configuring using the EXALEAD search provider :

<Search provider="exalead" />
The search provider’s callsign name is used when selecting which provider to use (instead of the qualified name of the java class)
The ENOVIA search provider is used by default
Sections

Search results can be rendered in sections. For example sections can be used to divide search result based on type, parts is displayed in one section, documents in another and so on. Different sections can have different views to show different set of information/attributes in different format.

The root element of the configuration is <Sections> and following child elements are supported by built-in SectionProvider:

Name Description Example

Section

Root element for defining a Section. See [Section] for detailed configuration.

<Sections>
    <Section>
        <Filter>
            <DataField>attribute[Material Category]</DataField>
            <Value>Rubber</Value>
        </Filter>
        <Label>acme.search.section.rubberparts</Label>
    </Section>
</Sections>

FallbackSection

Root element for fallback section. When a search result hit matches none of the defined sections, it is put into fallback section. See Built-in Section Provider for detailed configuration.

<Sections>
    <FallbackSection>
        <Label>acme.search.section.otherparts</Label>
    </FallbackSection>
</Sections>
FallbackSection is optional
image
Figure 16. Sections

See Custom Section Provider for details on custom section provider.

Built-in Section Provider

Built in SectionProvider supports configuration of multiple sections. Each section defines a filter condition, which is evaluated against each search result hit and if hit matches filter condition, hit is kept in this section. Section also support different UIs or views for showing search result. For example it can used to show different attributes for parts and documents.

Name Description Example

Filter

Filter is condition based on which search result will be sectionized. It must contains a DataField against which search hit will be evaluated and a Value that will be matched.

<Filter>
    <DataField>attribute[Material Category]</DataField>
    <Value>Rubber</Value>
</Filter>
Not applicable on FallbackSection.

Label

Label can be used to specify title.

<Label>acme.search.section.softwareparts</Label>

UIs

Each section can have multiple UIs elements to render search result. See Section UIs for more details.

<UI id="id0" default="true">
    <Type>tile</Type>
    <TileHitTemplate>helium/templates/search/v2/primaryimage-result-hit</TileHitTemplate>
    <ResultTemplate>helium/templates/search/v2/primaryimage-result</ResultTemplate>
    <Icon>ti-f ti-menu-f</Icon>
    <Settings>
        <Setting name="title" value="Primary Image" />
    </Settings>
</UI>
Section UIs

SectionUIs or UIs are used to render search result under each section. Multiple UIs can be configured for a section and user can navigate from one UI to another. It is possible to configure UIs in Search and refer into section. SectionUI is referred using ìd attribute on elemenet UI. It is possible to refer and override SectionUI configuration in Section. The root element of the configuration is <UIs> containing multiple <UI> and the following child elements are supported in <UI>:

Name Description Example

Type

Type of view. tile is default.tile and table are the only views supported currently.

Selected view will persist for the user.
<Type>tile</Type>

Or

<Type>table</Type>

Icon

Icon of UI to be shown for selecting UI.

<Icon>ti-f ti-table-f</Icon>

ResultTemplate

Template for showing search results in section. For built-in template see Built-in Tile Templates

<ResultTemplate>helium/templates/search/v2/primaryimage-result</ResultTemplate>

TileHitTemplate

Template to rendering each search hit and applies only to tile view. For built-in template see Built-in Tile Templates

<TileHitTemplate>helium/templates/search/v2/row-result-hit</TileHitTemplate>

Table

Table configuration for adding columns and applies only to table view.

<Table>
    <Column>
        <DataField>type</DataField>
        <Label>Type</Label>
    </Column>
</Table>

Settings

Additional settings.

<Settings>
    <Setting name="title" value="Single Row Result" />
</Settings>

Following attribute can be defined on root element SectionUI.

Name Description Example

id

Defines id of SectionUI. This is useful when SectionUIs are defined in Search and can be referred in Section using id.

<UI id="id1">
    .
    .
</UI>

default

In context of Search, it defines whether SectionUI should act as default for when no SectionUI is defined in Section. And in context of Section, it defines whether SectionUI should be rendered by default.

<UI id="id0" default="true">
    .
    .
</UI>
Context Menu

Context menu can be configured to show actions on search result tiles. Context menu is defined inside a Section by using element ContextMenu with reference to menu using attribute ref.

<Section>
    .
    .
    .
    <ContextMenu ref="tvc:menu:acme:common/SearchActions.xml"/>
</Section>
Context menu is not applicable for table view and sub menus are not supported in a context menu.

Following menu elements are utilized on context menu.

Name Description Example

FontIcon

Icon to be showed for context menu.

<FontIcon>ti-f ti-menu-f</FontIcon>

Command

Command in the context menu.

<Menu>
	<Command>
		<Label>Open History</Label>
		<FontIcon>ti-f ti-menu-f</FontIcon>
		<AccessExpression>context.user.assignment === 'Design Engineer'</AccessExpression>
		<Setting name="OnClick">App.hex.openObject</Setting>
		<Setting name="OnClickParams">{
			"options": {
				"tab": "#history"
			}
		}</Setting>
	</Command>
</Menu>

Following Command settings are utilized in rendering of context menu.

Setting Name Description Example

OnClick

Javascript function to be called on click of command

<Command>
    .
    .
	<Setting name="OnClick">App.hex.openObject</Setting>
</Command>

OnClickParams

Additional parameters to passed into command on click.

<Menu>
	<Command>
		.
		.
		<Setting name="OnClickParams">{
			"options": {
				"tab": "#history"
			}
		}</Setting>
	</Command>
</Menu>

Sample context menu defined in a section -

<Section>
    .
    .
    .
    <ContextMenu ref="tvc:menu:acme:common/SearchActions.xml"/>
</Section>

Sample context menu definition -

<Menu>
	<Command>
		<Label>Open History</Label>
		<FontIcon>ti-f ti-menu-f</FontIcon>
		<Setting name="OnClick">App.acme.openObject</Setting>
		<Setting name="OnClickParams">{
			"options": {
				"tab": "#history"
			}
		}</Setting>
	</Command>
	<Command>
		<Label>Open Charts</Label>
		<Href>javascript:App.hex.openObject</Href>
		<FontIcon>ti-f ti-piechart-f</FontIcon>
		<Setting name="OnClickParams">{
			"options": {
				"tab": "#charts"
			}
		}</Setting>
	</Command>
		<Command>
		<Label>Open Lifecycle</Label>
		<FontIcon>ti-f ti-lifecycle-f</FontIcon>
		<Setting name="OnClick">App.acme.openObject</Setting>
		<Setting name="OnClickParams">{
			"options": {
				"tab": "#lifecycle"
			}
		}</Setting>
	</Command>
	<Command>
		<Label>Promote</Label>
		<FontIcon>ti-f ti-promote-f</FontIcon>
		<Setting name="OnClick">App.acme.promoteObject</Setting>
	</Command>
	<Command>
		<Label>Demote</Label>
		<FontIcon>ti-f ti-demote-f</FontIcon>
		<AccessExpression>context.user === 'admin_platform'</AccessExpression>
		<Setting name="OnClick">App.acme.demoteObject</Setting>
	</Command>
	<Setting name="showOnHover" value="false"/>
</Menu>
image
Figure 17. Context Menu
Custom Section Provider

Custom section provider can be implemented to sectionize search result. It can be specified using attribute className on element Sections.

Interface to implement:

com.technia.tvc.search.api.section.SectionProvider

Example configuration:

<Search provider="enovia" version="2">
    .
    .
    <Sections className="com.acme.MySectionProvider" />
</Search>
Built-in Tile Templates

Template are used to display search result hit in tile mode. Following are the built-in tile hit templates:

Single Row

Single tile takes up the whole width of section. Useful for displaying document with large description text. Tile also shows primary image of the object in left side. It also displays Type, Name, Revision, Description, State and Last Modified of the object.

Result Template path: helium/templates/search/v2/row-result

Hit Template path: helium/templates/search/v2/row-result-hit

image
Figure 18. Single Row
Primary Image

Three tiles are displayed in each row. Tile also shows primary image of the object in left side. It also displays Type, Name, Revision and Description of the object.

Result Template path: helium/templates/search/v2/primaryimage-result

Hit Template path: helium/templates/search/v2/primaryimage-result-hit

Three Tiles

Three tiles are displayed in each row. Tile also shows count if present in search hit data on like a bubble of right top corner. It also displays Type, Name, Revision of the object along with all the additional data present in the search result hit.

Result Template path: helium/templates/search/v2/result

Hit Template path: helium/templates/search/v2/result-hit

image
Figure 19. Three Tiles
Table view

Table takes up the whole width of section. Useful for displaying data in tabular form.

Result Template path: helium/templates/search/v2/table-result

image
Figure 20. Table View
Server-Side Triggers

Server-side triggers are used to accomplish advanced use cases. For example a presearch trigger can be used to validate the search criteria and a postsearch trigger can be used to ensure that the user has access to view all the search hits.

preSearch

Executed before the search is executed.

Interface to implement:

com.technia.tvc.search.api.triggers.PreSearchTrigger

Example configuration:

<Server preSearch="com.acme.MyPreSearchTrigger" />
postSearch

Executed after the search has been executed.

Interface to implement:

com.technia.tvc.search.api.triggers.PostSearchTrigger

Example configuration:

<Server postSearch="com.acme.MyPostSearchTrigger" />
Client-Side Callbacks
ready

Callback function when search is ready. Example configuration:

<Client ready="App.custom.searchReady"/>
onHitClick

Callback function when search result hit tile is clicked. By default search window is closed and object is opened. Example configuration:

<Client onHitClick="App.custom.openObject"/>
onRenderResult

Callback function to create search result renderer object. This function should return javascript object implementing method render, which will be responsible for rendering search result. SectionRenderer is built in implementation for rendering search result in sections. Example configuration:

<Client onRenderResult="App.custon.createSectionRenderer"/>
Javascript API

Methods

Method Description

open

Opens the search

close

Closes the search

isOpen

Is the search open

search

Performs a search

getQuery

Gets the search criteria

searchPanel

Get API for searchpanel, if any available

result

Get API for result

on

Register to an event

off

Deregisters an event

Events

Event Name Description

open

Called after the quick search overlay is opened

close

Called after the quick search overlay is closed

preSearch

Called before the search is executed

postSearch

Called after the search is executed

destroy

Called when component is destroyed

Search Panel

Methods

Method Description

open

Opens the search panel

close

Closes the search panel

isOpen

Is the search panel open

toggleVisibility

Toggles the search panel

getSearchForm

Returns UIP search form instance

destroy

destroys the search panel and performs clean up

searchPanel

Get API for searchpanel, if any available

updateSearchFormFields

Updates the search form fields

Result

Result is responsible for rendering search result. Result calls render method on resultRenderer for rendering search result.

Methods

Method Description

clear

Clears the search result

isRendered

Return whether results are rendered

on

Register to an event

off

Deregister to an event

destroy

Destroys the result element

resultRenderer

returns resultRenderer object associated with this result object.

Events

Event Name Description

renderBefore

Called before rendering search result.

render

Called when search result is about to be rendered. Search query and search result is passed as arguments.

renderAfter

Called after rendering search result.

destroy

Called when result is destroyed.

Section Renderer

Section renderer is built-in and default result renderer, which renders result in sections

Methods

Method Description

clear

Clears the search result

getSections

Return list of sections

render

renders result sections. This called from result when search result is received.

destroy

Destroys the result component.

Example Configuration
<?xml version="1.0" encoding="UTF-8"?>
<Search provider="enovia" version="2">
    <Limit>200</Limit>
    <SearchForm
        ref="tvc:searchformv2:helium/TopBarSearchForm.xml" />
    <Sections>
        <Section>
            <Filter>
                <DataField>attribute[Material Category]</DataField>
                <Value>Rubber</Value>
            </Filter>
            <Label>Rubber</Label>
            <UIs>
                <UI id="id0" />
                <UI id="id1" />
                <UI id="id2" default="true"/>
            </UIs>
        </Section>
        <Section>
            <Filter>
                <DataField>attribute[Material Category]</DataField>
                <Value>Metal</Value>
            </Filter>
            <Label>Metal</Label>
            <UIs>
                <UI id="id1" default="true"/>
                <UI id="id2" />
                <UI id="id3" />
            </UIs>
        </Section>
        <Section>
            <Filter>
                <DataField>attribute[Material Category]</DataField>
                <Value>Concrete</Value>
            </Filter>
            <Label>Concrete</Label>
        </Section>
        <FallbackSection>
            <Label>searchv2.section.defaultTitle</Label>
        </FallbackSection>
    </Sections>
    <UIs>
        <UI id="id0" default="true">
            <Type>tile</Type>
            <TileHitTemplate>helium/templates/search/v2/primaryimage-result-hit</TileHitTemplate>
            <ResultTemplate>helium/templates/search/v2/primaryimage-result</ResultTemplate>
            <Icon>ti-f ti-menu-f</Icon>
            <Settings>
                <Setting name="title" value="Primary Image" />
            </Settings>
        </UI>
        <UI id="id1">
            <Type>tile</Type>
            <TileHitTemplate>helium/templates/search/v2/row-result-hit</TileHitTemplate>
            <ResultTemplate>helium/templates/search/v2/row-result</ResultTemplate>
            <Icon>ti-f ti-table-f</Icon>
            <Settings>
                <Setting name="title" value="Single Row Result" />
            </Settings>
        </UI>
        <UI id="id2">
            <Type>tile</Type>
            <TileHitTemplate>helium/templates/search/v2/result-hit</TileHitTemplate>
            <ResultTemplate>helium/templates/search/v2/result</ResultTemplate>
            <Icon>ti-f ti-menu2-f</Icon>
            <Settings>
                <Setting name="title" value="Three Tile Result" />
            </Settings>
        </UI>
        <UI id="id3">
            <Type>tile</Type>
            <TileHitTemplate>helium/templates/search/v2/result-hit</TileHitTemplate>
            <ResultTemplate>helium/templates/search/v2/result</ResultTemplate>
            <Icon>ti-f ti-menu2-f</Icon>
        </UI>
    </UIs>
    <DataFields>
        <DataField>type</DataField>
        <DataField>name</DataField>
        <DataField>revision</DataField>
        <DataField>description</DataField>
        <DataField>primaryimage</DataField>
        <DataField>${attribute[attribute_EndItem]}</DataField>
    </DataFields>
    <Settings>
        <Setting name="termWhere" value="name ~~ '*%s*' OR description ~~ '*%s*' OR current ~~ '*%s*'" />
    </Settings>
    <Client ready="App.custom.searchReady"
        onRenderResult="App.searchV2.createSectionRenderer" />
</Search>

1.11.2. Search Side Panel

With search side panel, search can be configured within a page. Similar to quick search, search side panel allows users a way to easily find objects of interest related to context objects and load search result into page dashboard. When configured search side panel opens on left side with a search form.

When search is performed dashboards in the page can be reloaded with search result, it is possible to configure which dashboards should be reloaded. It may desired that only one dashboard is reloaded with search result and rest are left unaffected. It is also possible to customize this behaviour using javascript callback function and take complete control on what should happen when search is performed, see Client-Side Callbacks for more details.

Like quick search, search panel supports usage of Search Providers. This means that ENOVIA, EXALEAD or other data source can be used to find relevant information.

image
Figure 21. Search Side Panel
Configuration Format

SearchPanel configuration files are placed in folder searchpanel. The root element of the configuration file is <SearchPanel>.

Name Description Example

Limit

The maximum number of search results to be returned.

<Limit>100</Limit>

DataFields

The data to include for the search result. For example, type, name, revision and current state.

<DataFields>
    <DataField>type</DataField>
    <DataField>name</DataField>
    <DataField>${attribute[attribute_MaterialCategory]}</DataField>
</DataFields>

SearchOnCriteriaUpdate

Controls if the search is submitted when the search criteria is updated.

For example, after the user has selected state "Released" in the search form or search for "00230" in the term field a search is submitted and the search result is displayed.

This setting is useful when using indexing engine as search provider. The search is throttled to 400ms.

<SearchOnCriteriaUpdate>true</SearchOnCriteriaUpdate>

SearchIcon

Search Icon for collapsed search panel.

<SearchIcon>find icon</SearchIcon>

SearchTitle

Title for collapsed search panel

<SearchTitle>Search Sidepanel</SearchTitle>

ResultTitle

Title for drilldown of search results

<ResultTitle>Drilldown Search Results</ResultTitle>

Settings

Additional settings for the search. These settings are accessible in SearchProvider and can be used while performing search.

<Settings>
    <Setting name="name-of-setting" value="the-value" />
    <Setting name="another-setting" value="another-value" />
</Settings>

Server

Triggers executed server-side at different steps during the life-cycle of a search operation.

See Server-Side Triggers for more details

<Server
    preSearch="com.acme.MyPreSearchHandler"
    postSearch="com.acme.MyPostSearchHandler" />

Client

Callbacks triggered on the client at specific points.

See Client-Side Callbacks for more details.

Example how to register a callback executed when the search is rendered and ready:

<Client ready="MyApp.searchPanelReady" />

HomePage

Defines page that should be loaded in background, when search is launched via direct or exported URL. See Export Search for more details.

<HomePage>
    <Page namespace="helium" name="DefaultPage.xml"/>
</HomePage>
Client-Side Callbacks
ready

Callback function when search panel is ready. Example configuration:

<Client ready="App.custom.searchPanelReady"/>
js

Callback function to render search panel. This allows user to take complete control over search panel rendering and behaviour. This function should return javascript object implementing method render. Default function is App.searchV2.defaultSearchPanel. Example configuration:

<Client js="App.custom.mySearchPanel"/>
onResult

Callback function to handle search result. Default functon is App.searchV2.defaultOnSearchResult, which reloads dashboards with search result objects. Example configuration:

<Client onResult="App.custon.onSearchResult"/>
Configuration In Page

Search panel is configured in page using element <SearchPanel> with reference to search panel configuration resource using attribute ref. See Configuration Format for search panel configuration. Example -

<Page>
    .
    .
    .
	<SearchPanel ref="tvc:searchpanel:acem:common/PSearchPanel.xml">
	<OnSearchResult>
    	<ReloadDashboards>
    		<Dashboard ns="hex:engineering" name="PartFamilyParts.xml" />
    	</ReloadDashboards>
	</OnSearchResult>
	<SearchOnLoad>true</SearchOnLoad>
	<OpenOnLoad>true</OpenOnLoad>
    </SearchPanel>
</Page>

It is possible to use same searchpanel configuration as reference in different page configurations. Following configurations can be done in a searchpanel at page level:

Name Description Default Example

OpenOnLoad

Whether to open search panel when page is loaded.

true

<SearchPanel ref="tvc:searchpanel:hex:common/PartFamilySearchPanel.xml">
	<OpenOnLoad>true</OpenOnLoad>
</SearchPanel>

SearchOnLoad

Whether to perform search when page is loaded.

false

<SearchPanel ref="tvc:searchpanel:hex:common/PartFamilySearchPanel.xml">
	<SearchOnLoad>true</SearchOnLoad>
</SearchPanel>

OnSearchResult

Defines what should happen on load of search result. See On Search Result

<OnSearchResult>
	<ReloadDashboards>
		<Dashboard ns="acme:common" name="AcmePartDashboard.xml" />
		<Dashboard ns="acme:engineering" name="AcmePartFamilyDashboard.xml" />
	</ReloadDashboards>
</OnSearchResult>
On Search Result

Defines what should happen on load of search result. It supports both client side and server side loading of search result. On search result can be configured in search panel using element <OnSearchResult>. See Search Panel Configuration for search panel configuration.

The search result can be loaded client side or server side. When loaded client side, search result are sent to the client and loaded back into configured dashboards as context objects using dashboard drilldown. When loaded server side, search results are directly loaded in the configured widget at the server side. This also enables page wise search if index-based search provider is present.

Following sub elements can be defined under <OnSearchResult>:

Name Description Default Example

ReloadDashboards

Dashboards that should be reloaded with search results when a search is performed. It is possible to configure more than one dashboard for reloading.

Dashboard should be part of page configuration.
<OnSearchResult>
	<ReloadDashboards>
		<Dashboard ns="acme:common" name="AcmePartDashboard.xml" />
		<Dashboard ns="acme:engineering" name="AcmePartFamilyDashboard.xml" />
	</ReloadDashboards>
	<SearchOnLoad>true</SearchOnLoad>
</OnSearchResult>

LoadServerSide

Sub element of <ReloadDashboards>. Defines whether search result should be loaded server side.

false

<ReloadDashboards>
	<LoadServerSide>true</LoadServerSide>
</ReloadDashboards>

Dashboard

Sub element of <ReloadDashboards>. Defines dashboard or dashboard widgets that should be loaded with search result.

When no dashboard is defined under <ReloadDashboards> all the dashboards are loaded with search result.
<ReloadDashboards>
	<Dashboard ns="acme:common" name="AcmePartDashboard.xml" />
</ReloadDashboards>

WidgetId

Sub element of <Dashboard>. Defines dashboard widget ids that should be loaded with the search result. Since widget id is used to identify the widget at run time, if widget with configured WidgetId is not present in the dashboard, an error will be thrown. Toggling of widget feature is not supported.

When no widget id is defined under <Dashboard> all the widgets are loaded with search result.
<ReloadDashboards>
	<Dashboard ns="acme:common" name="AcmePartDashboard.xml">
	    <WidgetId>myParts</WidgetId>
	</Dashboard>
</ReloadDashboards>
Paginated Search Result

Index based search providers, like Exalead may provide a capability to load search result page wise. New search can leverage this capability of index based search providers and search result pages can be retrieved as user navigates through pages on table widget.

When client side loading in enabled, search results are loaded into dashboard as drilldown feature and dashboard will reload to reflect new context objects. In contrast, when server side loading is enabled, search results are directly added into table widget bean at server side. As user navigates through pages, search provider is called to fetch result for current page.

Only one table widget can be enabled for loading search result at the server side.
Paginated Search Result
SearchBasedLoader

Table widget should have <SearchBasedLoader> as data loader for paginated search result and server side search result loading enabled in page configuration. It is also possible to have a custom SearchBasedLoader by using attribute className on tag <SearchBasedLoader> as shown below.

<SearchBasedLoader className="com.acme.AcmeSearchLoader"/>

Interface the Java class needs to implement:

com.technia.tvc.structurebrowser.search.loader.SearchBasedTableLoader

Example configuraton

In below example, searchpanel is defined in the page. On search, the result should be loaded at server-side into widget myParts present within the dashboard AcmePartDashboard.xml in acme:common namespace. It is possible to configure multiple dashboards and multiple widgets per dashboard, however, that will result in each individual widget performing search and loading itself separately. The most common use case will be to have a single widget configured for loading the search result.

Page configuration on which search panel should be present.

<Page>
...
    <SearchPanel ref="tvc:searchpanel:acme:common/AcmePartSearchPanel.xml">
    ...
        <ReloadDashboards>
        	<Dashboard ns="acme:common" name="AcmePartDashboard.xml">
        	    <WidgetId>myParts</WidgetId>
        	</Dashboard>
        </ReloadDashboards>
    </SearchPanel>
</Page>

See On Search Result for configuration details.

TableConfig which will be used to display search result should have <SearchBasedLoader> as DataLoader. SearchBasedLoader ensures that search results are loaded at server side and on page navigation, a new search is performed to retrieve result for the changed page.

<TableConfig>
	<Title></Title>
	<DataLoader>
		<SearchBasedLoader/>
	</DataLoader>
	<Table namespace="acme:common">AcmeParts.xml</Table>
	<DisplayMode>flat</DisplayMode>
	<RowSelect>multi</RowSelect>
	<Pagination size="15" disabled="false" />
	<ClientSideProcessing enabled="false" threshold="10000" />
</TableConfig>

SearchBasedLoader can be implemented for non-indexed search by setting attribute indexedSearch to false. The default value is true.

Example Config:

<TableConfig>
	<Title></Title>
	<DataLoader>
		<SearchBasedLoader indexedSearch="false"/>
	</DataLoader>
    ...
</TableConfig>
Javascript API

Methods

Method Description

open

Opens the search panel

close

Closes the search panel

isOpen

Is the search panel open

search

Performs a search

getPage

Returns the context page object

getOptions

Returns the options this search instance

getQuery

Gets the search criteria

searchPanel

Get API for searchpanel

destroy

Destroys and cleans up the search instance

on

Register to an event

off

Deregister to an event

Events

Event Name Description

ready

Called after search panel is ready

open

Called after the quick search overlay is opened

close

Called after the quick search overlay is closed

search

Called before the search is executed. Query is passed as argument.

result

Called after the search is executed. Search result is passed as argument.

destroy

Called when component is destroyed

Example Configuration

Page

<?xml version="1.0" encoding="UTF-8"?>
<Page>
	<Title>${TYPE}, ${NAME}:${REVISION}</Title>
	<Dashboard namespace="hex:engineering" name="PartFamilyTopPanel.xml"/>
	<Tabs>
		<Settings>
			<Theme>material</Theme>
			<IconTheme>material</IconTheme>
			<Orientation>horizontal</Orientation>
			<TabDrop>true</TabDrop>
			<UserRearrange>true</UserRearrange>
			<UserOrientationSwitch>true</UserOrientationSwitch>
			<UserHide>true</UserHide>
		</Settings>
		<Tab id="Parts">
			<Label>Parts</Label>
			<Dashboard ns="hex:engineering" name="PartFamilyParts.xml" />
		</Tab>
		<Tab id="history">
			<Label>History</Label>
			<Dashboard namespace="hex:common" name="History.xml" />
			<IconClass>ti-c ti-large ti-history2</IconClass>
		</Tab>
		<Tab id="lifecycle">
			<Label>Lifecycle</Label>
			<Dashboard namespace="hex:common" name="Lifecycle.xml" />
			<IconClass>purple exchange alternate icon</IconClass>
		</Tab>
	</Tabs>
	<SearchPanel ref="tvc:searchpanel:hex:common/PartFamilySearchPanel.xml">
	    <OnSearchResult>
    		<ReloadDashboards>
    			<Dashboard ns="hex:engineering" name="PartFamilyParts.xml">
    			    <Widget id="myParts"/>
    			</Dashboard>
    		</ReloadDashboards>
		</OnSearchResult>
		<SearchOnLoad>true</SearchOnLoad>
	</SearchPanel>
</Page>

Search Panel

<?xml version="1.0" encoding="UTF-8"?>
<SearchPanel provider="enovia">
    <Limit>500</Limit>
    <SearchIcon>icon find</SearchIcon>
    <SearchTitle>Part Family Search</SearchTitle>
    <ResultTitle>Part Family Search Results</ResultTitle>
    <SearchForm
        ref="tvc:searchformv2:hex:common/PartFamilySearchForm.xml"/>
    <DataFields>
        <DataField>type</DataField>
        <DataField>name</DataField>
        <DataField>revision</DataField>
        <DataField>description</DataField>
        <DataField>modified</DataField>
        <DataField>primaryimage</DataField>
    </DataFields>
    <Client ready='App.hex.partFamilySearchReady'></Client>
</SearchPanel>
Apply filter on structure node expand

The search side panel is used to load objects in the table widget and it might be needed to apply the same search criteria on expanding the node. For example, once the user performs a search to load parts specific to RDO, it might be needed that on expanding part only parts belonging to that RDO should be shown. This can be achieved by keeping one on one mapping between columns in the table and search field.

This feature can be enabled at table configuration level by using below setting in table config:

<ApplySearchFilterOnExpand>true</ApplySearchFilterOnExpand>

<TableConfig>
...
    <ApplySearchFilterOnExpand>true</ApplySearchFilterOnExpand>
</TableConfig>

Additional setting is needed on searchform field to indicate the field should be considered for applying filter on expanded node.

Setting Name Description Example

applyOnTableExpand

Whether the field should be considered for applying filter on expanded node

<SearchForm>
    ...
    <Fields>
        ...
        <Field>
            ...
            <Setting name="applyOnTableExpand" value="true"/>
        </Field>
    </Fields>
</SearchForm>

tableExpandKey

Special case when field DataField of search form field cannot be applied on table expand as column expression is different. For example search form field is attribute[Weight] and column expression is attribute[Weight].dbvalue. In this case setting tableExpandKey can be used.

<SearchForm>
    ...
    <Fields>
        ...
        <Field>
            ...
            <Setting name="applyOnTableExpand" value="true"/>
            <Setting name="tableExpandKey" value="attribute[Weight].dbvalue"/>
        </Field>
    </Fields>
</SearchForm>

It is mandatory that search form field DataField or setting tableExpandKey should match exacty with table column expression. See example below:

Search feld for Material Category

<Field attribute="attribute_MaterialCategory"
	id="material_category" sectionId="others">
	<Label>Material Category</Label>
	<DataField>attribute[Material Category]</DataField>
	<Values attribute="attribute_MaterialCategory" />
	<Settings>
		<Setting name="showFilter" value="true" />
		<Setting name="showRangeAmount" value="10" />
		<Setting name="applyOnTableExpand" value="true" />
	</Settings>
</Field>

Table column for Material Category

<Column>
	<Name>Material Category</Name>
	<Expression>attribute[Material Category]</Expression>
	<Label>emxFramework.Attribute.Material_Category</Label>
	<RegisteredSuite>Framework</RegisteredSuite>
	<AllowShowMore>TRUE</AllowShowMore>
	<Editable>TRUE</Editable>
	<InputType>combobox</InputType>
	<SortType>string</SortType>
</Column>
This feature works at client side without additional server call to reduce performance impact, therefore this feature is limited to direct text match and will not work with Revision and Type field.

There is a workaround for type field by adding an additional hidden column with kindof and mapping it to searchform type field.

Kindof table column

<Column>
	<Name>KindOf</Name>
	<Expression>type.kindof</Expression>
	<Label>KindOf</Label>
	<Editable>false</Editable>
	<Visible>false</Visible>
</Column>

Searchform field

<TypeField id="type" sectionId="basic">
	<Values>
		<Value value="Part" default="true" />
	</Values>
	<SearchableTypes>
		<Type>type_Part</Type>
		<Type>type_DOCUMENTS</Type>
	</SearchableTypes>
	<Tooltip>
		<Title>customer.search.type.tooltip.title</Title>
		<Content>customer.search.type.tooltip.content</Content>
	</Tooltip>
	<Settings>
		<Setting name="casesensitive" value="true" />
		<Setting name="applyOnTableExpand" value="true" />
		<Setting name="tableExpandKey" value="type.kindof" />
	</Settings>
</TypeField>
Validations
Search Limit

Validations are in place for search limit to ensure that search limit value must be non-empty, non-negative, numeric value and between 1 & the upper search limit value.

image
Figure 22. search limit validation

1.11.3. Search Form

Form Configuration Format

The searchform configuration files are placed in the folder searchformv2.

The root element of the configuration file is <SearchForm> and the following child elements are supported:

Name Description Example

Title

Title of the search Form. Displayed above the fields.

<Title>Part Search</Title>

Fields

Available fields in the search form.

See Field Configuration Format for details on how to configure each field.

<Fields>
    <Field>
        <Label>Name</Label>
        <DataField>name</DataField>
    </Field>
</Fields>

Sections

Group fields into collapsible sections in the search form.

See Section Configuration Format for details on how to configure a section.

<Sections>
	<Section id="basic">
		<Label>Basic</Label>
		<Tooltip>
			<Title>Basic Fields</Title>
			<Content>This is a section for basic fields.</Content>
		</Tooltip>
		<Expanded>true</Expanded>
	</Section>
</Sections>

Toolbar

Add custom toolbar to include commands and menus in the search form.

See Toolbar Configuration Format for details on how to configure a section.

<Toolbar>
    <Command ref="tvc:command:helium/mail.xml" />
    <Command ref="tvc:command:hex:common/export.xml" />
    <SaveSearch>
        <Label>save</Label>
        <FontIcon>ti-f ti-save-f</FontIcon>
        <Alt>Save Search</Alt>
    </SaveSearch>
    <LoadSearch>
        <Label>load</Label>
        <FontIcon>ti-f ti-menu-f</FontIcon>
        <Alt>Load Search</Alt>
    </LoadSearch>
    <Menu ref="tvc:menu:helium/mymenu.xml" />
</Toolbar>

OnCreate

Trigger executed when the search form has been created. Useful to manipulate the search form, e.g. updating field values or changing order of fields, before it’s sent to the client.

Specify the Java class name containing the custom logic using the attribute className. Interface the Java class needs to implement:

com.technia.tvc.search.searchform.OnCreateSearchForm
<OnCreate className="com.acme.SearchFormEvents" />
Field Configuration Format

Field can be configured inline within a searchform or it can be configured in a separate file. The field configuration files are placed in the folder searchformfield. If configured in a separate file, it can be referred within searchform using attribute ref as below -

<Fields>
    <Field ref="tvc:searchformfield:acme:common/Name.xml"/>
    <Field ref="tvc:searchformfield:acme:common/Modified.xml"/>
</Fields>

The root element is <Field> and the following child elements are supported:

Name Description Example

Label

The label for the field. If the value is an existing i18n key internationalisation will be performed.

<Label>Type</Label>

Tooltip

Tooltip for the field. Displayed when hovering the label.If the value is an existing i18n key internaionalisation will be performed.

<Tooltip>
    <Header>Type Selection</Header>
    <Content>Select the type by entering its name and select it from the list.</Content>
</Tooltip>

Required

Specifies that a value is required for the field in order for the form to be valid. Whether term field is mandatory for performing the search.

Note: In case of "SearchOnCriteriaUpdate", search would be blocked but user would not be shown any alert message.

<Required>true</Required>

DataField

The data to search among.

The search provider might use this in different ways. See specific Search Providers for details about it.

For example the ENOVIA Search Provider users standard statement as type, name, attribute[Material Category].

ENOVIA example:

<DataField>type</DataField>

EXALEAD example:

<DataField>ATTRIBUTE_MATERIAL_CATEGORY</DataField>

DataType

Type of data to be searched. Valid values:

  • string

  • date

  • integer

  • decimal

  • boolean

<DataType>date</DataType>

UIType

Kind of user interface user presented to the user. For example, autocomplete, ranges and text.

See UI Types for more details.

<UIType>autocomplete</UIType>

Visible

Defines visibility of field in search form. It allows configuration to make field visible or hidden based on selection on another field. By default field is visible.

<Visible ifField="enovia_type">
    <HasValues>
        <Value>Part</Value>
    </HasValues>
</Visible>

Values

Values available for the field. For example, when ranges for an ENOVIA attribute is displayed each of the ranges is represented by one value.

It also controls the default selected value.

See Values for more details.

Use ranges on attribute Material Category as values:

<Values attribute="attribute_MaterialCategory" />

Part is the default value:

<Values>
    <Value value="type_Part" default="true" />
</Values>

Dimensions

Dimensions available for the field when searchWithUnit is true. For example, when dimensions for an ENOVIA attribute is displayed each of the dimensions is represented by one value.

See Dimensions for more details.

Use dimensions on attribute Weight as below:

<Dimensions attribute="attribute_Weight" />

Part is the default value:

<Dimensions>
    <Dimension name="kg" label="kilograms" multiplier="1000.0" />
</Dimensions>

Settings

Settings to further configure the field. Look at each UI Type for details on supported settings.

Enabling the search box above the values when using <UIType>ranges</UIType>:

<Settings>
    <Setting name="showFilter" value="true" />
</Settings>

casesensitive

case sensitivity for the input value. Default value is false

<Settings>
    <Setting name="casesensitive" value="true" />
</Settings>

ConditionalFields

Additional fields which should be added to search form based on value selected for this field. See Conditional Fields for details.

<Field>
    .
    .
    <ConditionalFields className="com.acme.MyConditionalFieldsProvider" />
</Field>

The ENOVIA attribute can be specified on the <Field> element using the attribute attribute. This specifies that the field is searching in that specific attribute and sets sensible default values for the field, e.g. it picks <UIType>date</UIType> and sets <DataType>date</DataType> in case the attribute stores a date.

Example:

<Field attribute="attribute_MaterialCategory" />
Specifying the attribute is useful when searching for with for example EXALEAD. The attribute is used to get the correct UI Type etc.
Values

Values are used for two purposes:

  1. To define the values the user can search by

  2. To define which value that is selected by default

There are a number of ways to control the available values:

  1. Configure a predefined list of values, see below for configuration format

  2. Specify an attribute using the attribute attribute. Example:

    <Values attribute="attribute_MaterialCategory" />
  3. Write a ValueProvider and configure it using the attribute className, Example:

    <Values className="com.acme.MyValueProvider" />
Value Configuration Format

The <Values> and <Value> element is used when configuring a predefined list or specifying default values for a field.

Attribute Name Description Example

value

The value. It’s mandatory to specify it.

<Values>
    <Value value="Part" />
</Values>

label

Text presented to the user. If none is provided the value is displayed. Label also supports localization.

<Values>
    <Value value="Part" label="Le Part" />
    <Value value="Document" label="com.technia.tvc.search.form.type.document" />
</Values>

type

Type of the value, if it is Enovia specific value like type, attribute range, state. For example if value is attribute range, its type should be <AttributeName>.Range. This used for applying localization on said value and it is based on localization of schema elements in Enovia.

<Values>
    <Value value="Part" type="Type" />
    <Value value="Rubber" type="Material_Category.Range" />
</Values>

default

Controls if the value is selected by default.

<Values>
    <Value value="Part" default="true" />
</Values>
Dimensions

Dimensions are used to allow search with different units for numeric fields.

There are a number of ways to control the available dimensions:

  1. Configure a predefined list of dimensions, see below for configuration format

  2. Specify an attribute using the attribute attribute. Example:

    <Dimensions attribute="attribute_MaterialCategory" />
  3. Write a DimensionProvider and configure it using the attribute className, Example:

    <Dimensions className="com.acme.MyDimensionProvider" />
Dimensions Configuration Format

The <Dimensions> and <Dimension> element is used when configuring a predefined list or specifying default dimensions for a field.

Attribute Name Description Example

Dimension

It’s mandatory to specify name, label and multiplier. Label also supports localization.

<Dimensions>
    <Dimension name="g" label="Grams" multiplier="1.0"/>
    <Dimension name="kg" label="com.technia.tvc.search.unit.kg" multiplier="1000.0"/>
</Dimensions>
Conditional Fields

Additional fields can be added to search form based on value selected on this field. For example it may be desired for type field to add additional fields when Part is selected as type.

Conditional Fields can be implemented by implementing a interface com.technia.tvc.search.searchform.conditionalfields.ConditionalFieldsProvider and configure it using the attribute className, Example:

<ConditionalFields className="com.acme.MyConditionalFieldsProvider" />
API Description

createConditionalFields

Returns set of additional fields to be added to searchform

Field Visibility

Field can be shown or hidden based on selection made on another field. It can be useful to configure use case when different attributes or fields are enabled for searching based on type selected. For example when type is selected as 'Part', part attributes like 'Weight' can be shown.

When field is not visible it will not be considered as search criteria.

The <Visible> element within <Field> is used for configuring visibility rules for the field. Following attribute and sub elements can be used for configuration.

Name Element / Attribute Description Example

hidden

attribute

Defines whether field should be hidden by default.

<Visible hidden="true"/>

ifField

attribute

Defines id of field on which visibility of this field depends. For example if 'Weight' field is to be shown when 'Type' field has value Part.

<Visible fieldId="type_enovia"/>

HasValues

element

Defines discrete list of values, on which field will be visible.

<HasValues>
    <Value>Hardware Part</Value>
    <Value>Electrical Part</Value>
    <Value>Mechanical Part</Value>
</HasValues>

jsFunction

attribute on <HasValues>

Javascript function returning true/false. Arguments passed to function are field id and criteria selected on field.

<HasValues jsFunction="App.hex.isPart"/>

includeWhenHidden

attribute

Defines whether field should be considered in search criteria, when field is not visible.

<Visible hidden="true" includeWhenHidden="true"/>

Examples-

Example configuration to show part states when type selected is Part.

<Field id="partstates">
    <Values>
        <Value value="Review" default="true"/>
        <Value value="Preliminary"/>
    </Values>
    <Label>Part States</Label>
    <DataField>current</DataField>
    <Visible ifField="enovia_type">
        <HasValues>
            <Value>Part</Value>
        </HasValues>
    </Visible>
</Field>

Example configuration to show weight when javascript function App.hex.isTypePart returns true.

<Field attribute="attribute_Weight">
    <Label>Weight</Label>
    <Visible ifField="enovia_type">
        <HasValues jsFunction="App.hex.isTypePart" />
    </Visible>
</Field>
Custom Fields

Custom field definition can also be used to implement a field. It can be specified using attribute className on element Field.

Interface to implement:

com.technia.tvc.search.searchform.FieldDef

<Field className="com.acme.search.CustomField"/>
Built-in ENOVIA Fields
TypeField

Field designed to select an ENOVIA type. The field uses autocomplete. Available types to search among is configurable using the SearchableTypes element.

Example configuration of a TypeField where the user can select any type in either Parts or Document hierarchy. The default value is set to 'Part':

<TypeField>
    <Values>
        <Value value="Part" default="true" />
    </Values>
    <SearchableTypes>
        <Type>type_Part</Type>
        <Type>type_DOCUMENTS</Type>
    </SearchableTypes>
</TypeField>
RevisionField

Field designed to select an ENOVIA revision. The field uses radio button type. Available values to search among is configurable using provided tags.

Example configuration of a RevisionField where the user can select any revision in either Parts or Document hierarchy. The default value is set using selected="true" attribute:

<RevisionField sectionId="basic">
    <AnyRevision />
    <FirstRevision />
    <LastRevision />
    <LatestInState policy="EC Part" state="Release" />
    <LastAndLatestInState policy="EC Part" state="Release" />
</RevisionField>
Field Description

AnyRevision

Shows all the revisions

FirstRevision

Shows only first revision

LastRevision

Shows only last revision

LatestInState

Shows latest revision with passed in state value

LastAndLatestInState

Shows the combination of LastRevision and LatestInState

NameField

This field uses a text input field and looks in the name field in ENOVIA.

Example:

<NameField />
PersonField

Field used to select a person. The field uses autocomplete.

Example:

<PersonField>
    <Label>Owner</Label>
    <DataField>owner</DataField>
</PersonField>
StateField

Field used to select one or more states. The available states to choose from is configured by specifying one or more policies.

It’s mandatory to specify at least one policy.

Example where the user can select states from the EC Part and / or Development Part policy:

<StateField>
    <Policies>
        <Policy name="EC Part" />
        <Policy name="Development Part" />
    </Policies>
</StateField>

The states are by default grouped by policy. The groups are expanded / collapsed when clicked. Clicking the label of the field expands / collapses all groups.

Tip: Use the setting expandGroups to control if the polices should be expanded / collapsed when the search form is loaded.

The StateField uses the UI type ranges. The settings described in the settings table of the UI type ranges is available for the StateField. For example, it’s possible to add the filter feature and control if the groups should be expanded when the search form is loaded. Two settings are not available: showAllRanges and showRangeAmount. All ranges are shown for the StateField.

Settings:

Attribute Name Description Default Example

groupByState

Groups the states into their corresponding policies.

true

<Settings>
    <Setting name="groupByState" value="false" />
</Settings>

valueSeparator

The separator to use in the value to separate the policy and state name.

For example, the value of state Preliminary for policy EC Part is EC Part:Prelimiary

:

<Settings>
    <Setting name="valueSeparator" value="@" />
</Settings>
ClassificationField

ClassificationField is a Enovia built-in field designed as preconfigured field to support Enovia classification hierarchy. In Enovia, classification is maintained as hierarchy where Library objects acts as root objects. There can be single or multiple root Library objects, beneath a Library there are Family or Classification objects. There can be single or multiple Family or Classification objects below each Library object. There can be more Family or Classification objects (also known as Sub Family) beneath a Family or Classification object forming a hierarchy. At the end of hierarchy classified items will be present.

ClassificationField has a built in autocomplete handler which allow navigation through Library, Family and Sub Family or Classification objects. Handler also allows configurations on root Library and Family objects, more details can be found here Built-in Autocomplete Handler.

Once user selects a Family or Classification, built-in ConditionalFields loads attributes dynamically into searchform, see Built-in Conditional Fields for details.

Example:

<ClassificationField>
    <Label>Part Family</Label>
    <DataField>to[Classified Item].from.id</DataField>
    <ConditionalFields></ConditionalFields>
    <Settings>
        <Setting name="defaultsToContextObject" value="true" />
        <Setting name="autocompletehandler">
        {
            "name": "classification",
            "rootTypePattern": "type_Libraries",
            "rootVaultPattern": "vault_eServiceProduction",
            "rootWhereClause": "current === Active",
            "expandTypePattern": "type_PartFamily",
            "relPattern": "relationship_Subclass",
            "expandWhereClause": "current === Active",
            "queryType": "expandWithTerm",
            "displayMacro":"${name} ${current}"
        }
    </Setting>
    <Setting name="defaultMinInteger" value="0" />
    <Setting name="defaultMaxInteger" value="1000" />
    <Setting name="defaultMinReal" value="0.0" />
    <Setting name="defaultMaxReal" value="100.0" />
    </Settings>
</ClassificationField>

Settings:

Setting Name Description Example

defaultsToContextObject

Context object is set as default selected in field. Useful when search panel is open in object context and it expected to default to context object. Default is false.

<Settings>
    <Setting name="defaultsToContextObject" value="true" />
</Settings>

defaultMinInteger

Minimum value for integer type attribute when added dynamically via Classification Field.

<Settings>
    <Setting name="defaultMinInteger" value="0" />
</Settings>

defaultMaxInteger

Maximum value for integer type attribute when added dynamically via Classification Field.

<Settings>
    <Setting name="defaultMaxInteger" value="1000" />
</Settings>

defaultMinReal

Minimum value for a real type attribute when added dynamically via Classification Field.

<Settings>
    <Setting name="defaultMinReal" value="1.0" />
</Settings>

defaultMaxReal

Maximum value for real type attribute when added dynamically via Classification Field.

<Settings>
    <Setting name="defaultMaxReal" value="100.0" />
</Settings>
Built-in Autocomplete Handler

Classification built-in handler retrieves Family objects in two steps -

  1. Query Library objects

  2. Expand Library objects to retrieve Family objects

Example:

<Setting name="autocompletehandler">
    {
        "name": "classification",
        "rootTypePattern": "type_Libraries",
        "rootVaultPattern": "vault_eServiceProduction",
        "rootWhereClause": "current === Active",
        "expandTypePattern": "type_PartFamily",
        "relPattern": "relationship_Subclass",
        "expandWhereClause": "current === Active",
        "queryType": "expandWithTerm",
        "displayMacro":"${name} ${current}"
    }
</Setting>

Following arguments provides flexibility in retrieving Library and Family or Classification objects.

Argument Description Default Example

rootTypePattern

TypePattern of top level Library.

type_Library

<Setting name="autocompletehandler">
    {
        "name": "classification",
        "rootTypePattern": "type_Libraries"
    }
</Setting>

rootNamePattern

NamePattern of top level Library.

*

<Setting name="autocompletehandler">
    {
        "name": "classification",
        "rootNamePattern": "Part*"
    }
</Setting>

rootRevPattern

RevisionPattern of top level Library.

*

<Setting name="autocompletehandler">
    {
        "name": "classification",
        "rootRevPattern": "A"
    }
</Setting>

rootVaultPattern

VaultPattern of top level Library.

*

<Setting name="autocompletehandler">
    {
        "name": "classification",
        "rootVaultPattern": "eService Production"
    }
</Setting>

rootWhereClause

Where clause for querying Library objects.

<Setting name="autocompletehandler">
    {
        "name": "classification",
        "rootWhereClause": "current === Active",
    }
</Setting>

relPattern

Relationship pattern for expanding Library objects

relationship_Subclass

<Setting name="autocompletehandler">
    {
        "name": "classification",
        "relPattern": "relationship_Subclass*"
    }
</Setting>

expandTypePattern

Type pattern for Family or Classification objects.

type_PartFamily

<Setting name="autocompletehandler">
    {
        "name": "classification",
        "expandTypePattern": "type_PartFamily*"
    }
</Setting>

expandWhereClause

Where clause for expanding Family or Classification objects.

<Setting name="autocompletehandler">
    {
        "name": "classification",
        "expandWhereClause": "current === Active"
    }
</Setting>

queryType

Following four options are supported:

  • queryWithTerm: Library objects will be queried first as per setting defined and expanded to retrieve Family objects. User input will be applied as where while finding Family objects.

  • expandWithTerm: Library objects passed as argument or context object will be expanded to retrieve Family objects. User input will be applied as where while finding Family objects.

  • query: Library objects will be queried first as per setting defined and expanded to retrieve Family objects. User input will be not considered.

  • expand: Library objects passed as argument or context object will be expanded to retrieve Family objects. User input will be not applied.

query

<Setting name="autocompletehandler">
    {
        "name": "classification",
        "queryType": "expandWithTerm",
    }
</Setting>

searchType

Defines how user input should be used in finding Family objects. Valid values are:

  • startswith

  • endswith

  • contains

startswith

<Setting name="autocompletehandler">
    {
        "name": "classification",
        "searchType": "startswith"
    }
</Setting>
Auto setting default value on field

The New Search Experience (NSX) in TVC allows user to find objects of interest by configuring the search within a page. NSX comes with side panel for search and the results are displayed in a flat table. NSX supports search providers - Enovia, Exalead or other data source.

When NSX form gets loaded, the fields can be pre-populated with their default values.

However, it might be needed that these default values are not pre-selected but can be added with a single click.

As an example for a person field, the default value could be the logged in user; but the user may want to set the value on click of an icon instead of prefilling it. We have now added a new feature of setting the default value by clicking an icon This feature is only applicable for an auto-complete field. This can be enabled by using the below settings :

<Settings>
    <Setting name="currentUserDefault" value="true" />
    <Setting name="setToDefaultOnIconClick" value="true" />
    <Setting name="populateDefaultValueIcon" value="ti-c ti-person-c" />
    <Setting name="populateDefaultValueIconTooltip" value="Click to set context user" />
</Settings>

The icon and its tool tip are configurable. The tooltip also supports localization.

image
Figure 23. Icon to set default value
Built-in Conditional Fields

Classification built-in conditional field add interface attributes from selected Classification/Family object to searchform.

Example:

<ClassificationField>
    .
    .
    <ConditionalFields></ConditionalFields>
    .
</ClassificationField>

It is also possible to use custom conditionals field, see Conditional Fields for details.

UI Types

For each field a UI type is configured. It defines what kind of user interface that is presented to the user. Is it a simple text input field, datepicker, autocomplete field where data is fetched from the server or some other kind of UI.

If no UI type is configured for a field a (hopefully) sensible decision is done
Text

A simple input field where a user can enter a text.

Suitable for example when searching in name and description in ENOVIA.

Autocomplete

Autocomplete field aiding the user to select a value. As the user enters a value the available values are presented in a dropdown.

There are two ways to specify the values the user can choose from:

  1. Predefined list of values. Configure the available values using the Values element. The values are sent to the client when the search form is rendered and no later requests to the server is required.

  2. AutoCompleteHandler. Specify which AutoCompleteHandler which should provide values, e.g. type or person. When the user enters a search term a request is sent to server for evaluating suitable values.

Configure which AutoCompleteHandler to use and other settings using a <Setting> with the name set to autocompletehandler.

Example configuring a field to use the type AutoCompeleteHandler:

<Field>
    <Label>Type</Label>
    <DataField>type</DataField>
    <UIType>autocomplete</UIType>
    <Settings>
        <Setting name="autocompletehandler">
        {
            "name": "type",
            "rootTypes": [ "Part" ]
        }
        </Setting>
    </Settings>
</Field>
This is quite close to what is done behind the scenes when using the Built-in TypeField

More information about AutoCompleteHandlers is found in the TVC Classic Core documentation.

The react-select component is used to provide the autocomplete feature. Settings available in the documentation is possible to configure using the <Setting value="reactselect"> element.

Example:

<Setting name="reactselect">
{
    getOptionValue: (option) { return option.id; },
    getOptionLabel: (option) { return option.login; }
}
</Setting>
Multi Value Selection

React select supports selection of multiple values, to enable isMulti setting should be set to true using the <Setting name="reactselect"> element as shown below.

<Setting name="reactselect">
     {
         "isMulti": "true"
     }
</Setting>

React-Select has undergone significant changes in version 2. The main change, from a search form perspective, is that the valueKey and labelKey no longer are supported. Instead the methods getOptionValue(option) and getOptionLabel(option) are used, see example above. More details is found in the upgrade guide. Helium 2018.6.0+ is using React-Select version 2.

Ranges

Presents a fixed number of ranges to the user. This could for example be the ranges of an ENOVIA attribute or a number of states.

The available ranges to choose from is specifid using the Values element.

Example displaying ranges for the Material Category attribute:

<Field>
    <Label>Material Category</Label>
    <DataField>ATTRIBUTE_MATERIAL_CATEGORY</DataField>
    <UIType>ranges</UIType>
    <Values attribute="attribute_MaterialCategory" />
</Field>

Settings:

Attribute Name Description Default Example

showFilter

Show input field above ranges used to filter visible ranges.

false

<Settings>
    <Setting name="showFilter" value="true" />
</Settings>

showAllRanges

If all ranges should be shown. User will need to scroll in case this setting is false.

false

<Settings>
    <Setting name="showAllRanges" value="true" />
</Settings>

showRangeAmount

Number of ranges to show in case showAllRanges is false.

5

<Settings>
    <Setting name="showRangeAmount" value="10" />
</Settings>

expandGroups

Controls if the groups should be expanded when the search form is loaded. Useful in case there are a large amount of groups / ranges.

true

<Settings>
    <Setting name="expandGroups" value="false" />
</Settings>

hideRangesWithZeroCount

Controls if ranges with count zero should be hidden.

false

<Settings>
    <Setting name="hideRangesWithZeroCount" value="true" />
</Settings>

termFieldRequired

It’s possible that the user will want to make the term field mandatory. By specifying it as a search config level, it can be used. / ranges.

false

<Settings>
    <Setting name="termFieldRequired" value="true" />
</Settings>
The count for each range is displayed in case that information is available in the provided values
Try exchanging the UIType to autocomplete to see if it fits better for your needs
Date Picker

The user can select a date range to search within. If only start / end is selected all objects after / before the date is displayed.

Example:

<Field>
    <Label>Modified</Label>
    <DataField>modified</DataField>
    <UIType>datepicker</UIType>
</Field>
The UI type is redundant in the example above. As modified is specified on the field element sensible default values for the field are applied. For example, the UIType is set to datepicker as modified has the data type date.

The react-daterange-picker component is used to provide the datepicker feature. Settings available in their documentation is possible to configure by adding a <Setting> with the name reactdates.

Example configuring react-dates to display three months in the picker and remove the clear button:

<Field>
    <Label>Modified</Label>
    <DataField>modified</DataField>
    <UIType>datepicker</UIType>
    <Settings>
        <Setting name="reactdates">
        {
            "numberOfMonths": 3,
            "showClearDates": false
        }
        </Setting>
    </Settings>
</Field>

Settings:

Attribute Name Description Default Example

valuesInclusive

Includes the specified ‘from’ and ‘to’ values

true

<Settings>
    <Setting name="valuesInclusive" value="false" />
</Settings>

dateDisplayFormat

Date Format to be used for this field. Input format based on Unicode Technical Standard. Supported values are: y, M, MM, MMM, MMMM, d, dd.

'd-M-y'

<Settings>
    <Setting name="useOldDatePicker" value="false" />
</Settings>

useOldDatePicker

Displays older date picker for selection (depreciated)

false

<Settings>
    <Setting name="useOldDatePicker" value="true" />
</Settings>
The old date picker using the setting useOldDatePicker is depreciated and might get removed in future releases.
Slider

Used to define a number range to search within. Useful when searching for instance of Parts with weight between 12 and 30 grams.

Dimensions can be added using Dimensions tag.

A slider is displayed to allow the user to easily adjust the range.

Example configuration:

<Field attribute="attribute_Weight">
    <Label>Weight</Label>
    <UIType>Slider</UIType>
    <Settings>
        <Setting name="unit" value="g" />
        <Setting name="min" value="0" />
        <Setting name="max" value="100" />
    </Settings>
</Field>

Example configuration with dimensions:

image
Figure 24. Search With Dimensions
<Field attribute="attribute_Weight">
    <Label>Weight</Label>
    <UIType>Slider</UIType>
    <Settings>
        <Setting name="searchWithUnit" value="true" />
        <Setting name="min" value="0" />
        <Setting name="max" value="100" />
    </Settings>
</Field>
The UI type is redundant in the example above. As the attribute weight is specified on the field element sensible default values for the field are applied. For example, the UIType is set to slider as weight contains numeric values.

Settings:

Attribute Name Description Default Example

showSlider

Should the slider be displayed

true

<Settings>
    <Setting name="showSlider" value="false" />
</Settings>

min

The minimum value that is selectable. This setting is mandatory in case the slider is displayed.

<Settings>
    <Setting name="min" value="0" />
</Settings>

max

The maximum value that is selectable. This setting is mandatory in case the slider is displayed.

<Settings>
    <Setting name="max" value="100" />
</Settings>

unit

A unit to display next to the input fields, e.g. $ and g.

<Settings>
    <Setting name="unit" value="$" />
</Settings>

searchWithUnit

should the field allow search with available dimensions for numeric types.

false

<Settings>
    <Setting name="searchWithUnit" value="true" />
</Settings>

step

Increments when changing the value using the slider.

1

<Settings>
    <Setting name="step" value="0.1" />
</Settings>

precision

Decimal precision for the field.

1

<Settings>
    <Setting name="precision" value="3" />
</Settings>

valuesInclusive

Includes the specified ‘from’ and ‘to’ values

true

<Settings>
    <Setting name="valuesInclusive" value="false" />
</Settings>
Tree Field

Treefield can be used to create a tree-like structure with nodes and each node can be expanded or selected. It is useful for selecting values from classification and sub-classification like type hierarchy.

There are three ways to specify the values/nodes the user can select from:

  1. Predefined list of values. Configure the available values/nodes using the Values element. The values/nodes are sent to the client when the search form is rendered and no further request to the server is required.

  2. TreeHandler. Specify which TreeHandler should provide values/nodes, e.g. type or businessobject. When the user expands a node a request is sent to the server for fetching child nodes. Child nodes are added to expanded node and child nodes can further be expanded.

  3. Combination of both. Configure the available values/nodes using the Values element and specify which TreeHandler which should provide values/nodes on expanding the preconfigured nodes. The predefined values/nodes are sent to the client when the search form is rendered. When the user expands a node a request is sent to the server for evaluating and fetching child values/nodes. Combination of both us useful to define the root node, which can be further expanded.

Type Hierarchy

Following settings are supported by Treefield:

Setting Name Description Default Example

showValueCount

Whether to show count against the node if provided by TreeHandler.

true

<Settings>
    <Setting name="showValueCount" value="false" />
</Settings>

selectChildren

Whether child nodes should be auto selected on selecting parent node.

If this is configured true, child nodes cannot be unselected when parent node is selected.

false

<Settings>
    <Setting name="selectChildren" value="true" />
</Settings>

submitOnlyParent

Whether to submit only parent node when child nodes are auto selected.

This setting is applicable only when selectChildren is true.

false

<Settings>
    <Setting name="submitOnlyParent" value="true" />
</Settings>

showAllNodes

Whether to show all nodes or show limited number of nodes with scroll.

false

<Settings>
    <Setting name="showAllNodes" value="true" />
</Settings>

showNodesCount

How many node should be visible, after which scroll will be shown.

5

<Settings>
    <Setting name="showNodesCount" value="8" />
</Settings>

loadOptions

A JSON configuration object used to define TreeHandler and other sub settings needed by TreeHandler. See Tree Handlers for more detail.

<Setting name="loadOptions">
{
    "handler": {
        "name": "com.acme.CustomTreeHandler"
    },
    "valueKey": "value",
    "labelKey": "label"
}
</Setting>
Predefined Values

Predefined values can be specified using Values element. Attribute parent can be used to build a node hierarchy for predefined values.

Example:

<Field id="type" sectionId="basic">
    <UIType>tree</UIType>
    <Label>Type</Label>
    <DataField>TYPE</DataField>
    <Values>
        <Value value="Part">Part</Value>
        <Value value="Software Part" parent="Part">Software Part</Value>
        <Value value="Hardware Part" parent="Part">Hardware Part</Value>
        <Value value="Mechanical Part" parent="Hardware Part">Mechanical Part</Value>
        <Value value="Electrical Part" parent="Hardware Part">Electrical Part</Value>
    </Values>
</Field>
image
Figure 25. Predefined Tree Nodes
Predefined values can be used to load root nodes when used together with a TreeHandler.
Tree Handlers

A TreeHandler is used to expand a node. When a node is expanded an ajax request is sent to the server with the expanded node as input, the TreeHandler processes this input and prepares a list of child nodes, which are sent back to the client. Child nodes are added to the expanded node and node is marked as expanded.

Tree handler is a java class and must implement following interface com.technia.tvc.search.ui.tree.handler.TreeHandler. Tree handler can be configured using a <Setting> called loadOptions with the handler name set to treehandler.

Example configuring a field to use the type TreeHandler:

<Field id="type2" sectionId="basic">
    <UIType>tree</UIType>
    <Label>Type</Label>
    <DataField>TYPE</DataField>
    <Values>
        <Value value="Part" default="true" disableSelection="false">Part</Value>
    </Values>
    <Settings>
        <Setting name="casesensitive" value="true" />
        <Setting name="showValueCount" value="true" />
        <Setting name="selectChildren" value="true" />
        <Setting name="submitOnlyParent" value="false" />
        <Setting name="loadOptions">
        {
            "handler": {
                "name": "com.acme.CustomTreeHandler"
            },
            "valueKey": "value",
            "labelKey": "label"
        }
        </Setting>
    </Settings>
</Field>

Following sub settings are supported by loadOptions:

Setting Name Description Default Example

forceNodeFetchOnExpand

Whether a new server request should be made when an already expanded node is collapsed and expanded again. This setting should be set to true when nodes are business objects and data can change in between.

false

<Setting name="loadOptions">
{
    "handler": {
        "name": "com.acme.TreeHandler",
        ....
    },
    "forceNodeFetchOnExpand": "true"
}
</Setting>

valueKey

Key which should be used to retrieve value from added child node.

value

<Setting name="loadOptions">
{
    "handler": {
        "name": "com.acme.TreeHandler",
        ....
    },
    "valueKey": "value"
}
</Setting>

labelKey

Key which should be used to retrieve label from added child node.

label

<Setting name="loadOptions">
{
    "handler": {
        "name": "com.acme.TreeHandler",
        ....
    },
    "labelKey": "label"
}
</Setting>
Built in Tree Handlers

There are two built in TreeHandlers:

Type

type TreeHandler is used to create a tree field based on Enovia type hierarchy. Each node represents a type in Enovia and on expanding its subtypes are fetched and added as child nodes. It can be configured using shorthand type as shown below -

<Field id="type2" sectionId="basic">
    <Values>
        <Value value="Part" default="true" disableSelection="false">Part</Value>
    </Values>
   ...
    <Settings>
        <Setting name="loadOptions">
        {
            "handler": {
                "name": "type"
            },
            "valueKey": "value",
            "labelKey": "label"
        }
		</Setting>
    </Settings>
</Field>
Business Object

businessobject TreeHandler is used to create a tree field by expanding the business object. To start a root node or nodes must be configured. The root node can be configured as a static node via predefined values and value must be root which acts as a starting node. On expanding the starting node, businessobject adds real root nodes under the starting node via Enovia MQL query as configured in handler settings. When the root node or nodes are expanded, Enovia MQL expand is used to add child nodes under the root node.

Root node configured as predefined value is dummy node and lets TreeHandler businessobject know that root nodes should be added via Enovia MQL query. On each node expansion thereafter Enovia MQL expand is performed.

Business object handler can be configured using short hand TreeHandler businessobject.

Following sub settings are supported by businessobject TreeHandler:

Setting Name Description Example

rootTypePattern

Type pattern to quering the root nodes.

<Setting name="loadOptions">
{
    "handler": {
        "name": "businessobject",
        "rootTypePattern": "type_Libraries",
        ....
    }
}
</Setting>

rootNamePattern

Name pattern to quering the root nodes.

<Setting name="loadOptions">
{
    "handler": {
        "name": "businessobject",
        "rootNamePattern": "Diode*",
        ....
    }
}
</Setting>

rootRevPattern

Revision pattern to quering the root nodes.

<Setting name="loadOptions">
{
    "handler": {
        "name": "businessobject",
        "rootRevPattern": "A",
        ....
    }
}
</Setting>

rootVaultPattern

Vault pattern to quering the root nodes.

<Setting name="loadOptions">
{
    "handler": {
        "name": "businessobject",
        "rootVaultPattern": "eService Production",
        ....
    }
}
</Setting>

rootWhereClause

Where clause that should be applied while quering the root nodes.

<Setting name="loadOptions">
{
    "handler": {
        "name": "businessobject",
        "rootWhereClause": "current == Active",
        ....
    }
}
</Setting>

disableRoots

Whether root nodes should be disabled for selection.

<Setting name="loadOptions">
{
    "handler": {
        "name": "businessobject",
        "disableRoots": "true",
        ....
    }
}
</Setting>

typePattern

Type pattern for expanding root and other nodes.

<Setting name="loadOptions">
{
    "handler": {
        "name": "businessobject",
        "typePattern": "type_PartFamily",
        ....
    }
}
</Setting>

relPattern

Relationship pattern for expanding root and other nodes.

<Setting name="loadOptions">
{
    "handler": {
        "name": "businessobject",
        "relPattern": "B",
        ....
    }
}
</Setting>

relWhereClause

Relationship where clause for expanding root and other nodes.

<Setting name="loadOptions">
{
    "handler": {
        "name": "businessobject",
        "relWhereClause": "attribute[Is Primary Plant] == True",
        ....
    }
}
</Setting>

objectWhereClause

Object where clause for expanding root and other nodes.

<Setting name="loadOptions">
{
    "handler": {
        "name": "businessobject",
        "objectWhereClause": "current != Inactive",
        ....
    }
}
</Setting>

displayMacro

displayMacro for showing lable of expanded child nodes.

<Setting name="loadOptions">
{
    "handler": {
        "name": "businessobject",
        "displayMacro":"${name} ${current}",
        ....
    }
}
</Setting>

Example businessobject handler configuration for the scenario where can select a part family classification. In Enovia part families are connected with libraries and part families can have subpart families. In the configuration below on expanding dummy start node, part libraries are queried using root config settings and part library and part family are further expanded using type and rel patterns.

<Field sectionId="related">
    <Label>Classification Tree</Label>
    <DataField>to[Classified Item].from.id</DataField>
    <ConditionalFields></ConditionalFields>
    <UIType>tree</UIType>
    <Values>
        <Value value="root" disableSelection="true">Start...</Value>>
    </Values>
    <Settings>
        <Setting name="loadOptions">
        {
            "handler": {
                "name": "businessobject",                       // handler name
                "rootTypePattern": "type_Libraries",            // Root type pattern
                "rootNamePattern": "*",                         // Root name pattern
                "rootRevPattern": "-",                          // Root revision pattern
                "rootVaultPattern": "vault_eServiceProduction", // Root vault pattern
                "rootWhereClause": "current == Active",         // Root where clause
                "disableRoots": "true",                         // If part library should be disabled for selection
                "typePattern": "type_PartFamily",               // Type pattern for part family. Supports more than one comma separated values.
                "relPattern": "relationship_Subclass",          // Relation between library and part family and between part family and
                                                                // sub part families. Supports more than one comma separated values.
                "objectWhereClause": "current == Active",       // Relation where clause
                "displayMacro":"${name} ${current}"             // Display marco
            },
            "valueKey": "value",
            "labelKey": "label"
        }
    	</Setting>
    	<Setting name="submitOnlyParent" value="true" />
    </Settings>
</Field>
Part Classification Tree Field
In this example we are adding a dummy start node in the begining and on expanding dummy start node, root nodes are added as child to dummy nodes. It is possible to use combination of predefined values and businessobject TreeHandler to laod root nodes directly as searchform is loaded.
Combination of Predefined Values and TreeHandler

A root node or nodes in the tree field are the starting point tree expansion. It is important to configure root nodes properly for the intuitive end-user experience. For example when using a built-in TreeHandler type, the root node can be configured using a predefined value :

<Field id="type2" sectionId="basic">
    <Values>
        <Value value="Part" default="true" disableSelection="false">Part</Value>
    </Values>
   ...
    <Settings>
        <Setting name="loadOptions">
        {
            "handler": {
                "name": "type"
            },
            "valueKey": "value",
            "labelKey": "label"
        }
		</Setting>
    </Settings>
</Field>

or in case of businessobject handler root nodes can be added using root node configuration. However, it is possible to use a custom java class to load root nodes and allow businessobject handler to only handle the expansion of nodes. See Values for more details.

<Field sectionId="related">
    <Label>Classification Tree</Label>
    <DataField>to[Classified Item].from.id</DataField>
    <ConditionalFields></ConditionalFields>
    <UIType>tree</UIType>
    <Values className="com.acme.RootNodeProvider" />
    <Settings>
        <Setting name="loadOptions">
        {
            "handler": {
                "name": "businessobject",                       // handler name
                "typePattern": "type_PartFamily",               // Type pattern for part family
                "relPattern": "relationship_Subclass",          // Relation between library and part family and between part family
                                                                // and sub part families.
                "objectWhereClause": "current == Active",       // Relation where clause
                "displayMacro":"${name} ${current}"             // Display marco
            },
            "valueKey": "value",
            "labelKey": "label"
        }
    	</Setting>
    </Settings>
</Field>
Term Field

Term field is special field designed to be used for search overlay. Implementing Search Provider can decide on how to interpret term field and use for performing search. See Enovia Provider Settings for details on how built-in ENOVIA Search Provider uses term field. Term field can be identified by property FieldType as term on field.

Section Configuration Format

The root element is <Section> and the following child elements and attributes are supported:

Name Description Example

id

Attribute on <Section> tag.

id is mandatory and should be unique for each section.
<Section id="basic">
...
</Section>

Label

The label for the section. I18n is supported through string resources file.

<Label>Type</Label>

Tooltip

Tooltip for the field. Displayed when hovering the label.

<Tooltip>
    <Header>Basic</Header>
    <Content>Section to display basic fields.</Content>
</Tooltip>

Expanded

Whether section should be expanded on load of searchform. Default value is true.

<Expanded>true</Expanded>

Sections can be used to divide fields into collapsible group or sections. Each field configuration should specify its section using attribute sectionId on <Field> tag, which should match with id on corresponding <Section>. See example configuration below -

<SearchForm>
    <Title>Part Search</Title>
    <Sections>
    	<Section id="basic">
    		<Label>com.technia.tvc.search.form.name.label</Label>
    		<Tooltip>
    			<Title>Basic Fields</Title>
    			<Content>This is a section for basic fields.</Content>
    		</Tooltip>
    		<Expanded>true</Expanded>
    	</Section>
    	<Section id="classification">
    		<Label>Classification</Label>
    		<Tooltip>
    			<Title>Classification Fields</Title>
    			<Content>This is a section for classification fields.</Content>
    		</Tooltip>
    		<Expanded>false</Expanded>
    	</Section>
    	<Section id="others">
    		<Label>Other</Label>
    		<Tooltip>
    			<Title>Other Fields</Title>
    			<Content>This is a section for other fields.</Content>
    		</Tooltip>
    		<Expanded>false</Expanded>
    	</Section>
    </Sections>
    <Fields>
        <NameField sectionId="basic">
        	<Settings>
                <Setting name="casesensitive" value="true" />
            </Settings>
        </NameField>
        <TypeField id="type" sectionId="basic">
            ...
        </TypeField>

        <StateField sectionId="basic">
            ...
        </StateField>

        <RevisionField sectionId="basic">
            ...
        </RevisionField>

        <ClassificationField sectionId="classification">
            ...
        </ClassificationField>

        <Field sectionId="others">
            ...
        </Field>

        <PersonField sectionId="others">
            ....
        </PersonField>

        <Field attribute="attribute_MaterialCategory" id="material_category" sectionId="classification">
        ...
        </Field>
    </Fields>
</SearchForm>

Search criteria can be saved using saved search functionality. Saved searches can be loaded to fill search criteria on the search form. User can also directly launch a search by clicking on find icon.

image
Figure 26. Save Search
image
Figure 27. Load Search

Search criteria present on search form can be exported as URL, which can be shared as copied text. Exported URL can then be directly be used to launch search in overlay mode. When a search is launched via URL, a default empty homepage is shown in the background to avoid loading heavy homepage impacting performance. However, it is possible to load a custom homepage via configuration tag <HomePage> on search config. <HomePage> should have the page reference that needs to be loaded in the background.

Example:

<Search provider="enovia" version="2">
    ...
    <HomePage>
        <Page namespace="helium" name="SearchPage.xml"/>
    </HomePage>
</Search>
image
Figure 28. Export Search
User settings
Search On Criteria Update

User Setting to enable/disable Search On Criteria Update for Search.

User can now control whether the search is submitted when the search criteria is updated. Earlier this feature was limited to search config and it was not possible to enable or disable for a specific user.

A built-in command SaveSearchUserSettings is added to allow users to enable or disable search on criteria updates. This built-in command needs to be added to the search form toolbar.

For detailed information on search on criteria update, please refer Search On Criteria Update

Search On Load

User Setting to enable/disable Search On Load for Search. Search config setting SearchOnLoad can be used to perform the initial search as search form loads.

User can now control whether the search should be initiated when the search form loads. Earlier this feature was limited to search config and it was not possible to enable or disable for a specific user.

A built-in command is added to allow users to enable or disable search on load feature. This built-in command needs to be added to the search form toolbar.

For detailed information on search on load, please refer Search On Load

<Toolbar>
  <SaveSearchUserSettings />
</Toolbar>
SaveSearchUserSettings command is used to club both the user settings ie Search On Criteria Update and Search On Load
image
Figure 29. Usersetting for search on criteria update & search on load
Javascript API

Methods

Method Description

setCriteria

Sets the criteria on search form

getCriteria

Gets the search criteria

updateFieldsVisibility

Updates visibility of fields on searchform

getState

Current fields of search form. State of searchform represents all the fields within searchform.

setFieldValues

Sets the field values on search form.

setFields

Sets the fields on search form. It is used when search result returns search form fields.

updateFieldValueCounts

Updates count on searchform fields.

on

Register to an event

off

Deregister to an event

Events

Event Name Description

search

Called when search button is clicked.

close

Called when searchform is closed

resetFields

Called when fields are reset.

criteriaUpdate

Called when search criteria is updated.

Example Configuration
<?xml version="1.0" encoding="UTF-8"?>
<SearchForm>
    <Title>Part Search</Title>

    <Fields>
        <NameField />

        <TypeField>
            <Values>
                <Value value="Part" default="true" />
            </Values>
            <SearchableTypes>
                <Type>type_Part</Type>
                <Type>type_DOCUMENTS</Type>
            </SearchableTypes>
            <Tooltip>
                <Title>customer.search.type.tooltip.title</Title>
                <Content>customer.search.type.tooltip.content</Content>
            </Tooltip>
        </TypeField>

        <Field>
            <Label>Material Category</Label>
            <DataField>MATERIAL_CATEGORY</DataField>
            <Values attribute="attribute_MaterialCategory" />
            <Settings>
                <Setting name="showFilter" value="true" />
                <Setting name="showRangeAmount" value="10" />
            </Settings>
        </Field>
    </Fields>
</SearchForm>
Toolbar Configuration Format

Toolbar can be configured inline within a searchform. Command/Menu can be configured in a separate file and added to the toolbar element.

image
Figure 30. SearchForm Toolbar

The command configuration files are placed in the folder command and menu configuration files are placed in the folder menu. If configured in a separate file, it can be referred within searchform using attribute ref as below -

<Toolbar>
    <Command ref="tvc:command:helium/mail.xml"/>
    <Menu ref="tvc:menu:helium/mymenu.xml"/>
</Toolbar>
Command Configuration Format

The root element is <Command> and the following child elements are supported:

Name Description Example

Label

The label for the command. I18n is supported through string resources file.

<Label>Mail</Label>

Alt

Tooltip for the command. Displayed when hovering the label.

<Alt>This is the tooltip.</Alt>

FontIcon

Icon for the command. Displayed left of the label.

<FontIcon>ti-f ti-mail-f</FontIcon>

Setting

Setting with name and value can be passed to include onClick and other required information.

<Setting name="onClick" value="App.searchFunctions.customFunction"></Setting>

The root element is <Menu> and the following child elements are supported:

Name Description Example

Label

The label for the command. I18n is supported through string resources file.

<Label>Mail</Label>

Alt

Tooltip for the menu. Displayed when hovering the label.

<Alt>This is the tooltip.</Alt>

FontIcon

Icon for the menu. Displayed left to the label.

<FontIcon>ti-f ti-mail-f</FontIcon>

Command

Commands for this menu visible as dropdown elements on clicking the menu.

<Command ref="tvc:command:helium/mail.xml" />
In-built Commands:

The in-built search commands can also be configured and only icon,label and tooltip can be modified.

<SaveSearch>
    <Label>save</Label>
    <FontIcon>ti-f ti-save-f</FontIcon>
    <Alt>Save Search</Alt>
</SaveSearch>
<LoadSearch>
    <Label>load</Label>
    <FontIcon>ti-f ti-menu-f</FontIcon>
    <Alt>Load Search</Alt>
</LoadSearch>
If toolbar is not defined in the searchForm, a default toolbar with in-built commands takes its place. If toolbar is configured, these inbuilt commands are needed to be included if required.

1.11.4. Search Providers

ENOVIA Search Provider

Built-in ENOVIA Search Provider can be used to perform search in ENOVIA. It can be used with enovia callsign name in Search Configuration.

<Search provider="enovia" />
Settings

ENOVIA Search Provider supports following settings, which are defined in Search Configuration. See Configuration Format for details on how to configure settings.

Setting Name Description Default Example

vault

Enovia vaults where search should be performed. Multiple comma separated vaults can be configured.

eService Production

<Settings>
    <Setting name="vault" value="vault_eServiceProduction, vault_ACMEVault" />
</Settings>

where

A custom where clause can be passed to search provider. For example it can be used to search only non-obsolete parts.

none

<Settings>
    <Setting name="where" value="current != 'Obsolete'" />
</Settings>

termWhere

termWhere is applicable for term search. It defines where clause, into which user search term is to be injected while performing Enovia search. For example, if user entered term search as test, Enovia where clause will look like name ~~ 'test' OR type ~~ 'test' OR description ~~ 'test'

name ~~ '%s' OR type ~~ '%s' OR description ~~ '%s'

<Settings>
    <Setting name="termWhere" value="name ~~ '*%s*' OR description ~~ '*%s*' OR current ~~ '*%s*'" />
</Settings>
EXALEAD Search Provider

Built-in EXALEAD Search Provider can be used to perform search in Exalead. It can be used with exalead callsign name in Search Configuration.

<Search provider="exalead" />
Settings

EXALEAD Search Provider supports following settings, which are defined in Search Configuration. See Configuration Format for details on how to configure settings.

Setting Name Description Default Example

xl:termFields

Fields against which term search should be evaluated.

Term search is by default queried as against all indexed fields

<Settings>
    <Setting name="xl:termFields" value="NAME,DESCRIPTION" />
</Settings>

xl:sortField

Field on which search should be sorted.

none

<Settings>
    <Setting name="xl:sortField" value="NAME" />
</Settings>

xl:sortOrder

Sort order of search result.

ascending

<Settings>
    <Setting name="xl:sortOrder" value="DESCENDING" />
</Settings>

xl:enableWildcardSearch

Whether to add wildcard to term search.

false

<Settings>
    <Setting name="xl:enableWildcardSearch" value="false"/>
</Settings>

xl:inlcudeFacets

Whether to include facets or field counts.

true

<Settings>
    <Setting name="xl:inlcudeFacets" value="true" />
</Settings>
RevisionField

In case of exalead search provider, RevisionField can be configured in search form like below

<RevisionField sectionId="basic">
    <AnyRevision />
    <FirstRevision />
    <LastRevision />
    <LatestInState policy="EC Part" state="Release" />
    <LastAndLatestInRelease />
    <Settings>
        <Setting name="xl:lastRevision" value="LASTREVISION"></Setting>
        <Setting name="xl:firstRevision" value="FIRSTREVISION"></Setting>
        <Setting name="xl:latestRevision" value="LATESTREVISION"></Setting>
        <Setting name="xl:lastAndLatestRevision" value="LASTANDLATESTREVISION"></Setting>
    </Settings>
</RevisionField>

Following Exalead settings can be defined on search form fields. See Field Configuration Format for details on how to configure settings.

Setting Name Description Default Example

xl:firstRevision

Exalead key for first revision.

NOTE

This setting is applicable for revision field.

FIRSTREVISION

<Settings>
    <Setting name="xl:firstRevision" value="FIRSTREVISION" />
</Settings>

xl:lastRevision

Exalead key for last revision.

NOTE

This setting is applicable for revision field.

LASTREVISION

<Settings>
    <Setting name="xl:lastRevision" value="LASTREVISION" />
</Settings>

xl:latestRevision

Exalead key for latest revision.

NOTE

This setting is applicable for revision field.

LATESTREVISION

<Settings>
    <Setting name="xl:latestRevision" value="LATESTREVISION" />
</Settings>

xl:lastAndLatestRevision

Exalead key for lastAndLatestRevision revision.

NOTE

This setting is applicable for revision field.

LASTANDLATESTREVISION

<Settings>
    <Setting name="xl:lastAndLatestRevision" value="LASTANDLATESTREVISION" />
</Settings>

xl:showZeroCount

Whether '0' should be shown when Exalead count for a field value is 0.

false

<Settings>
    <Setting name="xl:showZeroCount" value="true" />
</Settings>
Custom Search Provider

Custom Search Provider can be used to perform search. Custom Search Provider should implement interface com.technia.tvc.search.api.SearchProvider and provide implementation to method search(SearchContext context). SearchContext object provide access to following api to perform search.

API Description

getCriteria

Search criteria supplied by the client. Typically what the user enters in the search form including term search.

getSearchForm

Instance of searchform to be used to get access to data fields against which search is performed

getDataFields

DataField which should be include in search result. This is used for rendering search result on UI.

getSettings

Custom Settings defined in Search Config. This is useful for passing adhoc settings to SearchProvider, see ENOVIA Search Provider Settings for reference.

getSectionProvider

Section Provider to be used for sectionizing search results. Refer Built-in Section Provider for default implementation.

getSearchForm

Instance of searchform to be used to get access to data fields against which search is performed

1.12. Internationalisation

Helium supports both server-side and client-side internationalization.

The server-side internationalization is achieved by defining a set of string resource files inside <webapp-root>/WEB-INF/classes directory of the web application.

    <Column>
        <Label>emxFramework.Common.Name</Label>
    </Column>

The client-side internationalization is achieved by defining a set of language files in JSON format inside <webapp-root>/helium/lang or <webapp-root>/helium/custom/lang directory.

To decide which language to load, Helium will look at the current browser language (navigator.language), but if no suitable file is found a default one will be used.

    <Column>
        <Label>column.common.name</Label>
    </Column>

For exporting table data the support for internationalization is limited only to server-side and client-side internationalization is not supported. This limitation is applicable to all export formats.

    <Column>
        <Label>emxFramework.Common.Name</Label> // Supported
        <Label>column.common.name</Label> // Not Supported
    </Column>

1.12.1. File format

Each file should be given a name based on the locale they are to support. For instance, a file containing US English should be named en_us.json and a file containing Swedish should be named sv.json.

The files are simple JSON objects, with a key and a string as value, like the one below:

{
  "test": "My test message"
}

Where the key is test and the message is My test message. The keys can be nested arbitrarily deep in a nested object. For example the file below will create the keys form.createNew.title and form.createNew.message.

{
 "form" : {
   "createNew" : {
     "title" : "New Object",
     "message" : "The object {objectId} was successfully created."
   }
 }

The value for the key form.createNew.message contains a placeholder ({objectId}) which will be populated with the actual value by the framework. For an example see the JavaScript API.

1.12.2. Resolving files

The language files are located in <webapp-root>/helium/lang or <webapp-root>/helium/custom/lang.

The internationalisation framework will first look for files inside <webapp-root>/helium/custom/lang, if no suitable file is found, it will fall back to files defined in <webapp-root>/helium/lang and if still no file is found, it will default to a file named default.json

1.12.3. Javascript API

The above described keys can be accessed through javascript with the following syntax:

// Will return "My test message"
App.i18n.t('test')

It is possible to pass arguments to the App.i18n.t function that will be interpolated. See example below.

//  Will return "The obejct 1.2.3.4 was successfully created."
App.i18n.t('form.createNew.message', {objectId: '1.2.3.4'})
Handlebars helper

In Helium, there is a Handlebars helper for easy access to the internationalisation API. It is invoked by using the i18n helper.

{{i18n myTranslationKey}}

This will internally call the App.i18n.t function with the passed in key as its argument. The i18n helper of course also supports passing in arguments, like so:

{{i18n myTranslationKey myObjectContainingVariables}

1.13. Toaster

Helium use toaster message to provide user notification. These messgae can be shown using javascript api.

The default options use to show toaster notification can be changed through javascript as shown below :

(function () {
  App.toaster.defaultOpts = {
		"closeButton": true,
		  "newestOnTop": true,
		  "progressBar": true,
		  "positionClass": "toast-bottom-full-width",
		  "preventDuplicates": false,
		  "onclick": null,
		  "showDuration": "300",
		  "hideDuration": "1000",
		  "timeOut": "15000",
		  "extendedTimeOut": "1000",
		  "showEasing": "swing",
		  "hideEasing": "linear",
		  "showMethod": "fadeIn",
		  "hideMethod": "fadeOut"
  }
})();

The above javascript can be placed in webapps/helium/custom folder.

The toaster message are shown for 8 seconds by default, but user might want to see it for longer duration. This can be achieved by adding below configuration in tvc.properties:

tvc.helium.toaster.timeout = 25000 // default is 8000

1.14. Access Control

Helium has a common way of configuring access control that is shared among the different components (except table columns) that has this support (page, tab, commands etc.).

Access Control for table columns can be defined similar to TVC Classic. Please click here for more details.

The access restriction for components (other than table columns) can be defined based upon following:

  • Role Assignment

  • Group Assignment

  • Person (A named user)

  • Access Mask (Access mask for the current object)

  • Access Program (A JPO that evaluates the access rights)

  • Access Expression (MQL expression that evaluates the access)

The example below illustrates how you can construct the access restriction:

<Access>
    <Role>role_FirstRole</Role>
    <Role>role_SecondRole</Role>
    <Group>group_SomeGroup</Group>
    <Mask>modify,checkout</Mask>
</Access>

Or use an access program:

<Access>
    <Program name="MyJPO" method="checkAccess"/>
</Access>

Or use an access expression:

<Access>
    <Expression><![CDATA[owner == context.user]]></Expression>
</Access>

For Topbar Search command :

<Search ref="tvc:search:helium/TopBarSearch.xml">
    <Access>
        <Group>group_SomeGroup</Group>
    </Access>
</Search>

For Topbar Myspace and Logout command :

<Myspace>
    <Access>
        <Group>group_SomeGroup</Group>
    </Access>
</Myspace>

1.15. Loader

A loader alerts a user to wait for an activity to complete.

image
Figure 31. Loader

It can contain message also. This message appears just below the animation.

One can enable this feature by defining key-value pair like below in translation JSON files

"loader": {
    "message": "Loading..."
}

By defining this key/ value pair, all loading animations in the application will automatically display this value. No further configuration is needed.

It is also possible to define custom messages for different loading animations, e.g.

new App.Loader($element,{"message":'loader.customMessage'})

Or

new App.Loader($element,{"message":'Loading...'})

A mix of the above, i.e. default message and custom message is also possible.

Also we can add loader over any particular element on the UI, for ex a table row

new App.Loader(element, { rowLoader: true }

JavaScript API, Loader.

image
Figure 32. Loader with message(Loading…​).

1.16. Dimmable Modal

It would be helpful for users to have dim and non-reactive backgrounds while working on modal or fullscreen views. This feature can be enabled by configuring tvc.helium.widget.overlay.dimmable= true // default is false in tvc.properties.

image
Figure 33. Dim and Non-reactive Background