update
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
<script setup lang="ts">
|
||||
import { ref, watch, nextTick } from 'vue';
|
||||
import { ref, watch, nextTick, onMounted, onBeforeUnmount, defineExpose } from 'vue';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
import { useFocusSwitcherStore } from '../stores/focusSwitcher.store'; // 导入 Store
|
||||
// 假设你有一个图标库,例如 unplugin-icons 或类似库
|
||||
@@ -63,6 +63,7 @@ watch(searchTerm, (newValue) => {
|
||||
|
||||
// 可以在这里添加一个 ref 用于聚焦搜索框
|
||||
const searchInputRef = ref<HTMLInputElement | null>(null);
|
||||
const commandInputRef = ref<HTMLInputElement | null>(null); // Ref for command input
|
||||
|
||||
// Removed debug computed property
|
||||
|
||||
@@ -84,6 +85,46 @@ watch(() => focusSwitcherStore.activateTerminalSearchTrigger, () => {
|
||||
}
|
||||
});
|
||||
|
||||
// --- Focus Actions ---
|
||||
const focusCommandInput = (): boolean => {
|
||||
if (commandInputRef.value) {
|
||||
commandInputRef.value.focus();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
const focusSearchInput = (): boolean => {
|
||||
if (!isSearching.value) {
|
||||
// If search is not active, activate it first
|
||||
toggleSearch(); // This might need nextTick if toggleSearch is async
|
||||
nextTick(() => { // Ensure DOM is updated after toggleSearch
|
||||
if (searchInputRef.value) {
|
||||
searchInputRef.value.focus();
|
||||
}
|
||||
});
|
||||
// Since focusing might be async after toggle, we optimistically return true
|
||||
// or adjust based on toggleSearch's behavior. For simplicity, assume it works.
|
||||
return true;
|
||||
} else if (searchInputRef.value) {
|
||||
searchInputRef.value.focus();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
defineExpose({ focusCommandInput, focusSearchInput });
|
||||
|
||||
// --- Register/Unregister Focus Actions ---
|
||||
onMounted(() => {
|
||||
focusSwitcherStore.registerFocusAction('commandInput', focusCommandInput);
|
||||
focusSwitcherStore.registerFocusAction('terminalSearch', focusSearchInput);
|
||||
});
|
||||
|
||||
onBeforeUnmount(() => {
|
||||
focusSwitcherStore.unregisterFocusAction('commandInput');
|
||||
focusSwitcherStore.unregisterFocusAction('terminalSearch');
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
@@ -99,6 +140,7 @@ watch(() => focusSwitcherStore.activateTerminalSearchTrigger, () => {
|
||||
v-model="commandInput"
|
||||
:placeholder="t('commandInputBar.placeholder')"
|
||||
class="command-input"
|
||||
ref="commandInputRef"
|
||||
data-focus-id="commandInput"
|
||||
@keydown.enter="sendCommand"
|
||||
@keydown="handleCommandInputKeydown"
|
||||
|
||||
@@ -1,13 +1,15 @@
|
||||
<script setup lang="ts">
|
||||
import { computed, type PropType, ref, watch } from 'vue'; // 添加 ref 和 watch
|
||||
import { computed, type PropType, ref, watch, defineExpose, onMounted, onBeforeUnmount } from 'vue'; // 添加 ref, watch, defineExpose, onMounted, onBeforeUnmount
|
||||
import { useI18n } from 'vue-i18n';
|
||||
// import { storeToRefs } from 'pinia'; // 移除 storeToRefs
|
||||
import MonacoEditor from './MonacoEditor.vue'; // 导入 Monaco Editor 组件
|
||||
import FileEditorTabs from './FileEditorTabs.vue'; // 导入标签栏组件 (路径确认无误)
|
||||
// import { useFileEditorStore } from '../stores/fileEditor.store'; // 移除 Store 导入
|
||||
import type { FileTab } from '../stores/fileEditor.store'; // 保留类型导入
|
||||
import { useFocusSwitcherStore } from '../stores/focusSwitcher.store'; // +++ 导入焦点切换 Store +++
|
||||
|
||||
const { t } = useI18n();
|
||||
const focusSwitcherStore = useFocusSwitcherStore(); // +++ 实例化焦点切换 Store +++
|
||||
|
||||
// --- Props ---
|
||||
const props = defineProps({
|
||||
@@ -92,6 +94,28 @@ const handleSaveRequest = () => {
|
||||
// const handleCloseContainer = () => { ... };
|
||||
// const handleMinimizeContainer = () => { ... };
|
||||
|
||||
// 新增:Monaco Editor 组件的引用
|
||||
const monacoEditorRef = ref<InstanceType<typeof MonacoEditor> | null>(null);
|
||||
|
||||
// 新增:聚焦活动编辑器的方法
|
||||
const focusActiveEditor = (): boolean => {
|
||||
if (monacoEditorRef.value) {
|
||||
monacoEditorRef.value.focus();
|
||||
return true; // 聚焦成功
|
||||
}
|
||||
return false; // 聚焦失败
|
||||
};
|
||||
|
||||
// 新增:暴露聚焦方法
|
||||
defineExpose({ focusActiveEditor });
|
||||
|
||||
// +++ 注册/注销自定义聚焦动作 +++
|
||||
onMounted(() => {
|
||||
focusSwitcherStore.registerFocusAction('fileEditorActive', focusActiveEditor);
|
||||
});
|
||||
onBeforeUnmount(() => {
|
||||
focusSwitcherStore.unregisterFocusAction('fileEditorActive');
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
@@ -135,6 +159,7 @@ const handleSaveRequest = () => {
|
||||
<div v-else-if="currentTabLoadingError" class="editor-error">{{ currentTabLoadingError }}</div>
|
||||
<MonacoEditor
|
||||
v-else-if="activeTab"
|
||||
ref="monacoEditorRef"
|
||||
:key="activeTab.id"
|
||||
v-model="localEditorContent"
|
||||
:language="currentTabLanguage"
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<script setup lang="ts">
|
||||
import { ref, computed, onMounted, onBeforeUnmount, nextTick, watch, watchEffect, type PropType, readonly } from 'vue'; // 恢复导入, 添加 watch
|
||||
import { ref, computed, onMounted, onBeforeUnmount, nextTick, watch, watchEffect, type PropType, readonly, defineExpose } from 'vue'; // 恢复导入, 添加 watch, defineExpose
|
||||
import { useI18n } from 'vue-i18n';
|
||||
import { useRoute } from 'vue-router'; // 保留用于生成下载 URL (如果下载逻辑移动则可移除)
|
||||
import { storeToRefs } from 'pinia'; // 导入 storeToRefs
|
||||
@@ -536,6 +536,14 @@ onBeforeUnmount(() => {
|
||||
cleanupSftpHandlers();
|
||||
});
|
||||
|
||||
// +++ 注册/注销自定义聚焦动作 +++
|
||||
onMounted(() => {
|
||||
focusSwitcherStore.registerFocusAction('fileManagerSearch', focusSearchInput);
|
||||
});
|
||||
onBeforeUnmount(() => {
|
||||
focusSwitcherStore.unregisterFocusAction('fileManagerSearch');
|
||||
});
|
||||
|
||||
// --- 列宽调整逻辑 (保持不变) ---
|
||||
const getColumnKeyByIndex = (index: number): keyof typeof colWidths.value | null => {
|
||||
const keys = Object.keys(colWidths.value) as Array<keyof typeof colWidths.value>;
|
||||
@@ -653,6 +661,25 @@ const handleWheel = (event: WheelEvent) => {
|
||||
}
|
||||
};
|
||||
|
||||
// +++ 新增:聚焦搜索框的方法 +++
|
||||
const focusSearchInput = (): boolean => {
|
||||
if (!isSearchActive.value) {
|
||||
activateSearch(); // Activate search first
|
||||
nextTick(() => { // Wait for DOM update
|
||||
if (searchInputRef.value) {
|
||||
searchInputRef.value.focus();
|
||||
}
|
||||
});
|
||||
// Assume activation and focus will likely succeed
|
||||
return true;
|
||||
} else if (searchInputRef.value) {
|
||||
searchInputRef.value.focus();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
defineExpose({ focusSearchInput });
|
||||
|
||||
</script>
|
||||
|
||||
<template>
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, onMounted, onBeforeUnmount, watch } from 'vue';
|
||||
import { ref, onMounted, onBeforeUnmount, watch, defineExpose } from 'vue';
|
||||
import * as monaco from 'monaco-editor';
|
||||
import { useAppearanceStore } from '../stores/appearance.store'; // <-- 导入 Store
|
||||
import { storeToRefs } from 'pinia'; // <-- 导入 storeToRefs
|
||||
@@ -227,6 +227,11 @@ onBeforeUnmount(() => {
|
||||
// getValue: () => editorInstance?.getValue()
|
||||
// });
|
||||
|
||||
// Expose the focus method
|
||||
defineExpose({
|
||||
focus: () => editorInstance?.focus()
|
||||
});
|
||||
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
<script setup lang="ts">
|
||||
import { ref, computed, onMounted } from 'vue'; // 确保 ref 已导入
|
||||
import { ref, computed, onMounted, onBeforeUnmount, defineExpose } from 'vue'; // 确保 ref, defineExpose, onBeforeUnmount 已导入
|
||||
import { storeToRefs } from 'pinia';
|
||||
// import { useRouter } from 'vue-router'; // 不再需要 router
|
||||
import { useI18n } from 'vue-i18n';
|
||||
import { useConnectionsStore, ConnectionInfo } from '../stores/connections.store';
|
||||
import { useTagsStore, TagInfo } from '../stores/tags.store';
|
||||
import { useSessionStore } from '../stores/session.store'; // 导入 session store
|
||||
import { useFocusSwitcherStore } from '../stores/focusSwitcher.store'; // +++ 导入焦点切换 Store +++
|
||||
|
||||
// 定义事件
|
||||
const emit = defineEmits([
|
||||
@@ -20,12 +21,14 @@ const { t } = useI18n();
|
||||
const connectionsStore = useConnectionsStore();
|
||||
const tagsStore = useTagsStore();
|
||||
const sessionStore = useSessionStore(); // 获取 session store 实例
|
||||
const focusSwitcherStore = useFocusSwitcherStore(); // +++ 实例化焦点切换 Store +++
|
||||
|
||||
const { connections, isLoading: connectionsLoading, error: connectionsError } = storeToRefs(connectionsStore);
|
||||
const { tags, isLoading: tagsLoading, error: tagsError } = storeToRefs(tagsStore);
|
||||
|
||||
// 搜索词
|
||||
const searchTerm = ref('');
|
||||
const searchInputRef = ref<HTMLInputElement | null>(null); // 新增:搜索输入框的 ref
|
||||
|
||||
// 右键菜单状态
|
||||
const contextMenuVisible = ref(false);
|
||||
@@ -168,6 +171,14 @@ onMounted(() => {
|
||||
tagsStore.fetchTags();
|
||||
});
|
||||
|
||||
// +++ 注册/注销自定义聚焦动作 +++
|
||||
onMounted(() => {
|
||||
focusSwitcherStore.registerFocusAction('connectionListSearch', focusSearchInput);
|
||||
});
|
||||
onBeforeUnmount(() => {
|
||||
focusSwitcherStore.unregisterFocusAction('connectionListSearch');
|
||||
});
|
||||
|
||||
// 处理中键点击(在新标签页打开)
|
||||
const handleOpenInNewTab = (connectionId: number) => {
|
||||
console.log(`[WkspConnList] handleOpenInNewTab (中键/辅助键) called for ID: ${connectionId}`);
|
||||
@@ -176,6 +187,16 @@ const handleOpenInNewTab = (connectionId: number) => {
|
||||
closeContextMenu(); // 如果右键菜单是打开的,也关闭它
|
||||
return false; // 尝试显式阻止进一步处理
|
||||
};
|
||||
|
||||
// 新增:暴露聚焦搜索框的方法
|
||||
const focusSearchInput = (): boolean => {
|
||||
if (searchInputRef.value) {
|
||||
searchInputRef.value.focus();
|
||||
return true; // 聚焦成功
|
||||
}
|
||||
return false; // 聚焦失败
|
||||
};
|
||||
defineExpose({ focusSearchInput });
|
||||
</script>
|
||||
|
||||
<template>
|
||||
@@ -193,7 +214,9 @@ const handleOpenInNewTab = (connectionId: number) => {
|
||||
type="text"
|
||||
v-model="searchTerm"
|
||||
:placeholder="t('workspaceConnectionList.searchPlaceholder')"
|
||||
ref="searchInputRef"
|
||||
class="search-input"
|
||||
data-focus-id="connectionListSearch"
|
||||
/>
|
||||
<button
|
||||
class="add-button"
|
||||
|
||||
Reference in New Issue
Block a user