Files
agent/apps/web_v1/src/pages/projects/project-task-edit-modal.tsx

112 lines
3.2 KiB
TypeScript

import { Alert, 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) => Promise<void>
}) {
const tagOptions = useMemo(() => workspace.tags.filter((tag) => tag !== 'all' && tag !== '全部'), [workspace.tags])
const [draft, setDraft] = useState<TaskDraft>({ title: '', summary: '', tag: '', completed: false })
const [saving, setSaving] = useState(false)
const [saveError, setSaveError] = useState('')
useEffect(() => {
if (!task) return
setSaveError('')
setDraft({
title: task.title,
summary: task.summary,
tag: task.tag,
completed: task.completed,
})
}, [task])
async function saveTask() {
if (!task || saving) return
setSaving(true)
setSaveError('')
try {
await onSubmit({
taskId: task.id,
title: draft.title.trim() || task.title,
summary: draft.summary.trim(),
tag: draft.tag.trim(),
completed: draft.completed,
})
onClose()
} catch (error) {
setSaveError(error instanceof Error ? error.message : '任务保存失败,请稍后重试')
} finally {
setSaving(false)
}
}
return (
<Modal
className="action-modal"
title="编辑计划"
visible={Boolean(task)}
confirmLoading={saving}
maskClosable={!saving}
cancelButtonProps={{ disabled: saving }}
onCancel={() => { if (!saving) onClose() }}
onOk={() => void saveTask()}
>
<Space direction="vertical" size={12} className="action-form">
{saveError && <Alert type="error" content={saveError} />}
<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>
)
}