hrms-manual/src/views/MainLayout.vue
2024-06-28 10:05:44 +07:00

439 lines
12 KiB
Vue

<script setup lang="ts">
import { onMounted, ref, watch } from "vue";
import { useRoute } from "vue-router";
import { useDataStore } from "@/stores/data";
import { useManualStore } from "@/stores/manual";
import { storeToRefs } from "pinia";
import { menuList } from "../interface/request/main/main";
const dataStore = useDataStore();
const manualStore = useManualStore();
const route = useRoute();
const { toc } = storeToRefs(manualStore);
const { loader } = storeToRefs(dataStore);
const drawerMini = ref(false);
const drawerMain = ref(false);
const search = ref("");
/**
* ปุ่มย่อ ขยาย สารบัญทางขวาของคู่มือ
*/
const toggleManualToc = () => {
toc.value = !toc.value;
};
/**
* toggleBtnLeft ปุ่มย่อ ขยาย drawer ซ้าย เมื่อหน้าจอ ย่อถึงขนาด 1024 px
* ปกติเป็นการย่อโดยใช้ Ministate
*/
const toggleBtnLeft = () => {
if (window.innerWidth < 1024) {
drawerMain.value = !drawerMain.value;
} else {
drawerMini.value = !drawerMini.value;
}
};
onMounted(async () => {
{
const data = await fetch("/toc.json").then((r) => r.json());
menuList.value = data;
}
});
const downloadManual = () => {
const fileName = route.fullPath.split("/").pop();
const pdfUrl = window.location.href.split("manual/").join("") + ".pdf";
const link = document.createElement("a");
link.href = pdfUrl;
link.download = fileName ?? ""; // ชื่อไฟล์ที่ต้องการดาวน์โหลด
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
};
const downloadManualAll = () => {
const fileName = "manual-all.pdf";
const pdfUrl = window.location.origin + "/manual-all.pdf";
const link = document.createElement("a");
link.href = pdfUrl;
link.download = `${fileName}`; // ชื่อไฟล์ที่ต้องการดาวน์โหลด
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
};
</script>
<!-- โครงเว -->
<template>
<!-- แบบเก design แรก -->
<!-- <q-layout view="lHh Lpr lff"> -->
<!-- ปรบใหบหน รายละเอยดทะเบยนประว -->
<q-layout view="lHh LpR lff">
<!-- header -->
<q-header flat class="bg-grey-2 text-dark" height-hint="7">
<q-toolbar style="padding: 0 2%">
<q-btn
size="13px"
class="bg-grey-3"
flat
dense
round
@click="toggleBtnLeft"
aria-label="Menu"
>
<q-icon
:name="drawerMini == false ? 'mdi-backburger' : 'mdi-menu-open'"
size="20px"
color="grey-7"
/>
</q-btn>
<q-space />
<q-btn
v-if="route.path !== '/'"
size="12px"
flat
dense
round
icon="mdi-download"
color="primary"
>
<q-tooltip>ดาวน์โหลด</q-tooltip>
<q-menu>
<q-list style="min-width: 150px">
<q-item
clickable
class="row items-center no-wrap"
v-close-popup
@click="downloadManual()"
>
<q-icon
color="red"
size="28px"
name="mdi-file-pdf"
class="q-mr-md"
/>
ดาวน์โหลดคู่มือ
</q-item>
<q-item
clickable
class="row items-center no-wrap"
v-close-popup
@click="downloadManualAll()"
>
<q-icon
color="red"
size="28px"
name="mdi-file-pdf"
class="q-mr-md"
/>
ดาวน์โหลดคู่มือทั้งหมด
</q-item>
</q-list>
</q-menu>
</q-btn>
<q-btn
size="13px"
class="bg-blue-1"
v-if="$route.path.startsWith('/manual') && $q.screen.width < 1024"
flat
dense
round
@click="toggleManualToc"
aria-label="Menu"
>
<q-icon name="mdi-menu" class="rotate-180" size="20px" color="blue" />
</q-btn>
</q-toolbar>
</q-header>
<!-- end header -->
<!-- drawer -->
<q-drawer
side="left"
class="text-white"
style="background: #273238"
v-model="drawerMain"
show-if-above
:width="260"
:breakpoint="1023"
:mini="drawerMini"
>
<!-- ส่วนของเมนู mini -->
<template v-slot:mini>
<q-scroll-area class="fit mini-slot cursor-pointer">
<q-toolbar class="q-py-md">
<q-img
src="@/assets/logo.png"
spinner-color="white"
style="height: 32px; max-width: 32px"
/>
</q-toolbar>
<q-separator color="grey-9" />
<!-- เมนูย่อย ตอนย่อ -->
<q-list padding>
<div v-for="(menuItem, index) in menuList" :key="index">
<q-item
clickable
v-ripple
:to="menuItem.path"
:active="
$route.path === menuItem.path ||
($route.path !== '/' && menuItem.path?.includes($route.path))
"
active-class="text-primary menuActiveMini"
>
<q-item-section avatar>
<q-avatar size="md" font-size="20px">
<q-icon :name="menuItem.icon" />
</q-avatar>
</q-item-section>
<q-tooltip
anchor="center right"
self="center left"
:offset="[10, 10]"
>
{{ menuItem.label }}
</q-tooltip>
</q-item>
</div>
</q-list>
</q-scroll-area>
</template>
<!-- จบส่วนของเมนู mini -->
<!-- ส่วนของเมนู -->
<q-scroll-area class="fit">
<q-toolbar class="q-py-md">
<q-toolbar-title shrink class="row items-center no-wrap">
<q-img
src="@/assets/logo.png"
spinner-color="white"
style="height: 40px; max-width: 40px"
/>
<div class="row q-ml-md">
<div
style="color: #ffffff; letter-spacing: 1px"
class="text-body2 text-weight-bolder"
>
ระบบ<span class="text-primary">ทรัพยากรบุคคล</span>
</div>
<div class="text-caption text-white">&nbsp;กรุงเทพมหานคร</div>
</div>
</q-toolbar-title>
</q-toolbar>
<q-separator inset color="grey-9" />
<div class="row">
<div class="col-12 q-pa-md">
<q-input
outlined
bg-color="white"
label="ค้นหา"
v-model="search"
dense
>
<template v-slot:prepend>
<q-icon name="search" />
</template>
</q-input>
</div>
</div>
<q-list padding>
<div v-for="(menuItem, index) in menuList" :key="index">
<!-- เมนูย่อย -->
<q-expansion-item
v-if="menuItem.children && menuItem.children.length > 0"
class="menuSub"
expand-icon="mdi-chevron-down"
expanded-icon="mdi-chevron-up"
>
<template v-slot:header>
<q-item-section avatar>
<q-avatar :icon="menuItem.icon" size="md" font-size="20px" />
</q-item-section>
<q-item-section>{{ menuItem.label }}</q-item-section>
</template>
<!-- เมนอย 1 -->
<q-item
dense
class="menuSubHover"
active-class="text-primary active-item text-weight-bold menuSubAct"
clickable
v-for="child in menuItem.children"
:key="child.path"
:to="child.path"
>
<q-item-section>
<q-item-label class="font-400">
{{ child.label }}
</q-item-label>
</q-item-section>
</q-item>
</q-expansion-item>
<q-item
v-else
class="text-weight-medium menu"
:active="$route.path === menuItem.path"
active-class="text-primary active-item text-weight-bold menuActive"
:to="menuItem.path"
clickable
v-ripple
dense
exact
>
<q-item-section avatar>
<q-avatar size="md" font-size="20px">
<q-icon
:name="
$route.path === menuItem.path
? menuItem.activeIcon
: menuItem.icon
"
/>
</q-avatar>
</q-item-section>
<q-item-section>
<q-item-label>{{ menuItem.label }}</q-item-label>
</q-item-section>
</q-item>
</div>
</q-list>
</q-scroll-area>
</q-drawer>
<!-- drawer page login -->
<q-page-container class="bg-grey-2">
<q-page style="padding: 0 2%">
<router-view :key="$route.fullPath" />
</q-page>
</q-page-container>
<full-loader :visibility="loader" />
</q-layout>
</template>
<style>
.menuSub .q-item__section--avatar,
.menu .q-item__section--avatar {
min-width: 0px;
}
.menu {
padding-bottom: 5px;
padding-top: 5px;
border-radius: 0 100px 100px 0;
margin-right: 2%;
}
.menuActive {
background: #212a2f;
border-radius: 0 100px 100px 0;
margin-right: 2%;
}
.menuActiveMini {
background: #212a2f;
}
.menuSub .q-item {
border-radius: 0 100px 100px 0;
margin-right: 2%;
font-weight: 500;
}
.expan2 .q-item {
padding-left: 10%;
}
.subLabel {
white-space: nowrap;
width: 160px;
overflow: hidden;
text-overflow: ellipsis;
}
.font-400 {
font-weight: 400;
}
.expan2 .menuSubHover {
padding-left: 30%;
border-radius: 20px;
}
.menuSubHover {
padding-left: 25%;
border-radius: 20px;
}
.menuSub .q-expansion-item__content {
background: #212a2f;
padding: 5px 0px;
margin-bottom: 5px;
}
.tabNative {
color: grey;
padding-left: 8%;
border-radius: 100px 0px 0px 100px;
}
.tabActive {
padding-left: 8%;
background: #e4f2ff;
border-radius: 100px 0px 0px 100px;
}
.q-card {
box-shadow: 3px 3px 20px -10px rgba(151, 150, 150, 0.261) !important;
}
.q-card--bordered {
border: 1px solid #ededed;
box-shadow: none !important;
}
.q-menu {
box-shadow: 3px 3px 10px 1px rgba(95, 95, 95, 0.15) !important;
}
.toptitle {
font-size: 1.2rem;
font-weight: bold;
margin-bottom: 1%;
}
.q-field--outlined .q-field__control {
border-radius: 50px;
}
.q-field--outlined .q-field__control:before {
border-color: #c8d3db;
}
.btnManu {
min-height: 48px;
border-radius: 0px 100px 100px 0px;
}
.q-field--outlined .q-icon {
color: #7474747f;
}
.q-card__actions .q-btn--rectangle {
padding: 0 14px !important;
}
/* custom scrollbar */
::-webkit-scrollbar {
width: 12px;
height: 12px;
}
::-webkit-scrollbar-track {
background-color: transparent;
}
::-webkit-scrollbar-thumb {
background-color: #d6dee1;
border-radius: 20px;
border: 3px solid transparent;
background-clip: content-box;
}
::-webkit-scrollbar-thumb:hover {
background-color: #a8bbbf;
}
</style>