gateway/modules/shared/frontendTypes.py
2026-04-10 12:33:27 +02:00

236 lines
7.3 KiB
Python

# Copyright (c) 2025 Patrick Motsch
# All rights reserved.
"""
Global frontend type definitions for UI rendering.
This module provides a centralized definition of all frontend types used across the application,
including standard types (text, select, etc.) and custom types (userConnection, documentReference, etc.).
Custom types support dynamic option loading via API endpoints.
"""
from enum import Enum
from typing import Dict, Any, Optional
class FrontendType(str, Enum):
"""
Frontend rendering types for UI components.
Standard Types:
- Basic input types: text, textarea, number, checkbox, date, datetime, email, timestamp
- Selection types: select, multiselect
- Complex types: json, multilingual, file
Custom Types (for Actions):
- userConnection: User connection selector (dynamic options from /api/options/user.connection)
- documentReference: Document reference selector (dynamic options from workflow context)
- workflowAction: Workflow action selector (dynamic options from available actions)
"""
# Standard Types
TEXT = "text"
TEXTAREA = "textarea"
NUMBER = "number"
CHECKBOX = "checkbox"
DATE = "date"
DATETIME = "datetime"
EMAIL = "email"
TIMESTAMP = "timestamp"
SELECT = "select"
MULTISELECT = "multiselect"
JSON = "json"
MULTILINGUAL = "multilingual"
FILE = "file"
HIDDEN = "hidden"
# Custom Types for Actions
USER_CONNECTION = "userConnection"
"""User connection selector - fetches connections for current user from /api/options/user.connection"""
DOCUMENT_REFERENCE = "documentReference"
"""Document reference selector - fetches available document references from workflow context"""
WORKFLOW_ACTION = "workflowAction"
"""Workflow action selector - fetches available actions from workflow context"""
SHAREPOINT_FOLDER = "sharepointFolder"
"""SharePoint folder selector - requires connectionReference parameter in same action to load folders"""
SHAREPOINT_FILE = "sharepointFile"
"""SharePoint file selector - requires connectionReference parameter"""
CLICKUP_LIST = "clickupList"
"""ClickUp list selector - requires connectionReference parameter"""
CLICKUP_TASK = "clickupTask"
"""ClickUp task selector - requires connectionReference parameter"""
# Complex Structure Types (for graph editor node configs)
CASE_LIST = "caseList"
"""Case list editor for flow.switch cases"""
FIELD_BUILDER = "fieldBuilder"
"""Field builder for input.form field definitions"""
KEY_VALUE_ROWS = "keyValueRows"
"""Key-value row editor for task update entries"""
CRON = "cron"
"""Cron expression builder"""
CONDITION = "condition"
"""Structured condition builder for flow.ifElse"""
MAPPING_TABLE = "mappingTable"
"""Mapping table editor for data.transform"""
FILTER_EXPRESSION = "filterExpression"
"""Filter expression builder for data.filter"""
# Mapping of custom types to their API endpoint for dynamic options
CUSTOM_TYPE_OPTIONS_API: Dict[FrontendType, str] = {
FrontendType.USER_CONNECTION: "user.connection",
FrontendType.DOCUMENT_REFERENCE: "workflow.documentReference",
FrontendType.WORKFLOW_ACTION: "workflow.action",
FrontendType.SHAREPOINT_FOLDER: "sharepoint.folder",
FrontendType.SHAREPOINT_FILE: "sharepoint.file",
FrontendType.CLICKUP_LIST: "clickup.list",
FrontendType.CLICKUP_TASK: "clickup.task",
}
# Mapping of custom types to their description
CUSTOM_TYPE_DESCRIPTIONS: Dict[FrontendType, Dict[str, str]] = {
FrontendType.USER_CONNECTION: {
"en": "User Connection",
"fr": "Connexion utilisateur",
"de": "Benutzerverbindung"
},
FrontendType.DOCUMENT_REFERENCE: {
"en": "Document Reference",
"fr": "Référence de document",
"de": "Dokumentreferenz"
},
FrontendType.WORKFLOW_ACTION: {
"en": "Workflow Action",
"fr": "Action de workflow",
"de": "Workflow-Aktion"
},
FrontendType.SHAREPOINT_FOLDER: {
"en": "SharePoint Folder",
"fr": "Dossier SharePoint",
"de": "SharePoint-Ordner"
},
FrontendType.SHAREPOINT_FILE: {
"en": "SharePoint File",
"fr": "Fichier SharePoint",
"de": "SharePoint-Datei"
},
FrontendType.CLICKUP_LIST: {
"en": "ClickUp List",
"fr": "Liste ClickUp",
"de": "ClickUp-Liste"
},
FrontendType.CLICKUP_TASK: {
"en": "ClickUp Task",
"fr": "Tâche ClickUp",
"de": "ClickUp-Aufgabe"
},
FrontendType.CASE_LIST: {
"en": "Case List",
"fr": "Liste de cas",
"de": "Fallunterscheidung"
},
FrontendType.FIELD_BUILDER: {
"en": "Field Builder",
"fr": "Constructeur de champs",
"de": "Feld-Editor"
},
FrontendType.KEY_VALUE_ROWS: {
"en": "Key-Value Rows",
"fr": "Lignes clé-valeur",
"de": "Schlüssel-Wert-Zeilen"
},
FrontendType.CRON: {
"en": "Cron Expression",
"fr": "Expression cron",
"de": "Cron-Ausdruck"
},
FrontendType.CONDITION: {
"en": "Condition",
"fr": "Condition",
"de": "Bedingung"
},
FrontendType.MAPPING_TABLE: {
"en": "Mapping Table",
"fr": "Table de correspondance",
"de": "Zuordnungstabelle"
},
FrontendType.FILTER_EXPRESSION: {
"en": "Filter Expression",
"fr": "Expression de filtre",
"de": "Filterausdruck"
},
}
def getOptionsApiEndpoint(frontendType: FrontendType) -> Optional[str]:
"""
Get the API endpoint for fetching dynamic options for a custom frontend type.
Args:
frontendType: The frontend type to get options API endpoint for
Returns:
API endpoint string (e.g., "user.connection") or None if not a custom type
"""
return CUSTOM_TYPE_OPTIONS_API.get(frontendType)
def isCustomType(frontendType: FrontendType) -> bool:
"""
Check if a frontend type is a custom type that requires dynamic options.
Args:
frontendType: The frontend type to check
Returns:
True if it's a custom type, False otherwise
"""
return frontendType in CUSTOM_TYPE_OPTIONS_API
def getCustomTypeDescription(frontendType: FrontendType, language: str = "en") -> Optional[str]:
"""
Get the description for a custom frontend type.
Args:
frontendType: The frontend type to get description for
language: Language code (default: "en")
Returns:
Description string or None if not a custom type
"""
descriptions = CUSTOM_TYPE_DESCRIPTIONS.get(frontendType)
if not descriptions:
return None
return descriptions.get(language, descriptions.get("en"))
def registerCustomType(
frontendType: FrontendType,
optionsApiEndpoint: str,
description: Dict[str, str]
) -> None:
"""
Register a new custom frontend type.
Args:
frontendType: The frontend type enum value
optionsApiEndpoint: API endpoint for fetching options (e.g., "custom.type")
description: Multilingual description dict (e.g., {"en": "Description", "fr": "Description"})
"""
CUSTOM_TYPE_OPTIONS_API[frontendType] = optionsApiEndpoint
CUSTOM_TYPE_DESCRIPTIONS[frontendType] = description