ปรับข้อมูลการลา และปรับ layout หน้าหลักการลา
This commit is contained in:
Warunee Tamkoo 2023-11-21 15:59:14 +07:00
parent 0705eff57c
commit 1ea53b0fe5
7 changed files with 1465 additions and 1521 deletions

View file

@ -1,17 +1,19 @@
<script setup lang="ts"> <script setup lang="ts">
import { ref, watch, onMounted } from "vue" import { ref, watch, onMounted } from "vue";
import FullCalendar from "@fullcalendar/vue3" import FullCalendar from "@fullcalendar/vue3";
import dayGridPlugin from "@fullcalendar/daygrid" import dayGridPlugin from "@fullcalendar/daygrid";
import type { CalendarOptions } from "@fullcalendar/core" import type { CalendarOptions } from "@fullcalendar/core";
import timeGridPlugin from "@fullcalendar/timegrid" import timeGridPlugin from "@fullcalendar/timegrid";
import interactionPlugin from "@fullcalendar/interaction" import interactionPlugin from "@fullcalendar/interaction";
import allLocales from "@fullcalendar/core/locales-all" import allLocales from "@fullcalendar/core/locales-all";
import listPlugin from "@fullcalendar/list" import listPlugin from "@fullcalendar/list";
import { useCounterMixin } from "@/stores/mixin";
import type { DataDateMonthObject } from "@/modules/05_leave/interface/request/Calendar.ts";
/** /**
* Option ของปฏ * Option ของปฏ
*/ */
const fullCalendar = ref<any>() //ref calendar const fullCalendar = ref<any>(); //ref calendar
const calendarOptions = ref<CalendarOptions>({ const calendarOptions = ref<CalendarOptions>({
plugins: [ plugins: [
dayGridPlugin, dayGridPlugin,
@ -19,11 +21,11 @@ const calendarOptions = ref<CalendarOptions>({
interactionPlugin, // needed for dateClick interactionPlugin, // needed for dateClick
listPlugin, listPlugin,
], ],
buttonText: { // buttonText: {
listYear: "รายการ", // listYear: "",
dayGridMonth: "ปฏิทิน", // dayGridMonth: "",
test: "เพิ่มวันหยุด", // test: "",
}, // },
headerToolbar: false, headerToolbar: false,
initialView: "dayGridMonth", initialView: "dayGridMonth",
initialEvents: [], // alternatively, use the `events` setting to fetch from a feed initialEvents: [], // alternatively, use the `events` setting to fetch from a feed
@ -41,138 +43,283 @@ const calendarOptions = ref<CalendarOptions>({
displayEventTime: false, displayEventTime: false,
editable: true, editable: true,
events: [ events: [
{ groupId: "3", title: "ลากิจส่วนตัว", start: "2023-10-10", allDay: true, status: "done", color: "#E3FDDA" }, {
{ groupId: "3", title: "ลากิจส่วนตัว", start: "2023-11-10", allDay: true, status: "done", color: "#E3FDDA" }, groupId: "2",
{ groupId: "3", title: "ลากิจส่วนตัว", start: "2023-10-11", allDay: true, status: "done", color: "#E3FDDA" }, title: "ลาป่วย",
{ groupId: "3", title: "ลากิจส่วนตัว", start: "2023-10-12", allDay: true, status: "done", color: "#E3FDDA" }, start: "2023-11-24",
{ groupId: "3", title: "ลากิจส่วนตัว", start: "2023-10-13", allDay: true, status: "done", color: "#E3FDDA" }, end: "2023-11-25",
{ groupId: "2", title: "ลาป่วย", start: "2023-10-19", allDay: true, status: "proceed", color: "#e4f3ff" }, allDay: true,
{ groupId: "1", title: "ลาป่วย", start: "2023-10-20", allDay: true, status: "new", color: "#FFF1CC" }, color: "#4CAF4F",
textColor: "white",
},
{
groupId: "4",
title: "ลากิจ",
start: "2023-11-15",
allDay: true,
color: "#4CAF4F",
textColor: "white",
},
{
groupId: "4",
title: "นางสาวสมศรี ใจดี (ลากิจ)",
start: "2023-11-21",
end: "2023-11-23",
allDay: true,
color: "#ddd",
},
{
groupId: "4",
title: "นายสมชาย สุขใจ",
start: "2023-11-21",
allDay: true,
color: "#ddd",
},
], ],
}) });
/** /**
* วแปรทงหมด * วแปรทงหมด
*/ */
const modalCancel = ref(false) const modalCancel = ref(false);
const title = ref("") const title = ref("");
const location = ref("บ้าน") const location = ref("บ้าน");
const subject = ref("ลาป่วย") const subject = ref("ลาป่วย");
const dateStart = ref("20 ส.ค. 2566") const dateStart = ref("20 ส.ค. 2566");
const dateEnd = ref("21 ส.ค. 2566") const dateEnd = ref("21 ส.ค. 2566");
const numDate = ref("20") const numDate = ref("20");
const place = ref("บ้าน") const place = ref("บ้าน");
const phone = ref("000-00000000") const phone = ref("000-00000000");
const reason = ref("ยกเลิกการลา") const reason = ref("ยกเลิกการลา");
const model = ref(null) const model = ref(null);
const modeCancel = ref(true) const modeCancel = ref(true);
/** รับ props มาจากหน้าหลัก */ const dateMonth = ref<DataDateMonthObject>({
const props = defineProps({ month: new Date().getMonth(),
dateYear: { year: new Date().getFullYear(),
//filter });
type: Number,
default: () => new Date().getFullYear(),
},
dateMonth: {
//filter
type: Number,
default: () => new Date().getMonth(),
},
// refreshData: {
// // main refresh data
// type: Boolean,
// required: true,
// },
fetchDataSummaryCalendar: {
//
type: Function,
default: () => console.log("not function"),
},
})
const dateYear = ref<number>(new Date().getFullYear());
const emit = defineEmits(["update:dateYear"]);
const mixin = useCounterMixin(); //
const { monthYear2Thai } = mixin;
/** /**
* เรยกฟงกนทงหมดตอนเรยกใชไฟล * แปลง และเดอนเปนภาษาไทย
* @param val datepicker แบบเลอกปและเดอน
*/ */
onMounted(async () => { const monthYearThai = (val: DataDateMonthObject) => {
if (fullCalendar !== undefined) { if (val == null) return "";
const calen = fullCalendar.value.getApi() else return monthYear2Thai(val.month, val.year);
const date = new Date(props.dateYear, props.dateMonth) };
calen.gotoDate(date)
const updateMonth = async (e: DataDateMonthObject) => {
// console.log(dateMonth.value);
if (e != null) {
dateYear.value = e.year;
emit("update:dateYear", e.year);
const calen = fullCalendar.value.getApi();
const date = new Date(dateMonth.value.year, dateMonth.value.month);
calen.gotoDate(date);
} }
}) };
/**
* props(นเดอนปเลอก) ตอนอพเดท าฏนใหพเดทใหม
*/
watch(props, async (count, prevCount) => {
const calen = fullCalendar.value.getApi()
const date = new Date(props.dateYear, props.dateMonth)
calen.gotoDate(date)
})
/** /**
* งกนยกเล model * งกนยกเล model
* @param text * @param text
*/ */
const cancel = async (text: string) => { const cancel = async (text: string) => {
title.value = text title.value = text;
modalCancel.value = true modalCancel.value = true;
modeCancel.value = true modeCancel.value = true;
} };
/** /**
* งกนเป model * งกนเป model
* @param text * @param text
*/ */
const view = async (text: string) => { const view = async (text: string) => {
title.value = text title.value = text;
modalCancel.value = true modalCancel.value = true;
modeCancel.value = false modeCancel.value = false;
} };
// filter calendar left
const filterLists = ref<any[]>([
{
id: "x1",
name: "นางสาววารุณี แต้มคู",
color: "green",
},
{
id: "x2",
name: "นางสาวสมศรี ใจดี",
color: "grey",
},
{
id: "x3",
name: "นายสมชาย สุขใจ",
color: "grey",
},
]);
const filterVal = ref(["x1"]);
</script> </script>
<template> <template>
<div class="row">
<!-- Filter ตามคนและประเภทการลา -->
<div class="col-sm-12 col-md-3 q-mt-sm q-pr-sm">
<q-card class="col-12">
<div class="q-gutter-sm">
<q-list bordered class="rounded-borders">
<!-- <q-item-label header>User</q-item-label> -->
<q-item
v-for="(item, i) in filterLists"
:key="i"
tag="label"
v-ripple
>
<q-checkbox
size="sm"
v-model="filterVal"
:val="item.id"
:color="item.color"
/>
<q-item-section>
<q-item-label>{{ item.name }}</q-item-label>
</q-item-section>
</q-item>
</q-list>
</div>
<!-- show value filterVal -->
<!-- <div class="q-px-sm q-mt-sm">
Your selection is: <strong>{{ filterVal }}</strong>
</div> -->
</q-card>
</div>
<div class="col-sm-12 col-md-9">
<div class="q-mt-sm"> <div class="q-mt-sm">
<div class="row q-gutter-sm q-pb-sm main-content"> <div class="row col-12 q-gutter-sm">
<div class="demo-app-main"> <div class="demo-app-main">
<FullCalendar ref="fullCalendar" class="demo-app-calendar" :options="calendarOptions"> <q-card bordered flat class="q-pa-sm col-12 row bg-grey-1 shadow-0">
<div class="items-center col-12 row q-col-gutter-sm">
<!-- filter เลอกเดอนป -->
<datepicker
v-model="dateMonth"
:locale="'th'"
autoApply
month-picker
:enableTimePicker="false"
@update:modelValue="updateMonth"
>
<template #year="{ year }">{{ year + 543 }}</template>
<template #year-overlay-value="{ value }">{{
parseInt(value + 543)
}}</template>
<template #trigger>
<q-input
:model-value="monthYearThai(dateMonth)"
dense
outlined
bg-color="white"
style="width: 130px"
>
<template v-slot:prepend>
<q-icon
name="event"
class="cursor-pointer"
style="color: var(--q-primary)"
>
</q-icon>
</template>
</q-input>
</template>
</datepicker>
</div>
</q-card>
<div class="main-content">
<FullCalendar
ref="fullCalendar"
class="demo-app-calendar"
:options="calendarOptions"
>
<template v-slot:eventContent="arg"> <template v-slot:eventContent="arg">
<div class="row col-12 items-center no-wrap" :style="`background: + ${arg.event.color}`"> <div
class="row col-12 items-center no-wrap"
:style="`background: + ${arg.event.color}`"
>
<!-- <b>{{ arg.timeText }}</b> --> <!-- <b>{{ arg.timeText }}</b> -->
<div class="textHover col-10" @click="view(arg.event.title)">{{ arg.event.title }}</div> <div
<q-btn dense v-if="arg.event.groupId == 1" icon="mdi-close" flat round size="8px" @click="cancel(arg.event.title)" /> class="textHover col-10"
@click="view(arg.event.title)"
>
{{ arg.event.title }}
</div>
<q-btn
dense
v-if="arg.event.groupId == 1"
icon="mdi-close"
flat
round
size="8px"
@click="cancel(arg.event.title)"
/>
</div> </div>
</template> </template>
</FullCalendar> </FullCalendar>
</div> </div>
</div> </div>
</div>
<div class="row q-col-gutter-lg justify-end"> <div class="row q-col-gutter-lg justify-end">
<div class="items-center row"> <div class="items-center row">
<q-icon size="10px" color="light-green" name="mdi-circle" class="q-mr-sm" /> <q-icon
<span class="text-caption text-grey-8">สถานะอน</span> size="10px"
color="green-7"
name="mdi-circle"
class="q-mr-sm"
/>
<span class="text-caption text-grey-8">การลาของฉ</span>
</div> </div>
<div class="items-center row"> <div class="items-center row">
<q-icon size="10px" color="red-6" name="mdi-circle" class="q-mr-sm" /> <q-icon
<span class="text-caption text-grey-8">สถานะไมอน</span> size="10px"
color="grey-6"
name="mdi-circle"
class="q-mr-sm"
/>
<span class="text-caption text-grey-8">การลาของบคคลอ</span>
</div> </div>
<div class="items-center row"> <!-- <div class="items-center row">
<q-icon size="10px" color="light-blue-14" name="mdi-circle" class="q-mr-sm" /> <q-icon size="10px" color="light-blue-14" name="mdi-circle" class="q-mr-sm" />
<span class="text-caption text-grey-8">สถานะอยระหวางดำเนนการ</span> <span class="text-caption text-grey-8">สถานะอยระหวางดำเนนการ</span>
</div> </div>
<div class="items-center row"> <div class="items-center row">
<q-icon size="10px" color="orange" name="mdi-circle" class="q-mr-sm" /> <q-icon size="10px" color="orange" name="mdi-circle" class="q-mr-sm" />
<span class="text-caption text-grey-8">สถานะใหม</span> <span class="text-caption text-grey-8">สถานะใหม</span>
</div> -->
</div>
</div> </div>
</div> </div>
</div> </div>
<!-- modal ขอยกเล/รายละเอยด --> <!-- modal รายละเอยด -->
<q-dialog v-model="modalCancel" persistent> <q-dialog v-model="modalCancel" persistent>
<q-card :style="modeCancel == true ? 'min-width: 50%;' : 'min-width:30%'"> <q-card :style="modeCancel == true ? 'min-width: 50%;' : 'min-width:30%'">
<q-card-section class="row items-center q-pa-sm"> <q-card-section class="row items-center q-pa-sm">
<div v-if="modeCancel == false" class="text-bold q-pl-sm">รายละเอียดของ{{ title }}</div> <div v-if="modeCancel == false" class="text-bold q-pl-sm">
รายละเอยดของ{{ title }}
</div>
<div v-else class="text-bold q-pl-sm">ขอยกเล{{ title }}</div> <div v-else class="text-bold q-pl-sm">ขอยกเล{{ title }}</div>
<q-space /> <q-space />
<q-btn icon="close" unelevated round dense v-close-popup style="color: #ff8080; background-color: #ffdede" /> <q-btn
icon="close"
unelevated
round
dense
v-close-popup
style="color: #ff8080; background-color: #ffdede"
/>
</q-card-section> </q-card-section>
<q-separator /> <q-separator />
<q-card-section class="q-p-md row q-gutter-y-md"> <q-card-section class="q-p-md row q-gutter-y-md">
@ -195,8 +342,21 @@ const view = async (text: string) => {
</div> </div>
</div> </div>
<div flat class="col-xs-6 col-sm-6" v-if="modeCancel == true"> <div flat class="col-xs-6 col-sm-6" v-if="modeCancel == true">
<q-input v-model="reason" type="textarea" label="กรอกเหตุผล" outlined dense /> <q-input
<q-file outlined v-model="model" label="เลือกไฟล์เอกสารหลักฐาน" class="q-mt-md" use-chips dense> v-model="reason"
type="textarea"
label="กรอกเหตุผล"
outlined
dense
/>
<q-file
outlined
v-model="model"
label="เลือกไฟล์เอกสารหลักฐาน"
class="q-mt-md"
use-chips
dense
>
<template v-slot:prepend> <template v-slot:prepend>
<q-icon name="attach_file" /> <q-icon name="attach_file" />
</template> </template>
@ -204,9 +364,19 @@ const view = async (text: string) => {
</div> </div>
</q-card-section> </q-card-section>
<q-separator /> <q-separator />
<q-card-section class="row items-center q-pa-sm" v-if="modeCancel == true"> <q-card-section
class="row items-center q-pa-sm"
v-if="modeCancel == true"
>
<q-space /> <q-space />
<q-btn label="ยืนยัน" unelevated color="secondary" dense class="q-px-md" v-close-popup /> <q-btn
label="ยืนยัน"
unelevated
color="secondary"
dense
class="q-px-md"
v-close-popup
/>
</q-card-section> </q-card-section>
</q-card> </q-card>
</q-dialog> </q-dialog>
@ -214,11 +384,7 @@ const view = async (text: string) => {
<style scope lang="scss"> <style scope lang="scss">
.main-content { .main-content {
height: 65vh; height: 70vh;
}
.color-main {
color: #18a259;
} }
.padding-content { .padding-content {
@ -373,6 +539,6 @@ const view = async (text: string) => {
} }
.textHover:hover { .textHover:hover {
color: #18a259; color: var(--q-primary);
} }
</style> </style>

View file

@ -1,67 +1,68 @@
<script setup lang="ts"> <script setup lang="ts">
import type { QTableProps } from "quasar" import type { QTableProps } from "quasar";
import { ref, onMounted } from "vue" import { ref, onMounted } from "vue";
import Table from "@/modules/05_leave/componenst/Table.vue" import Table from "@/modules/05_leave/componenst/Table.vue";
import { useLeaveStore } from "@/modules/05_leave/store" import { useLeaveStore } from "@/modules/05_leave/store";
const LeaveData = useLeaveStore() const LeaveData = useLeaveStore();
const { fecthList, searchFilterTable } = LeaveData const { fecthList, searchFilterTable } = LeaveData;
const filter = ref<string>("") const filter = ref<string>("");
/** /**
* งค pagination * งค pagination
*/ */
const initialPagination = ref({ const initialPagination = ref({
rowsPerPage: 0, rowsPerPage: 0,
}) });
/** /**
* mocking าในตวแปร * mocking าในตวแปร
*/ */
const modalCancel = ref(false) const modalCancel = ref(false);
const title = ref("") const title = ref("");
const location = ref("บ้าน") const location = ref("บ้าน");
const subject = ref("ลาป่วย") const subject = ref("ลาป่วย");
const dateStart = ref("20 ส.ค. 2566") const dateStart = ref("20 ส.ค. 2566");
const dateEnd = ref("21 ส.ค. 2566") const dateEnd = ref("21 ส.ค. 2566");
const numDate = ref("20") const numDate = ref("20");
const place = ref("บ้าน") const place = ref("บ้าน");
const phone = ref("000-00000000") const phone = ref("000-00000000");
const reason = ref("ยกเลิกการลา") const reason = ref("ยกเลิกการลา");
const model = ref(null) const writeAt = ref<string>("");
const modeCancel = ref(true) const model = ref(null);
const modeCancel = ref(true);
/** /**
* งกนยกเล model * งกนยกเล model
* @param text * @param text
*/ */
const cancel = async (text: string) => { const cancel = async (text: string) => {
title.value = text title.value = text;
modalCancel.value = true modalCancel.value = true;
modeCancel.value = true modeCancel.value = true;
} };
/** /**
* งกนเป model * งกนเป model
* @param text * @param text
*/ */
const view = async (text: string) => { const view = async (text: string) => {
title.value = text title.value = text;
modalCancel.value = true modalCancel.value = true;
modeCancel.value = false modeCancel.value = false;
} };
/** /**
* เรยกฟงกนทงหมดตอนเรยกใชไฟล * เรยกฟงกนทงหมดตอนเรยกใชไฟล
*/ */
onMounted(async () => { onMounted(async () => {
searchFilterTable() searchFilterTable();
fecthList([ fecthList([
{ no: "1", date: "2023-09-20", type: "1", status: "4", year: "1" }, { no: "1", date: "2023-09-20", type: "1", status: "4", year: "1" },
{ no: "2", date: "2023-09-19", type: "1", status: "2", year: "1" }, { no: "2", date: "2023-09-19", type: "1", status: "2", year: "1" },
{ no: "3", date: "2023-09-10", type: "2", status: "3", year: "1" }, { no: "3", date: "2023-09-10", type: "2", status: "3", year: "1" },
]) ]);
}) });
</script> </script>
<template> <template>
<Table <Table
@ -91,14 +92,47 @@ onMounted(async () => {
<q-td key="status" :props="props"> <q-td key="status" :props="props">
<div class="col-12 row items-center"> <div class="col-12 row items-center">
<div @click="view(props.row.type)"> <div @click="view(props.row.type)">
<q-icon v-if="props.row.status == 'อนุมัติ'" size="10px" color="light-green" name="mdi-circle" class="q-mr-sm" /> <q-icon
<q-icon v-else-if="props.row.status == 'ไม่อนุมัติ'" size="10px" color="red-6" name="mdi-circle" class="q-mr-sm" /> v-if="props.row.status == 'อนุมัติ'"
<q-icon v-else-if="props.row.status == 'อยู่ระหว่างดำเนินการ'" size="10px" color="light-blue-14" name="mdi-circle" class="q-mr-sm" /> size="10px"
<q-icon v-else-if="props.row.status == 'ใหม่'" size="10px" color="orange" name="mdi-circle" class="q-mr-sm" /> color="light-green"
name="mdi-circle"
class="q-mr-sm"
/>
<q-icon
v-else-if="props.row.status == 'ไม่อนุมัติ'"
size="10px"
color="red-6"
name="mdi-circle"
class="q-mr-sm"
/>
<q-icon
v-else-if="props.row.status == 'อยู่ระหว่างดำเนินการ'"
size="10px"
color="light-blue-14"
name="mdi-circle"
class="q-mr-sm"
/>
<q-icon
v-else-if="props.row.status == 'ใหม่'"
size="10px"
color="orange"
name="mdi-circle"
class="q-mr-sm"
/>
<span class="q-pr-md">{{ props.row.status }}</span> <span class="q-pr-md">{{ props.row.status }}</span>
</div> </div>
<q-space /> <q-space />
<q-btn v-if="props.row.status == 'ใหม่'" label="ขอยกเลิก" @click="cancel(props.row.type)" size="13px" class="q-px-sm" outline dense color="orange" /> <q-btn
v-if="props.row.status == 'ใหม่'"
label="ขอยกเลิก"
@click="cancel(props.row.type)"
size="13px"
class="q-px-sm"
outline
dense
color="orange"
/>
</div> </div>
</q-td> </q-td>
</q-tr> </q-tr>
@ -109,17 +143,24 @@ onMounted(async () => {
<q-dialog v-model="modalCancel" persistent> <q-dialog v-model="modalCancel" persistent>
<q-card :style="modeCancel == true ? 'min-width: 50%;' : 'min-width:30%'"> <q-card :style="modeCancel == true ? 'min-width: 50%;' : 'min-width:30%'">
<q-card-section class="row items-center q-pa-sm"> <q-card-section class="row items-center q-pa-sm">
<div v-if="modeCancel == false" class="text-bold q-pl-sm">รายละเอียดของ{{ title }}</div> <div v-if="modeCancel == false" class="text-bold q-pl-sm">
รายละเอยดของ{{ title }}
</div>
<div v-else class="text-bold q-pl-sm">ขอยกเล{{ title }}</div> <div v-else class="text-bold q-pl-sm">ขอยกเล{{ title }}</div>
<q-space /> <q-space />
<q-btn icon="close" unelevated round dense v-close-popup style="color: #ff8080; background-color: #ffdede" /> <q-btn
icon="close"
unelevated
round
dense
v-close-popup
style="color: #ff8080; background-color: #ffdede"
/>
</q-card-section> </q-card-section>
<q-separator /> <q-separator />
<q-card-section class="q-p-md row q-gutter-y-md"> <q-card-section class="q-p-md row q-gutter-y-md">
<div flat :class="modeCancel == true ? 'col-xs-6 col-sm-6' : 'col-12'"> <div flat :class="modeCancel == true ? 'col-xs-6 col-sm-6' : 'col-12'">
<div class="col-12 q-col-gutter-sm row items-center"> <div class="col-12 q-col-gutter-sm row items-center">
<div class="col-6 text-grey-7">เขยนท</div>
<div class="col-6 text-black">{{ location }}</div>
<div class="col-6 text-grey-7">เรองและเหตผลการลา</div> <div class="col-6 text-grey-7">เรองและเหตผลการลา</div>
<div class="col-6 text-black">{{ subject }}</div> <div class="col-6 text-black">{{ subject }}</div>
<div class="col-6 text-grey-7"> เดอน เรมต</div> <div class="col-6 text-grey-7"> เดอน เรมต</div>
@ -135,8 +176,23 @@ onMounted(async () => {
</div> </div>
</div> </div>
<div flat class="col-xs-6 col-sm-6" v-if="modeCancel == true"> <div flat class="col-xs-6 col-sm-6" v-if="modeCancel == true">
<q-input v-model="reason" type="textarea" label="กรอกเหตุผล" outlined dense /> <q-input v-model="writeAt" label="เขียนที่" outlined dense />
<q-file outlined v-model="model" label="เลือกไฟล์เอกสารหลักฐาน" class="q-mt-md" use-chips dense> <q-input
v-model="reason"
type="textarea"
label="กรอกเหตุผล"
class="q-mt-md"
outlined
dense
/>
<q-file
outlined
v-model="model"
label="เลือกไฟล์เอกสารหลักฐาน"
class="q-mt-md"
use-chips
dense
>
<template v-slot:prepend> <template v-slot:prepend>
<q-icon name="attach_file" /> <q-icon name="attach_file" />
</template> </template>
@ -144,9 +200,19 @@ onMounted(async () => {
</div> </div>
</q-card-section> </q-card-section>
<q-separator /> <q-separator />
<q-card-section class="row items-center q-pa-sm" v-if="modeCancel == true"> <q-card-section
class="row items-center q-pa-sm"
v-if="modeCancel == true"
>
<q-space /> <q-space />
<q-btn label="ยืนยัน" unelevated color="secondary" dense class="q-px-md" v-close-popup /> <q-btn
label="ยืนยัน"
unelevated
color="secondary"
dense
class="q-px-md"
v-close-popup
/>
</q-card-section> </q-card-section>
</q-card> </q-card>
</q-dialog> </q-dialog>

View file

@ -2,8 +2,8 @@
import { ref, useAttrs, reactive, onMounted } from "vue" import { ref, useAttrs, reactive, onMounted } from "vue"
import { useLeaveStore } from "@/modules/05_leave/store" import { useLeaveStore } from "@/modules/05_leave/store"
const LeaveData = useLeaveStore() const leaveStore = useLeaveStore()
const { filterSelector, searchFilterTable } = LeaveData const { filterSelector, searchFilterTable } = leaveStore
const attrs = ref<any>(useAttrs()) const attrs = ref<any>(useAttrs())
const table = ref<any>(null) const table = ref<any>(null)
const filterRef = ref<any>(null) const filterRef = ref<any>(null)
@ -59,18 +59,38 @@ const resetFilter = () => {
<div class="q-py-sm row"> <div class="q-py-sm row">
<q-card bordered flat class="q-py-sm q-pl-sm col-12 row bg-grey-1 shadow-0"> <q-card bordered flat class="q-py-sm q-pl-sm col-12 row bg-grey-1 shadow-0">
<div class="items-center col-12 row q-col-gutter-sm"> <div class="items-center col-12 row q-col-gutter-sm">
<q-select
v-if="leaveStore.tabValue === 'list'"
outlined
dense
lazy-rules
v-model="leaveStore.fiscalYearyear"
:label="`${'ปี พ.ศ.'}`"
emit-value
map-options
option-label="name"
:options="leaveStore.fiscalyearOP"
option-value="id"
hide-bottom-space
style="min-width: 150px"
class="col-xs-12 col-sm-auto"
@update:model-value="searchFilterTable"
@filter="(inputValue:any,
doneFn:Function) => filterSelector(inputValue, doneFn,'fiscalyearOP'
) "
/>
<!-- นหาขอความใน table --> <!-- นหาขอความใน table -->
<q-select <q-select
outlined outlined
dense dense
lazy-rules lazy-rules
v-model="LeaveData.LeaveType" v-model="leaveStore.LeaveType"
:rules="[val => !!val || `${'กรุณาเลือกประเภทใบลา'}`]" :rules="[val => !!val || `${'กรุณาเลือกประเภทใบลา'}`]"
:label="`${'ประเภทใบลา'}`" :label="`${'ประเภทใบลา'}`"
emit-value emit-value
map-options map-options
option-label="name" option-label="name"
:options="LeaveData.typeOptions" :options="leaveStore.typeOptions"
option-value="id" option-value="id"
hide-bottom-space hide-bottom-space
style="min-width: 150px" style="min-width: 150px"
@ -84,13 +104,13 @@ const resetFilter = () => {
outlined outlined
dense dense
lazy-rules lazy-rules
v-model="LeaveData.LeaveStatus" v-model="leaveStore.LeaveStatus"
:rules="[val => !!val || `${'กรุณาเลือกสถานะ'}`]" :rules="[val => !!val || `${'กรุณาเลือกสถานะ'}`]"
:label="`${'สถานะ'}`" :label="`${'สถานะ'}`"
emit-value emit-value
map-options map-options
option-label="name" option-label="name"
:options="LeaveData.statusOptions" :options="leaveStore.statusOptions"
option-value="id" option-value="id"
hide-bottom-space hide-bottom-space
style="min-width: 150px" style="min-width: 150px"

View file

@ -1,374 +0,0 @@
<script setup lang="ts">
import { ref, onMounted } from "vue"
import { useQuasar } from "quasar"
import { useRouter, useRoute } from "vue-router"
import { useCounterMixin } from "@/stores/mixin"
import { useLeaveStore } from "@/modules/05_leave/store"
import http from "@/plugins/http"
import config from "@/app.config"
import type { QForm } from "quasar"
const mixin = useCounterMixin()
const dataStore = useLeaveStore()
const { date2Thai, dateToISO, success, messageError, showLoader, hideLoader } = mixin
const router = useRouter()
const route = useRoute()
const myform = ref<QForm | null>(null)
const $q = useQuasar()
const routeName = router.currentRoute.value.name
const id = ref<string>("")
const fileDocDataUpload = ref<File[]>([])
const files = ref<any>()
const locationAbsence = ref<string>("")
const levelStudy = ref<string>("")
const degree = ref<string>("")
const major = ref<string>("")
const educational = ref<string>("")
const studyPeriod = ref<string>("")
const country = ref<string>("")
const capital = ref<string>("")
const tel = ref<number>()
const detail = ref<string>()
const Writeat = ref<string>()
const dateLeaveStart = ref<Date>(new Date())
const dateLeaveEnd = ref<Date>(new Date())
const dateTotal = ref<number>()
const noteReason = ref("")
const nameFile = ref<string>("")
const model = ref(null)
const modelSpecific = ref(null)
const options = ref([
{ id: "0", name: "ลาป่วย" },
{ id: "1", name: "ลากิจส่วนตัว" },
{ id: "2", name: "ลาคลอดบุตร" },
{ id: "3", name: "ลาไปช่วยเหลือภริยาที่คลอดบุตร" },
{ id: "4", name: "ลาพักผ่อน" },
{ id: "5", name: "ลาอุปสมบทหรือลาประกอบพิธีฮัจย์ฯ" },
{ id: "6", name: "ลาเข้ารับการตรวจเลือกหรือเข้ารับการเตรียมพล" },
{ id: "7", name: "ลาไปศึกษา ฝึกอบรม ปฎิบัติการวิจัย หรือดูงาน" },
{ id: "8", name: "ลาไปปฎิบัติงานในองค์การระหว่างประเทศ" },
{ id: "9", name: "ลาติดตามคู่สมรส" },
{ id: "10", name: "ลาไปฟื้นฟูสมรรถภาพด้านอาชีพ" },
])
const optionsSpecific = ref([
{ id: "0", name: "ลาไปศึกษา" },
{ id: "1", name: "ฝึกอบรม" },
{ id: "2", name: "ปฎิบัติการวิจัย" },
{ id: "3", name: "ดูงาน" },
])
const dataDetail = ref<any>({
datetext: "",
activeDate: new Date(),
createdAt: new Date(),
firstName: "",
id: "",
isActive: true,
lastName: "",
location: "",
organizationPositionOld: "",
positionLevelOld: "",
positionNumberOld: "",
positionTypeOld: "",
prefix: "",
profileId: "",
reason: "",
salary: 0,
sendDate: new Date(),
status: "",
statustext: "",
fullname: "",
})
const clickBack = () => {
router.push(`/leave`)
}
onMounted(() => {})
const saveAbsence = () => {
$q.dialog({
title: "ยืนยันการยื่นใบลา",
message: "ต้องการยืนยันการยื่นใบลานี้ใช่หรือไม่?",
cancel: {
flat: true,
color: "negative",
},
persistent: true,
})
.onOk(() => {
// createFormresign()
if (model.value !== "ลาไปศึกษา ฝึกอบรม ปฎิบัติการวิจัย หรือดูงาน") {
console.log(1)
} else if (model.value === "ลาไปศึกษา ฝึกอบรม ปฎิบัติการวิจัย หรือดูงาน") {
console.log(2)
}
router.push(`/leave`)
})
.onCancel(() => {})
.onDismiss(() => {})
}
</script>
<template>
<div class="col-12 row justify-center">
<div class="col-xs-12 col-sm-12 col-md-11">
<div class="toptitle text-white col-12 row items-center">
<q-btn icon="mdi-arrow-left" unelevated round dense flat color="primary" class="q-mr-sm" @click="clickBack" />
<div>นใบลา</div>
</div>
<q-form ref="myform" class="col-12">
<q-card bordered>
<div class="col-12 row q-col-gutter-md q-pa-md">
<div class="col-xs-12 col-sm-12">
<q-icon name="mdi-numeric-1-circle" size="20px" color="primary" />
<div class="q-pl-sm text-weight-bold text-dark">เลอกประเภทการลา</div>
<div class="col-12 row q-pa-sm q-col-gutter-sm">
<q-select dense class="q-ml-lg col-6" outlined v-model="model" :options="dataStore.optionsSpecific" prefix="ประเภทใบลา :" />
<div class="col-6 row q-pa-sm" v-if="model == 'ลาไปศึกษา ฝึกอบรม ปฎิบัติการวิจัย หรือดูงาน'">
<q-select dense class="q-ml-lg col-6" outlined v-model="modelSpecific" :options="optionsSpecific" prefix="ประเภทใบลา :" />
</div>
</div>
<q-icon name="mdi-numeric-2-circle" size="20px" color="primary" v-if="model == 'ลาไปศึกษา ฝึกอบรม ปฎิบัติการวิจัย หรือดูงาน'" />
<div class="q-pl-sm text-weight-bold text-dark" v-if="model == 'ลาไปศึกษา ฝึกอบรม ปฎิบัติการวิจัย หรือดูงาน'">เลือกประเภทใบลาศึกษา ฝึกอบรม ปฎิบัติการวิจัย หรือดูงาน</div>
<div class="col-12 row q-pa-sm q-col-gutter-sm" v-if="model == 'ลาไปศึกษา ฝึกอบรม ปฎิบัติการวิจัย หรือดูงาน'">
<q-select dense class="q-ml-lg col-6" outlined v-model="modelSpecific" :options="optionsSpecific" prefix="ประเภทใบลา :" />
</div>
<q-icon name="mdi-numeric-2-circle" size="20px" color="primary" v-else />
<q-icon name="mdi-numeric-3-circle" size="20px" color="primary" v-if="model == 'ลาไปศึกษา ฝึกอบรม ปฎิบัติการวิจัย หรือดูงาน'" />
<div class="q-pl-sm text-weight-bold text-dark">กรอกขอม</div>
<q-card bordered class="q-pa-md bg-grey-1">
<div class="col-12 row q-pa-sm q-col-gutter-sm">
<datepicker
class="col-2"
menu-class-name="modalfix"
v-model="dateLeaveStart"
:locale="'th'"
autoApply
borderless
:enableTimePicker="false"
week-start="0"
:readonly="routeName != 'addAbsence'"
>
<template #year="{ year }">
{{ year + 543 }}
</template>
<template #year-overlay-value="{ value }">
{{ parseInt(value + 543) }}
</template>
<template #trigger>
<q-input
outlined
dense
hide-bottom-space
:readonly="routeName != 'addAbsence'"
class="full-width datepicker"
:model-value="dateLeaveStart != null ? date2Thai(dateLeaveStart) : null"
:label="`${'วันที่เริ่ม'}`"
:rules="[val => !!val || `${'กรุณาเลือกวันที่เริ่มลา'}`]"
>
<template v-slot:prepend>
<q-icon name="event" class="cursor-pointer" style="color: var(--q-primary)"> </q-icon>
</template>
</q-input>
</template>
</datepicker>
<datepicker
class="col-2"
menu-class-name="modalfix"
v-model="dateLeaveEnd"
:locale="'th'"
autoApply
borderless
:enableTimePicker="false"
week-start="0"
:readonly="routeName != 'addAbsence'"
>
<template #year="{ year }">
{{ year + 543 }}
</template>
<template #year-overlay-value="{ value }">
{{ parseInt(value + 543) }}
</template>
<template #trigger>
<q-input
outlined
dense
hide-bottom-space
:readonly="routeName != 'addAbsence'"
class="full-width datepicker"
:model-value="dateLeaveEnd != null ? date2Thai(dateLeaveEnd) : null"
:label="`${'จนถึงวันที่'}`"
:rules="[val => !!val || `${'กรุณาเลือกวันที่่สิ้นสุดการลา'}`]"
>
<template v-slot:prepend>
<q-icon name="event" class="cursor-pointer" style="color: var(--q-primary)"> </q-icon>
</template>
</q-input>
</template>
</datepicker>
<q-input
class="col-2"
dense
outlined
type="number"
v-model="dateTotal"
label="จำนวนวัน(บันทึกลง ก.พ.7)"
:readonly="routeName != 'addAbsence'"
:rules="[val => !!val || `${'กรุณากรอกจำนวนวัน'}`]"
/>
<q-input class="col-3" dense outlined v-model="Writeat" label="เขียนที่" :readonly="routeName != 'addAbsence'" :rules="[val => !!val || `${'เขียนที่'}`]" />
<q-input
class="col-3"
dense
outlined
v-model="tel"
mask="(###)-###-####"
unmasked-value
label="หมายเลขโทรศัพท์ที่ติดต่อได้"
:readonly="routeName != 'addAbsence'"
:rules="[val => !!val || `${'กรุณากรอกหมายเลขโทรศัพท์ที่ติดต่อได้'}`]"
/>
<q-input
class="col-6"
dense
outlined
v-model="detail"
label="รายละเอียด"
:readonly="routeName != 'addAbsence'"
:rules="[val => !!val || `${'กรุณากรอกรายละเอียด'}`]"
/>
<q-input
class="col-6"
dense
outlined
v-model="locationAbsence"
label="สถาที่ติดต่อขณะลา"
:readonly="routeName != 'addAbsence'"
:rules="[val => !!val || `${'กรุณากรอกสถาที่ติดต่อขณะลา'}`]"
/>
<q-input
class="col-4"
v-if="model == 'ลาไปศึกษา ฝึกอบรม ปฎิบัติการวิจัย หรือดูงาน'"
dense
outlined
v-model="levelStudy"
label="ระดับที่ขอลาศึกษา"
:readonly="routeName != 'addAbsence'"
/>
<q-input
class="col-4"
v-if="model == 'ลาไปศึกษา ฝึกอบรม ปฎิบัติการวิจัย หรือดูงาน'"
dense
outlined
v-model="degree"
label="ชื่อปริญญา/ประกาศนียบัตร"
:readonly="routeName != 'addAbsence'"
/>
<q-input
class="col-4"
v-if="model == 'ลาไปศึกษา ฝึกอบรม ปฎิบัติการวิจัย หรือดูงาน'"
dense
outlined
v-model="major"
label="สาขาวิชาเอก/หลักสูตร/วิชา"
:readonly="routeName != 'addAbsence'"
/>
<q-input
class="col-4"
v-if="model == 'ลาไปศึกษา ฝึกอบรม ปฎิบัติการวิจัย หรือดูงาน'"
dense
outlined
v-model="educational"
label="ณ สถานศึกษา"
:readonly="routeName != 'addAbsence'"
/>
<q-input
class="col-4"
v-if="model == 'ลาไปศึกษา ฝึกอบรม ปฎิบัติการวิจัย หรือดูงาน'"
dense
outlined
v-model="studyPeriod"
label="ระยะเวลาในการศึกษาตลอดหลักสูตร"
:readonly="routeName != 'addAbsence'"
/>
<q-input
class="col-4"
v-if="model == 'ลาไปศึกษา ฝึกอบรม ปฎิบัติการวิจัย หรือดูงาน'"
dense
outlined
v-model="country"
label="ประเทศ"
:readonly="routeName != 'addAbsence'"
/>
<q-input
class="col-4"
v-if="model == 'ลาไปศึกษา ฝึกอบรม ปฎิบัติการวิจัย หรือดูงาน'"
dense
outlined
v-model="capital"
label="ด้วยทุน"
:readonly="routeName != 'addAbsence'"
/>
<q-input
class="col-8"
v-if="model == 'ลาไปศึกษา ฝึกอบรม ปฎิบัติการวิจัย หรือดูงาน'"
dense
outlined
v-model="noteReason"
label="ที่มาของหลักสูตร"
:readonly="routeName != 'addAbsence'"
/>
<q-file v-model="files" dense label="เอกสารประกอบ" outlined use-chips multiple class="q-pl-sm col-6">
<template v-slot:prepend>
<q-icon name="attach_file" color="primary" />
</template>
</q-file>
<div class="col-12 row" v-if="routeName != 'addAbsence'">
<div class="bg-grey-1 q-pa-sm col-12 row items-center text-primary">
<div class="q-pl-sm text-weight-bold text-dark">เอกสารเพมเต</div>
</div>
<q-card bordered flat class="full-width">
<q-list separator>
<q-item v-for="file in files" :key="file.key" class="q-my-xs">
<q-item-section>
<q-item-label class="full-width ellipsis">
{{ file.fileName }}
</q-item-label>
<q-item-label caption> </q-item-label>
</q-item-section>
</q-item>
</q-list>
</q-card>
</div>
</div>
</q-card>
</div>
</div>
<q-separator />
<div class="row col-12 q-pa-md">
<q-space />
<q-btn unelevated dense class="q-px-md items-center btnBlue" label="บันทึก" @click="saveAbsence" />
</div>
</q-card>
</q-form>
</div>
</div>
</template>
<style scoped lang="scss">
.btnBlue {
background-color: #016987;
color: #fff;
}
</style>

View file

@ -1,19 +1,24 @@
import { defineStore } from "pinia" import { defineStore } from "pinia";
import { ref, computed } from "vue" import { ref, computed } from "vue";
import type { QTableProps } from "quasar" import type { QTableProps } from "quasar";
import type { FormLeavetMainData, OptionData, formListLeaveData } from "@/modules/05_leave/interface/index/main" import type {
import { useCounterMixin } from "@/stores/mixin" FormLeavetMainData,
OptionData,
formListLeaveData,
} from "@/modules/05_leave/interface/index/main";
import { useCounterMixin } from "@/stores/mixin";
export const useLeaveStore = defineStore("Leave", () => { export const useLeaveStore = defineStore("Leave", () => {
const tabValue = ref<string>("calendar"); const tabValue = ref<string>("calendar");
const typeLeave = ref<string|undefined>('') const typeLeave = ref<string | undefined>("");
const mixin = useCounterMixin() const mixin = useCounterMixin();
const { date2Thai } = mixin const { date2Thai } = mixin;
const LeaveType = ref<string | null>("0") const LeaveType = ref<string | null>("0");
const LeaveStatus = ref<string | null>("0") const LeaveStatus = ref<string | null>("0");
const fiscalYearyear = ref<string | null>("0") const fiscalYearyear = ref<string | null>("0");
const rows = ref<formListLeaveData[]>([]) const rows = ref<formListLeaveData[]>([]);
const DataMainOrig = ref<formListLeaveData[]>([]) // ข้อมูลหลักดั้งเดิม const DataMainOrig = ref<formListLeaveData[]>([]); // ข้อมูลหลักดั้งเดิม
async function fecthList(data: formListLeaveData[]) { async function fecthList(data: formListLeaveData[]) {
let datalist: formListLeaveData[] = data.map((e: any) => ({ let datalist: formListLeaveData[] = data.map((e: any) => ({
no: e.no, no: e.no,
@ -21,193 +26,227 @@ export const useLeaveStore = defineStore("Leave", () => {
status: e.status, status: e.status,
date: e.date, date: e.date,
year: e.year, year: e.year,
})) }));
rows.value = datalist rows.value = datalist;
DataMainOrig.value = datalist DataMainOrig.value = datalist;
} }
const DataMainUpdate = ref<formListLeaveData[]>([]) // ข้อมูลเปลี่ยนแปลง
const DataMain = (val: formListLeaveData[]) => (DataMainOrig.value = val) const DataMainUpdate = ref<formListLeaveData[]>([]); // ข้อมูลเปลี่ยนแปลง
const DataUpdate = (filterType: string, filterStatus: string, filterYear: string) => { const DataMain = (val: formListLeaveData[]) => (DataMainOrig.value = val);
DataMainUpdate.value = [] const DataUpdate = (
filterType: string,
filterStatus: string,
filterYear: string
) => {
DataMainUpdate.value = [];
if (filterType === "" && filterStatus === "" && filterYear === "") { if (filterType === "" && filterStatus === "" && filterYear === "") {
DataMainUpdate.value = DataMainOrig.value DataMainUpdate.value = DataMainOrig.value;
} else if (filterType !== "" && filterStatus === "" && filterYear === "") { } else if (filterType !== "" && filterStatus === "" && filterYear === "") {
DataMainUpdate.value = DataMainOrig.value.filter((item: formListLeaveData) => item.type === filterType) DataMainUpdate.value = DataMainOrig.value.filter(
} else if (filterType !== "" && filterStatus !== "" && filterYear === null) { (item: formListLeaveData) => item.type === filterType
DataMainUpdate.value = DataMainOrig.value.filter((item: formListLeaveData) => item.type === filterType && item.status === filterStatus) );
} else if (
filterType !== "" &&
filterStatus !== "" &&
filterYear === null
) {
DataMainUpdate.value = DataMainOrig.value.filter(
(item: formListLeaveData) =>
item.type === filterType && item.status === filterStatus
);
} else if (filterType !== "" && filterStatus === "" && filterYear !== "") { } else if (filterType !== "" && filterStatus === "" && filterYear !== "") {
DataMainUpdate.value = DataMainOrig.value.filter((item: formListLeaveData) => item.type === filterType && item.year === filterYear) DataMainUpdate.value = DataMainOrig.value.filter(
(item: formListLeaveData) =>
item.type === filterType && item.year === filterYear
);
} else if (filterType === "" && filterStatus !== "" && filterYear === "") { } else if (filterType === "" && filterStatus !== "" && filterYear === "") {
DataMainUpdate.value = DataMainOrig.value.filter((item: formListLeaveData) => item.status === filterStatus) DataMainUpdate.value = DataMainOrig.value.filter(
(item: formListLeaveData) => item.status === filterStatus
);
} else if (filterType === "" && filterStatus === "" && filterYear !== "") { } else if (filterType === "" && filterStatus === "" && filterYear !== "") {
DataMainUpdate.value = DataMainOrig.value.filter((item: formListLeaveData) => item.year === filterYear) DataMainUpdate.value = DataMainOrig.value.filter(
} else if (filterType === "" && filterStatus !== "" && filterYear !== null) { (item: formListLeaveData) => item.year === filterYear
DataMainUpdate.value = DataMainOrig.value.filter((item: formListLeaveData) => item.status === filterStatus && item.year === filterYear) );
} else if (
filterType === "" &&
filterStatus !== "" &&
filterYear !== null
) {
DataMainUpdate.value = DataMainOrig.value.filter(
(item: formListLeaveData) =>
item.status === filterStatus && item.year === filterYear
);
} else if (filterType !== "" && filterStatus !== "" && filterYear === "") { } else if (filterType !== "" && filterStatus !== "" && filterYear === "") {
DataMainUpdate.value = DataMainOrig.value.filter((item: formListLeaveData) => item.status === filterStatus && item.type === filterType) DataMainUpdate.value = DataMainOrig.value.filter(
} else if (filterType !== "" && filterStatus !== "" && filterYear !== null) { (item: formListLeaveData) =>
DataMainUpdate.value = DataMainOrig.value.filter((item: formListLeaveData) => item.type === filterType && item.status === filterStatus && item.year === filterYear) item.status === filterStatus && item.type === filterType
} else if (filterType == "0" && filterStatus == "0" && filterYear !== null) { );
DataMainUpdate.value = DataMainOrig.value } else if (
} filterType !== "" &&
filterStatus !== "" &&
filterYear !== null
) {
DataMainUpdate.value = DataMainOrig.value.filter(
(item: formListLeaveData) =>
item.type === filterType &&
item.status === filterStatus &&
item.year === filterYear
);
} else if (
filterType == "0" &&
filterStatus == "0" &&
filterYear !== null
) {
DataMainUpdate.value = DataMainOrig.value;
} }
};
//--------------|ฟิลเตอร์|--------------------------------------// //--------------|ฟิลเตอร์|--------------------------------------//
const searchFilterTable = async () => { const searchFilterTable = async () => {
rows.value = [] rows.value = [];
if (LeaveType.value !== undefined && LeaveType.value !== null) { if (LeaveType.value !== undefined && LeaveType.value !== null) {
await DataUpdate(LeaveType.value === "0" ? "all" : LeaveType.value!, LeaveStatus.value === "0" ? "all" : LeaveStatus.value!, fiscalYearyear.value === "0" ? "all" : fiscalYearyear.value!) await DataUpdate(
let filteredData = DataMainOrig.value LeaveType.value === "0" ? "all" : LeaveType.value!,
LeaveStatus.value === "0" ? "all" : LeaveStatus.value!,
fiscalYearyear.value === "0" ? "all" : fiscalYearyear.value!
);
let filteredData = DataMainOrig.value;
if (LeaveType.value !== "0") { if (LeaveType.value !== "0") {
filteredData = filteredData.filter((item: formListLeaveData) => item.type === LeaveType.value) filteredData = filteredData.filter(
(item: formListLeaveData) => item.type === LeaveType.value
);
} }
if (LeaveStatus.value !== "0") { if (LeaveStatus.value !== "0") {
filteredData = filteredData.filter((item: formListLeaveData) => item.status === LeaveStatus.value) filteredData = filteredData.filter(
(item: formListLeaveData) => item.status === LeaveStatus.value
);
} }
if (fiscalYearyear.value !== "0") { if (fiscalYearyear.value !== "0") {
filteredData = filteredData.filter((item: formListLeaveData) => item.year === fiscalYearyear.value) filteredData = filteredData.filter(
(item: formListLeaveData) => item.year === fiscalYearyear.value
);
} }
const dataArr: formListLeaveData[] = filteredData.map((e: any) => ({ const dataArr: formListLeaveData[] = filteredData.map((e: any) => ({
no: e.no, no: e.no,
type: convertType(e.type) || '', type: convertType(e.type) || "",
status: convertStatus(e.status) || '', status: convertStatus(e.status) || "",
date: date2Thai(new Date(e.date)), date: date2Thai(new Date(e.date)),
year: e.year !== undefined ? e.year : '' year: e.year !== undefined ? e.year : "",
})); }));
rows.value = dataArr rows.value = dataArr;
}
} }
};
/**
*
* @param val
* @param update
* @param refData
*/
const filterSelector = (val: any, update: Function, refData: string) => { const filterSelector = (val: any, update: Function, refData: string) => {
switch (refData) { switch (refData) {
case "fiscalyearOP": case "fiscalyearOP":
update(() => { update(() => {
fiscalyearOP.value = fiscalyearOP.value.filter((v: any) => v.name.indexOf(val) > -1) fiscalyearOP.value = fiscalyearOP.value.filter(
}) (v: any) => v.name.indexOf(val) > -1
break );
});
break;
case "LeaveTypeOption": case "LeaveTypeOption":
update(() => { update(() => {
typeOptions.value = typeOptions.value.filter((v: any) => v.name.indexOf(val) > -1) typeOptions.value = typeOptions.value.filter(
}) (v: any) => v.name.indexOf(val) > -1
break );
});
break;
case "LeaveStatusOption": case "LeaveStatusOption":
update(() => { update(() => {
statusOptions.value = statusOptions.value.filter((v: any) => v.name.indexOf(val) > -1) statusOptions.value = statusOptions.value.filter(
}) (v: any) => v.name.indexOf(val) > -1
break );
});
break;
default: default:
break break;
}
} }
};
/** filter ปี */
const fiscalyearOP = ref<OptionData[]>([ const fiscalyearOP = ref<OptionData[]>([
{ id: "0", name: "ทั้งหมด" }, { id: "0", name: "ทั้งหมด" },
{ id: "1", name: "2566" }, { id: "1", name: "2566" },
{ id: "2", name: "2567" }, { id: "2", name: "2567" },
{ id: "2", name: "2568" }, { id: "2", name: "2568" },
]) ]);
/**
*
* @param val
* @returns
*/
function convertType(val: string) { function convertType(val: string) {
switch (val) { if (val == "0") return "ทั้งหมด";
case "0": else return options.value.find((x) => x.id == val)?.name;
return "ทั้งหมด"
case "1":
return "ลาป่วย"
case "2":
return "ลากิจส่วนตัว"
case "3":
return "ลาคลอดบุตร"
case "4":
return "ลาไปช่วยเหลือภริยาที่คลอดบุตร"
case "5":
return "ลาอุปสมบทหรือลาประกอบพิธีฮัจย์ฯ"
case "6":
return "ลาเข้ารับการตรวจเลือกหรือเข้ารับการเตรียมพล"
case "7":
return "ลาไปศึกษา ฝึกอบรม ปฎิบัติการวิจัย หรือดูงาน"
case "8":
return "ลาไปปฎิบัติงานในองค์การระหว่างประเทศ"
case "9":
return "ลาติดตามคู่สมรส"
case "10":
return "ลาไปฟื้นฟูสมรรถภาพด้านอาชีพ"
}
}
function convertStatus(val: string) {
switch (val) {
case "0":
return "ทั้งหมด"
case "1":
return "อนุมัติ"
case "2":
return "ไม่อนุมัติ"
case "3":
return "อยู่ระหว่างดำเนินการ"
case "4":
return "ใหม่"
}
}
function convertYear(val: string) {
switch (val) {
case "0":
return "ทั้งหมด"
case "1":
return "2566"
case "2":
return "2567"
case "3":
return "2568"
case "4":
return "2569"
}
} }
/** รายการประเภทการลาของ ลาไปศึกษา ฝึกอบรม ปฎิบัติการวิจัย หรือดูงาน*/
const optionsSpecific = ref([ const optionsSpecific = ref([
{ id: 's0', name: "ลาไปศึกษาต่อ" }, { id: "s0", name: "ลาไปศึกษาต่อ" },
{ id: 's1', name: "ลาฝึกอบรม" }, { id: "s1", name: "ลาฝึกอบรม" },
{ id: 's2', name: "ลาปฎิบัติการวิจัย" }, { id: "s2", name: "ลาปฎิบัติการวิจัย" },
{ id: 's3', name: "ลาดูงาน" }, { id: "s3", name: "ลาดูงาน" },
]); ]);
/** รายการประเภทการลาของ ลาอุปสมบทหรือลาประกอบพิธีฮัจย์ฯ*/
const optionsOrdination = ref([ const optionsOrdination = ref([
{ id: '0', name: "ลาอุปสมบท" }, { id: "0", name: "ลาอุปสมบท" },
{ id: '1', name: "ลาประกอบพิธีฮัจย์" }, { id: "1", name: "ลาประกอบพิธีฮัจย์" },
]); ]);
const typeOptions = ref<OptionData[]>([
{ id: "0", name: "ทั้งหมด" }, /** รายการข้อมูลประเภทใบลา */
const options = ref<OptionData[]>([
{ id: "1", name: "ลาป่วย" }, { id: "1", name: "ลาป่วย" },
{ id: "2", name: "ลากิจส่วนตัว" }, { id: "2", name: "ลากิจส่วนตัว" },
{ id: "3", name: "ลาคลอดบุตร" }, { id: "3", name: "ลาคลอดบุตร" },
{ id: "4", name: "ลาไปช่วยเหลือภริยาที่คลอดบุตร" }, { id: "4", name: "ลาไปช่วยเหลือภริยาที่คลอดบุตร" },
{ id: "5", name: "ลาอุปสมบทหรือลาประกอบพิธีฮัจย์ฯ" }, { id: "5", name: "ลาพักผ่อน" },
{ id: "6", name: "ลาเข้ารับการตรวจเลือกหรือเข้ารับการเตรียมพล" }, { id: "6", name: "ลาอุปสมบทหรือลาประกอบพิธีฮัจย์ฯ" },
{ id: "7", name: "ลาไปศึกษา ฝึกอบรม ปฎิบัติการวิจัย หรือดูงาน" }, { id: "7", name: "ลาเข้ารับการตรวจเลือกหรือเข้ารับการเตรียมพล" },
{ id: "8", name: "ลาไปปฎิบัติงานในองค์การระหว่างประเทศ" }, { id: "8", name: "ลาไปศึกษา ฝึกอบรม ปฎิบัติการวิจัย หรือดูงาน" },
{ id: "9", name: "ลาติดตามคู่สมรส" }, { id: "9", name: "ลาไปปฎิบัติงานในองค์การระหว่างประเทศ" },
{ id: "10", name: "ลาไปฟื้นฟูสมรรถภาพด้านอาชีพ" }, { id: "10", name: "ลาติดตามคู่สมรส" },
]) { id: "11", name: "ลาไปฟื้นฟูสมรรถภาพด้านอาชีพ" },
const options = ref<OptionData[]>([
{ id: '0', name: "ลาป่วย" },
{ id: '1', name: "ลากิจส่วนตัว" },
{ id: '2', name: "ลาคลอดบุตร" },
{ id: '3', name: "ลาไปช่วยเหลือภริยาที่คลอดบุตร" },
{ id: '4', name: "ลาพักผ่อน" },
{ id: '5', name: "ลาอุปสมบทหรือลาประกอบพิธีฮัจย์ฯ" },
{ id: '6', name: "ลาเข้ารับการตรวจเลือกหรือเข้ารับการเตรียมพล" },
{ id: '7', name: "ลาไปศึกษา ฝึกอบรม ปฎิบัติการวิจัย หรือดูงาน" },
{ id: '8', name: "ลาไปปฎิบัติงานในองค์การระหว่างประเทศ" },
{ id: '9', name: "ลาติดตามคู่สมรส" },
{ id: '10', name: "ลาไปฟื้นฟูสมรรถภาพด้านอาชีพ" },
]); ]);
/** filter ประเภทการลา */
const typeOptions = ref<OptionData[]>([
{ id: "0", name: "ทั้งหมด" },
...options.value,
]);
/** สถานะของการลา */
const statusOptions = ref<OptionData[]>([ const statusOptions = ref<OptionData[]>([
{ id: "0", name: "ทั้งหมด" }, { id: "0", name: "ทั้งหมด" },
{ id: "1", name: "อนุมัติ" }, { id: "1", name: "อนุมัติ" },
{ id: "2", name: "ไม่อนุมัติ" }, { id: "2", name: "ไม่อนุมัติ" },
{ id: "3", name: "อยู่ระหว่างดำเนินการ" }, { id: "3", name: "อยู่ระหว่างดำเนินการ" },
{ id: "4", name: "ใหม่" }, { id: "4", name: "ใหม่" },
]) ]);
const visibleColumns = ref<String[]>(["no", "type", "date", "status"])
/**
*
* @param val
* @returns
*/
function convertStatus(val: string) {
if (val == "0") return "ทั้งหมด";
else return statusOptions.value.find((x) => x.id == val)?.name;
}
/** data table filter & column ของรายการลา */
const visibleColumns = ref<String[]>(["no", "type", "date", "status"]);
const columns = ref<QTableProps["columns"]>([ const columns = ref<QTableProps["columns"]>([
{ {
name: "no", name: "no",
@ -245,53 +284,49 @@ export const useLeaveStore = defineStore("Leave", () => {
headerStyle: "font-size: 14px", headerStyle: "font-size: 14px",
style: "font-size: 14px; width:10%;", style: "font-size: 14px; width:10%;",
}, },
]) ]);
function typeConvert(item: string,subitem:any) {
console.log('first',item)
if (item !== '5' && item !== '7') {
typeLeave.value = convertSubtitle(item);
}else if(item === '5'){
typeLeave.value = convertSubtitleInfo(subitem);
}else if(item === '7'){ /**
*
* @param item
* @param subitem
*/
function typeConvert(item: string, subitem: any) {
// console.log('first',item)
if (item !== "6" && item !== "8") {
typeLeave.value = convertSubtitle(item);
} else if (item === "6") {
typeLeave.value = convertSubtitleInfo(subitem);
} else if (item === "8") {
typeLeave.value = convertSubtitleInfo2(subitem); typeLeave.value = convertSubtitleInfo2(subitem);
} }
} }
/**
*
* @param val
* @returns
*/
function convertSubtitle(val: string) { function convertSubtitle(val: string) {
if (val) { return options.value.find((x) => x.id == val)?.name;
switch (val) {
case "0": return "ลาป่วย";
case "1": return "ลากิจส่วนตัว";
case "2": return "ลาคลอดบุตร";
case "3": return "ลาไปช่วยเหลือภริยาที่คลอดบุตร";
case "4": return "ลาพักผ่อน";
case "5": return "ลาอุปสมบทหรือลาประกอบพิธีฮัจย์ฯ";
case "6": return "ลาเข้ารับการตรวจเลือกหรือเข้ารับการเตรียมพล";
case "7": return "ลาไปศึกษา ฝึกอบรม ปฎิบัติการวิจัย หรือดูงาน";
case "8": return "ลาไปปฎิบัติงานในองค์การระหว่างประเทศ";
case "9": return "ลาติดตามคู่สมรส";
case "10": return "ลาไปฟื้นฟูสมรรถภาพด้านอาชีพ";
}
}
} }
/**
*
* @param val
* @returns
*/
function convertSubtitleInfo(val: string) { function convertSubtitleInfo(val: string) {
if (val) { return optionsOrdination.value.find((x) => x.id == val)?.name;
switch (val) {
case "0": return "ลาอุปสมบท";
case "1": return "ลาประกอบพิธีฮัจย์";
}
}
} }
/**
*
* @param val
* @returns
*/
function convertSubtitleInfo2(val: string) { function convertSubtitleInfo2(val: string) {
if (val) { return optionsSpecific.value.find((x) => x.id == val)?.name;
switch (val) {
case "s0": return "ลาไปศึกษาต่อ";
case "s1": return "ลาฝึกอบรม";
case "s2": return "ลาปฎิบัติการวิจัย";
case "s3": return "ลาดูงาน";
}
}
} }
return { return {
@ -316,6 +351,6 @@ export const useLeaveStore = defineStore("Leave", () => {
options, options,
optionsOrdination, optionsOrdination,
typeConvert, typeConvert,
typeLeave typeLeave,
} };
}) });

View file

@ -1,37 +1,37 @@
<script setup lang="ts"> <script setup lang="ts">
import { ref, onMounted, computed } from "vue" import { ref, onMounted, computed } from "vue";
import { useQuasar } from "quasar" import { useQuasar } from "quasar";
import { useRouter, useRoute } from "vue-router" import { useRouter, useRoute } from "vue-router";
import Form from "@/modules/05_leave/componenst/Forms/Form.vue" import FormPart2 from "@/modules/05_leave/componenst/Forms/Form.vue";
import Form3 from "@/modules/05_leave/componenst/Forms/01_SickForm.vue" import SickForm from "@/modules/05_leave/componenst/Forms/01_SickForm.vue";
import FormBirth from "@/modules/05_leave/componenst/Forms/03_Birth.vue" import FormBirth from "@/modules/05_leave/componenst/Forms/03_Birth.vue";
import Form4 from "@/modules/05_leave/componenst/Forms/04_HelpWifeBirthForm.vue" import HelpWifeBirthForm from "@/modules/05_leave/componenst/Forms/04_HelpWifeBirthForm.vue";
import Form5 from "@/modules/05_leave/componenst/Forms/05_VacationForm.vue" import VacationForm from "@/modules/05_leave/componenst/Forms/05_VacationForm.vue";
import Form6 from "@/modules/05_leave/componenst/Forms/06_OrdinationForm.vue" import OrdinationForm from "@/modules/05_leave/componenst/Forms/06_OrdinationForm.vue";
import Form7 from "@/modules/05_leave/componenst/Forms/07_HajjForm.vue" import HajjForm from "@/modules/05_leave/componenst/Forms/07_HajjForm.vue";
import Form8 from "@/modules/05_leave/componenst/Forms/08_MilitaryForm.vue" import MilitaryForm from "@/modules/05_leave/componenst/Forms/08_MilitaryForm.vue";
import Form9 from "@/modules/05_leave/componenst/Forms/09_StudyForm.vue" import StudyForm from "@/modules/05_leave/componenst/Forms/09_StudyForm.vue";
import Form10 from "@/modules/05_leave/componenst/Forms/10_TrainForm.vue" import TrainForm from "@/modules/05_leave/componenst/Forms/10_TrainForm.vue";
import Form11 from "@/modules/05_leave/componenst/Forms/11_WorkInternationalForm.vue" import WorkInternationalForm from "@/modules/05_leave/componenst/Forms/11_WorkInternationalForm.vue";
import Form12 from "@/modules/05_leave/componenst/Forms/12_FollowSpouseForm.vue" import FollowSpouseForm from "@/modules/05_leave/componenst/Forms/12_FollowSpouseForm.vue";
import Form13 from "@/modules/05_leave/componenst/Forms/13_RehabilitationForm.vue" import RehabilitationForm from "@/modules/05_leave/componenst/Forms/13_RehabilitationForm.vue";
import { useLeaveStore } from "@/modules/05_leave/store" import { useLeaveStore } from "@/modules/05_leave/store";
import http from "@/plugins/http" import http from "@/plugins/http";
import config from "@/app.config" import config from "@/app.config";
import type { QForm } from "quasar" import type { QForm } from "quasar";
import { useCounterMixin } from "@/stores/mixin" import { useCounterMixin } from "@/stores/mixin";
const dataStore = useLeaveStore() const dataStore = useLeaveStore();
const mixin = useCounterMixin() const mixin = useCounterMixin();
const { date2Thai, dialogConfirm } = mixin const { date2Thai, dialogConfirm } = mixin;
const router = useRouter() const router = useRouter();
const route = useRoute() const route = useRoute();
const myform = ref<QForm | null>(null) const myform = ref<QForm | null>(null);
const $q = useQuasar() const $q = useQuasar();
const model = ref<string>("") const model = ref<string>("");
const modelSpecific = ref<string>("") const modelSpecific = ref<string>("");
// onMounted(() => {}); // onMounted(() => {});
@ -48,28 +48,42 @@ const saveAbsence = () => {
.onOk(() => { .onOk(() => {
// createFormresign() // createFormresign()
if (model.value !== "7") { if (model.value !== "7") {
console.log(1) console.log(1);
} else if (model.value === "7") { } else if (model.value === "7") {
console.log(2) console.log(2);
} }
router.push(`/leave`) router.push(`/leave`);
}) })
.onCancel(() => {}) .onCancel(() => {})
.onDismiss(() => {}) .onDismiss(() => {});
} };
/** ฟังก์ชั่น บันทึก */ /** ฟังก์ชั่น บันทึก */
const onSubmit = async () => { const onSubmit = async () => {
dialogConfirm($q, async () => {}, "ยืนยันการยื่นใบลา", "ต้องการยืนยันการยื่นใบลานี้ใช่หรือไม่ ?") dialogConfirm(
$q,
async () => {},
"ยืนยันการยื่นใบลา",
"ต้องการยืนยันการยื่นใบลานี้ใช่หรือไม่ ?"
);
console.log("save") console.log("save");
} };
</script> </script>
<template> <template>
<div class="col-12 row justify-center"> <div class="col-12 row justify-center">
<div class="col-xs-12 col-sm-12 col-md-11"> <div class="col-xs-12 col-sm-12 col-md-11">
<div class="toptitle text-white col-12 row items-center"> <div class="toptitle text-white col-12 row items-center">
<q-btn to="/leave" icon="mdi-arrow-left" unelevated round dense flat color="primary" class="q-mr-sm" /> <q-btn
to="/leave"
icon="mdi-arrow-left"
unelevated
round
dense
flat
color="primary"
class="q-mr-sm"
/>
<div>นใบลา</div> <div>นใบลา</div>
</div> </div>
@ -78,8 +92,14 @@ const onSubmit = async () => {
<div class="col-12 row q-col-gutter-md q-pa-md"> <div class="col-12 row q-col-gutter-md q-pa-md">
<div class="col-xs-12 col-sm-12"> <div class="col-xs-12 col-sm-12">
<div style="display: flex; align-items: center"> <div style="display: flex; align-items: center">
<q-icon name="mdi-numeric-1-circle" size="20px" color="primary" /> <q-icon
<div class="q-pl-sm text-weight-bold text-dark">เลอกประเภทการลา</div> name="mdi-numeric-1-circle"
size="20px"
color="primary"
/>
<div class="q-pl-sm text-weight-bold text-dark">
เลอกประเภทการลา
</div>
</div> </div>
<div class="q-py-sm q-px-lg"> <div class="q-py-sm q-px-lg">
<div class="row"> <div class="row">
@ -94,22 +114,33 @@ const onSubmit = async () => {
emit-value emit-value
map-options map-options
prefix="ประเภทใบลา :" prefix="ประเภทใบลา :"
@update:model-value="dataStore.typeConvert(model, null)" @update:model-value="
dataStore.typeConvert(model, null), (modelSpecific = '')
"
/> />
</div> </div>
<div class="row q-mt-sm"> <div class="row q-mt-sm">
<div class="col-12 col-sm-6 col-md-3" v-if="model === '5' || model === '7'"> <div
class="col-12 col-sm-6 col-md-3"
v-if="model === '6' || model === '8'"
>
<q-select <q-select
dense dense
outlined outlined
v-model="modelSpecific" v-model="modelSpecific"
:options="model === '5' ? dataStore.optionsOrdination : dataStore.optionsSpecific" :options="
model === '6'
? dataStore.optionsOrdination
: dataStore.optionsSpecific
"
option-value="id" option-value="id"
option-label="name" option-label="name"
emit-value emit-value
map-options map-options
prefix="ประเภทใบลา :" prefix="ประเภทการลา :"
@update:model-value="dataStore.typeConvert(model, modelSpecific)" @update:model-value="
dataStore.typeConvert(model, modelSpecific)
"
/> />
</div> </div>
</div> </div>
@ -119,25 +150,53 @@ const onSubmit = async () => {
<div> <div>
<div style="display: flex; align-items: center"> <div style="display: flex; align-items: center">
<q-icon name="mdi-numeric-2-circle" size="20px" color="primary" /> <q-icon
<div class="q-pl-sm text-weight-bold text-dark">อมลการลา</div> name="mdi-numeric-2-circle"
size="20px"
color="primary"
/>
<div class="q-pl-sm text-weight-bold text-dark">
อมลการลา
</div> </div>
<Form :model="model" /> </div>
<FormPart2 :model="model" />
</div> </div>
</div> </div>
<div v-if="model" class="col-12"> <div v-if="model" class="col-12">
<Form3 :on-submit="onSubmit" v-if="model === '0' || model === '1'" /> <SickForm
<FormBirth :on-submit="onSubmit" v-if="model === '2'" /> :on-submit="onSubmit"
<Form4 :on-submit="onSubmit" v-if="model === '3'" /> v-if="model === '1' || model === '2'"
<Form5 :on-submit="onSubmit" v-if="model === '4'" /> />
<Form6 :on-submit="onSubmit" v-if="model === '5' && modelSpecific === '0'" /> <FormBirth :on-submit="onSubmit" v-if="model === '3'" />
<Form7 :on-submit="onSubmit" v-if="model === '5' && modelSpecific === '1'" /> <HelpWifeBirthForm :on-submit="onSubmit" v-if="model === '4'" />
<Form8 :on-submit="onSubmit" v-if="model === '6'" style="width: 100%" /> <VacationForm :on-submit="onSubmit" v-if="model === '5'" />
<Form9 :on-submit="onSubmit" v-if="model === '7' && modelSpecific === 's0'" style="width: 100%" /> <OrdinationForm
<Form10 :on-submit="onSubmit" v-if="model === '7' && modelSpecific != 's0' && modelSpecific != ''" /> :on-submit="onSubmit"
<Form11 :on-submit="onSubmit" v-if="model === '8'" /> v-if="model === '6' && modelSpecific === '0'"
<Form12 :on-submit="onSubmit" v-if="model === '9'" /> />
<Form13 :on-submit="onSubmit" v-if="model === '10'" /> <HajjForm
:on-submit="onSubmit"
v-if="model === '6' && modelSpecific === '1'"
/>
<MilitaryForm
:on-submit="onSubmit"
v-if="model === '7'"
style="width: 100%"
/>
<StudyForm
:on-submit="onSubmit"
v-if="model === '8' && modelSpecific === 's0'"
style="width: 100%"
/>
<TrainForm
:on-submit="onSubmit"
v-if="
model === '8' && modelSpecific != 's0' && modelSpecific != ''
"
/>
<WorkInternationalForm :on-submit="onSubmit" v-if="model === '9'" />
<FollowSpouseForm :on-submit="onSubmit" v-if="model === '10'" />
<RehabilitationForm :on-submit="onSubmit" v-if="model === '11'" />
</div> </div>
</div> </div>
</q-card> </q-card>

View file

@ -1,55 +1,15 @@
<script setup lang="ts"> <script setup lang="ts">
import type { QTableProps } from "quasar" import type { QTableProps } from "quasar";
import { defineComponent, onMounted } from "@vue/runtime-core" // import { defineComponent, onMounted } from "@vue/runtime-core";
import { reactive, ref, watch } from "vue" import { ref } from "vue";
import { useRouter } from "vue-router" import { useRouter } from "vue-router";
import subCalendarComponent from "@/modules/05_leave/componenst/Calendar.vue" import CalendarView from "@/modules/05_leave/componenst/Calendar.vue";
import subListCalendarComponent from "@/modules/05_leave/componenst/ListCalendar.vue" import ListView from "@/modules/05_leave/componenst/ListCalendar.vue";
import { useCounterMixin } from "@/stores/mixin" import { useLeaveStore } from "@/modules/05_leave/store";
import type { DataDateMonthObject } from "@/modules/05_leave/interface/request/Calendar.ts"
import { useLeaveStore } from "@/modules/05_leave/store"
const leaveStore = useLeaveStore() const leaveStore = useLeaveStore();
const { filterSelector, searchFilterTable } = leaveStore const router = useRouter();
const router = useRouter()
const dateMonth = ref<DataDateMonthObject>({
month: new Date().getMonth(),
year: new Date().getFullYear(),
})
// console.log(dateMonth.value);
const props = defineProps({
dateYear: Number, // parent
fetchDataSummaryCalendar: {
//
type: Function,
default: () => console.log("not function"),
},
})
const dateYear = ref<number>(new Date().getFullYear())
const emit = defineEmits(["update:dateYear"])
const mixin = useCounterMixin() //
const { monthYear2Thai } = mixin
/**
* แปลง และเดอนเปนภาษาไทย
* @param val datepicker แบบเลอกปและเดอน
*/
const monthYearThai = (val: DataDateMonthObject) => {
if (val == null) return ""
else return monthYear2Thai(val.month, val.year)
}
const updateMonth = async (e: DataDateMonthObject) => {
console.log(dateMonth.value)
if (e != null) {
dateYear.value = e.year
emit("update:dateYear", e.year)
await props.fetchDataSummaryCalendar()
}
console.log(dateMonth.value)
}
const value = ref(90)
const itemPie = ref([ const itemPie = ref([
{ {
text: "ลาป่วย", text: "ลาป่วย",
@ -75,25 +35,26 @@ const itemPie = ref([
use: "17", use: "17",
remain: "3", remain: "3",
}, },
]) ]);
const data = ref(false);
const data = ref(false)
const columns = ref<QTableProps["columns"]>([ const columns = ref<QTableProps["columns"]>([
{ {
name: "no", name: "id",
align: "left", align: "left",
label: "ลำดับ", label: "ลำดับ",
sortable: true, sortable: true,
field: "no", field: "id",
headerStyle: "font-size: 14px", headerStyle: "font-size: 14px",
style: "font-size: 14px; width:5%;", style: "font-size: 14px; width:5%;",
}, },
{ {
name: "type", name: "name",
align: "left", align: "left",
label: "ประเภทการลา", label: "ประเภทการลา",
sortable: true, sortable: true,
field: "type", field: "name",
headerStyle: "font-size: 14px", headerStyle: "font-size: 14px",
style: "font-size: 14px; width:15%;", style: "font-size: 14px; width:15%;",
}, },
@ -160,159 +121,79 @@ const columns = ref<QTableProps["columns"]>([
headerStyle: "font-size: 14px", headerStyle: "font-size: 14px",
style: "font-size: 14px; width:15%;", style: "font-size: 14px; width:15%;",
}, },
]) ]);
const rows = ref<any>([
{ no: "1", type: "ลาป่วย" }, const pagination = ref({ rowsPerPage: 10 });
{ no: "2", type: "ลากิจส่วนตัว" },
{ no: "3", type: "ลาคลอดบุตร" },
{ no: "4", type: "ลาช่วยเหลือภริยาที่คลอดบุตร" },
{ no: "5", type: "ลาพักผ่อน" },
{ no: "6", type: "ลาอุปสมบทหรือการลาประกอบพิธีฮัจย์ฯ" },
{ no: "7", type: "ลาเข้ารับการตรวจเลือกหรือเข้ารับการเตรียมพล" },
{ no: "8", type: "ลาไปศึกษา ฝึกอบรม ปฏิบัติการวิจัย หรือดูงาน" },
{ no: "9", type: "ลาไปปฏิบัติงานในองค์การระหว่างประเทศ" },
{ no: "10", type: "ลาติดตามคู่สมรส" },
{ no: "11", type: "ลาฟื้นฟูสมรรถภาพด้านอาชีพ" },
])
const pagination = ref({ rowsPerPage: 11 })
const addAbsence = async () => { const addAbsence = async () => {
router.push(`/leave/add`) router.push(`/leave/add`);
} };
</script> </script>
<template> <template>
<div class="col-12 row justify-center"> <div class="col-12 row justify-center">
<div class="col-xs-12 col-sm-12 col-md-11"> <div class="col-xs-12 col-sm-12 col-md-11">
<div class="toptitle text-white col-12 row items-center"> <div class="toptitle text-white col-12 row items-center">
<q-btn icon="mdi-arrow-left" unelevated round dense flat color="primary" class="q-mr-sm" @click="router.go(-1)" /> <q-btn
icon="mdi-arrow-left"
unelevated
round
dense
flat
color="primary"
class="q-mr-sm"
@click="router.go(-1)"
/>
<div>รายการลา</div> <div>รายการลา</div>
</div> </div>
</div> </div>
<div class="col-xs-12 col-sm-12 col-md-11 row q-col-gutter-md">
<div class="row col-12 q-col-gutter-sm">
<div class="col-xs-12 col-sm-9 col-md-9 row">
<q-card bordered class="q-pa-md col-12">
<div class="row col-12">
<div class="row items-center">
<!-- filter เลอกเดอนป -->
<datepicker
v-model="dateMonth"
:locale="'th'"
autoApply
month-picker
:enableTimePicker="false"
v-if="leaveStore.tabValue === 'calendar'"
@update:modelValue="updateMonth"
>
<template #year="{ year }">{{ year + 543 }}</template>
<template #year-overlay-value="{ value }">{{ parseInt(value + 543) }}</template>
<template #trigger>
<q-input :model-value="monthYearThai(dateMonth)" dense outlined style="width: 130px">
<template v-slot:prepend>
<q-icon name="event" class="cursor-pointer" style="color: var(--q-primary)"> </q-icon>
</template>
</q-input>
</template>
</datepicker>
<q-select
v-if="leaveStore.tabValue === 'list'"
outlined
dense
lazy-rules
v-model="leaveStore.fiscalYearyear"
:label="`${'ปี พ.ศ.'}`"
emit-value
map-options
option-label="name"
:options="leaveStore.fiscalyearOP"
option-value="id"
hide-bottom-space
style="min-width: 150px"
class="col-xs-12 col-sm-auto"
@update:model-value="searchFilterTable"
@filter="(inputValue:any,
doneFn:Function) => filterSelector(inputValue, doneFn,'fiscalyearOP'
) "
/>
<!-- filter เลอกป -->
<!-- <datepicker v-model="dateYear" :locale="'th'" autoApply year-picker :enableTimePicker="false" v-if="leaveStore.tabValue === 'list'">
<template #year="{ year }">{{ year + 543 }}</template>
<template #year-overlay-value="{ value }">{{ parseInt(value + 543) }}</template>
<template #trigger>
<q-input :model-value="dateYear + 543" dense outlined style="width: 100px" hide-bottom-space>
<template v-slot:prepend>
<q-icon name="event" class="cursor-pointer" style="color: var(--q-primary)"> </q-icon>
</template>
</q-input>
</template>
</datepicker> -->
<div class="q-ml-sm">
<!-- icon เพมวนหย -->
<q-btn round dense flat size="13px" class="q-px-sm" @click="addAbsence">
<q-icon name="mdi-plus" size="22px" color="primary" />
<q-tooltip>นใบลา</q-tooltip>
</q-btn>
</div>
</div>
<q-space />
<div class="justify-center row items-center">
<!-- tab ปแบบแสดงวนหย ปฏนกบรายการ -->
<q-tabs v-model="leaveStore.tabValue" indicator-color="transparent" align="left" active-color="activetab" class="text-nativetab" inline-label dense>
<q-btn
name="calendar"
round
size="12px"
flat
icon="mdi-calendar-month"
@click="leaveStore.tabValue = 'calendar'"
:color="leaveStore.tabValue == 'calendar' ? 'primary' : 'grey-6'"
class="q-mr-sm"
>
<q-tooltip>ปฏ</q-tooltip>
</q-btn>
<q-separator vertical inset />
<q-btn
name="list"
round
size="12px"
flat
icon="mdi-format-list-bulleted"
@click="leaveStore.tabValue = 'list'"
:color="leaveStore.tabValue == 'list' ? 'primary' : 'grey-6'"
class="q-ml-sm"
>
<q-tooltip>รายการ</q-tooltip>
</q-btn>
</q-tabs>
</div>
</div>
<div class="col-12">
<subCalendarComponent :dateYear="dateMonth.year" :dateMonth="dateMonth.month" v-if="leaveStore.tabValue === 'calendar'" />
</div>
<div class="col-12"> <div class="col-xs-12 col-sm-12 col-md-11 row q-col-gutter-md">
<subListCalendarComponent v-if="leaveStore.tabValue === 'list'" /> <!-- สถการลา -->
</div>
</q-card>
</div>
<div class="col-xs-12 col-sm-3 col-md-3 row">
<q-card bordered class="col-12 row caedNone">
<div class="col-12 row"> <div class="col-12 row">
<q-card bordered class="col-12 row caedNone">
<q-card class="row col-12 items-center q-px-md q-py-sm"> <q-card class="row col-12 items-center q-px-md q-py-sm">
<div class="text-weight-bold">สถการลา</div> <div class="text-weight-bold">สถการลา</div>
<q-space /> <q-space />
<q-btn dense flat class="text-blue" icon="mdi-chart-line-variant" @click="data = true" label="ตารางสถิติการลา" /> <q-btn
dense
flat
class="text-blue"
icon="mdi-chart-line-variant"
@click="data = true"
label="ตารางสถิติการลา"
/>
</q-card> </q-card>
<div bordered class="col-12 row justify-center q-px-md q-pb-md" v-for="(item, index) in itemPie" :key="index"> <div
<q-card bordered flat class="col-12 row q-pt-md justify-center shadow-0"> bordered
<q-knob readonly v-model="item.value" show-value size="70px" :thickness="0.15" track-color="grey-3" :class="`${item.color}`"> class="col-4 row justify-center q-px-md q-pb-md"
<span class="text-subtitle2 text-weight-bold">{{ item.value }}%</span> v-for="(item, index) in itemPie"
:key="index"
>
<q-card
bordered
flat
class="col-12 row q-pt-md justify-center shadow-0"
>
<q-knob
readonly
v-model="item.value"
show-value
size="70px"
:thickness="0.15"
track-color="grey-3"
:class="`${item.color}`"
>
<span class="text-subtitle2 text-weight-bold"
>{{ item.value }}%</span
>
</q-knob> </q-knob>
<div class="col-12 text-center text-weight-medium q-py-xs"> <div class="col-12 text-center text-weight-medium q-py-xs">
{{ item.text }} {{ item.text }}
</div> </div>
<div class="col-12 row bg-grey-1 no-wrap text-dark text-body2 items-center borderTop"> <div
class="col-12 row bg-grey-1 no-wrap text-dark text-body2 items-center borderTop"
>
<div class="col-4 column q-pa-xs text-center"> <div class="col-4 column q-pa-xs text-center">
<span class="text-weight-bold">{{ item.all }}</span> <span class="text-weight-bold">{{ item.all }}</span>
<span class="text-grey-7 text-caption">ได</span> <span class="text-grey-7 text-caption">ได</span>
@ -330,23 +211,114 @@ const addAbsence = async () => {
</div> </div>
</q-card> </q-card>
</div> </div>
</q-card>
</div>
<div class="row col-12 q-col-gutter-sm">
<!-- แสดงปฏ -->
<div class="col-12 row">
<q-card bordered class="q-pa-md col-12">
<div class="row col-12">
<div class="row items-center">
<div class="q-ml-sm">
<q-btn
round
dense
flat
size="13px"
class="q-px-sm"
@click="addAbsence"
>
<q-icon name="mdi-plus" size="22px" color="blue" />
<q-tooltip>นใบลา</q-tooltip>
</q-btn>
</div>
</div>
<q-space />
<div class="justify-center row items-center">
<!-- tab ปแบบแสดงวนหย ปฏนกบรายการ -->
<q-tabs
v-model="leaveStore.tabValue"
indicator-color="transparent"
align="left"
active-color="activetab"
class="text-nativetab"
inline-label
dense
>
<q-btn
name="calendar"
round
size="12px"
flat
icon="mdi-calendar-month"
@click="leaveStore.tabValue = 'calendar'"
:color="
leaveStore.tabValue == 'calendar' ? 'primary' : 'grey-6'
"
class="q-mr-sm"
>
<q-tooltip>ปฏ</q-tooltip>
</q-btn>
<q-separator vertical inset />
<q-btn
name="list"
round
size="12px"
flat
icon="mdi-format-list-bulleted"
@click="leaveStore.tabValue = 'list'"
:color="
leaveStore.tabValue == 'list' ? 'primary' : 'grey-6'
"
class="q-ml-sm"
>
<q-tooltip>รายการ</q-tooltip>
</q-btn>
</q-tabs>
</div>
</div>
<div class="col-12">
<CalendarView v-if="leaveStore.tabValue === 'calendar'" />
</div>
<div class="col-12">
<ListView v-if="leaveStore.tabValue === 'list'" />
</div> </div>
</q-card> </q-card>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
<!-- modal ตารางสถการลา --> <!-- modal ตารางสถการลา -->
<q-dialog v-model="data" persistent> <q-dialog v-model="data" persistent>
<q-card style="min-width: 85%"> <q-card style="min-width: 85%">
<q-card-section class="row items-center q-pa-sm"> <q-card-section class="row items-center q-pa-sm">
<div class="text-bold q-pl-sm">ตารางสถการลา</div> <div class="text-bold q-pl-sm">ตารางสถการลา</div>
<q-space /> <q-space />
<q-btn icon="close" unelevated round dense v-close-popup style="color: #ff8080; background-color: #ffdede" /> <q-btn
icon="close"
unelevated
round
dense
v-close-popup
style="color: #ff8080; background-color: #ffdede"
/>
</q-card-section> </q-card-section>
<q-separator /> <q-separator />
<q-card-section class="q-p-md row"> <q-card-section class="q-p-md row">
<q-table flat bordered dense :rows="rows" :columns="columns" row-key="name" class="col-12" hide-bottom v-model:pagination="pagination" /> <q-table
flat
bordered
dense
:rows="leaveStore.options"
:columns="columns"
row-key="name"
class="col-12"
hide-bottom
v-model:pagination="pagination"
/>
</q-card-section> </q-card-section>
</q-card> </q-card>
</q-dialog> </q-dialog>