119 lines
2.8 KiB
Vue
119 lines
2.8 KiB
Vue
<script setup lang="ts">
|
||
import { useRouter } from 'vue-router';
|
||
|
||
type LinkItem = {
|
||
title: string;
|
||
icon: string;
|
||
to: { name: string };
|
||
disabled?: boolean;
|
||
};
|
||
|
||
type BlockItem = {
|
||
id: string;
|
||
title: string;
|
||
list: any[];
|
||
avatarRound: boolean;
|
||
link: {
|
||
to: {
|
||
name: string;
|
||
params: {
|
||
namespace?: string;
|
||
};
|
||
};
|
||
};
|
||
};
|
||
|
||
defineProps<{
|
||
linkList: LinkItem[];
|
||
blockList: BlockItem[];
|
||
}>();
|
||
|
||
const emit = defineEmits<{(event: 'handleToggle', value: boolean): void;
|
||
}>();
|
||
|
||
const router = useRouter();
|
||
// repo\org切换,强制页面重载
|
||
const handleLinkClick = (event, data) => {
|
||
const href = router.resolve(data.to).fullPath;
|
||
window.open(href, '_self');
|
||
emit('handleToggle', false);
|
||
|
||
event?.stopPropagation();
|
||
};
|
||
</script>
|
||
|
||
<template>
|
||
<div class="g-entrance-menu">
|
||
<div class="g-entrance-menu-links">
|
||
<OptionLink v-for="item in linkList" :key="item.title" v-bind="item">
|
||
<GIcon :name="item.icon" />{{ item.title }}
|
||
</OptionLink>
|
||
</div>
|
||
<div class="g-entrance-menu-block" v-for="block in blockList" :key="block.id">
|
||
<div class="g-entrance-menu-block-title">
|
||
<span>{{ block.title }}</span>
|
||
<GLink v-bind="block.link">
|
||
<GIcon name="gt-more-operate" />
|
||
</GLink>
|
||
</div>
|
||
<div class="g-entrance-menu-block-list">
|
||
<DataPanel :loading="block.loading" :empty="!block.list?.length" :card="false" skeleton>
|
||
<OptionLink
|
||
v-for="item in block.list"
|
||
:key="item.name"
|
||
v-bind="item"
|
||
@click="handleLinkClick($event, item)"
|
||
>
|
||
<GAvatar
|
||
:src="item.avatar"
|
||
:name="item.avatarText"
|
||
:width="16"
|
||
:height="16"
|
||
:is_round="block.avatarRound"
|
||
></GAvatar>
|
||
<d-tooltip :content="item.label" position="right" :mouse-enter-delay="800">
|
||
<div class="ellipsis">{{ item.label }}</div>
|
||
</d-tooltip>
|
||
</OptionLink>
|
||
<template #empty>
|
||
<div class="py-2 flex-center opacity-50">暂无数据</div>
|
||
</template>
|
||
<template #loading>
|
||
<d-skeleton :rows="5" />
|
||
</template>
|
||
</DataPanel>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</template>
|
||
|
||
<style scoped lang="scss">
|
||
@import 'devui-theme/styles-var/devui-var.scss';
|
||
|
||
.g-entrance-menu {
|
||
&-links {
|
||
display: flex;
|
||
flex-direction: column;
|
||
}
|
||
&-block {
|
||
display: flex;
|
||
flex-direction: column;
|
||
border-top: 1px solid var(--color-border-light);
|
||
margin-top: 16px;
|
||
&:last-child {
|
||
padding-bottom: 0;
|
||
}
|
||
&-title {
|
||
display: flex;
|
||
justify-content: space-between;
|
||
align-items: center;
|
||
font-size: 14px;
|
||
font-weight: 500;
|
||
color: #2d2d2e;
|
||
line-height: 32px;
|
||
margin-top: 8px;
|
||
}
|
||
}
|
||
}
|
||
</style>
|