OXYGENHUB
# 0ee5c3fb32eb oxygenhub / templates / report.html
7.3 KiB · HTML · last changed Reports retention: files beyond the newest 50 runs off the default bookmark expire 24 days ago source blame history raw
1
{% extends "base.html" %}
2
{% import "repo_tabs.html" as m %}
3
{% block title %}{{ report.title }} · Reports · {{ repo.owner }}/{{ repo.name }}{% endblock %}
4
{% block tabs %}{% call m::tabs(repo, "reports") %}{% endblock %}
5
{% block content %}
6
<section class="cov-hero">
7
  <div class="cov-hero-head">
8
    <div>
9
      <div class="small"><a href="{{ repo.url }}/reports">Reports</a> /</div>
10
      <h1>{{ report.title }} <span class="tag rep-kind rep-{{ report.kind }}">{{ report.kind }}</span></h1>
11
      <div class="cov-sub">{% if bookmarks.len() > 1 %}<form class="inline" method="get" action="{{ repo.url }}/reports/{{ report.name }}"><label for="rep-bm" class="mute">bookmark</label> <select id="rep-bm" name="bookmark" onchange="this.form.submit()">{% for b in bookmarks %}<option value="{{ b }}"{% if b.as_str() == report.bookmark.as_str() %} selected{% endif %}>{{ b }}</option>{% endfor %}</select> <noscript><button>Show</button></noscript></form>{% else %}<span class="mute">on</span> <strong>{{ report.bookmark }}</strong>{% endif %}
12
        {% if let Some(n) = report.run_number %}· <a href="{{ repo.url }}/flow/{{ n }}">run #{{ n }}</a>{% endif %} · job {{ report.job }} · <time title="{{ report.created_ms|when_i }}">{{ report.created_ms|ago_i }}</time> · {{ report.files }} files, {{ report.bytes|bytes }} · <a href="{{ files_base }}/report.toml" target="_blank" rel="noopener">report.toml</a></div>
13
      {% if !report.summary.is_empty() %}<p class="rep-summary">{{ report.summary }}</p>{% endif %}
14
    </div>
15
  </div>
16
</section>
17
18
{% if timeline.len() > 1 %}
19
<section class="rep-timeline" data-timeline{% if let Some(p) = play %} data-play="{{ p }}"{% endif %}>
20
  <div class="rep-tl-bar">
21
    <button type="button" class="rep-tl-btn" data-tl-play aria-label="{% if play.is_some() %}Stop playing{% else %}Play through the runs{% endif %}">{% if play.is_some() %}■ Stop{% else %}▶ Play{% endif %}</button>
22
    <label class="small mute">every <select data-tl-speed aria-label="Seconds per run">{% for s in [1u32, 2, 3, 5, 10] %}<option value="{{ s }}"{% if play.unwrap_or(2) == *s %} selected{% endif %}>{{ s }} s</option>{% endfor %}</select></label>
23
    <form class="inline small" method="get" action="{{ repo.url }}/reports/{{ report.name }}">
24
      <input type="hidden" name="id" value="{{ report.id }}">
25
      <label class="mute">compare with <select name="compare" onchange="this.form.submit()" aria-label="Run to compare with"><option value="">none</option>{% for t in timeline %}{% if !t.current %}<option value="{{ t.id }}"{% if t.compared %} selected{% endif %}>{{ t.label }}</option>{% endif %}{% endfor %}</select></label>
26
      <noscript><button>Compare</button></noscript>
27
    </form>
28
    <span class="small mute rep-tl-keys">← → step through runs</span>
29
  </div>
30
  <ol class="rep-tl-stops">
31
    {% for t in timeline %}<li><a href="{{ t.href }}" class="rep-tl-stop{% if t.current %} on{% endif %}{% if t.compared %} cmp{% endif %}" title="{{ t.tip }}"{% if t.current %} aria-current="true"{% endif %} data-tl-stop><span class="sr">{{ t.label }}</span></a></li>{% endfor %}
32
  </ol>
33
  <div class="rep-tl-ends small mute"><span>{% if let Some(f) = timeline.first() %}{{ f.label }}{% endif %}</span><span>{% if let Some(l) = timeline.last() %}{{ l.label }}{% endif %}</span></div>
34
</section>
35
{% endif %}
36
37
{% if let Some((other, rows, _)) = compare %}
38
<section class="panel">
39
  <h2 class="rep-cmp-h">This run against {% if let Some(n) = other.run_number %}run #{{ n }}{% else %}an upload{% endif %} <a class="small" href="{{ repo.url }}/reports/{{ report.name }}?id={{ report.id }}">stop comparing</a></h2>
40
  <table class="rep-table">
