"""HTML views for lease and collision visibility (#433)."""
from __future__ import annotations
import html
import json
from webui.layout import render_page
from webui.lease_loader import LeaseSnapshot
def _escape(text: str) -> str:
return html.escape(text, quote=True)
def _warnings_block(snapshot: LeaseSnapshot) -> str:
warnings = list(snapshot.duplicate_prs) + list(snapshot.duplicate_branches)
if not warnings:
return "
No duplicate PR/branch collisions detected in current inventory.
"
items = "".join(f"{_escape(w.message)}" for w in warnings)
return f""
def _lock_block(snapshot: LeaseSnapshot) -> str:
lock = snapshot.issue_lock
if not lock:
return "No active local issue lock file.
"
return (
""
f"{_escape(json.dumps(lock, indent=2, sort_keys=True))}"
""
)
def _claims_table(snapshot: LeaseSnapshot) -> str:
entries = snapshot.claim_inventory.get("entries") or []
if not entries:
return "No in-progress issue claims in fetched inventory.
"
rows = []
for entry in entries:
rows.append(
""
f"| #{entry.get('issue_number')} | "
f""
f"{_escape(str(entry.get('status')))} | "
f"{_escape(str(entry.get('linked_open_pr') or '—'))} | "
f"{entry.get('heartbeat_count', 0)} | "
f"{_escape(', '.join(entry.get('matching_branches') or []) or '—')} | "
f"{_escape('; '.join(entry.get('reasons') or []))} | "
"
"
)
return (
""
"| Issue | Claim status | Open PR | "
"Heartbeats | Branches | Notes |
"
f"{''.join(rows)}
"
)
def _reviewer_leases_table(snapshot: LeaseSnapshot) -> str:
if not snapshot.reviewer_leases:
return (
"No active reviewer PR lease comments found "
"(marker <!-- mcp-review-lease:v1 -->; see #407).
"
)
rows = []
for lease in snapshot.reviewer_leases:
rows.append(
""
f"| #{lease.get('pr_number')} | "
f"{_escape(str(lease.get('reviewer_identity') or '—'))} | "
f"{_escape(str(lease.get('profile') or '—'))} | "
f"{_escape(str(lease.get('phase') or '—'))} | "
f"{_escape(str(lease.get('expires_at') or '—'))} | "
"
"
)
return (
""
"| PR | Reviewer | Profile | "
"Phase | Expires |
"
f"{''.join(rows)}
"
)
def _history_links(snapshot: LeaseSnapshot) -> str:
items = "".join(
f"#{item['number']} — {_escape(item['title'])}"
for item in snapshot.collision_history
)
return f""
LEASE_PAGE_STYLES = """
"""
def render_leases_page(snapshot: LeaseSnapshot) -> str:
error_block = ""
if snapshot.fetch_error:
error_block = (
'Partial load: '
f"{_escape(snapshot.fetch_error)}
"
)
body = (
"Leases & collisions
"
"Read-only visibility for issue claims, reviewer PR leases, and "
"duplicate-work risks. Does not acquire or release leases.
"
f"{error_block}"
f"Project: {_escape(snapshot.repo_label)}
"
"Collision warnings
"
f"{_warnings_block(snapshot)}"
"Local issue lock
"
f"{_lock_block(snapshot)}"
"In-progress issue claims (#268)
"
f"{_claims_table(snapshot)}"
"Reviewer PR leases (#407)
"
f"{_reviewer_leases_table(snapshot)}"
"Collision / lease history issues
"
f"{_history_links(snapshot)}"
"JSON API
"
f"{LEASE_PAGE_STYLES}"
)
return render_page(title="Leases", body_html=body)