-
Notifications
You must be signed in to change notification settings - Fork 0
Frontend
Wenkang Zhu edited this page Aug 10, 2026
·
3 revisions
src/
├── App.tsx # 全局主题(AntD ConfigProvider,明暗主题)
├── main.tsx # 入口
├── pages/
│ └── HomePage.tsx # 唯一主页面:侧栏 + 标签页 + 各面板
├── components/
│ ├── home/HomeQuickActions.tsx # 首页快捷操作
│ ├── host/HostEditorDialog.tsx # 主机编辑对话框
│ ├── terminal/TerminalTabs.tsx # 会话标签栏
│ ├── terminal/TerminalPane.tsx # 会话面板容器
│ ├── terminal/XtermView.tsx # xterm.js 渲染封装
│ ├── status/ServerStatusPanel.tsx # 监控指标面板
│ ├── sftp/SftpPanel.tsx # SFTP 面板容器(目录 + 传输队列)
│ ├── sftp/FileExplorer.tsx # 远程文件浏览
│ └── sftp/TransferQueue.tsx # 传输任务队列
├── stores/ # Zustand stores(无业务逻辑在组件内)
│ ├── host.ts # 主机配置 CRUD(invoke)
│ ├── session.ts # 会话状态机(后端权威状态,无回写/无超时改写)
│ ├── monitor.ts # 监控快照 + 长任务状态 + 事件缓存补投
│ ├── sftp.ts # SFTP 目录 + 传输任务 + 事件缓存补投
│ ├── layout.ts # 侧栏宽度(可拖拽)
│ └── theme.ts # 明暗主题
├── types/ # TS 类型定义(与 Rust 模型 camelCase 对齐)
│ ├── host.ts · session.ts · monitor.ts · sftp.ts
└── test/ # 单测 + 集成测试 + mocks
| Store | 状态 | 职责 |
|---|---|---|
| host | hosts: HostConfig[] | 主机列表 CRUD,调用 list_hosts / save_host / delete_host
|
| session | sessions: Map<id, SessionInfo>、activeView、statusMessage | 会话生命周期,applySessionStatus/Progress 消费后端权威事件;Connected 后初始化该会话 SFTP 根目录;closeSession 只请求后端 teardown 后清理本地投影(含 monitor/sftp 的 clearSession);事件监听入口 initListeners
|
| monitor | snapshots、tasks、sessionTaskMap、pendingTaskEvents | 监控快照缓存、长任务状态机、事件缓存补投(invoke 返回前到达的 task:status 在任务元数据到达后应用) |
| sftp | sessionStates: Map<sessionId, SftpState>、pendingTaskEvents | 目录浏览、任务队列、进度更新,监听 sftp:progress / sftp:task_status,同样带事件缓存补投 |
| layout | sidebarWidth | 侧栏拖拽宽度(MAX_SIDEBAR_WIDTH 钳制) |
| theme | theme: 'light' | 'dark' |
HomePage 点击主机 → sessionStore.openSession(hostId)
→ invoke('open_session') → 写入 sessions + activeView
→ monitorStore.startMonitoring(失败不阻断主流程)
→ initListeners 注册:session:status / session:progress / monitor:snapshot / task:status
→ Connected 事件到达 → 自动初始化 SFTP 根目录(listDir '/')
closeSession(sessionId) → invoke('close_session')(后端统一 teardown Terminal/Monitoring/SFTP)
→ 移除本地 sessions 投影 + 重置 activeView
→ monitorStore.clearSession / sftpStore.clearSession(只清投影,不再发停止命令)
-
XtermView持有 xterm Terminal + FitAddon,只负责渲染 - 键盘输入 →
writeTerminal(sessionId, data)→ invokewrite_terminal - 后端
terminal:data→ xterm 写入缓冲区 - 尺寸变化 → FitAddon →
resizeTerminal→ invokeresize_terminal
-
monitor:snapshot事件 → applySnapshot →ServerStatusPanel直接消费 -
task:status→ applyTaskStatus(未知任务缓存,latest-wins,元数据到达后补投) - 前端不做任何聚合,一次更新一个完整 payload(无分图请求)
-
SftpPanel展示 FileExplorer + TransferQueue - 上传/下载经 Tauri dialog 选文件 →
sftp_upload / sftp_download返回 TransferTask -
sftp:progress(~500ms)更新进度条(终态任务忽略进度回退),sftp:task_status驱动任务状态机;Done 时进度强制为总大小 - 快速完成/快速失败事件先于 invoke 返回时缓存,任务元数据写入后补投,避免任务卡 Pending
- 单测:stores 状态流转(stores.test.ts,含事件缓存补投、latest-wins、clearSession 清理)、类型/工具(fixtures)
- 组件测试:React Testing Library(components.test.tsx、xterm-view.test.tsx),无业务逻辑断言
- 集成测试:homepage.integration.test.tsx —— invoke/event 契约验证
- Mock:src/test/mocks/(tauri.ts、event.ts、dialog.ts),jsdom 环境(setup.ts)
-
E2E:Playwright +
__TAURI_TEST__桥接(e2e/app.spec.ts),mock 后端事件驱动全闭环
- 组件内不允许业务逻辑;只消费 store 状态与事件
- 事件监听由各 store 的
initListeners注册(session / monitor / sftp),统一在 HomePage useEffect 的 cleanup 中销毁 - 前端类型必须与 Rust serde camelCase 输出严格一致