Skip to content

BPMN ​

Назначение ​

Панель bpmn загружает граф процесса из метода бэкенда, преобразует ресурсы Object в узлы BPMN и, если это разрешено конфигурацией, создаёт, изменяет, перемещает, соединяет и удаляет элементы процесса.

Когда использовать ​

Выбирайте BPMN для графа, чьи Object и Link существуют в бэкенде, а жизненный цикл сохраняется через действия над Object, Link и методами. Панель не предназначена для статических или полностью клиентских диаграмм.

Предварительные условия и ответственность ​

  • request.parent и request.method должны указывать на метод, который возвращает ожидаемое панелью состояние графа.
  • Передайте request.objects либо настройте request.getSelectedObjectForEventId.
  • graph.nodes сопоставляет типы сущностей бэкенда с карточками и операциями узлов BPMN.
  • Элементы graph.toolbar.items настраивают создание. Существующие Link приходят из ответа метода.
  • Панель отвечает за вызов метода, преобразование ответа, операции сохранения и положение области просмотра. Установленный @mes/bpmn@0.8.0 отвечает за холст и палитру.

Основные разделы конфигурации ​

request загружает граф, graph.nodes описывает существующие ресурсы Object, graph.toolbar — создание и инструменты пакета, а graph.readOnly — доступность редактирования. graph.theme остаётся объявленным ограничением и не настраивает тему во время выполнения.

Возможности ​

ОбластьПоддерживаемое поведение
ЗагрузкаОдин вызов метода с parent, method, разрешёнными objects и непрозрачными params
УзлыСопоставление по metaType.typeName; bpmnType может переопределить вывод типа
Виды узловЗадача, начальное и конечное событие, исключающий и параллельный шлюз
КарточкиШаблоны заголовка и подзаголовка, значок или аватар, поля в одну или несколько колонок
ПалитраСтабильные идентификаторы, задачи, события, шлюзы и коннекторы с linkName, source и target
ИнструментыВидимость руки, оптимизации и удаления передаётся в установленный пакет
Жизненный циклonObjectCreate; настроенные обновление и удаление узлов; создание и удаление коннекторов; изменение концов сохранённого коннектора только через удаление и создание нового; сохранение координат
Только чтениеgraph.readOnly: true запрещает редактирование
Область просмотраМасштаб и положение сохраняются между повторными монтированиями виджета в текущей сессии

Модель работы ​

  1. Панель получает objects: сначала использует непустой явный массив, иначе — Object из события выбора.
  2. Панель вызывает метод и разворачивает возвращённые блоки Object и Link.
  3. Ресурсы Object становятся узлами BPMN. typeName выбирает карточку; явный bpmnType имеет приоритет над выводом начального события, конечного события или шлюза из имени типа.
  4. Ресурсы Link из ответа API становятся обычными или условными переходами.
  5. Изменения пользователя сравниваются с последней подтверждённой моделью и передаются в настроенные операции создания, обновления и удаления. Если пользователь переносит начало или конец сохранённого коннектора на другой узел, панель отменяет перенос. Вместо этого удалите коннектор и нарисуйте новый.

Создание и отображение разделены: элементы палитры определяют, как создать сущность, а graph.nodes — как показать и изменить уже существующую.

Варианты, значения по умолчанию и приоритеты ​

  • Непустой request.objects имеет приоритет над Object из события.
  • По умолчанию graph.readOnly равен false.
  • Вид узла выбирается в порядке: bpmnType подходящего описания узла, вывод из имени типа, затем task.
  • Заголовок новой задачи выбирается в порядке: placeholderCard.title, заголовок подходящей карточки, typeName, затем id элемента палитры.
  • Если флаги инструментов не заданы, пакет показывает руку, оптимизацию и удаление.
  • Размер новой задачи по умолчанию — 292 × 132; явный size его заменяет.

Ограничения и расхождения с объявленными типами ​

  • graph.edges не относится к поддерживаемым параметрам конфигурации. Старые сохранённые JSON-конфигурации с этим полем продолжают загружаться: панель не читает лишнее поле. При редактировании удалите его; существующие коннекторы по-прежнему строятся из ресурсов Link в ответе метода графа.
  • graph.theme объявлен, но не используется; адаптер передаёт собственную тему.
  • graph.toolbar.showConnect передаётся адаптером, но установленный пакет его игнорирует.
  • params зависят от метода и намеренно имеют непрозрачный тип.
  • Локальный пример работает только для чтения. Он не доказывает сохранение создания, обновления, удаления или коннекторов.

