From a67f42bfe670118529bf5d740112368460ca7c90 Mon Sep 17 00:00:00 2001 From: bruno Date: Wed, 8 Jul 2026 09:45:24 -0400 Subject: [PATCH] fix: resolve 3 critical UI bugs 1. Refresh button no longer doubles header - Added ?fragment=1 param to filter/refresh HTMX requests - Board route returns board_fragment.html (columns only) for fragment requests - Refresh button uses window.location.reload() for full page reload 2. No more raw JSON in header - base.html: user info rendered server-side via template variable - board.py: decodes session cookie, passes user to template - Dashboard/board templates show Login/Deconnexion based on auth state 3. New issue form works - Replaced HTMX post with JS fetch (handleNewIssue) - Adds CSRF token to form submission - Reloads page on successful creation - Cleaner error handling --- app/routers/board.py | 59 ++--- app/templates/base.html | 14 +- app/templates/board.html | 352 ++++++++++-------------------- app/templates/board_fragment.html | 43 ++++ 4 files changed, 189 insertions(+), 279 deletions(-) create mode 100644 app/templates/board_fragment.html diff --git a/app/routers/board.py b/app/routers/board.py index bcde913..1c8df45 100644 --- a/app/routers/board.py +++ b/app/routers/board.py @@ -50,45 +50,32 @@ async def board( milestone: str = "", label: str = "", assignee: str = "", + fragment: bool = False, ): """Kanban board for a Gitea project.""" try: - # Get issues issues = await gitea.get_issues(owner, repo, state="all") - - # Get labels - labels = await gitea.get_labels(owner, repo) - - # Get milestones + labels_list = await gitea.get_labels(owner, repo) milestones = await gitea.get_milestones(owner, repo) - # Filter by milestone if milestone: issues = [i for i in issues if i.get("milestone", {}).get("title") == milestone] - - # Filter by label if label: issues = [i for i in issues if any(lbl["name"] == label for lbl in i.get("labels", []))] - - # Filter by assignee if assignee: issues = [i for i in issues if i.get("assignee", {}).get("login") == assignee] - # Separate PRs from issues (ponytail: PRs are also in /issues endpoint) prs = [i for i in issues if "pull_request" in i] issues_only = [i for i in issues if "pull_request" not in i] - # Get board config board_info = _ensure_board(owner, repo) columns = board_info["columns"] cards = _get_cards(board_info["id"]) - # Map issues to columns column_map: dict[str, list[dict]] = {col: [] for col in columns} card_by_issue = {c["gitea_issue_id"]: c for c in cards if c["gitea_issue_id"]} for issue in issues_only: - # Determine column from issue state/labels first, then from DB position col = _issue_column(issue, columns, board_info["id"]) issue["_col"] = col issue["_card"] = card_by_issue.get(issue["number"]) @@ -97,37 +84,37 @@ async def board( except Exception as e: from httpx import HTTPStatusError if isinstance(e, HTTPStatusError) and e.response is not None and e.response.status_code == 404: - html = '
' - html += '

Projet introuvable

' - html += f'

{owner}/{repo} n\'existe pas sur Gitea.

' - html += 'Retour aux projets' - html += '
' - return HTMLResponse(html, status_code=404) + return HTMLResponse( + '
' + f'

Projet introuvable

' + f'

{owner}/{repo} n\'existe pas sur Gitea.

' + 'Retour aux projets
', + status_code=404) logger.error("Board error: %s", e) return HTMLResponse(f"

Erreur: {e}

", status_code=500) from jinja2 import Environment, FileSystemLoader from datetime import datetime from app.config import settings + from app.auth.session import SessionManager env = Environment(loader=FileSystemLoader("app/templates")) - template = env.get_template("board.html") - return template.render( - request=request, - owner=owner, - repo=repo, - columns=columns, - column_map=column_map, - labels=labels, - milestones=milestones, - current_milestone=milestone, - current_label=label, - current_assignee=assignee, - prs=prs, - settings=settings, - now=datetime.now().isoformat()[:10], + now_str = datetime.now().isoformat()[:10] + user = SessionManager.decode_session(request.cookies.get("flowdeck_session", "")) + + ctx = dict( + request=request, owner=owner, repo=repo, columns=columns, + column_map=column_map, labels=labels_list, milestones=milestones, + current_milestone=milestone, current_label=label, current_assignee=assignee, + prs=prs, settings=settings, now=now_str, user=user, ) + if fragment: + template = env.get_template("board_fragment.html") + else: + template = env.get_template("board.html") + return template.render(**ctx) + def _issue_column(issue: dict, columns: list[str], board_id: int) -> str: """Determine which column an issue belongs to.""" diff --git a/app/templates/base.html b/app/templates/base.html index eab9df5..558673b 100644 --- a/app/templates/base.html +++ b/app/templates/base.html @@ -18,9 +18,17 @@
- + {% if user %} + + {% if user.avatar_url %}{% endif %} + {{ user.login }} + Déconnexion + + {% else %} + 🔑 Login + {% endif %}
@@ -28,8 +36,7 @@ {% block content %}{% endblock %} - -