Menü der Dokumentation

Einfügen von Benutzeraktivitäten

In diesem Thema erhalten Sie grundlegende Informationen über die Verwendung und Anpassung des BPMN-Elements User Task (Benutzeraktivität).

Wissenswertes zu Benutzeraktivitäten

Im BPMN-Standard gibt es unterschiedliche Konstrukte für die Zuweisung von Empfängern innerhalb eines User Task (Benutzeraktivität).

Wir empfehlen die Verwendung der Eigenschaft camunda:candidateUsers.

Potential Owner

<userTask id='theTask' name='important task' camunda:candidateUsers="${variables.get('myPerformer')}" />

Verwenden von Konstanten für Empfänger

Wenn Sie die Empfänger einer Aktivität als Konstante angeben möchten, verwenden Sie folgende Syntax:

${collections.from("identity:///identityprovider/scim/users/someUserId")}
// or
${collections.from("identity:///identityprovider/scim/users/someUserId", "identity:///identityprovider/scim/users/someOtherUserId")} 

Verwenden von Variablen für Empfänger

Wenn die Empfänger einer Aktivität aus Variablen ermittelt werden sollen, verwenden Sie folgende Syntax für die Referenzierung der Variablen:

${variables.get("variableName")}

Verlinken von Zusatzinformationen zu Benutzeraktivitäten

Um Benutzeraktivitäten Zusatzinformationen für die Bearbeitung hinzuzufügen, können Sie die dafür reservierte Prozessvariable dv_attachment verwenden.

In dieser Variable können Sie eine URL speichern. Die URL wird bei Erstellung einer Aktivität hinzugefügt, wenn Sie sie zuvor eingetragen haben.

Warnung

Die Prozessvariable dv_attachment ist mit dem Datentyp DmsObject vordefiniert. Möchten Sie eine andere URI als die zu einem Objekt der DMS-App verwenden, müssen Sie den Wert des Datentyps auf String ändern.

Hinzufügen von Metadaten zu Benutzeraktivitäten

Um Metadaten zu Benutzeraktivitäten hinzuzufügen, können Sie die Metadaten innerhalb des BPMN-Elements userTask definieren. Fügen Sie das Element extensionElements und darunter das Element camunda:properties hinzu, falls die Prozessdefinition diese Elemente noch nicht enthält. Unterhalb des Elements camunda:properties können Sie nun wie folgt Metadaten definieren:

<userTask>
...
        <extensionElements>
                <camunda:properties>
                        <camunda:property name="metadata:invoiceNumber:value" value="${variables.get("invoiceNumber")}" />
                <camunda:property name="metadata:invoiceNumber:caption" value="Invoice Number" />
                <camunda:property name="metadata:invoiceNumber:caption:de" value="Rechnungsnummer" />
                <camunda:property name="metadata:invoiceNumber:type" value="String" /> 
        </camunda:properties>
        </extensionElements>
...
</userTask>

Das Attribut name innerhalb des Elements camunda:property kann folgende Werte annehmen:

Wert

Bedeutung

metadata:<key>:value

Definiert den Wert eines Metadatums.

Der Key des Metadatums muss folgendem Ausdruck entsprechen: [A-Za-z0-9]{1,255}

metadata:<key>:caption

(Optional) Definiert die Standardbeschriftung eines Metadatums.

Falls nicht vorhanden, wird der Schlüssel als Beschriftung verwendet.

metadata:<key>:caption:<language>

(Optional) Definiert die Beschriftung eines Metadatums für die angegebene Sprache. Das Sprachkürzel muss der ISO-639-1 Norm entsprechend aus zwei Buchstaben bestehen.

Falls nicht vorhanden, wird die Standardbeschriftung bzw. der Schlüssel verwendet.

metadata:<key>:type

(Optional) Definiert den Datentyp des Metadatums.

Entspricht dem Datentyp aus der TaskApp (String, Number, Money, Date). Wenn kein Typ angegeben wird, wird der Typ String angenommen.

Das Attribut value kann entweder einen festen Wert oder einen Ausdruck enthalten. Dieser Wert darf maximal 255 Zeichen lang sein. Bei der Verwendung eines Ausdrucks gilt diese Beschränkung für das Ergebnis des Ausdrucks. Darüber hinaus muss das Ergebnis eines Ausdrucks ein einzelner Wert sein. Werte vom Typ Collection oder Array sind nicht erlaubt.

Bestimmen der Aufbewahrungsdauer einer Benutzeraktivität

