peach-workspace/peach-web-lite/src/templates/status.rs

497 lines
29 KiB
Rust

use maud::{html, PreEscaped};
use crate::context::{network::NetworkStatusContext, status::StatusContext};
use crate::{templates, STANDALONE_MODE};
fn ap_network_card(status: NetworkStatusContext) -> PreEscaped<String> {
html! {
(PreEscaped("<!-- NETWORK CARD -->"))
div class="card center" {
(PreEscaped("<!-- NETWORK INFO BOX -->"))
div class="capsule capsule-container success-border" {
(PreEscaped("<!-- NETWORK STATUS GRID -->"))
div class="two-grid" title="PeachCloud network mode and status" {
(PreEscaped("<!-- top-right config icon -->"))
a class="link two-grid-top-right" href="/settings/network" title="Configure network settings" {
img id="configureNetworking" class="icon-small" src="/static/icons/cog.svg" alt="Configure";
}
(PreEscaped("<!-- left column -->"))
(PreEscaped("<!-- network mode icon with label -->"))
div class="grid-column-1" {
img id="netModeIcon" class="center icon icon-active" src="/static/icons/router.svg" alt="WiFi router";
label id="netModeLabel" for="netModeIcon" class="center label-small font-gray" title="Access Point Online" { "ONLINE" }
}
(PreEscaped("<!-- right column -->"))
(PreEscaped("<!-- network mode, ssid & ip with labels -->"))
div class="grid-column-2" {
label class="label-small font-gray" for="netMode" title="Network Mode" { "MODE" }
p id="netMode" class="card-text" title="Network Mode" { "Access Point" }
label class="label-small font-gray" for="netSsid" title="Access Point SSID" { "SSID" }
p id="netSsid" class="card-text" title="SSID" { (status.ap_ssid) }
label class="label-small font-gray" for="netIp" title="Access Point IP Address" { "IP" }
p id="netIp" class="card-text" title="IP" { (status.ap_ip) }
}
}
(PreEscaped("<!-- horizontal dividing line -->"))
hr;
(PreEscaped("<!-- DEVICES AND TRAFFIC GRID -->"))
div class="three-grid card-container" {
// devices stack
div class="stack" {
img id="devices" class="icon icon-medium" title="Connected devices" src="/static/icons/devices.svg" alt="Digital devices";
div class="flex-grid" style="padding-top: 0.5rem;" {
label class="label-medium" for="devices" style="padding-right: 3px;" title="Number of connected devices";
}
label class="label-small font-gray" { "DEVICES" }
}
// download stack
div class="stack" {
img id="dataDownload" class="icon icon-medium" title="Download" src="/static/icons/down-arrow.svg" alt="Download";
div class="flex-grid" style="padding-top: 0.5rem;" {
@if let Some(traffic) = &status.ap_traffic {
label class="label-medium" for="dataDownload" style="padding-right: 3px;" title="Data download total in "{ (traffic.rx_unit) }"" { (traffic.rx) }
label class="label-small font-near-black" { (traffic.rx_unit) }
} @else {
label class="label-medium" for="dataDownload" style="padding-right: 3px;" title="Data download total";
label class="label-small font-near-black" { "0" }
}
}
label class="label-small font-gray" { "DOWNLOAD" }
}
// upload stack
div class="stack" {
img id="dataUpload" class="icon icon-medium" title="Upload" src="/static/icons/up-arrow.svg" alt="Upload";
div class="flex-grid" style="padding-top: 0.5rem;" {
@if let Some(traffic) = status.ap_traffic {
label class="label-medium" for="dataUpload" style="padding-right: 3px;" title="Data upload total in "{ (traffic.tx_unit) }"" { (traffic.tx) }
label class="label-small font-near-black" { (traffic.tx_unit) }
} @else {
label class="label-medium" for="dataUpload" style="padding-right: 3px;" title="Data upload total";
label class="label-small font-near-black" { "0" }
}
}
label class="label-small font-gray" { "UPLOAD" }
}
}
}
}
}
}
fn wlan_network_card(status: NetworkStatusContext) -> PreEscaped<String> {
let capsule = if status.wlan_state == *"up" {
"capsule capsule-container success-border"
} else {
"capsule capsule-container warning-border"
};
html! {
(PreEscaped("<!-- NETWORK CARD -->"))
div class="card center" {
(PreEscaped("<!-- NETWORK INFO BOX -->"))
div class=(capsule) {
@if status.wlan_state == *"up" {
(PreEscaped("<!-- NETWORK STATUS GRID -->"))
div id="netInfoBox" class="two-grid" title="PeachCloud network mode and status" {
a class="link two-grid-top-right" href="/settings/network" title="Configure network settings" {
img id="configureNetworking" class="icon-small" src="/static/icons/cog.svg" alt="Configure";
}
(PreEscaped("<!-- NETWORK STATUS -->"))
(PreEscaped("<!-- left column -->"))
(PreEscaped("<!-- network mode icon with label -->"))
div class="grid-column-1" {
img id="netModeIcon" class="center icon icon-active" src="/static/icons/wifi.svg" alt="WiFi online";
label id="netModeLabel" for="netModeIcon" class="center label-small font-gray" title="WiFi Client Status" { "ONLINE" }
}
div class="grid-column-2" {
(PreEscaped("<!-- right column -->"))
(PreEscaped("<!-- network mode, ssid & ip with labels -->"))
label class="label-small font-gray" for="netMode" title="Network Mode" { "MODE" }
p id="netMode" class="card-text" title="Network Mode" { "WiFi Client" }
label class="label-small font-gray" for="netSsid" title="WiFi SSID" { "SSID" }
p id="netSsid" class="card-text" title="SSID" { (status.wlan_ssid) }
label class="label-small font-gray" for="netIp" title="WiFi Client IP Address" { "IP" }
p id="netIp" class="card-text" title="IP" { (status.wlan_ip) }
}
}
} @else {
div id="netInfoBox" class="two-grid" title="PeachCloud network mode and status" {
a class="link two-grid-top-right" href="/settings/network" title="Configure network settings" {
img id="configureNetworking" class="icon-small" src="/static/icons/cog.svg" alt="Configure";
}
div class="grid-column-1" {
img id="netModeIcon" class="center icon icon-inactive" src="/static/icons/wifi.svg" alt="WiFi offline";
label id="netModeLabel" for="netModeIcon" class="center label-small font-gray" title="WiFi Client Status" { "OFFLINE" }
}
div class="grid-column-2" {
(PreEscaped("<!-- right column -->"))
(PreEscaped("<!-- network mode, ssid & ip with labels -->"))
label class="label-small font-gray" for="netMode" title="Network Mode" { "MODE" }
p id="netMode" class="card-text" title="Network Mode" { "WiFi Client" }
label class="label-small font-gray" for="netSsid" title="WiFi SSID" { "SSID" }
p id="netSsid" class="card-text" title="SSID" { (status.wlan_ssid) }
label class="label-small font-gray" for="netIp" title="WiFi Client IP Address" { "IP" }
p id="netIp" class="card-text" title="IP" { (status.wlan_ip) }
}
}
}
(PreEscaped("<!-- horizontal dividing line -->"))
hr;
(PreEscaped("<!-- SIGNAL AND TRAFFIC GRID -->"))
(PreEscaped("<!-- row of icons representing network statistics -->"))
div class="three-grid card-container" {
div class="stack" {
img id="netSignal" class="icon icon-medium" alt="Signal" title="WiFi Signal (%)" src="/static/icons/low-signal.svg";
div class="flex-grid" style="padding-top: 0.5rem;" {
label class="label-medium" for="netSignal" style="padding-right: 3px;" title="Signal strength of WiFi connection (%)" {
@if let Some(wlan_rssi) = status.wlan_rssi { (wlan_rssi) } @else { "0" }
}
}
label class="label-small font-gray" { "SIGNAL" }
}
div class="stack" {
img id="dataDownload" class="icon icon-medium" alt="Download" title="WiFi download total" src="/static/icons/down-arrow.svg";
div class="flex-grid" style="padding-top: 0.5rem;" {
@if let Some(traffic) = &status.wlan_traffic {
(PreEscaped("<!-- display wlan traffic data -->"))
label class="label-medium" for="dataDownload" style="padding-right: 3px;" title="Data download total in "{ (traffic.rx_unit) }"" { (traffic.rx) }
label class="label-small font-near-black" { (traffic.rx_unit) }
} @else {
(PreEscaped("<!-- no wlan traffic data to display -->"))
label class="label-medium" for="dataDownload" style="padding-right: 3px;" title="Data download total" { "0" }
label class="label-small font-near-black" { "MB" }
}
}
label class="label-small font-gray" { "DOWNLOAD" }
}
div class="stack" {
img id="dataUpload" class="icon icon-medium" alt="Upload" title="WiFi upload total" src="/static/icons/up-arrow.svg";
div class="flex-grid" style="padding-top: 0.5rem;" {
@if let Some(traffic) = status.wlan_traffic {
(PreEscaped("<!-- display wlan traffic data -->"))
label class="label-medium" for="dataUpload" style="padding-right: 3px;" title="Data upload total in "{ (traffic.tx_unit) }"" { (traffic.tx) }
label class="label-small font-near-black" { (traffic.tx_unit) }
} @else {
(PreEscaped("<!-- no wlan traffic data to display -->"))
label class="label-medium" for="dataUpload" style="padding-right: 3px;" title="Data upload total" { "0" }
label class="label-small font-near-black" { "MB" }
}
}
label class="label-small font-gray" { "UPLOAD" }
}
}
}
}
}
}
/*
* WORKS ... kinda
fn wlan_network_card(status: NetworkStatusContext) -> PreEscaped<String> {
html! {
(PreEscaped("<!-- NETWORK CARD -->"))
div class="card center" {
(PreEscaped("<!-- NETWORK INFO BOX -->"))
@if status.wlan_state == *"up" {
div class="capsule capsule-container success-border" {
(PreEscaped("<!-- NETWORK STATUS GRID -->"))
div id="netInfoBox" class="two-grid" title="PeachCloud network mode and status" {
a class="link two-grid-top-right" href="/settings/network" title="Configure network settings" {
img id="configureNetworking" class="icon-small" src="/static/icons/cog.svg" alt="Configure";
}
(PreEscaped("<!-- NETWORK STATUS -->"))
(PreEscaped("<!-- left column -->"))
(PreEscaped("<!-- network mode icon with label -->"))
div class="grid-column-1" {
img id="netModeIcon" class="center icon icon-active" src="/static/icons/wifi.svg" alt="WiFi online";
label id="netModeLabel" for="netModeIcon" class="center label-small font-gray" title="WiFi Client Status" { "ONLINE" }
}
div class="grid-column-2" {
(PreEscaped("<!-- right column -->"))
(PreEscaped("<!-- network mode, ssid & ip with labels -->"))
label class="label-small font-gray" for="netMode" title="Network Mode" { "MODE" }
p id="netMode" class="card-text" title="Network Mode" { "WiFi Client" }
label class="label-small font-gray" for="netSsid" title="WiFi SSID" { "SSID" }
p id="netSsid" class="card-text" title="SSID" { (status.wlan_ssid) }
label class="label-small font-gray" for="netIp" title="WiFi Client IP Address" { "IP" }
p id="netIp" class="card-text" title="IP" { (status.wlan_ip) }
}
}
}
} @else {
div class="capsule capsule-container warning-border" {
div id="netInfoBox" class="two-grid" title="PeachCloud network mode and status" {
a class="link two-grid-top-right" href="/settings/network" title="Configure network settings" {
img id="configureNetworking" class="icon-small" src="/static/icons/cog.svg" alt="Configure";
}
div class="grid-column-1" {
img id="netModeIcon" class="center icon icon-inactive" src="/static/icons/wifi.svg" alt="WiFi offline";
label id="netModeLabel" for="netModeIcon" class="center label-small font-gray" title="WiFi Client Status" { "OFFLINE" }
}
div class="grid-column-2" {
(PreEscaped("<!-- right column -->"))
(PreEscaped("<!-- network mode, ssid & ip with labels -->"))
label class="label-small font-gray" for="netMode" title="Network Mode" { "MODE" }
p id="netMode" class="card-text" title="Network Mode" { "WiFi Client" }
label class="label-small font-gray" for="netSsid" title="WiFi SSID" { "SSID" }
p id="netSsid" class="card-text" title="SSID" { (status.wlan_ssid) }
label class="label-small font-gray" for="netIp" title="WiFi Client IP Address" { "IP" }
p id="netIp" class="card-text" title="IP" { (status.wlan_ip) }
}
}
}
}
(PreEscaped("<!-- horizontal dividing line -->"))
hr;
(PreEscaped("<!-- SIGNAL AND TRAFFIC GRID -->"))
(PreEscaped("<!-- row of icons representing network statistics -->"))
div class="three-grid card-container" {
div class="stack" {
img id="netSignal" class="icon icon-medium" alt="Signal" title="WiFi Signal (%)" src="/static/icons/low-signal.svg";
div class="flex-grid" style="padding-top: 0.5rem;" {
label class="label-medium" for="netSignal" style="padding-right: 3px;" title="Signal strength of WiFi connection (%)" {
@if let Some(wlan_rssi) = status.wlan_rssi { (wlan_rssi) } @else { "0" }
}
}
label class="label-small font-gray" { "SIGNAL" }
}
div class="stack" {
img id="dataDownload" class="icon icon-medium" alt="Download" title="WiFi download total" src="/static/icons/down-arrow.svg";
div class="flex-grid" style="padding-top: 0.5rem;" {
@if let Some(traffic) = &status.wlan_traffic {
(PreEscaped("<!-- display wlan traffic data -->"))
label class="label-medium" for="dataDownload" style="padding-right: 3px;" title="Data download total in "{ (traffic.rx_unit) }"" { (traffic.rx) }
label class="label-small font-near-black" { (traffic.rx_unit) }
} @else {
(PreEscaped("<!-- no wlan traffic data to display -->"))
label class="label-medium" for="dataDownload" style="padding-right: 3px;" title="Data download total" { "0" }
label class="label-small font-near-black" { "MB" }
}
}
label class="label-small font-gray" { "DOWNLOAD" }
}
div class="stack" {
img id="dataUpload" class="icon icon-medium" alt="Upload" title="WiFi upload total" src="/static/icons/up-arrow.svg";
div class="flex-grid" style="padding-top: 0.5rem;" {
@if let Some(traffic) = status.wlan_traffic {
(PreEscaped("<!-- display wlan traffic data -->"))
label class="label-medium" for="dataUpload" style="padding-right: 3px;" title="Data upload total in "{ (traffic.tx_unit) }"" { (traffic.tx) }
label class="label-small font-near-black" { (traffic.tx_unit) }
} @else {
(PreEscaped("<!-- no wlan traffic data to display -->"))
label class="label-medium" for="dataUpload" style="padding-right: 3px;" title="Data upload total" { "0" }
label class="label-small font-near-black" { "MB" }
}
}
label class="label-small font-gray" { "UPLOAD" }
}
}
}
}
}
*/
pub fn network() -> PreEscaped<String> {
let back = "/status".to_string();
let title = "Network Status".to_string();
// retrieve network status data
let status = NetworkStatusContext::build();
let content = html! {
(PreEscaped("<!-- NETWORK STATUS -->"))
// if ap is up, show ap card, else show wlan card
@if status.ap_state == *"up" {
(ap_network_card(status))
} @else {
(wlan_network_card(status))
}
};
templates::base::base(back, title, content)
}
fn scuttlebutt_status() -> PreEscaped<String> {
html! {
(PreEscaped("<!-- SCUTTLEBUTT STATUS -->"))
div class="card center" {
div class="card-container" {
p { "Network key: " }
p { "Replication hops: " }
p { "Sbot version: " }
p { "Process status: " }
p { "Process uptime: " }
p { "Blobstore size: " }
p { "Latest sequence number: " }
p { "Last time you visited this page, latest sequence was x ... now it's y" }
p { "Number of follows / followers / friends / blocks" }
}
}
}
}
pub fn status() -> PreEscaped<String> {
let back = "/".to_string();
let title = if *STANDALONE_MODE {
"Scuttlebutt Status".to_string()
} else {
"System Status".to_string()
};
// retrieve system status data
let status = StatusContext::build();
// render the scuttlebutt status template
let content = if *STANDALONE_MODE {
scuttlebutt_status()
// or render the complete system status template
} else {
html! {
(PreEscaped("<!-- SYSTEM STATUS -->"))
div class="card center" {
div class="card-container" {
div class="three-grid" {
(PreEscaped("<!-- PEACH-NETWORK STATUS STACK -->"))
(PreEscaped("<!-- Display microservice status for network, oled & stats -->"))
a class="link" href="/status/network" {
div class="stack capsule success-border" {
img id="networkIcon" class="icon icon-medium" alt="Network" title="Network microservice status" src="/static/icons/wifi.svg";
div class="stack" style="padding-top: 0.5rem;" {
label class="label-small font-near-black" { "Networking" };
label class="label-small font-near-black" { "(network_ping)" };
}
}
}
(PreEscaped("<!-- PEACH-OLED STATUS STACK -->"))
div class="stack capsule success-border" {
img id="oledIcon" class="icon icon-medium" alt="Display" title="OLED display microservice status" src="/static/icons/lcd.svg";
div class="stack" style="padding-top: 0.5rem;" {
label class="label-small font-near-black" { "Display" };
label class="label-small font-near-black" { "(oled_ping)" };
}
}
(PreEscaped("<!-- PEACH-STATS STATUS STACK -->"))
div class="stack capsule success-border" {
img id="statsIcon" class="icon icon-medium" alt="Stats" title="System statistics microservice status" src="/static/icons/chart.svg";
div class="stack" style="padding-top: 0.5rem;" {
label class="label-small font-near-black" { "Statistics" };
label class="label-small font-near-black" { "AVAILABLE" };
}
}
(PreEscaped("<!-- DYNDNS STATUS STACK -->"))
(PreEscaped("<!-- Display status for dynsdns, config & sbot -->"))
div class="stack capsule success-border" {
img id="networkIcon" class="icon icon-medium" alt="Dyndns" title="Dyndns status" src="/static/icons/dns.png";
div class="stack" style="padding-top: 0.5rem;" {
label class="label-small font-near-black" { "Dyn DNS" };
label class="label-small font-near-black" { "(dns_ping)" };
}
}
(PreEscaped("<!-- CONFIG STATUS STACK -->"))
// TODO: render capsule border according to status
div class="stack capsule success-border" {
img id="networkIcon" class="icon icon-medium" alt="Config" title="Config status" src="/static/icons/clipboard.png";
div class="stack" style="padding-top: 0.5rem;" {
label class="label-small font-near-black" { "Config" };
label class="label-small font-near-black" { "(status)" };
}
}
(PreEscaped("<!-- SBOT STATUS STACK -->"))
div class="stack capsule success-border" {
img id="networkIcon" class="icon icon-medium" alt="Sbot" title="Sbot status" src="/static/icons/hermies.svg";
div class="stack" style="padding-top: 0.5rem;" {
label class="label-small font-near-black" { "Sbot" };
label class="label-small font-near-black" { "(sbot_status)" }
}
}
}
}
div class="card-container" {
(PreEscaped("<!-- Display CPU usage meter -->"))
@match status.cpu_usage_percent {
Some(x) => {
div class="flex-grid" {
span class="card-text" { "CPU" }
span class="label-small push-right" { (x) "%" }
}
meter value=(x) min="0" max="100" title="CPU usage" {
div class="meter-gauge" {
span style="width: "{(x)}"%;" { "CPU Usage" }
}
}
},
_ => p class="card-text" { "CPU usage data unavailable" }
}
(PreEscaped("<!-- Display memory usage meter -->"))
@match status.mem_usage_percent {
Some(x) => {
@let (mem_free, mem_unit) = match status.mem_free {
Some(x) => {
if x > 1024 {
((x / 1024), "GB".to_string())
} else {
(x, "MB".to_string())
}
},
_ => (0, "MB".to_string())
};
@let mem_total = status.mem_total.unwrap_or(0);
@let mem_used = status.mem_used.unwrap_or(0);
div class="flex-grid" {
span class="card-text" { "Memory" }
span class="label-small push-right" { (x) " % ("(mem_free)" "(mem_unit)" free)" }
}
meter value=(mem_used) min="0" max=(mem_total) title="Memory usage" {
div class="meter-gauge" {
span style="width: "{(x)}"%;" { "Memory Usage" }
}
}
},
_ => p class="card-text" { "Memory usage data unavailable" }
}
(PreEscaped("<!-- Display disk usage meter -->"))
@match status.disk_usage_percent {
Some(x) => {
// define free disk space with appropriate unit (GB if > 1024)
@let (disk_free, disk_unit) = match status.disk_free {
Some(x) => {
if x > 1024 {
((x / 1024), "GB".to_string())
} else {
(x, "MB".to_string())
}
},
_ => (0, "MB".to_string())
};
div class="flex-grid" {
span class="card-text" { "Disk" };
span class="label-small push-right" { (x) " % ("(disk_free)" "(disk_unit)")" };
}
meter value=(x) min="0" max="100" title="Disk usage" {
div class="meter-gauge" {
span style="width: "{(x)}"%;" { "Disk Usage" };
}
}
},
_ => p class="card-text" { "Disk usage data unavailable" }
}
(PreEscaped("<!-- Display system uptime in minutes -->"))
@match status.uptime {
Some(x) => {
@if x < 60 {
p class="capsule center-text" { "Uptime: "(x)" minutes" }
} @else {
@let hours = x / 60;
@let mins = x % 60;
p class="capsule center-text" { "Uptime: "(hours)" hours, "(mins)" minutes" }
}
},
_ => p class="card-text" { "Uptime data unavailable" }
}
}
}
}
};
templates::base::base(back, title, content)
}