По умолчанию новый коннектор сохраняет в sourceGuid и targetGuid GUID Object, которым соответствуют соединённые BPMN-узлы. Настройте getGraphContextLink для нужного конца, если вместо GUID такого Object коннектор должен сохранить GUID уже существующего Link между текущим Object из запроса графа и Object, представленным этим узлом.

Пользователь только рисует коннектор. Существующий Link BPMN находит автоматически:

  1. BPMN читает GUID Object, переданные в текущий запрос графа после обработки request.objects или request.getSelectedObjectForEventId. Поиск продолжается, только если во входных данных один GUID; этот Object становится текущим Object запроса графа. Панель не определяет его по ответу метода.
  2. Создание коннектора запускает POST /Object/getLinkedObjects. BPMN передаёт текущий Object запроса графа, обязательный технический getGraphContextLink.linkName и настроенное направление.
  3. BPMN сопоставляет ответ с визуальным концом и принимает ровно один уникальный link.objectGuid.
  4. Непосредственно перед POST /Link BPMN проверяет, что текущим остался тот же Object запроса графа. Принятый GUID Link записывается в настроенный sourceGuid или targetGuid; ненастроенный конец сохраняет GUID Object, соответствующего соединённому узлу.
  5. BPMN повторно вызывает метод получения графа. Полученный граф заменяет временный коннектор на холсте сохранённым коннектором с GUID сохранённого Link.

Для этого не нужны Tree, Table, выбор связанной строки, предварительная загрузка или panelId.

Эта конфигурация показывает все поля, необходимые для создания коннектора Link-to-Object. Перед использованием замените проектные значения:

  • FlowHead — метатип, для которого настроен метод получения графа;
  • getFlowGraph — имя этого метода MethodRun;
  • значение в request.objects — единственный GUID текущего Object запроса графа;
  • FlowStatus — технический тип существующего контекстного Link;
  • ContextualStatusTransition — тип нового коннектора, совместимый с концами Link-to-Object.

Эта панель BPMN создаёт коннектор Link-to-Object. Существующий Link FlowStatus от текущего Object запроса графа к Object, представленному визуальным источником, становится сохранённым источником нового коннектора:

json
{
  "id": "flow-bpmn",
  "type": "bpmn",
  "request": {
    "parent": "FlowHead",
    "method": "getFlowGraph",
    "objects": ["11111111-1111-1111-1111-111111111111"],
    "params": {}
  },
  "graph": {
    "readOnly": false,
    "toolbar": {
      "items": [
        {
          "id": "contextual-status-transition",
          "bpmnType": "bpmn:SequenceFlow",
          "request": {
            "linkName": "ContextualStatusTransition",
            "source": {
              "getGraphContextLink": {
                "linkName": "FlowStatus",
                "reverse": false
              }
            }
          }
        }
      ]
    },
    "nodes": []
  }
}

getGraphContextLink.linkName — обязательное техническое имя типа существующего контекстного Link. Обычно оно отличается от внешнего request.linkName, который задаёт тип нового коннектора.

reverse задаёт направление существующего Link, который BPMN ищет через POST /Object/getLinkedObjects:

  • без reverse либо с reverse: false: текущий Object запроса графа → Object, представленный визуальным узлом;
  • с reverse: true: Object, представленный визуальным узлом → текущий Object запроса графа.

Это направление существующего контекстного Link, а не визуальное направление нового коннектора. Такой же объект getGraphContextLink в request.target позволяет создавать Object-to-Link и Link-to-Link.

Если конец коннектора должен определяться явно выбранной пользователем строкой, используйте событие. Оно должно сохранить ObjectSelector действием addSelectedObjectToRequest:

