feat(project): 업무 시간 지정(종일 기본) + 타임라인 시간 반영
- tasks 에 start_time/due_time TIME 컬럼 추가(마이그레이션 003). NULL=종일
- 업무 모달에 '시간 지정' 체크박스 → 체크 시 시작/마감 시간 입력란 표시.
미체크면 종일로 저장(시간 null)
- store.validate_time(HH:MM), db create/update + TIME 직렬화('HH:MM')
- 타임라인: 시간 있으면 date+time 으로 정확히 배치, 없으면 종일
DB: scripts/sql/project_db_003_task_times.sql 서버서 적용 필요.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
+22
-3
@@ -231,12 +231,16 @@
|
||||
.map(function (t) {
|
||||
const s = t.start_date || t.due_date;
|
||||
const e = t.due_date || t.start_date;
|
||||
// 시간 지정 시 date+time, 아니면 종일(날짜만)
|
||||
const startISO = s + (t.start_time ? "T" + t.start_time : "");
|
||||
const endISO = e + (t.due_time ? "T" + t.due_time : "");
|
||||
const isRange = (e !== s) || (!!t.start_time && !!t.due_time && t.start_time !== t.due_time);
|
||||
return {
|
||||
id: t.id,
|
||||
content: t.title,
|
||||
start: s,
|
||||
end: e !== s ? e : undefined,
|
||||
type: e !== s ? "range" : "point",
|
||||
start: startISO,
|
||||
end: isRange ? endISO : undefined,
|
||||
type: isRange ? "range" : "point",
|
||||
style: "background-color:" + (t.completed_at ? "#9aa5b1" : (t.project_color || "#4573d2")) + ";color:#fff;border:none;",
|
||||
};
|
||||
});
|
||||
@@ -447,6 +451,12 @@
|
||||
el("pj-t-priority").value = task ? (task.priority || "normal") : "normal";
|
||||
el("pj-t-start").value = task ? (task.start_date || "") : "";
|
||||
el("pj-t-due").value = task ? (task.due_date || "") : "";
|
||||
// 시간 — 값이 있으면 '시간 지정' 체크 + 입력란 표시
|
||||
const useTime = !!(task && (task.start_time || task.due_time));
|
||||
el("pj-t-usetime").checked = useTime;
|
||||
el("pj-t-stime").value = task ? (task.start_time || "") : "";
|
||||
el("pj-t-dtime").value = task ? (task.due_time || "") : "";
|
||||
el("pj-time-row").hidden = !useTime;
|
||||
el("pj-delete-task").hidden = !task;
|
||||
// 댓글·첨부는 기존 업무 편집 시에만
|
||||
currentTaskId = task ? task.id : null;
|
||||
@@ -586,10 +596,16 @@
|
||||
const newTaskBtn = el("pj-new-task");
|
||||
if (newTaskBtn) newTaskBtn.addEventListener("click", function () { openTaskModal(null); });
|
||||
|
||||
// '시간 지정' 체크 → 시간 입력란 토글
|
||||
el("pj-t-usetime").addEventListener("change", function () {
|
||||
el("pj-time-row").hidden = !this.checked;
|
||||
});
|
||||
|
||||
el("pj-save-task").addEventListener("click", async function () {
|
||||
const id = el("pj-t-id").value;
|
||||
const assigneeSel = el("pj-t-assignee");
|
||||
const assigneeName = assigneeSel.selectedOptions[0] ? (assigneeSel.selectedOptions[0].dataset.name || "") : "";
|
||||
const useTime = el("pj-t-usetime").checked;
|
||||
const payload = {
|
||||
title: el("pj-t-title").value.trim(),
|
||||
description: el("pj-t-desc").value.trim(),
|
||||
@@ -599,6 +615,9 @@
|
||||
priority: el("pj-t-priority").value,
|
||||
start_date: el("pj-t-start").value || null,
|
||||
due_date: el("pj-t-due").value || null,
|
||||
// 시간 미지정(체크 해제) = 종일 → null 전송
|
||||
start_time: useTime ? (el("pj-t-stime").value || null) : null,
|
||||
due_time: useTime ? (el("pj-t-dtime").value || null) : null,
|
||||
};
|
||||
if (!payload.title) { alert("제목을 입력하세요."); return; }
|
||||
try {
|
||||
|
||||
Reference in New Issue
Block a user