Open Source Dokumentenmanagement
Dokumentation

Durchsuchbare Dokumentation aufrufen | Zurück zur Dokumentationsübersicht

Navigation: Dokumentationen agorum core > agorum core workflow 3.0 > ACLs/Berechtigungen im Workflow setzen > DATEV XML-Schnittstelle online > Übersicht vorhandener Knoten


UI

Interne ID: agorum.interaction.ui

Sie können mit diesem Knoten eine Bedienoberfläche für den Bearbeiter erzeugen und den Bearbeiter Informationen in die vorgesehenen Felder eingeben oder wählen lassen. Führt der Bearbeiter bestimmte Aktionen durch, kann außerdem ein Events-Skript aufgerufen werden, das wiederum bestimmte Aktionen durchführt.

Aussehen des Knotens

Verhaltensweise


Erreicht das System den Knoten im Workflow, stoppt der Workflow an dieser Stelle und wird erst wieder fortgeführt, wenn ein Bearbeiter die Bedienoberfläche über eine Schaltfläche verlässt, der Bearbeiter also Daten eingegeben oder gewählt und etwa mit OK bestätigt hat.

Wiederverwendung


Den UI-Knoten können Sie wiederverwenden.

Beispiel

Ein Benutzer erhält ein UI angezeigt. Sobald er auf Weiter klickt, erhält er nochmals das gleiche UI, aber mit anderen Werten. Damit die Werte vom System um UI aktualisiert werden können, müssen Sie per valueChanged auf die Werteveränderung reagieren.

Endpoints


Standard Veränderbar? Weitere Endpoints möglich?
Default (Inlet) Nein, kann nur ausgeblendet werden. ja, beliebig viele (nur Outlets)

Parameter


Parameter Beschreibung Beispiel
Anzeigename Definiert einen Namen, der im Workflow in der Spalte Prozessschritt in der Bedienoberfläche erscheint. Anzeigename
Beschreibung Definiert die Beschreibung, die im Workflow in der Spalte Prozessbeschreibung erscheint. Beschreibung
Automatisches Annehmen Definiert, ob die UI-Maske automatisch vom Benutzer angenommen wird, wenn dieser eine Eingabe in der Bedienoberfläche tätigt.
  • Gilt für Masken, die an mehrere Benutzer gleichzeitig gerichtet sind.
  • Im Standard ist der Parameter aktiviert.
Benutzer/Gruppen (Bearbeiter)  Setzt die definierten Benutzer / Benutzergruppen des passierenden Tokens als Bearbeiter des Workflowschritts und aller nachfolgenden Schritte inklusive Zugriff auf die Anhänge des Workflows.

Haben Sie eine Benutzergruppe als Bearbeiter gesetzt, darf jedes Mitglied aus dieser Benutzergruppe den Workflow annehmen, bearbeiten und abgeben.

Die Berechtigung für das Token kann in einem Script-Knoten gelöscht oder neu gesetzt werden, siehe Beispiele für das Entfernen/Ändern des Bearbeiters.

Benutzer/Gruppen (Bearbeiter)
Benutzer/Gruppen (Vertreter) Setzt die definierten Benutzer / Benutzergruppen als Vertreter für den Workflowschritt und aller nachfolgenden Schritte inklusive Zugriff auf die Anhänge des Workflows.
  • Haben Sie eine Benutzergruppe als Vertreter gesetzt, darf jedes Mitglied aus dieser Benutzergruppe den Workflowschritt bei Bedarf annehmen, bearbeiten und abgeben. Vertreter sehen jedoch diesen Schritt nicht in der Filteroption für mich (im Filter Workflow Aufgaben).
  • Vertreter können die Benutzergruppe und Benutzer, die als Bearbeiter eingetragen sind, nicht einsehen. Bei den entsprechenden Schritten, die von diesen Benutzergruppen oder Benutzern bearbeitet werden, erscheint in der Bedienoberfläche der Eintrag unbekannter Benutzer oder unbekannte Gruppe. Dies ist etwa in der Historie des Workflows der Fall.

    Tipp: Soll ein Vertreter die Benutzergruppe, die den Schritt bearbeitet, sehen können, führen Sie einen der folgenden Schritte durch:

    • Stellen Sie die ACL der Bearbeitergruppe auf Published.

    • Fügen Sie den Vertreter in den Parameter Aktuellen Benutzer als Bearbeiter hinzufügen mit lesendem Zugriff hinzu.

