// ========================================== // STORAGE MANAGER COMPONENT // ========================================== // Manages CCW centralized storage (~/.ccw/) // State let storageData = null; let storageLoading = false; /** * Initialize storage manager */ async function initStorageManager() { await loadStorageStats(); } /** * Load storage statistics from API */ async function loadStorageStats() { if (storageLoading) return; storageLoading = true; try { const res = await fetch('/api/storage/stats'); if (!res.ok) throw new Error('Failed to load storage stats'); storageData = await res.json(); renderStorageCard(); } catch (err) { console.error('Failed to load storage stats:', err); renderStorageCardError(err.message); } finally { storageLoading = false; } } /** * Render storage card in the dashboard */ function renderStorageCard() { const container = document.getElementById('storageCard'); if (!container || !storageData) return; const { location, totalSizeFormatted, projectCount, projects } = storageData; // Format relative time const formatTimeAgo = (isoString) => { if (!isoString) return 'Never'; const date = new Date(isoString); const now = new Date(); const diffMs = now - date; const diffMins = Math.floor(diffMs / 60000); const diffHours = Math.floor(diffMins / 60); const diffDays = Math.floor(diffHours / 24); if (diffMins < 1) return 'Just now'; if (diffMins < 60) return diffMins + 'm ago'; if (diffHours < 24) return diffHours + 'h ago'; if (diffDays < 30) return diffDays + 'd ago'; return date.toLocaleDateString(); }; // Build project tree (hierarchical view) let projectRows = ''; if (projects && projects.length > 0) { const tree = buildProjectTree(projects); projectRows = renderProjectTree(tree, 0, formatTimeAgo); // Initially hide all child rows (level > 0) setTimeout(() => { const allRows = document.querySelectorAll('.project-row'); allRows.forEach(row => { const level = parseInt(row.getAttribute('data-level')); if (level > 0) { row.style.display = 'none'; } }); }, 0); } else { projectRows = '\
| Project ID | \Size | \History | \Last Used | \\ |
|---|
' + escapeHtml(message) + '
\ \