atr/blueprints/admin/templates/performance.html (162 lines of code) (raw):
{% extends "layouts/base-admin.html" %}
{% block title %}
Performance dashboard
{% endblock title %}
{% block stylesheets %}
{{ super() }}
<style>
.page-performance-stats {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
gap: 1rem;
margin: 1rem 0;
}
.page-route-card {
background: #fff;
border-radius: 8px;
padding: 1rem;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
}
.page-route-card.slow {
border-left: 4px solid #dc3545;
}
.page-route-card.medium {
border-left: 4px solid #ffc107;
}
.page-route-card.fast {
border-left: 4px solid #28a745;
}
.page-route-card h3 {
margin: 0 0 0.5rem 0;
font-size: 1.1rem;
font-family: monospace;
}
.page-route-meta {
display: flex;
gap: 1rem;
font-size: 0.9rem;
color: #666;
margin-bottom: 1rem;
}
.page-timing-grid {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 1rem;
margin-bottom: 1rem;
}
.page-timing-section h4 {
margin: 0 0 0.5rem 0;
font-size: 0.9rem;
color: #444;
}
.page-timing-section dl {
margin: 0;
font-size: 0.85rem;
}
.page-timing-section dt {
color: #666;
float: left;
clear: left;
margin-right: 0.5rem;
}
.page-timing-section dd {
margin: 0;
font-family: monospace;
}
.page-last-seen {
font-size: 0.8rem;
color: #666;
border-top: 1px solid #eee;
padding-top: 0.5rem;
}
</style>
{% endblock stylesheets %}
{% block content %}
<h1>Performance dashboard</h1>
{% if not stats %}
<p class="alert alert-warning">No performance data available.</p>
{% else %}
<div class="page-performance-stats">
{% for path, data in stats.items() %}
<div class="page-route-card {% if data.total.mean > 100 %}slow{% elif data.total.mean < 20 %}fast{% else %}medium{% endif %}">
<h3>{{ path }}</h3>
<div class="page-route-meta">
<span class="methods">{{ data.methods }}</span>
<span class="function">{{ data.function }}</span>
<span class="count">{{ data.count }} requests</span>
</div>
<div class="page-timing-grid">
<div class="page-timing-section">
<h4>Total time (ms)</h4>
<dl>
<dt>Mean</dt>
<dd>
{{ "%.1f"|format(data.total.mean) }}
</dd>
<dt>Median</dt>
<dd>
{{ "%.1f"|format(data.total.median) }}
</dd>
<dt>Min</dt>
<dd>
{{ data.total.min }}
</dd>
<dt>Max</dt>
<dd>
{{ data.total.max }}
</dd>
<dt>Std Dev</dt>
<dd>
{{ "%.1f"|format(data.total.stdev) }}
</dd>
</dl>
</div>
<div class="page-timing-section">
<h4>Sync time (ms)</h4>
<dl>
<dt>Mean</dt>
<dd>
{{ "%.1f"|format(data.sync.mean) }}
</dd>
<dt>Median</dt>
<dd>
{{ "%.1f"|format(data.sync.median) }}
</dd>
<dt>Min</dt>
<dd>
{{ data.sync.min }}
</dd>
<dt>Max</dt>
<dd>
{{ data.sync.max }}
</dd>
</dl>
</div>
<div class="page-timing-section">
<h4>Async time (ms)</h4>
<dl>
<dt>Mean</dt>
<dd>
{{ "%.1f"|format(data.async.mean) }}
</dd>
<dt>Median</dt>
<dd>
{{ "%.1f"|format(data.async.median) }}
</dd>
<dt>Min</dt>
<dd>
{{ data.async.min }}
</dd>
<dt>Max</dt>
<dd>
{{ data.async.max }}
</dd>
</dl>
</div>
</div>
<div class="page-last-seen">Last request: {{ data.last_timestamp }}</div>
</div>
{% endfor %}
</div>
{% endif %}
{% endblock content %}