diff --git a/CLAUDE.md b/CLAUDE.md index 96d821f..9ae7473 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -396,9 +396,16 @@ When code changes are made to cm-dashboard, the NixOS configuration at `~/nixosb sha256 = "sha256-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="; }' 2>&1 | grep "got:" ``` + + Example output: + ``` + error: hash mismatch in fixed-output derivation '/nix/store/...': + specified: sha256-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA= + got: sha256-x8crxNusOUYRrkP9mYEOG+Ga3JCPIdJLkEAc5P1ZxdQ= + ``` 4. **Update Configuration with Correct Hash** - Replace the placeholder with the hash from the error message. + Replace the placeholder with the hash from the error message (the "got:" line). 5. **Commit NixOS Configuration** ```bash diff --git a/README.md b/README.md index 352f149..23516c8 100644 --- a/README.md +++ b/README.md @@ -486,8 +486,15 @@ nix-build --no-out-link -E 'with import {}; fetchFromGitea { }' 2>&1 | grep "got:" ``` +Example output: +``` +error: hash mismatch in fixed-output derivation '/nix/store/...': + specified: sha256-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA= + got: sha256-x8crxNusOUYRrkP9mYEOG+Ga3JCPIdJLkEAc5P1ZxdQ= +``` + #### 4. Update the Hash -Replace the placeholder with the correct hash: +Replace the placeholder with the correct hash from the error message (the "got:" line): ```nix hash = "sha256-vjy+j91iDCHUf0RE43anK4WZ+rKcyohP/3SykwZGof8="; # Use actual hash ``` diff --git a/dashboard/src/data/metrics.rs b/dashboard/src/data/metrics.rs index 110bbbd..3eb8027 100644 --- a/dashboard/src/data/metrics.rs +++ b/dashboard/src/data/metrics.rs @@ -58,6 +58,8 @@ pub struct SystemSummary { pub cpu_temp_status: Option, #[serde(default)] pub cpu_cstate: Option>, + #[serde(default)] + pub logged_in_users: Option>, } #[derive(Debug, Clone, Serialize, Deserialize)] diff --git a/dashboard/src/ui/backup.rs b/dashboard/src/ui/backup.rs index 37035e7..6560452 100644 --- a/dashboard/src/ui/backup.rs +++ b/dashboard/src/ui/backup.rs @@ -59,11 +59,11 @@ fn render_metrics(frame: &mut Frame, _host: &HostDisplayData, metrics: &BackupMe data.add_row( Some(WidgetStatus::new(latest_status)), - vec![format!("{} archives, {:.1} GiB total", metrics.backup.snapshot_count, metrics.backup.size_gb)], + vec![format!("{} archives, {:.1}GB total", metrics.backup.snapshot_count, metrics.backup.size_gb)], vec![ "Latest".to_string(), latest_time, - format!("{:.1} GiB", metrics.backup.latest_archive_size_gb.unwrap_or(metrics.backup.size_gb)), + format!("{:.1}GB", metrics.backup.latest_archive_size_gb.unwrap_or(metrics.backup.size_gb)), ], ); @@ -81,7 +81,15 @@ fn render_metrics(frame: &mut Frame, _host: &HostDisplayData, metrics: &BackupMe vec![ "Disk".to_string(), disk.health.clone(), - format!("{:.1}/{:.0} GB ({:.0}%)", disk.used_gb, disk.total_gb, disk.usage_percent), + { + let used_mb = disk.used_gb * 1000.0; + let used_str = if used_mb < 1000.0 { + format!("{:.0}MB", used_mb) + } else { + format!("{:.1}GB", disk.used_gb) + }; + format!("{} ({}GB)", used_str, disk.total_gb.round() as u32) + }, ], ); } else { diff --git a/dashboard/src/ui/services.rs b/dashboard/src/ui/services.rs index a25f7b0..e79cb4b 100644 --- a/dashboard/src/ui/services.rs +++ b/dashboard/src/ui/services.rs @@ -154,13 +154,8 @@ fn format_memory_value(used: f32, quota: f32) -> String { if quota > 0.05 { let quota_gb = quota / 1000.0; - // Format quota nicely - show decimals only if needed - let quota_str = if quota_gb.fract() == 0.0 { - format!("{}G", quota_gb as u32) - } else { - format!("{:.1}G", quota_gb) - }; - format!("{} ({})", used_value, quota_str) + // Format quota without decimals and use GB + format!("{} ({}GB)", used_value, quota_gb as u32) } else { used_value } @@ -178,13 +173,8 @@ fn format_disk_value(used: f32, quota: f32) -> String { let used_value = format_bytes(used * 1000.0); // Convert GB to MB for format_bytes if quota > 0.05 { - // Format quota nicely - show decimals only if needed - let quota_str = if quota.fract() == 0.0 { - format!("{}G", quota as u32) - } else { - format!("{:.1}G", quota) - }; - format!("{} ({})", used_value, quota_str) + // Format quota without decimals and use GB (round to nearest GB) + format!("{} ({}GB)", used_value, quota.round() as u32) } else { used_value } diff --git a/dashboard/src/ui/system.rs b/dashboard/src/ui/system.rs index 41e2cd6..3d84837 100644 --- a/dashboard/src/ui/system.rs +++ b/dashboard/src/ui/system.rs @@ -65,12 +65,35 @@ fn render_metrics( overall_status.clone() ); - // Use agent-provided C-states as description (agent decides what goes in descriptions) - let cstate_description = summary.cpu_cstate.clone().unwrap_or_default(); + // Use agent-provided C-states and logged-in users as description + let mut description_lines = Vec::new(); + + // Add C-states with prefix on first line, indent subsequent lines + if let Some(cstates) = &summary.cpu_cstate { + for (i, cstate_line) in cstates.iter().enumerate() { + if i == 0 { + description_lines.push(format!("C-State: {}", cstate_line)); + } else { + description_lines.push(format!(" {}", cstate_line)); + } + } + } + + // Add logged-in users to description + if let Some(users) = &summary.logged_in_users { + if !users.is_empty() { + let user_line = if users.len() == 1 { + format!("Logged in: {}", users[0]) + } else { + format!("Logged in: {} users ({})", users.len(), users.join(", ")) + }; + description_lines.push(user_line); + } + } system_dataset.add_row( overall_status.clone(), - cstate_description, + description_lines, vec![ format!("{:.1} / {:.1} GB", summary.memory_used_mb / 1000.0, summary.memory_total_mb / 1000.0), format!("{:.2} • {:.2} • {:.2}", summary.cpu_load_1, summary.cpu_load_5, summary.cpu_load_15),