Die Berechtigung für das Token kann in einem Script-Knoten gelöscht oder neu gesetzt werden, siehe Beispiele für das Entfernen/Ändern des Bearbeiters.

Benutzer/Gruppen (Vertreter)
Benutzer/Gruppen (Betrachter) Setzt die definierten Benutzer / Benutzergruppen als Betrachter des Workflowschritts und aller nachfolgenden Schritte inklusive Zugriff auf die Anhänge des Workflows.

Haben Sie eine Benutzergruppe als Betrachter gesetzt, darf jedes Mitglied aus dieser Benutzergruppe den Workflowschritt sehen, ihn jedoch nicht bearbeiten. Betrachter sehen außerdem diesen Schritt nicht in der Filteroption für mich (im Filter Workflow Aufgaben).

Die Berechtigung für das Token kann in einem Script-Knoten gelöscht oder neu gesetzt werden, siehe Beispiele für das Entfernen/Ändern des Bearbeiters.

Outlet Variable Speichert in der Variable, die hier angegeben wird, das Outlet, über das der UI-Knoten verlassen wurde. Outlet Variable
Oberflächenscript Erstellt ein Skript für das UI, das dem Bearbeiter angezeigt wird. Oberflächenscript
Events Erstellt ein Skript, das aufgerufen wird, wenn im UI bestimmte Aktionen durchgeführt werden (Workflow annehmen, Workflow abgeben, speichern und verlassen). Events

Anzeigename

Angabe eines Anzeigenamens im Editor:

Bitte geben Sie die Wiedervorlage Daten ein!

Hinterlegen Sie einen Anzeigenamen als Parameter, zeigt das System diesen als Prozessschritt in der Bedienoberfläche an.

Anzeigename in der Bedienoberfläche

Beschreibung
 

Im Editor

Angabe einer Beschreibung im Editor:

Dokument korrigieren


Als Expression

Angabe einer Beschreibung als Expression:

token.variables.taskTitle

Hinterlegen Sie hier einen Text oder eine Variable, zeigt das System deren Inhalt als Prozessbeschreibung in der Bedienoberfläche an.

Meistens ist es nicht sinnvoll, einen festen Text im Editor einzutragen, etwa wenn es sich um einen Aufgabenworkflow handelt, da die Aufgabe pro Durchlauf eines Workflows unterschiedlich ausfällt. Stattdessen sollten Sie mit Variablen in der Expression arbeiten. So können Sie etwa ein Eingabefeld im UI-Knoten mit der Beschreibung vom Benutzer dynamisch befüllen:

 // task title
    {
      type: 'agorum.composite.form.element.text',
      name: 'taskTitle',
      label: '_acmsg:taskTitle.label=Titel',
      validation: [
        {
          // this value is required
          required: true
        }
      ]
    },

Der Benutzer gibt in diesem UI-Knoten den Titel der Aufgabe in einem Feld namens Titel (label). Der Titel wird in der Variable taskTitle (name) gespeichert. Durch einen nachfolgenden set-Knoten, der die interne Variable sys_acw_processDescription verwendet, wird die Variable taskTitle aus dem UI-Knoten als Prozessbeschreibung gesetzt:

Eingesetzter set-Knoten mit interner Variable und Wert

In der Bedienoberfläche taucht der Titel überall in der Spalte Prozessbeschreibung auf.

Benutzer/Gruppen (Bearbeiter)
 

Im Editor

Gesetzter Benutzer als Bearbeiter mit lesenden Rechten auf Anhänge


Als Expression

Als Expression können Sie zuvor definierte Variablen setzen, etwa solche, die Sie über einen vorherigen Skript-Knoten definiert haben.


Aufbau der Variable / Zugriff auf die Variable

token.variables.sampleRecipient


Zugriff auf mehrere Variablen über ein Array

[ token.variables.sampleRecipient, token.variables.testAssign ]

Für das Setzen von Rechten auf Anhänge mithilfe eines Skript-Knotens siehe Rechte auf Anhänge (Attachments) vergeben.

Alternativ setzen Sie die Werte direkt in der Expression:

[ {id: 'group:GRP_sample_escalation_3', attachmentPermission: 'write'} ] 

Benutzer/Gruppen (Vertreter)

Definiert einen Stellvertreter.

