// Disk Safety Settings Panel (function() { let diskSettings = null; async function loadDiskSettings() { try { const res = await secureFetch('/api/v1/disk-settings'); if (res.ok) { diskSettings = await res.json(); renderDiskSettingsModal(); } } catch (e) { console.error('Failed to load disk settings:', e); } } function renderDiskSettingsModal() { const existing = document.getElementById('disk-settings-modal'); if (existing) existing.remove(); const c = diskSettings?.current || {}; const du = diskSettings?.diskUsage || {}; const usedGB = (du.dataDirSize / 1073741824).toFixed(2); const diskFreeGB = (du.free / 1073741824).toFixed(1); const diskTotalGB = (du.total / 1073741824).toFixed(1); const diskPct = du.total > 0 ? ((du.used / du.total) * 100).toFixed(1) : 0; const modal = document.createElement('div'); modal.id = 'disk-settings-modal'; modal.className = 'modal'; modal.style.cssText = 'display:flex;position:fixed;top:0;left:0;width:100%;height:100%;background:rgba(0,0,0,0.7);z-index:10000;align-items:center;justify-content:center;'; modal.innerHTML = `

💾 Disk Safety

DashCaddy Data Size ${usedGB} GB
Disk Free ${diskFreeGB} GB / ${diskTotalGB} GB (${diskPct}% used)
⚠ Disk impact: Lowering the health check interval increases how often data is written to disk. DashCaddy caps history at max entries per service and prunes entries older than the retention period, so these two values together determine steady-state disk usage. For busy hosts, prefer a longer interval (60–120s) and a lower entry cap.
${settingRow('Health Check Interval', 'healthInterval', c.healthCheckInterval, 'seconds', Math.round((c.healthCheckInterval||30000)/1000), 5, 300)} ${settingRow('Max Health Entries/Service', 'healthMaxEntries', c.healthMaxEntries, 'entries', c.healthMaxEntries||500, 50, 5000)} ${settingRow('Health Retention', 'healthRetentionDays', c.healthRetentionDays, 'days', c.healthRetentionDays||30, 1, 90)} ${settingRow('Max Stats Entries', 'statsMaxEntries', c.statsMaxEntries, 'entries', c.statsMaxEntries||500, 100, 10000)} ${settingRow('Max Audit Entries', 'auditMaxEntries', c.auditMaxEntries, 'entries', c.auditMaxEntries||1000, 100, 10000)}

Some changes apply on next container restart.

`; document.body.appendChild(modal); } function settingRow(label, id, current, unit, displayVal, min, max) { return `
${displayVal} ${unit}
`; } async function saveDiskSettings() { const payload = { healthInterval: parseInt(document.getElementById('disk-healthInterval').value) * 1000, healthMaxEntries: parseInt(document.getElementById('disk-healthMaxEntries').value), healthRetentionDays: parseInt(document.getElementById('disk-healthRetentionDays').value), statsMaxEntries: parseInt(document.getElementById('disk-statsMaxEntries').value), auditMaxEntries: parseInt(document.getElementById('disk-auditMaxEntries').value), }; try { const res = await secureFetch('/api/v1/disk-settings', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(payload) }); const data = await res.json(); if (data.success) { showToast('Disk settings saved', 'success'); } else { showToast(data.error || 'Save failed', 'error'); } } catch (e) { showToast('Error: ' + e.message, 'error'); } } async function cleanupDiskNow() { if (!confirm('Clean up old health entries, stats, and audit logs now?')) return; try { const res = await secureFetch('/api/v1/disk-settings/cleanup', { method: 'POST' }); const data = await res.json(); if (data.success) { const items = Object.entries(data.results.cleaned).map(([k,v]) => `${k}: ${v}`).join('\n'); showToast('Cleanup complete', 'success'); loadDiskSettings(); } } catch (e) { showToast('Error: ' + e.message, 'error'); } } window.openDiskSettings = function() { loadDiskSettings(); }; window.saveDiskSettings = saveDiskSettings; window.cleanupDiskNow = cleanupDiskNow; })();