refactor: 修改终端布局.

This commit is contained in:
lijiahangmax
2024-01-08 00:20:11 +08:00
parent 48156ebb0d
commit 918ce861d3
5 changed files with 142 additions and 37 deletions

View File

@@ -3,8 +3,11 @@ import { Message } from '@arco-design/web-vue';
export default function useCopy() {
const { isSupported, copy: c, text, copied } = useClipboard();
const copy = async (value: string, tips = `${value} 已复制`) => {
const copy = async (value: string | undefined, tips = `${value} 已复制`) => {
try {
if (!value) {
return;
}
await c(value);
if (tips) {
Message.success(tips);

View File

@@ -192,17 +192,6 @@ body[terminal-theme='dark'] .host-layout {
}
}
// tooltip 内容
.terminal-tooltip-content {
color: var(--color-sidebar-tooltip-text);
background: var(--color-sidebar-tooltip-bg);
}
// tooltip 箭头
.terminal-tooltip-arrow {
display: none;
}
// 终端设置容器
.terminal-setting-container {
padding: 32px 16px 16px 16px;
@@ -246,3 +235,14 @@ body[terminal-theme='dark'] .host-layout {
}
}
// tooltip 内容
.terminal-tooltip-content {
color: var(--color-sidebar-tooltip-text);
background: var(--color-sidebar-tooltip-bg);
}
// tooltip 箭头
.terminal-tooltip-arrow {
display: none;
}

View File

@@ -20,16 +20,11 @@
<script lang="ts" setup>
import type { SidebarAction } from '../../types/terminal.const';
import IconActions from './icon-actions.vue';
import { computed } from 'vue';
import { useTerminalStore } from '@/store';
import { DarkTheme } from '@/store/modules/terminal';
const emits = defineEmits(['openSnippet', 'openSftp', 'openTransfer', 'screenshot']);
const terminalStore = useTerminalStore();
// 顶部操作
const topActions = computed<Array<SidebarAction>>(() => [
const topActions = [
{
icon: 'icon-code-block',
content: '打开命令片段',
@@ -48,12 +43,7 @@
},
click: () => emits('openTransfer')
},
{
icon: terminalStore.isDarkTheme ? 'icon-sun-fill' : 'icon-moon-fill',
content: terminalStore.isDarkTheme ? '点击切换为亮色模式' : '点击切换为暗色模式',
click: () => terminalStore.changeDarkTheme(terminalStore.isDarkTheme ? DarkTheme.LIGHT : DarkTheme.DARK)
},
]);
];
// 底部操作
const bottomActions: Array<SidebarAction> = [

View File

@@ -60,7 +60,7 @@
:max-length="32"
:disabled="item.loading"
size="mini"
:placeholder="`${item.name} (${item.code})`"
:placeholder="item.name"
@blur="saveAlias(item)"
@pressEnter="saveAlias(item)"
@change="saveAlias(item)">
@@ -215,10 +215,20 @@
// 打开终端
const openTerminal = (record: HostQueryResponse) => {
// 获取 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(),
title: record.alias || (`${record.name} ${record.address}`),
seq: nextSeq,
title: `(${nextSeq}) ${record.alias || record.name}`,
hostId: record.id,
address: record.address
});

View File

@@ -1,11 +1,35 @@
<template>
<div class="terminal-container">
<!-- 头部 -->
<div class="terminal-header">
终端 {{ tab.key }} {{ tab.title }}
<div class="terminal-header"
:style="{
background: adjustColor(preference.themeSchema.background, -10)
}">
<!-- 左侧操作 -->
<div class="terminal-header-left">
<!-- 主机地址 -->
<span class="address-wrapper">
{{ tab.address }}
<span class="address-copy copy-left" title="复制" @click="copy(tab.address as string)">
<icon-copy />
</span>
</span>
</div>
<!-- 右侧操作 -->
<div class="terminal-header-right">
<icon-actions class="bottom-actions"
:actions="bottomActions"
position="right" />
<span @click="pl">
粘贴
</span>
</div>
</div>
<!-- 终端 -->
<div class="terminal-wrapper">
<div class="terminal-wrapper"
:style="{
background: preference.themeSchema.background
}">
<div class="terminal-inst" ref="terminalRef" />
</div>
</div>
@@ -21,22 +45,61 @@
import type { TerminalTabItem } from '../../types/terminal.type';
import { onMounted, onUnmounted, ref } from 'vue';
import { useTerminalStore } from '@/store';
import useCopy from '@/hooks/copy';
import IconActions from '@/views/host/terminal/components/layout/icon-actions.vue';
import { SidebarAction } from '@/views/host/terminal/types/terminal.const';
const props = defineProps<{
tab: TerminalTabItem
}>();
const { sessionManager } = useTerminalStore();
const { copy } = useCopy();
const { preference, sessionManager } = useTerminalStore();
const terminalRef = ref();
// 初始化回话
// 底部操作
const bottomActions: Array<SidebarAction> = [
{
icon: 'icon-command',
content: '快捷键设置',
click: () => {
}
},
{
icon: 'icon-palette',
content: '外观设置',
click: () => {
}
},
];
// 调整颜色
const adjustColor = (color: string, range: number) => {
let newColor = '#';
for (let i = 0; i < 3; i++) {
let c = parseInt(color.substring(i * 2 + 1, i * 2 + 3), 16);
c += range;
if (c < 0) {
c = 0;
} else if (c > 255) {
c = 255;
}
newColor += c.toString(16).padStart(2, '0');
}
return newColor;
};
const pl = () => {
};
// 初始化会话
onMounted(async () => {
// 创建终端处理器
sessionManager.openSession(props.tab, terminalRef.value);
});
// 关闭回
//
onUnmounted(() => {
sessionManager.closeSession(props.tab.key);
});
@@ -44,7 +107,8 @@
</script>
<style lang="less" scoped>
@terminal-header-height: 30px;
@terminal-header-height: 32px;
.terminal-container {
width: 100%;
height: calc(100vh - var(--header-height));
@@ -54,16 +118,54 @@
.terminal-header {
width: 100%;
height: @terminal-header-height;
padding: 0 6px;
display: flex;
align-items: center;
justify-content: space-between;
&-left, &-right {
display: flex;
align-items: center;
font-size: 12px;
width: 100%;
height: 100%;
}
&-left:hover {
.address-copy {
display: unset;
}
}
&-right {
justify-content: flex-end;
}
.address-wrapper:before {
content: 'IP:';
padding-right: 4px;
user-select: none;
}
.address-copy {
display: none;
}
}
.terminal-wrapper {
width: 100%;
height: calc(100% - @terminal-header-height);
position: relative;
padding: 6px 0 0 6px;
.terminal-inst {
width: 100%;
height: 100%;
::-webkit-scrollbar {
display: none;
}
}
}
.terminal-inst {
width: 100%;
height: 100%;
}
</style>