feat(project): 담당자는 아이디만 표기 + 구글 머티리얼 아이콘
담당자 표시를 이메일 아이디(@ 앞)로 통일. 아바타를 letter 원형에서 구글 Material Symbols account_circle 아이콘으로 교체(멤버 목록·보드 카드· 모달 선택지·리스트 뷰). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -1,7 +1,9 @@
|
|||||||
{% extends "erp_base.html" %}
|
{% extends "erp_base.html" %}
|
||||||
|
|
||||||
{% block head_extra %}
|
{% block head_extra %}
|
||||||
<link rel="stylesheet" href="/static/project.css?v=20260625b" />
|
<link rel="stylesheet" href="/static/project.css?v=20260625c" />
|
||||||
|
<!-- 구글 머티리얼 심볼(담당자 아이콘 등) -->
|
||||||
|
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@24,400,0,0" />
|
||||||
<!-- 달력은 휴가 모듈과 동일한 서버 렌더 그리드(project.css). 타임라인만 vis(CDN, 추후 self-host) -->
|
<!-- 달력은 휴가 모듈과 동일한 서버 렌더 그리드(project.css). 타임라인만 vis(CDN, 추후 self-host) -->
|
||||||
<link href="https://cdn.jsdelivr.net/npm/vis-timeline@7.7.3/styles/vis-timeline-graph2d.min.css" rel="stylesheet" />
|
<link href="https://cdn.jsdelivr.net/npm/vis-timeline@7.7.3/styles/vis-timeline-graph2d.min.css" rel="stylesheet" />
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
@@ -49,8 +51,8 @@
|
|||||||
<ul class="pj-member-list" id="pj-member-list">
|
<ul class="pj-member-list" id="pj-member-list">
|
||||||
{% for m in members %}
|
{% for m in members %}
|
||||||
<li>
|
<li>
|
||||||
<span class="pj-avatar">{{ (m.user_name or m.user_email)[0] | upper }}</span>
|
<span class="material-symbols-outlined pj-gicon">account_circle</span>
|
||||||
<span class="pj-member-name">{{ m.user_name or m.user_email }}</span>
|
<span class="pj-member-name">{{ m.user_email.split('@')[0] }}</span>
|
||||||
{% if m.role == 'manager' %}<span class="pj-chip pj-chip-sm">관리</span>{% endif %}
|
{% if m.role == 'manager' %}<span class="pj-chip pj-chip-sm">관리</span>{% endif %}
|
||||||
{% if is_admin %}
|
{% if is_admin %}
|
||||||
<button type="button" class="pj-icon-btn pj-del-member" data-email="{{ m.user_email }}" title="제외">×</button>
|
<button type="button" class="pj-icon-btn pj-del-member" data-email="{{ m.user_email }}" title="제외">×</button>
|
||||||
@@ -154,8 +156,8 @@
|
|||||||
<select id="pj-t-assignee">
|
<select id="pj-t-assignee">
|
||||||
<option value="">(미지정)</option>
|
<option value="">(미지정)</option>
|
||||||
{% for m in members %}
|
{% for m in members %}
|
||||||
<option value="{{ m.user_email }}" data-name="{{ m.user_name or m.user_email }}">
|
<option value="{{ m.user_email }}" data-name="{{ m.user_email.split('@')[0] }}">
|
||||||
{{ m.user_name or m.user_email }}
|
{{ m.user_email.split('@')[0] }}
|
||||||
</option>
|
</option>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</select>
|
</select>
|
||||||
@@ -200,5 +202,5 @@
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<script src="https://cdn.jsdelivr.net/npm/vis-timeline@7.7.3/standalone/umd/vis-timeline-graph2d.min.js"></script>
|
<script src="https://cdn.jsdelivr.net/npm/vis-timeline@7.7.3/standalone/umd/vis-timeline-graph2d.min.js"></script>
|
||||||
<script src="/static/project.js?v=20260625b" defer></script>
|
<script src="/static/project.js?v=20260625c" defer></script>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|||||||
@@ -67,8 +67,11 @@
|
|||||||
.pj-sub-dot { width: 8px; height: 8px; border-radius: 50%; }
|
.pj-sub-dot { width: 8px; height: 8px; border-radius: 50%; }
|
||||||
.pj-member-name { font-size: 13px; flex: 1; }
|
.pj-member-name { font-size: 13px; flex: 1; }
|
||||||
|
|
||||||
.pj-avatar { display: inline-flex; align-items: center; justify-content: center; width: 24px; height: 24px; border-radius: 50%; background: #d6e0f5; color: #2b4a85; font-size: 11px; font-weight: 700; flex: 0 0 auto; }
|
/* 구글 머티리얼 심볼 아이콘(담당자) */
|
||||||
.pj-avatar-sm { width: 20px; height: 20px; font-size: 10px; }
|
.material-symbols-outlined { font-variation-settings: 'FILL' 0, 'wght' 400, 'GRAD' 0, 'opsz' 24; line-height: 1; vertical-align: middle; }
|
||||||
|
.pj-gicon { font-size: 24px; color: #5f6368; flex: 0 0 auto; }
|
||||||
|
.pj-gicon-sm { font-size: 20px; }
|
||||||
|
.pj-assignee { display: inline-flex; align-items: center; gap: 3px; font-size: 12px; color: #5f6368; }
|
||||||
|
|
||||||
/* ── 툴바 + 탭 ── */
|
/* ── 툴바 + 탭 ── */
|
||||||
.pj-toolbar { display: flex; align-items: center; justify-content: space-between; margin-bottom: 16px; }
|
.pj-toolbar { display: flex; align-items: center; justify-content: space-between; margin-bottom: 16px; }
|
||||||
|
|||||||
@@ -204,7 +204,10 @@
|
|||||||
(t.priority && t.priority !== "normal"
|
(t.priority && t.priority !== "normal"
|
||||||
? '<span class="pj-pri pj-pri-' + t.priority + '">' + (priorityLabels[t.priority] || t.priority) + "</span>"
|
? '<span class="pj-pri pj-pri-' + t.priority + '">' + (priorityLabels[t.priority] || t.priority) + "</span>"
|
||||||
: "") +
|
: "") +
|
||||||
(t.assignee_email ? '<span class="pj-avatar pj-avatar-sm">' + escapeHtml((t.assignee_name || t.assignee_email)[0].toUpperCase()) + "</span>" : "") +
|
(t.assignee_email
|
||||||
|
? '<span class="pj-assignee"><span class="material-symbols-outlined pj-gicon pj-gicon-sm">account_circle</span>' +
|
||||||
|
escapeHtml(idOf(t.assignee_email)) + "</span>"
|
||||||
|
: "") +
|
||||||
(t.due_date ? '<span class="pj-card-due">' + t.due_date + "</span>" : "") +
|
(t.due_date ? '<span class="pj-card-due">' + t.due_date + "</span>" : "") +
|
||||||
"</div>";
|
"</div>";
|
||||||
card.addEventListener("click", function () { if (canManage) openTaskModal(t); });
|
card.addEventListener("click", function () { if (canManage) openTaskModal(t); });
|
||||||
@@ -244,7 +247,7 @@
|
|||||||
if (t.completed_at) tr.className = "is-done";
|
if (t.completed_at) tr.className = "is-done";
|
||||||
tr.innerHTML =
|
tr.innerHTML =
|
||||||
"<td>" + escapeHtml(t.title) + "</td>" +
|
"<td>" + escapeHtml(t.title) + "</td>" +
|
||||||
"<td>" + escapeHtml(t.assignee_name || t.assignee_email || "-") + "</td>" +
|
"<td>" + (t.assignee_email ? escapeHtml(idOf(t.assignee_email)) : "-") + "</td>" +
|
||||||
"<td>" + escapeHtml(t.stage_name || "-") + "</td>" +
|
"<td>" + escapeHtml(t.stage_name || "-") + "</td>" +
|
||||||
"<td>" + (priorityLabels[t.priority] || t.priority || "-") + "</td>" +
|
"<td>" + (priorityLabels[t.priority] || t.priority || "-") + "</td>" +
|
||||||
"<td>" + (t.start_date || "-") + "</td>" +
|
"<td>" + (t.start_date || "-") + "</td>" +
|
||||||
@@ -367,6 +370,10 @@
|
|||||||
wireCalendar();
|
wireCalendar();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function idOf(email) {
|
||||||
|
return String(email == null ? "" : email).split("@")[0];
|
||||||
|
}
|
||||||
|
|
||||||
function escapeHtml(s) {
|
function escapeHtml(s) {
|
||||||
return String(s == null ? "" : s)
|
return String(s == null ? "" : s)
|
||||||
.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">")
|
.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">")
|
||||||
|
|||||||
Reference in New Issue
Block a user