yumoqing ffdc7fc983 feat: modern UI redesign - shell layout, theme switching, dashboard revamp
Phase 1-2 deliverables:
- shell.ui: Global layout framework (topbar + collapsible sidebar + main content)
- shell_theme.css: Dark/light theme CSS custom properties system
- shell_theme.js: Theme toggle + sidebar collapse with localStorage persistence
- global_menu.ui: Unified module navigation menu with RBAC visibility
- index.ui: Redesigned dashboard homepage with modern stat cards + quick links
- Stat card widgets: today_usage, today_amount, total_users, concurrent, errors
- chart_top_models.ui + api/top_models.dspy: ChartBar with data_url pattern
- table_top_users_amount.ui: Jinja2-rendered user ranking table
- build.sh: Added .css file linking support

Design system:
- Dark theme (default): slate color palette (#0B1120, #111827, #1E293B)
- Light theme: clean white palette with matching structure
- Theme persisted in localStorage, toggled via topbar button
- Sidebar collapsible with icon-only mode, state persisted in localStorage
- Responsive stat cards with hover effects and trend indicators
- Quick link cards for model management, users, knowledge base, errors
2026-05-25 16:53:36 +08:00

378 lines
18 KiB
XML
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

{
"widgettype": "VBox",
"options": {
"width": "100%",
"height": "100%"
},
"subwidgets": [
{
"widgettype": "HBox",
"options": {
"width": "100%",
"alignItems": "center",
"marginBottom": "24px"
},
"subwidgets": [
{
"widgettype": "Title2",
"options": {
"text": "数据概览",
"color": "#F1F5F9",
"fontWeight": "700"
}
},
{
"widgettype": "Filler"
},
{
"widgettype": "Text",
"options": {
"text": "最后更新: {{get_today_usage(request) and request._run_ns.curDateString() or ''}}",
"fontSize": "13px",
"color": "#64748B"
}
}
]
},
{
"widgettype": "ResponsableBox",
"options": {
"gap": "16px",
"minWidth": "220px",
"marginBottom": "24px"
},
"subwidgets": [
{
"widgettype": "RefreshWidget",
"id": "stat_today_usage",
"options": {
"period_seconds": 30,
"url": "{{entire_url('stat_today_usage.ui')}}"
}
},
{
"widgettype": "RefreshWidget",
"id": "stat_today_amount",
"options": {
"period_seconds": 30,
"url": "{{entire_url('stat_today_amount.ui')}}"
}
},
{
"widgettype": "RefreshWidget",
"id": "stat_total_users",
"options": {
"period_seconds": 60,
"url": "{{entire_url('stat_total_users.ui')}}"
}
},
{
"widgettype": "RefreshWidget",
"id": "stat_concurrent",
"options": {
"period_seconds": 15,
"url": "{{entire_url('stat_concurrent.ui')}}"
}
},
{
"widgettype": "RefreshWidget",
"id": "stat_errors",
"options": {
"period_seconds": 30,
"url": "{{entire_url('stat_errors.ui')}}"
}
}
]
},
{
"widgettype": "HBox",
"options": {
"width": "100%",
"gap": "20px",
"height": "auto"
},
"subwidgets": [
{
"widgettype": "VBox",
"options": {
"width": "60%",
"bgcolor": "#1E293B",
"borderRadius": "12px",
"padding": "20px",
"border": "1px solid #334155"
},
"subwidgets": [
{
"widgettype": "HBox",
"options": {
"width": "100%",
"alignItems": "center",
"marginBottom": "16px"
},
"subwidgets": [
{
"widgettype": "Title4",
"options": {
"text": "Top 3 模型(今日调用)",
"color": "#F1F5F9",
"fontWeight": "600"
}
},
{
"widgettype": "Filler"
},
{
"widgettype": "Button",
"options": {
"label": "刷新",
"bgcolor": "#334155",
"color": "#94A3B8",
"border": "none",
"borderRadius": "6px",
"padding": "4px 12px",
"fontSize": "12px"
},
"binds": [
{
"wid": "self",
"event": "click",
"actiontype": "method",
"target": "-@RefreshWidget",
"method": "render_urldata",
"params": {}
}
]
}
]
},
{
"widgettype": "RefreshWidget",
"id": "chart_top_models",
"options": {
"period_seconds": 30,
"url": "{{entire_url('chart_top_models.ui')}}"
}
}
]
},
{
"widgettype": "VBox",
"options": {
"width": "40%",
"bgcolor": "#1E293B",
"borderRadius": "12px",
"padding": "20px",
"border": "1px solid #334155"
},
"subwidgets": [
{
"widgettype": "Title4",
"options": {
"text": "快捷入口",
"color": "#F1F5F9",
"fontWeight": "600",
"marginBottom": "16px"
}
},
{
"widgettype": "ResponsableBox",
"options": {
"gap": "12px",
"minWidth": "120px"
},
"subwidgets": [
{
"widgettype": "VBox",
"options": {
"bgcolor": "#334155",
"padding": "16px",
"borderRadius": "8px",
"cursor": "pointer",
"textAlign": "center"
},
"binds": [
{
"wid": "self",
"event": "click",
"actiontype": "urlwidget",
"target": "app.sage_main_content",
"options": {
"url": "{{entire_url('/llmage/llm')}}"
},
"mode": "replace"
}
],
"subwidgets": [
{
"widgettype": "Svg",
"options": {
"svg": "<svg width=\"28\" height=\"28\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"#90caf9\" stroke-width=\"2\"><path d=\"M9.75 3.104v5.714a2.25 2.25 0 01-.659 1.591L5 14.5M9.75 3.104c-.251.023-.501.05-.75.082m.75-.082a24.301 24.301 0 014.5 0m0 0v5.714c0 .597.237 1.17.659 1.591L19.8 15.3M14.25 3.104c.251.023.501.05.75.082M19.8 15.3l-1.57.393A9.065 9.065 0 0112 15.75c-2.062 0-4.024-.614-5.67-1.757l-1.57-.393m15.04 0L12 21 5.25 13.893\"/></svg>"
}
},
{
"widgettype": "Text",
"options": {
"text": "模型管理",
"color": "#E2E8F0",
"fontSize": "13px",
"marginTop": "8px"
}
}
]
},
{
"widgettype": "VBox",
"options": {
"bgcolor": "#334155",
"padding": "16px",
"borderRadius": "8px",
"cursor": "pointer",
"textAlign": "center"
},
"binds": [
{
"wid": "self",
"event": "click",
"actiontype": "urlwidget",
"target": "app.sage_main_content",
"options": {
"url": "{{entire_url('/rbac/users')}}"
},
"mode": "replace"
}
],
"subwidgets": [
{
"widgettype": "Svg",
"options": {
"svg": "<svg width=\"28\" height=\"28\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"#4caf50\" stroke-width=\"2\"><path d=\"M15 19.128a9.38 9.38 0 002.625.372 9.337 9.337 0 004.121-.952 4.125 4.125 0 00-7.533-2.493M15 19.128v-.003c0-1.113-.285-2.16-.786-3.07M15 19.128v.106A12.318 12.318 0 018.624 21c-2.331 0-4.512-.645-6.374-1.766l-.001-.109a6.375 6.375 0 0111.964-3.07M12 6.375a3.375 3.375 0 11-6.75 0 3.375 3.375 0 016.75 0zm8.25 2.25a2.625 2.625 0 11-5.25 0 2.625 2.625 0 015.25 0z\"/></svg>"
}
},
{
"widgettype": "Text",
"options": {
"text": "用户管理",
"color": "#E2E8F0",
"fontSize": "13px",
"marginTop": "8px"
}
}
]
},
{
"widgettype": "VBox",
"options": {
"bgcolor": "#334155",
"padding": "16px",
"borderRadius": "8px",
"cursor": "pointer",
"textAlign": "center"
},
"binds": [
{
"wid": "self",
"event": "click",
"actiontype": "urlwidget",
"target": "app.sage_main_content",
"options": {
"url": "{{entire_url('/rag/kdb')}}"
},
"mode": "replace"
}
],
"subwidgets": [
{
"widgettype": "Svg",
"options": {
"svg": "<svg width=\"28\" height=\"28\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"#f59e0b\" stroke-width=\"2\"><path d=\"M20.25 6.375c0 2.278-3.694 4.125-8.25 4.125S3.75 8.653 3.75 6.375m16.5 0c0-2.278-3.694-4.125-8.25-4.125S3.75 4.097 3.75 6.375m16.5 0v11.25c0 2.278-3.694 4.125-8.25 4.125s-8.25-1.847-8.25-4.125V6.375m16.5 0v3.75m-16.5-3.75v3.75m16.5 0v3.75C20.25 16.153 16.556 18 12 18s-8.25-1.847-8.25-4.125v-3.75m16.5 0c0 2.278-3.694 4.125-8.25 4.125s-8.25-1.847-8.25-4.125\"/></svg>"
}
},
{
"widgettype": "Text",
"options": {
"text": "知识库",
"color": "#E2E8F0",
"fontSize": "13px",
"marginTop": "8px"
}
}
]
},
{
"widgettype": "VBox",
"options": {
"bgcolor": "#334155",
"padding": "16px",
"borderRadius": "8px",
"cursor": "pointer",
"textAlign": "center"
},
"binds": [
{
"wid": "self",
"event": "click",
"actiontype": "urlwidget",
"target": "app.sage_main_content",
"options": {
"url": "{{entire_url('/llmage/failed_accounting.ui')}}"
},
"mode": "replace"
}
],
"subwidgets": [
{
"widgettype": "Svg",
"options": {
"svg": "<svg width=\"28\" height=\"28\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"#ef4444\" stroke-width=\"2\"><path d=\"M12 9v3.75m-9.303 3.376c-.866 1.5.217 3.374 1.948 3.374h14.71c1.73 0 2.813-1.874 1.948-3.374L13.949 3.378c-.866-1.5-3.032-1.5-3.898 0L2.697 16.126zM12 15.75h.007v.008H12v-.008z\"/></svg>"
}
},
{
"widgettype": "Text",
"options": {
"text": "异常记录",
"color": "#E2E8F0",
"fontSize": "13px",
"marginTop": "8px"
}
}
]
}
]
}
]
}
]
},
{
"widgettype": "VBox",
"options": {
"width": "100%",
"bgcolor": "#1E293B",
"borderRadius": "12px",
"padding": "20px",
"border": "1px solid #334155",
"marginTop": "20px"
},
"subwidgets": [
{
"widgettype": "Title4",
"options": {
"text": "用户消费排行Top 5",
"color": "#F1F5F9",
"fontWeight": "600",
"marginBottom": "16px"
}
},
{
"widgettype": "RefreshWidget",
"id": "table_top_users",
"options": {
"period_seconds": 30,
"url": "{{entire_url('table_top_users.ui')}}"
}
}
]
}
]
}