Remove SB column and improve widget formatting

Services widget:
- Remove SB (sandbox) column and related formatting function
- Fix quota formatting to show decimals when needed (1.5G not 1G)
- Remove spaces in unit display (128MB not 128 MB)

Storage widget:
- Change usage format to 23GB (932GB) for better readability

Documentation:
- Add NixOS configuration update process to CLAUDE.md
This commit is contained in:
Christoffer Martinsson 2025-10-14 18:40:12 +02:00
parent b0d3d85fb9
commit 3e5e91f078
3 changed files with 67 additions and 21 deletions

View File

@ -364,3 +364,49 @@ NEVER implement code without first getting explicit user agreement on the approa
- ✅ "Implement maintenance mode for backup operations"
- ✅ "Restructure storage widget with improved layout"
- ✅ "Update CPU thresholds to production values"
## NixOS Configuration Updates
When code changes are made to cm-dashboard, the NixOS configuration at `~/nixosbox` must be updated to deploy the changes.
### Update Process
1. **Get Latest Commit Hash**
```bash
git log -1 --format="%H"
```
2. **Update NixOS Configuration**
Edit `~/nixosbox/hosts/common/cm-dashboard.nix`:
```nix
src = pkgs.fetchgit {
url = "https://gitea.cmtec.se/cm/cm-dashboard.git";
rev = "NEW_COMMIT_HASH_HERE";
sha256 = "sha256-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="; # Placeholder
};
```
3. **Get Correct Source Hash**
Build with placeholder hash to get the actual hash:
```bash
cd ~/nixosbox
nix-build --no-out-link -E 'with import <nixpkgs> {}; fetchgit {
url = "https://gitea.cmtec.se/cm/cm-dashboard.git";
rev = "NEW_COMMIT_HASH";
sha256 = "sha256-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=";
}' 2>&1 | grep "got:"
```
4. **Update Configuration with Correct Hash**
Replace the placeholder with the hash from the error message.
5. **Commit NixOS Configuration**
```bash
cd ~/nixosbox
git add hosts/common/cm-dashboard.nix
git commit -m "Update cm-dashboard to latest version (SHORT_HASH)"
git push
```
6. **Rebuild System**
The user handles the system rebuild step - this cannot be automated.

View File

@ -50,7 +50,7 @@ fn render_metrics(
let mut data = WidgetData::new(
title,
Some(WidgetStatus::new(widget_status)),
vec!["Service".to_string(), "RAM".to_string(), "CPU".to_string(), "Disk".to_string(), "SB".to_string()]
vec!["Service".to_string(), "RAM".to_string(), "CPU".to_string(), "Disk".to_string()]
);
@ -63,7 +63,6 @@ fn render_metrics(
"".to_string(),
"".to_string(),
"".to_string(),
"".to_string(),
],
);
render_widget_data(frame, area, data);
@ -115,7 +114,6 @@ fn render_metrics(
"".to_string(),
"".to_string(),
"".to_string(),
"".to_string(),
],
svc.sub_service.clone(),
);
@ -129,7 +127,6 @@ fn render_metrics(
format_memory_value(svc.memory_used_mb, svc.memory_quota_mb),
format_cpu_value(svc.cpu_percent),
format_disk_value(svc.disk_used_gb, svc.disk_quota_gb),
format_sandbox_value(svc.is_sandboxed, svc.is_sandbox_excluded),
],
);
}
@ -144,11 +141,11 @@ fn format_bytes(mb: f32) -> String {
if mb < 0.1 {
"0".to_string()
} else if mb < 1.0 {
format!("{:.0} kB", mb * 1000.0)
format!("{:.0}kB", mb * 1000.0)
} else if mb < 1000.0 {
format!("{:.0} MB", mb)
format!("{:.0}MB", mb)
} else {
format!("{:.1} GB", mb / 1000.0)
format!("{:.1}GB", mb / 1000.0)
}
}
@ -157,7 +154,13 @@ fn format_memory_value(used: f32, quota: f32) -> String {
if quota > 0.05 {
let quota_gb = quota / 1000.0;
format!("{} ({}G)", used_value, quota_gb as u32)
// 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)
} else {
used_value
}
@ -175,19 +178,16 @@ 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!("{} ({}G)", used_value, quota as u32)
// 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)
} else {
used_value
}
}
fn format_sandbox_value(is_sandboxed: bool, is_excluded: bool) -> String {
if is_sandboxed {
"yes".to_string()
} else if is_excluded {
"-".to_string() // Excluded services don't need sandboxing
} else {
"no".to_string() // Services that should be sandboxed but aren't
}
}

View File

@ -109,13 +109,13 @@ fn format_percent(value: f32) -> String {
fn format_usage(used: Option<f32>, capacity: Option<f32>) -> String {
match (used, capacity) {
(Some(used_gb), Some(total_gb)) if used_gb > 0.0 && total_gb > 0.0 => {
format!("{:.0}G/{:.0}G", used_gb, total_gb)
format!("{:.0}GB ({:.0}GB)", used_gb, total_gb)
}
(Some(used_gb), None) if used_gb > 0.0 => {
format!("{:.0}G", used_gb)
format!("{:.0}GB", used_gb)
}
(None, Some(total_gb)) if total_gb > 0.0 => {
format!("/{:.0}G", total_gb)
format!(" ({:.0}GB)", total_gb)
}
_ => "".to_string(),
}