JSF-формы задач

Этот раздел перенесён из документации Camunda 7 и в дальнейшем будет доработан с учётом особенностей OpenBPM Engine

Добавление JSF-форм в процессное приложение

Необходимые CDI-бины для этой функциональности сейчас недоступны из коробки в приложениях Quarkus.

Если добавить JSF-формы так, как описано ниже, их можно легко использовать как внешние формы задач.

Рабочий пример можно найти в репозитории примеров: https://github.com/camunda/camunda-bpm-examples/tree/master/usertask/task-form-external-jsf.

BPMN-процесс, используемый в этом примере, показан на изображении ниже:

Процесс с формами задач

В этой модели процесса мы добавили так называемые form keys к:

  • Start Event invoice received. Это форма, которую пользователь должен заполнить, чтобы запустить новый экземпляр процесса.

  • User Tasks. Это формы, которые пользователь должен заполнить при завершении назначенных ему пользовательских задач.

Вот как эти формы указываются в BPMN 2.0 XML с помощью атрибута camunda:formKey:

<startEvent id="start" name="invoice received"
    camunda:formKey="app:sample-start-form.jsf"/>

<userTask id="categorize-invoice" name="Categorize Invoice"
    camunda:formKey="app:sample-task-form-1.jsf" />

<userTask id="file-invoice" name="File Invoice"
    camunda:formKey="app:sample-task-form-2.jsf" />

<userTask id="acknowledge-categorization" name="Acknowledge Categorization"
    camunda:formKey="app:acknowledge-form.jsf" />

Создание простых JSF-форм пользовательских задач

Создайте JSF-страницу в src/main/webapp/WEB-INF, которая будет представлять форму для User Tasks. Ниже показан пример очень простой формы задачи:

<!DOCTYPE HTML>
<html lang="en" xmlns="http://www.w3.org/1999/xhtml"
  xmlns:ui="http://java.sun.com/jsf/facelets"
  xmlns:h="http://java.sun.com/jsf/html"
  xmlns:f="http://java.sun.com/jsf/core">

<f:view>
  <h:head>
    <f:metadata>
      <f:event type="preRenderView" listener="#{camundaTaskForm.startTaskForm()}" />
    </f:metadata>
    <title>Task Form: #{task.name}</title>
  </h:head>
  <h:body>
    <h1>#{task.name}</h1>
    <h:form id="someForm">
      <p>
        Here you would see the actual form to work on the task in a design
        normally either matching your task list or your business application
        (or both in the best case).
      </p>

      <h:commandButton id="complete" value="Task Completed"
          action="#{camundaTaskForm.completeTask()}" />
    </h:form>
  </h:body>
</f:view>
</html>

Обратите внимание, что для доступности бина camundaTaskForm вам понадобится зависимость openbpm-engine-cdi.

Как это работает?

Если пользователь нажмёт кнопку "Start to work on task" Start Task Button в OpenBPM Engine Tasklist, он перейдёт по ссылке на эту форму, включающей taskId и callback URL (URL для доступа к центральному Tasklist) как GET-параметры. При открытии формы будет активирован специальный CDI-бин camundaTaskForm, который:

  • начинает conversation;

  • запоминает callback URL;

  • запускает User Task в процессном движке, то есть бин устанавливает дату начала и связывает задачу с CDI business process scope. Подробнее см. в интеграции CDI.

Для этого нужно просто добавить следующий блок кода в начало JSF-view:

<f:metadata>
  <f:event type="preRenderView" listener="#{camundaTaskForm.startTaskForm()}" />
</f:metadata>

Отправка формы затем снова вызывает бин camundaTaskForm, который:

  • завершает задачу в процессном движке, из-за чего текущий token продвигается по процессу;

  • завершает conversation;

  • выполняет redirect на callback URL Tasklist.

<h:commandButton id="complete" value="task completed" action="#{camundaTaskForm.completeTask()}" />

Обратите внимание, что кнопка команды не обязательно должна находиться в той же форме. До кнопки completeTask у вас может быть целый мастер из нескольких последовательных форм. Это будет работать благодаря conversation, выполняющейся в фоне.

Доступ к переменным процесса

В формах можно использовать собственные CDI-бины, как обычно, а также CDI-бины OpenBPM Engine. Это упрощает доступ к переменным процесса, например через CDI-бин processVariables:

<h:form id="someForm">
  <p>Here you would see the actual form to work on the task in some design normally either matching you task list or your business application (or both in the best case).</p>
  [cols="1,1,1",options="header"]
