From 1c58825a7be8eb17a002d0a94749698e98aa2c57 Mon Sep 17 00:00:00 2001 From: yanweidong Date: Tue, 21 Jul 2026 01:18:06 +0800 Subject: [PATCH] feat: add project task edit modal --- apps/senlinai-acro-react/src/api/mappers.tsx | 2 +- .../pages/projects/project-channel-page.tsx | 7 +- .../src/pages/projects/project-overview.tsx | 41 +++++++- .../projects/project-task-edit-modal.tsx | 93 +++++++++++++++++++ .../src/pages/projects/project-tasks.tsx | 15 ++- .../src/pages/workspace-body.tsx | 18 ++-- .../src/pages/workspace-home.tsx | 13 +++ 7 files changed, 174 insertions(+), 15 deletions(-) create mode 100644 apps/senlinai-acro-react/src/pages/projects/project-task-edit-modal.tsx diff --git a/apps/senlinai-acro-react/src/api/mappers.tsx b/apps/senlinai-acro-react/src/api/mappers.tsx index a1e0135..564bea8 100644 --- a/apps/senlinai-acro-react/src/api/mappers.tsx +++ b/apps/senlinai-acro-react/src/api/mappers.tsx @@ -147,7 +147,7 @@ function mapTask(task: BackendTask): TaskItem { createdAt: formatCreatedAt(task.createdAt), completedAt: task.completedAt ? formatCreatedAt(task.completedAt) : '', duration: task.duration || '', - tag: task.tag || (task.completed ? '已完成' : '进行中'), + tag: task.tag || '', summary: task.summary, completed: task.completed, } diff --git a/apps/senlinai-acro-react/src/pages/projects/project-channel-page.tsx b/apps/senlinai-acro-react/src/pages/projects/project-channel-page.tsx index 4b6f523..2e1b313 100644 --- a/apps/senlinai-acro-react/src/pages/projects/project-channel-page.tsx +++ b/apps/senlinai-acro-react/src/pages/projects/project-channel-page.tsx @@ -3,6 +3,7 @@ import { ProjectCron } from './project-cron' import { ProjectNewChannel } from './project-new-channel' import { ProjectNotes } from './project-notes' import { ProjectOverview } from './project-overview' +import type { ProjectTaskUpdate } from './project-task-edit-modal' import { ProjectTasks } from './project-tasks' import type { ChannelKey, ProjectWorkspace } from './project-types' @@ -17,6 +18,7 @@ export function ProjectChannelPage({ onUploadSource, onCreateCronPlan, onCreateProjectTag, + onUpdateTask, }: { activeChannel: ChannelKey activeWorkspace: ProjectWorkspace @@ -28,10 +30,11 @@ export function ProjectChannelPage({ onUploadSource: () => void onCreateCronPlan: () => void onCreateProjectTag: (name: string) => void + onUpdateTask: (update: ProjectTaskUpdate) => void }) { switch (activeChannel) { case 'tasks': - return + return case 'ai': return case 'notes': @@ -42,6 +45,6 @@ export function ProjectChannelPage({ return case 'overview': default: - return + return } } diff --git a/apps/senlinai-acro-react/src/pages/projects/project-overview.tsx b/apps/senlinai-acro-react/src/pages/projects/project-overview.tsx index 6a55c3d..b39f5a9 100644 --- a/apps/senlinai-acro-react/src/pages/projects/project-overview.tsx +++ b/apps/senlinai-acro-react/src/pages/projects/project-overview.tsx @@ -1,16 +1,26 @@ -import { useMemo } from 'react' +import { useMemo, useState } from 'react' import { Button, Card, Grid, Space, Tag, Typography } from '@arco-design/web-react' import { IconCheckCircleFill, IconClockCircle, IconFile, IconLink } from '@arco-design/web-react/icon' import { ProjectFileGrid } from './project-file-grid' +import { ProjectTaskEditModal, type ProjectTaskUpdate } from './project-task-edit-modal' import type { ProjectWorkspace, TaskItem } from './project-types' const { Row, Col } = Grid const { Title, Text, Paragraph } = Typography -export function ProjectOverview({ activeWorkspace, onSelectItem }: { activeWorkspace: ProjectWorkspace; onSelectItem: (title: string) => void }) { +export function ProjectOverview({ + activeWorkspace, + onSelectItem, + onUpdateTask, +}: { + activeWorkspace: ProjectWorkspace + onSelectItem: (title: string) => void + onUpdateTask: (update: ProjectTaskUpdate) => void +}) { const { project, tasks, notes, cronJobs } = activeWorkspace const runningTasks = useMemo(() => tasks.filter((task) => !task.completed), [tasks]) const completedTasks = useMemo(() => tasks.filter((task) => task.completed), [tasks]) + const [editingTask, setEditingTask] = useState(null) const shareURL = useMemo(() => projectShareURL(project.identifier || project.id), [project.id, project.identifier]) const metrics = useMemo(() => [ { title: '进行中的任务', value: runningTasks.length, icon: , color: 'green' }, @@ -52,14 +62,35 @@ export function ProjectOverview({ activeWorkspace, onSelectItem }: { activeWorks ))} - + + setEditingTask(null)} + onSubmit={(update) => { + onUpdateTask(update) + setEditingTask(null) + }} + /> ) } -function TaskCardSection({ title, tasks, emptyText, onSelectItem }: { title: string; tasks: TaskItem[]; emptyText: string; onSelectItem: (title: string) => void }) { +function TaskCardSection({ + title, + tasks, + emptyText, + onSelectItem, + onEditTask, +}: { + title: string + tasks: TaskItem[] + emptyText: string + onSelectItem?: (title: string) => void + onEditTask?: (task: TaskItem) => void +}) { return (
@@ -71,7 +102,7 @@ function TaskCardSection({ title, tasks, emptyText, onSelectItem }: { title: str ) : (
{tasks.map((task) => ( -