# Copyright (c) 2025 Patrick Motsch # Flow control node definitions. from modules.shared.i18nRegistry import t LOOP_ITEM_DATA_PICK_OPTIONS = [ { "path": ["currentItem"], "pickerLabel": t("Aktuelles Element"), "detail": t("Das aktuelle Iterationselement."), "recommended": True, "type": "Any", }, { "path": ["currentIndex"], "pickerLabel": t("Aktueller Index"), "detail": t("0-basierter Index der aktuellen Iteration."), "recommended": False, "type": "int", }, { "path": ["items"], "pickerLabel": t("Alle Elemente"), "detail": t("Die vollständige Quellliste."), "recommended": False, "type": "List[Any]", }, { "path": ["count"], "pickerLabel": t("Gesamtanzahl"), "detail": t("Anzahl der Elemente in der Schleife."), "recommended": False, "type": "int", }, ] MERGE_RESULT_DATA_PICK_OPTIONS = [ { "path": ["merged"], "pickerLabel": t("Zusammengeführt"), "detail": t("Zusammengeführtes Ergebnis (je nach Modus)."), "recommended": True, "type": "Dict", }, { "path": ["first"], "pickerLabel": t("Erster Zweig"), "detail": t("Daten vom ersten verbundenen Eingang (Modus „first“)."), "recommended": False, "type": "Any", }, { "path": ["inputs"], "pickerLabel": t("Alle Eingänge"), "detail": t("Dict der Eingabeobjekte nach Port-Index."), "recommended": False, "type": "Dict[int,Any]", }, ] # Ports, die typische Schritt-Ausgaben durchreichen (nicht nur leerer Transit). _FLOW_INPUT_SCHEMAS = [ "Transit", "FormPayload", "AiResult", "TextResult", "ActionResult", "DocumentList", "FileList", "EmailList", "TaskList", "QueryResult", "MergeResult", "LoopItem", "BoolResult", "UdmDocument", ] FLOW_NODES = [ { "id": "flow.ifElse", "category": "flow", "label": t("Wenn / Sonst"), "description": t( "Verzweigt anhand einer Bedingung auf ein vorheriges Feld oder einen Ausdruck. " "Die Daten vom Eingangskanal werden an den gewählten Ausgang durchgereicht." ), "parameters": [ { "name": "condition", "type": "json", "required": True, "frontendType": "condition", "description": t("Bedingung: Feld aus einem vorherigen Schritt und Vergleich"), }, ], "inputs": 1, "outputs": 2, "outputLabels": [t("Ja"), t("Nein")], "inputPorts": {0: {"accepts": list(_FLOW_INPUT_SCHEMAS)}}, "outputPorts": {0: {"schema": "Transit"}, 1: {"schema": "Transit"}}, "executor": "flow", "meta": {"icon": "mdi-source-branch", "color": "#FF9800", "usesAi": False}, }, { "id": "flow.switch", "category": "flow", "label": t("Switch"), "description": t( "Mehrere Zweige nach einem Wert aus einem vorherigen Schritt (Data Picker). " "Definiere Fälle mit Vergleichsoperator; der Eingang wird an den ersten passenden Zweig durchgereicht." ), "parameters": [ { "name": "value", "type": "Any", "required": True, "frontendType": "dataRef", "description": t("Wert zum Vergleichen (Feld aus einem vorherigen Schritt)"), }, { "name": "cases", "type": "array", "required": False, "frontendType": "caseList", "description": t("Fälle: Operator und Vergleichswert"), }, ], "inputs": 1, "outputs": 1, "inputPorts": {0: {"accepts": list(_FLOW_INPUT_SCHEMAS)}}, "outputPorts": {0: {"schema": "Transit"}}, "executor": "flow", "meta": {"icon": "mdi-swap-horizontal", "color": "#FF9800", "usesAi": False}, }, { "id": "flow.loop", "category": "flow", "label": t("Schleife / Für jedes"), "description": t( "Iteriert über ein Array aus einem vorherigen Schritt (z. B. documente, Zeilen, Listeneinträge). " "Optional: UDM-Ebene für strukturierte Dokumente." ), "parameters": [ { "name": "items", "type": "Any", "required": True, "frontendType": "dataRef", "description": t("Liste oder Sammlung zum Durchlaufen (im Data Picker wählen)"), }, { "name": "level", "type": "str", "required": False, "frontendType": "select", "frontendOptions": {"options": ["auto", "documents", "structuralNodes", "contentBlocks"]}, "description": t("Nur bei UDM-Daten: welche Strukturebene als Elemente verwendet wird"), "default": "auto", }, { "name": "concurrency", "type": "int", "required": False, "frontendType": "number", "frontendOptions": {"min": 1, "max": 20}, "description": t("Parallele Durchläufe (1 = nacheinander)"), "default": 1, }, ], "inputs": 1, "outputs": 1, "inputPorts": {0: {"accepts": [ "Transit", "UdmDocument", "EmailList", "DocumentList", "FileList", "TaskList", "ActionResult", "AiResult", "QueryResult", "FormPayload", ]}}, "outputPorts": {0: {"schema": "LoopItem", "dataPickOptions": LOOP_ITEM_DATA_PICK_OPTIONS}}, "executor": "flow", "meta": {"icon": "mdi-repeat", "color": "#FF9800", "usesAi": False}, }, { "id": "flow.merge", "category": "flow", "label": t("Zusammenführen"), "description": t( "Führt 2–5 Zweige zusammen, wenn alle verbunden sind. " "Modus legt fest, wie die Eingabeobjekte im Ergebnis kombiniert werden." ), "parameters": [ { "name": "mode", "type": "str", "required": False, "frontendType": "select", "frontendOptions": {"options": ["first", "all", "append"]}, "description": t("first: erster Zweig; all: Dict-Felder zusammenführen; append: Listen anhängen"), "default": "first", }, { "name": "inputCount", "type": "int", "required": False, "frontendType": "number", "frontendOptions": {"min": 2, "max": 5}, "description": t("Anzahl Eingänge dieses Nodes (2–5)"), "default": 2, }, ], "inputs": 2, "outputs": 1, "inputPorts": { 0: {"accepts": list(_FLOW_INPUT_SCHEMAS)}, 1: {"accepts": list(_FLOW_INPUT_SCHEMAS)}, }, "outputPorts": {0: {"schema": "MergeResult", "dataPickOptions": MERGE_RESULT_DATA_PICK_OPTIONS}}, "executor": "flow", "meta": {"icon": "mdi-call-merge", "color": "#FF9800", "usesAi": False}, }, ]