feat: add project task edit modal
This commit is contained in:
@@ -147,7 +147,7 @@ function mapTask(task: BackendTask): TaskItem {
|
|||||||
createdAt: formatCreatedAt(task.createdAt),
|
createdAt: formatCreatedAt(task.createdAt),
|
||||||
completedAt: task.completedAt ? formatCreatedAt(task.completedAt) : '',
|
completedAt: task.completedAt ? formatCreatedAt(task.completedAt) : '',
|
||||||
duration: task.duration || '',
|
duration: task.duration || '',
|
||||||
tag: task.tag || (task.completed ? '已完成' : '进行中'),
|
tag: task.tag || '',
|
||||||
summary: task.summary,
|
summary: task.summary,
|
||||||
completed: task.completed,
|
completed: task.completed,
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ import { ProjectCron } from './project-cron'
|
|||||||
import { ProjectNewChannel } from './project-new-channel'
|
import { ProjectNewChannel } from './project-new-channel'
|
||||||
import { ProjectNotes } from './project-notes'
|
import { ProjectNotes } from './project-notes'
|
||||||
import { ProjectOverview } from './project-overview'
|
import { ProjectOverview } from './project-overview'
|
||||||
|
import type { ProjectTaskUpdate } from './project-task-edit-modal'
|
||||||
import { ProjectTasks } from './project-tasks'
|
import { ProjectTasks } from './project-tasks'
|
||||||
import type { ChannelKey, ProjectWorkspace } from './project-types'
|
import type { ChannelKey, ProjectWorkspace } from './project-types'
|
||||||
|
|
||||||
@@ -17,6 +18,7 @@ export function ProjectChannelPage({
|
|||||||
onUploadSource,
|
onUploadSource,
|
||||||
onCreateCronPlan,
|
onCreateCronPlan,
|
||||||
onCreateProjectTag,
|
onCreateProjectTag,
|
||||||
|
onUpdateTask,
|
||||||
}: {
|
}: {
|
||||||
activeChannel: ChannelKey
|
activeChannel: ChannelKey
|
||||||
activeWorkspace: ProjectWorkspace
|
activeWorkspace: ProjectWorkspace
|
||||||
@@ -28,10 +30,11 @@ export function ProjectChannelPage({
|
|||||||
onUploadSource: () => void
|
onUploadSource: () => void
|
||||||
onCreateCronPlan: () => void
|
onCreateCronPlan: () => void
|
||||||
onCreateProjectTag: (name: string) => void
|
onCreateProjectTag: (name: string) => void
|
||||||
|
onUpdateTask: (update: ProjectTaskUpdate) => void
|
||||||
}) {
|
}) {
|
||||||
switch (activeChannel) {
|
switch (activeChannel) {
|
||||||
case 'tasks':
|
case 'tasks':
|
||||||
return <ProjectTasks activeWorkspace={activeWorkspace} activeTaskID={activeTaskID} onOpenTask={onOpenTask} onCloseTask={onCloseTask} onSelectItem={onSelectItem} onCreateTask={onCreateTask} onCreateProjectTag={onCreateProjectTag} />
|
return <ProjectTasks activeWorkspace={activeWorkspace} activeTaskID={activeTaskID} onOpenTask={onOpenTask} onCloseTask={onCloseTask} onSelectItem={onSelectItem} onCreateTask={onCreateTask} onCreateProjectTag={onCreateProjectTag} onUpdateTask={onUpdateTask} />
|
||||||
case 'ai':
|
case 'ai':
|
||||||
return <ProjectAi activeWorkspace={activeWorkspace} onSelectItem={onSelectItem} />
|
return <ProjectAi activeWorkspace={activeWorkspace} onSelectItem={onSelectItem} />
|
||||||
case 'notes':
|
case 'notes':
|
||||||
@@ -42,6 +45,6 @@ export function ProjectChannelPage({
|
|||||||
return <ProjectNewChannel activeWorkspace={activeWorkspace} />
|
return <ProjectNewChannel activeWorkspace={activeWorkspace} />
|
||||||
case 'overview':
|
case 'overview':
|
||||||
default:
|
default:
|
||||||
return <ProjectOverview activeWorkspace={activeWorkspace} onSelectItem={onSelectItem} />
|
return <ProjectOverview activeWorkspace={activeWorkspace} onSelectItem={onSelectItem} onUpdateTask={onUpdateTask} />
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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 { Button, Card, Grid, Space, Tag, Typography } from '@arco-design/web-react'
|
||||||
import { IconCheckCircleFill, IconClockCircle, IconFile, IconLink } from '@arco-design/web-react/icon'
|
import { IconCheckCircleFill, IconClockCircle, IconFile, IconLink } from '@arco-design/web-react/icon'
|
||||||
import { ProjectFileGrid } from './project-file-grid'
|
import { ProjectFileGrid } from './project-file-grid'
|
||||||
|
import { ProjectTaskEditModal, type ProjectTaskUpdate } from './project-task-edit-modal'
|
||||||
import type { ProjectWorkspace, TaskItem } from './project-types'
|
import type { ProjectWorkspace, TaskItem } from './project-types'
|
||||||
|
|
||||||
const { Row, Col } = Grid
|
const { Row, Col } = Grid
|
||||||
const { Title, Text, Paragraph } = Typography
|
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 { project, tasks, notes, cronJobs } = activeWorkspace
|
||||||
const runningTasks = useMemo(() => tasks.filter((task) => !task.completed), [tasks])
|
const runningTasks = useMemo(() => tasks.filter((task) => !task.completed), [tasks])
|
||||||
const completedTasks = useMemo(() => tasks.filter((task) => task.completed), [tasks])
|
const completedTasks = useMemo(() => tasks.filter((task) => task.completed), [tasks])
|
||||||
|
const [editingTask, setEditingTask] = useState<TaskItem | null>(null)
|
||||||
const shareURL = useMemo(() => projectShareURL(project.identifier || project.id), [project.id, project.identifier])
|
const shareURL = useMemo(() => projectShareURL(project.identifier || project.id), [project.id, project.identifier])
|
||||||
const metrics = useMemo(() => [
|
const metrics = useMemo(() => [
|
||||||
{ title: '进行中的任务', value: runningTasks.length, icon: <IconCheckCircleFill />, color: 'green' },
|
{ title: '进行中的任务', value: runningTasks.length, icon: <IconCheckCircleFill />, color: 'green' },
|
||||||
@@ -52,14 +62,35 @@ export function ProjectOverview({ activeWorkspace, onSelectItem }: { activeWorks
|
|||||||
))}
|
))}
|
||||||
</Row>
|
</Row>
|
||||||
|
|
||||||
<TaskCardSection title={`进行中的任务(${runningTasks.length})`} tasks={runningTasks} emptyText="当前没有进行中的任务" onSelectItem={onSelectItem} />
|
<TaskCardSection title={`进行中的任务(${runningTasks.length})`} tasks={runningTasks} emptyText="当前没有进行中的任务" onEditTask={setEditingTask} />
|
||||||
<TaskCardSection title={`完成的任务(${completedTasks.length})`} tasks={completedTasks} emptyText="当前没有完成的任务" onSelectItem={onSelectItem} />
|
<TaskCardSection title={`完成的任务(${completedTasks.length})`} tasks={completedTasks} emptyText="当前没有完成的任务" onSelectItem={onSelectItem} />
|
||||||
<NoteSection notes={notes} onSelectItem={onSelectItem} />
|
<NoteSection notes={notes} onSelectItem={onSelectItem} />
|
||||||
|
<ProjectTaskEditModal
|
||||||
|
task={editingTask}
|
||||||
|
workspace={activeWorkspace}
|
||||||
|
onClose={() => setEditingTask(null)}
|
||||||
|
onSubmit={(update) => {
|
||||||
|
onUpdateTask(update)
|
||||||
|
setEditingTask(null)
|
||||||
|
}}
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
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 (
|
return (
|
||||||
<Card className="queue-section overview-task-section" bordered>
|
<Card className="queue-section overview-task-section" bordered>
|
||||||
<div className="section-header">
|
<div className="section-header">
|
||||||
@@ -71,7 +102,7 @@ function TaskCardSection({ title, tasks, emptyText, onSelectItem }: { title: str
|
|||||||
) : (
|
) : (
|
||||||
<div className="overview-task-grid">
|
<div className="overview-task-grid">
|
||||||
{tasks.map((task) => (
|
{tasks.map((task) => (
|
||||||
<button key={task.id} className={task.completed ? 'overview-task-card completed' : 'overview-task-card'} onClick={() => onSelectItem(task.title)}>
|
<button key={task.id} className={task.completed ? 'overview-task-card completed' : 'overview-task-card'} onClick={() => onEditTask ? onEditTask(task) : onSelectItem?.(task.title)}>
|
||||||
<span className="overview-task-title">
|
<span className="overview-task-title">
|
||||||
<IconCheckCircleFill />
|
<IconCheckCircleFill />
|
||||||
{task.title}
|
{task.title}
|
||||||
|
|||||||
@@ -0,0 +1,93 @@
|
|||||||
|
import { Input, Modal, Select, Space, Switch, Typography } from '@arco-design/web-react'
|
||||||
|
import { useEffect, useMemo, useState } from 'react'
|
||||||
|
import type { ProjectWorkspace, TaskItem } from './project-types'
|
||||||
|
|
||||||
|
const { Text } = Typography
|
||||||
|
const { TextArea } = Input
|
||||||
|
|
||||||
|
export type ProjectTaskUpdate = {
|
||||||
|
taskId: string
|
||||||
|
title: string
|
||||||
|
summary: string
|
||||||
|
tag: string
|
||||||
|
completed: boolean
|
||||||
|
}
|
||||||
|
|
||||||
|
type TaskDraft = {
|
||||||
|
title: string
|
||||||
|
summary: string
|
||||||
|
tag: string
|
||||||
|
completed: boolean
|
||||||
|
}
|
||||||
|
|
||||||
|
export function ProjectTaskEditModal({
|
||||||
|
task,
|
||||||
|
workspace,
|
||||||
|
onClose,
|
||||||
|
onSubmit,
|
||||||
|
}: {
|
||||||
|
task: TaskItem | null
|
||||||
|
workspace: ProjectWorkspace
|
||||||
|
onClose: () => void
|
||||||
|
onSubmit: (update: ProjectTaskUpdate) => void
|
||||||
|
}) {
|
||||||
|
const tagOptions = useMemo(() => workspace.tags.filter((tag) => tag !== 'all' && tag !== '全部'), [workspace.tags])
|
||||||
|
const [draft, setDraft] = useState<TaskDraft>({ title: '', summary: '', tag: '', completed: false })
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (!task) return
|
||||||
|
setDraft({
|
||||||
|
title: task.title,
|
||||||
|
summary: task.summary,
|
||||||
|
tag: task.tag,
|
||||||
|
completed: task.completed,
|
||||||
|
})
|
||||||
|
}, [task])
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Modal
|
||||||
|
className="action-modal"
|
||||||
|
title="编辑计划"
|
||||||
|
visible={Boolean(task)}
|
||||||
|
onCancel={onClose}
|
||||||
|
onOk={() => {
|
||||||
|
if (!task) return
|
||||||
|
onSubmit({
|
||||||
|
taskId: task.id,
|
||||||
|
title: draft.title.trim() || task.title,
|
||||||
|
summary: draft.summary.trim(),
|
||||||
|
tag: draft.tag.trim(),
|
||||||
|
completed: draft.completed,
|
||||||
|
})
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Space direction="vertical" size={12} className="action-form">
|
||||||
|
<label>
|
||||||
|
<Text>标题</Text>
|
||||||
|
<Input value={draft.title} onChange={(title) => setDraft((value) => ({ ...value, title }))} />
|
||||||
|
</label>
|
||||||
|
<label>
|
||||||
|
<Text>正文</Text>
|
||||||
|
<TextArea rows={4} value={draft.summary} onChange={(summary) => setDraft((value) => ({ ...value, summary }))} />
|
||||||
|
</label>
|
||||||
|
<label>
|
||||||
|
<Text>标签</Text>
|
||||||
|
<Select
|
||||||
|
allowClear
|
||||||
|
value={draft.tag || undefined}
|
||||||
|
placeholder="不设置标签"
|
||||||
|
onChange={(tag) => setDraft((value) => ({ ...value, tag: tag ?? '' }))}
|
||||||
|
>
|
||||||
|
{tagOptions.map((tag) => (
|
||||||
|
<Select.Option key={tag} value={tag}>{tag}</Select.Option>
|
||||||
|
))}
|
||||||
|
</Select>
|
||||||
|
</label>
|
||||||
|
<label className="action-switch">
|
||||||
|
<Text>完成状态</Text>
|
||||||
|
<Switch checked={draft.completed} checkedText="完成" uncheckedText="未完成" onChange={(completed) => setDraft((value) => ({ ...value, completed }))} />
|
||||||
|
</label>
|
||||||
|
</Space>
|
||||||
|
</Modal>
|
||||||
|
)
|
||||||
|
}
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
import { useState } from 'react'
|
import { useState } from 'react'
|
||||||
import { Button, Card, Descriptions, Input, Modal, Progress, Space, Tag, Typography } from '@arco-design/web-react'
|
import { Button, Card, Descriptions, Input, Modal, Progress, Space, Tag, Typography } from '@arco-design/web-react'
|
||||||
import { IconArrowLeft, IconCalendar, IconCheckCircle, IconCheckCircleFill, IconClockCircle, IconPlus } from '@arco-design/web-react/icon'
|
import { IconArrowLeft, IconCalendar, IconCheckCircle, IconCheckCircleFill, IconClockCircle, IconPlus } from '@arco-design/web-react/icon'
|
||||||
|
import { ProjectTaskEditModal, type ProjectTaskUpdate } from './project-task-edit-modal'
|
||||||
import type { ProjectWorkspace, TaskItem } from './project-types'
|
import type { ProjectWorkspace, TaskItem } from './project-types'
|
||||||
|
|
||||||
const { Title, Text, Paragraph } = Typography
|
const { Title, Text, Paragraph } = Typography
|
||||||
@@ -12,6 +13,7 @@ export function ProjectTasks({
|
|||||||
onCloseTask,
|
onCloseTask,
|
||||||
onCreateTask,
|
onCreateTask,
|
||||||
onCreateProjectTag,
|
onCreateProjectTag,
|
||||||
|
onUpdateTask,
|
||||||
}: {
|
}: {
|
||||||
activeWorkspace: ProjectWorkspace
|
activeWorkspace: ProjectWorkspace
|
||||||
activeTaskID: string | null
|
activeTaskID: string | null
|
||||||
@@ -20,6 +22,7 @@ export function ProjectTasks({
|
|||||||
onSelectItem: (title: string) => void
|
onSelectItem: (title: string) => void
|
||||||
onCreateTask: () => void
|
onCreateTask: () => void
|
||||||
onCreateProjectTag: (name: string) => void
|
onCreateProjectTag: (name: string) => void
|
||||||
|
onUpdateTask: (update: ProjectTaskUpdate) => void
|
||||||
}) {
|
}) {
|
||||||
const { tasks, project, tags } = activeWorkspace
|
const { tasks, project, tags } = activeWorkspace
|
||||||
const activeTask = tasks.find((task) => task.id === activeTaskID)
|
const activeTask = tasks.find((task) => task.id === activeTaskID)
|
||||||
@@ -28,6 +31,7 @@ export function ProjectTasks({
|
|||||||
const projectTags = tags.filter((tag) => tag !== 'all' && tag !== '全部')
|
const projectTags = tags.filter((tag) => tag !== 'all' && tag !== '全部')
|
||||||
const [tagModalOpen, setTagModalOpen] = useState(false)
|
const [tagModalOpen, setTagModalOpen] = useState(false)
|
||||||
const [tagName, setTagName] = useState('')
|
const [tagName, setTagName] = useState('')
|
||||||
|
const [editingTask, setEditingTask] = useState<TaskItem | null>(null)
|
||||||
|
|
||||||
if (activeTask) {
|
if (activeTask) {
|
||||||
return <TaskDetail activeWorkspace={activeWorkspace} task={activeTask} onBack={onCloseTask} />
|
return <TaskDetail activeWorkspace={activeWorkspace} task={activeTask} onBack={onCloseTask} />
|
||||||
@@ -71,7 +75,7 @@ export function ProjectTasks({
|
|||||||
</div>
|
</div>
|
||||||
<div className="task-plan-card-grid">
|
<div className="task-plan-card-grid">
|
||||||
{pendingTasks.map((task) => (
|
{pendingTasks.map((task) => (
|
||||||
<button className="task-plan-card" key={task.id} onClick={() => onOpenTask(task.id)}>
|
<button className="task-plan-card" key={task.id} onClick={() => setEditingTask(task)}>
|
||||||
<span className="task-plan-title"><IconCheckCircleFill />{task.title}</span>
|
<span className="task-plan-title"><IconCheckCircleFill />{task.title}</span>
|
||||||
<Paragraph ellipsis={{ rows: 2 }} type="secondary">{task.summary || '暂无正文'}</Paragraph>
|
<Paragraph ellipsis={{ rows: 2 }} type="secondary">{task.summary || '暂无正文'}</Paragraph>
|
||||||
<div className="task-plan-meta">
|
<div className="task-plan-meta">
|
||||||
@@ -120,6 +124,15 @@ export function ProjectTasks({
|
|||||||
</label>
|
</label>
|
||||||
</Space>
|
</Space>
|
||||||
</Modal>
|
</Modal>
|
||||||
|
<ProjectTaskEditModal
|
||||||
|
task={editingTask}
|
||||||
|
workspace={activeWorkspace}
|
||||||
|
onClose={() => setEditingTask(null)}
|
||||||
|
onSubmit={(update) => {
|
||||||
|
onUpdateTask(update)
|
||||||
|
setEditingTask(null)
|
||||||
|
}}
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -44,6 +44,7 @@ export function WorkspacePage({
|
|||||||
onUpdateTask: (update: WorkspaceTaskUpdate) => void
|
onUpdateTask: (update: WorkspaceTaskUpdate) => void
|
||||||
}) {
|
}) {
|
||||||
const projects = workspaces.map((workspace) => workspace.project)
|
const projects = workspaces.map((workspace) => workspace.project)
|
||||||
|
const projectOptions = useMemo(() => workspaces.map((workspace) => workspace.project), [workspaces])
|
||||||
const unfinishedTasks: WorkspaceTask[] = workspaces.flatMap((workspace) =>
|
const unfinishedTasks: WorkspaceTask[] = workspaces.flatMap((workspace) =>
|
||||||
workspace.tasks
|
workspace.tasks
|
||||||
.filter((task) => !task.completed)
|
.filter((task) => !task.completed)
|
||||||
@@ -78,7 +79,7 @@ export function WorkspacePage({
|
|||||||
const urgentProjects = projects.filter((project) => project.urgent).length
|
const urgentProjects = projects.filter((project) => project.urgent).length
|
||||||
const workspaceMetrics = [
|
const workspaceMetrics = [
|
||||||
{ title: '项目总数', value: projects.length, delta: `${urgentProjects} 个高优先级`, icon: <IconDashboard />, color: 'arcoblue' },
|
{ title: '项目总数', value: projects.length, delta: `${urgentProjects} 个高优先级`, icon: <IconDashboard />, color: 'arcoblue' },
|
||||||
{ title: '未完成任务', value: unfinishedTasks.length, delta: '跨项目聚合', icon: <IconCheckCircleFill />, color: 'green' },
|
{ title: '未完成计划', value: unfinishedTasks.length, delta: '跨项目聚合', icon: <IconCheckCircleFill />, color: 'green' },
|
||||||
{ title: 'AI 会话', value: aiSessions.length, delta: '项目内上下文', icon: <IconRobot />, color: 'purple' },
|
{ title: 'AI 会话', value: aiSessions.length, delta: '项目内上下文', icon: <IconRobot />, color: 'purple' },
|
||||||
{ title: '知识资料', value: notes.length, delta: '笔记与资料合计', icon: <IconFile />, color: 'cyan' },
|
{ title: '知识资料', value: notes.length, delta: '笔记与资料合计', icon: <IconFile />, color: 'cyan' },
|
||||||
]
|
]
|
||||||
@@ -111,7 +112,7 @@ export function WorkspacePage({
|
|||||||
|
|
||||||
<Card className="queue-section" bordered>
|
<Card className="queue-section" bordered>
|
||||||
<div className="section-header">
|
<div className="section-header">
|
||||||
<Title heading={6}>未完成的任务</Title>
|
<Title heading={6}>未完成的计划</Title>
|
||||||
<Tag color="arcoblue">{unfinishedTasks.length}</Tag>
|
<Tag color="arcoblue">{unfinishedTasks.length}</Tag>
|
||||||
</div>
|
</div>
|
||||||
{unfinishedTasks.length ? (
|
{unfinishedTasks.length ? (
|
||||||
@@ -129,14 +130,14 @@ export function WorkspacePage({
|
|||||||
</div>
|
</div>
|
||||||
<div className="workspace-task-meta">
|
<div className="workspace-task-meta">
|
||||||
<Tag color={task.project.urgent ? 'red' : 'arcoblue'}>{task.project.name}</Tag>
|
<Tag color={task.project.urgent ? 'red' : 'arcoblue'}>{task.project.name}</Tag>
|
||||||
|
<Tag color="green">{task.tag || '-'}</Tag>
|
||||||
<span><IconCalendar /> {task.createdAt}</span>
|
<span><IconCalendar /> {task.createdAt}</span>
|
||||||
<Tag color="green">{task.tag}</Tag>
|
|
||||||
</div>
|
</div>
|
||||||
</button>
|
</button>
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
) : (
|
) : (
|
||||||
<Empty description="暂无未完成任务" />
|
<Empty description="暂无未完成计划" />
|
||||||
)}
|
)}
|
||||||
</Card>
|
</Card>
|
||||||
|
|
||||||
@@ -170,8 +171,13 @@ export function WorkspacePage({
|
|||||||
</label>
|
</label>
|
||||||
<label>
|
<label>
|
||||||
<Text>所属项目</Text>
|
<Text>所属项目</Text>
|
||||||
<Select value={draft.projectId} onChange={(projectId) => setDraft((value) => ({ ...value, projectId }))}>
|
<Select
|
||||||
{projects.map((project) => (
|
showSearch
|
||||||
|
value={draft.projectId}
|
||||||
|
placeholder="选择项目"
|
||||||
|
onChange={(projectId) => setDraft((value) => ({ ...value, projectId }))}
|
||||||
|
>
|
||||||
|
{projectOptions.map((project) => (
|
||||||
<Select.Option key={project.id} value={project.id}>{project.name}</Select.Option>
|
<Select.Option key={project.id} value={project.id}>{project.name}</Select.Option>
|
||||||
))}
|
))}
|
||||||
</Select>
|
</Select>
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ import { Layout } from '@arco-design/web-react'
|
|||||||
import { WorkspacePage, type WorkspaceTaskUpdate } from './workspace-body'
|
import { WorkspacePage, type WorkspaceTaskUpdate } from './workspace-body'
|
||||||
import { WorkspaceExplorePage } from './workspace-explore'
|
import { WorkspaceExplorePage } from './workspace-explore'
|
||||||
import { ProjectChannelPage } from './projects/project-channel-page'
|
import { ProjectChannelPage } from './projects/project-channel-page'
|
||||||
|
import type { ProjectTaskUpdate } from './projects/project-task-edit-modal'
|
||||||
import { ProjectRail } from './projects/project-rail'
|
import { ProjectRail } from './projects/project-rail'
|
||||||
import { ProjectSidebar, type ProjectSettingsUpdate } from './projects/project-sidebar'
|
import { ProjectSidebar, type ProjectSettingsUpdate } from './projects/project-sidebar'
|
||||||
import { ProjectStatusbar } from './projects/project-statusbar'
|
import { ProjectStatusbar } from './projects/project-statusbar'
|
||||||
@@ -57,6 +58,17 @@ export function ProjectPage({
|
|||||||
}) {
|
}) {
|
||||||
const isProject = activeView === 'project'
|
const isProject = activeView === 'project'
|
||||||
const projects = workspaces.map((workspace) => workspace.project)
|
const projects = workspaces.map((workspace) => workspace.project)
|
||||||
|
const updateActiveProjectTask = (update: ProjectTaskUpdate) => {
|
||||||
|
onUpdateWorkspaceTask({
|
||||||
|
originalProjectId: activeWorkspace.project.id,
|
||||||
|
nextProjectId: activeWorkspace.project.id,
|
||||||
|
taskId: update.taskId,
|
||||||
|
title: update.title,
|
||||||
|
summary: update.summary,
|
||||||
|
tag: update.tag,
|
||||||
|
completed: update.completed,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Layout className="workbench-shell">
|
<Layout className="workbench-shell">
|
||||||
@@ -101,6 +113,7 @@ export function ProjectPage({
|
|||||||
onUploadSource={onUploadSource}
|
onUploadSource={onUploadSource}
|
||||||
onCreateCronPlan={onCreateCronPlan}
|
onCreateCronPlan={onCreateCronPlan}
|
||||||
onCreateProjectTag={onCreateProjectTag}
|
onCreateProjectTag={onCreateProjectTag}
|
||||||
|
onUpdateTask={updateActiveProjectTask}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
</Content>
|
</Content>
|
||||||
|
|||||||
Reference in New Issue
Block a user