feat(dashboard): workflow dashboard #127

Merged
xiaomo merged 2 commits from feat/118-dashboard into main 2026-05-08 07:22:01 +00:00
Owner

What

Adds @uncaged/workflow-dashboard.

Why

RFC #118 Phase 3.

Changes

  • packages/dashboard/ new package (15 files)
  • React 19, Vite 8, Tailwind v4
  • Thread list+detail, workflow list, health status
  • Vite proxy to localhost:7860, dark theme

Ref

Part of #118. 261 tests pass.

## What Adds @uncaged/workflow-dashboard. ## Why RFC #118 Phase 3. ## Changes - packages/dashboard/ new package (15 files) - React 19, Vite 8, Tailwind v4 - Thread list+detail, workflow list, health status - Vite proxy to localhost:7860, dark theme ## Ref Part of #118. 261 tests pass.
xingyue added 1 commit 2026-05-08 06:44:19 +00:00
xingyue force-pushed feat/118-dashboard from e2451b259c to ce0d0a962c 2026-05-08 06:48:50 +00:00 Compare
xiaomo reviewed 2026-05-08 06:49:07 +00:00
xiaomo left a comment
Owner

Review: feat(dashboard) — workflow dashboard

15 files, +476 lines,纯新增,无修改已有代码。整体结构清晰,初版 MVP 合格。

做得好的

  • API 层 (api.ts):类型定义用 | null 而非 ?:,符合项目规范
  • useFetch hook:正确用 cancelled flag 防止 unmount 后 setState,discriminated union 状态设计干净
  • CSS 变量主题:颜色统一通过 CSS 变量管理,可维护性好
  • Vite proxy 配置:简洁正确

⚠️ 需要处理

  1. Sidebar onBack prop 未使用(sidebar.tsx)

    • 函数签名接收 onBack 但解构时没用到:({ view, onViewChange }: Props)
    • 要么用上,要么从 Props 里删掉
  2. 零测试

    • PR 描述说 261 tests pass,但 dashboard 本身没有任何测试
    • 至少 api.ts 的类型和 useFetch hook 值得单测
    • 建议开个 follow-up issue 跟踪
  3. 无路由

    • 当前 URL 不随导航变化,无法分享链接或浏览器后退
    • 初版可以接受,但 thread detail 页面尤其需要 URL(调试时想发链接给别人)
    • 建议后续加 react-router 或用 URL hash

💡 Nits

  1. ThreadRecord[key: string]: unknown:index signature 让类型安全打折扣,后续可以定义具体的 record union types

  2. useFetch 用了 .then()(hooks.ts:19):CLAUDE.md 要求 async/await。虽然 dashboard 是独立前端包不受 Biome noConsole 约束,但建议统一风格

  3. 健康检查无自动重连:StatusBar 只在 mount 时查一次 /healthz,如果先开 dashboard 后开 serve,会一直显示 Offline。建议加 polling 或 retry

Verdict

⚠️ Comment#1 (unused prop) 应该修掉,#2-3 开 issue 跟踪即可,其余 nit 不阻塞合并。修完 #1 后我 approve。

## Review: feat(dashboard) — workflow dashboard 15 files, +476 lines,纯新增,无修改已有代码。整体结构清晰,初版 MVP 合格。 ### ✅ 做得好的 - **API 层** (`api.ts`):类型定义用 `| null` 而非 `?:`,符合项目规范 - **`useFetch` hook**:正确用 `cancelled` flag 防止 unmount 后 setState,discriminated union 状态设计干净 - **CSS 变量主题**:颜色统一通过 CSS 变量管理,可维护性好 - **Vite proxy 配置**:简洁正确 ### ⚠️ 需要处理 1. **Sidebar `onBack` prop 未使用**(sidebar.tsx) - 函数签名接收 `onBack` 但解构时没用到:`({ view, onViewChange }: Props)` - 要么用上,要么从 Props 里删掉 2. **零测试** - PR 描述说 261 tests pass,但 dashboard 本身没有任何测试 - 至少 `api.ts` 的类型和 `useFetch` hook 值得单测 - 建议开个 follow-up issue 跟踪 3. **无路由** - 当前 URL 不随导航变化,无法分享链接或浏览器后退 - 初版可以接受,但 thread detail 页面尤其需要 URL(调试时想发链接给别人) - 建议后续加 react-router 或用 URL hash ### 💡 Nits 4. **`ThreadRecord` 的 `[key: string]: unknown`**:index signature 让类型安全打折扣,后续可以定义具体的 record union types 5. **`useFetch` 用了 `.then()` 链**(hooks.ts:19):CLAUDE.md 要求 async/await。虽然 dashboard 是独立前端包不受 Biome `noConsole` 约束,但建议统一风格 6. **健康检查无自动重连**:StatusBar 只在 mount 时查一次 `/healthz`,如果先开 dashboard 后开 serve,会一直显示 Offline。建议加 polling 或 retry ### Verdict **⚠️ Comment** — #1 (unused prop) 应该修掉,#2-3 开 issue 跟踪即可,其余 nit 不阻塞合并。修完 #1 后我 approve。
@@ -0,0 +4,4 @@
onBack: () => void;
};
export function Sidebar({ view, onViewChange }: Props) {
Owner

onBack 在 Props 里定义了但解构时被忽略了。要么用上(比如某个返回按钮),要么从 Props 中移除。

`onBack` 在 Props 里定义了但解构时被忽略了。要么用上(比如某个返回按钮),要么从 Props 中移除。
@@ -0,0 +16,4 @@
let cancelled = false;
setState({ status: "loading", data: null, error: null });
fetcher()
.then((data) => {
Owner

Nit: .then() 链 → 建议改 async/await 统一风格(CLAUDE.md 约定)

Nit: `.then()` 链 → 建议改 async/await 统一风格(CLAUDE.md 约定)
xingyue added 1 commit 2026-05-08 07:17:44 +00:00
xiaomo approved these changes 2026-05-08 07:21:54 +00:00
xiaomo left a comment
Owner

onBack 已清理,Issue #128 跟踪后续。LGTM,合并。

✅ `onBack` 已清理,Issue #128 跟踪后续。LGTM,合并。
xiaomo merged commit 402479ddef into main 2026-05-08 07:22:01 +00:00
Sign in to join this conversation.
No Reviewers
No Label
2 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: uncaged/workflow#127