<Name>ACME</Name>
05 May 2016
This chapter describes the built in features of TVC Helium. Some of them may be configurable and some may not be enabled by default.
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
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. |
|
LoginPage |
Describes the LoginPage |
|
Sidepanel |
Describes the PageSidepanel |
|
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 |
|
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 |
|
StartPage |
Specifies which page the user should be redirected to after a successful login (if no other page is requested). |
|
TopBar |
Specifies what the TopBar should contain. |
|
PageMapping |
Specifies the PageMapping. What pages are accessible given object type and what roles the user has. |
|
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. |
|
Title |
The title of the login page |
|
FormTitle |
Specifies what title the login form should have. |
|
FormSubTitle |
Specifies what sub title the login form should have. |
|
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.
The <TopBar>
element supports the following child elements.
Name | Description | Example | ||
---|---|---|---|---|
ShowAppName |
Whether the application name should be visible or not. Valid values:
|
|
||
TooltipSettings |
Optional settings as given in Semantic Popup Settings can be passed for tooltip.
|
|
||
Left |
Child elements to the |
|
||
Middle |
Child elements that are aligned in the middle of the available remaining space between |
|
||
Right |
Child elements to the |
|
||
ShowBreadcrumb |
Whether the breadcrumb navigation should be visible or not. Valid values: true or false (default). See Breadcrumb section. |
|
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.
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.
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 |
|
Menu |
Will render a dropdown menu containing commands. The menu is defined in the xml referenced inside of the element. |
|
Command |
Will render a command. The command is defined in the xml reference from inside of the element. |
|
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.
Name | Description | Required | Example | ||
---|---|---|---|---|---|
dynamicmenu |
Defines a menu as a dynamic menu |
true |
|
||
href |
Ajax endpoint to fetch JSON data for dynamic content |
true |
|
||
id |
Unique identifier for the dynamic menu. Can be used, for e.g. to get hold of the menu from JavaScript. |
false |
|
||
template |
Reference to Handlebars template to render content on client |
false* |
|
||
onActivate |
JavaScript callback to handle menu when activated. If defined, it’s this callbacks' responsibility to configure dynamic menu content.
|
false* |
|
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. |
<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&reload=true&bindKey=foo" />
</Menu>
"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.
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" 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
.
To enable it, add following in the Topbar definition in Helium.xml.
...
<TopBar>
<Right>
<Menu>tvc:menu:helium:theme/ChangeTheme.xml</Menu>
</Right>
</TopBar>
...
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 Only evaluate the page if the rules given via the child elements |
|
FallbackPage |
The page to fall back to if none of the above rules have been applied. Supports the |
|
<?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>
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.
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. |
|
Dashboard |
Points to a reference to a Dashboard instance. |
|
Tabs |
Configures a list of Tabs |
|
Sidepanel |
Configures sidepanel Sidepanel |
|
Settings |
Simple key value pairs of settings that are passed to the page. If a setting named |
|
Access |
Defines access rules. |
See Access Control |
<?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>
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 |
|
OnInit |
Javascript function that creates the widget. |
|
OnInitOption |
Additional options that is to be passed to the OnInit function. |
|
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
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 };
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.
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 |
|
Tabs |
A new |
|
CacheBehaviour |
Describes how this tab should be cached. The cache behavior will only affect tabs that holds a dashboard. Valid values are:
|
|
Dashboard |
Holds a reference to a dashboard that will be rendered in this tab. |
|
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. |
See Access Control |
CustomClass |
Adds one or more HTML classes on the tab DOM element. This can be used for applying custom styling |
|
IconClass |
Adds an HTML class that represents a font icon. The icon will be rendered in front of the label |
|
Fixed |
Prevents users from hiding/moving the tab |
|
Visible |
Initially have the tab hidden or visible |
|
Settings |
Settings to control the behavior of this instance of tabs |
See Tab Settings section for details. |
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:
|
|
||
IconTheme |
Control the visual style of all built in tabs icons. Valid values are:
|
|
||
Orientation |
Control the rendering of the tabs (vertical/horizontal)
|
|
||
TabDrop |
Feature that automatically "hides" tabs that does not fit on one row (default true) |
|
||
UserReset |
Ability for users to reset the customization (default true) |
|
||
UserRearrange |
Ability for users to change tab order (default true) |
|
||
UserOrientationSwitch |
Ability for users to toggle between horizontal and vertical orientation (default true) |
|
||
UserHide |
Ability for users to hide tabs (default true).
|
|
||
RememberUserSelection |
Enable the feature to automatically save the last selected tab (default true) |
|
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
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).
It supports the following child elements:
Name | Description | Example |
---|---|---|
Label |
A simple text that should be rendered in the badge |
|
Position |
Badge position relative to the tab label. Valid values are:
|
|
Provider |
A provider can be used instead of a
|
|
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. |
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>
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.
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. |
The <Toolbar>
element supports the following attributes.
Java class that points to an implementation of an action handler. See custom action handler
Whether the toolbar should be configured to be rendered in vertical mode. Valid values true
or false
. Defaults to false
.
Whether to render uip-toolbar or default helium toolbar. Valid values true
or false
. Default is false.
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 |
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' |
|
||
FontIcon |
What icon should be rendered next to the label. |
|
||
Image |
What image should be rendered next to the label |
|
||
RegisteredSuite |
Defines the registered suite. This will be used to resolve macros |
|
||
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.
|
|
||
Alt |
Tooltips can be configured for menu by adding <Alt>
|
|
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". |
|
||
Alt |
Option for configuring tooltip other than label |
|
||
FontIcon |
What icon should be rendered next to the label. |
|
||
Image |
What image should be rendered next to the label |
|
||
RegisteredSuite |
Defines the registered suite. This will be used to resolve macros |
|
||
OnClick |
What javascript function should be executed when the
user clicks the command, for example:
|
|
||
OnClickParams |
Additional parameters to send to the javascript function. Usually a javascript object.
|
|
||
ValidFor |
Defines the command is valid for which rows in datatable |
|
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 |
default value of showparents is false |
ExpandAll |
Whether the toolbar should have a button to fully expand all nodes in structure table. |
|
ExportExcel |
Preconfigured command that exports the rows of the table to Excel format. |
|
ExportPDF |
Preconfigured command that exports the rows of the table to PDF format. |
|
ExportCSV |
Preconfigured command that exports the rows of the table to CSV format. |
|
Collection |
Adds a collection menu with below commands to manage businessobjects in Clipboard and Collection.
Refer Customize Collection section for customizations |
|
<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>
<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>
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. |
Yes |
|
resultExpression |
An expression that will be applied to the result from the service invoke. |
Yes |
|
from |
Direction to add the new object to table. |
Yes |
|
selection |
It defines how many object can be selected to perform this action. Default is |
No |
|
refreshBehavior |
It defines how a new node would be added from the result to the table. Default is |
No |
|
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.
ServiceCommand
will be used to configure an OOTB service. XML configure is shown as below.
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&isMultiSel=0&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>
Parameter | Description | Required | Example | ||
---|---|---|---|---|---|
url |
This element defines the URL of intial service. |
Yes |
|
||
header |
The header of the initial service call. |
No |
|
||
body |
The body of the service call. It supports injecting macro statments |
No |
example: |
||
macro |
If we have any macros defined in Body, then this setting needs to be true |
No |
|
||
macroElements |
If we have any macros defined in Body, then that macro elements should be defined in this tag. It requires |
No |
|
||
addCsrfToken |
This setting can be configured as true to put 3dspace csrf token in service request header. |
No |
|
||
addSecurityContext |
This setting can be configured as true to put security context in service request header. |
No |
|
||
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 |
|
||
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 |
|
||
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 |
|
||
successMessage |
User can specify, success messge in translation file (default.json) and use it’s key. |
No |
|
||
resolverPaths |
Service chaining can be configured using |
No |
|
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 |
Here, data[0].dataelements.ticketURL is the part of response object where we get the URL of next service call OR
|
order |
A number value used to define in which order service will be executed. The lowest order number will get executed first. |
Yes |
|
header |
The header of the next service call can be configured for service request. |
No |
|
body |
The body of the service call. It supports injecting macro statments |
No |
` "body":{"fcsjobTicket":"{{data[0].dataelements.ticket}}"}` Here, |
bodyResolver |
It is used to resolve macro statement mentioned inside the |
No |
|
addCsrfToken |
This setting can be configured as true to put 3dspace csrf token in service request header. |
No |
|
addSecurityContext |
This setting can be configured as true to put security context in service request header. |
No |
|
method |
HTTP method/verb that should be used to invoke the next service. Valid values are:
By default it is |
No |
|
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 |
|
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 |
|
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&e6w-lang=en&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&e6w-lang=en&e6w-timezone=-330&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);
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 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 |
|
options |
This element defines Helium’s Form options setting which will looks for config file |
Yes |
|
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 |
|
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 |
No |
|
body |
The body of the service which will be called on the submission of the form. It supports injecting macro statments |
No |
Here, |
bodyResolver |
It is used to resolve macro statement mentioned inside the |
No |
|
addCsrfToken |
This setting can be configured as true to put csrf token in service request header. |
No |
|
addSecurityContext |
This setting can be configured as true to put security context in service request header. |
No |
|
method |
HTTP method/verb that should be used to invoke the service. Valid values are:
|
No |
|
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 |
|
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&xrequestedwith=xmlhttprequest&_=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&_=1613402130670&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>
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>
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&_=1613402130670&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>
The main responsibility of the Dashboard is to hold references to different widgets.
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 |
|
DisableCustomization |
Dashboard customization can be disabled for dashboard. Valid values |
|
Floating |
Whether the dashboard should be floating to the top of the page or not. Valid values |
|
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
|
|
Widgets |
Specifies what Widgets this dashboard should contain. |
|
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.
(*) 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
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.
|
|
||||||
Locked |
Whether the widget should be locked or not. A locked widget can not be customized. Valid values |
|
||||||
Width |
The width of the widget. Valid value: Positive integer between 1 and 12. It supports the following attributes:
|
|
||||||
Height |
The height of the widget. Valid value: Positive integer. It supports the following attributes:
|
|
||||||
X |
Specifies where on the X axis the widget should be placed. Valid value: Positive integer. |
|
||||||
Y |
Specifies where on the Y axis the widget should be placed. Valid value: Positive integer. |
|
||||||
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 |
or
|
||||||
Badge |
This element is used to render a small |
|
<?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>
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.
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.
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.
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
All widgets (DataTable, Form, Charts) or any custom widget as described in the widget tutorial, share the following configuration options.
Name | Description | Example | ||
---|---|---|---|---|
Title |
The title of the widget. Supports macros if a context object exists, e.g. |
|
||
OnInit |
Javascript function that creates the widget.
|
|
||
OnInitOption |
Additional options that is to be passed to the OnInit function. |
|
||
PostRender |
A javascript function that will be executed when the content of the widget has been rendered.
|
|
||
HeaderActions |
By providing a reference to a menu XML file, it is possible to add custom actions to the widget header. |
|
||
ShowActionTooltip |
Whether the header actions tooltip should be visible or not. Default value is true. |
|
||
Html |
HTML that should be rendered inside of the widget container |
|
||
Toolbar |
Describes the toolbar of the widget. For more information, see the Toolbar chapter. |
|
||
Sidepanel |
Describes an optional sidepanel in the widget. For more information see the Sidepanel chapter |
|
||
Access |
Defines access rules. |
See Access Control |
To toggle/replace a widget with another (switching views) you can do the following.
Create the initial widget as described in the Dashboard chapter.
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
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 |
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 |
|
||
Html |
Custom html to be rendered in the widget |
|
||
Closable |
Whether sidepanel will be closed when clicking inside the same widget. Default is false. |
|
||
Toolbar |
A Toolbar definition. It is encouraged to supply the toolbar definition with the
|
|
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
<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.
The <Search>
format supports the following child elements.
Name | Description | Example | ||
---|---|---|---|---|
Limit |
The maximum number of search results returned. |
|
||
Types |
Show only results of the listed 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. |
|
||
Where |
A Where clause, following MQL syntax. Use %s to indicate where to inject the criteria entered by the user performing the search. |
|
||
HitOnClick |
Name of a JavaScript function to execute when clicking on a search result item. The argument passed will be the object ID. |
|
||
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. |
|
||
ResultRenderCallback |
Customize complete search result. Great flexibility but requires custom implementation to handle onclick events, responsiveness etc. |
|
||
SearchProvider |
Search Provider to be used for this search config. If none is specified global Search Provider will used as default.
|
|
<?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>
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.
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>
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. |
|
||||
upperSearchLimitValue |
The maximum number of search results allowed to be displayed.
|
|
||||
DataFields |
The data to include for the search result. For example, type, name, revision and current state. |
|
||||
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. |
|
||||
InitialHitsCount |
The number of hits to display in each section. A "Show more" link is supplied to view more hits. |
|
||||
ShowMoreHitsCount |
The number of additional hits to add to the result when "show more" is clicked. |
|
||||
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. |
|
||||
Settings |
Additional settings for the search. These settings are accessible in |
|
||||
Server |
Triggers executed server-side at different steps during the life-cycle of a search operation. See Server-Side Triggers for more details |
|
||||
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:
|
||||
UIs |
It defines UI elements for rendering search result in a section. See Section UIs for more details. |
|
||||
OpenOnLoad |
Controls if the search panel should be opened by default on load. Default value is false.
|
|
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 |
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. |
|
||
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. |
|
See Custom Section Provider for details on custom 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. |
|
||
Label |
Label can be used to specify title. |
|
||
UIs |
Each section can have multiple UIs elements to render search result. See Section UIs for more details. |
|
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.
|
|
||
Icon |
Icon of UI to be shown for selecting UI. |
|
||
ResultTemplate |
Template for showing search results in section. For built-in template see Built-in Tile Templates |
|
||
TileHitTemplate |
Template to rendering each search hit and applies only to |
|
||
Table |
Table configuration for adding columns and applies only to |
|
||
Settings |
Additional 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. |
|
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. |
|
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. |
|
Command |
Command in the context 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 |
|
OnClickParams |
Additional parameters to passed into command on click. |
|
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>
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>
Template are used to display search result hit in tile mode. Following are the built-in tile hit templates:
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
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 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
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.
Callback function when search is ready. Example configuration:
<Client ready="App.custom.searchReady"/>
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"/>
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"/>
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 |
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 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 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. |
<?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>
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.
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. |
|
DataFields |
The data to include for the search result. For example, type, name, revision and current state. |
|
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. |
|
SearchIcon |
Search Icon for collapsed search panel. |
|
SearchTitle |
Title for collapsed search panel |
|
ResultTitle |
Title for drilldown of search results |
|
Settings |
Additional settings for the search. These settings are accessible in |
|
Server |
Triggers executed server-side at different steps during the life-cycle of a search operation. See Server-Side Triggers for more details |
|
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:
|
HomePage |
Defines page that should be loaded in background, when search is launched via direct or exported URL. See Export Search for more details. |
|
Callback function when search panel is ready. Example configuration:
<Client ready="App.custom.searchPanelReady"/>
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"/>
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 |
|
SearchOnLoad |
Whether to perform search when page is loaded. |
false |
|
OnSearchResult |
Defines what should happen on load of search result. See 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.
|
|
|||
LoadServerSide |
Sub element of |
false |
|
||
Dashboard |
Sub element of
|
|
|||
WidgetId |
Sub element of
|
|
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. |
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>
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 |
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>
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 |
|
tableExpandKey |
Special case when field |
|
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>
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. |
|
Fields |
Available fields in the search form. See Field Configuration Format for details on how to configure each field. |
|
Sections |
Group fields into collapsible sections in the search form. See Section Configuration Format for details on how to configure a section. |
|
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. |
|
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 com.technia.tvc.search.searchform.OnCreateSearchForm |
|
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. |
|
Tooltip |
Tooltip for the field. Displayed when hovering the label.If the value is an existing i18n key internaionalisation will be performed. |
|
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. |
|
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 |
ENOVIA example:
EXALEAD example:
|
DataType |
Type of data to be searched. Valid values:
|
|
UIType |
Kind of user interface user presented to the user. For example, autocomplete, ranges and text. See UI Types for more details. |
|
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. |
|
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:
Part is the default value:
|
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:
Part is the default value:
|
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
|
casesensitive |
case sensitivity for the input value. Default value is false |
|
ConditionalFields |
Additional fields which should be added to search form based on value selected for this field. See Conditional Fields for details. |
|
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 are used for two purposes:
To define the values the user can search by
To define which value that is selected by default
There are a number of ways to control the available values:
Configure a predefined list of values, see below for configuration format
Specify an attribute using the attribute attribute
. Example:
<Values attribute="attribute_MaterialCategory" />
Write a ValueProvider and configure it using the attribute className
, Example:
<Values className="com.acme.MyValueProvider" />
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. |
|
label |
Text presented to the user. If none is provided the value is displayed. Label also supports localization. |
|
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 |
|
default |
Controls if the value is selected by default. |
|
Dimensions are used to allow search with different units for numeric fields.
There are a number of ways to control the available dimensions:
Configure a predefined list of dimensions, see below for configuration format
Specify an attribute using the attribute attribute
. Example:
<Dimensions attribute="attribute_MaterialCategory" />
Write a DimensionProvider and configure it using the attribute className
, Example:
<Dimensions className="com.acme.MyDimensionProvider" />
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. |
|
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 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. |
|
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. |
|
HasValues |
element |
Defines discrete list of values, on which field will be visible. |
|
jsFunction |
attribute on <HasValues> |
Javascript function returning true/false. Arguments passed to function are field id and criteria selected on field. |
|
includeWhenHidden |
attribute |
Defines whether field should be considered in search criteria, when field is not visible. |
|
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 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"/>
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>
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 |
This field uses a text input field and looks in the name field in ENOVIA.
Example:
<NameField />
Field used to select a person. The field uses autocomplete.
Example:
<PersonField>
<Label>Owner</Label>
<DataField>owner</DataField>
</PersonField>
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 |
|
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 |
|
|
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. |
|
defaultMinInteger |
Minimum value for integer type attribute when added dynamically via Classification Field. |
|
defaultMaxInteger |
Maximum value for integer type attribute when added dynamically via Classification Field. |
|
defaultMinReal |
Minimum value for a real type attribute when added dynamically via Classification Field. |
|
defaultMaxReal |
Maximum value for real type attribute when added dynamically via Classification Field. |
|
Classification built-in handler retrieves Family objects in two steps -
Query Library objects
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. |
|
|
rootNamePattern |
NamePattern of top level Library. |
|
|
rootRevPattern |
RevisionPattern of top level Library. |
|
|
rootVaultPattern |
VaultPattern of top level Library. |
|
|
rootWhereClause |
Where clause for querying Library objects. |
|
|
relPattern |
Relationship pattern for expanding Library objects |
|
|
expandTypePattern |
Type pattern for Family or Classification objects. |
|
|
expandWhereClause |
Where clause for expanding Family or Classification objects. |
|
|
queryType |
Following four options are supported:
|
query |
|
searchType |
Defines how user input should be used in finding Family objects. Valid values are:
|
startswith |
|
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.
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.
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 |
A simple input field where a user can enter a text.
Suitable for example when searching in name and description in ENOVIA.
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:
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.
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>
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.
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 |
|
showAllRanges |
If all ranges should be shown. User will need to scroll in case this setting is false. |
false |
|
showRangeAmount |
Number of ranges to show in case showAllRanges is false. |
5 |
|
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 |
|
hideRangesWithZeroCount |
Controls if ranges with count zero should be hidden. |
false |
|
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 |
|
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 |
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 |
|
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' |
|
useOldDatePicker |
Displays older date picker for selection (depreciated) |
false |
|
The old date picker using the setting useOldDatePicker is depreciated and might get removed in future releases. |
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:
<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 |
|
min |
The minimum value that is selectable. This setting is mandatory in case the slider is displayed. |
|
|
max |
The maximum value that is selectable. This setting is mandatory in case the slider is displayed. |
|
|
unit |
A unit to display next to the input fields, e.g. $ and g. |
|
|
searchWithUnit |
should the field allow search with available dimensions for numeric types. |
false |
|
step |
Increments when changing the value using the slider. |
1 |
|
precision |
Decimal precision for the field. |
1 |
|
valuesInclusive |
Includes the specified ‘from’ and ‘to’ values |
true |
|
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:
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.
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.
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.
Following settings are supported by Treefield:
Setting Name | Description | Default | Example | ||
---|---|---|---|---|---|
showValueCount |
Whether to show count against the node if provided by TreeHandler. |
true |
|
||
selectChildren |
Whether child nodes should be auto selected on selecting parent node.
|
false |
|
||
submitOnlyParent |
Whether to submit only parent node when child nodes are auto selected.
|
false |
|
||
showAllNodes |
Whether to show all nodes or show limited number of nodes with scroll. |
false |
|
||
showNodesCount |
How many node should be visible, after which scroll will be shown. |
5 |
|
||
loadOptions |
A JSON configuration object used to define TreeHandler and other sub settings needed by TreeHandler. See Tree Handlers for more detail. |
|
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>
Predefined values can be used to load root nodes when used together with a TreeHandler. |
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 |
false |
|
valueKey |
Key which should be used to retrieve value from added child node. |
value |
|
labelKey |
Key which should be used to retrieve label from added child node. |
label |
|
There are two built in TreeHandlers:
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>
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. |
|
rootNamePattern |
Name pattern to quering the root nodes. |
|
rootRevPattern |
Revision pattern to quering the root nodes. |
|
rootVaultPattern |
Vault pattern to quering the root nodes. |
|
rootWhereClause |
Where clause that should be applied while quering the root nodes. |
|
disableRoots |
Whether root nodes should be disabled for selection. |
|
typePattern |
Type pattern for expanding root and other nodes. |
|
relPattern |
Relationship pattern for expanding root and other nodes. |
|
relWhereClause |
Relationship where clause for expanding root and other nodes. |
|
objectWhereClause |
Object where clause for expanding root and other nodes. |
|
displayMacro |
displayMacro for showing lable of expanded child nodes. |
|
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>
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.
|
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 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.
The root element is <Section>
and the following child elements and attributes are supported:
Name | Description | Example | ||
---|---|---|---|---|
id |
Attribute on
|
|
||
Label |
The label for the section. I18n is supported through string resources file. |
|
||
Tooltip |
Tooltip for the field. Displayed when hovering the label. |
|
||
Expanded |
Whether section should be expanded on load of searchform. Default value is true. |
|
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.
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>
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
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
|
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. |
<?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 can be configured inline within a searchform
. Command/Menu can be configured in a separate file and added to the toolbar element.
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>
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. |
|
Alt |
Tooltip for the command. Displayed when hovering the label. |
|
FontIcon |
Icon for the command. Displayed left of the label. |
|
Setting |
Setting with name and value can be passed to include onClick and other required information. |
|
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. |
|
Alt |
Tooltip for the menu. Displayed when hovering the label. |
|
FontIcon |
Icon for the menu. Displayed left to the label. |
|
Command |
Commands for this menu visible as dropdown elements on clicking the menu. |
|
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. |
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" />
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 |
|
where |
A custom where clause can be passed to search provider. For example it can be used to search only non-obsolete parts. |
none |
|
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 |
|
|
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" />
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 |
|
xl:sortField |
Field on which search should be sorted. |
none |
|
xl:sortOrder |
Sort order of search result. |
ascending |
|
xl:enableWildcardSearch |
Whether to add wildcard to term search. |
false |
|
xl:inlcudeFacets |
Whether to include facets or field counts. |
true |
|
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.
|
FIRSTREVISION |
|
xl:lastRevision |
Exalead key for last revision.
|
LASTREVISION |
|
xl:latestRevision |
Exalead key for latest revision.
|
LATESTREVISION |
|
xl:lastAndLatestRevision |
Exalead key for lastAndLatestRevision revision.
|
LASTANDLATESTREVISION |
|
xl:showZeroCount |
Whether '0' should be shown when Exalead count for a field value is 0. |
false |
|
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 |
getDataFields |
|
getSettings |
Custom |
getSectionProvider |
Section Provider to be used for sectionizing search results. Refer Built-in Section Provider for default implementation. |
getSearchForm |
Instance of |
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
|
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.
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
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'})
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}
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
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>
A loader alerts a user to wait for an activity to complete.
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
.
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.