96 lines
2.7 KiB
Vue
96 lines
2.7 KiB
Vue
<script setup lang="ts">
|
|
import { computed, ref } from 'vue'
|
|
import { useRoute } from 'vue-router'
|
|
import { mdiHome } from '@mdi/js'
|
|
import MainLayout from '@/components/layouts/MainLayout.vue'
|
|
import PlainLayout from '@/components/layouts/PlainLayout.vue'
|
|
import { useAppShell } from '@/composables/layout/useAppShell'
|
|
import AppTabs from './AppTabs.vue'
|
|
import GlobalOverlays from './GlobalOverlays.vue'
|
|
|
|
type AppTabsInstance = InstanceType<typeof AppTabs>
|
|
type GlobalOverlaysInstance = InstanceType<typeof GlobalOverlays>
|
|
|
|
const route = useRoute()
|
|
const appTabs = ref<AppTabsInstance | null>(null)
|
|
const globalOverlays = ref<GlobalOverlaysInstance | null>(null)
|
|
|
|
const layoutMap = {
|
|
default: MainLayout,
|
|
none: PlainLayout,
|
|
}
|
|
|
|
const activeLayout = computed(
|
|
() => layoutMap[route.meta.layout as 'default' | 'none'] || MainLayout
|
|
)
|
|
const showTabs = computed(() => route.meta.layout === 'default')
|
|
|
|
function clearTabs() {
|
|
appTabs.value?.clearTabs()
|
|
}
|
|
|
|
const {
|
|
favoriteActionIcon,
|
|
favoriteActionLabel,
|
|
favoritesStore,
|
|
goHome,
|
|
handleLayoutAction,
|
|
handleLogout,
|
|
handleRemoveFavorite,
|
|
handleSelect,
|
|
isFavoriteActionDisabled,
|
|
layoutProps,
|
|
menuStore,
|
|
mergedMenuItems,
|
|
toggleFavorite,
|
|
} = useAppShell({ onLogout: clearTabs })
|
|
|
|
function handleSearch(value: string) {
|
|
globalOverlays.value?.handleSearch(value)
|
|
}
|
|
</script>
|
|
|
|
<template>
|
|
<component
|
|
:is="activeLayout"
|
|
v-bind="layoutProps"
|
|
v-model:breadcrumb-bar-visible="favoritesStore.breadcrumbBarVisible"
|
|
v-model:favorites-bar-visible="favoritesStore.favoritesBarVisible"
|
|
v-model:is-rail="menuStore.isRail"
|
|
@action="handleLayoutAction"
|
|
@logout="handleLogout"
|
|
@remove-favorite="handleRemoveFavorite"
|
|
@search="handleSearch"
|
|
@select="handleSelect"
|
|
>
|
|
<template #breadcrumb-actions>
|
|
<v-btn
|
|
color="secondary"
|
|
:disabled="isFavoriteActionDisabled"
|
|
size="small"
|
|
variant="outlined"
|
|
@click="toggleFavorite"
|
|
>
|
|
<v-icon class="mr-1" size="14" :icon="favoriteActionIcon" />
|
|
{{ favoriteActionLabel }}
|
|
</v-btn>
|
|
<v-btn class="ml-2" color="primary" size="small" variant="text" @click="goHome">
|
|
<v-icon class="mr-1" size="14" :icon="mdiHome" />
|
|
返回首頁
|
|
</v-btn>
|
|
</template>
|
|
|
|
<AppTabs ref="appTabs" :menu-items="mergedMenuItems" :show-tabs="showTabs">
|
|
<router-view v-if="showTabs" v-slot="{ Component }">
|
|
<keep-alive>
|
|
<component :is="Component" :key="route.fullPath" />
|
|
</keep-alive>
|
|
</router-view>
|
|
|
|
<router-view v-else />
|
|
</AppTabs>
|
|
</component>
|
|
|
|
<GlobalOverlays ref="globalOverlays" :menu-items="mergedMenuItems" @search-select="handleSelect" />
|
|
</template>
|