94 lines
2.6 KiB
TypeScript
94 lines
2.6 KiB
TypeScript
|
|
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>
|
||
|
|
)
|
||
|
|
}
|