From 7696cbf5c5c59720a6c2219899ab8baf5bc3d62b Mon Sep 17 00:00:00 2001 From: 7418 <7418@openclaw.ai> Date: Sat, 28 Feb 2026 13:27:30 +0800 Subject: [PATCH] =?UTF-8?q?refactor:=20=E5=8F=B3=E4=BE=A7=E9=9D=A2?= =?UTF-8?q?=E6=9D=BF=20Tasks/Files=20=E5=90=88=E5=B9=B6=E4=B8=BA=E5=8D=95?= =?UTF-8?q?=E8=A7=86=E5=9B=BE=20+=20=E7=AE=80=E5=8C=96=20TaskList?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - RightPanel: 移除 Files/Tasks 双 Tab 切换,改为单视图布局 - 顶部标题改为 TASKS,下方直接渲染 TaskList - 中间用 mx-4 非贯通分隔线 + border-border/40 降低视觉强度 - 分隔线下方增加 FILES 小标题,再接 FileTree - TaskList: 大幅简化 - 移除筛选 Tab(全部/进行中/已完成) - 移除新增任务输入框 - 移除 TaskCard 组件引用,改为 checkbox + 标题单行展示 - 点击切换 completed/pending 状态 - 勾选框使用 foreground 色(黑/白)替代蓝色 - 空状态显示"暂无任务" - bump version to 0.20.1 Co-Authored-By: Claude Opus 4.6 --- package-lock.json | 4 +- package.json | 2 +- src/components/layout/RightPanel.tsx | 50 ++++---- src/components/project/TaskList.tsx | 175 ++++++++------------------- 4 files changed, 76 insertions(+), 155 deletions(-) diff --git a/package-lock.json b/package-lock.json index c4bb28a..ba1c154 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "codepilot", - "version": "0.20.0", + "version": "0.20.1", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "codepilot", - "version": "0.20.0", + "version": "0.20.1", "dependencies": { "@ai-sdk/anthropic": "^3.0.47", "@ai-sdk/google": "^3.0.31", diff --git a/package.json b/package.json index 97a35af..96a99ec 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "codepilot", - "version": "0.20.0", + "version": "0.20.1", "private": true, "author": { "name": "op7418", diff --git a/src/components/layout/RightPanel.tsx b/src/components/layout/RightPanel.tsx index 351d511..e55cbe3 100644 --- a/src/components/layout/RightPanel.tsx +++ b/src/components/layout/RightPanel.tsx @@ -13,14 +13,13 @@ import { usePanel } from "@/hooks/usePanel"; import { useTranslation } from "@/hooks/useTranslation"; import { FileTree } from "@/components/project/FileTree"; import { TaskList } from "@/components/project/TaskList"; -import { cn } from "@/lib/utils"; interface RightPanelProps { width?: number; } export function RightPanel({ width }: RightPanelProps) { - const { panelOpen, setPanelOpen, panelContent, setPanelContent, workingDirectory, sessionId, previewFile, setPreviewFile } = usePanel(); + const { panelOpen, setPanelOpen, workingDirectory, sessionId, previewFile, setPreviewFile } = usePanel(); const { t } = useTranslation(); const handleFileAdd = useCallback((path: string) => { @@ -73,26 +72,9 @@ export function RightPanel({ width }: RightPanelProps) { ); diff --git a/src/components/project/TaskList.tsx b/src/components/project/TaskList.tsx index f44c4c4..6ec3d8b 100644 --- a/src/components/project/TaskList.tsx +++ b/src/components/project/TaskList.tsx @@ -1,13 +1,7 @@ "use client"; import { useState, useEffect, useCallback } from "react"; -import { HugeiconsIcon } from "@hugeicons/react"; -import { PlusSignIcon } from "@hugeicons/core-free-icons"; -import { Input } from "@/components/ui/input"; -import { Button } from "@/components/ui/button"; -import { ScrollArea } from "@/components/ui/scroll-area"; import { cn } from "@/lib/utils"; -import { TaskCard } from "./TaskCard"; import { useTranslation } from "@/hooks/useTranslation"; import type { TaskItem, TaskStatus } from "@/types"; @@ -15,14 +9,10 @@ interface TaskListProps { sessionId: string; } -type FilterTab = "all" | "in_progress" | "completed"; - export function TaskList({ sessionId }: TaskListProps) { const { t } = useTranslation(); const [tasks, setTasks] = useState([]); const [loading, setLoading] = useState(false); - const [newTitle, setNewTitle] = useState(""); - const [filter, setFilter] = useState("all"); const fetchTasks = useCallback(async () => { if (!sessionId) return; @@ -51,135 +41,74 @@ export function TaskList({ sessionId }: TaskListProps) { return () => window.removeEventListener('tasks-updated', handler); }, [fetchTasks]); - const handleCreate = async () => { - const title = newTitle.trim(); - if (!title || !sessionId) return; - + const handleToggle = async (task: TaskItem) => { + const nextStatus: TaskStatus = task.status === "completed" ? "pending" : "completed"; try { - const res = await fetch("/api/tasks", { - method: "POST", - headers: { "Content-Type": "application/json" }, - body: JSON.stringify({ session_id: sessionId, title }), - }); - if (res.ok) { - const data = await res.json(); - setTasks((prev) => [...prev, data.task]); - setNewTitle(""); - } - } catch { - // silently fail - } - }; - - const handleUpdate = async ( - id: string, - updates: { title?: string; status?: TaskStatus } - ) => { - try { - const res = await fetch(`/api/tasks/${id}`, { + const res = await fetch(`/api/tasks/${task.id}`, { method: "PATCH", headers: { "Content-Type": "application/json" }, - body: JSON.stringify(updates), + body: JSON.stringify({ status: nextStatus }), }); if (res.ok) { const data = await res.json(); - setTasks((prev) => prev.map((t) => (t.id === id ? data.task : t))); + setTasks((prev) => prev.map((t) => (t.id === task.id ? data.task : t))); } } catch { // silently fail } }; - const handleDelete = async (id: string) => { - try { - const res = await fetch(`/api/tasks/${id}`, { method: "DELETE" }); - if (res.ok) { - setTasks((prev) => prev.filter((t) => t.id !== id)); - } - } catch { - // silently fail - } - }; + if (loading && tasks.length === 0) { + return ( +

+ {t('tasks.loading')} +

+ ); + } - const filtered = tasks.filter((task) => { - if (filter === "all") return true; - if (filter === "in_progress") - return task.status === "pending" || task.status === "in_progress"; - if (filter === "completed") return task.status === "completed"; - return true; - }); - - const filterTabs: { key: FilterTab; label: string }[] = [ - { key: "all", label: t('tasks.all') }, - { key: "in_progress", label: t('tasks.active') }, - { key: "completed", label: t('tasks.done') }, - ]; + if (tasks.length === 0) { + return ( +

+ {t('tasks.noTasks')} +

+ ); + } return ( -
- {/* Filter tabs */} -
- {filterTabs.map((tab) => ( - - ))} -
- - {/* Add task input */} -
- setNewTitle(e.target.value)} - onKeyDown={(e) => { - if (e.key === "Enter") handleCreate(); - }} - className="h-7 text-xs" - /> - -
- - {/* Task list */} - - {loading && tasks.length === 0 ? ( -

- {t('tasks.loading')} -

- ) : filtered.length === 0 ? ( -

- {tasks.length === 0 ? t('tasks.noTasks') : t('tasks.noMatching')} -

- ) : ( -
- {filtered.map((task) => ( - - ))} -
- )} -
+ + {isDone && ( + + + + )} + + + {task.title} + + + ); + })}
); }