# Screen Map — dịch lời người dùng thành file:line Người dùng báo lỗi bằng lời ("cái bảng bên phải màn thống kê"). File này để agent Triage quy nó về đúng widget. --- ## 1. Nav rail — bốn màn chính Định nghĩa tại `presentation/shell/main_window.py:151` (`_nav_defs`), thứ tự = page index: | Row | i18n key | Icon | Dựng | Widget | |---|---|---|---|---| | 0 | `app.tab.dashboard` | `dashboard` | lười | `presentation/dashboard/dashboard_tab.py::DashboardTab` | | 1 | `app.tab.schedule` | `schedule` | lười | `presentation/scheduling/schedule_task_tab.py::ScheduleTaskTab` | | 2 | `app.tab.workspace` | `workspaces` | **ngay** (màn HOME) | `ui/workspace_tab.py::WorkspaceTab` | | 3 | `app.tab.monitoring` | `monitoring` | lười | `ui/monitoring_tab.py::MonitoringTab` | App mở lên là ở **Workspace ▸ Project**. ## 2. Sub-tab của Workspace `ui/workspace_tab.py:214-245`: | Tab | i18n key | Widget | |---|---|---| | Project | `workspace.tab_project` | `_build_project_tab()` trong chính file đó | | Cowork | `workspace.tab_cowork` | `ui/cowork_tab.py` | | Co4E | `workspace.tab_co4e` | `ui/co4e_tab.py` → `presentation/co4e/` | | Folder | `workspace.tab_folder` | `presentation/folder/folder_tab.py` | | GraphRAG | `workspace.tab_graphrag` | `presentation/graph/structure_graph_view.py` | Monitoring **giữ tab strip riêng** với 8 sub-view (tổng quan, trạng thái agent, công cụ, nhật ký hành động, lịch sử gọi MCP, sự kiện bảo mật, agents admin, icon). Workspace là màn duy nhất giấu tab strip đi. ## 3. Thành phần luôn nổi trên mọi màn | Thành phần | File | Triệu chứng người dùng hay mô tả | |---|---|---| | Nav rail trái, nút thu gọn | `presentation/shell/nav_rail.py` | "menu bị co lại", "không thấy tên project" | | Top bar (theme, ngôn ngữ) | `presentation/shell/top_bar.py` | "đổi giao diện không ăn" | | Toast góc trên trái | `presentation/shell/toast.py` | "thông báo xong việc che mất nút" | | Help agent nổi góc dưới phải | `ui/help_agent_widget.py` | "con robot che nút gửi" | | Status bar dưới cùng | `main_window.statusBar()` | "dòng chữ dưới đáy không đổi" | ## 4. Dialog `ui/`: `login_dialog.py`, `permission_dialog.py`, `settings_dialog.py`, `skills_dialog.py`, `task_editor_dialog.py`, `file_edit_dialog.py`, `flow_dialog.py`, `mcp_servers_dialog.py`, `co4e_agent_dialog.py`, `ext_connector_dialog.py`. ## 5. 🔎 Hai file tra cứu bắt buộc dùng ### `docs/screens/manifest.json` Mỗi màn đã chụp ảnh có một entry: `slug`, `title`, `theme`, `note` (**đúng `file.py:line` nơi màn đó được dựng**), `file` (ảnh), `nav`. ```bash # Người dùng nói "màn Kanban lịch trình" python -c "import json;print([e for e in json.load(open('docs/screens/manifest.json')) if 'schedule' in e['slug']])" ``` Ảnh có **cả bản dark và light** (`*-dark.png` / `*-light.png`) — dùng để đối chiếu trước/sau và để kiểm tra bug chỉ xảy ra ở một theme. ### `docs/screens/controls.json` Danh mục **mọi control** đã trích tự động từ source: `file`, `var`, `type` (`QLineEdit`...), `kind` (mô tả tiếng Việt: "ô nhập", "nút"...), `label`, `line`, `signals`, `object_name`. ```bash # Người dùng nói "ô nhập email trong màn tài khoản" python - <<'PY' import json for f in json.load(open('docs/screens/controls.json')): for c in f['controls']: if 'email' in (c['var'] + c['label']).lower(): print(f["file"], c["line"], c["var"], c["type"], c["object_name"]) PY ``` Cột `object_name` đặc biệt quan trọng khi sửa bug màu/style: rỗng nghĩa là widget **chưa** được style qua `_TEMPLATE`, nên nó đang ăn style mặc định của class — thường chính là nguyên nhân của "chỗ này nhìn khác chỗ kia". ## 6. Quy trình tra 4 bước cho Triage 1. Xác định **nav row** (Dashboard / Schedule / Workspace / Monitoring) từ mô tả hoặc ảnh. 2. Xác định **sub-tab / dialog**. 3. Tra `manifest.json` → lấy `note` = `file.py:line`. 4. Tra `controls.json` → lấy đúng `var` + `line` + `object_name` của control bị lỗi. Không qua đủ 4 bước thì `confidence` tối đa là `low`.