Overview

The customization system allows you to extend the user interface by adding custom buttons, panels, field links, and visual styling to various parts of the application. These customizations are entity-specific and can be configured to appear in different contexts based on user permissions, system state, and custom conditions.

Four Types of Customizations

  • Custom Buttons โ€” Interactive actions in data grids and details
  • Custom Panels โ€” Additional information panels in the editor interface
  • Custom Links โ€” Field-level links to external systems based on record data
  • Column Colours โ€” Conditional cell background colors in data grids
card: Custom Buttons
Interactive buttons that appear in data grids or data details and can execute custom actions on selected records. Support URL opening with context variables or running automated workflows.
card: Custom Panels
Collapsible panels that appear in the editor interface to display additional information, embed external content, or provide custom controls for enhanced workflows.
card: Custom Links
Field-level links that appear on editor fields and open external applications with context data. Visible only when field has a value and optional conditions are met.
card: Column Colours
Conditional background colors for data grid cells based on filter expressions. Apply to all columns or specific columns for visual data highlighting.
Key Capabilities
- Entity-specific โ€” Attach customizations to any data entity
- Context-aware โ€” Access user info, selected records, and system state
- Conditional visibility โ€” Show/hide based on custom filter expressions
- Changeset & readonly aware โ€” Respect system modes and permissions

Custom Buttons [badge:Buttons|warning]

Interactive buttons that enhance data list or data detail functionality

[try:/customButtons|Manage Custom Buttons โ†’|right]

Key Features

  • Appear in data grids next to standard action buttons
  • Execute custom actions on selected records
  • Support both single and multiple record selection
  • Can be conditionally shown based on record state
  • Respect changeset and readonly mode restrictions

Configuration Fields

Basic Properties

  • name โ€” Button label displayed to users
  • entityId โ€” Target entity for the button
  • icon โ€” Icon displayed on the button
  • color โ€” Button color theme

Behavior

  • allowMultiple โ€” Whether button works with multiple selected records
  • condition โ€” Optional filter expression to enable/disable button
  • action โ€” The action type: “openUrl” or “runAutomation”
  • url โ€” Target URL (for openUrl action)
  • automation_id โ€” Target automation (for runAutomation action)

Visibility Control

  • allowInChangeSet โ€” Show button when changeset is active
  • allowInReadOnly โ€” Show button in readonly mode

Action Types

openUrl โ€” Open URL Action

Opens a URL in the browser with contextual information from the UI. This allows for powerful custom integrations and external system connections.

Available Context Variables:

  • {user.id} โ€” Current user ID
  • {user.email} โ€” Current user email
  • {selectedIds} โ€” Comma-separated list of selected record IDs
  • {entityId} โ€” Target entity identifier
  • {orgId} โ€” Current organization ID

Example URL:

https://external-system.com/api/export?records={selectedIds}&user={user.id}&org={orgId}

runAutomation โ€” Run Automation Action

Executes a predefined automation workflow on the selected records. This enables complex data processing, transformations, and business logic execution.

Automation Capabilities:

  • Data modification and updates
  • Field calculations and transformations
  • Integration with external systems
  • Batch processing operations
  • Workflow trigger execution

Example Use Cases:

  • Bulk price updates based on cost calculations
  • Automated inventory synchronization
  • Customer data enrichment workflows
  • Report generation and distribution

Example Configurations

OpenUrl Action Example:

{
  "name": "Export to PDF",
  "entityId": "products",
  "icon": "FileText",
  "color": "blue",
  "allowMultiple": true,
  "allowInChangeSet": false,
  "allowInReadOnly": true,
  "condition": "status = 'active'",
  "action": "openUrl",
  "url": "https://export.company.com/pdf?ids={selectedIds}&user={user.id}"
}

RunAutomation Action Example:

{
  "name": "Update Prices",
  "entityId": "products",
  "icon": "euro",
  "color": "green",
  "allowMultiple": true,
  "allowInChangeSet": true,
  "allowInReadOnly": false,
  "condition": "category.code = 'ELEC'",
  "action": "runAutomation",
  "automation_id": "code:bulk-price-update-automation"
}

Custom Panels [badge:Panels|info]

Collapsible panels that extend the editor interface

[try:/customPanels|Manage Custom Panelsโ†’|right]

Key Features

  • Appear in the editor sidebar alongside standard panels
  • Collapsible with coordinated expand/collapse behavior
  • Can display custom content, data, or controls
  • Support different positioning (left, right, top, bottom)
  • Can appear in list view, detail view, or both
  • Support for data-independent panels with requiresData option
  • Respect changeset and readonly mode restrictions

Configuration Fields

