feat: 主机列表视图.
This commit is contained in:
@@ -199,7 +199,6 @@
|
||||
name: undefined,
|
||||
code: undefined,
|
||||
address: undefined,
|
||||
favorite: undefined,
|
||||
tags: undefined,
|
||||
queryTag: true
|
||||
});
|
||||
|
||||
@@ -49,18 +49,6 @@
|
||||
<!-- 右侧操作 -->
|
||||
<div class="table-right-bar-handle">
|
||||
<a-space>
|
||||
<!-- 仅看收藏 fixme 去掉 -->
|
||||
<a-checkbox v-if="false" v-model="formModel.favorite" @change="fetchTableData()">
|
||||
<template #checkbox="{ checked }">
|
||||
<a-tag :checked="checked"
|
||||
class="only-favorite"
|
||||
size="large"
|
||||
color="arcoblue"
|
||||
checkable>
|
||||
仅看收藏
|
||||
</a-tag>
|
||||
</template>
|
||||
</a-checkbox>
|
||||
<!-- 主机分组 -->
|
||||
<a-button type="primary"
|
||||
v-permission="['asset:host-group:update']"
|
||||
@@ -162,19 +150,6 @@
|
||||
删除
|
||||
</a-button>
|
||||
</a-popconfirm>
|
||||
<!-- 收藏 -->
|
||||
<span v-if="record.favorite"
|
||||
title="取消收藏"
|
||||
class="host-favorite host-favorite-choice"
|
||||
@click="() => toggleFavorite(record, record.id)">
|
||||
<icon-star-fill />
|
||||
</span>
|
||||
<span v-else
|
||||
title="收藏"
|
||||
class="host-favorite host-favorite-un-choice"
|
||||
@click="() => toggleFavorite(record, record.id)">
|
||||
<icon-star />
|
||||
</span>
|
||||
</div>
|
||||
</template>
|
||||
</a-table>
|
||||
@@ -197,7 +172,6 @@
|
||||
import { tagColor } from '../types/const';
|
||||
import { usePagination } from '@/types/table';
|
||||
import useCopy from '@/hooks/copy';
|
||||
import useFavorite from '@/hooks/favorite';
|
||||
import { dataColor } from '@/utils';
|
||||
import TagMultiSelector from '@/components/meta/tag/tag-multi-selector.vue';
|
||||
import { GrantKey, GrantRouteName } from '@/views/asset/grant/types/const';
|
||||
@@ -208,7 +182,6 @@
|
||||
const emits = defineEmits(['openAdd', 'openUpdate', 'openUpdateConfig', 'openHostGroup']);
|
||||
|
||||
const { copy } = useCopy();
|
||||
const { toggle: toggleFavorite } = useFavorite('HOST');
|
||||
|
||||
const pagination = usePagination();
|
||||
|
||||
@@ -217,7 +190,6 @@
|
||||
name: undefined,
|
||||
code: undefined,
|
||||
address: undefined,
|
||||
favorite: undefined,
|
||||
tags: undefined,
|
||||
queryTag: true
|
||||
});
|
||||
@@ -284,37 +256,5 @@
|
||||
.row-handle-wrapper {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
.host-favorite {
|
||||
cursor: pointer;
|
||||
line-height: 19px;
|
||||
font-size: 19px;
|
||||
margin: 0 4px;
|
||||
}
|
||||
|
||||
.host-favorite-choice {
|
||||
color: rgb(var(--yellow-6));
|
||||
|
||||
:hover {
|
||||
transition: .2s;
|
||||
color: rgba(232, 203, 12, .9);
|
||||
}
|
||||
}
|
||||
|
||||
.host-favorite-un-choice {
|
||||
color: rgb(var(--gray-6));
|
||||
|
||||
:hover {
|
||||
transition: .2s;
|
||||
color: rgb(var(--yellow-6));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.only-favorite {
|
||||
user-select: none;
|
||||
color: rgb(var(--arcoblue-5));
|
||||
background: rgb(var(--gray-2));
|
||||
}
|
||||
|
||||
</style>
|
||||
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
|
||||
@@ -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();
|
||||
|
||||
Reference in New Issue
Block a user