runs list: mark older runs with duplicate-stem output as stale, hide their compare checkbox
When two runs share identical params they write to the same figs/<stem>.html, and the most recent overwrites the earlier. Previously both got a compare checkbox with the same data-stem, so toggling one toggled both via the JS Set. Now we flag older duplicates server-side (first occurrence wins — Prefect returns runs START_TIME_DESC), drop their checkbox, fade the row, and mark 'overwritten' on the outputs line.
This commit is contained in:
parent
fc1ae9dbc9
commit
a5614ac371
@ -611,6 +611,22 @@ def _run_view(run: Dict[str, Any]) -> Dict[str, Any]:
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def _mark_stale_views(views: List[Dict[str, Any]]) -> None:
|
||||||
|
"""Flag runs whose emb HTML was overwritten by a newer sibling with
|
||||||
|
identical params. Prefect returns runs sorted by START_TIME_DESC, so the
|
||||||
|
first occurrence of each stem is authoritative; later ones are stale.
|
||||||
|
Mutates views in place."""
|
||||||
|
seen: set = set()
|
||||||
|
for v in views:
|
||||||
|
stem = v["emb_file"][:-5] if v.get("emb_file") else None
|
||||||
|
if stem and stem in seen:
|
||||||
|
v["stale"] = True
|
||||||
|
else:
|
||||||
|
v["stale"] = False
|
||||||
|
if stem:
|
||||||
|
seen.add(stem)
|
||||||
|
|
||||||
|
|
||||||
def _reducer_choices() -> List[Dict[str, str]]:
|
def _reducer_choices() -> List[Dict[str, str]]:
|
||||||
return [
|
return [
|
||||||
{"key": k, "label": spec["label"], "blurb": spec["blurb"]}
|
{"key": k, "label": spec["label"], "blurb": spec["blurb"]}
|
||||||
@ -632,6 +648,7 @@ async def index(request: Request) -> HTMLResponse:
|
|||||||
runs = await PREFECT.recent_runs(client, limit=10)
|
runs = await PREFECT.recent_runs(client, limit=10)
|
||||||
dep_id = await PREFECT.deployment_id(client)
|
dep_id = await PREFECT.deployment_id(client)
|
||||||
views = [_run_view(r) for r in runs]
|
views = [_run_view(r) for r in runs]
|
||||||
|
_mark_stale_views(views)
|
||||||
return templates.TemplateResponse(
|
return templates.TemplateResponse(
|
||||||
request,
|
request,
|
||||||
"index.html",
|
"index.html",
|
||||||
@ -668,6 +685,7 @@ async def runs_partial(request: Request) -> HTMLResponse:
|
|||||||
async with httpx.AsyncClient(timeout=5.0) as client:
|
async with httpx.AsyncClient(timeout=5.0) as client:
|
||||||
runs = await PREFECT.recent_runs(client, limit=10)
|
runs = await PREFECT.recent_runs(client, limit=10)
|
||||||
views = [_run_view(r) for r in runs]
|
views = [_run_view(r) for r in runs]
|
||||||
|
_mark_stale_views(views)
|
||||||
return templates.TemplateResponse(
|
return templates.TemplateResponse(
|
||||||
request, "_runs.html", {"runs": views}
|
request, "_runs.html", {"runs": views}
|
||||||
)
|
)
|
||||||
@ -770,6 +788,7 @@ async def submit(request: Request) -> HTMLResponse:
|
|||||||
async with httpx.AsyncClient(timeout=5.0) as client:
|
async with httpx.AsyncClient(timeout=5.0) as client:
|
||||||
runs = await PREFECT.recent_runs(client, limit=10)
|
runs = await PREFECT.recent_runs(client, limit=10)
|
||||||
views = [_run_view(r) for r in runs]
|
views = [_run_view(r) for r in runs]
|
||||||
|
_mark_stale_views(views)
|
||||||
return templates.TemplateResponse(
|
return templates.TemplateResponse(
|
||||||
request,
|
request,
|
||||||
"_runs.html",
|
"_runs.html",
|
||||||
|
|||||||
@ -518,6 +518,15 @@ button.submit:disabled { background: var(--faint); border-color: var(--faint); c
|
|||||||
padding-left: 0.55rem;
|
padding-left: 0.55rem;
|
||||||
margin-left: -0.55rem;
|
margin-left: -0.55rem;
|
||||||
}
|
}
|
||||||
|
.runs li.run.stale {
|
||||||
|
opacity: 0.55;
|
||||||
|
}
|
||||||
|
.runs li.run.stale .stale-note {
|
||||||
|
color: var(--alarm);
|
||||||
|
font-style: italic;
|
||||||
|
font-size: 0.72rem;
|
||||||
|
margin-left: 0.3rem;
|
||||||
|
}
|
||||||
|
|
||||||
.run .stamp {
|
.run .stamp {
|
||||||
font-family: var(--mono);
|
font-family: var(--mono);
|
||||||
|
|||||||
@ -7,8 +7,8 @@
|
|||||||
{% else %}
|
{% else %}
|
||||||
<ul class="runs">
|
<ul class="runs">
|
||||||
{% for r in runs %}
|
{% for r in runs %}
|
||||||
<li class="run {% if just_submitted is defined and r.id == just_submitted %}just-submitted{% endif %}">
|
<li class="run {% if just_submitted is defined and r.id == just_submitted %}just-submitted{% endif %}{% if r.stale %} stale{% endif %}">
|
||||||
{% if r.emb_exists %}
|
{% if r.emb_exists and not r.stale %}
|
||||||
<input type="checkbox" class="compare-cb" data-stem="{{ r.emb_file[:-5] }}" aria-label="select run for comparison" />
|
<input type="checkbox" class="compare-cb" data-stem="{{ r.emb_file[:-5] }}" aria-label="select run for comparison" />
|
||||||
{% else %}
|
{% else %}
|
||||||
<span class="compare-cb-slot" aria-hidden="true"></span>
|
<span class="compare-cb-slot" aria-hidden="true"></span>
|
||||||
@ -47,6 +47,7 @@
|
|||||||
|
|
||||||
<div class="outputs">
|
<div class="outputs">
|
||||||
<span class="tag">fig</span>
|
<span class="tag">fig</span>
|
||||||
|
{% if r.stale %}<span class="stale-note" title="a newer run with identical params overwrote this output">overwritten</span>{% endif %}
|
||||||
{% if r.ref_file %}
|
{% if r.ref_file %}
|
||||||
{% if r.ref_exists %}
|
{% if r.ref_exists %}
|
||||||
<a href="/figs/{{ r.ref_file }}" target="_blank" rel="noopener">reference</a>
|
<a href="/figs/{{ r.ref_file }}" target="_blank" rel="noopener">reference</a>
|
||||||
|
|||||||
@ -4,7 +4,7 @@
|
|||||||
<meta charset="utf-8" />
|
<meta charset="utf-8" />
|
||||||
<meta name="viewport" content="width=device-width,initial-scale=1" />
|
<meta name="viewport" content="width=device-width,initial-scale=1" />
|
||||||
<title>embedding notebook · compare</title>
|
<title>embedding notebook · compare</title>
|
||||||
<link rel="stylesheet" href="/static/style.css?v=26" />
|
<link rel="stylesheet" href="/static/style.css?v=27" />
|
||||||
<script type="importmap">
|
<script type="importmap">
|
||||||
{
|
{
|
||||||
"imports": {
|
"imports": {
|
||||||
|
|||||||
@ -4,7 +4,7 @@
|
|||||||
<meta charset="utf-8" />
|
<meta charset="utf-8" />
|
||||||
<meta name="viewport" content="width=device-width,initial-scale=1" />
|
<meta name="viewport" content="width=device-width,initial-scale=1" />
|
||||||
<title>embedding notebook</title>
|
<title>embedding notebook</title>
|
||||||
<link rel="stylesheet" href="/static/style.css?v=26" />
|
<link rel="stylesheet" href="/static/style.css?v=27" />
|
||||||
<script src="https://unpkg.com/htmx.org@2.0.4"></script>
|
<script src="https://unpkg.com/htmx.org@2.0.4"></script>
|
||||||
<script type="importmap">
|
<script type="importmap">
|
||||||
{
|
{
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user