Welcome to the administration guide for UPV Toolkit. This guide
provides detailed instructions for managing the application
efficiently.
License
The License Management section allows administrators
to manage the application’s license key. This ensures compliance and
enables access to application features. All license keys are granted by
CAXperts.
Features
1. License Key Input
Provides a secure interface to input or update the license
key.
Dynamically toggles between masked and unmasked views for the
license key by using the Eye icon to the right of the
textbox.
License input masking
2. Validation and
Feedback
Displays toast notifications to confirm successful
updates.
Ensures that the provided license key is valid and
up-to-date.
If the license key is invalid, an error notification is
displayed, and the following screen is shown.
Invalid License
License Management Actions
View and Edit License
Key
Navigate to the License page.
The current license key is preloaded in the input field upon page
load.
To update the license key:
Enter the new key in the text field.
Use the Eye icon to toggle between masked and
unmasked views of the key.
Submit the License
Key
After entering the new key, click the Upload
button.
The system performs the following actions:
Validates the license key.
Updates the license key for the project.
Displays a success notification confirming the update.
Upon successful update, you are redirected to the
Home page.
Roles
The Roles page serves as a placeholder for all roles
available in the application. These roles are sourced from Keycloak and
are used to populate dropdown selections within the system. This table
does not control user permissions but ensures that all possible roles
from Keycloak are listed for reference.
The roles page
Tips
Double-check role edits before pressing Enter to avoid accidental
changes.
Deleted roles cannot be recovered—ensure confirmation before
proceeding.
Keycloak User
Synchronization
The Toolkit includes an automated synchronization system that keeps
user accounts and their assigned roles in sync between
Keycloak (the identity provider) and the
application database.
How the Synchronization
Works
Keycloak is the Source of Truth: The
synchronization process treats Keycloak as the authoritative source for
user roles and group assignments.
Automated Daily Sync: By default, the system
runs a scheduled synchronization job every day at 3:00
AM (03:00).
What Gets Synchronized:
All users with email addresses in Keycloak are processed
User group memberships in Keycloak are compared with role
assignments in the database
Missing roles are added to the database
Extra roles (present in database but not in Keycloak) are
removed
User accounts are created or updated as needed
Configuration
The synchronization behavior can be customized using environment
variables in your deployment configuration:
Enable/Disable
Synchronization
ENABLE_CRON=true
Set this to true to enable the cron job system
(including user synchronization). Set to false or leave
empty to disable.
Customize Sync Schedule
KC_GROUP_SYNC_CRON=0 3 * * *
This variable controls when the user synchronization runs using
standard cron expression syntax (5-field format):
Note: The cron expression must be valid. If an
invalid expression is provided, the system will default back to
0 3 * * * and log a warning.
Workflows
The Workflows page allows administrators to create,
view, edit, delete and assign default workflows.
The workflows administration
page
Overview
Workflows are assigned to specific punch items. They are used to
define the steps that must be completed to resolve a punch.
The admin defines those steps and who is authorized to complete
them.
When the workflow is successfully finished (once the last step is
approved), and if the last step contains a coded step closeWorkflow(),
the punchlist item is closed.
1. Workflow Navigation
The Workflow Management page displays a list of existing
workflows and their details.
Admins can add new workflows or edit existing ones.
Navigating the workflow
2. Default Workflow Assignment
The Assign Default Workflow feature lets
administrators designate or reassign the workflow that is automatically
applied to new punch items.
This option is accessible by clicking on the Workflow Tools
dropdown menu in the management pane.
Using the assign default workflow
feature
3. Workflow Interface
Administrators can create a new workflow by clicking the
Add Workflow button.
A popup prompts users to enter a unique workflow title.
Adding a new workflow
Once inside a new/existing workflow, the administrator can start
adding steps using the Plus button in the top right of
the page.
Once a step is added the different fields in the row can be
edited by double clicking in the respective cell.
Step Number, Title, Description and Responsible Person are all
mandatory fields and must be filled in otherwise an error will be
thrown.
After making any changes, the Save button in the
top right will become active and display a red background.
Administrators can save their modifications by clicking this
button.
The step number denotes the order in which the steps will need to
be completed to successfully finish the workflow.
The workflow step can have different use actions: “None”,
“Activity”, “Decision”.
“None” does not require any interaction from a user.
“Activity” requires the user to approve or disapprove the step with a
button click.
“Decision” requires the user to approve or disapprove with or without
signature.
4. Workflow Columns
Workflow Visible Steps column specifies which
workflow steps will be visible when the workflow step is pending. The
cell accepts comma separated numbers that represent workflow
steps.
Responsible Person column specifies who is
authorized to approve or deny the workflow step. The roles that are
shown are roles that are specified by admin in Keycloak Groups.
Forward Step ID column specifies what is the
next workflow step when the pending step is approved.
Backward Step ID column specifies what is the
next workflow step when the pending step is disapproved.
Note: The default behavior of the Forward
Step ID and Backward Step ID columns can be
overridden using Custom Code functions:
stepForwardJumpTo(stepNumber: number, message: string | null):
Jumps to the specified step number and, if a message is provided, it is
printed to the activity chat. This jump is treated as a success.
stepBackwardJumpTo(stepNumber: number, message: string | null):
Jumps to the specified step number and, if a message is provided, it is
printed to the activity chat. This jump is treated as a failure.
When used, these functions take priority over the Forward
Step ID and Backward Step ID values defined in the workflow
table.
5. Workflow Code
Allows users to define Custom Code that is
run when workflow step is accepted or disapproved.
Before saving the code, it must be compiled with a mockup interface
that does not influence original punch items. The admin can choose
different punches for examplary compilation if they specify a number in
“PunchlistID for compilation” field. If the compilation is successful
the code can be saved.
Related Features:
Use Event Listeners to trigger
actions based on workflow events (step acceptance, field changes,
etc.)
Use Field Validators to enforce data
validation rules before field values are saved
6. Workflow Email Message
Allows users to send an email with the provided html body to the
specified responsible group in the workflow step.
Available Dynamic Variables:
Ticket Fields - Include any punch field
value:
${Details["<field name>"]}
Example:
Pipe in Area System: ${Details["Area System"]} broken.
Ticket ID - Include the punch item ID:
${PunchItem}
Example:
Ticket #${PunchItem} requires attention.
Server Address - Include the application server
URL:
Example:
This notification was sent on ${Date("yyyy-MM-dd")}
Email Template Example:
<h2>Ticket Update Notification</h2><p>Dear Team,</p><p>Ticket <strong>#${PunchItem}</strong> has been updated.</p><ul><li><strong>Status:</strong> ${Details["Status"]}</li><li><strong>Priority:</strong> ${Details["Priority"]}</li><li><strong>Area System:</strong> ${Details["Area System"]}</li><li><strong>Date:</strong> ${Date("MMMM dd, yyyy")}</li></ul><p><a href="${serverAddress}/tickets/${PunchItem}">Click here to view the ticket</a></p><p>This is an automated notification from ${serverAddress}</p>
Note: Subject lines can also use dynamic variable
replacement with the same syntax shown above.
Workflows Kanban
The Kanban Settings page allows administrators to
configure the appearance of the Kanban cards that appear in the
“Planning” section by selecting fields for the title,
subtitle, and content zones. These settings impact how information is
displayed within the Kanban view, enabling a tailored experience to suit
specific workflows.
The workflows kanban settings
page
Kanban Settings Actions
Purpose: Define what information appears on the
Kanban cards for the title, subtitle, and content areas.
How to Use:
Open the drop-down menus for Title,
Subtitle, and Content.
Select a field from the list of available options, which are
fetched from the system’s punch details available fields.
Adjusting the fields
Each selection updates the Kanban card preview in real time,
allowing you to instantly see how your choices affect the card layout.
The preview is displayed to the right of the select boxes.
The values from the fields you select in the drop-down menus will
automatically populate the corresponding sections of each individual
Kanban card.
Utilizing the drop-down
menus
After finalizing your selections, click the Save
button.
A confirmation message will appear, notifying you that the
settings have been saved successfully.
Punchlist Fields
The Punchlist Fields page allows administrators to
add, configure and manage available punchlist fields effectively. These
fields define how information is structured and displayed in punchlists,
ensuring adaptability to various workflows and requirements.
Punchlist fields
Managing Punchlist Fields
Administrators can add, edit, delete, and reorder punchlist fields
using the following actions:
Adding a New Punchlist Field
Add a Field:
Click the Plus (+) button in the top right corner
to add a new punchlist field.
Fill in Field Details:
Fields are accessed by single-clicking on the respective cell.
Detail (Required): Enter the name of the
punchlist field.
Type (Required): Select the field type. See
options below.
dxTextBox: A textbox for user input of text
data.
dxSelectBox: A dropdown select box allowing users
to choose from predefined options. These options are specified by the
administrator in the “Items” column.
dxDateBox: A date picker for selecting dates.
dxHyperLink: A hyperlink element that navigates to
a user specified URL.
Breakline: Inserts a horizontal line to separate
content sections in punchlist user form.
Additional Options:
Column Span: Specify the number of columns this
field should occupy on the punch item’s detail page.
Default View: Choose whether this field should
be displayed by default in the main punchlist table.
Items (for Selectbox): If the type is Selectbox,
specify the available options in the Items
column.
Editors: Grant the selected roles permission to
edit the specified field. The field will be in a read-only state for
roles not included in this option.
Making a field read-only
Save or Revert:
Save: Click the Save button at
the end of the row to save the new field.
Revert: Click the Revert button
to discard the new entry.
Editing an Existing
Punchlist Field
Click the Pencil icon at the end of the row
corresponding to the field you wish to edit.
Modify the necessary details.
Click Save to apply changes or
Revert to cancel.
Deleting a Punchlist Field
Click the Trash icon at the end of the row for
the field you want to delete.
Warning: Deleted fields cannot be recovered.
Confirm the deletion when prompted.
Reordering Punchlist Fields
Drag and Drop:
Click and hold the Six-Dot icon (⋮⋮) to the left
of a row.
Drag the row to your desired position within the table.
Release to drop the row in the new position.
The order of the rows in the table defines the order in which the
fields appear in the punchlist user form.
Re-ordering fields
Attribute Mapping
The Attribute Mapping section enables administrators
to define relationships between ticket detail fields and model
attributes. These mappings are applied to the comments of ticket items
that are created using the “Create with Comment” option
in main tickets table.
The attributes mapping page
Features
1. Mapping Interface
Overview
Punch Details List: Displays un-mapped ticket
details available for mapping.
Mapped Attributes List: Lists existing mappings
with details such as the mapped attribute(s) and type (2D, 3D, or
Code).
2. Mapping Actions
Add Detail to Mapping
Click the “+” button to move the detail to the mapped attributes
list.
The detail is now ready to be mapped to an attribute.
Select up to 3 ticket details to generate a custom ticket
comment.
Adding detail to mapping
Map Attribute to Detail
In the Mappings pane click the
Edit button of the field you would like to map an
attribute to.
This will open a pop-up that has options to either map to a 3D,
2D or custom code attribute.
Click on any of these options to choose a mapping type:
3D Single Mapping: Map the field to a 3D
attribute. A list is available for the administrator to select from
which contains all possible model attributes.
2D Single Mapping: Map the field to a 2D
attribute. These attributes can be user-defined in the textbox.
Creating a ticket with the option “Create with Comment” now reflect
changes made with regards to attribute mapping:
Create with Comment
Delete Mapping
Click the Trash button next to a mapped
attribute to remove the mapping.
The detail returns to the Ticket Details list
for future use.
Event Listeners
The Event Listeners section provides administrators
with tools to manage event-driven automation throughout the Toolkit
application. Event listeners enable custom actions or behaviors
triggered by specific conditions, such as field value changes, workflow
actions, ticket creation, email sending, or scheduled intervals.
Unlike Field Validators which
prevent invalid data from being saved, event listeners
react to events after they occur, executing custom code
to automate workflows, send notifications, update related fields, or
trigger external integrations.
The event listener section
Understanding Listener Types
Each listener must have a Type that determines when
and how it triggers. The listener’s required fields vary based on the
selected type. Administrators must select the appropriate type and
configure type-specific fields to create functional listeners.
Available Listener Types
1. onWorkflowAccepted
Description: Triggers when a specific workflow step
is accepted by a user.
When it triggers: After a user approves/accepts a
workflow step and the step status changes to “Accepted”.
Required Fields:
Type: onWorkflowAccepted
Checked Field: Step number (e.g., “1”, “2”,
“3”)
Checked Value: “Accepted”
Workflow ID: The workflow this listener applies
to
Custom Code: JavaScript code to execute when
triggered
Description: Triggers when a new ticket is
created.
When it triggers: Immediately after a new ticket is
created in the system.
Required Fields:
Type: onTicketCreated
Default: Typically set to true (apply
to all new tickets)
Custom Code: JavaScript code to execute when
triggered (can include filtering logic)
Use Cases:
Auto-assign new tickets based on criteria
Set initial field values
Send creation notifications
Apply default workflows
Example:
Type: onTicketCreated
Default: true
Custom Code:
const area = getTicketValue("Area");
if (area === "Engine Room") {
setTicketValue("AssignedTo", "engineering@example.com");
}
4. onEmailSend
Description: Triggers when an interaction email is
sent from the support ticket system, filtered by regex patterns matching
the email subject and/or body content.
When it triggers: After an email is sent through the
Interactions feature, if the email subject or body matches the specified
regex patterns.
Required Fields:
Type: onEmailSend
Subject Regex: Regular expression pattern to match
email subject (max 500 characters)
Content Regex: Regular expression pattern to match
email body (max 500 characters)
Custom Code: JavaScript code to execute when
triggered
Important Notes:
The system tracks processed emails using the
ProcessedEmailListeners table to prevent duplicate triggers
for the same email
Both regex fields are optional, but at least one should be specified
for effective filtering
Regex patterns are case-sensitive unless specified otherwise in the
pattern
Use Cases:
Track specific keywords in outgoing emails
Log emails containing certain phrases
Trigger actions based on email content (e.g., escalate tickets with
“urgent” in subject)
Create audit trail for compliance
Regex Examples:
Match emails with “Invoice” in subject:
Subject Regex: Invoice
Content Regex: (leave empty or .*)
Match emails containing specific order numbers in
body:
Type: onPunchlistDetail
Checked Field: Status
Checked Value: Closed
Default: true
Workflow ID: (can be null)
Custom Code: setTicketValue("ClosedDate", Date())
→ Triggers for all tickets when Status changes to
“Closed”, regardless of workflow
Disabled Flag
Type: Boolean (checkbox) Default
Value: false
Purpose: The Disabled flag
completely stops listener execution without deleting the
configuration.
How it works:
Disabled = false: Listener is active and will
trigger when conditions are met
Disabled = true: Listener is completely inactive
and will never trigger, even if conditions are met
Special behavior for onTicketOverdue:
Setting Disabled = true stops the associated cron
job
Setting Disabled = false starts/resumes the cron
job
When to use Disabled = true:
Temporarily pause automation during maintenance
Disable problematic listeners while debugging
Seasonal or conditional listeners (enable/disable as needed)
Testing alternative implementations
Best Practice: Use Disabled instead of deleting
listeners to preserve configuration for future use.
Listeners Table
The listeners table
The Listeners Table:
Displays all configured event listeners in a tabular format
Shows Type, Checked Field, Checked Value, Workflow, Default,
Disabled, and other type-specific columns
Provides an interface to add, edit, and delete listeners
Integrates with punch workflows and punch details
Managing Event Listeners
Add a Listener
Click the Add Row (+) button above the
table
Select the Type from the dropdown (required
first step)
Enter the type-specific required fields:
For onWorkflowAccepted: Checked Field (step
number), Checked Value (“Accepted”), Workflow ID
For onPunchlistDetail: Checked Field (field name),
Checked Value (trigger value), Workflow ID or Default
For onTicketCreated: Default (typically true)
For onEmailSend: Subject Regex and/or Content
Regex
For onTicketOverdue: Interval (cron expression),
Overdue (milliseconds)
Configure special flags:
Default: Check to make listener
workflow-independent (applies globally)
Disabled: Check to temporarily disable the
listener
Write Custom Code:
Click the Custom Code cell to open the code editor
Write JavaScript using available Custom
Code functions
Test and save the code
Press Enter or click the Save
icon at the end of the row to save the new listener
Edit a Listener
Click the Edit (pencil) icon on the listener
row
Modify any fields:
Change Type (note: required fields will change)
Update Checked Field/Value
Modify regex patterns for email listeners
Adjust Interval/Overdue for scheduled listeners
Toggle Default or Disabled flags
Update Custom Code
Click Save to apply changes
Delete a Listener
Click the Trash icon on the listener
row
Confirm deletion when prompted
Note: For onTicketOverdue listeners, deletion also
stops the associated cron job.
Test a Listener
Before Activating:
Configure the listener with Disabled = true
Test the custom code using the Custom Code editor
Verify the trigger conditions are correct
Set Disabled = false to activate
Live Testing:
Create or modify a ticket to match the trigger conditions
Verify the listener executes (check logs, email notifications, field
updates)
Review any errors in the system logs
Custom Code Integration
Event listeners utilize the full Custom
Code API. When a listener triggers, the custom code executes with
access to:
All ticket fields via getTicketValue() and
setTicketValue()
Workflow control functions like
stepForwardJumpTo()
Communication functions like sendMailTo()
File operations like createPdfReport()
Utility functions like Date()
Important: Event listeners execute
after the triggering event has already occurred and
been saved to the database. They cannot prevent or block the event
(unlike Field Validators).
Test listeners thoroughly before deploying to production
Use Default = true sparingly (only for truly global automation)
Keep custom code focused and maintainable
Performance
Avoid heavy processing in frequently-triggered listeners
For onTicketOverdue, choose appropriate intervals (avoid overly
frequent checks)
Consider using Disabled flag during high-load periods
Error Handling
Include error handling in custom code (try/catch blocks)
Test edge cases (null values, missing fields, etc.)
Monitor system logs for listener execution errors
Regex for Email Listeners
Test regex patterns before deploying
Use case-insensitive matching when appropriate:
(?i)pattern
Escape special regex characters: \., \?,
\+, etc.
Keep patterns under 500 characters
Workflow Integration
Document which workflows have listeners attached
Coordinate with workflow designers to avoid conflicts
Use Default flag consistently across related listeners
Custom Code
The Custom Code feature enables administrators to
write JavaScript code that executes custom logic and automation
throughout the Toolkit application. This powerful feature is used in
multiple components:
Workflow Steps - Execute actions when workflow
steps are accepted or disapproved
Email Message Templates - Generate dynamic email
content with ticket data
Punchfield Mapping - Transform attribute values
during ticket creation
Event Listeners - Automate actions triggered by
specific events (see Event
Listeners)
Field Validators - Enforce custom validation rules
on ticket fields (see Field
Validators)
Security & Execution
Environment
Custom code is run as JavaScript in a secured sandbox
environment with the following protections:
Sandboxed Execution: Restricts access to internal
system functions and prevents malware execution
Rate Limiting: 10 requests per minute per user to
prevent abuse
Code Length Limit: Maximum 10,000 characters per
code block
Dangerous Pattern Detection: Automatically blocks
code containing SQL injection attempts, eval(), process
access, and other security risks
Server-Side Execution: All custom code runs on the
server, never exposing sensitive operations to the client
Available Objects
Custom code has access to the following predefined objects:
userAction.Result: Contains the
result of the current workflow step action (ActionResult value)
language: String containing the
current user’s language code (e.g., “en-US”, “ko”)
Usage example:
if (userAction.Result=== ActionResult.Yes) {console.log("The step was approved");setStatus("Approved");} else {console.log("The step was disapproved");setStatus("Rejected");}
Available Functions
Ticket Management Functions
getPunchlistDetails() Returns an
object containing all ticket field names and their current values.
updatePunchlistDetails(data: Map<string, string>[])
Updates multiple ticket fields with new values. Takes an array of
objects with Detail (field name) and Value
properties.
setStatus(status: string) Sets the
status of the current ticket to the specified value.
setStatus("Closed");
closeWorkflow() Closes the current
workflow and sets the ticket status to “Closed”.
if (userAction.Result=== ActionResult.Yes) {closeWorkflow();}
Workflow Control Functions
stepForwardJumpTo(stepNumber: number, message?: string)
Jumps to the specified workflow step number as a success/forward action.
If a message is provided, it is printed to the activity chat.
This function overrides the Forward Step ID column
value.
// Jump to step 5 with a messagestepForwardJumpTo(5,"Skipping steps 2-4 - auto-approved");
Note: This function has priority over the default
Forward Step ID column when utilized for workflows.
stepBackwardJumpTo(stepNumber: number, message?: string)
Jumps to the specified workflow step number as a failure/backward
action. If a message is provided, it is printed to the activity chat.
This function overrides the Backward Step ID column
value.
// Jump back to step 1 with a messagestepBackwardJumpTo(1,"Additional information required");
Note: This function has priority over the default
Backward Step ID column when utilized for workflows.
Communication Functions
sendMailTo(recipients: string[], message: string, subject: string, attachments?: any[])
Sends an email to the specified recipients with optional
attachments.
sendMailTo( ["user@example.com","manager@example.com"],"Ticket #"+getTicketValue("PunchItem") +" has been approved.","Ticket Approval Notification");// With attachmentssendMailTo( ["user@example.com"],"Please see attached report.","Weekly Report", [reportPdfBuffer]);
createComment(message: string)
Creates a comment on the current ticket.
createComment("Automatically updated by workflow step 3");
File Operations Functions
createPdfReport(templateName?: string, ...params)
Generates a PDF report using the configured template or specified
template name. Additional parameters can be passed to customize the
report.
const reportBuffer =createPdfReport();// Or with specific templateconst customReport =createPdfReport("CustomTemplate", {includeImages:true,});
extractUpvf(fileName?: string)
Extracts a UPVF file as a buffer. If no fileName is provided, extracts
the ticket’s associated UPVF file.
const upvfBuffer =extractUpvf();// Or specific fileconst specificFile =extractUpvf("project-model-v2.upvf");
deleteUpvf(fileID: number) Deletes
a UPVF file by its ID.
deleteUpvf(123);
Utility Functions
Date(formatString?: string) Returns
the current date formatted according to the specified format string.
Default format is “yyyy-MM-dd”.
Example
1: Auto-populate fields based on status change
// When ticket is marked as "Closed", auto-populate closure date and notify teamif (getTicketValue("Status") ==="Closed") {setTicketValue("ClosedDate",Date("yyyy-MM-dd"));setTicketValue("ClosedBy", language ==="en-US"?"System":"システム");sendMailTo( ["team@example.com"],"Ticket #"+getTicketValue("PunchItem") +" has been closed.","Ticket Closure Notification" );}
Example 2: Conditional
workflow jumps
// If priority is "Critical", skip review step and go directly to approvalconst priority =getTicketValue("Priority");if (userAction.Result=== ActionResult.Yes&& priority ==="Critical") {stepForwardJumpTo(5,"Critical priority - skipping review step");} elseif (userAction.Result=== ActionResult.Yes) {stepForwardJumpTo(3,"Moving to standard review");}
Example 3: Cross-field
updates
// When Area is selected, auto-populate System based on mappingconst area =getTicketValue("Area");const areaSystemMap = {"Engine Room":"Propulsion","Bridge":"Navigation","Cargo Hold":"Cargo Handling",};if (areaSystemMap[area]) {setTicketValue("System", areaSystemMap[area]);}
Example 4: Date
calculations and validations
// Calculate and set due date to 7 days from nowconst today =newDate();const dueDate =newDate(today.setDate(today.getDate() +7));const formattedDueDate = dueDate.toISOString().split("T")[0];setTicketValue("DueDate", formattedDueDate);// Notify if ticket is overdueconst currentDueDate =newDate(getTicketValue("DueDate"));if (currentDueDate <newDate() &&getTicketValue("Status") !=="Closed") {sendMailTo( [getTicketValue("AssignedTo")],"Ticket #"+getTicketValue("PunchItem") +" is overdue!","OVERDUE: Action Required" );}
Example 5: Multi-language
support
// Send notifications in user's languageconst statusMessage = language ==="ko"?"티켓이 승인되었습니다":"Ticket has been approved";createComment(statusMessage);sendMailTo( [getTicketValue("AssignedTo")], statusMessage, language ==="ko"?"티켓 승인":"Ticket Approval");
Field Validators
The Field Validators section provides administrators
with powerful tools to enforce custom business rules and data validation
on ticket fields. Field validators trigger immediately when
ticket detail values change, validating the new value
before it is saved to the database.
Unlike Event Listeners which
react to changes after they occur, field validators
prevent invalid data from being saved in the first
place. When a validator fails, the user receives an immediate error
message via toast notification, and the field retains its previous
value.
Field validators use Custom Code with
specialized validation functions to enforce rules such as:
Data format requirements (uppercase, email format, regex
patterns)
Business logic validation (date ranges, conditional
requirements)
Cross-field dependencies (multi-field validation)
Role-based field restrictions (admins only, etc.)
Accessing Field Validators
To manage field validators:
Navigate to Settings → Workflows → Validators in
the administration menu
Select the workflow you want to configure from the dropdown
Field validators are workflow-specific - they only apply when the
selected workflow is active on a ticket
Key Differences from Event
Listeners
Feature
Field Validators
Event Listeners
Trigger Timing
Before save (immediate, on field change)
After save (event-driven)
Blocking
Blocks invalid changes - prevents save
Non-blocking - cannot prevent events
Purpose
Prevent invalid data from entering system
React to data changes with automation
User Feedback
Immediate error message in toast notification
Background execution, no immediate feedback
Multi-field Support
Yes - one validator can validate multiple fields
Single field per listener
Execution Context
Validation-specific helper functions
Full Custom Code API
Workflow Scope
Workflow-specific (only when workflow is active)
Can be workflow-specific or global (Default flag)
When to use Field Validators:
Enforce data format requirements (uppercase, email, phone
numbers)
Validate business rules before saving (end date > start
date)
Prevent invalid field values (negative numbers, invalid
statuses)
Cross-field validation (if A then B is required)
Role-based field restrictions (only admins can set certain
values)
When to use Event Listeners:
Send notifications when conditions are met
Auto-populate fields after changes
Trigger external integrations or workflows
Log events for audit trail
Schedule periodic checks
Validator Configuration
Validator Fields
When creating or editing a field validator, you configure the
following:
Workflow - Select which workflow this validator
applies to (required - validators are workflow-scoped)
Fields - Multi-select TagBox to choose one or more
fields to validate
Single-field validation: Select one field (e.g.,
“Description”)
When multiple fields are selected, the validator runs whenever ANY
of those fields change
Error Message - The message shown to the user when
validation fails (max 500 characters)
Be specific and actionable (e.g., “End Date must be after Start
Date”)
Active - Toggle to enable/disable the validator
without deleting it
Order - Execution order (drag-and-drop to reorder)
Validators execute in ascending order
Lower numbers execute first
If any validator fails, subsequent validators still run (all errors
are collected)
Custom Code - JavaScript validation logic that
returns true (allow) or false (block)
Validator Execution Flow
When a user changes a ticket field value:
Check for Active Workflows: System checks if the
ticket has any active (non-closed) workflows assigned
Find Applicable Validators: For each active
workflow, system fetches all Active validators that
include the changed field
Execute in Order: Validators execute in ascending
Order
Collect Errors: If any validator returns
false, its ErrorMessage is added to the error list
Block or Allow:
All validators pass (return true):
Change is saved to database
Any validator fails (return false):
Change is BLOCKED, error messages shown in toast, field
retains old value
Writing Validation Code
Field validator custom code must return a boolean value:
return true → Validation
PASSES (allow save)
return false → Validation
FAILS (block save, show ErrorMessage)
Validation-Specific Helper
Functions
Field validators have access to specialized functions for validation
context:
getCurrentFieldValue()
Returns: The value being validated (the new value
the user is trying to save)
Usage:
// Ensure Description field is uppercasereturngetCurrentFieldValue() ===getCurrentFieldValue().toUpperCase();
getFieldValue(fieldName: string)
Args:fieldName - Name of any field in
the ticket Returns: Current value of the specified
field
Usage:
// Cross-field validation: End Date must be after Start Dateconst startDate =newDate(getFieldValue("Start Date"));const endDate =newDate(getCurrentFieldValue());return endDate >= startDate;
getAllFields()
Returns: Object containing all field names and their
current values
Usage:
// Multi-field business logicconst fields =getAllFields();if (fields["Status"] ==="Closed"&&!fields["Resolution"]) {returnfalse;// Error: "Resolution required for closed tickets"}returntrue;
hasRole(roleName: string)
Args:roleName - Name of the role to
check Returns:true if current user has
the specified role, false otherwise
Usage:
// Only admins can set Priority to "Critical"if (getCurrentFieldValue() ==="Critical") {returnhasRole("Admin");}returntrue;
Available Context Variables
In addition to helper functions, the following variables are
available directly in validation code:
currentValue - The field value being
validated (same as getCurrentFieldValue())
fieldName - Name of the field being
validated (e.g., “Description”, “Status”)
punchDetails - Object with ALL field
values for the ticket (same as getAllFields())
userRoles - Array of current user’s
role names (e.g., ["Admin", "Editor"])
Validation Examples
Example 1: Format
Validation - Uppercase Only
Ensure a field only contains uppercase letters:
// Validation code for "Description" fieldreturngetCurrentFieldValue() ===getCurrentFieldValue().toUpperCase();
Error Message: “Description must be in uppercase
letters only”
Example 2: Format
Validation - Email Format
Validate email address format:
// Validation code for "Email" fieldconst emailRegex =/^[^\s@]+@[^\s@]+\.[^\s@]+$/;return emailRegex.test(getCurrentFieldValue());
Error Message: “Please enter a valid email
address”
Example 3: Cross-Field
Date Validation
Ensure End Date is after Start Date:
// Validation code for "Start Date" and "End Date" fields (both selected)if (fieldName ==="End Date") {const startDate =newDate(getFieldValue("Start Date"));const endDate =newDate(getCurrentFieldValue());return endDate >= startDate;}returntrue;// For Start Date changes, allow (End Date validator will catch issues)
Error Message: “End Date must be on or after Start
Date”
Example 4: Role-Based
Validation
Only admins can set priority to “Critical”:
// Validation code for "Priority" fieldif (getCurrentFieldValue() ==="Critical") {returnhasRole("Admin");}returntrue;// Allow all other priority values
Error Message: “Only administrators can set Priority
to Critical”
Example 5: Conditional
Required Field
Resolution is required when Status is “Closed”:
// Validation code for "Status" and "Resolution" fields (both selected)const fields =getAllFields();if (fieldName ==="Status"&&getCurrentFieldValue() ==="Closed") {// When closing, Resolution must be filledreturn fields["Resolution"] && fields["Resolution"].trim() !=="";}if (fieldName ==="Resolution"&& fields["Status"] ==="Closed") {// When status is already closed, Resolution cannot be emptyreturngetCurrentFieldValue() &&getCurrentFieldValue().trim() !=="";}returntrue;
Error Message: “Resolution is required when Status
is Closed”
Example 6: Numeric Range
Validation
Ensure Budget is within acceptable range:
// Validation code for "Budget" fieldconst budget =parseFloat(getCurrentFieldValue());// Check for valid numberif (isNaN(budget)) {returnfalse;}// Check rangereturn budget >=0&& budget <=1000000;
Error Message: “Budget must be between 0 and
1,000,000”
Example 7: Complex
Multi-Field Business Logic
Validate project milestone dates and dependencies:
// Validation code for "Phase Start", "Phase End", "Project Status" fieldsconst fields =getAllFields();const phaseStart =newDate(getFieldValue("Phase Start"));const phaseEnd =newDate(getFieldValue("Phase End"));const projectStatus =getFieldValue("Project Status");// Validate date rangeif (fieldName ==="Phase End"|| fieldName ==="Phase Start") {if (phaseEnd <= phaseStart) {returnfalse;// End must be after start }}// Cannot set status to "In Progress" without phase datesif ( fieldName ==="Project Status"&&getCurrentFieldValue() ==="In Progress") {if (!fields["Phase Start"] ||!fields["Phase End"]) {returnfalse; }}returntrue;
Error Message: “Phase End must be after Phase Start,
and phase dates are required before starting the project”
Management Actions
Add a Validator
Navigate to Settings → Workflows → Validators
Select the target workflow from the dropdown
Click the Add button (plus icon)
Configure the validator:
Fields: Click the TagBox and select one or more
fields to validate
Error Message: Enter a clear, specific error
message
Active: Check to enable (default: true)
Order: Set execution order (default: 0)
Custom Code: Click to open the integrated code
editor
Write validation code:
Write JavaScript code that returns true (pass) or
false (fail)
Use helper functions: getCurrentFieldValue(),
getFieldValue(), getAllFields(),
hasRole()
Test the code:
Click Compile button to check syntax errors
Click Test button to run with sample data
Review any error messages
Click Save in the code editor
Click Save in the validator form to persist to
database
Edit a Validator
Locate the validator in the table
Double-click the row OR click the Edit (pencil)
icon
Modify any fields:
Add/remove fields from the TagBox
Update error message
Toggle Active status
Change Order
Update Custom Code
Re-test if code was changed (Compile/Test buttons)
Click Save to apply changes
Delete a Validator
Locate the validator in the table
Click the Trash icon at the end of the row
Confirm deletion in the dialog
Warning: Deleted validators cannot be recovered.
Consider using Active = false instead to preserve
configuration.
Reorder Validators
Execution order matters - validators execute in ascending Order:
Locate the six-dot handle (⋮⋮) at the left of each
validator row
Click and drag the handle up or down
Release to drop the validator in the new position
The Order field updates automatically
Validators now execute in the new order
Best Practice: Order validators from simple to
complex:
Simple format checks first (fail fast)
Cross-field validations next
Complex business logic last
Testing Validators
Using the Integrated Code
Editor
Before activating a validator, test it thoroughly:
Syntax Check:
Click the Compile button
Review any syntax errors highlighted in red
Fix errors and compile again
Test with Sample Data:
Click the Test button
The editor runs your code with sample field values
Review the console output
Verify return value is boolean (true or
false)
Review Error Messages:
Ensure your Error Message is clear and actionable
Test with invalid data to see the message
Live Testing
After saving a validator, test it with real tickets:
Create or open a test ticket that has the
configured workflow assigned
Try to enter an invalid value in the validated
field
Verify the behavior:
Error message appears in toast notification at top of screen
Toast is red/error styled
Field retains its old value (change is blocked)
You cannot save the invalid value
Try entering a valid value:
No error message appears
Field updates successfully
Value is saved to database
Test edge cases:
Empty values
Null values
Boundary values (min/max)
Special characters
Very long strings
Debugging Validators
If a validator isn’t working as expected:
Check the basics:
Validator is Active (checkbox checked)
Workflow is assigned to the ticket
Field name matches exactly (case-sensitive)
Field is included in the validator’s Fields list
Review execution order:
Earlier validators might be blocking before yours runs
Check Order values and execution sequence
Test the code in isolation:
Use Compile button to check syntax
Use Test button with sample data
Add console.log() statements for debugging
Check browser console for runtime errors
Verify field names:
Field names in getFieldValue('FieldName') must match
exactly
Check field configuration in Punchlist Fields
section
Names are case-sensitive
Test with simple code first:
// Simplest test - always failreturnfalse;
If this doesn’t show an error, there’s a configuration issue (not a
code issue)
Best Practices
Error Messages
Be specific: “End Date must be after Start Date”
not “Invalid date”
Be actionable: Tell users what they need to
fix
Use examples: “Format: ABC-12345” or “Must be
uppercase”
Keep it concise: Under 200 characters when
possible
Avoid technical jargon: Write for end users, not
developers
Validation Code
Keep it simple: Complex logic is harder to maintain
and debug
Fail fast: Check simple conditions first (null,
empty, format)
Handle edge cases: Check for null, undefined, empty
strings
Use consistent return values: Always return
boolean, never undefined
Comment your code: Explain business rules for
future maintainers
Test thoroughly: Test with valid, invalid, null,
and boundary values
Multi-Field Validators
Be explicit: Use fieldName to check
which field triggered the validation
Validate both directions: If validating A against
B, handle changes to both A and B
Consider order: Validators run for all included
fields
Performance
Avoid heavy operations: Validators run on every
field change
Don’t call external APIs: Validators must be fast
and synchronous
Minimize getAllFields() calls: Call once and store
result if needed multiple times
Consider validator count: Too many validators can
slow down field updates
Organization
Use descriptive Order values: 10, 20, 30 instead of
1, 2, 3 (easier to insert new ones)
Group related validators: Use Order to keep related
validations together
Document complex logic: Add comments explaining
business rules
Review regularly: Outdated validators should be
deactivated or deleted
Security
Never trust client data: Always validate on the
server (validators run server-side ✓)
Use role-based validation: Restrict sensitive
fields with hasRole()
Validate format strictly: Use regex for formats
like email, phone, IDs
Prevent injection: Don’t use eval() or
construct SQL queries in validators
Troubleshooting
Validator Not Triggering
Problem: Validator doesn’t execute when field
changes
Solutions:
Verify validator is Active (checkbox checked)
Check that the workflow is assigned to the ticket
Confirm workflow is not Closed (validators only run
on active workflows)
Verify field name matches exactly (case-sensitive)
Check that field is in the validator’s Fields list
Review Order - try setting to 0 to execute first
Custom Code Errors
Problem: Validator code throws runtime errors
Solutions:
Use Compile button to check syntax errors
Test with sample data before saving
Check browser console for detailed error messages
Verify field names in getFieldValue() calls are
correct
Handle null/undefined values:
const value =getCurrentFieldValue();if (!value) returnfalse;// Require non-empty
Ensure you always return a boolean (true or
false)
Validation Too Strict
Problem: Validator blocks valid data
Solutions:
Review validation logic - may be too restrictive
Test edge cases (empty, null, special characters)
Consider role-based exceptions using hasRole()
Update error message to clarify requirements
Add logging to understand what values are being rejected:
Problem: Multi-field validation not working
correctly
Solutions:
Check which field triggered with fieldName
variable
Ensure both fields are included in the Fields list
Handle validation for each field explicitly:
if (fieldName ==="StartDate") {// Validate start date logic}if (fieldName ==="EndDate") {// Validate end date logic}
Use getFieldValue() to get the other field’s value
Consider creating separate validators for each field
Performance Issues
Problem: Field updates are slow when validators are
active
Solutions:
Reduce number of validators
Simplify complex validation logic
Remove unnecessary getAllFields() calls
Avoid loops and recursion in validation code
Consider combining multiple simple validators into one
Use Disabled flag to temporarily pause validators
during bulk updates
API Reference
For detailed information about all available Custom Code functions,
see the Custom Code section.
Validation-specific functions:
getCurrentFieldValue() - Get value being validated
getFieldValue(fieldName) - Get any field value
getAllFields() - Get all field values
hasRole(roleName) - Check user role
Available variables:
currentValue - Value being validated
fieldName - Field being validated
punchDetails - All field values
userRoles - User’s roles array
Comment Configuration
The Comment Configuration section allows
administrators to customize how comments are automatically generated
when creating punch items using the “Create with
comment” option. This feature enables a standardized naming
convention for comments by selecting which punchlist detail fields
should be included in the generated comment description.
Comment Generation
Overview
Comment Configuration controls the automatic generation of
comment descriptions when punch items are created with associated
comments.
Administrators can select up to three mapped
punchlist detail fields to include in the comment description.
The selected fields determine how the comment will be named,
following the format: “PI-[PunchID] : [Field1Value] : [Field2Value] :
[Field3Value]”.
Only punchlist details that have been mapped in the
Attribute Mapping section are available for
selection.
The feature includes a toggle to enable or disable automatic
comment generation entirely.
Features
1. Mapped Details
Selection
The page displays all punchlist details that have been mapped to 3D
attributes, 2D attributes, or custom code in the Attribute Mapping
section.
Each mapped detail is shown with its name and mapping information
(3D attribute, 2D attribute, or code mapping).
If no mapped details are available, the page prompts
administrators to configure attribute mappings first.
2. Field Selection for
Comments
Administrators select which fields to include in auto-generated
comments:
Click the Check button next to a detail to add
it to the comment configuration.
Up to 3 fields can be selected at once.
If you select a 4th field while 3 are already selected, the first
selected field is automatically removed.
The order in which fields are selected determines their
appearance order in the generated comment.
Fields can be deselected by clicking their Check
button again.
3. Comment Preview
The Ticket Comment Preview section shows a live
preview of how the selected fields will appear in the comment.
Fields are displayed in the format: “Field1-Field2-Field3”,
separated by hyphens.
A counter shows how many fields are currently selected (e.g.,
“Selected: 2/3”).
If no fields are selected, the preview displays “No fields
selected”.
4. Comment Generation
Toggle
The Comment Generation Enabled checkbox controls
whether automatic comment creation is active:
When enabled, punch items created with the “Create with comment”
option will automatically generate comments using the configured field
values.
When disabled, no automatic comments will be generated regardless
of field selection.
This toggle updates immediately without requiring a save
action.
Components
The Components section allows administrators to
customize the available attributes and control default column visibility
for the components table in the main punchlist details (Components
tab).
Components Page
Features
All available model attributes are displayed in the
Available Model Attributes List. Click an attribute to
move it from the Available Model Attributes list to the
Selected Attributes list. Attributes in the
Selected Attributes list are available as columns in
the main components table.
To remove an attribute, click it in the Selected
Attributes list to move it back to the Available Model
Attributes list.
Four columns are permanent and cannot be removed: Type, UID,
Bounding Box, and Drawing Name.
Administrators also have the ability to set the default
visibility of each selected attribute using checkboxes located at the
end of each row.
The visibility of the permanent columns can also be toggled as
needed.
This configuration is applied by default for a user accessing the
application for the first time.
Components Page Actions
Disable Features
Navigate to Enabled Pages in Admin menu
View and Edit Hidden
Routes
Specify the route in 1st column of Toolkit Pages table as
“/<route>” e.g. “/clashes”
Specify with boolean if it is allowed to view the specified route
with checkbox in 2nd column
View
and Edit Punchlist Tabs Visibility and Order
In the Punchlist Tabs table, administrators can toggle the Visible
checkbox to control which tabs appear in the punchlist details
section.
They can also set the order of the tabs by dragging and dropping
rows using the six dots to the left of each row.
Enabled Pages
Ticket Report Designer
The Ticket Report Designer page provides a powerful,
fully-featured PDF template editor that allows administrators to create
and customize professional reports for ticket items. Built on the open
source PDFME playground editor, this tool offers complete control over
report layout, fields, and styling.
Ticket Report Designer
Overview
Design custom PDF reports with a visual drag-and-drop interface
Map ticket detail fields to report elements
Support for text, images, tables, signatures, QR codes, and
more
Real-time preview of report layouts
Save templates to the database for use when generating ticket
reports
Load and modify existing templates or start from scratch
Features
1. Visual Template
Designer
The embedded PDFME designer provides an intuitive interface for
creating PDF report templates:
Drag-and-Drop Elements: Add text fields, images,
shapes, tables, barcodes, QR codes, and signature fields to your
template
Real-Time Preview: See exactly how your report will
look as you design it
Page Management: Create multi-page reports with
different layouts per page
Precise Positioning: Use pixel-perfect positioning
and alignment tools
Zoom Controls: Adjustable zoom with a draggable
zoom bar for detailed editing
2. Field Naming
Convention
To populate report fields with actual ticket data, use the following
naming conventions in the field “Name” property:
Regular Ticket Fields
Format: reportData.DetailName
Example: reportData.Tag No
References the “Tag No” field from the Ticket Fields
configuration
Automatically populates with the value from the ticket’s
details
Works with any custom field defined in the Punchlist
Fields admin section
Screenshot Images
Format: Initial or
Final
Initial — Displays the uploaded initial screenshot
image
Final — Displays the uploaded final screenshot
image
These fields should be added as image elements in the designer
Important: The field name must exactly match the
Detail name as defined in the Punchlist Fields administration page
(case-sensitive).
3. Base PDF
Management
Change Base PDF
Upload a PDF file to use as the base template for your reports
The base PDF appears as a background, with dynamic fields overlaid
on top
Useful for incorporating pre-designed features
File Requirements: Must be a valid PDF file
How to use:
Click “Change Base PDF (must be PDF)” in the top
navigation
Select a PDF file from your computer
The PDF pages become the background for your template
Add dynamic fields on top of the base PDF
4. Template
Management
Save Template
Click the “Save” button to save your current
template design to the database
The saved template is used when generating reports for tickets
A success notification confirms when the template is saved
Templates persist across sessions and are available to all
users
Load Template
Upload a previously saved template JSON file
Useful for importing templates created elsewhere or restoring
backups
File Requirements: Must be a valid JSON file in
PDFME format
How to use:
Click “Load Template (must be JSON)”
Select a JSON template file
The designer loads the template for editing
Download Template
Export your current template as a JSON file
Use this to create backups or share templates
Click “DL Template” to download
Reset Template
Click the “Reset” button to clear the current
template
Returns to a blank template with default settings
Warning: This action cannot be undone
Troubleshooting
Fields not populating with data
Verify the field name matches exactly (case-sensitive) with the
Detail name in Punchlist Fields
Ensure the naming convention reportData.DetailName is
used correctly
Check that the ticket has data in the specified field
Base PDF not displaying
Confirm the uploaded file is a valid PDF format
Check the PDF file size is reasonable (under 10MB recommended)
Verify the PDF is not password-protected or encrypted
Template not saving
Check browser console for error messages
Ensure you have administrator permissions
Verify database connectivity
Power BI
The Power BI section lets administrators manage
embedded reports. Reports are grouped by type and configured in-app
without modifying environment variables.
1. One‑Time Azure &
Power BI Setup
Azure Setup for Power BI
Embedding
Follow these 7 steps to configure your Azure and Power BI
environment. Once complete, no additional Azure changes are required —
everything else is managed inside the app.
#
Task
What to Do
1
Register an Azure AD App
Go to Azure Portal → Azure Active
Directory → App registrations → New
registration. Save the Application (Client)
ID and Directory (Tenant) ID. No extra
API permissions are needed.
2
Generate a Client Secret
Go to Certificates & Secrets → New
client secret. Copy the value and store it securely (used as
POWERBI_SECRET).
3
Enable Tenant Settings
In Power BI Service → Admin Portal
→ Tenant Settings, enable: ▪ Embed content in
apps ▪ Allow service principals to use Power BI APIs Scope =
Entire organization or a security group containing the service
principal.
4
Add Service Principal to Workspace
In each target workspace → Access → Add
member → search for the app name. Set Role
to Member or Admin.
5
Publish Reports
Open Power BI Desktop and publish your
.pbix file to the same workspace.
6
Provision Embedded Capacity
Go to Azure Portal → Power BI
Embedded → choose a capacity tier (e.g., A1). In Power BI
workspace: Settings → Premium → assign
the capacity.
7
(If report connects to Azure SQL)
In SQL Server → Networking →
enable “Allow Azure services and resources to access this server”.
Once these steps are completed, your Azure environment is ready. All
further actions are handled within the app.
2. Server‑Side
Environment Variables
Only three secrets live in the deployment environment (never in the
UI):
Note: Authentication Mode must remain
ServicePrincipal – this is the Microsoft‑recommended approach for
App‑Owns‑Data embeds and avoids user consent pop‑ups.
3. Adding
& Maintaining Reports inside the App
Use the Power BI UI page to:
Report Management Actions
Action
Steps
Add a Report
1. Navigate to Admin › Power BI. 2. Click
“+ Add Report”. 3. Enter: Report
Name, Report ID, Workspace
ID, and Type (copy GUIDs from Power BI Service
URL). 4. Click Save – the app validates IDs by
contacting Power BI.
Edit a Report
Click ✎ (edit) → change values →
Save.
Delete a Report
Click 🗑 on the appropriate report to delete the
report.
Create a Report Type
Type a new value into the Report Type field when adding a report —
it will be created automatically.
Delete a Report Type
Click 🗑 next to a type to remove it and all its
reports._
Hide / Show the Navbar
Click « or » to collapse the left
pane and view the report full‑width.
Power BI Page
LOTO Administration
The LOTO (Lockout/Tagout) administration section
enables administrators to configure templates, metadata fields, and
catalogue items that define how Lockout/Tagout work programs operate
throughout the application.
Overview
The LOTO system provides a comprehensive framework for managing
Lockout/Tagout work programs in industrial environments. Administrators
configure:
Templates: Reusable step sequences for different
work program types
Metadata Fields: Dynamic columns that appear in
work program list tables
Catalogue Items: Placeable symbols and equipment
types for P&ID drawings
Users leverage these configurations to create, execute, and track
work programs with proper safety procedures and documentation.
LOTO Templates
Navigate to Settings → LOTO Settings to manage
reusable templates that define step sequences for work programs.
What are LOTO Templates?
Templates are pre-configured sets of steps organized by phase
(Preparation, De-commissioning, Repair, Commissioning) that can be
applied to new work programs. They ensure consistency and best practices
across similar work activities.
Template Management Actions
View All Templates
The Templates page displays all available templates in a table format
with the following columns:
Template Name: Descriptive name for the
template
Type: Category or classification (e.g.,
“Maintenance”, “Inspection”)
Description: Detailed explanation of the template’s
purpose
Category: Grouping classification for organizing
templates
Last Modified: Date of last modification
Last Modified By: User who last updated the
template
Add a New Template
Click the Add (+) button in the toolbar
Enter the required fields:
Template Name: Unique identifier (required)
Type: Classification category
Description: Purpose and usage details
Category: Organizational grouping
Click Save to create the template
The template appears in the list and can now be opened to add
steps
Edit Template
Properties
Click the Edit (pencil) icon on the template
row
Modify any field:
Template Name
Type
Description
Category
Click Save to apply changes
Delete a Template
Click the Trash icon on the template row
Confirm deletion in the dialog
Warning: Deleting a template does not affect work
programs that were created using it. However, the template will no
longer be available for new work programs.
Configure Template
Steps
Double-click a template row OR click the template name
Navigate to the Template Steps page for that template
Template Steps Configuration
After selecting a template, administrators can configure the steps
for each phase.
Phase Tabs
Template steps are organized into four phases:
Preparation: Initial setup and safety
procedures
De-commissioning: Shutdown and isolation
procedures
Repair: Maintenance or repair work activities
Commissioning: Startup and restoration
procedures
Click each tab to view and edit steps for that phase.
Steps Table Columns
Column
Description
Order
Sequential number determining execution order (drag to reorder)
Interdependency: Select prerequisite steps by Order
number
Click Save or press Enter
Edit a Template Step
Click the Edit (pencil) icon on the step row
Modify any field
Click Save to apply changes
Note: Changes to template steps do NOT affect
existing work programs that were created from this template. They only
apply to newly created work programs.
Delete a Template
Step
Click the Trash icon on the step row
Confirm deletion
The step is removed from the template
Reorder Template
Steps
Locate the six-dot handle (⋮⋮) at the left of the
row
Click and drag the step to the desired position
Release to drop
The Order numbers update automatically
Set Step
Interdependencies
Interdependencies ensure that prerequisite steps must be completed
before a step becomes available.
Edit the step
Click the Interdependency cell
Select one or more prerequisite steps by their Order number
Save the step
Using Templates in Work
Programs
When users create a new work program, they can import a template
through the Planning → Template tab. The template steps
are copied to the work program, where users can then execute them.
Key Point: Template changes do not retroactively
affect existing work programs. Only new work programs created after the
template is modified will include the updates.
LOTO Metadata Configuration
Navigate to Settings → LOTO Metadata to define the
dynamic columns (metadata fields) that appear in work
program list tables (e.g., Blind List, Valves List, Electrical
Drives List, Drains List, Hose List, Other List). These fields
control what users can view and edit in each list.
What you can do here
Add new columns (fields) to specific lists.
Edit field properties (labels, data source, input
type, etc.).
Delete fields you no longer want shown.
Reorder fields by dragging rows to change the
column order in the list tables.
Field Reference
Field
What it means / how it’s used
Field Name
Internal identifier; must be unique, start with a letter, and use
only letters, numbers, or underscores.
Display Label
The column header shown to users in list tables.
Item Type
Determines which list/table shows this field (e.g., Blind List,
Valves List, etc.).
Data Source
Where the value comes from: UserEntered (users
type/select values) or ConnectedItem (auto-filled from
P&ID object).
Connected Item Attribute
Attribute to display when Data Source =
ConnectedItem.
Input Type (UserEntered only)
Editor control for manual entry: Text,
Dropdown, Boolean,
Number, or Date.
Dropdown Options (Dropdown only)
Allowed choices for Input Type = Dropdown; provide
as a comma-separated list.
Data Type
Must match the input type
(String/Number/Boolean/Date); enforced
automatically.
Common Operations
Common Metadata Operations
Add a Field
Click the “+” button.
Fill out:
Field Name: Internal name
(letters/numbers/underscores; must start with a letter).
Display Label: The column header users will
see.
Item Type: Which list the field appears in (e.g.,
Blind List).
Data Source:UserEntered (manually
entered in lists) or ConnectedItem (auto from connected
P&ID object).
Input Type (UserEntered only):Text, Dropdown,
Boolean, Number, or
Date.
If UserEntered → auto-matched and locked to the
Input Type: Text → String, Dropdown → String,
Boolean → Boolean, Number → Number,
Date → Date.
If ConnectedItem → choose
String/Number/Boolean/Date to match the source
attribute.
Connected Item Attribute (ConnectedItem only):
Attribute to pull from the P&ID object.
Click the Save Icon button. The field is added and
positioned at the end of the list’s columns.
Edit a Field
Click the Edit (pencil) icon on the row.
Adjust the properties.
When Data Source = ConnectedItem, Input
Type and Dropdown Options are disabled.
When Data Source = UserEntered, Connected
Item Attribute is disabled.
Click the Save Icon button to finalize
changes.
Delete a Field
Click the Delete (trash) icon and confirm.
The column disappears from the UI for users.
Existing values in the database are not
deleted.
Re-create the same Field Name later to show the
values again.
Reorder Fields (Column Order)
Drag the row handle up or down.
Release to drop. The new order is saved and reflected in the list
table layout.
Rules & Validation (Quick
Guide)
Required fields: Field Name, Display Label, Item
Type, Data Source, Data Type.
Dropdown Options: Required if Input Type =
Dropdown.
Type Matching:Data Type must
match the Input Type (checked automatically).
Connected vs UserEntered: Only the relevant inputs
are enabled; the others are dimmed and cannot be edited.
What End Users Will See
Fields you define here appear as columns in the
corresponding work program list types.
UserEntered fields can be edited
inline by list users (double-click cell, edit, press
Enter to save).
ConnectedItem fields are
read-only, reflecting live data from the connected
P&ID object.
Type is a special hardcoded column that
automatically displays the Connected Item Name (the
name of the catalogue item placed on the P&ID).
Catalogue
Use this page to manage the placeable
symbols/templates that appear in the Sketching/Placement tools
for work program lists (e.g., Blinds, Valves, Electrical Drives,
Drains, Hoses, Other). Each catalogue item corresponds to a
symbol (SVG) that users can place onto P&IDs when creating or
updating work program items.
What is the LOTO Catalogue?
The LOTO Catalogue contains the library of symbols and equipment
types that users can place on P&ID drawings when building work
programs. Each catalogue item represents a physical device (blind,
valve, electrical drive, etc.) and includes:
A visual symbol (SVG file) for placement on drawings
Associated actions for commissioning and de-commissioning (for
Blinds, Valves, and Electrical Drives only)
Classification by list type
Catalogue Management Actions
Add, Edit,
Delete, and Reorder catalogue
items
Effect for users: Items you configure here appear
in the Add list item flow and Sketching Tool catalogue
lists
Field Reference
Field
Description
Catalogue Item Name
Friendly name shown to users in placement dialogs (e.g., “SC-1 Spade
Blind”, “Gate Valve 2-inch”)
SVG Path
Path to the SVG symbol file in the model/catalogue folder (e.g.,
IntelliPidCatalogue\LOTO_Symbols\Lototo_V2_w_ll.svg)
List Type
Which work program list this item appears under: Blind
List, Valves List, Electrical Drives
List, Drains List, Hose List,
Other List
Display Order
Hidden system field updated when you drag rows; controls visible
order in placement pickers
Responsible party for commissioning (Blinds, Valves, Electrical
Drives only)
DeCom Action Owner
Responsible party for de-commissioning (Blinds, Valves, Electrical
Drives only)
Note: Action fields (Com Action, DeCom Action, Com
Action Owner, DeCom Action Owner) are only available for Blind
List, Valves List, and Electrical
Drives List. These fields are automatically disabled for Drains
List, Hose List, and Other List.
Common Operations
Common Catalogue Operations
Add a Catalogue Item
Click the Add (+) button
Fill out the required fields:
Catalogue Item Name: The name users see when
selecting an item to place (e.g., “SC-1 Spade Blind”, “Gate Valve
2-inch”)
SVG Path: The file path to the symbol (SVG) in your
model/catalogue folder (e.g.,
IntelliPidCatalogue\LOTO_Symbols\Lototo_V2_w_ll.svg)
Ensure the SVG exists and is accessible in the deployment
environment
List Type: Which work program list this item
belongs to
(Optional) For Blinds, Valves, and Electrical Drives, enter:
Com Action: Description of commissioning
action
DeCom Action: Description of de-commissioning
action
Com Action Owner: Responsible party for
commissioning
DeCom Action Owner: Responsible party for
de-commissioning
Click the Save icon button
The new item appears for users in the corresponding placement
catalogue
Tip: Use descriptive names that help users quickly
identify the correct item (e.g., “Spectacle Blind 6-inch” instead of
just “Blind”).
Edit a Catalogue
Item
Click the Edit (pencil) icon on the row
Update any field:
Name
SVG Path
List Type
Action fields (if applicable)
Click Save to finalize changes
Note: If you change the List Type from
Blinds/Valves/Electrical Drives to Drains/Hose/Other, the action fields
are automatically cleared.
Delete a Catalogue
Item
Click the Delete (trash) icon on the row
Confirm deletion in the dialog
Important:
The item is removed from the placement catalogue
for users
Already-placed objects using that SVG are
not deleted from P&IDs or work programs
Users can no longer select this item for new placements
Reorder Catalogue
Items
Drag the six-dot handle (⋮⋮) up or down to change
order
Release to drop
The Display Order updates automatically
Items appear in this order in the placement picker for users
Best Practice: Order items logically (e.g., group
similar items together, or order by frequency of use).
SVG Symbol Requirements
File Format: Must be a valid SVG file
Location: Must exist in the model/catalogue folder
accessible by the application
Path Format: Use backslashes for Windows paths
(e.g., IntelliPidCatalogue\LOTO_Symbols\symbol.svg)
Languages
The Languages page allows administrators to manage
all language translations used throughout the application. This section
enables administrators to add new languages, edit existing translations,
import/export standard translations from Excel, and configure default
language settings.
The languages administration
page
Overview
The Language Management system uses a two-table
architecture:
Standard Translations: Base translations loaded
from Excel files that serve as read-only templates
Custom Translations: User-editable translation
overrides that take priority over standard translations
Administrators can set a default language, from Standard
Translations that serves as the fallback for all translations.
Users can select their preferred language from available custom
languages, which persists across sessions.
Translation priority system ensures the best available
translation is displayed:
Custom translation in current language (highest priority)
Standard translation in current language
Custom translation in default language
Standard translation in default language
Features
1. Language Selection
Current Language
Select which custom language dictionary the app will use.
Default Language
Defines the base language used as the fallback when translations
are missing in other languages.
Can be set from the dropdown and saved with the “Set Default
Language” button.
Serves as the template for creating new custom
languages.
Edit Language
Select which custom language dictionary to view and edit in the
translation grid.
Displays all translation key-value pairs.
2. Translation Grid
Displays a merged view of all translation keys and their
corresponding values for the selected language.
Visual Indicators: Rows with:
Green dot: Custom translation (editable, stored in
Custom Translations)
Yellow/Orange dot: Standard translation (read-only,
from Standard Translations)
These rows indicate missing keys/rows from Custom Translations, that
are present in Standard Translations.
Visual Indicator
Key Column: Contains the translation key
(read-only, cannot be edited).
Value Column: Contains the translated text
(editable for custom translations).
Editing Translations:
Click the edit icon to modify a value
Edits to standard translations rows(Yellow/Orange
dot) automatically create a custom override, adding them to the
custom translations for the edited language.
Features filter row for quick searching of specific
translations.
3. Standard
Translations
Standard translations serve as the base translation templates and are
loaded from the translations.xlsx file when the application
starts.
Excel File Format:
Multi-sheet workbook where each sheet represents one language
Each sheet has 3 columns: language, key,
value
The language column contains the language code for all
rows in that sheet
Sheet name typically matches the language code
Updating Standard Translations:
To update standard translations, edit the
translations.xlsx file in the project root directory and
restart the application. The translations will be automatically loaded
from the file at startup.
4. Add Custom
Language
Create a new custom language dictionary that can be edited directly
in the interface:
Click the Add Language button.
Select a language code from the ISO language list (e.g.,
en-US, ko, ar).
Click Create Language.
A new custom language is created with:
All keys copied from the default language’s standard
translations
Empty values that you can fill in
The new language appears in the “Edit Language”
dropdown.
Edit translations directly in the translation grid.
Adding a new language
5. Import Custom
Language from Excel
Import a custom language dictionary from a Excel file:
Click the Import Language Dictionary
button.
Select a language code or enter a custom one.
Download a template Excel:
Download Template: Gets all keys from default
language with empty values
Fill in the Excel file:
key
value
Add Language
언어 추가
Update Language
언어 업데이트
Select a file
파일 선택
Upload the completed Excel file.
Click Import to save the custom
language.
Note: If the language already exists, importing will
update the existing custom translations
Managing Languages
Update Existing
Custom Translations (In detail)
Select the custom language to edit from the Edit
Language dropdown.
Use the filter row to search for specific translations.
Click the edit icon button to edit the row.
Modify the value and click the Save
button.
Editing translations
Set Default Language
Select the desired language from the Default
Language dropdown.
The system updates the default language.
Understanding Translation
Priority
When the application displays a translation, it follows this priority
order:
Custom translation in user’s current language -
User-specific overrides
Standard translation in user’s current language -
Base translations from Excel
Custom translation in default language - Fallback
custom translations
Standard translation in default language - Fallback
base translations
This ensures users always see the most appropriate translation
available.
Excel File Format
When importing custom language dictionaries via Excel, the file must
follow this exact column layout:
language
key
value
ko
Add Language
언어 추가
ko
Update Language
언어 업데이트
ko
Select a file
파일 선택
Requirements
The Excel file must contain a header row with
exactly these columns:
language
key
value
Each row represents a single translation entry.
Each sheet represents one language (e.g., en-US,
ko, he-IL) if using multi-sheet
format.
Keys must match the standard translation keys exactly (do not
modify keys).
Values should contain your custom translations.
Right-to-Left (RTL) Language
Support
The application automatically supports Right-to-Left languages such
as Arabic (ar), and Hebrew (he).
When a language with RTL directionality is selected, the
interface layout automatically adjusts to display content from right to
left.
Text alignment, menu positioning, and component layouts are
automatically reversed to provide a natural reading experience.
RTL support is determined by the language code, languages like
ar, ar-SA, he, fa,
and ur will trigger RTL mode.
All UI components adapt to the RTL layout automatically.
RTL
General Settings
Navigate to Settings at the bottom of the navigation
bar
Change the Toolkit
Theme
Users can personalize the Toolkit’s appearance by selecting a
theme from a dropdown menu.
Each theme modifies the application’s visual style to match the
selected design.
Once a theme is chosen, the selection is saved.
The selected theme is automatically applied across all future
sessions for that user.
Setting Theme
Configure Language
Options
Users can select their preferred language from the Language
Settings section.
Use the dropdown menu to select from available custom
languages.
The selected language is tied to the user account and is saved
automatically.
The language preference is applied across all future
sessions.
If a translation is missing in the selected language, the system
will fall back to:
Standard translation in the selected language
Custom translation in the default language
Standard translation in the default language
en-US as the ultimate fallback
Note: Only languages with custom translations
(created by administrators in the Languages admin page) appear in this
dropdown. For information on creating and managing languages, see the Languages section.
Signature Settings
The Signature Settings section on the Settings page allows
administrators to manage their own personal Interactions email
signature.
This signature is automatically included in the default message
body when composing an Interactions email.
Automatically appends a consistent sign-off to each
email.
Updates to the signature are saved to the user’s profile and
persist across sessions, eliminating the need to re-enter it each
time.
Setting Theme
Company Settings
The Company Settings section allows administrators to customize
branding for the Toolkit application by setting a company name and
uploading a company logo.
Company Settings
Company Name
Enter your organization’s name in the Company
Name text field.
The name will automatically save.
This company name will appear on outgoing communications and
throughout UI elements.
Use the Clear button (X icon) to quickly remove
the current company name if needed.
A “Saving…” indicator appears briefly to confirm that your
changes are being saved.
Company Logo
Upload a custom logo to represent your organization throughout
the Toolkit interface.
The logo uploader supports all standard image formats (PNG, JPG,
JPEG, GIF, SVG, etc.).
You can either drag and drop an image file into
the upload area or click to browse and select a file
from your computer.
Once selected, the logo is automatically uploaded and
saved.
A preview of your uploaded logo is displayed below the uploader
for verification.
The selected logo persists across all sessions and is visible to
all users.
Best Practices:
Use a square or wide image for optimal display
across different UI components
Transparent PNG format is recommended for the best
visual results
Ensure the logo has sufficient contrast against both light and dark
backgrounds
Keep file sizes reasonable (under 2MB) for faster loading