feat(project): 홈 카드도 완료 체크 시 반투명 + 대시보드 끝으로(세션과 동일 원칙)
기존엔 완료 프로젝트가 "완료된 프로젝트" 별도 섹션(숨기기 토글 포함)으로 빠졌는데, 요청에 따라 세션 완료 처리와 같은 방식으로 바꿈 — 같은 그리드 안에서 완료 여부 → sort_order → id 순으로 안정 정렬해 완료면 맨 끝으로, 해제하면 sort_order 기준 원래 자리로 자동 복귀(resortProjectGrid, 서버 쪽도 index() 에서 같은 기준으로 미리 정렬해 내려줌: _group 아님, 별도 정렬 한 줄 sorted(tree, key=...)). 완료 섹션/숨기기 토글 관련 죽은 코드(JS·CSS·템플릿) 정리. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
@@ -389,9 +389,11 @@ async def index(request: Request) -> HTMLResponse:
|
||||
member_email=None if admin else user["email"],
|
||||
)
|
||||
tree = _build_tree(projects)
|
||||
# 진행중/완료 프로젝트를 구분해 별도 섹션으로 표시.
|
||||
active_projects = [p for p in tree if p.get("status") != "completed"]
|
||||
done_projects = [p for p in tree if p.get("status") == "completed"]
|
||||
# 완료 프로젝트는 별도 섹션 대신, 같은 대시보드 안에서 반투명 + 맨
|
||||
# 끝으로만 보낸다(세션 완료 처리와 같은 원칙). sorted() 는 안정 정렬이라
|
||||
# tree 가 이미 sort_order 순이면 완료 여부로만 다시 나눠도 각 그룹
|
||||
# 내부 순서는 그대로 유지된다 — 완료 해제 시 원래 자리로 자동 복귀.
|
||||
home_projects = sorted(tree, key=lambda p: p.get("status") == "completed")
|
||||
|
||||
# 아바타 맵: 이메일(소문자) → 구글 프로필 이미지 URL (홈 카드 업무 담당자 표시용)
|
||||
from app.main import user_store # noqa: WPS433
|
||||
@@ -473,8 +475,7 @@ async def index(request: Request) -> HTMLResponse:
|
||||
"page_title": "프로젝트 관리",
|
||||
"page_subtitle": "달력·타임라인·보드로 프로젝트를 관리하세요.",
|
||||
"force_sidebar_collapsed": True,
|
||||
"active_projects": active_projects,
|
||||
"done_projects": done_projects,
|
||||
"home_projects": home_projects,
|
||||
"my_projects": my_projects,
|
||||
"avatars": avatars,
|
||||
"home_tasks": home_tasks,
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{% extends "erp_base.html" %}
|
||||
|
||||
{% block head_extra %}
|
||||
<link rel="stylesheet" href="/static/project.css?v=20260917v" />
|
||||
<link rel="stylesheet" href="/static/project.css?v=20260917w" />
|
||||
<link rel="stylesheet" href="/static/vendor/material-symbols/material-symbols.css" />
|
||||
{% endblock %}
|
||||
|
||||
@@ -45,5 +45,5 @@
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
<script src="/static/project.js?v=20260917y" defer></script>
|
||||
<script src="/static/project.js?v=20260917z" defer></script>
|
||||
{% endblock %}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{% extends "erp_base.html" %}
|
||||
|
||||
{% block head_extra %}
|
||||
<link rel="stylesheet" href="/static/project.css?v=20260917v" />
|
||||
<link rel="stylesheet" href="/static/project.css?v=20260917w" />
|
||||
<link rel="stylesheet" href="/static/vendor/material-symbols/material-symbols.css" />
|
||||
{% endblock %}
|
||||
|
||||
@@ -21,7 +21,8 @@
|
||||
data-color="{{ p.color }}"
|
||||
data-status="{{ p.status or 'active' }}"
|
||||
data-creator="{{ p.created_by or '' }}"
|
||||
data-has-stages="{{ 'true' if p.has_stages else 'false' }}">
|
||||
data-has-stages="{{ 'true' if p.has_stages else 'false' }}"
|
||||
data-sort-order="{{ p.sort_order or 0 }}">
|
||||
<a class="pj-project-cardlink" href="/project/p/{{ p.id }}">
|
||||
<div class="pj-project-header">
|
||||
<span class="pj-project-name">{{ p.name }}
|
||||
@@ -124,29 +125,19 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% if not active_projects and not done_projects %}
|
||||
{% if not home_projects %}
|
||||
<div class="pj-empty">
|
||||
아직 프로젝트가 없습니다. 상단의 <b>새 프로젝트</b> 버튼으로 만들어 보세요.
|
||||
</div>
|
||||
{% elif not active_projects %}
|
||||
<div class="pj-empty pj-empty-sm">진행중인 프로젝트가 없습니다.</div>
|
||||
{% endif %}
|
||||
|
||||
<!-- 완료 프로젝트는 별도 섹션이 아니라 같은 그리드 안에서 반투명 +
|
||||
맨 끝으로만(세션 완료 처리와 같은 원칙). 서버가 이미 정렬해서
|
||||
내려주고(완료 여부로만 안정 정렬), 완료 토글 시 JS가 같은
|
||||
기준으로 카드를 다시 배치한다(resortProjectGrid). -->
|
||||
<div class="pj-project-grid" id="pj-project-grid">
|
||||
{% for p in active_projects %}{{ project_card(p) }}{% endfor %}
|
||||
{% for p in home_projects %}{{ project_card(p) }}{% endfor %}
|
||||
</div>
|
||||
|
||||
{% if done_projects %}
|
||||
<div class="pj-section-head pj-section-head-done">
|
||||
<h2>완료된 프로젝트</h2>
|
||||
<button type="button" class="pj-btn" id="pj-toggle-done" data-count="{{ done_projects | length }}">
|
||||
완료 {{ done_projects | length }}개 숨기기
|
||||
</button>
|
||||
</div>
|
||||
<div class="pj-project-grid" id="pj-project-grid-done">
|
||||
{% for p in done_projects %}{{ project_card(p) }}{% endfor %}
|
||||
</div>
|
||||
{% endif %}
|
||||
</section>
|
||||
|
||||
<!-- 내 업무 -->
|
||||
@@ -429,5 +420,5 @@
|
||||
window.PJ_COLORS = {{ ["#4573d2","#37a3a3","#62a420","#e8a33d","#e8384f","#aa62e3","#f06a6a","#5a6772"] | tojson }};
|
||||
window.PJ_STAGE_COLORS = {{ ["#4573d2","#37a3a3","#62a420","#e8a33d","#e8384f","#aa62e3","#f06a6a","#5a6772","#e8398a","#a15c43"] | tojson }};
|
||||
</script>
|
||||
<script src="/static/project.js?v=20260917y" defer></script>
|
||||
<script src="/static/project.js?v=20260917z" defer></script>
|
||||
{% endblock %}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{% extends "erp_base.html" %}
|
||||
|
||||
{% block head_extra %}
|
||||
<link rel="stylesheet" href="/static/project.css?v=20260917v" />
|
||||
<link rel="stylesheet" href="/static/project.css?v=20260917w" />
|
||||
<!-- 구글 머티리얼 심볼(담당자 아이콘 등) — self-host -->
|
||||
<link rel="stylesheet" href="/static/vendor/material-symbols/material-symbols.css" />
|
||||
<!-- 타임라인 vis-timeline — self-host -->
|
||||
@@ -543,5 +543,5 @@
|
||||
</script>
|
||||
|
||||
<script src="/static/vendor/vis-timeline/vis-timeline-graph2d.min.js"></script>
|
||||
<script src="/static/project.js?v=20260917y" defer></script>
|
||||
<script src="/static/project.js?v=20260917z" defer></script>
|
||||
{% endblock %}
|
||||
|
||||
Reference in New Issue
Block a user