json
{
  "source": {
    "getSelectedObjectForEventId": "source-status--on-select"
  },
  "target": {
    "getSelectedObjectForEventId": "target-status--on-select",
    "idSource": "link"
  }
}
  • idSource: "link" возвращает GUID выбранного Link.
  • Без idSource либо с idSource: "linkedObject" возвращается GUID выбранного Object.
  • getSelectedObjectForEventId и getGraphContextLink взаимоисключают друг друга для одного конца. Смешанная настройка отклоняется до любого запроса.
  • Если source или target не задан, сохраняется GUID Object, соответствующего соединённому BPMN-узлу.
  • getGraphContextLink.linkName должен содержать непустое техническое имя типа Link.
  • Если ответ со связанными Object отсутствует, неоднозначен, повреждён или неполон, конец считается неразрешённым. Смена контекста графа во время запроса даёт тот же результат. BPMN не подставляет GUID Object, соответствующего узлу, и не создаёт коннектор.
  • Внешний request.linkName должен обозначать тип Link нового коннектора, совместимый с видами Object/Link в его концах. Тип Object-to-Object нельзя использовать для Link-to-Object.

Если после рисования коннектор не остался на диаграмме ​

BPMN не отправляет POST /Link, когда не может безопасно определить GUID Link для настроенного конца. Панель показывает причину в уведомлении, снова получает граф и убирает несохранённый коннектор. Сначала прочитайте уведомление, затем выберите соответствующее действие:

  1. Нужен ровно один текущий Object графа. Укажите один GUID в request.objects или настройте request.getSelectedObjectForEventId, чтобы до вызова метода графа он передавал один GUID. Панель проверяет входные данные автоматически; проверять ответ метода вручную не нужно. Если по сценарию Object нет или их несколько, getGraphContextLink не подходит: уберите source или target для конца-Object либо настройте явный выбор Link через событие и idSource: "link".
  2. Link не найден. Проверьте три значения: технический тип в getGraphContextLink.linkName, направление в reverse и GUID Object в запросе графа. Для reverse: false существующий Link должен идти от этого Object к Object визуального узла; для reverse: true — в обратную сторону. Повторите попытку только после исправления значения или создания отсутствующего Link в интерфейсе приложения, где редактируются связи между Object. Если конец должен хранить GUID Object, уберите source или target и используйте совместимый тип нового Link.
  3. Найдено несколько Link. Автоматический поиск не может выбрать один. Удалите ошибочные дубли в интерфейсе редактирования связей. Если все Link нужны, настройте показанный выше явный выбор через getSelectedObjectForEventId и idSource: "link".
  4. Граф загружается или его Object изменился. Дождитесь актуального графа и нарисуйте коннектор снова. BPMN не использует результат из предыдущего контекста.
  5. Запрос к API завершился ошибкой или ответ некорректен. Дождитесь актуального графа и повторите попытку один раз. Если ошибка повторится, приложите к обращению текст уведомления, значение getGraphContextLink.linkName, значение getGraphContextLink.reverse, GUID Object из запроса графа и GUID соединяемого узла. До исправления ответа API этот вариант конца коннектора использовать нельзя.

Если редактирование связей недоступно, не повторяйте рисование при сообщении об отсутствующем или неоднозначном Link. Приложите к обращению текст уведомления, getGraphContextLink.linkName, getGraphContextLink.reverse, GUID Object из запроса графа и GUID соединяемого узла.

Повторное рисование без изменения конфигурации, данных или состояния API даст тот же результат. Создание коннектора не создаёт отсутствующий Link и не удаляет дубли автоматически.

После POST /Link сервер должен вернуть по одному UUID на каждый запрошенный Link. Затем BPMN снова вызывает метод получения графа и сообщает об успехе, только если полученный граф содержит все UUID из ответа на создание.

  • Если уведомление сообщает, что Link создан, но его коннектор не появился, Link уже существует. Виджет показывает его GUID. Не рисуйте коннектор снова. Проверьте Link по GUID в интерфейсе редактирования связей или приложите GUID и текст уведомления к обращению.
  • Если уведомление сообщает, что BPMN не удалось определить, был ли создан Link, не рисуйте коннектор снова, пока не проверите коннектор между исходным и целевым узлами и ожидаемый Link в интерфейсе редактирования связей. Если такая проверка недоступна, приложите к обращению текст уведомления и полный блок request из конфигурации панели; по нему видно request.linkName и наличие либо отсутствие необязательных полей request.source и request.target.

