style: 优化设置界面布局,添加导航栏
This commit is contained in:
@@ -1,31 +1,31 @@
|
||||
<script setup lang="ts">
|
||||
import { onMounted, onBeforeUnmount, computed, ref } from 'vue';
|
||||
import { onMounted, onBeforeUnmount, computed, ref, shallowRef, type PropType } from 'vue';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
import { storeToRefs } from 'pinia';
|
||||
import { useBreakpoints, breakpointsTailwind } from '@vueuse/core'; // +++ 引入 useBreakpoints +++
|
||||
import { useBreakpoints, breakpointsTailwind } from '@vueuse/core';
|
||||
import { useLayoutStore } from '../stores/layout.store';
|
||||
import { useConnectionsStore, type ConnectionInfo } from '../stores/connections.store';
|
||||
import AddConnectionFormComponent from '../components/AddConnectionForm.vue';
|
||||
import TerminalTabBar from '../components/TerminalTabBar.vue';
|
||||
import LayoutRenderer from '../components/LayoutRenderer.vue';
|
||||
import LayoutConfigurator from '../components/LayoutConfigurator.vue';
|
||||
import RemoteDesktopModal from '../components/RemoteDesktopModal.vue';
|
||||
import VncModal from '../components/VncModal.vue'; // +++ 引入 VncModal 组件 +++
|
||||
import Terminal from '../components/Terminal.vue'; // +++ 引入 Terminal 组件 +++
|
||||
import CommandInputBar from '../components/CommandInputBar.vue'; // +++ 引入 CommandInputBar 组件 +++
|
||||
import VirtualKeyboard from '../components/VirtualKeyboard.vue'; // +++ 引入 VirtualKeyboard 组件 +++
|
||||
import Terminal from '../components/Terminal.vue';
|
||||
import CommandInputBar from '../components/CommandInputBar.vue';
|
||||
import VirtualKeyboard from '../components/VirtualKeyboard.vue';
|
||||
import FileManager from '../components/FileManager.vue';
|
||||
import { useSessionStore } from '../stores/session.store';
|
||||
import type { SessionTabInfoWithStatus, SshTerminalInstance } from '../stores/session/types';
|
||||
import { useSettingsStore } from '../stores/settings.store';
|
||||
import { useFileEditorStore, type FileTab } from '../stores/fileEditor.store';
|
||||
import { useCommandHistoryStore } from '../stores/commandHistory.store';
|
||||
import type { Terminal as XtermTerminal } from 'xterm';
|
||||
import type { Terminal as XtermTerminal } from 'xterm';
|
||||
import type { ISearchOptions } from '@xterm/addon-search';
|
||||
import {
|
||||
useWorkspaceEventSubscriber,
|
||||
useWorkspaceEventOff,
|
||||
type WorkspaceEventPayloads
|
||||
} from '../composables/workspaceEvents';
|
||||
import type { WebSocketDependencies } from '../composables/useSftpActions';
|
||||
|
||||
// --- Setup ---
|
||||
const { t } = useI18n();
|
||||
@@ -75,6 +75,15 @@ const currentSearchTerm = ref(''); // 当前搜索的关键词
|
||||
const mobileTerminalRef = ref<InstanceType<typeof Terminal> | null>(null);
|
||||
const isVirtualKeyboardVisible = ref(true); // +++ State for virtual keyboard visibility +++
|
||||
|
||||
// --- 文件管理器模态框状态 ---
|
||||
const showFileManagerModal = ref(false);
|
||||
const fileManagerProps = shallowRef<null | {
|
||||
sessionId: string;
|
||||
instanceId: string;
|
||||
dbConnectionId: string;
|
||||
wsDeps: WebSocketDependencies;
|
||||
}>(null);
|
||||
|
||||
// --- 处理全局键盘事件 ---
|
||||
const handleGlobalKeyDown = (event: KeyboardEvent) => {
|
||||
// 检查是否按下了 Alt 键以及上/下箭头键
|
||||
@@ -154,6 +163,7 @@ onMounted(() => {
|
||||
subscribeToWorkspaceEvents('session:closeToRight', (payload) => handleCloseSessionsToRight(payload.targetSessionId));
|
||||
subscribeToWorkspaceEvents('session:closeToLeft', (payload) => handleCloseSessionsToLeft(payload.targetSessionId));
|
||||
subscribeToWorkspaceEvents('ui:openLayoutConfigurator', handleOpenLayoutConfigurator);
|
||||
subscribeToWorkspaceEvents('fileManager:openModalRequest', handleFileManagerOpenRequest); // +++ 订阅文件管理器打开请求 +++
|
||||
});
|
||||
|
||||
onBeforeUnmount(() => {
|
||||
@@ -196,6 +206,7 @@ onBeforeUnmount(() => {
|
||||
unsubscribeFromWorkspaceEvents('session:closeToRight', (payload) => handleCloseSessionsToRight(payload.targetSessionId));
|
||||
unsubscribeFromWorkspaceEvents('session:closeToLeft', (payload) => handleCloseSessionsToLeft(payload.targetSessionId));
|
||||
unsubscribeFromWorkspaceEvents('ui:openLayoutConfigurator', handleOpenLayoutConfigurator);
|
||||
unsubscribeFromWorkspaceEvents('fileManager:openModalRequest', handleFileManagerOpenRequest); // +++ 取消订阅文件管理器打开请求 +++
|
||||
});
|
||||
|
||||
const subscribeToWorkspaceEvents = useWorkspaceEventSubscriber(); // +++ 定义订阅和取消订阅函数 +++
|
||||
@@ -634,6 +645,64 @@ const toggleVirtualKeyboard = () => {
|
||||
tabsToClose.forEach(id => handleCloseEditorTab(id));
|
||||
};
|
||||
|
||||
// --- 文件管理器模态框处理 ---
|
||||
const handleFileManagerOpenRequest = (payload: { sessionId: string }) => {
|
||||
const { sessionId } = payload;
|
||||
const session = sessionStore.sessions.get(sessionId);
|
||||
if (!session) {
|
||||
console.error(`[WorkspaceView] Cannot open file manager: Session ${sessionId} not found.`);
|
||||
// TODO: Show error notification
|
||||
return;
|
||||
}
|
||||
|
||||
// 1. 获取 dbConnectionId
|
||||
const dbConnectionId = session.connectionId;
|
||||
if (!dbConnectionId) {
|
||||
console.error(`[WorkspaceView] Cannot open file manager: Missing dbConnectionId for session ${sessionId}.`);
|
||||
// TODO: Show error notification
|
||||
return;
|
||||
}
|
||||
|
||||
// 2. 获取 wsDeps (从 session.wsManager 获取)
|
||||
if (!session.wsManager) {
|
||||
console.error(`[WorkspaceView] Cannot open file manager: wsManager not found for session ${sessionId}.`);
|
||||
// TODO: Show error notification
|
||||
return;
|
||||
}
|
||||
const wsDeps: WebSocketDependencies = {
|
||||
sendMessage: session.wsManager.sendMessage,
|
||||
onMessage: session.wsManager.onMessage,
|
||||
isConnected: session.wsManager.isConnected,
|
||||
isSftpReady: session.wsManager.isSftpReady,
|
||||
};
|
||||
console.log(`[WorkspaceView] Retrieved wsDeps from session.wsManager for session ${sessionId}.`);
|
||||
|
||||
if (!wsDeps) {
|
||||
// 如果 wsDeps 仍然为 null,则无法继续
|
||||
console.error(`[WorkspaceView] Cannot open file manager: wsDeps are null after attempting retrieval for session ${sessionId}.`);
|
||||
return;
|
||||
}
|
||||
|
||||
// 3. 生成 instanceId
|
||||
const instanceId = `fm-modal-${sessionId}-${Date.now()}`;
|
||||
|
||||
// 4. 设置 props 并显示模态框
|
||||
fileManagerProps.value = {
|
||||
sessionId,
|
||||
instanceId,
|
||||
dbConnectionId: String(dbConnectionId), // 确保是 string
|
||||
wsDeps,
|
||||
};
|
||||
showFileManagerModal.value = true;
|
||||
console.log(`[WorkspaceView] Opening FileManager modal with props:`, fileManagerProps.value);
|
||||
};
|
||||
|
||||
const closeFileManagerModal = () => {
|
||||
showFileManagerModal.value = false;
|
||||
fileManagerProps.value = null; // 清理 props
|
||||
console.log('[WorkspaceView] FileManager modal closed.');
|
||||
};
|
||||
|
||||
</script>
|
||||
|
||||
<template>
|
||||
@@ -726,6 +795,28 @@ const toggleVirtualKeyboard = () => {
|
||||
|
||||
<!-- RDP Modal is now rendered in App.vue -->
|
||||
<!-- VNC Modal is now rendered in App.vue -->
|
||||
|
||||
<!-- FileManager Modal -->
|
||||
<div v-if="showFileManagerModal && fileManagerProps" class="fixed inset-0 bg-black bg-opacity-60 flex items-center justify-center z-50 p-4">
|
||||
<div class="bg-background rounded-lg shadow-xl w-full max-w-4xl h-[85vh] flex flex-col overflow-hidden border border-border">
|
||||
<div class="flex justify-between items-center p-3 border-b border-border flex-shrink-0 bg-header">
|
||||
<h2 class="text-lg font-semibold text-foreground">{{ t('fileManager.modalTitle', '文件管理器') }} ({{ fileManagerProps.sessionId }})</h2>
|
||||
<button @click="closeFileManagerModal" class="text-text-secondary hover:text-foreground transition-colors">
|
||||
<i class="fas fa-times text-xl"></i>
|
||||
</button>
|
||||
</div>
|
||||
<div class="flex-grow overflow-hidden">
|
||||
<FileManager
|
||||
:session-id="fileManagerProps.sessionId"
|
||||
:instance-id="fileManagerProps.instanceId"
|
||||
:db-connection-id="fileManagerProps.dbConnectionId"
|
||||
:ws-deps="fileManagerProps.wsDeps"
|
||||
class="h-full"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user