♻️ 添加终端面板快捷键.
This commit is contained in:
@@ -62,6 +62,18 @@ public class TerminalPreferenceStrategy implements IPreferenceStrategy<TerminalP
|
|||||||
String shortcutSetting = TerminalPreferenceModel.ShortcutSettingModel.builder()
|
String shortcutSetting = TerminalPreferenceModel.ShortcutSettingModel.builder()
|
||||||
.enabled(true)
|
.enabled(true)
|
||||||
.keys(Lists.of(
|
.keys(Lists.of(
|
||||||
|
// 全局快捷键
|
||||||
|
new TerminalPreferenceModel.ShortcutKeysModel("closeTab", true, true, true, "KeyW", true),
|
||||||
|
new TerminalPreferenceModel.ShortcutKeysModel("changeToPrevTab", true, true, true, "BracketLeft", true),
|
||||||
|
new TerminalPreferenceModel.ShortcutKeysModel("changeToNextTab", true, true, true, "BracketRight", true),
|
||||||
|
new TerminalPreferenceModel.ShortcutKeysModel("openNewConnectTab", true, true, true, "KeyN", true),
|
||||||
|
// 终端面板快捷键
|
||||||
|
new TerminalPreferenceModel.ShortcutKeysModel("openNewConnectModal", true, false, true, "KeyN", true),
|
||||||
|
new TerminalPreferenceModel.ShortcutKeysModel("copyTerminal", true, false, true, "KeyO", true),
|
||||||
|
new TerminalPreferenceModel.ShortcutKeysModel("closeTerminal", true, false, true, "KeyW", true),
|
||||||
|
new TerminalPreferenceModel.ShortcutKeysModel("changeToPrevTerminal", true, false, true, "BracketLeft", true),
|
||||||
|
new TerminalPreferenceModel.ShortcutKeysModel("changeToNextTerminal", true, false, true, "BracketRight", true),
|
||||||
|
// 终端会话快捷键
|
||||||
new TerminalPreferenceModel.ShortcutKeysModel("copy", true, true, false, "KeyC", true),
|
new TerminalPreferenceModel.ShortcutKeysModel("copy", true, true, false, "KeyC", true),
|
||||||
new TerminalPreferenceModel.ShortcutKeysModel("paste", true, true, false, "KeyV", true),
|
new TerminalPreferenceModel.ShortcutKeysModel("paste", true, true, false, "KeyV", true),
|
||||||
new TerminalPreferenceModel.ShortcutKeysModel("toTop", true, true, false, "ArrowUp", true),
|
new TerminalPreferenceModel.ShortcutKeysModel("toTop", true, true, false, "ArrowUp", true),
|
||||||
@@ -70,12 +82,7 @@ public class TerminalPreferenceStrategy implements IPreferenceStrategy<TerminalP
|
|||||||
new TerminalPreferenceModel.ShortcutKeysModel("search", true, true, false, "KeyF", true),
|
new TerminalPreferenceModel.ShortcutKeysModel("search", true, true, false, "KeyF", true),
|
||||||
new TerminalPreferenceModel.ShortcutKeysModel("commandEditor", true, false, true, "KeyE", true),
|
new TerminalPreferenceModel.ShortcutKeysModel("commandEditor", true, false, true, "KeyE", true),
|
||||||
new TerminalPreferenceModel.ShortcutKeysModel("fontSizePlus", true, false, true, "Equal", true),
|
new TerminalPreferenceModel.ShortcutKeysModel("fontSizePlus", true, false, true, "Equal", true),
|
||||||
new TerminalPreferenceModel.ShortcutKeysModel("fontSizeSubtract", true, false, true, "Minus", true),
|
new TerminalPreferenceModel.ShortcutKeysModel("fontSizeSubtract", true, false, true, "Minus", true)
|
||||||
new TerminalPreferenceModel.ShortcutKeysModel("closeTab", true, false, true, "KeyW", true),
|
|
||||||
new TerminalPreferenceModel.ShortcutKeysModel("changeToPrevTab", true, false, true, "ArrowLeft", true),
|
|
||||||
new TerminalPreferenceModel.ShortcutKeysModel("changeToNextTab", true, false, true, "ArrowRight", true),
|
|
||||||
new TerminalPreferenceModel.ShortcutKeysModel("openCopyTerminalTab", true, false, true, "KeyO", true),
|
|
||||||
new TerminalPreferenceModel.ShortcutKeysModel("openNewConnectTab", true, false, true, "KeyN", true)
|
|
||||||
))
|
))
|
||||||
.build()
|
.build()
|
||||||
.toJsonString();
|
.toJsonString();
|
||||||
|
|||||||
6
orion-ops-ui/components.d.ts
vendored
6
orion-ops-ui/components.d.ts
vendored
@@ -5,11 +5,11 @@
|
|||||||
// Read more: https://github.com/vuejs/core/pull/3399
|
// Read more: https://github.com/vuejs/core/pull/3399
|
||||||
import '@vue/runtime-core';
|
import '@vue/runtime-core';
|
||||||
|
|
||||||
export {};
|
export {}
|
||||||
|
|
||||||
declare module '@vue/runtime-core' {
|
declare module '@vue/runtime-core' {
|
||||||
export interface GlobalComponents {
|
export interface GlobalComponents {
|
||||||
RouterLink: typeof import('vue-router')['RouterLink'];
|
RouterLink: typeof import('vue-router')['RouterLink']
|
||||||
RouterView: typeof import('vue-router')['RouterView'];
|
RouterView: typeof import('vue-router')['RouterView']
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -157,7 +157,7 @@
|
|||||||
});
|
});
|
||||||
|
|
||||||
// 点击命令
|
// 点击命令
|
||||||
const clickCommand = (e: PointerEvent) => {
|
const clickCommand = (e: Event) => {
|
||||||
if (props.item.expand) {
|
if (props.item.expand) {
|
||||||
// 获取选中的文本
|
// 获取选中的文本
|
||||||
const selectedText = window.getSelection()?.toString();
|
const selectedText = window.getSelection()?.toString();
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
:editable="true"
|
:editable="true"
|
||||||
:auto-switch="true"
|
:auto-switch="true"
|
||||||
:show-add-button="true"
|
:show-add-button="true"
|
||||||
@add="openHostModal"
|
@add="openNewConnect"
|
||||||
@tab-click="k => panel.clickTab(k as string)"
|
@tab-click="k => panel.clickTab(k as string)"
|
||||||
@delete="k => panel.deleteTab(k as string)">
|
@delete="k => panel.deleteTab(k as string)">
|
||||||
<!-- 右侧按钮 -->
|
<!-- 右侧按钮 -->
|
||||||
@@ -32,9 +32,6 @@
|
|||||||
<terminal-view :tab="tab" />
|
<terminal-view :tab="tab" />
|
||||||
</a-tab-pane>
|
</a-tab-pane>
|
||||||
</a-tabs>
|
</a-tabs>
|
||||||
<!-- 新建连接模态框 -->
|
|
||||||
<host-list-modal ref="hostModal"
|
|
||||||
@choose="item => openTerminal(item, index)" />
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@@ -46,22 +43,19 @@
|
|||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import type { ITerminalTabManager, TerminalPanelTabItem } from '../../types/terminal.type';
|
import type { ITerminalTabManager, TerminalPanelTabItem } from '../../types/terminal.type';
|
||||||
import { ref, watch } from 'vue';
|
import { watch } from 'vue';
|
||||||
import { useTerminalStore } from '@/store';
|
import { useTerminalStore } from '@/store';
|
||||||
import { TerminalPanelTabType } from '../../types/terminal.const';
|
import { TerminalPanelTabType } from '../../types/terminal.const';
|
||||||
import TerminalView from '../xterm/terminal-view.vue';
|
import TerminalView from '../xterm/terminal-view.vue';
|
||||||
import HostListModal from '../new-connection/host-list-modal.vue';
|
|
||||||
|
|
||||||
const props = defineProps<{
|
const props = defineProps<{
|
||||||
index: number,
|
index: number,
|
||||||
panel: ITerminalTabManager<TerminalPanelTabItem>,
|
panel: ITerminalTabManager<TerminalPanelTabItem>,
|
||||||
}>();
|
}>();
|
||||||
|
|
||||||
const emits = defineEmits(['close']);
|
const emits = defineEmits(['close', 'openNewConnect']);
|
||||||
|
|
||||||
const { sessionManager, openTerminal } = useTerminalStore();
|
const { sessionManager } = useTerminalStore();
|
||||||
|
|
||||||
const hostModal = ref();
|
|
||||||
|
|
||||||
// 监听 tab 切换
|
// 监听 tab 切换
|
||||||
watch(() => props.panel.active, (active, before) => {
|
watch(() => props.panel.active, (active, before) => {
|
||||||
@@ -86,8 +80,8 @@
|
|||||||
});
|
});
|
||||||
|
|
||||||
// 打开主机模态框
|
// 打开主机模态框
|
||||||
const openHostModal = () => {
|
const openNewConnect = () => {
|
||||||
hostModal.value.open();
|
emits('openNewConnect', props.index);
|
||||||
};
|
};
|
||||||
|
|
||||||
// 关闭面板
|
// 关闭面板
|
||||||
|
|||||||
@@ -1,11 +1,14 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="terminal-panels-container">
|
<div class="terminal-panels-container">
|
||||||
<!-- 面板 -->
|
<!-- 终端面板 -->
|
||||||
<terminal-panel v-for="(panel, index) in panelManager.panels"
|
<terminal-panel v-for="(panel, index) in panelManager.panels"
|
||||||
:key="index"
|
:key="index"
|
||||||
:index="index"
|
:index="index"
|
||||||
:panel="panel"
|
:panel="panel"
|
||||||
|
@open-new-connect="openHostModal"
|
||||||
@close="closePanel" />
|
@close="closePanel" />
|
||||||
|
<!-- 新建连接模态框 -->
|
||||||
|
<host-list-modal ref="hostModal" />
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@@ -17,11 +20,20 @@
|
|||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { useTerminalStore } from '@/store';
|
import { useTerminalStore } from '@/store';
|
||||||
import { onUnmounted } from 'vue';
|
import { ref, onMounted, onUnmounted } from 'vue';
|
||||||
import { TerminalTabs } from '../../types/terminal.const';
|
import { TerminalShortcutKeys, TerminalTabs } from '../../types/terminal.const';
|
||||||
|
import { addEventListen, removeEventListen } from '@/utils/event';
|
||||||
import TerminalPanel from './terminal-panel.vue';
|
import TerminalPanel from './terminal-panel.vue';
|
||||||
|
import HostListModal from '../new-connection/host-list-modal.vue';
|
||||||
|
|
||||||
const { tabManager, panelManager } = useTerminalStore();
|
const { preference, tabManager, panelManager, copyTerminalSession } = useTerminalStore();
|
||||||
|
|
||||||
|
const hostModal = ref();
|
||||||
|
|
||||||
|
// 打开主机模态框
|
||||||
|
const openHostModal = (index: number) => {
|
||||||
|
hostModal.value.open(index);
|
||||||
|
};
|
||||||
|
|
||||||
// 移除面板
|
// 移除面板
|
||||||
const closePanel = (index: number) => {
|
const closePanel = (index: number) => {
|
||||||
@@ -35,9 +47,67 @@
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// 卸载清空
|
// 处理全局快捷键逻辑
|
||||||
|
const handlerKeyboard = (event: Event) => {
|
||||||
|
const e = event as KeyboardEvent;
|
||||||
|
// 检测触发的快捷键
|
||||||
|
const key = preference.shortcutSetting.keys.find(key => {
|
||||||
|
return key.code === e.code
|
||||||
|
&& key.altKey === e.altKey
|
||||||
|
&& key.shiftKey === e.shiftKey
|
||||||
|
&& key.ctrlKey === e.ctrlKey;
|
||||||
|
});
|
||||||
|
if (!key) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// 触发逻辑
|
||||||
|
switch (key.item) {
|
||||||
|
case TerminalShortcutKeys.OPEN_NEW_CONNECT_MODAL:
|
||||||
|
// 打开新建连接弹框
|
||||||
|
hostModal.value.open(panelManager.active);
|
||||||
|
break;
|
||||||
|
case TerminalShortcutKeys.COPY_TERMINAL:
|
||||||
|
// 复制终端
|
||||||
|
const hostId = panelManager.getCurrentPanel().getCurrentTab()?.hostId;
|
||||||
|
if (hostId) {
|
||||||
|
copyTerminalSession(hostId, panelManager.active);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case TerminalShortcutKeys.CLOSE_TERMINAL:
|
||||||
|
// 关闭终端
|
||||||
|
const panel = panelManager.getCurrentPanel();
|
||||||
|
if (panel.active) {
|
||||||
|
panel.deleteTab(panel.active);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case TerminalShortcutKeys.CHANGE_TO_PREV_TERMINAL:
|
||||||
|
// 切换至前一个终端
|
||||||
|
panelManager.getCurrentPanel().changeToPrevTab();
|
||||||
|
break;
|
||||||
|
case TerminalShortcutKeys.CHANGE_TO_NEXT_TERMINAL:
|
||||||
|
// 切换至后一个终端
|
||||||
|
panelManager.getCurrentPanel().changeToNextTab();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// 监听键盘事件
|
||||||
|
onMounted(() => {
|
||||||
|
if (preference.shortcutSetting.enabled) {
|
||||||
|
addEventListen(window, 'keydown', handlerKeyboard);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// 卸载回调
|
||||||
onUnmounted(() => {
|
onUnmounted(() => {
|
||||||
|
// 清空面板
|
||||||
panelManager.reset();
|
panelManager.reset();
|
||||||
|
// 移除键盘事件
|
||||||
|
if (preference.shortcutSetting.enabled) {
|
||||||
|
removeEventListen(window, 'keydown', handlerKeyboard);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -49,17 +49,17 @@
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
|
import type { HostQueryResponse } from '@/api/asset/host';
|
||||||
import { computed, ref } from 'vue';
|
import { computed, ref } from 'vue';
|
||||||
import { useTerminalStore } from '@/store';
|
import { useTerminalStore } from '@/store';
|
||||||
import useVisible from '@/hooks/visible';
|
import useVisible from '@/hooks/visible';
|
||||||
import { HostQueryResponse } from '@/api/asset/host';
|
|
||||||
|
|
||||||
const emits = defineEmits(['choose']);
|
const { hosts, openTerminal } = useTerminalStore();
|
||||||
|
|
||||||
const { hosts } = useTerminalStore();
|
|
||||||
const { visible, setVisible } = useVisible();
|
const { visible, setVisible } = useVisible();
|
||||||
|
|
||||||
|
const panelIndex = ref();
|
||||||
const filterValue = ref('');
|
const filterValue = ref('');
|
||||||
|
|
||||||
const hostList = computed(() => {
|
const hostList = computed(() => {
|
||||||
const filterVal = filterValue.value.toLowerCase();
|
const filterVal = filterValue.value.toLowerCase();
|
||||||
let list;
|
let list;
|
||||||
@@ -88,7 +88,8 @@
|
|||||||
});
|
});
|
||||||
|
|
||||||
// 打开配置
|
// 打开配置
|
||||||
const open = () => {
|
const open = (index: number) => {
|
||||||
|
panelIndex.value = index;
|
||||||
setVisible(true);
|
setVisible(true);
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -96,7 +97,7 @@
|
|||||||
|
|
||||||
// 打开终端
|
// 打开终端
|
||||||
const clickHost = (item: HostQueryResponse) => {
|
const clickHost = (item: HostQueryResponse) => {
|
||||||
emits('choose', item);
|
openTerminal(item, panelIndex.value);
|
||||||
setVisible(false);
|
setVisible(false);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -26,8 +26,15 @@
|
|||||||
@set-editable="setEditableStatus"
|
@set-editable="setEditableStatus"
|
||||||
@clear-editable="clearEditableStatus"
|
@clear-editable="clearEditableStatus"
|
||||||
@update-enabled="updateEnabledStatus" />
|
@update-enabled="updateEnabledStatus" />
|
||||||
<!-- 终端快捷键 -->
|
<!-- 终端面板快捷键 -->
|
||||||
<terminal-shortcut-keys-block title="终端快捷键"
|
<terminal-shortcut-keys-block title="终端面板快捷键"
|
||||||
|
:type="TerminalShortcutType.PANEL"
|
||||||
|
:items="shortcutKeys"
|
||||||
|
@set-editable="setEditableStatus"
|
||||||
|
@clear-editable="clearEditableStatus"
|
||||||
|
@update-enabled="updateEnabledStatus" />
|
||||||
|
<!-- 终端会话快捷键 -->
|
||||||
|
<terminal-shortcut-keys-block title="终端会话快捷键"
|
||||||
:type="TerminalShortcutType.TERMINAL"
|
:type="TerminalShortcutType.TERMINAL"
|
||||||
:items="shortcutKeys"
|
:items="shortcutKeys"
|
||||||
@set-editable="setEditableStatus"
|
@set-editable="setEditableStatus"
|
||||||
|
|||||||
@@ -131,8 +131,9 @@ export const ActionBarItems = [
|
|||||||
|
|
||||||
// 终端快捷键操作类型
|
// 终端快捷键操作类型
|
||||||
export const TerminalShortcutType = {
|
export const TerminalShortcutType = {
|
||||||
TAB: 1,
|
GLOBAL: 1,
|
||||||
TERMINAL: 2
|
PANEL: 2,
|
||||||
|
TERMINAL: 3
|
||||||
};
|
};
|
||||||
|
|
||||||
// 终端操作快捷键 key
|
// 终端操作快捷键 key
|
||||||
@@ -145,6 +146,16 @@ export const TerminalShortcutKeys = {
|
|||||||
CLOSE_TAB: 'closeTab',
|
CLOSE_TAB: 'closeTab',
|
||||||
// 打开新建连接 tab
|
// 打开新建连接 tab
|
||||||
OPEN_NEW_CONNECT_TAB: 'openNewConnectTab',
|
OPEN_NEW_CONNECT_TAB: 'openNewConnectTab',
|
||||||
|
// 打开新建连接弹框
|
||||||
|
OPEN_NEW_CONNECT_MODAL: 'openNewConnectModal',
|
||||||
|
// 复制终端
|
||||||
|
COPY_TERMINAL: 'copyTerminal',
|
||||||
|
// 关闭终端
|
||||||
|
CLOSE_TERMINAL: 'closeTerminal',
|
||||||
|
// 切换至前一个终端
|
||||||
|
CHANGE_TO_PREV_TERMINAL: 'changeToPrevTerminal',
|
||||||
|
// 切换至后一个终端
|
||||||
|
CHANGE_TO_NEXT_TERMINAL: 'changeToNextTerminal',
|
||||||
};
|
};
|
||||||
|
|
||||||
// 终端操作快捷键
|
// 终端操作快捷键
|
||||||
@@ -152,23 +163,39 @@ export const TerminalShortcutItems: Array<ShortcutKeyItem> = [
|
|||||||
{
|
{
|
||||||
item: TerminalShortcutKeys.CHANGE_TO_PREV_TAB,
|
item: TerminalShortcutKeys.CHANGE_TO_PREV_TAB,
|
||||||
content: '切换为前一个 tab',
|
content: '切换为前一个 tab',
|
||||||
type: TerminalShortcutType.TAB
|
type: TerminalShortcutType.GLOBAL
|
||||||
}, {
|
}, {
|
||||||
item: TerminalShortcutKeys.CHANGE_TO_NEXT_TAB,
|
item: TerminalShortcutKeys.CHANGE_TO_NEXT_TAB,
|
||||||
content: '切换为后一个 tab',
|
content: '切换为后一个 tab',
|
||||||
type: TerminalShortcutType.TAB
|
type: TerminalShortcutType.GLOBAL
|
||||||
}, {
|
}, {
|
||||||
item: TerminalShortcutKeys.CLOSE_TAB,
|
item: TerminalShortcutKeys.CLOSE_TAB,
|
||||||
content: '关闭当前 tab',
|
content: '关闭当前 tab',
|
||||||
type: TerminalShortcutType.TAB
|
type: TerminalShortcutType.GLOBAL
|
||||||
}, {
|
}, {
|
||||||
item: TerminalShortcutKeys.OPEN_NEW_CONNECT_TAB,
|
item: TerminalShortcutKeys.OPEN_NEW_CONNECT_TAB,
|
||||||
content: '打开新建连接 tab',
|
content: '打开新建连接 tab',
|
||||||
type: TerminalShortcutType.TAB
|
type: TerminalShortcutType.GLOBAL
|
||||||
}, {
|
}, {
|
||||||
item: 'openCopyTerminalTab',
|
item: TerminalShortcutKeys.OPEN_NEW_CONNECT_MODAL,
|
||||||
content: '复制当前终端 tab',
|
content: '打开新建连接弹框',
|
||||||
type: TerminalShortcutType.TERMINAL
|
type: TerminalShortcutType.PANEL
|
||||||
|
}, {
|
||||||
|
item: TerminalShortcutKeys.COPY_TERMINAL,
|
||||||
|
content: '复制终端',
|
||||||
|
type: TerminalShortcutType.PANEL
|
||||||
|
}, {
|
||||||
|
item: TerminalShortcutKeys.CLOSE_TERMINAL,
|
||||||
|
content: '关闭终端',
|
||||||
|
type: TerminalShortcutType.PANEL
|
||||||
|
}, {
|
||||||
|
item: TerminalShortcutKeys.CHANGE_TO_PREV_TERMINAL,
|
||||||
|
content: '切换至前一个终端',
|
||||||
|
type: TerminalShortcutType.PANEL
|
||||||
|
}, {
|
||||||
|
item: TerminalShortcutKeys.CHANGE_TO_NEXT_TERMINAL,
|
||||||
|
content: '切换至后一个终端',
|
||||||
|
type: TerminalShortcutType.PANEL
|
||||||
}, {
|
}, {
|
||||||
item: 'copy',
|
item: 'copy',
|
||||||
content: '复制',
|
content: '复制',
|
||||||
|
|||||||
Reference in New Issue
Block a user