This commit is contained in:
Marco De Araujo 2026-01-18 15:43:40 -04:00
parent 70a70af859
commit 00cb8f7a9b
4 changed files with 41 additions and 27 deletions

View file

@ -1,3 +1,4 @@
use std::borrow::Cow;
use std::collections::HashMap; use std::collections::HashMap;
use crate::core::models::{UnifiedData, UnifiedGroupData, UnifiedMonitorData}; use crate::core::models::{UnifiedData, UnifiedGroupData, UnifiedMonitorData};
@ -6,32 +7,38 @@ use crate::data::{
status_page::model::StatusPageResponse, status_page::model::StatusPageResponse,
}; };
pub fn unify_data(status_page: &StatusPageResponse, heartbeat: &HeartbeatResponse) -> UnifiedData { pub fn unify_data<'a>(status_page: &'a StatusPageResponse, heartbeat: &'a HeartbeatResponse) -> UnifiedData<'a> {
let mut groups = Vec::with_capacity(status_page.public_group_list.len()); let mut groups = Vec::with_capacity(status_page.public_group_list.len());
let heartbeat_map: HashMap<u64, Vec<HeartbeatEntry>> = heartbeat let heartbeat_map: HashMap<u64, &'a [HeartbeatEntry]> = heartbeat
.monitors .monitors
.iter() .iter()
.map(|m| (m.monitor_id, m.heartbeats.clone())) .map(|m| (m.monitor_id, &m.heartbeats[..]))
.collect(); .collect();
let uptime_map: HashMap<(u64, u32), UptimeData> = heartbeat let uptime_map: HashMap<(u64, u32), &'a UptimeData> = heartbeat
.uptime_data .uptime_data
.iter() .iter()
.map(|u| ((u.monitor_id, u.period_hours), u.clone())) .map(|u| ((u.monitor_id, u.period_hours), u))
.collect(); .collect();
for group in &status_page.public_group_list { for group in &status_page.public_group_list {
let mut monitors = Vec::with_capacity(group.monitor_list.len()); let mut monitors = Vec::with_capacity(group.monitor_list.len());
for monitor_info in &group.monitor_list { for monitor_info in &group.monitor_list {
let uptime_data = uptime_map.get(&(monitor_info.id, 24)).cloned(); let uptime_data = uptime_map.get(&(monitor_info.id, 24)).copied();
let heartbeats = heartbeat_map let heartbeats = heartbeat_map
.get(&monitor_info.id) .get(&monitor_info.id)
.cloned() .copied()
.unwrap_or_default(); .unwrap_or(&[]);
let name: Cow<'a, str> = if monitor_info.name.len() > 100 {
Cow::Owned(monitor_info.name.clone())
} else {
Cow::Borrowed(monitor_info.name.as_str())
};
monitors.push(UnifiedMonitorData { monitors.push(UnifiedMonitorData {
id: monitor_info.id, id: monitor_info.id,
name: monitor_info.name.clone(), name,
heartbeats, heartbeats,
uptime_data, uptime_data,
}); });
@ -40,7 +47,7 @@ pub fn unify_data(status_page: &StatusPageResponse, heartbeat: &HeartbeatRespons
monitors.sort_by_key(|m| m.id); monitors.sort_by_key(|m| m.id);
groups.push(UnifiedGroupData { groups.push(UnifiedGroupData {
group_info: group.clone(), group_info: group,
monitors, monitors,
}); });
} }
@ -48,8 +55,8 @@ pub fn unify_data(status_page: &StatusPageResponse, heartbeat: &HeartbeatRespons
groups.sort_by_key(|g| g.group_info.weight); groups.sort_by_key(|g| g.group_info.weight);
UnifiedData { UnifiedData {
title: status_page.config.title.clone(), title: Cow::Borrowed(&status_page.config.title),
description: status_page.config.description.clone(), description: status_page.config.description.as_deref().map(Cow::Borrowed),
groups, groups,
auto_refresh_interval: status_page.config.auto_refresh_interval, auto_refresh_interval: status_page.config.auto_refresh_interval,
} }

View file

@ -1,24 +1,26 @@
use std::borrow::Cow;
use crate::data::heartbeat::model::{HeartbeatEntry, UptimeData}; use crate::data::heartbeat::model::{HeartbeatEntry, UptimeData};
use crate::data::status_page::model::{StatusPageGroup}; use crate::data::status_page::model::{StatusPageGroup};
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub struct UnifiedMonitorData { pub struct UnifiedMonitorData<'a> {
pub id: u64, pub id: u64,
pub name: String, pub name: Cow<'a, str>,
pub heartbeats: Vec<HeartbeatEntry>, pub heartbeats: &'a [HeartbeatEntry],
pub uptime_data: Option<UptimeData>, pub uptime_data: Option<&'a UptimeData>,
} }
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub struct UnifiedData { pub struct UnifiedData<'a> {
pub title: String, pub title: Cow<'a, str>,
pub description: Option<String>, pub description: Option<Cow<'a, str>>,
pub auto_refresh_interval: u32, pub auto_refresh_interval: u32,
pub groups: Vec<UnifiedGroupData>, pub groups: Vec<UnifiedGroupData<'a>>,
} }
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub struct UnifiedGroupData { pub struct UnifiedGroupData<'a> {
pub group_info: StatusPageGroup, pub group_info: &'a StatusPageGroup,
pub monitors: Vec<UnifiedMonitorData>, pub monitors: Vec<UnifiedMonitorData<'a>>,
} }

View file

@ -75,7 +75,7 @@ fn render_group(frame: &mut Frame, area: Rect, group: &GroupViewState, is_first_
.constraints([Constraint::Length(1), Constraint::Min(1)]) .constraints([Constraint::Length(1), Constraint::Min(1)])
.split(area); .split(area);
if chunks[0].height <= 0 || chunks[1].height <= 0 || group.monitors.is_empty() { if chunks[0].height == 0 || chunks[1].height == 0 || group.monitors.is_empty() {
return; return;
} }

View file

@ -70,8 +70,8 @@ impl DashboardViewState {
.sum(); .sum();
Self { Self {
title: data.title, title: data.title.into_owned(),
descriptions: data.description, descriptions: data.description.map(|d| d.into_owned()),
groups, groups,
is_loading: false, is_loading: false,
error_message: None, error_message: None,
@ -140,8 +140,13 @@ fn add_monitor_view_state(group: UnifiedGroupData) -> Vec<MonitorViewState> {
.map(|u| u.get_perc_formated()) .map(|u| u.get_perc_formated())
.unwrap_or_else(|| t("unknown").to_string()); .unwrap_or_else(|| t("unknown").to_string());
let name: Cow<'static, str> = match monitor.name {
Cow::Borrowed(borrowed) => Cow::Owned(borrowed.to_string()),
Cow::Owned(owned) => Cow::Owned(owned)
};
MonitorViewState { MonitorViewState {
name: Cow::Owned(monitor.name), name,
status, status,
response_time, response_time,
uptime_24h, uptime_24h,