🎨 添加终端聚焦样式.
This commit is contained in:
@@ -15,6 +15,7 @@
|
||||
:class="[
|
||||
iconClass,
|
||||
action.checked === true ? 'checked-item' : '',
|
||||
action.active === true ? 'active-item' : '',
|
||||
]"
|
||||
:disabled="action.disabled === true"
|
||||
@click="action.click()">
|
||||
|
||||
@@ -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">
|
||||
<!-- 标题 -->
|
||||
|
||||
@@ -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>
|
||||
|
||||
|
||||
@@ -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>
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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 });
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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">
|
||||
|
||||
@@ -103,7 +103,7 @@
|
||||
const openCommandBar = () => {
|
||||
const session = getCurrentSession<ISshSession>(PanelSessionType.SSH.type, true);
|
||||
if (session) {
|
||||
layoutState.commandBar = true;
|
||||
layoutState.commandBar = !layoutState.commandBar;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -30,6 +30,7 @@ export interface SidebarAction {
|
||||
visible?: boolean;
|
||||
disabled?: boolean;
|
||||
checked?: boolean;
|
||||
active?: boolean;
|
||||
iconStyle?: CSSProperties;
|
||||
click: () => void;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user