From f1ee46e1ac7417ea05f2583cab6fe2cbf0f3b3e8 Mon Sep 17 00:00:00 2001 From: catlog22 Date: Sat, 20 Dec 2025 23:46:11 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E4=BC=98=E5=8C=96=E6=96=87=E4=BB=B6?= =?UTF-8?q?=E7=AE=A1=E7=90=86=E5=99=A8=E7=9A=84=E5=8A=A0=E8=BD=BD=E4=BD=93?= =?UTF-8?q?=E9=AA=8C=EF=BC=8C=E5=BC=82=E6=AD=A5=E5=8A=A0=E8=BD=BD=E6=96=B0?= =?UTF-8?q?=E9=B2=9C=E5=BA=A6=E6=95=B0=E6=8D=AE=E5=B9=B6=E6=B7=BB=E5=8A=A0?= =?UTF-8?q?=E5=8A=A0=E8=BD=BD=E7=8A=B6=E6=80=81=E6=8C=87=E7=A4=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../dashboard-css/24-prompt-history.css | 4 +- .../dashboard-css/26-claude-manager.css | 39 +++++++++++++- .../dashboard-js/views/claude-manager.js | 54 ++++++++++++++++--- 3 files changed, 89 insertions(+), 8 deletions(-) diff --git a/ccw/src/templates/dashboard-css/24-prompt-history.css b/ccw/src/templates/dashboard-css/24-prompt-history.css index 33371813..7bd178cd 100644 --- a/ccw/src/templates/dashboard-css/24-prompt-history.css +++ b/ccw/src/templates/dashboard-css/24-prompt-history.css @@ -90,7 +90,9 @@ display: grid; grid-template-columns: 1fr 400px; gap: 1.5rem; - align-items: start; + align-items: stretch; + flex: 1; + min-height: 0; } @media (max-width: 1200px) { diff --git a/ccw/src/templates/dashboard-css/26-claude-manager.css b/ccw/src/templates/dashboard-css/26-claude-manager.css index 8f15c94a..d9a02641 100644 --- a/ccw/src/templates/dashboard-css/26-claude-manager.css +++ b/ccw/src/templates/dashboard-css/26-claude-manager.css @@ -94,6 +94,8 @@ .claude-manager-column.center { overflow: hidden; height: 100%; + display: flex; + flex-direction: column; } .claude-manager-column.right { @@ -286,11 +288,15 @@ flex: 1; overflow-y: auto; padding: 1rem; + min-height: 0; + background: hsl(var(--muted) / 0.3); + border-radius: 0 0 0.5rem 0.5rem; } .markdown-content { line-height: 1.6; color: hsl(var(--foreground)); + min-height: 100%; } .markdown-content h1 { @@ -507,10 +513,14 @@ flex-direction: column; align-items: center; justify-content: center; - height: 100%; + flex: 1; + min-height: 200px; color: hsl(var(--muted-foreground)); text-align: center; padding: 2rem; + background: hsl(var(--muted) / 0.3); + border-radius: 0.5rem; + margin: 0.5rem; } .empty-state i { @@ -763,6 +773,18 @@ color: hsl(0, 72%, 51%); } +.freshness-badge.loading { + background: hsl(var(--muted)); + color: hsl(var(--muted-foreground)); + min-width: 28px; + animation: pulse 1.5s ease-in-out infinite; +} + +@keyframes pulse { + 0%, 100% { opacity: 0.5; } + 50% { opacity: 1; } +} + /* File tree item freshness states */ .file-tree-item.freshness-stale { border-left: 2px solid hsl(0, 72%, 51%); @@ -846,6 +868,21 @@ color: hsl(38, 92%, 50%); } +/* Freshness loading state */ +.freshness-loading { + display: flex; + align-items: center; + justify-content: center; + gap: 0.5rem; + padding: 1.5rem; + color: hsl(var(--muted-foreground)); + font-size: 0.875rem; +} + +.freshness-loading i { + animation: spin 1s linear infinite; +} + /* ======================================== * Responsive Design * ======================================== */ diff --git a/ccw/src/templates/dashboard-js/views/claude-manager.js b/ccw/src/templates/dashboard-js/views/claude-manager.js index 24eaa28a..dd3575bc 100644 --- a/ccw/src/templates/dashboard-js/views/claude-manager.js +++ b/ccw/src/templates/dashboard-js/views/claude-manager.js @@ -37,11 +37,10 @@ async function renderClaudeManager() { '

' + t('common.loading') + '

' + ''; - // Load data + // Load file data first (fast operation) await loadClaudeFiles(); - await loadFreshnessData(); - // Render layout + // Render layout immediately without waiting for freshness data container.innerHTML = '
' + '
' + '
' + @@ -64,13 +63,34 @@ async function renderClaudeManager() { '
' + '
'; - // Render each column + // Render each column immediately (without freshness data) renderFileTree(); renderFileViewer(); renderFileMetadata(); // Initialize Lucide icons if (window.lucide) lucide.createIcons(); + + // Load freshness data asynchronously in the background (non-blocking) + loadFreshnessDataAsync(); +} + +// Async freshness loader - loads in background and updates UI when ready +function loadFreshnessDataAsync() { + // Use setTimeout to ensure UI is rendered first + setTimeout(async function() { + try { + await loadFreshnessData(); + // Re-render file tree and metadata with freshness data + renderFileTree(); + if (selectedFile) { + renderFileMetadata(); + } + if (window.lucide) lucide.createIcons(); + } catch (error) { + console.error('Error loading freshness data in background:', error); + } + }, 100); } // ========== Data Loading ========== @@ -88,9 +108,14 @@ async function loadClaudeFiles() { async function refreshClaudeFiles() { await loadClaudeFiles(); - await loadFreshnessData(); - await renderClaudeManager(); + // Re-render file tree immediately + renderFileTree(); + renderFileViewer(); + renderFileMetadata(); + if (window.lucide) lucide.createIcons(); addGlobalNotification('success', t('claudeManager.refreshed'), null, 'CLAUDE.md'); + // Load freshness data in background + loadFreshnessDataAsync(); } // ========== Freshness Data Loading ========== @@ -241,6 +266,9 @@ function renderFileTreeItem(file, indentLevel) { var freshnessClass = ''; var freshnessBadge = ''; + // Check if freshness data is loaded (freshnessSummary is set after load) + var freshnessLoaded = freshnessSummary !== null || Object.keys(freshnessData).length > 0; + if (fd) { if (fd.freshness >= 75) { freshnessClass = ' freshness-good'; @@ -252,6 +280,9 @@ function renderFileTreeItem(file, indentLevel) { freshnessClass = ' freshness-stale'; freshnessBadge = '' + fd.freshness + '%'; } + } else if (!freshnessLoaded) { + // Show loading badge while freshness data is being fetched + freshnessBadge = '...'; } return '
0; + if (fd) { var freshnessBarClass = fd.freshness >= 75 ? 'good' : fd.freshness >= 50 ? 'warn' : 'stale'; html += ''; + } else if (!freshnessLoaded) { + // Show loading state while freshness data is being fetched + html += ''; } html += '