From ef05f9d362d10f2b59c5d29f8432f85800a40347 Mon Sep 17 00:00:00 2001 From: king Date: Tue, 15 Sep 2026 09:02:31 +0900 Subject: [PATCH] =?UTF-8?q?fix(project):=20=EC=99=84=EB=A3=8C=20=ED=94=84?= =?UTF-8?q?=EB=A1=9C=EC=A0=9D=ED=8A=B8=20=EC=88=A8=EA=B8=B0=EA=B8=B0=20?= =?UTF-8?q?=EB=B2=84=ED=8A=BC=20=EB=8F=99=EC=9E=91=20=EC=95=88=20=ED=95=98?= =?UTF-8?q?=EB=8D=98=20CSS=20=ED=8A=B9=EC=9D=B4=EB=8F=84=20=EB=AC=B8?= =?UTF-8?q?=EC=A0=9C=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - .pj-project-grid[hidden] 규칙 추가 — display:grid 규칙과 특이도가 같아 [hidden] 속성이 무시되던 버그 - 홈 카드 업무 미리보기에 단계(stage_name) 칩 표시 - 홈 화면 날짜 표기를 yy/mm/dd(요일) 형식으로 통일(프로젝트 마감·업무 마감·내 업무 기간) Co-Authored-By: Claude Sonnet 5 --- app/modules/project/router.py | 19 +++++++++++++++++++ .../project/templates/project/inbox.html | 2 +- .../project/templates/project/index.html | 13 +++++++------ .../project/templates/project/project.html | 2 +- app/static/project.css | 6 ++++++ 5 files changed, 34 insertions(+), 8 deletions(-) diff --git a/app/modules/project/router.py b/app/modules/project/router.py index 6b85579..bb88aef 100644 --- a/app/modules/project/router.py +++ b/app/modules/project/router.py @@ -191,6 +191,20 @@ def _render_config_needed(request: Request, user: dict[str, Any]) -> HTMLRespons ) +_WEEKDAYS_KR = ["월", "화", "수", "목", "금", "토", "일"] + + +def _fmt_date_kr(d: str | None) -> str: + """'YYYY-MM-DD' → 'yy/mm/dd(요일)'. 형식이 아니면 원본 그대로.""" + if not d: + return "" + try: + dd = date.fromisoformat(d[:10]) + except (ValueError, TypeError): + return d + return dd.strftime("%y/%m/%d") + f"({_WEEKDAYS_KR[dd.weekday()]})" + + def _build_tree(projects: list[dict[str, Any]]) -> list[dict[str, Any]]: """평면 프로젝트 목록 → parent_id 기준 트리(children 키).""" by_id: dict[int, dict[str, Any]] = {} @@ -367,13 +381,18 @@ async def index(request: Request) -> HTMLResponse: ) d = t.get("due_date") t["due_overdue"] = bool(d and d[:10] < today_iso and not t.get("completed_at")) + t["due_label"] = _fmt_date_kr(d) p["task_total"] = total p["task_done"] = len(done_tasks) p["task_percent"] = round(len(done_tasks) * 100 / total) if total else 0 p["task_preview"] = ordered_tasks[:8] p["task_more"] = max(0, len(ordered_tasks) - 8) + p["due_label"] = _fmt_date_kr(p.get("due_date")) my_tasks = st.list_tasks(assignee_email=user["email"], limit=500) + for t in my_tasks: + t["start_label"] = _fmt_date_kr(t.get("start_date")) + t["due_label"] = _fmt_date_kr(t.get("due_date")) # 내 업무를 프로젝트별로 묶어 트리로 표시 my_groups: dict[int, dict[str, Any]] = {} for t in my_tasks: diff --git a/app/modules/project/templates/project/inbox.html b/app/modules/project/templates/project/inbox.html index 86d84b8..a9cb03e 100644 --- a/app/modules/project/templates/project/inbox.html +++ b/app/modules/project/templates/project/inbox.html @@ -1,7 +1,7 @@ {% extends "erp_base.html" %} {% block head_extra %} - + {% endblock %} diff --git a/app/modules/project/templates/project/index.html b/app/modules/project/templates/project/index.html index f557814..1c7f947 100644 --- a/app/modules/project/templates/project/index.html +++ b/app/modules/project/templates/project/index.html @@ -1,7 +1,7 @@ {% extends "erp_base.html" %} {% block head_extra %} - + {% endblock %} @@ -29,7 +29,7 @@ {% if p.description %}
{{ p.description }}
{% endif %}
- {% if p.due_date %}마감 {{ p.due_date }}{% endif %} + {% if p.due_date %}마감 {{ p.due_label }}{% endif %} {% if p.task_total %}업무 {{ p.task_done }}/{{ p.task_total }}{% endif %}
{% if p.task_total %} @@ -52,6 +52,7 @@ {% if t.completed_at %}task_alt{% else %}radio_button_unchecked{% endif %} {{ t.title }} + {% if t.stage_name %}{{ t.stage_name }}{% endif %} {% if t.assignee_display %} {% if avatars.get(t.assignee_email | lower) %} @@ -61,7 +62,7 @@ {% endif %} {% if t.due_date %} - {{ t.due_date[:10] }} + {{ t.due_label }} {% endif %} @@ -143,9 +144,9 @@ {{ t.title }} {% if t.start_date or t.due_date %} - {% if t.start_date and t.due_date %}{{ t.start_date }} ~ {{ t.due_date }} - {% elif t.due_date %}~ {{ t.due_date }} - {% else %}{{ t.start_date }} ~{% endif %} + {% if t.start_date and t.due_date %}{{ t.start_label }} ~ {{ t.due_label }} + {% elif t.due_date %}~ {{ t.due_label }} + {% else %}{{ t.start_label }} ~{% endif %} {% endif %} diff --git a/app/modules/project/templates/project/project.html b/app/modules/project/templates/project/project.html index cea81e5..bf26ec3 100644 --- a/app/modules/project/templates/project/project.html +++ b/app/modules/project/templates/project/project.html @@ -1,7 +1,7 @@ {% extends "erp_base.html" %} {% block head_extra %} - + diff --git a/app/static/project.css b/app/static/project.css index 5cecdb8..42b0d3a 100644 --- a/app/static/project.css +++ b/app/static/project.css @@ -34,6 +34,7 @@ @media (max-width: 980px) { .pj-home { grid-template-columns: 1fr; } } .pj-project-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(320px, 1fr)); gap: 14px; align-items: start; } +.pj-project-grid[hidden] { display: none; } .pj-project-card { position: relative; border: 1px solid #e7e9ec; border-radius: 14px; background: #fff; transition: box-shadow .14s, transform .1s; @@ -72,6 +73,11 @@ font-size: 12.5px; font-weight: 600; flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } +.pj-project-task-stage { + flex: 0 0 auto; font-size: 10px; font-weight: 700; color: #6b7280; + background: #eef0f2; border-radius: 999px; padding: 1px 7px; + max-width: 70px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; +} .pj-project-task-assignee { display: inline-flex; align-items: center; gap: 4px; font-size: 11px; color: #6b7280; flex: 0 0 auto; max-width: 90px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;