tvc.collaboration.appServerNotificationStrategy = ehcache | http
21 March 2016
© Copyright 2003-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/).
The TVC Workflow feature adds a set of functionality that allows users to collaborate around ENOVIA™ process in various ways. Some of the features are:
Workflows in context of ENOVIA™ objects
Real time notifications on workflow events
Inbox to view received tasks
Approve or reject a task
The following is a list of the requirements for the installation of this TVC. If your system is different, consult Technia before installing. For best performance it is recommended to use the latest version of browsers and application servers.
Requires ENOVIA™ V6R2013 or any later version.
Application Server according to the ENOVIA™ core product requirements that is also in the list of supported platforms for the Atmosphere framework (see disclaimer below).
If you are using multiple application servers, you must read the next chapter.
For the Exalead™ powered features you need to install and setup Exalead
Disclaimer: This feature uses a framework called Atmosphere for sending notifications from the server to the clients. This framework supports a wide range of browser and app servers. We will not be able to add support for browsers and/or app servers that is outside of this frameworks support. Also we might not be able to fix issues that could appear in the usage of this framework. See following pages for a list of this frameworks supported platforms and known issues:
Web browser IE11 in IE9 mode is not supported. |
Many environments are scaled horizontally to support a larger amount of users. When having > 1 application server you need to use a load balancer that can divide the users across these application servers somehow.
The Collaboration component uses the web socket technology for setting up persistent connections between clients and servers and this technology has a completely different analogy than the traditional request/response paradigm used in HTTP/HTTPS communication. This will have some impact on your infrastructure since your load-balancer must be able to deal with web sockets correctly.
Technia cannot support every possible infrastructure combination. We can however share information how we have tested it, on what software’s and our configurations. To enable this feature in your own environment / setup-combination you must consult the documentation of your infrastructure components. |
Since users in fact are connected to different application servers, but still should be able to receive notifications from other users – there is a need for the application servers to be able to speak with each other.
There are currently two different implementations available that solves this, one of the implementation uses HTTP communication between the servers and the second implementation uses the Open Source library named Ehcache. The latter is the default communication strategy.
The choice of strategy is defined with a TVC init-parameter. The name of the parameter and the possible values are shown below:
tvc.collaboration.appServerNotificationStrategy = ehcache | http
The Ehcache™ component allows us to setup caches which are replicated among all the other application servers in the same cluster. This replication is done via the RMI protocol and each application server in the cluster is joining a TCP multicast-group.
The strategy of this implementation will try to automatically setup the network communication, but, there are some init-parameters that you may want to fine-tune for some reason or other.
For example, the port that we bind to is automatically picked by selecting a random free port within a specified range. Most likely, you want to define the port manually and in some cases also the network interface to bind to. If your host has multiple network interfaces you might need to specify the host name also. By default, the host name is resolved via the Java API:
InetAddress.getLocalHost().getHostAddress()
Defining the port and host can be done either with JVM system parameters OR TVC init parameters. The parameter name is the same regardless if you define them as a JVM system parameter or as a TVC init parameter. Below is an example how to define as JVM system parameter.
-Dtvc.collaboration.cache.listener.hostName=172.16.16.100 -Dtvc.collaboration.cache.listener.port=2010
The table below shows the additional TVC init parameters that you may want to change in some cases.
Init Parameter Name | Description | Default Value |
---|---|---|
tvc.collaboration.cache.listener.portRangeStart |
If you have defined a port explicitly as described above, this parameter can be ignored. Defines the lowest port number that we will try to use. |
4001 |
tvc.collaboration.cache.listener.portRangeEnd |
See above. Defines the highest port number that we might use. |
41020 |
tvc.collaboration.cache.listener.socketTimeoutMillis |
The number of milli-seconds client sockets will wait when sending messages to this listener until they give up. |
2000 |
tvc.collaboration.cache.provider.multicastGroupAddress |
The multi-cast address to be used. |
230.0.0.1 |
tvc.collaboration.cache.provider.multicastGroupPort |
The multi-cast port to be used. |
446 |
tvc.collaboration.cache.provider.timeToLive |
You can control how far the multicast packets propagate by this setting. Using the multicast IP protocol, the timeToLive value indicates the scope or range in which a packet may be forwarded. By convention:
|
1 |
tvc.collaboration.exalead.cache.replicateAsynchronously |
whether replications are asynchronous (true) or synchronous (false) |
false |
When selecting the HTTP communication approach, each app-server must be able to connect to the other app server(s) in the cluster via HTTP. The implementation will try to identify the URL of the Application server automatically, but, this might in many cases fail due to the setup of load-balancers / proxies and hence you must inform each application server about their own HTTP address. This is done easiest by providing a JVM system parameter to the application server as shown below:
-Dtvc.collaboration.appServerURL=http://the-appserver-machine:8080/enovia
Technia have during the development of the Collaboration component tested on a setup using an Apache HTTPD server acting as a load-balancer and behind having a couple of app servers running Apache Tomcat. All on a Windows 7 host.
The Apache HTTPD server has lately improved their support for web-socket tunneling, and we were using the version 2.4.10.VC11 (64 bit).
The Apache Tomcat versions were 7.0.56 (64 bit).
Below are the configurations we made. Note that we only provide these as examples and you should and might need to adjust them to your needs.
The modules we explicitly enabled were:
proxy_module
proxy_ajp_module
proxy_balancer_module
proxy_wstunnel_module
lbmethod_byrequests_module
lbmethod_bytraffic_module
slotmem_shm_module
Proxy configuration
<Proxy balancer://ws>
BalancerMember ws://inv3373:8080 route=t8009
BalancerMember ws://inv3373:8081 route=t8010
ProxySet lbmethod=bytraffic
ProxySet stickysession=JSESSIONID
</Proxy>
ProxyPass /enovia/collaboration/communication balancer://ws/enovia/collaboration/communication
<Proxy balancer://ajp>
BalancerMember ajp://inv3373:8009 loadfactor=1 route=t8009
BalancerMember ajp://inv3373:8010 loadfactor=1 route=t8010
ProxySet lbmethod=bytraffic
ProxySet stickysession=JSESSIONID
</Proxy>
ProxyPass /enovia balancer://ajp/enovia
Each Tomcat instance were started up using a dedicated start script. Since they were all running on the same machine, we had to configure the ports per instance.
In that start script we configured a number of CATALINA_OPTS
as shown
below.
set CATALINA_OPTS=-Dtvc.collaboration.appServerURL=http://localhost:8080/enovia
set CATALINA_OPTS=%CATALINA_OPTS% -Dtomcat.server.port=8005
set CATALINA_OPTS=%CATALINA_OPTS% -Dtomcat.http.port=8080
set CATALINA_OPTS=%CATALINA_OPTS% -Dtomcat.redirect.port=8443
set CATALINA_OPTS=%CATALINA_OPTS% -Dtomcat.ajp.port=8009
The Tomcat server.xml file were changed (note for readability, only changed parts included):
<Server port="${tomcat.server.port}"
<Connector port="${tomcat.http.port}" redirectPort="${tomcat.redirect.port}" />
<Connector port="${tomcat.ajp.port}" protocol="AJP/1.3" redirectPort="${tomcat.redirect.port}" />
<Engine name="Catalina" defaultHost="localhost" jvmRoute="t${tomcat.ajp.port}">
If apache is used to proxy the request to the tomcat server, websocket request could be dropped. Websocket communication is required for collaboration myspace to work properly.
Following is the configuration done in one of the httpd.conf used in apache with ENOVIA 2017x to proxy websocket requests.
3DSpace_httpd_fragment.conf
# to be added in <VirtualHost _default_:443> section of httpd-ssl.conf
RequestHeader set X-Forwarded-Proto "https"
RequestHeader set X-Forwarded-Port "444"
# TVC Collaboration Websocket configuration Starts
LoadModule proxy_module modules/mod_proxy.so
LoadModule proxy_wstunnel_module modules/mod_proxy_wstunnel.so
RewriteEngine on
ProxyRequests Off
ProxyPreserveHost on
ProxyPass /3dspace/collaboration/communication ws://localhost:8090/3dspace/collaboration/communication
ProxyPassReverse /3dspace/collaboration/communication ws://localhost:8090/3dspace/collaboration/communication
# TVC Collaboration Websocket configuration Ends
ProxyPass /3dspace http://localhost:8090/3dspace
ProxyPassReverse /3dspace http://localhost:8090/3dspace
In Enovia versions which are higher than 2017x and using location-based httpd configuration, proxy pass entries can be added in 3DSpace_httpd_fragment.conf in following way.
# TVC Collaboration Websocket configuration Starts
<Location /3dspace/collaboration/communication>
ProxyPass ws://localhost:9080/3dspace/collaboration/communication
ProxyPassReverse ws://localhost:9080/3dspace/collaboration/communication
</Location>
# TVC Collaboration Websocket configuration Ends
After installing TVC, you must perform three tasks in order to take this feature in to use.
The first task is needed in order to include some functionality within the "emxNavigator.jsp" page (resides in the common folder in your application directory). The only change needed in this file, is to add a single line of code.
Just after the "body" element tag, add the line below (shown in bold):
<body ...>
<%@include file = "/tvc/collaboration/emxNavigator.jspf" %>
...
The second task is needed in order to include some functionality within the "emxNavigatorDialog.jsp" page (resides in the common folder in your application directory). The only change needed in this file, is to add a single line of code.
Just after the "body" element tag, add the line below (shown in bold):
<body ...>
<%@include file = "/tvc/collaboration/emxNavigator.jspf" %>
...
The third task needed is the registration of the Atmosphere servlet that is used for sending notifications from the server to the client (https://github.com/Atmosphere/atmosphere). The following lines should be added to web.xml
<servlet>
<servlet-name>AtmosphereServlet</servlet-name>
<servlet-class>org.atmosphere.cpr.AtmosphereServlet</servlet-class>
<async-supported>true</async-supported>
<init-param>
<param-name>org.atmosphere.cpr.packages</param-name>
<param-value>com.technia.tvc.collaboration.core.io</param-value>
</init-param>
<init-param>
<param-name>org.atmosphere.annotation.packages</param-name>
<param-value>com.technia.tvc.collaboration.core.io</param-value>
</init-param>
<load-on-startup>5</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>AtmosphereServlet</servlet-name>
<url-pattern>/collaboration/*</url-pattern>
</servlet-mapping>
Collaboration panel are also rendered in stand-alone tvc pages like /launchFromPortal
, /loadCategoryTopPanel
, /loadTopPanel
and /searchBasedTable
based on configuration.
Following is the default configuration.
tvc.core.collaboration.inject.pages=launch-portal|top-panel|category-panel|search-table
If collaboration panel injection is not required on any of the supported pages, that page can be removed in the configuration.
tvc.core.collaboration.inject.pages=top-panel|category-panel
Even on the supported stand-alone pages, Collaboration panel is rendered by default only if the page is top most.(Popup or browser tab)
That behavior could be changed with the following property configuration.
tvc.core.collaboration.inject.top.only=true
This could be used in application where emxNagivator.jsp is not configured with collaboration and tvc pages only used for navigation.
Figure: Collaboration panel for /launchFromPortal
Figure: Collaboration panel for /loadTopPanel
Figure: Collaboration panel for /loadCategoryTopPanel
Figure: Collaboration panel for /searchBasedTable
There are three built-in providers available in Collaboration. They are "config"(default), "enovia" and "exalead". The provider value can also be a class full-name which extends "com.technia.tvc.collaboration.core.model.Provider". The provider can be configured as below.
tvc.collaboration.providerClass=config
The default "config" provider enables possibility to have Discussion and Workflow components run in different mode.
tvc.collaboration.discussion.mode=exalead
tvc.collaboration.workflow.mode=enovia
The other "enovia" or "exalead" provider makes both Discussion and Workflow run in same mode.
In order to use any of the features that requires Exalead you need to install Exalead and set it up for collaboration. To enable Exalead for Collaboration there is a TVC Init parameter that needs to be set.
tvc.collaboration.providerClass=exalead
or
tvc.collaboration.providerClass=config tvc.collaboration.discussion.mode=exalead tvc.collaboration.workflow.mode=exalead
In order for Exalead to know what data to index for Collaboration the following needs to be added to your Exalead index configuration file.
<BOTYPEFIELDS name="TVCCollaborationSet">
<FIELD name="TVC_COLLAB_SET_TYPE" select="type" type="STRING" />
<FIELD name="TVC_COLLAB_SET_ID"
select="program[TVCCollaborationIndex -method getSetId ${OBJECTID}]"
type="STRING" />
<FIELD name="TVC_COLLAB_SET_OWNER" select="owner" type="STRING" />
<FIELD name="TVC_COLLAB_SET_CONTEXT_ID"
select="program[TVCCollaborationIndex -method getSetContextIds ${OBJECTID}]"
type="STRING" />
<FIELD name="TVC_COLLAB_NOTIFICATION_USER_NAME"
select="program[TVCCollaborationIndex -method getSelectDataList ${OBJECTID} 'to[TVC Collaboration Notification].from.owner']"
type="STRING" />
<FIELD name="TVC_COLLAB_NOTIFICATION_USER_TAGS"
select="program[TVCCollaborationIndex -method getNotificationUserTags ${OBJECTID}]"
type="STRING" />
<FIELD name="TVC_COLLAB_NOTIFICATION_CATEGORIES"
select="program[TVCCollaborationIndex -method getNotificationCategories ${OBJECTID}]"
type="STRING" />
<FIELD name="TVC_COLLAB_NOTIFICATION_STATUS"
select="program[TVCCollaborationIndex -method getNotificationStatus ${OBJECTID}]"
type="STRING" />
<FIELD name="TVC_COLLAB_NOTIFICATION_UNREAD_USERS"
select="program[TVCCollaborationIndex -method getNotificationUnreadUsers ${OBJECTID}]"
type="STRING" />
<FIELD name="TVC_COLLAB_FOLLOWUP_USER_NAME"
select="program[TVCCollaborationIndex -method getSelectDataList ${OBJECTID} 'to[TVC Collaboration Followup].from.owner']"
type="STRING" />
<FIELD name="NAME"
select="program[TVCCollaborationIndex -method getSetSortValue ${OBJECTID}]"
type="STRING" fastsort="true" />
</BOTYPEFIELDS>
<BOTYPE name="TVC Collaboration Thread" includes="TVCCollaborationSet,TVCCollaborationThread" />
<BOTYPEFIELDS name="TVCCollaborationThread">
<FIELD name="TVC_COLLAB_THREAD_CLOUDS"
select="program[TVCCollaborationIndex -method getClouds ${OBJECTID}]"
type="STRING" />
<FIELD name="TVC_COLLAB_THREAD_FIRST_MSG_SENT_FROM" select="from[TVC Collaboration First Message].to.owner"
type="STRING" />
<FIELD name="TVC_COLLAB_THREAD_FIRST_MSG_SENT_TO"
select="program[TVCCollaborationIndex -method getSelectDataList ${OBJECTID} 'from[TVC Collaboration First Message].to.from[TVC Collaboration Sent To].to.owner']"
type="STRING" />
<FIELD name="TVC_COLLAB_THREAD_HAS_ATTACHMENT"
select="from[TVC Collaboration First Message].to.format.hasfile"
type="STRING" />
<FIELD name="TVC_COLLAB_THREAD_IMPORTANT"
select="from[TVC Collaboration First Message].to.attribute[TVC Collaboration Important]"
type="STRING" />
<FIELD name="TVC_COLLAB_THREAD_LAST_MSG_SENT_FROM" select="from[TVC Collaboration Last Message].to.owner"
type="STRING" />
<FIELD name="TVC_COLLAB_THREAD_LAST_MSG_SENT_TO"
select="program[TVCCollaborationIndex -method getLastMessageSentTo ${OBJECTID}]"
type="STRING" />
<FIELD name="TVC_COLLAB_THREAD_LAST_MSG_SENT_CC"
select="program[TVCCollaborationIndex -method getLastMessageSentCc ${OBJECTID}]"
type="STRING" />
<FIELD name="TVC_COLLAB_THREAD_PRIVATE" select="attribute[TVC Collaboration Private]"
type="BOOLEAN" />
<FIELD name="TVC_COLLAB_THREAD_SENT_FROM" select="from[TVC Collaboration Thread Message].to.owner"
type="STRING" />
<FIELD name="TVC_COLLAB_THREAD_SENT_TO"
select="program[TVCCollaborationIndex -method getSelectDataList ${OBJECTID} 'from[TVC Collaboration Thread Message].to.from[TVC Collaboration Sent To].to.owner']"
type="STRING" />
<FIELD name="TVC_COLLAB_THREAD_SUBJECT" select="attribute[TVC Collaboration Subject]"
type="STRING" />
<FIELD name="TVC_COLLAB_THREAD_SYSTEM_TAGS"
select="program[TVCCollaborationIndex -method getSystemTags ${OBJECTID}]"
type="STRING" />
<FIELD name="TVC_COLLAB_THREAD_USER_TAGS"
select="program[TVCCollaborationIndex -method getUserTags ${OBJECTID}]"
type="STRING" />
<!-- Example of custom index field for a specific tag
<FIELD name="CUSTOM_TAG_FIELD_OFFICE"
select="program[TVCCollaborationIndex -method getIndexedSystemTag ${OBJECTID} 'office']"
type="STRING" /> -->
</BOTYPEFIELDS>
<BOTYPE name="TVC Collaboration Workflow" includes="TVCCollaborationSet,TVCCollaborationWorkflow" />
<BOTYPEFIELDS name="TVCCollaborationWorkflow">
<FIELD name="TVC_COLLAB_WORKFLOW_TITLE" select="attribute[TVC Collaboration Workflow Title]"
type="STRING" />
<FIELD name="TVC_COLLAB_WORKFLOW_STATUS" select="attribute[TVC Collaboration Workflow Status]"
type="STRING" />
<FIELD name="TVC_COLLAB_WORKFLOW_COMPLETION_DATE"
select="attribute[TVC Collaboration Workflow Completion Date]" type="STRING" />
<FIELD name="TVC_COLLAB_WORKFLOW_DUE"
select="program[TVCCollaborationIndex -method getWorkflowDue ${OBJECTID}]"
type="BOOLEAN" />
<FIELD name="TVC_COLLAB_TASK_ASSIGNED"
select="program[TVCCollaborationIndex -method getTaskAssigned ${OBJECTID}]"
type="STRING" />
<FIELD name="TVC_COLLAB_TASK_STATUS"
select="program[TVCCollaborationIndex -method getSelectDataList ${OBJECTID} 'from[TVC Collaboration Item].to[*|revision==last].attribute[TVC Collaboration Task Status]']"
type="STRING" />
</BOTYPEFIELDS>
Sorting in Exalead is only possible to do on the field called "NAME". In case you have other information you need to index and sort on you will probably already have a name field in your config.xml. This means that objects indexed by TVC Collaboration needs to coexist with other objects on what data to index in the name field.
The way forward is to make a JPO in which you determine if the object belongs to TVC Collaboration or not. In case it is a TVC Collaboration object the value to index is determined by Collaboration otherwise it is delegated to the Exalead standard indexing mechanism.
Example code snippet handling the name field:
private static final Collection<String> TVC_COLLABORATION_TYPES = Arrays.asList("TVC Collaboration Thread", "TVC Collaboration Workflow");
if (TVC_COLLABORATION_TYPES.contains(type)) {
IndexProgram.getMessageSortValueJPO(ctx, args);
// Or if you have access to the object id directly
//IndexProgram.getMessageSortValue(objectId);
} else {
// Logical handling all other type of objects
}
To optimize the indexing performance when there is no other BOTTYPE configutation other than Collaboration specific configuration, use the below:
<INDEXER>
<LINKTARGET active="false" size="100000"/>
<!--
.. other configurations
-->
</INDEXER>
Below properties can be configured to alter default behaviour.
Property | Description | Default Value |
---|---|---|
tvc.collaboration.exalead.index.partial |
thread is pushed to partial indexing |
true |
tvc.collaboration.exalead.thread.modified |
thread modified date is updated |
true |
tvc.collaboration.search.pagesize |
Result count returned by exalead. This property will be used in case page size is not defined in Workflow find API execution |
100 |
All data generated by the TVC Collaboration Workflow is stored as Business Objects in the ENOVIA database.
All objects created by the TVC Collaboration Workflow component are saved in a separate vault called "TVC Collaboration"
Attribute holding the Completion Date of workflow
Attribute holding workflow title
Attribute holding the jsonconfig for workflow
Attribute holding workflow status
Attribute holding the last modification Date of workflow
Attribute holding access assignee
Attribute holding id of workflow
Attribute holding status of task.
Attribute holding task title
Attribute holding workflow field value
Attribute holding last read workflow id
Attribute holding notification status
Attribute holding recipient organization name
Attribute holding recipient type
Attribute holding sender organization name
Attribute holding number of unread count.
Attribute holding user server url
Attribute holding the delegator of the task
Attribute holding Activation Date of the task
Relationship used to connect an Enovia Object to its Proxy Object.
Relationship used to connect a TVC Collaboration Person to its TVC Collaboration Person Proxy Object.
Relationship used to connect TVC Collaboration Person to TVC Collaboration Workflow.
Relationship used to connect TVC Collaboration Person to TVC Collaboration Workflow.
Relationship used to connect TVC Collaboration Person to TVC Collaboration Workflow.
Relationship used to connect TVC Collaboration Object Proxy to TVC Collaboration Workflow.
Relationship used to connect TVC Collaboration Workflow to TVC Collaboration Task.
Relationship used to connect TVC Collaboration Object Proxy to TVC Collaboration Item.
Relationship used to connect TVC Collaboration Task to TVC Collaboration Task.
The workflow functionality allows you to create custom workflow process around any type of object in ENOVIA™. The workflow functionality is located in a side panel on the right side of the page content. This allows the users to create workflows around an object while still being able to navigate around the different pages of an object.
The panel that contains the workflow functionality is located in the right side of the application. It is injected on the side of the page content so it will stay visible even when navigating around the different pages of an object. The panel is collapsed by default and will be expanded on click.
After clicking on the panel it will be expanded towards the left side and show the workflows for the object that you are currently in context of.
If you have not enabled the workflow functionality for some object types by configuration the panel will be greyed out and the user will not be able to expand it.
If there is single set in the set list and user want to load the details of set on load of panel or on switching the panel tab then following system property need to be set as true (default:false).
Property | Description | Default Value |
---|---|---|
tvc.collaboration.panel.showSingleSet |
to load the details of set if there is only one in the list |
false |
In Single set load, set id priority will be in following order:
Passed setId in panel load option
Set Id If there is single set in the set list and property is true.
Cached working set Id in session storage
When the user is standing in context of an object that has support enabled for workflows it will be possible to expand the discussion panel in order to view and/or create workflows. The default view of the panel will show a toolbar in the top and below that a list of all the workflows that has been started around the context object.
Each workflow in the list is clickable. The entire workflow will be loaded when a user clicks on it. See next chapter for more details on that.
When a workflow in the list has been clicked it will load the entire workflow in the panel. In this view the user will be able to see all the tasks in the workflow and also have the ability to assign or reassign or approve or complete or reject task. If the task’s context is the current contextual object then it is highlighted with a blue shadow in the workflow graph.
Task Status |
Colour Code |
Colour |
Active |
#3498db |
Blue |
Approved |
#27ae60 |
Green |
Reassigned |
#9b59b6 |
Deep Purple |
Complete |
#27ae60 |
Green |
Pending |
#7f8c8d |
Grey |
Due |
#facc2e |
Yellow |
Rejected |
#e74c3c |
Cinnabar |
Unassigned |
#de8eff |
Light Purple |
Active and Unassigned |
#3498db |
Blue |
Active and Due |
#facc2e |
Yellow |
To navigate to the task details through the workflow graph, the user can click on a task node in the workflow graph. The respective task thread will be highlighted in a popup as shown below.
In order to create a new workflow you use the action in the top toolbar (plus sign). That will launch a form that allows you enter the data needed to create a new workflow. When there are multiple configurations matching for the context object, chooser will be shown to choose a configuration.
The following data can be entered based on configuration:
Assignee for Tasks (Person or Role or Group or Custom Assignee)
Field values for Tasks if configured (e.g. Instructions)
An active workflow can be stopped using "Stop Flow" workflow operation by the workflow owner. When a workflow is stopped all the ongoing task operations are disabled.
An adhoc task can be added in active workflow by using "Add Task" workflow operation by the workflow owner. When add task operation is executed, it is displaying the + icon on appropriate nodes and branches in workflow graph where task can be added. Through node’s add task operation, parallel tasks are created while thorugh branch serial tasks are created.
With the default behavior, complete, approved, excluded
task statuses are considered to activate the next level tasks and the task could not be added for previous level tasks. With the extensive and configurable behavior of workflow, another task status could also be used for task completion and move to the next level of tasks such as rejected. In such a scenario, the complete-statuses
configuration could be used to define the list of completed statuses to block the add task icon for tasks.
"workflow":{
.....
"operations":[
{
"operation": "add",
"config": {
"complete-statuses": ["Complete", "Approved", "Rejected"]
}
}
],
.....
}
On clicking the + icon, Add Task form is opened with the task configurations which are having adhoc property as true(default). Any configuration can be choosen to create the adhoc task.
A task which is not active or completed, can be deleted by using "Delete Task" workflow operation by the workflow owner. When delete task operation is executed, "-" icon is displayed on appropriate task nodes to delete the task.
On clicking the - icon, Delete Task form is opened with warning (if warning field is configured for task). On clicking delete, task is deleted and workflow is updated accordingly.
Configurations:
"workflow":{
.....
"operations":[
"delete"
],
.....
}
With the default behavior, active tasks are not allowed to delete by this operation.For allowing to Delete Active Tasks, the allow-active
configuration needs to add under the config section as below.
"workflow":{
.....
"operations":[
{
"operation": "delete",
"config": {
"allow-active": "true"
}
}
],
.....
}
A stopped workflow can be restarted using "Restart Flow" workflow operation by the workflow owner.
Active or stopped workflow can be terminated using "Terminate Flow" workflow operation by the workflow owner. When a workflow is terminated all the ongoing task operations are disabled. Terminated workflow can not be restarted.
By default confirmation message will be shown, but it can be disabled by using the below config in operation.
"config":{
"confirmation":false,
"confirmation-message": "tvc.collaboration.workflow.terminate.confirm.message"
}
It is also possible to customize the confirmation message by defining a custom operation that extends to com.technia.tvc.collaboration.workflow.cfg.operation.impl.builtin.TerminateOperation
.
Alternatively, the default confirmation message can be modified by changing the below property in tvc.properties.
tvc.collaboration.workflow.terminate.confirm.message
A user having access to this operation can reassign all the tasks or set of tasks using ReassignTasks operation located at the top of the workflow.
Note: Default access is only to Workflow Owner.
Configuration
e.g. Case 1 : Reassign all the non-completed tasks using in-built operation.
"workflow":{
.....
.....
"operations":[
"reassigntasks",
"add",
"delete",
"stop",
"restart",
"terminate"
],
.....
.....
}
Case 2 : Reassign specific tasks using custom operation.
"workflow":{
.....
.....
"operations":[
{
"base": null,
"id": "operation-reassigntasks",
"operation": "reassigntasks",
"label": "ReassignTasks",
"config": {
"task-list": [
"createspecification",
"designreview"
]
},
},
"add",
"delete",
"stop",
"restart",
"terminate"
],
.....
.....
}
The task owner or one of the assignees can reassign the task to another user using the Reassign command located at the bottom of the task. The Reassign form will have an assignee field and optional custom fields if configured (e.g. comments)
A task owner can approve the task when that task is active using Approve command located at the bottom of the task. The Approve form can have optional custom fields if configured (e.g. comments)
A task assignee can assign the task to him/her-self using Assign command located at the bottom of the task.
A user having access to this operation can set due date using Set Due Date command located at the bottom of the task.
User may also clear due date by setting it to blank via this operation.
Note: Default Access is only to Workflow Owner.
Configuration
e.g. Case 1 : Using inbuilt Operation and inbuilt field
{
...
"tasks": [
{
"id": "tpmApproval",
"label": "TPM Approval",
"multiple": true,
"fields": ["comments", "instructions", "warning", "dueDate"],
"operations": [
"complete",
"reject",
"approve",
"operation-Approve",
"assign",
"reassign",
"setduedate"
]
}
]
...
}
Case 2: Using Custom Operation and Custom Field
{
...
"fields": [
{
"id": "Custom_due_date_field",
"label": "Custom:DueDate_Handler",
"type": "date",
"handler": "com.technia.tvc.collaboration.discussion.model.dao.enovia.example.fieldvaluehandler.DueDateFieldValueHandler",
"appearance": {
"create": "hidden",
"reject": "hidden",
"thread": "hidden",
"reassign": "hidden",
"approve": "hidden",
"complete": "hidden",
"due": "editable"
}
}
],
"operations": [
{
"base": null,
"id": "operation-setduedate",
"where": "(attribute[TVC Collaboration Task Title].value != 'TPM Date Approval')",
"operation": "setduedate",
"label": "Custom:SetDueDate2_Where"
}
],
"tasks": [
{
"id": "tpmApproval",
"label": "TPM Approval",
"fields": [
"Custom_due_date_field"
],
"operations": [
"operation-setduedate"
]
}
]
...
}
Note: To Prepopulate value of due date in custom due date field, DueDateFieldValueHandler is necessary.
A task owner can reject the task when that task is active using Reject command located at the bottom of the task. The Reject form can have optional custom fields if configured (e.g. comments).
User can configure rejectTo field which will show the list of completed tasks. User can select the specific task to be revised and activated after the reject operation.
Users can updated their Absence dates and Delegatee to be assigned for any future active Workflow tasks during that period can be configured in Myspace’s Profile Action page.
On selection of absent person for To, CC or assignee field, it will be reflected in red and tooltip will provide the absence related information.
Property |
Description |
Default |
tvc.collaboration.person.showAbsenceMessage |
To show the absent person selection in red and tooltip for absence details |
true |
tvc.collaboration.person.profile.startDateInputTime |
to add the start day input time on selected date |
00:00:00 |
tvc.collaboration.person.profile.endDateInputTime |
to add the end day input time on selected date |
23:59:59 |
tvc.collaboration.person.delegation.cache |
to use java object cache to fetch the person delegation information |
true |
In Absence and Delegation, only when the tasks are about to be activated the delegatee is assigned to the task.
The Delegator name will be shown for the delegated tasks in task list view.
The ability to have workflow around objects can be configured on the server.
This is done in a file called TVCWorkflowConfig.xml
that is placed in
/WEB-INF/classes/TVCWorkflowConfig.xml
. If you skip to have this
configuration file the users will not be able to have workflow around ANY object
in ENOVIA™ with default settings.
Below is an example configuration file that shows the supported elements and their location.
<WorkflowConfigs>
<TabOrder>1</TabOrder>
<ConfiguredTypes>
<Type derived="false" status="disabled">type_MechanicalPart</Type>
<Type derived="false" status="disabled">type_SoftwarePart</Type>
<Type derived="false" status="expand" if="$<context.user.isassigned[role_Designer]>">type_HardwarePart</Type>
<Type derived="false" status="disabled">type_HardwarePart</Type>
<Type derived="false" status="enabled" className="com.technia.tvc.collaboration.workflow.model.dao.enovia.config.builtin.WorkflowConfigType">type_NutPart</Type>
</ConfiguredTypes>
<WorkflowConfig for="type_Part" if="current=='Review' singleActive="true" ">
<JsonConfig
ref="tvc:workflowconfig:tvx:collaboration/PartReview.json" />
</WorkflowConfig>
<WorkflowConfig for="type_CAD Model" if="current=='Review' or current=='Approved'">
<ContextInfoResolver>
<Macro>${TYPE}, ${NAME} : ${REVISION}</Macro>
<URL>/common/emxNavigator.jsp?workflow-sk=document&objectId=${OBJECTID}</URL>
<FileInfoResolver className="com.technia.tvc.collaboration.core.test.TestFileInfoResolver">
<Settings>
<Setting name="Always Show File Name">false</Setting>
<Setting name="Show Subscription">false</Setting>
<Setting name="Show Checkin">false</Setting>
<Setting name="Filename Length">25</Setting>
</Settings>
</FileInfoResolver>
</ContextInfoResolver>
<JsonConfig ref="tvc:workflowconfig:slb:collaboration/ECR_PR_SUBMIT.json" />
</WorkflowConfig>
<ObjectIdResolver/>
<OrganizationResolver/>
<ContextInfoResolver/>
<WorkflowConfigProvider className="com.technia.tvc.collaboration.workflow.cfg.provider.impl.RouteWorkflowConfigProvider"/>
<WorkflowConfigSorter className="com.technia.tvc.collaboration.workflow.test.ReverseWorkflowConfigSorter" />
<WorkflowEngine className="com.technia.tvc.collaboration.workflow.DefaultWorkflowEngine" />
</WorkflowConfigs>
This element defines the component position in sidepanel and myspace. The text value should be integer and Components are arranged in ascending order.
To open the collaboration panel for a context object with previously active component tab or set, browser storage is used.
This behavior could be controlled by using different type of storage which is handled by following property.
Property Key | values | Description |
---|---|---|
tvc.collaboration.panel.storage.preference |
memory(default) |
persist only for panel instance |
local |
persist until the user manually clears the browser cache or until your web app clears the data |
|
session |
persist until the window or tab is closed. |
The <ConfiguredTypes>
tag allows configuration of component’s visibility for different types in the system.
The child elements for this are <Type>
This element allows you to control the collaboration behavior for a specific type. Following are the supported attributes for Type element.
Attribute | Description | Default Value |
---|---|---|
status |
enabled, disabled, hidden, expand (enabled and automatically opened side panel) or none |
none |
derived |
whether status applicable to derived types |
true |
if |
whether configuration is applicable |
|
className |
class extending com.technia.tvc.collaboration.core.model.dao.enovia.config.panel.DefaultConfigType for custom logic |
Following system property can be used to persist the panel status of a context object type for a user.
Proeprty | Description | Default Value |
---|---|---|
tvc.collaboration.panel.status.persist |
Persist the status through the data object of a person |
false |
Default panel status for non-configured type is "disabled".
Following property can be used to change the behaviour.
Property | Description | Default Value |
---|---|---|
tvc.collaboration.workflow.panel.status |
hidden |
disabled |
The <WorkflowConfig> element is used if you want to configure the workflow behavior for a type of object. You can have any amount of this element in your configuration.
Following are the supported attributes for WorkflowConfig element.
Attribute | Description | Default Value |
---|---|---|
singleActive |
true, false (workflow creation is not allowed if there is an active workflow existed) |
false |
Inactive unassiged tasks are enabled in task list panel and graph to change the assignee by owner or any privileged user. Following property can be used to disable the inactive unassiged tasks.
Property | Ranges | Default Value |
---|---|---|
tvc.workflow.disable.unassigned.task |
true/false |
false |
Excluded tasks are disabled in task list panel and graph Following property can be used to enable excluded tasks.
Property | Ranges | Default Value |
---|---|---|
tvc.workflow.enable.excluded.task |
true/false |
false |
The <JsonConfig> element allows you to point out a json file that will have the configuration for workflow tasks. The complete path of the file to use is added to the attribute called "ref". That file path follows TVC path pattern.
This element is applicable to a single CollaborationConfig (i.e DiscussionConfig or WorkflowConfig) and also to all CollaborationConfigs. This element can be used to configure custom settings for the context information related to an object (used to display a link to the context object for a discussion/workflow).
The child element <Macro>
is used to configure the "display name" and
the <URL>
element is used to configure the URL to the context object.
The child element <FileInfoResolver>
is used to configure the File Actions displayed in the inbox if the context object holds files.
If TVC Office component is available, the actions behave similar to column type "actions".
Default implementation resolves display name from <Macro> ${type},
${name} : ${revision}</Macro>
and context URL from <URL>
/common/emxNavigator.jsp?objectId=${OBJECTID}</URL>
.
The complete name of the class to use is added to the attribute called
"className". That class has to implement the interface
com.technia.tvc.collaboration.core.model.context.ContextInfoResolver
.
Following properties can be used to configure the behavior of context path.
Property | Description | Default Value |
---|---|---|
tvc.collaboration.contextpath.popup |
Whether context path should be opened popup |
false |
tvc.collaboration.contextpath.popup.width |
Width of context path popup window in pixel |
900 |
tvc.collaboration.contextpath.popup.height |
Height of context path popup window in pixel |
700 |
tvc.collaboration.helium.route |
Whether to use helium route when running in Helium |
true |
This element is required only when custom parameters instead of objectId passed to load discussions. Allows you to point out a class that will have the logic for returning objectId from the parameters.
Default implementation resolves objectId based on type, name, revision
and vault values separated by &
. (type=Part&name=10001&revision=1&vault=Production)
.
The complete name of the class to use is added to the attribute called
"className". That class has to implement the interface
com.technia.tvc.collaboration.core.model.dao.enovia.config.ObjectIdResolver
.
This element allows to return the Organization of the user, which can be used to show along with user name is Collaboration component. When there are multiple Organizations returned for the user, multiple entries will be shown in the autocomplete for the given user each for each organization.
Default implementation resolves Organizations based on Member relationship to Organization by "Organization Name" attribute value.
The complete name of the class to use is added to the attribute called
"className". That class has to implement the interface
com.technia.tvc.collaboration.core.model.dao.enovia.config.OrganizationResolver
.
This element also supports an attribute called "select" which can be selectable to get Organization value.
<OrganizationResolver select="attribute[Organization Name]"/>.
From/Sender user organization is resolved using the implementation of OrganizationResolver’s getSenderOrganizations.
This property has to be enabled for Organization
tvc.collaboration.showOrganization=true.
Following properties can be used to tune autocomplete field.
Property | Description | Default Value |
---|---|---|
tvc.collaboration.showOrganization |
To enable Organizations inside collaboration component |
false |
tvc.collaboration.autocomplete.startWith |
Whether search criteria should match starting instead of contains |
false |
tvc.collaboration.autocomplete.minLength |
No. of characters after autocomplete initiated |
2 |
tvc.collaboration.autocomplete.loadThrottle |
No. of milliseconds after autocomplete initiated |
400 |
tvc.collaboration.autocomplete.caseSensitive |
Whether search criteria should be case sensitive |
false |
tvc.collaboration.autocomplete.clear.client.cache |
Whether to clear existing cached search result |
false |
tvc.collaboration.autocomplete.loadOnFocus |
To preload and open the assignee list on focus |
false |
public class TestOrganizationResolver extends DefaultOrganizationResolver {
@Override
public List<Organization> getOrganizations(String user) throws TVCException {
return super.getOrganizations(user);
}
@Override
public List<Organization> getSenderOrganizations(OrganizationContext context) throws TVCException {
//context contains Message, previously resolved Organizations, contextIds and Env
return super.getSenderOrganizations(context);
}
}
This element is applicable to a single CollaborationConfig (i.e DiscussionConfig or WorkflowConfig) and also to all CollaborationConfigs.
This element is used to get the user Suggestions for auto complete field along with the recently selected users.
The attribute select
is used to configure expression which will be executed for context ids to get the person suggestions.
<PersonSuggestionsResolver className="tvc.collaboration.person.suggestions.TestPersonSuggestionsResolver" select="context.user"/>
The complete name of the class to use is added to the attribute called
"className". That class has to implement the interface
com.technia.tvc.collaboration.core.model.person.suggestions.PersonSuggestionsResolver
.
This property can be used for disabling the saving and displaying the suggestions. It is true by default.
tvc.collaboration.autocomplete.suggestions.enabled=true.
Following properties can be used to tune suggestions for autocomplete field.
Property | Description | Default Value |
---|---|---|
tvc.collaboration.autocomplete.suggestions.count |
Max number of suggestions to be displayed |
5 |
tvc.collaboration.autocomplete.search.fields |
search criteria should based on the field of the search result. value is comma separated field list such as "label,value" |
label |
public class TestPersonSuggestionsResolver extends DefaultPersonSuggestionsResolver {
@Override
public List<Organization> getSuggestions(PersonSuggestionsData data){
return super.getOrganizations(data);
}
}
TVCWorkflowConfig.xml
<WorkflowConfigs>
...
<WorkflowConfig for="type_Part">
<PersonSuggestionsResolver select="owner"/>
</WorkflowConfig>
<PersonSuggestionsResolver className="tvc.collaboration.person.suggestions.TestPersonSuggestionsResolver" select="context.user"/>
...
</WorkflowConfigs>
This element is applicable to a single CollaborationConfig (i.e DiscussionConfig or WorkflowConfig) and also to all CollaborationConfigs. This element can be used to configure custom settings for the context information related to an object (used to display a link to the context object for a discussion/workflow).
The child element <Macro>
is used to configure the "display name" and
the <URL>
element is used to configure the URL to the context object.
The child element <FileInfoResolver>
is used to configure the File Actions displayed in the inbox if the context object holds files.
If TVC Office component is available, the actions behave similar to column type "actions".
Default implementation resolves display name from <Macro> ${type},
${name} : ${revision}</Macro>
and context URL from <URL>
/common/emxNavigator.jsp?objectId=${OBJECTID}</URL>
.
The complete name of the class to use is added to the attribute called
"className". That class has to implement the interface
com.technia.tvc.collaboration.core.model.context.ContextInfoResolver
.
Following properties can be used to configure the behavior of context path.
Property | Description | Default Value |
---|---|---|
tvc.collaboration.contextpath.popup |
Whether context path should be opened popup |
false |
tvc.collaboration.contextpath.popup.width |
Width of context path popup window in pixel |
900 |
tvc.collaboration.contextpath.popup.height |
Height of context path popup window in pixel |
700 |
tvc.collaboration.helium.route |
Whether to use helium route when running in Helium |
true |
This element allows configuration of custom sort program for WorkflowConfigs.
The complete name of the class to use is added to the attribute called
"className". That class has to implement the interface
com.technia.tvc.collaboration.workflow.model.dao.enovia.config.WorkflowConfigSorter
.
More details at WorkflowConfigProvider.
The <WorkflowEngine>
element allows posibility to provide custom workflow engine to be used in the application.
The full name of the class which implements the interface "com.technia.tvc.collaboration.workflow.WorkflowEngine" is configured in attribute "className". Default implementation is available in "com.technia.tvc.collaboration.workflow.DefaultWorkflowEngine".
e.g.
public class CustomWorkflowEngine extends DefaultWorkflowEngine implements WorkflowEngine {
@Override
public EngineResult start(WorkflowContext wctx) throws TVCException {
EngineResult result = super.start(wctx);
// custom processing
return result;
}
....
}
At some events that occur in the workflow functionality there are "notifications" sent out to users that are involved in a workflow/task in one or more ways. If someone starts a workflow/task around an object then the owner/assignees of that active task will get a notification. Users will also get notifications when another user rejected a task that user approved.
There are some system properties which could control the notification behavior. Please find the details as below:
Property | Description | Default Value |
---|---|---|
tvc.collaboration.workflow.watcher.includeOwner |
By default, the workflow owner is added to the watcher list so that workflow could be observed by the owner through notification. Set false for excluding the workflow owner from the watcher list. |
true |
tvc.collaboration.workflow.notification.sender |
User name of a person to set the default “from” address for notification to be sent from a system user |
EMPTY/NULL |
tvc.collaboration.workflow.task.assignees.notify |
By default, all the task assignees are notified of the task operation along with the task owner. Set false for excluding the assignees to be notified |
true |
These notifications are sent to the user instantly when an event is occurring. We have two ways of notifying the users, one called "Inline notifications" and one called "Web notifications". These work in the same way but are displayed in different ways.
Inline notifications are rendered in the top right corner of the browser window when an event occurs.
Inline notification
Web notifications are displayed on the computer desktop, outside of the browser window. The benefit of this is that you will notice it even if your browser window is minimized. This is currently not supported in Internet Explorer and really old versions of the other browsers. Clicking the notification will show the browser window and open My Space.
Web notification
Notification Handler can be used to enable other type of notifications like Email, Log or custom implementations. Default is Web notification which is used to send real-time notification to browsers.
Notification Handler is supported in both Collaboration Configs. (DiscussionConfigs or WorkflowConfigs).
It can be built-in handlers like <Web/>, <Email> or <Log/> or class implementing interface "com.technia.tvc.collaboration.core.model.dao.enovia.config.NotificationHandler"
NotificationHandler contains isValidNotification method which needs to be overridden to avoid the notification for a specific condition.
|
<WorkflowConfigs> or <DiscussionConfigs>
...
<Notification>
<Web />
<Email />
<Log />
<Handler className="com.technia.tvc.collaboration.core.model.dao.enovia.config.notification.LogNotificationHandler" />
</Notification>
</WorkflowConfigs> or </DiscussionConfigs>
When Email Notification Handler is enabled, notifications will also be sent out to the recipients and watchers via Emails. The email notifications will not be sent to the context person and it can be controlled by the following property.
Property | Description | Default Value |
---|---|---|
tvc.collaboration.notification.email.to.context_user |
Set |
false |
Users can enable and disable the Email notification through the profile in Myspace. See Myspace Profile Section for details.
On enabling/disabling the Email Notification, it sets the preference_NotificationEmail property on the person admin object.
|
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.collaboration.workflow.email.template =
tvc.collaboration.workflow.active.email.template =
tvc.collaboration.workflow.pending.email.template =
tvc.collaboration.workflow.complete.email.template =
tvc.collaboration.workflow.stopped.email.template =
tvc.collaboration.workflow.terminated.email.template =
tvc.collaboration.task.active.email.template =
tvc.collaboration.task.pending.email.template =
tvc.collaboration.task.rejected.email.template =
tvc.collaboration.task.approved.email.template =
tvc.collaboration.task.active-and-unassigned.email.template =
Following are the MACROs that can be used as $(MACRO)
in the email templates.
CONTEXT_USER
CONTEXT_EMAIL
FROM_USER
FROM_EMAIL
TO_USER
TO_EMAIL
DATE
MESSAGE
CONTEXT_INFO
WORKFLOW_TITLE
WORKFLOW_OWNER
WORKFLOW_STATUS
WORKFLOW_TASKS_COUNT
WORKFLOW_CREATED_DATE
WORKFLOW_MODIFIED_DATE
WORKFLOW_COMPLETED_DATE
WORKFLOW_TERMINATED_DATE
WORKFLOW_STOPPED_DATE
WORKFLOW_COMPLETION_DATE
TASK_LABEL
TASK_FIELDS
TASK_OWNER
TASK_STATUS
TASK_DUE_DATE
TASK_APPROVED_DATE
TASK_REJECTED_DATE
TASK_COMPLETED_DATE
TASK_COMPLETION_DATE
TASK_CREATED_DATE
TASK_MODIFIED_DATE
TASK_DELEGATOR
Example:
tvc.collaboration.task.approved.email.template = <p>Hello $(TO_USER),</p> \
<p>The task "<strong>$(TASK_LABEL)</strong>" in workflow "<em>$(WORKFLOW_TITLE)</em>" is "<span style="color: #008000;"><strong>$(TASK_STATUS)</strong></span>" by "<strong>$(FROM_USER)</strong>" on <em>$(TASK_APPROVED_DATE)</em>.</p> \
<p> </p> \
<p>Workflow is currently "<strong>$(WORKFLOW_STATUS)</strong>" at $(CONTEXT_INFO)</p> \
<p> </p> \
<p><span style="text-decoration: underline;"><strong>Task Fields</strong></span>:</p> \
$(TASK_FIELDS) \
<p> </p> \
<pre><em><sub>This message is system generated and sent by TVC Workflow.</sub></em></pre>
Email can be configured based on the task and workflow status.
To send the email for the specific task/workflow status, the following configuration could be used.
<WorkflowConfigs>
...
<Notification>
<Email>
<WorkflowStatus>Complete</WorkflowStatus>
<TaskStatus>Active, Approved</TaskStatus>
</Email>
</Notification>
</WorkflowConfigs>
In the absence of any one of the TaskStatus and WorkflowStatus tag, an email will be sent to all status as the default behavior.
|
When clicking on the icon in the global toolbar it will open something called "My Space" as a big overlay in the browser window. "My Space" contains a set of different functionality related to the user and the TVC Collaboration feature. Inbox and Profile are the default preconfigured "My Space" Actions. The functionality that is displayed on first load is called "Inbox" and is described in the next chapter. First load "My Space" Action can be rearranged TVCWorkflowConfig.xml.
The inbox is a functionality used for displaying all notifications that a user has received. It has a layout that is similar to a mail application.
Figure: Inbox displaying notifications
When MySpaceConfig is modified to include other "My Space" Actions. It is mandatory to include default Actions as well. Actions can be reordered. All Inbox derived actions can be repeated with different configuration but with unique action id. Actions can also be grouped under different labels.
<MySpaceConfig>
<!-- short form -->
<!-- <WorkflowAction/> -->
<!-- custom inbox with custom id -->
<!-- <WorkflowAction id="some-unique-action-id"/> -->
<InboxAction></InboxAction>
<InboxAction>
<Font>fa-inbox</Font>
<Label>Inbox</Label>
<Label locale="de">Posteingang</Label>
<Label locale="sv">inkorg</Label>
<Header>Inbox</Header>
<Header locale="de">Posteingang</Header>
<Header locale="sv">inkorg</Header>
</InboxAction>
</MySpaceConfig>
"DeletedAction" is a predefined custom Inbox Actions that can used in "My Space". This action shows the inbox items which are deleted using delete context command by the context user.
"UnreadAction" is a predefined custom Inbox Actions that can be used in "My Space". The Performance of this inbox action would be better with the Exalead mode. This action shows the inbox items which are not read by the context user.
The profile page has functionality for doing various types of actions related to the user. It is used for uploading an avatar image that will be displayed in discussions and for controlling user preferences.
Figure: Profile Page
"ExternalAction" is a predefined custom Inbox Actions which can used in "My Space". This action can be used to host External web application inside iframe of Collaboration component.
Bing.com as MySpace Action:
<MySpaceConfig>
<ExternalAction id="bing">
<Label>Bing</Label>
<Font>fa-search</Font>
<Header>Bing</Header>
<Href>http://bing.com</Href>
</ExternalAction>
<ExternalAction id="verge">
<Label>Verge</Label>
<Header>The Verge</Header>
<Href>http://www.theverge.com/</Href>
</ExternalAction>
</MySpaceConfig>
From a table page, you can add a column that will show an icon when a workflow exists for the object. Clicking on the icon brings up the workflow panel.
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>
<ColumnType>workflow-chart</ColumnType>
</Column>
</Table>
If the table is defined as a system table, use the setting "Column Type" to achieve the same.
Below a screenshot illustrating the clickable table miniature. It will appear when there is a related workflow.
Since 2017.3.0 release we can use Configurable CellShowableExpression
setting in workflow-chart column like below to show or not show value of cell.
<Table>
...
<Column>
<Name>workflow-chart</Name>
<ColumnType>workflow-chart</ColumnType>
<CellShowableExpression>type.kindOf[Software Part]</CellShowableExpression>
</Column>
</Table>
In above example Workflow will be visible only for Software Part in workflow-chart column of table.
Structure Browser table can be configured to list the Workflow task objects with workflow chart column.
Clicking on the icon brings up the workflow with the highlighted task in the panel.
Below a screenshot illustrating the clickable table miniature behavior for the Workflow Task objects table.
In the case of 3DDashboard, if a table page is configured along with workflow chart column in a tvc widget then Collaboration panel widget need to be configured and added into dashboard to open a respective workflow on clicking the workflow chart icon.
Refer 3DDashboard Widgets to add the collaboration panel App and widget.
Now users can validate all collaboration json files with help of "WorkflowConfig.schema.json"
Three ways to validate using above schema:-
Tool: Using VS Code Editor
Steps:
Step 1: Download VS CODE https://code.visualstudio.com/
Step 2: Open any collaboration json file e.g PartPreliminary.json
Step 3: Link schema with json as follows.
Output: Editor will highlight key value pair in green to notify user about any warning due to missing property or wrong spelling.
Requirements: Node should be installed and Grunt should be configured.
Steps:
Step 1: Type: npm install grunt-jsonschema-ajv --save-dev in cmd.
Step 2: Sample package.json
{
"name": "json-validator",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "",
"license": "ISC",
"dependencies": {
"ajv": "^6.10.0",
"grunt": "^1.0.4"
},
"devDependencies": {
"grunt-jsonschema-ajv": "^0.1.0"
}
}
Step 3: Sample GruntFile.js
module.exports = function(grunt) {
grunt.loadNpmTasks("grunt-jsonschema-ajv");
grunt.initConfig({
jsonschema: {
tests: {
files: {
"tests_schema.json": "tests/*.json"
}
}
}
});
};
Step 4: Arrange json and its schema files according to below reference.
Note: Both schema and corresponding json files need to be present locally in the system.
Step 5: Run node jsonschema
Output: It will show error/warning if any in the console.
Note: Below configuration is not a valid JSON document. it represents the Workflow JSON configuration keys and it is associated types.
{
"id": Id,
"label": Label,
"version": Version,
"default": Default,
"dues": Array<Due>,
"accesses": Array<Accesse>,
"fields": Array<Field>,
"operations": Array<Operation>,
"contexts": Array<Context>,
"assignees": Array<Assignee>,
"triggers": Array<Trigger>,
"tasks": Array<Task>,
"workflow": Workflow
}
Following is a sample workflow configuration.
e.g.
{
"id": "sample-builder",
"label": "Sample Workflow",
"version": 1,
"default": {
"due": {
"id": "default",
"days": 4,
"activation": "task-activated"
},
"field": {
"id": "default",
"multiline": true,
"appearance": {
"reject": "readable",
"thread": "hidden",
"reassign": "readable",
"approve": "readable",
"complete": "readable"
}
},
"access": {
"id": "default",
"include": [
"Adam Sandler",
"Jennifer Aniston",
"Software Quality Engineering"
],
"exclude": [
"Test Everything",
"Software Quality Engineer"
],
"config": {
"inverse":true
}
},
"operation": {
"id": "default",
"status": {
"task": [
"approved",
"rejected"
],
"flow": [
"active"
]
},
"users": [
"participant",
"assignee"
],
"where":"context.user == 'creator'",
"access":{
"include":[
"Adam Sandler",
"Jennifer Aniston",
"Software Quality Engineering"
],
"exclude": [
"Test Everything",
"Software Quality Engineer"
],
"config": {
"inverse": true
}
}
},
"trigger": {
"id": "default",
"where": "(context.user == 'creator')",
"events": [
]
},
"assignee": {
"id": "default",
"type": "user",
"values": [
"Test Everything"
],
"appearance": {
"reject": "readable",
"thread": "hidden",
"reassign": "readable",
"approve": "readable",
"complete": "readable"
},
"autocomplete": "user",
"config": {
"key": "value"
}
},
"task": {
"id": "default",
"label": "Task",
"signature": false,
"mandatory": false,
"repeatable": false,
"multiple": true,
"where": "context.user == 'Test Everything'",
"appearance": "visible",
"operations": [
"approve",
"reject",
"reassign",
"assign"
],
"actions": [
"history"
],
"fields": [
"instructions",
"comments"
],
"due": {
"days": 2,
"activation": "task-activated"
}
}
},
"dues": [
{
"base": null,
"id": "due-task-1",
"days": 1,
"activation": "workflow-started"
}
],
"accesses": [
{
"base": null,
"id": "access-inverse",
"access": "com.technia.tvc.collaboration.discussion.model.dao.enovia.example.access.CustomAccess",
"config": {
"inverse": true
},
"include": [
"Jennifer Aniston",
"Will Smith"
],
"exclude": [
"Test Everything",
"Adam Sandler"
]
}
],
"fields": [
{
"base": null,
"id": "field-mos",
"label": "Meaning of signature",
"multiline": null,
"value": "this is Approval",
"handler": null,
"values": null,
"appearance": null
},
{
"base": null,
"id": "field-custom-value",
"label": "Custom Value",
"multiline": null,
"value": "sample custom value field",
"handler": null,
"values": null,
"appearance": null
},
{
"base": null,
"id": "field-context-name",
"label": "Context Object Name",
"multiline": null,
"value": null,
"handler": "com.technia.tvc.collaboration.discussion.model.dao.enovia.example.fieldvaluehandler.NameFieldValueHandler",
"values": null,
"appearance": null
}
],
"operations": [
{
"base": null,
"id": "operation-reassign-task",
"where": null,
"operation": "reassign",
"config": {
"key": "value"
},
"access": "access-inverse",
"users": [
"assignee",
"owner",
"participant"
],
"statuses": [
"approved"
]
}
],
"assignees": [
{
"base": null,
"id": "assignee-task-1",
"type": "role",
"values": [
"Software Quality Engineer"
],
"handler": null,
"autocomplete": "role",
"values": null,
"appearance": {
"create": "readable"
}
},
{
"base": null,
"id": "assignee-task-2.1",
"type": "com.technia.tvc.collaboration.discussion.model.dao.enovia.example.assignee.CustomAssignee",
"values": [],
"handler": {
"name": "com.technia.tvc.collaboration.discussion.model.dao.enovia.example.assignee.CustomAssigneeHandler",
"config": null
},
"autocomplete": "com.technia.tvc.collaboration.discussion.model.dao.enovia.example.assignee.CustomAssigneeAutocompleteHandler",
"values": null,
"appearance": null
},
{
"base": null,
"id": "assignee-task-2.2",
"type": "person",
"values": null,
"config": null,
"handler": null,
"autocomplete": {
"handler": "person",
"config": {
"roles": [
"Design Engineer",
"role_LibraryUser",
"role_Employee"
]
}
},
"values": null,
"appearance": null
},
{
"base": null,
"id": "assignee-task-3",
"type": "user",
"values": null,
"config": null,
"handler": null,
"autocomplete": "user",
"values": [
"Adam Sandler",
"Software Quality Engineering",
"Will Smith"
],
"appearance": null
}
],
"triggers": [
{
"base": null,
"id": "action-flow-complete",
"description":"Action Flow Complete",
"where": null,
"events": [
"approved"
],
"trigger": "flowstatus",
"config": {
"status": "complete"
}
},
{
"base": null,
"id": "action-any-rejected",
"description":"Action Rejected",
"where": null,
"events": [
"rejected"
],
"trigger": "demote",
"config": {
"privileged": false
}
},
{
"base": null,
"id": "action-custom-history",
"description":"Sample custom history",
"where": null,
"events": [
"approved"
],
"trigger": "history",
"config": {
"value": "custom history info",
"privileged": false
}
}
],
"tasks": [
{
"base": null,
"id": "task-1",
"label": "Task 1 (role)",
"where": null,
"contentURL": null,
"multiple": null,
"mandatory": null,
"signature": null,
"repeatable": true,
"appearance": "visible",
"due": "due-task-1",
"assignee": "assignee-task-1",
"fields": [
"comments",
"instructions"
],
"checks": null,
"actions": [
"history"
],
"operations": [
"complete",
"reassign",
"assign"
]
},
{
"base": null,
"id": "task-2.1",
"label": "Task 2.1 (custom)",
"where": null,
"contentURL": null,
"multiple": null,
"mandatory": null,
"signature": null,
"repeatable": null,
"appearance": null,
"due": null,
"assignee": "assignee-task-2.1",
"context": {
"context": "expression",
"config": {
"expressions": [
"id",
"from[EBOM].to.id"
],
"privileged": true
}
},
"fields": [
"instructions"
],
"checks": null,
"actions": [
"history"
],
"operations": [
"complete",
"reassign",
"assign"
]
},
{
"base": null,
"id": "task-2.2",
"label": "Task 2.2 (person-in-role)",
"where": null,
"contentURL": null,
"multiple": null,
"mandatory": null,
"signature": true,
"repeatable": null,
"appearance": null,
"due": null,
"assignee": "assignee-task-2.2",
"fields": [
"comments",
"field-mos",
"field-context-name",
"field-custom-value",
"instructions"
],
"checks": null,
"actions": [
"history"
],
"operations": [
"complete",
"reassign",
"assign"
]
},
{
"base": null,
"id": "task-3",
"label": "Task 3 (user)",
"where": null,
"contentURL": null,
"multiple": true,
"mandatory": null,
"signature": true,
"repeatable": true,
"appearance": null,
"due": null,
"assignee": "assignee-task-3",
"fields": [
"comments"
],
"checks": null,
"actions": [
"history"
],
"operations": [
"complete",
"assign"
]
}
],
"groups":[
{
"id":"g1",
"tasks": [
"task-2.1",
"task-2.2"
],
"actions":[
"promote"
]
}
],
"workflow": {
"flow": [
[
"task-1",
[
"task-2.1",
"task-2.2"
],
"task-3"
]
],
"actions": [
"history",
{
"events": [
"Started",
"Stopped",
"Terminated"
],
"trigger": "promote",
"config": {
"privileged": true
}
}
],
"context": {
"context": "expression",
"config": {
"expressions": [
"id",
"from[EBOM].to.id"
],
"privileged": true
}
},
"watcher": {
"id": "watcher-flow",
"type": "person",
"values": null,
"config": null,
"handler": {
"name": "com.technia.tvc.collaboration.discussion.model.dao.enovia.example.watcher.EverythingWatcher",
"config": {
"key": "value"
}
},
"values": [
"Adam Sandler",
"Jennifer Aniston"
]
},
"operations": [
"add",
"delete",
"stop",
"restart",
"terminate"
]
}
}
Type: String
unique id for the workflow configuration.
e.g.
{
"id": "global-sample-builder",
...
}
Type: String
label for the workflow configuration.
e.g.
{
...
"label": "Global Sample Workflow",
...
}
Type: DefaultCfg
Schema
{
"due": DefaultDue,
"field": DefaultField,
"access": DefaultAccess,
"operation": DefaultOperation,
"trigger": DefaultTrigger,
"assignee": DefaultAssignee,
"task": DefaultTask
}
Represents a Default, that can be referred by Workflow.
e.g.
{
...
"default": {
"due": {
"id": "default",
"days": 4,
"activation": "task-activated"
},
"field": {
"id": "default",
"multiline": true,
"appearance": {
"reject": "readable",
"thread": "hidden",
"reassign": "readable",
"approve": "readable",
"complete": "readable"
}
},
"access": {
"id": "default",
"include": [
"Adam Sandler",
"Jennifer Aniston",
"Software Quality Engineering"
],
"exclude": [
"Test Everything",
"Software Quality Engineer"
],
"config": {
"inverse":true
}
},
"operation": {
"id": "default",
"status": {
"task": [
"approved",
"rejected"
],
"flow": [
"active"
]
},
"users": [
"participant",
"assignee"
],
"where":"context.user == 'creator'",
"access":{
"include":[
"Adam Sandler",
"Jennifer Aniston",
"Software Quality Engineering"
],
"exclude": [
"Test Everything",
"Software Quality Engineer"
],
"config": {
"inverse": true
}
}
},
"trigger": {
"id": "default",
"where": "(context.user == 'creator')",
"events": [
]
},
"context": {
"context": "expression",
"config": {
"expressions": [
"id",
"from[EBOM].to.id"
],
"privileged": true
}
},
"assignee": {
"id": "default",
"type": "user",
"values": [
"Test Everything"
],
"appearance": {
"reject": "readable",
"thread": "hidden",
"reassign": "readable",
"approve": "readable",
"complete": "readable"
},
"autocomplete": "user",
"config": {
"key": "value"
}
},
"task": {
"id": "default",
"label": "Task",
"signature": false,
"mandatory": false,
"repeatable": false,
"multiple": true,
"where": "context.user == 'Test Everything'",
"appearance": "visible",
"operations": [
"approve",
"reject",
"reassign",
"assign"
],
"actions": [
"history"
],
"fields": [
"instructions",
"comments"
],
"due": {
"days": 2,
"activation": "task-activated"
}
}
}
...
}
Type: DueCfg
refers an inline DueCfg.
e.g.
{
...
"default": {
...
"due": {
"id": "default",
"days": 4,
"activation": "task-activated",
"handler":{
"name":"com.technia.tvx.collaboration.workflow.cfg.dueHandler.CustomDueDateHandler",
"config":{
}
}
}
...
}
...
}
Type: FieldCfg
refers an inline FieldCfg.
e.g.
{
...
"default": {
...
"field": {
"id": "default",
"multiline": true,
"appearance": {
"reject": "readable",
"thread": "hidden",
"reassign": "readable",
"approve": "readable",
"complete": "readable"
}
}
...
}
...
}
Type: AccessCfg
refers an inline AccessCfg.
e.g.
{
...
"default": {
...
"access": {
"id": "default",
"include": [
"Adam Sandler",
"Jennifer Aniston",
"Software Quality Engineering"
],
"exclude": [
"Test Everything",
"Software Quality Engineer"
],
"config": {
"inverse": true
}
}
...
}
...
}
Type: OperationCfg
refers an inline OperationCfg.
e.g.
{
...
"default": {
...
"operation": {
"id": "default",
"status": {
"task": [
"approved",
"rejected"
],
"flow": [
"active"
]
},
"users": [
"participant",
"assignee"
],
"where": "context.user == 'creator'",
"access": {
"include": [
"Adam Sandler",
"Jennifer Aniston",
"Software Quality Engineering"
],
"exclude": [
"Test Everything",
"Software Quality Engineer"
],
"config": {
"inverse":true
}
}
}
...
}
...
}
Type: TriggerCfg
refers an inline TriggerCfg.
e.g.
{
...
"default": {
...
"trigger": {
"id": "default",
"where": "(context.user == 'creator')",
"events":[
]
}
...
}
...
}
Type: ContextCfg
refers an inline ContextCfg.
e.g.
{
...
"default": {
...
"context": {
"context": "expression",
"config": {
"expressions": [
"id",
"from[EBOM].to.id"
],
"privileged": true
}
}
...
}
...
}
Type: AssigneeCfg
refers an inline AssigneeCfg.
e.g.
{
...
"default": {
...
"assignee": {
"id": "default",
"type": "user",
"values": [
"Test Everything"
],
"appearance": {
"reject": "readable",
"thread": "hidden",
"reassign": "readable",
"approve": "readable",
"complete": "readable"
},
"autocomplete": "user",
"config": {
"key": "value"
}
}
...
}
...
}
Type: TaskCfg
refers an inline TaskCfg.
e.g.
{
...
"default": {
...
"task": {
"id": "default",
"history":false,
"label": "Task",
"signature": false,
"mandatory": false,
"repeatable": false,
"multiple": true,
"where": "context.user == 'Test Everything'",
"appearance": "visible",
"operations": [
"approve",
"reject",
"reassign",
"assign"
],
"actions": [
"history"
],
"fields": [
"instructions",
"comments"
],
"due": {
"days": 2,
"activation": "task-activated"
}
}
...
}
...
}
Type: DueCfg
Schema
{
"base": DueBase,
"id": DueId,
"days": DueDays,
"activation": DueActivation,
"handler":{
"name":"com.technia.tvx.collaboration.workflow.cfg.dueHandler.CustomDueDateHandler",
"config":{
}
}
}
Represents a Due, that can be referred by Tasks.
e.g.
{
...
"task:" {
...
"due": {
"base": null,
"id": "default",
"days": 1,
"activation": "task-activated",
"handler":"com.technia.tvx.collaboration.workflow.cfg.dueHandler.CustomDueDateHandler"
}
...
}
...
}
Type: String
refers a existing configured DueCfg’s DueId. This inherits configurations from the base, that can be overriden locally.
e.g.
{
"base": "due-urgent",
"id": "due-asap"
...
}
Type: String
fixed value. options are,
"workflow-started"
"task-activated"
e.g.
{
"activation": "task-activated",
...
}
To use the custom logic to set the due date for task.
Type: String/Object
refers a class’s full name which implements com.technia.tvc.collaboration.workflow.model.dao.enovia.config.DueHandler
e.g.
{
"handler":"com.technia.tvx.collaboration.workflow.cfg.dueHandler.CustomDueDateHandler",
...
}
To pass some config parameters, we could define the handler with following property:
name : refers a class’s full name which implements com.technia.tvc.collaboration.workflow.model.dao.enovia.config.DueHandler
config : additional parameter
{
"handler":{
"name":"com.technia.tvx.collaboration.workflow.cfg.dueHandler.CustomDueDateHandler",
"config":{
}
},
...
}
Type: AccessCfg
Schema
{
"base": AccessBase,
"id": AccessId,
"access": AccessHandler,
"config": AccessConfig,
"include": AccessIncludeAssignees,
"exclude": AccessExcludeAssignees
}
Represents a Access, that can be referred by Tasks.
e.g.
{
...
"accesses": [
{
"base": null,
"id": "access-inverse",
"access": "com.technia.tvc.collaboration.discussion.model.dao.enovia.example.access.CustomAccess",
"config": {
"inverse": true
},
"include": [
"Jennifer Aniston",
"Will Smith"
],
"exclude": [
"Test Everything",
"Adam Sandler"
]
}
],
...
}
Type: String
refers a existing configured AccessCfg’s AccessId. This inherits configurations from the base, that can be overridden locally.
e.g.
{
"base": "access-user",
"id": "access-super-user"
...
}
Type: String
refers a class’s full name which implements com.technia.tvc.collaboration.workflow.model.access.Access.
e.g.
{
...
"access": "com.technia.tvc.collaboration.discussion.model.dao.enovia.example.access.CustomAccess",
...
}
Type: Map<Object,Object>
any custom configuration values.
e.g.
{
...
"config": {
"inverse": true
}
...
}
Type: FieldCfg
Schema
{
"base": FieldBase,
"id": FieldId,
"label": FieldLabel,
"type": FieldType,
"multiline": FieldMultiline,
"retain": FieldRetain,
"value": FieldValue,
"handler": FieldHandler,
"values": Array<FieldValue>,
"appearance": FieldAppearance,
"type": FieldType
}
Represents a Field, that can be referred by Tasks.
There are following built-in fields which are,
"instructions"
"comments"
"warning" : warning message during delete task operation
"dueDate"
"automationDetails" : It shows the descriptions of actions which will be performed after completion of task operation, in task operation form.
e.g.
{
...
"fields": [
{
"base": null,
"id": "field-context-name",
"label": "Context Object Name",
"multiline": false,
"list":"ordered",
"value": "<context object name>",
"handler": "com.technia.tvc.collaboration.discussion.model.dao.enovia.example.fieldvaluehandler.NameFieldValueHandler",
"values": null,
"appearance": {
"create": "readable",
"reassign": "editable",
"thread": "hidden",
"approve": "readable",
"complete": "readable",
"reject": "readable",
"assign": "readable"
}
}
],
...
}
Type: String
refers a existing configured FieldCfg’s FieldId. This inherits configurations from the base, that can be overriden locally.
e.g.
{
"base": "field-common",
"id": "field-steps"
...
}
Type: String
The label that will be displyed on the Workflow Forms for the field.
e.g.
{
...
"label": "Context Object Name",
...
}
Type: Boolean
Whether to show multiline input control for the field.
e.g.
{
...
"multiline": true,
...
}
Type: String
To show the values of field in ordered or unordered list
e.g.
{
...
"list": "ordered/unordered",
...
}
view
. Field Value 1
. Field Value 2
Type: Boolean
Whether to retain the field value for reassign and assign operations. The default value is true. For builtin field "comments" is false.
e.g.
{
...
"retain": true,
...
}
Type: Boolean
Whether to replicate
the field value for reassign and assign operations on both the current and the new revisions. The default value is false. When replicate
is true, both the latest revision and previous revision gets updated with the field value.
e.g.
{
...
"replicate": true,
...
}
For the reassign and assign operations, if the field setting replicate
is false, then the field value is copied only to the new revision.
Type: FieldValue
Schema
{
"value": String,
"display": String,
"selected": Boolean
}
Represents a field value.
e.g.
{
...
"values" : [
{
"value": "actual value",
"display": "display value",
"selected": true
}
]
...
}
FieldValue could also be a string resource property key for internationalization.
Sample configuration
{
...
"values" : [
"tvc.workflow.task.field.value1",
"tvc.workflow.task.field.value2",
"tvc.workflow.task.field.value3"
],
...
}
Corresponding properties can be defined in the string resource property file as shown below.
e.g.
tvc.workflow.task.field.value1 = Set Change Order Approval List
Type: String
refers a class’s full name which implements com.technia.tvc.collaboration.workflow.model.dao.enovia.config.FieldHandler.
FieldHandler is used to return multiple values.
Built-In Handler | Description |
---|---|
AutomationDetailsFieldValueHandler |
It captures description of trigger and push it to automationDetails field. |
DueDateFieldValueHandler |
It populates due date value in dueDate field. |
NameFieldValueHandler |
Statement based field value handler |
DescriptionFieldValueHandler |
Statement based field value handler |
WarningFieldValueHandler |
It populates value inside warning field. |
e.g.
{
...
"handler": "com.technia.tvc.collaboration.discussion.model.dao.enovia.example.fieldvaluehandler.NameFieldValueHandler",
...
}
Type: Map<Component, Appearance>
Type: Component
fixed value. options are,
"create"
"reassign"
"thread"
"approve"
"complete"
"reject"
"assign"
Type: Appearance
fixed value. options are,
"readable"
"hidden"
"mandatory"
"editable"
"text"
"visible"
Represents a component and appearance mapping.
e.g.
{
...
"appearance": {
"create": "readable",
"reassign": "editable",
"thread": "hidden",
"approve": "readable",
"complete": "readable",
"reject": "readable",
"assign": "readable"
}
...
}
Type: String
Current Supported types are date and select.
date : value should be passed in "YYYY-MM-DD" format only.
e.g.
{
...
"type": "date",
"value": "2019-01-23"
...
}
* select : to select a value from the list of values.
*e.g.*
```json
{
...
"type": "select",
"values": [Follow Instruction1, Follow Instruction2, Follow Instruction3]
...
}
Type: Map<TaskStatus, Appearance>
Represents a Task Status and appearance mapping. Based on this mapping, field will be displayed in task details based on task status. Default value is visible.
e.g.
{
...
"status": {
"active": "visible",
"rejected": "hidden",
"unassigned": "hidden",
"approved": "visible",
"complete": "hidden",
"pending": "hidden"
}
...
}
Type: OperationCfg
Schema
{
"base": OperationBase,
"id": OperationId,
"label": OperationLabel,
"where": OperationWhere,
"operation": OperationHandler,
"config": OperationConfig,
"access": OperationAccess,
"users": OperationUser,
"statuses": OperationStatuses
}
Represents a Operation, that can be referred by Tasks.
There are following built-in operations that are,
"complete"
"approve"
"reject"
"assign"
"reassign"
e.g.
{
...
"operations": [
{
"base": null,
"id": "operation-reassign-task",
"label": null,
"where": null,
"operation": "reassign",
"config": {
"key": "value"
},
"access": "access-inverse",
"users": [
"assignee",
"owner",
"participant"
],
"statuses": [
"approved"
]
}
],
...
}
Type: String
refers a existing configured OperationCfg’s OperationId. This inherits configurations from the base, that can be overriden locally.
e.g.
{
"base": "operation-common",
"id": "operation-reassign-task"
...
}
Type: String
unique id of the operation.
e.g.
{
"id": "operation-reassign-task",
...
}
Type: String
Custom label for the operation. label can be a property key.
e.g.
{
...
"base": "complete",
"label": "Done Task",
...
}
Type: String
Whether the operation can be executed.
e.g.
{
...
"where": "(context.user == 'Test Everything')",
...
}
Type: String
refers a class’s full name which implements com.technia.tvc.collaboration.workflow.model.operation.Operation.
e.g.
{
...
"operation": "com.technia.tvc.collaboration.discussion.model.dao.enovia.example.operation.CustomOperation",
...
}
Type: Map<Object,Object>
custom configuration values in key value pair.
Following are pre-defined configs which could be used for operation definition.
Name | Details |
---|---|
form-title |
String value or String resource property key for operation form custom title. |
form-submit-label |
String value or String resource property key for operation form custom submit label. |
e.g.
{
...
"config": {
"inverse": true,
"form-title":"Forwarding the Task",
"form-submit-label":"forward"
}
...
}
Type: String
refers a existing configured AccessCfg’s AccessId. This inherits configurations from the base, that can be overriden locally.
e.g.
{
...
"access": "access-librarian"
...
}
Type: Array<User>
Type: User
fixed value. options are,
Option | Description |
---|---|
assignee |
Assignee of the Task. |
owner |
Creator of the workflow. |
recipient |
Persons in Group/Role when Task is assigned to Group/Role. |
watcher |
Watchers on the Workflow. |
all |
All users. |
Types of user for whom the operation is available.
e.g.
{
...
"users": [
"assignee",
"owner",
"recipient"
],
...
}
Type: Array<Status>
Type: Status
fixed value. options are,
"Rejected"
"Approved"
"Reassigned"
"Complete"
"Pending"
"Active"
"Unassigned"
"Excluded"
"Assigned"
"Active and Unassigned"
"Started"
"Stopped"
"Restarted"
"Terminated"
Types of task status at which operation is enabled.
e.g.
{
...
"statuses": [
"approved",
"complete"
],
...
}
Type: ContextCfg
Schema
{
"base": ContextBase,
"id": ContextId,
"context": Context,
"config": ContextConfig
}
Represents a Context, that can be referred by Tasks/ Workflow.
There is a built-in contexts that is,
expression
if "expression" context returns no contexts, then current context would be connected. To include current contexts along with expression contexts use "id" selectable in "expressions" config. |
repeatable
if there are multiple context for task then task will be splitted into multiple task each per context. single context will be connected to each splitted task. |
e.g.
{
...
"contexts": [
{
"base": null,
"id": "context-from-ebom",
"context": "expression",
"repeatable": true,
"config": {
"expressions": [
"id",
"from[EBOM].to.id"
],
"privileged": true
}
}
...
],
...
}
Type: String
refers a existing configured ContextCfg’s ContextId. This inherits configurations from the base, that can be overriden locally.
e.g.
{
"base": "context-promote",
"id": "context-selective-promote"
...
}
Type: String
refers a class’s full name which implements com.technia.tvc.collaboration.workflow.model.context.Context.
e.g.
{
...
"context": "com.technia.tvc.collaboration.workflow.cfg.context.impl.builtin.ExampleContext",
...
}
Type: Map<Object,Object>
any custom configuration values.
e.g.
{
...
{
...
"context": "expression",
"config": {
"expressions": [
"id",
"from[EBOM].to.id"
]
}
...
}
...
}
Support for editing the context object through the helium widget.
It will help to avoid navigating to multiple windows to edit the context object which requires to complete a task.
The user could define a form widget with the required fields for the specific task.
editWidget: Helium based Widget to edit the context object.
editTarget: inline or popup. In inline mode, the widget is open inside the task thread. default is a popup mode which open as a modal dialog.
{
...
{
...
"context": "expression",
"config": {
...,
"editWidget":"/hex/engineering/ChangeProcess",
"editTarget":"inline"
}
...
}
...
}
Type: AssigneeCfg
Schema
{
"base": AssigneeBase,
"id": AssigneeId,
"type": AssigneeType,
"config": AssigneeConfig,
"handler": AssigneeHandlerCfg,
"autocomplete": AssigneeAutocompleteCfg,
"values": Array<AssigneeValue>,
"appearance": AssigneeAppearance
}
Represents a Assignee, that can be referred by Tasks.
e.g.
{
...
"assignees": [
{
"base": null,
"id": "assignee-person-within-role",
"type": "person",
"values": null,
"handler": null,
"autocomplete": {
"handler": "person",
"config": {
"roles": [
"Design Engineer",
"role_LibraryUser",
"role_Employee"
]
}
},
"values": null,
"appearance": null
},
{
"base": null,
"id": "assignee-custom",
"type": "com.technia.tvc.collaboration.discussion.model.dao.enovia.example.assignee.CustomAssignee",
"handler": "com.technia.tvc.collaboration.discussion.model.dao.enovia.example.assignee.CustomAssigneeHandler",
"autocomplete": "com.technia.tvc.collaboration.discussion.model.dao.enovia.example.assignee.CustomAssigneeAutocompleteHandler",
"values": null,
"appearance": null
}
],
...
}
Type: String
refers a existing configured AssigneeCfg’s AssigneeId. This inherits configurations from the base, that can be overriden locally.
e.g.
{
"base": "assignee-task-common",
"id": "assignee-task-review"
...
}
Type: String
unique id of the assignee.
e.g.
{
"id": "assignee-task-release",
...
}
Type: AssigneeType
fixed or custom value. options are,
"person"
"role"
"group"
"user"
"memberlist"
or any class implementing "com.technia.tvc.collaboration.core.model.Assignee"
e.g.
{
...
"assignees" : [
{
...
"type": "role",
...
},
{
...
"type": "com.technia.tvc.collaboration.discussion.model.dao.enovia.example.assignee.CustomAssignee",
...
}
]
...
}
Type: String
Assignee name that can match the Assignee-Type configured.
e.g.
{
...
"assignees" : [
{
...
"type": "user",
"values": [
"Adam Sandler",
"Software Quality Engineering",
"Will Smith"
],
...
}
]
...
}
Type: AssigneeHandler | AssigneeHandlerCfg
Type: AssigneeHandlerCfg
Schema
{
"name": AssigneeHandler,
"config": AssigneeHandlerConfig
}
Represents a AssigneeHandler, that is used in Assignee.
e.g.
{
...
"assignees": [
{
...
"handler": "com.technia.tvc.collaboration.discussion.model.dao.enovia.example.assignee.CustomAssigneeHandler",
...
},
{
...
"handler": {
"name": "com.technia.tvc.collaboration.discussion.model.dao.enovia.example.assignee.CustomAssigneeHandler",
"config": {
"key": "value"
}
}
...
}
],
...
}
Type: String
refers a class’s full name which implements com.technia.tvc.collaboration.workflow.model.dao.enovia.config.AssigneeHandler.
e.g.
{
...
"assignees": [
{
...
"handler": "com.technia.tvc.collaboration.discussion.model.dao.enovia.example.assignee.CustomAssigneeHandler",
...
},
{
...
"handler": {
"name": "com.technia.tvc.collaboration.discussion.model.dao.enovia.example.assignee.CustomAssigneeHandler",
}
...
}
],
...
}
Type: Map<Object,Object>
any custom configuration values. This configuration will be available for AssigneeHandler.
e.g.
{
...
"assignees": [
{
...
"handler": {
"name": "com.technia.tvc.collaboration.discussion.model.dao.enovia.example.assignee.CustomAssigneeHandler",
"config": {
"key": "value"
}
}
...
}
],
...
}
Type: String | AssigneeAutocompleteCfg
fixed or custom complex value. options are,
"person"
"role"
"group"
"user"
"memberlist"
Schema
{
"handler": AssigneeAutocompleteHandler,
"config": AssigneeAutocompleteConfig
}
Type: String
refers a class’s full name which implements com.technia.tvc.collaboration.workflow.model.operation.Operation.
e.g.
{
...
"assignees": [
{
...
"autocomplete": "com.technia.tvc.collaboration.discussion.model.dao.enovia.example.assignee.CustomAssigneeAutocompleteHandler"
...
},
{
...
"autocomplete": {
"handler": "com.technia.tvc.collaboration.discussion.model.dao.enovia.example.assignee.CustomAssigneeAutocompleteHandler",
"config": {
"key": "value"
}
}
...
},
],
...
}
Type: Map<Object,Object>
any custom configuration values. This configuration will be available for AssigneeAutocompleteHandler.
e.g.
{
...
"config": {
"key": "value"
}
...
}
Type: Map<Component, Appearance>
Type: Component
fixed value. options are,
"create"
"reassign"
"thread"
"approve"
"complete"
"reject"
"assign"
Type: Appearance
fixed value. options are,
"readable"
"hidden"
"mandatory"
"editable"
"text"
"visible"
Represents a component and appearance mapping.
e.g.
{
...
"appearance": {
"create": "readable",
"reassign": "editable",
"thread": "hidden",
"approve": "readable",
"complete": "readable",
"reject": "readable",
"assign": "readable"
}
...
}
Type: String / String Resource Property
The pretext that will be displayed on task list page before task assignee.
e.g.
{
...
"pretext": "Assigned to group : ",
...
}
{
...
"pretext": "tvc.collaboration.workflow.task.assignee.pretext ",
...
}
Type: Map<Object,Object>
any custom configuration values.
e.g.
{
...
{
...
"type": "person",
"config": {
"preload": true,
"openOnFocus": true
}
...
}
...
}
The following config can be used to tune the assignee autocomplete field.
preload: to load the assignee options on a load of field.
openOnFocus: To open the assignee list on focus.
These configuration properties would override the behavior of following TVC system property.
Property | Description | Default Value |
---|---|---|
tvc.collaboration.autocomplete.loadOnFocus |
To preload and open the assignee list on focus |
false |
Refer OrganizationResolver chapter for more details.
Type: TriggerCfg
Schema
{
"base": TriggerBase,
"id": TriggerId,
"descriptions": TriggerDescriptions,
"where": TriggerWhere,
"events": TriggerEvents,
"trigger": Trigger,
"config": TriggerConfig
}
Represents a Trigger, that can be referred by Tasks.
There are following built-in triggers that are,
"promote"
"demote"
"history"
"setstate"
"sign"
"jpo"
"flowstatus"
"script"
"copy"
copy built-in trigger does only support owner and description basic properties and all attribute to update in context object. |
"workflowhistory"
workflowhistory built-in trigger is used to add the custom history of task operations in workflow. |
e.g.
{
...
"triggers": [
{
"base": null,
"id": "action-custom-history",
"descriptions":["custom history"],
"where": null,
"events": [
"approved",
"complete",
"rejected"
],
"trigger": "history",
"config": {
"value": "custom history info",
"privileged": true,
"context": "both",
"alternate-ids-expression" : "from[EBOM].to.id",
"sort-ids-expression": "from[EBOM].to.id"
}
},
{
"base": null,
"id": "copy-trigger",
"descriptions": ["copy context object"],
"where": null,
"events": [
"approved",
"complete"
],
"trigger": "copy",
"config": {
"copy": {
"owner": ["description", "attribute_Notes"],
"modified": "attribute_Notes",
"attribute_TVCCollaborationTitle": "attribute_Notes"
},
"privileged": true,
"context": "task"
}
}
...
],
...
}
Type: String
refers a existing configured TriggerCfg’s TriggerId. This inherits configurations from the base, that can be overriden locally.
e.g.
{
"base": "trigger-promote",
"id": "trigger-selective-promote"
...
}
Type: Array<String>
descriptions for trigger.
You can also change description of built in trigger directly using below properties in TVCStringResources.properties file.
Trigger Key | Default Value |
---|---|
tvc.collaboration.workflow.trigger.promote.description |
Promote Context Object |
tvc.collaboration.workflow.trigger.demote.description |
Demote Context Object |
tvc.collaboration.workflow.trigger.copy.description |
Copy the task attributes on context object attributes |
tvc.collaboration.workflow.trigger.history.description |
Adding the task operation into context object history log |
e.g.
{
"tasks": [
{
"fields": ["automationDetails","instructions"],
"actions": ["copy-trigger", "history"]
}
],
"triggers": [
{
"id": "copy-trigger",
"descriptions": ["tvc.collaboration.label.sent"]
}
]
...
}
Type: String
Whether the trigger can be executed.
e.g.
{
...
"where": "(context.user == 'Test Everything')",
...
}
Type: String
refers a class’s full name which implements com.technia.tvc.collaboration.workflow.model.trigger.Trigger.
e.g.
{
...
"trigger": "com.technia.tvc.collaboration.workflow.cfg.trigger.impl.builtin.ExampleTrigger",
...
}
If TriggerHandler returns an error without error message, the default error message 'Error From Trigger : TRIGGER_NAME'
will be shown. It can be configurable by changing value for the property key tvc.collaboration.workflow.trigger.failure.alert in TVCStringResources.properties file as shown below.
tvc.collaboration.workflow.trigger.failure.alert = Error From Trigger : {0}
Type: Map<Object,Object>
Following are specific configs used by respective builtin triggers.
Name | Default Value | Details |
---|---|---|
alternate-ids-expression |
null |
Expression to evaluate alternate ids |
sort-ids-expression |
null |
Expression to sorts physical id’s to be promoted in specific order. |
privileged |
null |
boolean to execute the trigger on privileged context. |
context |
either |
enum of 'workflow', 'task', 'both', 'either' to execute the trigger in context of task/workflow. |
e.g.
{
...
{
...
"trigger": "promote",
"config": {
"alternate-ids-expression" : "from[Proposed Activities].to.paths.path[Where].element[0].physicalid"
}
...
},
{
...
"trigger": "flowstatus",
"config": {
"status": "complete",
"context": "workflow"
}
...
},
{
...
"trigger": "jpo",
"config": {
"program": "emxCustomProgram",
"method": "logEvent",
"context": "task"
}
...
},
{
...
"trigger": "setstate",
"config": {
"state": "Review",
"privileged": true,
"context": "either"
}
...
},
{
...
"trigger": "sign",
"config": {
"signature": "Design Reviewer",
"action": "approve",
"comment": "approving the design",
"privileged": true,
"context": "both"
}
...
},
{
...
"trigger": "script",
"config":{
"modules": [
"panel",
"myspace"
],
"script":"(function(){top.refreshTablePage();}())"
}
...
}
...
}
Type: Array<Event>
Type: Event
fixed value. options are,
"Rejected"
"Approved"
"Reassigned"
"Complete"
"Pending"
"Active"
"Unassigned"
"Excluded"
"Assigned"
"Active and Unassigned"
"Started"
"Stopped"
"Restarted"
"Terminated"
Types of task events at which trigger is enabled.
e.g.
{
...
"events": [
"approved",
"complete",
"stopped"
],
...
}
Type: TaskCfg
Schema
{
"base": TaskBase,
"id": TaskId,
"label": TaskLabel,
"where": TaskWhere,
"multiple": TaskMultiple,
"mandatory": TaskMandatory,
"signature": TaskSignature,
"repeatable": TaskRepeatable,
"appearance": TaskAppearance,
"due": TaskDue,
"assignee": TaskAssignee,
"context": TaskContext,
"fields": Array<TaskField>,
"checks": Array<TaskTrigger>,
"actions": Array<TaskTrigger>,
"operations": Array<TaskOperation>,
"history": TaskHistory,
"automationHistory" : TaskAutomationHistory
}
Represents a Task, that can be referred by Workflow.
e.g.
{
...
"tasks": [
{
"base": null,
"id": "task-review",
"label": "Part Review",
"where": null,
"multiple": true,
"mandatory": null,
"signature": true,
"repeatable": false,
"appearance": null,
"due": null,
"assignee": "assignee-task-review",
"context": {
"context": "expression",
"config": {
"expressions": [
"id",
"from[EBOM].to.id"
],
"privileged": true
}
},
"fields": [
"comments"
"field-context-name",
"instructions",
"automationDetails"
],
"checks": null,
"actions": [
"history",
"action-super-promote",
],
"operations": [
"reassign",
"assign",
"operation-review"
],
"history":true,
"automationHistory":true
}
...
],
...
}
Type: String
refers a existing configured TaskCfg’s TaskId. This inherits configurations from the base, that can be overriden locally.
e.g.
{
"base": "task-review",
"id": "task-manager-review"
...
}
Type: String
The label of the task.
e.g.
{
...
"label": "Buyers Review",
...
}
TaskLabel could also be a string resource property key for internationalization.
Sample configuration
{
...
"id":"setup",
"label":"tvc.collaboration.workflow.task.label.setup",
"signature":false,
...
}
Corresponding properties can be defined in the string resource property file as shown below.
e.g.
tvc.collaboration.workflow.task.label.setup = setup
Type: String
Whether the task can be included.
e.g.
{
...
"where": "(context.user == 'Test Everything')",
...
}
Type: Boolean
Whether to allow selection of multiple assignee for the task.
e.g.
{
...
"multiple": true,
...
}
Type: Boolean
Whether selection of assignee for the task is mandatory.
e.g.
{
...
"mandatory": true,
...
}
Type: Boolean
Whether the task approval or rejection requires re-entry of user credential. Core Authenticator would be used to authenticate the user credential.
e.g.
{
...
"signature": true,
...
}
Type: Boolean
Whether the task will be repeated if multiple assignees selected or the assignee types resolves to multiple users.
e.g.
{
...
"repeatable": true,
...
}
Type: Boolean | AdhocCfg
Defines the add task operation behavior for context task. Default behavior is true.
It defines following behavior.
Whether the task configuration should be used for Add Task workflow operation.
Whether + icon will be displayed to add the parallel and serial task.
e.g.
{
...
"adhoc": true,
...
}
{
...
"adhoc": {
"add" : true,
"serial" : true,
"parallel" : true
},
...
}
Whether the task configuration should be used for Add Task workflow operation. If false then task configuration will not be displayed in configuration list in add task form.
{
...
"adhoc": {
"add" : false,
},
...
}
Whether the task should have + icon for adding parallel task. + icon will not be displayed on task with false value.
{
...
"adhoc": {
"parallel" : false,
},
...
}
Whether the task branch should have + icon for adding serial task. + icon will not be displayed on task branches which are in forward direction with false value.
{
...
"adhoc": {
"serial" : false,
},
...
}
Type: Map<Component, Appearance>
Type: Component
fixed value. options are,
"create"
"reassign"
"thread"
"approve"
"complete"
"reject"
"assign"
Type: Appearance
fixed value. options are,
"hidden"
"visible"
Represents a component and appearance mapping.
e.g.
{
...
"appearance": {
"create": "hidden",
"reassign": "visible",
"thread": "hidden",
"approve": "visible",
"complete": "visible",
"reject": "visible",
"assign": "visible"
}
...
}
Type: String | DueCfg
e.g.
{
...
"tasks": [
{
...
"due": "due-urgent"
...
},
{
...
"due": {
"days": 1,
"activation": "task-activated"
}
...
}
]
...
}
Type: String | AssigneeCfg
refers a AssigneeId (recommended as it enables reuse) or inline AssigneeCfg.
e.g.
{
...
"tasks": [
{
...
"assignee": "assignee-person-within-role"
...
},
{
...
"assignee": {
"type": "person",
"autocomplete": {
"handler": "person",
"config": {
"roles": [
"Design Engineer",
"role_LibraryUser",
"role_Employee"
]
}
}
}
...
}
]
...
}
Type: String | ContextCfg
refers a ContextId (recommended as it enables reuse) or inline ContextCfg.
repeatable
if there are multiple context for task then task will be splitted into multiple task each per context. single context will be connected to each splitted task. |
e.g.
{
...
"tasks": [
{
...
"context": {
"context": "expression",
"repeatable": true,
"config": {
"expressions": [
"id",
"from[EBOM].to.id"
],
"privileged": true
}
}
...
}
]
...
}
Type: String | FieldCfg
e.g.
{
...
"tasks": [
{
...
"fields": [
"instruction",
"field-context-name",
"automationDetails",
{
"label": "Meaning of signature",
"multiline": false,
"value": "This is Approval",
"appearance": {
"create": "readable",
"reassign": "editable"
}
}
]
...
}
]
...
}
Type: String | TriggerCfg
refers a TriggerId (recommended as it enables reuse) or inline TriggerCfg.
e.g.
{
...
"tasks": [
{
...
"checks": [
"check-valid-state"
],
"actions": [
"action-promote-connected",
{
"events": [
"approved",
"complete",
"rejected"
],
"trigger": "history",
"config": {
"privileged": true
}
}
]
...
}
]
...
}
Type: String | OperationCfg
refers a OperationId (recommended as it enables reuse) or inline OperationCfg.
e.g.
{
...
"tasks": [
{
...
"operations": [
"complete",
"reassign",
"assign",
{
"operation": "reassign",
"access": "access-inverse",
"users": [
"assignee",
"owner",
"participant"
],
"statuses": [
"approved"
]
}
]
...
}
]
...
}
Type: Boolean
refers to task history icon Default Value: true
Note: This property will be used only if user set tvc.collaboration.workflow.task.history=true inside tvc.properties file.
e.g.
{
"history": false
...
}
Type: Boolean
Display the Automation which are executed on task in task thread including task activation (Default value: false).
For Example:
if task is completed then show the task completions and activation(if only activated) automation details in thread.
e.g.
{
"automationHistory": true
...
}
Type: Map<TaskStatus, String>
Represents a Task Status and custom css class mapping. Custom class will be added into the class list of graph node and other elements of task UI.
Additional css resources can be added in TVCWorkflowConfig.xml to define custom classes. (refer Additional Resources in Workflow admin guide)
e.g.
{
...
"css-class-mapping": {
"reassigned": "forwarded",
"approved": "done",
"rejected": "absconded",
}
...
}
Type: Map<TaskStatus, String>
Represents a Task Status and custom display status mapping. Custom display status will be displayed in tooltip and other UI instances in place of original status.
custom display status could also be a String resource property key for internationalization.
e.g.
{
...
"status-mapping": {
"reassigned": "forwarded",
"approved": "tvc.workflow.approved.customstatus",
"rejected": "absconded",
}
...
}
Type: GroupCfg
Schema
{
"base": GroupBase,
"id": GroupId,
"tasks": [
Task-Id1,
Task-Id2],
"actions": [
GroupAction
],
"context":GroupContext
}
Allows you to configure the group of task to acheive the following grouped behavior:
An action to execute after a combination of tasks has been completed. This is achieved by adding the tasks in a group. The action is then assigned to the group. The action will be executed once when all tasks in a group fulfills the action event.
e.g.
...
"groups:" [
{
"base": null,
"id": "group1",
"tasks": [
"Task1"
],
"actions": [
"promote"
]
},
{
"base": null,
"id": "group2",
"tasks": [
"Task2.1",
"Task2.2"
],
"actions": [
"demote"
]
},
]
...
To split the group of tasks if there are multiple group context. Group of tasks will be splitted into multiple groups each per context and will be arranged in separate parallel flow. e.g.
...
"groups:" [
{
"base": null,
"id": "group1",
"tasks": [
"B","C"
],
"context": {
"context": "expression",
"repeatable": true,
"config": {
"expressions": [
"from[Change Action].to.id"
]
}
}
}
]
...
A - - B - - C - - D
Above flow is arranged in following flow if group is having 2 context for the group.
- B1 - - C1 -
A - | | - D
- B2 - - C2 -
Type: String
Refers a existing configured GroupCfg’s GroupId. This inherits configurations from the base, that can be overriden locally.
e.g.
{
"base": "group1",
"id": "group2"
...
}
Type: Array
List of task config id to be grouped.
e.g.
{
"tasks": [
"Task2.1",
"Task2.2"
],
...
}
Type: Array
List of actions which need to be executed on group of tasks.
e.g.
{
"actions": [
"custom-trigger",
"promote"
],
...
}
Type: String | ContextCfg
refers a ContextId (recommended as it enables reuse) or inline ContextCfg.
repeatable
if there are multiple context for group then group will be splitted into multiple group each per context. Group will be arranged in separate parallel flow. |
e.g.
{
...
"groups": [
{
...
"context": {
"context": "expression",
"repeatable": true,
"config": {
"expressions": [
"id",
"from[Change Action].to.id"
],
"privileged": true
}
}
...
}
]
...
}
Type: WorkflowCfg
Schema
{
"flow": WorkflowFlow,
"watcher": WorkflowWatcher,
"context": WorkflowContext,
"operations": Array<WorkflowOperation>,
"actions": Array<WorkflowActions>
}
Represents Workflow, that layouts Tasks and workflow level operations.
e.g.
{
...
"workflow": {
"flow": [
[
"task-1",
[
"task-2.1",
"task-2.2"
],
"task-3"
]
],
"actions": [
"custom-trigger",
{
"events": [
"Started",
"Stopped",
"Terminated"
],
"trigger": "promote",
"config": {
"privileged": true
}
}
],
"context": {
"context": "expression",
"config": {
"expressions": [
"id",
"from[EBOM].to.id"
],
"privileged": true
}
},
"watcher": {
"type": "person",
"values": [
"Adam Sandler",
"Jennifer Aniston"
],
"handler": {
"name": "com.technia.tvc.collaboration.discussion.model.dao.enovia.example.watcher.EverythingWatcher",
"config": {
"key": "value"
},
}
},
"operations": [
"add",
"delete",
"stop",
"restart",
"terminate"
]
}
...
}
Type: String | Array
defines the structure/flow of the workflow using configured TaskId's
e.g.
{
...
"workflow": [
[
"task-1",
[
"task-2.1",
"task-2.2"
],
"task-3"
]
]
...
}
Type: String | ContextCfg
refers a ContextId (recommended as it enables reuse) or inline ContextCfg.
e.g.
{
...
"workflow": {
...
"context": {
"context": "expression",
"config": {
"expressions": [
"id",
"from[EBOM].to.id"
],
"privileged": true
}
}
...
}
...
}
Type: WatcherCfg
Schema
{
"type": WatcherType,
"values": Array<WatcherValue>,
"handler": WatcherHandlerCfg
}
Represents a Watcher configuration, which can result into multiple watchers who watch the workflow.
e.g.
e.g.
{
...
"workflow": {
...
"watcher": {
"type": "person",
"values": [
"Adam Sandler",
"Jennifer Aniston"
],
"handler": {
"name": "com.technia.tvc.collaboration.discussion.model.dao.enovia.example.watcher.EverythingWatcher",
"config": {
"key": "value"
},
}
},
...
}
...
}
Type: AssigneeType
fixed or custom value. options are,
"person"
"role"
"group"
"user"
"memberlist"
or any class implementing "com.technia.tvc.collaboration.core.model.Assignee"
e.g.
{
...
"assignees" : [
{
...
"type": "role",
...
},
{
...
"type": "com.technia.tvc.collaboration.discussion.model.dao.enovia.example.assignee.CustomAssignee",
...
}
]
...
}
Type: String
Watcher name that can match the WatcherType configured.
e.g.
{
...
"watcher" : {
...
"type": "user",
"values": [
"Adam Sandler",
"Software Quality Engineering",
"Will Smith"
],
...
}
...
}
Type: WatcherHandler | WatcherHandlerCfg
Type: WatcherHandlerCfg
Schema
{
"name": WatcherHandler,
"config": WatcherHandlerConfig
}
Represents a WatcherHandler, that is used in Watcher.
e.g.
{
...
"handler": "com.technia.tvc.collaboration.discussion.model.dao.enovia.example.watcher.EverythingWatcher",
...
}
or
{
...
"handler": {
"name": "com.technia.tvc.collaboration.discussion.model.dao.enovia.example.watcher.EverythingWatcher",
"config": {
"key": "value"
}
}
...
}
Type: String
refers a class’s full name which implements com.technia.tvc.collaboration.workflow.model.dao.enovia.config.WatcherHandler.
e.g.
{
...
"handler": "com.technia.tvc.collaboration.discussion.model.dao.enovia.example.watcher.EverythingWatcher",
...
}
or
{
...
"handler": {
"name": "com.technia.tvc.collaboration.discussion.model.dao.enovia.example.watcher.EverythingWatcher",
}
...
}
Type: Map<Object,Object>
any custom configuration values. This configuration will be available for WatcherHandler.
e.g.
{
...
"handler": {
"name": "com.technia.tvc.collaboration.discussion.model.dao.enovia.example.watcher.EverythingWatcher",
"config": {
"key": "value"
}
}
...
}
Type: String | OperationCfg
refers a OperationId (recommended as it enables reuse) or inline OperationCfg.
e.g.
{
...
"workflow": {
...
"operations": [
"add",
"delete",
"stop",
"restart",
"terminate"
]
...
}
...
}
Type: Array
List of actions which need to be executed on workflow.
e.g.
{
...
"actions": [
"custom-trigger",
{
"events": [
"Started",
"Stopped",
"Terminated"
],
"trigger": "promote",
"config": {
"privileged": true
}
}
],
...
}
Type: Boolean
All the task assignee get the notification on workflow creation by default. The following configuration could be used to control this behaviour and send the notification only to the initially activated task assignee.
e.g.
{
...
"notifyAllOnStart": false,
...
}
Following TVC property can be used to control this behavior at global level.
Property | Description | Default Value |
---|---|---|
tvc.collaboration.workflow.notifyAllOnStart |
To control the notification send on workflow creation to all task assignee or only active task assignee |
true |
Type: Boolean
Refers to workflow history icon to show the workflow history. The default value is true.
tvc.collaboration.workflow.history TVC property can be used to control the display of workflow history icon at the system level. The default value is true.
|
e.g.
{
...
"history": false,
...
}
With the use of workflowhistory
built-in trigger task operation’s custom history could be added under workflow.
"tasks":[{
...
"actions":["workflowhistory"],
...
}]
Type: Boolean
Workflow Form Template is used to save the prefilled assignee and field values as templates so that users can quickly apply saved templates during the setup new workflow.
By default save template menu is enabled for all the workflow json config. The following system property could be used to hide the save template menu globally.
Property | Description | Default Value |
---|---|---|
tvc.collaboration.workflow.saveFormTemplate |
To show the save template menu |
true |
To disable this behavior only to a specific workflow json, saveFormTemplate
property is introduced which could be defined as below
"workflow":{
...
"saveFormTemplate":"false",
...
}
The <WorkflowConfigProvider>
element allows to provide dynamic Workflow Configuration for the context object.
The full name of the class which implements the interface "com.technia.tvc.collaboration.workflow.cfg.WorkflowConfigProvider" is configured in attribute "className".
e.g.
A basic Route Template based provider is part of the installation. RouteWorkflowConfigProvider finds the available "Route Templates" in ENOVIA and converts them as TVC WorkflowConfigs.
package com.technia.tvc.collaboration.workflow.cfg.provider.impl;
public class RouteWorkflowConfigProvider implements WorkflowConfigProvider {
@Override
public String getId() {
return "Example Route Based Template Config Provider";
}
@Override
public Collection<WorkflowConfig> getConfigs(ConfigContext ctx, boolean best) throws TVCException {
switch(ctx.getMode()){
case FILTER :
// return EMPTY list of BLANK config with custom FILTER panel config
case TOOLBAR:
// return BLANK config with only id along with custom menu if any
case CONTEXT:
// return EMPTY list of BLANK config with custom context info reolver
case CONFIG:
return getRouteConfigs();
}
}
....
}
NOTE:
Workflow configs are fetched through getConfigs
API. The API is invoked multiple times to get multiple child configs. There could be a performance issue with the workflow config provider when multiple lines of code or DB calls are executed to get the workflow configs.
Workflow configs could be returned based on the condition which can get through the getMode
method of ConfigContext
. An Empty list or blank config with custom Toolbar/filter/contextInfoResolver if any could be returned based on the config mode.
There are the following config modes.
FILTER : to get the panel filter config
TOOLBAR : to get the panel toolbar config.
CONTEXT : to get the ContextInfoResolver config.
CONFIG : It is the default mode. JSON Config is required to create the workflow.
Apart from WorkflowConfig and [JSONConfig], a Java based Builder API is available to create the Workflow Config JSON using Java.
e.g.
...
public WorkflowConfig createConfig() throws TVCException {
try {
JsonConfigValue json = new JsonConfigValue.Builder().setVersion(1.0f)
.setLabel("Global Sample Workflow (Builder)")
.setId("global-sample-builder")
.setDefault(new DefaultCfgValue.Builder()
.setDue(new DueCfgValue.Builder("default").setDays(1)
.setActivation(Activation.TASK_ACTIVATED)
.build())
.setField(new FieldCfgValue.Builder("default").setLabel("default")
.setMultiline(false)
.setAppearance(Component.CREATE, Appearance.READABLE)
.setAppearance(Component.REASSIGN, Appearance.EDITABLE)
.setAppearance(Component.THREAD, Appearance.HIDDEN)
.setAppearance(Component.APPROVE, Appearance.READABLE)
.setAppearance(Component.COMPLETE, Appearance.READABLE)
.setAppearance(Component.REJECT, Appearance.READABLE)
.setAppearance(Component.ASSIGN, Appearance.READABLE)
.build())
.setTask(
new TaskCfgValue.Builder("default").setSignature(false)
.setMandatory(true)
.setMultiple(true)
// .setRepeatable(false)
.setFields("comments")
.setOperations("approve", "reject", "assign")
.build())
.build())
.addDue(new DueCfgValue.Builder("due-task-1").setDays(1)
.setActivation(Activation.WORKFLOW_STARTED)
.build())
.addOperation(new OperationCfgValue.Builder("operation-reassign-task")
.setAccess(new AccessCfgValue.Builder("access-inverse")
.setConfig(new StructBuilder().set(CustomAccess.INVERSE, true).build())
.setExcludes("Test Everything", "Adam Sandler")
.setIncludes("Jennifer Aniston", "Will Smith")
.setAccess(CustomAccess.class)
.build())
.setConfig(new StructBuilder().set("key", "value").build())
.setOperation("reassign")
.setUsers(User.ASSIGNEE, User.OWNER, User.PARTICIPANT)
.setWhere(null)
.setTaskStatuses(TaskStatus.APPROVED)
.build())
.addField(new FieldCfgValue.Builder("field-mos").setLabel("Meaning of signature")
.setValue("this is Approval")
.build())
.addField(new FieldCfgValue.Builder("field-custom-value").setLabel("Custom Value")
.setValue("sample custom value field")
.build())
.addField(new FieldCfgValue.Builder("field-context-name").setLabel("Context Object Name")
.setHandler(new FieldValueHandlerCfgValue.Builder(NameFieldValueHandler.class, null).build())
.build())
.addAssignee(new AssigneeCfgValue.Builder("assignee-task-1").setAssigneeType(AssigneeType.PERSON)
.setValues("Will Smith")
.setAutocomplete("person")
.setAppearance(Component.CREATE, Appearance.READABLE)
.build())
.addAssignee(new AssigneeCfgValue.Builder("assignee-task-2.1").setAssigneeType(CustomAssignee.class)
.setHandler(CustomAssigneeHandler.class)
.setAutocomplete(CustomAssigneeAutocompleteHandler.class)
.build())
.addAssignee(new AssigneeCfgValue.Builder("assignee-task-2.2").setAssigneeType(AssigneeType.PERSON)
.setAutocomplete(new AssigneeAutocompleteCfgValue.Builder("person").setConfig(new StructBuilder()
.set("roles", new ArrayBuilder().item("Design Engineer", "role_LibraryUser").build())
.build()).build())
.build())
.addAssignee(new AssigneeCfgValue.Builder("assignee-task-3").setAssigneeType(AssigneeType.USER)
.setAutocomplete("user")
.setValues("Adam Sandler", "Software Quality Engineering", "Will Smith")
.build())
.addTrigger(new TriggerCfgValue.Builder("action-flow-complete")
.setEvents(Arrays.asList(TaskStatus.APPROVED))
.setTrigger("flowstatus")
.setConfig(new StructBuilder().set("status", "complete").build())
.build())
.addTrigger(new TriggerCfgValue.Builder("action-any-rejected")
.setEvents(Arrays.asList(TaskStatus.REJECTED))
.setTrigger("demote")
.setConfig(new StructBuilder().set("privileged", false).build())
.build())
.addTrigger(new TriggerCfgValue.Builder("action-custom-history")
.setEvents(Arrays.asList(TaskStatus.APPROVED))
.setTrigger("history")
.setConfig(new StructBuilder().set("privileged", false).set("value", "custom history info").build())
.build())
.addTrigger(new TriggerCfgValue.Builder("action-panel-table-refresh")
.setEvents(Arrays.asList(TaskStatus.APPROVED, TaskStatus.COMPLETE, TaskStatus.REJECTED))
.setTrigger("script")
.setConfig(new StructBuilder().set("script", "(function(){ top.refreshTablePage(); }())")
.set("modules", new ArrayBuilder().item("panel", "myspace", "collaboration").build())
.build())
.build())
.addTask(new TaskCfgValue.Builder("task-1").setLabel("Task 1 (role)")
.setSignature(true)
.setAppearance(Appearance.VISIBLE)
.setActions("history", "action-panel-table-refresh")
.setFields("comments", "instructions")
.setOperations("complete", "reassign", "assign")
.setDue("due-task-1")
.setRepeatable(true)
.setAssignee("assignee-task-1")
.build())
.addTask(new TaskCfgValue.Builder("task-2.1").setLabel("Task 2.1 (custom)")
.setActions("history", "action-panel-table-refresh")
.setFields("instructions")
.setOperations("complete", "reassign", "assign")
.setAssignee("assignee-task-2.1")
.build())
.addTask(
new TaskCfgValue.Builder("task-2.2").setLabel("Task 2.2 (person-in-role)")
.setSignature(true)
.setActions("history", "action-panel-table-refresh")
.setFields("comments", "field-mos", "field-context-name", "field-custom-value",
"instructions")
.setOperations("complete", "reassign", "assign")
.setAssignee("assignee-task-2.2")
.build())
.addTask(new TaskCfgValue.Builder("task-3").setLabel("Task 3 (user)")
.setSignature(true)
.setMultiple(true)
.setActions("history", "action-panel-table-refresh")
.setFields("comments")
.setRepeatable(true)
.setOperations("complete", "assign")
.setAssignee("assignee-task-3")
.build())
.setWorkflow(
new WorkflowCfgValue.Builder()
.setFlow(new Flow(new Flow(new TaskCfgValue.Builder("task-1").build(),
new Flow(new TaskCfgValue.Builder("task-2.1").build(),
new TaskCfgValue.Builder("task-2.2").build()),
new TaskCfgValue.Builder("task-3").build())))
.addTrigger(new TriggerCfgValue.Builder("action-custom-promote")
.setEvents(Arrays.asList(WorkflowStatus.COMPLETE))
.setTrigger("promote")
.setConfig(new StructBuilder().set("privileged", true).build())
.build())
.setWatcher(new WatcherCfgValue.Builder("watcher-flow").setValues("Jennifer Aniston")
.setHandler(new WatcherHandlerCfgValue.Builder().setName(EverythingWatcher.class)
.setConfig(new StructBuilder().set("key", "value").build())
.build())
.build())
.build())
.build();
WorkflowConfig config = new WorkflowConfig.Builder(json).setUIEnabled(true).build();
return config;
} catch (Exception ex) {
throw new TVCException(ex);
}
}
...
It is possible to configure something called advanced filter in order to control the data loaded for this component. This type of filtering is able to load and filter on data that has been indexed by Exalead. This can be used to filter out both notifications in the inbox and workflows in the side panel. These filters can be hidden or visible so that the user can change values in the UI.
In order to enable a filter you can reference a filter configuration in your TVCWorkflowConfig.xml file like this.
<Filter ref="tvc:collaborationfilter:tvx:collaboration/Product.xml" />
<Filter>
elementThe base element for the actual filter configuration is the <Filter> element. That one has a number of attributes that can be used to control some behavior for the entire filter.
<Filter showOnLoad="true" visibleRowCount="3" visible="true">
Attribute | Description | Default Value |
---|---|---|
showOnLoad |
Show filter on load or not (if set to false the user will have to click the filter icon to show the filter |
true |
visibleRowCount |
How many filter rows (rows described later) that will be showed on load. Visibility of rest can be toggled by the user. |
|
visible |
Whether the filter should be shown or be hidden |
true |
<Row>
elementEach filter can have any amount of rows. A row corresponds to a row in the filter user interface. Each row can have a label set and that will then be rendered to the far left. Each row can then have a single or multiple filter items. A row can be hidden using the "visible" attribute.
<Row visible="true">
<Label>Anything</Label>
<FilterItem>..</FilterItem>
<FilterItem>..</FilterItem>
</Row>
<FilterItem>
A <FilterItem>
represents an element that can be used to filter data
(textfield, dropdown, button etc.). Each filteritem maps against one or
multiple values that has been indexed by Exalead. Below is a complete
example of a filteritem. Each element described after the example
<FilterItem>
<Label>Workflow Status</Label>
<Operator>EQUAL</Operator>
<LogicalOperator>OR</LogicalOperator>
<MapsTo>
<Field>
<Name>TVC_COLLAB_WORKFLOW_STATUS</Name>
</Field>
</MapsTo>
<Values>
<Value selected="true">
<SubmitValue>Active</SubmitValue>
<DisplayValue>Active</DisplayValue>
</Value>
<Value>
<SubmitValue>Pending</SubmitValue>
<DisplayValue>Pending</DisplayValue>
</Value>
<Value>
<SubmitValue>Complete</SubmitValue>
<DisplayValue>Complete</DisplayValue>
</Value>
<Value>
<SubmitValue>Stopped</SubmitValue>
<DisplayValue>Stopped</DisplayValue>
</Value>
</Values>
<UIControl>textbutton</UIControl>
</FilterItem>
<Operator>
Can be used to control what operator to use for this field item. It is not mandatory to specify this.
EQUAL (default)
NOT_EQUAL
LESS_THAN
GREATER_THAN
<LogicalOperator>
Can be used to control what logical operator to use for this field item. Not mandatory to set this.
OR (default)
AND
<MapsTo>
This element is used to map this field against either tags or indexed fields in Exalead. In order to filter on tags one or more <Tag> elements are used and in order to filter on fields one or more <Field> elements are used.
<MapsTo>
<Tag>
<Name>category</Name>
</Tag>
<Field>
<Name>TVC_COLLAB_WORKFLOW_STATUS</Name>
</Field>
</MapsTo>
<UIControl>
This element is used to control what type of UI control to use for this field. Supported values are:
Dropdown list with possibility to select ONE value.
Dropdown list with possibility to select MULTIPLE values.
Text field where user can enter any text
Yes/No buttons
Buttons containing custom values. (Each value renders as a button)
Some of these elements require you to configure the values that can be used. See next section
<Values>
This element is used to configure the allowed values for a <UIControl>
.
All UI controls except BOOLEANBUTTON
and TEXT
requires one or more
values. Each value has a submit-value that is sent to the server and a
display-value that is rendered for the user. A value can be configured
to be default selected with the attribute "selected"
<Values>
<Value>
<SubmitValue>MHK</SubmitValue>
<DisplayValue>MHK</DisplayValue>
</Value>
<Value selected="true">
Values can also be loaded through Java code like this.
<Values valueHandler="com.technia.tvc.example.valuehandler.ObjectIdValueHandler"/>
The value handler class needs to implement the
com.technia.tvc.collaboration.core.model.dao.enovia.config.ValueHandler
(deprecated) interface.
ValueHandler
interface has been deprecated in favour of
com.technia.tvc.collaboration.core.model.dao.enovia.config.FilterValueHandler
.
Mine FilterItem Configuration
<FilterItem>
<Label>Categories</Label>
<Operator>EQUAL</Operator>
<LogicalOperator>AND</LogicalOperator>
<Type>mine</Type>
<UIControl>textbutton</UIControl>
</FilterItem>
Due FilterItem Configuration
<FilterItem>
<Label>Categories</Label>
<Operator>EQUAL</Operator>
<LogicalOperator>AND</LogicalOperator>
<Type>due</Type>
<UIControl>textbutton</UIControl>
</FilterItem>
Assigned FilterItem Configuration
Filter workflows based on Active tasks which are assigned to context user.
<FilterItem>
<Operator>EQUAL</Operator>
<LogicalOperator>AND</LogicalOperator>
<Type>assigned</Type>
<Value>
<SubmitValue>Assigned</SubmitValue>
<DisplayValue>Assigned</DisplayValue>
</Value>
<UIControl>textbutton</UIControl>
</FilterItem>
It is possible to enable Exalead powered feature and filter in enovia mode by setting the following system property key:
tvc.collaboration.enovia.filter=true
We could have performamce issue in comparision of exalead mode as searching mechanism is different in case of enovia and exlead mode.
In Enovia mode, the same configurations which are defined for Exalead Powered feature need to be done to use the filter and features such as Unread, Archive, To ME, CC Me, Followup etc…
Following fields must be added in Exalead Indexed Configuration file.
<BOTYPEFIELDS name="TVCCollaborationMXCriteria">
<FIELD name="TVC_COLLAB_MX_NOTIFICATION_USER_NAME"
select="to[TVC Collaboration Notification].from.owner"
type="STRING" />
<FIELD name="TVC_COLLAB_MX_WORKFLOW_CONTEXT_ID"
select="to[TVC Collaboration Set].from.to[TVC Collaboration Object Proxy].from.id"
type="STRING" />
<FIELD name="TVC_COLLAB_MX_THREAD_CONTEXT_ID"
select="to[TVC Collaboration Discussion].from.to[TVC Collaboration Discussion Container].from.id"
type="STRING" />
<FIELD name="TVC_COLLAB_MX_WORKFLOW_CONTEXT_PHYSICAL_ID"
select="to[TVC Collaboration Set].from.to[TVC Collaboration Object Proxy].from.physicalid"
type="STRING" />
<FIELD name="TVC_COLLAB_MX_THREAD_CONTEXT_PHYSICAL_ID"
select="to[TVC Collaboration Discussion].from.to[TVC Collaboration Discussion Container].from.physicalid"
type="STRING" />
<FIELD name="TVC_COLLAB_MX_THREAD_SENT_TO"
select="from[TVC Collaboration Thread Message].to.from[TVC Collaboration Sent To].to.owner"
type="STRING" />
<FIELD name="TVC_COLLAB_MX_NOTIFICATION_UNREAD_USERS"
select="to[TVC Collaboration Notification|attribute\[TVC Collaboration Unread Count\]>0].from.owner"
type="STRING" />
<FIELD name="TVC_COLLAB_MX_THREAD_LAST_MSG_SENT_TO"
select="from[TVC Collaboration Last Message].to.from[TVC Collaboration Sent To|attribute\[TVC Collaboration Recipient Type\]==0].to.owner"
type="STRING" />
<FIELD name="TVC_COLLAB_MX_THREAD_LAST_MSG_SENT_CC"
select="from[TVC Collaboration Last Message].to.from[TVC Collaboration Sent To|attribute\[TVC Collaboration Recipient Type\]==1].to.owner"
type="STRING" />
<FIELD name="TVC_COLLAB_MX_FOLLOWUP_USER_NAME"
select="to[TVC Collaboration Followup].from.owner"
type="STRING" />
<FIELD name="TVC_COLLAB_MX_THREAD_FIRST_MSG_SENT_TO"
select="from[TVC Collaboration First Message].to.from[TVC Collaboration Sent To].to.owner"
type="STRING" />
<FIELD name="TVC_COLLAB_MX_TASK_ASSIGNED"
select="from[TVC Collaboration Item].to[|attribute\[TVC Collaboration Task Status\]==Active].owner"
type="STRING" />
<FIELD name="TVC_COLLAB_MX_TASK_STATUS"
select="from[TVC Collaboration Item].to[*|revision==last].attribute[TVC Collaboration Task Status]"
type="STRING" />
</BOTYPEFIELDS>
Multiple JPOs have been configured for mutiple filters for Exalead mode. These fields has been introduced to improve the performance on some extent by avoiding these JPO invocation.
Collaboration Panel can be used in variety of mode. ex: standalone, embedded, cross-domain. When using Helium in embedded mode, there could be double side panels. To avoid such situation and also to control which mode Collaboration Panel is enabled, following configurations can be used.
Property | Description | Default Value |
---|---|---|
tvc.collaboration.panel.classic.standalone |
Enabling classic collaboration panel in standalone (using tvcCollaborationPanelContent.jsp directly) |
true |
tvc.collaboration.panel.classic.embedded |
Enabling classic collaboration panel in embedded (default collaboration setup in ENOVIA or using tvcCollaborationPanelContent.jsp in iframes) |
true |
tvc.collaboration.panel.classic.crossdomain |
Enabling classic collaboration panel in cross-domain (using tvcCollaborationPanelContent.jsp in cross-domain iframe) |
true |
tvc.collaboration.panel.helium.standalone |
Enabling helium collaboration panel in standalone (default collaboration setup in Helium) |
true |
tvc.collaboration.panel.helium.embedded |
Enabling helium collaboration panel in embedded (using Helium in ENOVIA embedded mode) |
false |
tvc.collaboration.panel.helium.crossdomain |
Enabling helium collaboration panel in cross-domain (using Helium in ENOVIA cross domain embedded mode) |
true |
Workflow can be created in context of multiple objects using collaboration javascript API.
e.g.
Following javascript can be called from command to launch the create dialog of workflow in context of multiple objects.
top.getCollaborator().openCollaborationPanel(['14668.27509.6640.55228', '14668.27509.6641.7837', '14668.27509.36080.39209'], { component: 'workflow', launchCreate: true });
Date formats inside collaboration user interface can be configured to display custom date format.
Collaboration component uses moment.js version 2.4.0 (http://momentjs.com/) for date/time display. So supporting formats documented here http://momentjs.com/docs/#/displaying/format/ and also a custom format "fromNow" equivalent to moment.js’s "fromNow" functionality.
Below properties can be configured to format the date used in sections of the collaboration component.
Property | Description | Default Value |
---|---|---|
tvc.collaboration.date.convert.userPreferenceTimeZone |
Format the date depending on user preference timezone. Refer Figure 24. |
true |
tvc.collaboration.workflow.task.dateFormat |
Date format used in Workflow task |
fromNow |
tvc.collaboration.workflow.list.dateFormat |
Date format used in Workflows List |
fromNow |
Use |
operator to pass multiple date formats as shown below.
tvc.collaboration.workflow.task.dateFormat="YYYY-MM-DD, HH:mm:ss |
fromNow"
Additional property configurations for Collaboration
Property | Description | Default Value |
---|---|---|
tvc.collaboration.toastr.timeout |
How long the toast alert will display (in Millisecond) |
5000 (set 0 to stay indefinitely until closed) |
Additional resources like JavaScript, CSS, AjaxService and Custom Template can be included in workflow component.
<JavaScript>
, <StyleSheet>
, <AjaxService>
and <Template>
element can be repeated to support multiple resource inclusion.
<Resources>
configuration can be under configuration elements like <MySpaceConfig>
, <MySpaceAction>
, <TopbarConfig>
, <WorkflowConfigs>
, <WorkflowConfig>
.
<WorkflowConfigs>
<Resources>
<StyleSheet src="/tvx/collaboration/layout-styles.css"/>
<Template id="panel/layout" src="/tvx/collaboration/panel-layout.hbs"/>
</Resources>
<WorkflowConfig for="type_Part">
<Resources>
<JavaScript src="/tvx/js/custom.js" />
<AjaxService service="messages" />
</Resources>
</WorkflowConfig>
<TopbarConfig>
<Resources>
<StyleSheet src="/tvx/css/custom.css" />
<Template id="customTemplate" src="/tvx/template/custom.jsp" />
</Resources>
</TopbarConfig>
<MySpaceConfig>
<Resources>
<StyleSheet src="/tvx/collaboration/layout-styles.css"/>
<Template id="myspace/layout" src="/tvx/collaboration/myspace-layout.hbs"/>
</Resources>
<WorkflowAction>
<Resources>
<AjaxService service="tvxCollaborationService"/>
<AjaxService service="jsontest"/>
<JavaScript src="/tvx/collaboration/inboxCustomScript.js"/>
<StyleSheet src="/tvx/collaboration/inboxCustomStyles.css"/>
</Resources>
<ContextMenu ref="tvc:menu:tvx:collaboration/InboxContextMenu.xml"/>
</WorkflowAction>
<ProfileAction>
<Resources>
<StyleSheet src="/tvx/css/custom.css"/>
</Resources>
</ProfileAction>
</MySpaceConfig>
</WorkflowConfigs>
Ex: inboxCustomScript.js
tvc.define('script.tvx', [ 'collaborator.ready!', 'ajax.tvxCollaborationService' ],
function($collaborator, tvxCollaborationService) {
var tvx = {
fakeDelete : function($event, $notification, $command, $inbox) {
tvxCollaborationService.fakeDeletePromise().then(function(result) {
$notification.addClass('fake-deleted');
alert(result);
});
}
};
return tvx;
});
Ex: InboxContextMenu.xml
...
<Command>
<Label>Fake delete (ajax example)</Label>
<Href><![CDATA[
javascript:(function($event, $notification, $command, $inbox) {
tvc.require(['script.tvx'], function(tvx) {
tvx.fakeDelete($event, $notification, $command, $inbox);
});
}($event, $notification, $command, $inbox));
]]></Href>
</Command>
...