File size: 2,725 Bytes
d408255
58f7c7e
 
 
2b5680f
58f7c7e
2b5680f
 
58f7c7e
 
 
2b5680f
58f7c7e
 
 
2b5680f
 
58f7c7e
 
 
2b5680f
58f7c7e
 
 
 
2b5680f
58f7c7e
2b5680f
58f7c7e
 
 
2b5680f
58f7c7e
2b5680f
58f7c7e
 
 
 
 
 
2b5680f
58f7c7e
2b5680f
 
58f7c7e
 
 
2b5680f
58f7c7e
 
 
2b5680f
58f7c7e
 
 
 
 
 
2b5680f
58f7c7e
2b5680f
58f7c7e
 
 
 
 
 
 
 
2b5680f
58f7c7e
 
 
 
 
2b5680f
58f7c7e
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
from fastapi import APIRouter
from fastapi.responses import HTMLResponse, FileResponse
from pathlib import Path
from typing import Dict, List

from core.registry.tasks_registry import TASKS


# =====================================================
# CONFIG
# =====================================================

BASE_DIR = Path(__file__).resolve().parents[2]
UI_DIR = BASE_DIR / "ui"
INDEX_FILE = UI_DIR / "index.html"


# =====================================================
# TASK GROUPING
# =====================================================

def group_tasks() -> Dict[str, List[dict]]:
    """
    Converts registry → categorized UI structure.
    """

    categories: Dict[str, List[dict]] = {}

    for task in TASKS:
        if not getattr(task, "enabled", True):
            continue

        category = getattr(task, "category", "general")

        categories.setdefault(category, []).append(
            {
                "name": task.name,
                "description": getattr(task, "description", ""),
            }
        )

    return categories


# =====================================================
# ROUTER BUILDER
# =====================================================

def build_ui_router() -> APIRouter:
    """
    Serves UI + dynamic UI metadata.

    Endpoints:
        /
        /ui
        /ui/tasks
        /ui/health
    """

    router = APIRouter(tags=["UI"])

    # -------------------------------------------------
    # MAIN UI
    # -------------------------------------------------
    @router.get("/", response_class=HTMLResponse)
    async def serve_root():
        """
        Serves index.html
        """

        if not INDEX_FILE.exists():
            return HTMLResponse(
                "<h1>Basyx UI Missing</h1>",
                status_code=500,
            )

        return FileResponse(INDEX_FILE)

    # -------------------------------------------------
    # Explicit UI route
    # -------------------------------------------------
    @router.get("/ui", response_class=HTMLResponse)
    async def serve_ui():
        return await serve_root()

    # -------------------------------------------------
    # UI TASK CATALOG
    # -------------------------------------------------
    @router.get("/ui/tasks")
    async def ui_tasks():
        """
        UI fetches this to build sidebar dynamically.
        """
        return group_tasks()

    # -------------------------------------------------
    # HEALTH
    # -------------------------------------------------
    @router.get("/ui/health")
    async def ui_health():
        return {
            "status": "ok",
            "ui": "active",
            "tasks": len(TASKS),
        }

    return router