Basic Properties

  • name โ€” Panel title displayed to users
  • entityId โ€” Target entity for the panel
  • icon โ€” Icon displayed in panel header
  • position โ€” Panel placement (left, right, top, bottom)
  • location โ€” Where to show the panel (list, detail, both)
  • size โ€” Panel size (tiny, small, medium, large)

Content & Behavior

  • action โ€” Action type: “openUrl” or “showHtml”
  • body โ€” HTML content to display (for showHtml action)
  • url โ€” Target URL (for openUrl action)
  • requiresData โ€” Whether panel depends on selected data
  • condition โ€” Optional filter expression to show/hide panel

Visibility Control

  • allowInChangeSet โ€” Show panel when changeset is active
  • allowInReadOnly โ€” Show panel in readonly mode

Action Types

openUrl โ€” Open URL Action

Opens a URL in the browser with contextual information from the UI, same as CustomButtons. This allows for external integrations and dynamic content based on current context.

Supports the same context variables as CustomButtons:

  • {user.id}, {user.email} โ€” Current user information
  • {selectedIds} โ€” Selected record IDs
  • {entityId}, {orgId} โ€” Context identifiers
โš ๏ธ Important: Iframe Embedding Requirements

When the URL is loaded in an iframe within the application, the target server must be properly configured:
- `X-Frame-Options: ALLOW-FROM {HOSTNAME}` โ€” Allow embedding from your server
- `Content-Security-Policy: frame-ancestors 'self' {HOSTNAME}` โ€” Modern CSP alternative
- HTTPS required if the parent application uses HTTPS (mixed content policy)
- Cookies may not work properly due to SameSite restrictions in cross-origin iframes

showHtml โ€” Show HTML Action

Displays the content from the body field as HTML within the panel. This enables rich formatted content directly in the interface.

HTML Limitations:

  • Limited HTML subset is supported for security
  • JavaScript is not allowed
  • External script tags and event handlers are filtered out
  • Safe tags like headings, paragraphs, lists, and basic formatting are supported

Example HTML Body:

<h3>Product Information</h3><p>Additional details about this product...</p><ul><li>Feature 1</li><li>Feature 2</li></ul>

Data Dependencies

requiresData Property

Controls whether the panel depends on currently selected data. When set to false, the panel can be displayed even when no data is selected, making it independent of the current selection state.

  • requiresData: true โ€” Panel only appears when data is selected. Context variables like selectedIds will be available.
  • requiresData: false โ€” Panel can appear independently. Useful for help text, static information, or global actions.

Example Configurations

ShowHtml Action Example:

{
  "name": "Product Help",
  "entityId": "products",
  "icon": "HelpCircle",
  "position": "right",
  "location": "detail",
  "size": "small",
  "requiresData": false,
  "allowInChangeSet": true,
  "allowInReadOnly": true,
  "action": "showHtml",
  "body": "<h3>Product Guidelines</h3><p>Follow these steps when editing products...</p>"
}

OpenUrl Action Example:

{
  "name": "Product Analytics",
  "entityId": "products",
  "icon": "BarChart",
  "position": "right",
  "location": "detail",
  "size": "medium",
  "requiresData": true,
  "allowInChangeSet": true,
  "allowInReadOnly": true,
  "action": "openUrl",
  "url": "https://analytics.company.com/product?id={selectedIds}&user={user.id}"
}

Visibility Control

Understanding when customizations are shown or hidden

System States

Changeset Mode

When a changeset is active, only customizations with allowInChangeSet: true are visible.

Readonly Mode

When in readonly mode, only customizations with allowInReadOnly: true are visible.

Visibility Matrix

ModeallowInChangeSetallowInReadOnlyVisible
Normal--โœ…
Changeset Activetrue-โœ…
Changeset Activefalse-โŒ
Readonly-trueโœ…
Readonly-falseโŒ

Iframe Embedding Considerations

Important technical requirements and limitations when embedding external content

โš ๏ธ Critical Server Configuration Requirements

External URLs loaded in custom panels must be specifically designed for iframe embedding. The target server MUST provide proper HTTP security headers to allow embedding.

Required HTTP Headers

Critical โ€” X-Frame-Options Header:

X-Frame-Options: ALLOW-FROM {HOSTNAME}

Use your actual application domain. This header allows your application to embed the external content in an iframe.

Modern Alternative โ€” Content Security Policy (CSP):

Content-Security-Policy: frame-ancestors 'self' {HOSTNAME}

Modern browsers prefer CSP over X-Frame-Options. This directive controls which domains can embed the page in frames. Replace with your actual application domain.

Recommended โ€” Additional Security Headers:

X-Content-Type-Options: nosniff
X-XSS-Protection: 1; mode=block
Referrer-Policy: strict-origin-when-cross-origin

Additional security headers that improve the security posture of embedded content.

