# Dashboard Improvement Ideas This document contains recommended improvements for the Thanos Systems Monitor dashboard. ## Status Legend - ✅ **Completed**: Implementation finished - 🔄 **In Progress**: Currently being worked on - ⏳ **Pending**: Not yet started - 💡 **Proposed**: Idea for consideration --- ## 1. Security Concerns ✅ **Status**: COMPLETED (2025-11-22) **Implementation**: - ✅ Created separate `config.js` file for API credentials - ✅ Added `config.js` to `.gitignore` - ✅ Created `config.example.js` template - ✅ Updated `script.js` to remove hardcoded credentials - ✅ Added validation check for missing configuration --- ## 2. Error Handling and User Feedback ⏳ **Current Limitation**: The `showError()` function at `script.js:479-485` only displays errors in the timestamp element, which does not exist in your HTML. **Proposed Improvements**: ### 2.1 Add Timestamp and Error Display - Add timestamp element to header showing last update time - Create dedicated error notification system - Style error notifications with cyberpunk theme ### 2.2 Enhanced Error Handling - Implement retry logic with exponential backoff when API requests fail - Display connection status indicator (online/offline/connecting) - Show loading states during initial data fetch - Add user-friendly error messages for common failures ### 2.3 Implementation Details ```javascript // Retry logic with exponential backoff async function fetchWithRetry(fetchFunction, maxRetries = 3) { for (let i = 0; i < maxRetries; i++) { try { return await fetchFunction(); } catch (error) { if (i === maxRetries - 1) throw error; await new Promise(resolve => setTimeout(resolve, Math.pow(2, i) * 1000)); } } } // Connection status indicator function updateConnectionStatus(status) { // 'online', 'offline', 'connecting', 'error' } ``` --- ## 3. Data Visualization Enhancements ✅ ### 3.1 Ring Chart Improvements **Status**: COMPLETED (2025-11-22) **Implemented Features**: - ✅ Added smooth CSS transitions for ring chart value changes - ✅ Display trend indicators (▲/▼/━ showing increasing/decreasing/stable usage) - ✅ Added hover tooltips showing detailed information (Used, Free, Total, Usage %) - ✅ Implemented historical data tracking (last 20 data points per metric) - ✅ Enhanced hover effects with scale transformation - ✅ Refactored code to use generic updateRingChartGeneric() function, reducing duplication **Implementation Details**: - Created HistoricalData object to track CPU, Memory, and individual disk usage over time - Added createTrendIndicator() helper function for visual trend display - Added createTooltip() helper function for consistent tooltip formatting - Tooltips display on hover with fade-in animation - Trend calculation based on last 3 data points with 1% threshold for stability ### 3.2 Disk Array Enhancements **Status**: COMPLETED (2025-11-22) **Implemented Features**: - ✅ Added hover tooltips for each disk showing capacity, temperature, usage, and status - ✅ Added trend indicators to disk progress bars (▲/▼/━) - ✅ Enhanced hover effects (background color change, border color change) - ✅ Historical data tracking for individual disks **Remaining Enhancements**: - ⏳ Visual indicators for disk health status (SMART data if available from API) - ⏳ Show read/write speed metrics if available from API - ⏳ Group disks by function (parity, cache, data) more clearly - ⏳ Add disk age/hours powered on if available from API ### 3.3 Historical Data Graphs **New Feature**: - Line graphs for CPU usage over time (last hour/day) - Memory usage trends - Disk I/O graphs - Network traffic visualization - Implement using HTML5 Canvas or lightweight charting library --- ## 4. Performance Optimizations ⏳ **Current Implementation**: Updates occur every 5 seconds regardless of visibility ### 4.1 Page Visibility API ```javascript document.addEventListener('visibilitychange', () => { if (document.hidden) { // Pause updates clearInterval(updateInterval); } else { // Resume updates updateInterval = setInterval(updateDashboard, 5000); updateDashboard(); // Immediate update on return } }); ``` ### 4.2 Animation Optimization - Use `requestAnimationFrame` for smoother animations - Batch DOM updates to minimize reflows - Use CSS transforms instead of position changes ### 4.3 Differential Updates - Only update DOM elements that have changed values - Compare previous state with current state - Reduce unnecessary re-renders ### 4.4 Web Workers - Move data processing to Web Worker - Keep UI thread responsive - Process API responses in background --- ## 5. Code Quality Improvements ⏳ ### 5.1 Eliminate Code Duplication **Current Issue**: Ring chart update functions (`script.js:113-240`) contain significant duplication **Refactoring Recommendation**: ```javascript function updateRingChart(elementId, percentage, usedKB, totalKB) { const ring = document.getElementById(`${elementId}-ring`); const text = document.getElementById(`${elementId}-percentage`); const fraction = document.getElementById(`${elementId}-fraction`); const circumference = 2 * Math.PI * 80; const offset = circumference - (percentage / 100) * circumference; ring.style.strokeDashoffset = offset; text.textContent = percentage + '%'; const usedTB = (usedKB / 1024 / 1024 / 1024).toFixed(2); const totalTB = (totalKB / 1024 / 1024 / 1024).toFixed(2); fraction.textContent = `${usedTB} / ${totalTB} TB`; // Apply color coding applyThresholdColors(ring, text, fraction, percentage); } function applyThresholdColors(ring, text, fraction, percentage) { const color = percentage >= 90 ? '#ffffff' : percentage >= 70 ? '#ff00ff' : '#00ffff'; ring.style.stroke = color; text.style.fill = color; fraction.style.fill = color; } // Usage updateRingChart('disk', totalUsagePercentage, totalUsed, totalCapacity); updateRingChart('docker', dockerUsagePercentage, dockerUsed, dockerCapacity); updateRingChart('photos', photosUsagePercentage, photosUsed, photosCapacity); updateRingChart('media', mediaUsagePercentage, mediaUsed, mediaCapacity); ``` ### 5.2 Extract Constants ```javascript // Configuration constants const CONSTANTS = { UPDATE_INTERVAL: 5000, RING_RADIUS: 80, WARNING_THRESHOLD: 70, CRITICAL_THRESHOLD: 90, COLORS: { PRIMARY: '#00ffff', WARNING: '#ff00ff', CRITICAL: '#ffffff', BACKGROUND: '#1a1a1a' } }; ``` ### 5.3 Add JSDoc Documentation ```javascript /** * Updates a ring chart with usage data * @param {string} elementId - The base ID for the ring chart elements * @param {number} percentage - Usage percentage (0-100) * @param {number} usedKB - Used space in kilobytes * @param {number} totalKB - Total space in kilobytes */ function updateRingChart(elementId, percentage, usedKB, totalKB) { // Implementation } ``` ### 5.4 Error Boundaries - Add try-catch blocks around each update function - Prevent one failing component from breaking entire dashboard - Log errors for debugging ### 5.5 Data Validation ```javascript function validateMetricsData(data) { if (!data || typeof data !== 'object') { throw new Error('Invalid metrics data'); } if (data.cpu && typeof data.cpu.percentTotal !== 'number') { console.warn('Invalid CPU data:', data.cpu); } return data; } ``` --- ## 6. Responsive Design Enhancements ⏳ **Current State**: Basic responsive design at 768px breakpoint ### 6.1 Additional Breakpoints ```css /* Tablet landscape */ @media (max-width: 1024px) { .grid-row-1 { grid-template-columns: 1fr; } .disk-usage-layout { grid-template-columns: 1fr; } } /* Tablet portrait */ @media (max-width: 768px) { .ring-chart-row-split { grid-template-columns: 1fr; } } /* Mobile */ @media (max-width: 480px) { .mini-ring-chart { width: 120px; height: 120px; } .title { font-size: 1.5rem; } } ``` ### 6.2 Raspberry Pi Display Optimization - Test on actual Raspberry Pi display resolution - Optimize for common resolutions: 1920x1080, 1280x720 - Consider touch-friendly interface elements - Test browser performance on Raspberry Pi 3 ### 6.3 Orientation Support - Handle landscape and portrait orientations - Reflow layout appropriately for vertical displays --- ## 7. Accessibility Improvements ⏳ **Current State**: Limited accessibility features ### 7.1 ARIA Labels and Roles ```html
75%
PARITY STATUS: VALID
``` ### 7.2 Live Regions ```html
``` ### 7.3 Keyboard Navigation - Add tab index to interactive elements - Implement keyboard shortcuts for common actions - Ensure focus indicators are visible ### 7.4 Color Contrast - Verify all text meets WCAG AA standards (4.5:1 ratio) - Current cyan (#00ffff) on black (#000000) has 15.3:1 ratio ✓ - Test magenta (#ff00ff) and white (#ffffff) combinations - Consider adding high contrast mode option ### 7.5 Screen Reader Support ```javascript function announceUpdate(message) { const announcer = document.getElementById('status-announcer'); announcer.textContent = message; } // Usage announceUpdate('CPU usage increased to 85%'); announceUpdate('Docker container "plex" started'); ``` --- ## 8. Additional Features 💡 ### 8.1 User Preferences **Proposed Implementation**: ```javascript const UserPreferences = { updateInterval: 5000, theme: 'dark', // Future: 'light' option showAnimations: true, temperatureUnit: 'celsius', // or 'fahrenheit' notifications: { enabled: true, cpuThreshold: 90, memoryThreshold: 90, diskThreshold: 90 } }; // Save to localStorage function savePreferences(prefs) { localStorage.setItem('dashboardPrefs', JSON.stringify(prefs)); } // Load from localStorage function loadPreferences() { const saved = localStorage.getItem('dashboardPrefs'); return saved ? JSON.parse(saved) : UserPreferences; } ``` ### 8.2 Configurable Alerts - Set custom thresholds for warnings - Browser notifications for critical states - Email/webhook notifications (requires backend) - Sound alerts for critical conditions ### 8.3 Data Export ```javascript function exportData(format = 'json') { const data = { timestamp: new Date().toISOString(), cpu: currentCPUUsage, memory: currentMemoryUsage, disks: currentDiskData, docker: currentDockerData }; if (format === 'json') { const blob = new Blob([JSON.stringify(data, null, 2)], { type: 'application/json' }); downloadFile(blob, `unraid-metrics-${Date.now()}.json`); } else if (format === 'csv') { // Convert to CSV and download } } ``` ### 8.4 Theme Options - Light theme option - Custom color schemes - Adjustable glow intensity - Disable animations option (for performance) ### 8.5 Network Monitoring **If Available from API**: - Network interface statistics - Upload/download speeds - Total bandwidth usage - Per-container network usage ### 8.6 UPS Status **If Available from API**: - Battery charge level - Runtime remaining - Power status (on battery/on AC) - UPS load percentage ### 8.7 System Temperature Monitoring **If Available from API**: - CPU temperature - Motherboard temperature - Additional thermal sensors - Temperature history graphs ### 8.8 Cache Drive Monitoring - Separate cache drive statistics - Cache utilization - Mover status and schedule --- ## 9. Docker Container Enhancements ⏳ **Current Display**: Basic name and status ### 9.1 Additional Container Information **Proposed Additions**: - CPU usage per container (if available) - Memory usage per container (if available) - Port mappings display - Container uptime - Container health check status - Image version/tag ### 9.2 Container Controls **If API Supports**: ```javascript async function controlContainer(containerId, action) { // action: 'start', 'stop', 'restart' const query = `mutation { dockerContainerControl(id: "${containerId}", action: "${action}") { success message } }`; return await executeGraphQLQuery(query); } ``` **UI Implementation**: - Add start/stop/restart buttons to each container card - Confirmation dialog for destructive actions - Loading state during action execution - Success/error feedback ### 9.3 Container Details Modal - Click container to view detailed information - Show logs (last 100 lines) - Environment variables - Volume mounts - Network configuration --- ## 10. Testing and Monitoring ⏳ ### 10.1 Unit Tests **Proposed Framework**: Jest or Vitest (lightweight) ```javascript // Example test file: script.test.js describe('formatBytes', () => { test('formats bytes correctly', () => { expect(formatBytes(0)).toBe('0 B'); expect(formatBytes(1024)).toBe('1 KB'); expect(formatBytes(1048576)).toBe('1 MB'); expect(formatBytes(1073741824)).toBe('1 GB'); }); }); describe('updateCPU', () => { test('applies critical class above 90%', () => { document.body.innerHTML = `
`; updateCPU(95); const progressBar = document.getElementById('cpu-progress'); expect(progressBar.classList.contains('critical')).toBe(true); }); }); ``` ### 10.2 Integration Tests **Test API Integration**: ```javascript describe('API Integration', () => { test('fetches system metrics successfully', async () => { const metrics = await fetchSystemMetrics(); expect(metrics).toHaveProperty('cpu'); expect(metrics).toHaveProperty('memory'); }); test('handles API errors gracefully', async () => { // Mock failed request global.fetch = jest.fn(() => Promise.reject('API Error')); await expect(fetchSystemMetrics()).rejects.toThrow(); }); }); ``` ### 10.3 Performance Monitoring ```javascript // Add performance tracking const performanceMetrics = { apiCallDuration: [], renderDuration: [], totalUpdateDuration: [] }; async function updateDashboard() { const startTime = performance.now(); try { // Existing update logic } finally { const duration = performance.now() - startTime; performanceMetrics.totalUpdateDuration.push(duration); // Log if update takes too long if (duration > 1000) { console.warn(`Slow update: ${duration}ms`); } } } ``` ### 10.4 Error Logging **Client-Side Error Tracking**: ```javascript // Simple error logger const ErrorLogger = { errors: [], log(error, context = {}) { const errorEntry = { timestamp: new Date().toISOString(), message: error.message, stack: error.stack, context: context }; this.errors.push(errorEntry); console.error('Error logged:', errorEntry); // Optional: Send to remote logging service // this.sendToRemote(errorEntry); }, getErrors() { return this.errors; }, clearErrors() { this.errors = []; } }; // Global error handler window.addEventListener('error', (event) => { ErrorLogger.log(event.error, { type: 'uncaught', filename: event.filename, lineno: event.lineno }); }); ``` ### 10.5 Health Check Endpoint **If you add a service worker**: ```javascript // Monitor dashboard health function dashboardHealthCheck() { return { status: 'healthy', lastUpdate: lastUpdateTimestamp, apiConnected: apiConnectionStatus, errorCount: ErrorLogger.errors.length, uptime: performance.now() }; } ``` --- ## 11. Advanced Features 💡 ### 11.1 Mobile App - Progressive Web App (PWA) support - Add manifest.json - Service worker for offline capability - App install prompt ### 11.2 Multi-Server Support - Monitor multiple Unraid servers - Server selector dropdown - Aggregate statistics - Server comparison view ### 11.3 Custom Widgets - Drag-and-drop dashboard customization - User-configurable layout - Widget library (add/remove sections) - Save custom layouts ### 11.4 Scheduled Reports - Daily/weekly summary emails - PDF report generation - Usage trends analysis - Capacity planning recommendations --- ## Implementation Priority ### High Priority (Core Functionality) 1. ✅ Security improvements 2. Error handling and user feedback 3. Code quality improvements (reduce duplication) 4. Performance optimizations (Page Visibility API) ### Medium Priority (User Experience) 5. Docker container enhancements 6. Data visualization improvements 7. Responsive design enhancements 8. Accessibility improvements ### Low Priority (Nice to Have) 9. Additional features (themes, preferences) 10. Testing infrastructure 11. Advanced features (PWA, multi-server) --- ## Notes - All improvements should maintain the cyberpunk aesthetic - Keep implementation lightweight for Raspberry Pi 3 performance - Test thoroughly on actual hardware before deployment - Document all configuration options - Maintain backward compatibility where possible --- **Last Updated**: 2025-11-22 **Status**: Living document - update as improvements are implemented