### Development Setup for Camunda Modeler
Source: https://github.com/camunda/camunda-modeler/blob/develop/README.md
Command to spin up the application for development with all strings attached.
```sh
npm run dev
```
--------------------------------
### Build and Development Commands for Camunda Modeler
Source: https://context7.com/camunda/camunda-modeler/llms.txt
Commands for installing dependencies, running checks, building distributables, and starting the application in development mode with hot reload.
```sh
# Install all workspace dependencies
npm install
# Run all checks: lint, test, and build
npm run all
# Build distributable packages to ./dist
npm run build
# Start development mode with hot reload
npm run dev
# Open a specific file on launch
npm run dev -- resources/diagram/simple.bpmn
```
--------------------------------
### Build Camunda Modeler
Source: https://github.com/camunda/camunda-modeler/blob/develop/README.md
Commands to checkout a tag, install dependencies, run all checks, and build the application.
```sh
git checkout main
npm install
npm run all
npm run build
```
--------------------------------
### Camunda Modeler CLI File Arguments
Source: https://context7.com/camunda/camunda-modeler/llms.txt
Examples of using the Camunda Modeler command-line interface to open specific files or directories on startup. Files are resolved relative to the current working directory.
```sh
# Open one or more files directly from the command line
camunda-modeler path/to/diagram.bpmn path/to/decisions.dmn
# Open a BPMN file using a relative path (resolved from cwd)
camunda-modeler ./my-process.bpmn
# Chromium switches are filtered before file parsing
camunda-modeler --allow-file-access-from-files ./local.bpmn
```
--------------------------------
### Registering a Headless React Component as a Client Extension
Source: https://context7.com/camunda/camunda-modeler/llms.txt
Example of registering a React component as a client extension using `registerClientExtension`. This component can subscribe to events, interact with configuration, and render into UI slots.
```js
// resources/plugins/my-plugin/client/index.js
import { registerClientExtension } from 'camunda-modeler-plugin-helpers';
import { PureComponent } from 'react';
class MyExtension extends PureComponent {
constructor(props) {
super(props);
const { subscribe, displayNotification, config } = props;
// React to every tab save
subscribe('tab.saved', ({ tab }) => {
console.log('Saved tab:', tab.name);
displayNotification({
type: 'success', // 'info' | 'success' | 'warning' | 'error'
title: 'Saved!',
content: `${tab.name} was saved.`,
duration: 3000 // ms; 0 = persistent
});
});
// React when the active tab changes
subscribe('app.activeTabChanged', ({ activeTab }) => {
console.log('Active tab type:', activeTab.type);
// tab.type: 'bpmn' | 'cloud-bpmn' | 'dmn' | 'cloud-dmn' | 'form' | 'cloud-form'
});
// Persist plugin state across sessions
config.setForPlugin('my-plugin', 'lastUsed', Date.now());
config.getForPlugin('my-plugin', 'lastUsed', null).then(value => {
console.log('Last used:', value);
});
}
render() { return null; }
}
registerClientExtension(MyExtension);
```
--------------------------------
### Configure Camunda Modeler Application Settings
Source: https://context7.com/camunda/camunda-modeler/llms.txt
Use the `Config` class in the Electron main process to manage application-level settings. Access configuration values using `config.get(key, defaultValue)` and persist changes with `config.set(key, value)`. This includes retrieving editor themes, element templates for specific files, general settings, editor instance IDs, and OS information.
```javascript
const Config = require('./app/lib/config');
const config = new Config({
userPath: '/home/user/.config/camunda-modeler',
resourcesPaths: ['/opt/camunda-modeler/resources'],
ignoredPaths: []
});
// Get a simple config value (falls back to defaultValue)
const theme = config.get('editor.theme', 'dark');
// Get element templates for a given open file
const templates = config.get('bpmn.elementTemplates', { path: '/home/user/project/diagram.bpmn' });
// => loads from /home/user/project/.camunda/element-templates/**/*.json
// + global resources/element-templates/**/*.json
// + any 'elementTemplates' key stored in config.json
// Get current settings
const settings = config.get('settings');
// Persist a value
config.set('editor.theme', 'light');
// Get editor instance UUID (auto-generated, stored in .editorid)
const editorId = config.get('editor.id');
// Get OS info
const osInfo = config.get('os.info');
// => { platform: 'linux', release: '5.15.0', ... }
```
--------------------------------
### Store and Retrieve Plugin Configuration
Source: https://context7.com/camunda/camunda-modeler/llms.txt
Use `config.getForPlugin` to load persisted configuration values across sessions, and `config.setForPlugin` to store updated values. These methods return Promises.
```javascript
import { registerClientExtension } from 'camunda-modeler-plugin-helpers';
import { useEffect, useState } from 'react';
const PLUGIN_NAME = 'my-plugin';
function MyStatefulPlugin({ config }) {
const [counter, setCounter] = useState(0);
useEffect(() => {
// Load persisted value from previous session (returns a Promise)
config.getForPlugin(PLUGIN_NAME, 'counter', 0).then(savedValue => {
console.log('Restored counter:', savedValue);
setCounter(savedValue);
});
}, []);
useEffect(() => {
// Persist updated value on every change
config.setForPlugin(PLUGIN_NAME, 'counter', counter);
}, [counter]);
return null;
}
registerClientExtension(MyStatefulPlugin);
```
--------------------------------
### Register New File Type with Custom Editor
Source: https://context7.com/camunda/camunda-modeler/llms.txt
Use `registerClientPlugin` to add support for a new file format. Define the file extension, how to open it, and provide a custom React component for editing.
```javascript
// client/index.js
import React, { PureComponent } from 'react';
import { registerClientPlugin } from 'camunda-modeler-plugin-helpers';
class MyCustomEditor extends PureComponent {
// Called by the app to get current serialized content
triggerAction(action, context) {
if (action === 'save') {
return this.getCurrentContent();
}
}
render() {
return
My Custom Editor
;
}
}
const tabDescriptor = {
myFormat: {
name: 'My Format',
encoding: 'utf8',
exports: {},
extensions: ['myformat'], // file extensions this tab handles
canOpen(file) {
return file.name.endsWith('.myformat');
},
getComponent(options) {
return MyCustomEditor;
},
getIcon() {
return null; // return SVG component or null
},
getInitialContents() {
return '{}'; // default content for new files
},
getInitialFilename(suffix) {
return `diagram_${suffix}.myformat`;
},
getHelpMenu() {
return []; // array of { label, action } entries
},
getNewFileMenu() {
return [{
label: 'My Format Diagram',
group: 'Camunda 8',
action: 'create-diagram',
options: { type: 'myFormat' }
}];
},
getLinter() {
return null; // return a linter instance or null
}
}
};
registerClientPlugin(tabDescriptor, 'tabs');
```
--------------------------------
### Register Plugin Settings Schema
Source: https://context7.com/camunda/camunda-modeler/llms.txt
Use `settings.register` to define your plugin's configuration schema. This schema appears in the application's Settings panel. Use `settings.subscribe` to receive reactive updates for individual property changes.
```javascript
import React, { useEffect, useState } from 'react';
import { registerClientExtension } from 'camunda-modeler-plugin-helpers';
const PLUGIN_SETTINGS = {
id: 'myPlugin',
title: 'My Plugin Settings',
properties: {
'myPlugin.enabled': {
type: 'boolean',
default: true,
label: 'Enable My Plugin',
description: 'Toggle the plugin on or off.'
},
'myPlugin.endpoint': {
type: 'text',
default: 'https://api.example.com',
label: 'API Endpoint',
hint: 'Must be a valid HTTPS URL',
constraints: {
notEmpty: 'Endpoint is required',
pattern: {
value: /^https:\/\/.+/,
message: 'Must start with https://'
}
}
},
'myPlugin.mode': {
type: 'select',
label: 'Operation Mode',
options: [
{ label: 'Development', value: 'dev' },
{ label: 'Production', value: 'prod' }
],
condition: { property: 'myPlugin.enabled', equals: true }
}
}
};
function MySettingsPlugin({ settings }) {
const [enabled, setEnabled] = useState(true);
const [endpoint, setEndpoint] = useState('https://api.example.com');
useEffect(() => {
// Register settings schema and read current values
settings.register(PLUGIN_SETTINGS);
const values = settings.get();
setEnabled(values['myPlugin.enabled']);
setEndpoint(values['myPlugin.endpoint']);
}, []);
useEffect(() => {
// Subscribe to individual property changes
const unsub = settings.subscribe('myPlugin.enabled', ({ value }) => {
setEnabled(value);
});
return unsub; // call to unsubscribe
}, []);
return null;
}
registerClientExtension(MySettingsPlugin);
```
--------------------------------
### Camunda Modeler Plugin Entry Point Descriptor
Source: https://context7.com/camunda/camunda-modeler/llms.txt
Descriptor file for a Camunda Modeler plugin, specifying its name and the script to be executed for the client bundle.
```js
// Plugin entry point descriptor: resources/plugins/my-plugin/index.js
module.exports = {
name: 'my-plugin',
script: './dist/client.js' // built bundle
};
```
--------------------------------
### Plugin Settings API - register and subscribe
Source: https://context7.com/camunda/camunda-modeler/llms.txt
Register a plugin's settings schema to make its configuration appear in the application's Settings panel. Subscribe to individual property changes for reactive updates.
```APIDOC
## Plugin Settings API — `settings.register` and `settings.subscribe`
Register a plugin's settings schema so that its configuration appears in the application's Settings panel. Subscribe to individual property changes for reactive updates.
```js
import React, { useEffect, useState } from 'react';
import { registerClientExtension } from 'camunda-modeler-plugin-helpers';
const PLUGIN_SETTINGS = {
id: 'myPlugin',
title: 'My Plugin Settings',
properties: {
'myPlugin.enabled': {
type: 'boolean',
default: true,
label: 'Enable My Plugin',
description: 'Toggle the plugin on or off.'
},
'myPlugin.endpoint': {
type: 'text',
default: 'https://api.example.com',
label: 'API Endpoint',
hint: 'Must be a valid HTTPS URL',
constraints: {
notEmpty: 'Endpoint is required',
pattern: {
value: /^https:\/\/.+/,
message: 'Must start with https://'
}
}
},
'myPlugin.mode': {
type: 'select',
label: 'Operation Mode',
options: [
{ label: 'Development', value: 'dev' },
{ label: 'Production', value: 'prod' }
],
condition: { property: 'myPlugin.enabled', equals: true }
}
}
};
function MySettingsPlugin({ settings }) {
const [enabled, setEnabled] = useState(true);
const [endpoint, setEndpoint] = useState('https://api.example.com');
useEffect(() => {
// Register settings schema and read current values
settings.register(PLUGIN_SETTINGS);
const values = settings.get();
setEnabled(values['myPlugin.enabled']);
setEndpoint(values['myPlugin.endpoint']);
}, []);
useEffect(() => {
// Subscribe to individual property changes
const unsub = settings.subscribe('myPlugin.enabled', ({ value }) => {
setEnabled(value);
});
return unsub; // call to unsubscribe
}, []);
return null;
}
registerClientExtension(MySettingsPlugin);
```
```
--------------------------------
### triggerAction - Programmatic App Actions
Source: https://context7.com/camunda/camunda-modeler/llms.txt
The `triggerAction` prop on plugin components dispatches named actions to the main application. Available actions cover file lifecycle, tab management, UI, and notifications.
```APIDOC
## `triggerAction` — Programmatic App Actions
The `triggerAction` function allows plugins to programmatically trigger various actions within the Camunda Modeler application. This enables automation of tasks like creating new diagrams, managing files, navigating tabs, and interacting with UI panels.
### Description
This function is available as a prop to plugin components and can be invoked to perform predefined application actions. It accepts the action name as the first argument and an optional payload object as the second argument.
### Usage
```javascript
triggerAction(actionName: string, payload?: object)
```
### Available Actions
#### Diagram Creation
- **`create-bpmn-diagram`**: Creates a new BPMN diagram.
- **`create-cloud-bpmn-diagram`**: Creates a new Camunda 8 BPMN diagram.
- **`create-dmn-diagram`**: Creates a new DMN diagram.
- **`create-form`**: Creates a new Form.
#### File Operations
- **`open-diagram`**: Opens a file dialog to select and open a diagram. Can optionally take a `path` parameter to open a specific file.
- **`payload.path`** (string, optional): The absolute path to the file to open.
- **`save`**: Saves the currently active diagram.
- **`save-as`**: Opens a dialog to save the current diagram with a new name or location.
- **`save-all`**: Saves all open diagrams.
- **`export-as`**: Opens a dialog to export the current diagram in various formats.
#### Tab Management
- **`select-tab`**: Selects a specific tab. Use `'next'` or `'previous'` to navigate tabs.
- **`payload`** (string): `'next'`, `'previous'`, or the ID of the tab to select.
- **`close-active-tab`**: Closes the currently active tab.
- **`close-all-tabs`**: Closes all open tabs.
- **`reopen-last-tab`**: Reopens the last closed tab.
#### Panels and UI
- **`open-panel`**: Opens a specific application panel.
- **`payload.tab`** (string): The identifier of the panel to open (e.g., `'log'`).
- **`close-panel`**: Closes the currently open application panel.
- **`show-shortcuts`**: Displays the keyboard shortcuts dialog.
#### Notifications
- **`display-notification`**: Shows a notification message to the user.
- **`payload`** (object):
- **`type`** (string): The type of notification (e.g., `'info'`, `'warning'`, `'error'`).
- **`title`** (string): The title of the notification.
- **`content`** (string): The main content of the notification.
- **`duration`** (number, optional): The duration in milliseconds the notification should be displayed.
### Example Usage
```javascript
// Triggering various actions using triggerAction
// Create a new BPMN diagram
triggerAction('create-bpmn-diagram');
// Open a specific file
triggerAction('open-diagram', { path: '/absolute/path/to/file.bpmn' });
// Show a notification
triggerAction('display-notification', {
type: 'info',
title: 'Action Completed',
content: 'The diagram has been saved successfully.',
duration: 5000
});
```
```
--------------------------------
### Plugin Config API - getForPlugin / setForPlugin
Source: https://context7.com/camunda/camunda-modeler/llms.txt
Store and retrieve plugin-specific persistent configuration across sessions.
```APIDOC
## Plugin Config API — `config.getForPlugin` / `config.setForPlugin`
Store and retrieve plugin-specific persistent configuration across sessions.
```js
import { registerClientExtension } from 'camunda-modeler-plugin-helpers';
import { useEffect, useState } from 'react';
const PLUGIN_NAME = 'my-plugin';
function MyStatefulPlugin({ config }) {
const [counter, setCounter] = useState(0);
useEffect(() => {
// Load persisted value from previous session (returns a Promise)
config.getForPlugin(PLUGIN_NAME, 'counter', 0).then(savedValue => {
console.log('Restored counter:', savedValue);
setCounter(savedValue);
});
}, []);
useEffect(() => {
// Persist updated value on every change
config.setForPlugin(PLUGIN_NAME, 'counter', counter);
}, [counter]);
return null;
}
registerClientExtension(MyStatefulPlugin);
```
```
--------------------------------
### Trigger Application Actions Programmatically
Source: https://context7.com/camunda/camunda-modeler/llms.txt
Dispatch named actions to the main application using the `triggerAction` prop on plugin components. Available actions cover file lifecycle, tab management, UI, and notifications.
```javascript
import { registerClientExtension } from 'camunda-modeler-plugin-helpers';
import Fill from 'camunda-modeler-plugin-helpers/components/Fill';
import React from 'react';
function ActionPlugin({ triggerAction }) {
return (
{/* Create new diagrams */}
{/* File operations */}
{/* Tab navigation */}
{/* Panels and UI */}
{/* Open a specific file programmatically */}
{/* Notifications */}
);
}
registerClientExtension(ActionPlugin);
```
--------------------------------
### Subscribe to Modeler Lifecycle Events
Source: https://context7.com/camunda/camunda-modeler/llms.txt
Hook into the modeler lifecycle to inject custom modules and react to low-level modeler events for both BPMN and DMN editors. Use `bpmn.modeler.configure` and `dmn.modeler.configure` to inject additional modules, and `bpmn.modeler.created` and `dmn.modeler.created` to access the modeler instance after creation.
```javascript
import { PureComponent } from 'react';
import { registerClientExtension } from 'camunda-modeler-plugin-helpers';
// A custom bpmn-js module
const MyBpmnModule = {
__init__: ['myService'],
myService: ['type', class {
constructor(eventBus) {
eventBus.on('element.click', ({ element }) => {
console.log('Clicked element:', element.id, element.type);
});
}
}]
};
class ModelerEventsPlugin extends PureComponent {
constructor(props) {
super(props);
const { subscribe } = props;
// Inject custom module before the modeler is instantiated
subscribe('bpmn.modeler.configure', (event) => {
const { tab, middlewares } = event;
middlewares.push((config) => ({
...config,
additionalModules: [
...(config.additionalModules || []),
MyBpmnModule
]
}));
});
// Access the modeler instance after creation
subscribe('bpmn.modeler.created', ({ tab, modeler }) => {
// Subscribe to bpmn-js internal events
modeler.on('saveXML.start', ({ definitions }) => {
console.log('Saving diagram for tab:', tab.name);
});
modeler.on('import.done', ({ error, warnings }) => {
if (error) console.error('Import failed:', error);
if (warnings.length) console.warn('Import warnings:', warnings);
});
});
// Similarly for DMN editors
subscribe('dmn.modeler.configure', (event) => {
const { middlewares } = event;
middlewares.push((config) => {
const newConfig = { ...config };
for (const viewer of ['drd', 'decisionTable', 'literalExpression']) {
newConfig[viewer] = {
...(newConfig[viewer] || {}),
additionalModules: [
...((newConfig[viewer] || {}).additionalModules || [])
]
};
}
return newConfig;
});
});
subscribe('dmn.modeler.created', ({ tab, modeler }) => {
console.log('DMN modeler created for tab:', tab.name);
});
// Post-save hook
subscribe('tab.saved', ({ tab }) => {
console.log('Tab saved:', tab.name, 'path:', tab.file && tab.file.path);
});
}
render() { return null; }
}
registerClientExtension(ModelerEventsPlugin);
```
--------------------------------
### Render Focused Modal Dialog
Source: https://context7.com/camunda/camunda-modeler/llms.txt
Use the `Modal` helper component to display focused modal dialogs within the Camunda Modeler. This is useful for user confirmations or input forms.
```javascript
import React, { useState } from 'react';
import { registerClientExtension } from 'camunda-modeler-plugin-helpers';
import Fill from 'camunda-modeler-plugin-helpers/components/Fill';
import Modal from 'camunda-modeler-plugin-helpers/components/Modal';
function MyModalPlugin(props) {
const [open, setOpen] = useState(false);
return (
{open && (
Confirm Action
Are you sure you want to proceed?
)}
);
}
registerClientExtension(MyModalPlugin);
```
--------------------------------
### Internal CLI Argument Parsing in Camunda Modeler
Source: https://context7.com/camunda/camunda-modeler/llms.txt
Internal JavaScript usage for parsing command-line arguments and the current working directory within the Camunda Modeler's main process.
```js
// Internal usage in app/lib/cli.js
const { parse } = require('./cli');
const { files, flags } = parse(process.argv, process.cwd());
// files => ['/absolute/path/to/diagram.bpmn']
// flags => { 'some-flag': true }
```
--------------------------------
### Feature Flags Configuration
Source: https://context7.com/camunda/camunda-modeler/llms.txt
JSON configuration for enabling or disabling Modeler features. Flags can be set globally in `resources/flags.json` or overridden via command-line arguments.
```json
// resources/flags.json
{
"disable-rpa": false
}
```
```javascript
// Available flag names (from client/src/app/util/Flags.js)
// DISABLE_DMN — hide DMN editor
// DISABLE_FORM — hide Form editor
// DISABLE_ZEEBE — hide all Camunda 8 / Zeebe tabs
// DISABLE_PLATFORM — hide all Camunda 7 / Platform tabs
// DISABLE_RPA — hide RPA script editor
// DISABLE_HTTL_HINT — disable "HTTP Task Listener" hint
// DEFAULT_HTTL — set default HTTL version
// CLI override example:
// camunda-modeler --disable-zeebe=true
// camunda-modeler --disable-dmn
// camunda-modeler --no-disable-rpa (negate a flag)
```
--------------------------------
### Subscribing to Editor Events
Source: https://context7.com/camunda/camunda-modeler/llms.txt
Hook into the modeler lifecycle to inject custom bpmn-js or dmn-js modules and react to low-level modeler events. This allows for customization before the modeler is instantiated and interaction with the modeler instance after creation.
```APIDOC
## Subscribing to Editor Events
This section describes how to subscribe to various events emitted by the Camunda Modeler's BPMN and DMN editors to customize their behavior or react to lifecycle changes.
### `bpmn.modeler.configure`
**Description**: Called before the BPMN modeler is instantiated. Allows modification of the modeler configuration, such as injecting additional bpmn-js modules.
**Usage**: Subscribe to this event to provide custom modules or configurations to the BPMN editor.
```javascript
subscribe('bpmn.modeler.configure', (event) => {
const { tab, middlewares } = event;
middlewares.push((config) => ({
...config,
additionalModules: [
...(config.additionalModules || []),
MyBpmnModule // Your custom bpmn-js module
]
}));
});
```
### `bpmn.modeler.created`
**Description**: Called after the BPMN modeler instance has been created. Allows direct interaction with the modeler instance and subscription to its internal events.
**Usage**: Subscribe to this event to perform actions once the BPMN editor is ready, like logging diagram save events or handling import results.
```javascript
subscribe('bpmn.modeler.created', ({ tab, modeler }) => {
// Subscribe to bpmn-js internal events
modeler.on('saveXML.start', ({ definitions }) => {
console.log('Saving diagram for tab:', tab.name);
});
modeler.on('import.done', ({ error, warnings }) => {
if (error) console.error('Import failed:', error);
if (warnings.length) console.warn('Import warnings:', warnings);
});
});
```
### `dmn.modeler.configure`
**Description**: Called before the DMN modeler is instantiated. Allows modification of the DMN modeler configuration.
**Usage**: Subscribe to this event to provide custom configurations to the DMN editor.
```javascript
subscribe('dmn.modeler.configure', (event) => {
const { middlewares } = event;
middlewares.push((config) => {
const newConfig = { ...config };
for (const viewer of ['drd', 'decisionTable', 'literalExpression']) {
newConfig[viewer] = {
...(newConfig[viewer] || {}),
additionalModules: [
...((newConfig[viewer] || {}).additionalModules || [])
]
};
}
return newConfig;
});
});
```
### `dmn.modeler.created`
**Description**: Called after the DMN modeler instance has been created. Allows interaction with the DMN modeler instance.
**Usage**: Subscribe to this event to perform actions once the DMN editor is ready.
```javascript
subscribe('dmn.modeler.created', ({ tab, modeler }) => {
console.log('DMN modeler created for tab:', tab.name);
});
```
### `tab.saved`
**Description**: Called after a tab has been successfully saved.
**Usage**: Subscribe to this event to perform actions after a file is saved, such as logging the saved file path.
```javascript
subscribe('tab.saved', ({ tab }) => {
console.log('Tab saved:', tab.name, 'path:', tab.file && tab.file.path);
});
```
```
--------------------------------
### Inject UI Elements into Application Shell
Source: https://context7.com/camunda/camunda-modeler/llms.txt
Use the `Fill` component to inject custom UI elements into predefined slots within the Camunda Modeler's application shell, such as the toolbar or status bar.
```javascript
import React, { Fragment, useState } from 'react';
import { registerClientExtension } from 'camunda-modeler-plugin-helpers';
import Fill from 'camunda-modeler-plugin-helpers/components/Fill';
function MyToolbarPlugin(props) {
const { subscribe } = props;
const [count, setCount] = useState(0);
subscribe('tab.saved', () => setCount(c => c + 1));
return (
{/* Inject into the main toolbar */}
Saves: {count}
{/* Inject a button into the file section of the status bar */}
{/* Inject into the application section of the status bar with ordering */}
Plugin Ready
{/* Inject a panel into the bottom panel (conditional on tab type) */}
Custom Analysis
);
}
registerClientExtension(MyToolbarPlugin);
```
--------------------------------
### Camunda 8 Element Template JSON Schema
Source: https://context7.com/camunda/camunda-modeler/llms.txt
Defines element templates for Camunda 8 (Zeebe/Cloud) using the Zeebe binding schema. These templates are placed in the same directories as Camunda 7 templates.
```json
[
{
"$schema": "https://unpkg.com/@camunda/zeebe-element-templates-json-schema/resources/schema.json",
"name": "Email Connector",
"id": "io.camunda.examples.EmailConnector",
"description": "Sends an email via SMTP.",
"appliesTo": ["bpmn:ServiceTask"],
"properties": [
{
"type": "Hidden",
"value": "send-email",
"binding": { "type": "zeebe:taskDefinition:type" }
},
{
"label": "SMTP Host",
"type": "String",
"binding": {
"type": "zeebe:input",
"name": "HOST_NAME"
},
"constraints": { "notEmpty": true }
},
{
"label": "Port",
"type": "String",
"value": "= 25",
"optional": true,
"binding": {
"type": "zeebe:input",
"name": "PORT"
}
},
{
"label": "Recipient",
"type": "String",
"binding": {
"type": "zeebe:input",
"name": "recipient"
},
"constraints": { "notEmpty": true }
}
]
}
]
```
--------------------------------
### Register Custom bpmnlint Rules
Source: https://context7.com/camunda/camunda-modeler/llms.txt
Extend BPMN diagram validation by registering custom lint rules. This involves providing a configuration and resolver from your bpmnlint configuration file.
```javascript
// resources/plugins/my-lint-rules/client/index.js
import { registerClientPlugin } from 'camunda-modeler-plugin-helpers';
import { config, resolver } from '../.bpmnlintrc';
// Apply rules to both Camunda 7 and Camunda 8 BPMN editors
registerClientPlugin({ config, resolver }, 'lintRules.bpmn');
registerClientPlugin({ config, resolver }, 'lintRules.cloud-bpmn');
```
```json
// .bpmnlintrc — bpmnlint configuration
{
"extends": "bpmnlint:recommended",
"rules": {
"label-required": "warn",
"no-implicit-split": "error"
}
}
```
--------------------------------
### Camunda 7 Element Template JSON Schema
Source: https://context7.com/camunda/camunda-modeler/llms.txt
Defines element templates for Camunda 7 (Platform) using JSON. These templates configure BPMN service tasks with pre-defined properties and are placed in specific directories.
```json
[
{
"$schema": "https://unpkg.com/@camunda/element-templates-json-schema/resources/schema.json",
"name": "Mail Task",
"id": "com.camunda.example.MailTask",
"appliesTo": ["bpmn:ServiceTask"],
"properties": [
{
"label": "Implementation Type",
"type": "String",
"value": "com.mycompany.MailTaskImpl",
"editable": false,
"binding": {
"type": "property",
"name": "camunda:class"
}
},
{
"label": "Sender",
"type": "String",
"binding": {
"type": "camunda:inputParameter",
"name": "sender"
},
"constraints": {
"notEmpty": true,
"pattern": {
"value": "^[A-z0-9._%+-]+@[A-z0-9.-]+\\.[A-z]{2,}$",
"message": "Must be a valid email."
}
}
},
{
"label": "Template",
"description": "Supports Freemarker templates",
"value": "Hello ${firstName}!",
"type": "Text",
"binding": {
"type": "camunda:inputParameter",
"name": "messageBody",
"scriptFormat": "freemarker"
},
"constraints": { "notEmpty": true }
}
]
}
]
```
--------------------------------
### Display Toast Notifications with Update/Close Control
Source: https://context7.com/camunda/camunda-modeler/llms.txt
Use `displayNotification` to show transient messages. You can dynamically update or manually close these notifications. Set `duration` to 0 for persistent notifications.
```javascript
import { registerClientExtension } from 'camunda-modeler-plugin-helpers';
import Fill from 'camunda-modeler-plugin-helpers/components/Fill';
import React from 'react';
function NotificationPlugin({ displayNotification, subscribe }) {
subscribe('tab.saved', async ({ tab }) => {
// Show a notification and get handles to update/close it
const notification = displayNotification({
type: 'success', // 'info' | 'success' | 'warning' | 'error'
title: 'Saved',
content: `${tab.name} saved successfully.`,
duration: 4000 // auto-close after 4 seconds; 0 = persistent
});
// Dynamically update the notification content
setTimeout(() => {
notification.update({ title: 'Synced', content: 'Also pushed to server.' });
}, 1000);
// Manually close it
setTimeout(() => notification.close(), 3000);
});
return null;
}
registerClientExtension(NotificationPlugin);
```
=== COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.