Skip to content

Commit 2e33924

Browse files
committed
fix: Optimize UI and fix bugs
1 parent 1171adb commit 2e33924

3 files changed

Lines changed: 244 additions & 73 deletions

File tree

frontend/src/views/Dashboard.vue

Lines changed: 133 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -53,13 +53,23 @@
5353
</el-button>
5454
</div>
5555

56+
<div class="server-search">
57+
<el-input
58+
v-model="searchQuery"
59+
placeholder="搜索服务器..."
60+
clearable
61+
:prefix-icon="Search"
62+
/>
63+
</div>
64+
5665
<div class="server-list">
5766
<el-tree
5867
:data="serverTree"
5968
node-key="id"
6069
:default-expanded-keys="expandedKeys"
6170
:expand-on-click-node="false"
6271
@node-click="handleServerClick"
72+
@node-dblclick="handleServerDblClick"
6373
@node-expand="handleNodeExpand"
6474
@node-collapse="handleNodeCollapse"
6575
>
@@ -178,7 +188,7 @@
178188
import { ref, computed, onMounted } from 'vue'
179189
import { useRouter } from 'vue-router'
180190
import { ElMessage, ElMessageBox } from 'element-plus'
181-
import { Plus, Folder, Monitor, Connection, Lock, More, Edit, Delete, User, SwitchButton, UserFilled } from '@element-plus/icons-vue'
191+
import { Plus, Folder, Monitor, Connection, Lock, More, Edit, Delete, User, SwitchButton, UserFilled, Search } from '@element-plus/icons-vue'
182192
import { useServersStore } from '@/stores/servers'
183193
import { useAuthStore } from '@/stores/auth'
184194
import ServerForm from '@/components/ServerForm.vue'
@@ -191,6 +201,7 @@ const showAddServerDialog = ref(false)
191201
const showEditServerDialog = ref(false)
192202
const editingServerId = ref(null)
193203
const editingServerName = ref('')
204+
const searchQuery = ref('')
194205
195206
// 分组展开状态持久化 (sessionStorage)
196207
const EXPANDED_KEYS_STORAGE_KEY = 'webssh_dashboard_expanded_keys'
@@ -216,8 +227,18 @@ const handleNodeCollapse = (data) => {
216227
const serverTree = computed(() => {
217228
const groups = {}
218229
230+
let filteredServers = serversStore.servers
231+
if (searchQuery.value) {
232+
const q = searchQuery.value.toLowerCase()
233+
filteredServers = filteredServers.filter(server => {
234+
return server.name?.toLowerCase().includes(q) ||
235+
server.host?.toLowerCase().includes(q) ||
236+
server.group_name?.toLowerCase().includes(q)
237+
})
238+
}
239+
219240
// 按分组组织服务器
220-
serversStore.servers.forEach(server => {
241+
filteredServers.forEach(server => {
221242
const groupName = server.group_name || 'Default'
222243
if (!groups[groupName]) {
223244
groups[groupName] = []
@@ -243,9 +264,18 @@ const serverTree = computed(() => {
243264
})
244265
245266
// 处理服务器点击
246-
const handleServerClick = (data) => {
267+
const handleServerClick = (data, node) => {
247268
if (data.type === 'server') {
248269
router.push(`/terminal/${data.serverId}`)
270+
} else if (data.type === 'group' && node) {
271+
node.expanded = !node.expanded
272+
}
273+
}
274+
275+
// 处理服务器双击
276+
const handleServerDblClick = (data, node) => {
277+
if (data.type === 'group' && node) {
278+
node.expanded = !node.expanded
249279
}
250280
}
251281
@@ -393,9 +423,11 @@ onMounted(async () => {
393423
}
394424
395425
.sidebar {
396-
background: white;
397-
border-right: 1px solid #e4e7ed;
398-
padding: 20px;
426+
background: rgba(255, 255, 255, 0.65);
427+
backdrop-filter: blur(20px);
428+
-webkit-backdrop-filter: blur(20px);
429+
border-right: 1px solid rgba(0, 0, 0, 0.1);
430+
padding: 24px 20px;
399431
display: flex;
400432
flex-direction: column;
401433
}
@@ -404,13 +436,39 @@ onMounted(async () => {
404436
display: flex;
405437
justify-content: space-between;
406438
align-items: center;
407-
margin-bottom: 20px;
439+
margin-bottom: 24px;
408440
}
409441
410442
.sidebar-header h2 {
411443
margin: 0;
412-
color: #333;
444+
color: #1c1c1e;
413445
font-size: 18px;
446+
font-weight: 600;
447+
letter-spacing: -0.5px;
448+
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
449+
}
450+
451+
.server-search {
452+
margin-bottom: 20px;
453+
}
454+
455+
.server-search :deep(.el-input__wrapper) {
456+
background-color: rgba(0, 0, 0, 0.05);
457+
border-radius: 8px;
458+
box-shadow: none !important;
459+
border: 1px solid rgba(0, 0, 0, 0.08);
460+
transition: all 0.2s;
461+
}
462+
463+
.server-search :deep(.el-input__wrapper.is-focus) {
464+
background-color: rgba(255, 255, 255, 1);
465+
border-color: #007AFF;
466+
box-shadow: 0 0 0 3px rgba(0, 122, 255, 0.2) !important;
467+
}
468+
469+
.server-search :deep(.el-input__inner) {
470+
color: #1c1c1e;
471+
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
414472
}
415473
416474
.server-list {
@@ -420,11 +478,48 @@ onMounted(async () => {
420478
}
421479
422480
/* 树形组件样式调整 */
481+
:deep(.el-tree) {
482+
background: transparent;
483+
}
484+
423485
:deep(.el-tree-node__content) {
424-
height: 56px !important;
425-
padding: 0 16px !important;
426-
margin-bottom: 0 !important;
427-
transition: all 0.3s ease !important;
486+
height: auto !important;
487+
padding: 4px 8px !important;
488+
margin-bottom: 2px !important;
489+
border-radius: 8px;
490+
transition: all 0.2s ease !important;
491+
}
492+
493+
:deep(.el-tree-node__content:hover) {
494+
background-color: rgba(0, 0, 0, 0.06) !important;
495+
}
496+
497+
:deep(.el-tree-node.is-current > .el-tree-node__content:has(.server-node)) {
498+
background-color: #007AFF !important;
499+
color: white;
500+
}
501+
502+
:deep(.el-tree-node.is-current > .el-tree-node__content:has(.group-node)) {
503+
background-color: transparent !important;
504+
}
505+
506+
:deep(.el-tree-node.is-current > .el-tree-node__content .server-node .server-name),
507+
:deep(.el-tree-node.is-current > .el-tree-node__content .server-node .server-address) {
508+
color: white !important;
509+
}
510+
511+
:deep(.el-tree-node.is-current > .el-tree-node__content .server-node .server-name:hover) {
512+
color: white !important;
513+
}
514+
515+
:deep(.el-tree-node.is-current > .el-tree-node__content .server-actions) {
516+
background-color: transparent;
517+
border-color: rgba(255, 255, 255, 0.4);
518+
color: white;
519+
}
520+
521+
:deep(.el-tree-node.is-current > .el-tree-node__content .server-actions:hover) {
522+
background-color: rgba(255, 255, 255, 0.2);
428523
}
429524
430525
:deep(.el-tree-node) {
@@ -435,72 +530,76 @@ onMounted(async () => {
435530
display: flex;
436531
align-items: center;
437532
width: 100%;
438-
padding: 6px 0;
533+
padding: 2px 0;
439534
min-height: 48px;
440535
box-sizing: border-box;
441536
}
442537
443538
.group-node {
444539
font-weight: 600;
445-
color: #333;
446-
padding: 8px 0;
447-
min-height: 40px;
540+
color: #1c1c1e;
541+
padding: 8px 4px;
542+
min-height: auto;
543+
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
544+
display: flex;
545+
align-items: center;
546+
gap: 8px;
448547
}
449548
450549
.server-node {
451550
display: flex;
452551
justify-content: space-between;
453552
align-items: center;
454553
width: 100%;
455-
padding: 8px;
456-
border-radius: 4px;
457-
transition: all 0.3s;
458-
min-height: 56px;
554+
padding: 6px;
555+
border-radius: 6px;
556+
min-height: auto;
459557
box-sizing: border-box;
460558
}
461559
462560
.server-node:hover {
463-
background-color: #f5f7fa;
561+
background-color: transparent; /* rely on node content hover */
464562
}
465563
466564
.server-info-wrapper {
467565
flex: 1;
468-
margin: 0 8px;
566+
margin: 0 10px;
469567
min-width: 0;
470568
}
471569
472570
.server-name {
473571
font-weight: 500;
474572
font-size: 14px;
475-
color: #333;
573+
color: #1c1c1e;
476574
cursor: pointer;
477575
margin-bottom: 2px;
576+
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
478577
}
479578
480579
.server-name:hover {
481-
color: #409eff;
580+
color: #007AFF;
482581
}
483582
484583
.server-address {
485584
font-size: 11px;
486-
color: #999;
487-
opacity: 0.8;
585+
color: rgba(28, 28, 30, 0.6);
586+
font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace;
488587
}
489588
490589
.server-actions {
491590
padding: 4px 8px;
492-
border: 1px solid #dcdfe6;
493-
border-radius: 4px;
494-
background-color: white;
495-
color: #606266;
496-
transition: all 0.3s;
591+
border: 1px solid rgba(0, 0, 0, 0.1);
592+
border-radius: 6px;
593+
background-color: rgba(255, 255, 255, 0.8);
594+
color: #1c1c1e;
595+
transition: all 0.2s;
497596
white-space: nowrap;
498597
}
499598
500599
.server-actions:hover {
501-
border-color: #409eff;
502-
color: #409eff;
503-
background-color: #f0f7ff;
600+
border-color: #007AFF;
601+
color: #007AFF;
602+
background-color: rgba(0, 122, 255, 0.1);
504603
}
505604
506605
.action-text {

0 commit comments

Comments
 (0)