feat: 终端承载页.

This commit is contained in:
lijiahang
2024-01-12 19:42:16 +08:00
parent 322301d9c9
commit 720c2247c8
7 changed files with 153 additions and 35 deletions

View File

@@ -3,7 +3,7 @@
// @ts-nocheck
// Generated by unplugin-vue-components
// Read more: https://github.com/vuejs/core/pull/3399
import '@vue/runtime-core'
import '@vue/runtime-core';
export {}

View File

@@ -0,0 +1,90 @@
<template>
<div class="terminal-setting-container">
<div class="terminal-setting-wrapper">
<!-- 组合容器 -->
<div class="combined-container">
<!-- 新建连接 -->
<div class="combined-handler">
<!-- 图标 -->
<div class="combined-handler-icon">
<icon-plus />
</div>
<!-- 内容 -->
<div class="combined-handler-text">
新建连接
</div>
</div>
<!-- 主机列表 -->
<div class="combined-handler">
<!-- 图标 -->
<div class="combined-handler-icon">
<icon-desktop />
</div>
<!-- 内容 -->
<div class="combined-handler-text">
历史1
</div>
</div>
</div>
</div>
</div>
</template>
<script lang="ts">
export default {
name: 'emptyRecommend'
};
</script>
<script lang="ts" setup>
import { useTerminalStore } from '@/store';
const { tabManager, hosts } = useTerminalStore();
</script>
<style lang="less" scoped>
@handler-height: 48px;
.combined-container {
padding: 8px;
margin: 64px auto;
width: 448px;
height: 448px;
display: flex;
flex-direction: column;
overflow: hidden;
&:hover {
overflow: auto;
}
}
.combined-handler {
width: 100%;
height: @handler-height;
border-radius: 4px;
margin-bottom: 6px;
background-color: var(--color-fill-2);
display: flex;
align-items: center;
color: var(--color-content-text-1);
&-icon {
width: @handler-height;
height: @handler-height;
display: flex;
align-items: center;
justify-content: center;
font-size: 18px;
}
&-text {
height: 100%;
display: flex;
align-items: center;
font-size: 14px;
}
}
</style>

View File

@@ -0,0 +1,29 @@
<template>
<div class="terminal-setting-container">
<div class="terminal-setting-wrapper terminal-skeleton">
<!-- 加载骨架 -->
<a-skeleton class="full"
:animation="true">
<a-skeleton-line :rows="6"
:line-height="42"
:line-spacing="24" />
</a-skeleton>
</div>
</div>
</template>
<script lang="ts">
export default {
name: 'loadingSkeleton'
};
</script>
<script lang="ts" setup>
</script>
<style lang="less" scoped>
.terminal-skeleton {
margin: 32px auto;
}
</style>

View File

