feat: restore original admin shell quality
This commit is contained in:
@@ -1,11 +1,20 @@
|
||||
<script lang="ts" setup>
|
||||
import { computed, defineAsyncComponent, useSlots } from 'vue';
|
||||
import { computed, useSlots } from 'vue';
|
||||
|
||||
import { preferences } from '@vben/preferences';
|
||||
import { useRefresh } from '@vben/hooks';
|
||||
import { RotateCw } from '@vben/icons';
|
||||
import { preferences, usePreferences } from '@vben/preferences';
|
||||
import { useAccessStore } from '@vben/stores';
|
||||
|
||||
const ThemeToggle = defineAsyncComponent(
|
||||
() => import('../../widgets/theme-toggle/theme-toggle.vue'),
|
||||
);
|
||||
import { VbenFullScreen, VbenIconButton } from '@vben-core/shadcn-ui';
|
||||
|
||||
import {
|
||||
GlobalSearch,
|
||||
LanguageToggle,
|
||||
PreferencesButton,
|
||||
ThemeToggle,
|
||||
TimezoneButton,
|
||||
} from '../../widgets';
|
||||
|
||||
interface Props {
|
||||
/**
|
||||
@@ -22,19 +31,55 @@ withDefaults(defineProps<Props>(), {
|
||||
theme: 'light',
|
||||
});
|
||||
|
||||
const emit = defineEmits<{ clearPreferencesAndLogout: [] }>();
|
||||
|
||||
const REFERENCE_VALUE = 50;
|
||||
|
||||
const accessStore = useAccessStore();
|
||||
const slots = useSlots();
|
||||
const { refresh } = useRefresh();
|
||||
const { globalSearchShortcutKey, preferencesButtonPosition } =
|
||||
usePreferences();
|
||||
|
||||
const rightSlots = computed(() => {
|
||||
const list = [{ index: REFERENCE_VALUE + 100, name: 'user-dropdown' }];
|
||||
|
||||
if (preferences.widget.globalSearch) {
|
||||
list.push({
|
||||
index: REFERENCE_VALUE,
|
||||
name: 'global-search',
|
||||
});
|
||||
}
|
||||
if (preferencesButtonPosition.value.header) {
|
||||
list.push({
|
||||
index: REFERENCE_VALUE + 10,
|
||||
name: 'preferences',
|
||||
});
|
||||
}
|
||||
if (preferences.widget.themeToggle) {
|
||||
list.push({
|
||||
index: REFERENCE_VALUE + 20,
|
||||
name: 'theme-toggle',
|
||||
});
|
||||
}
|
||||
if (preferences.widget.languageToggle) {
|
||||
list.push({
|
||||
index: REFERENCE_VALUE + 30,
|
||||
name: 'language-toggle',
|
||||
});
|
||||
}
|
||||
if (preferences.widget.timezone) {
|
||||
list.push({
|
||||
index: REFERENCE_VALUE + 40,
|
||||
name: 'timezone',
|
||||
});
|
||||
}
|
||||
if (preferences.widget.fullscreen) {
|
||||
list.push({
|
||||
index: REFERENCE_VALUE + 50,
|
||||
name: 'fullscreen',
|
||||
});
|
||||
}
|
||||
if (preferences.widget.notification) {
|
||||
list.push({
|
||||
index: REFERENCE_VALUE + 60,
|
||||
@@ -54,6 +99,13 @@ const rightSlots = computed(() => {
|
||||
const leftSlots = computed(() => {
|
||||
const list: Array<{ index: number; name: string }> = [];
|
||||
|
||||
if (preferences.widget.refresh) {
|
||||
list.push({
|
||||
index: 0,
|
||||
name: 'refresh',
|
||||
});
|
||||
}
|
||||
|
||||
Object.keys(slots).forEach((key) => {
|
||||
const name = key.split('-');
|
||||
if (key.startsWith('header-left')) {
|
||||
@@ -63,6 +115,9 @@ const leftSlots = computed(() => {
|
||||
return list.sort((a, b) => a.index - b.index);
|
||||
});
|
||||
|
||||
function clearPreferencesAndLogout() {
|
||||
emit('clearPreferencesAndLogout');
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
@@ -71,6 +126,11 @@ const leftSlots = computed(() => {
|
||||
:key="slot.name"
|
||||
>
|
||||
<slot :name="slot.name">
|
||||
<template v-if="slot.name === 'refresh'">
|
||||
<VbenIconButton class="my-0 mr-1 rounded-md" @click="refresh">
|
||||
<RotateCw class="size-4" />
|
||||
</VbenIconButton>
|
||||
</template>
|
||||
</slot>
|
||||
</template>
|
||||
<div class="flex-center hidden lg:block">
|
||||
@@ -91,9 +151,31 @@ const leftSlots = computed(() => {
|
||||
<div class="flex h-full min-w-0 flex-shrink-0 items-center">
|
||||
<template v-for="slot in rightSlots" :key="slot.name">
|
||||
<slot :name="slot.name">
|
||||
<template v-if="slot.name === 'theme-toggle'">
|
||||
<template v-if="slot.name === 'global-search'">
|
||||
<GlobalSearch
|
||||
:enable-shortcut-key="globalSearchShortcutKey"
|
||||
:menus="accessStore.accessMenus"
|
||||
class="mr-1 sm:mr-4"
|
||||
/>
|
||||
</template>
|
||||
<template v-else-if="slot.name === 'preferences'">
|
||||
<PreferencesButton
|
||||
class="mr-1"
|
||||
@clear-preferences-and-logout="clearPreferencesAndLogout"
|
||||
/>
|
||||
</template>
|
||||
<template v-else-if="slot.name === 'theme-toggle'">
|
||||
<ThemeToggle class="mr-1 mt-[2px]" />
|
||||
</template>
|
||||
<template v-else-if="slot.name === 'language-toggle'">
|
||||
<LanguageToggle class="mr-1" />
|
||||
</template>
|
||||
<template v-else-if="slot.name === 'fullscreen'">
|
||||
<VbenFullScreen class="mr-1" />
|
||||
</template>
|
||||
<template v-else-if="slot.name === 'timezone'">
|
||||
<TimezoneButton class="mr-1 mt-[2px]" />
|
||||
</template>
|
||||
</slot>
|
||||
</template>
|
||||
</div>
|
||||
|
||||
@@ -14,12 +14,13 @@ import {
|
||||
updatePreferences,
|
||||
usePreferences,
|
||||
} from '@vben/preferences';
|
||||
import { useAccessStore } from '@vben/stores';
|
||||
import { cloneDeep, mapTree } from '@vben/utils';
|
||||
|
||||
import { VbenAdminLayout } from '@vben-core/layout-ui';
|
||||
import { VbenBackTop, VbenLogo } from '@vben-core/shadcn-ui';
|
||||
|
||||
import Breadcrumb from '../widgets/breadcrumb.vue';
|
||||
import { Breadcrumb, CheckUpdates, Preferences } from '../widgets';
|
||||
import { LayoutContent, LayoutContentSpinner } from './content';
|
||||
import { Copyright } from './copyright';
|
||||
import { LayoutFooter } from './footer';
|
||||
@@ -35,7 +36,7 @@ import { LayoutTabbar } from './tabbar';
|
||||
|
||||
defineOptions({ name: 'BasicLayout' });
|
||||
|
||||
const emit = defineEmits<{ clickLogo: [] }>();
|
||||
const emit = defineEmits<{ clearPreferencesAndLogout: []; clickLogo: [] }>();
|
||||
|
||||
const {
|
||||
isDark,
|
||||
@@ -46,9 +47,11 @@ const {
|
||||
isHeaderMixedNav,
|
||||
isHeaderSidebarNav,
|
||||
layout,
|
||||
preferencesButtonPosition,
|
||||
sidebarCollapsed,
|
||||
theme,
|
||||
} = usePreferences();
|
||||
const accessStore = useAccessStore();
|
||||
const { refresh } = useRefresh();
|
||||
|
||||
const sidebarTheme = computed(() => {
|
||||
@@ -144,6 +147,10 @@ function toggleSidebar() {
|
||||
});
|
||||
}
|
||||
|
||||
function clearPreferencesAndLogout() {
|
||||
emit('clearPreferencesAndLogout');
|
||||
}
|
||||
|
||||
function clickLogo() {
|
||||
emit('clickLogo');
|
||||
}
|
||||
@@ -264,7 +271,10 @@ const headerSlots = computed(() => {
|
||||
</template>
|
||||
<!-- 头部区域 -->
|
||||
<template #header>
|
||||
<LayoutHeader :theme="theme">
|
||||
<LayoutHeader
|
||||
:theme="theme"
|
||||
@clear-preferences-and-logout="clearPreferencesAndLogout"
|
||||
>
|
||||
<template
|
||||
v-if="!showHeaderNav && preferences.breadcrumb.enable"
|
||||
#breadcrumb
|
||||
@@ -382,6 +392,21 @@ const headerSlots = computed(() => {
|
||||
|
||||
<template #extra>
|
||||
<slot name="extra"></slot>
|
||||
<CheckUpdates
|
||||
v-if="preferences.app.enableCheckUpdates"
|
||||
:check-updates-interval="preferences.app.checkUpdatesInterval"
|
||||
/>
|
||||
|
||||
<Transition v-if="preferences.widget.lockScreen" name="slide-up">
|
||||
<slot v-if="accessStore.isLockScreen" name="lock-screen"></slot>
|
||||
</Transition>
|
||||
|
||||
<template v-if="preferencesButtonPosition.fixed">
|
||||
<Preferences
|
||||
class="z-100 fixed bottom-20 right-0"
|
||||
@clear-preferences-and-logout="clearPreferencesAndLogout"
|
||||
/>
|
||||
</template>
|
||||
<VbenBackTop />
|
||||
</template>
|
||||
</VbenAdminLayout>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<script lang="ts" setup>
|
||||
import { computed } from 'vue';
|
||||
import { computed, nextTick } from 'vue';
|
||||
import { useRoute } from 'vue-router';
|
||||
|
||||
import { useContentMaximize, useTabs } from '@vben/hooks';
|
||||
@@ -43,7 +43,7 @@ const menus = computed(() => {
|
||||
|
||||
// 刷新后如果不保持tab状态,关闭其他tab
|
||||
if (!preferences.tabbar.persist) {
|
||||
tabbarStore.closeOtherTabs(route);
|
||||
nextTick(() => tabbarStore.closeOtherTabs(route));
|
||||
}
|
||||
</script>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user