Sie können die Aufbewahrungsdauer von Benutzeraktivitäten innerhalb des BPMN-Elements userTask definieren. Fügen Sie das Element extensionElements und darunter das Element camunda:properties hinzu, falls die Prozessdefinition diese Elemente noch nicht enthält. Unterhalb des Elements camunda:properties können Sie nun wie folgt die Aufbewahrungsdauer definieren:

<userTask>
...
        <extensionElements>
                <camunda:properties>
                        <camunda:property name="retentionTime" value="P7D" />
                </camunda:properties>
        </extensionElements>
...
</userTask>

Das Attribut value kann entweder einen festen Wert oder einen Ausdruck enthalten. Definieren Sie die Aufbewahrungsdauer als Zeitspanne nach ISO-8601 in Tagen, z.B. P30D für 30 Tage.

Bestimmen der Nutzbarkeit von Aktionen in der Benutzeroberfläche einer Benutzeraktivität

Sie können die Nutbarkeit von Aktionen in der Benutzeroberfläche der Benutzeraktivität innerhalb des BPMN-Elements userTask definieren. Fügen Sie das Element extensionElements und darunter das Element camunda:properties hinzu, falls die Prozessdefinition diese Elemente noch nicht enthält. Unterhalb des Elements camunda:properties können Sie nun wie folgt die Aufbewahrungsdauer definieren:

<userTask>
...
        <extensionElements>
                <camunda:properties>
                        <camunda:property name="actionScope:complete" value="[list, details]" />
                </camunda:properties>
        </extensionElements>
...
</userTask> 

Die Eigenschaft name des Elements enthält das Prefix actionScope gefolgt von der zu konfigurierenden Aktion (in diesem Beispiel complete). Die Eigenschaft value enthält die gewünschten Optionen für die Nutzbarkeit. Welche Aktionen und Nutzbarkeitsoptionen möglich sind, können Sie der API-Dokumentation der TaskApp entnehmen.

Hinzufügen von Benutzeroberflächen zu einer Benutzeraktivität

Wenn Sie bei der Erstellung eines Prozessmodells das BPMN-Element User Task (Benutzeraktivität) verwenden, können Sie der Aktivität eine Benutzeroberfläche hinzufügen. Dem Benutzer wird dann beispielsweise eine Schaltfläche angezeigt, mit der er eine Aufgabe beginnen kann.

Um eine Benutzeroberfläche hinzuzufügen, verwenden Sie die Eigenschaft f ormKey.

Beispiel

Form Key

<userTask id="someTask" camunda:formKey="uri:/myapp/myform">
  ...
</userTask>

Der Schlüssel besteht aus einem Präfix und einem Wert. Diese werden durch einen Doppelpunkt voneinander getrennt. Folgende Präfixe können verwendet werden:

Präfix

Bedeutung

Beispiel

uri

Die Benutzeroberfläche wird über eine URI angegeben.

uri:https://example.com/

Verwenden von Prozessvariablen

Der Schlüssel kann auch Prozessvariablen beinhalten. Diese können in Form von Expression Language angegeben werden.

Beispiel

uri:${variables.get("formUri")}

uri:https://example.com/?queryParam=${variables.get("formParam")}

Externer Zugriff auf Prozessvariablen

Mit dem Ausdruck ${process.task.variablesUri} kann ein URI erzeugt werden, um einer externen Applikation den Zugriff auf die aktuellen Variablen dieser Benutzeroberfläche zu ermöglichen. Mittels der HTTP-Methoden GET und PUT können diese Variablen gelesen und verändert werden. In dieser Bearbeitungsoberfläche muss zu den verwendenden Variablen ein Input- und Output-Mapping definiert sein.

Beispiel

uri:/myApp?variablesUri=${process.task.variablesUri}
Verwenden von Prozessvariablen in einer Benutzeroberfläche

Enthält eine Benutzeraktivität ein Formular, können Sie mit HTTP lesend und schreibend auf die verwendeten Prozessvariablen zugreifen.

Zum Einstieg in das Arbeiten mit Prozessvariablen in einem Formular ist es hilfreich, wenn Sie zunächst einen einfachen Prozess mit einer Benutzeraktivität erstellen. Dieser Prozess sieht beispielsweise so aus:

<?xml version="1.0" encoding="UTF-8"?>
<definitions xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:camunda="http://camunda.org/schema/1.0/bpmn" targetNamespace="" exporter="d.velop process modeler">
  <process id="GettingStarted" name="Example: Getting started" isExecutable="true">
    <startEvent id="start"/>
    <userTask id='task_hello_world' name='Hello World' camunda:candidateUsers="${variables.get('dv_initiator')}" />
    <endEvent id="end"/>       
    <sequenceFlow id="s1" sourceRef="start" targetRef="task_hello_world" />
    <sequenceFlow id="s2" sourceRef="task_hello_world" targetRef="end" />
  </process> 