Die Benutzer oder Benutzergruppen, die Sie hier als Vertreter wählen, können jeden Schritt eines Workflows nachvollziehen und so etwa Auskunft geben, sofern nötig. Bei Bedarf können Sie in den Workflow eingreifen, indem Sie die Schaltfläche Annehmen anklicken. Die Vertreter können danach genauso wie ein Bearbeiter Daten in den Dialog eingeben.

Vertreter können den Schritt in der Bedienoberfläche einsehen, sofern diese die Filteroption für mich in den Workflow Aufgaben deaktivieren.


Im Editor

Gesetzte Benutzergruppe als Vertreter mit lesenden Rechten auf Anhänge


Als Expression

gleicher Fall wie bei Benutzer/Gruppe (Bearbeiter)

Outlet Variable

Angabe einer Outlet-Variable im Editor:

andererAusgang

Setzen Sie eine Outlet-Variable, so wird der UI-Knoten zunächst über das Standard-Outlet mit leave verlassen. Das System speichert die Aktion des Benutzers in die hier angegebene Outlet Variable. Folgt danach ein anderer Knoten, kann dieser nachfolgende Knoten auf die Outlet-Variable und deren Inhalt zugreifen.

Folgendes Beispiel verdeutlicht die Funktion der Outlet-Variable:

Beispielworkflow mit UI-Knoten

Im UI-Knoten (1. Knoten) ist folgende Outlet-Variable angegeben:

nextOutlet

Führt der Benutzer in der Bedienoberfläche im UI-Knoten nun eine Aktion aus (etwa klickt er auf die Schaltfläche ok), speichert das System diese Aktion in die Outlet-Variable nextOutlet als Wert. Danach folgt der Knoten dateiAblegen1, der eine Datei in einem Pfad ablegt. Anschließend folgt ein Skript-Knoten. In diesem ist folgendes Skript angegeben:

/* global sc, sca, token, instance, outlets, inlet, parameters */

token.leave(token.variables.nextOutlet);

Das System verlässt diesen Skript-Knoten über das Standard-Outlet mit den Informationen, die der Benutzer im UI-Knoten (1. Knoten) eingegeben hat (Schaltfläche ok angeklickt). Der Skript-Knoten konnte also die Information aus dem UI-Knoten als Variable verarbeiten.

Oberflächenskript

Das System erstellt das Oberflächenskript automatisch, wenn Sie auf Script erstellen klicken:

let aguila = require('common/aguila');

// Create form for workflow step.
// This sample contains some common elements, feel free to use or remove them
let form = aguila.create({
  // value: the current token's variables (in/out)
  // id: the currently selected attachment's UUID (in/out)
  // tokenId: the current token's UUID (in)
  properties: ['id', 'tokenId'],
  type: 'agorum.composite.form.basic',
  labelPosition: 'top',
  elements: [
    // some description
    {
      type: 'agorum.textDisplay',

      // use _acmsg:key=Text for translation
      // you have to activate translation in workflow settings
      text: '_acmsg:title=This is a short description of this mask',
    },

    // a text input field
    {
      type: 'agorum.composite.form.element.text',
      name: 'sampleText',
      label: '_acmsg:sampleText.label=Text',
      validation: [
        {
          // this value is required
          required: true,
        },
      ],
    },

    // user select field
    {
      type: 'agorum.composite.form.element.select',
      name: 'sampleRecipient',
      label: '_acmsg:sampleRecipient.label=Recipient',
      // multi: true,
      restricted: true,
      dataSource: 'MAIN_MODULE_MANAGEMENT/customers/acworkflow/Data/acworkflow_assignee',
    },

    // two other input fields, side by side
    {
      type: 'agorum.hbox',
      items: [
        // number input field on left side
        {
          type: 'agorum.composite.form.element.number',
          name: 'sampleNumber',
          label: '_acmsg:sampleNumber.label=Number',
          flexible: true,
        },
        // date input field on right side
        {
          type: 'agorum.composite.form.element.date',
          name: 'sampleDate',
          label: '_acmsg:sampleDate.label=Date',
          flexible: true,
        },
      ],
    },

    // buttons
    {
      type: 'agorum.spacer',
      height: 24,
    },
    {
      type: 'agorum.hbox',
      items: [
        // buttons on left side
        {
          type: 'agorum.composite.form.element.button',
          name: 'cancel',
          text: '_acmsg:cancel=Abort',
          icon: 'aguila-icon cancel',
        },

        {
          type: 'agorum.spacer',
          flexible: true,
        },

        // buttons on right side
        {
          type: 'agorum.composite.form.element.button',
          name: 'ok',
          text: '_acmsg:ok=Ok',
          icon: 'aguila-icon check',
        },
      ],
    },
  ],
});