Метод получения графа или его скрипт по-прежнему должен преобразовывать сохранённый Link обратно в идентификаторы визуальных узлов source и target. Начало или конец любого сохранённого коннектора нельзя перенести на другой узел независимо от текущей настройки палитры. Если пользователь попытается это сделать, BPMN не отправит PUT /Link, а снова вызовет настроенный метод получения графа. Коннектор вернётся в прежнее положение. Чтобы изменить соединение, удалите коннектор и нарисуйте новый. Ограничение нужно потому, что ответ метода содержит достаточно данных для показа ребра, но не сообщает, чем были сохранены его концы — GUID Object или GUID Link.

Удаление существующего коннектора не изменилось. BPMN удаляет его по GUID сохранённого Link, соответствующего коннектору и возвращённого методом графа; при удалении getGraphContextLink не выполняется.

Минимальная конфигурация ​

json
{
  "id": "workflow",
  "type": "bpmn",
  "request": {
    "parent": "WFEntityInstance",
    "method": "getWorkFlowGraphState",
    "objects": [],
    "params": {}
  },
  "graph": {
    "readOnly": true,
    "toolbar": { "items": [] },
    "nodes": []
  }
}

Сценарий: редактируемые задачи и коннекторы ​

json
{
  "id": "work-order-workflow",
  "type": "bpmn",
  "request": {
    "parent": "WFEntityInstance",
    "method": "getWorkFlowGraphState",
    "objects": [],
    "params": {},
    "getSelectedObjectForEventId": "work-orders--selected"
  },
  "graph": {
    "readOnly": false,
    "toolbar": {
      "items": [
        {
          "id": "task-operation",
          "bpmnType": "task",
          "typeName": "WorkOrderOperation",
          "icon": "icon icon--task",
          "size": { "w": 292, "h": 132 },
          "placeholderCard": { "title": "New operation" },
          "events": [
            {
              "id": "workflow--create-operation",
              "name": "onObjectCreate",
              "actions": [
                {
                  "name": "create",
                  "editor": {
                    "mode": "modal",
                    "entityType": {
                      "object": { "metaTypeName": "WorkOrderOperation" }
                    },
                    "fields": [
                      { "attribute": "itemId", "label": "Number" },
                      { "attribute": "name", "label": "Name" }
                    ]
                  }
                }
              ]
            }
          ]
        },
        {
          "id": "workflow-link",
          "bpmnType": "bpmn:SequenceFlow",
          "icon": "icon icon--arrow",
          "request": { "linkName": "WFConnectorInstance" }
        }
      ],
      "showHand": true,
      "showOptimize": true,
      "showDelete": true
    },
    "nodes": [
      {
        "typeName": "WorkOrderOperation",
        "bpmnType": "task",
        "card": {
          "title": "{{name}}",
          "subtitle": "{{itemId}}",
          "icon": "clock-settings",
          "fields": [
            { "key": "state", "label": "State" },
            [
              { "key": "created_at", "label": "Created" },
              { "key": "modified_at", "label": "Modified" }
            ]
          ]
        },
        "events": []
      }
    ]
  }
}

Ожидаемый результат: выбор заказа запускает метод графа, операции отображаются как карточки, а палитра создаёт настроенные задачи и коннекторы. Добавляйте точные события обновления и удаления только после проверки контрактов бэкенда.

Рабочий пример ​

Открыть общие сценарии настройки

На вкладке BPMN панель передаёт parent, method, один GUID Object и непустые params в настоящий маршрут POST /MetaMethods/Run. Локальный обработчик возвращает ожидаемый адаптером ответ: три узла LocalObject и два ресурса Link. Элементы graph.nodes сопоставляют typeName, вид BPMN и поля карточки.

Пример использует graph.readOnly: true, пустую палитру и скрытое удаление. Он доказывает только загрузку, преобразование, отображение и режим чтения.

Точная справка по параметрам ​

Полная справка TypeDoc пока публикуется только на английском языке:

Связанные руководства и следующий шаг ​

Сначала скопируйте загрузку графа только для чтения и сопоставление узлов. Проверьте один реальный путь сохранения, прежде чем включать создание, изменение, удаление или коннекторы.