feat: 终端承载页.
This commit is contained in:
2
orion-ops-ui/components.d.ts
vendored
2
orion-ops-ui/components.d.ts
vendored
@@ -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 {}
|
||||
|
||||
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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 开发阶段
|
||||
|
||||
Reference in New Issue
Block a user