Files
bio_frontend/layouts/default.vue

94 lines
2.2 KiB
Vue

<template>
<div class="layout">
<AppHeader v-model="activeMenu" @update:model-value="handleMenuChange" />
<!-- 서브메뉴 -->
<SubMenuBar
:show-submenu-bar="showSubmenuBar"
:active-menu="activeMenu"
:sub-menus="subMenus"
@submenu-click="onSubMenuClick"
/>
<!-- -->
<TabBar />
<main class="main">
<slot />
</main>
</div>
</template>
<script setup lang="ts">
import AppHeader from "../components/layout/AppHeader.vue";
import SubMenuBar from "../components/layout/SubMenuBar.vue";
import TabBar from "../components/layout/TabBar.vue";
import { ref, computed } from "vue";
import { useTabsStore } from "../stores/tab";
import { usePermissionsStore } from "~/stores/permissions";
const activeMenu = ref("HOME");
const showSubmenuBar = ref(false);
const tabsStore = useTabsStore();
const permissionStore = usePermissionsStore();
// 권한 기반 서브메뉴 생성
const subMenus = computed(() => {
if (activeMenu.value === "HOME") return [];
// 활성 메뉴의 코드 찾기 (PG01, PG02 등)
const activeMenuCode = activeMenu.value;
// 해당 페이지그룹의 하위 페이지들 필터링 (menu_yn이 "Y"인 것만)
return permissionStore.permissions.resources.pages
.filter(page => page.parentCode === activeMenuCode)
.filter(page => page.menuYn === "Y") // 메뉴에 표시할 페이지만
.filter(page => permissionStore.hasPagePermission(page.path || ""))
.sort((a, b) => a.sortOrder - b.sortOrder)
.map(page => ({
key: page.code,
label: page.name,
to: page.path || "",
componentName: page.name,
}));
});
async function handleMenuChange(_menuCode: string) {
if (activeMenu.value === "HOME") {
showSubmenuBar.value = false;
await navigateTo("/");
} else {
showSubmenuBar.value = true;
}
}
function onSubMenuClick(sub: {
key: string;
label: string;
to: string;
componentName: string;
}) {
tabsStore.updateActiveTab(sub);
}
</script>
<style scoped>
.layout {
min-height: 100vh;
display: flex;
flex-direction: column;
position: relative;
}
.main {
flex: 1;
padding: 2rem;
padding-top: 0.5rem;
}
.footer {
background: #f8f9fa;
padding: 1rem;
text-align: center;
border-top: 1px solid #e9ecef;
}
</style>