feat(project): 카드 드래그 순서변경/전체멤버/탭 슬라이드/내업무 실시간반영
- 홈 프로젝트 카드 드래그 재정렬(관리자, projects.sort_order 공유) - 프로젝트 제목 색상 pill 스타일로 강조 - 보드 세션 우클릭에 "업무 추가" 메뉴 추가 - 좌측 "멤버"→"프로젝트 멤버" + "전체 멤버" 그리드(클릭 시 담당 업무 팝업) - 뷰 탭/스코프 토글에 슬라이드 하이라이트 애니메이션 - "내 업무" 패널이 8초 실시간 폴링에서 빠져 있던 문제 수정(홈/프로젝트 화면 모두 /api/my-tasks 로 patch) Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
@@ -732,6 +732,22 @@ async def api_delete_project(request: Request, project_id: int) -> JSONResponse:
|
||||
return JSONResponse({"ok": True})
|
||||
|
||||
|
||||
@router.put("/api/projects/order")
|
||||
async def api_reorder_projects(
|
||||
request: Request, payload: dict[str, Any] = Body(...)
|
||||
) -> JSONResponse:
|
||||
"""홈 화면 프로젝트 카드 드래그 순서 변경. 최상위 프로젝트만 대상이며,
|
||||
순서는 이 화면을 보는 모든 사용자에게 공유되므로(세션 재정렬과 동일 원칙)
|
||||
관리자 전용으로 제한한다."""
|
||||
_require_admin(request)
|
||||
st = _db_or_503(request)
|
||||
ids = payload.get("ordered_ids") or []
|
||||
if not isinstance(ids, list) or not ids:
|
||||
raise HTTPException(status_code=400, detail="ordered_ids 가 필요합니다.")
|
||||
st.reorder_projects(ordered_ids=[int(i) for i in ids])
|
||||
return JSONResponse({"ok": True})
|
||||
|
||||
|
||||
# ────────────────────────────────────────────────────────────
|
||||
# JSON API — 멤버 (관리자가 사용자 배정)
|
||||
# ────────────────────────────────────────────────────────────
|
||||
@@ -759,6 +775,38 @@ async def api_assignable_users(request: Request) -> JSONResponse:
|
||||
return JSONResponse({"users": out})
|
||||
|
||||
|
||||
@router.get("/api/all-users")
|
||||
async def api_all_users(request: Request) -> JSONResponse:
|
||||
"""프로젝트 화면 좌측 "전체 멤버" 표시용 — project 모듈 권한 보유 등록
|
||||
사용자 전원. assignable-users 와 후보군은 같지만, 이건 멤버 배정(쓰기)이
|
||||
아니라 단순 열람용이라 관리자가 아니어도 볼 수 있다."""
|
||||
_require_user(request)
|
||||
from app.main import user_store # noqa: WPS433
|
||||
from app.store import has_module # noqa: WPS433
|
||||
|
||||
out = [
|
||||
{
|
||||
"email": u["email"],
|
||||
"name": u.get("name") or u["email"].split("@")[0],
|
||||
"id": u["email"].split("@")[0],
|
||||
"avatar": u.get("picture") or "",
|
||||
}
|
||||
for u in user_store.list_all()
|
||||
if has_module(u, "project")
|
||||
]
|
||||
out.sort(key=lambda x: x["id"])
|
||||
return JSONResponse({"users": out})
|
||||
|
||||
|
||||
@router.get("/api/users/tasks")
|
||||
async def api_user_tasks(request: Request, email: str) -> JSONResponse:
|
||||
"""'전체 멤버' 아이콘 클릭 팝업 — 지정한 사용자가 담당자인 업무 목록
|
||||
(프로젝트/세션/마감일). /api/my-tasks 와 같은 조회를 이메일만 바꿔 재사용."""
|
||||
_require_user(request)
|
||||
st = _db_or_503(request)
|
||||
return JSONResponse({"tasks": st.list_tasks(assignee_email=email, limit=500)})
|
||||
|
||||
|
||||
@router.get("/api/projects/{project_id}/members")
|
||||
async def api_list_members(request: Request, project_id: int) -> JSONResponse:
|
||||
_require_user(request)
|
||||
|
||||
Reference in New Issue
Block a user