update
This commit is contained in:
@@ -1,10 +1,18 @@
|
||||
<script setup lang="ts">
|
||||
import { ref, PropType } from 'vue'; // 导入 ref
|
||||
import { ref, computed, PropType } from 'vue'; // 导入 ref 和 computed
|
||||
import { useI18n } from 'vue-i18n'; // 导入 i18n
|
||||
import { storeToRefs } from 'pinia'; // 导入 storeToRefs
|
||||
import WorkspaceConnectionListComponent from './WorkspaceConnectionList.vue'; // 导入连接列表组件
|
||||
import { useSessionStore } from '../stores/session.store'; // 导入 session store
|
||||
import { useLayoutStore, type PaneName } from '../stores/layout.store'; // 导入布局 store 和类型
|
||||
// 导入会话状态类型
|
||||
import type { SessionTabInfoWithStatus } from '../stores/session.store'; // 导入更新后的类型
|
||||
|
||||
// --- Setup ---
|
||||
const { t } = useI18n(); // 初始化 i18n
|
||||
const layoutStore = useLayoutStore(); // 初始化布局 store
|
||||
const { paneVisibility } = storeToRefs(layoutStore); // 修正:使用 storeToRefs 获取响应式状态
|
||||
|
||||
// 定义 Props
|
||||
const props = defineProps({
|
||||
sessions: {
|
||||
@@ -31,9 +39,10 @@ const closeSession = (event: MouseEvent, sessionId: string) => {
|
||||
emit('close-session', sessionId);
|
||||
};
|
||||
|
||||
// --- 新增:弹出窗口状态和处理 ---
|
||||
const sessionStore = useSessionStore();
|
||||
const showConnectionListPopup = ref(false);
|
||||
// --- 本地状态 ---
|
||||
const sessionStore = useSessionStore(); // Session store 保持不变
|
||||
const showConnectionListPopup = ref(false); // 连接列表弹出状态
|
||||
const showLayoutMenu = ref(false); // 新增:布局菜单弹出状态
|
||||
|
||||
const togglePopup = () => {
|
||||
showConnectionListPopup.value = !showConnectionListPopup.value;
|
||||
@@ -46,13 +55,42 @@ const handlePopupConnect = (connectionId: number) => {
|
||||
sessionStore.handleConnectRequest(connectionId);
|
||||
showConnectionListPopup.value = false; // 关闭弹出窗口
|
||||
};
|
||||
|
||||
// --- 新增:布局菜单处理 ---
|
||||
const toggleLayoutMenu = () => {
|
||||
console.log('Toggling layout menu visibility. Current state:', showLayoutMenu.value); // 添加日志
|
||||
showLayoutMenu.value = !showLayoutMenu.value;
|
||||
console.log('New state:', showLayoutMenu.value); // 添加日志
|
||||
};
|
||||
|
||||
// 定义面板名称到显示文本的映射 (恢复 commandBar)
|
||||
const paneLabels: Record<PaneName, string> = {
|
||||
connections: t('layout.pane.connections'),
|
||||
terminal: t('layout.pane.terminal'),
|
||||
commandBar: t('layout.pane.commandBar'), // 恢复
|
||||
fileManager: t('layout.pane.fileManager'),
|
||||
editor: t('layout.pane.editor'),
|
||||
statusMonitor: t('layout.pane.statusMonitor'),
|
||||
};
|
||||
|
||||
// 获取所有可控制的面板名称
|
||||
const availablePanes = computed(() => Object.keys(paneVisibility.value) as PaneName[]); // 修正:使用 .value
|
||||
|
||||
// 处理菜单项点击
|
||||
const handleTogglePane = (paneName: PaneName) => {
|
||||
layoutStore.togglePaneVisibility(paneName);
|
||||
// 可以选择点击后关闭菜单,或者保持打开
|
||||
// showLayoutMenu.value = false;
|
||||
};
|
||||
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="terminal-tab-bar">
|
||||
<ul class="tab-list">
|
||||
<li
|
||||
v-for="session in sessions"
|
||||
<div class="tabs-and-add-button"> <!-- 新容器包裹标签和+按钮 -->
|
||||
<ul class="tab-list">
|
||||
<li
|
||||
v-for="session in sessions"
|
||||
:key="session.sessionId"
|
||||
:class="['tab-item', { active: session.sessionId === activeSessionId }]"
|
||||
@click="activateSession(session.sessionId)"
|
||||
@@ -64,14 +102,30 @@ const handlePopupConnect = (connectionId: number) => {
|
||||
<button class="close-tab-button" @click="closeSession($event, session.sessionId)" title="关闭标签页">
|
||||
× <!-- 使用 HTML 实体 '×' -->
|
||||
</button>
|
||||
</li>
|
||||
</ul>
|
||||
<!-- 新增 "+" 按钮 -->
|
||||
<button class="add-tab-button" @click="togglePopup" title="新建连接标签页">
|
||||
<i class="fas fa-plus"></i>
|
||||
</button>
|
||||
|
||||
<!-- 新增:连接列表弹出窗口 -->
|
||||
</li>
|
||||
</ul>
|
||||
<!-- "+" 按钮紧随标签列表 -->
|
||||
<button class="add-tab-button" @click="togglePopup" title="新建连接标签页">
|
||||
<i class="fas fa-plus"></i>
|
||||
</button>
|
||||
</div>
|
||||
<!-- 布局菜单按钮容器(推到最右侧) -->
|
||||
<div class="layout-menu-container">
|
||||
<button class="layout-menu-button" @click="toggleLayoutMenu" title="调整布局">
|
||||
<i class="fas fa-bars"></i> <!-- 使用 Font Awesome bars 图标 -->
|
||||
</button>
|
||||
<!-- 布局菜单下拉列表 (保持不变) -->
|
||||
<div v-if="showLayoutMenu" class="layout-menu-dropdown">
|
||||
<ul>
|
||||
<li v-for="pane in availablePanes" :key="pane" @click="handleTogglePane(pane)">
|
||||
<span class="checkmark">{{ paneVisibility[pane] ? '✓' : '' }}</span>
|
||||
{{ paneLabels[pane] || pane }}
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 移除多余的结束标签 -->
|
||||
<!-- 连接列表弹出窗口 (保持不变) -->
|
||||
<div v-if="showConnectionListPopup" class="connection-list-popup" @click.self="togglePopup">
|
||||
<div class="popup-content">
|
||||
<button class="popup-close-button" @click="togglePopup">×</button>
|
||||
@@ -91,12 +145,23 @@ const handlePopupConnect = (connectionId: number) => {
|
||||
display: flex;
|
||||
background-color: #e0e0e0; /* 标签栏背景色 */
|
||||
border-bottom: 1px solid #bdbdbd;
|
||||
overflow-x: auto; /* 如果标签过多则允许水平滚动 */
|
||||
white-space: nowrap;
|
||||
/* padding: 0 0.5rem; */ /* 移除左右内边距,让标签列表和按钮自己控制 */
|
||||
padding-right: 0.5rem; /* 只保留右侧内边距给按钮 */
|
||||
height: 2.5rem; /* 固定标签栏高度 */
|
||||
box-sizing: border-box; /* 确保 padding 不会增加总高度 */
|
||||
/* justify-content: space-between; */ /* 移除,让内容自然靠左 */
|
||||
overflow: hidden; /* 恢复:防止标签过多时破坏布局 */
|
||||
}
|
||||
|
||||
/* 包裹标签和+按钮的容器 */
|
||||
.tabs-and-add-button {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
overflow-x: auto; /* 允许标签和+按钮区域滚动 */
|
||||
/* flex-grow: 1; */ /* 移除:让其自然宽度 */
|
||||
/* max-width: calc(100% - 50px); */ /* 移除宽度限制 */
|
||||
flex-shrink: 1; /* 允许在空间不足时收缩 */
|
||||
min-width: 0; /* 允许收缩到0 */
|
||||
height: 100%; /* 确保高度与父元素相同,消除上下间距 */
|
||||
}
|
||||
|
||||
/* 状态点样式 */
|
||||
@@ -117,9 +182,11 @@ const handlePopupConnect = (connectionId: number) => {
|
||||
|
||||
.tab-list {
|
||||
list-style: none;
|
||||
padding: 0; /* 确保列表无内边距 */
|
||||
margin: 0; /* 确保列表无外边距 */
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
display: flex;
|
||||
flex-shrink: 0; /* 防止标签列表被压缩 */
|
||||
height: 100%; /* 确保占满整个高度 */
|
||||
}
|
||||
|
||||
.tab-item {
|
||||
@@ -133,7 +200,7 @@ const handlePopupConnect = (connectionId: number) => {
|
||||
background-color: #f0f0f0; /* 未激活标签背景 */
|
||||
color: #616161; /* 未激活标签文字颜色 */
|
||||
transition: background-color 0.2s ease, color 0.2s ease;
|
||||
max-width: 200px; /* 限制标签最大宽度 */
|
||||
/* max-width: 200px; */ /* 移除最大宽度限制 */
|
||||
position: relative; /* 保持相对定位,以防万一需要定位子元素 */
|
||||
}
|
||||
|
||||
@@ -153,10 +220,11 @@ const handlePopupConnect = (connectionId: number) => {
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
/* margin-right: 1.5rem; */ /* 调整右边距,因为关闭按钮现在是 flex item */
|
||||
/* margin-right: 1.5rem; */ /* 移除 */
|
||||
line-height: normal; /* 默认行高 */
|
||||
flex-grow: 1; /* 允许名称伸展 */
|
||||
flex-grow: 1; /* 保持:允许名称伸展 */
|
||||
margin-left: 4px; /* 在状态点和名称之间添加一点间距 */
|
||||
text-align: left; /* 保持文本左对齐 */
|
||||
}
|
||||
|
||||
.close-tab-button {
|
||||
@@ -169,9 +237,9 @@ const handlePopupConnect = (connectionId: number) => {
|
||||
padding: 0 0.3rem;
|
||||
line-height: 1;
|
||||
border-radius: 50%;
|
||||
margin-left: auto; /* 推到右侧 */
|
||||
margin-left: auto; /* 保持 auto 将按钮推到最右侧 */
|
||||
flex-shrink: 0; /* 防止按钮被压缩 */
|
||||
/* 移除绝对定位 */
|
||||
/* position: absolute; */
|
||||
/* top: 50%; */
|
||||
/* right: 0.5rem; */
|
||||
/* transform: translateY(-50%); */
|
||||
@@ -194,9 +262,8 @@ const handlePopupConnect = (connectionId: number) => {
|
||||
.add-tab-button {
|
||||
background: none;
|
||||
border: none;
|
||||
border-left: 1px solid #bdbdbd; /* 左侧分隔线 */
|
||||
border-left: 1px solid #bdbdbd; /* 恢复左侧分隔线 */
|
||||
padding: 0 0.8rem;
|
||||
/* margin-left: 0.5rem; */ /* 移除左外边距 */
|
||||
cursor: pointer;
|
||||
font-size: 1.1em;
|
||||
color: #616161;
|
||||
@@ -213,6 +280,8 @@ const handlePopupConnect = (connectionId: number) => {
|
||||
line-height: 1; /* 确保图标垂直居中 */
|
||||
}
|
||||
|
||||
/* 移除 action-buttons-container 样式 */
|
||||
|
||||
/* 弹出窗口样式 */
|
||||
.connection-list-popup {
|
||||
position: fixed; /* 固定定位,覆盖整个屏幕 */
|
||||
@@ -277,4 +346,77 @@ const handlePopupConnect = (connectionId: number) => {
|
||||
padding: 0; /* 保持移除内边距 */
|
||||
}
|
||||
|
||||
/* 新增:布局菜单样式 */
|
||||
.layout-menu-container {
|
||||
position: relative; /* 用于定位下拉菜单 */
|
||||
display: flex; /* 确保按钮垂直居中 */
|
||||
align-items: center;
|
||||
height: 100%;
|
||||
margin-left: auto; /* 保持:将布局按钮推到最右侧 */
|
||||
border-left: 1px solid #bdbdbd; /* 确保布局按钮左侧有分隔线 */
|
||||
flex-shrink: 0; /* 保持:防止被压缩 */
|
||||
}
|
||||
|
||||
.layout-menu-button {
|
||||
background: none;
|
||||
border: none;
|
||||
/* border-left: 1px solid #bdbdbd; */ /* 移除按钮左侧分隔线 */
|
||||
padding: 0 0.8rem;
|
||||
cursor: pointer;
|
||||
font-size: 1.1em;
|
||||
color: #616161;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
height: 100%;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
.layout-menu-button:hover {
|
||||
background-color: #d0d0d0;
|
||||
}
|
||||
.layout-menu-button i {
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
.layout-menu-dropdown {
|
||||
position: absolute; /* 恢复绝对定位 */
|
||||
top: 100%; /* 定位在按钮下方 */
|
||||
right: 0; /* 对齐到右侧 */
|
||||
background-color: lightblue; /* 临时调试背景色 */
|
||||
min-height: 20px; /* 临时调试最小高度 */
|
||||
border: 1px solid #ccc;
|
||||
box-shadow: 0 2px 5px rgba(0,0,0,0.15);
|
||||
z-index: 9999; /* 保持高 z-index */
|
||||
min-width: 150px; /* 最小宽度 */
|
||||
padding: 5px 0;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
.layout-menu-dropdown ul {
|
||||
list-style: none;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.layout-menu-dropdown li {
|
||||
padding: 8px 15px;
|
||||
cursor: pointer;
|
||||
white-space: nowrap;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.layout-menu-dropdown li:hover {
|
||||
background-color: #f0f0f0;
|
||||
}
|
||||
|
||||
.layout-menu-dropdown .checkmark {
|
||||
display: inline-block;
|
||||
width: 20px; /* 固定宽度以便对齐 */
|
||||
text-align: center;
|
||||
margin-right: 5px;
|
||||
font-weight: bold;
|
||||
color: #28a745; /* 勾选标记颜色 */
|
||||
}
|
||||
|
||||
</style>
|
||||
|
||||
Reference in New Issue
Block a user