// Listen for changed values by user
/*
form.on('input', data => {
  console.log('User has changed value of the form:', data.name, data.value);
});
*/

// Listen for actions on the widget
form.on('action', action => {
  /*
  console.log('Button with name: ' + action.name + ' was clicked');
  */

  // find out, which button has been pressed
  // and leave the ui node through the associated outlet
  switch (action.name) {
    case 'ok':
      // the form has to be valid, before the ui can be left through the "ok"-outlet
      if (form.validate()) {
        form.fire('leave', 'ok');
      }
      break;
    case 'cancel':
      // when cancel is pressed, leavel to "cancel"-outlet without validation
      form.fire('leave', 'cancel');
      break;
  }
});

// sample for accessing variables
// all token variables are available in the form value
/*
form.on('valueChanged', value => {
  // get the values for textInput and numberInput, and also the displayName of the step:
  console.log('form values: ' + 
              'textInput: ' + value.textInput + ', ' + 
              'numberInput: ' + value.numberInput + ', ' + 
              'setDisplayName: ' + value.sys_acw_stepDisplayName);
  
  // and all values
  console.log('all form values:', value);
});
*/

form;

Das Skript enthält Beispiele, Sie können das Skript jedoch auf eigene Bedürfnisse anpassen. Für weitere Informationen zur Verwendung von form siehe agorum.composite.form.

properties

Der Parameter properties in der Funktion aguila.create ist ein Array, das dazu dient, Daten zu übergeben oder zu empfangen, die im Kontext des Workflows wichtig sind.

Parameter Beschreibung
id Die UUID des aktuell ausgewählten Attachments. Die Eigenschaft kann sowohl zum Einlesen als auch zum Schreiben verwendet werden.
tokenId

Die UUID des aktuellen Tokens. Diese Eigenschaft kann nur beim Lesen verwendet werden, um den aktuellen Kontext des Workflows zu identifizieren.

Events

Das System erstellt das Events-Skript automatisch, wenn Sie auf Script erstellen klicken:

/* global sc, sca, token, instance, outlets, inlet, parameters, action */

/**
 * This script is called, when the an event occurs in the UI step
 *
 * parameters:
 *   sc: sessionController of user
 *   sca: sessionController of admin
 *   token: the current token
 *   instance: the workflow instance
 *   outlets: available outlets as array
 *   inlet: the inlet, that was used, when entering this node
 *   parameters: parameters of the node (as set in the parameters tab)
 *   action: containing information about the action for this event (see details below)
 *
 * action:
 *   type: type of action, possible values: acquire, release, save, leave
 *
 * action (type=acquire):
 *   User wants to acquire the current token in UI step.
 *   Parameters:
 *     force: when type=acquire: If the UI node is acquire by a user, who is not directly assigned, than force=true, otherwise it is false.
 *            token.variables.assignee contains the previous assignee, if present.
 *            The assignment will be done to the user in sc.loginUser
 *
 * action (type=release):
 *   User release the current token in UI step.
 *   Parameters:
 *     token.variables.assignee contains the currently assigned user, that will be removed
 *
 * action (type=save):
 *   The user saves the current UI information.
 *   Parameters:
 *     variables: contains the variables of the UI node (aguila script), that will be stored to token.variables
 *
 * action (type=leave):
 *   The user leaves the UI script (e.g. clicked on a button, that calls a leave...)
 *   Parameters:
 *     outlet: the name of the outlet, this token is sent to
 *     variables: contains the variables of the UI node (aguila script), that will be stored to token.variables
 */

/**
 * Get object library with admin session
 * normal a script node uses admin session to modify objects.
 * If you want to use a user session, remove (sca)
 */
let objects = require('common/objects')(sca);

// sample for logging to console
/*
console.log('we came from the inlet: "' + inlet + '"');
console.log('the current user is: ' + sc.loginUser.name);
console.log('the available outlets are',  outlets);
console.log('the parameters are',  parameters);
console.log('the instance variables are',  instance.variables);
console.log('the token variables are',  token.variables);
console.log('the action details for action.type=' + action.type + ' are',  action);
*/

// sample for manipulation variables from the UI, before they are saved (either through save or when leaved)
/*
if (action.type === 'save' || action.type === 'leave') {
  action.variables.textInput = (action.variables.textInput || '') + ' add some string to the value textInput';
  
  // or set a new value
  action.variables.newValue1 = 'Some new value';
}
*/