@@ -1,7 +1,8 @@
<template>
<div class="terminal-content">
<!-- 内容 tabs -->
<a-tabs v-model:active-key="tabManager.active">
<a-tabs v-if="tabManager.active"
v-model:active-key="tabManager.active">
<a-tab-pane v-for="tab in tabManager.items"
:key="tab.key"
:title="tab.title">
@@ -22,6 +23,8 @@
</template>
</a-tab-pane>
</a-tabs>
<!-- 承载页推荐 -->
<empty-recommend v-else />
</div>
</template>
@@ -35,6 +38,7 @@
import { TabType, InnerTabs } from '../../types/terminal.const';
import { useTerminalStore } from '@/store';
import { watch } from 'vue';
import EmptyRecommend from './empty-recommend.vue';
import NewConnectionView from '../new-connection/new-connection-view.vue';
import TerminalDisplaySetting from '../view-setting/terminal-display-setting.vue';
import TerminalThemeSetting from '../view-setting/terminal-theme-setting.vue';
@@ -46,6 +50,8 @@
// 监听 tab 修改
watch(() => tabManager.active, active => {
if (!active) {
// 修改标题
document.title = '主机终端';
return;
}
// 获取 tab

View File

@@ -40,16 +40,8 @@
</div>
<!-- 内容区域 -->
<div class="terminal-setting-body body-container">
<!-- 加载中 -->
<a-skeleton v-if="loading"
class="hosts-skeleton"
:animation="true">
<a-skeleton-line :rows="6"
:line-height="40"
:line-spacing="20" />
</a-skeleton>
<!-- 无数据 -->
<a-empty v-else-if="!hosts.hostList?.length">
<a-empty v-if="!hosts.hostList?.length">
<template #image>
<icon-desktop />
</template>
@@ -77,16 +69,14 @@
import type { SelectOptionData } from '@arco-design/web-vue';
import { onBeforeMount, ref } from 'vue';
import { NewConnectionType, newConnectionTypeKey } from '../../types/terminal.const';
import useLoading from '@/hooks/loading';
import { useDictStore, useTerminalStore } from '@/store';
import { PreferenceItem } from '@/store/modules/terminal';
import { dataColor } from '@/utils';
import { tagColor } from '@/views/asset/host-list/types/const';
import HostsView from './hosts-view.vue';
const { loading, setLoading } = useLoading();
const { toRadioOptions } = useDictStore();
const { preference, updateTerminalPreference, hosts, loadHosts } = useTerminalStore();
const { preference, updateTerminalPreference, hosts } = useTerminalStore();
const newConnectionType = ref(preference.newConnectionType || NewConnectionType.GROUP);
const filterValue = ref('');
@@ -123,21 +113,8 @@
}).forEach(s => filterOptions.value.push(s));
};
// 加载主机信息
const initHosts = async () => {
try {
setLoading(true);
// 加载主机信息
await loadHosts();
// 初始化过滤项
initFilterOptions();
} finally {
setLoading(false);
}
};
// 加载主机信息
onBeforeMount(initHosts);
// 初始化过滤器项
onBeforeMount(initFilterOptions);
</script>
@@ -155,10 +132,6 @@
.body-container {
justify-content: space-between;
.hosts-skeleton {
width: 100%;
}
.host-view-container {
width: 100%;
height: calc(100vh - 240px);

View File

@@ -9,7 +9,9 @@ export default class TerminalTabManager implements ITerminalTabManager {
public items: Array<TerminalTabItem>;
constructor() {
this.active = InnerTabs.NEW_CONNECTION.key;
// fixme
// this.active = InnerTabs.NEW_CONNECTION.key;
this.active = undefined as unknown as string;
this.items = [InnerTabs.NEW_CONNECTION];
}
@@ -27,6 +29,8 @@ export default class TerminalTabManager implements ITerminalTabManager {
if (key === this.active && this.items.length !== 0) {
// 切换为前一个 tab
this.active = this.items[Math.max(tabIndex - 1, 0)].key;
} else {
this.active = undefined as unknown as string;
}
}

View File

@@ -12,7 +12,10 @@
</div>
<!-- 内容区域 -->
<div class="host-layout-content">
<terminal-content />
<!-- 主机加载中骨架 -->
<loading-skeleton v-if="contentLoading" />
<!-- 终端内容区域 -->
<terminal-content v-else />
</div>
<!-- 右侧操作栏 -->
<div class="host-layout-right">
@@ -36,12 +39,15 @@
import TerminalLeftSidebar from './components/layout/terminal-left-sidebar.vue';
import TerminalRightSidebar from './components/layout/terminal-right-sidebar.vue';
import TerminalContent from './components/layout/terminal-content.vue';
import LoadingSkeleton from './components/layout/loading-skeleton.vue';
import './assets/styles/layout.less';
import 'xterm/css/xterm.css';
import useLoading from '@/hooks/loading';
const terminalStore = useTerminalStore();
const dictStore = useDictStore();
const cacheStore = useCacheStore();
const { loading: contentLoading, setLoading: setContentLoading } = useLoading(true);
const originTitle = document.title;
const render = ref(false);
@@ -66,6 +72,16 @@
await dictStore.loadKeys([...dictKeys]);
});
// 加载主机信息
onMounted(async () => {
try {
await terminalStore.loadHosts();
} catch (e) {
} finally {
setContentLoading(false);
}
});
// 注册关闭视口事件
onMounted(() => {
// FIXME 开发阶段