Common Iframe Problems & Solutions

HTTPS Mixed Content

Problem: Browser blocks HTTP content when parent page uses HTTPS

Solution: Ensure all external URLs use HTTPS protocol. Modern browsers require secure connections for iframe embedding.

โœ… https://external-app.com/panel
โŒ http://external-app.com/panel

Cookie/Session Issues

Problem: Authentication cookies don’t work in cross-origin iframes

Solution: Use SameSite=None; Secure for cookies that need to work in iframes, or implement token-based authentication through URL parameters.

Frame Busting Scripts

Problem: JavaScript code prevents iframe embedding

Solution: Remove or modify scripts that check window.top !== window.self or similar frame-busting logic.

Responsive Design

Problem: Content doesn’t adapt well to iframe constraints

Solution: Design iframe-specific layouts or use responsive CSS that works well in constrained spaces. Consider the panel size settings (tiny, small, medium, large).

Communication

Problem: Limited communication between iframe and parent

Solution: Use postMessage API for secure cross-origin communication if the embedded content needs to interact with the parent application.

Server Configuration Examples

๐Ÿ“ Domain Configuration โ€” replace {HOSTNAME} with your actual application domain.

Apache (.htaccess):

Header always append X-Frame-Options "ALLOW-FROM {HOSTNAME}"
Header always set Content-Security-Policy "frame-ancestors 'self' {HOSTNAME}"
Header always set X-Content-Type-Options "nosniff"
Header always set X-XSS-Protection "1; mode=block"

Nginx:

add_header X-Frame-Options "ALLOW-FROM {HOSTNAME}" always;
add_header Content-Security-Policy "frame-ancestors 'self' {HOSTNAME}" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-XSS-Protection "1; mode=block" always;

Node.js/Express:

app.use((req, res, next) => {
  res.setHeader('X-Frame-Options', 'ALLOW-FROM {HOSTNAME}');
  res.setHeader('Content-Security-Policy', "frame-ancestors 'self' {HOSTNAME}");
  res.setHeader('X-Content-Type-Options', 'nosniff');
  res.setHeader('X-XSS-Protection', '1; mode=block');
  next();
});
๐Ÿ’ก Testing Iframe Compatibility: Before deploying, test your external URL by creating a simple HTML file with an iframe pointing to your content. Open it in a browser and check the developer console for any frame-related errors.

Field-level links that appear on editor fields and open external applications with context data

[try:/customLinks|Manage Custom Links โ†’|right]

Custom Links allow you to add contextual links to specific fields in the editor interface. These links can open external applications, search databases, or navigate to related systems, all populated with data from the current record.

  • Add links directly to field labels, icons next to inputs, or buttons below fields
  • Open external applications with context from the current record (e.g., name, ID, user info)
  • Links are visible only when the selected field has a value
  • Support conditional display based on filter expressions
  • Respect changeset and readonly mode restrictions

Common Use Cases

๐Ÿ”— Link to CRM System

Add a link on the customer name field that opens the customer record in your CRM system.

๐Ÿ” Search EAN Database

Add a link on the EAN field to search for product information in an external database.

๐Ÿ›’ Open on E-commerce

Add a link to view the product on your e-commerce platform’s frontend.

Custom Links can appear in three different positions relative to the field:

Label Position

The field label becomes a clickable link. When clicked, it opens the external URL. This is useful for making the entire label interactive.

Icon Position

A small icon button appears after the input field. Multiple icon links can appear side by side. This is useful for providing quick access without changing the field’s appearance.

Under Position

Link appears as a small text link below the input field. Multiple links can wrap to multiple lines. This is useful for secondary actions that don’t need immediate visibility.

Configuration Fields

Basic Properties

  • name โ€” Link text displayed to users
  • entityId โ€” Target entity for the link
  • columns โ€” Array of field IDs where the link should appear
  • icon โ€” Icon displayed with the link (for icon and under positions)
  • position โ€” Where to show the link: “label”, “icon”, or “under”

Action Configuration

  • action โ€” Action type (currently only “openUrl” is supported)
  • url โ€” Target URL template with variable placeholders

Conditional Display

  • condition โ€” Optional filter expression to show/hide the link
  • allowInChangeSet โ€” Show link when changeset is active
  • allowInReadOnly โ€” Show link in readonly mode

URL Template Variables

The URL can contain placeholders that are replaced with actual data when the link is clicked:

Record Data

  • {data.fieldName} โ€” Value of any field from the current record (e.g., {data.name}, {data.ean})
  • {objectIds} โ€” Current record ID
  • {entityId} โ€” Entity identifier

User Information

  • {user.id} โ€” Current user ID
  • {user.username} โ€” Current user’s username
  • {user.email} โ€” Current user’s email address

