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( "

Basyx UI Missing

", 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