Merge branch 'develop' of github.com:Frappet/bma-ehr-frontend into me

# Conflicts:
#	src/modules/08_registryEmployee/views/Main.vue
This commit is contained in:
Thanit Konmek 2023-07-07 15:30:24 +07:00
commit e72f86e1d4
6 changed files with 297 additions and 711 deletions

View file

@ -568,6 +568,14 @@ const clickAdd = () => {
router.push({ name: "OrderplacementDetail" }); router.push({ name: "OrderplacementDetail" });
}; };
// const viewDetail = (id: string, status: string) => {
// if (status == "checkPayment") {
// router.push(`${route.fullPath}/payment/${id}`);
// } else {
// router.push(`${route.fullPath}/profile/${id}`);
// }
// };
// //
const fiscalyear = ref<number | null>(0); const fiscalyear = ref<number | null>(0);
const fiscalyearOP = reactive<DataOption[]>([{ id: 0, name: "ทั้งหมด" }]); const fiscalyearOP = reactive<DataOption[]>([{ id: 0, name: "ทั้งหมด" }]);

View file

@ -1,8 +1,11 @@
<script setup lang="ts"> <script setup lang="ts">
import { ref } from "vue"; import { onMounted, ref } from "vue";
import { defineAsyncComponent } from "@vue/runtime-core"; import { defineAsyncComponent } from "@vue/runtime-core";
import { useRouter } from "vue-router"; import { useRouter } from "vue-router";
import cardTop from "@/modules/05_placement/components/pass/StatCard.vue"; import cardTop from "@/modules/05_placement/components/pass/StatCard.vue";
import keycloak from "@/plugins/keycloak";
let roleAdmin = ref<boolean>(false);
const router = useRouter(); const router = useRouter();
const year = ref<string>("2566"); const year = ref<string>("2566");
@ -18,6 +21,12 @@ const stat = ref<any>({
contain: 1, contain: 1,
disclaim: 0, disclaim: 0,
}); });
onMounted(async () => {
if (keycloak.tokenParsed != null) {
roleAdmin.value = await keycloak.tokenParsed.role.includes("placement1");
}
});
</script> </script>
<template> <template>
<div class="col-xs-12 col-sm-12 col-md-8 col-lg-8 row"> <div class="col-xs-12 col-sm-12 col-md-8 col-lg-8 row">
@ -39,7 +48,7 @@ const stat = ref<any>({
<div class="fit q-px-md q-py-sm"> <div class="fit q-px-md q-py-sm">
<div class="row col-12 q-col-gutter-md fit"> <div class="row col-12 q-col-gutter-md fit">
<cardTop :amount="stat.total" label="จำนวนทั้งหมด" color="#016987" /> <cardTop :amount="stat.total" label="จำนวนทั้งหมด" color="#016987" />
<cardTop :amount="stat.unContain" label="จำนวนที่ยังไม่บรรจุ" color="#02A998" /> <cardTop v-if="roleAdmin" :amount="stat.unContain" label="จำนวนที่ยังไม่บรรจุ" color="#02A998" />
<cardTop :amount="stat.prepareContain" label="จำนวนที่เตรียมบรรจุ" color="#2EA0FF" /> <cardTop :amount="stat.prepareContain" label="จำนวนที่เตรียมบรรจุ" color="#2EA0FF" />
<cardTop :amount="stat.contain" label="จำนวนที่บรรจุแล้ว" color="#4154B3" /> <cardTop :amount="stat.contain" label="จำนวนที่บรรจุแล้ว" color="#4154B3" />
<cardTop :amount="stat.disclaim" label="จำนวนที่สละสิทธิ์" color="#FF5C5F" /> <cardTop :amount="stat.disclaim" label="จำนวนที่สละสิทธิ์" color="#FF5C5F" />

View file

@ -1,5 +1,5 @@
<script setup lang="ts"> <script setup lang="ts">
import { ref, onMounted } from "vue"; import { ref, onMounted, watch } from "vue";
import { useQuasar, QForm } from "quasar"; import { useQuasar, QForm } from "quasar";
import type { QTableProps } from "quasar"; import type { QTableProps } from "quasar";
import { useCounterMixin } from "@/stores/mixin"; import { useCounterMixin } from "@/stores/mixin";
@ -9,7 +9,7 @@ import DialogCard from "@/modules/05_placement/components/pass/TableDetail.vue";
import DialogFooter from "@/modules/05_placement/components/pass/DialogFooter.vue"; import DialogFooter from "@/modules/05_placement/components/pass/DialogFooter.vue";
import DialogHeader from "@/modules/05_placement/components/pass/DialogHeader.vue"; import DialogHeader from "@/modules/05_placement/components/pass/DialogHeader.vue";
import type { TableName } from "@/modules/05_placement/interface/request/placement"; import type { TableName } from "@/modules/05_placement/interface/request/placement";
import type Deferment from "@/modules/05_placement/components/pass/Deferment.vue"; // import type Deferment from "@/modules/05_placement/components/pass/Deferment.vue";
import type { import type {
treeTab, treeTab,
DataOption, DataOption,
@ -17,6 +17,10 @@ import type {
import http from "@/plugins/http"; import http from "@/plugins/http";
import config from "@/app.config"; import config from "@/app.config";
import keycloak from "@/plugins/keycloak";
import router from "@/router";
let roleAdmin = ref<boolean>(false);
const edit = ref<boolean>(true); const edit = ref<boolean>(true);
const modal = ref<boolean>(false); //modal add detail const modal = ref<boolean>(false); //modal add detail
@ -78,6 +82,7 @@ const $q = useQuasar(); // show dialog
const positionLevelOptions = ref<any[]>([]); const positionLevelOptions = ref<any[]>([]);
const { date2Thai, success, dateToISO, messageError, showLoader, hideLoader } = const { date2Thai, success, dateToISO, messageError, showLoader, hideLoader } =
mixin; mixin;
const fetchPosition = async () => { const fetchPosition = async () => {
showLoader(); showLoader();
await http await http
@ -159,7 +164,7 @@ const fetchPosition = async () => {
}); });
// positionLevelOptionsFilter.value = optionPositionLevels; // positionLevelOptionsFilter.value = optionPositionLevels;
}) })
.catch((e: any) => {}) .catch((e: any) => { })
.finally(() => { .finally(() => {
hideLoader(); hideLoader();
}); });
@ -292,7 +297,11 @@ const getClass = (val: boolean) => {
}; };
const selectData = (props: TableName) => { const selectData = (props: TableName) => {
itemtest.value = props; itemtest.value = props;
modal.value = true; if (roleAdmin.value === true) {
modal.value = true;
} else {
router.push("/placement/detail/08db7322-5712-4626-8a76-e2d28cd1a13b");
}
}; };
const onSelected = async (id: string) => { const onSelected = async (id: string) => {
await fetchPositionNumber(id); await fetchPositionNumber(id);
@ -347,15 +356,15 @@ const editDetail = (
}; };
placementData.mappingPosition.columns.length == 0 placementData.mappingPosition.columns.length == 0
? (visibleColumns.value = [ ? (visibleColumns.value = [
"position", "position",
"Name", "Name",
"ExamOrder", "ExamOrder",
"Unit", "Unit",
"ReportingDate", "ReportingDate",
"BMAOfficer", "BMAOfficer",
"Status", "Status",
"checkList", "checkList",
]) ])
: (visibleColumns.value = placementData.mappingPosition.columns); : (visibleColumns.value = placementData.mappingPosition.columns);
const columns = ref<QTableProps["columns"]>([ const columns = ref<QTableProps["columns"]>([
{ {
@ -672,40 +681,40 @@ const rows = ref<TableName[]>([
examResult: "ผ่าน", examResult: "ผ่าน",
}, },
}, },
{ // {
profileID: "401650002245", // profileID: "401650002245",
position: 7, // position: 7,
fullName: "นายอภินัน บอบู่", // fullName: " ",
dateOfBirth: "17 ก.พ. 2535", // dateOfBirth: "17 .. 2535",
gender: "ชาย", // gender: "",
ExamOrder: 7, // ExamOrder: 7,
unitId: "", // unitId: "",
UnitGroup: "กลุ่มงานช่วยนักบริหาร (กบห.)", // UnitGroup: " (.)",
Unit: "นักทรัพยากรบุคคล (กบห.4)", // Unit: " (.4)",
ReportingDate: "2023-05-30", // // ReportingDate: "2023-05-30", //
BMAOfficer: "ลูกจ้างชั่วคราว", // BMAOfficer: "",
Status: "ขอผ่อนผัน", // Status: "",
checkList: null, // checkList: null,
address: // address:
"200/88 ซอยศาลายา3 ถนนพุทธมณฑลสาย4 แขวงศาลายา เขตพุทธมณฑล อำเภอพุทธมณฑล จังหวัดนครปฐม 73170", // "200/88 3 4 73170",
university: "มหาวิทยาลัยบูรพา", // university: "",
degree: "การศึกษาบัณฑิต", // degree: "",
major: "เทคโนโลยีการศึกษา", // major: "",
remark: "-", // remark: "-",
number: 3, // number: 3,
examCount: 5, // examCount: 5,
scoreResult: { // scoreResult: {
scoreAFull: 200, // scoreAFull: 200,
scoreA: 133, // scoreA: 133,
scoreBFull: 200, // scoreBFull: 200,
scoreB: 149, // scoreB: 149,
scoreCFull: 100, // scoreCFull: 100,
scoreC: 0, // scoreC: 0,
scoreSumFull: 500, // scoreSumFull: 500,
scoreSum: 282, // scoreSum: 282,
examResult: "ผ่าน", // examResult: "",
}, // },
}, // },
]); ]);
const refOptions = ref<DataOption[]>([ const refOptions = ref<DataOption[]>([
@ -1012,6 +1021,13 @@ const save = () => {
console.log("rows===>", rows.value); console.log("rows===>", rows.value);
}; };
onMounted(async () => { onMounted(async () => {
if (keycloak.tokenParsed != null) {
roleAdmin.value = await keycloak.tokenParsed.role.includes("placement1");
console.log("roleAdmin===>", roleAdmin)
}
await fetchPosition(); await fetchPosition();
await nodeTree(); await nodeTree();
// await fetchData(); // await fetchData();
@ -1058,186 +1074,104 @@ const listKeyId = (data: any) => {
optionsLevel: positionLevelOptions.value, optionsLevel: positionLevelOptions.value,
}; };
}; };
const expiredAccount = ref<boolean>(false);
watch(expiredAccount, () => {
console.log("expiredAccount===>", expiredAccount.value);
});
</script> </script>
<template> <template>
<q-form ref="myForm"> <!-- <q-form ref="myForm"> -->
<Table <Table :expired-account="expiredAccount" :rows="rows" :columns="columns" :filter="filter"
:rows="rows" :visible-columns="visibleColumns" v-model:inputfilter="filter" v-model:inputvisible="visibleColumns"
:columns="columns" v-model:editvisible="editvisible" v-model:expiredaccountfilter="expiredAccount" :history="true" :boss="true"
:filter="filter" :saveNoDraft="true" :add="save" :role-admin="roleAdmin">
:visible-columns="visibleColumns" <template #columns="props">
v-model:inputfilter="filter" <q-tr :props="props">
v-model:inputvisible="visibleColumns" <q-icon class="q-mr-sm" size="15px" color="primary" name="mdi-bookmark" v-if="props.row.isDirector"></q-icon>
v-model:editvisible="editvisible"
:history="true"
:boss="true"
:saveNoDraft="true"
:add="save"
>
<template #columns="props">
<q-tr :props="props">
<q-icon
class="q-mr-sm"
size="15px"
color="primary"
name="mdi-bookmark"
v-if="props.row.isDirector"
></q-icon>
<q-td <q-td v-for="col in props.cols" :key="col.name" :props="props" @click="selectData(props.row)"
v-for="col in props.cols" class="cursor-pointer">
:key="col.name" <div v-if="col.name == 'Name'" class="table_ellipsis">
:props="props" {{ col.value }}
@click="selectData(props.row)" <div class="row col-12 text-no-wrap items-center">
class="cursor-pointer" <img v-if="props.row.avatar == null" src="@/assets/avatar_user.jpg" class="col-4 img-info" />
> <img v-else :src="props.row.avatar" class="col-4 img-info" />
<div v-if="col.name == 'Name'" class="table_ellipsis"> <div class="col-4">
{{ col.value }} <div class="text-weight-medium">
<div class="row col-12 text-no-wrap items-center"> {{ props.row.fullName }}
<img </div>
v-if="props.row.avatar == null" <div class="text-weight-light">
src="@/assets/avatar_user.jpg" {{ props.row.profileID }}
class="col-4 img-info"
/>
<img v-else :src="props.row.avatar" class="col-4 img-info" />
<div class="col-4">
<div class="text-weight-medium">
{{ props.row.fullName }}
</div>
<div class="text-weight-light">
{{ props.row.profileID }}
</div>
</div> </div>
</div> </div>
</div> </div>
<div v-else-if="col.name == 'Unit'" class="table_ellipsis"> </div>
<div <div v-else-if="col.name == 'Unit'" class="table_ellipsis">
v-if=" <div v-if="props.row.Status == 'ยังไม่บรรจุ' ||
props.row.Status == 'ยังไม่บรรจุ' || props.row.Status == 'สละสิทธิ์'
props.row.Status == 'สละสิทธิ์' ">
" -
>
-
</div>
<div v-else>
{{ props.row.UnitGroup }}
<p>{{ col.value }}</p>
</div>
</div> </div>
<div <div v-else>
v-else-if="col.name == 'ReportingDate' && col.value != '-'" {{ props.row.UnitGroup }}
class="table_ellipsis" <p>{{ col.value }}</p>
>
{{ mixin.date2Thai(col.value) }}
</div> </div>
<div v-else class="table_ellipsis"> </div>
{{ col.value }} <div v-else-if="col.name == 'ReportingDate' && col.value != '-'" class="table_ellipsis">
</div> {{ mixin.date2Thai(col.value) }}
</q-td> </div>
<q-td auto-width> <div v-else class="table_ellipsis">
<q-btn {{ col.value }}
v-if=" </div>
props.row.Status !== 'สละสิทธิ์' && </q-td>
props.row.Status !== 'บรรจุเเล้ว' <q-td auto-width>
" <q-btn v-if="props.row.Status !== 'สละสิทธิ์' &&
icon="mdi-dots-vertical" props.row.Status !== 'บรรจุเเล้ว'
size="12px" " icon="mdi-dots-vertical" size="12px" color="grey-7" flat round dense>
color="grey-7" <q-menu transition-show="jump-down" transition-hide="jump-up">
flat <q-list dense style="min-width: 100px">
round <q-item v-if="roleAdmin === true && props.row.Status === 'ยังไม่บรรจุ'" clickable v-close-popup
dense @click="openAppointModal">
> <q-item-section style="min-width: 0px" avatar class="q-py-sm">
<q-menu transition-show="jump-down" transition-hide="jump-up"> <q-icon color="primary" size="xs" name="mdi-bookmark-outline" />
<q-list dense style="min-width: 100px"> </q-item-section>
<q-item <q-item-section>เลอกหนวยงานทบบรรจ</q-item-section>
v-if="props.row.Status === 'ยังไม่บรรจุ'" </q-item>
clickable <q-separator />
v-close-popup <q-item v-if="roleAdmin === true && props.row.Status === 'ยังไม่บรรจุ'" clickable v-close-popup
@click="openAppointModal" @click="editDetail(props.row, 'wait')">
> <q-item-section style="min-width: 0px" avatar class="q-py-sm">
<q-item-section <q-icon color="blue" size="xs" name="mdi-account-alert-outline" />
style="min-width: 0px" </q-item-section>
avatar <q-item-section>ขอผอนผ</q-item-section>
class="q-py-sm" </q-item>
> <q-item v-else-if="props.row.Status === 'ขอผ่อนผัน'" clickable v-close-popup
<q-icon @click="editDetail(props.row, 'waitInfo')">
color="primary" <q-item-section style="min-width: 0px" avatar class="q-py-sm">
size="xs" <q-icon color="blue" size="xs" name="mdi-account-details-outline" />
name="mdi-bookmark-outline" </q-item-section>
/> <q-item-section>อมลการผอนผ</q-item-section>
</q-item-section> </q-item>
<q-item-section>เลอกหนวยงานทบบรรจ</q-item-section> <q-separator />
</q-item> <q-item v-if="props.row.Status === 'ยังไม่บรรจุ' ||
<q-separator /> props.row.Status === 'เตรียมบรรจุ'
<q-item " clickable v-close-popup @click="editDetail(props.row, 'cancel')">
v-if="props.row.Status === 'ยังไม่บรรจุ'" <q-item-section style="min-width: 0px" avatar class="q-py-sm">
clickable <q-icon color="pink" size="xs" name="mdi-account-cancel-outline" />
v-close-popup </q-item-section>
@click="editDetail(props.row, 'wait')" <q-item-section>สละสทธ</q-item-section>
> </q-item>
<q-item-section </q-list>
style="min-width: 0px" </q-menu>
avatar </q-btn>
class="q-py-sm" </q-td>
> </q-tr>
<q-icon </template>
color="blue" </Table>
size="xs" <!-- </q-form> -->
name="mdi-account-alert-outline"
/>
</q-item-section>
<q-item-section>ขอผอนผ</q-item-section>
</q-item>
<q-item
v-else-if="props.row.Status === 'ขอผ่อนผัน'"
clickable
v-close-popup
@click="editDetail(props.row, 'waitInfo')"
>
<q-item-section
style="min-width: 0px"
avatar
class="q-py-sm"
>
<q-icon
color="blue"
size="xs"
name="mdi-account-details-outline"
/>
</q-item-section>
<q-item-section>อมลการผอนผ</q-item-section>
</q-item>
<q-separator />
<q-item
v-if="
props.row.Status === 'ยังไม่บรรจุ' ||
props.row.Status === 'เตรียมบรรจุ'
"
clickable
v-close-popup
@click="editDetail(props.row, 'cancel')"
>
<q-item-section
style="min-width: 0px"
avatar
class="q-py-sm"
>
<q-icon
color="pink"
size="xs"
name="mdi-account-cancel-outline"
/>
</q-item-section>
<q-item-section>สละสทธ</q-item-section>
</q-item>
</q-list>
</q-menu>
</q-btn>
</q-td>
</q-tr>
</template>
</Table>
</q-form>
<q-dialog v-model="appointModal" persistent full-width> <q-dialog v-model="appointModal" persistent full-width>
<q-card> <q-card>
@ -1249,50 +1183,25 @@ const listKeyId = (data: any) => {
<div class="col-xs-12 col-sm-6 row"> <div class="col-xs-12 col-sm-6 row">
<q-card flat bordered class="fit q-pa-sm"> <q-card flat bordered class="fit q-pa-sm">
<q-scroll-area visible style="height: 70vh"> <q-scroll-area visible style="height: 70vh">
<q-input <q-input outlined dense v-model="search" placeholder="ค้นหา" class="q-mb-sm">
outlined
dense
v-model="search"
placeholder="ค้นหา"
class="q-mb-sm"
>
<template v-slot:append> <template v-slot:append>
<q-icon name="mdi-magnify" /> <q-icon name="mdi-magnify" />
</template> </template>
</q-input> </q-input>
<q-tree <q-tree no-transition ref="qtreeEdit" :nodes="nodesTree" node-key="keyId" @lazy-load="onLazyLoad" dense>
no-transition
ref="qtreeEdit"
:nodes="nodesTree"
node-key="keyId"
@lazy-load="onLazyLoad"
dense
>
<!--organization บรรทดแสดงชอหนวยงาน & + --> <!--organization บรรทดแสดงชอหนวยงาน & + -->
<template v-slot:header-organization="prop"> <template v-slot:header-organization="prop">
<div class="col"> <div class="col">
<div <div class="row items-center q-px-xs q-pt-xs q-gutter-sm">
class="row items-center q-px-xs q-pt-xs q-gutter-sm"
>
<!--แสดงชอแผนก มพวหนา คลกแลวกาง/ Tree--> <!--แสดงชอแผนก มพวหนา คลกแลวกาง/ Tree-->
<div class="text-weight-medium"> <div class="text-weight-medium">
{{ prop.node.organizationName }} {{ prop.node.organizationName }}
</div> </div>
<!--แสดง Total Count PositionNum--> <!--แสดง Total Count PositionNum-->
<q-badge <q-badge rounded color="grey-2" text-color="dark" :label="prop.node.totalPositionCount" />
rounded <q-badge v-if="prop.node.totalPositionVacant > 0" rounded color="red" outline
color="grey-2" :label="prop.node.totalPositionVacant" />
text-color="dark"
:label="prop.node.totalPositionCount"
/>
<q-badge
v-if="prop.node.totalPositionVacant > 0"
rounded
color="red"
outline
:label="prop.node.totalPositionVacant"
/>
<q-space /> <q-space />
</div> </div>
@ -1305,51 +1214,31 @@ const listKeyId = (data: any) => {
</div> </div>
</template> </template>
<template v-slot:header-person="prop"> <template v-slot:header-person="prop">
<q-item <q-item clickable :active="clickAction === prop.node.keyId" @click="
clickable clickAction =
:active="clickAction === prop.node.keyId" prop.node.name == `ว่าง` ||
@click="
clickAction =
prop.node.name == `ว่าง` ||
prop.node.name == `N/A` ||
prop.node.name == null
? listKeyId(prop)
: ''
"
active-class="my-list-link text-primary text-weight-medium"
:class="
prop.node.name == `ว่าง` ||
prop.node.name == `N/A` || prop.node.name == `N/A` ||
prop.node.name == null prop.node.name == null
? 'row items-center text-dark q-py-xs q-pl-sm rounded-borders my-list' ? listKeyId(prop)
: 'row items-center text-dark q-py-xs q-pl-sm rounded-borders my-list disabled' : ''
" " active-class="my-list-link text-primary text-weight-medium" :class="prop.node.name == `ว่าง` ||
> prop.node.name == `N/A` ||
<img prop.node.name == null
v-if=" ? 'row items-center text-dark q-py-xs q-pl-sm rounded-borders my-list'
prop.node.avatar == '' || : 'row items-center text-dark q-py-xs q-pl-sm rounded-borders my-list disabled'
prop.node.avatar == ">
'https://cdn.quasar.dev/img/boy-avatar.png' <img v-if="prop.node.avatar == '' ||
" prop.node.avatar ==
src="@/assets/avatar_user.jpg" 'https://cdn.quasar.dev/img/boy-avatar.png'
class="col-xs-1 col-sm-2" " src="@/assets/avatar_user.jpg" class="col-xs-1 col-sm-2"
style="width: 28px; height: 28px; border-radius: 50%" style="width: 28px; height: 28px; border-radius: 50%" />
/> <img v-else :src="prop.node.avatar" class="col-xs-1 col-sm-2"
<img style="width: 28px; height: 28px; border-radius: 50%" />
v-else
:src="prop.node.avatar"
class="col-xs-1 col-sm-2"
style="width: 28px; height: 28px; border-radius: 50%"
/>
<!--=====ตำแหนงวาง แดง=====--> <!--=====ตำแหนงวาง แดง=====-->
<div <div v-if="prop.node.name == `ว่าง` ||
v-if=" prop.node.name == `N/A` ||
prop.node.name == `ว่าง` || prop.node.name == null
prop.node.name == `N/A` || " class="q-px-sm text-weight-medium text-red">
prop.node.name == null
"
class="q-px-sm text-weight-medium text-red"
>
าง าง
</div> </div>
<!--=====วหน เขยว=====--> <!--=====วหน เขยว=====-->
@ -1374,13 +1263,8 @@ const listKeyId = (data: any) => {
<div class="q-pr-sm"> <div class="q-pr-sm">
{{ prop.node.positionLevel }} {{ prop.node.positionLevel }}
</div> </div>
<q-icon <q-icon v-if="prop.node.positionLeaderFlag" class="q-mr-sm" size="15px" color="primary"
v-if="prop.node.positionLeaderFlag" name="mdi-bookmark"></q-icon>
class="q-mr-sm"
size="15px"
color="primary"
name="mdi-bookmark"
></q-icon>
<q-space /> <q-space />
</q-item> </q-item>
@ -1395,46 +1279,24 @@ const listKeyId = (data: any) => {
<div class="row col-12 q-col-gutter-xs"> <div class="row col-12 q-col-gutter-xs">
<div class="col-xs-12 col-sm-12 col-md-12"></div> <div class="col-xs-12 col-sm-12 col-md-12"></div>
<div class="col-xs-6 col-sm-6 col-md-6"> <div class="col-xs-6 col-sm-6 col-md-6">
<datepicker <datepicker menu-class-name="modalfix" :readonly="!edit" v-model="date" :locale="'th'" autoApply
menu-class-name="modalfix" :enableTimePicker="false" @update:modelValue="clickEditRow" week-start="0">
:readonly="!edit"
v-model="date"
:locale="'th'"
autoApply
:enableTimePicker="false"
@update:modelValue="clickEditRow"
week-start="0"
>
<template #year="{ year }">{{ year + 543 }}</template> <template #year="{ year }">{{ year + 543 }}</template>
<template #year-overlay-value="{ value }">{{ <template #year-overlay-value="{ value }">{{
parseInt(value + 543) parseInt(value + 543)
}}</template> }}</template>
<template #trigger> <template #trigger>
<q-input <q-input :class="getClass(edit)" :outlined="edit" dense lazy-rules :borderless="!edit"
:class="getClass(edit)" :model-value="date2Thai(date)" :rules="[
:outlined="edit" (val: string) =>
dense !!val ||
lazy-rules `${'วันที่รายงานตัว'}`,
:borderless="!edit" ]" :label="`${'วันที่รายงานตัว'}`" hide-bottom-space>
:model-value="date2Thai(date)"
:rules="[
(val: string) =>
!!val ||
`${'วันที่รายงานตัว'}`,
]"
:label="`${'วันที่รายงานตัว'}`"
hide-bottom-space
>
<template v-slot:prepend> <template v-slot:prepend>
<q-icon <q-icon name="event" class="cursor-pointer" :style="edit
name="event" ? 'color: var(--q-primary)'
class="cursor-pointer" : 'color: var(--q-grey)'
:style=" ">
edit
? 'color: var(--q-primary)'
: 'color: var(--q-grey)'
"
>
</q-icon> </q-icon>
</template> </template>
</q-input> </q-input>
@ -1443,145 +1305,58 @@ const listKeyId = (data: any) => {
</div> </div>
<q-space /> <q-space />
<div class="col-xs-6 col-sm-6 col-md-6"> <div class="col-xs-6 col-sm-6 col-md-6">
<q-input <q-input disable standout readonly class="custom-input" dense lazy-rules v-model="posNoId"
disable :label="`${'เลขที่ตำแหน่ง'}`" />
standout
readonly
class="custom-input"
dense
lazy-rules
v-model="posNoId"
:label="`${'เลขที่ตำแหน่ง'}`"
/>
</div> </div>
<div class="col-xs-6 col-sm-6 col-md-6"> <div class="col-xs-6 col-sm-6 col-md-6">
<q-input <q-input disable readonly class="custom-input" standout dense lazy-rules v-model="positionId"
disable :label="`${'ตำแหน่ง'}`" />
readonly
class="custom-input"
standout
dense
lazy-rules
v-model="positionId"
:label="`${'ตำแหน่ง'}`"
/>
</div> </div>
<div class="col-xs-6 col-sm-6 col-md-6"> <div class="col-xs-6 col-sm-6 col-md-6">
<q-select <q-select :class="getClass(edit)" :outlined="edit" :readonly="!edit" class="custom-input" standout
:class="getClass(edit)" dense hide-bottom-space lazy-rules v-model="positionPathSideId"
:outlined="edit" :rules="[(val: string) => !!val || `${'ด้าน/สาขา'}`]" :label="`${'ด้าน/สาขา'}`" />
:readonly="!edit"
class="custom-input"
standout
dense
hide-bottom-space
lazy-rules
v-model="positionPathSideId"
:rules="[(val:string) => !!val || `${'ด้าน/สาขา'}`]"
:label="`${'ด้าน/สาขา'}`"
/>
</div> </div>
<!-- :rules="[(val:string) => !!val || `${'กรุณาเลือกด้าน/สาขา'}`]" --> <!-- :rules="[(val:string) => !!val || `${'กรุณาเลือกด้าน/สาขา'}`]" -->
<div class="col-xs-6 col-sm-6 col-md-6"> <div class="col-xs-6 col-sm-6 col-md-6">
<q-input <q-input disable readonly class="custom-input" standout dense lazy-rules v-model="positionTypeId"
disable :label="`${'ประเภทตำแหน่ง'}`" />
readonly
class="custom-input"
standout
dense
lazy-rules
v-model="positionTypeId"
:label="`${'ประเภทตำแหน่ง'}`"
/>
</div> </div>
<div class="col-xs-6 col-sm-6 col-md-6"> <div class="col-xs-6 col-sm-6 col-md-6">
<q-input <q-input disable readonly class="custom-input" standout dense lazy-rules v-model="positionLineId"
disable :label="`${'สายงาน'}`" />
readonly
class="custom-input"
standout
dense
lazy-rules
v-model="positionLineId"
:label="`${'สายงาน'}`"
/>
</div> </div>
<div class="col-xs-6 col-sm-6 col-md-6"> <div class="col-xs-6 col-sm-6 col-md-6">
<q-select <q-select :class="getClass(edit)" :outlined="edit" :readonly="!edit" class="custom-input" standout
:class="getClass(edit)" dense lazy-rules :options="positionLevelOptions" v-model="positionLevelId" :label="`${'ระดับ'}`"
:outlined="edit" hide-bottom-space :rules="[(val: string) => !!val || `${'กรุณาเลือกระดับ'}`]" emit-value
:readonly="!edit" map-options />
class="custom-input"
standout
dense
lazy-rules
:options="positionLevelOptions"
v-model="positionLevelId"
:label="`${'ระดับ'}`"
hide-bottom-space
:rules="[(val:string) => !!val || `${'กรุณาเลือกระดับ'}`]"
emit-value
map-options
/>
</div> </div>
<div class="col-sx-12 col-sm-12 col-md-12"> <div class="col-sx-12 col-sm-12 col-md-12">
<q-separator inset size="2px" class="q-my-md" /> <q-separator inset size="2px" class="q-my-md" />
</div> </div>
<div class="col-xs-6 col-sm-6 col-md-6"> <div class="col-xs-6 col-sm-6 col-md-6">
<q-input <q-input :class="getClass(edit)" :outlined="edit" dense lazy-rules :readonly="!edit"
:class="getClass(edit)" :borderless="!edit" v-model="amount" :rules="[(val) => !!val || `${'กรุณากรอกเงินเดือน'}`]"
:outlined="edit" :label="`${'เงินเดือน'}`" @update:modelValue="clickEditRow" type="number" hide-bottom-space />
dense
lazy-rules
:readonly="!edit"
:borderless="!edit"
v-model="amount"
:rules="[(val) => !!val || `${'กรุณากรอกเงินเดือน'}`]"
:label="`${'เงินเดือน'}`"
@update:modelValue="clickEditRow"
type="number"
hide-bottom-space
/>
</div> </div>
<div class="col-xs-6 col-sm-6 col-md-6"> <div class="col-xs-6 col-sm-6 col-md-6">
<q-input <q-input :class="getClass(edit)" :outlined="edit" dense lazy-rules :readonly="!edit"
:class="getClass(edit)" :borderless="!edit" v-model="positionSalaryAmount" :rules="[
:outlined="edit"
dense
lazy-rules
:readonly="!edit"
:borderless="!edit"
v-model="positionSalaryAmount"
:rules="[
(val) => !!val || `${'กรุณากรอกเงินประจำตำแหน่ง'}`, (val) => !!val || `${'กรุณากรอกเงินประจำตำแหน่ง'}`,
]" ]" :label="`${'เงินประจำตำแหน่ง'}`" @update:modelValue="clickEditRow" type="number"
:label="`${'เงินประจำตำแหน่ง'}`" hide-bottom-space />
@update:modelValue="clickEditRow"
type="number"
hide-bottom-space
/>
</div> </div>
<div class="col-xs-6 col-sm-6 col-md-6"> <div class="col-xs-6 col-sm-6 col-md-6">
<q-input <q-input :class="getClass(edit)" :outlined="edit" dense lazy-rules :readonly="!edit"
:class="getClass(edit)" :borderless="!edit" v-model="mouthSalaryAmount" :rules="[
:outlined="edit"
dense
lazy-rules
:readonly="!edit"
:borderless="!edit"
v-model="mouthSalaryAmount"
:rules="[
(val) => (val) =>
!!val || `${'กรุณากรอกเงินค่าตอบแทนรายเดือน'}`, !!val || `${'กรุณากรอกเงินค่าตอบแทนรายเดือน'}`,
]" ]" :label="`${'เงินค่าตอบแทนรายเดือน'}`" @update:modelValue="clickEditRow" type="number"
:label="`${'เงินค่าตอบแทนรายเดือน'}`" hide-bottom-space />
@update:modelValue="clickEditRow"
type="number"
hide-bottom-space
/>
</div> </div>
</div> </div>
</q-scroll-area> </q-scroll-area>
@ -1591,87 +1366,47 @@ const listKeyId = (data: any) => {
</q-card-section> </q-card-section>
<q-separator /> <q-separator />
<DialogFooter <DialogFooter v-model:editvisible="edit" :validate="validateData" v-model:modalEdit="modalEdit"
v-model:editvisible="edit" :save="saveAppoint" />
:validate="validateData"
v-model:modalEdit="modalEdit"
:save="saveAppoint"
/>
</q-form> </q-form>
</q-card> </q-card>
</q-dialog> </q-dialog>
<q-form ref="myForm"> <q-form ref="myForm">
<DialogCard <DialogCard v-model:Modal="modal" :getdetail="itemtest" :close="clickClose" :validate="validateData" />
v-model:Modal="modal"
:getdetail="itemtest"
:close="clickClose"
:validate="validateData"
/>
</q-form> </q-form>
<q-dialog v-model="modal_right" persistent> <q-dialog v-model="modal_right" persistent>
<q-card style="width: 800px"> <q-card style="width: 800px">
<q-form ref="myForm"> <q-form ref="myForm">
<DialogHeader <DialogHeader :title="`${modalEdit ? 'ขอผ่อนผัน' : 'สละสิทธิ์'} ชื่อ${Name}`" :close="clickClose" />
:title="`${modalEdit ? 'ขอผ่อนผัน' : 'สละสิทธิ์'} ชื่อ${Name}`" <q-separator />
:close="clickClose" <q-card-section class="q-p-sm">
/> <div class="col-xs-12 col-sm-12 col-md-12">
<q-separator /> <q-input :class="getClass(edit)" hide-bottom-space :outlined="edit" dense lazy-rules
<q-card-section class="q-p-sm"> :rules="[(val) => !!val || 'กรุณากรอกเหตุผล']" :readonly="!edit" :borderless="!edit"
<div class="col-xs-12 col-sm-12 col-md-12"> v-model="positionMasterUserNote" :label="`${'กรอกเหตุผล'}`" @update:model-value="clickEditRow"
<q-input type="textarea" />
:class="getClass(edit)" <q-file v-if="getNumFile === 1" v-model="files" dense :label="`${'เลือกไฟล์เอกสารหลักฐาน'}`" outlined
hide-bottom-space use-chips :rules="[(val) => !!val || 'กรุณาเลือกไฟล์เอกสารหลักฐาน']" multiple
:outlined="edit" @update:model-value="clickEditRow" class="q-py-sm">
dense <template v-slot:prepend>
lazy-rules <q-icon name="attach_file" color="primary" />
:rules="[(val) => !!val || 'กรุณากรอกเหตุผล']" </template>
:readonly="!edit" </q-file>
:borderless="!edit" </div>
v-model="positionMasterUserNote" </q-card-section>
:label="`${'กรอกเหตุผล'}`" <q-separator />
@update:model-value="clickEditRow" <DialogFooter v-model:editvisible="edit" v-model:modalEdit="modalEdit" :validate="validateData"
:save="modalEdit ? savePostpone : saveDisclaim" />
type="textarea" </q-form>
/> </q-card>
<q-file
v-if="getNumFile === 1"
v-model="files"
dense
:label="`${'เลือกไฟล์เอกสารหลักฐาน'}`"
outlined
use-chips
:rules="[(val) => !!val || 'กรุณาเลือกไฟล์เอกสารหลักฐาน']"
multiple
@update:model-value="clickEditRow"
class="q-py-sm"
>
<template v-slot:prepend>
<q-icon name="attach_file" color="primary" />
</template>
</q-file>
</div>
</q-card-section>
<q-separator />
<DialogFooter
v-model:editvisible="edit"
v-model:modalEdit="modalEdit"
:validate="validateData"
:save="modalEdit ? savePostpone : saveDisclaim"
/>
</q-form>
</q-card>
</q-dialog> </q-dialog>
<!-- dialog ขอผอนผ / สละสทธ --> <!-- dialog ขอผอนผ / สละสทธ -->
<q-dialog v-model="modalwaitInfo" persistent> <q-dialog v-model="modalwaitInfo" persistent>
<q-card style="width: 500px; max-width: 500px"> <q-card style="width: 500px; max-width: 500px">
<q-form ref="myForm" <q-form ref="myForm">
>สละสทธ <DialogHeader :title="`${modalEdit ? 'ขอผ่อนผัน' : 'สละสิทธิ์'} ชื่อ${Name}`" :close="clickClose" />
<DialogHeader
:title="`${modalEdit ? 'ขอผ่อนผัน' : 'สละสิทธิ์'} ชื่อ${Name}`"
:close="clickClose"
/>
<q-separator /> <q-separator />
<q-card-section class="q-p-sm"> <q-card-section class="q-p-sm">
<div class="row"> <div class="row">
@ -1681,14 +1416,7 @@ const listKeyId = (data: any) => {
<div class="row q-pt-md"> <div class="row q-pt-md">
<div class="col-3 text-grey-7 q-mt-sm">เอกสารหลกฐาน</div> <div class="col-3 text-grey-7 q-mt-sm">เอกสารหลกฐาน</div>
<div class="col-2 q-mt-sm">กรอกเหตผล</div> <div class="col-2 q-mt-sm">กรอกเหตผล</div>
<q-btn <q-btn color="primary" flat dense round size="14px" icon="mdi-download" />
color="primary"
flat
dense
round
size="14px"
icon="mdi-download"
/>
</div> </div>
</q-card-section> </q-card-section>
<q-separator /> <q-separator />
@ -1701,6 +1429,7 @@ const listKeyId = (data: any) => {
.custom-input { .custom-input {
font-size: 16px; font-size: 16px;
} }
.my-list-link { .my-list-link {
border-radius: 5px; border-radius: 5px;
@ -1712,6 +1441,7 @@ const listKeyId = (data: any) => {
margin-bottom: 0; margin-bottom: 0;
color: #818181; color: #818181;
} }
.img-info { .img-info {
width: 30px !important; width: 30px !important;
height: 30px !important; height: 30px !important;

View file

@ -1,132 +1,30 @@
<template> <template>
<div class="q-px-md q-pb-md"> <div class="q-px-md q-pb-md">
<div class="col-12 row q-py-sm" v-if="nornmalData == false"> <div class="col-12 row q-py-sm">
<q-toggle v-if="roleAdmin === false" class="col-xs-12 col-sm-5 col-md-5 toggle-expired-account"
:model-value="expiredAccount" color="blue" label="แสดงบัญชีหมดอายุ" @update:model-value="updateExpiredAccount" />
<q-space /> <q-space />
<div class="items-center" style="display: flex"> <div class="items-center" style="display: flex">
<div <q-input standout dense :model-value="inputfilter" ref="filterRef" @update:model-value="updateInput" outlined
class="row items-center" debounce="300" placeholder="ค้นหา" style="max-width: 200px" class="q-ml-sm">
style="display: flex"
v-if="publicData == false && publicNoBtn == false"
></div>
<q-input
standout
dense
:model-value="inputfilter"
ref="filterRef"
@update:model-value="updateInput"
outlined
debounce="300"
placeholder="ค้นหา"
style="max-width: 200px"
class="q-ml-sm"
>
<template v-slot:append> <template v-slot:append>
<q-icon v-if="inputfilter == ''" name="search" /> <q-icon v-if="inputfilter == ''" name="search" />
<q-icon <q-icon v-if="inputfilter !== ''" name="clear" class="cursor-pointer" @click="resetFilter" />
v-if="inputfilter !== ''"
name="clear"
class="cursor-pointer"
@click="resetFilter"
/>
</template> </template>
</q-input> </q-input>
<!-- แสดง table ใน คอลมน --> <!-- แสดง table ใน คอลมน -->
<q-select <q-select :model-value="inputvisible" @update:model-value="updateVisible" :display-value="$q.lang.table.columns"
:model-value="inputvisible" multiple outlined dense :options="attrs.columns" options-dense option-value="name" map-options emit-value
@update:model-value="updateVisible" style="min-width: 150px" class="gt-xs q-ml-sm" />
:display-value="$q.lang.table.columns"
multiple
outlined
dense
:options="attrs.columns"
options-dense
option-value="name"
map-options
emit-value
style="min-width: 150px"
class="gt-xs q-ml-sm"
/>
</div> </div>
</div> </div>
<div class="col-12 row q-py-sm items-center" v-if="nornmalData == true"> <q-table ref="table" flat bordered class="custom-header-table" v-bind="attrs" virtual-scroll
<span class="text-subtitle1">{{ titleText }}</span> :virtual-scroll-sticky-size-start="48" dense :pagination-label="paginationLabel" v-model:pagination="pagination">
<q-btn
flat
round
color="primary"
@click="refresh"
icon="mdi-refresh"
v-if="props.refreshBtn"
>
<q-tooltip>ปเดตขอม</q-tooltip>
</q-btn>
<q-space />
<div class="items-center" style="display: flex">
<!-- นหาขอความใน table -->
<q-input
standout
dense
:model-value="inputfilter"
ref="filterRef"
@update:model-value="updateInput"
outlined
debounce="300"
placeholder="ค้นหา"
style="max-width: 200px"
class="q-ml-sm"
>
<template v-slot:append>
<q-icon v-if="inputfilter == ''" name="search" />
<q-icon
v-if="inputfilter !== ''"
name="clear"
class="cursor-pointer"
@click="resetFilter"
/>
</template>
</q-input>
<!-- แสดงคอลมนใน table -->
<q-select
:model-value="inputvisible"
@update:model-value="updateVisible"
:display-value="$q.lang.table.columns"
multiple
outlined
dense
:options="attrs.columns"
options-dense
option-value="name"
map-options
emit-value
style="min-width: 150px"
class="gt-xs q-ml-sm"
/>
</div>
</div>
<q-table
ref="table"
flat
bordered
class="custom-header-table"
v-bind="attrs"
virtual-scroll
:virtual-scroll-sticky-size-start="48"
dense
:pagination-label="paginationLabel"
v-model:pagination="pagination"
>
<template v-slot:pagination="scope"> <template v-slot:pagination="scope">
<q-pagination <q-pagination v-model="pagination.page" color="primary" :max="scope.pagesNumber" :max-pages="5" size="sm"
v-model="pagination.page" boundary-links direction-links></q-pagination>
color="primary"
:max="scope.pagesNumber"
:max-pages="5"
size="sm"
boundary-links
direction-links
></q-pagination>
</template> </template>
<template v-slot:header="props"> <template v-slot:header="props">
<q-tr :props="props"> <q-tr :props="props">
@ -142,6 +40,7 @@
</q-table> </q-table>
</div> </div>
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { ref, useAttrs } from "vue"; import { ref, useAttrs } from "vue";
import { useCounterMixin } from "@/stores/mixin"; import { useCounterMixin } from "@/stores/mixin";
@ -240,6 +139,8 @@ const props = defineProps({
type: Function, type: Function,
default: () => console.log("not function"), default: () => console.log("not function"),
}, },
expiredAccount: Boolean,
roleAdmin: Boolean
}); });
const pagination = ref({ const pagination = ref({
sortBy: "desc", sortBy: "desc",
@ -263,11 +164,9 @@ const emit = defineEmits([
"update:editvisible", "update:editvisible",
"update:titleText", "update:titleText",
"update:inputvisibleFilter", "update:inputvisibleFilter",
"update:expiredaccountfilter"
]); ]);
const updateEdit = (value: any) => {
emit("update:editvisible", value);
};
const updateInput = (value: any) => { const updateInput = (value: any) => {
emit("update:inputfilter", value); emit("update:inputfilter", value);
}; };
@ -278,6 +177,10 @@ const updateVisibleFilter = (value: any) => {
emit("update:inputvisibleFilter", value); emit("update:inputvisibleFilter", value);
}; };
const updateExpiredAccount = (value: any) => {
emit("update:expiredaccountfilter", value);
};
const checkSave = () => { const checkSave = () => {
props.validate(); props.validate();
props.save(); props.save();
@ -288,71 +191,6 @@ const checkSave = () => {
// }); // });
// } // }
}; };
const clickEdit = () => {
updateEdit(!props.editvisible);
editvisible.value = !editvisible.value;
props.edit();
};
const clickCancel = () => {
updateEdit(!props.editvisible);
editvisible.value = !editvisible.value;
props.cancel();
};
const publishModal = () => {
props.validate();
const filter = attrs.value.rows.filter((r: any) => r.name == "");
if (filter.length == 0 || attrs.value.rows.length == 0) {
// modalPublish.value = true;
dialogMessage(
$q,
"ต้องการเผยแพร่ข้อมูลนี้หรือไม่?",
"ข้อมูลที่กำลังถูกเผยแพร่นี้จะมีผลใช้งานทันที",
"public",
"เผยแพร่",
"public",
props.publish,
undefined
);
}
};
const DeleteModal = () => {
// modalDelete.value = true;
dialogMessage(
$q,
"ต้องการลบข้อมูลบันทึกร่างนี้หรือไม่?",
"ข้อมูลบันทึกร่างที่กำลังถูกลบนี้จะมีผลใช้งานทันที",
"mdi-file-remove-outline",
"ลบบันทึก",
"red",
props.deleted,
undefined
);
};
const edit = async () => {
updateEdit(!props.editvisible);
props.edit();
};
const add = async () => {
// if (myForm.value !== null) {
// myForm.value.validate();
// }
props.validate();
props.add();
await table.value.lastPage();
await table.value.scrollTo(attrs.value.rows.length - 1);
};
const deleted = async () => {
// const deletedF = () => {
if (props.publicNoBtn === false) {
updateEdit(false);
}
props.deleted();
};
const resetFilter = () => { const resetFilter = () => {
// reset X // reset X

View file

@ -14,7 +14,7 @@ const Detail = defineAsyncComponent(
export default [ export default [
{ {
path: "/registryEmployee", path: "/registry-employee",
name: "registryEmployee", name: "registryEmployee",
component: Main, component: Main,
meta: { meta: {

View file

@ -112,7 +112,7 @@
dense dense
> >
<q-menu transition-show="jump-down" transition-hide="jump-up"> <q-menu transition-show="jump-down" transition-hide="jump-up">
<q-list dense style="min-width: 100px"> <q-list dense style="min-width: 150px">
<q-item <q-item
clickable clickable
v-close-popup v-close-popup
@ -166,6 +166,7 @@
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { ref, onMounted } from "vue"; import { ref, onMounted } from "vue";
import router from "@/router";
import { useQuasar } from "quasar"; import { useQuasar } from "quasar";
import { useCounterMixin } from "@/stores/mixin"; import { useCounterMixin } from "@/stores/mixin";
import type { QInput, QForm } from "quasar"; import type { QInput, QForm } from "quasar";