System Information

  • {language} โ€” Current UI language code
  • {orgId} โ€” Current organization ID

Example URL Template:

https://crm.example.com/customer?name={data.name}&email={data.email}&lang={language}&user={user.username}

Visibility Rules

โš ๏ธ Important: Field Value Requirement

Custom Links are **only visible when the associated field has a value**. If the field is empty (null, undefined, or empty string), the link will not appear, even if all other conditions are met.

Conditional Display Example

You can use filter expressions to show links only when specific conditions are met:

platform.code = 'shoptet'

This link will only appear when the product is on the Shoptet platform.

Example Configuration

Complete Custom Link Example:

{
  "name": "View in CRM",
  "entityId": "products",
  "columns": ["name", "ean"],
  "icon": "ExternalLink",
  "position": "icon",
  "action": "openUrl",
  "url": "https://crm.example.com/product?ean={data.ean}&name={data.name}&user={user.email}",
  "condition": "platform.code = 'shoptet' AND status = 'active'",
  "allowInChangeSet": false,
  "allowInReadOnly": true,
  "disabled": false
}

This link appears as an icon next to the “name” and “ean” fields when the product is on the Shoptet platform, is active, and the field has a value. It opens the CRM with the product’s EAN, name, and current user’s email.

๐Ÿ’ก Best Practices
- Use icon position for frequently accessed links to keep the UI clean
- Use label position when the link is the primary action for that field
- Use under position for secondary or less common actions
- Keep link names short and descriptive
- Test URL templates with different record data to ensure they work correctly
- Use conditions to show links only when they're relevant
- Consider using `allowInReadOnly=true` for view-only links

Column Colours [badge:Colours|success]

Conditional background colors for data grid cells

[try:/columnColours|Manage Custom Colours โ†’|right]

Key Features

  • Apply background colors to data grid cells based on filter conditions
  • Target all columns or specific columns in an entity
  • Multiple color rules can be defined per entity
  • Evaluated in real-time as data changes
  • Great for visual highlighting of important data (e.g., overdue items, stock levels)

Configuration Fields

Basic Properties

  • name โ€” Descriptive name for the color rule
  • entityId โ€” Target entity for the color rule
  • colour โ€” Background color (hex format, e.g., #ff0000)
  • description โ€” Optional description of the rule

Filtering

  • filter โ€” SQL-like condition that determines when to apply the color
    • Example: status = 'overdue' AND priority = 'high'

Column Targeting

  • allColumns โ€” Apply color to all columns in the row
  • columns โ€” Array of specific column names to color (if allColumns is false)
    • Example: ["price", "discount", "total"]

Control

  • disabled โ€” Temporarily disable the color rule without deleting it

Use Cases

Status Highlighting

Highlight rows based on status values. For example, show overdue tasks in red, completed tasks in green, and in-progress tasks in yellow.

Example Configuration:

Entity: tasks
Filter: status = 'overdue'
Colour: #ffcccc (light red)
All Columns: true

Threshold Alerts

Highlight specific columns when values exceed thresholds. For example, highlight the stock column in red when inventory falls below minimum levels.

Example Configuration:

Entity: products
Filter: stock < minimumStock
Colour: #ff6666 (red)
All Columns: false
Columns: ["stock"]

Priority Visualization

Use different colors for different priority levels to help users quickly identify high-priority items in large datasets.

Example Configuration:

Entity: orders
Filter: priority = 'urgent'
Colour: #ffe6e6 (light red)
All Columns: true

Financial Indicators

Highlight financial data based on conditions, such as negative balances, outstanding payments, or profit margins below targets.

Example Configuration:

Entity: invoices
Filter: balance < 0
Colour: #fff3cd (light yellow)
All Columns: false
Columns: ["balance", "status"]

Behavior & Precedence

Evaluation Order

Column color rules are evaluated for each row in the grid. If multiple rules match a row, the last matching rule (in the order they appear in the database) is applied.

Performance Considerations

Column colors are evaluated in real-time as data changes. Keep filter expressions simple and efficient for best performance, especially on large datasets.

Disabled Rules

Use the disabled field to temporarily turn off color rules without deleting them. This is useful for testing or seasonal adjustments.

๐Ÿ’ก Best Practices
- Use subtle colors that don't interfere with text readability
- Limit the number of color rules per entity to avoid visual clutter
- Test color combinations for accessibility (contrast ratios)
- Give rules descriptive names to help maintain them later
- Consider user preferences - some users may be color-blind

Implementation Notes

Performance

Customizations are loaded and filtered efficiently using React hooks with proper dependency management and atomic state updates to prevent UI flickering.

Security

All customizations respect the underlying permission system and entity access controls. Users can only see and interact with customizations for entities they have access to.