update
This commit is contained in:
@@ -55,6 +55,21 @@
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<!-- 共享编辑器标签页设置 -->
|
||||
<div class="settings-section">
|
||||
<h2>{{ $t('settings.shareEditorTabs.title') }}</h2>
|
||||
<form @submit.prevent="handleUpdateShareTabsSetting">
|
||||
<div class="form-group form-group-checkbox">
|
||||
<input type="checkbox" id="shareEditorTabs" v-model="shareTabsEnabled">
|
||||
<label for="shareEditorTabs">{{ $t('settings.shareEditorTabs.enableLabel') }}</label>
|
||||
</div>
|
||||
<p class="setting-description">{{ $t('settings.shareEditorTabs.description') }}</p>
|
||||
<button type="submit" :disabled="shareTabsLoading">{{ shareTabsLoading ? $t('common.saving') : $t('settings.shareEditorTabs.saveButton') }}</button>
|
||||
<p v-if="shareTabsMessage" :class="{ 'success-message': shareTabsSuccess, 'error-message': !shareTabsSuccess }">{{ shareTabsMessage }}</p>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
|
||||
<hr>
|
||||
|
||||
<div class="settings-section">
|
||||
@@ -197,6 +212,7 @@ import { ref, onMounted, computed, reactive, watch, toRefs } from 'vue';
|
||||
import { useAuthStore } from '../stores/auth.store';
|
||||
import { useSettingsStore } from '../stores/settings.store';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
import { storeToRefs } from 'pinia'; // 导入 storeToRefs
|
||||
// setLocale is handled by the store now
|
||||
import axios from 'axios';
|
||||
import { startRegistration } from '@simplewebauthn/browser';
|
||||
@@ -206,7 +222,8 @@ const settingsStore = useSettingsStore();
|
||||
const { t } = useI18n();
|
||||
|
||||
// --- Reactive state from store ---
|
||||
const { settings, isLoading: settingsLoading, error: settingsError, showPopupFileEditorBoolean } = toRefs(settingsStore);
|
||||
// 使用 storeToRefs 获取响应式 getter
|
||||
const { settings, isLoading: settingsLoading, error: settingsError, showPopupFileEditorBoolean, shareFileEditorTabsBoolean } = storeToRefs(settingsStore);
|
||||
|
||||
// --- Local state for forms ---
|
||||
const ipWhitelistInput = ref('');
|
||||
@@ -230,6 +247,10 @@ const blacklistSettingsSuccess = ref(false);
|
||||
const popupEditorLoading = ref(false);
|
||||
const popupEditorMessage = ref('');
|
||||
const popupEditorSuccess = ref(false);
|
||||
const shareTabsEnabled = ref(true); // 本地状态,用于共享标签页 v-model
|
||||
const shareTabsLoading = ref(false);
|
||||
const shareTabsMessage = ref('');
|
||||
const shareTabsSuccess = ref(false);
|
||||
|
||||
// --- Watcher to sync local form state with store state ---
|
||||
watch(settings, (newSettings) => {
|
||||
@@ -239,6 +260,8 @@ watch(settings, (newSettings) => {
|
||||
blacklistSettingsForm.loginBanDuration = newSettings.loginBanDuration || '300';
|
||||
// 同步弹窗编辑器设置
|
||||
popupEditorEnabled.value = showPopupFileEditorBoolean.value;
|
||||
// 同步共享标签页设置
|
||||
shareTabsEnabled.value = shareFileEditorTabsBoolean.value;
|
||||
}, { deep: true, immediate: true }); // immediate: true to run on initial load
|
||||
|
||||
// --- Popup Editor setting method ---
|
||||
@@ -263,6 +286,27 @@ const handleUpdatePopupEditorSetting = async () => {
|
||||
}
|
||||
};
|
||||
|
||||
// --- Share Editor Tabs setting method ---
|
||||
const handleUpdateShareTabsSetting = async () => {
|
||||
shareTabsLoading.value = true;
|
||||
shareTabsMessage.value = '';
|
||||
shareTabsSuccess.value = false;
|
||||
try {
|
||||
const valueToSave = shareTabsEnabled.value ? 'true' : 'false';
|
||||
await settingsStore.updateSetting('shareFileEditorTabs', valueToSave);
|
||||
shareTabsMessage.value = t('settings.shareEditorTabs.success.saved'); // 需要添加翻译
|
||||
shareTabsSuccess.value = true;
|
||||
} catch (error: any) {
|
||||
console.error('更新共享编辑器标签页设置失败:', error);
|
||||
shareTabsMessage.value = error.message || t('settings.shareEditorTabs.error.saveFailed'); // 需要添加翻译
|
||||
shareTabsSuccess.value = false;
|
||||
// 保存失败时,将本地复选框状态恢复为 Store 中的状态
|
||||
shareTabsEnabled.value = shareFileEditorTabsBoolean.value;
|
||||
} finally {
|
||||
shareTabsLoading.value = false;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
// --- Passkey state & methods --- (Keep as is)
|
||||
const passkeyName = ref('');
|
||||
|
||||
@@ -11,6 +11,8 @@ import TerminalTabBar from '../components/TerminalTabBar.vue';
|
||||
import CommandInputBar from '../components/CommandInputBar.vue';
|
||||
import FileEditorContainer from '../components/FileEditorContainer.vue'; // 导入编辑器容器
|
||||
import { useSessionStore, type SessionTabInfoWithStatus, type SshTerminalInstance } from '../stores/session.store'; // 导入 SshTerminalInstance
|
||||
import { useSettingsStore } from '../stores/settings.store'; // 导入设置 Store
|
||||
import { useFileEditorStore } from '../stores/fileEditor.store'; // 导入文件编辑器 Store
|
||||
import type { ConnectionInfo } from '../stores/connections.store';
|
||||
// 导入 splitpanes 组件
|
||||
import { Splitpanes, Pane } from 'splitpanes';
|
||||
@@ -20,9 +22,36 @@ import { Splitpanes, Pane } from 'splitpanes';
|
||||
// --- Setup ---
|
||||
const { t } = useI18n();
|
||||
const sessionStore = useSessionStore();
|
||||
const settingsStore = useSettingsStore(); // 初始化设置 Store
|
||||
const fileEditorStore = useFileEditorStore(); // 初始化文件编辑器 Store (用于共享模式)
|
||||
|
||||
// --- 从 Store 获取响应式状态和 Getters ---
|
||||
const { sessionTabsWithStatus, activeSessionId, activeSession } = storeToRefs(sessionStore);
|
||||
const { shareFileEditorTabsBoolean } = storeToRefs(settingsStore); // 获取共享设置
|
||||
const { orderedTabs: globalEditorTabs, activeTabId: globalActiveEditorTabId } = storeToRefs(fileEditorStore); // 获取全局编辑器状态
|
||||
|
||||
// --- 计算属性 (用于动态绑定编辑器 Props) ---
|
||||
// **再次修正:** 确保计算属性在共享模式下严格只依赖全局状态
|
||||
const editorTabs = computed(() => {
|
||||
if (shareFileEditorTabsBoolean.value) {
|
||||
// console.log('[WorkspaceView] Shared Mode: Returning globalEditorTabs');
|
||||
return globalEditorTabs.value; // 共享模式:只依赖全局 store 的 tabs
|
||||
} else {
|
||||
// console.log('[WorkspaceView] Independent Mode: Returning activeSession tabs');
|
||||
return activeSession.value?.editorTabs.value ?? []; // 独立模式:依赖 activeSession
|
||||
}
|
||||
});
|
||||
|
||||
const activeEditorTabId = computed(() => {
|
||||
if (shareFileEditorTabsBoolean.value) {
|
||||
// console.log('[WorkspaceView] Shared Mode: Returning globalActiveEditorTabId');
|
||||
return globalActiveEditorTabId.value; // 共享模式:只依赖全局 store 的 activeTabId
|
||||
} else {
|
||||
// console.log('[WorkspaceView] Independent Mode: Returning activeSession activeEditorTabId');
|
||||
return activeSession.value?.activeEditorTabId.value ?? null; // 独立模式:依赖 activeSession
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
// --- UI 状态 (保持本地) ---
|
||||
const showAddEditForm = ref(false);
|
||||
@@ -77,6 +106,69 @@ onBeforeUnmount(() => {
|
||||
// 可以考虑给用户一个提示
|
||||
}
|
||||
};
|
||||
|
||||
// --- 编辑器操作处理 ---
|
||||
const handleCloseEditorTab = (tabId: string) => {
|
||||
const isShared = shareFileEditorTabsBoolean.value; // 在函数开始时获取模式
|
||||
console.log(`[WorkspaceView] handleCloseEditorTab: ${tabId}, Shared mode: ${isShared}`);
|
||||
if (isShared) {
|
||||
fileEditorStore.closeTab(tabId);
|
||||
} else {
|
||||
const currentActiveSessionId = activeSessionId.value; // 获取当前的 activeSessionId
|
||||
if (currentActiveSessionId) {
|
||||
sessionStore.closeEditorTabInSession(currentActiveSessionId, tabId);
|
||||
} else {
|
||||
console.warn('[WorkspaceView] Cannot close editor tab: No active session in independent mode.');
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const handleActivateEditorTab = (tabId: string) => {
|
||||
const isShared = shareFileEditorTabsBoolean.value; // 在函数开始时获取模式
|
||||
console.log(`[WorkspaceView] handleActivateEditorTab: ${tabId}, Shared mode: ${isShared}`);
|
||||
if (isShared) {
|
||||
fileEditorStore.setActiveTab(tabId);
|
||||
} else {
|
||||
const currentActiveSessionId = activeSessionId.value; // 获取当前的 activeSessionId
|
||||
if (currentActiveSessionId) {
|
||||
sessionStore.setActiveEditorTabInSession(currentActiveSessionId, tabId);
|
||||
} else {
|
||||
console.warn('[WorkspaceView] Cannot activate editor tab: No active session in independent mode.');
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// 处理编辑器内容更新事件
|
||||
const handleUpdateEditorContent = (payload: { tabId: string; content: string }) => {
|
||||
const isShared = shareFileEditorTabsBoolean.value; // 在函数开始时获取模式
|
||||
console.log(`[WorkspaceView] handleUpdateEditorContent for tab ${payload.tabId}, Shared mode: ${isShared}`);
|
||||
if (isShared) {
|
||||
fileEditorStore.updateFileContent(payload.tabId, payload.content);
|
||||
} else {
|
||||
const currentActiveSessionId = activeSessionId.value; // 获取当前的 activeSessionId
|
||||
if (currentActiveSessionId) {
|
||||
sessionStore.updateFileContentInSession(currentActiveSessionId, payload.tabId, payload.content);
|
||||
} else {
|
||||
console.warn('[WorkspaceView] Cannot update editor content: No active session in independent mode.');
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// 处理编辑器保存请求事件
|
||||
const handleSaveEditorTab = (tabId: string) => {
|
||||
const isShared = shareFileEditorTabsBoolean.value; // 在函数开始时获取模式
|
||||
console.log(`[WorkspaceView] handleSaveEditorTab: ${tabId}, Shared mode: ${isShared}`);
|
||||
if (isShared) {
|
||||
fileEditorStore.saveFile(tabId);
|
||||
} else {
|
||||
const currentActiveSessionId = activeSessionId.value; // 获取当前的 activeSessionId
|
||||
if (currentActiveSessionId) {
|
||||
sessionStore.saveFileInSession(currentActiveSessionId, tabId);
|
||||
} else {
|
||||
console.warn('[WorkspaceView] Cannot save editor tab: No active session in independent mode.');
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<template>
|
||||
@@ -166,7 +258,15 @@ onBeforeUnmount(() => {
|
||||
|
||||
<!-- 3. 右侧区域 1 Pane (文件编辑器) -->
|
||||
<pane size="20" min-size="15" class="file-editor-pane"> <!-- 新增编辑器窗格 -->
|
||||
<FileEditorContainer />
|
||||
<FileEditorContainer
|
||||
:tabs="editorTabs"
|
||||
:active-tab-id="activeEditorTabId"
|
||||
:session-id="activeSessionId"
|
||||
@close-tab="handleCloseEditorTab"
|
||||
@activate-tab="handleActivateEditorTab"
|
||||
@update:content="handleUpdateEditorContent"
|
||||
@request-save="handleSaveEditorTab"
|
||||
/>
|
||||
</pane>
|
||||
|
||||
<!-- 4. 右侧区域 2 Pane (状态监视器) -->
|
||||
|
||||
Reference in New Issue
Block a user