41
    <thead><tr><th>Metric</th><th class="num">{% if let Some(n) = report.run_number %}run #{{ n }}{% else %}this{% endif %}</th><th class="num">{% if let Some(n) = other.run_number %}run #{{ n }}{% else %}that{% endif %}</th><th class="num">Difference</th></tr></thead>
42
    <tbody>
43
    {% for c in rows %}
44
      <tr><td><code>{{ c.key }}</code></td><td class="num"><strong>{{ c.here }}</strong>{% if !c.unit.is_empty() %} <small class="mute">{{ c.unit }}</small>{% endif %}</td><td class="num">{{ c.there }}</td><td class="num">{% if !c.delta.is_empty() %}<span class="rep-delta {{ c.trend }}">{{ c.delta }}</span>{% else %}<span class="mute">–</span>{% endif %}</td></tr>
45
    {% endfor %}
46
    </tbody>
47
  </table>
48
</section>
49
{% endif %}
50
51
{% if !metrics.is_empty() && compare.is_none() %}
52
<section class="panel">
53
  <table class="rep-table">
54
    <thead><tr><th>Metric</th><th class="num">Value</th><th class="num">Change</th><th>Across runs</th><th>Threshold</th></tr></thead>
55
    <tbody>
56
    {% for v in metrics %}
57
      <tr class="{% if v.failing %}rep-failing{% endif %}">
58
        <td><code>{{ v.key }}</code></td>
59
        <td class="num"><strong>{{ v.value }}</strong>{% if !v.unit.is_empty() %} <small class="mute">{{ v.unit }}</small>{% endif %}</td>
60
        <td class="num">{% if !v.delta.is_empty() %}<span class="rep-delta {{ v.trend }}">{{ v.delta }}</span>{% else %}<span class="mute">–</span>{% endif %}</td>
61
        <td>{{ v.spark|safe }}</td>
62
        <td class="small">{% if v.failing %}<span class="error">{{ v.threshold }}: failing</span>{% else %}<span class="mute">{{ v.threshold }}</span>{% endif %}</td>
63
      </tr>
64
    {% endfor %}
65
    </tbody>
66
  </table>
67
</section>
68
{% endif %}
69
70
{% if report.files_expired_ms.is_some() %}<p class="strip">This run's files have expired under retention: its metrics and summary are kept, its page and data are not. Runs on {{ repo.default_bookmark }} keep their files, and the newest {{ crate::reports::KEEP_OTHER_RUNS }} runs on any other bookmark.</p>{% endif %}
71
{% if let Some(src) = frame %}
72
<section class="rep-frame-wrap{% if let Some((_, _, Some(_))) = compare %} rep-side{% endif %}">
73
  <iframe class="rep-frame" src="{{ src }}" sandbox="allow-scripts" referrerpolicy="no-referrer" loading="lazy" title="{{ report.title }}" data-report-runs="{{ runs_json }}" data-report-current="{{ report.id }}"></iframe>
74
  {% if let Some((other, _, Some(osrc))) = compare %}<iframe class="rep-frame" src="{{ osrc }}" sandbox="allow-scripts" referrerpolicy="no-referrer" loading="lazy" title="{{ report.title }}, {% if let Some(n) = other.run_number %}run #{{ n }}{% else %}upload{% endif %}" data-report-runs="{{ runs_json }}" data-report-current="{{ other.id }}"></iframe>{% endif %}
75
  <p class="small mute">The report's own page, in a sandbox: its scripts run with no access to your session or this hub. <a href="{{ src }}" target="_blank" rel="noopener">Open it alone</a>.</p>
76
</section>
77
{% endif %}
78
79
<div class="cov-grid">
80
  {% if !context.is_empty() %}
81
  <section class="panel cov-card">
82
    <h2>Context</h2>
83
    <dl class="rep-context">{% for (k, v) in context %}<dt>{{ k }}</dt><dd>{{ v }}</dd>{% endfor %}</dl>
84
  </section>
85
  {% endif %}
86
  <section class="panel cov-card">
87
    <h2>Runs on {{ report.bookmark }}</h2>
88
    <ul class="rep-runs">
89
    {% for r in runs.iter().take(15) %}
90
      <li{% if r.id == report.id %} class="on"{% endif %}><a href="{{ repo.url }}/reports/{{ report.name }}?id={{ r.id }}">{% if let Some(n) = r.run_number %}run #{{ n }}{% else %}upload{% endif %}</a> <span class="mute small"><time title="{{ r.created_ms|when_i }}">{{ r.created_ms|ago_i }}</time>{% if !r.summary.is_empty() %} · {{ r.summary }}{% endif %}</span></li>
91
    {% endfor %}
92
    </ul>
93
  </section>
94
</div>
95
{% endblock %}