feat(project): 홈 카드 세션 없으면 업무추가 버튼 비활성화

세션이 하나도 없으면 업무를 넣을 세션이 없으므로 아이콘 버튼(disabled)과
우클릭 메뉴 둘 다 막는다. "세션 추가"로 첫 세션을 만들면 새로고침 없이
바로 활성화(dataset.hasStages 갱신 + disabled 해제).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
2026-09-17 14:18:37 +09:00
parent 29ce3554b1
commit e2734e176c
6 changed files with 38 additions and 17 deletions
+21 -9
View File
@@ -565,7 +565,8 @@
' data-id="' + p.id + '" data-name="' + escapeHtml(p.name || "") + '"' +
' data-desc="' + escapeHtml(p.description || "") + '"' +
' data-start="' + (p.start_date || "") + '" data-due="' + (p.due_date || "") + '"' +
' data-color="' + color + '" data-status="active" data-creator="' + escapeHtml(p.created_by || "") + '">' +
' data-color="' + color + '" data-status="active" data-creator="' + escapeHtml(p.created_by || "") + '"' +
' data-has-stages="false">' +
'<a class="pj-project-cardlink" href="/project/p/' + p.id + '">' +
'<div class="pj-project-header"><span class="pj-project-name">' + escapeHtml(p.name || "") + "</span></div>" +
'<div class="pj-project-body">' +
@@ -576,7 +577,7 @@
'<div class="pj-card-actions">' +
'<button type="button" class="pj-icon-btn pj-card-addstage" title="세션 추가">' +
'<span class="material-symbols-outlined">view_column</span></button>' +
'<button type="button" class="pj-icon-btn pj-card-addtask" data-project-id="' + p.id + '" title="업무 추가">' +
'<button type="button" class="pj-icon-btn pj-card-addtask" data-project-id="' + p.id + '" disabled title="세션을 먼저 추가하세요">' +
'<span class="material-symbols-outlined">add_task</span></button>' +
'<button type="button" class="pj-icon-btn pj-card-edit" title="프로젝트 수정">' +
'<span class="material-symbols-outlined">edit</span></button></div>' +
@@ -610,6 +611,13 @@
try {
await api("POST", "/project/api/projects/" + stageModalProjectId + "/stages", { name: name, color: color });
closeModal(stageModal);
// 이 프로젝트에 세션이 처음 생겼으면 "업무 추가" 버튼을 바로 활성화.
const targetCard = document.querySelector('.pj-project-card[data-id="' + stageModalProjectId + '"]');
if (targetCard) {
targetCard.dataset.hasStages = "true";
const addTaskBtn = targetCard.querySelector(".pj-card-addtask");
if (addTaskBtn) { addTaskBtn.disabled = false; addTaskBtn.title = "업무 추가"; }
}
showToast("세션이 추가되었습니다.", "success");
} catch (e) { showToast("추가 실패: " + e.message, "error"); }
});
@@ -643,14 +651,18 @@
card.addEventListener("contextmenu", function (e) {
if (!card.querySelector(".pj-card-edit")) return; // 관리 권한 없는 카드는 메뉴 없음
e.preventDefault();
showContextMenu(e.clientX, e.clientY, [
const items = [
{ label: "열기", onClick: function () { location.href = "/project/p/" + card.dataset.id; } },
{ label: "업무 추가", onClick: function () { if (openNewTaskModalRef) openNewTaskModalRef(card.dataset.id, card.dataset.name); } },
{ label: "세션 추가", onClick: function () { openStageModalForProject(card.dataset.id, card.dataset.name); } },
{ label: "수정", onClick: function () { openCardEditModal(card); } },
null,
{ label: "삭제", danger: true, onClick: function () { deleteProjectCard(card); } },
]);
];
// 세션이 없으면 업무를 넣을 곳이 없다 — 메뉴에서도 뺀다(아이콘 버튼과 동일 원칙).
if (card.dataset.hasStages !== "false") {
items.push({ label: "업무 추가", onClick: function () { if (openNewTaskModalRef) openNewTaskModalRef(card.dataset.id, card.dataset.name); } });
}
items.push({ label: "세션 추가", onClick: function () { openStageModalForProject(card.dataset.id, card.dataset.name); } });
items.push({ label: "수정", onClick: function () { openCardEditModal(card); } });
items.push(null);
items.push({ label: "삭제", danger: true, onClick: function () { deleteProjectCard(card); } });
showContextMenu(e.clientX, e.clientY, items);
});
}