update
This commit is contained in:
@@ -3,8 +3,8 @@ import { ref, reactive, watch, computed, onMounted } from 'vue'; // 添加 onMou
|
|||||||
import { storeToRefs } from 'pinia';
|
import { storeToRefs } from 'pinia';
|
||||||
import { useI18n } from 'vue-i18n';
|
import { useI18n } from 'vue-i18n';
|
||||||
import { useProxiesStore, ProxyInfo } from '../stores/proxies.store';
|
import { useProxiesStore, ProxyInfo } from '../stores/proxies.store';
|
||||||
import { useTagsStore } from '../stores/tags.store'; // 引入标签 Store
|
import { useTagsStore } from '../stores/tags.store';
|
||||||
import TagInput from './TagInput.vue'; // 导入新的 TagInput 组件
|
import TagInput from './TagInput.vue';
|
||||||
|
|
||||||
// 定义组件发出的事件
|
// 定义组件发出的事件
|
||||||
const emit = defineEmits(['close', 'proxy-added', 'proxy-updated']);
|
const emit = defineEmits(['close', 'proxy-added', 'proxy-updated']);
|
||||||
|
|||||||
@@ -1,23 +1,18 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { ref, watch, nextTick, onMounted, onBeforeUnmount, defineExpose, computed } from 'vue'; // Import computed
|
import { ref, watch, nextTick, onMounted, onBeforeUnmount, defineExpose, computed } from 'vue';
|
||||||
import { useI18n } from 'vue-i18n';
|
import { useI18n } from 'vue-i18n';
|
||||||
import { storeToRefs } from 'pinia'; // Import storeToRefs
|
import { storeToRefs } from 'pinia';
|
||||||
import { useFocusSwitcherStore } from '../stores/focusSwitcher.store'; // 导入 Store
|
import { useFocusSwitcherStore } from '../stores/focusSwitcher.store';
|
||||||
import { useSettingsStore } from '../stores/settings.store'; // NEW: Import settings store
|
import { useSettingsStore } from '../stores/settings.store';
|
||||||
import { useQuickCommandsStore } from '../stores/quickCommands.store'; // NEW: Import quick commands store
|
import { useQuickCommandsStore } from '../stores/quickCommands.store';
|
||||||
import { useCommandHistoryStore } from '../stores/commandHistory.store'; // NEW: Import command history store
|
import { useCommandHistoryStore } from '../stores/commandHistory.store';
|
||||||
// 假设你有一个图标库,例如 unplugin-icons 或类似库
|
|
||||||
// import SearchIcon from '~icons/mdi/magnify';
|
|
||||||
// import ArrowUpIcon from '~icons/mdi/arrow-up';
|
|
||||||
// import ArrowDownIcon from '~icons/mdi/arrow-down';
|
|
||||||
// import CloseIcon from '~icons/mdi/close';
|
|
||||||
|
|
||||||
const emit = defineEmits(['send-command', 'search', 'find-next', 'find-previous', 'close-search']); // 移除 open-focus-switcher-config 事件
|
const emit = defineEmits(['send-command', 'search', 'find-next', 'find-previous', 'close-search']);
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
const focusSwitcherStore = useFocusSwitcherStore(); // +++ 实例化 Store +++
|
const focusSwitcherStore = useFocusSwitcherStore();
|
||||||
const settingsStore = useSettingsStore(); // NEW: Instantiate settings store
|
const settingsStore = useSettingsStore();
|
||||||
const quickCommandsStore = useQuickCommandsStore(); // NEW: Instantiate quick commands store
|
const quickCommandsStore = useQuickCommandsStore();
|
||||||
const commandHistoryStore = useCommandHistoryStore(); // NEW: Instantiate command history store
|
const commandHistoryStore = useCommandHistoryStore();
|
||||||
|
|
||||||
// Get reactive setting from store
|
// Get reactive setting from store
|
||||||
const { commandInputSyncTarget } = storeToRefs(settingsStore);
|
const { commandInputSyncTarget } = storeToRefs(settingsStore);
|
||||||
|
|||||||
@@ -1,18 +1,18 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { onMounted, computed, ref, reactive, watch } from 'vue'; // 统一导入, 添加 watch
|
import { onMounted, computed, ref, reactive, watch } from 'vue';
|
||||||
import { storeToRefs } from 'pinia';
|
import { storeToRefs } from 'pinia';
|
||||||
import { useRouter } from 'vue-router';
|
import { useRouter } from 'vue-router';
|
||||||
import { useI18n } from 'vue-i18n';
|
import { useI18n } from 'vue-i18n';
|
||||||
import { useConnectionsStore, ConnectionInfo } from '../stores/connections.store'; // 引入 ConnectionInfo 类型
|
import { useConnectionsStore, ConnectionInfo } from '../stores/connections.store';
|
||||||
import { useTagsStore } from '../stores/tags.store'; // 引入 Tags Store
|
import { useTagsStore } from '../stores/tags.store';
|
||||||
|
|
||||||
const { t } = useI18n(); // 获取 t 函数
|
const { t } = useI18n();
|
||||||
const router = useRouter(); // 获取 router 实例
|
const router = useRouter();
|
||||||
const tagsStore = useTagsStore(); // 获取 Tags Store 实例
|
const tagsStore = useTagsStore();
|
||||||
// 使用 storeToRefs 来保持 state 属性的响应性
|
|
||||||
// 不再直接从 connectionsStore 获取 connections, isLoading, error
|
|
||||||
// const { connections, isLoading, error } = storeToRefs(connectionsStore);
|
|
||||||
const { tags: allTags, isLoading: isTagsLoading, error: tagsError } = storeToRefs(tagsStore); // 获取所有标签及其状态
|
const { tags: allTags, isLoading: isTagsLoading, error: tagsError } = storeToRefs(tagsStore);
|
||||||
|
|
||||||
// 定义 Props,接收筛选后的连接列表
|
// 定义 Props,接收筛选后的连接列表
|
||||||
const props = defineProps<{
|
const props = defineProps<{
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { computed } from 'vue';
|
import { computed } from 'vue';
|
||||||
import { useI18n } from 'vue-i18n';
|
import { useI18n } from 'vue-i18n';
|
||||||
import { useSessionStore } from '../stores/session.store'; // Import session store
|
import { useSessionStore } from '../stores/session.store';
|
||||||
import { storeToRefs } from 'pinia';
|
import { storeToRefs } from 'pinia';
|
||||||
// Removed unused imports: ref, onMounted, onUnmounted, watch, useSettingsStore
|
|
||||||
// Removed unused interfaces: PortInfo, DockerContainer, DockerStats (now in composable)
|
|
||||||
|
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
const sessionStore = useSessionStore();
|
const sessionStore = useSessionStore();
|
||||||
|
|||||||
@@ -4,16 +4,15 @@ import { useI18n } from 'vue-i18n';
|
|||||||
import { storeToRefs } from 'pinia';
|
import { storeToRefs } from 'pinia';
|
||||||
import MonacoEditor from './MonacoEditor.vue';
|
import MonacoEditor from './MonacoEditor.vue';
|
||||||
import FileEditorTabs from './FileEditorTabs.vue';
|
import FileEditorTabs from './FileEditorTabs.vue';
|
||||||
import { useFileEditorStore, type FileTab } from '../stores/fileEditor.store'; // 导入 FileTab 类型
|
import { useFileEditorStore, type FileTab } from '../stores/fileEditor.store';
|
||||||
import { useSettingsStore } from '../stores/settings.store';
|
import { useSettingsStore } from '../stores/settings.store';
|
||||||
import { useSessionStore } from '../stores/session.store'; // 导入 Session Store
|
import { useSessionStore } from '../stores/session.store';
|
||||||
import type { EditorFileContent, SaveStatus } from '../types/sftp.types';
|
|
||||||
import { getLanguageFromFilename, getFilenameFromPath } from '../stores/fileEditor.store';
|
|
||||||
|
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
const fileEditorStore = useFileEditorStore();
|
const fileEditorStore = useFileEditorStore();
|
||||||
const settingsStore = useSettingsStore();
|
const settingsStore = useSettingsStore();
|
||||||
const sessionStore = useSessionStore(); // 实例化 Session Store
|
const sessionStore = useSessionStore();
|
||||||
|
|
||||||
// --- 本地状态控制弹窗显示 ---
|
// --- 本地状态控制弹窗显示 ---
|
||||||
const isVisible = ref(false);
|
const isVisible = ref(false);
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import type { PropType } from 'vue';
|
import type { PropType } from 'vue';
|
||||||
import { useI18n } from 'vue-i18n';
|
import { useI18n } from 'vue-i18n';
|
||||||
import type { FileTab } from '../stores/fileEditor.store'; // 导入 FileTab 类型
|
import type { FileTab } from '../stores/fileEditor.store';
|
||||||
|
|
||||||
defineProps({
|
defineProps({
|
||||||
tabs: {
|
tabs: {
|
||||||
|
|||||||
@@ -1,31 +1,24 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { ref, computed, onMounted, onBeforeUnmount, nextTick, watch, watchEffect, type PropType, readonly, defineExpose, shallowRef } from 'vue';
|
import { ref, computed, onMounted, onBeforeUnmount, nextTick, watch, watchEffect, type PropType, readonly, defineExpose, shallowRef } from 'vue';
|
||||||
// 移除 debounce 导入
|
|
||||||
import { useI18n } from 'vue-i18n';
|
import { useI18n } from 'vue-i18n';
|
||||||
import { useRoute } from 'vue-router'; // 保留用于生成下载 URL (如果下载逻辑移动则可移除)
|
import { useRoute } from 'vue-router';
|
||||||
import { storeToRefs } from 'pinia'; // 导入 storeToRefs
|
import { storeToRefs } from 'pinia';
|
||||||
// 导入 SFTP Actions 工厂函数和所需的类型
|
|
||||||
import { createSftpActionsManager, type WebSocketDependencies } from '../composables/useSftpActions';
|
import { createSftpActionsManager, type WebSocketDependencies } from '../composables/useSftpActions';
|
||||||
import { useFileUploader } from '../composables/useFileUploader';
|
import { useFileUploader } from '../composables/useFileUploader';
|
||||||
// import { useFileEditor } from '../composables/useFileEditor'; // 移除旧的 composable 导入
|
import { useFileEditorStore, type FileInfo } from '../stores/fileEditor.store';
|
||||||
import { useFileEditorStore, type FileInfo } from '../stores/fileEditor.store'; // 导入新的 Store 和 FileInfo 类型
|
|
||||||
import { useSessionStore } from '../stores/session.store';
|
import { useSessionStore } from '../stores/session.store';
|
||||||
import { useSettingsStore } from '../stores/settings.store'; // +++ 实例化 Settings Store +++
|
import { useSettingsStore } from '../stores/settings.store';
|
||||||
import { useFocusSwitcherStore } from '../stores/focusSwitcher.store'; // +++ 实例化焦点切换 Store +++
|
import { useFocusSwitcherStore } from '../stores/focusSwitcher.store';
|
||||||
import { useFileManagerContextMenu, type ClipboardState } from '../composables/file-manager/useFileManagerContextMenu'; // +++ 导入上下文菜单 Composable 和 ClipboardState +++
|
import { useFileManagerContextMenu, type ClipboardState } from '../composables/file-manager/useFileManagerContextMenu';
|
||||||
import { useFileManagerSelection } from '../composables/file-manager/useFileManagerSelection'; // +++ 导入选择 Composable +++
|
import { useFileManagerSelection } from '../composables/file-manager/useFileManagerSelection';
|
||||||
import { useFileManagerDragAndDrop } from '../composables/file-manager/useFileManagerDragAndDrop'; // +++ 导入拖放 Composable +++
|
import { useFileManagerDragAndDrop } from '../composables/file-manager/useFileManagerDragAndDrop';
|
||||||
import { useFileManagerKeyboardNavigation } from '../composables/file-manager/useFileManagerKeyboardNavigation'; // +++ 导入键盘导航 Composable +++
|
import { useFileManagerKeyboardNavigation } from '../composables/file-manager/useFileManagerKeyboardNavigation';
|
||||||
// WebSocket composable 不再直接使用
|
|
||||||
import FileUploadPopup from './FileUploadPopup.vue';
|
import FileUploadPopup from './FileUploadPopup.vue';
|
||||||
import FileManagerContextMenu from './FileManagerContextMenu.vue'; // +++ 导入上下文菜单组件 +++
|
import FileManagerContextMenu from './FileManagerContextMenu.vue';
|
||||||
// import FileEditorOverlay from './FileEditorOverlay.vue'; // 不再在此处渲染
|
|
||||||
// 从类型文件导入所需类型
|
|
||||||
import type { FileListItem } from '../types/sftp.types';
|
import type { FileListItem } from '../types/sftp.types';
|
||||||
// 从 websocket 类型文件导入所需类型
|
import type { WebSocketMessage } from '../types/websocket.types';
|
||||||
import type { WebSocketMessage } from '../types/websocket.types'; // 导入 WebSocketMessage
|
|
||||||
|
|
||||||
// 定义 SftpManagerInstance 类型,基于 createSftpActionsManager 的返回类型
|
|
||||||
type SftpManagerInstance = ReturnType<typeof createSftpActionsManager>;
|
type SftpManagerInstance = ReturnType<typeof createSftpActionsManager>;
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { computed } from 'vue';
|
import { computed } from 'vue';
|
||||||
import { useI18n } from 'vue-i18n';
|
import { useI18n } from 'vue-i18n';
|
||||||
import type { UploadItem } from '../types/upload.types'; // 导入上传项类型
|
import type { UploadItem } from '../types/upload.types';
|
||||||
|
|
||||||
const props = defineProps<{
|
const props = defineProps<{
|
||||||
uploads: Record<string, UploadItem>; // 接收上传任务字典
|
uploads: Record<string, UploadItem>; // 接收上传任务字典
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { ref, computed, watch, reactive, type Ref } from 'vue'; // 添加 Ref
|
import { ref, computed, watch, reactive, type Ref } from 'vue';
|
||||||
import { useI18n } from 'vue-i18n';
|
import { useI18n } from 'vue-i18n';
|
||||||
import draggable from 'vuedraggable';
|
import draggable from 'vuedraggable';
|
||||||
import { useFocusSwitcherStore, type FocusableInput, type FocusItemConfig, type FocusSwitcherFullConfig } from '../stores/focusSwitcher.store'; // ++ 导入新接口 ++
|
import { useFocusSwitcherStore, type FocusableInput, type FocusItemConfig, type FocusSwitcherFullConfig } from '../stores/focusSwitcher.store';
|
||||||
import { storeToRefs } from 'pinia';
|
import { storeToRefs } from 'pinia';
|
||||||
|
|
||||||
// 本地接口,仅用于右侧列表显示
|
// 本地接口,仅用于右侧列表显示
|
||||||
|
|||||||
@@ -236,9 +236,6 @@ const clonePane = (paneName: PaneName): LayoutNode => {
|
|||||||
// Handle updates from LayoutNodeEditor (for main layout)
|
// Handle updates from LayoutNodeEditor (for main layout)
|
||||||
const handleNodeUpdate = (updatedNode: LayoutNode) => {
|
const handleNodeUpdate = (updatedNode: LayoutNode) => {
|
||||||
console.log('[LayoutConfigurator] Received node update from editor:', updatedNode);
|
console.log('[LayoutConfigurator] Received node update from editor:', updatedNode);
|
||||||
// Assuming the update is for the root node for simplicity
|
|
||||||
// v-model on LayoutNodeEditor might handle this, but explicit update is safer
|
|
||||||
// Update the local tree; isModified will react automatically
|
|
||||||
localLayoutTree.value = updatedNode;
|
localLayoutTree.value = updatedNode;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -278,11 +275,6 @@ const handleNodeRemove = (payload: { parentNodeId: string | undefined; nodeIndex
|
|||||||
console.log('[LayoutConfigurator] Received node remove request:', payload);
|
console.log('[LayoutConfigurator] Received node remove request:', payload);
|
||||||
if (payload.parentNodeId === undefined && payload.nodeIndex === 0) {
|
if (payload.parentNodeId === undefined && payload.nodeIndex === 0) {
|
||||||
if (confirm(t('layoutConfigurator.confirmClearLayout', '确定要清空整个布局吗?所有面板将返回可用列表。'))) { // Keep default text for now
|
if (confirm(t('layoutConfigurator.confirmClearLayout', '确定要清空整个布局吗?所有面板将返回可用列表。'))) { // Keep default text for now
|
||||||
// Add all panes from the tree back to available list before clearing - REMOVED, no longer needed
|
|
||||||
// const usedInTree = getMainLayoutUsedPaneNames(localLayoutTree.value);
|
|
||||||
// usedInTree.forEach(paneName => addPaneToAvailableList(paneName));
|
|
||||||
// Clear the tree
|
|
||||||
// Update the local tree; isModified will react automatically
|
|
||||||
localLayoutTree.value = null;
|
localLayoutTree.value = null;
|
||||||
}
|
}
|
||||||
} else if (payload.parentNodeId) {
|
} else if (payload.parentNodeId) {
|
||||||
|
|||||||
@@ -102,23 +102,8 @@ const handleChildUpdate = (updatedChildNode: LayoutNode, index: number) => {
|
|||||||
// 处理子节点移除事件
|
// 处理子节点移除事件
|
||||||
const handleChildRemove = (payload: { parentNodeId: string | undefined; nodeIndex: number }) => {
|
const handleChildRemove = (payload: { parentNodeId: string | undefined; nodeIndex: number }) => {
|
||||||
// 总是将移除事件向上传递,让顶层 LayoutConfigurator 处理
|
// 总是将移除事件向上传递,让顶层 LayoutConfigurator 处理
|
||||||
console.log(`[LayoutNodeEditor ${props.node.id}] Relaying removeNode event upwards:`, payload); // 添加日志
|
console.log(`[LayoutNodeEditor ${props.node.id}] Relaying removeNode event upwards:`, payload);
|
||||||
emit('removeNode', payload);
|
emit('removeNode', payload);
|
||||||
|
|
||||||
/* 移除旧逻辑:
|
|
||||||
// 如果移除的是当前节点的直接子节点
|
|
||||||
if (payload.parentNodeId === props.node.id && props.node.children) {
|
|
||||||
const newChildren = [...props.node.children];
|
|
||||||
newChildren.splice(payload.nodeIndex, 1);
|
|
||||||
// 如果容器变空,可以选择移除容器自身或保留空容器
|
|
||||||
// 这里选择保留空容器,让用户手动删除
|
|
||||||
// 问题:这里 emit update:node,但实际移除逻辑在 LayoutConfigurator
|
|
||||||
emit('update:node', { ...props.node, children: newChildren });
|
|
||||||
} else {
|
|
||||||
// 如果不是直接子节点,继续向上传递事件
|
|
||||||
emit('removeNode', payload);
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
};
|
};
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
@@ -194,28 +179,16 @@ const handleChildRemove = (payload: { parentNodeId: string | undefined; nodeInde
|
|||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
.layout-node-editor {
|
.layout-node-editor {
|
||||||
/* border: 1px solid var(--border-color);
|
|
||||||
margin: var(--base-margin);
|
|
||||||
padding: var(--base-margin);
|
|
||||||
position: relative;
|
|
||||||
background-color: var(--header-bg-color);
|
|
||||||
min-height: 60px;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column; */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* .node-type-container {
|
|
||||||
background-color: var(--app-bg-color);
|
|
||||||
}
|
|
||||||
.node-type-pane {
|
|
||||||
background-color: var(--app-bg-color);
|
|
||||||
} */
|
|
||||||
|
|
||||||
.node-controls {
|
.node-controls {
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
background-color: var(--header-bg-color); /* Or a specific control bar background */
|
background-color: var(--header-bg-color);
|
||||||
padding: 3px var(--base-margin);
|
padding: 3px var(--base-margin);
|
||||||
margin-bottom: var(--base-margin);
|
margin-bottom: var(--base-margin);
|
||||||
font-size: 0.8em;
|
font-size: 0.8em;
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
import { ref, onMounted, onBeforeUnmount, watch, defineExpose } from 'vue';
|
import { ref, onMounted, onBeforeUnmount, watch, defineExpose } from 'vue';
|
||||||
import * as monaco from 'monaco-editor';
|
import * as monaco from 'monaco-editor';
|
||||||
|
|
||||||
const localFontSize = ref(14); // <-- 添加本地字体大小状态,默认 14
|
const localFontSize = ref(14); // 添加本地字体大小状态,默认 14
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
modelValue: {
|
modelValue: {
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="p-0"> <!-- Remove padding from here, parent view provides it -->
|
<div class="p-0">
|
||||||
<h2 class="text-xl font-semibold text-foreground mb-4 pb-2 border-b border-border"> <!-- Title styling -->
|
<h2 class="text-xl font-semibold text-foreground mb-4 pb-2 border-b border-border"> <!-- Title styling -->
|
||||||
{{ $t('settings.notifications.title') }}
|
{{ $t('settings.notifications.title') }}
|
||||||
</h2>
|
</h2>
|
||||||
|
|||||||
@@ -1,40 +1,40 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { ref, reactive, onMounted, watch, computed } from 'vue';
|
import { ref, reactive, onMounted, watch, computed } from 'vue';
|
||||||
import { useI18n } from 'vue-i18n';
|
import { useI18n } from 'vue-i18n';
|
||||||
import { useAppearanceStore } from '../stores/appearance.store'; // 使用新的 store
|
import { useAppearanceStore } from '../stores/appearance.store';
|
||||||
import { storeToRefs } from 'pinia';
|
import { storeToRefs } from 'pinia';
|
||||||
import type { ITheme } from 'xterm';
|
import type { ITheme } from 'xterm';
|
||||||
import type { TerminalTheme } from '../types/terminal-theme.types'; // 引入本地类型
|
import type { TerminalTheme } from '../types/terminal-theme.types';
|
||||||
import { defaultXtermTheme } from '../features/appearance/config/default-themes'; // 引入默认主题
|
import { defaultXtermTheme } from '../features/appearance/config/default-themes';
|
||||||
|
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
const appearanceStore = useAppearanceStore();
|
const appearanceStore = useAppearanceStore();
|
||||||
const {
|
const {
|
||||||
appearanceSettings, // <-- 添加这个 ref
|
appearanceSettings,
|
||||||
currentUiTheme,
|
currentUiTheme,
|
||||||
// currentTerminalTheme, // 这个是计算属性,只读,在编辑时不需要直接用
|
|
||||||
activeTerminalThemeId, // 现在是 number | null | undefined
|
activeTerminalThemeId,
|
||||||
allTerminalThemes, // 使用重命名后的变量
|
allTerminalThemes,
|
||||||
currentTerminalFontFamily,
|
currentTerminalFontFamily,
|
||||||
currentTerminalFontSize,
|
currentTerminalFontSize,
|
||||||
currentEditorFontSize, // <-- 新增
|
currentEditorFontSize,
|
||||||
pageBackgroundImage,
|
pageBackgroundImage,
|
||||||
// pageBackgroundOpacity, // Removed
|
|
||||||
terminalBackgroundImage,
|
terminalBackgroundImage,
|
||||||
// terminalBackgroundOpacity, // Removed
|
|
||||||
isTerminalBackgroundEnabled, // <-- 新增:终端背景启用状态
|
isTerminalBackgroundEnabled,
|
||||||
} = storeToRefs(appearanceStore);
|
} = storeToRefs(appearanceStore);
|
||||||
|
|
||||||
// --- 本地状态用于编辑 ---
|
|
||||||
const editableUiTheme = ref<Record<string, string>>({});
|
const editableUiTheme = ref<Record<string, string>>({});
|
||||||
const editableTerminalFontFamily = ref('');
|
const editableTerminalFontFamily = ref('');
|
||||||
const editableTerminalFontSize = ref(14);
|
const editableTerminalFontSize = ref(14);
|
||||||
const editableEditorFontSize = ref(14); // <-- 新增,编辑器字体大小
|
const editableEditorFontSize = ref(14);
|
||||||
// const editablePageBackgroundOpacity = ref(1.0); // Removed
|
|
||||||
// const editableTerminalBackgroundOpacity = ref(1.0); // Removed
|
|
||||||
const editableUiThemeString = ref(''); // 用于 textarea 绑定
|
const editableUiThemeString = ref('');
|
||||||
const themeParseError = ref<string | null>(null); // 用于显示 JSON 解析错误
|
const themeParseError = ref<string | null>(null);
|
||||||
const localTerminalBackgroundEnabled = ref(true); // <-- 新增:本地终端背景开关状态
|
const localTerminalBackgroundEnabled = ref(true);
|
||||||
|
|
||||||
// 终端主题管理相关状态
|
// 终端主题管理相关状态
|
||||||
const isEditingTheme = ref(false); // 是否正在编辑某个主题
|
const isEditingTheme = ref(false); // 是否正在编辑某个主题
|
||||||
|
|||||||
@@ -1,15 +1,14 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { ref, onMounted, onBeforeUnmount, watch, nextTick } from 'vue';
|
import { ref, onMounted, onBeforeUnmount, watch, nextTick } from 'vue';
|
||||||
import { ITheme } from 'xterm';
|
import { Terminal, ITerminalAddon, IDisposable } from 'xterm';
|
||||||
import { Terminal, ITerminalAddon, IDisposable } from 'xterm'; // +++ 导入 ITerminalAddon 和 IDisposable +++
|
import { useAppearanceStore } from '../stores/appearance.store';
|
||||||
import { useAppearanceStore } from '../stores/appearance.store'; // 导入外观 store
|
import { useSettingsStore } from '../stores/settings.store';
|
||||||
import { useSettingsStore } from '../stores/settings.store'; // +++ 导入设置 store +++
|
import { storeToRefs } from 'pinia';
|
||||||
import { storeToRefs } from 'pinia'; // 导入 storeToRefs
|
|
||||||
import { FitAddon } from 'xterm-addon-fit';
|
import { FitAddon } from 'xterm-addon-fit';
|
||||||
import { WebLinksAddon } from 'xterm-addon-web-links';
|
import { WebLinksAddon } from 'xterm-addon-web-links';
|
||||||
import { SearchAddon, type ISearchOptions } from '@xterm/addon-search'; // *** 更新导入路径 ***
|
import { SearchAddon, type ISearchOptions } from '@xterm/addon-search';
|
||||||
import 'xterm/css/xterm.css'; // 引入 xterm 样式
|
import 'xterm/css/xterm.css';
|
||||||
// *** 移除无效的 CSS 导入 ***
|
|
||||||
|
|
||||||
// 定义 props 和 emits
|
// 定义 props 和 emits
|
||||||
const props = defineProps<{
|
const props = defineProps<{
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ import WorkspaceConnectionListComponent from './WorkspaceConnectionList.vue';
|
|||||||
import { useSessionStore } from '../stores/session.store';
|
import { useSessionStore } from '../stores/session.store';
|
||||||
import { useConnectionsStore, type ConnectionInfo } from '../stores/connections.store';
|
import { useConnectionsStore, type ConnectionInfo } from '../stores/connections.store';
|
||||||
import { useLayoutStore, type PaneName } from '../stores/layout.store';
|
import { useLayoutStore, type PaneName } from '../stores/layout.store';
|
||||||
// 导入会话状态类型
|
|
||||||
import type { SessionTabInfoWithStatus } from '../stores/session.store';
|
import type { SessionTabInfoWithStatus } from '../stores/session.store';
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,13 +1,13 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { ref, computed, onMounted, onBeforeUnmount, defineExpose, watch, nextTick } from 'vue';
|
import { ref, computed, onMounted, onBeforeUnmount, defineExpose, watch, nextTick } from 'vue';
|
||||||
import { storeToRefs } from 'pinia';
|
import { storeToRefs } from 'pinia';
|
||||||
// import { useRouter } from 'vue-router'; // 不再需要 router
|
|
||||||
import { useI18n } from 'vue-i18n';
|
import { useI18n } from 'vue-i18n';
|
||||||
// import RemoteDesktopModal from './RemoteDesktopModal.vue'; // --- 移除 RDP 模态框导入 ---
|
|
||||||
import { useConnectionsStore, ConnectionInfo } from '../stores/connections.store';
|
import { useConnectionsStore, ConnectionInfo } from '../stores/connections.store';
|
||||||
import { useTagsStore, TagInfo } from '../stores/tags.store';
|
import { useTagsStore, TagInfo } from '../stores/tags.store';
|
||||||
import { useSessionStore } from '../stores/session.store'; // 导入 session store
|
import { useSessionStore } from '../stores/session.store';
|
||||||
import { useFocusSwitcherStore } from '../stores/focusSwitcher.store'; // +++ 导入焦点切换 Store +++
|
import { useFocusSwitcherStore } from '../stores/focusSwitcher.store';
|
||||||
|
|
||||||
// 定义事件
|
// 定义事件
|
||||||
const emit = defineEmits([
|
const emit = defineEmits([
|
||||||
@@ -15,8 +15,7 @@ const emit = defineEmits([
|
|||||||
// 'open-new-session', // 中键单击 - 请求在新标签中打开 (已移除)
|
// 'open-new-session', // 中键单击 - 请求在新标签中打开 (已移除)
|
||||||
'request-add-connection', // 右键菜单 - 添加
|
'request-add-connection', // 右键菜单 - 添加
|
||||||
'request-edit-connection' // 右键菜单 - 编辑
|
'request-edit-connection' // 右键菜单 - 编辑
|
||||||
// --- 移除 RDP 事件 ---
|
|
||||||
// 'request-rdp-modal'
|
|
||||||
]);
|
]);
|
||||||
|
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
|
|||||||
Reference in New Issue
Block a user