feat: v0.5.0→v0.8.0 — multi-vues, filtres, tri, modale, checklists
CI / test (push) Failing after 4s
CI / lint (push) Failing after 3s

v0.5.0 (Kanban complet):
- Card detail modal avec checklists + commentaires Gitea
- Création d'issues inline (formulaire + POST /api/issues)
- Édition inline (contenteditable)

v0.6.0 (Table view):
- table_view.html: colonnes Name/Status/Assign/Deadline/Team/Keywords
- Tri par colonne (clic en-tête, asc/desc)
- Groupes rétractables (Design/Engineering)

v0.7.0 (Filtres & Tri):
- Filtres cumulables AND (backend _apply_filters + UI pastilles)
- Status dropdown avec checkboxes + dots colorés
- Sort panel multi-critères (+ Add sort / Delete sort)
- Backend _apply_sorts avec asc/desc

v0.8.0 (Vues spéciales):
- status_overview.html: SVG donut chart + légende + pourcentages
- team_load.html: barres empilées par avatar
- detailed_board.html: cartes avec toutes propriétés

Backend:
- /board/{o}/{r}/view/{view} — 5 fragments HTMX
- /api/issues/{o}/{r}/{id}?format=html — modal HTML
- _map_issue_to_card, STATUS_COLORS/LABELS exportés
This commit is contained in:
2026-07-08 14:29:33 -04:00
parent ff555c6fd4
commit 751f13869a
10 changed files with 871 additions and 364 deletions
+31 -3
View File
@@ -7,10 +7,11 @@ from datetime import datetime
from typing import Optional
from fastapi import APIRouter, HTTPException, Query, Request
from fastapi.responses import HTMLResponse
from app.config import settings
from app.db import get_conn
from app.routers.board import _issue_column
from app.routers.board import _issue_column, _map_issue_to_card, STATUS_COLORS, STATUS_LABELS
from app.services.gitea_client import gitea
logger = logging.getLogger(__name__)
@@ -379,8 +380,9 @@ async def update_issue_api(
# ── v0.5.0: Card detail ──
@router.get("/issues/{owner}/{repo}/{issue_id}")
async def get_issue_detail(owner: str, repo: str, issue_id: int):
"""Get full issue details + comments."""
@router.get("/issues/{owner}/{repo}/{issue_id}/html")
async def get_issue_detail(owner: str, repo: str, issue_id: int, format: str = Query(default="json")):
"""Get full issue details + comments. Set format=html for HTML response."""
try:
issue = await gitea.get_issue(owner, repo, issue_id)
comments = await gitea.get_issue_comments(owner, repo, issue_id)
@@ -417,6 +419,32 @@ async def get_issue_detail(owner: str, repo: str, issue_id: int):
(board_id, issue_id),
).fetchone() if board_id else None
# HTML format for modal
if format == "html":
card_data = _map_issue_to_card(issue)
ctx = {
"issue": {
"id": issue_id,
"title": issue.get("title", ""),
"body": issue.get("body", ""),
"icon": card_data.get("icon", "📄"),
"author": issue.get("user", {}).get("login", "unknown") if issue.get("user") else "unknown",
"created": issue.get("created_at", "")[:10] if issue.get("created_at") else "",
"assignee": (issue.get("assignee") or {}).get("login", ""),
"due_date": issue.get("due_date", "") or "",
"status": card_data.get("status", "todo"),
"status_color": STATUS_COLORS.get(card_data.get("status", ""), "var(--gray)"),
"status_label": STATUS_LABELS.get(card_data.get("status", ""), "To-do"),
"labels": issue.get("labels", []),
},
"comments": comments,
"checklists": checklists,
}
from jinja2 import Environment, FileSystemLoader
env = Environment(loader=FileSystemLoader("app/templates"))
template = env.get_template("card_detail.html")
return HTMLResponse(template.render(**ctx))
return {
"issue": issue,
"comments": comments,