diff --git a/src/mcp_feedback_enhanced/web/locales/en/translation.json b/src/mcp_feedback_enhanced/web/locales/en/translation.json index 1e7b429..9de59e9 100644 --- a/src/mcp_feedback_enhanced/web/locales/en/translation.json +++ b/src/mcp_feedback_enhanced/web/locales/en/translation.json @@ -238,7 +238,10 @@ "summary": "Summary", "noSummary": "No summary available", "unknown": "Unknown" - } + }, + "copySessionContent": "Copy Session Content", + "copyUserContent": "Copy User Content", + "exportSession": "Export This Session" }, "sessionHistory": { "management": { diff --git a/src/mcp_feedback_enhanced/web/locales/zh-CN/translation.json b/src/mcp_feedback_enhanced/web/locales/zh-CN/translation.json index 4522fa7..9c339ab 100644 --- a/src/mcp_feedback_enhanced/web/locales/zh-CN/translation.json +++ b/src/mcp_feedback_enhanced/web/locales/zh-CN/translation.json @@ -238,7 +238,10 @@ "summary": "总结", "noSummary": "暂无总结", "unknown": "未知" - } + }, + "copySessionContent": "复制会话内容", + "copyUserContent": "复制用户内容", + "exportSession": "导出此会话" }, "sessionHistory": { "management": { diff --git a/src/mcp_feedback_enhanced/web/locales/zh-TW/translation.json b/src/mcp_feedback_enhanced/web/locales/zh-TW/translation.json index e623206..60d7e3f 100644 --- a/src/mcp_feedback_enhanced/web/locales/zh-TW/translation.json +++ b/src/mcp_feedback_enhanced/web/locales/zh-TW/translation.json @@ -243,7 +243,10 @@ "noSummary": "暫無摘要", "unknown": "未知" }, - "noSummary": "無摘要" + "noSummary": "無摘要", + "copySessionContent": "複製會話內容", + "copyUserContent": "複製用戶內容", + "exportSession": "匯出此會話" }, "sessionHistory": { "management": { diff --git a/src/mcp_feedback_enhanced/web/static/js/i18n.js b/src/mcp_feedback_enhanced/web/static/js/i18n.js index e2fbebb..e723ee5 100644 --- a/src/mcp_feedback_enhanced/web/static/js/i18n.js +++ b/src/mcp_feedback_enhanced/web/static/js/i18n.js @@ -227,6 +227,11 @@ class I18nManager { const stats = window.feedbackApp.sessionManager.dataManager.getStats(); window.feedbackApp.sessionManager.uiRenderer.renderStats(stats); console.log('🌐 已更新統計資訊的語言顯示'); + + // 重新渲染會話歷史以更新所有動態創建的元素 + const sessionHistory = window.feedbackApp.sessionManager.dataManager.getSessionHistory(); + window.feedbackApp.sessionManager.uiRenderer.renderSessionHistory(sessionHistory); + console.log('🌐 已更新會話歷史的語言顯示'); } } diff --git a/src/mcp_feedback_enhanced/web/static/js/modules/session/session-details-modal.js b/src/mcp_feedback_enhanced/web/static/js/modules/session/session-details-modal.js index 0fd8521..f5cf01a 100644 --- a/src/mcp_feedback_enhanced/web/static/js/modules/session/session-details-modal.js +++ b/src/mcp_feedback_enhanced/web/static/js/modules/session/session-details-modal.js @@ -31,7 +31,7 @@ this.currentModal = null; this.keydownHandler = null; - console.log('🔍 SessionDetailsModal 初始化完成'); + // console.log('🔍 SessionDetailsModal 初始化完成'); } /** @@ -43,7 +43,7 @@ return; } - console.log('🔍 顯示會話詳情:', sessionData.session_id); + // console.log('🔍 顯示會話詳情:', sessionData.session_id); // 存储当前会话数据,供复制功能使用 this.currentSessionData = sessionData; @@ -62,7 +62,7 @@ * 格式化會話詳情 */ SessionDetailsModal.prototype.formatSessionDetails = function(sessionData) { - console.log('🔍 格式化會話詳情:', sessionData); + // console.log('🔍 格式化會話詳情:', sessionData); // 處理會話 ID - 顯示完整 session ID const sessionId = sessionData.session_id || '未知'; @@ -171,7 +171,7 @@ ${i18n ? i18n.t('sessionManagement.aiSummary') : 'AI 摘要'}:
- +
${this.renderMarkdownSafely(details.summary)}
@@ -254,7 +254,7 @@ #${index + 1} ${timestamp} ${submissionMethod} - + ${contentHtml} @@ -346,7 +346,7 @@ if (!this.currentModal) return; // 彈窗已經通過 CSS 動畫自動顯示,無需額外處理 - console.log('🔍 會話詳情彈窗已顯示'); + // console.log('🔍 會話詳情彈窗已顯示'); }; /** @@ -395,9 +395,9 @@ if (!content) return ''; try { - // 检查 marked 和 DOMPurify 是否可用 + // 檢查 marked 和 DOMPurify 是否可用 if (typeof window.marked === 'undefined' || typeof window.DOMPurify === 'undefined') { - console.warn('⚠️ Markdown 库未载入,使用纯文字显示'); + console.warn('⚠️ Markdown 庫未載入,使用純文字顯示'); return this.escapeHtml(content); } @@ -413,156 +413,131 @@ return cleanHtml; } catch (error) { - console.error('❌ Markdown 渲染失败:', error); + console.error('❌ Markdown 渲染失敗:', error); return this.escapeHtml(content); } }; /** - * 复制摘要内容到剪贴板 + * 傳統複製文字到剪貼板的方法 */ - SessionDetailsModal.prototype.copySummaryToClipboard = function() { - const self = this; // 定义 self 变量 + SessionDetailsModal.prototype.fallbackCopyTextToClipboard = function(text, successMessage) { + const self = this; + const textArea = document.createElement('textarea'); + textArea.value = text; + textArea.style.position = 'fixed'; + textArea.style.left = '-999999px'; + textArea.style.top = '-999999px'; + document.body.appendChild(textArea); + textArea.focus(); + textArea.select(); try { - // 获取原始摘要内容(Markdown 源码) - const summaryContent = this.currentSessionData && this.currentSessionData.summary ? - this.currentSessionData.summary : ''; - - if (!summaryContent) { - console.warn('⚠️ 没有摘要内容可复制'); - return; - } - - // 传统复制方法 - const fallbackCopyTextToClipboard = function(text) { - const textArea = document.createElement('textarea'); - textArea.value = text; - textArea.style.position = 'fixed'; - textArea.style.left = '-999999px'; - textArea.style.top = '-999999px'; - document.body.appendChild(textArea); - textArea.focus(); - textArea.select(); - - try { - const successful = document.execCommand('copy'); - if (successful) { - console.log('✅ 摘要内容已复制到剪贴板(传统方法)'); - self.showToast('✅ 摘要已复制到剪贴板', 'success'); - } else { - console.error('❌ 复制失败(传统方法)'); - self.showToast('❌ 复制失败,请手动复制', 'error'); - } - } catch (err) { - console.error('❌ 复制失败:', err); - self.showToast('❌ 复制失败,请手动复制', 'error'); - } finally { - document.body.removeChild(textArea); - } - }; - - // 使用现代 Clipboard API - if (navigator.clipboard && window.isSecureContext) { - navigator.clipboard.writeText(summaryContent).then(function() { - console.log('✅ 摘要内容已复制到剪贴板'); - self.showToast('✅ 摘要已复制到剪贴板', 'success'); - }).catch(function(err) { - console.error('❌ 复制失败:', err); - // 降级到传统方法 - fallbackCopyTextToClipboard(summaryContent); - }); + const successful = document.execCommand('copy'); + if (successful) { + // console.log('✅ 內容已複製到剪貼板(傳統方法)'); + self.showToast(successMessage, 'success'); } else { - // 降级到传统方法 - fallbackCopyTextToClipboard(summaryContent); + console.error('❌ 複製失敗(傳統方法)'); + self.showToast('❌ 複製失敗,請手動複製', 'error'); } - } catch (error) { - console.error('❌ 复制摘要时发生错误:', error); - this.showToast('❌ 复制失败,请手动复制', 'error'); + } catch (err) { + console.error('❌ 複製失敗:', err); + self.showToast('❌ 複製失敗,請手動複製', 'error'); + } finally { + document.body.removeChild(textArea); } }; /** - * 复制用户消息内容到剪贴板 + * 複製摘要內容到剪貼板 + */ + SessionDetailsModal.prototype.copySummaryToClipboard = function() { + const self = this; + + try { + // 獲取原始摘要內容(Markdown 原始碼) + const summaryContent = this.currentSessionData && this.currentSessionData.summary ? + this.currentSessionData.summary : ''; + + if (!summaryContent) { + console.warn('⚠️ 沒有摘要內容可複製'); + return; + } + + // 使用現代 Clipboard API + if (navigator.clipboard && window.isSecureContext) { + navigator.clipboard.writeText(summaryContent).then(function() { + // console.log('✅ 摘要內容已複製到剪貼板'); + self.showToast('✅ 摘要已複製到剪貼板', 'success'); + }).catch(function(err) { + console.error('❌ 複製失敗:', err); + // 降級到傳統方法 + self.fallbackCopyTextToClipboard(summaryContent, '✅ 摘要已複製到剪貼板'); + }); + } else { + // 降級到傳統方法 + this.fallbackCopyTextToClipboard(summaryContent, '✅ 摘要已複製到剪貼板'); + } + } catch (error) { + console.error('❌ 複製摘要時發生錯誤:', error); + this.showToast('❌ 複製失敗,請手動複製', 'error'); + } + }; + + /** + * 複製用戶消息內容到剪貼板 */ SessionDetailsModal.prototype.copyMessageToClipboard = function(messageContent) { if (!messageContent) { - console.warn('⚠️ 没有消息内容可复制'); + console.warn('⚠️ 沒有消息內容可複製'); return; } const self = this; try { - // 使用现代 Clipboard API + // 使用現代 Clipboard API if (navigator.clipboard && window.isSecureContext) { navigator.clipboard.writeText(messageContent).then(function() { - console.log('✅ 用户消息已复制到剪贴板'); - self.showToast('✅ 消息已复制到剪贴板', 'success'); + // console.log('✅ 用戶消息已複製到剪貼板'); + self.showToast('✅ 消息已複製到剪貼板', 'success'); }).catch(function(err) { - console.error('❌ 复制失败:', err); - // 降级到传统方法 - fallbackCopyTextToClipboard(messageContent); + console.error('❌ 複製失敗:', err); + // 降級到傳統方法 + self.fallbackCopyTextToClipboard(messageContent, '✅ 消息已複製到剪貼板'); }); } else { - // 降级到传统方法 - fallbackCopyTextToClipboard(messageContent); + // 降級到傳統方法 + this.fallbackCopyTextToClipboard(messageContent, '✅ 消息已複製到剪貼板'); } - - // 传统复制方法 - const fallbackCopyTextToClipboard = function(text) { - const textArea = document.createElement('textarea'); - textArea.value = text; - textArea.style.position = 'fixed'; - textArea.style.left = '-999999px'; - textArea.style.top = '-999999px'; - document.body.appendChild(textArea); - textArea.focus(); - textArea.select(); - - try { - const successful = document.execCommand('copy'); - if (successful) { - console.log('✅ 用户消息已复制到剪贴板(传统方法)'); - self.showToast('✅ 消息已复制到剪贴板', 'success'); - } else { - console.error('❌ 复制失败(传统方法)'); - self.showToast('❌ 复制失败,请手动复制', 'error'); - } - } catch (err) { - console.error('❌ 复制失败:', err); - self.showToast('❌ 复制失败,请手动复制', 'error'); - } finally { - document.body.removeChild(textArea); - } - }; } catch (error) { - console.error('❌ 复制用户消息时发生错误:', error); - this.showToast('❌ 复制失败,请手动复制', 'error'); + console.error('❌ 複製用戶消息時發生錯誤:', error); + this.showToast('❌ 複製失敗,請手動複製', 'error'); } }; /** - * 显示提示消息 + * 顯示提示消息 */ SessionDetailsModal.prototype.showToast = function(message, type) { - // 创建提示元素 + // 創建提示元素 const toast = document.createElement('div'); toast.className = 'copy-toast copy-toast-' + type; toast.textContent = message; - // 添加到弹窗中 + // 添加到彈窗中 if (this.currentModal) { this.currentModal.appendChild(toast); - // 显示动画 + // 顯示動畫 setTimeout(function() { toast.classList.add('show'); }, 10); - // 自动隐藏 + // 自動隱藏 setTimeout(function() { toast.classList.remove('show'); setTimeout(function() { @@ -608,12 +583,12 @@ */ SessionDetailsModal.prototype.cleanup = function() { this.forceCloseAll(); - console.log('🔍 SessionDetailsModal 清理完成'); + // console.log('🔍 SessionDetailsModal 清理完成'); }; // 將 SessionDetailsModal 加入命名空間 window.MCPFeedback.Session.DetailsModal = SessionDetailsModal; - console.log('✅ SessionDetailsModal 模組載入完成'); + // console.log('✅ SessionDetailsModal 模組載入完成'); })(); diff --git a/src/mcp_feedback_enhanced/web/static/js/modules/session/session-ui-renderer.js b/src/mcp_feedback_enhanced/web/static/js/modules/session/session-ui-renderer.js index 12d5b3b..98ca393 100644 --- a/src/mcp_feedback_enhanced/web/static/js/modules/session/session-ui-renderer.js +++ b/src/mcp_feedback_enhanced/web/static/js/modules/session/session-ui-renderer.js @@ -20,6 +20,9 @@ new window.MCPFeedback.Logger({ moduleName: 'SessionUIRenderer' }) : console; const StatusUtils = window.MCPFeedback.Utils.Status; + + // 調試模式標誌 - 生產環境應設為 false + const DEBUG_MODE = false; /** * 會話 UI 渲染器 @@ -80,31 +83,31 @@ * 初始化專案路徑顯示 */ SessionUIRenderer.prototype.initializeProjectPathDisplay = function() { - console.log('🎨 初始化專案路徑顯示'); + if (DEBUG_MODE) console.log('🎨 初始化專案路徑顯示'); const projectPathElement = document.getElementById('projectPathDisplay'); - console.log('🎨 初始化時找到專案路徑元素:', !!projectPathElement); + if (DEBUG_MODE) console.log('🎨 初始化時找到專案路徑元素:', !!projectPathElement); if (projectPathElement) { const fullPath = projectPathElement.getAttribute('data-full-path'); - console.log('🎨 初始化時的完整路徑:', fullPath); + if (DEBUG_MODE) console.log('🎨 初始化時的完整路徑:', fullPath); if (fullPath) { // 使用工具函數截斷路徑 const pathResult = window.MCPFeedback.Utils.truncatePathFromRight(fullPath, 2, 40); - console.log('🎨 初始化時路徑處理:', { fullPath, shortPath: pathResult.truncated }); + if (DEBUG_MODE) console.log('🎨 初始化時路徑處理:', { fullPath, shortPath: pathResult.truncated }); // 更新顯示文字 DOMUtils.safeSetTextContent(projectPathElement, pathResult.truncated); // 添加點擊複製功能 if (!projectPathElement.hasAttribute('data-copy-handler')) { - console.log('🎨 初始化時添加點擊複製功能'); + if (DEBUG_MODE) console.log('🎨 初始化時添加點擊複製功能'); projectPathElement.setAttribute('data-copy-handler', 'true'); projectPathElement.addEventListener('click', function() { - console.log('🎨 初始化的專案路徑被點擊'); + if (DEBUG_MODE) console.log('🎨 初始化的專案路徑被點擊'); const fullPath = this.getAttribute('data-full-path'); - console.log('🎨 初始化時準備複製路徑:', fullPath); + if (DEBUG_MODE) console.log('🎨 初始化時準備複製路徑:', fullPath); if (fullPath) { const successMessage = window.i18nManager ? @@ -114,12 +117,12 @@ window.i18nManager.t('app.pathCopyFailed', '複製路徑失敗') : '複製路徑失敗'; - console.log('🎨 初始化時調用複製函數'); + if (DEBUG_MODE) console.log('🎨 初始化時調用複製函數'); window.MCPFeedback.Utils.copyToClipboard(fullPath, successMessage, errorMessage); } }); } else { - console.log('🎨 初始化時點擊複製功能已存在'); + if (DEBUG_MODE) console.log('🎨 初始化時點擊複製功能已存在'); } // 添加 tooltip 位置自動調整 @@ -168,7 +171,7 @@ * 執行實際的當前會話渲染 */ SessionUIRenderer.prototype._performCurrentSessionRender = function(sessionData, isNewSession) { - console.log('🎨 渲染當前會話:', sessionData); + if (DEBUG_MODE) console.log('🎨 渲染當前會話:', sessionData); // 更新快取 this.lastRenderedData.currentSessionId = sessionData.session_id; @@ -176,7 +179,7 @@ // 如果是新會話,重置活躍時間定時器 if (isNewSession) { - console.log('🎨 檢測到新會話,重置活躍時間定時器'); + if (DEBUG_MODE) console.log('🎨 檢測到新會話,重置活躍時間定時器'); this.resetActiveTimeTimer(); } @@ -258,17 +261,17 @@ * 更新頂部狀態列的專案路徑顯示 */ SessionUIRenderer.prototype.updateTopProjectPathDisplay = function(sessionData) { - console.log('🎨 updateProjectPathDisplay 被調用:', sessionData); + if (DEBUG_MODE) console.log('🎨 updateProjectPathDisplay 被調用:', sessionData); const projectPathElement = document.getElementById('projectPathDisplay'); - console.log('🎨 找到專案路徑元素:', !!projectPathElement); + if (DEBUG_MODE) console.log('🎨 找到專案路徑元素:', !!projectPathElement); if (projectPathElement && sessionData.project_directory) { const fullPath = sessionData.project_directory; // 使用工具函數截斷路徑 const pathResult = window.MCPFeedback.Utils.truncatePathFromRight(fullPath, 2, 40); - console.log('🎨 路徑處理:', { fullPath, shortPath: pathResult.truncated }); + if (DEBUG_MODE) console.log('🎨 路徑處理:', { fullPath, shortPath: pathResult.truncated }); // 更新顯示文字 DOMUtils.safeSetTextContent(projectPathElement, pathResult.truncated); @@ -278,12 +281,12 @@ // 添加點擊複製功能(如果還沒有) if (!projectPathElement.hasAttribute('data-copy-handler')) { - console.log('🎨 添加點擊複製功能'); + if (DEBUG_MODE) console.log('🎨 添加點擊複製功能'); projectPathElement.setAttribute('data-copy-handler', 'true'); projectPathElement.addEventListener('click', function() { - console.log('🎨 專案路徑被點擊'); + if (DEBUG_MODE) console.log('🎨 專案路徑被點擊'); const fullPath = this.getAttribute('data-full-path'); - console.log('🎨 準備複製路徑:', fullPath); + if (DEBUG_MODE) console.log('🎨 準備複製路徑:', fullPath); if (fullPath) { const successMessage = window.i18nManager ? @@ -293,12 +296,12 @@ window.i18nManager.t('app.pathCopyFailed', '複製路徑失敗') : '複製路徑失敗'; - console.log('🎨 調用複製函數'); + if (DEBUG_MODE) console.log('🎨 調用複製函數'); window.MCPFeedback.Utils.copyToClipboard(fullPath, successMessage, errorMessage); } }); } else { - console.log('🎨 點擊複製功能已存在'); + if (DEBUG_MODE) console.log('🎨 點擊複製功能已存在'); } // 添加 tooltip 位置自動調整 @@ -352,7 +355,7 @@ SessionUIRenderer.prototype.updateSessionStatusBar = function(sessionData) { if (!sessionData) return; - console.log('🎨 更新會話狀態列:', sessionData); + if (DEBUG_MODE) console.log('🎨 更新會話狀態列:', sessionData); // 更新當前會話 ID - 顯示縮短版本,完整ID存在data-full-id中 const currentSessionElement = document.getElementById('currentSessionId'); @@ -413,7 +416,7 @@ * 執行實際的會話歷史渲染 */ SessionUIRenderer.prototype._performHistoryRender = function(sessionHistory) { - console.log('🎨 渲染會話歷史:', sessionHistory.length, '個會話'); + if (DEBUG_MODE) console.log('🎨 渲染會話歷史:', sessionHistory.length, '個會話'); // 更新快取 this.lastRenderedData.historyLength = sessionHistory.length; @@ -477,23 +480,39 @@ SessionUIRenderer.prototype.createSessionHeader = function(sessionData) { const header = DOMUtils.createElement('div', { className: 'session-header' }); - // 會話 ID - const sessionIdLabel = window.i18nManager ? window.i18nManager.t('sessionManagement.sessionId') : '會話 ID'; - const sessionId = DOMUtils.createElement('div', { - className: 'session-id', - textContent: sessionIdLabel + ': ' + (sessionData.session_id || '').substring(0, 8) + '...' + // 會話 ID 容器 + const sessionIdContainer = DOMUtils.createElement('div', { + className: 'session-id' }); + // 會話 ID 標籤 + const sessionIdLabel = DOMUtils.createElement('span', { + attributes: { + 'data-i18n': 'sessionManagement.sessionId' + }, + textContent: window.i18nManager ? window.i18nManager.t('sessionManagement.sessionId') : '會話 ID' + }); + + // 會話 ID 值 + const sessionIdValue = DOMUtils.createElement('span', { + textContent: ': ' + (sessionData.session_id || '').substring(0, 8) + '...' + }); + + sessionIdContainer.appendChild(sessionIdLabel); + sessionIdContainer.appendChild(sessionIdValue); + // 狀態徽章 const statusContainer = DOMUtils.createElement('div', { className: 'session-status' }); const statusText = StatusUtils.getStatusText(sessionData.status); // 添加調試信息 - console.log('🎨 會話狀態調試:', { - sessionId: sessionData.session_id ? sessionData.session_id.substring(0, 8) + '...' : 'unknown', - rawStatus: sessionData.status, - displayText: statusText - }); + if (DEBUG_MODE) { + console.log('🎨 會話狀態調試:', { + sessionId: sessionData.session_id ? sessionData.session_id.substring(0, 8) + '...' : 'unknown', + rawStatus: sessionData.status, + displayText: statusText + }); + } const statusBadge = DOMUtils.createElement('span', { className: 'status-badge ' + (sessionData.status || 'waiting'), @@ -501,7 +520,7 @@ }); statusContainer.appendChild(statusBadge); - header.appendChild(sessionId); + header.appendChild(sessionIdContainer); header.appendChild(statusContainer); return header; @@ -513,31 +532,57 @@ SessionUIRenderer.prototype.createSessionInfo = function(sessionData, isHistory) { const info = DOMUtils.createElement('div', { className: 'session-info' }); - // 時間資訊 + // 時間資訊容器 + const timeContainer = DOMUtils.createElement('div', { + className: 'session-time' + }); + + // 時間標籤 + const timeLabelKey = isHistory ? 'sessionManagement.createdTime' : 'sessionManagement.createdTime'; + const timeLabel = DOMUtils.createElement('span', { + attributes: { + 'data-i18n': timeLabelKey + }, + textContent: window.i18nManager ? window.i18nManager.t(timeLabelKey) : '建立時間' + }); + + // 時間值 const timeText = sessionData.created_at ? TimeUtils.formatTimestamp(sessionData.created_at, { format: 'time' }) : '--:--:--'; - - const timeLabel = isHistory ? - (window.i18nManager ? window.i18nManager.t('sessionManagement.sessionDetails.duration') : '完成時間') : - (window.i18nManager ? window.i18nManager.t('sessionManagement.createdTime') : '建立時間'); - - const timeElement = DOMUtils.createElement('div', { - className: 'session-time', - textContent: timeLabel + ': ' + timeText + const timeValue = DOMUtils.createElement('span', { + textContent: ': ' + timeText }); - info.appendChild(timeElement); + timeContainer.appendChild(timeLabel); + timeContainer.appendChild(timeValue); + info.appendChild(timeContainer); // 歷史會話顯示持續時間 if (isHistory) { const duration = this.calculateDisplayDuration(sessionData); - const durationLabel = window.i18nManager ? window.i18nManager.t('sessionManagement.sessionDetails.duration') : '持續時間'; - const durationElement = DOMUtils.createElement('div', { - className: 'session-duration', - textContent: durationLabel + ': ' + duration + + // 持續時間容器 + const durationContainer = DOMUtils.createElement('div', { + className: 'session-duration' }); - info.appendChild(durationElement); + + // 持續時間標籤 + const durationLabel = DOMUtils.createElement('span', { + attributes: { + 'data-i18n': 'sessionManagement.sessionDetails.duration' + }, + textContent: window.i18nManager ? window.i18nManager.t('sessionManagement.sessionDetails.duration') : '持續時間' + }); + + // 持續時間值 + const durationValue = DOMUtils.createElement('span', { + textContent: ': ' + duration + }); + + durationContainer.appendChild(durationLabel); + durationContainer.appendChild(durationValue); + info.appendChild(durationContainer); } return info; @@ -564,13 +609,13 @@ SessionUIRenderer.prototype.createSessionActions = function(sessionData, isHistory) { const actions = DOMUtils.createElement('div', { className: 'session-actions' }); - const buttonText = isHistory ? - (window.i18nManager ? window.i18nManager.t('sessionManagement.viewDetails') : '查看') : - (window.i18nManager ? window.i18nManager.t('sessionManagement.viewDetails') : '詳細資訊'); - + // 查看詳情按鈕 const viewButton = DOMUtils.createElement('button', { className: 'btn-small', - textContent: buttonText + attributes: { + 'data-i18n': 'sessionManagement.viewDetails' + }, + textContent: window.i18nManager ? window.i18nManager.t('sessionManagement.viewDetails') : '詳細資訊' }); // 添加查看詳情點擊事件 @@ -586,7 +631,10 @@ if (isHistory) { const exportButton = DOMUtils.createElement('button', { className: 'btn-small btn-export', - textContent: window.i18nManager ? window.i18nManager.t('sessionHistory.management.exportSingle') : '匯出', + attributes: { + 'data-i18n': 'sessionHistory.management.exportSingle' + }, + textContent: window.i18nManager ? window.i18nManager.t('sessionHistory.management.exportSingle') : '匯出此會話', style: 'margin-left: 4px; font-size: 11px; padding: 2px 6px;' }); @@ -695,7 +743,7 @@ self.updateActiveTime(); }, 1000); - console.log('🎨 活躍時間定時器已啟動'); + if (DEBUG_MODE) console.log('🎨 活躍時間定時器已啟動'); }; /** @@ -705,7 +753,7 @@ if (this.activeTimeTimer) { clearInterval(this.activeTimeTimer); this.activeTimeTimer = null; - console.log('🎨 活躍時間定時器已停止'); + if (DEBUG_MODE) console.log('🎨 活躍時間定時器已停止'); } }; @@ -758,12 +806,12 @@ currentSessionId: null }; - console.log('🎨 SessionUIRenderer 清理完成'); + if (DEBUG_MODE) console.log('🎨 SessionUIRenderer 清理完成'); }; // 將 SessionUIRenderer 加入命名空間 window.MCPFeedback.Session.UIRenderer = SessionUIRenderer; - console.log('✅ SessionUIRenderer 模組載入完成'); + if (DEBUG_MODE) console.log('✅ SessionUIRenderer 模組載入完成'); })(); diff --git a/src/mcp_feedback_enhanced/web/templates/feedback.html b/src/mcp_feedback_enhanced/web/templates/feedback.html index 3f2617d..92c09a4 100644 --- a/src/mcp_feedback_enhanced/web/templates/feedback.html +++ b/src/mcp_feedback_enhanced/web/templates/feedback.html @@ -657,8 +657,18 @@
- - + +