473 lines
16 KiB
JavaScript
Raw Normal View History

2025-06-10 07:19:47 +08:00
/**
* MCP Feedback Enhanced - UI 管理模組
* =================================
*
* 處理 UI 狀態更新指示器管理和頁籤切換
*/
(function() {
'use strict';
// 確保命名空間和依賴存在
window.MCPFeedback = window.MCPFeedback || {};
const Utils = window.MCPFeedback.Utils;
/**
* UI 管理器建構函數
*/
function UIManager(options) {
options = options || {};
// 當前狀態
this.currentTab = options.currentTab || 'combined';
this.feedbackState = Utils.CONSTANTS.FEEDBACK_WAITING;
this.layoutMode = options.layoutMode || 'combined-vertical';
this.lastSubmissionTime = null;
// UI 元素
this.connectionIndicator = null;
this.connectionText = null;
this.tabButtons = null;
this.tabContents = null;
this.submitBtn = null;
this.feedbackText = null;
// 回調函數
this.onTabChange = options.onTabChange || null;
this.onLayoutModeChange = options.onLayoutModeChange || null;
this.initUIElements();
}
/**
* 初始化 UI 元素
*/
UIManager.prototype.initUIElements = function() {
// 基本 UI 元素
this.connectionIndicator = Utils.safeQuerySelector('#connectionIndicator');
this.connectionText = Utils.safeQuerySelector('#connectionText');
// 頁籤相關元素
this.tabButtons = document.querySelectorAll('.tab-button');
this.tabContents = document.querySelectorAll('.tab-content');
// 回饋相關元素
this.feedbackText = Utils.safeQuerySelector('#feedbackText');
this.submitBtn = Utils.safeQuerySelector('#submitBtn');
console.log('✅ UI 元素初始化完成');
};
/**
* 初始化頁籤功能
*/
UIManager.prototype.initTabs = function() {
const self = this;
// 設置頁籤點擊事件
this.tabButtons.forEach(function(button) {
button.addEventListener('click', function() {
const tabName = button.getAttribute('data-tab');
self.switchTab(tabName);
});
});
// 根據佈局模式確定初始頁籤
let initialTab = this.currentTab;
if (this.layoutMode.startsWith('combined')) {
initialTab = 'combined';
} else if (this.currentTab === 'combined') {
initialTab = 'feedback';
}
// 設置初始頁籤
this.setInitialTab(initialTab);
};
/**
* 設置初始頁籤不觸發保存
*/
UIManager.prototype.setInitialTab = function(tabName) {
this.currentTab = tabName;
this.updateTabDisplay(tabName);
this.handleSpecialTabs(tabName);
console.log('初始化頁籤: ' + tabName);
};
/**
* 切換頁籤
*/
UIManager.prototype.switchTab = function(tabName) {
this.currentTab = tabName;
this.updateTabDisplay(tabName);
this.handleSpecialTabs(tabName);
// 觸發回調
if (this.onTabChange) {
this.onTabChange(tabName);
}
console.log('切換到頁籤: ' + tabName);
};
/**
* 更新頁籤顯示
*/
UIManager.prototype.updateTabDisplay = function(tabName) {
// 更新按鈕狀態
this.tabButtons.forEach(function(button) {
if (button.getAttribute('data-tab') === tabName) {
button.classList.add('active');
} else {
button.classList.remove('active');
}
});
// 更新內容顯示
this.tabContents.forEach(function(content) {
if (content.id === 'tab-' + tabName) {
content.classList.add('active');
} else {
content.classList.remove('active');
}
});
};
/**
* 處理特殊頁籤
*/
UIManager.prototype.handleSpecialTabs = function(tabName) {
if (tabName === 'combined') {
this.handleCombinedMode();
}
};
/**
* 處理合併模式
*/
UIManager.prototype.handleCombinedMode = function() {
console.log('切換到組合模式');
// 確保合併模式的佈局樣式正確應用
const combinedTab = Utils.safeQuerySelector('#tab-combined');
if (combinedTab) {
combinedTab.classList.remove('combined-vertical', 'combined-horizontal');
if (this.layoutMode === 'combined-vertical') {
combinedTab.classList.add('combined-vertical');
} else if (this.layoutMode === 'combined-horizontal') {
combinedTab.classList.add('combined-horizontal');
}
}
};
/**
* 更新頁籤可見性
*/
UIManager.prototype.updateTabVisibility = function() {
const combinedTab = document.querySelector('.tab-button[data-tab="combined"]');
const feedbackTab = document.querySelector('.tab-button[data-tab="feedback"]');
const summaryTab = document.querySelector('.tab-button[data-tab="summary"]');
// 只使用合併模式顯示合併模式頁籤隱藏回饋和AI摘要頁籤
if (combinedTab) combinedTab.style.display = 'inline-block';
if (feedbackTab) feedbackTab.style.display = 'none';
if (summaryTab) summaryTab.style.display = 'none';
};
/**
* 設置回饋狀態
*/
UIManager.prototype.setFeedbackState = function(state, sessionId) {
const previousState = this.feedbackState;
this.feedbackState = state;
if (sessionId) {
console.log('🔄 會話 ID: ' + sessionId.substring(0, 8) + '...');
}
console.log('📊 狀態變更: ' + previousState + ' → ' + state);
this.updateUIState();
this.updateStatusIndicator();
};
/**
* 更新 UI 狀態
*/
UIManager.prototype.updateUIState = function() {
this.updateSubmitButton();
this.updateFeedbackInputs();
this.updateImageUploadAreas();
};
/**
* 更新提交按鈕狀態
*/
UIManager.prototype.updateSubmitButton = function() {
const submitButtons = [
Utils.safeQuerySelector('#submitBtn'),
Utils.safeQuerySelector('#combinedSubmitBtn')
].filter(function(btn) { return btn !== null; });
const self = this;
submitButtons.forEach(function(button) {
if (!button) return;
switch (self.feedbackState) {
case Utils.CONSTANTS.FEEDBACK_WAITING:
button.textContent = window.i18nManager ? window.i18nManager.t('buttons.submit') : '提交回饋';
button.className = 'btn btn-primary';
button.disabled = false;
break;
case Utils.CONSTANTS.FEEDBACK_PROCESSING:
button.textContent = window.i18nManager ? window.i18nManager.t('buttons.processing') : '處理中...';
button.className = 'btn btn-secondary';
button.disabled = true;
break;
case Utils.CONSTANTS.FEEDBACK_SUBMITTED:
button.textContent = window.i18nManager ? window.i18nManager.t('buttons.submitted') : '已提交';
button.className = 'btn btn-success';
button.disabled = true;
break;
}
});
};
/**
* 更新回饋輸入框狀態
*/
UIManager.prototype.updateFeedbackInputs = function() {
const feedbackInputs = [
Utils.safeQuerySelector('#feedbackText'),
Utils.safeQuerySelector('#combinedFeedbackText')
].filter(function(input) { return input !== null; });
const canInput = this.feedbackState === Utils.CONSTANTS.FEEDBACK_WAITING;
feedbackInputs.forEach(function(input) {
input.disabled = !canInput;
});
};
/**
* 更新圖片上傳區域狀態
*/
UIManager.prototype.updateImageUploadAreas = function() {
const uploadAreas = [
Utils.safeQuerySelector('#feedbackImageUploadArea'),
Utils.safeQuerySelector('#combinedImageUploadArea')
].filter(function(area) { return area !== null; });
const canUpload = this.feedbackState === Utils.CONSTANTS.FEEDBACK_WAITING;
uploadAreas.forEach(function(area) {
if (canUpload) {
area.classList.remove('disabled');
} else {
area.classList.add('disabled');
}
});
};
/**
* 更新狀態指示器
*/
UIManager.prototype.updateStatusIndicator = function() {
const feedbackStatusIndicator = Utils.safeQuerySelector('#feedbackStatusIndicator');
const combinedStatusIndicator = Utils.safeQuerySelector('#combinedFeedbackStatusIndicator');
const statusInfo = this.getStatusInfo();
if (feedbackStatusIndicator) {
this.updateStatusIndicatorElement(feedbackStatusIndicator, statusInfo);
}
if (combinedStatusIndicator) {
this.updateStatusIndicatorElement(combinedStatusIndicator, statusInfo);
}
console.log('✅ 狀態指示器已更新: ' + statusInfo.status + ' - ' + statusInfo.title);
};
/**
* 獲取狀態信息
*/
UIManager.prototype.getStatusInfo = function() {
let icon, title, message, status;
switch (this.feedbackState) {
case Utils.CONSTANTS.FEEDBACK_WAITING:
icon = '⏳';
title = window.i18nManager ? window.i18nManager.t('status.waiting.title') : '等待回饋';
message = window.i18nManager ? window.i18nManager.t('status.waiting.message') : '請提供您的回饋意見';
status = 'waiting';
break;
case Utils.CONSTANTS.FEEDBACK_PROCESSING:
icon = '⚙️';
title = window.i18nManager ? window.i18nManager.t('status.processing.title') : '處理中';
message = window.i18nManager ? window.i18nManager.t('status.processing.message') : '正在提交您的回饋...';
status = 'processing';
break;
case Utils.CONSTANTS.FEEDBACK_SUBMITTED:
const timeStr = this.lastSubmissionTime ?
new Date(this.lastSubmissionTime).toLocaleTimeString() : '';
icon = '✅';
title = window.i18nManager ? window.i18nManager.t('status.submitted.title') : '回饋已提交';
message = window.i18nManager ? window.i18nManager.t('status.submitted.message') : '等待下次 MCP 調用';
if (timeStr) {
message += ' (' + timeStr + ')';
}
status = 'submitted';
break;
default:
icon = '⏳';
2025-06-13 10:33:24 +08:00
title = window.i18nManager ? window.i18nManager.t('status.waiting.title') : '等待回饋';
message = window.i18nManager ? window.i18nManager.t('status.waiting.message') : '請提供您的回饋意見';
2025-06-10 07:19:47 +08:00
status = 'waiting';
}
return { icon: icon, title: title, message: message, status: status };
};
/**
* 更新單個狀態指示器元素
*/
UIManager.prototype.updateStatusIndicatorElement = function(element, statusInfo) {
if (!element) return;
// 更新狀態類別
element.className = 'feedback-status-indicator status-' + statusInfo.status;
element.style.display = 'block';
// 更新標題
const titleElement = element.querySelector('.status-title');
if (titleElement) {
titleElement.textContent = statusInfo.icon + ' ' + statusInfo.title;
}
// 更新訊息
const messageElement = element.querySelector('.status-message');
if (messageElement) {
messageElement.textContent = statusInfo.message;
}
console.log('🔧 已更新狀態指示器: ' + element.id + ' -> ' + statusInfo.status);
};
/**
* 更新連接狀態
*/
UIManager.prototype.updateConnectionStatus = function(status, text) {
if (this.connectionIndicator) {
this.connectionIndicator.className = 'connection-indicator ' + status;
}
if (this.connectionText) {
this.connectionText.textContent = text;
}
};
/**
* 更新 AI 摘要內容
*/
UIManager.prototype.updateAISummaryContent = function(summary) {
console.log('📝 更新 AI 摘要內容...');
const summaryContent = Utils.safeQuerySelector('#summaryContent');
if (summaryContent) {
summaryContent.textContent = summary;
console.log('✅ 已更新分頁模式摘要內容');
}
const combinedSummaryContent = Utils.safeQuerySelector('#combinedSummaryContent');
if (combinedSummaryContent) {
combinedSummaryContent.textContent = summary;
console.log('✅ 已更新合併模式摘要內容');
}
};
/**
* 重置回饋表單
*/
UIManager.prototype.resetFeedbackForm = function() {
console.log('🔄 重置回饋表單...');
// 清空回饋輸入
const feedbackInputs = [
Utils.safeQuerySelector('#feedbackText'),
Utils.safeQuerySelector('#combinedFeedbackText')
].filter(function(input) { return input !== null; });
feedbackInputs.forEach(function(input) {
input.value = '';
input.disabled = false;
});
// 重新啟用提交按鈕
const submitButtons = [
Utils.safeQuerySelector('#submitBtn'),
Utils.safeQuerySelector('#combinedSubmitBtn')
].filter(function(btn) { return btn !== null; });
submitButtons.forEach(function(button) {
button.disabled = false;
2025-06-13 10:33:24 +08:00
const defaultText = window.i18nManager ? window.i18nManager.t('buttons.submit') : '提交回饋';
button.textContent = button.getAttribute('data-original-text') || defaultText;
2025-06-10 07:19:47 +08:00
});
console.log('✅ 回饋表單重置完成');
};
/**
* 應用佈局模式
*/
UIManager.prototype.applyLayoutMode = function(layoutMode) {
this.layoutMode = layoutMode;
const expectedClassName = 'layout-' + layoutMode;
if (document.body.className !== expectedClassName) {
console.log('應用佈局模式: ' + layoutMode);
document.body.className = expectedClassName;
}
this.updateTabVisibility();
// 如果當前頁籤不是合併模式,則切換到合併模式頁籤
if (this.currentTab !== 'combined') {
this.currentTab = 'combined';
}
// 觸發回調
if (this.onLayoutModeChange) {
this.onLayoutModeChange(layoutMode);
}
};
/**
* 獲取當前頁籤
*/
UIManager.prototype.getCurrentTab = function() {
return this.currentTab;
};
/**
* 獲取當前回饋狀態
*/
UIManager.prototype.getFeedbackState = function() {
return this.feedbackState;
};
/**
* 設置最後提交時間
*/
UIManager.prototype.setLastSubmissionTime = function(timestamp) {
this.lastSubmissionTime = timestamp;
this.updateStatusIndicator();
};
// 將 UIManager 加入命名空間
window.MCPFeedback.UIManager = UIManager;
console.log('✅ UIManager 模組載入完成');
})();