| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346 |
- <template>
- <div class="navbar" :style="{ width: currentWidth }">
- <div class="left-side">
- <a-button
- type="text"
- :style="{
- padding: '0 7px',
- height: '25px',
- lineHeight: '25px',
- color: 'var(--color-text-3)',
- }"
- @click="toggleCollapse"
- >
- <icon-menu-unfold v-if="collapsed" />
- <icon-menu-fold v-else />
- </a-button>
- </div>
- <GlobalBreadcrumb v-show="!topMenu" />
- <div class="center-side">
- <Menu v-if="topMenu" />
- </div>
- <ul class="right-side">
- <li>
- <a-tooltip :content="$t('settings.search')">
- <a-button class="nav-btn" type="outline" :shape="'circle'">
- <template #icon>
- <icon-search />
- </template>
- </a-button>
- </a-tooltip>
- </li>
- <li>
- <a-tooltip :content="$t('settings.language')">
- <a-button
- class="nav-btn"
- type="outline"
- :shape="'circle'"
- @click="setDropDownVisible"
- >
- <template #icon>
- <icon-language />
- </template>
- </a-button>
- </a-tooltip>
- <a-dropdown trigger="click" @select="changeLocale as any">
- <div ref="triggerBtn" class="trigger-btn"></div>
- <template #content>
- <a-doption
- v-for="item in locales"
- :key="item.value"
- :value="item.value"
- >
- <template #icon>
- <icon-check v-show="item.value === currentLocale" />
- </template>
- {{ item.label }}
- </a-doption>
- </template>
- </a-dropdown>
- </li>
- <li>
- <a-tooltip
- :content="
- theme === 'light'
- ? $t('settings.navbar.theme.toDark')
- : $t('settings.navbar.theme.toLight')
- "
- >
- <a-button
- class="nav-btn"
- type="outline"
- :shape="'circle'"
- @click="handleToggleTheme"
- >
- <template #icon>
- <icon-moon-fill v-if="theme === 'dark'" />
- <icon-sun-fill v-else />
- </template>
- </a-button>
- </a-tooltip>
- </li>
- <li>
- <a-tooltip :content="$t('settings.navbar.alerts')">
- <div class="message-box-trigger">
- <a-badge :count="9" dot>
- <a-button
- class="nav-btn"
- type="outline"
- :shape="'circle'"
- @click="setPopoverVisible"
- >
- <icon-notification />
- </a-button>
- </a-badge>
- </div>
- </a-tooltip>
- <a-popover
- trigger="click"
- :arrow-style="{ display: 'none' }"
- :content-style="{ padding: 0, minWidth: '400px' }"
- content-class="message-popover"
- >
- <div ref="refBtn" class="ref-btn"></div>
- <template #content>
- <message-box />
- </template>
- </a-popover>
- </li>
- <li>
- <a-tooltip
- :content="
- isFullscreen
- ? $t('settings.navbar.screen.toExit')
- : $t('settings.navbar.screen.toFull')
- "
- >
- <a-button
- class="nav-btn"
- type="outline"
- :shape="'circle'"
- @click="toggleFullScreen"
- >
- <template #icon>
- <icon-fullscreen-exit v-if="isFullscreen" />
- <icon-fullscreen v-else />
- </template>
- </a-button>
- </a-tooltip>
- </li>
- <li>
- <a-tooltip :content="$t('settings.title')">
- <a-button
- class="nav-btn"
- type="outline"
- :shape="'circle'"
- @click="setVisible"
- >
- <template #icon>
- <icon-settings />
- </template>
- </a-button>
- </a-tooltip>
- </li>
- <li>
- <a-dropdown trigger="click">
- <a-avatar
- :size="32"
- :style="{ marginRight: '8px', cursor: 'pointer' }"
- >
- <img alt="avatar" :src="avatar" />
- </a-avatar>
- <template #content>
- <a-doption>
- <a-space @click="switchRoles">
- <icon-tag />
- <span>
- {{ $t('messageBox.switchRoles') }}
- </span>
- </a-space>
- </a-doption>
- <a-doption>
- <a-space @click="$router.push({ name: 'Info' })">
- <icon-user />
- <span>
- {{ $t('messageBox.userCenter') }}
- </span>
- </a-space>
- </a-doption>
- <a-doption>
- <a-space @click="$router.push({ name: 'Setting' })">
- <icon-settings />
- <span>
- {{ $t('messageBox.userSettings') }}
- </span>
- </a-space>
- </a-doption>
- <a-doption>
- <a-space @click="handleLogout">
- <icon-export />
- <span>
- {{ $t('messageBox.logout') }}
- </span>
- </a-space>
- </a-doption>
- </template>
- </a-dropdown>
- </li>
- </ul>
- </div>
- </template>
- <script name="NavBar" lang="ts" setup>
- import { computed, ref } from 'vue';
- import { Message } from '@arco-design/web-vue';
- import { useDark, useToggle, useFullscreen } from '@vueuse/core';
- import { useAppStore, useUserStore } from '@/store';
- import { LOCALE_OPTIONS } from '@/locale';
- import useLocale from '@/hooks/locale';
- import useUser from '@/hooks/user';
- import Menu from '@/components/menu/index.vue';
- import MessageBox from '../message-box/index.vue';
- import GlobalBreadcrumb from '../global-breadcrumb/index.vue';
- const appStore = useAppStore();
- const userStore = useUserStore();
- const { logout } = useUser();
- const { changeLocale, currentLocale } = useLocale();
- const { isFullscreen, toggle: toggleFullScreen } = useFullscreen();
- const locales = [...LOCALE_OPTIONS];
- const avatar = computed(() => {
- return userStore.avatar;
- });
- const theme = computed(() => {
- return appStore.theme;
- });
- const topMenu = computed(() => appStore.topMenu && appStore.menu);
- const collapsed = computed(() => {
- return appStore.menuCollapse;
- });
- const menuWidth = computed(() => {
- return appStore.menuWidth;
- });
- const currentWidth = computed(() => {
- let width = menuWidth.value - 12;
- return collapsed.value ? 'calc(100% - 38px)' : `calc(100% - ${width}px)`;
- });
- const isDark = useDark({
- selector: 'body',
- attribute: 'arco-theme',
- valueDark: 'dark',
- valueLight: 'light',
- storageKey: 'arco-theme',
- onChanged(dark: boolean) {
- // overridden default behavior
- appStore.toggleTheme(dark);
- },
- });
- const toggleTheme = useToggle(isDark);
- const handleToggleTheme = () => {
- toggleTheme();
- };
- const setVisible = () => {
- appStore.updateSettings({ globalSettings: true });
- };
- const refBtn = ref();
- const triggerBtn = ref();
- const setPopoverVisible = () => {
- const event = new MouseEvent('click', {
- view: window,
- bubbles: true,
- cancelable: true,
- });
- refBtn.value.dispatchEvent(event);
- };
- const handleLogout = () => {
- logout();
- };
- const setDropDownVisible = () => {
- const event = new MouseEvent('click', {
- view: window,
- bubbles: true,
- cancelable: true,
- });
- triggerBtn.value.dispatchEvent(event);
- };
- const switchRoles = async () => {
- const res = await userStore.switchRoles();
- Message.success(res as string);
- };
- const setCollapse = (val: boolean) => {
- if (appStore.device === 'desktop')
- appStore.updateSettings({ menuCollapse: val });
- };
- const toggleCollapse = () => {
- setCollapse(!collapsed.value);
- // toggleWidth(collapsed.value);
- };
- </script>
- <style scoped lang="less">
- .navbar {
- display: flex;
- justify-content: space-between;
- justify-self: end;
- height: 100%;
- background-color: var(--color-bg-2);
- border-bottom: 1px solid var(--color-border);
- }
- .left-side {
- display: flex;
- align-items: center;
- padding-left: 20px;
- }
- .center-side {
- flex: 1;
- }
- .right-side {
- display: flex;
- padding-right: 20px;
- list-style: none;
- :deep(.locale-select) {
- border-radius: 20px;
- }
- li {
- display: flex;
- align-items: center;
- padding: 0 10px;
- }
- a {
- color: var(--color-text-1);
- text-decoration: none;
- }
- .nav-btn {
- color: rgb(var(--gray-8));
- font-size: 16px;
- border-color: rgb(var(--gray-2));
- }
- .trigger-btn,
- .ref-btn {
- position: absolute;
- bottom: 14px;
- }
- .trigger-btn {
- margin-left: 14px;
- }
- }
- </style>
- <style lang="less">
- .message-popover {
- .arco-popover-content {
- margin-top: 0;
- }
- }
- </style>
|