Files
deploy-felhom-compose/TASK.md
T

351 lines
12 KiB
Markdown

# TASK.md — v0.5.4: Monitoring Page Frontend Fixes
> Version bump: **v0.5.4**
> Scope: Frontend-only — all changes in `monitoring.html` and `style.css`
> No Go code changes needed.
---
## IMPORTANT: Build & Validation
Build must happen in `~/build/felhom-controller/`, NOT in the git repo:
```bash
cd ~/build/felhom-controller
git -C ~/git/deploy-felhom-compose pull
./build.sh 0.5.2 --push
```
**Never run `go build` inside `~/git/deploy-felhom-compose/controller/`.**
After deployment, validate all 4 fixes by:
1. Opening https://felhom.demo-felhom.eu/monitoring in browser
2. Opening the browser Developer Tools (F12) → Console tab
3. Checking each item below
If you cannot access the browser, validate by reading the deployed HTML source:
```bash
ssh kisfenyo@192.168.0.162 "docker exec felhom-controller cat /app/templates/monitoring.html" | head -50
```
---
## Bug 1: Tooltip shows "Invalid Date"
### Root cause
The tooltip callback uses `items[0].parsed.x` which should return a numeric timestamp on a Chart.js linear axis. However, depending on the Chart.js version/build, `parsed.x` may return something unexpected (undefined, wrong type) causing `new Date()` to produce "Invalid Date".
### Diagnosis step
Before fixing, add a temporary console.log to confirm what `parsed.x` actually returns. In `monitoring.html`, in the tooltip callback inside `chartOpts()`:
```javascript
title: function(items) {
if (!items.length) return '';
console.log('[tooltip debug]', 'parsed.x:', items[0].parsed.x, typeof items[0].parsed.x, 'raw:', items[0].raw);
return formatTimestamp(items[0].parsed.x);
}
```
Deploy, hover over a data point, check browser console. Possible findings:
- `parsed.x` is `undefined` → Chart.js isn't finding the x value from `{x,y}` data
- `parsed.x` is a very small number (like an index) → linear scale isn't applied
- `parsed.x` is correct ms timestamp → bug is in `formatTimestamp`
### Fix
Replace the tooltip callback with a more robust approach that accesses the raw data point directly:
```javascript
callbacks: {
title: function(items) {
if (!items.length) return '';
// Access raw {x, y} data point directly — most reliable across Chart.js versions
var raw = items[0].raw;
if (raw && typeof raw === 'object' && raw.x) {
return formatTimestamp(raw.x);
}
// Fallback: try parsed.x
if (items[0].parsed && items[0].parsed.x) {
return formatTimestamp(items[0].parsed.x);
}
return '';
}
}
```
After deploying and verifying, remove the console.log line.
### Verification
- Hover over any data point on any chart → tooltip title shows formatted date like "2026. 02. 16. 11:30"
- Verify on CPU, Memory, Temperature, Load charts
- Verify on container detail charts too (same `chartOpts` function is shared)
---
## Bug 2: Charts fill full width regardless of data density
### Root cause
`setChartXBounds()` sets `chart.options.scales.x.min/max` after chart initialization. Chart.js may not pick up dynamically added `min`/`max` properties if they weren't present in the options during initialization. The scale was created without `min`/`max`, and adding them at runtime may be ignored.
### Diagnosis step
Add console.log in `loadSystemMetrics()` after setting bounds and updating:
```javascript
allCharts.forEach(function(c) { setChartXBounds(c, systemRange); });
updateLineChart(chartCPU, timestamps, d.cpu);
console.log('[bounds debug] range:', systemRange,
'options.min:', chartCPU.options.scales.x.min,
'options.max:', chartCPU.options.scales.x.max,
'scale.min:', chartCPU.scales.x.min,
'scale.max:', chartCPU.scales.x.max);
```
Select "7 nap", check console. If `options.min/max` are set correctly but `scales.x.min/max` show the data extent, then Chart.js is ignoring the runtime-added properties.
### Fix
Include `min` and `max` in the initial chart options so Chart.js registers them from creation. Then dynamic updates work.
**Step 1**: Modify `chartOpts()` to include initial min/max:
```javascript
function chartOpts(yLabel, beginAtZero) {
var now = Date.now();
var defaultRangeMs = parseRangeMs('1h'); // match default systemRange
return {
responsive: true,
maintainAspectRatio: false,
animation: {duration: 300},
plugins: {
legend: {display: false},
tooltip: {
backgroundColor: '#1c2128',
titleColor: '#e6edf3',
bodyColor: '#8b949e',
borderColor: '#30363d',
borderWidth: 1,
callbacks: {
title: function(items) {
if (!items.length) return '';
var raw = items[0].raw;
if (raw && typeof raw === 'object' && raw.x) {
return formatTimestamp(raw.x);
}
if (items[0].parsed && items[0].parsed.x) {
return formatTimestamp(items[0].parsed.x);
}
return '';
}
}
}
},
scales: {
x: {
type: 'linear',
min: now - defaultRangeMs,
max: now,
grid: {color: 'rgba(48,54,61,0.5)'},
ticks: {
color: '#8b949e',
maxTicksLimit: 8,
callback: function(v) {
return formatTimeLabel(v);
}
}
},
y: {
grid: {color: 'rgba(48,54,61,0.5)'},
ticks: {color: '#8b949e'},
beginAtZero: beginAtZero !== false,
title: {display: !!yLabel, text: yLabel || '', color: '#6e7681', font: {size: 11}}
}
}
};
}
```
Key change: `min: now - defaultRangeMs, max: now` are present from creation.
**Step 2**: `setChartXBounds()` stays the same — it updates existing properties.
**Step 3**: Same fix for container detail charts — `initDetailCharts()` uses the same `chartOpts()` so it gets min/max automatically.
### Verification
- Select "7 nap" → x-axis spans 7 full days (Feb 9 to Feb 16), data appears as a small cluster on the far right
- Select "1 óra" → data fills most of the chart width
- Select "24 óra" → data fills proportional to collection time
- X-axis labels for 7d show dates (02.09 .. 02.16), not times
- X-axis labels for 1h/6h/24h show times (10:00, 11:00, etc.)
---
## Bug 3: System overview values not consistently right-aligned
### Root cause
`.sysinfo-row` uses `display: flex; justify-content: space-between` which does push values to the right of each cell. But `.sysinfo-grid` uses `repeat(auto-fill, minmax(280px, 1fr))` which creates varying cell widths — values don't align to a consistent edge across columns.
The `<style>` block in `monitoring.html` sets `text-align: right` on `.sysinfo-value`, but `text-align` has no effect on flex items — flex alignment controls their position.
### Fix
**In `style.css`**, replace the sysinfo rules:
```css
.sysinfo-grid {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 0;
}
.sysinfo-row {
display: flex;
justify-content: space-between;
align-items: baseline;
padding: .5rem .75rem;
border-bottom: 1px solid rgba(48, 54, 61, 0.3);
font-size: .9rem;
gap: 1rem;
}
.sysinfo-row:last-child { border-bottom: none; }
.sysinfo-label {
color: var(--text-secondary);
font-weight: 500;
white-space: nowrap;
flex-shrink: 0;
}
.sysinfo-value {
color: var(--text-primary);
font-family: 'JetBrains Mono', monospace;
font-size: .85rem;
font-weight: 600;
text-align: right;
word-break: break-word;
}
```
Key changes from original:
- `.sysinfo-grid`: `grid-template-columns: 1fr 1fr` (fixed 2-column instead of `auto-fill`)
- `.sysinfo-grid`: `gap: 0` (no gap between cells — border-bottom handles separation)
- `.sysinfo-row`: `align-items: baseline` (text baseline alignment)
- `.sysinfo-row`: `gap: 1rem` (minimum space between label and value)
- `.sysinfo-label`: `white-space: nowrap; flex-shrink: 0` (prevent label wrapping/shrinking)
- `.sysinfo-value`: `font-weight: 600; word-break: break-word` (bold values, allow long values to wrap)
**In `monitoring.html`**, remove the `<style>` block at the top:
```html
<!-- REMOVE THIS -->
<style>
/* Monitoring page specific overrides */
.sysinfo-value {
text-align: right;
font-weight: bold;
}
</style>
```
The mobile rule `@media(max-width: 768px) { .sysinfo-grid { grid-template-columns: 1fr; } }` already exists and stays — collapses to single column on mobile.
### Verification
- Values are consistently right-aligned within each cell
- "Debian GNU/Linux 13 (trixie)" and "6.12.69+deb13-amd64" align to the right edge
- Both grid columns have equal width
- Long values wrap without breaking layout
---
## Bug 4: Charts overflow their container on mobile
### Root cause
`.chart-wrap` has `position: relative; height: 180px` but no overflow or width constraint. CSS grid children default to `min-width: auto`, preventing them from shrinking below their content width. Chart.js canvas may render wider than the parent on narrow screens.
### Fix
**In `style.css`**, update these rules:
```css
.chart-box {
background: var(--bg-secondary);
border-radius: 8px;
padding: .75rem;
border: 1px solid rgba(48, 54, 61, 0.5);
min-width: 0; /* Allow grid children to shrink — critical fix */
overflow: hidden;
}
.chart-wrap {
position: relative;
height: 180px;
overflow: hidden;
max-width: 100%;
}
.chart-wrap canvas {
max-width: 100%;
}
.chart-wrap-bar {
position: relative;
height: 250px;
overflow: hidden;
max-width: 100%;
}
```
Also add `.chart-box-half` update:
```css
.chart-box-half {
flex: 1;
min-width: 0; /* Same fix for flex containers */
}
```
Key additions:
- `min-width: 0` on `.chart-box`**the critical CSS grid fix**: prevents grid children from forcing the grid wider than the viewport
- `overflow: hidden` on `.chart-wrap` and `.chart-wrap-bar` — clips any canvas overflow
- `max-width: 100%` on `.chart-wrap` and canvas
- `min-width: 0` on `.chart-box-half` — same fix for the flex-based container charts
### Verification
- Open monitoring page at 375px width (browser devtools responsive mode)
- All four system metric charts fit within the screen
- Container bar charts fit within the screen
- No horizontal scrollbar appears
- Charts remain interactive (hover/click works)
---
## Implementation order
1. Edit `style.css` — sysinfo alignment + chart overflow fixes
2. Edit `monitoring.html` — remove `<style>` block, fix tooltip callback, add initial min/max to chartOpts
3. Commit
4. Build (`~/build/felhom-controller/build.sh 0.5.2 --push`)
5. Deploy to demo node
6. Verify all 4 fixes in browser
---
## Files to modify
```
controller/internal/web/templates/monitoring.html — tooltip fix, chartOpts min/max, remove <style> block
controller/internal/web/templates/style.css — sysinfo alignment, chart overflow
```
---
## Verification Checklist
- [ ] Tooltip shows correct date (e.g., "2026. 02. 16. 11:30") — no "Invalid Date"
- [ ] "7 nap" range shows full 7-day x-axis, data clustered on the right
- [ ] "1 óra" shows data filling most of the chart
- [ ] "30 nap" shows full 30-day x-axis with data on far right
- [ ] X-axis labels: HH:MM for 1h/6h/24h, MM-DD for 7d/30d
- [ ] System overview values right-aligned, consistent across both columns
- [ ] No `<style>` block at top of monitoring.html (moved to style.css)
- [ ] On mobile (375px): charts fit, no horizontal scroll
- [ ] Container detail panel works (click bar → expand)
- [ ] Auto-refresh works (wait 60s, charts update)
- [ ] No console.log debug lines in final deployed version
- [ ] Build happened in `~/build/felhom-controller/`, no binary in git repo