diff --git a/app/main.py b/app/main.py index fead3e8..82e2c70 100644 --- a/app/main.py +++ b/app/main.py @@ -832,13 +832,25 @@ async def board(request: Request, owner: str, repo: str, milestone: str = ""): # A kanban:* label changed outside Kanbante wins over local state. _adopt_label_columns(full_name, open_issues, get_board_state(full_name)) + # Closed issues stay visible while the board tracks them as done + # (reconcile_board_state moved their row). Merging open issues only + # made the "Terminé" column permanently empty. + done_numbers = { + c["issue_number"] for c in get_board_state(full_name).get("done", []) + } + closed_display = [ + i + for i in issues + if i.get("state") != "open" and i["number"] in done_numbers + ] + # Milestone view: filter the board to one milestone (sprint-style), # with its deadline and completion progress. milestones: list[dict] = [] selected_milestone = None milestone_progress = None milestone_forecast = None - display_issues = open_issues + display_issues = open_issues + closed_display try: milestones = await gitea.get_milestones(owner, repo) except Exception as exc: # milestones are decoration, never fatal @@ -851,7 +863,7 @@ async def board(request: Request, owner: str, repo: str, milestone: str = ""): str(ms.get("id")) == milestone or ms.get("title") == milestone ) - display_issues = [i for i in open_issues if _in_milestone(i)] + display_issues = [i for i in display_issues if _in_milestone(i)] selected_milestone = next( ( m for m in milestones @@ -941,7 +953,16 @@ def _board_columns_for( for number in changes["closed_numbers"]: log_event(full_name, number, "closed", to_column="done", source="gitea") _adopt_label_columns(full_name, open_issues, get_board_state(full_name)) - display_issues = open_issues + board_state = get_board_state(full_name) + # Closed issues stay visible while the board tracks them as done + # (reconcile_board_state moved their row). Merging open issues only + # made the "Terminé" column permanently empty. + done_numbers = {c["issue_number"] for c in board_state.get("done", [])} + display_issues = open_issues + [ + i + for i in issues + if i.get("state") != "open" and i["number"] in done_numbers + ] if milestone: def _in_ms(issue: dict) -> bool: ms = issue.get("milestone") or {} @@ -949,8 +970,7 @@ def _board_columns_for( str(ms.get("id")) == milestone or ms.get("title") == milestone ) - display_issues = [i for i in open_issues if _in_ms(i)] - board_state = get_board_state(full_name) + display_issues = [i for i in display_issues if _in_ms(i)] columns = _merge_issues_with_board(display_issues, board_state) return columns, display_issues, board_state