|===

      <td>
        Process variable x (given in in the start form):
      </td>
      <td>
        <h:outputText value="#{processVariables['x']}" />
      </td>


      <td>
        Process variable y (added in this task form):
      </td>
      <td>
        <h:inputText value="#{processVariables['y']}" />
      </td>


      |
      <td>
        <h:commandButton id="complete" value="Task Completed"
            action="#{camundaTaskForm.completeTask()}" />
      </td>

  |===
</h:form>

В результате это будет отрисовано как простая форма:

Пример формы переменных задачи

Тот же механизм можно использовать и для запуска нового экземпляра процесса:

<!DOCTYPE HTML>
<html lang="en" xmlns="http://www.w3.org/1999/xhtml"
  xmlns:ui="http://java.sun.com/jsf/facelets"
  xmlns:h="http://java.sun.com/jsf/html"
  xmlns:f="http://java.sun.com/jsf/core">

<f:view>
  <f:metadata>
    <f:event type="preRenderView" listener="#{camundaTaskForm.startProcessInstanceByKeyForm()}" />
  </f:metadata>
  <h:head>
    <title>Start Process: #{camundaTaskForm.processDefinition.name}</title>
  </h:head>
  <h:body>
    <h1>#{camundaTaskForm.processDefinition.name}</h1>
    <p>Start a new process instance in version: #{camundaTaskForm.processDefinition.version}</p>
    <h:form id="someForm">
      <p>
        Here you see the actual form to start a new process instance, normally
        this would be in some design  either matching you task list or your business
        application (or both in the best case).
      </p>

      [cols="1,1,1",options="header"]
|===

          <td>
            Process variable x:
          </td>
          <td>
            <h:inputText value="#{processVariables['x']}" />
          </td>


          |
          <td>
            <h:commandButton id="start" value="Start Process Instance"
                action="#{camundaTaskForm.completeProcessInstanceForm()}" />
          </td>

      |===
    </h:form>
  </h:body>
</f:view>
</html>

Пример стартовой формы

Если пользователь нажмёт кнопку "Start a process instance" Start Process Button в OpenBPM Engine Tasklist и выберет процесс, к которому привязана стартовая форма, он перейдёт по ссылке на эту форму, включающей processDefinitionKey и callback URL (URL для доступа к центральному Tasklist) как GET-параметры. При открытии формы будет активирован специальный CDI-бин camundaTaskForm, который:

  • начинает conversation;

  • запоминает callback URL центрального Tasklist.

Вам нужно добавить следующий блок кода в начало JSF-view:

<f:metadata>
  <f:event type="preRenderView" listener="#{camundaTaskForm.startProcessInstanceByIdForm()}" />
</f:metadata>

После этого отправка стартовой формы:

  • запускает экземпляр процесса в процессном движке;

  • завершает conversation;

  • выполняет redirect на callback URL Tasklist.

<h:commandButton id="start" value="Start Process Instance" action="#{camundaTaskForm.completeProcessInstanceForm()}" />

Обратите внимание, что кнопка команды не обязательно должна находиться в той же форме. До кнопки completeProcessInstanceForm у вас может быть целый мастер из нескольких последовательных форм. Это будет работать благодаря conversation, выполняющейся в фоне.

Оформление форм задач

В OpenBPM Engine Tasklist используется Twitter Bootstrap http://getbootstrap.com/. Поэтому имеет смысл добавить его и в ваше процессное приложение, чтобы без труда улучшить внешний вид UI:

Стартовые формы Tasklist с оформлением

Чтобы подключить CSS- и JavaScript-библиотеки в проект, можно добавить их как зависимости Maven:

<dependencies>

  <!-- ... -->

  <dependency>
    <groupId>org.webjars</groupId>
    <artifactId>bootstrap</artifactId>
    <version>3.1.1</version>
  </dependency>

</dependencies>

Чтобы использовать их, добавьте в JSF-страницу теги вида, показанного ниже. Если у вас несколько форм, может быть удобно создать шаблон и ссылаться на него из форм, чтобы избежать дублирования.

<h:head>
  <title>your title</title>
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />

  <!-- CSS Stylesheets -->
  <h:outputStylesheet library="webjars/bootstrap/3.1.1/css" name="bootstrap.css"/>
  <h:outputStylesheet library="css" name="style.css"/>

  <!-- Javascript Libraries -->
  <h:outputScript type="text/javascript" library="webjars/bootstrap/3.1.1/js" name="bootstrap.js" />
</h:head>

Лицензия и атрибуция

Эта документация была создана на базе материала "Camunda 7 Docs" от Camunda, находится под лицензией Creative Commons Attribution-ShareAlike 3.0 Unported License .

Оригинал документации: https://docs.camunda.org