🎨 添加终端聚焦样式.

This commit is contained in:
lijiahang
2025-01-15 10:21:01 +08:00
parent 0e14e55c5a
commit 932bdb86ad
13 changed files with 113 additions and 82 deletions

View File

@@ -6,7 +6,9 @@ body {
--color-bg-content: #FEFEFE;
--color-sidebar-icon: #737070;
--color-sidebar-icon-bg: #D7D8DB;
--color-sidebar-icon-checked: #CBCCCF;
--color-sidebar-icon-checked-bg: #CBCCCF;
--color-sidebar-icon-active-bg: #3860FF;
--color-sidebar-icon-active-text: rgba(255, 255, 255, .85);
--color-sidebar-tooltip-text: rgba(255, 255, 255, .9);
--color-sidebar-tooltip-bg: rgb(29, 33, 41);
--color-content-text-1: rgba(0, 0, 0, .8);
@@ -21,7 +23,7 @@ body {
--color-panel-gradient-start: rgba(218, 218, 218, 1);
--color-panel-gradient-end: rgba(218, 218, 218, 0);
--color-button-bg: #E3E3E3;
--color-button-bg-active: var(--color-sidebar-icon-checked);
--color-button-bg-active: var(--color-sidebar-icon-checked-bg);
--search-bg-focus: rgba(234, 234, 234, .95);
--search-bg: rgba(234, 234, 234, .75);
--search-color-text: #0E0E0E;
@@ -40,7 +42,9 @@ body[terminal-theme='dark'] {
--color-bg-content: #1A1B1C;
--color-sidebar-icon: #C3C6C9;
--color-sidebar-icon-bg: #3D3E3F;
--color-sidebar-icon-checked: #51525C;
--color-sidebar-icon-checked-bg: #51525C;
--color-sidebar-icon-active-bg: #3860FF;
--color-sidebar-icon-active-text: rgba(255, 255, 255, .85);
--color-sidebar-tooltip-text: rgba(255, 255, 255, .9);
--color-sidebar-tooltip-bg: var(--color-sidebar-icon-bg);
--color-content-text-1: rgba(255, 255, 255, .8);
@@ -72,7 +76,7 @@ body[terminal-theme='dark'] {
--panel-nav-height: 40px;
--sidebar-width: 44px;
--sidebar-icon-wrapper-size: var(--header-height);
--sidebar-icon-size: 32px;
--sidebar-icon-size: 30px;
--sidebar-icon-font-size: 22px;
--color-bg-header-tabs: var(--color-bg-header);
--color-bg-header-tabs-active: #434343;
@@ -519,7 +523,12 @@ body[terminal-theme='dark'] .arco-modal-container {
}
&.checked-item {
background: var(--color-sidebar-icon-checked);
background: var(--color-sidebar-icon-checked-bg);
}
&.active-item {
background: var(--color-sidebar-icon-active-bg);
color: var(--color-sidebar-icon-active-text);
}
&.disabled-item {

View File

@@ -18,6 +18,7 @@ import { defineStore } from 'pinia';
import { getPreference, updatePreference } from '@/api/user/preference';
import { getLatestConnectHostId } from '@/api/asset/terminal-connect-log';
import { nextId } from '@/utils';
import { isObject } from '@/utils/is';
import { Message } from '@arco-design/web-vue';
import { PanelSessionType, TerminalTabs } from '@/views/host/terminal/types/const';
import TerminalTabManager from '@/views/host/terminal/handler/terminal-tab-manager';
@@ -121,7 +122,7 @@ export default defineStore('terminal', {
await updatePreference({
type: 'TERMINAL',
item,
value
value: isObject(value) ? JSON.stringify(value) : value,
});
} catch (e) {
Message.error('同步失败');

View File

@@ -15,6 +15,7 @@
:class="[
iconClass,
action.checked === true ? 'checked-item' : '',
action.active === true ? 'active-item' : '',
]"
:disabled="action.disabled === true"
@click="action.click()">

View File

@@ -14,8 +14,8 @@
:editable="true"
:hide-content="true"
:auto-switch="true"
@tab-click="(k: string) => tabManager.clickTab(k)"
@delete="(k: string) => tabManager.deleteTab(k)">
@tab-click="(k) => tabManager.clickTab(k as string)"
@delete="(k) => tabManager.deleteTab(k as string)">
<a-tab-pane v-for="tab in tabManager.items"
:key="tab.key">
<!-- 标题 -->

View File

@@ -19,6 +19,7 @@
<script lang="ts" setup>
import type { SidebarAction } from '../../types/define';
import { computed } from 'vue';
import { TerminalTabs } from '../../types/const';
import { useTerminalStore } from '@/store';
import IconActions from './icon-actions.vue';
@@ -26,37 +27,47 @@
const { tabManager } = useTerminalStore();
// 顶部操作
const topActions: Array<SidebarAction> = [
{
icon: TerminalTabs.NEW_CONNECTION.icon,
content: TerminalTabs.NEW_CONNECTION.title,
click: () => tabManager.openTab(TerminalTabs.NEW_CONNECTION)
},
];
const topActions = computed<Array<SidebarAction>>(() => {
return [
{
icon: TerminalTabs.NEW_CONNECTION.icon,
content: TerminalTabs.NEW_CONNECTION.title,
click: () => tabManager.openTab(TerminalTabs.NEW_CONNECTION),
active: tabManager.active === TerminalTabs.NEW_CONNECTION.key
|| tabManager.active === TerminalTabs.TERMINAL_PANEL.key,
},
];
});
// 底部操作
const bottomActions: Array<SidebarAction> = [
{
icon: TerminalTabs.SHORTCUT_SETTING.icon,
content: TerminalTabs.SHORTCUT_SETTING.title,
click: () => tabManager.openTab(TerminalTabs.SHORTCUT_SETTING)
},
{
icon: TerminalTabs.DISPLAY_SETTING.icon,
content: TerminalTabs.DISPLAY_SETTING.title,
click: () => tabManager.openTab(TerminalTabs.DISPLAY_SETTING)
},
{
icon: TerminalTabs.THEME_SETTING.icon,
content: TerminalTabs.THEME_SETTING.title,
click: () => tabManager.openTab(TerminalTabs.THEME_SETTING)
},
{
icon: TerminalTabs.TERMINAL_SETTING.icon,
content: TerminalTabs.TERMINAL_SETTING.title,
click: () => tabManager.openTab(TerminalTabs.TERMINAL_SETTING)
},
];
const bottomActions = computed<Array<SidebarAction>>(() => {
return [
{
icon: TerminalTabs.SHORTCUT_SETTING.icon,
content: TerminalTabs.SHORTCUT_SETTING.title,
click: () => tabManager.openTab(TerminalTabs.SHORTCUT_SETTING),
active: tabManager.active === TerminalTabs.SHORTCUT_SETTING.key,
},
{
icon: TerminalTabs.DISPLAY_SETTING.icon,
content: TerminalTabs.DISPLAY_SETTING.title,
click: () => tabManager.openTab(TerminalTabs.DISPLAY_SETTING),
active: tabManager.active === TerminalTabs.DISPLAY_SETTING.key,
},
{
icon: TerminalTabs.THEME_SETTING.icon,
content: TerminalTabs.THEME_SETTING.title,
click: () => tabManager.openTab(TerminalTabs.THEME_SETTING),
active: tabManager.active === TerminalTabs.THEME_SETTING.key,
},
{
icon: TerminalTabs.TERMINAL_SETTING.icon,
content: TerminalTabs.TERMINAL_SETTING.title,
click: () => tabManager.openTab(TerminalTabs.TERMINAL_SETTING),
active: tabManager.active === TerminalTabs.TERMINAL_SETTING.key,
},
];
});
</script>

View File

@@ -19,42 +19,50 @@
<script lang="ts" setup>
import type { SidebarAction } from '../../types/define';
import { computed } from 'vue';
import { useTerminalStore } from '@/store';
import { TerminalTabs } from '../../types/const';
import IconActions from './icon-actions.vue';
const emits = defineEmits(['openCommandSnippet', 'openPathBookmark', 'openTransferList', 'openCommandBar', 'screenshot']);
const { layoutState, tabManager } = useTerminalStore();
// 顶部操作
const topActions = [
const topActions: Array<SidebarAction> = [
{
icon: 'icon-code-block',
content: '打开命令片段',
click: () => emits('openCommandSnippet')
click: () => emits('openCommandSnippet'),
}, {
icon: 'icon-bookmark',
content: '打开路径书签',
click: () => emits('openPathBookmark')
click: () => emits('openPathBookmark'),
}, {
icon: 'icon-swap',
content: '文件传输列表',
iconStyle: {
transform: 'rotate(90deg)'
},
click: () => emits('openTransferList')
click: () => emits('openTransferList'),
},
];
// 底部操作
const bottomActions: Array<SidebarAction> = [
{
icon: 'icon-send',
content: '发送命令',
click: () => emits('openCommandBar')
}, {
icon: 'icon-camera',
content: '截图',
click: () => emits('screenshot')
},
];
const bottomActions = computed<Array<SidebarAction>>(() => {
return [
{
icon: 'icon-send',
content: '发送命令',
active: layoutState.commandBar && tabManager.active === TerminalTabs.TERMINAL_PANEL.key,
click: () => emits('openCommandBar'),
}, {
icon: 'icon-camera',
content: '截图',
click: () => emits('screenshot'),
},
];
});
</script>

View File

@@ -6,8 +6,8 @@
:auto-switch="false"
:show-add-button="true"
@add="openNewConnect"
@tab-click="(k: string) => panel.clickTab(k)"
@delete="(k: string) => panel.deleteTab(k)">
@tab-click="(k) => panel.clickTab(k as string)"
@delete="(k) => panel.deleteTab(k as string)">
<!-- 右侧按钮 -->
<template #extra>
<a-space class="panel-extra">
@@ -123,7 +123,7 @@
margin-right: 6px;
}
&:hover{
&:hover {
filter: brightness(1.04);
}

View File

@@ -10,7 +10,7 @@
type="button"
class="usn"
:options="toRadioOptions(newConnectionTypeKey)"
@change="(s: string) => updateTerminalPreference(TerminalPreferenceItem.NEW_CONNECTION_TYPE, s, true)" />
@change="(s) => updateTerminalPreference(TerminalPreferenceItem.NEW_CONNECTION_TYPE, s as string, true)" />
<!-- 过滤 -->
<a-auto-complete v-model="filterValue"
class="host-filter"

View File

@@ -133,7 +133,7 @@
// 监听内容变化
watch(formModel, (v, before) => {
if (!v) {
if (!v || !Object.keys(v).length) {
return;
}
const options = previewTerminal.value?.term?.options;
@@ -149,29 +149,29 @@
options[key] = (formModel.value as any)[key];
}
});
// 非初始化则修改终端样式
if (before) {
Object.values(sessionManager.sessions)
.filter(Boolean)
.filter(s => s.type === PanelSessionType.SSH.type)
.map(s => s as ISshSession)
.forEach(s => {
const options = s.inst.options;
s.inst;
// 修改样式
Object.keys(v).forEach(k => {
let value = v[k as keyof TerminalDisplaySetting];
if (k === 'fontFamily') {
value = value === '_' ? defaultFontFamily : `${value}, ${defaultFontFamily}`;
}
options[k as keyof typeof options] = value;
});
// 自适应
s.fit();
// 修改终端样式
Object.values(sessionManager.sessions)
.filter(Boolean)
.filter(s => s.type === PanelSessionType.SSH.type)
.map(s => s as ISshSession)
.forEach(s => {
const options = s.inst.options;
s.inst;
// 修改样式
Object.keys(v).forEach(k => {
let value = v[k as keyof TerminalDisplaySetting];
if (k === 'fontFamily') {
value = value === '_' ? defaultFontFamily : `${value}, ${defaultFontFamily}`;
}
options[k as keyof typeof options] = value;
});
// 自适应
s.fit();
});
// 非初始化则同步
if (Object.keys(before).length) {
updateTerminalPreference(TerminalPreferenceItem.DISPLAY_SETTING, formModel.value, true);
}
// 同步
updateTerminalPreference(TerminalPreferenceItem.DISPLAY_SETTING, formModel.value, true);
// 聚焦
previewTerminal.value.term.focus();
}, { deep: true });

View File

@@ -281,8 +281,8 @@
// 加载配置
onMounted(async () => {
const data = await useCacheStore().loadSystemSetting<SftpSetting>('SFTP');
previewSize.value = data?.previewSize;
const { sftp } = await useCacheStore().loadSystemSetting();
previewSize.value = sftp?.previewSize;
});
</script>

View File

@@ -11,7 +11,7 @@
<template v-if="session && preference.interactSetting.enableRightClickMenu" #content>
<a-doption v-for="(action, index) in actions"
:key="index"
:disabled="!session.handler.enabledStatus(action.item)"
:disabled="!session || !session.handler.enabledStatus(action.item)"
@click="emits('handle', action.item)">
<!-- 图标 -->
<div class="terminal-context-menu-icon">

View File

@@ -103,7 +103,7 @@
const openCommandBar = () => {
const session = getCurrentSession<ISshSession>(PanelSessionType.SSH.type, true);
if (session) {
layoutState.commandBar = true;
layoutState.commandBar = !layoutState.commandBar;
}
};

View File

@@ -30,6 +30,7 @@ export interface SidebarAction {
visible?: boolean;
disabled?: boolean;
checked?: boolean;
active?: boolean;
iconStyle?: CSSProperties;
click: () => void;
}