Merge branch 'develop' into work

This commit is contained in:
Kittapath 2023-07-22 23:13:37 +07:00
commit 1b4465bf36
9 changed files with 2672 additions and 1603 deletions

View file

@ -206,6 +206,7 @@ const menuList = readonly<any[]>([
}, },
], ],
}, },
{ {
key: 7, key: 7,
icon: "mdi-account-cancel-outline", icon: "mdi-account-cancel-outline",
@ -213,6 +214,44 @@ const menuList = readonly<any[]>([
label: "พ้นจากราชการ", label: "พ้นจากราชการ",
path: "retirement", path: "retirement",
role: "retirement", role: "retirement",
children: [
{
key: 7.1,
label: "ประกาศเกษียณ",
path: "retirement",
role: "retirement",
},
{
key: 7.2,
label: "ลาออก",
path: "resign",
role: "retirement",
},
{
key: 7.3,
label: "คำสั่งลาออก",
path: "resign-order",
role: "retirement",
},
{
key: 7.4,
label: "Exit interviwe",
// path: "",
role: "retirement",
},
{
key: 7.5,
label: "ถึงแก่กรรม",
path: "deceased",
role: "retirement",
},
{
key: 7.6,
label: "คำสั่งให้ออก ปลดออก ไล่ออก",
path: "dismiss-order",
role: "retirement",
},
],
}, },
{ {
key: 8, key: 8,

View file

@ -153,6 +153,42 @@
</div> </div>
</div> </div>
<q-space /> <q-space />
<q-btn round flat color="pink-5" icon="mdi-file-eye-outline">
<q-tooltip>{{
reasonStatus ? "การกลับเข้ารับราชการ" : "การออกจากราชการ"
}}</q-tooltip>
<q-menu transition-show="jump-down" transition-hide="jump-up">
<q-list dense style="min-width: 160px">
<q-item clickable v-close-popup @click="clickPassaway">
<q-item-section style="min-width: 0px" avatar class="q-py-sm">
</q-item-section>
<q-item-section>งแกกรรม</q-item-section>
</q-item>
<q-separator />
<q-item clickable v-close-popup @click="clickaddOrder">
<q-item-section style="min-width: 0px" avatar class="q-py-sm">
</q-item-section>
<q-item-section>ใหออกจากราชการ</q-item-section>
</q-item>
<q-separator />
<q-item clickable v-close-popup @click="clickaddOrder">
<q-item-section style="min-width: 0px" avatar class="q-py-sm">
</q-item-section>
<q-item-section>ปลดออกจากราชการ</q-item-section>
</q-item>
<q-separator />
<q-item clickable v-close-popup @click="clickaddOrder">
<q-item-section style="min-width: 0px" avatar class="q-py-sm">
</q-item-section>
<q-item-section>ไลออกจากราชการ</q-item-section>
</q-item>
<q-separator />
</q-list>
</q-menu>
</q-btn>
<q-btn <q-btn
round round
flat flat
@ -349,6 +385,41 @@
</q-card-actions> </q-card-actions>
</q-card> </q-card>
</q-dialog> </q-dialog>
<!-- Dialog แนบใบมรณบตร -->
<q-dialog v-model="dialogPassaway" persistent>
<q-card style="width: 100vw; max-width: 60vw">
<q-card-section class="q-py-sm row">
<div class="text-h6">แนบใบมรณบตร</div>
<q-space />
<q-btn
icon="close"
unelevated
round
dense
@click="closePassaway"
style="color: #ff8080; background-color: #ffdede"
>
<q-tooltip>ดหนาน</q-tooltip>
</q-btn>
</q-card-section>
<q-separator />
<q-card-actions align="right">
<q-file
class="col-xs-12 col-sm-12"
outlined
dense
v-model="filePassaway"
label="แนบใบมรณบัตร"
hide-bottom-space
lazy-rules
>
<template v-slot:prepend>
<q-icon name="attach_file" />
</template>
</q-file>
</q-card-actions>
</q-card>
</q-dialog>
<!-- Dialog เลอก เกษยณ --> <!-- Dialog เลอก เกษยณ -->
<q-dialog v-model="dialogLeave" persistent> <q-dialog v-model="dialogLeave" persistent>
<q-card style="width: 600px"> <q-card style="width: 600px">
@ -559,9 +630,11 @@ const dialog = ref<boolean>(false);
const dialogShort = ref<boolean>(false); const dialogShort = ref<boolean>(false);
const dialogLeave = ref<boolean>(false); const dialogLeave = ref<boolean>(false);
const dialogImage = ref<boolean>(false); const dialogImage = ref<boolean>(false);
const dialogPassaway = ref<boolean>(false);
const loader = ref<boolean>(false); // const loader = ref<boolean>(false); //
const statusEdit = ref<boolean>(false); const statusEdit = ref<boolean>(false);
const activeImage = ref<any | null>(null); const activeImage = ref<any | null>(null);
const filePassaway = ref(null);
const images = ref<any>([]); const images = ref<any>([]);
const profileId = ref<string>(route.params.id.toString()); const profileId = ref<string>(route.params.id.toString());
const profileType = ref<string>(""); const profileType = ref<string>("");
@ -806,6 +879,10 @@ const closeImage = () => {
dialogImage.value = false; dialogImage.value = false;
}; };
const closePassaway = () => {
dialogPassaway.value = false;
};
const closeLeave = () => { const closeLeave = () => {
dialogLeave.value = false; dialogLeave.value = false;
}; };
@ -818,6 +895,10 @@ const closeKp7Short = () => {
dialogShort.value = false; dialogShort.value = false;
}; };
const clickaddOrder = () => {
router.push({ name: "addOrder" });
};
const downloadKP7 = () => {}; const downloadKP7 = () => {};
const downloadKP7Short = () => {}; const downloadKP7Short = () => {};
@ -896,6 +977,10 @@ const clickRetire = async () => {
} }
}; };
const clickPassaway = async () => {
dialogPassaway.value = true;
};
const Retire = async () => { const Retire = async () => {
if (reasonStatus.value == true) { if (reasonStatus.value == true) {
loaderPage(true); loaderPage(true);

View file

@ -4,6 +4,10 @@
const Main = () => import("@/modules/04_registry/views/Main.vue"); const Main = () => import("@/modules/04_registry/views/Main.vue");
const Detail = () => import("@/modules/04_registry/components/Profile.vue"); const Detail = () => import("@/modules/04_registry/components/Profile.vue");
const addOrder = () =>
import(
"@/modules/05_placement/components/OrderPlacement/addOrderPlacement.vue"
);
export default [ export default [
{ {
@ -26,4 +30,14 @@ export default [
Role: "registry", Role: "registry",
}, },
}, },
{
path: "/dismiss-order/add",
name: "addOrder",
component: addOrder,
meta: {
Auth: true,
Key: [7],
Role: "registry",
},
},
]; ];

View file

@ -0,0 +1,791 @@
<template>
<div class="toptitle text-dark col-12 row items-center">คำสงลาออก</div>
<div>
<q-card flat bordered class="col-12 q-mt-sm q-pa-md">
<div class="row q-col-gutter-sm">
<div class="row col-12 q-col-gutter-sm">
<q-select
class="col-xs-12 col-sm-3 col-md-2"
v-model="fiscalyear"
label="ปีงบประมาณ"
dense
emit-value
map-options
:options="fiscalyearOP"
option-value="id"
option-label="name"
lazy-rules
hide-bottom-space
:readonly="false"
:borderless="false"
:outlined="true"
:hide-dropdown-icon="false"
@update:model-value="searchFilterTable"
/>
<div>
<q-btn
size="12px"
flat
round
color="add"
icon="mdi-plus"
@click="clickAdd"
>
<q-tooltip>เพมขอม</q-tooltip>
<!-- <q-menu>
<q-list style="min-width: 100px">
<q-item clickable @click="clickAdd">
<q-item-section>ลายเซนช (ออฟไลน)</q-item-section>
</q-item>
<q-item clickable v-close-popup disable>
<q-item-section
>ลายเซนอเลกทรอนกส (ออนไลน)</q-item-section
>
</q-item>
</q-list>
</q-menu> -->
</q-btn>
</div>
<q-space />
<q-input
class="col-xs-12 col-sm-3 col-md-2"
standout
dense
v-model="filterKeyword"
ref="filterRef"
outlined
debounce="300"
placeholder="ค้นหา"
>
<template v-slot:append>
<q-icon v-if="filterKeyword == ''" name="search" />
<q-icon
v-if="filterKeyword !== ''"
name="clear"
class="cursor-pointer"
@click="resetFilter"
/>
</template>
</q-input>
<q-select
v-model="visibleColumns"
multiple
outlined
dense
options-dense
:display-value="$q.lang.table.columns"
emit-value
map-options
:options="columns"
option-value="name"
options-cover
style="min-width: 150px"
class="col-xs-12 col-sm-3 col-md-2"
/>
</div>
<div class="col-12">
<q-card bordered class="col-12 filter-card q-pa-sm">
<div class="row col-12 q-col-gutter-sm">
<q-select
class="col-xs-12 col-sm-3 col-md-2"
v-model="OrderType"
label="ประเภท"
dense
emit-value
map-options
option-label="name"
:options="OrderTypeOption"
option-value="id"
lazy-rules
hide-bottom-space
:readonly="false"
:borderless="false"
:outlined="true"
:hide-dropdown-icon="false"
@update:model-value="searchFilterTable"
/>
<q-select
class="col-xs-12 col-sm-3 col-md-2"
v-model="OrderStatus"
label="สถานะ"
dense
emit-value
map-options
option-label="name"
:options="OrderStatusOption"
option-value="id"
lazy-rules
hide-bottom-space
:readonly="false"
:borderless="false"
:outlined="true"
:hide-dropdown-icon="false"
@update:model-value="searchFilterTable"
/>
</div>
</q-card>
</div>
<div class="col-12">
<q-table
ref="table"
:columns="columns"
:rows="UpdataData"
:filter="filterKeyword"
row-key="Order"
flat
bordered
:paging="true"
dense
class="custom-header-table"
v-bind="attrs"
:visible-columns="visibleColumns"
:pagination-label="paginationLabel"
v-model:pagination="pagination"
>
<template v-slot:header="props">
<q-tr :props="props">
<q-th v-for="col in props.cols" :key="col.name" :props="props">
<span class="text-weight-medium">{{ col.label }}</span>
</q-th>
<q-th auto-width />
</q-tr>
</template>
<template v-slot:body="props">
<q-tr :props="props" class="cursor-pointer">
<q-td
key="Order"
:props="props"
@click="redirectToPage(props.row.Order)"
>
{{ props.row.Order }}
</q-td>
<q-td
key="OrderNum"
:props="props"
@click="redirectToPage(props.row.Order)"
>
{{ props.row.OrderNum }}
</q-td>
<q-td
key="OrderType"
:props="props"
@click="redirectToPage(props.row.OrderType)"
>
{{ props.row.OrderType }}
</q-td>
<q-td
key="OrderDate"
:props="props"
@click="redirectToPage(props.row.Order)"
>
{{ props.row.OrderDate }}
</q-td>
<q-td
key="OrderBy"
:props="props"
@click="redirectToPage(props.row.Order)"
>
{{ props.row.OrderBy }}
</q-td>
<q-td
key="Signer"
:props="props"
@click="redirectToPage(props.row.Order)"
>
{{ props.row.Signer }}
</q-td>
<q-td
key="OrderStatus"
:props="props"
@click="redirectToPage(props.row.Order)"
>
{{ props.row.OrderStatus }}
</q-td>
<q-td auto-width>
<q-btn
dense
size="12px"
flat
round
color="red"
@click="clickDelete(props.row.id)"
icon="mdi-delete"
>
<q-tooltip>ลบขอม</q-tooltip>
</q-btn>
</q-td>
</q-tr>
</template>
<template v-slot:pagination="scope">
<q-pagination
v-model="pagination.page"
active-color="primary"
color="dark"
:max="scope.pagesNumber"
:max-pages="5"
size="sm"
boundary-links
direction-links
></q-pagination>
</template>
</q-table>
</div>
</div>
</q-card>
</div>
</template>
<script setup lang="ts">
import { onMounted, reactive, ref, useAttrs, computed } from "vue";
import type { QTableProps } from "quasar";
import type { FormOrderPlacementMainData } from "@/modules/05_placement/interface/request/Main";
import type { DataOption } from "@/modules/05_placement/interface/index/Main";
import { useCounterMixin } from "@/stores/mixin";
import { useOrderPlacementDataStore } from "@/modules/05_placement/store";
import router from "@/router";
import { useQuasar } from "quasar";
const $q = useQuasar(); // noti quasar
const DataStore = useOrderPlacementDataStore();
const pagination = ref({
sortBy: "desc",
descending: false,
page: 1,
rowsPerPage: 10,
});
const mixin = useCounterMixin();
const { dateText } = mixin;
// . .
const textDate = (value: Date) => {
return dateText(value);
};
const visibleColumns = ref<string[]>([
"Order",
"OrderType",
"OrderNum",
"OrderDate",
"OrderBy",
"Signer",
"OrderStatus",
]); //
//
const columns = ref<QTableProps["columns"]>([
{
name: "Order",
align: "left",
label: "คำสั่ง",
sortable: true,
field: "Order",
headerStyle: "font-size: 14px",
style: "font-size: 14px",
sort: (a: string, b: string) =>
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
},
{
name: "OrderNum",
align: "left",
label: "เลขที่คำสั่ง",
sortable: true,
field: "OrderNum",
headerStyle: "font-size: 14px",
style: "font-size: 14px",
},
{
name: "OrderType",
align: "left",
label: "ประเภท",
sortable: false,
field: "OrderType",
headerStyle: "font-size: 14px",
style: "font-size: 14px",
sort: (a: string, b: string) =>
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
},
{
name: "OrderDate",
align: "left",
label: "สั่ง ณ วันที่/วันที่คำสั่งมีผล",
sortable: true,
field: "OrderDate",
headerStyle: "font-size: 14px",
style: "font-size: 14px",
sort: (a: string, b: string) =>
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
},
{
name: "OrderBy",
align: "left",
label: "คำสั่งโดย",
sortable: true,
field: "OrderBy",
headerStyle: "font-size: 14px",
style: "font-size: 14px",
sort: (a: string, b: string) =>
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
},
{
name: "Signer",
align: "left",
label: "ผู้ลงนาม",
sortable: false,
field: "Signer",
headerStyle: "font-size: 14px",
style: "font-size: 14px",
sort: (a: string, b: string) =>
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
},
{
name: "OrderStatus",
align: "center",
label: "สถานะคำสั่ง",
sortable: false,
field: "OrderStatus",
headerStyle: "font-size: 14px",
style: "font-size: 14px",
sort: (a: string, b: string) =>
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
},
{
name: "fiscalYear",
align: "left",
label: "ปีงบประมาณ",
sortable: true,
field: "fiscalYear",
headerStyle: "font-size: 14px",
style: "font-size: 14px",
},
]);
// ()
const rows = ref<FormOrderPlacementMainData[]>([
{
Order: "คำสั่งแต่งตั้งผู้สอบแข่งขันได้",
OrderNum: "1/2565",
fiscalYear: 2565,
OrderDate: "30 พ.ค. 2565",
OrderBy: "สำนักงาน กทม.",
Signer: "นาม สมคิด ยอดใจ ",
OrderStatus: "จัดทำร่างคำสั่ง",
OrderType: "คำสั่งย้าย",
},
{
Order: "คำสั่งแต่งตั้งผู้สอบแข่งขันได้",
OrderNum: "1/2565",
fiscalYear: 2565,
OrderDate: "30 พ.ค. 2565",
OrderBy: "สำนักงาน กทม.",
Signer: "นาม สมคิด ยอดใจ ",
OrderStatus: "จัดทำร่างคำสั่ง",
OrderType: "คำสั่งบรรจุและแต่งตั้ง",
},
{
Order: "คำสั่งแต่งตั้งผู้สอบแข่งขันได้",
OrderNum: "1/2564",
fiscalYear: 2564,
OrderDate: "30 พ.ค. 2564",
OrderBy: "สำนักงาน กทม.",
Signer: "นาม สมคิด ยอดใจ ",
OrderStatus: "บัญชีแนบท้าย",
OrderType: "คำสั่งบรรจุและแต่งตั้ง",
},
{
Order: "คำสั่งแต่งตั้งผู้สอบแข่งขันได้",
OrderNum: "1/2564",
fiscalYear: 2564,
OrderDate: "30 พ.ค. 2564",
OrderBy: "สำนักงาน กทม.",
Signer: "นาม สมคิด ยอดใจ ",
OrderStatus: "บัญชีแนบท้าย",
OrderType: "คำสั่งย้าย",
},
{
Order: "คำสั่งแต่งตั้งผู้สอบแข่งขันได้",
OrderNum: "1/2564",
fiscalYear: 2564,
OrderDate: "30 พ.ค. 2564",
OrderBy: "สำนักงาน กทม.",
Signer: "นาม สมคิด ยอดใจ ",
OrderStatus: "ส่งสำเนาคำสั่ง",
OrderType: "คำสั่งย้าย",
},
{
Order: "คำสั่งแต่งตั้งผู้สอบแข่งขันได้",
OrderNum: "1/2564",
fiscalYear: 2564,
OrderDate: "30 พ.ค. 2564",
OrderBy: "สำนักงาน กทม.",
Signer: "นาม สมคิด ยอดใจ ",
OrderStatus: "ส่งสำเนาคำสั่ง",
OrderType: "คำสั่งบรรจุและแต่งตั้ง",
},
{
Order: "คำสั่งแต่งตั้งผู้สอบแข่งขันได้",
OrderNum: "1/2566",
fiscalYear: 2566,
OrderDate: "30 พ.ค. 2566",
OrderBy: "สำนักงาน กทม.",
Signer: "นาม สมคิด ยอดใจ ",
OrderStatus: "รอลงนาม",
OrderType: "คำสั่งบรรจุและแต่งตั้ง",
},
{
Order: "คำสั่งแต่งตั้งผู้สอบแข่งขันได้",
OrderNum: "1/2566",
fiscalYear: 2566,
OrderDate: "30 พ.ค. 2566",
OrderBy: "สำนักงาน กทม.",
Signer: "นาม สมคิด ยอดใจ ",
OrderStatus: "ออกคำสั่งแล้ว",
OrderType: "คำสั่งแต่งตั้ง",
},
{
Order: "คำสั่งแต่งตั้งผู้สอบแข่งขันได้",
OrderNum: "1/2565",
fiscalYear: 2565,
OrderDate: "30 พ.ค. 2565",
OrderBy: "สำนักงาน กทม.",
Signer: "นาม สมคิด ยอดใจ ",
OrderStatus: "ออกคำสั่งแล้ว",
OrderType: "คำสั่งบรรจุและแต่งตั้ง",
},
{
Order: "คำสั่งแต่งตั้งผู้สอบแข่งขันได้",
OrderNum: "1/2566",
fiscalYear: 2566,
OrderDate: "30 พ.ค. 2566",
OrderBy: "สำนักงาน กทม.",
Signer: "นาม สมคิด ยอดใจ ",
OrderStatus: "ออกคำสั่งแล้ว",
OrderType: "คำสั่งแต่งตั้ง",
},
{
Order: "คำสั่งแต่งตั้งผู้สอบแข่งขันได้",
OrderNum: "1/2566",
fiscalYear: 2566,
OrderDate: "30 พ.ค. 2566",
OrderBy: "สำนักงาน กทม.",
Signer: "นาม สมคิด ยอดใจ ",
OrderStatus: "ออกคำสั่งแล้ว",
OrderType: "คำสั่งย้าย",
},
{
Order: "คำสั่งแต่งตั้งผู้สอบแข่งขันได้",
OrderNum: "1/2564",
fiscalYear: 2564,
OrderDate: "30 พ.ค. 2564",
OrderBy: "สำนักงาน กทม.",
Signer: "นาม สมคิด ยอดใจ ",
OrderStatus: "ออกคำสั่งแล้ว",
OrderType: "คำสั่งแต่งตั้ง",
},
{
Order: "คำสั่งแต่งตั้งผู้สอบแข่งขันได้",
OrderNum: "1/2566",
fiscalYear: 2566,
OrderDate: "30 พ.ค. 2566",
OrderBy: "สำนักงาน กทม.",
Signer: "นาม สมคิด ยอดใจ ",
OrderStatus: "ออกคำสั่งแล้ว",
OrderType: "คำสั่งแต่งตั้ง",
},
]);
// const OrderStatusOption = [
// "",
// "",
// "",
// "",
// ];
let OriginalData = ref<FormOrderPlacementMainData[]>([]);
let UpdataData = ref<FormOrderPlacementMainData[]>([]);
onMounted(async () => {
await OriginalDataFetch();
fiscalYearFilter();
searchFilterTable();
OrderStatusFilter();
OrderTypeFilter();
});
const OriginalDataFetch = async () => {
// API
// await http
// .get(config.API.// )
// .then((res: any) => {
// })
// .catch((e: any) => {
// messageError($q, e);
// })
// .finally(async () => {
// });
await DataStore.DataMainOrder(rows.value);
OriginalData.value = await DataStore.DataMainOrigOrder;
UpdataData.value = OriginalData.value;
};
//
const redirectToPage = (id?: number) => {
// router.push({ name: "placementDetail" });
router.push(`/placement/order/detail`);
};
const clickDelete = (id: string) => {
$q.dialog({
title: "ยืนยันการลบข้อมูล",
message: "ต้องการลบข้อมูลนี้ใช่หรือไม่?",
cancel: {
flat: true,
color: "negative",
},
persistent: true,
})
.onOk(async () => {
// await deleteData(id);
})
.onCancel(() => {})
.onDismiss(() => {});
};
// const deleteData = async (id: string) => {
// loaderPage(true);
// await http
// .delete(config.API.orderReplace(id))
// .then((res) => {
// success($q, "");
// })
// .catch((e) => {
// messageError($q, e);
// })
// .finally(async () => {
// loaderPage(false);
// await fetchData();
// });
// };
const clickAdd = () => {
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 fiscalyearOP = reactive<DataOption[]>([{ id: 0, name: "ทั้งหมด" }]);
const addedfiscalYearValues: number[] = [];
const fiscalYearFilter = async () => {
// API
// await http
// .get(config.API.// )
// .then((res: any) => {
// DataStore.DataMainYearSet(rows.value);
// fiscalyearOP.value = DataStore.DataMainYearGet;
// })
// .catch((e: any) => {
// messageError($q, e);
// })
// .finally(async () => {
// });
for (let data of OriginalData.value) {
const year = data.fiscalYear;
console.log(year);
if (fiscalyear.value === null || year > fiscalyear.value) {
fiscalyear.value = year;
}
if (!addedfiscalYearValues.includes(year)) {
fiscalyearOP.push({ id: year, name: year.toString() });
addedfiscalYearValues.push(year);
}
}
};
const OrderType = ref<string>("");
const OrderTypeOption = reactive<DataOption[]>([{ id: 0, name: "ทั้งหมด" }]);
const addedOrderTypeValues: string[] = [];
const OrderTypeFilter = async () => {
// API
// await http
// .get(config.API.// )
// .then((res: any) => {
// DataStore.DataMainYearSet(rows.value);
// fiscalyearOP.value = DataStore.DataMainYearGet;
// })
// .catch((e: any) => {
// messageError($q, e);
// })
// .finally(async () => {
// });
for (let data of OriginalData.value) {
const OrderTypeValue = data.OrderType;
console.log(OrderTypeValue);
// if (OrderTypeValue === null || OrderType > OrderTypeValue) {
// OrderTypeValue = OrderType;
// }
if (!addedOrderTypeValues.includes(OrderTypeValue)) {
OrderTypeOption.push({
// id: OrderTypeValue ?? 0,
id: OrderTypeOption.length,
name: OrderTypeValue,
});
addedOrderTypeValues.push(OrderTypeValue);
}
// if (!addedOrderTypeValues.includes(OrderTypeValue)) {
// OrderTypeOption.push({
// id: OrderTypeValue,
// name: OrderTypeValue.toString(),
// });
// addedOrderTypeValues.push(OrderTypeValue);
// }
}
};
const OrderStatus = ref<string>("");
const OrderStatusText = ref<FormOrderPlacementMainData[]>(
DataStore.DataMainOrigOrder
);
const OrderStatusOption = reactive<DataOption[]>([{ id: 1, name: "ทั้งหมด" }]);
const addedOrderStatusValues: string[] = [];
const OrderStatusFilter = async () => {
// API
// await http
// .get(config.API.// )
// .then((res: any) => {
// DataStore.DataMainYearSet(rows.value);
// fiscalyearOP.value = DataStore.DataMainYearGet;
// })
// .catch((e: any) => {
// messageError($q, e);
// })
// .finally(async () => {
// });
for (let data of OriginalData.value) {
const OrderStatusValue = data.OrderStatus;
console.log(OrderStatusValue);
if (
OrderStatusValue === null ||
parseInt(OrderStatusValue) > parseInt(OrderStatusValue)
) {
OrderStatus.value = OrderStatusValue;
}
if (!addedOrderStatusValues.includes(OrderStatusValue)) {
OrderStatusOption.push({
// id: OrderStatusValue,
id: OrderStatusOption.length,
name: OrderStatusValue,
});
addedOrderStatusValues.push(OrderStatusValue);
}
}
};
// API
const searchfiscalyear = () => {
console.log("Input value changed:", fiscalyear.value);
// API
// await http
// .get(config.API.// )
// .then((res: any) => {
// })
// .catch((e: any) => {
// messageError($q, e);
// })
// .finally(async () => {
// });
};
//
const filterKeyword = ref<string>("");
const filterRef = ref<any>(null);
const resetFilter = () => {
filterKeyword.value = "";
filterRef.value.focus();
};
const attrs = ref<any>(useAttrs());
const searchFilterTable = async () => {
// console.log('Input value changed:', examTime.value, examType.value, expiredAccount.value);
await DataStore.DataUpdateOrder(
OrderType.value,
OrderStatus.value,
fiscalyear.value
);
UpdataData.value = DataStore.DataMainUpdateOrder;
};
// UpdataData.value = DataStore.DataMainUpdate;
// console.log("Input value changed:", OrderStatus.value, OrderType.value);
const paging = ref<boolean>(true);
const paginationLabel = (start: string, end: string, total: string) => {
if (paging.value == true) return " " + start + "-" + end + " ใน " + total;
else return start + "-" + end + " ใน " + total;
};
</script>
<style lang="scss" scope>
.filter-card {
background-color: #f1f1f1b0;
}
.toggle-expired-account {
font-size: 12px;
font-weight: 400;
font-size: 15px;
line-height: 150%;
color: #35373c;
}
.icon-color {
color: #4154b3;
}
.custom-header-table {
max-height: 64vh;
.q-table tr:nth-child(odd) td {
background: white;
}
.q-table tr:nth-child(even) td {
background: #f8f8f8;
}
.q-table thead tr {
background: #ecebeb;
}
.q-table thead tr th {
position: sticky;
z-index: 1;
}
/* this will be the loading indicator */
.q-table thead tr:last-child th {
/* height of all previous header rows */
top: 48px;
}
.q-table thead tr:first-child th {
top: 0;
}
}
</style>

View file

@ -58,6 +58,7 @@ const fetchPublishFile = async () => {
// json // json
const treeData = ref<Array<any>>([]); const treeData = ref<Array<any>>([]);
const loadTreeData = async () => { const loadTreeData = async () => {
expanded.value = [];
await http await http
.get(`${config.s3ClusterUrl}${selectedFile.value}`) .get(`${config.s3ClusterUrl}${selectedFile.value}`)
.then((res: any) => { .then((res: any) => {
@ -126,20 +127,20 @@ const myFilterMethod = (node: any, filter: string) => {
// ((node.name && node.name == null) || !node.name) && // ((node.name && node.name == null) || !node.name) &&
(node.name && node.name.indexOf(filt) > -1) || (node.name && node.name.indexOf(filt) > -1) ||
(node.organizationName && node.organizationName.indexOf(filt) > -1) || (node.organizationName && node.organizationName.indexOf(filt) > -1) ||
(node.positionNum && node.positionNum.indexOf(filt) > -1) || (node.positionNum && node.positionNum.indexOf(filt) > -1) ||
(node.positionName && node.positionName.indexOf(filt) > -1) || (node.positionName && node.positionName.indexOf(filt) > -1) ||
(node.governmentCode && (node.governmentCode &&
node.governmentCode.toString().indexOf(filt) > -1) || node.governmentCode.toString().indexOf(filt) > -1) ||
(node.agency && node.agency.indexOf(filt) > -1) || (node.agency && node.agency.indexOf(filt) > -1) ||
(node.government && node.government.indexOf(filt) > -1) || (node.government && node.government.indexOf(filt) > -1) ||
(node.department && node.department.indexOf(filt) > -1) || (node.department && node.department.indexOf(filt) > -1) ||
(node.pile && node.pile.indexOf(filt) > -1) || (node.pile && node.pile.indexOf(filt) > -1) ||
(node.organizationShortName && (node.organizationShortName &&
node.organizationShortName.indexOf(filt) > -1) || node.organizationShortName.indexOf(filt) > -1) ||
(node.positionSideName && node.positionSideName.indexOf(filt) > -1) || (node.positionSideName && node.positionSideName.indexOf(filt) > -1) ||
(node.executivePosition && node.executivePosition.indexOf(filt) > -1) || (node.executivePosition && node.executivePosition.indexOf(filt) > -1) ||
(node.executivePositionSide && (node.executivePositionSide &&
node.executivePositionSide.indexOf(filt) > -1) || node.executivePositionSide.indexOf(filt) > -1) ||
(node.positionLevel && node.positionLevel.indexOf(filt) > -1) (node.positionLevel && node.positionLevel.indexOf(filt) > -1)
); );
}; };
@ -361,8 +362,10 @@ const checkPosition = (val: string) => {
return num; return num;
}; };
const personal = ref<any>(); const personal = ref<any>();
const expanded = ref<string[]>([]);
watch(props, () => { watch(props, () => {
expanded.value = [];
const dataPersonal = props.personal; const dataPersonal = props.personal;
if (dataPersonal) { if (dataPersonal) {
dataPersonal.map((data: any) => { dataPersonal.map((data: any) => {
@ -370,29 +373,39 @@ watch(props, () => {
}); });
console.log("personal", personal.value); console.log("personal", personal.value);
} }
// console.log("draft===>", personal.value.draft); // console.log("draft===>", personal.value.draft);
if (personal.value.draft === true) { if (personal.value && personal.value.draft === false) {
// const findData = dataRespone.value.find(findByPerson); // const findData = dataRespone.value.find(findByPerson);
let findData: any = null; let findData: any = null;
console.log(dataRespone.value);
dataRespone.value.map((x: any) => { dataRespone.value.map((x: any) => {
findData = findByPerson(x); findData = findByPerson(x);
if (findData != null) { if (findData != null) {
console.log("findData===>", findData); console.log("findData===>", findData);
selectedPosition(findData) selectedPosition(findData);
for (let i = 3; i <= findData.keyId.length; i += 2) {
expanded.value.push(findData.keyId.slice(0, i));
}
} }
}) });
// loadTreeData(); // loadTreeData();
// selectedPosition(findData.children.children.children) // selectedPosition(findData.children.children.children)
} }
}); });
function findByPerson(element: any) { function findByPerson(element: any): any {
// console.log("searchTree element===>", element) // console.log("searchTree element===>", element)
if (element.positionNumId && element.positionLineId === personal.value.positionLineId && if (
element.positionNumId &&
element.positionLineId === personal.value.positionLineId &&
element.positionTypeId === personal.value.positionTypeId && element.positionTypeId === personal.value.positionTypeId &&
element.positionNumId === personal.value.posNoId element.positionNumId === personal.value.posNoId &&
(element.positionLevelObj === null ||
element.positionLevelObj[0].Id === personal.value.positionLevelId) &&
(element.positionSideNameObj === null ||
element.positionSideNameObj[0].Id === personal.value.positionPathSideId)
) { ) {
return element; return element;
} else if (element.children) { } else if (element.children) {
@ -408,153 +421,156 @@ function findByPerson(element: any) {
</script> </script>
<template> <template>
<q-dialog v-model="props.modal" persistent> <q-dialog v-model="props.modal" persistent>
<q-card style="width: 900px; max-width: 80vw"> <q-card style="width: 900px; max-width: 80vw">
<q-form ref="myFormPosition"> <q-form ref="myFormPosition">
<DialogHeader title="เลือกหน่วยงานที่รับบรรจุ" :close="closeModal" /> <DialogHeader title="เลือกหน่วยงานที่รับบรรจุ" :close="closeModal" />
<q-separator /> <q-separator />
<q-card-section class="q-pa-sm bg-grey-1"> <q-card-section class="q-pa-sm bg-grey-1">
<div class="row col-12 q-col-gutter-sm"> <div class="row col-12 q-col-gutter-sm">
<div class="col-xs-12 col-sm-7 row"> <div class="col-xs-12 col-sm-7 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 outlined
dense dense
ref="filterRef" ref="filterRef"
v-model="search" v-model="search"
placeholder="ค้นหา" placeholder="ค้นหา"
class="q-mb-sm" 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>
<div class="q-pa-sm q-gutter-sm"> <div class="q-pa-sm q-gutter-sm">
<q-tree <q-tree
no-transition no-transition
dense dense
:nodes="treeData" :nodes="treeData"
node-key="keyId" node-key="keyId"
:filter="search" :filter="search"
:no-results-label="notFound" :no-results-label="notFound"
:no-nodes-label="noData" :no-nodes-label="noData"
:filter-method="myFilterMethod" :filter-method="myFilterMethod"
> v-model:expanded="expanded"
<template v-slot:header-organization="prop"> >
<div class="col"> <template v-slot:header-organization="prop">
<div <div class="col">
class="row items-center q-px-xs q-pt-xs q-gutter-sm" <div
> class="row items-center q-px-xs q-pt-xs q-gutter-sm"
<!--แสดงชอแผนก มพวหนา คลกแลวกาง/ Tree--> >
<div class="text-weight-medium"> <!--แสดงชอแผนก มพวหนา คลกแลวกาง/ Tree-->
{{ prop.node.organizationName }} <div class="text-weight-medium">
</div> {{ prop.node.organizationName }}
</div>
<!--แสดง Total Count PositionNum--> <!--แสดง Total Count PositionNum-->
<!-- <q-badge rounded color="grey-2" text-color="dark" <!-- <q-badge rounded color="grey-2" text-color="dark"
:label="prop.node.totalPositionCount" /> --> :label="prop.node.totalPositionCount" /> -->
<q-badge <q-badge
v-if="prop.node.totalPositionVacant > 0" v-if="prop.node.totalPositionVacant > 0"
rounded rounded
color="red" color="red"
outline outline
:label="prop.node.totalPositionVacant" :label="prop.node.totalPositionVacant"
/> />
<q-space /> <q-space />
</div> </div>
<div class="col items-center q-px-xs q-pt-xs"> <div class="col items-center q-px-xs q-pt-xs">
<div class="text-weight-medium text-grey-7"> <div class="text-weight-medium text-grey-7">
{{ prop.node.governmentCode }} {{ prop.node.governmentCode }}
{{ prop.node.organizationShortName }} {{ prop.node.organizationShortName }}
</div> </div>
</div> </div>
</div> </div>
</template> </template>
<template v-slot:header-person="prop"> <template v-slot:header-person="prop">
<q-item <q-item
clickable clickable
:active="selected == prop.node.keyId" :active="selected == prop.node.keyId"
@click="selectedPosition(prop.node)" @click="selectedPosition(prop.node)"
:disable="prop.node.name != null || :disable="
checkPosition(prop.node.positionNumId) != -1 prop.node.name != null ||
" checkPosition(prop.node.positionNumId) != -1
active-class="my-list-link text-primary text-weight-medium" "
class="row items-center text-dark q-py-xs q-pl-sm rounded-borders my-list" active-class="my-list-link text-primary text-weight-medium"
> class="row items-center text-dark q-py-xs q-pl-sm rounded-borders my-list"
<img >
v-if="prop.node.avatar == '' || <img
prop.node.avatar == v-if="
'https://cdn.quasar.dev/img/boy-avatar.png' 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" "
style=" src="@/assets/avatar_user.jpg"
class="col-xs-1 col-sm-2"
style="
width: 28px; width: 28px;
height: 28px; height: 28px;
border-radius: 50%; border-radius: 50%;
" "
/> />
<img <img
v-else v-else
:src="prop.node.avatar" :src="prop.node.avatar"
class="col-xs-1 col-sm-2" class="col-xs-1 col-sm-2"
style=" style="
width: 28px; width: 28px;
height: 28px; height: 28px;
border-radius: 50%; border-radius: 50%;
" "
/> />
<!--=====ตำแหนงวาง แดง=====--> <!--=====ตำแหนงวาง แดง=====-->
<div <div
v-if="prop.node.name == null" v-if="prop.node.name == null"
class="q-px-sm text-weight-medium text-red" class="q-px-sm text-weight-medium text-red"
> >
าง าง
</div> </div>
<!--=====วหน เขยว=====--> <!--=====วหน เขยว=====-->
<div v-else-if="prop.node.positionLeaderFlag"> <div v-else-if="prop.node.positionLeaderFlag">
<div <div
class="q-px-sm text-weight-medium text-primary" class="q-px-sm text-weight-medium text-primary"
> >
{{ prop.node.name }} {{ prop.node.name }}
</div> </div>
</div> </div>
<!--=====กนอง ปกต=====--> <!--=====กนอง ปกต=====-->
<div v-else> <div v-else>
<div class="q-px-sm text-weight-medium"> <div class="q-px-sm text-weight-medium">
{{ prop.node.name }} {{ prop.node.name }}
</div> </div>
</div> </div>
<!--อทายชอคน แสดงสปกต--> <!--อทายชอคน แสดงสปกต-->
<div class="q-pr-sm"> <div class="q-pr-sm">
{{ prop.node.positionName }} {{ prop.node.positionName }}
</div> </div>
<div class="q-pr-sm"> <div class="q-pr-sm">
{{ prop.node.positionNum }} {{ prop.node.positionNum }}
</div> </div>
<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" v-if="prop.node.positionLeaderFlag"
class="q-mr-sm" class="q-mr-sm"
size="15px" size="15px"
color="primary" color="primary"
name="mdi-bookmark" name="mdi-bookmark"
></q-icon> ></q-icon>
<q-space /> <q-space />
</q-item> </q-item>
</template> </template>
</q-tree> </q-tree>
</div> </div>
</q-scroll-area> </q-scroll-area>
</q-card> </q-card>
</div> </div>
<div class="col-xs-12 col-sm-5"> <div class="col-xs-12 col-sm-5">
<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">
<div class="row col-12 q-col-gutter-xs"> <div class="row col-12 q-col-gutter-xs">

View file

@ -195,9 +195,9 @@ const convertContainStatus = (val: string) => {
}; };
const convertDraft = (val: boolean) => { const convertDraft = (val: boolean) => {
switch (val) { switch (val) {
case true:
return "รอส่งตัว";
case false: case false:
return "รอส่งตัว";
case true:
return "ส่งตัวแล้ว"; return "ส่งตัวแล้ว";
default: default:
return "-"; return "-";
@ -297,8 +297,8 @@ const saveDeferment = async () => {
hideLoader(); hideLoader();
}); });
}) })
.onCancel(() => {}) .onCancel(() => { })
.onDismiss(() => {}); .onDismiss(() => { });
} }
}); });
}; };
@ -338,8 +338,8 @@ const saveDisclaim = async () => {
hideLoader(); hideLoader();
}); });
}) })
.onCancel(() => {}) .onCancel(() => { })
.onDismiss(() => {}); .onDismiss(() => { });
} }
}); });
}; };
@ -441,6 +441,10 @@ const validateData = async () => {
}); });
}; };
const clickCloseSendModal = () => {
modaladdlist.value = false
}
const clickClose = async () => { const clickClose = async () => {
userNote.value = ""; userNote.value = "";
if (editRow.value == true) { if (editRow.value == true) {
@ -537,436 +541,235 @@ const paginationLabel = (start: number, end: number, total: number) => {
</script> </script>
<template> <template>
<q-form ref="myForm"> <q-form ref="myForm">
<Table <Table :contain-status="containStatus" :rows="rows" :columns="columns" :filter="filter"
:contain-status="containStatus" :visible-columns="visibleColumns" v-model:inputfilter="filter" v-model:inputvisible="visibleColumns"
:rows="rows" v-model:editvisible="editvisible" v-model:containfilter="containStatus"
:columns="columns" @update-modaladdlist="handleModalAddListUpdate" :history="true" :boss="true" :saveNoDraft="true"
:filter="filter" :role-admin="roleAdmin">
:visible-columns="visibleColumns" <template #columns="props">
v-model:inputfilter="filter" <q-tr :props="props">
v-model:inputvisible="visibleColumns" <q-td v-for="col in props.cols" :key="col.name" :props="props" @click="selectData(props.row.personalId)"
v-model:editvisible="editvisible" class="cursor-pointer">
v-model:containfilter="containStatus" <template v-if="col.name === 'position'">
@update-modaladdlist="handleModalAddListUpdate" {{ props.rowIndex + 1 }}
:history="true" </template>
:boss="true" <template v-else-if="col.name === 'fullName'" class="table_ellipsis">
:saveNoDraft="true" <div class="row col-12 text-no-wrap items-center">
:role-admin="roleAdmin" <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" />
<template #columns="props"> <div class="col-4">
<q-tr :props="props"> <div class="text-weight-medium">{{ props.row.name }}</div>
<q-td <div class="text-weight-light">{{ props.row.idCard }}</div>
v-for="col in props.cols" </div>
:key="col.name"
:props="props"
@click="selectData(props.row.personalId)"
class="cursor-pointer"
>
<template v-if="col.name === 'position'">
{{ props.rowIndex + 1 }}
</template>
<template
v-else-if="col.name === 'fullName'"
class="table_ellipsis"
>
<div class="row col-12 text-no-wrap items-center">
<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 class="col-4">
<div class="text-weight-medium">{{ props.row.name }}</div>
<div class="text-weight-light">{{ props.row.idCard }}</div>
</div> </div>
</div> </template>
</template> <template v-else-if="col.name === 'examNumber'">
<template v-else-if="col.name === 'examNumber'"> <div class="text-weight-medium">
<div class="text-weight-medium"> {{ props.row.examNumber !== null ? props.row.examNumber : "-" }}
{{ props.row.examNumber !== null ? props.row.examNumber : "-" }} </div>
</div> </template>
</template>
<template v-else-if="col.name === 'organizationName'"> <template v-else-if="col.name === 'organizationName'">
<div <div v-if="props.row.orgName !== null || props.row.positionPath !== null
v-if=" ">
props.row.orgName !== null || props.row.positionPath !== null <div class="col-4">
" <div class="text-weight-medium">
> {{ props.row.orgName !== null ? props.row.orgName : "-" }}
<div class="col-4"> {{
<div class="text-weight-medium"> props.row.organizationShortName !== null
{{ props.row.orgName !== null ? props.row.orgName : "-" }}
{{
props.row.organizationShortName !== null
? `(${props.row.organizationShortName})` ? `(${props.row.organizationShortName})`
: "" : ""
}} }}
</div> </div>
<div class="text-weight-light"> <div class="text-weight-light">
{{ {{
props.row.positionPath !== null props.row.positionPath !== null
? props.row.positionPath ? props.row.positionPath
: "-" : "-"
}} }}
{{ {{
props.row.positionNumber !== null props.row.positionNumber !== null
? `(${props.row.positionNumber})` ? `(${props.row.positionNumber})`
: "" : ""
}} }}
</div>
</div> </div>
</div> </div>
</div> <div v-else>
<div v-else> <div class="col-4">
<div class="col-4"> <div class="text-weight-medium">-</div>
<div class="text-weight-medium">-</div> </div>
</div> </div>
</div>
</template>
<template v-else-if="col.name === 'positionCandidate'">
<div
class="text-weight-medium"
v-if="props.row.positionCandidate == null"
>
-
</div>
<div class="text-weight-medium" v-else>
{{ props.row.positionCandidate }}
</div>
</template>
<template
v-else-if="col.name === 'reportingDate' && col.value !== '-'"
>
<div class="text-weight-medium">
{{ props.row.reportingDate }}
</div>
</template>
<template v-else-if="col.name === 'bmaOfficer'">
<div class="text-weight-medium">
{{ props.row.bmaOfficer !== null ? props.row.bmaOfficer : "-" }}
</div>
</template>
<template v-else-if="col.name === 'draft'">
<div class="text-weight-medium">
{{ props.row.draft }}
</div>
</template>
<template v-else-if="col.name === 'statusName'">
<div class="text-weight-medium">
{{ props.row.statusName }}
</div>
</template>
</q-td>
<q-td auto-width>
<q-btn
icon="mdi-dots-vertical"
size="12px"
color="grey-7"
flat
round
dense
>
<q-menu transition-show="jump-down" transition-hide="jump-up">
<q-list dense style="min-width: 100px">
<q-item
v-if="
(roleAdmin && props.row.statusId === 'UN-CONTAIN') ||
props.row.draft === 'รอส่งตัว'
"
clickable
v-close-popup
@click="openAppointModal(props.row.personalId)"
>
<q-item-section
style="min-width: 0px"
avatar
class="q-py-sm"
>
<q-icon
color="primary"
size="xs"
name="mdi-bookmark-outline"
/>
</q-item-section>
<q-item-section>เลอกหนวยงานทบบรรจ</q-item-section>
</q-item>
<q-separator />
<q-item
v-if="roleAdmin && props.row.statusId === 'UN-CONTAIN'"
clickable
v-close-popup
@click="editDetail(props.row, 'deferment')"
>
<q-item-section
style="min-width: 0px"
avatar
class="q-py-sm"
>
<q-icon
color="blue"
size="xs"
name="mdi-account-alert-outline"
/>
</q-item-section>
<q-item-section>ขอผอนผ</q-item-section>
</q-item>
<q-item
v-else-if="
props.row.deferment === true &&
props.row.statusId != 'DISCLAIM'
"
clickable
v-close-popup
@click="editDetail(props.row, 'defermentInfo')"
>
<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.statusId === 'UN-CONTAIN' ||
props.row.statusId === 'PREPARE-CONTAIN'
"
clickable
v-close-popup
@click="editDetail(props.row, 'disclaim')"
>
<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-item
v-else-if="props.row.statusId === 'DISCLAIM'"
clickable
v-close-popup
@click="editDetail(props.row, 'disclaimInfo')"
>
<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>
<!-- เลอกหนวยงานทบรรจ -->
<DialogOrgTree
v-model:modal="appointModal"
:personalId="personalId"
:close="clickCloseModalTree"
:personal="personal"
/>
<!-- popup ขอผอนผ / สละสทธ -->
<q-form ref="myForm">
<DialogCard
v-model:Modal="modal"
:personal-id="personalId"
:close="clickClose"
:validate="validateData"
/>
</q-form>
<q-dialog v-model="modalDefermentDisclaim" persistent>
<q-card style="width: 800px">
<q-form ref="myForm">
<DialogHeader
:title="`${modalDisclaim ? 'สละสิทธิ์' : 'ขอผ่อนผัน'} ชื่อ${Name}`"
:close="clickClose"
/>
<q-separator />
<q-card-section class="q-p-sm">
<div class="col-xs-12 col-sm-12 col-md-12">
<q-input
:class="getClass(edit)"
hide-bottom-space
:outlined="edit"
dense
lazy-rules
:rules="[(val) => !!val || 'กรุณากรอกเหตุผล']"
:readonly="!edit"
:borderless="!edit"
v-model="userNote"
:label="`${'กรอกเหตุผล'}`"
@update:model-value="clickEditRow"
type="textarea"
/>
<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> </template>
</q-file> <template v-else-if="col.name === 'positionCandidate'">
</div> <div class="text-weight-medium" v-if="props.row.positionCandidate == null">
</q-card-section> -
<q-separator /> </div>
<DialogFooter <div class="text-weight-medium" v-else>
:editvisible="true" {{ props.row.positionCandidate }}
:validate="validateData" </div>
:save="modalDisclaim ? saveDisclaim : saveDeferment" </template>
/> <template v-else-if="col.name === 'reportingDate' && col.value !== '-'">
</q-form> <div class="text-weight-medium">
</q-card> {{ props.row.reportingDate }}
</q-dialog> </div>
</template>
<template v-else-if="col.name === 'bmaOfficer'">
<div class="text-weight-medium">
{{ props.row.bmaOfficer !== null ? props.row.bmaOfficer : "-" }}
</div>
</template>
<template v-else-if="col.name === 'draft'">
<div class="text-weight-medium">
{{ props.row.draft }}
</div>
</template>
<template v-else-if="col.name === 'statusName'">
<div class="text-weight-medium">
{{ props.row.statusName }}
</div>
</template>
</q-td>
<q-td auto-width>
<q-btn icon="mdi-dots-vertical" size="12px" color="grey-7" flat round dense>
<q-menu transition-show="jump-down" transition-hide="jump-up">
<q-list dense style="min-width: 100px">
<q-item v-if="(roleAdmin && props.row.statusId === 'UN-CONTAIN') ||
props.row.draft === 'รอส่งตัว'
" clickable v-close-popup @click="openAppointModal(props.row.personalId)">
<q-item-section style="min-width: 0px" avatar class="q-py-sm">
<q-icon color="primary" size="xs" name="mdi-bookmark-outline" />
</q-item-section>
<q-item-section>เลอกหนวยงานทบบรรจ</q-item-section>
</q-item>
<!-- dialog อมลขอผอนผ / สละสทธ --> <q-separator />
<q-dialog v-model="modalwaitInfo" persistent> <q-item v-if="roleAdmin && props.row.statusId === 'UN-CONTAIN'" clickable v-close-popup
<q-card style="width: 500px; max-width: 500px"> @click="editDetail(props.row, 'deferment')">
<q-form ref="myForm"> <q-item-section style="min-width: 0px" avatar class="q-py-sm">
<DialogHeader <q-icon color="blue" size="xs" name="mdi-account-alert-outline" />
:title="`${modalDisclaim ? 'สละสิทธิ์' : 'ขอผ่อนผัน'} ชื่อ${Name}`" </q-item-section>
:close="clickClose" <q-item-section>ขอผอนผ</q-item-section>
/> </q-item>
<q-item v-else-if="props.row.deferment === true &&
props.row.statusId != 'DISCLAIM'
" clickable v-close-popup @click="editDetail(props.row, 'defermentInfo')">
<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.statusId === 'UN-CONTAIN' ||
props.row.statusId === 'PREPARE-CONTAIN'
" clickable v-close-popup @click="editDetail(props.row, 'disclaim')">
<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-item v-else-if="props.row.statusId === 'DISCLAIM'" clickable v-close-popup
@click="editDetail(props.row, 'disclaimInfo')">
<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>
<!-- เลอกหนวยงานทบรรจ -->
<DialogOrgTree v-model:modal="appointModal" :personalId="personalId" :close="clickCloseModalTree"
:personal="personal" />
<!-- popup ขอผอนผ / สละสทธ -->
<q-form ref="myForm">
<DialogCard v-model:Modal="modal" :personal-id="personalId" :close="clickClose" :validate="validateData" />
</q-form>
<q-dialog v-model="modalDefermentDisclaim" persistent>
<q-card style="width: 800px">
<q-form ref="myForm">
<DialogHeader :title="`${modalDisclaim ? 'สละสิทธิ์' : 'ขอผ่อนผัน'} ชื่อ${Name}`" :close="clickClose" />
<q-separator />
<q-card-section class="q-p-sm">
<div class="col-xs-12 col-sm-12 col-md-12">
<q-input :class="getClass(edit)" hide-bottom-space :outlined="edit" dense lazy-rules
:rules="[(val) => !!val || 'กรุณากรอกเหตุผล']" :readonly="!edit" :borderless="!edit" v-model="userNote"
:label="`${'กรอกเหตุผล'}`" @update:model-value="clickEditRow" type="textarea" />
<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 :editvisible="true" :validate="validateData" :save="modalDisclaim ? saveDisclaim : saveDeferment" />
</q-form>
</q-card>
</q-dialog>
<!-- dialog อมลขอผอนผ / สละสทธ -->
<q-dialog v-model="modalwaitInfo" persistent>
<q-card style="width: 500px; max-width: 500px">
<q-form ref="myForm">
<DialogHeader :title="`${modalDisclaim ? 'สละสิทธิ์' : 'ขอผ่อนผัน'} ชื่อ${Name}`" :close="clickClose" />
<q-separator />
<q-card-section class="q-p-sm">
<div class="row">
<div class="col-3 text-grey-7">เหตผล</div>
<div class="col-4">{{ dataInfo.reason }}</div>
</div>
<div v-if="!modalDisclaim" class="row q-pt-md">
<div class="col-3 text-grey-7 q-mt-sm">เอกสารหลกฐาน</div>
<div class="col-2 q-mt-sm">
<q-btn type="a" :href="dataInfo.reliefDoc" color="primary" flat dense round size="14px" icon="mdi-download"
target="_blank" />
</div>
</div>
</q-card-section>
<q-separator />
</q-form>
</q-card>
</q-dialog>
<!-- dialog เพมรายช -->
<q-dialog v-model="modaladdlist">
<q-card style="width: 900px; max-width: 80vw">
<DialogHeader title="ส่งรายชื่อไปยังหน่วยงาน" :close="clickCloseSendModal" />
<q-separator /> <q-separator />
<q-card-section class="q-p-sm"> <q-card-section class="q-pt-none">
<div class="row"> <div class="row justify-end">
<div class="col-3 text-grey-7">เหตผล</div> <div class="col-5">
<div class="col-4">{{ dataInfo.reason }}</div> <q-toolbar style="padding: 0">
</div> <q-input borderless outlined dense debounce="300" v-model="filterlistAdd" placeholder="ค้นหา"
<div v-if="!modalDisclaim" class="row q-pt-md"> style="width: 850px; max-width: auto">
<div class="col-3 text-grey-7 q-mt-sm">เอกสารหลกฐาน</div> <template v-slot:append>
<div class="col-2 q-mt-sm"> <q-icon name="search" />
<q-btn </template>
type="a" </q-input>
:href="dataInfo.reliefDoc" <q-select v-model="visibleColumnslist" multiple outlined dense options-dense
color="primary" :display-value="$q.lang.table.columns" emit-value map-options :options="columns" option-value="name"
flat options-cover style="min-width: 150px" class="gt-xs q-ml-sm" />
dense </q-toolbar>
round
size="14px"
icon="mdi-download"
target="_blank"
/>
</div> </div>
</div> </div>
</q-card-section>
<q-separator />
</q-form>
</q-card>
</q-dialog>
<!-- dialog เพมรายช --> <q-table flat bordered dense :rows="rowsFilter" :columns="columns" :filter="filterlistAdd" row-key="name"
<q-dialog v-model="modaladdlist"> class="custom-header-table" selection="multiple" v-model:selected="selected" :pagination-label="paginationLabel"
<q-card style="width: 900px; max-width: 80vw"> :visible-columns="visibleColumnslist">
<q-card-section> <template v-slot:header-selection="scope">
<q-checkbox keep-color color="primary" dense v-model="scope.selected" />
<q-toolbar class="q-py-md"> </template>
<q-toolbar-title class="header-text text-weight-bolder" <!-- <template v-slot:body-selection="scope">
>งรายชอไปยงหนวยงาน
</q-toolbar-title>
<q-btn
icon="close"
unelevated
round
dense
@click="modaladdlist = false"
style="color: #ff8080; background-color: #ffdede"
/>
</q-toolbar>
</q-card-section>
<q-card-section class="q-pt-none">
<div class="row justify-end">
<div class="col-5">
<q-toolbar style="padding: 0">
<q-input
borderless
outlined
dense
debounce="300"
v-model="filterlistAdd"
placeholder="ค้นหา"
style="width: 850px; max-width: auto"
>
<template v-slot:append>
<q-icon name="search" />
</template>
</q-input>
<q-select
v-model="visibleColumnslist"
multiple
outlined
dense
options-dense
:display-value="$q.lang.table.columns"
emit-value
map-options
:options="columns"
option-value="name"
options-cover
style="min-width: 150px"
class="gt-xs q-ml-sm"
/>
</q-toolbar>
</div>
</div>
<q-table
flat
bordered
dense
:rows="rowsFilter"
:columns="columns"
:filter="filterlistAdd"
row-key="name"
class="custom-header-table"
selection="multiple"
v-model:selected="selected"
:pagination-label="paginationLabel"
:visible-columns="visibleColumnslist"
>
<template v-slot:header-selection="scope">
<q-checkbox
keep-color
color="primary"
dense
v-model="scope.selected"
/>
</template>
<!-- <template v-slot:body-selection="scope">
<q-checkbox <q-checkbox
keep-color keep-color
color="primary" color="primary"
@ -974,153 +777,112 @@ const paginationLabel = (start: number, end: number, total: number) => {
v-model="scope.selected" v-model="scope.selected"
/> />
</template> --> </template> -->
<template v-slot:body="props"> <template v-slot:body="props">
<q-tr :props="props"> <q-tr :props="props">
<q-td> <q-td>
<q-checkbox <q-checkbox keep-color color="primary" dense v-model="props.selected" />
keep-color </q-td>
color="primary" <q-td v-for="col in props.cols" :key="col.name" :props="props" class="cursor-pointer">
dense <template v-if="col.name === 'position'">
v-model="props.selected" {{ props.rowIndex + 1 }}
/> </template>
</q-td> <template v-else-if="col.name === 'fullName'" class="table_ellipsis">
<q-td <div class="row col-12 text-no-wrap items-center">
v-for="col in props.cols" <img v-if="props.row.avatar == null" src="@/assets/avatar_user.jpg" class="col-4 img-info" />
:key="col.name" <img v-else :src="props.row.avatar" class="col-4 img-info" />
:props="props" <div class="col-4">
class="cursor-pointer" <div class="text-weight-medium">{{ props.row.name }}</div>
> <div class="text-weight-light">
<template v-if="col.name === 'position'"> {{ props.row.idCard }}
{{ props.rowIndex + 1 }} </div>
</template>
<template
v-else-if="col.name === 'fullName'"
class="table_ellipsis"
>
<div class="row col-12 text-no-wrap items-center">
<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 class="col-4">
<div class="text-weight-medium">{{ props.row.name }}</div>
<div class="text-weight-light">
{{ props.row.idCard }}
</div> </div>
</div> </div>
</div> </template>
</template> <template v-else-if="col.name === 'examNumber'">
<template v-else-if="col.name === 'examNumber'"> <div class="text-weight-medium">
<div class="text-weight-medium"> {{
{{ props.row.examNumber !== null ? props.row.examNumber : "-"
props.row.examNumber !== null ? props.row.examNumber : "-" }}
}} </div>
</div> </template>
</template>
<template v-else-if="col.name === 'organizationName'"> <template v-else-if="col.name === 'organizationName'">
<div <div v-if="props.row.orgName !== null ||
v-if="
props.row.orgName !== null ||
props.row.positionPath !== null props.row.positionPath !== null
" ">
> <div class="col-4">
<div class="col-4"> <div class="text-weight-medium">
<div class="text-weight-medium"> {{
{{ props.row.orgName !== null ? props.row.orgName : "-"
props.row.orgName !== null ? props.row.orgName : "-" }}
}} {{
{{ props.row.organizationShortName !== null
props.row.organizationShortName !== null
? `(${props.row.organizationShortName})` ? `(${props.row.organizationShortName})`
: "" : ""
}} }}
</div> </div>
<div class="text-weight-light"> <div class="text-weight-light">
{{ {{
props.row.positionPath !== null props.row.positionPath !== null
? props.row.positionPath ? props.row.positionPath
: "-" : "-"
}} }}
{{ {{
props.row.positionNumber !== null props.row.positionNumber !== null
? `(${props.row.positionNumber})` ? `(${props.row.positionNumber})`
: "" : ""
}} }}
</div>
</div> </div>
</div> </div>
</div> <div v-else>
<div v-else> <div class="col-4">
<div class="col-4"> <div class="text-weight-medium">-</div>
<div class="text-weight-medium">-</div> </div>
</div> </div>
</div> </template>
</template> <template v-else-if="col.name === 'positionCandidate'">
<template v-else-if="col.name === 'positionCandidate'"> <div class="text-weight-medium" v-if="props.row.positionCandidate == null">
<div -
class="text-weight-medium" </div>
v-if="props.row.positionCandidate == null" <div class="text-weight-medium" v-else>
> {{ props.row.positionCandidate }}
- </div>
</div> </template>
<div class="text-weight-medium" v-else> <template v-else-if="col.name === 'reportingDate' && col.value !== '-'">
{{ props.row.positionCandidate }} <div class="text-weight-medium">
</div> {{ props.row.reportingDate }}
</template> </div>
<template </template>
v-else-if="col.name === 'reportingDate' && col.value !== '-'" <template v-else-if="col.name === 'bmaOfficer'">
> <div class="text-weight-medium">
<div class="text-weight-medium"> {{
{{ props.row.reportingDate }} props.row.bmaOfficer !== null ? props.row.bmaOfficer : "-"
</div> }}
</template> </div>
<template v-else-if="col.name === 'bmaOfficer'"> </template>
<div class="text-weight-medium"> <template v-else-if="col.name === 'draft'">
{{ <div class="text-weight-medium">
props.row.bmaOfficer !== null ? props.row.bmaOfficer : "-" {{ props.row.draft }}
}} </div>
</div> </template>
</template> <template v-else-if="col.name === 'statusName'">
<template v-else-if="col.name === 'draft'"> <div class="text-weight-medium">
<div class="text-weight-medium"> {{ props.row.statusName }}
{{ props.row.draft }} </div>
</div> </template>
</template> </q-td>
<template v-else-if="col.name === 'statusName'"> </q-tr>
<div class="text-weight-medium"> </template>
{{ props.row.statusName }} <template v-slot:pagination="scope">
</div> <q-pagination v-model="pagination.page" color="primary" :max="scope.pagesNumber" :max-pages="5" size="sm"
</template> boundary-links direction-links></q-pagination>
</q-td> </template>
</q-tr> </q-table>
</template> </q-card-section>
<template v-slot:pagination="scope">
<q-pagination
v-model="pagination.page"
color="primary"
:max="scope.pagesNumber"
:max-pages="5"
size="sm"
boundary-links
direction-links
></q-pagination>
</template>
</q-table>
</q-card-section>
<q-card-actions align="right" class="bg-white text-teal"> <q-card-actions align="right" class="bg-white text-teal">
<q-btn <q-btn label="บันทึก" @click="savelist" :disable="checkSelected" color="public" />
flat
label="ยืนยันการส่งตัว"
@click="savelist"
:disable="checkSelected"
/>
</q-card-actions> </q-card-actions>
</q-card> </q-card>
</q-dialog> </q-dialog>

File diff suppressed because it is too large Load diff

View file

@ -30,7 +30,11 @@ const probationForm = () =>
import("@/modules/05_placement/components/probation/MainDetail.vue"); import("@/modules/05_placement/components/probation/MainDetail.vue");
const probationWorkAdd = () => const probationWorkAdd = () =>
import("@/modules/05_placement/components/probation/MainDetail.vue");
const probationWorkAdd2 = () =>
import("@/modules/05_placement/components/probation/AddWork.vue"); import("@/modules/05_placement/components/probation/AddWork.vue");
const resignOrder = () =>
import("@/modules/05_placement/components/OrderPlacement/ResignOrder.vue");
export default [ export default [
{ {
path: "/placement", path: "/placement",
@ -142,4 +146,24 @@ export default [
Role: "placement", Role: "placement",
}, },
}, },
{
path: "/probation/add",
name: "probationWorkAdd",
component: probationWorkAdd2,
meta: {
Auth: true,
Key: [6.3],
Role: "placement",
},
},
{
path: "/placement/resign-order",
name: "ResignOrderplacement",
component: resignOrder,
meta: {
Auth: true,
Key: [6.2],
Role: "placement",
},
},
]; ];

View file

@ -719,6 +719,7 @@ if (keycloak.tokenParsed != null) {
menuItem.key == 3 || menuItem.key == 3 ||
menuItem.key == 5 || menuItem.key == 5 ||
menuItem.key == 6 || menuItem.key == 6 ||
menuItem.key == 7 ||
menuItem.key == 8 menuItem.key == 8
" "
> >
@ -942,11 +943,11 @@ if (keycloak.tokenParsed != null) {
.expan2 .q-item { .expan2 .q-item {
padding-left: 10%; padding-left: 10%;
} }
.subLabel{ .subLabel {
white-space: nowrap; white-space: nowrap;
width: 160px; width: 160px;
overflow: hidden; overflow: hidden;
text-overflow: ellipsis; text-overflow: ellipsis;
} }
.font-400 { .font-400 {
font-weight: 400; font-weight: 400;