feat: 添加"弹出文件管理器窗口"设置项
This commit is contained in:
@@ -41,6 +41,7 @@ export const settingsController = {
|
||||
'autoCopyOnSelect', 'dockerStatusIntervalSeconds', 'dockerDefaultExpand',
|
||||
'statusMonitorIntervalSeconds', // +++ 添加状态监控间隔键 +++
|
||||
'workspaceSidebarPersistent', // +++ 添加侧边栏固定键 +++
|
||||
'showPopupFileManager', // +++ 添加弹窗文件管理器设置键 +++
|
||||
'sidebarPaneWidths', // +++ 添加侧边栏宽度对象键 +++
|
||||
'fileManagerRowSizeMultiplier', // +++ 添加文件管理器行大小键 +++
|
||||
'fileManagerColWidths', // +++ 添加文件管理器列宽键 +++
|
||||
|
||||
@@ -25,7 +25,7 @@ const commandHistoryStore = useCommandHistoryStore();
|
||||
const sessionStore = useSessionStore(); // +++ 初始化 Session Store +++
|
||||
|
||||
// Get reactive setting from store
|
||||
const { commandInputSyncTarget } = storeToRefs(settingsStore);
|
||||
const { commandInputSyncTarget, showPopupFileManagerBoolean } = storeToRefs(settingsStore); // +++ Import showPopupFileManagerBoolean +++
|
||||
// Get reactive state and actions from quick commands store
|
||||
const { selectedIndex: quickCommandsSelectedIndex, flatVisibleCommands: quickCommandsFiltered } = storeToRefs(quickCommandsStore);
|
||||
const { resetSelection: resetQuickCommandsSelection } = quickCommandsStore;
|
||||
@@ -298,6 +298,17 @@ const closeSuspendedSshSessionsModal = () => {
|
||||
showSuspendedSshSessionsModal.value = false;
|
||||
};
|
||||
|
||||
// +++ Function to request opening the file manager modal via event bus +++
|
||||
const openFileManagerModal = () => {
|
||||
if (activeSessionId.value) {
|
||||
console.log(`[CommandInputBar] Emitting fileManager:openModalRequest for session: ${activeSessionId.value}`);
|
||||
emitWorkspaceEvent('fileManager:openModalRequest', { sessionId: activeSessionId.value });
|
||||
} else {
|
||||
console.warn('[CommandInputBar] Cannot open file manager modal: No active session ID.');
|
||||
// Optionally, show a notification to the user
|
||||
}
|
||||
};
|
||||
|
||||
// +++ Handler for command execution from the modal +++
|
||||
const handleQuickCommandExecute = (command: string) => {
|
||||
console.log(`[CommandInputBar] Executing quick command: ${command}`);
|
||||
@@ -400,6 +411,15 @@ const handleQuickCommandExecute = (command: string) => {
|
||||
<i v-if="!isSearching" class="fas fa-search text-base"></i>
|
||||
<i v-else class="fas fa-times text-base"></i>
|
||||
</button>
|
||||
<!-- File Manager Button -->
|
||||
<button
|
||||
v-if="showPopupFileManagerBoolean"
|
||||
@click="openFileManagerModal"
|
||||
class="flex-shrink-0 flex items-center justify-center w-8 h-8 border border-border/50 rounded-lg text-text-secondary transition-colors duration-200 hover:bg-border hover:text-foreground"
|
||||
:title="t('fileManager.title', '文件管理器')"
|
||||
>
|
||||
<i class="fas fa-folder text-base"></i>
|
||||
</button>
|
||||
|
||||
<!-- Search navigation buttons (Hide on mobile when searching) -->
|
||||
<template v-if="isSearching && !props.isMobile"> <!-- +++ Add !props.isMobile condition +++ -->
|
||||
@@ -434,6 +454,7 @@ const handleQuickCommandExecute = (command: string) => {
|
||||
:is-visible="showSuspendedSshSessionsModal"
|
||||
@close="closeSuspendedSshSessionsModal"
|
||||
/>
|
||||
<!-- File Manager Modal is now handled by a listener for 'fileManager:openModalRequest' event -->
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
|
||||
@@ -21,6 +21,26 @@
|
||||
</form>
|
||||
</div>
|
||||
<hr class="border-border/50">
|
||||
<!-- Popup File Manager -->
|
||||
<div class="settings-section-content">
|
||||
<h3 class="text-base font-semibold text-foreground mb-3">{{ t('settings.popupFileManager.title') }}</h3>
|
||||
<form @submit.prevent="handleUpdateShowPopupFileManager" class="space-y-4">
|
||||
<div class="flex items-center">
|
||||
<input type="checkbox" id="showPopupFileManager" v-model="showPopupFileManagerLocal"
|
||||
class="h-4 w-4 rounded border-border text-primary focus:ring-primary mr-2 cursor-pointer">
|
||||
<label for="showPopupFileManager" class="text-sm text-foreground cursor-pointer select-none">{{ t('settings.popupFileManager.enableLabel') }}</label>
|
||||
</div>
|
||||
<small class="block mt-1 text-xs text-text-secondary">{{ t('settings.popupFileManager.description') }}</small>
|
||||
<div class="flex items-center justify-between">
|
||||
<button type="submit"
|
||||
class="px-4 py-2 bg-button text-button-text rounded-md shadow-sm hover:bg-button-hover focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-primary transition duration-150 ease-in-out text-sm font-medium">
|
||||
{{ t('common.save') }}
|
||||
</button>
|
||||
<p v-if="showPopupFileManagerMessage" :class="['text-sm', showPopupFileManagerSuccess ? 'text-success' : 'text-error']">{{ showPopupFileManagerMessage }}</p>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
<hr class="border-border/50">
|
||||
<!-- Share Tabs -->
|
||||
<div class="settings-section-content">
|
||||
<h3 class="text-base font-semibold text-foreground mb-3">{{ $t('settings.shareEditorTabs.title') }}</h3>
|
||||
@@ -268,6 +288,12 @@ const {
|
||||
terminalEnableRightClickPasteMessage, // NEW
|
||||
terminalEnableRightClickPasteSuccess, // NEW
|
||||
handleUpdateTerminalRightClickPasteSetting, // NEW
|
||||
// Popup File Manager
|
||||
showPopupFileManagerLocal,
|
||||
// showPopupFileManagerLoading, // Not used
|
||||
showPopupFileManagerMessage,
|
||||
showPopupFileManagerSuccess,
|
||||
handleUpdateShowPopupFileManager,
|
||||
} = useWorkspaceSettings();
|
||||
</script>
|
||||
|
||||
|
||||
@@ -163,7 +163,6 @@ export function useSystemSettings() {
|
||||
selectedLanguage.value = newVal;
|
||||
}, { immediate: true });
|
||||
|
||||
|
||||
return {
|
||||
// Language
|
||||
selectedLanguage,
|
||||
|
||||
@@ -18,6 +18,7 @@ export function useWorkspaceSettings() {
|
||||
terminalScrollbackLimitNumber,
|
||||
fileManagerShowDeleteConfirmationBoolean,
|
||||
terminalEnableRightClickPasteBoolean, // NEW
|
||||
showPopupFileManagerBoolean, // +++ Import the new getter +++
|
||||
} = storeToRefs(settingsStore);
|
||||
|
||||
// --- Popup Editor ---
|
||||
@@ -261,6 +262,30 @@ export function useWorkspaceSettings() {
|
||||
}
|
||||
};
|
||||
|
||||
// --- Popup File Manager ---
|
||||
const showPopupFileManagerLocal = ref(true);
|
||||
const showPopupFileManagerLoading = ref(false);
|
||||
const showPopupFileManagerMessage = ref('');
|
||||
const showPopupFileManagerSuccess = ref(false);
|
||||
|
||||
const handleUpdateShowPopupFileManager = async () => {
|
||||
showPopupFileManagerLoading.value = true;
|
||||
showPopupFileManagerMessage.value = '';
|
||||
showPopupFileManagerSuccess.value = false;
|
||||
try {
|
||||
const valueToSave = showPopupFileManagerLocal.value ? 'true' : 'false';
|
||||
await settingsStore.updateSetting('showPopupFileManager', valueToSave);
|
||||
showPopupFileManagerMessage.value = t('settings.popupFileManager.success.saved');
|
||||
showPopupFileManagerSuccess.value = true;
|
||||
} catch (error: any) {
|
||||
console.error('更新弹窗文件管理器设置失败:', error);
|
||||
showPopupFileManagerMessage.value = error.message || t('settings.popupFileManager.error.saveFailed');
|
||||
showPopupFileManagerSuccess.value = false;
|
||||
} finally {
|
||||
showPopupFileManagerLoading.value = false;
|
||||
}
|
||||
};
|
||||
|
||||
// Watchers to sync local state with store state
|
||||
watch(showPopupFileEditorBoolean, (newValue) => { popupEditorEnabled.value = newValue; }, { immediate: true });
|
||||
watch(shareFileEditorTabsBoolean, (newValue) => { shareTabsEnabled.value = newValue; }, { immediate: true });
|
||||
@@ -272,6 +297,7 @@ export function useWorkspaceSettings() {
|
||||
watch(terminalScrollbackLimitNumber, (newValue) => { terminalScrollbackLimitLocal.value = newValue; }, { immediate: true });
|
||||
watch(fileManagerShowDeleteConfirmationBoolean, (newValue) => { fileManagerShowDeleteConfirmationLocal.value = newValue; }, { immediate: true });
|
||||
watch(terminalEnableRightClickPasteBoolean, (newValue) => { terminalEnableRightClickPasteLocal.value = newValue; }, { immediate: true }); // NEW
|
||||
watch(showPopupFileManagerBoolean, (newValue) => { showPopupFileManagerLocal.value = newValue; }, { immediate: true }); // +++ Watch for popup file manager +++
|
||||
|
||||
|
||||
return {
|
||||
@@ -334,5 +360,12 @@ export function useWorkspaceSettings() {
|
||||
terminalEnableRightClickPasteMessage, // NEW
|
||||
terminalEnableRightClickPasteSuccess, // NEW
|
||||
handleUpdateTerminalRightClickPasteSetting, // NEW
|
||||
|
||||
// Popup File Manager
|
||||
showPopupFileManagerLocal,
|
||||
showPopupFileManagerLoading,
|
||||
showPopupFileManagerMessage,
|
||||
showPopupFileManagerSuccess,
|
||||
handleUpdateShowPopupFileManager,
|
||||
};
|
||||
}
|
||||
@@ -45,6 +45,7 @@ export type WorkspaceEventPayloads = {
|
||||
// UI Interaction Events
|
||||
'ui:openLayoutConfigurator': void;
|
||||
// 'ui:toggleVirtualKeyboard': void; // 如果决定迁移 CommandInputBar 的这个事件
|
||||
'fileManager:openModalRequest': { sessionId: string }; // 请求打开文件管理器模态框
|
||||
|
||||
// Suspended SSH Session Events
|
||||
'suspendedSession:actionCompleted': void; // Emitted when a resume/remove action is completed
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
{
|
||||
|
||||
"appName": "Nexus Terminal",
|
||||
"projectName": "Nexus Terminal",
|
||||
"slogan":"Stir the stars, command the terminal.",
|
||||
@@ -503,6 +504,17 @@
|
||||
"deleteFailed": "Failed to delete tag \"{name}\": {error}"
|
||||
},
|
||||
"settings": {
|
||||
"popupFileManager": {
|
||||
"title": "Popup File Manager",
|
||||
"enableLabel": "Enable Popup File Manager",
|
||||
"description": "When enabled, the file manager button will be displayed in the command input bar, allowing you to open the popup file manager.",
|
||||
"success": {
|
||||
"saved": "Popup File Manager settings saved successfully."
|
||||
},
|
||||
"error": {
|
||||
"saveFailed": "Failed to save Popup File Manager settings."
|
||||
}
|
||||
},
|
||||
"title": "Settings",
|
||||
"category": {
|
||||
"security": "Security Settings",
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
{
|
||||
|
||||
"appName": "星枢ターミナル",
|
||||
"auditLog": {
|
||||
"actions": {
|
||||
@@ -690,6 +691,17 @@
|
||||
"title": "VNCセッション"
|
||||
},
|
||||
"settings": {
|
||||
"popupFileManager": {
|
||||
"title": "ポップアップファイルマネージャー",
|
||||
"enableLabel": "ポップアップファイルマネージャーを有効にする",
|
||||
"description": "有効にすると、コマンド入力バーにファイルマネージャーボタンが表示され、ポップアップファイルマネージャーを開くことができます。",
|
||||
"success": {
|
||||
"saved": "ポップアップファイルマネージャーの設定が保存されました。"
|
||||
},
|
||||
"error": {
|
||||
"saveFailed": "ポップアップファイルマネージャーの設定の保存に失敗しました。"
|
||||
}
|
||||
},
|
||||
"appearance": {
|
||||
"customizeButton": "外観をカスタマイズ",
|
||||
"description": "アプリケーションのビジュアルテーマと背景をカスタマイズします。",
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
{
|
||||
|
||||
"appName": "星枢终端",
|
||||
"projectName": "星枢终端",
|
||||
"slogan": "星垂平野阔,枢动万端通",
|
||||
@@ -502,6 +503,17 @@
|
||||
"deleteFailed": "标签 \"{name}\" 删除失败: {error}"
|
||||
},
|
||||
"settings": {
|
||||
"popupFileManager": {
|
||||
"title": "弹窗文件管理器",
|
||||
"enableLabel": "启用弹窗文件管理器",
|
||||
"description": "启用后,命令输入栏将显示文件管理器按钮,点击可打开弹窗式文件管理器。",
|
||||
"success": {
|
||||
"saved": "弹窗文件管理器设置已保存。"
|
||||
},
|
||||
"error": {
|
||||
"saveFailed": "保存弹窗文件管理器设置失败。"
|
||||
}
|
||||
},
|
||||
"title": "设置",
|
||||
"category": {
|
||||
"security": "安全设置",
|
||||
|
||||
@@ -36,6 +36,7 @@ interface SettingsState {
|
||||
maxLoginAttempts?: string;
|
||||
loginBanDuration?: string;
|
||||
showPopupFileEditor?: string; // 'true' or 'false'
|
||||
showPopupFileManager?: string; // 'true' or 'false' - NEW: 弹窗文件管理器
|
||||
shareFileEditorTabs?: string; // 'true' or 'false'
|
||||
ipWhitelistEnabled?: string; // 添加 IP 白名单启用状态 'true' or 'false'
|
||||
autoCopyOnSelect?: string; // 'true' or 'false' - 终端选中自动复制
|
||||
@@ -114,6 +115,10 @@ export const useSettingsStore = defineStore('settings', () => {
|
||||
if (settings.value.showPopupFileEditor === undefined) {
|
||||
settings.value.showPopupFileEditor = 'true';
|
||||
}
|
||||
// +++ 添加 showPopupFileManager 默认值 (改为 false) +++
|
||||
if (settings.value.showPopupFileManager === undefined) {
|
||||
settings.value.showPopupFileManager = 'false'; // 默认禁用弹窗文件管理器
|
||||
}
|
||||
if (settings.value.shareFileEditorTabs === undefined) {
|
||||
settings.value.shareFileEditorTabs = 'true';
|
||||
}
|
||||
@@ -371,7 +376,7 @@ export const useSettingsStore = defineStore('settings', () => {
|
||||
// 移除外观相关的键检查
|
||||
const allowedKeys: Array<keyof SettingsState> = [
|
||||
'language', 'ipWhitelist', 'maxLoginAttempts', 'loginBanDuration',
|
||||
'showPopupFileEditor', 'shareFileEditorTabs', 'ipWhitelistEnabled',
|
||||
'showPopupFileEditor', 'showPopupFileManager', 'shareFileEditorTabs', 'ipWhitelistEnabled', // +++ 添加 showPopupFileManager +++
|
||||
'autoCopyOnSelect', 'dockerStatusIntervalSeconds', 'dockerDefaultExpand',
|
||||
'statusMonitorIntervalSeconds', // +++ 添加状态监控间隔键 +++
|
||||
'workspaceSidebarPersistent', // +++ 添加侧边栏固定键 +++
|
||||
@@ -466,7 +471,7 @@ export const useSettingsStore = defineStore('settings', () => {
|
||||
// 移除外观相关的键检查
|
||||
const allowedKeys: Array<keyof SettingsState> = [
|
||||
'language', 'ipWhitelist', 'maxLoginAttempts', 'loginBanDuration',
|
||||
'showPopupFileEditor', 'shareFileEditorTabs', 'ipWhitelistEnabled',
|
||||
'showPopupFileEditor', 'showPopupFileManager', 'shareFileEditorTabs', 'ipWhitelistEnabled', // +++ 添加 showPopupFileManager +++
|
||||
'autoCopyOnSelect', 'dockerStatusIntervalSeconds', 'dockerDefaultExpand',
|
||||
'statusMonitorIntervalSeconds', // +++ 添加状态监控间隔键 +++
|
||||
'workspaceSidebarPersistent', // +++ 添加侧边栏固定键 +++
|
||||
@@ -664,6 +669,11 @@ export const useSettingsStore = defineStore('settings', () => {
|
||||
return settings.value.showPopupFileEditor !== 'false';
|
||||
});
|
||||
|
||||
// +++ Getter for popup file manager setting, returning boolean +++
|
||||
const showPopupFileManagerBoolean = computed(() => {
|
||||
return settings.value.showPopupFileManager !== 'false'; // Default to true
|
||||
});
|
||||
|
||||
// Getter for sharing setting, returning boolean
|
||||
const shareFileEditorTabsBoolean = computed(() => {
|
||||
return settings.value.shareFileEditorTabs !== 'false';
|
||||
@@ -791,6 +801,7 @@ export const useSettingsStore = defineStore('settings', () => {
|
||||
error,
|
||||
language,
|
||||
showPopupFileEditorBoolean,
|
||||
showPopupFileManagerBoolean, // +++ 暴露弹窗文件管理器 getter +++
|
||||
shareFileEditorTabsBoolean,
|
||||
ipWhitelistEnabled, // 暴露 IP 白名单启用状态
|
||||
ipBlacklistEnabledBoolean, // <-- NEW: 暴露 IP 黑名单启用状态 getter
|
||||
|
||||
Reference in New Issue
Block a user