feat(project): 댓글 있는 업무에 말풍선 아이콘 표시(달력·타임라인·보드·리스트)
- list_tasks/get_task 에 comment_count 서브쿼리 추가 - 달력 막대/타임라인 항목/보드 카드/리스트 업무열에 댓글 수 말풍선 - 댓글 로드 시 메모리 카운트 동기화 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
+16
-3
@@ -175,6 +175,13 @@
|
||||
return !!cb && cb === me;
|
||||
}
|
||||
const DELETE_DENIED = "삭제는 만든 사람만 할 수 있습니다.";
|
||||
// 댓글 있으면 말풍선 아이콘(+개수). 색은 currentColor 상속(막대=흰, 카드/리스트=진회색).
|
||||
function cmtBadge(t, cls) {
|
||||
const n = t.comment_count || 0;
|
||||
if (!n) return "";
|
||||
return '<span class="material-symbols-outlined pj-cmt-ic ' + (cls || "") +
|
||||
'" title="댓글 ' + n + '개">chat_bubble</span><span class="pj-cmt-n">' + n + "</span>";
|
||||
}
|
||||
|
||||
const dataEl = el("pj-data");
|
||||
const data = JSON.parse(dataEl.textContent);
|
||||
@@ -326,7 +333,7 @@
|
||||
div.style.background = b.t.completed_at ? "#9aa5b1" : (b.t.project_color || "#4573d2");
|
||||
div.title = "[" + (b.t.project_name || "") + "] " + (b.t.title || "") +
|
||||
(b.t.assignee_email ? " · " + idOf(b.t.assignee_email) : "");
|
||||
div.innerHTML = '<span class="pj-bar-label">' + escapeHtml(b.t.title || "") + "</span>";
|
||||
div.innerHTML = '<span class="pj-bar-label">' + escapeHtml(b.t.title || "") + "</span>" + cmtBadge(b.t);
|
||||
cont.appendChild(div);
|
||||
});
|
||||
for (var col = 0; col < 7; col++) {
|
||||
@@ -484,7 +491,7 @@
|
||||
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);
|
||||
items.push({
|
||||
id: t.id, group: grp, content: t.title,
|
||||
id: t.id, group: grp, content: escapeHtml(t.title || "") + cmtBadge(t, "pj-cmt-ic-tl"),
|
||||
start: startISO, end: isRange ? endISO : undefined,
|
||||
type: isRange ? "range" : "point",
|
||||
style: "background-color:" + (t.completed_at ? "#9aa5b1" : projColor) + ";color:#fff;border:none;",
|
||||
@@ -613,6 +620,7 @@
|
||||
escapeHtml(idOf(t.assignee_email)) + "</span>"
|
||||
: "") +
|
||||
(t.due_date ? '<span class="pj-card-due">' + t.due_date + "</span>" : "") +
|
||||
(t.comment_count ? '<span class="pj-card-cmt">' + cmtBadge(t) + "</span>" : "") +
|
||||
"</div>";
|
||||
card.addEventListener("click", function () { if (canManage) openTaskModal(t); });
|
||||
if (canManage) {
|
||||
@@ -724,7 +732,9 @@
|
||||
const pc = t.project_color || "#4573d2";
|
||||
tr.style.background = pc + "14";
|
||||
tr.innerHTML = LIST_COLS.map(function (c) {
|
||||
return "<td>" + escapeHtml(String(c.text(t))) + "</td>";
|
||||
let inner = escapeHtml(String(c.text(t)));
|
||||
if (c.key === "title") inner += cmtBadge(t);
|
||||
return "<td>" + inner + "</td>";
|
||||
}).join("");
|
||||
if (canManage) { tr.style.cursor = "pointer"; tr.addEventListener("click", function () { openTaskModal(t); }); }
|
||||
tbody.appendChild(tr);
|
||||
@@ -833,6 +843,9 @@
|
||||
ul.innerHTML = "<li class='pj-empty-sm'>불러오는 중…</li>";
|
||||
try {
|
||||
const res = await api("GET", "/project/api/tasks/" + taskId + "/comments");
|
||||
// 메모리 업무의 댓글 수 동기화(아이콘 표시용)
|
||||
const tt = tasks.find(function (x) { return String(x.id) === String(taskId); });
|
||||
if (tt) tt.comment_count = res.comments.length;
|
||||
if (!res.comments.length) { ul.innerHTML = "<li class='pj-empty-sm'>댓글 없음</li>"; return; }
|
||||
ul.innerHTML = "";
|
||||
res.comments.forEach(function (c) {
|
||||
|
||||
Reference in New Issue
Block a user