|
@@ -1,91 +1,220 @@
|
|
|
<template>
|
|
<template>
|
|
|
<q-drawer
|
|
<q-drawer
|
|
|
|
|
+ v-bind="$attrs"
|
|
|
v-model="leftDrawerOpen"
|
|
v-model="leftDrawerOpen"
|
|
|
show-if-above
|
|
show-if-above
|
|
|
- :mini="miniState"
|
|
|
|
|
- mini-to-overlay
|
|
|
|
|
:width="250"
|
|
:width="250"
|
|
|
|
|
+ :mini-width="70"
|
|
|
:breakpoint="500"
|
|
:breakpoint="500"
|
|
|
- bordered
|
|
|
|
|
- @mouseover="miniState = false"
|
|
|
|
|
- @mouseout="miniState = true"
|
|
|
|
|
|
|
+ :mini="miniState"
|
|
|
|
|
+ class="detached-container"
|
|
|
>
|
|
>
|
|
|
- <q-scroll-area style="height: calc(100vh - 100px)">
|
|
|
|
|
- <q-list class="column no-wrap" style="height: calc(100vh - 100px)">
|
|
|
|
|
|
|
+ <div class="q-pa-sm">
|
|
|
|
|
+ <div
|
|
|
|
|
+ class="toggle-button-wrapper absolute"
|
|
|
|
|
+ style="top: 50%; right: -32px; z-index: 1"
|
|
|
|
|
+ >
|
|
|
|
|
+ <q-btn flat round size="sm" @click="miniState = !miniState">
|
|
|
|
|
+ <q-icon
|
|
|
|
|
+ :name="miniState ? 'mdi-chevron-right' : 'mdi-chevron-left'"
|
|
|
|
|
+ />
|
|
|
|
|
+ <q-tooltip
|
|
|
|
|
+ anchor="center right"
|
|
|
|
|
+ self="center left"
|
|
|
|
|
+ :offset="[10, 10]"
|
|
|
|
|
+ >{{ miniState ? "Expandir menu" : "Colapsar menu" }}</q-tooltip
|
|
|
|
|
+ >
|
|
|
|
|
+ </q-btn>
|
|
|
|
|
+ </div>
|
|
|
|
|
+
|
|
|
|
|
+ <q-list class="column q-mb-md no-wrap" style="border-radius: 6px">
|
|
|
|
|
+ <q-item v-ripple clickable>
|
|
|
|
|
+ <div class="flex">
|
|
|
|
|
+ <q-item-section avatar>
|
|
|
|
|
+ <template #default>
|
|
|
|
|
+ <img
|
|
|
|
|
+ :src="someAvatar()"
|
|
|
|
|
+ alt="avatar"
|
|
|
|
|
+ style="width: 20px; height: 20px; border-radius: 50%"
|
|
|
|
|
+ />
|
|
|
|
|
+ </template>
|
|
|
|
|
+ </q-item-section>
|
|
|
|
|
+ <q-item-section>Usuario</q-item-section>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <q-tooltip
|
|
|
|
|
+ v-if="miniState"
|
|
|
|
|
+ anchor="center right"
|
|
|
|
|
+ self="center left"
|
|
|
|
|
+ :offset="[10, 10]"
|
|
|
|
|
+ >Usuario</q-tooltip
|
|
|
|
|
+ >
|
|
|
|
|
+ </q-item>
|
|
|
|
|
+ </q-list>
|
|
|
|
|
+
|
|
|
|
|
+ <q-list class="column no-wrap">
|
|
|
<template v-for="menu in menus" :key="menu.name">
|
|
<template v-for="menu in menus" :key="menu.name">
|
|
|
- <!-- * Single menu -->
|
|
|
|
|
|
|
+ <!-- Single Menu -->
|
|
|
<q-item
|
|
<q-item
|
|
|
- v-if="menu.type == 'single' && menu.permission"
|
|
|
|
|
|
|
+ v-if="menu.type === 'single'"
|
|
|
v-ripple
|
|
v-ripple
|
|
|
clickable
|
|
clickable
|
|
|
- :to="{ name: menu.name }"
|
|
|
|
|
- :disable="menu.disable"
|
|
|
|
|
- class="text-subtitle1"
|
|
|
|
|
exact-active-class="menu-selected"
|
|
exact-active-class="menu-selected"
|
|
|
exact
|
|
exact
|
|
|
active-class="menu-selected"
|
|
active-class="menu-selected"
|
|
|
|
|
+ :to="{ name: menu.name }"
|
|
|
|
|
+ class="q-my-xs"
|
|
|
>
|
|
>
|
|
|
<q-item-section avatar>
|
|
<q-item-section avatar>
|
|
|
- <q-icon :name="menu.icon" />
|
|
|
|
|
|
|
+ <q-icon :name="menu.icon" style="font-size: 18px" />
|
|
|
</q-item-section>
|
|
</q-item-section>
|
|
|
-
|
|
|
|
|
- <q-item-section> {{ $t(menu.title) }} </q-item-section>
|
|
|
|
|
|
|
+ <q-item-section>{{ $t(menu.title) }}</q-item-section>
|
|
|
|
|
+ <q-tooltip
|
|
|
|
|
+ v-if="miniState"
|
|
|
|
|
+ anchor="center right"
|
|
|
|
|
+ self="center left"
|
|
|
|
|
+ :offset="[10, 10]"
|
|
|
|
|
+ >{{ $t(menu.title) }}</q-tooltip
|
|
|
|
|
+ >
|
|
|
</q-item>
|
|
</q-item>
|
|
|
- <q-expansion-item
|
|
|
|
|
- v-if="menu.type == 'expansive' && menu.permission"
|
|
|
|
|
- expand-separator
|
|
|
|
|
- header-class="text-subtitle1"
|
|
|
|
|
- :icon="menu.icon"
|
|
|
|
|
- :label="$t(menu.title)"
|
|
|
|
|
- :content-inset-level="0.4"
|
|
|
|
|
- :disable="menu.disable"
|
|
|
|
|
- >
|
|
|
|
|
- <template v-for="children in menu.childrens" :key="children.name">
|
|
|
|
|
|
|
+ <!-- Expansive Menu with children -->
|
|
|
|
|
+ <div v-else>
|
|
|
|
|
+ <template v-if="!miniState">
|
|
|
|
|
+ <q-tooltip
|
|
|
|
|
+ v-if="miniState"
|
|
|
|
|
+ anchor="center right"
|
|
|
|
|
+ self="center left"
|
|
|
|
|
+ :offset="[10, 10]"
|
|
|
|
|
+ >{{ $t(menu.title) }}</q-tooltip
|
|
|
|
|
+ >
|
|
|
|
|
+ <q-expansion-item
|
|
|
|
|
+ v-model="isExpasionItemExpanded"
|
|
|
|
|
+ header-class=" menu-item--spaced"
|
|
|
|
|
+ :class="{
|
|
|
|
|
+ 'menu-selected':
|
|
|
|
|
+ childrenAreActive(menu.children) && !isExpasionItemExpanded,
|
|
|
|
|
+ }"
|
|
|
|
|
+ class="menu-item--spaced"
|
|
|
|
|
+ >
|
|
|
|
|
+ <template #header>
|
|
|
|
|
+ <q-item-section avatar>
|
|
|
|
|
+ <q-icon :name="menu.icon" style="font-size: 18px" />
|
|
|
|
|
+ </q-item-section>
|
|
|
|
|
+ <q-item-section>{{ $t(menu.title) }}</q-item-section>
|
|
|
|
|
+ </template>
|
|
|
|
|
+ <div v-for="child in menu.childrens" :key="child.name">
|
|
|
|
|
+ <q-item
|
|
|
|
|
+ v-ripple
|
|
|
|
|
+ clickable
|
|
|
|
|
+ :to="{ name: child.name }"
|
|
|
|
|
+ exact
|
|
|
|
|
+ exact-active-class="menu-selected"
|
|
|
|
|
+ class="menu-item--spaced"
|
|
|
|
|
+ >
|
|
|
|
|
+ <q-item-section avatar>
|
|
|
|
|
+ <q-icon :name="child.icon" style="font-size: 18px" />
|
|
|
|
|
+ </q-item-section>
|
|
|
|
|
+ <q-item-section>{{ $t(child.title) }}</q-item-section>
|
|
|
|
|
+ <q-tooltip
|
|
|
|
|
+ v-if="miniState"
|
|
|
|
|
+ anchor="center right"
|
|
|
|
|
+ self="center left"
|
|
|
|
|
+ :offset="[10, 10]"
|
|
|
|
|
+ >{{ $t(child.title) }}</q-tooltip
|
|
|
|
|
+ >
|
|
|
|
|
+ </q-item>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </q-expansion-item>
|
|
|
|
|
+ </template>
|
|
|
|
|
+ <template v-else>
|
|
|
<q-item
|
|
<q-item
|
|
|
- v-if="children.permission"
|
|
|
|
|
v-ripple
|
|
v-ripple
|
|
|
clickable
|
|
clickable
|
|
|
- :to="{ name: children.name }"
|
|
|
|
|
- :disable="children.disable"
|
|
|
|
|
- class="text-subtitle1"
|
|
|
|
|
|
|
+ exact
|
|
|
exact-active-class="menu-selected"
|
|
exact-active-class="menu-selected"
|
|
|
|
|
+ class="menu-item--spaced"
|
|
|
|
|
+ @click="openMenu(menu)"
|
|
|
>
|
|
>
|
|
|
<q-item-section avatar>
|
|
<q-item-section avatar>
|
|
|
- <q-icon :name="children.icon" />
|
|
|
|
|
|
|
+ <q-icon :name="menu.icon" style="font-size: 18px" />
|
|
|
</q-item-section>
|
|
</q-item-section>
|
|
|
- <q-item-section> {{ $t(children.title) }} </q-item-section>
|
|
|
|
|
|
|
+ <q-item-section>{{ $t(menu.title) }}</q-item-section>
|
|
|
|
|
+ <q-tooltip
|
|
|
|
|
+ v-if="miniState"
|
|
|
|
|
+ anchor="center right"
|
|
|
|
|
+ self="center left"
|
|
|
|
|
+ :offset="[10, 10]"
|
|
|
|
|
+ >{{ $t(menu.title) }}</q-tooltip
|
|
|
|
|
+ >
|
|
|
|
|
+ <q-menu anchor="top right" self="top left">
|
|
|
|
|
+ <q-list style="min-width: 100px">
|
|
|
|
|
+ <q-item
|
|
|
|
|
+ v-for="child in menu.childrens"
|
|
|
|
|
+ :key="child.name"
|
|
|
|
|
+ v-ripple
|
|
|
|
|
+ v-close-popup
|
|
|
|
|
+ clickable
|
|
|
|
|
+ :to="{ name: child.name }"
|
|
|
|
|
+ exact
|
|
|
|
|
+ exact-active-class="menu-selected"
|
|
|
|
|
+ class="menu-item--spaced"
|
|
|
|
|
+ >
|
|
|
|
|
+ <q-item-section avatar>
|
|
|
|
|
+ <q-icon :name="child.icon" style="font-size: 18px" />
|
|
|
|
|
+ </q-item-section>
|
|
|
|
|
+ <q-item-section>{{ $t(child.title) }}</q-item-section>
|
|
|
|
|
+ </q-item>
|
|
|
|
|
+ </q-list>
|
|
|
|
|
+ </q-menu>
|
|
|
</q-item>
|
|
</q-item>
|
|
|
</template>
|
|
</template>
|
|
|
- </q-expansion-item>
|
|
|
|
|
|
|
+ </div>
|
|
|
</template>
|
|
</template>
|
|
|
- <q-item
|
|
|
|
|
- v-ripple
|
|
|
|
|
- clickable
|
|
|
|
|
- class="q-mt-auto text-subtitle1"
|
|
|
|
|
- @click="logout()"
|
|
|
|
|
- >
|
|
|
|
|
|
|
+ </q-list>
|
|
|
|
|
+
|
|
|
|
|
+ <q-list class="column q-mt-md no-wrap overflow-hidden">
|
|
|
|
|
+ <q-item v-ripple clickable @click="logoutFn">
|
|
|
<div class="flex">
|
|
<div class="flex">
|
|
|
<q-item-section avatar>
|
|
<q-item-section avatar>
|
|
|
- <q-icon name="mdi-logout-variant" color="negative" />
|
|
|
|
|
|
|
+ <q-icon name="logout" color="negative" style="font-size: 18px" />
|
|
|
</q-item-section>
|
|
</q-item-section>
|
|
|
- <q-item-section> {{ $t("navigation.logout") }} </q-item-section>
|
|
|
|
|
|
|
+ <q-item-section>Sair</q-item-section>
|
|
|
</div>
|
|
</div>
|
|
|
|
|
+ <q-tooltip
|
|
|
|
|
+ v-if="miniState"
|
|
|
|
|
+ anchor="center right"
|
|
|
|
|
+ self="center left"
|
|
|
|
|
+ :offset="[10, 10]"
|
|
|
|
|
+ >Sair</q-tooltip
|
|
|
|
|
+ >
|
|
|
</q-item>
|
|
</q-item>
|
|
|
</q-list>
|
|
</q-list>
|
|
|
- </q-scroll-area>
|
|
|
|
|
|
|
+ </div>
|
|
|
</q-drawer>
|
|
</q-drawer>
|
|
|
</template>
|
|
</template>
|
|
|
-
|
|
|
|
|
<script setup>
|
|
<script setup>
|
|
|
import { ref, onMounted } from "vue";
|
|
import { ref, onMounted } from "vue";
|
|
|
import { useAuth } from "src/composables/useAuth";
|
|
import { useAuth } from "src/composables/useAuth";
|
|
|
import { permissionStore } from "src/stores/permission";
|
|
import { permissionStore } from "src/stores/permission";
|
|
|
-import { useRouter } from "vue-router";
|
|
|
|
|
|
|
+import { useRouter, useRoute } from "vue-router";
|
|
|
|
|
|
|
|
-const auth = useAuth();
|
|
|
|
|
|
|
+const { logout } = useAuth();
|
|
|
const leftDrawerOpen = ref(true);
|
|
const leftDrawerOpen = ref(true);
|
|
|
const miniState = ref(true);
|
|
const miniState = ref(true);
|
|
|
const router = useRouter();
|
|
const router = useRouter();
|
|
|
|
|
+const route = useRoute();
|
|
|
|
|
+
|
|
|
|
|
+const childrenAreActive = (children) => {
|
|
|
|
|
+ if (!children) return false;
|
|
|
|
|
+ return children.some((child) => {
|
|
|
|
|
+ return route.path.includes(child.path);
|
|
|
|
|
+ });
|
|
|
|
|
+};
|
|
|
|
|
+
|
|
|
|
|
+const someAvatar = () => {
|
|
|
|
|
+ return "https://cdn.quasar.dev/img/avatar4.jpg";
|
|
|
|
|
+};
|
|
|
|
|
+
|
|
|
|
|
+const isExpasionItemExpanded = ref(false);
|
|
|
|
|
|
|
|
const menus = ref([
|
|
const menus = ref([
|
|
|
{
|
|
{
|
|
@@ -139,8 +268,8 @@ const getMenuAccess = () => {
|
|
|
.filter((menu) => menu !== null);
|
|
.filter((menu) => menu !== null);
|
|
|
};
|
|
};
|
|
|
|
|
|
|
|
-const logout = async () => {
|
|
|
|
|
- await auth.logout();
|
|
|
|
|
|
|
+const logoutFn = async () => {
|
|
|
|
|
+ await logout();
|
|
|
router.push({ name: "LoginPage" });
|
|
router.push({ name: "LoginPage" });
|
|
|
};
|
|
};
|
|
|
|
|
|
|
@@ -150,20 +279,27 @@ onMounted(() => {
|
|
|
</script>
|
|
</script>
|
|
|
|
|
|
|
|
<style lang="scss" scoped>
|
|
<style lang="scss" scoped>
|
|
|
|
|
+@import "/src/css/quasar.variables.scss";
|
|
|
|
|
+.text-subtitle3 {
|
|
|
|
|
+ font-size: 1.1rem !important;
|
|
|
|
|
+ font-weight: 400 !important;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
.menu-selected {
|
|
.menu-selected {
|
|
|
- color: #385873 !important;
|
|
|
|
|
- background: rgba(56, 88, 115, 0.15) !important;
|
|
|
|
|
-
|
|
|
|
|
- .body--light & {
|
|
|
|
|
- color: #385873 !important;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- .body--dark & {
|
|
|
|
|
- color: #5d93bf !important;
|
|
|
|
|
- }
|
|
|
|
|
- //sobreescrever comportamento padrao da classe .fit do quasar
|
|
|
|
|
- .fit {
|
|
|
|
|
- padding: 0px !important;
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ background-color: rgba($primary, 0.1);
|
|
|
|
|
+ color: $primary;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.toggle-button-wrapper {
|
|
|
|
|
+ transition: transform 0.3s ease;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.toggle-button-wrapper:hover {
|
|
|
|
|
+ transform: scale(1.1);
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.menu-item--spaced {
|
|
|
|
|
+ margin-top: 5px;
|
|
|
|
|
+ margin-bottom: 5px;
|
|
|
}
|
|
}
|
|
|
</style>
|
|
</style>
|