generated from coulomb/repo-seed
Layout optimization initial page
This commit is contained in:
@@ -3,7 +3,7 @@ from __future__ import annotations
|
||||
from dataclasses import asdict
|
||||
from html import escape
|
||||
from pathlib import Path
|
||||
from urllib.parse import quote_plus
|
||||
from urllib.parse import quote_plus, urlparse
|
||||
|
||||
from fastapi import APIRouter, Depends, Form, HTTPException, Query
|
||||
from fastapi.responses import HTMLResponse, PlainTextResponse, RedirectResponse
|
||||
@@ -17,6 +17,25 @@ router = APIRouter(include_in_schema=False)
|
||||
APP_NAME = "Repository Scoping"
|
||||
|
||||
|
||||
def repository_directory_name(url: str, fallback: str) -> str:
|
||||
parsed = urlparse(url)
|
||||
path = parsed.path if parsed.scheme or parsed.netloc else url
|
||||
normalized = path.replace("\\", "/").rstrip("/")
|
||||
name = normalized.rsplit("/", 1)[-1] if normalized else ""
|
||||
if name.endswith(".git"):
|
||||
name = name[:-4]
|
||||
return name or fallback
|
||||
|
||||
|
||||
def repository_display_name(repository) -> str:
|
||||
return repository_directory_name(repository.url, repository.name)
|
||||
|
||||
|
||||
def repository_dict_display_name(repository: dict) -> str:
|
||||
fallback = str(repository.get("name") or repository.get("repository_name") or "")
|
||||
return repository_directory_name(str(repository.get("url") or ""), fallback)
|
||||
|
||||
|
||||
def page(
|
||||
title: str,
|
||||
body: str,
|
||||
@@ -238,7 +257,7 @@ def render_repository_index(
|
||||
rows = "\n".join(
|
||||
f"""
|
||||
<tr>
|
||||
<td><a href="/ui/repos/{repo.id}">{escape(repo.name)}</a></td>
|
||||
<td><a href="/ui/repos/{repo.id}">{escape(repository_display_name(repo))}</a></td>
|
||||
<td><span class="pill">{escape(repo.status)}</span></td>
|
||||
<td class="source">{escape(repo.branch)}</td>
|
||||
<td class="source">{escape(repo.url)}</td>
|
||||
@@ -260,6 +279,15 @@ def render_repository_index(
|
||||
<h1>Repositories</h1>
|
||||
{error}
|
||||
<div class="grid">
|
||||
<section class="panel">
|
||||
<div class="actions">
|
||||
<h2 style="margin-right:auto">Registry</h2>
|
||||
</div>
|
||||
<table>
|
||||
<thead><tr><th>Name</th><th>Status</th><th>Branch</th><th>Source</th></tr></thead>
|
||||
<tbody>{rows or '<tr><td colspan="4" class="muted">No repositories yet.</td></tr>'}</tbody>
|
||||
</table>
|
||||
</section>
|
||||
<section class="panel">
|
||||
<h2>Register Repository</h2>
|
||||
<form class="stack" method="post" action="/ui/repos">
|
||||
@@ -276,16 +304,6 @@ def render_repository_index(
|
||||
</div>
|
||||
</form>
|
||||
</section>
|
||||
<section class="panel">
|
||||
<div class="actions">
|
||||
<h2 style="margin-right:auto">Registry</h2>
|
||||
<a class="button secondary" href="/ui/discovery">Discovery</a>
|
||||
</div>
|
||||
<table>
|
||||
<thead><tr><th>Name</th><th>Status</th><th>Branch</th><th>Source</th></tr></thead>
|
||||
<tbody>{rows or '<tr><td colspan="4" class="muted">No repositories yet.</td></tr>'}</tbody>
|
||||
</table>
|
||||
</section>
|
||||
</div>
|
||||
"""
|
||||
response = page("Repositories", body)
|
||||
@@ -323,6 +341,7 @@ def repository_scope_document(
|
||||
service: RegistryService = Depends(get_service),
|
||||
) -> HTMLResponse:
|
||||
repository = service.get_repository(repository_id)
|
||||
display_name = repository_display_name(repository)
|
||||
checkout = service.ingestion.cached_checkout(repository.url)
|
||||
if checkout is None:
|
||||
rendered = (
|
||||
@@ -342,14 +361,14 @@ def repository_scope_document(
|
||||
body = f"""
|
||||
<h1>SCOPE.md</h1>
|
||||
<section class="panel stack">
|
||||
<p class="muted">Canonical scope summary for the {escape(repository.name)} repository.</p>
|
||||
<p class="muted">Canonical scope summary for the {escape(display_name)} repository.</p>
|
||||
{rendered}
|
||||
</section>
|
||||
"""
|
||||
return page(
|
||||
"SCOPE.md",
|
||||
body,
|
||||
selected_repository=repository.name,
|
||||
selected_repository=display_name,
|
||||
selected_repository_id=repository.id,
|
||||
)
|
||||
|
||||
@@ -721,6 +740,7 @@ def repository_detail(
|
||||
repository = service.get_repository(repository_id)
|
||||
except NotFoundError as exc:
|
||||
raise HTTPException(status_code=404, detail=str(exc)) from exc
|
||||
display_name = repository_display_name(repository)
|
||||
runs = service.list_analysis_runs(repository_id)
|
||||
ability_map = service.ability_map(repository_id)
|
||||
latest_candidate = latest_completed_candidate_graph(
|
||||
@@ -746,7 +766,7 @@ def repository_detail(
|
||||
)
|
||||
body = f"""
|
||||
<div class="actions">
|
||||
<h1 style="margin-right:auto">{escape(repository.name)}</h1>
|
||||
<h1 style="margin-right:auto">{escape(display_name)}</h1>
|
||||
<a class="button secondary" href="/ui/repos/{repository_id}/export">Export</a>
|
||||
<a class="button secondary" href="/ui/repos/{repository_id}/scope">SCOPE</a>
|
||||
<a class="button secondary" href="/ui">Back</a>
|
||||
@@ -889,9 +909,9 @@ def repository_detail(
|
||||
</section>
|
||||
"""
|
||||
return page(
|
||||
repository.name,
|
||||
display_name,
|
||||
body,
|
||||
selected_repository=repository.name,
|
||||
selected_repository=display_name,
|
||||
selected_repository_id=repository.id,
|
||||
)
|
||||
|
||||
@@ -1254,6 +1274,7 @@ def analysis_run_detail(
|
||||
service: RegistryService = Depends(get_service),
|
||||
) -> HTMLResponse:
|
||||
repository = service.get_repository(repository_id)
|
||||
display_name = repository_display_name(repository)
|
||||
candidate_graph = service.candidate_graph(repository_id, analysis_run_id)
|
||||
candidate_graph_data = asdict(candidate_graph)
|
||||
facts = service.list_observed_facts(repository_id, analysis_run_id)
|
||||
@@ -1273,7 +1294,7 @@ def analysis_run_detail(
|
||||
)
|
||||
body = f"""
|
||||
<div class="actions">
|
||||
<h1 style="margin-right:auto">{escape(repository.name)} · Run #{analysis_run_id}</h1>
|
||||
<h1 style="margin-right:auto">{escape(display_name)} · Run #{analysis_run_id}</h1>
|
||||
{render_run_detail_compare_link(repository_id, analysis_run_id, service.list_analysis_runs(repository_id))}
|
||||
<a class="button secondary" href="/ui/repos/{repository_id}">Repository</a>
|
||||
</div>
|
||||
@@ -1346,9 +1367,9 @@ def analysis_run_detail(
|
||||
</section>
|
||||
"""
|
||||
return page(
|
||||
f"{repository.name} Run {analysis_run_id}",
|
||||
f"{display_name} Run {analysis_run_id}",
|
||||
body,
|
||||
selected_repository=repository.name,
|
||||
selected_repository=display_name,
|
||||
selected_repository_id=repository.id,
|
||||
)
|
||||
|
||||
@@ -1411,9 +1432,10 @@ def repository_element_listing(
|
||||
service: RegistryService = Depends(get_service),
|
||||
) -> HTMLResponse:
|
||||
repository = service.get_repository(repository_id)
|
||||
display_name = repository_display_name(repository)
|
||||
if scope in {"approved", "candidate"} and not entry_filter:
|
||||
entry_filter = scope
|
||||
title = element_listing_title(repository.name, scope, type)
|
||||
title = element_listing_title(display_name, scope, type)
|
||||
if scope in {"all", "approved", "candidate"}:
|
||||
elements = graph_element_rows(
|
||||
asdict(service.ability_map(repository_id)),
|
||||
@@ -1519,7 +1541,7 @@ def repository_element_listing(
|
||||
return page(
|
||||
title,
|
||||
body,
|
||||
selected_repository=repository.name,
|
||||
selected_repository=display_name,
|
||||
selected_repository_id=repository.id,
|
||||
)
|
||||
|
||||
@@ -1539,9 +1561,10 @@ def analysis_run_diff_detail(
|
||||
)
|
||||
except NotFoundError as exc:
|
||||
raise HTTPException(status_code=404, detail=str(exc)) from exc
|
||||
display_name = repository_display_name(diff.repository)
|
||||
body = f"""
|
||||
<div class="actions">
|
||||
<h1 style="margin-right:auto">{escape(diff.repository.name)} · Change Review</h1>
|
||||
<h1 style="margin-right:auto">{escape(display_name)} · Change Review</h1>
|
||||
<a class="button secondary" href="/ui/repos/{repository_id}/analysis-runs/{target_analysis_run_id}">Target Run</a>
|
||||
<a class="button secondary" href="/ui/repos/{repository_id}">Repository</a>
|
||||
</div>
|
||||
@@ -1575,9 +1598,9 @@ def analysis_run_diff_detail(
|
||||
</div>
|
||||
"""
|
||||
return page(
|
||||
f"{diff.repository.name} Change Review",
|
||||
f"{display_name} Change Review",
|
||||
body,
|
||||
selected_repository=diff.repository.name,
|
||||
selected_repository=display_name,
|
||||
selected_repository_id=diff.repository.id,
|
||||
)
|
||||
|
||||
@@ -2147,7 +2170,7 @@ def render_repository_checkbox_list(
|
||||
<label>
|
||||
<span>
|
||||
<input style="width:auto" type="checkbox" name="repository_ids" value="{repository.id}"{disabled}>
|
||||
{escape(repository.name)}
|
||||
{escape(repository_display_name(repository))}
|
||||
</span>
|
||||
<span class="muted">{escape(status)}</span>
|
||||
</label>
|
||||
@@ -2162,7 +2185,7 @@ def render_compared_repositories(repositories: list[dict]) -> str:
|
||||
rows = "\n".join(
|
||||
f"""
|
||||
<tr>
|
||||
<td><a href="/ui/repos/{repository['id']}">{escape(repository['name'])}</a></td>
|
||||
<td><a href="/ui/repos/{repository['id']}">{escape(repository_dict_display_name(repository))}</a></td>
|
||||
<td><span class="pill">{escape(repository['status'])}</span></td>
|
||||
<td class="source">{escape(repository['branch'])}</td>
|
||||
</tr>
|
||||
|
||||
Reference in New Issue
Block a user