### 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.