🎨 添加终端聚焦样式.
This commit is contained in:
@@ -6,7 +6,9 @@ body {
|
|||||||
--color-bg-content: #FEFEFE;
|
--color-bg-content: #FEFEFE;
|
||||||
--color-sidebar-icon: #737070;
|
--color-sidebar-icon: #737070;
|
||||||
--color-sidebar-icon-bg: #D7D8DB;
|
--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-text: rgba(255, 255, 255, .9);
|
||||||
--color-sidebar-tooltip-bg: rgb(29, 33, 41);
|
--color-sidebar-tooltip-bg: rgb(29, 33, 41);
|
||||||
--color-content-text-1: rgba(0, 0, 0, .8);
|
--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-start: rgba(218, 218, 218, 1);
|
||||||
--color-panel-gradient-end: rgba(218, 218, 218, 0);
|
--color-panel-gradient-end: rgba(218, 218, 218, 0);
|
||||||
--color-button-bg: #E3E3E3;
|
--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-focus: rgba(234, 234, 234, .95);
|
||||||
--search-bg: rgba(234, 234, 234, .75);
|
--search-bg: rgba(234, 234, 234, .75);
|
||||||
--search-color-text: #0E0E0E;
|
--search-color-text: #0E0E0E;
|
||||||
@@ -40,7 +42,9 @@ body[terminal-theme='dark'] {
|
|||||||
--color-bg-content: #1A1B1C;
|
--color-bg-content: #1A1B1C;
|
||||||
--color-sidebar-icon: #C3C6C9;
|
--color-sidebar-icon: #C3C6C9;
|
||||||
--color-sidebar-icon-bg: #3D3E3F;
|
--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-text: rgba(255, 255, 255, .9);
|
||||||
--color-sidebar-tooltip-bg: var(--color-sidebar-icon-bg);
|
--color-sidebar-tooltip-bg: var(--color-sidebar-icon-bg);
|
||||||
--color-content-text-1: rgba(255, 255, 255, .8);
|
--color-content-text-1: rgba(255, 255, 255, .8);
|
||||||
@@ -72,7 +76,7 @@ body[terminal-theme='dark'] {
|
|||||||
--panel-nav-height: 40px;
|
--panel-nav-height: 40px;
|
||||||
--sidebar-width: 44px;
|
--sidebar-width: 44px;
|
||||||
--sidebar-icon-wrapper-size: var(--header-height);
|
--sidebar-icon-wrapper-size: var(--header-height);
|
||||||
--sidebar-icon-size: 32px;
|
--sidebar-icon-size: 30px;
|
||||||
--sidebar-icon-font-size: 22px;
|
--sidebar-icon-font-size: 22px;
|
||||||
--color-bg-header-tabs: var(--color-bg-header);
|
--color-bg-header-tabs: var(--color-bg-header);
|
||||||
--color-bg-header-tabs-active: #434343;
|
--color-bg-header-tabs-active: #434343;
|
||||||
@@ -519,7 +523,12 @@ body[terminal-theme='dark'] .arco-modal-container {
|
|||||||
}
|
}
|
||||||
|
|
||||||
&.checked-item {
|
&.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 {
|
&.disabled-item {
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ import { defineStore } from 'pinia';
|
|||||||
import { getPreference, updatePreference } from '@/api/user/preference';
|
import { getPreference, updatePreference } from '@/api/user/preference';
|
||||||
import { getLatestConnectHostId } from '@/api/asset/terminal-connect-log';
|
import { getLatestConnectHostId } from '@/api/asset/terminal-connect-log';
|
||||||
import { nextId } from '@/utils';
|
import { nextId } from '@/utils';
|
||||||
|
import { isObject } from '@/utils/is';
|
||||||
import { Message } from '@arco-design/web-vue';
|
import { Message } from '@arco-design/web-vue';
|
||||||
import { PanelSessionType, TerminalTabs } from '@/views/host/terminal/types/const';
|
import { PanelSessionType, TerminalTabs } from '@/views/host/terminal/types/const';
|
||||||
import TerminalTabManager from '@/views/host/terminal/handler/terminal-tab-manager';
|
import TerminalTabManager from '@/views/host/terminal/handler/terminal-tab-manager';
|
||||||
@@ -121,7 +122,7 @@ export default defineStore('terminal', {
|
|||||||
await updatePreference({
|
await updatePreference({
|
||||||
type: 'TERMINAL',
|
type: 'TERMINAL',
|
||||||
item,
|
item,
|
||||||
value
|
value: isObject(value) ? JSON.stringify(value) : value,
|
||||||
});
|
});
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
Message.error('同步失败');
|
Message.error('同步失败');
|
||||||
|
|||||||
@@ -15,6 +15,7 @@
|
|||||||
:class="[
|
:class="[
|
||||||
iconClass,
|
iconClass,
|
||||||
action.checked === true ? 'checked-item' : '',
|
action.checked === true ? 'checked-item' : '',
|
||||||
|
action.active === true ? 'active-item' : '',
|
||||||
]"
|
]"
|
||||||
:disabled="action.disabled === true"
|
:disabled="action.disabled === true"
|
||||||
@click="action.click()">
|
@click="action.click()">
|
||||||
|
|||||||
@@ -14,8 +14,8 @@
|
|||||||
:editable="true"
|
:editable="true"
|
||||||
:hide-content="true"
|
:hide-content="true"
|
||||||
:auto-switch="true"
|
:auto-switch="true"
|
||||||
@tab-click="(k: string) => tabManager.clickTab(k)"
|
@tab-click="(k) => tabManager.clickTab(k as string)"
|
||||||
@delete="(k: string) => tabManager.deleteTab(k)">
|
@delete="(k) => tabManager.deleteTab(k as string)">
|
||||||
<a-tab-pane v-for="tab in tabManager.items"
|
<a-tab-pane v-for="tab in tabManager.items"
|
||||||
:key="tab.key">
|
:key="tab.key">
|
||||||
<!-- 标题 -->
|
<!-- 标题 -->
|
||||||
|
|||||||
@@ -19,6 +19,7 @@
|
|||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import type { SidebarAction } from '../../types/define';
|
import type { SidebarAction } from '../../types/define';
|
||||||
|
import { computed } from 'vue';
|
||||||
import { TerminalTabs } from '../../types/const';
|
import { TerminalTabs } from '../../types/const';
|
||||||
import { useTerminalStore } from '@/store';
|
import { useTerminalStore } from '@/store';
|
||||||
import IconActions from './icon-actions.vue';
|
import IconActions from './icon-actions.vue';
|
||||||
@@ -26,37 +27,47 @@
|
|||||||
const { tabManager } = useTerminalStore();
|
const { tabManager } = useTerminalStore();
|
||||||
|
|
||||||
// 顶部操作
|
// 顶部操作
|
||||||
const topActions: Array<SidebarAction> = [
|
const topActions = computed<Array<SidebarAction>>(() => {
|
||||||
{
|
return [
|
||||||
icon: TerminalTabs.NEW_CONNECTION.icon,
|
{
|
||||||
content: TerminalTabs.NEW_CONNECTION.title,
|
icon: TerminalTabs.NEW_CONNECTION.icon,
|
||||||
click: () => tabManager.openTab(TerminalTabs.NEW_CONNECTION)
|
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> = [
|
const bottomActions = computed<Array<SidebarAction>>(() => {
|
||||||
{
|
return [
|
||||||
icon: TerminalTabs.SHORTCUT_SETTING.icon,
|
{
|
||||||
content: TerminalTabs.SHORTCUT_SETTING.title,
|
icon: TerminalTabs.SHORTCUT_SETTING.icon,
|
||||||
click: () => tabManager.openTab(TerminalTabs.SHORTCUT_SETTING)
|
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)
|
icon: TerminalTabs.DISPLAY_SETTING.icon,
|
||||||
},
|
content: TerminalTabs.DISPLAY_SETTING.title,
|
||||||
{
|
click: () => tabManager.openTab(TerminalTabs.DISPLAY_SETTING),
|
||||||
icon: TerminalTabs.THEME_SETTING.icon,
|
active: tabManager.active === TerminalTabs.DISPLAY_SETTING.key,
|
||||||
content: TerminalTabs.THEME_SETTING.title,
|
},
|
||||||
click: () => tabManager.openTab(TerminalTabs.THEME_SETTING)
|
{
|
||||||
},
|
icon: TerminalTabs.THEME_SETTING.icon,
|
||||||
{
|
content: TerminalTabs.THEME_SETTING.title,
|
||||||
icon: TerminalTabs.TERMINAL_SETTING.icon,
|
click: () => tabManager.openTab(TerminalTabs.THEME_SETTING),
|
||||||
content: TerminalTabs.TERMINAL_SETTING.title,
|
active: tabManager.active === TerminalTabs.THEME_SETTING.key,
|
||||||
click: () => tabManager.openTab(TerminalTabs.TERMINAL_SETTING)
|
},
|
||||||
},
|
{
|
||||||
];
|
icon: TerminalTabs.TERMINAL_SETTING.icon,
|
||||||
|
content: TerminalTabs.TERMINAL_SETTING.title,
|
||||||
|
click: () => tabManager.openTab(TerminalTabs.TERMINAL_SETTING),
|
||||||
|
active: tabManager.active === TerminalTabs.TERMINAL_SETTING.key,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
});
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|||||||
@@ -19,42 +19,50 @@
|
|||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import type { SidebarAction } from '../../types/define';
|
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';
|
import IconActions from './icon-actions.vue';
|
||||||
|
|
||||||
const emits = defineEmits(['openCommandSnippet', 'openPathBookmark', 'openTransferList', 'openCommandBar', 'screenshot']);
|
const emits = defineEmits(['openCommandSnippet', 'openPathBookmark', 'openTransferList', 'openCommandBar', 'screenshot']);
|
||||||
|
|
||||||
|
const { layoutState, tabManager } = useTerminalStore();
|
||||||
|
|
||||||
// 顶部操作
|
// 顶部操作
|
||||||
const topActions = [
|
const topActions: Array<SidebarAction> = [
|
||||||
{
|
{
|
||||||
icon: 'icon-code-block',
|
icon: 'icon-code-block',
|
||||||
content: '打开命令片段',
|
content: '打开命令片段',
|
||||||
click: () => emits('openCommandSnippet')
|
click: () => emits('openCommandSnippet'),
|
||||||
}, {
|
}, {
|
||||||
icon: 'icon-bookmark',
|
icon: 'icon-bookmark',
|
||||||
content: '打开路径书签',
|
content: '打开路径书签',
|
||||||
click: () => emits('openPathBookmark')
|
click: () => emits('openPathBookmark'),
|
||||||
}, {
|
}, {
|
||||||
icon: 'icon-swap',
|
icon: 'icon-swap',
|
||||||
content: '文件传输列表',
|
content: '文件传输列表',
|
||||||
iconStyle: {
|
iconStyle: {
|
||||||
transform: 'rotate(90deg)'
|
transform: 'rotate(90deg)'
|
||||||
},
|
},
|
||||||
click: () => emits('openTransferList')
|
click: () => emits('openTransferList'),
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
// 底部操作
|
// 底部操作
|
||||||
const bottomActions: Array<SidebarAction> = [
|
const bottomActions = computed<Array<SidebarAction>>(() => {
|
||||||
{
|
return [
|
||||||
icon: 'icon-send',
|
{
|
||||||
content: '发送命令',
|
icon: 'icon-send',
|
||||||
click: () => emits('openCommandBar')
|
content: '发送命令',
|
||||||
}, {
|
active: layoutState.commandBar && tabManager.active === TerminalTabs.TERMINAL_PANEL.key,
|
||||||
icon: 'icon-camera',
|
click: () => emits('openCommandBar'),
|
||||||
content: '截图',
|
}, {
|
||||||
click: () => emits('screenshot')
|
icon: 'icon-camera',
|
||||||
},
|
content: '截图',
|
||||||
];
|
click: () => emits('screenshot'),
|
||||||
|
},
|
||||||
|
];
|
||||||
|
});
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|||||||
@@ -6,8 +6,8 @@
|
|||||||
:auto-switch="false"
|
:auto-switch="false"
|
||||||
:show-add-button="true"
|
:show-add-button="true"
|
||||||
@add="openNewConnect"
|
@add="openNewConnect"
|
||||||
@tab-click="(k: string) => panel.clickTab(k)"
|
@tab-click="(k) => panel.clickTab(k as string)"
|
||||||
@delete="(k: string) => panel.deleteTab(k)">
|
@delete="(k) => panel.deleteTab(k as string)">
|
||||||
<!-- 右侧按钮 -->
|
<!-- 右侧按钮 -->
|
||||||
<template #extra>
|
<template #extra>
|
||||||
<a-space class="panel-extra">
|
<a-space class="panel-extra">
|
||||||
@@ -123,7 +123,7 @@
|
|||||||
margin-right: 6px;
|
margin-right: 6px;
|
||||||
}
|
}
|
||||||
|
|
||||||
&:hover{
|
&:hover {
|
||||||
filter: brightness(1.04);
|
filter: brightness(1.04);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -10,7 +10,7 @@
|
|||||||
type="button"
|
type="button"
|
||||||
class="usn"
|
class="usn"
|
||||||
:options="toRadioOptions(newConnectionTypeKey)"
|
: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"
|
<a-auto-complete v-model="filterValue"
|
||||||
class="host-filter"
|
class="host-filter"
|
||||||
|
|||||||
@@ -133,7 +133,7 @@
|
|||||||
|
|
||||||
// 监听内容变化
|
// 监听内容变化
|
||||||
watch(formModel, (v, before) => {
|
watch(formModel, (v, before) => {
|
||||||
if (!v) {
|
if (!v || !Object.keys(v).length) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const options = previewTerminal.value?.term?.options;
|
const options = previewTerminal.value?.term?.options;
|
||||||
@@ -149,29 +149,29 @@
|
|||||||
options[key] = (formModel.value as any)[key];
|
options[key] = (formModel.value as any)[key];
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
// 非初始化则修改终端样式
|
// 修改终端样式
|
||||||
if (before) {
|
Object.values(sessionManager.sessions)
|
||||||
Object.values(sessionManager.sessions)
|
.filter(Boolean)
|
||||||
.filter(Boolean)
|
.filter(s => s.type === PanelSessionType.SSH.type)
|
||||||
.filter(s => s.type === PanelSessionType.SSH.type)
|
.map(s => s as ISshSession)
|
||||||
.map(s => s as ISshSession)
|
.forEach(s => {
|
||||||
.forEach(s => {
|
const options = s.inst.options;
|
||||||
const options = s.inst.options;
|
s.inst;
|
||||||
s.inst;
|
// 修改样式
|
||||||
// 修改样式
|
Object.keys(v).forEach(k => {
|
||||||
Object.keys(v).forEach(k => {
|
let value = v[k as keyof TerminalDisplaySetting];
|
||||||
let value = v[k as keyof TerminalDisplaySetting];
|
if (k === 'fontFamily') {
|
||||||
if (k === 'fontFamily') {
|
value = value === '_' ? defaultFontFamily : `${value}, ${defaultFontFamily}`;
|
||||||
value = value === '_' ? defaultFontFamily : `${value}, ${defaultFontFamily}`;
|
}
|
||||||
}
|
options[k as keyof typeof options] = value;
|
||||||
options[k as keyof typeof options] = value;
|
|
||||||
});
|
|
||||||
// 自适应
|
|
||||||
s.fit();
|
|
||||||
});
|
});
|
||||||
|
// 自适应
|
||||||
|
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();
|
previewTerminal.value.term.focus();
|
||||||
}, { deep: true });
|
}, { deep: true });
|
||||||
|
|||||||
@@ -281,8 +281,8 @@
|
|||||||
|
|
||||||
// 加载配置
|
// 加载配置
|
||||||
onMounted(async () => {
|
onMounted(async () => {
|
||||||
const data = await useCacheStore().loadSystemSetting<SftpSetting>('SFTP');
|
const { sftp } = await useCacheStore().loadSystemSetting();
|
||||||
previewSize.value = data?.previewSize;
|
previewSize.value = sftp?.previewSize;
|
||||||
});
|
});
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -11,7 +11,7 @@
|
|||||||
<template v-if="session && preference.interactSetting.enableRightClickMenu" #content>
|
<template v-if="session && preference.interactSetting.enableRightClickMenu" #content>
|
||||||
<a-doption v-for="(action, index) in actions"
|
<a-doption v-for="(action, index) in actions"
|
||||||
:key="index"
|
:key="index"
|
||||||
:disabled="!session.handler.enabledStatus(action.item)"
|
:disabled="!session || !session.handler.enabledStatus(action.item)"
|
||||||
@click="emits('handle', action.item)">
|
@click="emits('handle', action.item)">
|
||||||
<!-- 图标 -->
|
<!-- 图标 -->
|
||||||
<div class="terminal-context-menu-icon">
|
<div class="terminal-context-menu-icon">
|
||||||
|
|||||||
@@ -103,7 +103,7 @@
|
|||||||
const openCommandBar = () => {
|
const openCommandBar = () => {
|
||||||
const session = getCurrentSession<ISshSession>(PanelSessionType.SSH.type, true);
|
const session = getCurrentSession<ISshSession>(PanelSessionType.SSH.type, true);
|
||||||
if (session) {
|
if (session) {
|
||||||
layoutState.commandBar = true;
|
layoutState.commandBar = !layoutState.commandBar;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -30,6 +30,7 @@ export interface SidebarAction {
|
|||||||
visible?: boolean;
|
visible?: boolean;
|
||||||
disabled?: boolean;
|
disabled?: boolean;
|
||||||
checked?: boolean;
|
checked?: boolean;
|
||||||
|
active?: boolean;
|
||||||
iconStyle?: CSSProperties;
|
iconStyle?: CSSProperties;
|
||||||
click: () => void;
|
click: () => void;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user