<template>
<div
id="leftNavCollapse"
:class="[isCollapse ? 'close-state' : 'title-box', marginRight ? 'left-nav-margin-right' : '']"
>
<div class="nav-logo">
<img :src="logoImg" @error="getDefaultLogo" />
</div>
<el-menu
ref="menu"
class="el-menu-vertical"
:default-active="currentRouter"
:collapse="isCollapse"
:router="true"
:collapse-transition="false"
unique-opened="true"
>
<template v-for="item in mainMenus" :key="item.id">
<el-menu-item v-if="item.children.length === 0" :index="item.router">
<el-icon>
<span :id="item.id" class="icon-nav"></span>
</el-icon>
<template #title>
{{ $t(item.label, { smsName: productLabel, softwareName: productLabel }) }}
</template>
</el-menu-item>
<el-sub-menu v-else :index="item.router" popper-class="left-nav-popper">
<template #title>
<el-icon>
<span :id="item.id" class="icon-nav"></span>
</el-icon>
<span v-if="!isCollapse">
{{ $t(item.label, { smsName: productLabel, softwareName: productLabel }) }}
</span>
</template>
<el-menu-item-group>
<template v-for="child in item.children" :key="child.id">
<el-menu-item v-if="!child.hide" :index="child.router">
{{ $t(child.label, { smsName: productLabel, softwareName: productLabel }) }}
</el-menu-item>
</template>
</el-menu-item-group>
</el-sub-menu>
</template>
</el-menu>
<div class="control">
<div
v-show="isCollapse"
id="changeCollapseOpen"
class="change-collapse-btn"
@click="chengeCollapse"
>
<img
class="img"
src="@/assets/common/image/open.svg"
:title="$t('SERVICE_WBS_CRE_SHOW_MORE')"
/>
</div>
<div
v-show="!isCollapse"
id="changeCollapseClose"
class="change-collapse-btn"
@click="chengeCollapse"
>
<img
class="img"
src="@/assets/common/image/close.svg"
:title="$t('SERVICE_WBS_CRE_HIDE_MORE')"
/>
</div>
</div>
</div>
</template>
<script lang="ts" setup>
import { getLogoImage } from '@/utils/common-service';
import { nextTick, onMounted, ref } from 'vue';
import { useRoute, useRouter } from 'vue-router';
import useStore from '@/stores';
const store = useStore();
const mainMenus = store.state.menu.mainMenu;
const productLabel = useStore().state.loct.sn;
const $router = useRouter();
const $route = useRoute();
const marginRight = ref(false);
const isCollapse = ref(false);
const currentRouter = ref('/navigate/home');
const emits = defineEmits(['collapseChange']);
const chengeCollapse = () => {
isCollapse.value = !isCollapse.value;
emits('collapseChange', [isCollapse.value, marginRight.value]);
nextTick(() => {
setIcon();
});
};
resetLeftMenuType($route.fullPath);
$router.afterEach((to, from) => {
resetLeftMenuType(to.fullPath);
});
const logoImg = ref('');
logoImg.value = getLogoImage('home');
function getDefaultLogo() {
logoImg.value = '/image/ibmc.png';
}
function resetLeftMenuType(curRoute: string) {
marginRight.value = curRoute === '/navigate/home';
emits('collapseChange', [isCollapse.value, marginRight.value]);
if (curRoute.includes('/report/')) {
return;
} else if (curRoute.includes('/info/')) {
return;
} else if (curRoute.includes('/power/')) {
return;
} else if (curRoute.includes('/biosConfig/')) {
return;
} else if (curRoute.includes('/ibmclog/')) {
return;
} else if (curRoute.includes('/two-factor/')) {
return;
} else if (curRoute.includes('/security/')) {
return;
} else {
currentRouter.value = curRoute;
}
}
function setIcon() {
const svg = `<svg width="16px" height="16px" viewBox="0 0 16 16" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>65E3DA35-77AD-4F3F-BB39-E00A621C813C_0</title>
<defs>
<polygon id="path-1" points="12 6 8 10 4 6"></polygon>
</defs>
<g id="" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="" transform="translate(-224.000000, -425.000000)">
<g id="" transform="translate(8.000000, 57.000000)">
<g id="" transform="translate(0.000000, 360.000000)">
<g id="" transform="translate(216.000000, 8.000000)">
<mask id="mask-2" fill="white">
<use xlink:href="#path-1"></use>
</mask>
<use id="" fill="#FFFFFF" xlink:href="#path-1"></use>
<g mask="url(#mask-2)" fill="#8D98AA" id="svgFillColor">
<g>
<rect x="0" y="0" width="16" height="16"></rect>
</g>
</g>
</g>
</g>
</g>
</g>
</g>
</svg>`;
const svgs = document.querySelectorAll('.el-sub-menu__icon-arrow');
svgs.forEach(item => {
item.innerHTML = svg;
});
}
onMounted(() => {
setIcon();
});
</script>
<style lang="scss" scoped>
.nav-logo {
float: left;
display: flex;
align-items: center;
height: 52px;
font-weight: 600;
font-size: 16px;
width: 100%;
border-bottom: 1px solid var(--o-border-color-light);
margin-bottom: 8px;
padding-left: 24px;
img {
max-width: 100%;
max-height: 16px;
}
}
.el-menu-vertical {
width: 100%;
height: calc(100% - 49px);
overflow: auto;
}
@font-face {
font-family: 'icon';
src: url('./fonts/icon.eot?fsbm93');
src:
url('./fonts/icon.eot?fsbm93#iefix') format('embedded-opentype'),
url('./fonts/icon.ttf?fsbm93') format('truetype'),
url('./fonts/icon.woff?fsbm93') format('woff'),
url('./fonts/icon.svg?fsbm93#icon') format('svg');
font-weight: normal;
font-style: normal;
font-display: block;
}
[class^='icon-'],
[class*=' icon-'] {
font-family: 'icon' !important;
font-style: normal;
font-weight: normal;
font-variant: normal;
text-transform: none;
line-height: 1;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
color: var(--o-text-color-tertiary);
font-size: 16px;
}
#navHome:before {
content: '\e900';
}
#navSystemManager:before {
content: '\e903';
}
#navMaintance:before {
content: '\e901';
}
#navUsersManager:before {
content: '\e902';
}
#navServiceManager:before {
content: '\e905';
}
#navIbmcManager:before {
content: '\e904';
}
#leftNavCollapse {
height: 100vh;
background-color: var(--o-bg-color-base);
box-shadow: 0 2px 10px 4px rgba(0, 0, 0, 0.05);
display: flex;
flex-direction: column;
justify-content: space-between;
width: 256px;
flex-shrink: 0;
z-index: 1001;
position: fixed;
top: 0;
left: 0;
&.close-state {
width: 64px;
}
.control {
border-top: 1px solid var(--o-border-color-light);
width: 100%;
height: 49px;
line-height: 48px;
padding-left: 8px;
}
.el-menu {
border-right: none;
width: 100%;
padding: 0 8px;
background-color: var(--o-bg-color-base);
.el-menu-item {
height: 32px;
border-radius: var(--o-border-radius);
font-size: 14px;
padding: 0 16px !important;
color: var(--o-text-color-secondary);
&.is-active {
color: var(--o-text-color-fourth);
background-color: var(--o-color-primary);
span {
color: var(--o-text-color-fourth);
}
}
}
}
.el-sub-menu {
margin-top: 8px;
&.is-active {
.el-sub-menu__title {
color: var(--o-text-color-primary);
}
}
.el-menu--inline {
.el-menu-item {
margin-bottom: 8px;
padding: 0 40px !important;
color: var(--o-text-color-secondary);
&:not(.is-active):hover {
background-color: var(--o-bg-color-light);
}
&.is-active {
color: var(--o-text-color-fourth);
}
}
}
}
:deep(.el-sub-menu__title) {
height: 32px;
border-radius: var(--o-border-radius);
line-height: 32px;
color: var(--o-text-color-secondary);
padding: 0 16px !important;
}
:deep(.el-menu-item-group__title) {
display: none;
}
:deep(.el-sub-menu.is-active .el-sub-menu__title) {
color: var(--o-text-color-primary);
}
}
.close-state {
.nav-logo {
padding-left: 11px;
}
:deep(.el-sub-menu__title) {
justify-content: center;
}
:deep(.el-tooltip__trigger) {
padding: 0 !important;
}
:deep(.is-active .el-tooltip__trigger) {
color: var(--o-text-color-fourth);
border-radius: var(--o-border-radius);
}
:deep(.is-active .el-tooltip__trigger:hover) {
color: var(--o-text-color-fourth);
background-color: var(--o-color-primary);
}
:deep(.el-tooltip__trigger i) {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
.el-sub-menu.is-active {
color: var(--o-text-color-fourth);
background-color: var(--o-color-primary);
border-radius: var(--o-border-radius);
}
}
.left-nav-popper .el-menu--popup {
box-shadow: none;
}
.change-collapse-btn {
display: inline-block;
width: 48px;
height: 32px;
display: flex;
justify-content: center;
align-items: center;
border-radius: var(--o-border-radius);
margin-top: 8px;
&:hover {
background-color: var(--o-bg-color-light);
cursor: pointer;
}
}
</style>
<style lang="scss">
#leftNavCollapse {
.el-menu--collapse {
.el-sub-menu {
&:hover {
background-color: var(--o-bg-color-light);
}
.el-tooltip__trigger {
&:hover {
background-color: var(--o-bg-color-light);
}
}
&.is-active {
background-color: var(--o-color-primary);
.el-tooltip__trigger {
background-color: var(--o-color-primary);
&:hover {
background-color: var(--o-color-primary);
}
[class^='icon-'] {
color: var(--o-color-white);
}
}
}
&.is-opened {
background-color: var(--o-bg-color-light);
}
}
.el-menu-item:hover {
background-color: var(--o-bg-color-light);
}
}
.el-sub-menu {
.el-sub-menu__icon-arrow {
font-size: 16px;
right: 8px;
}
&.is-active {
svg g {
fill: var(--o-text-color-primary);
}
.el-sub-menu__title {
font-weight: bold;
margin-bottom: 8px;
color: var(--o-text-color-primary);
}
}
.el-sub-menu__title:hover {
background-color: var(--o-bg-color-light);
}
& > .el-menu-item.is-active {
font-weight: bold;
}
.el-icon {
width: auto;
margin-right: 8px;
}
.el-menu {
background-color: var(--o-bg-color-base);
}
}
.el-menu {
& > .el-menu-item {
.el-icon {
width: auto;
margin-right: 8px;
}
&:hover {
background-color: var(--o-bg-color-light);
}
}
}
}
.left-nav-popper.el-popper {
margin-left: 8px !important;
background: var(--o-bg-color-base);
border: none;
width: 256px;
.el-menu--popup {
box-shadow: none;
padding: 0;
background-color: var(--o-bg-color-base);
.el-menu-item-group {
padding: 8px 8px 0 8px;
}
.el-menu-item-group__title {
display: none;
}
.el-menu-item {
height: 32px;
margin-bottom: 8px;
border-radius: var(--o-border-radius);
padding: 0 16px !important;
color: var(--o-text-color-secondary);
&.is-active {
color: var(--o-text-color-fourth);
background-color: var(--o-color-primary);
}
&:hover {
background-color: var(--o-bg-color-light);
}
}
}
}
</style>