Simplify backup timestamp display with raw TOML format and remove spacing
All checks were successful
Build and Release / build-and-release (push) Successful in 1m41s

Replace timestamp parsing with direct display of start_time from backup TOML file to ensure timestamp always appears regardless of format. Remove empty line spacing above backup section for compact layout.

Changes:
- Remove parsed timestamp fields and use raw start_time string from TOML
- Display backup time directly from TOML file without parsing
- Remove blank line above backup section for tighter layout
- Simplify BackupData structure by removing last_run and next_scheduled fields

Version bump to v0.1.150
This commit is contained in:
Christoffer Martinsson 2025-11-25 00:08:36 +01:00
parent da37e28b6a
commit 67b59e9551
7 changed files with 21 additions and 49 deletions

6
Cargo.lock generated
View File

@ -279,7 +279,7 @@ checksum = "a1d728cc89cf3aee9ff92b05e62b19ee65a02b5702cff7d5a377e32c6ae29d8d"
[[package]] [[package]]
name = "cm-dashboard" name = "cm-dashboard"
version = "0.1.148" version = "0.1.149"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"chrono", "chrono",
@ -301,7 +301,7 @@ dependencies = [
[[package]] [[package]]
name = "cm-dashboard-agent" name = "cm-dashboard-agent"
version = "0.1.148" version = "0.1.149"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"async-trait", "async-trait",
@ -324,7 +324,7 @@ dependencies = [
[[package]] [[package]]
name = "cm-dashboard-shared" name = "cm-dashboard-shared"
version = "0.1.148" version = "0.1.149"
dependencies = [ dependencies = [
"chrono", "chrono",
"serde", "serde",

View File

@ -1,6 +1,6 @@
[package] [package]
name = "cm-dashboard-agent" name = "cm-dashboard-agent"
version = "0.1.149" version = "0.1.150"
edition = "2021" edition = "2021"
[dependencies] [dependencies]

View File

@ -1,5 +1,5 @@
use async_trait::async_trait; use async_trait::async_trait;
use chrono; use chrono::{NaiveDateTime, DateTime};
use cm_dashboard_shared::{AgentData, BackupData, BackupDiskData}; use cm_dashboard_shared::{AgentData, BackupData, BackupDiskData};
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use std::collections::HashMap; use std::collections::HashMap;
@ -47,15 +47,7 @@ impl BackupCollector {
/// Convert BackupStatusToml to BackupData and populate AgentData /// Convert BackupStatusToml to BackupData and populate AgentData
async fn populate_backup_data(&self, agent_data: &mut AgentData) -> Result<(), CollectorError> { async fn populate_backup_data(&self, agent_data: &mut AgentData) -> Result<(), CollectorError> {
if let Some(backup_status) = self.read_backup_status().await? { if let Some(backup_status) = self.read_backup_status().await? {
// Parse start_time to get last_run timestamp // Use raw start_time string from TOML
let last_run = if let Ok(parsed_time) = chrono::DateTime::parse_from_str(&backup_status.start_time, "%Y-%m-%d %H:%M:%S UTC") {
Some(parsed_time.timestamp() as u64)
} else {
None
};
// Calculate next_scheduled (if needed - may need to be provided by backup script)
let next_scheduled = None; // TODO: Extract from backup script if available
// Extract disk information // Extract disk information
let repository_disk = if let Some(disk_space) = &backup_status.disk_space { let repository_disk = if let Some(disk_space) = &backup_status.disk_space {
@ -89,12 +81,11 @@ impl BackupCollector {
let backup_data = BackupData { let backup_data = BackupData {
status: backup_status.status, status: backup_status.status,
last_run,
next_scheduled,
total_size_gb: Some(total_size_gb), total_size_gb: Some(total_size_gb),
repository_health: Some("ok".to_string()), // Derive from status if needed repository_health: Some("ok".to_string()), // Derive from status if needed
repository_disk, repository_disk,
last_backup_size_gb: None, // Not available in current TOML format last_backup_size_gb: None, // Not available in current TOML format
start_time_raw: Some(backup_status.start_time),
}; };
agent_data.backup = backup_data; agent_data.backup = backup_data;
@ -102,12 +93,11 @@ impl BackupCollector {
// No backup status available - set default values // No backup status available - set default values
agent_data.backup = BackupData { agent_data.backup = BackupData {
status: "unavailable".to_string(), status: "unavailable".to_string(),
last_run: None,
next_scheduled: None,
total_size_gb: None, total_size_gb: None,
repository_health: None, repository_health: None,
repository_disk: None, repository_disk: None,
last_backup_size_gb: None, last_backup_size_gb: None,
start_time_raw: None,
}; };
} }

View File

@ -1,6 +1,6 @@
[package] [package]
name = "cm-dashboard" name = "cm-dashboard"
version = "0.1.149" version = "0.1.150"
edition = "2021" edition = "2021"
[dependencies] [dependencies]

View File

@ -39,8 +39,7 @@ pub struct SystemWidget {
// Backup metrics // Backup metrics
backup_status: String, backup_status: String,
backup_last_run: Option<u64>, backup_start_time_raw: Option<String>,
backup_next_scheduled: Option<u64>,
backup_disk_serial: Option<String>, backup_disk_serial: Option<String>,
backup_disk_usage_percent: Option<f32>, backup_disk_usage_percent: Option<f32>,
backup_disk_used_gb: Option<f32>, backup_disk_used_gb: Option<f32>,
@ -104,8 +103,7 @@ impl SystemWidget {
tmpfs_mounts: Vec::new(), tmpfs_mounts: Vec::new(),
storage_pools: Vec::new(), storage_pools: Vec::new(),
backup_status: "unknown".to_string(), backup_status: "unknown".to_string(),
backup_last_run: None, backup_start_time_raw: None,
backup_next_scheduled: None,
backup_disk_serial: None, backup_disk_serial: None,
backup_disk_usage_percent: None, backup_disk_usage_percent: None,
backup_disk_used_gb: None, backup_disk_used_gb: None,
@ -196,8 +194,7 @@ impl Widget for SystemWidget {
// Extract backup data // Extract backup data
let backup = &agent_data.backup; let backup = &agent_data.backup;
self.backup_status = backup.status.clone(); self.backup_status = backup.status.clone();
self.backup_last_run = backup.last_run; self.backup_start_time_raw = backup.start_time_raw.clone();
self.backup_next_scheduled = backup.next_scheduled;
self.backup_last_size_gb = backup.last_backup_size_gb; self.backup_last_size_gb = backup.last_backup_size_gb;
if let Some(disk) = &backup.repository_disk { if let Some(disk) = &backup.repository_disk {
@ -427,27 +424,17 @@ impl SystemWidget {
let disk_spans = StatusIcons::create_status_spans(backup_status, &disk_text); let disk_spans = StatusIcons::create_status_spans(backup_status, &disk_text);
lines.push(Line::from(disk_spans)); lines.push(Line::from(disk_spans));
// Last backup time // Show backup time from TOML if available
if let Some(last_run) = self.backup_last_run { if let Some(start_time) = &self.backup_start_time_raw {
let time_ago = self.format_time_ago(last_run); let time_text = if let Some(size) = self.backup_last_size_gb {
let last_text = if let Some(size) = self.backup_last_size_gb { format!("Time: {} ({:.1}GB)", start_time, size)
format!("Last: {} ({:.1}GB)", time_ago, size)
} else { } else {
format!("Last: {}", time_ago) format!("Time: {}", start_time)
}; };
lines.push(Line::from(vec![ lines.push(Line::from(vec![
Span::styled(" ├─ ", Typography::tree()), Span::styled(" ├─ ", Typography::tree()),
Span::styled(last_text, Typography::secondary()) Span::styled(time_text, Typography::secondary())
]));
}
// Next backup time
if let Some(next_scheduled) = self.backup_next_scheduled {
let next_text = format!("Next: {}", self.format_time_until(next_scheduled));
lines.push(Line::from(vec![
Span::styled(" ├─ ", Typography::tree()),
Span::styled(next_text, Typography::secondary())
])); ]));
} }
@ -602,9 +589,6 @@ impl SystemWidget {
// Backup section (if available) // Backup section (if available)
if self.backup_status != "unavailable" && self.backup_status != "unknown" { if self.backup_status != "unavailable" && self.backup_status != "unknown" {
lines.push(Line::from(vec![
Span::styled("", Typography::secondary()) // Empty line for spacing
]));
lines.push(Line::from(vec![ lines.push(Line::from(vec![
Span::styled("Backup:", Typography::widget_title()) Span::styled("Backup:", Typography::widget_title())
])); ]));

View File

@ -1,6 +1,6 @@
[package] [package]
name = "cm-dashboard-shared" name = "cm-dashboard-shared"
version = "0.1.149" version = "0.1.150"
edition = "2021" edition = "2021"
[dependencies] [dependencies]

View File

@ -138,12 +138,11 @@ pub struct SubServiceMetric {
#[derive(Debug, Clone, Serialize, Deserialize)] #[derive(Debug, Clone, Serialize, Deserialize)]
pub struct BackupData { pub struct BackupData {
pub status: String, pub status: String,
pub last_run: Option<u64>,
pub next_scheduled: Option<u64>,
pub total_size_gb: Option<f32>, pub total_size_gb: Option<f32>,
pub repository_health: Option<String>, pub repository_health: Option<String>,
pub repository_disk: Option<BackupDiskData>, pub repository_disk: Option<BackupDiskData>,
pub last_backup_size_gb: Option<f32>, pub last_backup_size_gb: Option<f32>,
pub start_time_raw: Option<String>,
} }
/// Backup repository disk information /// Backup repository disk information
@ -193,12 +192,11 @@ impl AgentData {
services: Vec::new(), services: Vec::new(),
backup: BackupData { backup: BackupData {
status: "unknown".to_string(), status: "unknown".to_string(),
last_run: None,
next_scheduled: None,
total_size_gb: None, total_size_gb: None,
repository_health: None, repository_health: None,
repository_disk: None, repository_disk: None,
last_backup_size_gb: None, last_backup_size_gb: None,
start_time_raw: None,
}, },
} }
} }