bpmn-js Properties Panel

repository·main·Indexed 43 days ago

https://github.com/bpmn-io/bpmn-js-properties-panel

A properties panel extension for bpmn-js (v5.65.0) that allows users to edit technical BPMN properties, including generic and Camunda-specific (7 and 8) properties. It provides a consistent UX for configuring BPMN elements with support for FEEL expressions, custom property providers, and dynamic attachment to the DOM.

Tokens
6.6K
Snippets
26
Records
31
Agent score
56%

What's inside bpmn-js-properties-panel

  1. Understand the UX design principles of the properties panel

    main

    The bpmn-js-properties-panel is designed to provide a predictable and consistent experience for configuring BPMN elements, specifically for Camunda solutions. The design focuses on several key user experience traits:

    • Discoverability: Sections use semantic names and tooltips to provide guidance without requiring the user to open them.
    • Visual Indicators for Edits: An edited indicator appears on a per-section basis when task implementation deviates from default values, helping users identify what has been configured.
    • Global Section State: The open/closed state of a section is global. If a section (e.g., 'Documentation') is open for one element, it remains open when the user selects another element that also contains that section.
    • Contextual Learning: Documentation is provided via tooltips and links to external documentation to avoid cluttering the UI, ensuring expert users aren't distracted while beginners can still find help.
    • FEEL Expression Support: To distinguish between static configuration and dynamic FEEL (Friendly Enough Expression Language) evaluation, the panel uses a clear UI signal: typing = at the start of a value turns the field into a FEEL editor. If a field does not support FEEL, the = is treated as a static string.
  2. Develop the bpmn-js-properties-panel library

    main

    To contribute to or develop the library locally, follow these steps:

    1. Install dependencies: npm install
    2. Run the desired command:
      • npm run all: Build the library and run all tests.
      • npm start: Spin up a single local modeler instance.
      • npm run dev: Run the full development setup.
    npm install
    
    # build the library and run all tests
    npm run all
    
    # spin up a single local modeler instance
    npm start
    
    # run the full development setup
    npm run dev
  3. How to edit Camunda 8 properties

    main

    To enable editing of Camunda 8 (Zeebe) properties, you need a combination of a moddle extension (to allow bpmn-js to read/write the properties), a specific provider (to show them in the UI), and specific behaviors (to maintain model integrity).

    Required components:

    1. Moddle Extension: zeebe-bpmn-moddle
    2. Provider: ZeebePropertiesProviderModule from bpmn-js-properties-panel
    3. Behaviors: camunda-bpmn-js-behaviors/lib/camunda-cloud
    import BpmnModeler from 'bpmn-js/lib/Modeler';
    import {
      BpmnPropertiesPanelModule,
      BpmnPropertiesProviderModule,
      ZeebePropertiesProviderModule // Camunda 8 provider
    } from 'bpmn-js-properties-panel';
    
    // Camunda 8 moddle extension
    import zeebeModdle from 'zeebe-bpmn-moddle/resources/zeebe.json';
    
    // Camunda 8 behaviors
    import ZeebeBehaviorsModule from 'camunda-bpmn-js-behaviors/lib/camunda-cloud';
    
    const modeler = new BpmnModeler({
      container: '#canvas',
      propertiesPanel: {
        parent: '#properties'
      },
      additionalModules: [
        BpmnPropertiesPanelModule,
        BpmnPropertiesProviderModule,
        ZeebePropertiesProviderModule,
        ZeebeBehaviorsModule
      ],
      moddleExtensions: {
        zeebe: zeebeModdle
      }
    });
  4. Integrate bpmn-js-properties-panel with bpmn-js

    main

    To use the properties panel, you must provide two HTML elements: one for the BPMN diagram canvas and one for the properties panel container. You then bootstrap bpmn-js (specifically BpmnModeler) by passing the propertiesPanel.parent configuration and including the required modules in additionalModules.

    Required HTML structure:

    <div class="modeler">
      <div id="canvas"></div>
      <div id="properties"></div>
    </div>
    ```javascript
    import BpmnModeler from 'bpmn-js/lib/Modeler';
    import {
      BpmnPropertiesPanelModule,
      BpmnPropertiesProviderModule,
    } from 'bpmn-js-properties-panel';
    
    const modeler = new BpmnModeler({
      container: '#canvas',
      propertiesPanel: {
        parent: '#properties'
      },
      additionalModules: [
        BpmnPropertiesPanelModule,
        BpmnPropertiesProviderModule
      ]
    });
    ```},{
  5. Resolve entry IDs with getEntryId

    main

    The getEntryId(element, path) method resolves the unique ID of the UI entry that edits a specific moddle property path. This is useful for identifying which specific input field corresponds to a deep path in the element's business object.

    const propertiesPanel = modeler.get('propertiesPanel');
    
    const entryId = propertiesPanel.getEntryId(element, [
      'extensionElements', 'values', 0, 'inputParameters', 1, 'source'
    ]);
    // returns something like 'ServiceTask_1-input-1-source'
  6. Register a custom properties provider

    main

    To add custom property groups or modify existing ones, implement a PropertiesProvider and register it using registerProvider(priority, provider).

    Providers are asked in reverse render order based on their priority. A provider with a lower priority (e.g., a higher number) will be asked first if it intends to override others.

    class ExamplePropertiesProvider {
      constructor(propertiesPanel) {
        propertiesPanel.registerProvider(500, this);
      }
    
      getGroups(element) {
        return (groups) => {
    
          // add, modify or remove groups
          // ...
    
          return groups;
        };
      }
    }
    
    ExamplePropertiesProvider.$inject = [ 'propertiesPanel' ];
  7. Dynamically attach or detach the properties panel

    main

    You can manipulate the properties panel's location at runtime by retrieving it from the modeler instance using modeler.get('propertiesPanel').

    • Use .detach() to remove the panel from the DOM.
    • Use .attachTo(container) to attach it to a new element.
    • Use .attachTo(container, headerContainer) to separate the panel body and the header into different containers.
    const propertiesPanel = bpmnJS.get('propertiesPanel');
    
    // detach the panel
    propertiesPanel.detach();
    
    // attach it to some other element
    propertiesPanel.attachTo('#other-properties');
    
    // or attach the panel body and header to different containers
    propertiesPanel.attachTo('#properties', '#panel-header');
  8. Enable single start mode for debugging

    main

    Setting the SINGLE_START environment variable modifies the Karma configuration to facilitate debugging. It appends the Debug browser to the existing browser list and adds SINGLE_START to the environment preprocessor.

    # Example: Run tests in debug mode
    SINGLE_START=true npm test
  9. Run tests with coverage reporting

    main

    To generate code coverage reports during testing, set the COVERAGE environment variable. This triggers the following behaviors:

    • Uses test/coverageBundle.js as the test suite instead of test/testBundle.js.
    • Adds the coverage reporter to Karma.
    • Configures the coverageReporter to output lcov reports in the current directory.
    • Injects the istanbul plugin via Babel to instrument the code (excluding files in test/**/*).
    # Example: Run tests with coverage
    COVERAGE=true npm test
  10. Configure test browsers via environment variables

    main

    When running tests, you can specify which browsers to use by setting the TEST_BROWSERS environment variable. The value should be a comma-separated list of browser names. Supported browsers include:

    • ChromeHeadless (default)
    • Chrome
    • Firefox
    • IE
    • PhantomJS
    • Debug (added if SINGLE_START is set)
    # Example: Run tests in Chrome and Firefox
    TEST_BROWSERS=Chrome,Firefox npm test
  11. Configure Zeebe event condition properties

    main

    The EventConditionProps function provides the property entries for Zeebe event conditions. It handles two main types of properties depending on the element type:

    1. bpmn:Condition: Always provided if the element has a conditional event definition. It uses a BpmnFeelEntry for entering FEEL expressions.
    2. zeebe:ConditionalFilter: Provided if the element is a bpmn:SubProcess, bpmn:IntermediateCatchEvent, or bpmn:BoundaryEvent. This allows configuring variableEvents via a CheckboxGroup with the following options:
      • create (labeled 'Create')
      • update (labeled 'Update')

    Note: The id for these entries is generated using getSingletonEntryId to ensure uniqueness within the panel.

    import { EventConditionProps } from 'src/provider/zeebe/properties/EventConditionProps';
    
    // In a properties panel provider context:
    const entries = EventConditionProps({ element });