</definitions>

Zur Vereinfachung sind die grafischen Informationen zum BPMN-Diagramm in dieser BPMN-Beispieldatei nicht enthalten.

Erstellen eines Formulars

Erstellen Sie zunächst eine HTML-Datei. Diese kann wie folgt aussehen. Die Code-Beispiele sind auf die Funktionsweise in Google Chrome ausgerichtet. Andere Browser können möglicherweise eine andere Syntax erfordern.

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Getting started</title>
</head>
<body/>    
</html>

Legen Sie die HTML-Datei so ab, dass sie mit einem Http-Gateway erreichbar ist. Fügen Sie den URI des HTML-Dokuments zum BPMN-Element userTask hinzu.

...
<process id="GettingStarted" name="Example: Getting started" isExecutable="true">
        ...
    <userTask id='task_hello_world' name='Hello World' camunda:formKey="uri:/res/process/process-form.html?variables=${process.task.variablesUri}" camunda:candidateUsers="${variables.get('dv_initiator')}" />
    ...

Erläuterung der Eigenschaft

  • camunda:formKey: In dieser Eigenschaft wird der URI definiert, der die Oberfläche für die Benutzeraktivität bereitstellt. Das Präfix uri: ist dabei verpflichtend. Die Variable ${process.task.variablesUri} wird als Query-Parameter zum URI ergänzt. Die Variable wird von der Anwendung zur Laufzeit in einen URI aufgelöst, der einen HTTP-Endpunkt zum Lesen und Schreiben der Variablen bereitstellt.

Erstellen der Benutzeroberfläche

Erstellen Sie zunächst das Grundgerüst für eine HTML-Tabelle in Ihrem HTML-Dokument. Im späteren Verlauf werden die Variablen dann in dieser Tabelle angezeigt.

...
<body>
    <table id="variables">
                <thead>
                        <tr>
                                <th>Name</th>
                                <th>Value</th>
                        </tr>
                </thead>
                <tbody id="variableValues">
                </tbody>
        </table>
</body>
...

Abfragen der Prozessvariablen

Im Head des HTML-Dokuments erstellen Sie eine Funktion zum Auslesen der Prozessvariablen. Die Prozessvariablen werden mit einer HTTP-GET-Anforderung entsprechend der Rest-API von der Anwendung abgefragt. Das Laden der Variablen wird durch das onLoad-Event des body-Elements ausgelöst.

...
<head>
        ...
        <script type="text/javascript">
        
                var urlParams = new URLSearchParams(window.location.search);
                var variablesUri = urlParams.get('variables');
                        
                function loadVariables() {
                        fetch(variablesUri)
                                .then(response => response.json());
                }               
                
        </script>
</head>
<body onload="loadVariables()">
...

Nachdem die Variablen geladen wurden, können Sie diese nun in der vorbereiteten Tabelle anzeigen. Im folgenden Beispiel wird die JavaScript-Bibliothek jQuery verwendet. Fügen Sie im Head des HTML-Dokuments die jQuery-Bibliothek hinzu und implementieren Sie entsprechende Methoden zum Anzeigen der Variablen.

...
<head>
        <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.0/jquery.min.js"></script>
        <script type="text/javascript">
        
                var urlParams = new URLSearchParams(window.location.search);
                var variablesUri = urlParams.get('variables');
                        
                function loadVariables() {
                        fetch(variablesUri)
                                .then(response => response.json())
                                .then(json => createTableFromVariables(json.variables || {}));
                }       
        
                function createTableFromVariables(variables) {
                        Object.keys(variables).forEach(variable => {
                                var value = variables[variable];
                                $('#variableValues').append( `<tr class="variable">${createKeyColumn(variable)}${createValueColumn(value)}</tr>`);
                        });
                }
                
                function createKeyColumn(variable) {
                        return `<td><span class="key">${variable}</span></td>`;
                }
                
                function createValueColumn(value) {
                        return `<td><input class="value" type="text" value="${value}"></td>`;
                }

        </script>
</head>
<body onload="loadVariables()">
...
        

Die Variablen werden nun nach dem Laden des HTML-Dokuments abgefragt und angezeigt.

Schreiben der Prozessvariablen

