mirror of
https://github.com/1Panel-dev/1Panel.git
synced 2025-12-19 14:01:28 +08:00
feat: enhance terminal connection UI with improved popover design and search functionality (#10902)
This commit is contained in:
parent
3b73de32ad
commit
ec4533e7de
1 changed files with 171 additions and 44 deletions
|
|
@ -139,52 +139,108 @@
|
||||||
<el-tab-pane :closable="false" name="newTabs">
|
<el-tab-pane :closable="false" name="newTabs">
|
||||||
<template #label>
|
<template #label>
|
||||||
<el-button v-popover="popoverRef" class="tagButton" icon="Plus"></el-button>
|
<el-button v-popover="popoverRef" class="tagButton" icon="Plus"></el-button>
|
||||||
<el-popover ref="popoverRef" width="250px" trigger="hover" virtual-triggering persistent>
|
<el-popover
|
||||||
<div class="ml-2.5">
|
ref="popoverRef"
|
||||||
<el-button link type="primary" @click="onNewSsh">{{ $t('terminal.createConn') }}</el-button>
|
width="320px"
|
||||||
</div>
|
trigger="hover"
|
||||||
<div class="ml-2.5">
|
virtual-triggering
|
||||||
<el-button link type="primary" @click="onNewLocal">
|
persistent
|
||||||
{{ $t('terminal.localhost') }}
|
:offset="-4"
|
||||||
</el-button>
|
>
|
||||||
</div>
|
<div class="p-2 space-y-2">
|
||||||
<div class="search-button">
|
<div class="flex gap-2">
|
||||||
<el-input
|
<button
|
||||||
v-model="hostFilterInfo"
|
@click="onNewSsh"
|
||||||
class="mt-1.5 w-[90%]"
|
class="flex-1 flex flex-col items-center justify-center px-3 py-2.5 bg-[var(--el-fill-color-light)] hover:bg-[var(--panel-main-bg-color-9)] rounded transition-colors duration-200 cursor-pointer group border-0 outline-none"
|
||||||
clearable
|
>
|
||||||
suffix-icon="Search"
|
<el-icon
|
||||||
:placeholder="$t('commons.button.search')"
|
class="text-xl mb-1 text-[var(--el-text-color-primary)] group-hover:text-[var(--el-color-primary)] transition-colors"
|
||||||
></el-input>
|
>
|
||||||
</div>
|
<Plus />
|
||||||
<el-tree
|
</el-icon>
|
||||||
ref="treeRef"
|
<span
|
||||||
:expand-on-click-node="false"
|
class="text-xs text-[var(--el-text-color-primary)] group-hover:text-[var(--el-color-primary)] font-medium truncate w-full text-center transition-colors"
|
||||||
node-key="id"
|
>
|
||||||
:default-expand-all="true"
|
{{ $t('terminal.createConn') }}
|
||||||
:data="hostTree"
|
</span>
|
||||||
:props="defaultProps"
|
</button>
|
||||||
:filter-node-method="filterHost"
|
<button
|
||||||
:empty-text="$t('terminal.noHost')"
|
@click="onNewLocal"
|
||||||
>
|
class="flex-1 flex flex-col items-center justify-center px-3 py-2.5 bg-[var(--el-fill-color-light)] hover:bg-[var(--panel-main-bg-color-9)] rounded transition-colors duration-200 cursor-pointer group border-0 outline-none"
|
||||||
<template #default="{ node, data }">
|
>
|
||||||
<span class="custom-tree-node">
|
<el-icon
|
||||||
<span v-if="node.label === 'Default'">{{ $t('commons.table.default') }}</span>
|
class="text-xl mb-1 text-[var(--el-text-color-primary)] group-hover:text-[var(--el-color-primary)] transition-colors"
|
||||||
<div v-else>
|
>
|
||||||
<span v-if="node.label.length <= 25">
|
<House />
|
||||||
<a @click="onClickConn(node, data)">{{ node.label }}</a>
|
</el-icon>
|
||||||
|
<span
|
||||||
|
class="text-xs text-[var(--el-text-color-primary)] group-hover:text-[var(--el-color-primary)] font-medium truncate w-full text-center transition-colors"
|
||||||
|
>
|
||||||
|
{{ $t('terminal.localhost') }}
|
||||||
|
</span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<el-divider class="my-0" />
|
||||||
|
|
||||||
|
<div class="search-container px-1 py-1 bg-[var(--el-fill-color-light)] rounded">
|
||||||
|
<el-input
|
||||||
|
v-model="hostFilterInfo"
|
||||||
|
class="w-full"
|
||||||
|
clearable
|
||||||
|
suffix-icon="Search"
|
||||||
|
:placeholder="$t('commons.button.search')"
|
||||||
|
size="small"
|
||||||
|
>
|
||||||
|
<template #prefix>
|
||||||
|
<el-icon class="el-input__icon"><Search /></el-icon>
|
||||||
|
</template>
|
||||||
|
</el-input>
|
||||||
|
</div>
|
||||||
|
<el-tree
|
||||||
|
ref="treeRef"
|
||||||
|
:expand-on-click-node="false"
|
||||||
|
node-key="id"
|
||||||
|
:default-expand-all="true"
|
||||||
|
:data="hostTree"
|
||||||
|
:props="defaultProps"
|
||||||
|
:filter-node-method="filterHost"
|
||||||
|
:empty-text="$t('terminal.noHost')"
|
||||||
|
class="host-tree compact"
|
||||||
|
:style="{ 'max-height': '200px' }"
|
||||||
|
>
|
||||||
|
<template #default="{ node, data }">
|
||||||
|
<span class="custom-tree-node w-full">
|
||||||
|
<span
|
||||||
|
v-if="node.label === 'Default'"
|
||||||
|
class="text-xs font-medium text-[var(--el-text-color-primary)]"
|
||||||
|
>
|
||||||
|
{{ $t('commons.table.default') }}
|
||||||
</span>
|
</span>
|
||||||
<el-tooltip v-else :content="node.label" placement="right">
|
<div v-else class="w-full min-w-0">
|
||||||
<span>
|
<span v-if="node.label.length <= 22">
|
||||||
<a @click="onClickConn(node, data)">
|
<a
|
||||||
{{ node.label.substring(0, 22) }}...
|
@click="onClickConn(node, data)"
|
||||||
|
class="text-xs text-[var(--el-text-color-primary)] hover:text-[var(--el-color-primary)] transition-colors cursor-pointer block truncate"
|
||||||
|
>
|
||||||
|
{{ node.label }}
|
||||||
</a>
|
</a>
|
||||||
</span>
|
</span>
|
||||||
</el-tooltip>
|
<el-tooltip v-else :content="node.label" placement="right">
|
||||||
</div>
|
<span>
|
||||||
</span>
|
<a
|
||||||
</template>
|
@click="onClickConn(node, data)"
|
||||||
</el-tree>
|
class="text-xs text-[var(--el-text-color-primary)] hover:text-[var(--el-color-primary)] transition-colors cursor-pointer block truncate"
|
||||||
|
>
|
||||||
|
{{ node.label.substring(0, 30) }}...
|
||||||
|
</a>
|
||||||
|
</span>
|
||||||
|
</el-tooltip>
|
||||||
|
</div>
|
||||||
|
</span>
|
||||||
|
</template>
|
||||||
|
</el-tree>
|
||||||
|
</div>
|
||||||
</el-popover>
|
</el-popover>
|
||||||
</template>
|
</template>
|
||||||
</el-tab-pane>
|
</el-tab-pane>
|
||||||
|
|
@ -245,7 +301,7 @@ const loadTooltip = () => {
|
||||||
return i18n.global.t('commons.button.' + (globalStore.isFullScreen ? 'quitFullscreen' : 'fullscreen'));
|
return i18n.global.t('commons.button.' + (globalStore.isFullScreen ? 'quitFullscreen' : 'fullscreen'));
|
||||||
};
|
};
|
||||||
|
|
||||||
let timer: NodeJS.Timer | null = null;
|
let timer: ReturnType<typeof setInterval> | null = null;
|
||||||
const terminalValue = ref();
|
const terminalValue = ref();
|
||||||
const terminalTabs = ref([]) as any;
|
const terminalTabs = ref([]) as any;
|
||||||
let tabIndex = 0;
|
let tabIndex = 0;
|
||||||
|
|
@ -556,6 +612,77 @@ onMounted(() => {
|
||||||
background-color: var(--el-tabs__item);
|
background-color: var(--el-tabs__item);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.host-tree {
|
||||||
|
:deep(.el-tree-node) {
|
||||||
|
.el-tree-node__content {
|
||||||
|
height: 36px;
|
||||||
|
padding: 0 12px;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background-color: var(--el-fill-color-light);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.el-tree-node__label {
|
||||||
|
flex: 1;
|
||||||
|
padding-left: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.el-tree-node__expand-icon {
|
||||||
|
margin-right: 8px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
:deep(.el-tree__empty-block) {
|
||||||
|
padding: 24px 0;
|
||||||
|
min-height: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
:deep(.el-tree__empty-text) {
|
||||||
|
color: var(--el-text-color-secondary);
|
||||||
|
font-size: 13px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.compact {
|
||||||
|
:deep(.el-tree-node) {
|
||||||
|
.el-tree-node__content {
|
||||||
|
height: 28px;
|
||||||
|
padding: 0 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.el-tree-node__label {
|
||||||
|
padding-left: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.el-tree-node__expand-icon {
|
||||||
|
margin-right: 4px;
|
||||||
|
font-size: 12px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
:deep(.el-tree-node__children) {
|
||||||
|
.el-tree-node__content {
|
||||||
|
padding-left: 20px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.search-container {
|
||||||
|
:deep(.el-input__wrapper) {
|
||||||
|
border-radius: 6px;
|
||||||
|
box-shadow: 0 1px 2px 0 rgba(0, 0, 0, 0.05);
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.1);
|
||||||
|
}
|
||||||
|
|
||||||
|
&.is-focus {
|
||||||
|
box-shadow: 0 0 0 2px var(--el-color-primary-light-3);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.vertical-tabs > .el-tabs__content {
|
.vertical-tabs > .el-tabs__content {
|
||||||
padding: 32px;
|
padding: 32px;
|
||||||
color: #6b778c;
|
color: #6b778c;
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue