262 lines
6.4 KiB
Vue
262 lines
6.4 KiB
Vue
<script setup lang="ts">
|
|
import { ref, shallowRef, onMounted, computed } from "vue";
|
|
import { useCustomizerStore } from "~/store/customizer";
|
|
import sidebarItems from "./sidebarItem";
|
|
import Logo from "../logo/Logo.vue";
|
|
import { Icon } from "@iconify/vue";
|
|
import { useRoute } from "vue-router";
|
|
// MiniSidebar Icons
|
|
import MiniSideIcons from "./MinIconItems";
|
|
import { useUserMenu } from "~/composables/useUserMenu";
|
|
|
|
|
|
const route = useRoute();
|
|
const { menuItems, hasMenu, isLoading, error, initializeMenu } = useUserMenu();
|
|
|
|
|
|
const findTitleByPath = (items: any, path: any) => {
|
|
let title = "";
|
|
|
|
for (const item of items) {
|
|
if (item.to === path) {
|
|
title = item.id;
|
|
break;
|
|
} else if (item.children) {
|
|
for (const child of item.children) {
|
|
if (child.to === path) {
|
|
title = item.id;
|
|
break;
|
|
} else if (child.children) {
|
|
for (const grandChild of child.children) {
|
|
if (grandChild.to === path) {
|
|
title = item.id;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return title;
|
|
};
|
|
|
|
const sidebarMenu = computed(() => {
|
|
if (hasMenu.value) {
|
|
return menuItems.value;
|
|
} else {
|
|
return [];
|
|
}
|
|
});
|
|
|
|
|
|
const foundId = findTitleByPath(sidebarMenu.value, route.path);
|
|
const getCurrent = foundId ? foundId : 1;
|
|
const currentMenu = ref<any>(getCurrent);
|
|
function showData(data: any) {
|
|
currentMenu.value = data;
|
|
//customizer.SET_MINI_SIDEBAR(!customizer.mini_sidebar)
|
|
}
|
|
|
|
// MiniSidebar Icons End
|
|
const customizer = useCustomizerStore();
|
|
|
|
// Toggle mini sidebar
|
|
const toggleMiniSidebar = () => {
|
|
customizer.SET_MINI_SIDEBAR(!customizer.mini_sidebar);
|
|
};
|
|
</script>
|
|
|
|
<template>
|
|
<!-- Minisidebar Icons -->
|
|
|
|
|
|
<!-- LeftSidebar Items -->
|
|
<v-navigation-drawer
|
|
v-model="customizer.Sidebar_drawer"
|
|
elevation="0"
|
|
rail-width="90"
|
|
app
|
|
top="0"
|
|
class="leftSidebar"
|
|
:rail="customizer.mini_sidebar"
|
|
:expand-on-hover="customizer.mini_sidebar"
|
|
width="240"
|
|
>
|
|
<!---Logo part -->
|
|
<div class="pa-4 pb-0" :class="{ 'logo-mini': customizer.mini_sidebar }" :style="customizer.mini_sidebar ? '' : ''">
|
|
<Logo />
|
|
</div>
|
|
|
|
<!-- ---------------------------------------------- -->
|
|
<!---Navigation -->
|
|
<!-- ---------------------------------------------- -->
|
|
<perfect-scrollbar class="scrollnavbar">
|
|
<!-- Loading State -->
|
|
<div v-if="isLoading" class="px-4 py-8 text-center">
|
|
<v-skeleton-loader type="article" :loading="true" class="mb-0 grey-skeleton" />
|
|
<v-skeleton-loader type="article" :loading="true" class="mb-0 grey-skeleton" />
|
|
|
|
<!-- <v-skeleton-loader type="list-item-two-line" :loading="true" class="mb-4 grey-skeleton" />
|
|
<v-skeleton-loader type="list-item-three-line" :loading="true" class="mb-4 grey-skeleton" /> -->
|
|
</div>
|
|
<div v-else class="px-4 py-0 sidebar-menus">
|
|
<v-list class="py-1">
|
|
<template v-for="(item, i) in sidebarMenu">
|
|
<template v-if="currentMenu == item.id">
|
|
<!---Item Sub Header -->
|
|
<LazyLayoutFullVerticalSidebarNavGroup
|
|
:item="item"
|
|
v-if="item.header && !customizer.mini_sidebar"
|
|
:key="i"
|
|
/>
|
|
<!---If Has Child -->
|
|
<template v-for="sItem in item.children">
|
|
<LazyLayoutFullVerticalSidebarNavCollapse
|
|
class="leftPadding"
|
|
:item="sItem"
|
|
:level="0"
|
|
v-if="sItem.children"
|
|
/>
|
|
<LazyLayoutFullVerticalSidebarNavItem
|
|
:item="sItem"
|
|
class="leftPadding"
|
|
v-else
|
|
/>
|
|
</template>
|
|
</template>
|
|
</template>
|
|
</v-list>
|
|
</div>
|
|
</perfect-scrollbar>
|
|
|
|
<!-- Toggle Mini Sidebar Button -->
|
|
<!-- <div class="sidebar-toggle-wrapper">
|
|
<v-divider class="mb-0"></v-divider>
|
|
<v-btn
|
|
@click="toggleMiniSidebar"
|
|
variant="text"
|
|
block
|
|
class="sidebar-toggle-btn"
|
|
:ripple="false"
|
|
>
|
|
<v-tooltip location="right" v-if="customizer.mini_sidebar">
|
|
<template v-slot:activator="{ props }">
|
|
<v-icon v-bind="props" size="20">
|
|
mdi-lock-open-variant-outline
|
|
</v-icon>
|
|
</template>
|
|
<span>Expand Sidebar</span>
|
|
</v-tooltip>
|
|
|
|
<template v-else>
|
|
<v-icon size="20" class="mr-2">
|
|
mdi-lock-outline
|
|
</v-icon>
|
|
<span class="text-caption">Minimize</span>
|
|
</template>
|
|
</v-btn>
|
|
</div> -->
|
|
</v-navigation-drawer>
|
|
</template>
|
|
|
|
<style scoped>
|
|
.sidebar-toggle-wrapper {
|
|
position: absolute;
|
|
bottom: 0;
|
|
left: 0;
|
|
right: 0;
|
|
background: inherit;
|
|
z-index: 1;
|
|
}
|
|
|
|
.sidebar-toggle-btn {
|
|
height: 48px !important;
|
|
border-radius: 0 !important;
|
|
text-transform: none;
|
|
letter-spacing: normal;
|
|
font-weight: 500;
|
|
opacity: 0.7;
|
|
transition: all 0.2s ease;
|
|
}
|
|
|
|
.sidebar-toggle-btn:hover {
|
|
opacity: 1;
|
|
background-color: rgba(var(--v-theme-primary), 0.08);
|
|
}
|
|
|
|
/* Adjust scrollbar height to account for toggle button */
|
|
.scrollnavbar {
|
|
height: calc(100vh - 120px) !important;
|
|
}
|
|
|
|
/* Logo styling for mini mode */
|
|
.logo-mini :deep(img) {
|
|
transition: all 0.3s ease;
|
|
max-width: 500px;
|
|
margin-left: 20px;
|
|
height: auto;
|
|
}
|
|
|
|
/* Rail mode enhancements */
|
|
:deep(.v-navigation-drawer--rail) {
|
|
.sidebar-menus {
|
|
padding-left: 0 !important;
|
|
padding-right: 0 !important;
|
|
}
|
|
|
|
.v-list-item {
|
|
justify-content: center;
|
|
padding-left: 18px !important;
|
|
padding-right: 8px !important;
|
|
min-height: 48px;
|
|
margin: 4px 8px;
|
|
}
|
|
|
|
.v-list-item__prepend {
|
|
margin-right: 0 !important;
|
|
}
|
|
|
|
.v-list-item-title {
|
|
display: none;
|
|
}
|
|
|
|
.v-list-item__append {
|
|
display: none;
|
|
}
|
|
|
|
.v-list-item--active {
|
|
border-radius: 12px;
|
|
}
|
|
|
|
.v-list-item__overlay {
|
|
border-radius: 12px;
|
|
}
|
|
}
|
|
|
|
/* Show full menu on hover */
|
|
:deep(.v-navigation-drawer--rail.v-navigation-drawer--expand-on-hover:hover) {
|
|
.sidebar-menus {
|
|
padding-left: 16px !important;
|
|
padding-right: 16px !important;
|
|
}
|
|
|
|
.v-list-item {
|
|
justify-content: flex-start;
|
|
padding-left: 16px !important;
|
|
}
|
|
|
|
.v-list-item-title {
|
|
display: block;
|
|
}
|
|
|
|
.v-list-item__prepend {
|
|
margin-right: 16px !important;
|
|
}
|
|
|
|
.v-list-item__append {
|
|
display: flex;
|
|
}
|
|
}
|
|
</style>
|