feat: 主机列表视图.

This commit is contained in:
lijiahang
2023-12-15 16:35:11 +08:00
parent 0cd8b3ae02
commit 59c8a7fd2f
14 changed files with 270 additions and 116 deletions

View File

@@ -0,0 +1,31 @@
<template>
<div class="list-view-container">
<!-- 主机列表 -->
<host-list :hosts="hosts" />
</div>
</template>
<script lang="ts">
export default {
name: 'hostListView'
};
</script>
<script lang="ts" setup>
import type { AuthorizedHostQueryResponse } from '@/api/asset/asset-authorized-data';
import HostList from './host-list.vue';
const props = defineProps<{
hosts: AuthorizedHostQueryResponse
}>();
</script>
<style lang="less" scoped>
.list-view-container {
max-height: 100%;
width: 100%;
overflow: auto;
position: relative;
}
</style>

View File

@@ -1,5 +1,6 @@
<template>
<a-list size="large"
<a-list ref="listRel"
size="large"
max-height="100%"
:hoverable="true"
:data="hosts.hostList">
@@ -14,7 +15,7 @@
</template>
<!-- 数据 -->
<template #item="{ item }">
<a-list-item class="host-item-wrapper">
<a-list-item class="host-item-wrapper" @click="openTerminal(item)">
<div class="host-item">
<!-- 左侧图标-名称 -->
<div class="flex-center host-item-left">
@@ -46,24 +47,65 @@
</span>
</a-tooltip>
</div>
<!-- flex-center 右侧tag-操作 -->
<!-- 右侧tag-操作 -->
<div class="flex-center host-item-right">
<div v-if="item.code === 'main'">
<a-tag v-for="i in 5"
class="host-item-text"
:style="{
width: `calc(${100/5}% - ${i !== 5 ? '8px' : '0px'})`,
maxWidth: `calc(${100/5}% - ${i !== 5 ? '8px' : '0px'})`,
marginRight: `${i !== 5 ? '8px' : '0'}`,
}"
color="arcoblue">
<template v-for="j in i*5">
{{ j }}
</template>
</a-tag>
<!-- tags -->
<div class="host-item-right-tags">
<template v-if="item.tags?.length">
<a-tag v-for="(tag, i) in item.tags"
class="host-item-text"
:key="tag.id"
:style="{
maxWidth: `calc(${100 / item.tags.length}% - ${i !== item.tags.length - 1 ? '8px' : '0px'})`,
marginRight: `${i !== item.tags.length - 1 ? '8px' : '0'}`,
}"
:color="dataColor(tag.name, tagColor)">
{{ tag.name }}
</a-tag>
</template>
</div>
<div v-else>
<!-- 操作 -->
<div class="host-item-right-actions">
<!-- 连接主机 -->
<a-tooltip position="top"
:mini="true"
:popup-container="listRel?.$el?.parent"
content-class="terminal-tooltip-content"
arrow-class="terminal-tooltip-content"
content="连接主机">
<div class="terminal-sidebar-icon-wrapper">
<div class="terminal-sidebar-icon" @click.stop="openTerminal(item)">
<icon-thunderbolt />
</div>
</div>
</a-tooltip>
<!-- 连接设置 -->
<a-tooltip position="top"
:mini="true"
:popup-container="listRel?.$el?.parent"
content-class="terminal-tooltip-content"
arrow-class="terminal-tooltip-content"
content="连接设置">
<div class="terminal-sidebar-icon-wrapper">
<div class="terminal-sidebar-icon" @click.stop="openSetting(item)">
<icon-settings />
</div>
</div>
</a-tooltip>
<!-- 收藏 -->
<a-tooltip position="top"
:mini="true"
:popup-container="listRel?.$el?.parent"
content-class="terminal-tooltip-content"
arrow-class="terminal-tooltip-content"
content="收藏">
<div class="terminal-sidebar-icon-wrapper">
<div class="terminal-sidebar-icon" @click.stop="setFavorite(item)">
<icon-star-fill class="favorite" v-if="item.favorite" />
<icon-star v-else />
</div>
</div>
</a-tooltip>
</div>
</div>
</div>
@@ -80,11 +122,37 @@
<script lang="ts" setup>
import { AuthorizedHostQueryResponse } from '@/api/asset/asset-authorized-data';
import useFavorite from '@/hooks/favorite';
import { ref } from 'vue';
import { dataColor } from '@/utils';
import { tagColor } from '@/views/asset/host-list/types/const';
const props = defineProps<{
hosts: AuthorizedHostQueryResponse
}>();
const { toggle: toggleFavorite, loading: favoriteLoading } = useFavorite('HOST');
const listRel = ref();
// 打开终端
const openTerminal = (item: any) => {
console.log('ter', item);
};
// 打开配置
const openSetting = (item: any) => {
console.log('set', item);
};
// 设置收藏
const setFavorite = async (item: any) => {
if (favoriteLoading.value) {
return;
}
await toggleFavorite(item, item.id);
};
</script>
<style lang="less" scoped>
@@ -160,13 +228,44 @@
width: 25%;
&-address {
max-width: calc(100% - 8px);
max-width: 100%;
}
}
.host-item-right {
width: 40%;
height: 100%;
flex-direction: column;
justify-content: center;
position: relative;
&-tags {
// 必须设置 最外层用的是 min-width
position: absolute;
width: 100%;
}
&-actions {
position: absolute;
display: none;
width: 100%;
justify-content: flex-end;
}
}
&:hover {
.host-item-right-tags {
display: none;
}
.host-item-right-actions {
display: flex;
}
}
}
.favorite {
color: rgb(var(--yellow-6));
}
</style>

View File

@@ -48,6 +48,8 @@
<host-group-view v-if="NewConnectionType.GROUP === newConnectionType"
:hosts="hosts" />
<!-- 列表视图 -->
<host-list-view v-if="NewConnectionType.LIST === newConnectionType"
:hosts="hosts" />
<!-- 我的收藏 -->
@@ -72,8 +74,9 @@
import { onBeforeMount, ref } from 'vue';
import { NewConnectionType, NewConnectionTypeKey } from '../../types/terminal.const';
import useLoading from '@/hooks/loading';
import HostGroupView from './host-group-view.vue';
import { useDictStore } from '@/store';
import HostGroupView from './host-group-view.vue';
import HostListView from './host-list-view.vue';
const { loading, setLoading } = useLoading();
const { toOptions } = useDictStore();