Fügen Sie in den Skript-Bereich Methoden ein, die das Zurückschreiben der Variablen in die Anwendung ermöglichen. Anschließend fügen Sie einen button unterhalb der Tabelle hinzu, der die Methode saveVariables aufruft.

...
<head>
        <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.0/jquery.min.js"></script>
        <script type="text/javascript">
        
                var urlParams = new URLSearchParams(window.location.search);
                var variablesUri = urlParams.get('variables');
                        
                ...
                
                function saveVariables() {
                        var variables = createVariablesFromTable();    

                        // These variables are read-only and must not be sent to server when setting variables
                        delete variables['dv_initiator'];
                        delete variables['dv_start_time'];

                    const headers = new Headers();
                        headers.append('Cache-Control', 'no-cache');
                        headers.append('Content-Type', 'application/json');

                        let promise = fetch(variablesUri, {
                                method: 'PUT',
                                headers: headers,
                                credentials: 'same-origin',
                                body: JSON.stringify({variables})
                        });

                        promise.then(function(response) {
                                let status = response.status;
                                if (status !== 200 ) {
                                        window.alert("Saving variables failed: " + status);
                                } else {
                                        window.alert("Variables saved");
                                }
                                
                        });
                }

                function createVariablesFromTable() {
                        var variables = {};
                        $("tr.variable").each(function() {
                                $this = $(this);
                                var key = $this.find("span.key").html();
                                var value = $this.find("input.value").val();
                                variables[key] = value;
                        });
                        return variables;
                }

        </script>
</head>
<body onload="loadVariables()">
        ...
        <br/>
        <button onClick="saveVariables()">Save</button>
</body>

Mithilfe des Formulars, das bei der Ausführung des Prozesses angezeigt wird, können Sie die aktuellen Prozessvariablen anzeigen und ändern.

Das finale HTML-Dokument sieht wie folgt aus. Das HTML-Dokument enthält einige ergänzende CSS-Definitionen zur optimierten Darstellung der Oberflächenelemente.

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Process Form</title>
        <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.0/jquery.min.js"></script>
        <style>
                table {
                  border-collapse: collapse;
                  width: 100%;
                }
                
                table, th, td {
                  border: 1px solid black;
                }
                
                td {
                  padding: 3px;
                }
                
                .key {
                        color: gray;
                }
                
                th {
                  text-align: left;
                }
                
                input {
                        width: 100%;
                        border: 0;
                }
        </style>
    <script type="text/javascript">
        
                var urlParams = new URLSearchParams(window.location.search);
                var variablesUri = urlParams.get('variables');
                        
                function loadVariables() {
                        fetch(variablesUri)
                                .then(response => response.json())
                                .then(json => createTableFromVariables(json.variables || {}));
                }
                
                function saveVariables() {
                        var variables = createVariablesFromTable();   

                        // These variables are read-only and must not be sent to server when setting variables
                        delete variables['dv_initiator'];
                        delete variables['dv_start_time'];

                const headers = new Headers();
                        headers.append('Cache-Control', 'no-cache');
                        headers.append('Content-Type', 'application/json');

                        let promise = fetch(variablesUri, {
                                method: 'PUT',
                                headers: headers,
                                credentials: 'same-origin',
                                body: JSON.stringify({variables})
                        });

                        promise.then(function(response) {
                                let status = response.status;
                                if (status !== 200 ) {
                                        window.alert("Saving variables failed: " + status);
                                } else {
                                        window.alert("Variables saved");
                                }
                                
                        });
                }
                
                function createTableFromVariables(variables) {
                        Object.keys(variables).forEach(variable => {
                                var value = variables[variable];
                                $('#variableValues').append( `<tr class="variable">${createKeyColumn(variable)}${createValueColumn(value)}</tr>`);
                        });
                }
                
                function createKeyColumn(variable) {
                        return `<td><span class="key">${variable}</span></td>`;
                }
                
                function createValueColumn(value) {
                        return `<td><input class="value" type="text" value="${value}"></td>`;
                }
                
                function createVariablesFromTable() {
                        var variables = {};
                        $("tr.variable").each(function() {
                                $this = $(this);
                                var key = $this.find("span.key").html();
                                var value = $this.find("input.value").val();
                                variables[key] = value;
                        });
                        return variables;
                }
                
        </script>
</head>
<body onload="loadVariables()">
    <table id="variables">
                <thead>
                        <tr>
                                <th>Name</th>
                                <th>Value</th>
                        </tr>
                </thead>
                <tbody id="variableValues">
                </tbody>
        </table>
        <br/>
        <button onClick="saveVariables()">Save</button>
</body>
</html>