feat: 添加未选择页面的空承载页.
This commit is contained in:
@@ -9,16 +9,19 @@ import type {
|
||||
} from './types';
|
||||
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 { getTerminalThemes } from '@/api/asset/host-terminal';
|
||||
import { defineStore } from 'pinia';
|
||||
import { getPreference, updatePreference } from '@/api/user/preference';
|
||||
import { nextSessionId } from '@/utils';
|
||||
import { Message } from '@arco-design/web-vue';
|
||||
import { TerminalTabType } from '@/views/host/terminal/types/terminal.const';
|
||||
import TerminalTabManager from '@/views/host/terminal/handler/terminal-tab-manager';
|
||||
import TerminalSessionManager from '@/views/host/terminal/handler/terminal-session-manager';
|
||||
|
||||
// 偏好项
|
||||
export const PreferenceItem = {
|
||||
// 终端偏好项
|
||||
export const TerminalPreferenceItem = {
|
||||
// 新建连接类型
|
||||
NEW_CONNECTION_TYPE: 'newConnectionType',
|
||||
// 终端主题
|
||||
@@ -62,7 +65,7 @@ export default defineStore('terminal', {
|
||||
const { data: themes } = await getTerminalThemes();
|
||||
data.theme = themes[0];
|
||||
// 更新默认主题偏好
|
||||
await this.updateTerminalPreference(PreferenceItem.THEME, data.theme);
|
||||
await this.updateTerminalPreference(TerminalPreferenceItem.THEME, data.theme);
|
||||
}
|
||||
// 选择赋值
|
||||
const keys = Object.keys(this.preference);
|
||||
@@ -105,10 +108,28 @@ export default defineStore('terminal', {
|
||||
});
|
||||
},
|
||||
|
||||
// 添加到最近连接列表
|
||||
addToLatestConnect(hostId: number) {
|
||||
this.hosts.latestHosts = [...new Set([hostId, ...this.hosts.latestHosts])];
|
||||
}
|
||||
// 打开终端
|
||||
openTerminal(record: HostQueryResponse) {
|
||||
// 添加到最近连接
|
||||
this.hosts.latestHosts = [...new Set([record.id, ...this.hosts.latestHosts])];
|
||||
// 获取 seq
|
||||
const tabSeqArr = this.tabManager.items
|
||||
.map(s => s.seq)
|
||||
.filter(Boolean)
|
||||
.map(Number);
|
||||
const nextSeq = tabSeqArr.length
|
||||
? Math.max(...tabSeqArr) + 1
|
||||
: 1;
|
||||
// 打开 tab
|
||||
this.tabManager.openTab({
|
||||
type: TerminalTabType.TERMINAL,
|
||||
key: nextSessionId(10),
|
||||
seq: nextSeq,
|
||||
title: `(${nextSeq}) ${record.alias || record.name}`,
|
||||
hostId: record.id,
|
||||
address: record.address
|
||||
});
|
||||
},
|
||||
|
||||
},
|
||||
|
||||
|
||||
@@ -163,7 +163,7 @@ export const resetObject = (obj: any, ignore: string[] = []) => {
|
||||
export const objectTruthKeyCount = (obj: any, ignore: string[] = []) => {
|
||||
return Object.keys(obj)
|
||||
.filter(s => !ignore.includes(s))
|
||||
.reduce(function(acc, curr) {
|
||||
.reduce(function (acc, curr) {
|
||||
const currVal = obj[curr];
|
||||
return acc + ~~(currVal !== undefined && currVal !== null && currVal?.length !== 0 && currVal !== '');
|
||||
}, 0);
|
||||
@@ -196,13 +196,20 @@ export function detectZoom() {
|
||||
* 获取唯一的 UUID
|
||||
*/
|
||||
export function getUUID() {
|
||||
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
|
||||
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
|
||||
const r = Math.random() * 16 | 0;
|
||||
const v = c === 'x' ? r : (r & 0x3 | 0x8);
|
||||
return v.toString(16);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取会话id
|
||||
*/
|
||||
export const nextSessionId = (len: number): string => {
|
||||
return getUUID().replaceAll('-', '').substring(0, len);
|
||||
};
|
||||
|
||||
/**
|
||||
* 清除 xss
|
||||
*/
|
||||
|
||||
@@ -4,25 +4,16 @@
|
||||
<!-- 组合容器 -->
|
||||
<div class="combined-container">
|
||||
<!-- 新建连接 -->
|
||||
<div class="combined-handler">
|
||||
<div class="combined-handler" v-for="(handler, index) in combinedHandlers"
|
||||
:key="index"
|
||||
@click="clickHandlerItem(handler)">
|
||||
<!-- 图标 -->
|
||||
<div class="combined-handler-icon">
|
||||
<icon-plus />
|
||||
<component :is="handler.icon" />
|
||||
</div>
|
||||
<!-- 内容 -->
|
||||
<div class="combined-handler-text">
|
||||
新建连接
|
||||
</div>
|
||||
</div>
|
||||
<!-- 主机列表 -->
|
||||
<div class="combined-handler">
|
||||
<!-- 图标 -->
|
||||
<div class="combined-handler-icon">
|
||||
<icon-desktop />
|
||||
</div>
|
||||
<!-- 内容 -->
|
||||
<div class="combined-handler-text">
|
||||
历史1
|
||||
{{ handler.title }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -37,20 +28,83 @@
|
||||
</script>
|
||||
|
||||
<script lang="ts" setup>
|
||||
|
||||
import type { TerminalTabItem, CombinedHandlerItem } from '../../types/terminal.type';
|
||||
import type { HostQueryResponse } from '@/api/asset/host';
|
||||
import { onMounted, ref } from 'vue';
|
||||
import { useTerminalStore } from '@/store';
|
||||
import { InnerTabs, TerminalTabType } from '../../types/terminal.const';
|
||||
import { get } from 'lodash';
|
||||
|
||||
const { tabManager, hosts } = useTerminalStore();
|
||||
const totalCount = 8;
|
||||
const { tabManager, hosts, openTerminal } = useTerminalStore();
|
||||
|
||||
const combinedHandlers = ref<Array<CombinedHandlerItem>>([{
|
||||
title: InnerTabs.NEW_CONNECTION.title,
|
||||
settingTab: InnerTabs.NEW_CONNECTION,
|
||||
type: TerminalTabType.SETTING,
|
||||
icon: InnerTabs.NEW_CONNECTION.icon
|
||||
}]);
|
||||
|
||||
// 点击组合操作元素
|
||||
const clickHandlerItem = (item: CombinedHandlerItem) => {
|
||||
if (item.type === TerminalTabType.SETTING) {
|
||||
// 打开内置 tab
|
||||
tabManager.openTab(item.settingTab as TerminalTabItem);
|
||||
} else {
|
||||
// 打开终端
|
||||
openTerminal(item.host as HostQueryResponse);
|
||||
}
|
||||
};
|
||||
|
||||
// 组合主机列表
|
||||
onMounted(() => {
|
||||
// 推荐的主机 tab
|
||||
const combinedHosts = [
|
||||
...new Set([
|
||||
...hosts.latestHosts,
|
||||
...hosts.hostList.filter(s => s.favorite).map(s => s.id),
|
||||
...hosts.hostList.map(s => s.id)
|
||||
])
|
||||
].slice(0, totalCount - 1)
|
||||
.map(s => hosts.hostList.find(t => t.id === s) as HostQueryResponse)
|
||||
.filter(Boolean)
|
||||
.map(s => {
|
||||
return {
|
||||
title: `${s.alias || s.name} (${s.address})`,
|
||||
type: TerminalTabType.TERMINAL,
|
||||
host: s,
|
||||
icon: 'icon-desktop'
|
||||
};
|
||||
});
|
||||
// 插入主机列表
|
||||
combinedHandlers.value.push(...combinedHosts);
|
||||
// 不足显示的行数用设置补充
|
||||
if (totalCount - 1 - combinedHosts.length > 0) {
|
||||
const fillTabs = Object.keys(InnerTabs)
|
||||
.filter(s => s !== 'NEW_CONNECTION')
|
||||
.map(s => get(InnerTabs, s) as TerminalTabItem)
|
||||
.slice(0, totalCount - 1 - combinedHosts.length)
|
||||
.map(s => {
|
||||
return {
|
||||
title: s.title,
|
||||
settingTab: s,
|
||||
type: TerminalTabType.SETTING,
|
||||
icon: s.icon as string
|
||||
};
|
||||
});
|
||||
combinedHandlers.value.push(...fillTabs);
|
||||
}
|
||||
});
|
||||
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
@handler-height: 48px;
|
||||
@handler-height: 44px;
|
||||
|
||||
.combined-container {
|
||||
padding: 8px;
|
||||
padding: 12px;
|
||||
margin: 64px auto;
|
||||
width: 448px;
|
||||
width: 424px;
|
||||
height: 448px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
@@ -70,6 +124,12 @@
|
||||
display: flex;
|
||||
align-items: center;
|
||||
color: var(--color-content-text-1);
|
||||
cursor: pointer;
|
||||
transition: transform 0.3s ease;
|
||||
|
||||
&:hover {
|
||||
transform: scale(1.04);
|
||||
}
|
||||
|
||||
&-icon {
|
||||
width: @handler-height;
|
||||
@@ -77,14 +137,22 @@
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: 18px;
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
&-text {
|
||||
height: 100%;
|
||||
width: calc(100% - @handler-height - 12px);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
font-size: 14px;
|
||||
|
||||
&-wrapper {
|
||||
display: block;
|
||||
overflow: hidden;
|
||||
white-space: pre;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
:key="tab.key"
|
||||
:title="tab.title">
|
||||
<!-- 设置 -->
|
||||
<template v-if="tab.type === TabType.SETTING">
|
||||
<template v-if="tab.type === TerminalTabType.SETTING">
|
||||
<!-- 新建连接 -->
|
||||
<new-connection-view v-if="tab.key === InnerTabs.NEW_CONNECTION.key" />
|
||||
<!-- 显示设置 -->
|
||||
@@ -18,7 +18,7 @@
|
||||
<terminal-general-setting v-else-if="tab.key === InnerTabs.TERMINAL_SETTING.key" />
|
||||
</template>
|
||||
<!-- 终端 -->
|
||||
<template v-else-if="tab.type === TabType.TERMINAL">
|
||||
<template v-else-if="tab.type === TerminalTabType.TERMINAL">
|
||||
<terminal-view :tab="tab" />
|
||||
</template>
|
||||
</a-tab-pane>
|
||||
@@ -35,7 +35,7 @@
|
||||
</script>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { TabType, InnerTabs } from '../../types/terminal.const';
|
||||
import { TerminalTabType, InnerTabs } from '../../types/terminal.const';
|
||||
import { useTerminalStore } from '@/store';
|
||||
import { watch } from 'vue';
|
||||
import EmptyRecommend from './empty-recommend.vue';
|
||||
@@ -62,7 +62,7 @@
|
||||
// 修改标题
|
||||
document.title = tab.title;
|
||||
// terminal 自动聚焦
|
||||
if (tab?.type === TabType.TERMINAL) {
|
||||
if (tab?.type === TerminalTabType.TERMINAL) {
|
||||
sessionManager.getSession(active)?.focus();
|
||||
}
|
||||
});
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
// 顶部操作
|
||||
const topActions: Array<SidebarAction> = [
|
||||
{
|
||||
icon: 'icon-plus',
|
||||
icon: InnerTabs.NEW_CONNECTION.icon,
|
||||
content: InnerTabs.NEW_CONNECTION.title,
|
||||
click: () => tabManager.openTab(InnerTabs.NEW_CONNECTION)
|
||||
},
|
||||
@@ -37,22 +37,22 @@
|
||||
// 底部操作
|
||||
const bottomActions: Array<SidebarAction> = [
|
||||
{
|
||||
icon: 'icon-command',
|
||||
icon: InnerTabs.SHORTCUT_SETTING.icon,
|
||||
content: InnerTabs.SHORTCUT_SETTING.title,
|
||||
click: () => tabManager.openTab(InnerTabs.SHORTCUT_SETTING)
|
||||
},
|
||||
{
|
||||
icon: 'icon-desktop',
|
||||
icon: InnerTabs.DISPLAY_SETTING.icon,
|
||||
content: InnerTabs.DISPLAY_SETTING.title,
|
||||
click: () => tabManager.openTab(InnerTabs.DISPLAY_SETTING)
|
||||
},
|
||||
{
|
||||
icon: 'icon-palette',
|
||||
icon: InnerTabs.THEME_SETTING.icon,
|
||||
content: InnerTabs.THEME_SETTING.title,
|
||||
click: () => tabManager.openTab(InnerTabs.THEME_SETTING)
|
||||
},
|
||||
{
|
||||
icon: 'icon-settings',
|
||||
icon: InnerTabs.TERMINAL_SETTING.icon,
|
||||
content: InnerTabs.TERMINAL_SETTING.title,
|
||||
click: () => tabManager.openTab(InnerTabs.TERMINAL_SETTING)
|
||||
},
|
||||
|
||||
@@ -168,7 +168,7 @@
|
||||
import { dataColor } from '@/utils';
|
||||
import { tagColor } from '@/views/asset/host-list/types/const';
|
||||
import { updateHostAlias } from '@/api/asset/host-extra';
|
||||
import { nextSessionId, openSshModalKey, TabType } from '../../types/terminal.const';
|
||||
import { openSshModalKey } from '../../types/terminal.const';
|
||||
import { useTerminalStore } from '@/store';
|
||||
|
||||
const props = defineProps<{
|
||||
@@ -176,7 +176,7 @@
|
||||
emptyValue: string
|
||||
}>();
|
||||
|
||||
const { tabManager, addToLatestConnect } = useTerminalStore();
|
||||
const { openTerminal } = useTerminalStore();
|
||||
const { toggle: toggleFavorite, loading: favoriteLoading } = useFavorite('HOST');
|
||||
|
||||
const aliasNameInput = ref();
|
||||
@@ -213,29 +213,6 @@
|
||||
}
|
||||
};
|
||||
|
||||
// 打开终端
|
||||
const openTerminal = (record: HostQueryResponse) => {
|
||||
// 添加到最近连接
|
||||
addToLatestConnect(record.id);
|
||||
// 获取 seq
|
||||
const tabSeqArr = tabManager.items
|
||||
.map(s => s.seq)
|
||||
.filter(Boolean)
|
||||
.map(Number);
|
||||
const nextSeq = tabSeqArr.length
|
||||
? Math.max(...tabSeqArr) + 1
|
||||
: 1;
|
||||
// 打开 tab
|
||||
tabManager.openTab({
|
||||
type: TabType.TERMINAL,
|
||||
key: nextSessionId(),
|
||||
seq: nextSeq,
|
||||
title: `(${nextSeq}) ${record.alias || record.name}`,
|
||||
hostId: record.id,
|
||||
address: record.address
|
||||
});
|
||||
};
|
||||
|
||||
// 打开配置
|
||||
const openSetting = inject<(record: HostQueryResponse) => void>(openSshModalKey) as any;
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
type="button"
|
||||
class="usn"
|
||||
:options="toRadioOptions(newConnectionTypeKey)"
|
||||
@change="s => updateTerminalPreference(PreferenceItem.NEW_CONNECTION_TYPE, s as string, true)" />
|
||||
@change="s => updateTerminalPreference(TerminalPreferenceItem.NEW_CONNECTION_TYPE, s as string, true)" />
|
||||
<!-- 过滤 -->
|
||||
<a-auto-complete v-model="filterValue"
|
||||
class="host-filter"
|
||||
@@ -70,7 +70,7 @@
|
||||
import { onBeforeMount, ref } from 'vue';
|
||||
import { NewConnectionType, newConnectionTypeKey } from '../../types/terminal.const';
|
||||
import { useDictStore, useTerminalStore } from '@/store';
|
||||
import { PreferenceItem } from '@/store/modules/terminal';
|
||||
import { TerminalPreferenceItem } from '@/store/modules/terminal';
|
||||
import { dataColor } from '@/utils';
|
||||
import { tagColor } from '@/views/asset/host-list/types/const';
|
||||
import HostsView from './hosts-view.vue';
|
||||
|
||||
@@ -50,7 +50,7 @@
|
||||
import type { SidebarAction } from '../../types/terminal.type';
|
||||
import { computed, ref, watch } from 'vue';
|
||||
import { useTerminalStore } from '@/store';
|
||||
import { PreferenceItem } from '@/store/modules/terminal';
|
||||
import { TerminalPreferenceItem } from '@/store/modules/terminal';
|
||||
import { ActionBarItems } from '../../types/terminal.const';
|
||||
import IconActions from '../layout/icon-actions.vue';
|
||||
|
||||
@@ -64,7 +64,7 @@
|
||||
return;
|
||||
}
|
||||
// 同步
|
||||
updateTerminalPreference(PreferenceItem.ACTION_BAR_SETTING, formModel.value, true);
|
||||
updateTerminalPreference(TerminalPreferenceItem.ACTION_BAR_SETTING, formModel.value, true);
|
||||
}, { deep: true });
|
||||
|
||||
// 右侧操作
|
||||
|
||||
@@ -102,7 +102,7 @@
|
||||
import { useDictStore, useTerminalStore } from '@/store';
|
||||
import { fontFamilyKey, fontSizeKey, fontWeightKey, fontFamilySuffix, cursorStyleKey } from '../../types/terminal.const';
|
||||
import { labelFilter } from '@/types/form';
|
||||
import { PreferenceItem } from '@/store/modules/terminal';
|
||||
import { TerminalPreferenceItem } from '@/store/modules/terminal';
|
||||
import TerminalExample from '../view-setting/terminal-example.vue';
|
||||
|
||||
const { toOptions, toRadioOptions } = useDictStore();
|
||||
@@ -129,7 +129,7 @@
|
||||
}
|
||||
});
|
||||
// 同步
|
||||
updateTerminalPreference(PreferenceItem.DISPLAY_SETTING, formModel.value, true);
|
||||
updateTerminalPreference(TerminalPreferenceItem.DISPLAY_SETTING, formModel.value, true);
|
||||
// 聚焦
|
||||
previewTerminal.value.term.focus();
|
||||
}, { deep: true });
|
||||
|
||||
@@ -86,7 +86,7 @@
|
||||
import type { TerminalInteractSetting } from '@/store/modules/terminal/types';
|
||||
import { ref, watch } from 'vue';
|
||||
import { useTerminalStore } from '@/store';
|
||||
import { PreferenceItem } from '@/store/modules/terminal';
|
||||
import { TerminalPreferenceItem } from '@/store/modules/terminal';
|
||||
import BlockSettingItem from './block-setting-item.vue';
|
||||
|
||||
const { preference, updateTerminalPreference } = useTerminalStore();
|
||||
@@ -99,7 +99,7 @@
|
||||
return;
|
||||
}
|
||||
// 同步
|
||||
updateTerminalPreference(PreferenceItem.INTERACT_SETTING, formModel.value, true);
|
||||
updateTerminalPreference(TerminalPreferenceItem.INTERACT_SETTING, formModel.value, true);
|
||||
}, { deep: true });
|
||||
|
||||
</script>
|
||||
|
||||
@@ -41,7 +41,7 @@
|
||||
import type { TerminalPluginsSetting } from '@/store/modules/terminal/types';
|
||||
import { ref, watch } from 'vue';
|
||||
import { useTerminalStore } from '@/store';
|
||||
import { PreferenceItem } from '@/store/modules/terminal';
|
||||
import { TerminalPreferenceItem } from '@/store/modules/terminal';
|
||||
import BlockSettingItem from './block-setting-item.vue';
|
||||
|
||||
const { preference, updateTerminalPreference } = useTerminalStore();
|
||||
@@ -54,7 +54,7 @@
|
||||
return;
|
||||
}
|
||||
// 同步
|
||||
updateTerminalPreference(PreferenceItem.PLUGINS_SETTING, formModel.value, true);
|
||||
updateTerminalPreference(TerminalPreferenceItem.PLUGINS_SETTING, formModel.value, true);
|
||||
}, { deep: true });
|
||||
|
||||
</script>
|
||||
|
||||
@@ -41,7 +41,7 @@
|
||||
import type { TerminalSessionSetting } from '@/store/modules/terminal/types';
|
||||
import { ref, watch } from 'vue';
|
||||
import { useDictStore, useTerminalStore } from '@/store';
|
||||
import { PreferenceItem } from '@/store/modules/terminal';
|
||||
import { TerminalPreferenceItem } from '@/store/modules/terminal';
|
||||
import { terminalEmulationTypeKey } from '../../types/terminal.const';
|
||||
import BlockSettingItem from './block-setting-item.vue';
|
||||
|
||||
@@ -56,7 +56,7 @@
|
||||
return;
|
||||
}
|
||||
// 同步
|
||||
updateTerminalPreference(PreferenceItem.SESSION_SETTING, formModel.value, true);
|
||||
updateTerminalPreference(TerminalPreferenceItem.SESSION_SETTING, formModel.value, true);
|
||||
}, { deep: true });
|
||||
|
||||
</script>
|
||||
|
||||
@@ -56,12 +56,12 @@
|
||||
<script lang="ts" setup>
|
||||
import type { TerminalTheme } from '@/api/asset/host-terminal';
|
||||
import { useTerminalStore } from '@/store';
|
||||
import { PreferenceItem } from '@/store/modules/terminal';
|
||||
import { TerminalPreferenceItem } from '@/store/modules/terminal';
|
||||
import { onMounted, ref } from 'vue';
|
||||
import { getTerminalThemes } from '@/api/asset/host-terminal';
|
||||
import TerminalExample from './terminal-example.vue';
|
||||
import { getPreference } from '@/api/user/preference';
|
||||
import useLoading from '@/hooks/loading';
|
||||
import TerminalExample from './terminal-example.vue';
|
||||
|
||||
const { updateTerminalPreference } = useTerminalStore();
|
||||
const { loading, setLoading } = useLoading();
|
||||
@@ -72,14 +72,14 @@
|
||||
// 选择主题
|
||||
const selectTheme = async (theme: TerminalTheme) => {
|
||||
currentThemeName.value = theme.name;
|
||||
await updateTerminalPreference(PreferenceItem.THEME, theme);
|
||||
await updateTerminalPreference(TerminalPreferenceItem.THEME, theme);
|
||||
};
|
||||
|
||||
// 加载用户主题
|
||||
onMounted(async () => {
|
||||
try {
|
||||
const { data } = await getPreference<Record<string, any>>('TERMINAL', [PreferenceItem.THEME]);
|
||||
currentThemeName.value = data[PreferenceItem.THEME]?.name;
|
||||
const { data } = await getPreference<Record<string, any>>('TERMINAL', [TerminalPreferenceItem.THEME]);
|
||||
currentThemeName.value = data[TerminalPreferenceItem.THEME]?.name;
|
||||
} catch (e) {
|
||||
}
|
||||
});
|
||||
|
||||
@@ -9,9 +9,7 @@ export default class TerminalTabManager implements ITerminalTabManager {
|
||||
public items: Array<TerminalTabItem>;
|
||||
|
||||
constructor() {
|
||||
// fixme
|
||||
// this.active = InnerTabs.NEW_CONNECTION.key;
|
||||
this.active = undefined as unknown as string;
|
||||
this.active = InnerTabs.NEW_CONNECTION.key;
|
||||
this.items = [InnerTabs.NEW_CONNECTION];
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
import { getUUID } from '@/utils';
|
||||
|
||||
// tab 类型
|
||||
export const TabType = {
|
||||
export const TerminalTabType = {
|
||||
SETTING: 'setting',
|
||||
TERMINAL: 'terminal',
|
||||
};
|
||||
@@ -11,27 +9,32 @@ export const InnerTabs = {
|
||||
NEW_CONNECTION: {
|
||||
key: 'newConnection',
|
||||
title: '新建连接',
|
||||
type: TabType.SETTING
|
||||
icon: 'icon-plus',
|
||||
type: TerminalTabType.SETTING
|
||||
},
|
||||
SHORTCUT_SETTING: {
|
||||
key: 'shortcutSetting',
|
||||
title: '快捷键设置',
|
||||
type: TabType.SETTING
|
||||
icon: 'icon-command',
|
||||
type: TerminalTabType.SETTING
|
||||
},
|
||||
DISPLAY_SETTING: {
|
||||
key: 'displaySetting',
|
||||
title: '显示设置',
|
||||
type: TabType.SETTING
|
||||
icon: 'icon-dice',
|
||||
type: TerminalTabType.SETTING
|
||||
},
|
||||
THEME_SETTING: {
|
||||
key: 'themeSetting',
|
||||
title: '主题设置',
|
||||
type: TabType.SETTING
|
||||
icon: 'icon-palette',
|
||||
type: TerminalTabType.SETTING
|
||||
},
|
||||
TERMINAL_SETTING: {
|
||||
key: 'terminalSetting',
|
||||
title: '终端设置',
|
||||
type: TabType.SETTING
|
||||
icon: 'icon-settings',
|
||||
type: TerminalTabType.SETTING
|
||||
},
|
||||
};
|
||||
|
||||
@@ -124,11 +127,6 @@ export const ActionBarItems = [
|
||||
}
|
||||
];
|
||||
|
||||
// 获取会话id
|
||||
export const nextSessionId = (): string => {
|
||||
return getUUID().replaceAll('-', '').substring(0, 10);
|
||||
};
|
||||
|
||||
// 打开 sshModal key
|
||||
export const openSshModalKey = Symbol();
|
||||
|
||||
|
||||
@@ -6,12 +6,14 @@ import type { WebLinksAddon } from 'xterm-addon-web-links';
|
||||
import type { SearchAddon } from 'xterm-addon-search';
|
||||
import type { ImageAddon } from 'xterm-addon-image';
|
||||
import type { CSSProperties } from 'vue';
|
||||
import type { HostQueryResponse } from '@/api/asset/host';
|
||||
|
||||
// 终端 tab 元素
|
||||
export interface TerminalTabItem {
|
||||
key: string;
|
||||
title: string;
|
||||
type: string;
|
||||
icon?: string;
|
||||
|
||||
[key: string]: unknown;
|
||||
}
|
||||
@@ -27,6 +29,15 @@ export interface SidebarAction {
|
||||
click: () => void;
|
||||
}
|
||||
|
||||
// 组合操作元素
|
||||
export interface CombinedHandlerItem {
|
||||
icon: string,
|
||||
type: string,
|
||||
title: string;
|
||||
settingTab?: TerminalTabItem;
|
||||
host?: HostQueryResponse;
|
||||
}
|
||||
|
||||
// ssh 额外配置
|
||||
export interface SshExtraModel {
|
||||
authType?: string;
|
||||
|
||||
Reference in New Issue
Block a user