[메뉴 권한 1차 작업]
This commit is contained in:
@@ -1,125 +1,49 @@
|
||||
<script setup lang="ts">
|
||||
import AppHeader from "../components/layout/AppHeader.vue";
|
||||
import { ref, computed, watch } from "vue";
|
||||
import { ref, computed, watch, onMounted } from "vue";
|
||||
import { useRouter } from "vue-router";
|
||||
import { useTabsStore } from "../stores/tab";
|
||||
import { usePermissionsStore } from "~/stores/permissions";
|
||||
|
||||
const router = useRouter();
|
||||
const activeMenu = ref("home");
|
||||
const activeMenu = ref("HOME");
|
||||
const showSubmenuBar = ref(false);
|
||||
|
||||
const tabsStore = useTabsStore();
|
||||
const permissionStore = usePermissionsStore();
|
||||
|
||||
// 권한 초기화
|
||||
onMounted(async () => {
|
||||
await permissionStore.fetchPermissions();
|
||||
});
|
||||
|
||||
// 메뉴 클릭 시 홈 이동
|
||||
watch(activeMenu, newValue => {
|
||||
if (newValue === "home") router.push("/");
|
||||
if (newValue === "HOME") router.push("/");
|
||||
});
|
||||
|
||||
// 서브메뉴 정의
|
||||
// 권한 기반 서브메뉴 생성
|
||||
const subMenus = computed(() => {
|
||||
if (activeMenu.value === "test") {
|
||||
return [
|
||||
{
|
||||
key: "test",
|
||||
label: "테스트",
|
||||
to: "/test/test01",
|
||||
},
|
||||
{
|
||||
key: "igv",
|
||||
label: "ivg",
|
||||
to: "/test/test02",
|
||||
},
|
||||
{
|
||||
key: "igv2",
|
||||
label: "ivg2",
|
||||
to: "/test/igv2",
|
||||
},
|
||||
{
|
||||
key: "pathway",
|
||||
label: "pathway",
|
||||
to: "/test/pathway",
|
||||
},
|
||||
{
|
||||
key: "pathway2",
|
||||
label: "pathway2",
|
||||
to: "/test/pathway2",
|
||||
},
|
||||
{
|
||||
key: "pathway3",
|
||||
label: "pathway3",
|
||||
to: "/test/pathway3",
|
||||
},
|
||||
{
|
||||
key: "pathway4",
|
||||
label: "pathway4",
|
||||
to: "/cultureGraph/pathway4",
|
||||
},
|
||||
{
|
||||
key: "pathwayjson",
|
||||
label: "pathwayjson",
|
||||
to: "/test/pathwayjson",
|
||||
},
|
||||
{
|
||||
key: "cultureGraph",
|
||||
label: "배양그래프",
|
||||
to: "/test/culture-graph",
|
||||
},
|
||||
{
|
||||
key: "cultureGraphMulti",
|
||||
label: "배양그래프 멀티",
|
||||
to: "/test/culture-graph-multi",
|
||||
},
|
||||
{
|
||||
key: "cultureGraphTab",
|
||||
label: "배양그래프 탭",
|
||||
to: "/test/culture-graph-tab",
|
||||
},
|
||||
{
|
||||
key: "tui-grid",
|
||||
label: "tui-grid",
|
||||
to: "/tui",
|
||||
},
|
||||
{
|
||||
key: "리소스",
|
||||
label: "리소스",
|
||||
to: "/admin/resource",
|
||||
},
|
||||
{
|
||||
key: "sample",
|
||||
label: "sample",
|
||||
to: "/sampleList",
|
||||
},
|
||||
{
|
||||
key: "common-test",
|
||||
label: "공용 기능 테스트",
|
||||
to: "/common-test",
|
||||
},
|
||||
];
|
||||
} else if (activeMenu.value === "ADMIN") {
|
||||
return [
|
||||
{
|
||||
key: "logs",
|
||||
label: "접속기록",
|
||||
to: "/admin/logs",
|
||||
},
|
||||
{
|
||||
key: "codes",
|
||||
label: "공통코드",
|
||||
to: "/admin/codes",
|
||||
},
|
||||
{
|
||||
key: "programs",
|
||||
label: "프로그램",
|
||||
to: "/admin/programs",
|
||||
},
|
||||
];
|
||||
}
|
||||
return [];
|
||||
if (activeMenu.value === "HOME") return [];
|
||||
|
||||
// 활성 메뉴의 코드 찾기 (M01, M02 등)
|
||||
const activeMenuCode = activeMenu.value;
|
||||
|
||||
// 해당 메뉴의 하위 페이지들 필터링
|
||||
return permissionStore.permissions.resources.pages
|
||||
.filter(page => page.parentCode === activeMenuCode)
|
||||
.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,
|
||||
}));
|
||||
});
|
||||
|
||||
function onMenuClick(menu: string) {
|
||||
activeMenu.value = menu;
|
||||
showSubmenuBar.value = true;
|
||||
showSubmenuBar.value = menu !== "home";
|
||||
}
|
||||
|
||||
// ✅ 서브메뉴 클릭 → 현재 활성 탭 내용만 변경
|
||||
@@ -147,18 +71,24 @@ function addNewTab() {
|
||||
|
||||
<!-- 서브메뉴 바 -->
|
||||
<nav
|
||||
v-if="subMenus && subMenus.length && showSubmenuBar"
|
||||
class="submenu-bar"
|
||||
@click.stop
|
||||
v-if="showSubmenuBar && subMenus.length > 0"
|
||||
class="w-full bg-gray-100 shadow-sm px-4 py-2"
|
||||
>
|
||||
<button
|
||||
v-for="sub in subMenus"
|
||||
:key="sub.key"
|
||||
class="submenu-btn"
|
||||
@click="onSubMenuClick({ ...sub, componentName: sub.key })"
|
||||
>
|
||||
{{ sub.label }}
|
||||
</button>
|
||||
<div class="flex items-center space-x-6">
|
||||
<span class="text-sm font-medium text-gray-600 mr-4">
|
||||
{{ activeMenu }}
|
||||
</span>
|
||||
<div class="flex space-x-4">
|
||||
<button
|
||||
v-for="sub in subMenus"
|
||||
:key="sub.key"
|
||||
class="submenu-btn"
|
||||
@click="onSubMenuClick(sub)"
|
||||
>
|
||||
{{ sub.label }}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
<br /><br />
|
||||
<!-- 탭 바 -->
|
||||
@@ -221,25 +151,19 @@ function addNewTab() {
|
||||
z-index: 10;
|
||||
}
|
||||
.submenu-btn {
|
||||
font-size: 1.05rem;
|
||||
font-weight: 500;
|
||||
color: #222;
|
||||
padding: 0.25rem 0.75rem;
|
||||
font-size: 0.875rem;
|
||||
color: #374151;
|
||||
background: none;
|
||||
border: none;
|
||||
padding: 0.5rem 1.2rem;
|
||||
border-radius: 6px;
|
||||
transition:
|
||||
background 0.15s,
|
||||
color 0.15s;
|
||||
border-radius: 0.25rem;
|
||||
cursor: pointer;
|
||||
transition: all 0.15s ease;
|
||||
}
|
||||
.submenu-btn.active {
|
||||
background: none;
|
||||
color: #1976d2;
|
||||
}
|
||||
|
||||
.submenu-btn:hover {
|
||||
background: #e6f0fa;
|
||||
color: #1976d2;
|
||||
color: #2563eb;
|
||||
background-color: #eff6ff;
|
||||
}
|
||||
|
||||
/* 탭바 스타일 */
|
||||
|
||||
Reference in New Issue
Block a user