diff --git a/STATUS.md b/STATUS.md index 43c541c61..02f024c46 100644 --- a/STATUS.md +++ b/STATUS.md @@ -48,19 +48,22 @@ - ✅ API 文档(Swagger) ### 测试与质量 -- ✅ **15 个集成测试全绿**(素材管理 8 个 + 项目管理 7 个) +- ✅ **16 个集成测试全绿**(素材管理 8 个 + 项目管理 8 个) - ✅ 测试策略:集成测试优先,覆盖核心业务流程 --- ## 进行中 -### 项目推进器前端页面 -- 🔄 Next.js 页面设计与开发(下一步) -- 🔄 树形任务视图 +### 项目推进器前端功能扩展 +- ✅ 任务创建表单 +- ✅ 任务详情页 +- ✅ 任务列表链接跳转 +- ✅ 实时 API 集成 +- 🔄 任务编辑功能(下一步) +- 🔄 里程碑管理页面 +- 🔄 问题卡点创建与解决 - 🔄 甘特图视图 -- 🔄 里程碑时间轴 -- 🔄 问题卡点面板 ### 稳定化与部署打磨 - 🔄 Gitea workflows 持续优化 @@ -136,7 +139,7 @@ - **本地路径**: `F:\openclaw-saas` - **远程仓库**: `xiaoxia-server:/var/lib/xiaoxia-ci/xiaoxia-saas.git` - **分支**: `main` -- **最新提交**: `355dd0f feat: add project management module (tasks, milestones, issues)` +- **最新提交**: `ef4cd8a feat: add GET task detail endpoint and use case` --- diff --git a/apps/web/app/components/CreateIssueForm.tsx b/apps/web/app/components/CreateIssueForm.tsx new file mode 100644 index 000000000..38ec5f1e3 --- /dev/null +++ b/apps/web/app/components/CreateIssueForm.tsx @@ -0,0 +1,147 @@ +'use client'; + +import { useState } from 'react'; + +const API_BASE = process.env.NEXT_PUBLIC_API_URL || 'http://localhost:8000'; + +interface CreateIssueFormProps { + taskId: string; + projectId: string; + workspaceId: string; + onSuccess: () => void; + onCancel: () => void; +} + +export default function CreateIssueForm({ taskId, projectId, workspaceId, onSuccess, onCancel }: CreateIssueFormProps) { + const [loading, setLoading] = useState(false); + const [error, setError] = useState(''); + const [formData, setFormData] = useState({ + title: '', + description: '', + }); + + const handleSubmit = async (e: React.FormEvent) => { + e.preventDefault(); + setLoading(true); + setError(''); + + try { + const res = await fetch(`${API_BASE}/api/v1/project-management/issues`, { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify({ + task_id: taskId, + project_id: projectId, + workspace_id: workspaceId, + ...formData, + }), + }); + + if (!res.ok) { + const data = await res.json(); + throw new Error(data.detail || '创建失败'); + } + + onSuccess(); + } catch (err: any) { + setError(err.message); + } finally { + setLoading(false); + } + }; + + return ( +
+ {error && ( +
+ {error} +
+ )} + +
+ + setFormData({ ...formData, title: e.target.value })} + style={{ + width: '100%', + padding: '8px 12px', + border: '1px solid var(--border)', + borderRadius: '4px', + fontSize: '14px', + }} + placeholder="简要描述问题" + /> +
+ +
+ +