<script setup lang="ts">
import { computed, Ref, ref, watch } from 'vue';
import { useLangStore } from '@/stores';
import ONav from '@/components/ONav.vue';
import OIcon from 'opendesign/icon/OIcon.vue';
import { useI18n } from 'vue-i18n';
import { showGuard, logout, getUserAuth, useStoreData } from '@/shared/login';
import communityLogoWhite from '@/assets/openeuler-logo.png';
import QuickIssueLogo from '@/assets/quickissue-logo.png';
import IconLogin from '~icons/app/icon-login.svg';
import IconLocale from '~icons/app/icon-locale.svg';
import OButton from 'opendesign/button/src/button';
import { atomgitUrl } from '@/config';
const { t, locale } = useI18n();
const lang = computed(() => {
return useLangStore().lang === 'zh' ? 'zh' : 'en';
});
const langText = computed(() => {
return lang.value === 'zh' ? '中' : 'En';
})
const { token } = getUserAuth();
const { guardAuthClient } = useStoreData();
const navList = computed(() => {
return [
{
id: '',
label: 'ISSUE',
link: `/${lang.value}/issues/`,
},
{
id: 'pulls',
label: 'PR',
link: `/${lang.value}/pulls/`,
},
];
});
const options = ref([
{ value: 'zh', label: '简体中文' },
{ value: 'en', label: 'English' },
]);
const handleCommand = (command: Ref): void => {
locale.value = command.value;
const { pathname } = window.location;
const newHref = pathname.split('/');
newHref[1] = command.value;
useLangStore().setLangStore(command.value);
window.location.href = newHref.join('/');
};
watch(
() => {
return locale.value as 'zh' | 'en';
},
(val) => {
useLangStore().setLangStore(val);
}
);
const protalUrl = computed(() => {
return `${import.meta.env.VITE_MAIN_DOMAIN_URL}/${lang.value}`;
});
const jumpToUserZone = () => {
window.open(`${protalUrl.value}/my`, '_black');
};
</script>
<template>
<header class="app-header">
<div class="wrap">
<div class="header-logo">
<img class="quickissue-logo" :src="QuickIssueLogo" alt="" />
<span class="line"></span>
<a target="_blank" rel="noopener noreferrer" :href="protalUrl"
><img class="community-logo" :src="communityLogoWhite"
/></a>
</div>
<div class="out-box">
<ONav :nav-items="navList"></ONav>
</div>
<div class="opt-user">
<div v-if="token">
<div class="opt-info">
<img
v-if="guardAuthClient.photo"
:src="guardAuthClient.photo"
class="opt-img"
/>
<div v-else class="opt-img"></div>
<p class="opt-name" :title="guardAuthClient?.username">
{{ guardAuthClient.username }}
</p>
</div>
<ul class="menu-list">
<li @click="jumpToUserZone()">{{ t('common.USER_CENTER') }}</li>
<li @click="logout()">{{ t('common.LOGOUT') }}</li>
</ul>
</div>
<div v-else class="login" @click="showGuard()">
<OIcon class="icon">
<IconLogin />
</OIcon>
</div>
</div>
<a
:href="`${atomgitUrl}/openeuler/infrastructure/blob/master/docs/quickIssue/quickissue_api.md`"
class="api-docs"
rel="noopener noreferrer"
target="_blank"
>
API
</a>
<div class="language">
<el-dropdown popper-class="language-change" @command="handleCommand" >
<span class="el-dropdown-link">
<OIcon><IconLocale></IconLocale></OIcon>
<span class="lang-text" :class="`lang-${lang}`">{{ langText }}</span>
</span>
<template #dropdown>
<el-dropdown-menu>
<el-dropdown-item
v-for="(item, key) in options"
:key="key"
:class="{ active: lang === item.value }"
:command="item"
:divided="key !== 0"
>
<div class="lang-item">{{ item.label }}</div>
</el-dropdown-item>
</el-dropdown-menu>
</template>
</el-dropdown>
</div>
<a :href="`/${lang}/new-issues/`" class="new-issue">
<OButton>{{ t('quickIssue.SUBMIT_ISSUE') }} </OButton>
</a>
</div>
</header>
</template>
<style lang="scss" scoped>
.app-header {
.wrap {
display: flex;
padding: 0 44px;
margin: 0 auto;
align-items: center;
max-width: 1504px;
height: 80px;
.new-issue {
flex-shrink: 0;
.o-button {
font-size: var(--o-font-size-h8);
color: var(--o-color-text2);
border: 1px solid #fff;
}
}
.out-box {
width: 100%;
height: 100%;
}
.language {
display: flex;
justify-content: flex-end;
margin-right: 40px;
text-align: right;
.el-dropdown {
color: var(--o-color-text2);
cursor: pointer;
.el-dropdown-link {
display: flex;
color: var(--o-color-text2);
position: relative;
.lang-text {
height: 24px;
width: 24px;
line-height: 24px;
font-size: 20px;
transform-origin: right bottom;
position: absolute;
transform: scale(0.5) ;
bottom: 2px;
right: -2px;
text-align: center;
background-color: #000;
&.lang-en {
width: 32px;
right: -4px;
}
}
.o-icon {
font-size: 24px;
}
}
}
}
.api-docs {
margin-right: 40px;
font-size: var(--o-font-size-h8);
color: #fff;
}
}
&.isabout {
background: #000;
}
}
.header-logo {
display: flex;
align-items: center;
font-weight: bold;
font-size: var(--o-font-size-h5);
line-height: var(--o-line-height-h5);
.line {
height: 24px;
background: #fff;
margin: 0 12px;
display: block;
width: 1px;
}
a {
display: flex;
align-items: center;
.community-logo {
height: 32px;
}
}
.quickissue-logo {
height: 32px;
}
}
.opt-user {
margin-right: 40px;
height: 100%;
display: flex;
align-items: center;
position: relative;
.opt-info {
display: flex;
align-items: center;
.opt-img {
width: 32px;
height: 32px;
border-radius: 50%;
cursor: pointer;
vertical-align: middle;
@media (max-width: 1100px) {
width: 28px;
height: 28px;
}
}
.opt-name {
color: var(--o-color-text2);
margin-left: 8px;
white-space: nowrap;
text-overflow: ellipsis;
overflow: hidden;
width: 72px;
line-height: var(--o-line-height-h8);
@media (max-width: 1100px) {
display: none;
}
}
}
&:hover {
.menu-list {
display: block;
}
}
.menu-list {
display: none;
position: absolute;
top: 60px;
left: 0;
@media (max-width: 1100px) {
top: 48px;
left: -60px;
}
background: var(--o-color-bg2);
cursor: pointer;
z-index: 999;
box-shadow: var(--o-shadow-l1);
min-width: 78px;
li {
line-height: var(--o-line-height-h3);
text-align: center;
font-size: var(--o-font-size-text);
color: var(--o-color-text1);
border-bottom: 1px solid var(--o-color-division1);
padding: 0 var(--o-spacing-h5);
white-space: nowrap;
&:last-child {
border-bottom: 0 none;
}
&:hover {
background: var(--o-color-brand1);
color: var(--o-color-text2);
}
&.active {
color: var(--o-color-brand1);
background: none;
cursor: default;
}
}
}
}
.login {
.icon {
font-size: 24px;
color: var(--o-color-text2);
cursor: pointer;
}
}
</style>