Files
DokkuStatus/templates/apps_table.html
2025-12-24 10:01:38 +11:00

369 lines
14 KiB
HTML

{% macro gauge(label, pct, subtitle, value_text=None) %}
{% set p = pct if pct is not none else 0 %}
{% if p < 0 %}{% set p=0 %}{% endif %} {% if p> 100 %}{% set p = 100 %}{% endif %}
{% if p < 60 %} {% set col="#00ff88" %} {% set status="OK" %} {% elif p < 85 %} {% set col="#ffb86c" %} {% set
status="WARN" %} {% else %} {% set col="#ff5555" %} {% set status="CRIT" %} {% endif %} {% set txt=value_text if
value_text else (p|round(0)|int ~ "%" ) %} <div style="
border: 2px solid {{ col }};
background: rgba({{ '0, 255, 136' if p < 60 else ('255, 184, 108' if p < 85 else '255, 85, 85') }}, 0.05);
padding: 16px;
position: relative;
transition: all 0.3s ease;
">
<!-- Status indicator -->
<div style="
position: absolute;
top: 8px;
right: 8px;
font-size: 9px;
font-weight: 700;
letter-spacing: 1px;
color: {{ col }};
padding: 2px 6px;
border: 1px solid {{ col }};
background: rgba({{ '0, 255, 136' if p < 60 else ('255, 184, 108' if p < 85 else '255, 85, 85') }}, 0.1);
">
[{{ status }}]
</div>
<!-- Label -->
<div style="
font-size: 11px;
font-weight: 700;
letter-spacing: 2px;
color: #8b949e;
text-transform: uppercase;
margin-bottom: 8px;
">
> {{ label }}
</div>
<!-- Value -->
<div style="
font-size: 28px;
font-weight: 700;
color: {{ col }};
margin-bottom: 8px;
text-shadow: 0 0 10px rgba({{ '0, 255, 136' if p < 60 else ('255, 184, 108' if p < 85 else '255, 85, 85') }}, 0.5);
">
{{ txt }}
</div>
<!-- Subtitle -->
<div style="
font-size: 11px;
color: #8b949e;
margin-bottom: 12px;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
">
{{ subtitle }}
</div>
<!-- Progress bar -->
<div style="
height: 6px;
background: #30363d;
position: relative;
overflow: hidden;
">
<div style="
height: 100%;
width: {{ p }}%;
background: {{ col }};
box-shadow: 0 0 10px {{ col }};
transition: width 0.5s ease;
"></div>
</div>
<!-- ASCII bar representation -->
<div style="
font-size: 10px;
color: {{ col }};
margin-top: 8px;
font-family: 'JetBrains Mono', monospace;
letter-spacing: 0;
">
{% set blocks = (p / 5)|round(0)|int %}
{% set empty = 20 - blocks %}
[{% for i in range(blocks) %}█{% endfor %}{% for i in range(empty) %}░{% endfor %}]
</div>
</div>
{% endmacro %}
<h2>[ LIVE METRICS ]</h2>
<div
style="display: grid; grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); gap: 20px; margin: 0 0 32px 0;">
{{ gauge("CPU", data.gauges.cpu_total_pct, "Sum of container CPU% (clamped)") }}
{{ gauge("RAM", data.gauges.ram_pct, "All containers vs host RAM", (data.gauges.ram_used_h ~ " / " ~
data.gauges.ram_total_h)) }}
{{ gauge("DOCKER_DISK", data.gauges.docker_images_pct, "Images used vs total store") }}
</div>
<h2>[ SYSTEM INFO ]</h2>
<div
style="display: grid; grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); gap: 20px; margin: 0 0 32px 0;">
<div style="
border: 2px solid #30363d;
background: rgba(0, 217, 255, 0.02);
padding: 20px;
transition: all 0.3s ease;
" onmouseover="this.style.borderColor='#00d9ff'; this.style.boxShadow='0 0 20px rgba(0, 217, 255, 0.3)';"
onmouseout="this.style.borderColor='#30363d'; this.style.boxShadow='none';">
<div style="
color: #00d9ff;
font-size: 10px;
font-weight: 700;
letter-spacing: 2px;
text-transform: uppercase;
margin-bottom: 12px;
">
[HOST]
</div>
<div style="font-size: 18px; font-weight: 700; color: #c9d1d9; margin-bottom: 8px;">
{{ data.system.name or "—" }}
</div>
<div style="color: #8b949e; font-size: 12px; line-height: 1.6;">
{{ data.system.operating_system }}<br>
Kernel: {{ data.system.kernel_version }}
</div>
</div>
<div style="
border: 2px solid #30363d;
background: rgba(0, 255, 136, 0.02);
padding: 20px;
transition: all 0.3s ease;
" onmouseover="this.style.borderColor='#00ff88'; this.style.boxShadow='0 0 20px rgba(0, 255, 136, 0.3)';"
onmouseout="this.style.borderColor='#30363d'; this.style.boxShadow='none';">
<div style="
color: #00ff88;
font-size: 10px;
font-weight: 700;
letter-spacing: 2px;
text-transform: uppercase;
margin-bottom: 12px;
">
[COMPUTE]
</div>
<div style="font-size: 14px; font-weight: 600; color: #c9d1d9; margin-bottom: 6px;">
<span style="color: #00ff88; font-size: 20px; font-weight: 700;">{{ data.system.cpus or "—"
}}</span> CPUs
</div>
<div style="font-size: 14px; font-weight: 600; color: #c9d1d9;">
<span style="color: #00ff88; font-size: 20px; font-weight: 700;">{{ data.system.mem_total_h or "—"
}}</span> RAM
</div>
</div>
<div style="
border: 2px solid #30363d;
background: rgba(255, 184, 108, 0.02);
padding: 20px;
transition: all 0.3s ease;
" onmouseover="this.style.borderColor='#ffb86c'; this.style.boxShadow='0 0 20px rgba(255, 184, 108, 0.3)';"
onmouseout="this.style.borderColor='#30363d'; this.style.boxShadow='none';">
<div style="
color: #ffb86c;
font-size: 10px;
font-weight: 700;
letter-spacing: 2px;
text-transform: uppercase;
margin-bottom: 12px;
">
[DOCKER]
</div>
<div style="font-size: 12px; color: #c9d1d9; margin-bottom: 6px; line-height: 1.7;">
Engine: <span style="color: #ffb86c; font-weight: 700;">{{ data.system.server_version or "—"
}}</span>
</div>
<div style="font-size: 12px; color: #c9d1d9; margin-bottom: 6px; line-height: 1.7;">
Images: <span style="color: #ffb86c; font-weight: 700;">{{ data.system.images or "—" }}</span>
</div>
<div style="font-size: 12px; color: #c9d1d9; line-height: 1.7;">
Containers: <span style="color: #00ff88; font-weight: 700;">{{ data.system.containers_running or "—"
}}</span> up / <span style="color: #8b949e; font-weight: 700;">{{ data.system.containers_stopped
or "—" }}</span> down
</div>
</div>
</div>
<div style="
font-size: 11px;
color: #8b949e;
margin-bottom: 32px;
font-weight: 500;
">
<span style="color: #00d9ff;">[TIMESTAMP]</span> {{ data.generated_at }}
</div>
{% if data.warnings %}
<div style="
margin: 24px 0;
padding: 16px 20px;
border: 2px solid #ffb86c;
background: rgba(255, 184, 108, 0.05);
position: relative;
">
<div style="
position: absolute;
top: -12px;
left: 16px;
background: #161b22;
padding: 0 8px;
color: #ffb86c;
font-size: 11px;
font-weight: 700;
letter-spacing: 2px;
">
[!! WARNINGS !!]
</div>
<ul style="margin: 8px 0 0 0; padding-left: 24px; color: #ffb86c;">
{% for w in data.warnings %}
<li style="margin: 6px 0; font-size: 13px;">{{ w }}</li>
{% endfor %}
</ul>
</div>
{% endif %}
<h2>[ APPLICATIONS ]</h2>
<div style="overflow-x: auto; margin-bottom: 32px;">
<table>
<thead>
<tr>
<th>APP</th>
<th>URL</th>
<th>STATUS</th>
<th>CPU</th>
<th>RAM</th>
<th>RESTARTS</th>
<th>IMAGE</th>
</tr>
</thead>
<tbody>
{% for r in data.apps %}
<tr>
<td><span style="color: #00d9ff; font-weight: 700;">{{ r.app }}</span></td>
<td>
<a href="{{ r.url }}" style="
color: #00ff88;
text-decoration: none;
transition: all 0.2s ease;
" onmouseover="this.style.color='#00d9ff'; this.style.textShadow='0 0 10px rgba(0, 217, 255, 0.5)';"
onmouseout="this.style.color='#00ff88'; this.style.textShadow='none';">
{{ r.url }}
</a>
</td>
<td>
<span style="
padding: 3px 8px;
background: rgba(0, 255, 136, 0.1);
color: #00ff88;
border: 1px solid #00ff88;
font-size: 10px;
font-weight: 700;
letter-spacing: 1px;
">
{{ r.status }}
</span>
</td>
<td style="color: #00ff88; font-weight: 600;">{{ r.cpu or "—" }}</td>
<td style="font-size: 12px;">
{% if r.mem_used %}
{{ r.mem_used }} / {{ r.mem_limit }}
<span style="color: #00d9ff; font-weight: 700;">({{ r.mem_pct }})</span>
{% else %} — {% endif %}
</td>
<td style="
color: {% if r.restarts >= 3 %}#ff5555{% else %}#8b949e{% endif %};
font-weight: 700;
">
{{ r.restarts }}
</td>
<td style="color: #8b949e; font-size: 11px;">{{ r.image }}</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
{% if data.infra %}
<h2>[ INFRASTRUCTURE ]</h2>
<div style="overflow-x: auto;">
<table>
<thead>
<tr>
<th>CONTAINER</th>
<th>STATUS</th>
<th>CPU</th>
<th>RAM</th>
<th>RESTARTS</th>
<th>IMAGE</th>
</tr>
</thead>
<tbody>
{% for r in data.infra %}
<tr>
<td><span style="color: #ffb86c; font-weight: 700;">{{ r.container }}</span></td>
<td>
<span style="
padding: 3px 8px;
background: rgba(0, 255, 136, 0.1);
color: #00ff88;
border: 1px solid #00ff88;
font-size: 10px;
font-weight: 700;
letter-spacing: 1px;
">
{{ r.status }}
</span>
</td>
<td style="color: #00ff88; font-weight: 600;">{{ r.cpu or "—" }}</td>
<td style="font-size: 12px;">
{% if r.mem_used %}
{{ r.mem_used }} / {{ r.mem_limit }}
<span style="color: #00d9ff; font-weight: 700;">({{ r.mem_pct }})</span>
{% else %} — {% endif %}
</td>
<td style="
color: {% if r.restarts >= 3 %}#ff5555{% else %}#8b949e{% endif %};
font-weight: 700;
">
{{ r.restarts }}
</td>
<td style="color: #8b949e; font-size: 11px;">{{ r.image }}</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
{% endif %}
<h3>DOCKER DISK USAGE</h3>
<div style="overflow-x: auto; margin-bottom: 24px;">
<table>
<thead>
<tr>
<th>TYPE</th>
<th>TOTAL</th>
<th>ACTIVE</th>
<th>SIZE</th>
<th>RECLAIMABLE</th>
</tr>
</thead>
<tbody>
{% for typ, r in data.system.system_df.items() %}
<tr>
<td><span style="color: #00d9ff; font-weight: 700;">[{{ typ }}]</span></td>
<td>{{ r.total }}</td>
<td>{{ r.active }}</td>
<td>{{ r.size }}</td>
<td>{{ r.reclaimable }}</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>