Added ratatui

This commit is contained in:
Marco De Araujo 2025-12-23 11:36:41 -04:00
parent ba8b12c727
commit 28483fe165
8 changed files with 559 additions and 14 deletions

2
src/ui/dashboard/mod.rs Normal file
View file

@ -0,0 +1,2 @@
pub mod model;
pub use model::{DashboardViewState, MonitorStatus, MonitorViewState};

107
src/ui/dashboard/model.rs Normal file
View file

@ -0,0 +1,107 @@
use crate::core::models::{UnifiedData, UnifiedMonitorData};
use crate::i18n::t;
#[derive(Debug, Clone, PartialEq)]
pub enum MonitorStatus {
Up,
Down,
Unknown,
}
#[derive(Debug, Clone)]
pub struct MonitorViewState {
pub id: u64,
pub name: String,
pub group_name: String,
pub status: MonitorStatus,
pub response_time: String,
pub uptime_24h: String,
pub last_check: String,
}
#[derive(Debug, Clone)]
pub struct DashboardViewState {
pub title: String,
pub descriptions: Option<String>,
pub monitors: Vec<MonitorViewState>,
pub selected_index: usize,
pub is_loading: bool,
pub error_message: Option<String>,
}
impl DashboardViewState {
pub fn new() -> Self {
Self {
title: t("loading").to_string(),
descriptions: None,
monitors: Vec::new(),
selected_index: 0,
is_loading: true,
error_message: None,
}
}
pub fn from_unified_data(data: UnifiedData) -> Self {
let mut monitors = Vec::new();
for monitor in data.monitors {
let status = match monitor.heartbeats.last().map(|h| h.status) {
Some(1) => MonitorStatus::Up,
Some(0) => MonitorStatus::Down,
_ => MonitorStatus::Unknown,
};
let response_time = monitor
.heartbeats
.last()
.and_then(|h| h.ping)
.map(|ms| format!("{}", ms))
.unwrap_or_else(|| t("unknown").to_string());
let uptime_24h = monitor
.uptime_data
.map(|u| u.get_perc_formated())
.unwrap_or_else(|| t("unknown").to_string());
let last_check = monitor
.heartbeats
.last()
.map(|h| h.time.clone())
.unwrap_or_else(|| t("never").to_string());
monitors.push(MonitorViewState {
id: monitor.monitor_info.id,
name: monitor.monitor_info.name,
group_name: "Services".to_string(),
status,
response_time,
uptime_24h,
last_check,
});
}
monitors.sort_by_key(|m| m.name.clone());
Self {
title: data.title,
descriptions: data.description,
monitors,
selected_index: 0,
is_loading: false,
error_message: None,
}
}
pub fn get_selected_monitor(&self) -> Option<&MonitorViewState> {
self.monitors.get(self.selected_index)
}
pub fn move_selection(&mut self, direction: isize) {
if self.monitors.is_empty() {
return;
}
let new_index = (self.selected_index as isize + direction) as usize;
self.selected_index = new_index.clamp(0, self.monitors.len() - 1);
}
}

1
src/ui/mod.rs Normal file
View file

@ -0,0 +1 @@
pub mod dashboard;