// log the user who acquires the step
/*
if (action.type === 'acquire') {
  console.log('User: ' + sc.loginUser.name + ' is about to acquire (force=' + action.force + ') the UI node, previous assignee was: ', token.variables.assignee);
}
*/

// log the user who releases the step
/*
if (action.type === 'release') {
  console.log('User: ' + sc.loginUser.name + ' is about to release the UI node');
}
*/

// sample, if you want to intercept the acquire for a special user
/*
if (action.type === 'acquire') {
  if (sc.loginUser.name === 'demo') {
    throw new Error('User demo is not allowed to acquire this step!');
  }
}
*/

// log the info, when leaving
/*
if (action.type === 'leave') {
  console.log('User: ' + sc.loginUser.name + ' is about to leave the UI node via the outlet: "' + action.outlet + '"');
}
*/

Das Skript enthält Beispiele, Sie können das Skript jedoch auf eigene Bedürfnisse anpassen, indem Sie JavaScript verwenden.

Objekte selektieren und im Detailfenster anzeigen

Das folgende UI-Beispiel demonstriert die Selektion von Objekten aus einer Liste (mittlerer Bereich des UIs) und deren Anzeige im rechten Bereich (Detailfenster). Wenn ein Benutzer ein Objekt aus dem mittleren Bereich selektiert, sieht er rechts das Objekt in der Vorschau. Gleichzeitig hebt das System die Selektion aus dem mittleren Bereich auf, sobald ein Benutzer rechts im Detailfenster einen Anhang mit der Maus markiert.

Selektion von Objekten und Anzeige im Detailfenster

Folgendes Oberflächenskript ist dazu nötig (wichtige Bereiche sind fett hervorgehoben):

let aguila = require('common/aguila');

let form = aguila.create({
  type: 'agorum.composite.form.basic',
  labelPosition: 'top',
  
  // Um auf ID-Änderungen von außen, d. h. wenn ein Anhang ausgewählt wurde, reagieren zu
  // können, muss das Property "id" registriert werden
  properties: [
    'id'
  ],
  elements: [
    // Einige Beschreibungen
    {
      type: 'agorum.textDisplay',
      
      // Benutzen Sie _acmsg:key=Text für Übersetzungen
      // Zuvor müssen Sie die Übersetzung in den Workflowsettings aktivieren
      text: '_acmsg:title=Anzeige einer Suche und Selektion aus der Liste im rechten Details Bereich anzeigen'
    },

    // Darstellung einer Suche aller PDF-Dateien
    {
      type: 'agorum.explorer.list',
      name: 'list',
      border: true,
      height: 300,
      query: 'nameextension:pdf',
      label: '_acmsg:sampleText.label=PDF Dateien'
    },

    
    // Buttons
    {
      type: 'agorum.spacer',
      height: 24
    },
    {
      type: 'agorum.hbox',
      items: [
        {
          type: 'agorum.spacer',
          flexible: true
        },
        
        // Button auf der rechten Seite
        {
          type: 'agorum.composite.form.element.button',
          name: 'ok',
          text: '_acmsg:ok=Ok',
          icon: 'aguila-icon check'
        }
      ]
    }
  ]
});

let list = form.down('list');

// Die Funktion "suppress" bewirkt, dass der selectionChanged Event unserer Liste
// nicht den idChanged Event auf unserer Seite auf form-Ebene auslöst, sonst würde
// unser gerade selektierter Eintrag wieder deselektiert werden.
let suppressed;
let suppress = callback => {
  if (suppressed) return;
  suppressed = true;
  try {
    callback();
  }
  finally {
    suppressed = false;
  }
};

// Bei Selektierungen in unserer Liste soll das selektierte Objekt
// im Detailfenster des Workflows angezeigt werden.
list.on('selectionChanged', selection => {
  suppress(() => {
    form.id = selection && selection[0];
  });
});

// Reagieren auf Änderungen in der Liste der Anhänge:
// Deselektieren der Einträge in unserer eigenen Liste
form.on('idChanged', id => {
  suppress(() => {
    list.selection = [ id ];
  });
});


// Reagiert auf Actions im Widget
form.on('action', action => {
  switch (action.name) {
    case 'ok':
      // Die Form muss valide sein, bevor das ui durch das Outlet "ok" verlassen werden kann
      if (form.validate()) {
        form.fire('leave', 'ok');
      }
      break;
  }  
});

form;