feat(project): 담당자·댓글 작성자 아이콘을 구글 프로필 이미지(원형)로 표시

- 라우터: 이메일→구글 picture URL 아바타 맵을 pj-data 로 전달
- 보드 카드/리스트 담당자, 댓글 작성자에 원형 프로필 이미지 표시
- 이미지 없으면 기존 기본 아이콘 폴백. referrerpolicy=no-referrer

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-06-25 17:26:55 +09:00
parent 7c5a62ecc1
commit 6e0180944e
5 changed files with 32 additions and 8 deletions
+13 -2
View File
@@ -193,6 +193,14 @@
const projectsMeta = data.projects || [];
const stagesByProject = data.stagesByProject || {};
const boardStages = data.boardStages || [];
const avatars = data.avatars || {};
// 담당자/작성자 아이콘 = 구글 프로필 이미지(원형). 없으면 기본 아이콘.
function avatarHtml(email, cls) {
const url = email ? avatars[String(email).toLowerCase()] : "";
const c = cls || "";
if (url) return '<img class="pj-avatar ' + c + '" src="' + escapeHtml(url) + '" alt="" referrerpolicy="no-referrer">';
return '<span class="material-symbols-outlined pj-gicon ' + c + '">account_circle</span>';
}
let timeline = null;
let currentView = "calendar";
@@ -620,7 +628,7 @@
? '<span class="pj-pri pj-pri-' + t.priority + '">' + (priorityLabels[t.priority] || t.priority) + "</span>"
: "") +
(t.assignee_email
? '<span class="pj-assignee"><span class="material-symbols-outlined pj-gicon pj-gicon-sm">account_circle</span>' +
? '<span class="pj-assignee">' + avatarHtml(t.assignee_email, "pj-gicon-sm") +
escapeHtml(idOf(t.assignee_email)) + "</span>"
: "") +
(t.due_date ? '<span class="pj-card-due">' + t.due_date + "</span>" : "") +
@@ -738,6 +746,9 @@
tr.innerHTML = LIST_COLS.map(function (c) {
let inner = escapeHtml(String(c.text(t)));
if (c.key === "title") inner += cmtBadge(t);
if (c.key === "assignee" && t.assignee_email) {
inner = '<span class="pj-assignee">' + avatarHtml(t.assignee_email, "pj-gicon-sm") + escapeHtml(idOf(t.assignee_email)) + "</span>";
}
return "<td>" + inner + "</td>";
}).join("");
if (canManage) { tr.style.cursor = "pointer"; tr.addEventListener("click", function () { openTaskModal(t); }); }
@@ -856,7 +867,7 @@
const li = document.createElement("li");
li.className = "pj-comment-item";
li.innerHTML =
'<span class="material-symbols-outlined pj-gicon pj-gicon-sm">account_circle</span>' +
avatarHtml(c.author_email, "pj-gicon-sm") +
'<div class="pj-comment-main"><div class="pj-comment-head">' +
escapeHtml(idOf(c.author_email)) + ' <span class="pj-comment-time">' +
(c.created_at || "").slice(0, 16).replace("T", " ") + "</span></div>" +