feat: 添加终端右键菜单逻辑.
This commit is contained in:
@@ -8,6 +8,8 @@ import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 终端偏好模型
|
||||
*
|
||||
@@ -33,6 +35,9 @@ public class TerminalPreferenceModel implements PreferenceModel {
|
||||
@Schema(description = "操作栏设置")
|
||||
private JSONObject actionBarSetting;
|
||||
|
||||
@Schema(description = "右键菜单设置")
|
||||
private List<String> rightMenuSetting;
|
||||
|
||||
@Schema(description = "交互设置")
|
||||
private JSONObject interactSetting;
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package com.orion.ops.module.infra.handler.preference.strategy;
|
||||
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.orion.lang.utils.collect.Lists;
|
||||
import com.orion.net.host.ssh.TerminalType;
|
||||
import com.orion.ops.module.infra.handler.preference.model.TerminalPreferenceModel;
|
||||
import org.springframework.stereotype.Component;
|
||||
@@ -63,6 +64,7 @@ public class TerminalPreferenceStrategy implements IPreferenceStrategy<TerminalP
|
||||
.theme(new JSONObject())
|
||||
.displaySetting(JSONObject.parseObject(defaultDisplaySetting))
|
||||
.actionBarSetting(new JSONObject())
|
||||
.rightMenuSetting(Lists.of("copy", "paste", "checkAll", "search", "clear"))
|
||||
.interactSetting(JSONObject.parseObject(defaultInteractSetting))
|
||||
.pluginsSetting(JSONObject.parseObject(defaultPluginsSetting))
|
||||
.sessionSetting(JSONObject.parseObject(defaultSessionSetting))
|
||||
|
||||
@@ -10,7 +10,7 @@ import type {
|
||||
import type { AuthorizedHostQueryResponse } from '@/api/asset/asset-authorized-data';
|
||||
import { getCurrentAuthorizedHost } from '@/api/asset/asset-authorized-data';
|
||||
import type { HostQueryResponse } from '@/api/asset/host';
|
||||
import type { TerminalTheme } from '@/api/asset/host-terminal';
|
||||
import type { TerminalTheme, TerminalThemeSchema } from '@/api/asset/host-terminal';
|
||||
import { getTerminalThemes } from '@/api/asset/host-terminal';
|
||||
import { defineStore } from 'pinia';
|
||||
import { getPreference, updatePreference } from '@/api/user/preference';
|
||||
@@ -26,10 +26,14 @@ export const TerminalPreferenceItem = {
|
||||
NEW_CONNECTION_TYPE: 'newConnectionType',
|
||||
// 终端主题
|
||||
THEME: 'theme',
|
||||
// 快捷键设置
|
||||
SHORTCUT_SETTING: 'shortcutSetting',
|
||||
// 显示设置
|
||||
DISPLAY_SETTING: 'displaySetting',
|
||||
// 操作栏设置
|
||||
ACTION_BAR_SETTING: 'actionBarSetting',
|
||||
// 右键菜单设置
|
||||
RIGHT_MENU_SETTING: 'rightMenuSetting',
|
||||
// 交互设置
|
||||
INTERACT_SETTING: 'interactSetting',
|
||||
// 插件设置
|
||||
@@ -42,9 +46,12 @@ export default defineStore('terminal', {
|
||||
state: (): TerminalState => ({
|
||||
preference: {
|
||||
newConnectionType: 'group',
|
||||
theme: {} as TerminalTheme,
|
||||
theme: {
|
||||
schema: {} as TerminalThemeSchema
|
||||
} as TerminalTheme,
|
||||
displaySetting: {} as TerminalDisplaySetting,
|
||||
actionBarSetting: {} as TerminalActionBarSetting,
|
||||
rightMenuSetting: [],
|
||||
interactSetting: {} as TerminalInteractSetting,
|
||||
pluginsSetting: {} as TerminalPluginsSetting,
|
||||
sessionSetting: {} as TerminalSessionSetting,
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import type { ITerminalSessionManager, ITerminalTabManager } from '@/views/host/terminal/types/terminal.type';
|
||||
import type { TerminalTheme } from '@/api/asset/host-terminal';
|
||||
import type { AuthorizedHostQueryResponse } from '@/api/asset/asset-authorized-data';
|
||||
import type { TerminalTheme } from '@/api/asset/host-terminal';
|
||||
|
||||
export interface TerminalState {
|
||||
preference: TerminalPreference;
|
||||
@@ -15,6 +15,7 @@ export interface TerminalPreference {
|
||||
theme: TerminalTheme;
|
||||
displaySetting: TerminalDisplaySetting;
|
||||
actionBarSetting: TerminalActionBarSetting;
|
||||
rightMenuSetting: Array<string>,
|
||||
interactSetting: TerminalInteractSetting;
|
||||
pluginsSetting: TerminalPluginsSetting;
|
||||
sessionSetting: TerminalSessionSetting;
|
||||
|
||||
@@ -131,11 +131,13 @@ body .host-layout, .arco-modal-container {
|
||||
}
|
||||
|
||||
// arco 暗色配色
|
||||
body[terminal-theme='dark'],
|
||||
body[terminal-theme='dark'] .host-layout,
|
||||
body[terminal-theme='dark'] .arco-modal-container {
|
||||
--color-white: rgba(255, 255, 255, 0.9);
|
||||
--color-black: #000000;
|
||||
--color-border: #333335;
|
||||
--color-bg-popup: var(--color-bg-5);
|
||||
--color-bg-1: #17171a;
|
||||
--color-bg-2: #232324;
|
||||
--color-bg-3: #2a2a2b;
|
||||
@@ -260,7 +262,6 @@ body[terminal-theme='dark'] .arco-modal-container {
|
||||
display: flex;
|
||||
|
||||
&.block-body {
|
||||
display: flex;
|
||||
width: 100%;
|
||||
padding: 16px;
|
||||
border: 1px solid var(--color-fill-4);
|
||||
@@ -280,3 +281,17 @@ body[terminal-theme='dark'] .arco-modal-container {
|
||||
.terminal-tooltip-arrow {
|
||||
display: none;
|
||||
}
|
||||
|
||||
// 终端右键菜单
|
||||
.terminal-context-menu {
|
||||
.arco-dropdown-option {
|
||||
padding: 0 6px;
|
||||
line-height: 32px;
|
||||
|
||||
&-content {
|
||||
width: 120px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -126,6 +126,7 @@
|
||||
color: var(--color-content-text-1);
|
||||
cursor: pointer;
|
||||
transition: transform 0.3s ease;
|
||||
will-change: transform;
|
||||
|
||||
&:hover {
|
||||
transform: scale(1.04);
|
||||
|
||||
@@ -11,10 +11,10 @@
|
||||
<div class="terminal-sidebar-icon"
|
||||
:class="[
|
||||
iconClass,
|
||||
action.disabled !== false ? '' : 'disabled-item',
|
||||
action.disabled === true ? 'disabled-item' : '',
|
||||
action.checked === true ? 'checked-item' : '',
|
||||
]"
|
||||
@click="action.disabled !== false ? action.click() : false">
|
||||
@click="action.disabled === true ? false : action.click()">
|
||||
<component :is="action.icon" :style="action?.iconStyle" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -7,6 +7,8 @@
|
||||
<terminal-display-block />
|
||||
<!-- 顶部工具栏 -->
|
||||
<terminal-action-bar-block />
|
||||
<!-- 右键菜单 -->
|
||||
<terminal-right-menu-block />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
@@ -20,6 +22,7 @@
|
||||
<script lang="ts" setup>
|
||||
import TerminalDisplayBlock from './terminal-display-block.vue';
|
||||
import TerminalActionBarBlock from './terminal-action-bar-block.vue';
|
||||
import TerminalRightMenuBlock from './terminal-right-menu-block.vue';
|
||||
|
||||
</script>
|
||||
|
||||
|
||||
@@ -0,0 +1,227 @@
|
||||
<template>
|
||||
<div class="terminal-setting-block">
|
||||
<!-- 顶部 -->
|
||||
<div class="terminal-setting-subtitle-wrapper">
|
||||
<h3 class="terminal-setting-subtitle">
|
||||
右键菜单设置
|
||||
</h3>
|
||||
</div>
|
||||
<!-- 提示 -->
|
||||
<a-alert class="mb16">修改后会立刻保存, 重新打开终端后生效 (无需刷新页面)</a-alert>
|
||||
<!-- 内容区域 -->
|
||||
<div class="terminal-setting-body block-body setting-body">
|
||||
<!-- 功能项 -->
|
||||
<div class="actions-container">
|
||||
<div class="setting-label">功能</div>
|
||||
<!-- 功能项列表 -->
|
||||
<div class="actions-wrapper">
|
||||
<a-row :gutter="[8, 8]">
|
||||
<a-col :span="12"
|
||||
v-for="(action, index) in ActionBarItems"
|
||||
:key="index">
|
||||
<div class="action-item" @click="clickAction(action.item)">
|
||||
<!-- 图标 -->
|
||||
<div class="action-icon">
|
||||
<component :is="action.icon" />
|
||||
</div>
|
||||
<!-- 描述 -->
|
||||
<div class="action-desc">
|
||||
{{ action.content }}
|
||||
</div>
|
||||
</div>
|
||||
</a-col>
|
||||
</a-row>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 菜单预览容器 -->
|
||||
<div class="preview-container">
|
||||
<div class="setting-label">菜单预览</div>
|
||||
<div ref="popupContainer" />
|
||||
</div>
|
||||
<!-- 预览下拉菜单 -->
|
||||
<a-dropdown v-if="popupContainer"
|
||||
:popup-visible="true"
|
||||
:popup-container="popupContainer"
|
||||
:popup-max-height="false">
|
||||
<template #content v-if="rightActions.length">
|
||||
<a-doption v-for="(action, index) in rightActions"
|
||||
:key="index">
|
||||
<div class="preview-action">
|
||||
<!-- 图标 -->
|
||||
<div class="preview-icon">
|
||||
<component :is="action.icon" />
|
||||
</div>
|
||||
<!-- 文本 -->
|
||||
<div>{{ action.content }}</div>
|
||||
</div>
|
||||
<!-- 关闭按钮 -->
|
||||
<div class="close-icon" @click="clickAction(action.item)">
|
||||
<icon-close />
|
||||
</div>
|
||||
</a-doption>
|
||||
</template>
|
||||
<!-- 空数据 -->
|
||||
<template #content v-else>
|
||||
<a-doption>
|
||||
点击左侧功能添加
|
||||
</a-doption>
|
||||
</template>
|
||||
</a-dropdown>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
export default {
|
||||
name: 'terminalRightMenuBlock'
|
||||
};
|
||||
</script>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import type { ContextMenuItem } from '../../types/terminal.type';
|
||||
import { computed, ref, watch } from 'vue';
|
||||
import { useTerminalStore } from '@/store';
|
||||
import { TerminalPreferenceItem } from '@/store/modules/terminal';
|
||||
import { ActionBarItems } from '../../types/terminal.const';
|
||||
|
||||
const { preference, updateTerminalPreference } = useTerminalStore();
|
||||
|
||||
const popupContainer = ref();
|
||||
const rightActionItems = ref<Array<string>>([...preference.rightMenuSetting]);
|
||||
|
||||
// // 监听同步
|
||||
watch(rightActionItems, (v) => {
|
||||
// 同步
|
||||
updateTerminalPreference(TerminalPreferenceItem.RIGHT_MENU_SETTING, v, true);
|
||||
}, { deep: true });
|
||||
|
||||
// 实际操作项
|
||||
const rightActions = computed<Array<ContextMenuItem>>(() => {
|
||||
return rightActionItems.value
|
||||
.map(s => ActionBarItems.find(i => i.item === s) as ContextMenuItem)
|
||||
.filter(Boolean);
|
||||
});
|
||||
|
||||
// 添加操作项
|
||||
const clickAction = (item: string) => {
|
||||
if (rightActionItems.value.includes(item)) {
|
||||
// 移除
|
||||
rightActionItems.value.splice(rightActionItems.value.indexOf(item), 1);
|
||||
} else {
|
||||
// 添加
|
||||
rightActionItems.value.push(item);
|
||||
}
|
||||
};
|
||||
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
|
||||
.setting-body {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.setting-label {
|
||||
display: flex;
|
||||
max-width: 100%;
|
||||
color: var(--color-text-2);
|
||||
font-size: 14px;
|
||||
margin-bottom: 8px;
|
||||
padding: 0;
|
||||
line-height: 1.5715;
|
||||
white-space: normal;
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
.actions-container {
|
||||
width: 418px;
|
||||
height: auto;
|
||||
|
||||
.actions-wrapper {
|
||||
padding-right: 8px;
|
||||
margin-right: 32px;
|
||||
}
|
||||
|
||||
.action-item {
|
||||
display: flex;
|
||||
padding: 6px;
|
||||
align-items: center;
|
||||
cursor: pointer;
|
||||
border-radius: 4px;
|
||||
background-color: var(--color-fill-2);
|
||||
transition: transform 0.3s ease;
|
||||
will-change: transform;
|
||||
|
||||
&:hover {
|
||||
transform: scale(1.04);
|
||||
}
|
||||
}
|
||||
|
||||
.action-icon {
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: 16px;
|
||||
border-radius: 4px;
|
||||
margin-right: 8px;
|
||||
background-color: var(--color-fill-3);
|
||||
}
|
||||
|
||||
.action-desc {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
font-size: 14px;
|
||||
user-select: none;
|
||||
}
|
||||
}
|
||||
|
||||
.preview-container {
|
||||
width: 242px;
|
||||
height: auto;
|
||||
|
||||
:deep(.arco-dropdown-option-content) {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
|
||||
&:hover {
|
||||
.close-icon {
|
||||
display: flex;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.preview-action {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.preview-icon {
|
||||
font-size: 18px;
|
||||
margin-right: 6px;
|
||||
}
|
||||
|
||||
.close-icon {
|
||||
display: none;
|
||||
padding: 3px;
|
||||
border-radius: 12px;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
transition: .2s;
|
||||
font-size: 15px;
|
||||
|
||||
&:hover {
|
||||
background-color: var(--color-fill-3);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
:deep(.arco-trigger-popup) {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
</style>
|
||||
@@ -1,15 +1,25 @@
|
||||
<template>
|
||||
<!-- 终端右键菜单 -->
|
||||
<a-dropdown trigger="contextMenu"
|
||||
<a-dropdown class="terminal-context-menu"
|
||||
trigger="contextMenu"
|
||||
:popup-max-height="false"
|
||||
position="bl"
|
||||
alignPoint>
|
||||
<!-- 终端插槽 -->
|
||||
<slot />
|
||||
<!-- 右键菜单 -->
|
||||
<template v-if="preference.interactSetting.enableRightClickMenu" #content>
|
||||
<a-doption>Option 1</a-doption>
|
||||
<a-doption>Option 2</a-doption>
|
||||
<a-doption>Option 3</a-doption>
|
||||
<a-doption v-for="(action, index) in actions"
|
||||
:key="index"
|
||||
:disabled="enabledStatus[action.item] === false"
|
||||
@click="emits('click', action.item)">
|
||||
<!-- 图标 -->
|
||||
<div class="action-icon">
|
||||
<component :is="action.icon" />
|
||||
</div>
|
||||
<!-- 文本 -->
|
||||
<div>{{ action.content }}</div>
|
||||
</a-doption>
|
||||
</template>
|
||||
</a-dropdown>
|
||||
</template>
|
||||
@@ -21,14 +31,31 @@
|
||||
</script>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import type { ContextMenuItem } from '../../types/terminal.type';
|
||||
import { ActionBarItems } from '../../types/terminal.const';
|
||||
import { useTerminalStore } from '@/store';
|
||||
|
||||
defineProps<{
|
||||
enabledStatus: Record<string, boolean | undefined>
|
||||
}>();
|
||||
|
||||
const emits = defineEmits(['click']);
|
||||
|
||||
const { preference } = useTerminalStore();
|
||||
|
||||
// TODO 颜色 配置 触发事件
|
||||
const actions: Array<ContextMenuItem> = !preference.interactSetting.enableRightClickMenu
|
||||
? []
|
||||
: preference.rightMenuSetting
|
||||
.map(s => ActionBarItems.find(i => i.item === s) as ContextMenuItem)
|
||||
.filter(Boolean);
|
||||
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
|
||||
.action-icon {
|
||||
font-size: 16px;
|
||||
margin: 0 8px 0 4px;
|
||||
}
|
||||
|
||||
</style>
|
||||
|
||||
@@ -37,7 +37,8 @@
|
||||
</div>
|
||||
</div>
|
||||
<!-- 终端右键菜单 -->
|
||||
<terminal-context-menu>
|
||||
<terminal-context-menu :enabled-status="actionsEnabledStatus"
|
||||
@click="action => actionsClickHandler[action] && actionsClickHandler[action]()">
|
||||
<!-- 终端容器 -->
|
||||
<div class="terminal-wrapper"
|
||||
:style="{ background: preference.theme.schema.background }">
|
||||
@@ -92,9 +93,7 @@
|
||||
const session = ref<ITerminalSession>();
|
||||
|
||||
// TODO
|
||||
// 右键菜单补充 enableRightClickMenu 粘贴逻辑
|
||||
// 设置快捷键 粘贴逻辑
|
||||
// 读取快捷键并且禁用快捷键
|
||||
// 设置快捷键 粘贴逻辑 禁用
|
||||
// 截屏
|
||||
// sftp
|
||||
|
||||
@@ -124,14 +123,14 @@
|
||||
session.value?.find(word, next, options);
|
||||
};
|
||||
|
||||
// 操作禁用状态
|
||||
const actionsDisableStatus = computed<Record<string, boolean | undefined>>(() => {
|
||||
// 操作启用状态
|
||||
const actionsEnabledStatus = computed<Record<string, boolean | undefined>>(() => {
|
||||
return {
|
||||
paste: session.value?.canWrite,
|
||||
interrupt: session.value?.canWrite,
|
||||
enter: session.value?.canWrite,
|
||||
commandEditor: session.value?.canWrite,
|
||||
disconnect: session.value?.connected,
|
||||
paste: !!session.value?.canWrite,
|
||||
interrupt: !!session.value?.canWrite,
|
||||
enter: !!session.value?.canWrite,
|
||||
commandEditor: !!session.value?.canWrite,
|
||||
disconnect: !!session.value?.connected,
|
||||
};
|
||||
});
|
||||
|
||||
@@ -143,18 +142,16 @@
|
||||
toBottom: () => session.value?.toBottom(),
|
||||
// 全选
|
||||
checkAll: () => session.value?.selectAll(),
|
||||
// 复制选中部分
|
||||
copy: () => session.value?.copySelection(),
|
||||
// 搜索
|
||||
search: () => searchModal.value.toggle(),
|
||||
// 复制选中部分
|
||||
copy: () => session.value?.copySelection(),
|
||||
// 粘贴
|
||||
paste: async () => session.value?.pasteTrimEnd(await readText()),
|
||||
// ctrl + c
|
||||
interrupt: () => session.value?.paste(String.fromCharCode(3)),
|
||||
// 回车
|
||||
enter: () => session.value?.paste(String.fromCharCode(13)),
|
||||
// 命令编辑器
|
||||
commandEditor: () => editorModal.value.open('', ''),
|
||||
// 增大字号
|
||||
fontSizePlus: () => {
|
||||
if (session.value) {
|
||||
@@ -175,6 +172,8 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
// 命令编辑器
|
||||
commandEditor: () => editorModal.value.open('', ''),
|
||||
// 清空
|
||||
clear: () => session.value?.clear(),
|
||||
// 断开连接
|
||||
@@ -190,7 +189,7 @@
|
||||
icon: s.icon,
|
||||
content: s.content,
|
||||
visible: preference.actionBarSetting[s.item] !== false,
|
||||
disabled: actionsDisableStatus.value[s.item] !== false,
|
||||
disabled: actionsEnabledStatus.value[s.item] === false,
|
||||
click: () => {
|
||||
actionsClickHandler[s.item] && actionsClickHandler[s.item]();
|
||||
}
|
||||
|
||||
@@ -9,6 +9,9 @@ export default class TerminalTabManager implements ITerminalTabManager {
|
||||
public items: Array<TerminalTabItem>;
|
||||
|
||||
constructor() {
|
||||
// fixme
|
||||
// this.active = InnerTabs.SHORTCUT_SETTING.key;
|
||||
// this.items = [InnerTabs.SHORTCUT_SETTING];
|
||||
this.active = InnerTabs.NEW_CONNECTION.key;
|
||||
this.items = [InnerTabs.NEW_CONNECTION];
|
||||
}
|
||||
|
||||
@@ -35,6 +35,7 @@
|
||||
import { ref, onBeforeMount, onUnmounted, onMounted } from 'vue';
|
||||
import { dictKeys, InnerTabs } from './types/terminal.const';
|
||||
import { useCacheStore, useDictStore, useTerminalStore } from '@/store';
|
||||
import useLoading from '@/hooks/loading';
|
||||
import TerminalHeader from './components/layout/terminal-header.vue';
|
||||
import TerminalLeftSidebar from './components/layout/terminal-left-sidebar.vue';
|
||||
import TerminalRightSidebar from './components/layout/terminal-right-sidebar.vue';
|
||||
@@ -42,7 +43,6 @@
|
||||
import LoadingSkeleton from './components/layout/loading-skeleton.vue';
|
||||
import './assets/styles/layout.less';
|
||||
import 'xterm/css/xterm.css';
|
||||
import useLoading from '@/hooks/loading';
|
||||
|
||||
const terminalStore = useTerminalStore();
|
||||
const dictStore = useDictStore();
|
||||
|
||||
@@ -80,18 +80,18 @@ export const ActionBarItems = [
|
||||
item: 'checkAll',
|
||||
icon: 'icon-expand',
|
||||
content: '全选',
|
||||
}, {
|
||||
item: 'search',
|
||||
icon: 'icon-find-replace',
|
||||
content: '搜索',
|
||||
}, {
|
||||
item: 'copy',
|
||||
icon: 'icon-copy',
|
||||
content: '复制选中部分',
|
||||
content: '复制',
|
||||
}, {
|
||||
item: 'paste',
|
||||
icon: 'icon-paste',
|
||||
content: '粘贴',
|
||||
}, {
|
||||
item: 'search',
|
||||
icon: 'icon-find-replace',
|
||||
content: '搜索',
|
||||
}, {
|
||||
item: 'interrupt',
|
||||
icon: 'icon-formula',
|
||||
@@ -100,10 +100,6 @@ export const ActionBarItems = [
|
||||
item: 'enter',
|
||||
icon: 'icon-play-arrow-fill',
|
||||
content: '回车',
|
||||
}, {
|
||||
item: 'commandEditor',
|
||||
icon: 'icon-code-square',
|
||||
content: '命令编辑器',
|
||||
}, {
|
||||
item: 'fontSizePlus',
|
||||
icon: 'icon-zoom-in',
|
||||
@@ -112,6 +108,10 @@ export const ActionBarItems = [
|
||||
item: 'fontSizeSubtract',
|
||||
icon: 'icon-zoom-out',
|
||||
content: '减小字号',
|
||||
}, {
|
||||
item: 'commandEditor',
|
||||
icon: 'icon-code-square',
|
||||
content: '命令编辑器',
|
||||
}, {
|
||||
item: 'clear',
|
||||
icon: 'icon-delete',
|
||||
@@ -123,7 +123,7 @@ export const ActionBarItems = [
|
||||
}, {
|
||||
item: 'close',
|
||||
icon: 'icon-close',
|
||||
content: '关闭',
|
||||
content: '关闭终端',
|
||||
}
|
||||
];
|
||||
|
||||
|
||||
@@ -38,6 +38,13 @@ export interface CombinedHandlerItem {
|
||||
host?: HostQueryResponse;
|
||||
}
|
||||
|
||||
// 右键菜单元素
|
||||
export interface ContextMenuItem {
|
||||
item: string;
|
||||
icon: string;
|
||||
content: string;
|
||||
}
|
||||
|
||||
// ssh 额外配置
|
||||
export interface SshExtraModel {
|
||||
authType?: string;
|
||||
|
||||
Reference in New Issue
Block a user