diff --git a/static/app.js b/static/app.js index 9161b4e..fb3f1f6 100644 --- a/static/app.js +++ b/static/app.js @@ -172,31 +172,35 @@ window.createOperation = (event) => createResource(event, "operations"); window.createProduct = (event) => createResource(event, "products"); window.openTaskForm = (projectId, taskId) => { - const form = document.querySelector(`#task-form-${projectId}`); - form.classList.remove("hidden"); + const drawer = document.querySelector(`#task-drawer-${projectId}`); + const titleEl = drawer.querySelector(".task-drawer-title"); if (taskId === null) { - // new task document.querySelector(`#task-id-${projectId}`).value = ""; document.querySelector(`#task-name-${projectId}`).value = ""; - document.querySelector(`#task-phase-${projectId}`).value = "项目准备"; + document.querySelector(`#task-phase-${projectId}`).value = "商务洽谈"; document.querySelector(`#task-owner-${projectId}`).value = ""; document.querySelector(`#task-due-${projectId}`).value = ""; document.querySelector(`#task-notes-${projectId}`).value = ""; + document.querySelector(`#task-blockers-${projectId}`).value = ""; document.querySelector(`#task-submit-btn-${projectId}`).textContent = "确认新增"; + if (titleEl) titleEl.textContent = "新增任务"; } else { - // edit task const task = (state.data.tasks || []).find((t) => t.id === taskId); if (!task) return; document.querySelector(`#task-id-${projectId}`).value = task.id; document.querySelector(`#task-name-${projectId}`).value = task.task || ""; - document.querySelector(`#task-phase-${projectId}`).value = task.phase || "项目准备"; + document.querySelector(`#task-phase-${projectId}`).value = task.phase || "商务洽谈"; document.querySelector(`#task-owner-${projectId}`).value = task.owner || ""; document.querySelector(`#task-due-${projectId}`).value = task.due_date || ""; document.querySelector(`#task-notes-${projectId}`).value = task.notes || ""; document.querySelector(`#task-blockers-${projectId}`).value = task.blockers || ""; document.querySelector(`#task-submit-btn-${projectId}`).textContent = "保存修改"; + if (titleEl) titleEl.textContent = "编辑任务"; } - form.scrollIntoView({ behavior: "smooth" }); + drawer.classList.add("open"); +}; +window.closeTaskDrawer = (projectId) => { + document.querySelector(`#task-drawer-${projectId}`).classList.remove("open"); }; window.submitTaskForm = async (event, projectId) => { @@ -212,6 +216,7 @@ window.submitTaskForm = async (event, projectId) => { await api("/api/tasks", { method: "POST", body: JSON.stringify({ data }) }); } await load(); + closeTaskDrawer(projectId); showTaskModal(Number(projectId)); } catch (error) { alert("保存失败:" + error.message); @@ -255,27 +260,31 @@ function showTaskModal(projectId) { const project = state.data.operations.find((x) => x.id === projectId); const tasks = (state.data.tasks || []).filter((t) => t.project_id === projectId); const phases = ["商务洽谈", "系统上线", "团队分工", "项目交付", "上线推广", "结项验收"]; - document.querySelector("#taskModal").innerHTML = `
`; document.querySelector("#taskModal").classList.add("active"); if (window.lucide) window.lucide.createIcons(); } diff --git a/static/styles.css b/static/styles.css index 85267b8..c1ff82f 100644 --- a/static/styles.css +++ b/static/styles.css @@ -501,6 +501,7 @@ td { .task-panel { background: #fff; border-radius: 12px; width: 1000px; max-width: 96vw; box-shadow: 0 20px 60px rgba(0,0,0,0.12); margin-bottom: 48px; + overflow: hidden; } .task-header { display: flex; align-items: center; justify-content: space-between; @@ -512,7 +513,21 @@ td { padding: 4px; border-radius: 6px; display: flex; } .task-close:hover { color: #475569; background: #f1f5f9; } -.task-body { padding: 20px; display: flex; flex-direction: column; gap: 16px; } +.task-body-wrap { position: relative; overflow: hidden; } +.task-body { padding: 20px; display: flex; flex-direction: column; gap: 16px; transition: margin-right 0.25s ease; } +.task-drawer { + position: absolute; top: 0; right: 0; width: 420px; height: 100%; + background: #fff; border-left: 1px solid #e2e8f0; + transform: translateX(100%); transition: transform 0.25s ease; + z-index: 10; display: flex; flex-direction: column; +} +.task-drawer.open { transform: translateX(0); } +.task-drawer-hd { + display: flex; align-items: center; justify-content: space-between; + padding: 14px 20px; border-bottom: 1px solid #e2e8f0; +} +.task-drawer-title { font-size: 15px; font-weight: 600; color: #1e293b; } +.task-drawer-form { padding: 16px 20px; flex: 1; overflow-y: auto; display: flex; flex-direction: column; gap: 14px; } .task-group { background: #fff; border-radius: 8px; border: 1px solid #e2e8f0; overflow: hidden;