05 May 2016

Table of Contents

© Copyright 2015-2019 by TECHNIA AB

All rights reserved.

PROPRIETARY RIGHTS NOTICE: This documentation is proprietary property of TECHNIA AB. In accordance with the terms and conditions of the Software License Agreement between the Customer and TECHNIA AB, the Customer is allowed to print as many copies as necessary of documentation copyrighted by TECHNIA relating to the software being used. This documentation shall be treated as confidential information and should be used only by employees or contractors with the Customer in accordance with the Agreement.

This product includes software developed by the Apache Software Foundation. (http://www.apache.org/).

2. TVC Helium

2.1. What is it?

The Technia Value Components (TVC) product suite has existed for 10+ years, and contains well-established products such as Structure Browser, Graphic Reporting and File Manager. TVC Helium is the new version of these components, with the first General Availablity release in May of 2016.

Please note that not all features and functionality of TVC Classic have been implemented in TVC Helium.

2.2. Which are the differences compared to TVC Classic?

The progress of HTML5, JavaScript and web browsers enable us to move HTML rendering and parts of the business logic to the client side, within the end-user’s web browser.

  • You will likely use JavaScript more, but Java is still the backend language.

  • You will no longer render HTML on the server, but instead populate HTML templates on the client, which you will pass JSON response into.

2.3. What are the benefits?

Helium components are designed to be as efficient as possible in terms of reducing server requests, and they support consuming data from any backend serving JSON data. Server calls made by Helium do not return entire prerendered HTML pages - only the JSON data needed to populate the views, which are already cached on the client. This makes server requests both fewer and smaller, leading to benefits in terms of reduced data traffic and shorter load times. In short: Helium is faster and generates less server load.

TVC Helium pages consist of column based grids or dashboards, with all your data placed inside rearrangeable widget containers. This allows for a responsive, customizable design and seamless adoption to mobile devices. Helium is designed with the flat design concept in mind, for a modern, very lightweight look and feel. In short: Helium looks modern and it works on mobile devices.

3. System requirements and supported platforms

In general, TVC Helium supports the same operating systems and backend stacks as TVC Classic. However, due to the shift towards client side driven logic and extended use of HTML5 and next-gen JavaScript, Helium has additional requirements on the web browsers.

Browser support is therefore limited to so-called evergreen web browsers, which means browsers that are automatically updated. Firefox and Internet Explorer 11 belong in this category, whereas older Internet Explorer versions do not. Google Chrome is also supported for Helium in standalone mode.

For Helium in embedded mode with Internet Explorer, see IE Compatibility mode.

As TVC Helium is responsively designed, and therefore can be used on mobile devices, these browsers are also supported. For details on Mobile support, see OS and browser support.

4. Installation

Prior to installing TVC Helium, you must install TVC Classic in the same release version (e.g. 2019.4.0 for both installers).

TVC Helium does not contain any schema entities, hence the items being installed are solely web-application related files.

TVC Helium is distributed as an installer, one for Windows and one for UNIX like systems.

These installers will guide you through the installation and you will only need to answer a few questions.

After completing the installation, don’t forget to setup your Helium.xml configuration file, which controls elements like the login page, start page and commands in the topbar menu. An example file is included with the deployed webapp folder.

4.1. Silent Installation

You may install TVC Helium in silent mode. See example command below for details:

./tvc-helium-2016.1.0.sh -silent -exploded -target=/opt/enovia/webapps/helium

4.2. /META-INF/web-fragment.xml

The TVC Helium JAR file contains a /META-INF/web-fragment.xml, which contains the necessary web application descriptor content for Helium to work in a standard J2EE Web Application.

If you install to a web-application that has the metadata-complete="true" set in the WEB-INF/web.xml file, you need to manually configure your web.xml file and include the necessary configurations for Helium to work.

The web-fragment.xml file that is part of Helium looks like this:

<?xml version="1.0" encoding="UTF-8"?>
<web-fragment xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
	xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-fragment_3_0.xsd"
	id="tvc-helium" version="3.0">

	<filter>
		<filter-name>routing-filter</filter-name>
		<filter-class>com.technia.helium.core.routing.RoutingFilter</filter-class>
	</filter>
	<filter-mapping>
		<filter-name>routing-filter</filter-name>
		<url-pattern>/goto/*</url-pattern>
	</filter-mapping>

	<welcome-file-list>
		<welcome-file>/helium/main.jsp</welcome-file>
	</welcome-file-list>

</web-fragment>

4.3. IE Compatibility mode

Helium does not support ie compatibility mode but there are ways tell the browser to ignore this setting. Helium in standalone mode add these tags by default. For Helium embedded in tvc classic there is a filter that can be added to the web.xml that does the same.

Add to Web.xml

<filter>
      <filter-name>IECompatabilityFilter</filter-name>
      <filter-class>com.matrixone.apps.domain.util.IECompatabilityFilter</fil
ter-class>
      <init-param>
         <param-name>http-equiv</param-name>
         <param-value>X-UA-Compatible</param-value>
      </init-param>
      <init-param>
         <param-name>content</param-name>
         <param-value>IE=edge</param-value>
      </init-param>
   </filter>
   <filter-mapping>
      <filter-name>IECompatabilityFilter</filter-name>
      <url-pattern>*.jsp</url-pattern>
   </filter-mapping>
   <filter-mapping>
      <filter-name>IECompatabilityFilter</filter-name>
      <url-pattern>*.htm</url-pattern>
   </filter-mapping>
   <filter-mapping>
      <filter-name>IECompatabilityFilter</filter-name>
      <url-pattern>*.html</url-pattern>
   </filter-mapping>

4.4. Caching Client Resources

This feature requires https

Helium can use Service Workers to cache some service (dynamic) and static resources (.js, .css, .png etc.) so that they are served from the cache instead of making network requests.

4.5. Post Installation Configuration

4.5.1. Security Context in Helium

If security context is enabled for the 3DExperience platform and users wish to use it while working with Helium then administrators can enable it for them by configuring below entry in tvc.properties or as init-param in web.xml with value true. tvc.core.login.useSecurityContext = true

5. Helium on Mobile devices

Being dashboard based, Helium is designed to work very similarly on a mobile device, compared to a computer. Some UI elements like the Topbar, are adjusted to better fit the screen size and orientation. Widgets are stacked vertically if they do not fit side by side. Elements such as icons may also become a bit larger, to increase touch screen usability.

On a mobile device, you may also leverage even more of the Progressive Web App characteristics. Read more about this in the following section.

5.1. OS and browser support

TVC Helium is continuously tested and validated with latest versions of Apple iOS (with Safari as browser) and Android (with Chrome), on both mobile and tablet devices.

Please note that some features of Helium may be unavailable on handheld devices, and some behaviour may on the other hand be exclusively applicable for handheld devices (such as device vibration or a different notification mechanism).

5.2. Progressive Web App

The Progressive Web App design approach to a web application is in part enabled by the Service Worker browser capability, that enables caching of data for later use. This, along with SSL, are prerequisites for using Helium in Offline mode. Please refer to the Cache section to learn about ServiceWorkers and which tvc.properties exist to enable it, also guaranteeing that static files like JS and CSS are cached by the browser.

5.3. Installable behaviour

With the Helium webapp folder, a manifest file called manifest.json is deployed. When a user opens the Helium webapp URL in their browser, the browser will prompt* the option to install the Helium webapp.

image
Figure 1. Chrome prompting user to install the app

If the user accepts, they can then launch the webapp independently of their web browser, with a native-like behaviour, that minimizes the URL bar to give the webapp UI the fullcreen size. When multi tasking between applications, the app will also look and behave like a native app.

*behaviour varies depending on browser.

On iOS/Safari, manually adding the App to Homescreen may be needed.

image image

5.3.1. 3DPassport specifics

In a 3DExperience environment with 3DPassport, it may be necessary to exclude this file from the default servlet filters. Below you can find an example on how to do this.

<filter>
   <filter-name>CAS Validation Filter</filter-name>
   <filter-class>com.dassault_systemes.dspassport.cas.client.validation.DynamicServiceUrlCas20ProxyReceivingTicketValidationFilter</filter-class>
   <init-param>
   <param-name>skipFilterUrlPatterns</param-name>
   <param-value>/helium/manifest.json</param-value>
   </init-param>
</filter>

<filter>
   <filter-name>CAS Authentication Filter</filter-name>
   <filter-class>com.dassault_systemes.dspassport.cas.client.authentication.DynamicServiceUrlAuthenticationFilter</filter-class>
   <init-param>
   <param-name>skipFilterUrlPatterns</param-name>
   <param-value>/helium/manifest.json</param-value>
   </init-param>
</filter>

5.4. Offline functionality

If the Helium webapp detects that you have lost your network connectivity, it will indicate the offline status with a CSS class on the body element. You can then choose how this will be rendered in UI; using our examples you can e.g. color the Topbar element gray to indicate that you are not currently connected.

To keep using Helium offline in scenarios like this, you can leverage features like cached navigation to your previously visited Helium pages. To set this up, please refer to the example configuration, which you can customize for your needs.

In addition, it’s also possible to manually save object pages, e.g. for planned offline scenarios. To configure this behavior, please see Saving object pages for offline access.

5.5. Scan QR/ EAN/ DataMatrix Codes

A command can be added in the topbar or in any widget toolbar to allow scanning of QR, EAN and DataMatrix codes. By default, if the scanned content is detected as Enovia/ 3DEXPERIENCE object id, the framework will open corresponding object else it’ll perform a search for the matched content. The default behavior can be overridden by providing a callback, onScanComplete. Once the framework detects a code, it’ll invoke the callback with the scanned content.

5.5.1. Configuration

Following examples demonstrate how a command can be configured

  • Topbar

  <Command>
      <Label>Scan Code</Label>
      <FontIcon>qrcode icon</FontIcon>
      <URL href="javascript:App.scanner.create({options: {'onScanComplete': App.hex.onCodeDetect}});" />
  </Command>
  • Widget Toolbar

  <Command>
      <Label>Scan Code</Label>
      <FontIcon>qrcode icon</FontIcon>
      <OnClick>App.scanner.create</OnClick>
      <!-- Optional -->
      <OnClickParams>{
        "onScanComplete": "App.hex.onCodeDetect"
       }
       </OnClickParams>
  </Command>

By default, back camera will be used to scan codes. It is also possible to have programmatic control over the scanner (for e.g. scan with own preferred camera) using JavaScript. More information on how to do so can be found in App.Scanner JS documentation.

Scan QR/ EAN/ DataMatrix Codes

5.5.2. Supported Code formats

EAN-8, EAN-13, Code 39, Code 128, ITF, RSS-14, QR Code, Data Matrix

5.5.3. Supported browsers

  • Chrome on desktop

  • Firefox on desktop

  • Android: stock Chrome browser on newer versions

  • iOS: Safari on iOS 12.3+ on iPhone and iPad

5.6. Vibration

A javascript call can add vibration feedback for supported devices. For more information see the App.Utils JS documentation.

App.Utils.vibrate();

5.7. Table pagination swipe

It is now possible to jump between datatable pages by swiping left or right on the table. Feature is not supported for nonresponsive tables.

6. Routing General

In Helium, each business object the user is visiting is mapped to a page that defines the content to display. The mapping between business object and page is made within the main configuration file, called Helium.xml.

An example snippet of such a mapping is shown below:

<PageMapping>
   <!-- Route to displaying 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>
    ...

The page mappings are read in the order they are defined, and the first match will define how the page is configured (e.g. the Dashboards / Widgets).

6.1. Route - URL Mapping

The routing framework in Helium is mapped to the following URL pattern:

/goto/*

This means that any URL that contains the /goto/…​ relative from the context root will reach the Helium routing filter.

If the user is not logged in, e.g. the session has expired or the user clicks on a saved link, the routing framework will redirect the user to the login page that has been configured for Helium.

After login, the login mechanism together with the routing framework will try to resolve the link again, so that you are redirected to where you initially tried to navigate.

6.2. Route to Object

The URL to a particular business object is by default:

http://server:port/app/goto/o/Type/Name/Revision
                           ^^^

The first path part after the /goto url is /o, which will trigger the object route mapping logic.

The URI after /goto/o/ must contain at least the Type and Name. If the third parameter (revision) is omitted, the routing framework will make a query and find the latest revision of the object having the specified Type and Name.

Example URL:

http://192.168.0.1:8080/app/goto/o/Hardware+Part/A-000002/6
For security reasons, the URI may not contain wild-cards such as * or ?. In such cases, an exception is thrown.

6.3. Route to Global Page

A global page is a page that does not require a business-object as context. A global page is typically used as the first page the user see in Helium after login. The URL to a global page is by default:

http://server:port/app/goto/p/NameOfPage
                           ^^^

This will map to the page tvc:page/NameOfPage.xml.

If you want to map to a page in a sub-domain, see the next example:

http://server:port/app/goto/p/domain/subdomain/NameOfPage

This would then map to the page resource tvc:page:domain:subdomain/NameOfPage.xml.

You should omit the .xml suffix in the URL

See this page for more information about server side configuration within XML files.

6.4. Route to Dashboard

Routing to dashboard is typically used when embedding a Helium dashboard in another application, e.g. 3DExperience. Read the embedding chapter for more details.The URL to a dashboard is by default:

http://server:port/app/goto/d/NameOfDashboard
                          ^^^

This will map to the dashboard tvc:dashboard/NameOfDashboard.xml.

The dashboard may either have a context or be context-less. A widget in a dashboard showing details for a specific part is an example of a dashboard with context and a widget in a dashboard listing recently visited object is a example of a dashboard without context. Use the parameter objectId to specify the context object.

Example showing a part details dashboard with a context:

http://server:port/app/goto/d/PartDetails?objectId=1.2.3.4

6.5. Route to Widget

Routing to widgets is typically used when embedding a single Helium widget in another application, e.g. 3DExperience. Read the embedding chapter for more details.

The URL to a widget is by default:

http://server:port/app/goto/w/NameOfWidget
                           ^^^

This will map to the widget tvc:widget/NameOfWidget.xml.

Mapping to widgets in sub-domains works in the same way as when routing to pages.

The widget may either have a context or be context-less. A widget showing specifications for a specific part is an example of a widget with context and a widget listing recently visited object is a example of a context-less widget. Use the parameter objectId to specify the context object.

Example showing a specification widget with a context:

http://server:port/app/goto/w/Specifications?objectId=1.2.3.4

When routing to a widget the Helium page is rendered without the topbar menu and the widget rendered as headerless.

Note that actions in the header are not available when the widget is displayed in headerless mode. For example, it’s not possible for users to reset customizations unless an action is added inside the widget (e.g. in the toolbar).

Drill down in widgets is not supported when routing to a widget
Actions that interacts with other widgets or the sidepanel are not supported when routing directly a widget. For example, the workflow chart and discussion column in a table will not work as it uses the sidepanel. If you want such functionality, you can use the Page action, which not only contains a Widget, but the full Page, including any configured Sidepanel.

6.6. Route to File

The routing framework also handles files that are checked-in to a business object. The URL to a particular file is by default:

http://server:port/app/goto/f/Object-ID/Format/File-Name
                           ^^^

The first path part after the /goto url is /f, which will trigger the file download mechanism.

Even though this routing logic exists, it will typically only be used internally in Helium.

7. Extended Configuration

7.1. Theme support

There are currently three different UI themes included with TVC Helium out of the box. The default theme "light" is a gray-ish. It’s also suitable if you want to build your own theme from scratch.

image

The second theme, called "flat", is a bit more inspired by material design, and will evolve towards using more colors, icons and other visual elements.

image

The third theme, called "blue", is a bit more inspired by Enovia out of the box, that easily blends in if you are using Helium in embedded mode. This theme will be automatically applied on Helium in embedded mode. To disable this behavior, use tvc.helium.embed.forceConfiguredTheme=true in tvc.properties. The default value is false.

image

The fourth theme named "white", which easily blends with 3DDashboard. This theme will automatically applied when helium is embeded in 3DDashboard. To disable this behavior, use tvc.helium.embed.forceConfiguredTheme=true in tvc.properties. The default value is false.

To switch between themes, change the tvc.properties as below: tvc.helium.theme.current=flat where the value can be flat, blue,white or light (default).

7.1.1. Dark Theme

Dark theme makes it easier for users to use the application in low-light environment and improves visibility. On mobile devices, it can also save battery life.

image

Every theme available in application has its dark mode and user can switch to dark mode by using Themes Menu.

User’s theme preferences are persisted at application level.

Native OS dark theme is also supported. This means that Helium reads your OS display preferences (Light or Dark) from Windows, Android, iOS or Mac OS and automatically applies it within Helium, unless you actively choose another theme from the Theme menu

Dark theme is not supported in Internet Explorer.

7.2. Custom Resources (Scripts, Stylesheets)

TVC Helium allows including custom scripts and stylesheets and make them available to the client.

Simply putting the files to be included somewhere below /helium/custom and the TVC Helium framework will automatically pick them up for inclusion on the main.jsp page. A good recommendation is to use the following structure for the files.

/helium/custom/js
/helium/custom/css
Script files must have the suffix .js and stylesheets .css otherwise they will NOT be included.

In a production environment, the number of requests made by the client to the server should be as low as possible.

Try to concatenate and minify the scripts and stylesheets into a single file for optimal performance.

Ensure that TVC is running in production mode in production systems. This will force Helium to use its own concatenated files instead of requesting multiple scripts and/or stylesheets. Read more about Production mode in the admin guide for TVC Core.

7.3. Auto Coloring

Coloring gives better visual identity than plain text. Helium supports auto coloring for table columns and chart. This will help in maintaining consistency in color for a given text within the application.

This auto coloring by default enable for charts and table columns it can be configured.

For charts and datatable column, helium will map each string to color, and then these string value will appear in unique color in all over application.

It is by default enable for all charts. However, A Setting can be configured at column as follows

<Column>
  ...
  <Setting name="Colorable" value="true" />
  ...
</Column>
image
Figure 2. Auto Coloring

7.3.1. Fixed color mapping

It is also possible to assign a fixed color to a specific text. This will be helpful in assigning more meaningful color to text. For example, active can be green color and inactive can be red color.

The mapping files can be defined with name colorMapping.json at <webapp-root>/helium/custom/color.

The framework will first look for file inside <webapp-root>/helium/custom/color with name colorMapping.json, if no suitable file is found, it will fall back to file defined in <webapp-root>/helium/color with name colorMapping.json.

Following is example colorMapping.json file

{
    "In Work": "#6C7075",
    "Frozen": "#bbe116",
    "Released": "#8FCE00",
    "Obsolete": "#FFD966",
	"Material" :"#ccd5d4"
}

7.3.2. Auto colorable builtin handlebars template

Handlebar template defined to add customized look and feel to table column. A builtin auto colorable handlebar template is available for table column. It can be configured on column as follows:

<Column>
  ...
  <Setting name="template" value="helium/templates/table/autocolorable" />
  ...
</Column>

7.4. Custom Translations (i18n)

UI labels and other information that needs to be translated should be kept inside translation files, which are in JSON format.

Helium contains built-in translations located in the directory /helium/lang. There is a file called default.json that contains the built-in translations used internally by Helium. The files below /helium/lang should NOT be changed.

To customize the translations and/or provide translations required by your custom logic, you should put your own translation file below:

/helium/custom/lang

The base language you support should be put into the file /helium/custom/lang/default.json.

Translations go into locale specific files, example:

  • /helium/custom/lang/en_us.json

  • /helium/custom/lang/en.json

  • /helium/custom/lang/sv_se.json

  • …​

You can also maintain translations in modules structure.

  • /helium/custom/lang/projects/default.json

  • /helium/custom/lang/projects/en_us.json

  • /helium/custom/lang/projects/en.json

  • /helium/custom/lang/projects/sv_se.json

  • /helium/custom/lang/parts/default.json

  • /helium/custom/lang/parts/en_us.json

  • /helium/custom/lang/parts/en.json

  • /helium/custom/lang/parts/sv_se.json

  • …​

The data must be well-formed JSON data, if not, the application does not load correctly. It is wise to run a validation tool to sanity check the JSON files before deployment.

Please read more here.

7.5. Data Handlers

In many cases there is a need to select more complex data structures from an object and/or relationship, or deal with different kind of business rules. One place where you can do this is via so called data handlers.

Data Handlers is a concept that has been around in TVC since many years. It is a well proven way of doing these kind of things, and it allows you to do so without comprimising the performance.

Data Handlers are deeply described in the TVC Classic documentation package, both within the developer documentation as well as in the administration guides.

One important thing to remember when using Data Handlers in the context of TVC Helium, is that the data (normally kept inside instances of different Cell implementations) works in a slightly different way. E.g. since the consumer of the data is logic that is executed on the client, there must be possibilities to transfer custom data structures down to the client. The TVC Helium Framework has solutions for this.

7.5.1. JSONWriteable

Data handlers are responsible for creating Cell instances. A Cell in its simplest form is an instanceof a StringCell, IntCell, RealCell or BooleanCell, etc. These cells are simple because they typically only contain a single value or an array of values.

In more complex situations, you need to keep track of more information than just a literal value, and you need to manage it in a special data structure. So how do you transfer such data structure to the client? The solution is to let your Cell implementation also implement an interface called com.technia.tvc.core.util.json.JSONWriteable.

This interface has one method:

void toJSON(JSONWriter writer)

So letting your cell implement this interface and implement the toJSON method will let you transfer any kind of data structure to the client, where in most cases you will pass the JSON data into a Handlebar template that will render and display this data.

7.6. Cell Renderers replaced by Templates

In TVC Helium, you will not perform any HTML creation on server side. All HTML is created on the client, typically by using so called Handlebars templates. In general terms, this will mean that you will create a file containing a snippet of HTML, with {{brackets}} inserted where you want to display your data or perform logic on it.

Helium’s client side rendering means that features from TVC Classic like Cell Renderers, Field Renderers etc are NOT supported.

You can read more about Handlebars (a superset of Mustache) in their own documentation, at http://handlebarsjs.com

7.7. File Manager

7.7.1. Firefox Extension Alert

Firefox does not allow the side loading of the web extensions which fails to auto install the file manager plugin.

To address this issue, We have enabled a feature to show an alert message in firefox so that user can add the plugin manually by clicking the url available on the message. If user does not want to install the filemanager web extension, user can continue with fallback HTML UI and in that case user needs to disable the alert message by clicking on the button which says Do not show this message again.

tvc.office.filemanager.extension.firefoxInstallAlert=true
Default value is set to false.
image
Figure 3. Filemanager extension alert for firefox.

7.8. Session timeout notification

Sometimes when user tries to edit some field but due to session timeout those changes might not get saved and he has to type in the value. To save these efforts a notification is shown to the user when session is timed out.

image
Figure 4. Logout Notification

This can be enabled by configuring below in tvc.properties

tvc.helium.showTimeoutAlert= true // defaults to false

In order to get this notification before getting timedout, this can configured as below:

tvc.helium.timeoutAlert= 60 // seconds

After adding abover property in tvc.properties user will get notifcaiton 60 seconds prior to the timeout so that they can save unsaved changes.

7.9. Invoke Services

7.9.1. Subscription

3DExperience provides different services for subscription actions - Subscribe, Unsubscribe, Edit Subscription, and My Subscriptions. Helium provides provisions to make use of these services and perform the respective actions.

Invoke Service is generic capability in Value Component using which different 3DExperience services can be called. These existing services can be used to load data into table/widget or call the action from the toolbar

Subscribe

3DExperience provides a service to subscribe for events of a particular object for the context user. Helium provides a provision to add command subscribe in the toolbar of a datatable to facilitate subscribe. This command can be configured as below:

<Command>
	<Label>Subscribe</Label>
	<FontIcon>bell icon</FontIcon>
	<OnClick>App.ootbServices.subscribe</OnClick>
	<OnClickParams>{
		"selectionCriteria" : "multi",
		"serviceUrl":"resources/v1/modeler/subscriptions"
		}
	</OnClickParams>
</Command>
Unsubscribe

3DExperience provides a service to unSubscribe for events of a particular object for the context user. Helium provides a provision to add command unSubscribe in the toolbar of a datatable to unSubscribe and object’s events for the context user. This command can be configured as below:

<Command>
	<Label>Unsubscribe</Label>
	<FontIcon>bell slash icon</FontIcon>
	<OnClick>App.ootbServices.unSubscribe</OnClick>
	<OnClickParams>{
		"selectionCriteria" : "multi",
		"serviceUrl":"resources/v1/modeler/subscriptions"
		}
	</OnClickParams>
</Command>
Edit Subscriptions

3DExperience provides a service to edit subscriptions where we can choose to add or remove events on a particular object or group of objects' subscription. Helium provides similar functionality, edit subscriptions can be added as a toolbar command and configured as below:

<Command>
	<Label>Edit</Label>
	<FontIcon>pencil alternate icon</FontIcon>
	<OnClick>App.ootbServices.editSubscription</OnClick>
	<OnClickParams>{
		"selectionCriteria" : "multi",
		"eventsSubscribed": "dataelements.eventsSubscribed",
		"objEventList_NLS": "dataelements.objEventList_NLS",
		"objEventList": "dataelements.objEventList"
		}
	</OnClickParams>
</Command>

There are a few parameters that can be configured in OnClickParams

Name Description Example

eventsSubscribed

JSON path expression for events subscribed from the response of service call

"eventsSubscribed": "dataelements.eventsSubscribed"

objEventList_NLS

JSON path expression for available events(internationalized) for selected objects from the response of service call

"objEventList_NLS": "dataelements.objEventList_NLS"

objEventList

JSON path expression for available events for selected objects from the response of service call

"objEventList": "dataelements.objEventList"

There is an option to provide a parameter called serviceUrl where we can specify a URL to make service calls for subscribe/unSubscribe/edit Subscriptions in OnClickParams. This parameter is optional and if no serviceUrl is specified default service will be used.
My Subscriptions

3DExperience provides a service which gives list of all subscribed objects for the context user. Helium provides a provision to make use of the service call and populate data in the table directly form the received response. As this table is populated from response, display mode will be flat. Refer configurations related to populating table data from response of service call TableConfig, ColumnConfig

The subscription services are available from versions V6R2022x FP2250, V6R2023x FP2306 and can be used in versions starting with them or above.

8. Components

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

8.1. Helium

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

This file is responsible for the following.

  • The name of the application

  • The login page of the application

  • What pages should be accessible and to which users

  • What the application topbar should contain

8.1.1. Configuration

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

Name Description Example

Name

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

<Name>ACME</Name>

LoginPage

Describes the LoginPage

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

Sidepanel

Describes the PageSidepanel

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

DateFormat

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

<DateFormat>MMM DD, YYYY</DateFormat>

DateTimeFormat

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

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

StartPage

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

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

TopBar

Specifies what the TopBar should contain.

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

PageMapping

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

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

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

Name Description Example

Path

The path to the login page.

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

Title

The title of the login page

<Title>
    Login to Helium
</Title>

FormTitle

Specifies what title the login form should have.

<FormTitle>
    Welcome to Helium
</FormTitle>

FormSubTitle

Specifies what sub title the login form should have.

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

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

image
Figure 5. Top Bar

The <TopBar> element supports the following child elements.

Name Description Example

ShowAppName

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

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

TooltipSettings

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

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

Left

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

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

Middle

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

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

Right

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

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

ShowBreadcrumb

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

<ShowBreadcrumb>true</ShowBreadcrumb>

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

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

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

image
Figure 6. Breadcrumb

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

Mobile Breadcrumb

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

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

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

Separator

Will render a horizontal separator

<Separator />

Menu

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

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

Command

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

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

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

An example of such a menu is Recently Viewed objects.

Options
Name Description Required Example

dynamicmenu

Defines a menu as a dynamic menu

true

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

href

Ajax endpoint to fetch JSON data for dynamic content

true

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

id

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

false

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

template

Reference to Handlebars template to render content on client

false*

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

onActivate

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

onActivate and/ or template should be provided.

false*

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

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

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

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

image
Figure 7. Recent Objects Menu

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

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

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

image
Figure 8. Themes Menu

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

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

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

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

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

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

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

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

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

The <PageMapping> element supports the following child elements.

Name Description Example

Page

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

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

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

FallbackPage

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

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

8.1.2. Example

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

    <Name>ACME</Name>

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

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

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

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

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

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

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

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

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

</Application>

8.2. Page

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

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

image
Figure 9. Page

8.2.1. Configuration

The <Page> element supports the following child elements.

Name Description Example

Title

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

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

Dashboard

Points to a reference to a Dashboard instance.

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

Tabs

Configures a list of Tabs

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

Sidepanel

Configures sidepanel Sidepanel

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

Settings

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

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

Access

Defines access rules.

8.2.2. Example configuration

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

8.3. Page Sidepanel

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

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

The <Sidepanel> element supports the following child elements.

Name Description Example

Label

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

<Label>Sidepanel</Label>

OnInit

Javascript function that creates the widget.

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

OnInitOption

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

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

8.3.1. Javascript API

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

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

8.3.2. Custom Sidepanel Component

An Example Sidepanel component class with required methods in ES2016

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

    ExampleSidepanel.prototype = {

        constructor: ExampleSidepanel,

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

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

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

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

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

    App.Example = { Sidepanel : ExampleSidepanel };

8.3.3. Example

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

8.4. Tabs

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

image

8.4.1. Tabs configuration

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

Name Description Example

Label

The text that should be rendered in the tab

<Label>Tab 1</Label>

Tabs

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

<Tabs>...</Tabs>

CacheBehaviour

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

disabled

the tab will not be cached

preload

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

cache

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

<CacheBehaviour>
    preload
</CacheBehaviour>

Dashboard

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

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

Badge

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

See Tab Badge chapter for configuration syntax

See Tab Badge section for example

Access

Defines access rules.

CustomClass

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

<CustomClass>
    wide yellow
</CustomClass>

IconClass

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

<IconClass>
    fa fa-cog
</IconClass>

Fixed

Prevents users from hiding/moving the tab

<Fixed>true</Fixed>

Visible

Initially have the tab hidden or visible

<Visible>false</Visible>

Settings

Settings to control the behavior of this instance of tabs

See Tab Settings section for details.

8.4.2. Tab Settings

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

It supports the following child elements:

Name Description Example

Theme

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

classic

Classic tabs (default)

material

Material design style

menu

Menu/Toolbar look and feel

<Theme>material</Theme>

IconTheme

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

black

Black icons, no colors (default)

material

Material design style (color)

<IconTheme>material</IconTheme>

Orientation

Control the rendering of the tabs (vertical/horizontal)

horizontal

Horizontal orientation (default)

vertical

Vertical orientation

<Orientation>vertical</Orientation>

TabDrop

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

<TabDrop>true</TabDrop>
tvc.properties

tvc.core.gui.tabPage.enableTabDrop=true

UserReset

Ability for users to reset the customization (default true)

<UserReset>true</UserReset>
tvc.properties

tvc.core.gui.tabPage.enableReset=true

UserRearrange

Ability for users to change tab order (default true)

<UserRearrange>true</UserRearrange>
tvc.properties

tvc.core.gui.tabPage.enableTabCfg=true

UserOrientationSwitch

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

<UserOrientationSwitch>true</UserOrientationSwitch>
tvc.properties

tvc.core.gui.tabPage.enableOrientationSwitch=true

UserHide

Ability for users to hide tabs (default true).

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

tvc.core.gui.tabPage.enableCloseButton=true

RememberUserSelection

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

<RememberUserSelection>true</RememberUserSelection>
tvc.properties

tvc.core.gui.tabPage.rememberSelection=true

8.4.3. Tab Customization

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

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

tvc.core.customization.maxContentSize

default value: 100000 Characters

8.4.4. Tab Badge

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

image

It supports the following child elements:

Name Description Example

Label

A simple text that should be rendered in the badge

<Label></Label>

Position

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

right

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

left

Rendered to the left side of the tablabel

<Position>left</Position>

Provider

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

mqlcount

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

java

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

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

8.4.5. Deeplinking to tab

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

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

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

8.4.6. Example

This is placed within an Page element.

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

Example with child tabs:

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

8.5. Toolbar

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

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

8.5.1. Toolbar configuration

The <Toolbar> element supports the following attributes.

actionHandler

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

vertical

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

showUipToolbar

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

isCustomizable

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

The toolbar element supports the following child elements.

Name Description Example

Menu

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

See specific Menu configuration below

Command

Creates a command in the toolbar

See specific Command configuration below

Toolbar menu

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

The menu element supports the following child elements.

Name Description Example

Label

The name of the dropdown for instance 'Actions'

<Label>Actions</Label>

FontIcon

What icon should be rendered next to the label.

<FontIcon>
    he-pencil
</FontIcon>

Image

What image should be rendered next to the label

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

RegisteredSuite

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

<RegisteredSuite>EngineeringCentral</RegisteredSuite>

Command

Creates a command in the toolbar

See specific Command configuration below

Menu

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

This feature is only available for uip-toolbar.

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

Alt

Tooltips can be configured for menu by adding <Alt>

This feature is only available for uip-toolbar.

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

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

The <Command> element supports the following child elements.

Name Description Example

Label

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

<Label>
    Delete
</Label>

Alt

Option for configuring tooltip other than label

<Alt>
    Alternative tooltip
</Alt>

FontIcon

What icon should be rendered next to the label.

<FontIcon>
    he-pencil
</FontIcon>

Image

What image should be rendered next to the label

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

RegisteredSuite

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

<RegisteredSuite>EngineeringCentral</RegisteredSuite>

OnClick

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

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

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

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

OnClickParams

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

selectionCriteria

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

confirmMessage

To display a confirm message before executing the command.
Confirm Message can be either plain text or custom translation
entry in JSON file CustomTranslations

<OnClickParams>{
    "options": {foo: "bar"},
    "selectionCriteria" : "many",
    "confirmMessage" : "Are you sure to execute command?"
}</OnClickParams>

ValidFor

Defines the command is valid for which rows in datatable

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

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

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

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

Name Description Example

Search

Whether the toolbar should have a search field.

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

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

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

<Search showParents="true"/>

default value of showparents is false

ExpandAll

Preconfigured command that fully expand all nodes in structure table.

<ExpandAll />

CollapseAll

Preconfigured command that collapse all nodes in structure table.

<CollapseAll />

CreateAndConnectRow

Preconfigured command that can be used to add a new child object row to the selected parent object row.

This in-built command requires to configure CreateSettings in tableConfig.

<CreateAndConnectRow />

ExportExcel

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

<ExportExcel />

ExportPDF

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

<ExportPDF />

ExportCSV

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

<ExportCSV />

Collection

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

  1. Add to Clipboard

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

  2. View Clipboard

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

  3. Add to Collection

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

  4. View Collection

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

Refer Customize Collection section for customizations

<Collection />

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

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

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

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

</FormWidget>

8.5.2. Invoke Service

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

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

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

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

Parameter Description Required Example

config

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

Yes

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

resultExpression

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

Yes

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

from

Direction to add the new object to table.

Yes

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

selection

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

Default is multiple

No

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

refreshBehavior

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

Default is add.

No

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

8.6. Service Toolbar

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

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

8.6.1. Service Command

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

XML Definition

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

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

We can also use the reference of this command.

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

url

This element defines the URL of intial service.

Yes

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

header

The header of the initial service call.

No

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

body

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

No

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

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

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

macro

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

No

"macro":"true"

macroElements

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

No

"macroElements":"physicalid"

addCsrfToken

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

No

"addCsrfToken": "false"

addSecurityContext

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

No

"addSecurityContext": "false"

refreshRows

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

No

"refreshRows": "true"

preRequestCallback

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

No

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

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

responseCallback

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

No

"responseCallback":"App.invokeServiceCallbacks.initialResponseCallback"

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

successMessage

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

No

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

resolverPaths

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

No

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

ResolverPaths configuration supports following elements/settings.

Element Description Required Example

url

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

Yes

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

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

OR

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

order

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

Yes

"order":1

header

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

No

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

body

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

No

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

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

bodyResolver

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

No

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

addCsrfToken

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

No

"addCsrfToken": "false",

addSecurityContext

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

No

"addSecurityContext": "false",

method

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

GET

POST

PUT

PATCH

DELETE

By default it is GET.

No

"method":"POST",

preRequestCallback

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

No

"preRequestCallback": "App.invokeServiceCallbacks.firstResolverPathCallback"

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

responseCallback

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

No

"responseCallback": "App.invokeServiceCallbacks.firstResolverResponseCallback"

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

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

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

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

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

(function(window, App, $) {

    var invokeServiceCallbacks = {

        // callbacks for creating doc element

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

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

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

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

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

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

8.6.2. Input Based Service

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

Form Configuration

Form configuration supports following elements/settings.

Element Description Required Example

url

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

Yes

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

options

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

Yes

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

header

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

No

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

contentType

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

No

"contentType": "application/json"

body

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

No

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

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

bodyResolver

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

No

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

addCsrfToken

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

No

addCsrfToken: true

addSecurityContext

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

No

addSecurityContext": true

method

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

GET

POST

PUT

PATCH

DELETE

No

"method":"PUT

formCallback

Users can specify a reference to a javascript function that will be executed after service call. The function itself needs to be included in a javascript resource. The function have two argumensts. First is formInput which will be the form input of the form being modified or updated. Second is InvokeServiceForm instance which contains all details about formoptions, calling datatable and widget.

No

"formCallback": "App.invokeServiceCallbacks.formResponseCallback"

formResponseCallback: function(formInput, invokeServiceFormInstance) {
    console.log('in first response payloadCallback callback, calling datatable instance : ' + invokeServiceFormInstance.dataTable);
    console.log('in first response payloadCallback callback2, form input are : ' + formInput);
}
XML Definition

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

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

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

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

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

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

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

8.7. Dashboard

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

image
Figure 12. Dashboard with multiple widgets

8.7.1. Configuration

The <Dashboard> element supports the following child elements.

Name Description Example

Locked

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

<Locked>true</Locked>

DisableCustomization

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

<DisableCustomization>true</DisableCustomization>

Floating

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

<Floating>true</Floating>

ResizableHandles

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

  • e - Right

  • w - Left

  • s - Bottom

  • se - Bottom-Right

  • sw - Bottom-Left

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

Widgets

Specifies what Widgets this dashboard should contain.

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

8.7.2. Dashboard Customization

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

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

tvc.helium.dashboard.customization.enabled=false

or by configuring a dashboard or widget as locked.

Customization actions

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

Reset Customizations:

There are two icons to reset the customizations done on dashboard

Reset to default dashboard: Enduser can replace the default dashboard with the dashboard shared by config-admin. And also, when enduser adds new widgets to default dashboard, a new dashboard configuration will be created in background and replaces the default dashboard. In order to reset back to the default dashboard, you can click this icon reset to default dashboard.

Reset widget positions in dashboard: Enduser can shuffle widget’s positions inside dashboard or hide the default widgets in the default dashboard. This icon can be used to reset to the configured dashboard view.

Any XML based widgets removed from dashboard will be added back when reset widget positions icon is clicked.
image
Figure 13. Customizable Dashboard, showing the customizations menu
Property tvc.helium.dashboard.customization.resetEnduserWidget is deprecated from 2022.4.0 release as the feature is separated into two different reset icons.

In empty dashboard, height of the dashboard is 0px. Due to this tooltip for the last command in slide-in Dashboard Menu blocks other commands. To avoid this and to set height for empty dashboard according to requirement, value can be defined in the property tvc.helium.dashboard.emptyDashboardHeight and its value will be set as height for empty dashboard. By default empty dashboard height is set to 750px.

In the property, only numerical value is to be given. Eg: if the required height is 800px then the property should be tvc.helium.dashboard.emptyDashboardHeight=800

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

Dashboard Views

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

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

Customization maximum cap

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

tvc.core.customization.maxContentSize

default value: 100000 Characters

Widget

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

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

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

Expand and collapse icon on every widgets can be configured by defining global property tvc.helium.widget.enableHeaderExpandCollapse=true in tvc.properties. For enabling widgets floating behavior after collapsing , conventional <Floating> in dashboard should be false.

The <Widget> element supports the following child elements.

Name Description Example

Id

The identifier of the widget. Should be unique.

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

<Id>materialcategory</Id>

Locked

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

<Locked>true</Locked>

Width

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

minWidth

Specifies minimum width upto which Widget size can be shrink.

maxWidth

Specifies maximum width upto which Widget size can be expand.

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

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

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

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

Height

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

adjustHeight

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

true - Widget should adjust the height to fit the content

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

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

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

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

maxHeight

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

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

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

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

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

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

X

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

<X>0</X>

Y

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

<Y>1</Y>

Template

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

<Template>
    headerless
</Template>

or

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

Badge

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

<Badge>true</Badge>

Collapsed

This element is used to configure preconfigured collapse behavior for widget. Valid value are true or false. Default value is false.

<Collapsed>true</Collapsed>

8.7.3. Example

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

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

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

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

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

8.7.4. Widget Customization

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

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

Customization actions

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

image
Figure 14. Resetting widget customizations

8.7.5. Open in Sidepanel

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

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

image
Figure 15. Dashboard in Sidepanel

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

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

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

image
Figure 16. Load Related Widgets

8.7.7. Widget lock unlock icon

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

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

  • If widget is locked it would show unlock icon.

  • If widget is unlocked it would show lock icon.

This is the default behaviour.

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

  • If widget is locked, show lock icon.

  • If widget is unlocked, show unlock icon.

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

8.8. Widget

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

8.8.1. Configuration

Name Description Example

Title

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

<Title>Title of the widget</Title>

OnInit

Javascript function that creates the widget.

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

OnInitOption

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

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

PostRender

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

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

HeaderActions

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

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

ShowActionTooltip

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

<ShowActionTooltip>false<ShowActionTooltip/>

Html

HTML that should be rendered inside of the widget container

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

Toolbar

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

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

Sidepanel

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

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

Access

Defines access rules.

Replace/Toggle widgets

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

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

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

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

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

    For <Access> definition, see Access Control

8.8.2. Conditionally evaluate dataset on drilldown

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

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

Example widget configuration:

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

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

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

8.9. Widget Sidepanel

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

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

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

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

The <Sidepanel> element supports the following child elements.

Name Description Example

Label

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

<Label>Sidepanel</Label>

Html

Custom html to be rendered in the widget

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

Closable

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

<Closable>false</Closable>

Toolbar

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

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

8.9.1. Javascript API

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

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

8.9.2. Example

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

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

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

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

image
Figure 17. Top Bar

8.10.1. Search

The <Search> format supports the following child elements.

Name Description Example

Limit

The maximum number of search results returned.

<Limit>100</Limit>

Types

Show only results of the listed types.

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

Selects

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

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

Where

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

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

HitOnClick

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

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

HitTemplate

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

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

ResultRenderCallback

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

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

SearchProvider

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

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

8.10.2. Example

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

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

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

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

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

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

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

8.11. Internationalisation

Helium supports both server-side and client-side internationalization.

The server-side internationalization is achieved by defining a set of string resource files inside <webapp-root>/WEB-INF/classes directory of the web application.

    <Column>
        <Label>emxFramework.Common.Name</Label>
    </Column>

The client-side internationalization is achieved by defining a set of language files in JSON format inside <webapp-root>/helium/lang or <webapp-root>/helium/custom/lang directory.

To decide which language to load, Helium will look at the current browser language (navigator.language), but if no suitable file is found a default one will be used.

    <Column>
        <Label>column.common.name</Label>
    </Column>

For exporting table data the support for internationalization is limited only to server-side and client-side internationalization is not supported. This limitation is applicable to all export formats.

    <Column>
        <Label>emxFramework.Common.Name</Label> // Supported
        <Label>column.common.name</Label> // Not Supported
    </Column>

8.11.1. File format

Each file should be given a name based on the locale they are to support. For instance, a file containing US English should be named en_us.json and a file containing Swedish should be named sv.json.

The files are simple JSON objects, with a key and a string as value, like the one below:

{
  "test": "My test message"
}

Where the key is test and the message is My test message. The keys can be nested arbitrarily deep in a nested object. For example the file below will create the keys form.createNew.title and form.createNew.message.

{
 "form" : {
   "createNew" : {
     "title" : "New Object",
     "message" : "The object {objectId} was successfully created."
   }
 }

The value for the key form.createNew.message contains a placeholder ({objectId}) which will be populated with the actual value by the framework. For an example see the JavaScript API.

8.11.2. Resolving files

The language files are located in <webapp-root>/helium/lang or <webapp-root>/helium/custom/lang.

The internationalisation framework will first look for files inside <webapp-root>/helium/custom/lang, if no suitable file is found, it will fall back to files defined in <webapp-root>/helium/lang and if still no file is found, it will default to a file named default.json

8.11.3. Javascript API

The above described keys can be accessed through javascript with the following syntax:

// Will return "My test message"
App.i18n.t('test')

It is possible to pass arguments to the App.i18n.t function that will be interpolated. See example below.

//  Will return "The obejct 1.2.3.4 was successfully created."
App.i18n.t('form.createNew.message', {objectId: '1.2.3.4'})
Handlebars helper

In Helium, there is a Handlebars helper for easy access to the internationalisation API. It is invoked by using the i18n helper.

{{i18n myTranslationKey}}

This will internally call the App.i18n.t function with the passed in key as its argument. The i18n helper of course also supports passing in arguments, like so:

{{i18n myTranslationKey myObjectContainingVariables}

8.12. Toaster

Helium use toaster message to provide user notification. These messgae can be shown using javascript api.

The default options use to show toaster notification can be changed through javascript as shown below :

(function () {
  App.toaster.defaultOpts = {
		"closeButton": true,
		  "newestOnTop": true,
		  "progressBar": true,
		  "positionClass": "toast-bottom-full-width",
		  "preventDuplicates": false,
		  "onclick": null,
		  "showDuration": "300",
		  "hideDuration": "1000",
		  "timeOut": "15000",
		  "extendedTimeOut": "1000",
		  "showEasing": "swing",
		  "hideEasing": "linear",
		  "showMethod": "fadeIn",
		  "hideMethod": "fadeOut"
  }
})();

The above javascript can be placed in webapps/helium/custom folder.

The toaster message are shown for 8 seconds by default, but user might want to see it for longer duration. This can be achieved by adding below configuration in tvc.properties:

tvc.helium.toaster.timeout = 25000 // default is 8000

8.13. Access Control

Helium has a common way of configuring access control that is shared among the different components (except table columns) that has this support (page, tab, commands etc.).

Access Control for table columns can be defined similar to TVC Classic. Please click here for more details.

The access restriction for components (other than table columns) can be defined based upon following:

  • Role Assignment

  • Group Assignment

  • Person (A named user)

  • Access Mask (Access mask for the current object)

  • Access Program (A JPO that evaluates the access rights)

  • Access Expression (MQL expression that evaluates the access)

The example below illustrates how you can construct the access restriction:

<Access>
    <Role>role_FirstRole</Role>
    <Role>role_SecondRole</Role>
    <Group>group_SomeGroup</Group>
    <Mask>modify,checkout</Mask>
</Access>

Or use an access program:

<Access>
    <Program name="MyJPO" method="checkAccess"/>
</Access>

Or use an access expression:

<Access>
    <Expression><![CDATA[owner == context.user]]></Expression>
</Access>

For Topbar Search command :

<Search ref="tvc:search:helium/TopBarSearch.xml">
    <Access>
        <Group>group_SomeGroup</Group>
    </Access>
</Search>

For Topbar Myspace and Logout command :

<Myspace>
    <Access>
        <Group>group_SomeGroup</Group>
    </Access>
</Myspace>

8.14. Loader

A loader alerts a user to wait for an activity to complete.

image
Figure 18. Loader

It can contain message also. This message appears just below the animation.

One can enable this feature by defining key-value pair like below in translation JSON files

"loader": {
    "message": "Loading..."
}

By defining this key/ value pair, all loading animations in the application will automatically display this value. No further configuration is needed.

It is also possible to define custom messages for different loading animations, e.g.

new App.Loader($element,{"message":'loader.customMessage'})

Or

new App.Loader($element,{"message":'Loading...'})

A mix of the above, i.e. default message and custom message is also possible.

Also we can add loader over any particular element on the UI, for ex a table row

new App.Loader(element, { rowLoader: true }

JavaScript API, Loader.

image
Figure 19. Loader with message(Loading…​).

8.15. Dimmable Modal

It would be helpful for users to have dim and non-reactive backgrounds while working on modal or fullscreen views. This feature can be enabled by configuring tvc.helium.widget.overlay.dimmable= true // default is false in tvc.properties.

image
Figure 20. Dim and Non-reactive Background

9. New Search Experience

9.1. Quick Search

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

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

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

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

image
Figure 21. Quick Search
image
Figure 22. With Search Form

9.1.1. Configuration Format

To use this configuration format the version must be set to 2. This is done by setting the version attribute on the Search element to 2. Example: <Search version="2">

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

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

Sample configuration using Search

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

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

Sample configuration using Command

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

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

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

Name Description Example

Limit

The maximum number of search results returned.

<Limit>100</Limit>

upperSearchLimitValue

The maximum number of search results allowed to be displayed.

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

DataFields

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

To display files available for the object with download link, data fields format.file.name and format.file.format are to be included.

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

Sections

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

See Sections for more details.

SearchForm

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

See Search Form for more details.

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

InitialHitsCount

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

<InitialHitsCount>15</InitialHitsCount>

ShowMoreHitsCount

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

<ShowMoreHitsCount>50</ShowMoreHitsCount>

SearchOnCriteriaUpdate

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

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

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

<SearchOnCriteriaUpdate>true</SearchOnCriteriaUpdate>

Settings

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

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

Server

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

See Server-Side Triggers for more details

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

Client

Callbacks triggered on the client at specific points.

See Client-Side Callbacks for more details.

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

<Client ready="MyApp.globalSearchReady" />

UIs

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

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

OpenOnLoad

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

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

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

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

9.1.2. Sections

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

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

Name Description Example

Section

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

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

FallbackSection

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

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

See Custom Section Provider for details on custom section provider.

Built-in Section Provider

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

Name Description Example

Filter

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

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

Label

Label can be used to specify title.

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

UIs

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

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

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

Name Description Example

Type

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

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

Or

<Type>table</Type>

Icon

Icon of UI to be shown for selecting UI.

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

ResultTemplate

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

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

TileHitTemplate

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

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

Table

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

Column configuration to display files of an object with download link.

For files column, data fields for format.file.name and format.file.format are to be included.
<Table>
    <Column>
        <DataField>type</DataField>
        <Label>Type</Label>
    </Column>
</Table>
<Table>
    ...
    <Column>
        <DataField>format.file.name</DataField>
        <Label>Files</Label>
    </Column>
    ...
</Table>

Settings

Additional settings.

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

Following attribute can be defined on root element SectionUI.

Name Description Example

id

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

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

default

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

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

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

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

Following menu elements are utilized on context menu.

Name Description Example

FontIcon

Icon to be showed for context menu.

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

Command

Command in the context menu.

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

Following Command settings are utilized in rendering of context menu.

Setting Name Description Example

OnClick

Javascript function to be called on click of command

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

OnClickParams

Additional parameters to passed into command on click.

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

Sample context menu defined in a section -

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

Sample context menu definition -

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

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

Interface to implement:

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

Example configuration:

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

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

Single Row

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

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

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

image
Figure 25. Single Row
Primary Image

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

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

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

Three Tiles

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

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

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

image
Figure 26. Three Tiles
Table view

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

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

image
Figure 27. Table View

9.1.3. Server-Side Triggers

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

preSearch

Executed before the search is executed.

Interface to implement:

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

Example configuration:

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

Executed after the search has been executed.

Interface to implement:

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

Example configuration:

<Server postSearch="com.acme.MyPostSearchTrigger" />

9.1.4. Client-Side Callbacks

ready

Callback function when search is ready. Example configuration:

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

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

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

If you’re using Built-in tile templates and you have defined custom onHitClick callback then you can get physical id value by using element.getAttribute('data-physical-id')

onRenderResult

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

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

9.1.5. Javascript API

Methods

Method Description

open

Opens the search

close

Closes the search

isOpen

Is the search open

search

Performs a search

getQuery

Gets the search criteria

searchPanel

Get API for searchpanel, if any available

result

Get API for result

on

Register to an event

off

Deregisters an event

Events

Event Name Description

open

Called after the quick search overlay is opened

close

Called after the quick search overlay is closed

preSearch

Called before the search is executed

postSearch

Called after the search is executed

destroy

Called when component is destroyed

Search Panel

Methods

Method Description

open

Opens the search panel

close

Closes the search panel

isOpen

Is the search panel open

toggleVisibility

Toggles the search panel

getSearchForm

Returns UIP search form instance

destroy

destroys the search panel and performs clean up

searchPanel

Get API for searchpanel, if any available

updateSearchFormFields

Updates the search form fields

Result

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

Methods

Method Description

clear

Clears the search result

isRendered

Return whether results are rendered

on

Register to an event

off

Deregister to an event

destroy

Destroys the result element

resultRenderer

returns resultRenderer object associated with this result object.

Events

Event Name Description

renderBefore

Called before rendering search result.

render

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

renderAfter

Called after rendering search result.

destroy

Called when result is destroyed.

Section Renderer

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

Methods

Method Description

clear

Clears the search result

getSections

Return list of sections

render

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

destroy

Destroys the result component.

9.1.6. Example Configuration

<?xml version="1.0" encoding="UTF-8"?>
<Search provider="enovia" version="2">
    <Limit>200</Limit>
    <SearchForm
        ref="tvc:searchformv2:helium/TopBarSearchForm.xml" />
    <Sections>
        <Section>
            <Filter>
                <DataField>attribute[Material Category]</DataField>
                <Value>Rubber</Value>
            </Filter>
            <Label>Rubber</Label>
            <UIs>
                <UI id="id0" />
                <UI id="id1" />
                <UI id="id2" default="true"/>
            </UIs>
        </Section>
        <Section>
            <Filter>
                <DataField>attribute[Material Category]</DataField>
                <Value>Metal</Value>
            </Filter>
            <Label>Metal</Label>
            <UIs>
                <UI id="id1" default="true"/>
                <UI id="id2" />
                <UI id="id3" />
            </UIs>
        </Section>
        <Section>
            <Filter>
                <DataField>attribute[Material Category]</DataField>
                <Value>Concrete</Value>
            </Filter>
            <Label>Concrete</Label>
        </Section>
        <FallbackSection>
            <Label>searchv2.section.defaultTitle</Label>
        </FallbackSection>
    </Sections>
    <UIs>
        <UI id="id0" default="true">
            <Type>tile</Type>
            <TileHitTemplate>helium/templates/search/v2/primaryimage-result-hit</TileHitTemplate>
            <ResultTemplate>helium/templates/search/v2/primaryimage-result</ResultTemplate>
            <Icon>ti-f ti-menu-f</Icon>
            <Settings>
                <Setting name="title" value="Primary Image" />
            </Settings>
        </UI>
        <UI id="id1">
            <Type>tile</Type>
            <TileHitTemplate>helium/templates/search/v2/row-result-hit</TileHitTemplate>
            <ResultTemplate>helium/templates/search/v2/row-result</ResultTemplate>
            <Icon>ti-f ti-table-f</Icon>
            <Settings>
                <Setting name="title" value="Single Row Result" />
            </Settings>
        </UI>
        <UI id="id2">
            <Type>tile</Type>
            <TileHitTemplate>helium/templates/search/v2/result-hit</TileHitTemplate>
            <ResultTemplate>helium/templates/search/v2/result</ResultTemplate>
            <Icon>ti-f ti-menu2-f</Icon>
            <Settings>
                <Setting name="title" value="Three Tile Result" />
            </Settings>
        </UI>
        <UI id="id3">
            <Type>tile</Type>
            <TileHitTemplate>helium/templates/search/v2/result-hit</TileHitTemplate>
            <ResultTemplate>helium/templates/search/v2/result</ResultTemplate>
            <Icon>ti-f ti-menu2-f</Icon>
        </UI>
    </UIs>
    <DataFields>
        <DataField>type</DataField>
        <DataField>name</DataField>
        <DataField>revision</DataField>
        <DataField>description</DataField>
        <DataField>primaryimage</DataField>
        <DataField>${attribute[attribute_EndItem]}</DataField>
        <DataField>physicalid</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>

9.2. Search Side Panel

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

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

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

image
Figure 28. Search Side Panel

9.2.1. Configuration Format

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

Name Description Example

Limit

The maximum number of search results to be returned.

<Limit>100</Limit>

DataFields

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

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

SearchOnCriteriaUpdate

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

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

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

<SearchOnCriteriaUpdate>true</SearchOnCriteriaUpdate>

SearchIcon

Search Icon for collapsed search panel.

<SearchIcon>find icon</SearchIcon>

SearchTitle

Title for collapsed search panel

<SearchTitle>Search Sidepanel</SearchTitle>

ResultTitle

Title for drilldown of search results

<ResultTitle>Drilldown Search Results</ResultTitle>

Settings

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

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

Server

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

See Server-Side Triggers for more details

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

Client

Callbacks triggered on the client at specific points.

See Client-Side Callbacks for more details.

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

<Client ready="MyApp.searchPanelReady" />

HomePage

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

<HomePage>
    <Page namespace="helium" name="DefaultPage.xml"/>
</HomePage>

9.2.2. Client-Side Callbacks

ready

Callback function when search panel is ready. Example configuration:

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

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

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

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

<Client onResult="App.custon.onSearchResult"/>

9.2.3. Configuration In Page

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

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

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

Name Description Default Example

OpenOnLoad

Whether to open search panel when page is loaded.

true

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

SearchOnLoad

Whether to perform search when page is loaded.

false

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

OnSearchResult

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

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

9.2.4. On Search Result

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

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

Following sub elements can be defined under <OnSearchResult>:

Name Description Default Example

ReloadDashboards

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

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

LoadServerSide

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

false

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

Dashboard

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

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

WidgetId

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

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

9.2.5. Paginated Search Result

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

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

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

9.2.6. SearchBasedLoader

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

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

Interface the Java class needs to implement:

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

Example configuraton

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

Page configuration on which search panel should be present.

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

See On Search Result for configuration details.

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

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

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

Example Config:

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

9.2.7. Javascript API

Methods

Method Description

open

Opens the search panel

close

Closes the search panel

isOpen

Is the search panel open

search

Performs a search

getPage

Returns the context page object

getOptions

Returns the options this search instance

getQuery

Gets the search criteria

searchPanel

Get API for searchpanel

destroy

Destroys and cleans up the search instance

on

Register to an event

off

Deregister to an event

Events

Event Name Description

ready

Called after search panel is ready

open

Called after the quick search overlay is opened

close

Called after the quick search overlay is closed

search

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

result

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

destroy

Called when component is destroyed

9.2.8. Example Configuration

Page

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

Search Panel

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

9.2.9. Apply filter on structure node expand

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

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

<ApplySearchFilterOnExpand>true</ApplySearchFilterOnExpand>

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

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

Setting Name Description Example

applyOnTableExpand

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

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

tableExpandKey

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

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

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

Search feld for Material Category

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

Table column for Material Category

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

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

Kindof table column

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

Searchform field

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

9.2.10. Validations

Search Limit

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

image
Figure 29. search limit validation

9.3. Search Form

9.3.1. Form Configuration Format

The searchform configuration files are placed in the folder searchformv2.

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

Name Description Example

Title

Title of the search Form. Displayed above the fields.

<Title>Part Search</Title>

Fields

Available fields in the search form.

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

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

Sections

Group fields into collapsible sections in the search form.

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

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

Toolbar

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

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

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

OnCreate

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

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

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

9.3.2. Field Configuration Format

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

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

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

Name Description Example

Label

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

<Label>Type</Label>

Tooltip

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

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

Required

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

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

<Required>true</Required>

DataField

The data to search among.

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

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

ENOVIA example:

<DataField>type</DataField>

EXALEAD example:

<DataField>ATTRIBUTE_MATERIAL_CATEGORY</DataField>

DataType

Type of data to be searched. Valid values:

  • string

  • date

  • integer

  • decimal

  • boolean

<DataType>date</DataType>

UIType

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

See UI Types for more details.

<UIType>autocomplete</UIType>

Visible

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

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

Values

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

It also controls the default selected value.

See Values for more details.

Use ranges on attribute Material Category as values:

<Values attribute="attribute_MaterialCategory" />

Part is the default value:

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

Dimensions

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

See Dimensions for more details.

Use dimensions on attribute Weight as below:

<Dimensions attribute="attribute_Weight" />

Part is the default value:

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

Settings

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

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

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

casesensitive

case sensitivity for the input value. Default value is false

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

ConditionalFields

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

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

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

Example:

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

9.3.3. Values

Values are used for two purposes:

  1. To define the values the user can search by

  2. To define which value that is selected by default

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

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

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

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

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

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

Attribute Name Description Example

value

The value. It’s mandatory to specify it.

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

label

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

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

type

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

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

default

Controls if the value is selected by default.

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

9.3.4. Dimensions

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

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

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

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

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

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

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

Attribute Name Description Example

Dimension

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

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

9.3.5. Conditional Fields

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

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

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

createConditionalFields

Returns set of additional fields to be added to searchform

9.3.6. Field Visibility

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

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

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

Name Element / Attribute Description Example

hidden

attribute

Defines whether field should be hidden by default.

<Visible hidden="true"/>

ifField

attribute

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

<Visible fieldId="type_enovia"/>

HasValues

element

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

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

jsFunction

attribute on <HasValues>

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

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

includeWhenHidden

attribute

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

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

Examples-

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

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

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

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

9.3.7. Custom Fields

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

Interface to implement:

com.technia.tvc.search.searchform.FieldDef

<Field className="com.acme.search.CustomField"/>

9.3.8. Built-in ENOVIA Fields

TypeField

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

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

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

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

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

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

AnyRevision

Shows all the revisions

FirstRevision

Shows only first revision

LastRevision

Shows only last revision

LatestInState

Shows latest revision with passed in state value

LastAndLatestInState

Shows the combination of LastRevision and LatestInState

NameField

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

Example:

<NameField />
PersonField

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

Example:

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

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

It’s mandatory to specify at least one policy.

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

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

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

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

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

Settings:

Attribute Name Description Default Example

groupByState

Groups the states into their corresponding policies.

true

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

valueSeparator

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

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

:

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

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

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

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

Example:

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

Settings:

Setting Name Description Example

defaultsToContextObject

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

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

defaultMinInteger

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

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

defaultMaxInteger

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

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

defaultMinReal

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

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

defaultMaxReal

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

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

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

  1. Query Library objects

  2. Expand Library objects to retrieve Family objects

Example:

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

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

Argument Description Default Example

rootTypePattern

TypePattern of top level Library.

type_Library

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

rootNamePattern

NamePattern of top level Library.

*

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

rootRevPattern

RevisionPattern of top level Library.

*

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

rootVaultPattern

VaultPattern of top level Library.

*

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

rootWhereClause

Where clause for querying Library objects.

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

relPattern

Relationship pattern for expanding Library objects

relationship_Subclass

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

expandTypePattern

Type pattern for Family or Classification objects.

type_PartFamily

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

expandWhereClause

Where clause for expanding Family or Classification objects.

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

queryType

Following four options are supported:

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

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

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

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

query

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

searchType

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

  • startswith

  • endswith

  • contains

startswith

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

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

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

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

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

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

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

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

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

Example:

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

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

9.3.9. UI Types

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

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

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

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

User can also search for multiple values in a text field by using below setting :

Example:

<Field>
    .
    .
    <UIType>text</UIType>
    <Settings>
        <Setting name="allowMultipleValues" value="true" />
        <!-- Optional Settings for custom preferences-->
        <Setting name="reactselect">
            {
            "menuIsOpen": "true",
            "placeholder": "Enter Text",
            "noOptions": "Value already added!"
            }
        </Setting>
    </Settings>
    .
</Field>

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

image
Figure 31. Multivalued Text Field
Autocomplete

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

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

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

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

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

Example configuring a field to use the type AutoCompeleteHandler:

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

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

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

Example:

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

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

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

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

Ranges

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

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

Example displaying ranges for the Material Category attribute:

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

Settings:

Attribute Name Description Default Example

showFilter

Show input field above ranges used to filter visible ranges.

false

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

showAllRanges

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

false

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

showRangeAmount

Number of ranges to show in case showAllRanges is false.

5

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

expandGroups

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

true

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

hideRangesWithZeroCount

Controls if ranges with count zero should be hidden.

false

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

termFieldRequired

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

false

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

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

Example:

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

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

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

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

Settings:

Attribute Name Description Default Example

valuesInclusive

Includes the specified ‘from’ and ‘to’ values

true

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

dateDisplayFormat

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

'd-M-y'

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

useOldDatePicker

Displays older date picker for selection (depreciated)

false

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

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

Dimensions can be added using Dimensions tag.

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

Example configuration:

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

Example configuration with dimensions:

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

Settings:

Attribute Name Description Default Example

showSlider

Should the slider be displayed

true

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

min

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

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

max

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

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

unit

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

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

searchWithUnit

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

false

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

step

Increments when changing the value using the slider.

1

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

precision

Decimal precision for the field.

1

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

valuesInclusive

Includes the specified ‘from’ and ‘to’ values

true

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

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

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

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

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

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

Type Hierarchy

Following settings are supported by Treefield:

Setting Name Description Default Example

showValueCount

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

true

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

selectChildren

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

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

false

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

submitOnlyParent

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

This setting is applicable only when selectChildren is true.

false

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

showAllNodes

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

false

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

showNodesCount

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

5

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

loadOptions

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

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

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

Example:

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

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

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

Example configuring a field to use the type TreeHandler:

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

Following sub settings are supported by loadOptions:

Setting Name Description Default Example

forceNodeFetchOnExpand

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

false

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

valueKey

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

value

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

labelKey

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

label

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

There are two built in TreeHandlers:

Type

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

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

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

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

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

Following sub settings are supported by businessobject TreeHandler:

Setting Name Description Example

rootTypePattern

Type pattern to quering the root nodes.

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

rootNamePattern

Name pattern to quering the root nodes.

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

rootRevPattern

Revision pattern to quering the root nodes.

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

rootVaultPattern

Vault pattern to quering the root nodes.

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

rootWhereClause

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

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

disableRoots

Whether root nodes should be disabled for selection.

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

typePattern

Type pattern for expanding root and other nodes.

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

relPattern

Relationship pattern for expanding root and other nodes.

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

relWhereClause

Relationship where clause for expanding root and other nodes.

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

objectWhereClause

Object where clause for expanding root and other nodes.

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

displayMacro

displayMacro for showing lable of expanded child nodes.

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

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

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

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

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

or in case of businessobject handler root nodes can be added using root node configuration. However, it is possible to use a custom java class to load root nodes and allow businessobject handler to only handle the expansion of nodes. See Values for more details.

<Field sectionId="related">
    <Label>Classification Tree</Label>
    <DataField>to[Classified Item].from.id</DataField>
    <ConditionalFields></ConditionalFields>
    <UIType>tree</UIType>
    <Values className="com.acme.RootNodeProvider" />
    <Settings>
        <Setting name="loadOptions">
        {
            "handler": {
                "name": "businessobject",                       // handler name
                "typePattern": "type_PartFamily",               // Type pattern for part family
                "relPattern": "relationship_Subclass",          // Relation between library and part family and between part family
                                                                // and sub part families.
                "objectWhereClause": "current == Active",       // Relation where clause
                "displayMacro":"${name} ${current}"             // Display marco
            },
            "valueKey": "value",
            "labelKey": "label"
        }
    	</Setting>
    </Settings>
</Field>

9.3.10. Term Field

Term field is special field designed to be used for search overlay. Implementing Search Provider can decide on how to interpret term field and use for performing search. See Enovia Provider Settings for details on how built-in ENOVIA Search Provider uses term field. Term field can be identified by property FieldType as term on field.

9.3.11. Section Configuration Format

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

Name Description Example

id

Attribute on <Section> tag.

id is mandatory and should be unique for each section.
<Section id="basic">
...
</Section>

Label

The label for the section. I18n is supported through string resources file.

<Label>Type</Label>

Tooltip

Tooltip for the field. Displayed when hovering the label.

<Tooltip>
    <Header>Basic</Header>
    <Content>Section to display basic fields.</Content>
</Tooltip>

Expanded

Whether section should be expanded on load of searchform. Default value is true.

<Expanded>true</Expanded>

Sections can be used to divide fields into collapsible group or sections. Each field configuration should specify its section using attribute sectionId on <Field> tag, which should match with id on corresponding <Section>. See example configuration below -

<SearchForm>
    <Title>Part Search</Title>
    <Sections>
    	<Section id="basic">
    		<Label>com.technia.tvc.search.form.name.label</Label>
    		<Tooltip>
    			<Title>Basic Fields</Title>
    			<Content>This is a section for basic fields.</Content>
    		</Tooltip>
    		<Expanded>true</Expanded>
    	</Section>
    	<Section id="classification">
    		<Label>Classification</Label>
    		<Tooltip>
    			<Title>Classification Fields</Title>
    			<Content>This is a section for classification fields.</Content>
    		</Tooltip>
    		<Expanded>false</Expanded>
    	</Section>
    	<Section id="others">
    		<Label>Other</Label>
    		<Tooltip>
    			<Title>Other Fields</Title>
    			<Content>This is a section for other fields.</Content>
    		</Tooltip>
    		<Expanded>false</Expanded>
    	</Section>
    </Sections>
    <Fields>
        <NameField sectionId="basic">
        	<Settings>
                <Setting name="casesensitive" value="true" />
            </Settings>
        </NameField>
        <TypeField id="type" sectionId="basic">
            ...
        </TypeField>

        <StateField sectionId="basic">
            ...
        </StateField>

        <RevisionField sectionId="basic">
            ...
        </RevisionField>

        <ClassificationField sectionId="classification">
            ...
        </ClassificationField>

        <Field sectionId="others">
            ...
        </Field>

        <PersonField sectionId="others">
            ....
        </PersonField>

        <Field attribute="attribute_MaterialCategory" id="material_category" sectionId="classification">
        ...
        </Field>
    </Fields>
</SearchForm>

Search criteria can be saved using saved search functionality. Saved searches can be loaded to fill search criteria on the search form. User can also directly launch a search by clicking on find icon.

image
Figure 34. Save Search
image
Figure 35. Load Search

Search criteria present on search form can be exported as URL, which can be shared as copied text. Exported URL can then be directly be used to launch search in overlay mode. When a search is launched via URL, a default empty homepage is shown in the background to avoid loading heavy homepage impacting performance. However, it is possible to load a custom homepage via configuration tag <HomePage> on search config. <HomePage> should have the page reference that needs to be loaded in the background.

Example:

<Search provider="enovia" version="2">
    ...
    <HomePage>
        <Page namespace="helium" name="SearchPage.xml"/>
    </HomePage>
</Search>
image
Figure 36. Export Search

9.3.14. User settings

Search On Criteria Update

User Setting to enable/disable Search On Criteria Update for Search.

User can now control whether the search is submitted when the search criteria is updated. Earlier this feature was limited to search config and it was not possible to enable or disable for a specific user.

A built-in command SaveSearchUserSettings is added to allow users to enable or disable search on criteria updates. This built-in command needs to be added to the search form toolbar.

For detailed information on search on criteria update, please refer Search On Criteria Update

Search On Load

User Setting to enable/disable Search On Load for Search. Search config setting SearchOnLoad can be used to perform the initial search as search form loads.

User can now control whether the search should be initiated when the search form loads. Earlier this feature was limited to search config and it was not possible to enable or disable for a specific user.

A built-in command is added to allow users to enable or disable search on load feature. This built-in command needs to be added to the search form toolbar.

For detailed information on search on load, please refer Search On Load

<Toolbar>
  <SaveSearchUserSettings />
</Toolbar>
SaveSearchUserSettings command is used to club both the user settings ie Search On Criteria Update and Search On Load
image
Figure 37. Usersetting for search on criteria update & search on load

9.3.15. Javascript API

Methods

Method Description

setCriteria

Sets the criteria on search form

getCriteria

Gets the search criteria

updateFieldsVisibility

Updates visibility of fields on searchform

getState

Current fields of search form. State of searchform represents all the fields within searchform.

setFieldValues

Sets the field values on search form.

setFields

Sets the fields on search form. It is used when search result returns search form fields.

updateFieldValueCounts

Updates count on searchform fields.

on

Register to an event

off

Deregister to an event

Events

Event Name Description

search

Called when search button is clicked.

close

Called when searchform is closed

resetFields

Called when fields are reset.

criteriaUpdate

Called when search criteria is updated.

9.3.16. Example Configuration

<?xml version="1.0" encoding="UTF-8"?>
<SearchForm>
    <Title>Part Search</Title>

    <Fields>
        <NameField />

        <TypeField>
            <Values>
                <Value value="Part" default="true" />
            </Values>
            <SearchableTypes>
                <Type>type_Part</Type>
                <Type>type_DOCUMENTS</Type>
            </SearchableTypes>
            <Tooltip>
                <Title>customer.search.type.tooltip.title</Title>
                <Content>customer.search.type.tooltip.content</Content>
            </Tooltip>
        </TypeField>

        <Field>
            <Label>Material Category</Label>
            <DataField>MATERIAL_CATEGORY</DataField>
            <Values attribute="attribute_MaterialCategory" />
            <Settings>
                <Setting name="showFilter" value="true" />
                <Setting name="showRangeAmount" value="10" />
            </Settings>
        </Field>
    </Fields>
</SearchForm>

9.3.17. Toolbar Configuration Format

Toolbar can be configured inline within a searchform. Command/Menu can be configured in a separate file and added to the toolbar element.

image
Figure 38. SearchForm Toolbar

The command configuration files are placed in the folder command and menu configuration files are placed in the folder menu. If configured in a separate file, it can be referred within searchform using attribute ref as below -

<Toolbar>
    <Command ref="tvc:command:helium/mail.xml"/>
    <Menu ref="tvc:menu:helium/mymenu.xml"/>
</Toolbar>
Command Configuration Format

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

Name Description Example

Label

The label for the command. I18n is supported through string resources file.

<Label>Mail</Label>

Alt

Tooltip for the command. Displayed when hovering the label.

<Alt>This is the tooltip.</Alt>

FontIcon

Icon for the command. Displayed left of the label.

<FontIcon>ti-f ti-mail-f</FontIcon>

Setting

Setting with name and value can be passed to include onClick and other required information.

<Setting name="onClick" value="App.searchFunctions.customFunction"></Setting>

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

Name Description Example

Label

The label for the command. I18n is supported through string resources file.

<Label>Mail</Label>

Alt

Tooltip for the menu. Displayed when hovering the label.

<Alt>This is the tooltip.</Alt>

FontIcon

Icon for the menu. Displayed left to the label.

<FontIcon>ti-f ti-mail-f</FontIcon>

Command

Commands for this menu visible as dropdown elements on clicking the menu.

<Command ref="tvc:command:helium/mail.xml" />
In-built Commands:

The in-built search commands can also be configured and only icon,label and tooltip can be modified.

<SaveSearch>
    <Label>save</Label>
    <FontIcon>ti-f ti-save-f</FontIcon>
    <Alt>Save Search</Alt>
</SaveSearch>
<LoadSearch>
    <Label>load</Label>
    <FontIcon>ti-f ti-menu-f</FontIcon>
    <Alt>Load Search</Alt>
</LoadSearch>
If toolbar is not defined in the searchForm, a default toolbar with in-built commands takes its place. If toolbar is configured, these inbuilt commands are needed to be included if required.

9.4. Search Providers

9.4.1. ENOVIA Search Provider

Built-in ENOVIA Search Provider can be used to perform search in ENOVIA. It can be used with enovia callsign name in Search Configuration.

<Search provider="enovia" />
Settings

ENOVIA Search Provider supports following settings, which are defined in Search Configuration. See Configuration Format for details on how to configure settings.

Setting Name Description Default Example

vault

Enovia vaults where search should be performed. Multiple comma separated vaults can be configured.

eService Production

<Settings>
    <Setting name="vault" value="vault_eServiceProduction, vault_ACMEVault" />
</Settings>

where

A custom where clause can be passed to search provider. For example it can be used to search only non-obsolete parts.

none

<Settings>
    <Setting name="where" value="current != 'Obsolete'" />
</Settings>

termWhere

termWhere is applicable for term search. It defines where clause, into which user search term is to be injected while performing Enovia search. For example, if user entered term search as test, Enovia where clause will look like name ~~ 'test' OR type ~~ 'test' OR description ~~ 'test'

name ~~ '%s' OR type ~~ '%s' OR description ~~ '%s'

<Settings>
    <Setting name="termWhere" value="name ~~ '*%s*' OR description ~~ '*%s*' OR current ~~ '*%s*'" />
</Settings>

9.4.2. EXALEAD Search Provider

Built-in EXALEAD Search Provider can be used to perform search in Exalead. It can be used with exalead callsign name in Search Configuration.

<Search provider="exalead" />
Settings

EXALEAD Search Provider supports following settings, which are defined in Search Configuration. See Configuration Format for details on how to configure settings.

Setting Name Description Default Example

xl:termFields

Fields against which term search should be evaluated.

Term search is by default queried as against all indexed fields

<Settings>
    <Setting name="xl:termFields" value="NAME,DESCRIPTION" />
</Settings>

xl:sortField

Field on which search should be sorted.

none

<Settings>
    <Setting name="xl:sortField" value="NAME" />
</Settings>

xl:sortOrder

Sort order of search result.

ascending

<Settings>
    <Setting name="xl:sortOrder" value="DESCENDING" />
</Settings>

xl:enableWildcardSearch

Whether to add wildcard to term search.

false

<Settings>
    <Setting name="xl:enableWildcardSearch" value="false"/>
</Settings>

xl:inlcudeFacets

Whether to include facets or field counts.

true

<Settings>
    <Setting name="xl:inlcudeFacets" value="true" />
</Settings>

9.4.3. RevisionField

In case of exalead search provider, RevisionField can be configured in search form like below

<RevisionField sectionId="basic">
    <AnyRevision />
    <FirstRevision />
    <LastRevision />
    <LatestInState policy="EC Part" state="Release" />
    <LastAndLatestInRelease />
    <Settings>
        <Setting name="xl:lastRevision" value="LASTREVISION"></Setting>
        <Setting name="xl:firstRevision" value="FIRSTREVISION"></Setting>
        <Setting name="xl:latestRevision" value="LATESTREVISION"></Setting>
        <Setting name="xl:lastAndLatestRevision" value="LASTANDLATESTREVISION"></Setting>
    </Settings>
</RevisionField>

Following Exalead settings can be defined on search form fields. See Field Configuration Format for details on how to configure settings.

Setting Name Description Default Example

xl:firstRevision

Exalead key for first revision.

NOTE

This setting is applicable for revision field.

FIRSTREVISION

<Settings>
    <Setting name="xl:firstRevision" value="FIRSTREVISION" />
</Settings>

xl:lastRevision

Exalead key for last revision.

NOTE

This setting is applicable for revision field.

LASTREVISION

<Settings>
    <Setting name="xl:lastRevision" value="LASTREVISION" />
</Settings>

xl:latestRevision

Exalead key for latest revision.

NOTE

This setting is applicable for revision field.

LATESTREVISION

<Settings>
    <Setting name="xl:latestRevision" value="LATESTREVISION" />
</Settings>

xl:lastAndLatestRevision

Exalead key for lastAndLatestRevision revision.

NOTE

This setting is applicable for revision field.

LASTANDLATESTREVISION

<Settings>
    <Setting name="xl:lastAndLatestRevision" value="LASTANDLATESTREVISION" />
</Settings>

xl:showZeroCount

Whether '0' should be shown when Exalead count for a field value is 0.

false

<Settings>
    <Setting name="xl:showZeroCount" value="true" />
</Settings>

9.4.4. Custom Search Provider

Custom Search Provider can be used to perform search. Custom Search Provider should implement interface com.technia.tvc.search.api.SearchProvider and provide implementation to method search(SearchContext context). SearchContext object provide access to following api to perform search.

API Description

getCriteria

Search criteria supplied by the client. Typically what the user enters in the search form including term search.

getSearchForm

Instance of searchform to be used to get access to data fields against which search is performed

getDataFields

DataField which should be include in search result. This is used for rendering search result on UI.

getSettings

Custom Settings defined in Search Config. This is useful for passing adhoc settings to SearchProvider, see ENOVIA Search Provider Settings for reference.

getSectionProvider

Section Provider to be used for sectionizing search results. Refer Built-in Section Provider for default implementation.

getSearchForm

Instance of searchform to be used to get access to data fields against which search is performed

10. Widgets

10.1. Chart

Visualizes data in charts. Available type of charts:

  • Line

  • Bar

  • Pie

  • Donut

image

The chart solution is based on Chartist.js

A dataloader can be configured at dashboard level. The data loaded at dashboard level is available to all the chart widgets defined in the dashboard. In this case, the data will not be cached by the service worker.

10.1.1. Widget

To create a chart widget you must first create an xml with the following contents:

<ChartWidget>
    <Title>State</Title>
    <ChartConfig namespace="helium">StateChart.xml</ChartConfig>
</ChartWidget>

The <ChartWidget> element supports the following child elements.

Name Description Example

Title

The title of the chart widget

<Title>State</Title>

ChartConfig

Specifies the chart config file

<ChartConfig namespace="helium">StateChart.xml</ChartConfig>

UseVersion2

If set to true the new chart library ApexCharts will be used else the older one Chartist. This can be set globally by using tvc.helium.widget.chart.useVersion2, default value is true.

<UseVersion2>true</UseVersion2>

10.1.2. Chart configuration

The <ChartConfig> element can have the following children. Full example.

Name Description Example

DataSeries

Defines the data to display in the chart. More details

Sort

Controls sorting of the data. Sorts by default on label. More details

<Sort>
    <Label ascending="true" />
</Sort>

Tooltip

Controls if tooltips are displayed.

<Tooltip>true</Tooltip>

Top

The number of entries to display in the chart. The ones with highest values are displayed and others are grouped together in the "other" section. Useful when there are lots of entries and the chart feels crowded.

<Top>5</Top>

DrillDown

Reference to dashboard to use when performing drilldowns. Use either DrillDown or OnClick

<DrillDown>tvc:dashboard:acme/PartDrilldown.xml</DrillDown>

OnClick

Reference to javascript function which is invoked when user clicks on chart elements. Example

<OnClick>App.custom.onChartClick</OnClick>

Legend

Controls if legend are displayed. For multi series, it is automatically enabled.

<Legend>true</Legend>

Stack

To show multi series bar chart as a stacked bar chart. Defaults to false

<Stack>true</Stack>

Options

Options for the chart. For example you can control offsets/paddings of the chart, labels and layout.

The full list of the available options is available in the Chartist documentation.

Note that the options varies depends on the type of chart (bar, line etc).

Option for legend :
legendPosition :
For bar and line chart legend position either top or bottom and default is top.

<Options>{
  "high": 100,
  "low": 0,
  "chartPadding": {
    "top": 30
  },
  "legendPosition": "bottom"
}</Options>

ResponsiveOptions

Responsive options are used to adapt the chart to look good across different devices. Responsive options controls the layout based on media queries. The full list of the available options is available in the Chartist documentation.

Example displaying only first character of the month (J, F, M, A …​) on small screens:

<ResponsiveOptions>[
	['screen and (max-width: 640px)', {
	    seriesBarDistance: 5,
	    axisX: {
	        labelInterpolationFnc: function(value) {
	            return value[0];
	        }
	    }
	}]
]</ResponsiveOptions>

FunctionOptions

There could be some use cases like events etc. to configure custom js function as documented in apex charts library.

This is only supported version2 charts.

Example for using custom js functions

<Chart>
    ...
    <FunctionOptions>{
        	"chart": {
			"events": {
			"animationEnd": "App.hex.customEventListener",
			"beforeMount": "App.hex.customEventListener",
			"mounted": "App.hex.customEventListener",
			"updated": "App.hex.customEventListener",
			"mouseMove": "App.hex.customEventListener",
			"mouseLeave": "App.hex.customEventListener",
			"click": "App.hex.customEventListener",
			"legendClick": "App.hex.customEventListener",
			"markerClick": "App.hex.customEventListener",
			"selection": "App.hex.customEventListener",
			"dataPointSelection": "App.hex.customEventListener"
      }
		}
    }</FunctionOptions>
    ...
</Chart>

DataType

Controls the type of data to display in the chart. By default it uses the data type group. Read more

<DataType>group</DataType>

AnimateOnLoad

Reference to a JavaScript function which registers a chart animation. One included example for line charts is available via example.js as App.custom.registerLineChartAnimation. For more examples and details, please refer to Chartist - Examples.

This is not supported on version2 charts, you can pass configuration directly in options. For more details, please refer to Apex Charts-Animation
<AnimateOnLoad>App.custom.registerLineChartAnimation</AnimateOnLoad>

ExternalSource

A rest api url / some js function that returns request object or url

<ExternalSource>https://someresource.com/data</ExternalSource>

ExternalSourceDataFunction

A js function to convert the external source response to data expected by the chart library

<ExternalSourceDataFunction>somejsfunction</ExternalSourceDataFunction>
Sorting

Controls how to sort the data in the chart.

Name Description Example

Label

Sort on the label. Supports ascending="true|false".

<Sort>
  <Label ascending="true" />
</Sort>

Value

Sort on the value. Supports ascending="true|false".

Either Label or Value can be used for sorting
<Sort>
  <Value ascending="true" />
</Sort>

LabelFixed

Sort on label with a fixed order. Useful when display states.

<Sort>
  <LabelFixed>
    <Label>Create</Label>
    <Label>Peer Review</Label>
    <Label>Complete</Label>
    <Label>Obsolete</Label>
  </LabelFixed>
</Sort>

Value

DataSeries

Defines the data to display in the chart. There is pre-built support for multiple data series but the default data type 'group' supports only one serie. Multiple data series can be utilized when writing custom data type example.

Name Description Example

DataLoader

Optional. Data loader to use across all series in the chart. Use this setting in case all data series uses same set of objects.

<DataLoader>
  <DataSet>tvc:dataset:acme/MyParts.xml</DataSet>
</DataLoader>

Serie

Respresents one serie of data serie in the chart. More Details

For multi series chart DataSeries may contain multiple Serie and ChartType for all serie must be same.
Serie

Represents one serie of data in the chart.

Name Description Example

DataLoader

Defines which data to use in data serie. Optional in case specified on <DataSeries> level

<DataLoader>
  <DataSet>tvc:dataset:acme/MyParts.xml</DataSet>
</DataLoader>

Name

Legend label for bar and line chart.

<Name>XXX</Name>

Expression

Data to select. Used to group data by default.

  • usesBusinessObject: This attribute value on Expression tag enable to evaluate expression on relationship.

    • true: Expression is object selectable . This is default behaviour.

    • false: Expression is relationship selectable.

If usesBusinessObject attribute is used, then DataSet need to be defined in such a way that it will remove the root object.
<Expression><![CDATA[$<attribute[attribute_MaterialCategory]>]]></Expression>
<Expression usesBusinessObject="false">${attribute[attribute_UnitofMeasure]}</Expression>

If user want to show chart based on EBOM relationship on relationship attribute Unit of Measure then chart DataSeries and DataSet will be look like below

<DataSeries>
	<Serie>
		<DataLoader>
			<DataSet>tvc:dataset:hex:engineering/EBOM.xml</DataSet>
		</DataLoader>
		<Expression usesBusinessObject="false">${attribute[attribute_UnitofMeasure]}</Expression>
		<ChartType>pie</ChartType>
	</Serie>
</DataSeries>
<DataSet>
	<RemoveRoots>
		<Expand>
	        <From>true</From>
	        <To>false</To>
	        <Depth>1</Depth>
	        <RelationshipPattern>
	            <Relationship>relationship_EBOM</Relationship>
	        </RelationshipPattern>
	    </Expand>
	</RemoveRoots>
</DataSet>

Expressions

Supports multiple Expression elements which can be used to select data. By default, the first expression in the list will be used to group chart data. In this example data will be grouped by Material Category.

<Expressions>
	<Expression><![CDATA[$<attribute[attribute_MaterialCategory]>]]></Expression>
	<Expression><![CDATA[$<attribute[attribute_TargetCost]>]]></Expression>
	<Expression><![CDATA[$<attribute[attribute_EstimatedCost]>]]></Expression>
</Expressions>

SeriesExpression

Data used to create multi series chart. SeriesExpression value becomes legend label and Name setting ignored. For multiple Serie it will be ignored.

  • usesBusinessObject: This attribute value on SeriesExpression tag enable to evaluate expression on relationship.

    • true: SeriesExpression is object selectable . This is default behaviour.

    • false: SeriesExpression is relationship selectable.

If usesBusinessObject attribute is used, then DataSet need to be defined in such a way that it will remove the root object.
<SeriesExpression>current</SeriesExpression>
<SeriesExpression usesBusinessObject="false">${attribute[attribute_UnitofMeasure]}</SeriesExpression>

If user want to show multi series chart based on EBOM relationship on relationship attribute Unit of Measure then chart DataSeries and DataSet will be look like below

<DataSeries>
    <Serie>
        <DataLoader>
            <DataSet>tvc:dataset:hex:engineering/EBOM.xml</DataSet>
        </DataLoader>
        <Expression><![CDATA[$<attribute[attribute_MaterialCategory]>]]></Expression>
        <ChartType>line</ChartType>
        <SeriesExpression usesBusinessObject="false">${attribute[attribute_UnitofMeasure]}</SeriesExpression>
    </Serie>
</DataSeries>
<DataSet>
	<RemoveRoots>
		<Expand>
	        <From>true</From>
	        <To>false</To>
	        <Depth>1</Depth>
	        <RelationshipPattern>
	            <Relationship>relationship_EBOM</Relationship>
	        </RelationshipPattern>
	    </Expand>
	</RemoveRoots>
</DataSet>

ChartType

Type of chart.

Available kind of charts:

  • bar

  • line

  • pie

  • donut

  • radar*

  • Histogram*

  • radialBar*

  • scatter*

  • bubble*

  • heatmap*

  • Candlestick*

  • rangeBar* NOTE: * These are only available version2 charts.

<ChartType>line</ChartType>
Example configuration
<?xml version="1.0" encoding="UTF-8"?>
<Chart>
    <Sort>
        <Value ascending="false" />
    </Sort>
    <Tooltip>true</Tooltip>
    <Top>5</Top>
    <DrillDown>tvc:dashboard:helium/PartDrillDown.xml</DrillDown>
    <DataSeries>
        <Serie>
            <DataLoader>
                <DataSet>tvc:dataset:helium/MyParts.xml</DataSet>
            </DataLoader>
            <Expression><![CDATA[$<attribute[attribute_MaterialCategory]>]]></Expression>
            <ChartType>bar</ChartType>
        </Serie>
    </DataSeries>
</Chart>
Multi Series Chart Example configuration

Multi Series Bar Chart

image
<?xml version="1.0" encoding="UTF-8"?>
<Chart>
    <Sort>
        <Value ascending="false" />
    </Sort>
    <Options>{
  		"legendPosition": "top"
	}</Options>
    <Tooltip>true</Tooltip>
    <Legend>true</Legend>
    <Top>3</Top>
    <DrillDown>tvc:dashboard:helium/PartDrillDown.xml</DrillDown>
    <DataSeries>
        <Serie>
            <DataLoader>
                <DataSet>tvc:dataset:hex:engineering:homepage/MySoftwareParts.xml</DataSet>
            </DataLoader>
            <Expression><![CDATA[$<attribute[attribute_MaterialCategory]>]]></Expression>
            <ChartType>bar</ChartType>
            <Name>Software Part</Name>
        </Serie>
        <Serie>
            <DataLoader>
                <DataSet>tvc:dataset:hex:engineering:homepage/MyElectricalParts.xml</DataSet>
            </DataLoader>
            <Expression><![CDATA[$<attribute[attribute_MaterialCategory]>]]></Expression>
            <ChartType>bar</ChartType>
            <Name>Electrical Part</Name>
        </Serie>
         <Serie>
            <DataLoader>
                <DataSet>tvc:dataset:hex:engineering:homepage/MyMechanicalParts.xml</DataSet>
            </DataLoader>
            <Expression><![CDATA[$<attribute[attribute_MaterialCategory]>]]></Expression>
            <ChartType>bar</ChartType>
            <Name>Mechanical Part</Name>
        </Serie>
    </DataSeries>
</Chart>

Multi Series Stacked Bar Chart

image
<?xml version="1.0" encoding="UTF-8"?>
<Chart>
    <Sort>
        <Value ascending="false" />
    </Sort>
    <Options>{
  		"legendPosition": "top"
	}</Options>
    <Tooltip>true</Tooltip>
    <Legend>true</Legend>
    <Top>3</Top>
    <Stack>true</Stack>
    <DrillDown>tvc:dashboard:helium/PartDrillDown.xml</DrillDown>
    <DataSeries>
        <Serie>
            <DataLoader>
                <DataSet>tvc:dataset:hex:engineering:homepage/MyParts.xml</DataSet>
            </DataLoader>
            <Expression><![CDATA[$<attribute[attribute_MaterialCategory]>]]></Expression>
            <SeriesExpression>current</SeriesExpression>
            <ChartType>bar</ChartType>
            <Name>Software Part</Name>
        </Serie>
    </DataSeries>
</Chart>
Example custom onClick

The <OnClick> configuration can be used to perform custom action when the user clicks in the chart. This enables the possibility to do drill down, exchange information in tables or something else. In the configuration you specify the JavaScript function to invoke upon user clicks.

Configuration:

<OnClick>App.custom.chartOnClick</OnClick>

JavaScript:

var App = App || {};
var App.custom ={
    chartOnClick: function(data) {
        console.log('Clicking in chart');
        console.log('  Clicked data=', data);
        console.log('  Chart reference=', this);

        // Code performing something nifty
    }
};
Use either DrillDown OR OnClick.
The javascript function will be executed with this set to the chart.

10.1.3. Data Type

The data type controls how the data series in the chart are calculated. The input to the data type processing is the configurations done in the chart configuration file along with information about which objects that are displayed in the chart.

Output format:

{
    'labels': ['<label>', '<another-label>', ...],
    'series': [{
        'name': '<name>',
        'data': [{
            'value': <value>
            'objectIds': [
                '<object-id>',
                '<another-object-id>',
                ...
            ]
        },{
            ...
        }]
     },{
        ...
    }]
}

Example output:

{
    'labels': ['W34', 'W35', 'W36'],
    'series': [{
        'name': 'Created',
        'data': [{
            'value': 1
            'objectIds': [
                '1.2.3.4'
            ]
        }, {
            'value': 0
            'objectIds': []
        }, {
            'value': 3
            'objectIds': [
                '2.3.4.5',
                '5.6.7.8',
                '9.8.7.6'
            ]
        }]
     }, {
         'name': 'Resolved',
         'data': [{
             'value': 0
             'objectIds': []
         }, {
             'value': 1
             'objectIds': [
                 '1.2.3.4'
             ]
         }, {
             'value': 2
             'objectIds': [
                 '5.6.7.8',
                 '9.8.7.6'
             ]
         }]
      }]
}

Charts comes with a built-in data type strategy, but it also possible to write a custom data type.

Data Type: Group

The objects are grouped by a configured expression, e.g. type or state. Each unique value gets one label and the amount of objects is the data value. It expects there to be exactly one dataserie in the configuration.

Example custom data type

Configuration:

<DataType>App.custom.timeDataType</DataType>

JavaScript:

var App = App || {};
var App.custom = {
    timeDataType: function(config) {

        var getObjectDataValues = function(expression, objectId, relId) {
            if (expression.usesBusinessObject) {
                return App.ObjectStore.get(objectId).data[expression.name].values;
            }
            return App.ObjectStore.getRelationship(relId).data[expression.name].values;
        }


        // Check each label how many values there are per serie
        //    - 2015-06-24 5 created 3 solved issues
        //    - 2015-06-25 1 created 0 solved issues
        //    - 2015-06-26 3 created 2 solved issues

        var labels = ['2015-06-24', '2015-06-25', '2015-06-26'];
        var series = [];

        config.series.forEach(function(serie) {
            var expr = serie.expression;
            var result = {
                'name': expr.name
                'data': []
            };


            serie.objectIds.forEach(function(objectId, index) {
                let relId = serie.relIds[index];
                let values = getObjectDataValues(expr, objectId, relId);
                values.forEach(function(value) {

                    // Logic calculating amount of objects which have been created/resolved

                    var dataPoint = {
                        'value': 1,
                        'objectIds': ['1.2.3.4'],
                        'relIds': ['5.6.7.8']
                    };
                    result.data.push(dataPoint);
                });
            });

            series.push(result);
        });

        return {
            'labels': labels,
            'series': series
        };
    }
};
Example custom data type with support for multi-value attributes

Configuration:

<DataType>App.custom.customChartValues</DataType>

JavaScript:

var App = App || {};
var App.custom = {
    customChartValues: function(config) {

        var setLabelData = function(labelPoints, value, objectId, relId) {
            labelPoints[value].value += 1;
            labelPoints[value].objectIds.push(objectId);
            labelPoints[value].relIds.push(relId);
        }

        var getObjectDataValues = function(expression, objectId, relId) {
            if (expression.usesBusinessObject) {
                return App.ObjectStore.get(objectId).data[expression.name].values;
            }
            return App.ObjectStore.getRelationship(relId).data[expression.name].values;
        }

        var labels = config.options.labels;
        var series = [];

        config.series.forEach(function(serie) {
            var points = [];
            var expr = serie.expression;
            var labelPoints = {};
            var legendLabel = serie.name || '';

            labels.forEach(function(label) {
                var dataPoint = {
                    value: 0,
                    objectIds: [],
                     relIds: []
                };
                labelPoints[label] = dataPoint;
            });

            serie.objectIds.forEach(function(objectId, index) {
                var relId = serie.relIds[index];
                var values = getObjectDataValues(expr, objectId, relId);
                var filteredValues = values.map(function(v) {return v.value;}).filter(function(v) {return labels.includes(v)});

                filteredValues.forEach(function(value) {
                    setLabelData(labelPoints, value, objectId);
                });
                if (filteredValues.length > 1) {
                    setLabelData(labelPoints, labels[2], objectId);
                };
            });

            labels.forEach(function(label) {
                points.push(labelPoints[label]);
            });

            series.push({
                name: legendLabel,
                data: points
            });
        });

        return {
            labels,
            series
        };
    }
};
image
Figure 39. Chart displaying custom data type with multi-values

Image is showing:

  • DataSet is an inquiry that returns 33 objects based on attribute[Material Category]

  • 29 of these objects have the attribute value ‘Glass’

  • 10 of them have the attribute value ‘Plastic’

  • 6 of them have both attribute values ‘Glass’ and ‘Plastic’

10.1.4. API

The chart javascript api can be found here

10.1.5. Path Support

In 3dexperince, more and more of the data model is moving towards path-based. Change Process is one good example and there is a need to be able to visualize the path-based data model by config only.

Now the path related object/relationship information can be used to generate charts. This can be done using the path query dataset in chart config.

Below example generates a chart based on the attribute Severity of Change Orders related to context part EBOM structure. In this case, the loader must point to Path Query which will return change order id’s and the Expression should point to selects on those change order id’s, in this case, attribute 'Severity'.

<?xml version="1.0" encoding="UTF-8"?>
<Chart>
	<DataSeries>
		<Serie>
			<DataLoader>
				<DataSet>tvc:dataset:hex:engineering/ChangeObjects.xml</DataSet>
			</DataLoader>
			<Expression><![CDATA[$<attribute[attribute_Severity]>]]></Expression>
			<ChartType>donut</ChartType>
		</Serie>
	</DataSeries>
</Chart>

Below is the loader definition used in the above example.

<?xml version="1.0" encoding="UTF-8"?>
<PathQuery>
	<PathType>Proposed Activity.Where</PathType>
	<PathSelect>owner.to[Proposed Activities].from.to[Change Action].from.id</PathSelect>
	<Expand>
		<From>true</From>
		<To>false</To>
		<Depth>1</Depth>
		<RelationshipPattern>
			<Relationship>relationship_EBOM</Relationship>
		</RelationshipPattern>
	</Expand>
</PathQuery>
image
Figure 40. Path Support in Charts

Read the Path Support chapter for more details.

10.1.6. Combination Charts

Combination charts let you display different types of data in different ways on the same chart. You may display columns, lines, areas, and steps all on the same combination chart. Use them to visually highlight the differences between different sets of data.

There could be multiple combinations like line and bar or line, bar and area with different dataseries representing different chart type. One of the serie should have chart type as line.

This can be configured as below :

<ChartWidget>
	<Title>Multi Series Combo Charts</Title>
	<ChartConfig namespace="hex:engineering:homepage">CombinationCharts.xml</ChartConfig>
	<UseVersion2>true</UseVersion2>
</ChartWidget>
<Chart>
    <DataSeries>
        <Serie>
            <Name>bar</Name>
            <DataLoader>
                <DataSet>tvc:dataset:hex:engineering:homepage/Dataset3.xml</DataSet>
            </DataLoader>
            <Expression>current</Expression>
            <ChartType>line</ChartType>
        </Serie>
        <Serie>
            <Name>area</Name>
            <DataLoader>
                <DataSet>tvc:dataset:hex:engineering:homepage/Dataset1.xml</DataSet>
            </DataLoader>
            <Expression>current</Expression>
            <ChartType>area</ChartType>
        </Serie>
        <Serie>
            <Name>line</Name>
            <DataLoader>
                <DataSet>tvc:dataset:hex:engineering:homepage/MyParts.xml</DataSet>
            </DataLoader>
            <Expression>current</Expression>
            <ChartType>line</ChartType>
        </Serie>
        <Serie>
            <Name>column</Name>
            <DataLoader>
                <DataSet>tvc:dataset:hex:engineering:homepage/Dataset1.xml</D
                ataSet>
            </DataLoader>
            <Expression>current</Expression>
            <ChartType>bar</ChartType>
        </Serie>
    </DataSeries>
</Chart>
image
Figure 41. Combination Charts

10.1.7. Other Chart types

Now all the chart types available in Apex Charts are supported in helium, they can be configured by using below config :

<ChartWidget>
	<Title>EBOM Start Eff date to End Effectivity Date</Title>
	<ChartConfig namespace="hex:engineering">TimelineChart.xml</ChartConfig>
	<UseVersion2>true</UseVersion2>
</ChartWidget>

<Chart>
    <DrillDown>tvc:dashboard:hex:engineering:homepage/MyDocumentsDrillDown.xml</DrillDown>
    <Tooltip>true</Tooltip>
    <Legend>true</Legend>
    <Tooltip>true</Tooltip>
    <Stack>false</Stack>
    <DataType>App.custom.getTimelineChartData</DataType>
    <DataSeries>
        <Serie>
            <Name>Drawing Prints</Name>
            <DataLoader>
                <DataSet>tvc:dataset:hex:engineering/EBOM.xml</DataSet>
            </DataLoader>

            <Expressions>
            	<Expression>${attribute[attribute_StartEffectivityDate]}</Expression>
                <Expression>${attribute[attribute_EndEffectivityDate]}</Expression>
                <Expression>${name}</Expression>
            </Expressions>
            <ChartType>rangeBar</ChartType>
        </Serie>
    </DataSeries>
    <Options>{
    	"xaxis": {
          "type": "datetime"
        },
        "plotOptions": {
          "bar": {
            "horizontal": true
          }
        }
    }</Options>
</Chart>

Since every chart types expects data in different format so a js method can be passed in DataType which returns the data in the required format, refer below example.

var getTimelineChartData = function(config) {
		var objectIds = config.series[0].objectIds;
		var chartData = []
		var data = App.ObjectStore.getByIds(config.series[0].objectIds);
		objectIds.forEach(function(objectId){
			var objectData = data[objectId];
			var startDate = objectData.data['attribute[Start Effectivity Date]'].values[0].value;
			var endDate = objectData.data['attribute[End Effectivity Date]'].values[0].value;
			if(startDate ){
				endDate = endDate ? endDate : new Date();
				chartData.push({
				"x" : objectData.data['name'].values[0].value,
				"y" : [
					new Date(startDate).getTime(),
					new Date(endDate).getTime()
				]
			})
			}


		})
        return {
        	'dataType' : "version2",
            'series': [{"data" : chartData}]

        };
    }
image
Figure 42. TimelineChart

10.2. Datatable

The datatable widget presents data in a table. It is possible to interact with data in multiple ways. Some of the things the table supports are.

  • Filtering/Searching

  • Sorting

  • Pagination

  • Inline editing of cells

  • Exporting to PDF, CSV and Excel

  • Custom rendering of cells via either CSS or by applying a Handlebars template

  • Internationalization

Datatable

Find the possible configuration options for a table below

10.2.1. Widget

To create a data table widget you must first create an xml with the following contents:

<DataTable>
    <Title>Data Table</Title>
    <TableConfig namespace="helium">TableConfig.xml</TableConfig>
</DataTable>

The <DataTable> element supports the following child elements.

Name Description Example

Title

The title of the data table.

Currently not rendered in UI.

<Title>Data table title</Title>

TableConfig

Specifies the data table config file

<TableConfig namespace="helium">
    TableConfig.xml
</TableConfig>

Responsive

Specifies whether the table should be responsive, i.e adjust it self to small screens. If this element is set to true and the all the columns can’t fit on the screen an additional column containing a plus icon will be rendered. When the user clicks the icon the 'hidden' columns will be folded out. Defaults to true.

<Responsive>true</Responsive>

Paginated

This setting is deprecated and will no longer be supported from Helium release 2019.1.0 onward. The pagination setting provided in table configuration will be used for enabling/ disabling pagination.

<Paginated>true</Paginated>

Sortable

Specifies whether the table should support sorting or not. Defaults to true

<Sortable>true</Sortable>

FixedHeader

Specifies whether the table headers should be fixed or not. Defaults to false 

This can also be enabled at the global level for all the tables by using the key tvc.helium.datatable.fixedHeader=true in tvc.properties. The default value is false. This global setting can be overridden by individual level fixed header setting if explicitly adds FixedHeader.

<FixedHeader>true</FixedHeader>

PersistentExpandState

Specifies whether the structure will be expanded the same way the next time the same object view is loaded.

Please see Structure Browser Chapter for more details on how to configure persistent expand state and max count through init params

<PersistentExpandState>true</PersistentExpandState>

HotKeysNavigation

Enables user to use arrow keys for navigating from one cell to another while editing, Defaults to false.

In order to move within a text or select field, user can use arrow keys with ctrl.
This feature is currently supported for non responsive tables with client side processing true.

<HotKeysNavigation>true</HotKeysNavigation>

or globally

tvc.helium.datatable.hotKeysNavigation = true

10.2.2. Table Configuration

The <TableConfig> element can have the following children. Full example.

Name Description Example

Title

The title of the table.

Currently not rendered in UI.
<Title>Title of table</Title>

DataLoader

References to the dataset to be loaded into the table via the child element <DateSet> or <SearchBasedLoader>. SearchBasedLoader can be used when table is expected to load data from search side panel. See On Search Result for more details on search and search based loader.

When SearchBasedLoader is defined, ClientSideProcessing should be false and DisplayMode can only be flat.
<DataLoader>
  <DataSet>
    tvc:dataset:helium/MyDataset.xml
  </DataSet>
</DataLoader>

InvokeService

Whether to consider input of response received from service call or dataset of dataloader. Valid value is either true or false. By default it is false

if value is true, to make service call ServiceParams should be passed

<InvokeService>true</InvokeService>

ServiceParams

To load data into table from the response received after making service call. Dataoader will not be needed for this. To pick data from service call it is required have service parameters.

url

Service url to fetch list of all items to populate in table

method

Method type for making the service call

dataSrc

JSON path expression where list of objects available from where information can be fetched to populate table data

objectId

JSON path expression where objectId is available in data from dataSrc

urlParams

List of parameters that are to be passed while making service call. Parameters can be given in key : value format. Value can either be a call back function or string.

<ServiceParams>{
        "url":"resources/v1/modeler/subscriptions",
        "method":"GET",
        "dataSrc":"data",
        "objectId":"id",
        "urlParams": {
            "$language":"App.Utils.preferredLanguage",
            "xrequestedwith":"xmlhttprequest"
        },
    }
</ServiceParams>

Table

References to table configuration file that defines the columns

<Table namespace="helium">TableConfig.xml</Table>

DisplayMode

Valid options are flat and structure. Note: For structure mode tables, you also must provide the ExpandSettings element.

<DisplayMode>flat</DisplayMode>

ExpandSettings

Mandatory element for structure mode tables. Point out a filter and optionally initial expand depth.

InitialExpandDepth

InitialExpandDepth defines how many level root object(s) should be expanded on initial load. Default value is 1.

Mode

By default only first root node will be expanded. This can be overridden by using attribute mode on InitialExpandDepth. Valid values are none,first and all.

Custom Expander

In more advanced situations, custom java expander can be used to perform the expansion.

When InitialExpandDepth is defined along with Data Set Expand, InitialExpandDepth takes precedence over Data Set Expand depth.
EvaluateExpandableNodes

Optionally this can be set to True (default is False) to evaluate whether a node is a leaf node and make it non-expandable. This will improve usability as leaf nodes are indicated without an expand symbol (plus sign). This can also be controlled globally through the init-param tvc.core.structure.evaluate.expandable.node (default false) in web.xml.

This evaluation will make an extra expand which may affect performance (often very little). This feature is by default off.
<ExpandSettings>
    <Filter ns="helium">EBOMFrom.xml</Filter>
    <InitialExpandDepth mode="none">1</InitialExpandDepth>
</ExpandSettings>
<ExpandSettings>
<Expander>java:com.acme.MyExpander</Expander>
    <InitialExpandDepth mode="all">1</InitialExpandDepth>
</ExpandSettings>
<ExpandSettings>
   <EvaluateExpandableNodes>true</EvaluateExpandableNodes>
</ExpandSettings>

CreateSettings

Optional. Reference to the CreateAndConnectRow widget command to create and connect a new child row to the selected parent row. CreateSettings supports different child elements to pass values that are required to create and connect new child row object.

Example:

<CreateSettings>
  <Type value="type_Part" />
  <Name useNumberGenerator="true"                   tvcNumberGenerator="false" />
  <Revision firstInSequence="true" />
  <Policy value="policy_DevelopmentPart" />
  <Vault value="vault_eServiceProduction" />
  <Connection value="relationship_EBOM" direction="from" />
</CreateSettings>

ForceReload

Whether the table is forced to load data from the server each time widget is refreshed. Valid value is either true or false. By default it is false.

<ForceReload>true</ForceReload>

RowSelect

Whether the rows in the table should be selectable or not. Valid values none, single and multi.

<RowSelect>multi</RowSelect>

Pagination

Whether the table should support pagination or not. The element supports the following attributes:

disabled

If pagination should be disabled or not. Valid values, true or false

size

The default number of rows to show

lengthMenu

Comma seperated list of values that should be added in the menu as number of rows to show. Defaults to 10, 25, 50, 100. If the size value is not included in this list it will automatically be added.

<Pagination size="15" disabled="false" />

ClientSideProcessing

Whether sorting, filtering and pagination should be handled on the client or on the server. The element supports the following attributes:

enabled

Valid values true or false

threshold

If the table has more rows then the configured threshold (defaults to 10 000) then server side processing automatically will be turned on. For example: Client side processing is enabled via 'enabled="true"' and the threshold is set to 100 via 'threshold="100"'. If the current table contains 101 rows the 'enabled="true"' flag will be overridden and server side processing will be used.

<ClientSideProcessing enabled="true"
                      threshold="100" />

EvalCurrentPage

Whether table columns should be evaluated page wise.

It can also be defined globally via structure browser setting tvc.structurebrowser.evalCurrentPage. Setting defined in table config takes precedence over global setting. Default value is true.

Note

Only when client processing is disabled, page wise evaluation if enabled will take place.

<EvalCurrentPage>true</EvalCurrentPage>

StructureGUI

Whether the expand button should be rendered in its own column or in the first configured column.

default

The expand button is rendered in its own column.

caret

The expand button is rendered in the first configured column in the table.

In-cell editing is deactivated for the column that is used as the structure navigation column.
<StructureGUI>caret</StructureGUI>

ResizeColumns

Allow table columns to resize from UI. Valid value is either true or false. By default it is false.

Resize columns feature can also be enabled at the global level for all the tables by using the key tvc.helium.datatable.resizeColumns.enabled=true in tvc.properties. The default value is true.

While resizing the column if column header or data is truncated, then tooltip automatically enabled on column header and data. This feature can be disabled at the global level for all the tables by using the key tvc.helium.datatable.tooltip.onResizeColumns=false in tvc.properties. The default value is true.

<ResizeColumns>true</ResizeColumns>

FixedColumns

Allowing the specified number of left most non reponsive table columns to fix while horizontally scrolling.

<FixedColumns>2</FixedColumns>

RowDragAllowed

If row drag should be allowed from the table

<RowDragAllowed>true</RowDragAllowed>

DropConfigs

A Drop config defines what happen when a object is dropped on the row.

AllowedDropType

Defines the type of object on which can be dropped.

ValidRowType

Defines the type of object on which the row is being dropped.

RelationshipType

Defines the relationship for the connection.

RelationshipDirection

Defines on which side the dropped object should be connected.

PostAction

Defines if the row should be refresh or expand after an object is dropped.

RequestMethod

Defines the request method when the 3DExperience service is called.

PreInvokeServiceFunction

Some javascript function that can be invoked before calling 3DExperience service.

PostInvokeServiceFunction

Some javascript function that can be invoked after calling 3DExperience service.

InvokeServiceUrl

the url for the 3DExperience service.

Payload

Describes the request body of the 3DExperience service.

<DropConfigs>
    <DropConfig>
        <AllowedDropType>Part,Some Other Type</AllowedDropType>
        <ValidRowType>Part</ValidRowType>
        <RelationshipType>EBOM</RelationshipType>
        <RelationshipDirection>to</RelationshipDirection>
        <PostAction>refresh</PostAction>
    </DropConfig>
</DropConfigs>

AutoSelectContent

While editing cell content, this enables to auto select contents of cell. This applies to all eligible columns in the table. Defaults to false.

This can be overridden by defining autoSelectContent setting at column level.

Auto select of content is applicable only for textbox and textarea fields.
<AutoSelectContent>TRUE</AutoSelectContent>
Example
<TableConfig>
    <!-- This is the title element -->
    <Title>This is the default title</Title>
    <Title>Table title</Title>

    <DataLoader>
        <DataSet>tvc:dataset:helium/MyParts.xml</DataSet>
    </DataLoader>

    <Table>tvc:table:helium/BasicInfo.xml</Table>

    <DisplayMode>flat</DisplayMode>

    <StructureGUI>default</StructureGUI>

    <RowSelect>multi</RowSelect>

    <Pagination size="15" disabled="false" />

    <ClientSideProcessing enabled="false" threshold="100" />
</TableConfig>
StructureGUI
image
Figure 43. StructureGUI in default vs caret mode

10.2.3. Column configuration

How to configure columns is described below. This is the file that is referenced above in the Table configuration

The <Table> element supports the following child elements.

Name Description Example

DisplayName

The display name of the table.

Currently not rendered in UI.
<DisplayName>
    Basic Information
</DisplayName>

Column

Creates a column in the table

See Column specific details below

Column

The <Column> element describes the properties of a data table column.

The <Column> element supports the following child elements.

Name Description Example

ColumnType

<ColumnType>helium-column-actions</ColumnType>

Description

The brief details of the column that is rendered as a column header tooltip.

<Description>Brief detail of column</Description>

Alt

This setting renders brief details of the column as a column header tooltip. This setting is an alternative to the Description setting.

If Alt and Description settings are defined together then Description setting is given preference.

<Alt>Brief detail of column</Alt>

Editable

Whether the cells in the column should be editable or not.

If column editable setting is defined as false, then cell cannot be made editable via DataHandler. If it is intended that DataHandler should make cell editable or non-editable depending on some condition, then column editable setting should be set to true.

<Editable>true</Editable>

Expression

The expression that fetches the data from the backend. If column is populated using data received from response of service call, JSON path expression in the dataSrc is to be specified and additional setting option jsonResponse is to be given.

<Expression>name</Expression>

<Expression>dataelements.type</Expression>
<Setting name="options">{
	"jsonResponse":"true"
}</Setting>

InputType

If the column is editable, what input element should be rendered. Allowed values are:

textbox

will render a text input field

textarea

will render a text area

combobox

will render a select box

radiobutton

will render radio buttons

checkbox

will render checkboxes

datepicker

will render a date picker

If no input type is given the cell will default to an textbox.

<InputType>textarea</InputType>

Label

The name of the column that is rendered as a table header.

<Label>name</Label>

Name

The name of the column

The name is mandatory

<Name>Column name</Name>

NoWrap

This setting defines whether the column’s values will be wrapped or not.

True
The column’s values will not be wrapped. This is default behaviour.

False
The column’s values will be wrapped whenever needed to fit within the bounds of the column without enlarging the table too much.

<NoWrap>true</NoWrap>

Setting

Column specific setting. The supported attributes are:

name

the name of the setting

value

the value of the setting

If the ColumnType is set to helium-column-actions a setting with the name menu must be added and a value that points to an menu xml file. See second example.

If the name of the setting is options it is possible to add a json object as the element value. This way you can control client side validation, autocomplete settings,On Edit and column filter.

If the name of the setting is class it is possible to add class names as value for custom CSS classes

If the name of the setting is groupHeaderClass it is possible to add class names as value for custom CSS classes on group header just like class

If the name of the setting is autoSelectContent it is possible to auto select content when it is edited. This is applicable only for textbox and textarea fields.

<Setting name="template" value="helium/templates/table/test" />
<Column>
    <Label>emxComponents.Common.Actions</Label>
    <RegisteredSuite>Components</RegisteredSuite>
    <ColumnType>helium-column-actions</ColumnType>
    <Setting name="menu" value="tvc:menu:helium/ColumnActions.xml" />
</Column>
<Column>
    ...
    <Setting name="options">
        {
            "footerFilter": true
            "autocomplete": {
                "selectize": {
                    "preload": true
                },
                "handler" : {
                    "name": "user",
                    "localize": "true",
                    "contains": "true",
                    "caseSensitive": "false"
                }
            }
        }
    </Setting>
    ...
</Column>
<Setting name="class" value="col-weight col-bold col-red col-small" />
<Setting name="groupHeaderClass" value="green-color" />
<Setting name="autoSelectContent" value="true" />

AlternateOIDExpression

This setting can be used to control to which object the user should be routed when the column’s data is displayed as a hyperlink.

While using Alternate OID Expression, the default template is used and no custom template is supported. The value for this setting should be a valid select expression that returns object-ids.

$<to[relationship_DesignResponsibility].from.id>

$<to[relationship_EBOM].from.id>

Sortable

Specifies whether the column should be sortable or not. Valid values: true or false. Defaults to true.

<Sortable>false</Sortable>

SortDirection

Specifies the sort direction. Valid values: ascending and descending.

<SortDirection>ascending</SortDirection>

SortOrder

Specifies what column to make the initial sort on. Valid values: A positive integer (zero based). For example if you want the initial sorting to be based on the second column you would add the value 1.

<SortOrder>1</SortOrder>

SortType

Specifies the sort type, i.e numeric, string, numeric or date

<SortType>numeric</SortType>

TextLength

Defines number of characters to be displayed before truncation. The rest will be displayed in a tooltip.

<TextLength>25</TextLength>

TruncateDirection

Defines truncate direction on column, If the number of characters in a cell text exceeds the text length. Valid values: right, left or center. default value is right.

If truncate direction is center then user needs to provide additional setting LeftTextLength & RightTextLength.
<TruncateDirection>left</TruncateDirection>
<TruncateDirection>center</TruncateDirection>
<LeftTextLength>3</LeftTextLength>
<RightTextLength>3</RightTextLength>

Rows

Defines number of rows to be displayed before truncation. The rest will be displayed in a tooltip.

<Rows>3</Rows>

usesBusinessObject

This attribute value on column tag defines if column is for relationship.

true
Column expression is object selectable . This is default behaviour.

false
Column expression is relationship selectable

<Column usesBusinessObject="false">
...
</Column>

Visible

This setting defines whether a column should be visible or not.

The user is able to define his/her own set of visible columns.

True
The column will be visible (Default).

False
The column is not visible.

TargetLocation

This setting can be used when we are opening routing to emxTree.jsp in 3dspace.

Content
The object will open in same window.

Popup
The object will open in popup.

Href

Defines the Href

<Href>/${ROOT_DIR}/SomePage.jsp</Href>

AllowMultipleEdit

Specifies whether the column should be mass update or not. Valid values: true and false.

<AllowMultipleEdit>true</AllowMultipleEdit>

GroupHeader

Defines a group header for the column. Typically, a group header is used to group several columns together, with a common label. The setting need to be defined on all columns that are part of the group.

<GroupHeader>The group header</GroupHeader>

ColumnWidth

Defines the column width in pixels. If content is exceeding the defined width, then truncated content will be shown with ellipses and also tooltip will be enabled for the same.

<ColumnWidth>100</ColumnWidth>

ShowTypeIcon

Specifies if the type icon is shown or not. Default is false.

If it is set to true, a setting with the name template must be added
<Setting name="template" value="helium/templates/table/typeWithIcon" />

If you have already defined template then you can add following content to your existing template.

{{#if cell.values.0.iconURL}}
    <img class="left" src="{{cell.values.0.iconURL}}"  />
{{/if}}

<ShowTypeIcon>true</ShowTypeIcon>

Column template

The default rendering of a column cell can be overridden with a handlebars template.

{{!--
  Sample Handlebars template that can be applied to columns in a datatable.

  <Column>
  ...
  <Setting name="template" value="/path/to/this/template/test" />
  </Column>

  <Setting name="template" value="helium/templates/table/object-link" />
  <!-- If same table column is used in embeded mode, standalone mode and 3dashboard  -->

  <Setting name="template" value="helium\templates\table\object-link-with-alternate-oid" />
    <!-- For the column which has AlternateOIDExpression or columntype path, same table column is used in embeded mode, standalone mode and 3dashboard -->

  Available variables are:
  - object
  - row
  - cell

  To inspect what the content of the variables are, run {{debug variable}} and check your console

--}}
<a href="javascript:App.routing.open('{{objectId}}');">{{value}}</a>
Configurable column CSS classes

It is possible to add configurable CSS classes to columns in the column XML, use <Setting> with class as the name and the custom class names as value, separated by spaces

<Setting name="class" value="col-weight col-bold col-red col-small" />

Then in your custom css, you can target column level styling, e.g.

Some selectors require higher specificity or the use of !important rule.
.col-bold {
    font-weight: bold !important;
}

.col-red {
    color: red;
}

.col-small {
    width: 50px;
}

You can also specifically target a column’s header or body with th/td, e.g.

th.col-weight {
    font-weight: bold !important;
    color: darkred !important;
}

th.col-description {
    font-style: italic;
    color: darkgreen !important;
}

td.col-revision {
    color: darkorange;
}
Client side validation

It is possible to provide a javascript function that performs client side validation. This is achieved by applying the following element to an column:

<Setting name="options">{
    "validator": "App.custom.someJavascriptFunction",
    "validatorMsg": "Error message, either an message or a i18n key"
}</Setting>

The javascript function will be executed when the cell is blurred and with the value of the field passed in. The function must return a boolean, true if the value is valid and false otherwise.

Column filter

It is possible to add a filter to either the footer or the header of a column by specifying the following setting. Valid values for position is "footer" and "header". Default value is "footer".

<Setting name="options">{
    "filter": {
        "position": "footer"
     }
}</Setting>

This will render an input field in the column footer, where the user can filter out rows based on the values in that column. User can use multiple queries by using "|" as delimeter in between query.

It is not supported to have filters in both the header and the footer in the same table.
Column filter with row filter

It is possible to add a row filter to a column filter by specifying the setting rowFilter. The value should be a css class that matches the a row that the filter should be applied to. For example to apply the filter to only a certain level of a structure table add the value ".row-level-n" where n is the level the filter should be applied to.

<Setting name="options">{
    "filter": {
        "position": "footer",
        "rowFilter": ".row-level-1"
    }
}</Setting>

If the filter is applied on a row in a structure table and that row is expanded the child rows will not be affected of the filter.

On Edit

It is possible to configure different behavior on edit of a cell. This can be configured as below :

<Column>
    ...
    <Setting name="onEdit" value="refresh-parents" />
    ...
</Column>

Possible values are refresh-parents, refresh-table, or some custom javascript function.

If onEdit is not configured than only the current row will get refreshed.

In custom js function it will have context of datatable and row jquery element and column instance as arguments.

onColumnEdit : function($rowElement,column)  {
    	    		App.toaster.success("column edit successfully")
    	},
Name Description

refresh-parents

It will refresh the parent rows of the edited cell.

refresh-table

It will refresh the table.

some custom js function

It will call the js function passed in the value once the cell is edited.

headerNoTruncate

ResizeColumns allow table columns to resize from UI. This will allow user to truncate the column below the actual content of the header. This behavior can be controlled using the headerNoTruncate setting i.e. user can not resize the column below the actaul content of the header. This can be configured as below :

<Column>
    ...
    <Setting name="headerNoTruncate" value="true" />
    ...
</Column>

Possible values are true, or false. The default value is false.

This can also be enabled at the global level for all the tables by using the key tvc.helium.datatable.headerNoTruncate.enabled=true in tvc.properties

Autocomplete

All columns which renders an select field have basic autocomplete support. With the options outlined below the behavior can be customized to great extent.

For autocomplete to work the <InputType> element must be set to combobox

To customize autocomplete provide the following setting:

<Setting name="options"><![CDATA[
{
    "autocomplete": {
        "template": "...",
        "selectize": { ... },
        "handler" : { ... }
    }
}
]]>
</Setting>

Each block, template, selectize and handler is described below.

template

Provide an path to an template to customize the dropdown. Example of template:

<div>
    <p>{{label}}</p>
</div>
selectize

The client utilizes Selectize and all options described in the docs can be used here. To show selectize dropdown outside the widget boundaries. The global level property tvc.helium.selectize.showDropdownOutsideFrame can be defined in tvc.properties file or can be configured on specific column as below

<Setting name="options">{
        "autocomplete": {
            "selectize" : {
				"showDropdownOutsideFrame" : true
			}
        }
}</Setting>
handler

All settings that are described in the core admin guide can be used in the handler block including all predefined handlers.

If you wan’t to create a custom autocomplete handler, follow the admin guide and pass the java class as the value for the name key.

Full example:

<Setting name="options"><![CDATA[
    {
        "autocomplete": {
            "template": "/helium/templates/form/autocomplete",
            "selectize": {
                "preload": true,
                "maxItems": null,
                "labelField": "name",
                "searchField": ["name"]
            },
            "handler" : {
                "name": "dataset",
                "dataset": "tvc:dataset:helium/MyParts.xml",
                "select": ["name",  "current"]
            }
        }
    }
    ]]>
</Setting>
Highlight updated row cross-widget

Datatable rows that have their data updated via another widget will be highlighted to show the changes.

Showing cross-widget object update highlight
There is a API for highlighting any jQeury element here
Access Control

The access restriction for table column in Helium can be defined similar to TVC Classic based upon following settings:

  • AccessMask (Access mask for the current object)

  • AccessProgram and AccessFunction (A JPO and a function that evaluates the access rights)

  • AccessExpression (MQL expression that evaluates the access)

The example below illustrates how you can construct the access restriction:

<AccessMask>checkout,modify</AccessMask>

Or use an access program and access function:

<AccessProgram>MyAccessProgram</AccessProgram>
<AccessFunction>checkAccess</AccessFunction>

Or use an access expression:

<AccessExpression>policy == 'EC Part'</AccessExpression>

Please refer following links of TVC documentation for more details

Example
<Table xmlns="http://technia.com/TVC/Table" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://technia.com/TVC/Table http://products.technia.com/tvc/schema/latest/Table.xsd">
    <DisplayName>Basic Information</DisplayName>
    <Column>
        <Name>Type</Name>
        <Expression>type</Expression>
        <Label>Type</Label>
        <Fixed>TRUE</Fixed>
        <ShowTypeIcon>True</ShowTypeIcon>
        <NoWrap>true</NoWrap>
    </Column>
    <Column>
        <Name>Name</Name>
        <Expression>name</Expression>
        <Label>Name</Label>
        <Fixed>TRUE</Fixed>
        <SortDirection>ascending</SortDirection>
        <SortOrder>1</SortOrder>
        <Setting name="template" value="helium/templates/table/test" />
    </Column>
    <Column>
        <Name>Revision</Name>
        <Expression>revision</Expression>
        <Label>Revision</Label>
        <Fixed>TRUE</Fixed>
        <Editable>TRUE</Editable>
    </Column>
    <Column>
        <Name>Material Category</Name>
        <Expression>attribute[Material Category]</Expression>
        <Label>Material Category</Label>
        <AllowShowMore>TRUE</AllowShowMore>
        <Editable>TRUE</Editable>
        <InputType>combobox</InputType>
        <SortType>string</SortType>
        <AccessExpression>policy == 'EC Part'</AccessExpression>
    </Column>
    <Column>
        <Name>Desc</Name>
        <Expression>description</Expression>
        <Label>Description</Label>
        <Description>Describes this object in detail.</Description>
        <AllowShowMore>TRUE</AllowShowMore>
        <Editable>TRUE</Editable>
        <Columns>45</Columns>
        <Rows>5</Rows>
        <InputType>textarea</InputType>
        <SortType>string</SortType>
        <TextLength>40</TextLength>
    </Column>
    <Column>
        <Name>Owner</Name>
        <Expression>owner</Expression>
        <Label>Owner</Label>
    </Column>
    <Column>
        <Name>Weight</Name>
        <Label>Weight</Label>
        <Expression>attribute[Weight]</Expression>
        <Editable>TRUE</Editable>
        <SortDirection>ascending</SortDirection>
        <Setting name="class" value="col-weight col-bold col-red col-small" />
    	<AccessMask>checkout,modify</AccessMask>
    </Column>
</Table>
For Autocomplete functionality with Inquiry Dataset, USERQUERY macro can be used to pass user input to inquiry.

Example:

<Setting name="options"><![CDATA[
    {
        "autocomplete": {
            "handler" : {
                "name": "dataset",
                "dataset": "tvc:dataset:helium/MyParts.xml",
            }
        }
    }
    ]]>
</Setting>

and Dataset Inquiry is:

<Inquiry>
    <Code>temp query bus Part '*${USERQUERY}*' * where "owner == '${USER}'" limit 100 select id dump |</Code>
    <Format>${OID}</Format>
    <Pattern>*|*|*|${OID}</Pattern>
</Inquiry>
Cell content in modal instead of tooltip

The data in the cell content can be huge and it will be better to such data in the modal as it provides the ability to scroll and makes more user friendly while ready such content.

This can be achieved by adding following configuration.

<Column>
	...
	<TextLength>25</TextLength>
	<Rows>5</Rows>
	<TruncateDirection>right</TruncateDirection>
	<Setting name="class" value="he-tooltip-as-modal" />
	...
</Column>

By default, after text length limit three dot (…​) will be rendered on UI. If want to change this three dot then need to configure below properties in translation JSON files.

"dataTable": {
 "column": {
  "textLength": {
   "textToShowTooltip": "... (more)"
  }
 }
}

In some cases user might not want to see the close icon that could be achieved by below configuration.

<Column>
	...
	<UseVersion2>true</UseVersion2>
	<TextLength>25</TextLength>
	<Rows>5</Rows>
	<TruncateDirection>right</TruncateDirection>
	<Setting name="class" value="he-tooltip-as-modal he-without-close" />
	...
</Column>

By default a close icon will be shown on modal, to close the modal. If user doesn’t to see the close icon and wants the modal to close if he clicks anywhere outside the modal. this can be achieved with below config.

<Column>
	...
	<Setting name="class" value="he-tooltip-as-modal he-without-close" />
	...
</Column>
Hide static valued column in Data Grouping

Columns may contain static values, such as icons or images. However, these static values may also appear in the rows where data is grouped, which may not be desirable. To address this issue, a setting called DataGroupHidden can be applied to the column that contains static values. By setting this value to true in the column’s XML code, the static valued column will be hidden in the grouped rows.

Below setting is required for static valued columns to be hidden in data grouped rows

<Column>
	...
	<Setting name="DataGroupHidden" value="true" />
	...
</Column>

10.2.4. Progress Column

image The progress column will render a progress bar based on the value. Unlike the progress column in TVC Classic this column is only responsible for rendering the value. By default it will also show the percentage as text and in tooltip. This can be controlled with the options setting.

<Setting name="options">
    	{
			"showText" : false,
			"showTooltip" : false
		}
</Setting>
<Column>
	<Name>progress</Name>
	<Label>Progress</Label>
	<ColumnType>helium-progress</ColumnType>
	<Expression>${attribute[attribute_PercentComplete]}</Expression>
	<Setting name="options">
    	{
			"showText" : false,
			"showTooltip" : false
		}
	</Setting>
</Column>

10.2.5. Files Column

This feature requires the TVC File Manager license.

In a table displayed in Helium, you may have a column containing links to files related to objects in ENOVIA. There is a built-in column type that simplifies configuring this.

<Table>
	<Column>
		<Label>emxComponents.Common.Actions</Label>
		<RegisteredSuite>Components</RegisteredSuite>
		<ColumnType>helium-files</ColumnType> (1)
	</Column>
</Table>
1 Column type set to helium-files

This column inherts behaviour from the TVC File Manager component regarding configuration and others.

See this page for more details on how to configure the File Manager.

The screenshot below illustrates the file column

image
Figure 44. Files Column

Also, It is possible to reverse the lock icon to match the file lock status. Ex. When the file is locked, show the lock icon and similarly, when the file is unlocked, show the unlock icon.

This can be achieved by using below system property in tvc.properties.

Property Description Default Value

tvc.core.fileActions.reverseLockIcon

Reverse the lock icon

false

<Expression> tag support for Column type set to helium-files

A column set to Column type helium-files along with <Expression> tag as shown below, will display the file from related object found through the expression value. And file column with expression will always be non-editable.

<Table>
	<Column>
		<Label>Related Files</Label>
		<RegisteredSuite>Components</RegisteredSuite>
		<ColumnType>helium-files</ColumnType>
		<Expression>${from[relationship_ReferenceDocument].to}</Expression> (2)
	</Column>
</Table>

As an example in below screen, a part object displays the file from its related object found traversing through relationship "Reference Document"

All the files from all object found through the expression value will be displayed. For example, out of given expression if 3 objects are found, all files from all 3 objects will be displayed.

image
Figure 45. Files Column with Expression

Similarly we can show files that are connected the object using path, this can be achived by below configuration:

    <Column>
		<Label>files</Label>
		<ColumnType>helium-files</ColumnType>
		<PathType>SemanticRelation</PathType>
		<PathDirection>element</PathDirection>
		<PathExpression>from[VPLMrel/PLMConnection/V_Owner].to[PLMDocConnection]</PathExpression>
    </Column>

10.2.6. Drop Zone Column

This feature requires the TVC File Manager license.

In a table displayed in Helium, you may have a column containing a drop zone were the user may drag’n’drop files to be checked into ENOVIA™. Helium contains a built-in column type that simplifies configuring this.

<Table>
	<Column>
        <Alt>Drop Zone</Alt>
		<ColumnType>helium-dropzone</ColumnType> (1)
	</Column>
</Table>
1 Column type set to helium-dropzone to enable this feature.

You may include a file-dropzone in many places, as long as you have configured the column regarding what to do with the file depending on what object it is being dropped for. In some cases, you should create a new Document object, connect it with a certain relationship and then check-in the file.

Here is a complete example of how to configure a helium dropzone:

<Column>
    <Name>Dropzone</Name>
    <Label>Dropzone</Label>
    <ColumnType>helium-dropzone</ColumnType>
    <Setting name="dropzone:type_Part">
        relationship=relationship_ReferenceDocument,
        direction=from,
        type=type_Document,
        policy=policy_Document,
        vault=vault_eServiceProduction,
        format=generic,
        oneobjectperfile=true,
        refresh=refresh,
        selectformat=false
    </Setting>
</Column>

Please see file manager chapter for more details on how to configure a Drop Zone using TVC.

10.2.7. Primary Image Column

Showing a table column with thumbnails of an object’s primary image, is often helpful for identifying a particular object or to get an overview. Helium features a built-in columntype for this.

image

The tablecolumn uses lazy-loading to only request images that are within the visible area of the web browser, in order to not waste bandwidth. Images that come into the visible screen area after scrolling will be automatically fetched at that time.

<Table>
    <Column>
        <Name>PrimaryImage</Name>
        <Label>Image</Label>
        <ColumnType>helium-primaryimage</ColumnType>
    </Column>
</Table>
1 Column type set to helium-primaryimage to enable this feature.

10.2.8. User Column

Inbuilt ColumnType for showing an avatar/profile picture in a table cell. Useful for indicating who owns, created, or is assigned to an object. Needs a valid <Expression> to identify the User.

image

The tablecolumn uses lazy-loading to only request images that are within the visible area of the web browser, in order to not waste bandwidth. Images that come into the visible screen area after scrolling will be automatically fetched at that time.

<Table>
    <Column>
    	<Name>owner</Name>
    	<Expression>owner</Expression>
    	<Label>Owner</Label>
    	<Editable>false</Editable>
    	<ColumnType>helium-user</ColumnType>
    </Column>
</Table>
1 Column type set to helium-user to enable this feature.

10.2.9. Attachments Column

Showing a column with an attachments icon and clicking on the icon will open all the attachments related to that row in a modal. This can be configured as

<Column>
    <ColumnType>helium-attachment</ColumnType>
	<Setting name="Relationship" value="relationship_ReferenceDocument"/>
	<Setting name="Direction" value="From"/>
</Column>

Default value for Relationship is "Reference Document,Part Specification" and is defined on`tvc.office.server.attachmentRelationships` and for direction is "From".

10.2.10. Version Actions

This can be used to show the actions available on a particular version objects like download a file, check in, check out e.t.c

All Versions

10.2.11. Go There

Shows navigate icon which allows to navigate to a widget. The basic use case can be to show properties or structure of any object. This can be configured as below:

<Column>
	<Label>column.label.goThere</Label>
	<ColumnType>helium-go-there</ColumnType>
	<Setting name="widgetRef" value="tvc:widget:hex:engineering/EBOM.xml" />
</Column>

10.2.12. Add To Clipboard

Shows add to clipboard icon, which enables user to add an object to clipboard. This can be configured as below:

<Column>
		<Label>Add To Clipboard</Label>
		<ColumnType>helium-addToClipboard</ColumnType>
		<Alt>Add to Clipboard</Alt>
	</Column>

10.2.13. Classification Column

Classification is a Enovia built-in feature provided by Library central. Any business-object can be classified as per the concept of Library central. Classification is maintained as hierarchy where Library objects act as root objects followed by Family or Classification objects . 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. Thus Library central forms the classification path for any business-object.

Columntype helium-classification enables you to configure a column to view and edit the classification path for the businessobjects listing in the datatable.

Below XML configuration displays the built-in classification column with options to add and remove classifications for the respective row object.

<Column>
	<Label>Classification</Label>
	<ColumnType>helium-classification</ColumnType>
</Column>
image
Figure 46. Default Classification column

Columntype helium-classification was introduced in release 2022.3.0, to display a classification column and a icon to edit the classification from table-column. A edit form was opening on clicking the edit icon, to update the classification path by typing-in the known classifications. But there was no option to see all the available classifications.

From 2023.2.0 release, introducing a structure table to display the classification in hierarchy order. The edit icon in the classification column opens the default dashboard with a structure table to display the classification in hierarchy order. This hieraracal view helps to find the required classification and update to the respective row businessobject.

image
Figure 47. Edit Classification with Default Form and structure table

Refer a short video where a classification is updated to a row object.

Below are the optional settings to override the default behavior or the appearance of the classification column

Settings Description

hideAddClassificationIcon

By default this setting is false which means classification edit icon will be shown by default. You can configure the setting to true to hide the edit classification icon .

<Setting name="options">{"hideAddClassificationIcon":true}</Setting>

editDashboard

The default dashboard is tvc:dashboard:helium/ClassificationEditByName.xml. There is another in-built dashboard tvc:dashboard:helium/ClassificationEditByTitle.xml which can be used to view and edit based on the classification title. Moreover You can choose to clone these in-built XML files and configure a new dashboard as per your need for editing the classification. The default dashboard has widgets with widget ids classification-form and classification-str. The widgets are identified through these ids to apply the styles and logics. Maintain the same widget-ids in your new edit dashboard.

<Setting name="options">{"editDashboard":"tvc:dashboard:helium/ClassificationEditByTitle.xml"}</Setting>

editDashboardPosition

you can specify the edit dashboard position using this setting and override the default position.

<Setting name="options">{"editDashboardPosition":{"left": "25%","right": "25%","top": "25%","bottom": "25%"}</Setting>

classificationRelationship

"Classified Item" is the default relationship to get the classification path. This default relationship can be overriden by the below setting in column configuration.

<Setting name="classificationRelationship">relationship_PartClassification</Setting>

classifyFromLevel

This setting helps to specify from which level of the library heirarcy, the business object must be classified. The default value is 1, meaning that once the library is expanded, business objects can be classified from the first level of the hierarchy.

<Setting name="options">{"classifyFromLevel":2}</Setting>

displayExpression

By default, the name of the classification object is displayed in the classification path. This can be override by the below setting.

<Setting name="displayExpression">${attribute[attribute_title]}</Setting>

template

You can choose to override the default template with you custom template.

<Setting name="template">helium/templates/classification</Setting>

Below is the sample classification column configuration with all optional settings.

<Column>
	<Label>Classification</Label>
	<ColumnType>helium-classification</ColumnType>

	<!-- Optional Settings -->
	<Setting name="classificationRelationship">relationship_PartClassification</Setting>
	<Setting name="displayExpression">${attribute[attribute_Title]}</Setting>
	<Setting name="template">helium/templates/classification</Setting>
	<Setting name="options">{
		"hideAddClassificationIcon": true,
		"editDashboard":"tvc:dashboard:helium/EditClassification.xml",
		"editDashboardPosition":{
				"left": "25%",
				"right": "25%",
				"top": "25%",
				"bottom": "25%"
			}
		}
	</Setting>
</Column>

10.2.14. Related Object Column

As the user would like to make connections between object while editing a table cell, for ex connecting a specification to part. Now for such usecase we can configure related object column in helium.

    <Column>
	<Name>Specifications</Name>
	<Expression>${from[relationship_PartSpecification].to}</Expression>
	<AlternateOIDExpression>${from[relationship_PartSpecification].to.id}</AlternateOIDExpression>
	<Label>Specifications</Label>
	<TextLength>10</TextLength>
	<Rows>5</Rows>
	<TruncateDirection>left</TruncateDirection>
	<GroupHeader>Related Data</GroupHeader>
	<Setting name="options">{
				"formConfig":"tvc:form:helium/RelatedObjectForm.xml",
				"formWidth" : "300",
				"formHeight" : "300"
		}</Setting>
    <ColumnType>helium-relatedobject</ColumnType>
</Column>

As can be seen in the above config in settings we can pass a formconfig reference which would have all the details about the field which need to be edited.

10.2.15. Create and connect row command

In a structure table it is possible to create and insert a new row at a chosen depth. Select a row and click the "Create and connect row" command to add a child row to the selected parent row.

10.2.16. Upload File Command

This feature requires the TVC File Manager license.

This feature is similar to the "Dropzone above table" in the file manager chapter. Creates a row/new rows when a file is uploaded. The row will not be created until the file is uploaded successfully.

Currently supports the following options:

The table below shows and explains what parameters that you can use:

Parameter Value Notes / Description

createSettings

String or Object

The id of a predefined createSettings or the createSettings can be defined inline here. See the following createSettings: parameters.

createSettings:type

String type

The type of object that will be created. Can be a symbolic name or real name

createSettings:policy

String policy

The name of the policy to be used for the object that will be created. Can be a symbolic name or real name

oneFilePerObject

True or False

Whether or not to create one document object per file that is dropped. E.g. if the user drops three files, if this setting is set to true, three document objects will be created.

Default is false.

badChars

String/JS function

Chars that are not allowed in the file name. [1]

validFileExtensions

Array of Strings/JS function

Valid file extensions. [1]

maximumFileSize

Number/JS function

The maximum allowed file size in bytes. [1]

preProcessor

JS function

JS function executed before any table row is created.

postProcessor

JS function

JS function executed after all table rows are created.

when not configured, table is reloaded. custom postProcessor can take care of reloading the table or return true to reload.

  1. Can either be a value, or the name of a JS function returning a value

Example:

<Command>
    <Label>Save file</Label>
    <FontIcon>he-save</FontIcon>
    <OnClick>App.file.uploadFileCommand</OnClick>
    <OnClickParams><![CDATA[{
        "oneFilePerObject": true,
        "createSettings": {
            "type": "type_CADDrawing",
            "policy": "policy_CADDrawing"
        },
        "badChars": "App.custom.noSpaceOrComma",
        "validFileExtensions": [".png", ".jpg", ".jpeg", ".bmp", "gif", ".psd"],
        "maximumFileSize": "App.custom.fiveMegaBytes",
        "preProcessor" : "App.custom.validateFileSize",
        "postProcessor" : "App.custom.returnTrue"
    }]]></OnClickParams>
</Command>

10.2.17. Promote and Demote Command

In order to promote and demote business object(s) from a table widget, the promote and demote methods of App.table.BusinessObject JS API can be used. The API requires a data table reference as the mandatory first argument. After the action is performed, an optional status message can be displayed in the UI, informing whether action was successful or not. To display such message, an optional second argument containing a Toaster instance should be passed..

Example:

new App.table.BusinessObject(this).promote();
new App.table.BusinessObject(this, windows.App.toaster).promote();
new App.table.BusinessObject(this).demote();
new App.table.BusinessObject(this, windows.App.toaster).demote();

Inbuilt promote and demote command.

App.table.action.promote
App.table.action.demote

Example:

<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>

To print the content of widget, the print method of App.Widget JS API can be used. Command can be used either in widget toolbar or header actions. In responsive table only visible content can be printed.

This feature is supported only in View mode.

Example:

In Widget Toolbar

<Command>
	<Label>Print</Label>
	<OnClick>App.Widget.print</OnClick>
</Command>

In HeaderActions

<Command>
    <Label>Print</Label>
    <Setting name="OnClick" value="App.Widget.print" />
</Command>

10.2.19. Display Density Command

A built-in command <DisplayDensity /> can be added to a toolbar in a Table widget. This command allows decreasing height between rows resulting in more rows to be visible. User preference is preserved across sessions.

The user preference will be saved only for the Table widget where this command is used.
Change Display Density

10.2.20. File Package Download Command

A built-in command <FilePackageDownload /> can be added to a toolbar in a Table widget. This command allows bulk download of documents from selected objects using native file manager.

<FilePackageDownload>
    <!-- Optional fields-->
    <Label>FPD</Label>
    <FontIcon>cloud download icon</FontIcon>
    <Configuration>tvc:fpd:hex:engineering:homepage/NativeFilesForSelectedModels.xml</Configuration>
</FilePackageDownload>
To use this command, native file manager needs to be installed and enabled in user’s device.

10.2.21. Table Configurator Command

A built-in command <TableConfigurator /> can be added to a toolbar in a Table widget. This command allows adding,updating and removing user defined tables and maintaining End User Defined Columns for different tables.

The addition of new columns can only be done for end user tables and not the default file based table defined for a widget.

In datatable toolbar :

    <TableConfigurator default="columns" excludeInterfacePrefix="true" />
image
Figure 48. Table Configurator Menu Columns View
image
Figure 49. Table Configurator Menu Tables View

The table below shows and explains the available attributes for <TableConfigurator /> command:

Field Value Notes / Description

default

columns or tables

The default attribute defines which tab is active by default in menu.

Default selected tab is columns.

excludeInterfacePrefix

True or False

Whether the interface attributes should show interface name prefix in available columns' list.

Default value is true.

It is recommended not to add <ToggleColumnVisibility /> command if <TableConfigurator /> is used as it would be redundant to have both together in a toolbar.
Table Configurator

10.2.22. Search And Connect Command

A built-in command <SearchAndConnect></SearchAndConnect> can be added to a toolbar in a Table widget. This command opens a search modal configured with given searchform and relationships and user can select search results and connect to selected object.

In datatable toolbar :

    <SearchAndConnect >
        <Relationships >
            <Relationship default="true">
                relationship_EBOM
            </Relationship>
            <Relationship direction="to">
                relationship_PartSpecification
            </Relationship>
        </Relationships >
        <SearchConfig>tvc:search:hex:common/SearchAndConnect.xml</SearchConfig>
        <ExpandRow>true</ExpandRow>
    </SearchAndConnect>

The table below shows and explains the available tags for SearchAndConnect` command:

Field Value Notes / Description

Relationships

Relationship[]

The list of relationships available for connection in search modal.

Relationship

string

Name of the relationship to be added.It has two attributes default (sets the relationship as default selected for connection) and direction(the relationship direction to be used for connection)

Default value for direction is false. Default value for default is false.

SearchConfig

string

The search config path for the search modal.For further details see New Search Experience

ExpandRow

boolean

Whether context object in table should be expanded after new objects are connected from the modal.

OnSubmit

The OnSubmit configuration can be used to perform custom action when user click on submit button on search page.

<OnSubmit>App.hex.doConnections</OnSubmit>.

SubmitButtonLabel

This will overide submit button label. Default value is Submit

<SubmitButtonLabel>Add To Collection</SubmitButtonLabel>

Connect

Want to perform custom action which is not dependent on relationship, then this tag can be set false. The default value of this is true.

<Connect>false</Connect>

SelectionCriteria

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

<SelectionCriteria>none</SelectionCriteria>

Search And Connect Objects

10.2.23. Data Group Command

The data grouping function can be used to group data, based upon column values, into different groups.This function is available from any table page (flat list or structure), and operates on the data within a table/structure.

The data grouping function is launched via a built-in command <DataGroup/>, that can be added to a toolbar in a Table widget.

image
Figure 50. Data Grouping Button

As an example, assume that you have a structure like in the screenshot below.

image

Launching the data grouping function and define two groups: type + current state, would give a result like the screenshot below.

image

The different groups have different colours, and above the table there is a legend where the colour is mapped to the group. The first column after the structure shows the value (label) and the number of rows that mapped the group.

A group can be expanded in order to see the content of a particular group.

image
Light Mode Data Group

This enable user to open a data grouping form inline where user can select the column and apply the grouping even user can cancel the grouping.

This can enable by passing an attribute lightMode value as a true in exiting data group commnad.

<DataGroup lightMode="true"/>
image
Figure 51. Light Mode Data Group Form

10.2.24. Pre configure Data Group

For some tables user might want to see the preconfigured datagroups, the data can be grouped when the tabe is loaded initially loaded by providing simple configurations in the table config as follows :

 <DataGroup>
    <GroupBy>
        <Name>Material Category</Name>
		<Group condition="match" value="Glass" />
	</GroupBy>
	<ThenBy>
	    <Name>owner</Name>
	</ThenBy>
	<FinallyBy>
		<Name>State</Name>
	    <Group condition="match" value="In Work" />
	</FinallyBy>
	<GoBackAllowed>true</GoBackAllowed>
</DataGroup>

10.2.25. Advance Sorting Command

<AdvanceSorting/> built-in command can be added to toolbar in table widget. This command enable the user to sort the table. By clicking on this command, a UI will appear which enable user to choose desired sorting column and direction. Only sortable column will be appear in dropdown with which the user can choose to sort on up to three columns at same time.

image
Figure 52. Advance Sorting Command

The Advance Sorting UI has a initializeBlank attribute that can be used to control its pre-population behavior. If this attribute is set to true, the UI will be initialized with a blank state, and no sorting criteria will be prepopulated. On the other hand, if this attribute is set to false (or not set at all), the UI will be prepopulated with the current sorting criteria, which can be useful if the user has already selected their desired sorting criteria in a previous session. <AdvanceSorting initializeBlank="true"/>

10.2.26. Internationalisation

The data table widget supports internationalization. If a translation key is given to an <Label> element the translation for that key will be rendered. If no value is found for that key the actual value of the <Label> element will be rendered.

Customize messages

The following messages is defined in the default.json language file.

{
    "dataTable": {
        "messages": {
            "decimal":        "",
            "emptyTable":     "No data available in table",
            "info":           "Showing _START_ to _END_ of _TOTAL_ entries",
            "infoEmpty":      "Showing 0 to 0 of 0 entries",
            "infoFiltered":   "(filtered from _MAX_ total entries)",
            "infoPostFix":    "",
            "thousands":      ",",
            "lengthMenu":     "_MENU_",
            "loadingRecords": "Loading...",
            "processing":     "Processing...",
            "search":         "Search:",
            "zeroRecords":    "No matching records found",
            "paginate": {
                "first":      "First",
                "last":       "Last",
                "next":       "Next",
                "previous":   "Previous"
            },
            "aria": {
                "sortAscending":  ": activate to sort column ascending",
                "sortDescending": ": activate to sort column descending"
            }
        },
        "editor": {
            "messages": {
                "create": {
                    "button": "New",
                    "title":  "Create new entry",
                    "submit": "Create"
                },

                "edit": {
                    "button": "Edit",
                    "title":  "Edit entry",
                    "submit": "Update"
                },

                "remove": {
                    "button": "Delete",
                    "title":  "Delete",
                    "submit": "Delete",
                    "confirm": {
                        "_": "Are you sure you wish to delete %d rows?",
                        "1": "Are you sure you wish to delete 1 row?"
                    }
                },

                "error": {
                    "system": "A system error has occurred (More information)"
                },

                "multi": {
                    "title": "Multiple values",
                    "info": "The selected items contain different values for this input. To edit and set all items for this input to the same value, click or tap here, otherwise they will retain their individual values.",
                    "restore": "Undo changes"
                }
            }
        }
    }
}

It is possible to override the each message in your own language file by providing a key that matches one of the above. For example to override the dataTable.messages.emptyTable key you would add the following to your language files.

    {
        "dataTable": {
            "messages": {
                "emptyTable": "Currently no rows"
            }
        }
    }

Many translations for the tables can be found on here

10.2.27. API

The table javascript api can be found here

10.2.28. Mass Update

When <AllowMultipleEdit> has been set to true on a table column, the column is editable, and the user has access to edit at least one cell in the column, an icon will appear on the column header that the user can click in order to edit multiple cells in a single column to the same value.

image
Figure 53. Mass Update icon

The mass update form is shown in modal. If there is more than one column allowed for mass updating, the user can easily change the working column from the drop down list showing the column. The user can choose whether to edit the selected rows or all rows.

User can check "Keep Selection" to retain selection for further mass updating other columns.

By default "Keep Selection" is unchecked.

image
Figure 54. Mass Update form

10.2.29. Customization

The end user can change certain settings of a TableWidget, and automatically persist those customizations. Settings that are customizable include:

  • Column visibility (hide/show)

  • Data grouping (show/hide)

  • Column order (reorder the initial order from configuration)

  • Pagination length (number of table rows displayed per page)

  • Last sorted column (The column based on which the table should be sorted. Overrides the default/configured sort order)

image
Figure 55. Checkbox indicates column visibility. Drag-and-drop to reorder.
image
Figure 56. Pagination

Changes to the above settings are stored per TableWidget, and remembered across page changes and browser sessions, as long as the Dashboard Customization property is enabled.

To reset any customizations for a TableWidget, you can use the Widget Customization reset icon.

10.2.30. Styling / CSS

Offline available table rows

If dynamic caching of object pages has been enabled, the TableWidget now automatically applies a CSS class .offline-available on every <tr> element that has a cached entry.

This opens up for conditional styling, that helps the user understand which objects are cached and thereby possible to open while offline.

Below example is achieved with CSS:

tr.offline-available {
	background-color: #9fd39f !important;
}
image
Figure 57. Specific styling of offline-available objects

10.2.31. End User Defined Columns

Users can add, remove and update columns in a table from the existing list of attributes based on objects present in table including the unified type and interface attributes.

It is also possible to exclude some attributes from the addable list by adding following init-param in web.xml:

    tvc.core.attributes.excludedAttributes

It accepts comma-separated attribute names to be excluded. Furthermore, attribute labels support localization through framework properties.

In datatable toolbar :

    <TableConfigurator />
image
Figure 58. Columns menu

There are two ways of adding a new column to the existing table. User can simply check one/more columns from the existing list or use Add Advanced Column icon to add column with more custom settings.

The table below shows and explains the available settings in advanced mode:

Field Value Notes / Description

Name

String

The name appears as table column header

Description

String

The description acts as tooltip for column header.

Expression

String

The expression field provides a list of attributes to select from for the column data.

Template

String

The list of templates if configured. Refer Choose template to a Column section.

Valid For

String

The list of types to specify the column belongs to which type.

Is Editable

True or False

Whether the column should be editable or not.

Default is false.

InputType

String

List of input types to select from in case of editable field. E.g. If the attribute is of date format, you can select date as input type which will present a date picker to choose from in edit mode.

No Wrap

True or False

Whether the content of column should be wrapped. Default is true.

Filter

True or False

Whether column should have its own column filter.

Default is false.

Sortable

True or False

Whether column should be sortable or not.

Default is true.

image
Figure 59. Add Advanced Column form

After addition user can delete the column by unselecting it and update by using the pencil icon next to column item in the menu. Edit form provides same properties as add advanced form.

10.2.32. CDM document details widget

We can view the versions of the document object by configuring the columntype helium-go-there as given below:

<Column>
	<Label>Go There</Label>
	<ColumnType>helium-go-there</ColumnType>
	<Setting name="widgetRef" value="tvc:widget:helium:cdm/CDMDocumentVersions.xml" />
</Column>

Specification

If a document object would have several files checked in, you will first see the active version objects for each file checked in.

Active Versions

By simply clicking the go-there again for a particular file, you will then see all the versions of that file.

All Versions

10.2.33. Limitations of the date format table columns

When ClientSideProcessing is disabled, then the search performed using the column filter on date format columns will not give expected results if the date format specified with the tag DateFormat in Helium.xml is identified as invalid by the standard java class java.text.SimpleDateFormat.

For example, if the date format specified with the tag DateFormat in Helium.xml is MMMM Do YYYY, then the SimpleDateFormat Class consider this as an illegal pattern by logging error Illegal pattern character 'o'. In this case, the search results won’t be accurate.

10.2.34. Row Highlight Duration

Row highlight duration post actions such as promote, demote, row refresh e.t.c can be configured as below :

tvc.helium.row.highlightDuration= 5000 //1000 is default value

10.2.35. Path Attachment Column type

The File column type is useful to display the related document(s) and their files in the side panel. However, the File column type will only display the related document(s) connected via the given/default relationships.

There might be cases when the table row object can have the document(s) connected via path (A virtual relationship).If there are document(s) related to the object, a paper clip icon will be displayed and the user can click the icon to get the list of files in the modal.

Path Attachment Column type

The list will show all related document(s) and the files related to each document.

For the document(s), the user will be able to check-in new files if user has access to do so, see basic properties of the document or open the document object in a popup window.

Also, per file, the user will be able to download, view, checkout, unlock, lock or update the file (again, depending on access rights, all actions might not be available).

Unless you provide any settings at all to this data handler, it will default look for "Reference Documents" and "Part Specifications" connected from the object in the table. You can change the behaviour by changing the following settings:

Setting Value Description Required

Column Type

helium-pathattachment

This setting defines what type of column a particular column is.

Yes

Direction

From

The direction of the connection

No

Relationship

relationship_PartSpecification

A comma separated list of relationship names (or symbolic names)

No

PathDirection

owner or element

defines the direction for retrieving the path info for owner/element

No (default is owner)

PathType

Proposed Activity.Where

The Path type

No

PathExpression

An expression

The expression to retrieve the information in the context of path owner or to retreive the path owner in case of fetching the element information

No.

The example below illustrates how user/admin can construct the column of helium-pathattachment column type:

<Column>
	<ColumnType>helium-pathattachment</ColumnType>
	<Setting name="Relationship" value="SpecificationDocument" />
	<Setting name="Direction" value="from" />
	<PathType>SemanticRelation</PathType>
	<PathDirection>element</PathDirection>
	<PathExpression>from[VPLMrel/PLMConnection/V_Owner].to[PLMDocConnection]</PathExpression>
	<CardTitle>launchpad.ups.table.card.specDocs.Label</CardTitle>
	<CardID>ups_specdocuments</CardID>
	<Description>launchpad.ups.table.column.specDocFile.tooltip</Description>
	<Setting name="Render as Row Action" value="true" />
</Column>

10.3. Form

The form component is responsible for editing, creating or displaying object data.

A form can be configured to either be rendered inside of a widget or in standalone fullscreen mode.

The form component can be initialized in the following five modes.

VIEW

the fields of the form is shown in 'view' mode. No editing controls are displayed.

EDIT

the form is shown in edit mode with the form controls prepopulated with the values from the given object. The object to be edited is given by passing an objectId as an option in the constructor or if the form is rendered as a widget it can be configured to work with the current context object

CREATE

renders a form that creates a new object

CREATE_AND_CONNECT

renders a form that creates an object and connects it to an existing object

CREATE_WITH_CONNECTIONS

renders a form that creates an object and connects the created object to multiple existing objects

CREATE & CREATE_AND_CONNECT form support "Create New" button. This button allows the user to create an object and keep the form open to create another object instantly. When the user clicks on "Create New" button, the form will be submitted, an object will be created, the user will be notified of the new object and the form will remain open for creation of another object. If the user wishes not to create another object, the user can simply submit the form as the user used to previously by using the "Submit" button. For further information see Form in modal

The Edit Toggle button will not be displayed in the form unless the user owns modify access to any of the fields. In this case, if the form is opened in edit mode, the Toggle Edit Mode toolbar command can be used to toggle the modes.

There is factory functions for each mode described in the App.form API.

The form widget supports multiple languages, see i18n for more information.

10.3.1. Widget

To create a form widget create an widget definition XML with the following content:

<FormWidget>
    <FormConfig namespace="helium">Form1.xml</FormConfig>
    <ResolveContextId>page</ResolveContextId>
    <!--
    <FormMode>edit</FormMode>
     -->
</FormWidget>

The <FormWidget> element supports the following child elements.

Name Description Example

FormConfig

Reference to the XML file that configures the form. See [Configuration](#FormConfig) for further information.

<FormConfig namespace="helium">
    Form1.xml
</FormConfig>

ResolveContextId

If the form should use the current context object. Valid value page. If this element is omitted it is up to the function that creates the form to supply an objectId.

<ResolveContextId>
    page
</ResolveContextId>

FormMode

What mode should the form render in. Defaults to edit.

<FormMode>edit</FormMode>

ShowToggleButton

Whether the button that toggles between 'EDIT' and 'VIEW' mode should be visible. Defaults to true.

<ShowToggleButton>false</ShowToggleButton>

10.3.2. Configuration

A form consists of sections and fields. Each section holds one or more fields.

The root element of a form configuration is <Form>. It supports the following child elements.

Name Description Example

Title

The title of the form.

<Title>
    Test Form
</Title>

Description

The description of the form

<Description>
    Foo
</Description>

SourceObjectResolver

When the form is used for editing or viewing, a dataset can be used to load the source object for the form. If already in context of an object, that object can be used when for example an Expansion is necessary

<SourceObjectResolver>
    tvc:dataset:example/Example.xml
</SourceObjectResolver>

Layout

Describes how the fields in form should be positioned. For further information see Layout

<Layout>
    <Columns>2</Columns>
</Layout>

SubmitStrategy

Choose between submit strategies (Empty = default submit button, AUTO = Submit form on each field change)

<SubmitStrategy>AUTO</SubmitStrategy>

AlwaysShowEditButton

Always shows the Edit toggle button in the view mode and View/Submit button in the edit mode irrespective of the user access. Default value is false

<AlwaysShowEditButton>false</AlwaysShowEditButton>

Section

Used to divide form fields in different collapsible sections.

A form must have at least one <Section>. The <Section> element supports the dom-id attribute, which is used if a form is configured to use an layout template

For further information see the section chapter

Section

The <Section> element groups different form fields together. A form must have at least one <Section>.

The <Section> element supports the following child elements.

Name Description Example

Label

The label of the section. This will be rendered as a header for the current section.

<Label>
    First section
</Label>

Field

The field element describes the properties of an form field

For further information see the field chapter

RelatedObject

A field used for showing / editing of related objects

See this chapter for more info.

Help messages

To configure a help message for a section specify the helperMessage setting.

Tooltip can be configured by passing the settings listed in Semantic Popup Settings into the tooltipConfig attribute.

A help message when configured is indicated by a 'question mark' next to the section label. On hovering over the icon, tooltip is shown. Tooltip icon (Default : question circle) and icon position (Default : right) can be changed as needed. Icons Link

<Setting name="options"><![CDATA[
    {
    "helperMessage": "Help message for this section. May contain html such as <a href='http://example.com'>a link</a> or an i18n key",
    "iconClass":"red question circle outline",
    "iconPosition":"left",
    "tooltipConfig": {
        "delay": {
            "show": 300,
            "hide": 800
            },
        "hoverable": true,
        "offset": 10
        }
	}
    ]]>
</Setting>

Or

<Options>
    <![CDATA[{
    "helperMessage": "Help message for this field. May contain html such as <a href='http://example.com'>a link</a> or an i18n key",
    "iconClass":"red question circle outline",
    "iconPosition":"left",
    "tooltipConfig": {
        "delay": {
            "show": 300,
            "hide": 800
            },
        "hoverable": true,
        "offset": 10
        }
    }]]>
</Options>
Field

The <Field> element describes the properties of a single field in a form.

It is possible to use the ref or namespace and name attributes to point to an external xml file. Example:

<Field namespace="helium" name="Policy.xml" />
<Field ref="tvc:formfield:helium/Policy.xml" />
If user does not have modify access then field is rendered in non-editable mode.

The <Field> element supports the following child elements.

Name Description Example

Label

The label of the field. This will be rendered as an html label element.

<Label>Owner</Label>

Expression

The expression that is used to fetch the data for the field

<Expression>
    ${attribute[attribute_MaterialCategory]}
</Expression>

Editable

Whether the field is editable or not. Valid values true or false

When DataHandler makes a cell editable or non editable, field definition is ignored. DataHandler always takes precedence over field level setting.

<Editable>true</Editable>

DataType

What datatype is the field. For instance string or integer

<DataType>string</DataType>

FieldType

What field type is the field. For instance select, textarea, richtext, markdown, text, radiobutton or checkbox

<FieldType>select</FieldType>

Defaults

What default values should the field contain. The element supports the following attributes:

className

reference to a java class that is responsible for generating the list of default values

functionName

reference to a javascript function that is responsible for generating the list of values.

Currently only applicable if the field type is select

If none of the attributes are present the default values should be given as a list of <Value> elements. See the example.

The default values in the xml configuration, the range values from the database and the current value from the database will be merged with no duplicate values in the list. To avoid this, 'mergeDBValue' attribute with value false can be set on Defaults element.
<Defaults>
    <Value value="A">
        <Label locale="sv">
            Storlek-A
        </Label>
        <Label locale="en">
            Size-A
        </Label>
    </Value>
    <Value value="B">
        <Label locale="sv">
            Storlek-B
        </Label>
        <Label locale="en">
            Size-B
        </Label>
    </Value>
</Defaults>

Validation

What client side validation rules should be applied to the field. The following child elements are supported

<Required>

if the field is required or not. Valid values: true or false

<MinLength>

the minimum length of the field. Valid value: Positive integer

<MaxLength>

the maximum length of the field. Valid value: Positive integer

<Pattern>

a regexp that the value must match. Valid value: Valid RegExp. Note: All characters within the <Pattern> tag will be included in the pattern, including initial or trailing spaces or newline characters.

<BadCharacters>

This can be used to avoid users to enter invalid or reserved characters in text field.

<BadCharacters>#@)~</BadCharacters>
 Or
Globally configured in tvc.properties `tvc.helium.form.badCharacters = #@)~`. with following xml
<BadCharacters>true</BadCharacters>

Mandatory fields that also appear in red color along with an asterisk on the create/view/edit forms. By default this property is true tvc.helium.form.requiredFieldLabel.red = true

<Validation>
    <Required>true</Required>
    <MinLength>3</MinLength>
    <MaxLength>30</MaxLength>
	<Pattern>^(Hello|Goodbye)\sWorld$</Pattern>
</Validation>

Template

A path to an handlebars template that is responsible for rendering the field. Custom field templates only work in 'VIEW' form mode currently.

<Template>
    /path/to/template.handlebars
</Template>

Delimiter

Defines a custom delimiter used internally to split/join the range value. The default value is |.

If the range contains values including the comma character, another Delimiter character must be configured.
Do not use pipe separated range value.
<Delimiter>|</Delimiter>
<Defaults>
  <Value value="Metal,Glass">
    <Label>Metal,Glass</Label>
  </Value>
  <Value value="Plastic,Rubber">
    <Label>Plastic,Rubber</Label>
  </Value>
</Defaults>
Rich Text editor support

Especially multi line attributes that otherwise render as textareas, can sometimes benefit from allowing Rich Text (layouted text/HTML) input as well.

image
Figure 60. Rich Text editor

This can be easily configured by setting the <FieldType>richtext</FieldType> tag. Example:

<Field>
    <Label>Description</Label>
    <Expression>description</Expression>
    <Editable>true</Editable>
    <FieldType>richtext</FieldType>
</Field>

Hint: you may want to disable Table In-Cell-Editing for attributes containing HTML, and instead launch a Form, as showcased in the video above.

All characters will be stored in non-entity form except these XML default entities: & ( stored as &amp;), < ( stored as &lt;), > ( stored as &gt;).
Markdown editor support

Markdown support for inline text formatting can be achieved with markdown editor using markdown field type.

image
Figure 61. Markdown editor

This can be easily configured by setting the <FieldType>markdown</FieldType> tag. Example:

<Field>
    <Label>Description</Label>
    <Expression>description</Expression>
    <Editable>true</Editable>
    <FieldType>markdown</FieldType>
</Field>
Markdown editor support is available only for form fields.

10.3.3. Primary Image Field

Images gives visual identification to enovia objects like Part or Assembly. Helium forms can now show primary image mapped to business object. A new field PrimaryImageField is introduced to render the "Primary Image" of the object. This field also allow user to set, change and delete primary image.

Following is example configuration :-

<PrimaryImageField>
	<Label>Image</Label>
	<Editable>true</Editable>
    <Format>generic</Format>
</PrimaryImageField>
image
Figure 62. Primary Image
Autocomplete

All select fields have basic autocomplete support. With the options outlined below the behavior can be customized to great extent.

To customize autocomplete provide the following setting:

<Setting name="options"><![CDATA[
{
    "autocomplete": {
        "template": "...",
        "selectize": { ... },
        "handler" : { ... }
    }
}
]]>
</Setting>

Each block, template, selectize and handler is described below.

template

Provide an path to an template to customize the dropdown. Example of template:

<div>
    <p>{{label}}</p>
</div>
selectize

The client utilizes Selectize and all options described in the docs can be used here. Apart from those settings, it also supports custom setting called cache, which will clear the cached options after an autocomplete dropdown close if its value is false and this setting is only applicable with RelatedObject. The valid value is either true or false and default value is true.

To show selectize dropdown outside the widget boundaries. The global level property tvc.helium.selectize.showDropdownOutsideFrame can be defined in tvc.properties file or can be configured on specific field as below

<Options><![CDATA[{
			"selectize" : {
				"showDropdownOutsideFrame" : true;
    		}
}]]></Options>
handler

All settings that are described in the core admin guide can be used in the handler block including all predefined handlers.

If you wan’t to create a custom autocomplete handler, follow the admin guide and pass the java class as the value for the name key.

Full example:

<Setting name="options"><![CDATA[
    {
        "autocomplete": {
            "template": "/helium/templates/form/autocomplete",
            "selectize": {
                "preload": true,
                "cache": false,
                "maxItems": null,
                "labelField": "name",
                "searchField": ["name"]
            },
            "handler" : {
                "name": "dataset",
                "dataset": "tvc:dataset:helium/MyParts.xml",
                "select": ["name",  "current"]
            }
        }
    }
    ]]>
</Setting>
Custom client side validation

In addition to the validation rules described above in the <Validation> element, it is possible to provide an javascript function that performs validation. The function will be executed when the field is blurred and the value of the field will be passed to the function. The function must return a boolean, true if the value is valid and false if the value is invalid.

This is configured by providing the following setting:

<Setting name="options">{
    "validator": "App.custom.someJavascriptFunction",
    "validatorMsg": "Error message, either an messeage or a i18n key"
}</Setting>
Consolidated Error Message

In form by default errors are displayed at two places. One below respective field and one as consolidated error message near submit button. This is useful when form is big and consolidated message can give overall idea. However, in some cases it might be needed to disable consolidated error. This can be done using the key helium.form.error.consolidatedErrormessgae in tvc.properties. The valid value is either true or false and the default value is true.

Initial focus on a field

To set the focus on a field in edit/create mode add the focus option to the field.

If more than one fields have the focus option set to true, then the last form field is given priority and set to focus. It is recommended to have only one field with focus true.
<Setting name="options"><![CDATA[
    {
        "focus": true
    }
    ]]>
</Setting>
datePicker settings

The following settings are supported by date picker.

Name Description

minDate

The custom java script function which returns valid minimum selectable date.

maxDate

The custom java script function which returns valid maximum selectable date.

showWeekNumber

Boolean(true/false). Show the ISO week number at the head of the row.

defaultDate

The custom java script function which returns valid selectable date. This is the initial date to view when first opened.

setDefaultDate

Boolean (true/false). Make the defaultDate the initial selected value.

disableWeekends

Boolean(true/false). Disallow selection of Saturdays or Sundays.

firstDay

First day of the week (0: Sunday, 1: Monday, etc).

yearRange

Number of years either side (e.g. 10) or array of upper/lower range (e.g. [200,2030]).

numberOfMonths

Number of visible calendars.

disableDayFn

Callback function that gets passed a Date object for each day in view. Should return true to disable selection of that day.

<Setting name="options">{
    "datePicker":{
        "minDate": "App.hex.todayOrLater",
        "maxDate": "App.hex.endOfProjectDate",
        "showWeekNumber": true,
		"yearRange": [2000, 2030],
		"disableDayFn": "App.hex.disableDayFn",
		"firstDay": 2,
		"yearRange": [2000, 2030],
		"defaultDate": "App.hex.defaultDate",
		"setDefaultDate": true,
		"numberOfMonths": 2
    }
}</Setting>
The below setting format is deprecated and will no longer be supported from Helium release 2019.2.0 onward. Please move it into subobject datePicker as shown above.
<Setting name="options">{
    "minDate": "App.hex.todayOrLater",
    "maxDate": "App.hex.endOfProjectDate"
}</Setting>
Conditional dependencies
Field

It is possible to make fields dependent on values of other fields. This is achieved by adding the dependsOn and dependsOnValue attributes to the dependent field element.

Example:

<Field dependsOn="someOtherFieldExpressionOrId" dependsOnValue="someValue">

Given the example above, the field will only be visible if the field "someOtherFieldExpressionOrId" has the value "someValue". It is also possible to supply a list of comma separated values, if one of those values is equal to the value of the field "someOtherFieldExpressionOrId" the dependent field will be visible. Note: if the values contains commas you will need to create a custom javascript function as described below.

It is also possible to give an reference to a javascript function as the dependsOnValue value. In that case the supplied function will be executed with the value of the dependsOn field as an parameter. The function must return a boolean value. If the returned value is true the field will be shown otherwise it will be hidden.

For cross section dependencies

<Field crossSectionDependsOn="someOtherFieldExpressionOrId" crossSectionDependsOnValue="someValue">
Section

It is also possible to make sections dependent on value of some field. This can be achieved by adding the dependsOn and dependsOnValue attributes to the dependent section element.

Example:

<Section dependsOn="someFieldExpressionOrId" dependsOnValue="someValue">

In above example, the section will only be visible if the field "someOtherFieldExpressionOrId" has the value "someValue". It is also possible to supply a list of comma separated values, if one of those values is equal to the value of the field "someFieldExpressionOrId" the dependent section will be visible.

It is also possible to give an reference to a javascript function as the dependsOnValue value. In that case the supplied function will be executed with the value of the dependsOn field as an parameter. The function must return a boolean value. If the returned value is true the field will be shown otherwise it will be hidden.

Loading custom ranges based on other field values

Specify the dependsOn attribute and also add the element <Defaults> with the attribute functionName set. The functionName must point to an existing javascript function. That function will be executed every time the dependsOn field changes passing the value of the field to the function.

The configured function must return either an array containing javascript objects with value and label properties or a Promise that resolves to an array containing objects with value and label properties.

Example of valid array:

[
    {"label": "Label 1", "value": "Value 1"},
    {"label": "Label 2", "value": "Value 2"}
]
Help messages

To configure a help message for a field specify the helperMessage setting.

Tooltip can be configured by passing the settings listed in Semantic Popup Settings into the tooltipConfig attribute.

A help message when configured is indicated by a 'question mark' next to the section label. On hovering over the icon, tooltip is shown. Tooltip icon (Default : question circle) and icon position (Default : right) can be changed as needed. Icons Link

<Setting name="options"><![CDATA[
    {
    "helperMessage": "Help message for this field. May contain html such as <a href='http://example.com'>a link</a> or an i18n key",
    "iconClass":"red question circle outline",
    "iconPosition":"left",
    "tooltipConfig": {
        "delay": {
            "show": 300,
            "hide": 800
            },
        "hoverable": true,
        "offset": 10
        }
    }
    ]]>
</Setting>
Preserve Output

Whether to preserve the values retrieved from the database or not. Preserve in this case means that HTML sensitive characters will not be escaped when displayed in the field, e.g., when an attribute contains HTML markup that should be displayed as such. Note that this setting will only be effective for textarea type field.

true

The HTML sensitive characters in the output will not be escaped. This is the default value.

false

The HTML sensitive characters will be escaped.

<Setting name="options"><![CDATA[
    {
    "preserveOutput": false,
    }
    ]]>
</Setting>
Trim Output

Whether to remove leading and trailing whitespace, newline characters in the value retrieved from the database or not. Trim in this case means that all leading and trailing whitespace, newline characters will be removed when displayed in the field, e.g., when an attribute contains any leading and trailing whitespace, newline characters will be removed and displayed. Note that this setting will only be effective for textarea type field.

true

All leading and trailing whitespace, newline characters will be removed in the output.

false

All leading and trailing whitespace, newline characters will not be removed. This is the default value.

<Setting name="options"><![CDATA[
    {
    "trimOutput": true,
    }
    ]]>
</Setting>
Default User Icon

Whether to have a default user icon for owner field in create form. This icon can be used to populate owner field with logged in user. Value shown in the selectize field for default is configurable and to be given under setDefaultUserLabel. It can be a user info related string or a function. Some of the user info related strings. By default lable will be context user’s full name.

email

App.info.user.email

firstName

App.info.user.firstName

lastName

App.info.user.lastName

fullName

App.info.user.fullName

userId

App.info.user.id

<Setting name="options"><![CDATA[
    {
        ...
        "setDefaultUserIcon": true,
        "setDefaultUserLabel": "App.info.user.fullName",
        ...
    }
    ]]>
</Setting>
image
Figure 63. Default user icon
Default user icon is applicable only for person field with FieldType as select.
Files Field

In a Helium form, you can have a field that enables form to checkin files to the main form object(s). Example:

<FilesField>
	<Label>Files</Label>
	<Format>generic</Format>
	<UseCDM>true</UseCDM>
	<Editable>true</Editable>
	<Store>store</Store>
</FilesField>

By default the filesfield is editable as shown in below image. In order to make the filefield non-editable, need to specifically include <Editable>False</Editable> tag.

image
Figure 64. Files Field

you can easily upload a file by using drag and drop.

There are two delete buttons for cdm enabled field, one for delete latest version and other for delete all versions. For CDM disabled field, there is only one delete button.

FilesField can also be used to display files from related objects. For example, tag <Expression>${from[relationship_ReferenceDocument].to}</Expression> can be included in <FilesField> to display all the files from all objects found through expression value . Expression tag will make the FilesField non-editable and displays the files from related objects found through the expression value alone.

All the files from all object found through the expression value will be displayed in files field. For example, out of given expression if 3 objects are found, all files from all 3 objects will be displayed in files field.

image
Figure 65. Files section with Expression

These are the sub-elements that are specific to a Files Field element:

Name Description Example

Label

The label of field

<Label>Files</Label>

Format

Specifies the format to use when checking in the file

<Format>generic</Format>

UseCDM

It specifies if the "Common Document Model" functionality will be enabled for the field or not

<UseCDM>true</UseCDM>

Store

Name of store

<Store>store</Store>

Editable

Whether the field is editable or not. Valid values true or false

<Editable>true</Editable>

Validation

What client side validation rules should be applied to the field. The following child elements are supported

<Required>

if the field is required or not. Valid values: true or false

<Validation>
    <Required>true</Required>
</Validation>

Template

A path to an handlebars template that is responsible for rendering the field.

<Template>
    /path/to/template.handlebars
</Template>

OptionTemplate

A path to an handlebars template that is responsible for rendering the selected field option.

<OptionTemplate>
    /path/to/template.handlebars
</OptionTemplate>

Expression

displays the files from connected objects found through the expression

<Expression>${from[relationship_ReferenceDocument].to}</Expression>

Editable Expression

define an expression used to control edit access.

<EditableExpression>current!='Review'</EditableExpression>

Related Object

A <RelatedObject> element is used to place a field in a form for showing/editing of related object information.

The following child elements are inherited from the Field element:

  • Label

  • Editable

In addition, the table below shows RelatedObject specific configuration elements:

Name Description Example

Relationship

Specifies the relationship and direction to use as basis for this field.

Allowed attributes on the <Relationship> element are

name

The name of the relationship. Must be specified.

direction

from or to. If omitted, from is the default value.

cardinality

Optional Specify cardinality. Valid values are "one" or "many". The database will by default be queried what cardinality the relationship in question has.

typePattern

Optional. Specifies a comma separated list of object types, which the related object(s) must be a type or sub-type of. May be used to reduce the number of related objects the field instance operated upon.

where

Optional. Specifies an additional where clause to be applied on the related object(s). The where clause will be evaluated to TRUE or FALSE.

Examples:

<Relationship direction="from" name="relationship_PartSpecification" />
<Relationship
    name="relationship_PartSpecification"
    direction="from"
    typePattern="type_SpecialDocumentType1,type_SpecialDocumentType2"
    where="current == 'Released' OR current == 'Finalized'" />

Display

May be used to specify an ENOVIA select expression to be applied on the related object(s).

Note that you may define multiple display selectables.

<RelatedObject>
    ...
    <Display>type</Display>
    <Display>name</Display>
    <Display>revision</Display>
    <Display>current</Display>
</RelatedObject>

Options

A JSON configuration object that mainly is used to configure Auto Complete settings.

If you enable editing of the RelatedObject, you must configure Auto Complete settings. For additional information regarding Auto Complete, see this chapter.

Do not mix <Settings name="options"> and <Options> in your field configuration. One of those settings will override the other which will result in undefined behaviour.
<RelatedObject>
    ...
    <Options><![CDATA[{
        "autocomplete" : {
            "handler" : {
                "name" : "businessobject",
                "typePattern" : "type_DOCUMENTS",
                "vaultPattern" : "eService Production",
                "revisionPattern" : "*",
                "whereClause" : "${attribute[attribute_IsVersionObject]} == 'False'",
                "caseSensitive" : false,
                "searchType" : "contains",
                "value" : "id",
                "limit" : 100
            }
        }
    }]]></Options>
</RelatedObject>

A search UI can be also configured for searching and adding value to field. See second example.

<RelatedObject>
    ...
    <Options><![CDATA[{
        "searchAndAdd":{
			"searchConfig":"tvc:search:hex:common/SearchAndAdd.xml"
		},
        "autocomplete" : {
            ...
        }
    }]]></Options>
</RelatedObject>

DisplayDelimiter

This can be used to separate different selectables configured in Display.

For Related object field with cardinality many | is not supported.

Now, the RelatedObject field can be used to set the relationship attributes during the creation of the connection. This can be achieved by adding the below two settings in the field definition.

Set Relationship Attribute Names: Can pass a comma-separated list of attribute names for updating multiple attributes at once. This setting only works in conjunction with the Setting Set Relationship Attribute Values. The number of attribute names configured for this setting must be equal to the number of values configured for the Setting Set Relationship Attribute Values. Otherwise, this setting is ignored, with no relationship attributes updated.

Set Relationship Attribute Values: Can pass a comma-separated list of attribute values for updating multiple attributes at once. This setting only works in conjunction with the Setting Set Relationship Attribute Names. The number of attribute values configured for this setting must be equal to the number of attribute names configured for the Setting Set Relationship Attribute Names. Otherwise, this setting is ignored, with no relationship attributes updated.

Also there might be a case where the attribute values contains comma, so in that case Delimiter can be configured and the attribute names and values should be separated with delimiter.

<RelatedObject>
    ...
    <Setting name="Set Relationship Attribute Names" value="TestRelAttribute2|TestRelAttribute" />
    <Setting name="Set Relationship Attribute Values" value="Mukesh|Ashish" />
    <Delimiter>|</Delimiter>
    ...
</RelatedObject>

    or

<RelatedObject>
    ...
    <Setting name="Set Relationship Attribute Names" value="TestRelAttribute2,TestRelAttribute" />
    <Setting name="Set Relationship Attribute Values" value="Mukesh,Ashish" />
	...
</RelatedObject>
Dynamic Attribute Field

Dynamic Attribute Field can be used to render multiple fields for an object, either from object type or classification interface. Dynamic Attribute Field is supported only on edit form.

<DynamicAttributeField> element is used to place a field in a form for showing/editing objects dynamic attributes.

The following child elements are inherited from the Field element:

  • Label

  • Editable

    Note

    By default attribute fields added dynamically are non editable.

Table below shows the DynamicAttributeField specific configuration elements:

Name Description Example

Filter

Specifies Exclude elements to exclude attributes. It supports both symbolic and actual attribute name.

<DynamicAttributeField>
    <Filter>
    	<Exclude>attribute_Weight</Exclude>
    	<Exclude>attribute_EffectivityDate</Exclude>
    	<Exclude>attribute_MaterialCategory</Exclude>
    	<Exclude>attribute_UnitofMeasure</Exclude>
    	<Exclude>attribute_EstimatedCost</Exclude>
    	<Exclude>attribute_DesignPurchase</Exclude>
    	<Exclude>attribute_EndItem</Exclude>
    </Filter>
    <Editable>true</Editable>
</DynamicAttributeField>

ForClassification

Specifies whether DynamicAttributeField is to be used for ClassificationField. Valid values true or false

Supports below attributes -

interfaceAttribute

Attribute expression to be evaluated on related ClassifiedItem object for retrieving Interface. Default is mxsysInterface.

classificationFieldId

Field Id of corresponding ClassificationField.

<DynamicAttributeField id="dynamicField">
    <ForClassification interfaceAttribute="attribute[mxsysInterface]" classificationFieldId="classificationfield">true</ForClassification>
    <Editable>true</Editable>
</DynamicAttributeField

FromInterface

Specifies whether DynamicAttributeField is to be used for Interface. Valid values true or false. Default is false.

Supports below attributes -

interface

Attribute expression to be evaluated on the context object for retrieving Interface. If interface attribute is not defined, then it will load all attributes from the interface which is applied to that object.

<DynamicAttributeField id="dynamicField">
    <FromInterface interface="Component Compliance,Material Compliance">true</FromInterface>
    <Editable>true</Editable>
</DynamicAttributeField>
Classification Field

Classification Field is designed based on Enovia Library Central classifications with flexibility to configure classification relationship. It works in correlation with DynamicAttributeField, which renders attributes from interface as defined on classification object. Classification Field is supported only on edit form.

A <ClassificationField> element is used to place a field in a form for showing/editing object classification information.

The following child elements are inherited from the Field element:

  • Label

  • Editable

    Note

    By default Classification Field is non editable.

In addition, the table below shows ClassificationField specific configuration elements:

Name Description Example

ClassificationRelationship

Specifies the relationship and direction to be used for classification field. By default Classified Item is used as relationship.

Allowed attribute on the <ClassificationField> element is

direction

from or to. If omitted, from is the default value.

<ClassificationField direction="from">relationship_ClassificationItem<ClassificationField/>

LibraryLoader

References to the dataset to load libraries for this classification field, via the child element <DateSet>. These libraries are passed as argument "libraryIds" to auto complete handler. In default auto complete handler, these libraries are expanded to show families beneath for user selection.

LibraryLoader is mandatory for ClassificationField as it provides initial libraries.
<ClassificationField>
    ...
    <LibraryLoader>
		<DataSet namespace="helium">PartLibraries.xml</DataSet>
	</LibraryLoader>
</ClassificationField>

MultipleClassification

Whether to allow multiple classifications. When enabled user can select more than one classification for same object. By default MultipleClassification is disabled and previous classifications are removed.

<ClassificationField>
    ...
    <MultipleClassification>true</MultipleClassification>
</ClassificationField>

DisplayExpression

May be used to specify an ENOVIA select expression to be applied on the related object(s).

<ClassificationField>
    ...
    <DisplayExpression>type</DisplayExpression>
</ClassificationField>

LinksWith

When DynamicAttributeField is intended to be used to display attributes corresponding to this ClassificationField, this element should point to DynamicAttribute field id.

This works in correlation with DynamicAttributeField and corresponding DynamicAttributeField should also point to Classification Field.
<Section>
<DynamicAttributeField id="dynamicField">
    <ForClassification interfaceAttribute="attribute[mxsysInterface]" classificationFieldId="classificationfield">true</ForClassification>
    <Editable>true</Editable>
</DynamicAttributeField>
.
.
</Section>
<Section>
<ClassificationField id="classificationfield">
    <Label>Classification Field</Label>
    <LibraryLoader>
    <DataSet namespace="helium">Libraries.xml</DataSet>
    </LibraryLoader>
    <Editable>true</Editable>
    <LinksWith>dynamicField</LinksWith>
.
.
</ClassificationField>
</Section>

Options

A JSON configuration object that mainly is used to configure Auto Complete settings.

If you enable editing of the ClassificationRelationship, you can configure Auto Complete settings. If no autocomplete handler is specified, a default autocomplete handler is used to retrive Classification objects. For additional information regarding Auto Complete, see this chapter.

Do not mix <Settings name="options"> and <Options> in your field configuration. One of those settings will override the other which will result in undefined behaviour.
<ClassificationField>
    ...
    <Options><![CDATA[{
        "autocomplete" : {
            "handler" : {
                "name" : "businessobject",
                "typePattern" : "type_PartFamily",
                "vaultPattern" : "eService Production",
                "revisionPattern" : "*",
                "whereClause" : "current == Active",
                "caseSensitive" : false,
                "searchType" : "contains",
                "value" : "id",
                "limit" : 100
            }
        }
    }]]></Options>
</ClassificationField>
Default Classfication Auto Complete Handler

There is a in built auto complete handler for Classification field, it expands libraries loaded from Library Loader on relationship Subclass. In built handler allows following configurations

Name Description Example

typePattern

Type pattern to expand Library object

<ClassificationField>
    ...
	<Options>
	<![CDATA[{
		"autocomplete" : {
				"handler" : {
					  "typePattern" : "Part Family"
				}
			}
		}
	]]>
	</Options>
</ClassificationField>

relPattern

Relationship pattern on which Library object should be expanded. Default is Subclass

<ClassificationField>
    ...
	<Options>
	<![CDATA[{
		"autocomplete" : {
				"handler" : {
					  "relPattern" : "Subclass"
				}
			}
		}
	]]>
	</Options>
</ClassificationField>

whereClause

Object Where clause.

<ClassificationField>
    ...
	<Options>
	<![CDATA[{
		"autocomplete" : {
				"handler" : {
					  "whereClause" : "current == Active"
				}
			}
		}
	]]>
	</Options>
</ClassificationField>

searchType

How the search criteria will operate. Available values:

  • contains

  • startsWith

  • endsWith

Default is startsWith

<ClassificationField>
    ...
	<Options>
	<![CDATA[{
		"autocomplete" : {
				"handler" : {
					  "searchType" : "contains"
				}
			}
		}
	]]>
	</Options>
</ClassificationField>

showClassificationPath

Whether to show classification path in drop down. By default, it is true and classication path from library is shown.

<ClassificationField>
    ...
	<Options>
	<![CDATA[{
		"autocomplete" : {
				"handler" : {
					  "showClassificationPath" : "true"
				}
			}
		}
	]]>
	</Options>
</ClassificationField>

It is allowed to configure custom auto complete handler using standard Options and auto complete handler settings.

Layout

The <Layout> element is responsible for how the sections and fields in the form should be positioned. If the <Layout> element is omitted all sections and fields will be rendered from top to bottom.

The <Layout> element supports the following child elements.

Name Description Example

Columns

The number of columns the form should consist of. Each <Section> element ends up in a column. The value given must be evenly divisible by 12 and cannot be greater then 12. The columns will only be rendered on large screens, if the screen is small the columns will be stacked on top of each other.

<Columns>3</Columns>

Template

A path to an handlebars template that is responsible for rendering the form. If the <Columns> element is present this element will have no affect. For more information regarding layout templates see [Layout template](#LayoutTemplate)

<Template>
    /path/to/template.handlebars
</Template>

TableTemplate

In-built template for showing labels and values separated in a table-like, column based template view. For more information regarding TableTemplate see TableTemplate

<TableTemplate/>
TableTemplate

Using TableTemplate, form can be rendered in table-like, column based template view.

Example:

<Form>
    <Layout>
        <TableTemplate/>
    </Layout>
    <Section>
    <!-- Lots of field elements -->
    </Section>
    <Section>
    <!-- More field elements -->
    </Section>
</Form>

It can also be combined with <Columns> setting.

Example:

<Form>
    <Layout>
        <TableTemplate/>
        <Columns>3</Columns>
    </Layout>
    <Section>
    <!-- Lots of field elements -->
    </Section>
    <Section>
    <!-- More field elements -->
    </Section>
</Form>

NOTE : While using table template with <Columns> setting, choose the number of columns according to the width of field labels for proper layout.

Layout template

By configuring a form to use a layout template it is possible to specify exactly where the different <Section> elements should be rendered. This is accomplished by given each <Section> an dom-id attribute. The attribute value should match an id in your template.

Consider the example configuration below:

<Form>
    <Layout>
        <Template>/path/to/my/template.handlebars</Template>
    </Layout>
    <Section dom-id="left">
    <!-- Lots of field elements -->
    </Section>
    <Section dom-id="right">
    <!-- More field elements -->
    </Section>
</Form>

And the following handlebars template (/path/to/my/template.handlebars):

<div class="form-template-example">
    <div id="left"></div>
    <div id="right"></div>
</div>

This will render the <Section> with dom-id="left" in the div with id="left" and the <Section> with dom-id="right" in the div with id="right".

Form in modal

A form can be rendered in a modal via a custom command. This is achieved by passing in the fullscreen: true parameter when the form is created. Example of such a command:

<Command>
    <Label>Create Part</Label>
    <FontIcon>plus</FontIcon>
    <OnClick>App.form.createNew</OnClick>
    <OnClickParams>{
        "formConfigName": "tvc:form:helium/CreatePart.xml",
        "fullscreen": true
    }</OnClickParams>
</Command>

It is possible to configure Create New button with Reload Form on Create Part & Create Connect Part form. This is achieved by passing in the showCreateNew:true and reloadForm:true parameter when the form is created.

Default Value of showCreateNew and reloadForm is false.

Example:

<Command>
    <Label>Create Part</Label>
    <FontIcon>plus</FontIcon>
    <OnClick>App.form.createNew</OnClick>
    <OnClickParams>{
        "formConfigName": "tvc:form:helium/CreatePart.xml",
        "fullscreen": true,
        "showCreateNew":true,
        "reloadForm":true
    }</OnClickParams>
</Command>
<Command>
    <Label>Create Part</Label>
    <FontIcon>icon plus</FontIcon>
    <URL href="javascript:App.form.createNew({options: {'formConfigName': 'tvc:form:helium/CreatePart.xml', 'fullscreen': true, 'showCreateNew':false, 'reloadForm':false, modal: {resizableHandles: {autoHide: true, handles:'e, se, s, sw, w'}} }});" />
</Command>

It is possible to configure the size, position, resize and drag properties of the modal by the following modal property:

<Command>
    <Label>Create Part</Label>
    <FontIcon>plus</FontIcon>
    <OnClick>App.form.createNew</OnClick>
    <OnClickParams>{
        "formConfigName": "tvc:form:helium/CreatePart.xml",
        "fullscreen": true,
        "modal": {
            "position": {
                "top": "20%",
                "bottom": "20%",
                "left": "20%",
                "right": "20%"
            },
            "resizable": false,
            "draggable": false
        }
    }</OnClickParams>
</Command>

Resizable and draggable properties are by default true. Valid values for the position is either the string auto which will try to center the modal in the middle of the screen or you could pass in an object containing the properties top, bottom, left and right as the example above.

To toggle the controls that are visible in the header pass in the controls object. See example below:

<Command>
    <Label>Create Part</Label>
    <FontIcon>plus</FontIcon>
    <OnClick>App.form.createNew</OnClick>
    <OnClickParams>{
        "formConfigName": "tvc:form:helium/CreatePart.xml",
        "fullscreen": true,
        "modal": {
            "position": {
                "top": "20%",
                "bottom": "20%",
                "left": "20%",
                "right": "20%"
            },
            "controls": {
                "dock": true,
                "expand": true,
                "close": true
            }
        }
    }</OnClickParams>
</Command>

resizableHandles property is used to enable resize from different positions like right(e), left(w), bottom(s), left bottom(sw) or right bottom(se) of the modal. Default value is se.

Examples:

<Command>
    <Label>Create Part</Label>
    <FontIcon>icon plus</FontIcon>
    <URL href="javascript:App.form.createNew({options: {'formConfigName': 'tvc:form:helium/CreatePart.xml', 'fullscreen': true, modal: {resizableHandles: {autoHide: true, handles:'e, se, s, sw, w'}} }});" />
</Command>
<Command>
    <Label>Create Part123</Label>
    <FontIcon>plus</FontIcon>
    <OnClick>App.form.createNew</OnClick>
    <OnClickParams>{
        "formConfigName": "tvc:form:helium/CreatePart.xml",
        "fullscreen": true,
        "modal": {
            "resizableHandles": {
            	"autoHide": true,
            	"handles": "e, se, s, sw, w"
            }
        }
    }</OnClickParams>
</Command>
Example
<Form>

    <Title>Test Form</Title>

    <Description>Foo</Description>

    <Layout>
        <!--<Template>helium/templates/form/form</Template>-->
        <Columns>2</Columns> <!-- If columns is set it will override the template -->
    </Layout>

    <Section dom-id="left"> <!-- If a template is set the dom-id attribute will determine where the section should be rendered -->
        <Label>Section 1</Label>
        <Field>
            <Label>Type</Label>
            <Expression>type</Expression>
            <Editable>false</Editable>
        </Field>
        <Field>
            <Label>Name</Label>
            <Expression>name</Expression>
            <Editable>false</Editable>
        </Field>
        <Field>
            <Label>Revision</Label>
            <Expression>revision</Expression>
            <Editable>true</Editable>
        </Field>
    </Section>
    <Section dom-id="right">
        <Label>Section 2</Label>
        <Field>
            <Label>Beskrivning</Label>
            <Expression>description</Expression>
            <Editable>true</Editable>
            <Validation> <!-- Validation rules which are sent to the client -->
                <Required>true</Required>
                <MinLength>3</MinLength>
                <MaxLength>30</MaxLength>
                <Pattern>^(Hello|Goodbye)\sworld$</Pattern>
            </Validation>
            <!--<Template>helium/templates/form/description_field</Template>-->
        </Field>
        <Field>
            <Label>Owner</Label>
            <Expression>owner</Expression>
            <DataType>user</DataType>
            <Editable>true</Editable>
            <FieldType>select</FieldType>
            <Defaults>   <!-- Defaults supports attributes className='java.class' and functionName='javascriptFunctionName' -->
                <Value value="Test Everything">
                    <Label locale="en">Everything, Test</Label>
                    <Label locale="sv">Testar</Label>
                </Value>
                <Value value="Ove">
                    <Label locale="en">Ove</Label>
                    <Label locale="sv">Ove</Label>
                </Value>
                <Value value="Patrik">
                    <Label locale="en">Patrik</Label>
                    <Label locale="sv">Patrik</Label>
                </Value>
            </Defaults>
        </Field>
        <!--<Field>-->
            <!--<Label>Originated</Label>-->
            <!--<Expression>originated</Expression>-->
            <!--<DataType>date</DataType>-->
            <!--<Editable>true</Editable>-->
        <!--</Field>-->
        <Field>
            <Label>Vikt</Label>
            <Expression>${attribute[attribute_Weight]}</Expression>
            <Editable>true</Editable>
        </Field>
        <Field>
            <Label>Material</Label>
            <Expression>${attribute[attribute_MaterialCategory]}</Expression>
            <Editable>true</Editable>
            <FieldType>select</FieldType>
        </Field>
    </Section>

</Form>

10.3.4. Templates

Create Forms have built-in functionality for users to save form data as templates that be used for later.

As shown below, the form data can be saved as templates and same saved template can be used to load data on the new form.

image
Figure 66. Save Form Templates
image
Figure 67. Load Form Templates

Please note that the templates that are saved on one form can only be loaded on the same form type. Templates are saved per user, meaning they cannot be shared to other users.

Templates can be enabled/disabled on individual forms using a configuration:

<Form>

    <AllowTemplates>true</AllowTemplates>

</Form>
Templates are currently available on forms in Create mode.

10.3.5. Multivalue attribute field

Multiple values can be added by selecting multiple values from the drop down or type in new values, this can be configured as below:

<Field>
    <Label>Test Multi Value</Label>
    <Expression>attribute[Test Multi Value]</Expression>
		<Editable>true</Editable>
    <FieldType multiple='true'>select</FieldType>
</Field>

For allowing free text value can in multivalue attribute fields, this can be configured as below:

<Field>
    <Label>Test Multi Value</Label>
    <Expression>attribute[Test Multi Value]</Expression>
		<Editable>true</Editable>
		<Setting name="options">
        {

            "autocomplete": {
                "selectize" : {
				"create":"true"
			}
            }

        }
    </Setting>
    <FieldType multiple='true'>select</FieldType>
</Field>
For dynamic multivalue attribute fields from interface this will be available by default based on schema configuration of attribute.

10.3.6. i18n

The form widget supports multiple languages via the i18n framework. To make your form multilingual use translation keys in your configuration instead of hardcoded names.

For example instead of configure your form like this, where the <Label> is hardcoded to always show Weight:

<Field>
    <Label>Weight</Label>
    <!-- more elements -->
</Field>

Use a translation key that is defined in your language files instead. For example:

<Field>
    <Label>form.fields.labels.weight</Label> <!-- a key that points to a translation -->
    <!-- more elements -->
</Field>

If the translation key can’t be resolved the actual value of key will be rendered, in this case form.fields.labels.weight.

Form messages

The following form messages is defined in the default translation file (default.json). By looking at the key names it should be pretty self explanatory when they will be rendered in the form.

{
    "form: {
        "messages": {
            "invalidPattern": "This field should have pattern {0}",
            "stringTooShort": "This field should contain at least {0} numbers or characters",
            "stringTooLong": "This field should contain at most {0} numbers or characters",
            "invalidTime": "Invalid time",
            "invalidEmail": "Invalid Email address",
            "invalidIPv4": "Invalid IPv4 address, e.g. 192.168.0.1",
            "invalidPassword": "Invalid Password",
            "invalidURLFormat": "The URL provided is not a valid web address.",
            "wordLimitExceeded": "The maximum word limit of {0} has been exceeded.",
            "invalidZipcodeFormatFive": "Invalid Five-Digit Zipcode (#####)",
            "invalidZipcodeFormatNine": "Invalid Nine-Digit Zipcode (#####-####)",
            "keyNotUnique": "Keys of map field are not unique.",
            "keyMissing": "Map contains an empty key.",
            "stringNotAnInteger": "This value is not an integer.",
            "invalidDate": "Invalid date for format {0}",
            "stringNotAJSON": "This value is not a valid JSON string.",
            "editorAnnotationsExist": "The editor has errors in it that must be corrected",
            "noneLabel": "None",
            "stringValueTooSmall": "The minimum value for this field is {0}",
            "stringValueTooLarge": "The maximum value for this field is {0}",
            "stringValueTooSmallExclusive": "Value of this field must be greater than {0}",
            "stringValueTooLargeExclusive": "Value of this field must be less than {0}",
            "stringDivisibleBy": "The value must be divisible by {0}",
            "stringNotANumber": "This value is not a number.",
            "stringValueNotMultipleOf": "This value is not a multiple of {0}",
            "invalidValueOfEnum": "This field should have one of the values in {0}.  Current value is: {1}",
            "notEnoughItems": "The minimum number of items is {0}",
            "tooManyItems": "The maximum number of items is {0}",
            "valueNotUnique": "Values are not unique",
            "notAnArray": "This value is not an Array",
            "addItemButtonLabel": "Add New Item",
            "addButtonLabel": "Add",
            "removeButtonLabel": "Remove",
            "upButtonLabel": "Up",
            "downButtonLabel": "Down",
            "chooseFile": "Choose file...",
            "chooseFiles": "Choose files...",
            "dropZoneSingle": "Click the Choose button or Drag and Drop a file here to upload...",
            "dropZoneMultiple": "Click the Choose button or Drag and Drop files here to upload...",
            "disallowValue": "{0} are disallowed values.",
            "notOptional": "This field is not optional.",
            "tooManyProperties": "The maximum number of properties ({0}) has been exceeded.",
            "tooFewProperties": "There are not enough properties ({0} are required)"
        }
    }
}

It is of course possible to override all of these messages in your custom language files, for example to override the stringTooShort key you would add the following to your language files.

{
    "form": {
        "messages": {
            "stringTooShort": "The string you provided is to short. It should contain at least {0} letters"
        }
    }
}

10.3.7. API

The javascript API is described here

10.4. Lifecycle

The lifecycle widget can be used to display the lifecycle of an object you are in context of. It will render all of the states horizontally and has functionality for simple promoting and demoting.

image

Currently the lifecycle widget is not able to render signatures.

Below is an example of how this widget is configured:

<LifecycleWidget>
    <Title>Lifecycle</Title>
</LifecycleWidget>

10.5. History

The history widget can be used to display the history of an object you are in context of. It will render all of the history entries in a table with the ability to filter on it. Also it supports sorting and initial sort will be on basis of date in ascending order.

The data from history widget can be exported to excel or PDF and provision to print history can be included as toolbar commands.

image

Below is an example of how this widget is configured:

<HistoryWidget>
    <Title>History</Title>
    <OnInitOption name="sortDirection" value="asc" />
    <OnInitOption name="sortColumn" value="when" />
    <Toolbar vertical="true">
        <Command>
            <Label>history.command.exportToExcel</Label>
            <FontIcon>ti-c ti-large ti-excelexport-c</FontIcon>
            <OnClick>App.Widget.exportHistoryToExcel</OnClick>
        </Command>
        <Command>
            <Label>history.command.exortToPDF</Label>
            <FontIcon>ti-c ti-large ti-file-pdf-c</FontIcon>
            <OnClick>App.Widget.exportHistoryToPDF</OnClick>
        </Command>
        <Command>
            <Label>history.command.print</Label>
            <FontIcon>ti-c ti-large ti-printer</FontIcon>
            <OnClick>App.Widget.print</OnClick>
        </Command>
    </Toolbar>
</HistoryWidget>

10.5.1. Sorting options

The OnInitOptions listed above can be used to change the initial sorting, which by default is sorted by time, oldest first.

sortDirection is either asc or desc (default asc)

sortColumn is any column name from ['when', 'state', 'action', 'user', 'description'] (default when)

10.6. Count

The count widget executes a dataset and renders the number of hits.

image

10.6.1. Options

Name Description Required

dataset

Reference to a dataset to load

true

color

The text color (#FFF)

false

background

The widgets background color (#34495e)

false

iconClass

What icon to show (could be icons from semantic-ui.com)

false

iconColor

The icon color (#FFF)

false

iconAlignment

Possible values: right, left, center

false

template

Your own handlebars template

false

drillDown

Reference to a dashboard used for drilldown

false

onclick

A function that is executed when the widget is clicked

false

maxCount

If the result contains more hits than maxCount a + sign will be added (99+)

false

Below is an example of how this widget is configured:

<CountWidget xmlns="http://technia.com/helium/Widget">
    <!-- Title will be used in drilldowns -->
    <Title>Documents</Title>
    <!-- Required -->
    <DataSet>tvc:dataset:main:common/MyDocs.xml"</DataSet>

    <!-- Optional -->
    <OnInitOption name="background" value="#34495e" />
    <OnInitOption name="color" value="#fff" />
    <OnInitOption name="iconColor" value="#fff" />
    <OnInitOption name="iconClass" value="icon file" />
    <OnInitOption name="iconAlignment" value="right" />
    <OnInitOption name="maxCount" value="999" />
    <!-- You can specify dashboard to drilldown to -->
    <OnInitOption name="drillDown" value="tvc:dashboard:helium:main:projectspace/ProjectDrillDown.xml" />
    <!-- Or execute a Javascript function-->
    <OnInitOption name="onclick" value="App.custom.yourCustomFunction" />
</CountWidget>

10.6.2. Limitations

The Count widget does not support headerless template.

10.6.3. Customization

If the icon doesn’t align properly a class can be added to the "iconClass" option for custom css.

<OnInitOption name="iconClass" value="icon file custom-class" />

10.7. Tile

The tile widget can be used to display a table, rendered in another way. It still uses a TableConfig for defining and retrieving its data, but using a Handlebars template the objects can be rendered in a fully custom way. There is also a default tile template provided.

image

10.7.1. Options

Name Description Required

tableConfig

Reference to a tableConfig to load

true

selection

Enable selection of objects, for performing actions. Default is false.

false

template

Your own handlebars template

false

onClick

A function that is executed when the tile is clicked. Default is to navigate to the object.

false

image

Below is an example of how a TileWidget is configured:

<TileWidget>
    <Title>Tile widget</Title>
    <TableConfig>tvc:tableconfig:folder/MyTableConfig.xml</TableConfig>
    <!-- Optional parameters below -->
    <OnInitOption name="selection" value="true" />
    <OnInitOption name="onClick" value="App.routing.open" />
    <OnInitOption name="template" value="helium/custom/hex/templates/common/widget/images-tile" />
</TileWidget>

10.7.2. Built-in commands

Tile Widget supports local search (filtering) in the same way as a TableWidget. To enable it, configure the <Search/> command as described here

image

10.7.3. Limitations

The Tile widget does not support TableConfigs with server side processing. Other commands from the TableActionHandler are not guaranteed to work in the same way for Tile Widgets as for TableWidgets.

10.8. Recent Objects Widget

The recent widget can be used to display a list of objects that the user has recently visited. The built-in widget uses TableConfig for defining and retrieving its data and a handlebars template to display the data. Both of them can be overridden if needed, for e.g. to fetch and display information in a different way.

image
Figure 68. Recent Objects Widget

10.8.1. Options

Name Description Required

Title

Title for widget, default, 'Recent' or value returned by i18n key, recent.title

false

tableConfig

Reference to a tableConfig to load

false

template

Your own handlebars template

false

By default, 20 latest visited objects are stored/ displayed. A TVC property, tvc.core.recentobject.limit can be used to define different limit, e.g. tvc.core.recentobject.limit = 30

Below is an example of how a RecentObject Widget is configured:

<RecentObjectWidget />

If you’d like to use your own table for loading data and template for rendering, a sample configuration could be:

<RecentObjectWidget>
    <Title>acme.label.last.viewed</Title> <!-- i18n key  -->
    <OnInitOption name="tableConfig" value="tvc:tableconfig:acme/LastViewedObjects.xml" />
    <OnInitOption name="template" value="helium/custom/templates/common/widget/last-viewed" />
    <OnInitOption name="selection" value="false" />
    <OnInitOption name="onClick" value="App.custom.openObject" />
</RecentObjectWidget>

In addition, the com.technia.tvc.core.recentobject.RecentObjectHandlerManager Java class has APIs that can be used to get, save, and clear recently visited objects. See TVC Core Admin guide for more information of configuring recent objects.

Looking to configure recent objects within a menu in Topbar instead? See Recent Object Menu for more information.

10.9. Clipboard Widget

The clipboard widget can be used to show objects, selected by the user. The content of the clipboard is maintained between sessions. The built-in widget 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.

Clipboard objects can be removed by clicking on minus circle icon.

Clipboard widget is not supported with offline pages.
image
Figure 69. Clipboard Widget

10.9.1. Options

Name Description Required

Title

Title for widget, default, 'Clipboard' or value returned by i18n key, clipboard.title

false

tableConfig

Reference to a tableConfig to load

false

template

Your own handlebars template

false

Below is an example of how a Clipboard Widget is configured:

<ClipboardWidget />

If you’d like to use your own table for loading data and template for rendering, a sample configuration could be:

<ClipboardWidget>
    <Title>acme.label.clipboard.items</Title> <!-- i18n key  -->
    <OnInitOption name="tableConfig" value="tvc:tableconfig:acme/ClipboardItems.xml" />
    <OnInitOption name="template" value="helium/custom/templates/common/widget/clipboard-items" />
    <OnInitOption name="selection" value="false" />
    <OnInitOption name="onClick" value="App.custom.openObject" />
</ClipboardWidget>
User can defined at most one clipboard widget per page.

10.10. Clipboard Store

The content of the clipboard is by default stored into a set in the database.

This set is saved with the name mxClipboardCollections, if the ENOVIA version is V6R2009 of later. For earlier versions, this name is .clipboard.

It is however, possible to change this name through the following init-parameter (the name must not be longer than 127 characters, and might only contain characters that are valid for ENOVIA sets):

<init-param>
    <param-name>tvc.structurebrowser.clipboard.name</param-name>
    <param-value>My Clipboard</param-value>
</init-param>

10.11. Clear Clipboard

To clear the content of the clipboard, the clear method of App.clipboard JS API can be used. The command can be used in Clipboard widget toolbar.

Example:

In Clipboard Widget Toolbar

<ClipboardWidget>
	<Toolbar>
		<Command>
			<Label>Clear</Label>
			<Alt>Clear Clipboard</Alt>
			<FontIcon>ti-c ti-broom</FontIcon>
			<OnClick>App.clipboard.clear</OnClick>
		</Command>
	</Toolbar>
</ClipboardWidget>

10.12. Collections

Helium contains functionality allowing the user to work with collections. A collection is used to store arbitrary business objects.

10.12.1. Configure Collection:

Collections can be enabled from widget toolbars.

Adding <collection/> elements in toolbar, will enable a collection menu with 4 default commands.

  1. Add to Clipboard

  2. View Clipboard

  3. Add to Collection

  4. View Collection

Collection default menu will appear in UI as shown in below image.

image

Add to Collection command

This command opens a 'Add to Collection' widget in sidepanel and allows the user to add the selected objects from datatable to an existing or new collection. New collection can added by selecting the Add New Collection option in the select input field.

Add new Collection option can be internationalized by key helium.collection.addToCollection.addNewCollection using String Resource properties file.

image

View Collection command

This command opens a 'View collection' widget in sidepanel and allows user to view and manage collection objects. Collection widget has 6 default toolbar commands for managing the collection objects.

image

10.12.2. Manage collections:

User can manage the collections and its content from collection widget. Below 6 default toolbar commands in Collection widget enables users to manage their collection objects.

  1. Filter

  2. Create Collection

  3. Clear collections

  4. Delete collections

  5. Distribute selected collection(s)

  6. Merge selected collections

image

Filter

Lists the collection that contains the given search string in collection name.

image

Create collection

Enables to create a new collection object

image

Clear collections

Removes all the contents from the selected collections

image

Delete collections

Deletes the selected collections.

image

Distribute selected collection(s)

Enables to distribute the selected collections to another user within the same company as the user.

image

Merge selected collections

Enables to merge selected collections to a new or an existing collection object. User can choose to retain or deleted the old collections after the merge operation using the 'Keep old' field. And if merging to an existing collection, user can choose to append or not.

image

10.12.3. Manage collection

User can manage the individual collection widget content by using default toolbar commands:-

  • Search and Add

  • Remove

  • Clear Collection

image

Search and Add

This command opens a pre-configured search form to allow the user to search object and add to the collection.

image

10.12.4. Remove

This command will removed one or more objects from the collection widget.

10.12.5. Clear Collection

This command will clear all the content of the collection.

10.12.6. Customize Collection

Commands:

Collection default commands can be customized to change the label, font Icon, alt and visibility as shown in below xml.

<Collection>
    <Label>Favourites</Label>
    <FontIcon>Collection Icon</FontIcon>
    <AddToClipboard />
    <ViewClipboard />
    <AddToCollection>
    	<!-- 1 . Add to Collection label changed to My Collections -->
    	<Label>My Collections</Label>
    	<!-- 2. default Font Icon changed to 'Favourite Icon' -->
    	<FontIcon>Favorite Icon</FontIcon>
    	<!-- 3. Default Alt changed -->
    	<Alt>Add your favourite object</Alt>
    	<Label>My Collection</Label>
    	<FontIcon>Collection Icon</FontIcon>
    </AddToCollection>
    <!-- 4. visible='false' will hide "View Collection" command -->
    <ViewCollection visible='false'>
    	<Label>Display Collection</Label>
    	<FontIcon>Collection Icon</FontIcon>
    </ViewCollection>
</Collection>
Widgets:

Collection widget is configured to open in a sidepanel by default. But it can be customized to include in your required dashboards.

In order to configure in required dashboard, two widgets need to be included in the required dashboard as shown in below sample XML. The first widget (Collections.xml) is for viewing all collection objects, and the second widget(Collection.xml) is required for opening the individual collection object. Hence both the widgets should be included in the required dashboard.

Ideally no element values in the below widgets are suggested to change, except the positioning values.

<Dashboard">
	<Locked>false</Locked>
	<Floating>true</Floating>
	<Widgets>
		<Widget namespace="helium:collections" name="Collections.xml">
			<Id>collections</Id>
			<Width>12</Width>
			<Height>10</Height>
			<X>0</X>
			<Y>0</Y>
			<Locked>false</Locked>
			<Badge>true</Badge>
		</Widget>
		<Widget namespace="helium:collections" name="Collection.xml">
			<Id>collection</Id>
			<Width>12</Width>
			<Height>10</Height>
			<X>0</X>
			<Y>0</Y>
			<Locked>false</Locked>
			<Badge>true</Badge>
			<Hidden>true</Hidden>
		</Widget>
	</Widgets>
</Dashboard>

10.13. IframeWidget

While Helium is designed as a JSON-driven Single-Page Application, and we generally discourage the use of legacy iframes, sometimes embedding web pages from other applications or even servers can be necessary.

Another useful scenario of when to use an <IframeWidget> is if you want to reuse a JSP based tvc-action from the TVC Classic component family. Because the IframeWidget will receive the context objectId as a parameter, this enables using Helium for its standalone mode, while embedding TVC views that normally are seen inside 3DExperience.

The below example shows how you can embed the Gantt Chart view from TVC Graphic Reporting. Note that the Page’s objectId is passed into the <IframeWidget> automatically.

image

10.13.1. Options

Name Description Required

Title

Widget title, seen in header

false

Src

The URL to embed within the IframeWidget, to which ?objectId={objectId} will be appended

true

Options

A way to pass CSS classes and styling, see below

false

Full example, showing the configuration for above Gantt Chart scenario.

<IframeWidget>
  <Title>Gantt Chart</Title>
  <!-- Wrap the URL in a CDATA section to avoid issues with ampersands and other special characters -->
  <!-- Some ${macro} variables can be used within the Src element: ${CONTEXT_URL}, ${ROOT_DIR}, ${TVC_ACTION} -->
  <Src><![CDATA[${TVC_ACTION}/ganttChart?name=Sample&subHeader=TVC Graphic Reporting Sample&suiteKey=ProgramCentral&suiteKey=ProgramCentral&emxSuiteDirectory=programcentral&emxSuiteDirectory=programcentral&StringResourceFileId=emxProgramCentralStringResource&StringResourceFileId=emxProgramCentralStringResource&mode=replace&valueIndex=0&colName=Name&targetLocation=content]]></Src>
    <!--<Options>{-->
        <!--"id": "hidden-iframe",-->
        <!--"template": "some/other/template",-->
        <!--"classes": "additional classes separated with space",-->
        <!--"width": "100%",-->
        <!--"height": "100%"-->
        <!--}-->
    <!--</Options>-->
</IframeWidget>

11. Embedding in TVC Classic

Embedding can be done in two ways. Either:

  1. Embed a Helium Widget. Useful when you want to embed a single widget.

  2. Embed a Helium Page. Useful when you want to display a dashboard with multiple widgets.

11.1. Embed Widget

To embed Helium widget into a TVC Classic tab, create a Command with the following content:

<?xml version="1.0" encoding="UTF-8"?>
<Command 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/Command.xsd">
    <Label>Helium</Label>
    <URL href="/goto/w/helium/NameOfWidget" /> (1)
</Command>
1 The href attribute points to the Helium widget you want to embed.

Passing the current object id to Helium works in the same manner as for pages.

The Helium topbar will not be displayed and the widget is rendered in headerless mode.

See Route to Widget for more details.

11.2. Embed Page

To embed Helium page into a TVC Classic tab, create a Command with the following content:

<?xml version="1.0" encoding="UTF-8"?>
<Command 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/Command.xsd">
    <Label>Helium</Label>
    <URL href="/goto/p/helium/Page"> (1)
        <Param name="embed" value="true" /> (2)
    </URL>
</Command>
1 The href attribute points to the Helium page you want to embed.
2 The param embed with value true will make the helium page render without the topbar menu.

If you want to pass along the current object id to Helium, simply add the submit attribute to your command as in the example below:

<?xml version="1.0" encoding="UTF-8"?>
<Command 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/Command.xsd">
    <Label>Helium</Label>
    <URL submit="true" href="/goto/p/helium/Page"> (1)
        <Param name="embed" value="true" />
    </URL>
</Command>
1 submit attribute set to true results in the current objectId being passed to Helium

See Route to Page for more details.

11.3. Embed Dashboard

To embed Helium dashboard into a TVC Classic tab, create a Command with the following content:

<?xml version="1.0" encoding="UTF-8"?>
<Command 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/Command.xsd">
    <Label>Helium</Label>
    <URL href="/goto/d/NameOfDashboard"> (1)
    </URL>
</Command>
1 The href attribute points to the Helium dashboard you want to embed.

11.4. Embedded Tips

When running in embedded mode you might want to disable the headers of the different widgets. This is achieved by setting the <Template> element to headerless in your widget definition. See example below:

<Widget namespace="helium" name="TableWidget.xml">
    <Id>dt1</Id>
    <Width>6</Width>
    <Height>10</Height>
    <X>0</X>
    <Y>0</Y>
    <Template>headerless</Template>
</Widget>
It is recommended to explicity pass embed=false parameter to non embedded command so that topbar is always visible when switching from embedded mode to normal mode.
Verical stack mode for widgets is by default disabled in embeded. To enable this behavior, use tvc.helium.embedded.disableMobileMode=false in tvc.properties. The default value is true.
Breadcrumb in embeded mode can be enabled by defining tvc.helium.embedded.showBreadcrumb in tvc.properties. The default value is true.

12. 3DDashboard Support

Helium can run as a true widget inside 3DDashboard. Unlike TVC widget, it runs directly inside 3DDashboard widget iframe. True widget can be configured through the widget preferences in the administrator’s dashboard. As configurations are listed automatically in preferences UI admin is responsible for setting up and distributing proper/working configurations.

After a dashboard has been configured the administrator can share this to the users.

12.1. Configuration

Configure a dashboard:

  1. Login with administration access.

  2. Go to 3DDashboard.

image
Figure 70. Launch 3D Dashboard
  1. Go to Platform Management.

image
Figure 71. Go to Platform Management
  1. Go to Members tab.

  2. scroll down.

  3. Click on Create Additional app.

image
Figure 72. Add Additional app
  1. Fill the following details and click save button.

    1. Short Name.

    2. Long Name(Appears in tooltip).

    3. Compass Quadrant.

    4. Type.

    5. Source Code URL (Is widget path in webapps folder as shown in below image).

    6. Configuration file URL (Optional and required only when adding preconfigured JSON based widget). For more details refer Preconfigured Widgets JSON configuration

image
Figure 73. Create new widget.

The available Widget Type in widget preferences are as below:

Property Description Path

Helium Chart

When selecting page a list of helium widget configs for chart will be available for the user to choose from

/goto/w

Helium Dashboard

When selecting dashboard a list of helium widget configs for dashboard will be available for the user to choose from

/goto/d

Helium Page

When selecting page a list of helium page configs will be available for the user to choose from

/goto/p

Helium Table

When selecting page a list of helium page configs for table will be available for the user to choose from

/goto/w

image
Figure 74. All available Widget Type
image
Figure 75. Widget Conf

After selecting the MyPartsTable configuration in preferences widget will load the helium table with selected configuration. as shown below.

image
Figure 76. My Parts Table

Widget preferences available with True Widget are similar to wrapper TVC widget. For more details refer Widget Preferences

12.2. Common Features

Helium True Widget supports below common features similar to wrapper TVC Widget :

  • Custom Resources

  • Widget Preferences

  • Publish Subscribe

  • Search Support

  • 6WTags Filtering support

  • Widget Preferences Internationalisation

Please refer following link of TVC documentation 3DDashboard Support for more details.

12.3. Drag and Drop Support

Pre-requisite : For Drag and drop feature in True Widget, the user need to enable Drop Zone which can be achieved either by configuring -

  • Search Droppable preference like below, or

image
Figure 77. Search Droppable Preference
  • Search and Drop global property like below

tvc.3ddashboard.searchanddrop.enable=true

In True widget, Drop Zone will be visible once object is being dragged.

User can drag object from -

  • Using 3DSearch - With 3DSearch, an object can be dragged and dropped on True Widget to populate the context of the widget.

  • Using Object-link Column - With Object-link Column, an object from the Helium or true widget can be dragged and dropped into TVC / OOTB widgets and vice versa.

To achieve drag from Object-link Column, the below configuration need to be provided in the tvc structure browser table column.
    <Draggable>true</Draggable>

Complete Example of Draggable Table Column :

<Column>
    <Name>Name</Name>
    <Description>Name of this object</Description>
    <Expression>name</Expression>
    <Label>emxFramework.Common.Name</Label>
    <RegisteredSuite>Framework</RegisteredSuite>
    <Setting name="template" value="helium/templates/table/object-link" />
    <Href>/${COMMON_DIR}/emxTree.jsp</Href>
    <TargetLocation>content</TargetLocation>
    <Draggable>true</Draggable>
</Column>

12.4. File Manager

File Manager operations are supported in TrueWidget in 3DDashboard.

Native File Manager

File Package Download

Default File Manager (Fallback Mechanism)

To use fallback mechanism globally, Use tvc.3ddashboard.settings.useNativeFileManager = false property in tvc.properties.

12.5. Drag and Drop Objects

Earlier drag and drop of objects was only available to set or modify the context of objects, now we can use drag and drop for making connections between objects or invoking 3DExperience services.

Please refer link for more info on how to configure drag and drop

12.6. Drag and Drop objects on non-contextual widget.

Earlier, drag and drop only works with the widget which requires a context object to load. Now with this feature improvement user can drag and drop an object on non contextual widget.

dropped object on non-contextual widget are temporarily available once the widget gets refresed dropped object won’t be visible.

12.7. Search bar should be available when widget requires a context.

Earlier, when a widget requires context user has to search and drag-drop objects to set the context of the widget. Now, search bar is visible to the user whenever widget requires context object to load, user can search and select an object to set the context in widget it self. by default it shows searched results in type, name, revision format. User can set the search result format by setting the following property in tvc.properties file.

tvc.3ddashboard.search.display.format = type, name, revision

User can also enable or disable this feature by setting the following property true/false in tvc.properties file, default value is true.

tvc.heliumtruewidget.searchtext.enabled

12.8. Open available apps

Now available apps for can be launched from true widget by right clicking on any row. This feature can be enable by adding below configuration :

<TableConfig>
    ...
	<OpenWithMenu>true</OpenWithMenu>
	...
</TableConfig>
image
Figure 78. Open With Menu in true widget

12.9. 3DComments in Helium True Widget

It is possible to view, edit, add, like or reply 3dcomments related to a business object in helium true widget. This can be done by adding a helium widget with below configurations :

<Widget>
    <Html><![CDATA[<div class="comments-widget" id="3d-comments-widget"></div>]]></Html>
    <OnInit>App.Comment.create</OnInit>
    //below configurations are optional
    <OnInitOption name="getCommentsUrl" value="resources/commentproxy/subjects/pid:$OBJECTID/contributions" />
    <OnInitOption name="getReplyUrl" value="resources/commentproxy/subjects/pid:$OBJECTID/comments/$COMMENTID" />
    <OnInitOption name="postCommentsUrl" value="resources/commentproxy/subjects/pid:$OBJECTID/comments" />
    <OnInitOption name="deleteCommentUrl" value="resources/commentproxy/subjects/pid:$OBJECTID/comments/$COMMENTID" />
    <OnInitOption name="likeCommentUrl" value="resources/commentproxy/subjects/pid:$OBJECTID/endorses/me" />
</Widget>

Init options for various url are optional as the path for the endpoints may vary in different 3DExperience versions.

As the image of user is loaded from 3DSwym so 3DSwym image url can be configured in tvc.properties as below : tvc.helium.3dswym.person.url = https://23xdemo.technia.net/3dswym/api/user/getpicture/login/

13. Styling and Icons

Helium is using a third party framework called Semantic UI (https://semantic-ui.com/) for internal styling on many of the components. Helium also uses many of the icons included in that framework.

In the same way Helium is using this framework internally it is also possible (and preferred) to use this for custom functionality in Helium that needs a UI or Icons. The following section describes this in more detail.

13.1. Semantic UI Styling

The CSS and JS files for Semantic UI are automatically included in Helium so it is possible to use the different components in Semantic UI for custom functionality. Available components and the markup/scripts needed are available on the Semantic UI web page https://semantic-ui.com/

13.2. Semantic UI Icons

Semantic UI includes a complete port of the font icon toolkit called fontawesome (that we used to include in Helium but no longer do). Available icons and how they are used can be found on https://semantic-ui.com/elements/icon.html.

An example usage is <i class="alarm outline icon"></i>. When using in configurations that support font icons only the classes are used, in the previous example that would then be "alarm outline icon".

13.3. Icon Bundles

Helium ships 5 icon sets that are filled with beautiful svg icons that can spice up your application. You need to include them in your project to be able to use them. Read more about how to use them and browse the icons here.

13.4. Custom Icons

Custom made font icons or other font icon libraries can also be used by placing the resources that are needed in the "/custom" folder that holds all assets needed by custom functionality.

14. TVC Collaboration Integration

TVC Collaboration Components like Myspace and Panel are rendered in Helium standalone and Helium embedded using configurations.

Note: When TVC Classic with collaboration embeds Helium configured with Panel, then there would be two side panels. one within embedded Helium and one for the TVC Classic.

14.1. Myspace

Myspace inbox command is configured in Helium’s Topbar Right side command.

<Application xmlns="http://technia.com/helium/Application">
    <Name>ACME</Name>
    <!-- other configurations. refer chapter Helium.xml -->
    <TopBar>
        <!-- Left -->
        <Right>
            <Myspace />
            <Search />
            <Logout />
        </Right>
    </TopBar>
</Application>
image
Figure 79. Collaboration Myspace

14.2. Panel

Collaboration’s Panel component can be rendered inside Helium’s container component Page Sidepanel using configuration.

<Page>
    <!-- other configurations. refer chapter Page.xml -->
    <Sidepanel width="500" position="right">
        <Label>Collaboration</Label>
        <OnInit>App.Collaboration.Panel.instance</OnInit>
        <OnInitOption name="key" value="true" />
    </Sidepanel>
</Page>
image
Figure 80. Collaboration Panel

14.3. Widget

Collaboration’s Panel component can be rendered inside Helium’s container component Widget using configuration.

<Widget xmlns="http://technia.com/helium/Widget">
	<Title>Collaboration</Title>
	<OnInit>App.Collaboration.Panel.load</OnInit>
	<OnInitOption name="key" value="value" />
</Widget>
image
Figure 81. Collaboration Widget

14.4. Link to Discussion

In Helium table, you can add a column that will show an icon when a discussion exists for the object. Clicking on the icon brings up the discussion panel similar to Classic Collaboration.

To enable this column in your table, add a column like shown below:

<Table>
    ...
    <Column>
        <Name>discussion-link</Name>
        <ColumnType>discussion-link</ColumnType>

        <!-- an optional helium specific Template to have icon over image and rich tooltip -->
        <Setting name="Template" value="helium/templates/collaboration/discussion-link" />
    </Column>
</Table>
image
Figure 82. Link to discussion

14.5. Link to Workflow

In Helium table, you can add a column that will show workflow chart or an icon when a workflow exists for the object. Clicking on the icon brings up the workflow panel similar to Classic Collaboration.

When multiple workflows are defined on context object, the last modified workflow would be shown in Workflow Chart column.

To enable this column in your table, add a column like shown below:

<Table>
    ...
    <Column>
        <Name>workflow-chart</Name>
        <Label>workflow-chart</Label>
        <ColumnType>helium-workflow-chart</ColumnType>

        <!-- an optional helium specific iconOnly setting, to have static icon over dynamic workflow rendering -->
        <Setting name="iconOnly" value="true" />
    </Column>
</Table>

'iconOnly' setting is by default false.

image
Figure 83. Link to workflow(Chart)
image
Figure 84. Link to workflow(Icon)

15. In-App Designer

15.1. Introduction

In-App Designer (previously known as End User Definition/ End User UI) is a concept that brings the idea of creating, editing, and sharing configurations using the built-in admin user interface. These configurations can be used to define Helium dashboards, widgets, tables, charts, etc. Built-in Admin UI is provided to create, modify and share these configurations. In-App-Designer can be used from Helium standalone or Helium widget in 3DDASHBOARD. Once an admin has created and shared the config with the end-user, the end-user can use a built-in chooser UI to select and apply the configuration to his page, dashboard, or widget.

15.2. Admin Configuration UI

Using the built-in admin user interface, config-admin can design a new configuration like dashboard, widget, table, etc., and share the configurations with end-user.

Admin Configuration UI can be configured in both 3DDASHBOARD and standalone helium application.

Config-Admin or admin user is a person having TVC Config Admin role. And Admin Configuration UI can only by accessed by Config-Admin.

15.2.1. Configure Admin UI in StandAlone Helium Page

In standalone helium page, Admin Configuration UI can be accessed through the command Configuration Admin. Add this command in Helium.xml file as shown below.

<?xml version="1.0" encoding="UTF-8"?>
<Application xmlns="http://technia.com/helium/Application">
   ...
    <TopBar>
      	...
      <Command>tvc:command:helium:admin/ConfigAdminUI.xml</Command>
   	...
    </TopBar>
<Application/>

In Helium UI, you can see the "Configuration Admin" command in the topbar as shown in the image.

image
Figure 85. Command for Config Admin UI

15.2.2. Configure Admin UI in 3DDASHBOARD

In 3DDASHBOARD, create App for Admin UI from the "Additional Apps" UI as shown in the image.

image
Figure 86. App for Config Admin UI

Config-Admin can also add 3DDASHBOARD widget for Admin UI by choosing "AdminPage(tvc:page:helium:admin/AdminPage.xml)" in 3DDASHBOARD widget preference as shown in the image.

image
Figure 87. 3dd widget for Config Admin UI

15.3. Configuration Request

In-App-Designer process starts with end-user requesting for a new configuration like dashboard, widget, table, tablecolumn or expression, etc. from config-admin.

15.3.1. EndUser Requests

End-user can create a config request from the Request tab in Shared Config UI as shown in image. In the create form, end-user can write a detailed description about the new configuration requirement and can submit by clicking the Notify Config Admin button.

Once the request is created, config-admin will be notified about the new config request.

image
Figure 88. Create Config Request

15.3.2. ConfigAdmin - Request Tab

All the config requests created by end-user will be listed in the Configuration Requests tab of config-admin-UI as shown in image.

image
Figure 89. List of Configuration requests created by endusers

Config-Admin will create a new configuration based on the description in the config request, and share with the requested end-user. Once the configuration is created and shared with the end-user, config-admin can update the request object by adding the admin comment.

image
Figure 90. Add Admin comment

15.4. Create and Share Dashboard

Consider a scenario where the end-user has requested for a project dashboard with 3 widgets.

  1. Issue Tablewidget

  2. Task Tablewidget

  3. Issue priority Chartwidget

It involves 4 major steps to create and share the dashboard with the end-user.

  1. Create dataset

  2. Create dashboard

  3. Configure widgets and Update table columns

  4. Activate and Share dashboard with end-user

15.4.1. Step 1/4 - Create dataset

This scenario needs 2 datasets to list the issue and task objects. Refer the below configuration to create the dataset config.

For more information about datasets, refer to Dataset section.

From release 2023.1.0, it is not mandatory to have the preconfigured datasets and filters. Instead config-admin can choose to create the dataset and filters from within the create widget screen. Refer to Create dataset and filter inline widget section.
Dataset Configurations for Issues:
<?xml version="1.0" encoding="UTF-8"?>
<DataSet>
	<Inquiry>
		<Code>temp query bus Issue * * where "owner == context.user" limit 25 select id dump |</Code>
		<Format>${OID}</Format>
		<Pattern>*|*|*|${OID}</Pattern>
	</Inquiry>
</DataSet>
Dataset Configurations for Tasks:
<?xml version="1.0" encoding="UTF-8"?>
<DataSet>
	<Inquiry>
		<Code>temp query bus Task * * where "owner == context.user" limit 25 select id dump |</Code>
		<Format>${OID}</Format>
		<Pattern>*|*|*|${OID}</Pattern>
	</Inquiry>
</DataSet>

Create 2 new datasets with above configurations as shown in image

image
Figure 91. Create dataset configuration

Validate configuration using Validate option. Refer Validate XML against XSD section.

15.4.2. Step 2/4 - Create and Preview dashboard

Create a new dashboard by clicking the command Design Dashboard and name the dashboard "Project Dashboard"

image
Figure 92. Design Dashboard Screen

Once the dashboard is created, launch the dashboard using the preview icon. A new empty dashboard will open with options to create new widgets as shown in the images below.

image
Figure 93. Preview dashboard
image
Figure 94. Empty dashboard with Create widget options

15.4.3. Step 3/4 - Create widgets and Configure Table Columns

As per the scenario, create 3 new widgets by selecting the issue/task dataset and a new table

Widget 1: Create Issue TableWidget:
Form Field Name Description

Name field

Name of the tablewidget

Valid For Field

This field is mainly for filtering out the huge list in data source and table fields. This field lists only the business type for which datasets or tables are created already.

Datasource Field

Select the data source from the dropdown. This field lists all the accepeted datasets which shared by config-admin and also the one created from saved search. Refer create dataset from saved search section.

Widget Type field

List options to create a table or chart widget.

CreateNew Checkbox

Enables you to create a new table or lists existing tables for your selection.

For our scenario, choose the Issue data source and new table, and create a new tablewidget for displaying the Issue objects The new table will be created with a basic columns.

image
Figure 95. Create Issue Table Widget screen

The created tablewidget will have the basic columns like type, name and revision. Config-Admin can now add new columns to this table.

image
Figure 96. Issue TableWidget With basic columns

Update Table with columns:

Config-Admin can update the table with required columns using the Table Configurator.

Consider below 3 columns are required in the newly created tablewidget.

  1. Issue Status,

  2. Related Tasks, and

  3. Related Tasks Status

Using the Table Configurator, you can select the required tablecolumn from the existing list of columns, or you can create a new column by providing your expression as shown in the image.

image
Figure 97. Table Configurator to Add Columns

You can choose the predefined columns by searching with the text, or you can click on 'Add Advanced Column' to create new column with expression as shown in images.

image
Figure 98. Choose 'Maturity Status' from existing column list
image
Figure 99. Create new Column from Add advance column

Refer the below image where Issue tablewidget with new columns are configured.

image
Figure 100. New TableWidget created for Issue
Widget 2: Create Task TableWidget

Similar to the Issue tablewidget, create a tablewidget for "Tasks" by choosing the "Task" as datasource and the Create New table option enabled.

image
Figure 101. Create Task TableWidget

Choose the datasource as Tasks and create a new tablewidget for "Task"

image
Figure 102. Task TableWidget
Widget 3: Create Issue priority ChartWidget

Add a new chartwidget by selecting the widget type as "Chart" in create widget screen.

image
Figure 103. Create Chart Widget

Now, the "Project Dashboard" is created in the DRAFT state with 3 widgets in it. And it is ready to promote to an active state and share with end-user

image
Figure 104. Draft Project Dashboard

15.4.4. Step 4/4 - Activate and Share dashboard with end-user

Promote the created dashboard to an active state and share it with end-user

By default, the configured "Project Dashboard" will be in the draft state. Before we share it with the end-user, promote it to the active state. while Promoting the "Project Dashboard" config, all the related configuration objects (such as Widget, Table, Tablecolumn, and Dataset objects) will be auto promoted to active state

image
Figure 105. Promote the Draft Dashboard

Share the "Project Dashboard" configuration which is in an active state with the end-user using the Share Command. Once it is shared, end-user will be notified about the new configuration shared. See EndUser - Shared Configurations to know how the shared dashboard is accepted and used by enduser.

If config-admin need to make any further changes to the shared dashboard, the configuration object has to be revised.

image
Figure 106. Share the Project Dashboard

15.5. Revise Shared Dashboard

Once the configuration object is shared with the end-user, the admin cannot make any further changes to the shared configuration object. To make any changes, the configuration object has to be revised.

Consider a scenario where the end-user has requested to include one more tablewidget "Risk" in the shared project dashboard. For such a scenario, the admin can revise the project dashboard’s configuration object and add a new tablewidget for displaying the risk objects. It involves 4 major steps like

  1. Revise project dashboard

  2. Create a new dataset for listing "Risk" objects

  3. Create a new tablewidget "Risk" on the revised dashboard

  4. Promote the revised dashboard to active state.

15.5.1. Step 1/4: Revise project dashboard

Revise the "Project Dashboard" config using the revise command in Admin UI.

image
Figure 107. Revise the Project Dashboard

Once the revised object is created, launch the revised dashboard using the preview icon, or open it from the 3DD widget preference page by choosing the revised project dashboard object.

image
Figure 108. Choose revised Project Dashboard

On the revised "Project Dashboard", config-admin can add new widgets as per the user requirement.

15.5.2. Step 2/4: Create new dataset "Risk"

To create a "Risk" tablewidget, a new dataset is required to list "Risk" objects. Use the below configuration and create the dataset with name "Risks".

<?xml version="1.0" encoding="UTF-8"?>
<DataSet>
	<Inquiry>
		<Code>temp query bus Risk * * where "owner == context.user" limit 25 select id dump |</Code>
		<Format>${OID}</Format>
		<Pattern>*|*|*|${OID}</Pattern>
	</Inquiry>
</DataSet>

15.5.3. Step 3/4: Create new tablewidget "Risk"

Open the revised project dashboard which is in the draft state from the 3DD widget preference page or using the launch icon and create new widget "Risks" by choosing the already created dataset "Risks"

image
Figure 109. Add Risk Widget on revised Project Dashboard

Config-Admin can choose to re-arrange the widgets as per the need on the "Revised Dashboard". Once the Risk widget is added, "Revised Dashboard" is ready to promote. Please refer the below image for the final view of the Revised Dashboard.

image
Figure 110. Revised Project Dashboard with Risk tablewidget

15.5.4. Step 4/4: Promote Revised dashboard

Promote the revised object from Admin UI.

image
Figure 111. Revised Project Dashboard with Risk tablewidget

Once the revised object is promoted to the active state, the previous revision will be auto promoted to the obsolete state. End-user will be intimated about the revised "Project Dashboard". And the revised dashboard will reflect in the end-user UI automatically without end-user’s intervention.

15.6. Create and Share Widget

Consider a scenario where the end-user has requested for a "Issue" tablewidget to add in his dashboard.

Config-Admin can start with creating new dataset for listing the "Issue" dataset

15.6.1. Step 1: Create dataset

Create a "Issues" dataset with below configuration as shown in image.

<?xml version="1.0" encoding="UTF-8"?>
<DataSet>
	<Inquiry>
		<Code>temp query bus Issue * * where "owner == context.user" limit 25 select id dump |</Code>
		<Format>${OID}</Format>
		<Pattern>*|*|*|${OID}</Pattern>
	</Inquiry>
</DataSet>
image
Figure 112. Create dataset configuration

Validate configuration using Validate option. Refer Validate XML against XSD section.

15.6.2. Step 2: Create Widget

Create new or launch an existing empty dashboard. See Create and Preview dashboard section.

In the opened dashboard, add tablewidget to list "Issue" objects. Refer Create Issue TableWidget section to create a Issue tablewidget and configure new columns to the tablewidget.

15.6.3. Step 3: Promote Widget and Share with end-user

Select the created widget in admin UI and promote to active state, and the share with end-user as shown in image.

image
Figure 113. Promote and share widget

15.7. Configure Form Widget

Config admin can create Form Widget and add to the helium dashboards as like the Table Widget and Chart Widget.

To configure a formwidget, config admin needs two config objects namely Form Config and Widget Config. These configs can be created through the command "Create Config" in Config Admin UI page.

15.7.1. Create Form

As a first step, create the form config object with a form XML configuration as shown in the image.

image
Figure 114. Create Form config with form XML configuration

Sample form XML configuration

<Form>
    <SubmitStrategy>AUTO</SubmitStrategy>
	<Layout>
		<Columns>1</Columns>
	</Layout>
	<Section>
		<Label>Basics And Attribute</Label>
		<Field>
			<Label>Type</Label>
			<Expression>type</Expression>
			<Editable>false</Editable>
		</Field>
		<Field>
			<Label>Name</Label>
			<Expression>name</Expression>
			<Editable>false</Editable>
		</Field>
		<Field>
			<Label>Revision</Label>
			<Expression>revision</Expression>
			<Editable>false</Editable>
		</Field>
		<Field>
			<Label>State</Label>
			<Expression>current</Expression>
			<Editable>false</Editable>
		</Field>
		<Field namespace="hex:engineering" name="EstimatedCost.xml" />
	</Section>
</Form>

15.7.2. Create FormWidget

As a second step, config admin can create widget config by pointing to the form config create at the first step.

image
Figure 115. Create formwidget pointing the created formconfig

Sample FormWidget XML configuration

<FormWidget>
	<Title>${TYPE}:${NAME}:${REVISION}</Title>
	<FormConfig ref="CONFIG:00000000000" />
	<ResolveContextId>page</ResolveContextId>
	<FormMode>view</FormMode>
</FormWidget>

15.7.3. Add FormWidget to helium dashboard

The formwidget can be added to the helium dashboard as like the table widget and then the Helium dashboard can be viewed from 3DD widgets.

image
Figure 116. Add FormWidget to existing dashboard

Once the formwidget is added and the context object is set to 3DD Widget, the complete dashboard with formwidget can be viewed from 3DDashboard.

image
Figure 117. Add FormWidget to existing dashboard

15.7.4. FormWidget in 3DD Widget

Moreover, the formwidget can be directly viewed in 3DD widgets by choosing widget type as helium form in 3DD widget preferences.

image
Figure 118. Configure formwidget in 3DD widget by selecting 'Helium Form'
image
Figure 119. View formwidget in 3DD widget

15.8. Dataset

Datasets are used to retrieve data for the table and chart widgets. In-App-Designer supports all the existing tags and configuration of Dataset.

Depending on how it is designed Dataset query can cause performance issues. For example a query like temp query bus Part * * will likely cause system failure as it tries to query all parts in system, which can be in million for some companies. Therefore, we have by default restricted access to create Dataset to only system or business admin.

This can be disable using the key tvc.enduser.dataset.limitToAdmin in tvc.properties. The valid value is either true or false and the default value is true.

In Inquiry and Query dataset, type as a wildcard i.e * is not allowed, but this can be disabled using the key tvc.enduser.dataset.disallowWildcardInType in tvc.properties. The valid value is either true or false and the default value is true.

15.8.1. Save Search Criteria as Admin/End-user Dataset

NSX search form provides an easy way in UI to define a dataset. This allows end-users to directly use search/search results as datasets.

There are three options to save the search/search result.

  • Save Search

  • Save As Datasource

  • Save As Admin Datasource (only admin can access)

Save As Datasource : User can save the search/search result as dataset and use in create widget form.

Save As Admin Datasource: Admin can save the search/search result as dataset and can be shared with other users.

Also, admin can create admin dataset configs which can be used for designing the widget in draft state.

15.8.2. Create dataset and filter inline create widget screen

This feature is introduced from 2023.1.0 release.

To configure the widgets in a dashboard, it is a prerequisite to have the datasets and filters ready before creating the widgets. From release 2023.1.0, it is not mandatory to have the preconfigured datasets and filters. Instead, config-admin can choose to create the dataset and filters from within the create widget screen as shown in the image.

image
Figure 120. Inline Create Dataset and Filter

Refer the video where the dataset and filter are created and edited from the create widget screen.

Validate Inquiry-based dataset

The config-admin can set up the dataset by using the "Create Config" and "Create Dataset" commands from the admin-UI. We have introduced a "Validate Inquiry" button in the create/edit forms of dataset configs, to verify the query performance used in the dataset.

To measure the performance, Config-admin can set a time limit by which the query is expected to execute. If a query is taking more than the defined time limit, it will be flagged as bad performing query. By default the time limit is set as 2 seconds. It can be modfied by setting a property tvc.core.inappdesigner.validateInquiry.timeLimitInSeconds in tvc.properies file.

This feature enables the config-admin to assess the performance of a widget when it is loaded with the validated dataset. And by optimizing the query, the config-admin can ensure the best possible performance.

Create Dataset screen with Query performance

image
Figure 121. Query performance within defined time limit
image
Figure 122. Query that exceed defined time limit

Edit Dataset screen with Query performance

image
Figure 123. Edit Dataset - Query that exceed defined time limit

15.9. Table Configurator - Add more column link

The table-configurator menu is responsible for selecting or removing columns from the table structure. More columns can be added using property tvc.helium.tableconfigurator.showMoreColumnsLink which can be set as true or false as per requirement. The default value is true thus making the Add more columns link visible inside the table-configurator menu. It is also visible for config-admin when the table is in draft state.

Add more columns link is not visible for default table
image
Figure 124. Add more columns link

15.10. Expression

Admin can create expression by choosing selectexpression as a Configuration Type and any valid expression in Configuration.

Currently table column can be created with direct attributes on table objects like 'Material Category' for Parts, however it may be needed to add coumn to show related object data like state of connected part specification. User can create such expression and that expression can be used to create column to show the related object state.

These expressions can also be used to create charts in create chart wizard.

Expression example:

<Expression>from[Part Specification].to.name</Expression>
image
Figure 125. Expression Create Config
image
Figure 126. Add Select Expression Column

15.10.1. Expression support in advanced column

Now end-users can write an expression in the advanced column. This feature will facilitate end-user to write their expression to display the related object information in a table column. This can be enabled by adding the property tvc.helium.tableconfigurator.writeExpression.enabled = true in TVC.properties file. The default value for this property is false.

This feature needs to be enabled with caution and it is expected that the user knows the concept of Enovia MQL selects to use this feature.
image
Figure 127. Write expression for Column

15.11. Column configuration

Admin and end-user can configure columns dynamically to the configuring tables. These columns value can be displayed if they are configured in their respective tables.

15.11.1. Expression and Attributes as column

The feature of adding relationship attributes as column is introduced from 2023.2.0 release.

In-app designer enables config-admins and end-users to select the business-object and relationship attributes. Additionally config-admin can create expression using the advanced column link in the table configurator.

image
Figure 128. Advanced Columns
image
Figure 129. Relationship Attributes
image
Figure 130. Relationship Attribute as columns

If any relationship attribute is selected, its value can be seen upon expanding the parent business object. We are enabling to add relationship attributes as columns as well. For example user can now add EBOM relationship attributes like - Find Number, Quantity when using a structure table.

15.11.2. Column configuration with inline script

This feature is introduced from 2023.1.0 release.

Introducing in new column type helium-script to write a script in the column’s expression tag. This feature reduces the developer’s effort in writing the java based data handlers for simple data manipulation.

For example, consider a scenario where you want to have a table column named "No. of Child Parts" to display the number of child parts available for assembly and the consolidated EBOM quantity.

In the column’s expression tag, you can add a selectable and javascript logic to perform such data manipulation.

For our example scenario, the column configuration with expression tag can be,

 <Column usesBusinessObject="false">
    <Name> No. of Child Parts </Name>
    <Label> No. of Child Parts </Label>
    <ColumnType>helium-script</ColumnType>
    <Expression><![CDATA[
                <BusSelect varName="childnames" iteratable="true" >from[EBOM].to.name</BusSelect>
                <BusSelect varName="qtys" iteratable="true">from[EBOM].attribute[Quantity]</BusSelect>
                <RelSelect varName="relName">name</RelSelect>
                <Script>
                    var childCnt = 0;
                    while (childnames.hasNext()) {
                    childnames.next();
                    childCnt++;
                    }
                    var totalQty = 0;
                    while(qtys.hasNext()) {
                    var qty = parseInt(qtys.next());
                    totalQty = qty + totalQty ;
                    }
                    write(childCnt+ " ("+relName+") Childs with total Qty "+totalQty);
                </Script>
        ]]></Expression>
    </Column>

15.11.3. Expression tag components

This feature is introduced from 2023.1.0 release.
XML Tags Description
<BusSelect varName="childnames" iteratable="true" >
    from[EBOM].to.name
</BusSelect>

Specifies the businessobject selectables.

  1. "varName" is the mandatory XML attribute and

  2. "iteratable" is optional XML attribute. By default "iteratable" is false. If specified True, then use "hasNext()" and "next()" in-built methods to iterate and traverse through the result.

<RelSelect varName="relName">
    name
</RelName>

Specifies the relationship selectables. The XML attributes are similar to BusSelect tag.

<Script>
    var childCnt = 0;
    while (childnames.hasNext()) {
      childnames.next();
      childCnt++;
    }
    var totalQty = 0;
    while(qtys.hasNext()) {
      var qty = parseInt(qtys.next());
      totalQty = qty + totalQty ;
    }
    write(childCnt+ " Childs with total Qty "+totalQty +" RelName is: "+relName);
</Script>

Under Script tag, javascript logic can be added using the "varName" assigned in BusSelect and RelSelect tag. The in-built method write("cell text") writes the manupulated text to the cell.

15.12. File based Configurations in JSON

Config-admin can configure the file based configurations to list under create widget form using the TVC_InAppConfigurations.json file

If the json file (with name TVC_InAppConfigurations.json) is not configured, a few pre-built file based configurations will be displayed in the create widget form as shown below. To add or remove the file-based configs from the create widget dropdown, config-admin can create and configure them in TVC_InAppConfigurations.json in WEB-INF/classes/.

TVC_InAppConfigurations.json.sample file with the built-in file-based configurations, is available in WEB-INF/classes/ folder. Config-admin can rename the sample JSON file and add more or remove existing file-based configs.
image
Figure 131. Pre-built Configs if TVC_InAppConfigurations.json is not configured

Also Valid For can be defined as mapping for XML-based configs in a TVC_InAppConfigurations.json file. This allows the admin to decide which all XML-based configs can be used as In-App configs and also makes it easier to filter using the valid for at UI level.

Sample configurations: you can find the TVC_InAppConfigurations.json.sample file in WEB-INF\classes

//TVC_InAppConfigurations.json
{
  "datasets": {
    "Part": [
      {
        "label": "com.technia.inapp.dataset.label.ebom",
        "value": "tvc:dataset:hex:engineering/EBOM.xml"
      }
    ],
    "Document": [
      {
        "label": "com.technia.inapp.dataset.label.specifications",
        "value": "tvc:dataset:hex:engineering/Specifications.xml"
      }
    ]
  },
  "templates": [
    {
      "label": "ObjectLink",
      "value": "helium/templates/table/object-link"
    },
    {
      "label": "ObjectLinkWithAltOid",
      "value": "helium/templates/table/object-link-with-alternate-oid"
    }
  ]
}
Config Name Description Example

datasets

The json config which contains datasets specific to a particular valid for type to show in datasource field in create/edit widget form.

{
  "valid-for-Type": [
    {
      "label": "dataset label",
      "value": "dataset"
    }
  ]
}

templates

The list of column templates to show in create/edit form of the advanced column.

refer End User Defined Columns section.

[
  {
    "label": "template label",
    "value": "template"
  }
]

Internationalization Support: In the config file, the label could also be a string resource property key for internationalization.

The concept of Valid For is extended to datasets. Using JSON mapping, the file-based dataset can be listed in the Create Widget form.

image
Figure 132. Dataset Results based on validFor

15.13. Configure toolbar commands

This feature is introduced from 2023.1.0 release.

Config-admin can now add the built-in toolbar commands to the widgets that is being configured. The toolbar menu will appear only in the draft state for the config-admin. Config-admin can choose the command for the configuring widget and share it with the end-users. The end-user can use these commands on the selected BusinessObjects.

15.13.1. Built-in commands for Flat Table:

image
Figure 133. In-built toolbar commands for Flat Table

15.13.2. Built-in commands for Structure Table:

The Structure table will have "ExpandAll" and "CollapseAll" in addition.

image
Figure 134. In-built toolbar commands for Structure Table

These built-in toolbar commands are mapped in TVC_InAppConfigurations.json.

Config-admin can also include new commands to this JSON file and make it available in the configuring widgets.

image
Figure 135. In-built Toolbar commands mapped in JSON

15.14. Choose template to a Column

By applying the template to a column, the user can change the look and feel of a column.

There are some situations where the user likes to see column data more effectively.

  1. Identify all the approved tasks by colour.

  2. Differentiate the priority of an object using the appropriate colour.

  3. On clicking on the column value, Open the connected object.

  4. Show an icon when a part is connected to a specification.

  5. Open the side panel and show object information in a dashboard.

Users can address all these situations by applying templates to a column.

image
Figure 136. Choose Template To Column

A new template field is introduced in advanced column form to choose a template.

image
Figure 137. New Template Field

Template Creation: Admin can create any handlebar template and configure in TVC_InAppConfigurations.json file. Refer InApp Configurations with Valid-For Support section for more details.

{{!--
  Sample Handlebars template that can be applied to columns in a datatable.

  Available variables are:
  - object
  - row
  - cell

--}}
    <a href="javascript:App.routing.open('{{row.objectId}}');">{{cell.value}}</a>

15.15. Preselected Valid-For in Add Widget

For context pages like Part or Product, the widget will show related information. Therefore, it is good to pre-populate valid for with the context object type.

When the user is in the context of any object, the valid For field is preselected with context object type.

It is also possible to change Valid For to any other value.

This helps to eliminates the unrelated configs from the config list.

15.16. Manage Admin Configs

15.16.1. Share/Unshare configs with end-user and teams

Admin user can share created config definitions with end users and teams. To perform this, user can select the configuration from Configurations table and click on the Share command in toolbar. This will open Shared With widget in the sidepanel to allow admin to share/unshare configuration with end users and teams.

image
Figure 138. Configuration List
image
Figure 139. Share with widget
image
Figure 140. Search and share config with end user and team

15.16.2. Revise configs

Admin can revise the shared config objects which are already shared to enduser.

image
Figure 141. revise shared config

Admin can update the configuration changes on the created new revision and promote it to active state. Once the new revision is promoted to active state, the previous revision which is shared to end user will be auto-replace by new active revision. And the previous revision will be auto-promoted to obsolete state.

15.16.3. Delete Draft Configs

Config-Admin can choose to delete the draft configs if it is no more required.

Only the draft configs are allowed to delete.
image
Figure 142. Delete Config

15.16.4. Autopromote Child Configs

When the Dashboard is activated, all its child components like widgets, tables, tablecolumns, and datasets will be auto promoted to an active state.

15.16.5. Preview dashboard Configs

Admin can preview the configured dashboard before sharing with end users. From release 2021.4.0, admin can preview the Draft dashboards also. This is to facilitate admin to make changes on draft dashboard as required before promoting to active and share with end user.

15.17. Validate XML against XSD

Admin can validate XML in both create and edit config forms using validate option.

image
Figure 143. Validate Config

Sample XML to validate:

<DataTable>
    <Title>MyPartsTable</Title>
    <Toolbar>
        <Search/>
        <TableConfigurator/>
        <Menu>
            <Label>Export</Label>
            <FontIcon>icon share</FontIcon>
            <ExportExcel/>
            <ExportPDF/>
        </Menu>
    </Toolbar>
    <TableConfig ref="CONFIG:0000000000000108"/>
</DataTable>

Refer this video for more details:

15.18. Notifications

The Email notification will be sent to the user when an admin share or unshare the configurations and Also, on activation of a new revision of configuration which is already shared.

Email Notification requires the MX_SMTP_HOST is configured and users have valid email address.

Email Notification Handler uses templates configured in string resources.

Following are the default template property keys used for workflow email notifications.

tvc.inappdesigner.email.share.to.user.message =

tvc.inappdesigner.email.share.to.user.subject =

tvc.inappdesigner.email.unshare.to.user.message =

tvc.inappdesigner.email.unshare.to.user.subject =

tvc.inappdesigner.email.revision.active.to.user.message =

tvc.inappdesigner.email.revision.active.to.user.subject =

tvc.inappdesigner.email.share.to.team.message =

Following are the MACROs that can be used as $(MACRO) in the email templates.

TITLE
CONFIG_TYPE
CONTEXT_USER
TO_USER
DATE

Example:

tvc.inappdesigner.email.share.to.user.message = <p>Hello $(TO_USER),</p> \
<p>The Configuration "<strong>$(TITLE)</strong>" of type "$(CONFIG_TYPE)" has been shared with you by "<strong>$(CONTEXT_USER)</strong>" on $(DATE).</p> \
<p>&nbsp;</p> \
<p>Please accept "<strong>$(TITLE)</strong>" to use in your dashboards</p> \
<p>&nbsp;</p> \
<pre><em><sub>This message is system generated and sent by Administrator.</sub></em></pre>

tvc.inappdesigner.email.share.to.user.subject = New Config "$(TITLE)" is Shared

15.19. List Accepted Configs in 3DDASHBOARD Widget Preference

Following image of 3DDashboard widget preference shows that user can view their 'Accepted Shared Config' from Helium. Currently configurations of Helium Dashboard, Helium Chart Widget and Helium Table Widget are listed in preferences of TVC widget.

image
Figure 144. Accepted Shared Data Table widget in preferences

15.20. List Admin Configs in 3DDASHBOARD Widget Preference

Along with viewing Accepted Shared User Definitions, users who have 'TVC Config Admin' role, can view all the Admin Configs in 3DDashboard Widget. To disable this feature, please set tvc.3ddashboard.showAdminEndUserConfigObjects property to false in tvc.properties or web.xml file.

15.21. Export/Import Configurations

This feature is introduced from 2022.4.0 release.

In-App-Designer enables config-admins to create or configure dashboards, widgets, and their related configurations from the Config Admin UI page. Now Config-admin can copy the configurations from one environment to another environment using this export/import configuration feature. Using this feature, configs like dashboards or widgets can be configured and validated in pre-prod environments and then these validate configs can be exported and imported to the production enviromment.

15.21.1. Export Configuration

Config-admin can select the configurations from the admin UI and click the export command. The selected configurations will be downloaded as a ZIP file which can be imported into another environment or can be deployed in the web directories by extracting the needed files from the ZIP file.

image
Figure 145. Export Config Form

15.21.2. Import Configuration

The exported file can be imported into the new environment using the built-in command available in the config admin UI. New set of business-objects will be created based on the imported files. These business-objects will be created in the draft state and config-admin can review and activate.

image
Figure 146. Import Config Form

Moreover, the exported XML files can also be deployed in the web directory and used as the regular file-based configurations. You can extract the needed configurations from the ZIP file and deploy them in the web directory.

Please refer to the video where a dashboard with 4 widgets is exported and imported back.

15.22. Page Config for classic tabs

In this release, enabling config-admin to create/configure helium-page configuration which inturn can be configured in the TVC Classic pages. By this way In-App Designer’s feature can be used in TVC Classic pages also.

By default, helium-page config is disabled to create. Enable it by adding tvc.enduser.page.enableToCreate = true setting in TVC.properies file. By default, this property is set to false

Config admin can design a helium-page by configuring dashboards in it and add to the classic or Enovia command to view from the TVC classic page.

Consider a scenario where you want to view drawing print object’s related parts and the related part’s CO. For such scenerio, config admin can configure the related UI using "In-App Designer". From config-admin page, configure 2 dashboards to display the related parts and the part’s related CO. Then add the created dashboards to the helium-page object in a tabs as shown in the image.

image
Figure 147. Configure helium-page with the created dashboards

Once the helium-page is created, configure a enovia command or TVC command by pointing the helium-page object in the HREF as shown below. And add the command to the drawing print object’s tree menu.

The URL parameters used in the href are casesensitive.
print command DrawingPrintInAppView

command DrawingPrintInAppView
  description config admin configured dashboard view for drawing print type
  label 'Helium View'
  href '${ROOT_DIR}/goto/foo.jsp?embed=true&inAppPage=CONFIG:0000000000002698/Active'
  setting Target Location value content
  nothidden

Once the command DrawingPrintInAppView is configured in menu type_DrawingPrint, the helium-page can be seen as shown in below image

image
Figure 148. helium-page view configured for Drawing Print

15.23. EndUser

In-App-Designer enables the end users to customize how the content/information should displayed in the application.

End users can accept and apply the configurations shared by config-admin, and enables further customizations at user end as well. End-user will be notified about the new configuration shared by config-admin. New configuration can be a dashboard, widget, table, tablecolumns or expressions. All the shared configurations will be listed in the Pending Shared Config tab in Shared-Config-UI as shown in image. End-user have to accept the configuration before using it. In upcoming sections, you will be seeing how the shared configs will be used by end-user.

image
Figure 149. Pending Shared Config UI

15.24. Configure EndUser UI

Using the built-in Shared Config UI page, end-user can

  1. View and manage the self created configurations,

  2. Create a request for a new configuration (like dashboard, Widget, table, etc) and

  3. View and manage the configurations shared by config-admin and the self created configurations.

15.24.1. Configure Shared Config UI in StandAlone Helium Page

In standalone helium page, Shared Config UI can be accessed through the command Shared Configuration. Add this command in Helium.xml file as shown below.

<?xml version="1.0" encoding="UTF-8"?>
<Application xmlns="http://technia.com/helium/Application">
   ...
    <TopBar>
      	...
      <Command>tvc:command:helium:enduser/SharedConfigUI.xml</Command>
   	...
    </TopBar>
<Application/>

In Helium UI, you can see the "Shared Configuration" command in the topbar as shown in the image.

image
Figure 150. Shared config command and Page

15.24.2. Configure Shared Config in 3DDASHBOARD

In 3DDASHBOARD, create App for Shared Config UI from the "Additional Apps" UI as shown in the image.

image
Figure 151. Configure Shared config App

You can also add 3DD widget for Shared Config UI by choosing "SharedConfigUI (tvc:page:helium:enduser/SharedConfigUI.xml)" dashboard in 3DD widget preference page as shown in the image.

image
Figure 152. 3DDASHBOARD widget for Shared Conifg UI

15.25. Accept Shared Configurations

There is shared config widget which will be displayed, when user clicks on the configurable Shared Config command present in helium topbar. There are 3 tabs in this widget to display pending, accepted and rejected configurations. User will see all shared configurations in pending tab. Once it is accepted or rejected that will move to accepted or rejected tab.

All configurations shared with end user’s team are by default in accepted mode.
image
Figure 153. Shared configs with end user and team

15.26. View Accepted Dashboard

The accepted dashboard configurations can be used in 3 ways.

15.26.1. 1. Replace the existing dashboard with the Accepted Dashboard

Consider a scenario, where the default dashboard need to be replaced by the Admin shared dashboard.

  1. Add Shared dashboard command opens the sidepanel with all the accepted dashboards.

  2. End-user can select the Shared Dashboard from sidepanel and click on Apply command to replace the existing dashboard with selected Shared Dashboard.

  3. End-user can use Reset to Default Config command to resume back to the original dashboard it had earlier.

image
Figure 154. Replace Default dashboard with Shared Dashboard

15.26.2. 2. Add Accepted Dashboard in 3DDASHBOARD widgets.

All the accepted dashboard will be listed in 3ddashboard widget preference page. End-user can choose the accepted dashboard and add to the 3DDASHBOARD widget as shown in the images. Refer List Accepted Configs in 3DDASHBOARD widget preference section to enable or disable the accepted configs to list in 3DDASHBOARD widget preference.

image
Figure 155. Choose Shared Dashboard in 3DDashboard widget preference
image
Figure 156. View Shared Dashboard added from 3DD widget preference

15.26.3. 3. On Helium Standalone application, add dashboard to MyDashboard dynamic menu

Accepted shared dashboards can be accessed directly from a dynamic menu known as "My Dashboard". Under "Accepted shared config" tab, add and remove dashboard command are available to manage "My Dashboard" menu. This dynamic menu can be added in topbar as shown below

In Helium.xml,

<?xml version="1.0" encoding="UTF-8"?>
<Application xmlns="http://technia.com/helium/Application">
   ...
    <TopBar>
      	...
      <Menu>tvc:menu:helium:myconfigdashboard/MyConfigDashboards.xml</Menu>
   	...
    </TopBar>
<Application/>

15.27. User Configurations

All user created configs will be listed under User Configurations tab. Delete Config command can be used to delete the unused configs or configs which are no more required.

image
Figure 157. User Configurations

15.28. Create Dashboard By Enduser

Endusers can create dashboard and configure widgets in it. Previously, to set up a new dashboard, the end-user will have to request config-admin to configure and share. From now on, end-users can configure new dashboards themselves and that reduces config-admin dependency.

15.29. Widgets

Create and customize widgets.

15.29.1. Create widgets

A user can add new widgets to a dashboard by using the + sign in the dashboard settings menu. This will open a form at the top in the corresponding dashboard, where you can create your widget/specify things about the widget you want to create, like the name of the widget, what data to be displayed and more.

image
Figure 158. Create widget

User can also open this create widget form at the bottom of the corresponding dashboard by using the key tvc.helium.enduser.createWidget.placeHolder.bottomPosition in tvc.properties. The default value of this is false and valid value is either true or false.

There are two types of widgets one can create, a chart widget or a table widget.

15.29.2. Charts

Create different type of charts. In the "Chart Type" field you can choose how you want the data to be displayed. You can choose from all the different chart types, e.g. Bar, Line, Pie or Donut. In the "Data Source" field you select what set of objects you want to base the chart on. The list is populated by the datasets cached in your application. In the "Chart Expression" field you choose what information you want to be displayed in the chart. You can choose from the basics and attributes of the objects from the dataset selected in the "Data Scource" field.

image
Figure 159. Create chart

For more information about charts in general, it can be found in the Chart chapter.

15.29.3. Tables

Create a basic table.

image
Figure 160. Create table

15.29.4. Edit Widgets

A user can edit their own chart/table widgets by using the edit icon in the widget. This will take the user to the edit form where you can make changes and save your edited widget.

image
Figure 161. Editable end user chart widget

15.29.5. Create Widgets with Accepted Dataset and Tables

All the Dataset and tables that are shared by config-admin will be listed in create Widget section as shown in image.

End user can use the "Valid For" field to filter the datasets and tables based on the selected business type in "Valid For" field.

The "Valid For" field lists only the business type for which the datasets or tables are available.

image
Figure 162. Shared dataset and Tables
Create Widget with existing table

Also end-users can create a table widget by pointing to an existing table. This will allow the end-user to reuse any previously created table. For example, if the end-user has already created a table for Parts, the same table can be used to create a different widget that can list the Released Parts or My InWork Parts, etc. This will only require changing the dataset.

Select existing table:

All the existing tables will be listed here, which includes self-created tables and the tables shared by Config-Admin.

image
Figure 163. Select existing Table

Choose to create new table:

Here End-users can choose to create a new table by selecting the 'create new' checkbox.

image
Figure 164. Create new table by selecting selectbox

15.29.6. Add Accepted Widgets in Dashboard

End-user can extend any dashboard to create a personalized dashboard. In this dashboard, end-user can create a new widget or add existing widget to his dashboard. End-user can also add any shared widget to his dashboard.

All the accepted widgets and existing widgets will be listed in Add Widget section as shown in image.

End user can use the "Valid For" field to filter the Widget Configs based on the selected business type in "Valid For" field.

The "Valid For" field lists only the business type for which the widgets are available in the 'Widget Configs' field.

image
Figure 165. View Shared Widget

15.30. Teams Management widget

Team can be a logical group of people, of same or different department within organization. Admin can share UI configs to teams. This will be useful as admin will not have to share the configuration to individual users. Once a user is added to team, he/she will have access to all the configurations shared with that team. If user is removed from team, he/she will no longer have access to team shared configuration

Once admin user has created a configuration as per the request from end user or team of end users. Admin needs to define a team, and he will use this widget to create and manage a team. For managing teams a new widget called 'Teams' is added to Helium admin page with below functionalities.

  • Create a Team

  • Promote a Team

  • Demote a team

  • Connect with team members to a team

  • Disconnect team members from a team

Please refer the below video for more details on Teams widget functions.