From 92d2354cc7a7efa7e64314e904a5f76eb2bc1011 Mon Sep 17 00:00:00 2001 From: "DESKTOP-1R2VSQH\\Lenovo ThinkPad E490" Date: Mon, 14 Jul 2025 17:08:39 +0700 Subject: [PATCH 1/6] fix load --- .../components/05_Leave/Dialog/DialogAddCommander.vue | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/modules/09_leave/components/05_Leave/Dialog/DialogAddCommander.vue b/src/modules/09_leave/components/05_Leave/Dialog/DialogAddCommander.vue index 39db33568..ec7d1a437 100644 --- a/src/modules/09_leave/components/05_Leave/Dialog/DialogAddCommander.vue +++ b/src/modules/09_leave/components/05_Leave/Dialog/DialogAddCommander.vue @@ -159,14 +159,16 @@ function onSubmit() { ), body ) - .then((res) => { + .then(async () => { + await props.fetchDetailLeave?.(pageId.value); closeDialog(); success($q, "บันทึกสำเร็จ"); - props.fetchDetailLeave?.(pageId.value); }) .catch((e) => { - hideLoader(); messageError($q, e); + }) + .finally(() => { + hideLoader(); }); }); } else { From a3a318ba2d12f94ea5b3a710e9cd810f6c1fbc8c Mon Sep 17 00:00:00 2001 From: "DESKTOP-1R2VSQH\\Lenovo ThinkPad E490" Date: Mon, 14 Jul 2025 18:01:36 +0700 Subject: [PATCH 2/6] =?UTF-8?q?=E0=B8=9B=E0=B8=A3=E0=B8=B1=E0=B8=9A?= =?UTF-8?q?=E0=B8=81=E0=B8=B2=E0=B8=A3=E0=B9=81=E0=B8=AA=E0=B8=94=E0=B8=87?= =?UTF-8?q?=E0=B9=80=E0=B8=87=E0=B8=B7=E0=B9=88=E0=B8=AD=E0=B8=99=E0=B9=84?= =?UTF-8?q?=E0=B8=82=E0=B8=82=E0=B8=AD=E0=B8=87=E0=B8=81=E0=B8=B2=E0=B8=A3?= =?UTF-8?q?=E0=B8=9B=E0=B8=A3=E0=B8=B0=E0=B9=80=E0=B8=A1=E0=B8=B4=E0=B8=99?= =?UTF-8?q?=E0=B8=9E=E0=B8=A4=E0=B8=95=E0=B8=B4=E0=B8=81=E0=B8=A3=E0=B8=A3?= =?UTF-8?q?=E0=B8=A1=E0=B8=81=E0=B8=B2=E0=B8=A3=E0=B8=9B=E0=B8=8F=E0=B8=B4?= =?UTF-8?q?=E0=B8=9A=E0=B8=B1=E0=B8=95=E0=B8=B4=E0=B8=A3=E0=B8=B2=E0=B8=8A?= =?UTF-8?q?=E0=B8=81=E0=B8=B2=E0=B8=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../components/competency/05ListDetail.vue | 345 +++++++++++++++--- 1 file changed, 293 insertions(+), 52 deletions(-) diff --git a/src/modules/01_masterdata/components/competency/05ListDetail.vue b/src/modules/01_masterdata/components/competency/05ListDetail.vue index 5252f11aa..a57a23626 100644 --- a/src/modules/01_masterdata/components/competency/05ListDetail.vue +++ b/src/modules/01_masterdata/components/competency/05ListDetail.vue @@ -18,36 +18,55 @@
ประเภทสมรรถนะ
-
+
ประเภทและระดับตำแหน่ง
-
-
ทั่วไป
-
ปฏิบัติงาน
-
ชำนาญงาน
-
อาวุโส
+
+
ทั่วไป
+
+
+
ปฏิบัติงาน
+
ชำนาญงาน
+
อาวุโส
+
+
+
อาวุโส
+
(ที่ดำรงตำแหน่งทางการบริหาร)
+
+
-
-
วิชาการ
-
ปฏิบัติการ
-
ชำนาญการ
-
ชำนาญการพิเศษ
-
เชี่ยวชาญ
-
ทรงคุณวุฒิ
+ +
+
วิชาการ
+
+
+
ปฏิบัติงาน
+
ชำนาญงาน
+
ชำนาญการพิเศษ
+
เชี่ยวชาญ
+
ทรงคุณวุฒิ
+
+
+
ปฏิบัติการทรงคุณวุฒิ
+
(ที่ดำรงตำแหน่งทางการบริหาร)
+
+
-
+ +
อำนวยการ
ต้น สูง
-
+
บริหาร
ต้น สูง
-
+ +
ผู้ดำรงตำแหน่ง
@@ -62,23 +81,29 @@
สมรรถนะหลัก
(5 สมรรถนะ)
-
+
-
+
-
+
-
+
-
+
+ +
+
+ +
+
-
+
@@ -94,19 +119,22 @@
สมรรถนะประจำกลุ่มงาน
(3 สมรรถนะ ตามกลุ่มงาน)
-
+
-
+
-
+
+
-
-
+
+
+ +
-
+
@@ -118,19 +146,25 @@
สมรรถนะประจำผู้บริหารกรุงเทพมหานคร
(7 สมรรถนะ)
-
+
-
-
-
+
+
-
+
+
+ +
+
+ +
+
-
+
@@ -142,15 +176,17 @@
สมรรถนะเฉพาะสำหรับตำแหน่งผู้อำนวยการเขต
(4 สมรรถนะ)
-
+
-
-
-
-
+
+
+
+
+
+
-
+
@@ -166,15 +202,17 @@
(2 สมรรถนะ)
-
+
-
-
-
-
+
+
+
+
+
+
-
+
@@ -187,15 +225,17 @@
รวมสมรรถนะ
-
+
-
8
-
8
-
12
-
12
+
8
+
12
+
8
+
12
+
12
+
12
-
+
7
9
@@ -312,6 +352,203 @@
+ + + +
+ องค์ประกอบการประเมิน และแนวทางการประเมินของผู้รับการประเมินแต่ละกลุ่ม +
+
+ + + +
+
+
+ ผู้ประเมิน +
+ +
+
+ องค์ประกอบการประเมิน +
+
+
ผลสัมฤทธิ์ของงาน
+ +
+
+ พฤติกรรมการปฏิบัติราชการ +
+
+
สมรรถนะ
+
การพัฒนา
+
+
+
+
+
+
+
+
กลุ่มที่ 1
+
+ ผู้ดำรงตำแหน่ง ดังนี้
+ - ปลัดกรุงเทพมหานคร
+ - รองปลัดกรุงเทพมหานคร
+ - ผู้อำนวยการสำนัก
+ - หัวหน้าสำนักงาน ก.ก.
+ - หัวหน้าสำนักงานเลขานุการผู้ว่าราชการกรุงเทพมหานคร
+ - เลขานุการสภากรุงเทพมหานคร
+ - ผู้อำนวยการเขต
+ - หัวหน้าส่วนราชการในสังกัดสำนักปลัดกรุงเทพมหานคร
+
+
+
+
+
+ น้ำหนักคะแนน +
ร้อยละ 80
+ - มิติที่ 1 ภารกิจตามนโยบายและยุทธศาสตร์ของ กทม.
+ - มิติที่ 2 วาระเร่งด่วนที่ได้รับมอบหมายพิเศษ(ถ้ามี)
+
+
+ น้ำหนักคะแนน +
ร้อยละ 20
+ - สมรรถนะหลัก
+ - สมรรถนะประจำผู้บริหารกรุงเทพมหานคร
+
+
+
+
+
+ +
+
+
กลุ่มที่ 2
+
+ ผู้ดำรงตำแหน่ง ดังนี้
+ +
+
ประเภทบริหาร
+
ระดับต้น-สูง
+
+ +
+
+ ประเภทอำนวยการ +
+
ระดับต้น-สูง
+
+ +
+
+ ประเภทวิชาการ +
+
+
ระดับในปฏิบัติการ-ทรงคุณวุฒิ
+
ที่ดำรงตำแหน่งทางการบริหาร*
+
+
+ +
+
ประเภททั่วไป
+
+
ระดับอาวุโส
+
ที่ดำรงตำแหน่งทางการบริหาร*
+
+
+
+
+
+
+
+ น้ำหนักคะแนน +
ร้อยละ 80
+ - งานตามแผนปฏิบัติราชการประจำปี
+ - งานตามหน้าที่ความรับผิดชอบหลัก
+ - งานอื่นๆ ที่ได้รับมอบหมาย
+
+
+ น้ำหนักคะแนน +
ร้อยละ 20
+ - สมรรถนะหลัก
+ - สมรรถนะประจำผู้บริหารกรุงเทพมหานคร
+
+
+
+
+
+ +
+
+
กลุ่มที่ 3
+
+ ผู้ดำรงตำแหน่ง ดังนี้
+ +
+
+ ประเภทวิชาการ +
+
ระดับในปฏิบัติการ-ทรงคุณวุฒิ
+
+ +
+
ประเภททั่วไป
+
ระดับในปฏิบัติงาน-อาวุโส
+
+
+
+
+
+
+ น้ำหนักคะแนน +
ร้อยละ 70
+ - งานตามแผนปฏิบัติราชการประจำปี
+ - งานตามหน้าที่ความรับผิดชอบหลัก
+ - งานอื่นๆ ที่ได้รับมอบหมาย
+
+
+ น้ำหนักคะแนน +
ร้อยละ 20
+ - สมรรถนะหลัก
+ - สมรรถนะประจำกลุ่มงาน
+
+
+ น้ำหนักคะแนน +
ร้อยละ 10
+
+
+
+
+ +
+
+
กลุ่มทดลองปฏิบัติราชการ
+
ทุกตำแหน่ง
+
+
+
+
+ น้ำหนักคะแนน +
ร้อยละ 50
+ - งานตามแผนปฏิบัติราชการประจำปี
+ - งานตามหน้าที่ความรับผิดชอบหลัก
+ - งานอื่นๆ ที่ได้รับมอบหมาย
+
+
+ น้ำหนักคะแนน +
ร้อยละ 40
+ - สมรรถนะหลัก
+ - สมรรถนะประจำกลุ่มงาน
+
+
+ น้ำหนักคะแนน +
ร้อยละ 10
+
+
+
+
+
+
@@ -325,4 +562,8 @@ border-right: 1px solid black; } } + +.underlined { + text-decoration: underline; +} From 8022fcd1a5a4f08c6394cb17734b07728dfe7022 Mon Sep 17 00:00:00 2001 From: waruneeauy Date: Tue, 15 Jul 2025 09:22:40 +0700 Subject: [PATCH 3/6] =?UTF-8?q?=E0=B9=81=E0=B8=81=E0=B9=89=E0=B9=84?= =?UTF-8?q?=E0=B8=82=E0=B8=82=E0=B9=89=E0=B8=AD=E0=B8=84=E0=B8=A7=E0=B8=B2?= =?UTF-8?q?=E0=B8=A1=E0=B8=AD=E0=B8=87=E0=B8=84=E0=B9=8C=E0=B8=9B=E0=B8=A3?= =?UTF-8?q?=E0=B8=B0=E0=B8=81=E0=B8=AD=E0=B8=9A=E0=B8=81=E0=B8=B2=E0=B8=A3?= =?UTF-8?q?=E0=B8=9B=E0=B8=A3=E0=B8=B0=E0=B9=80=E0=B8=A1=E0=B8=B4=E0=B8=99?= =?UTF-8?q?=20=E0=B9=81=E0=B8=A5=E0=B8=B0=E0=B9=81=E0=B8=99=E0=B8=A7?= =?UTF-8?q?=E0=B8=97=E0=B8=B2=E0=B8=87=E0=B8=81=E0=B8=B2=E0=B8=A3=E0=B8=9B?= =?UTF-8?q?=E0=B8=A3=E0=B8=B0=E0=B9=80=E0=B8=A1=E0=B8=B4=E0=B8=99=E0=B8=82?= =?UTF-8?q?=E0=B8=AD=E0=B8=87=E0=B8=9C=E0=B8=B9=E0=B9=89=E0=B8=A3=E0=B8=B1?= =?UTF-8?q?=E0=B8=9A=E0=B8=81=E0=B8=B2=E0=B8=A3=E0=B8=9B=E0=B8=A3=E0=B8=B0?= =?UTF-8?q?=E0=B9=80=E0=B8=A1=E0=B8=B4=E0=B8=99=E0=B9=81=E0=B8=95=E0=B9=88?= =?UTF-8?q?=E0=B8=A5=E0=B8=B0=E0=B8=81=E0=B8=A5=E0=B8=B8=E0=B9=88=E0=B8=A1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../components/competency/05ListDetail.vue | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/modules/01_masterdata/components/competency/05ListDetail.vue b/src/modules/01_masterdata/components/competency/05ListDetail.vue index a57a23626..fb1bb76c7 100644 --- a/src/modules/01_masterdata/components/competency/05ListDetail.vue +++ b/src/modules/01_masterdata/components/competency/05ListDetail.vue @@ -49,7 +49,7 @@
ทรงคุณวุฒิ
-
ปฏิบัติการทรงคุณวุฒิ
+
ปฏิบัติการ -
ทรงคุณวุฒิ
(ที่ดำรงตำแหน่งทางการบริหาร)
@@ -245,7 +245,7 @@
- +
ระดับสมรรถนะ
@@ -365,7 +365,7 @@
- ผู้ประเมิน + ผู้รับการประเมิน
@@ -408,7 +408,7 @@ น้ำหนักคะแนน
ร้อยละ 80
- มิติที่ 1 ภารกิจตามนโยบายและยุทธศาสตร์ของ กทม.
- - มิติที่ 2 วาระเร่งด่วนที่ได้รับมอบหมายพิเศษ(ถ้ามี)
+ - มิติที่ 2 วาระเร่งด่วนที่ได้รับมอบหมายพิเศษ (ถ้ามี)
น้ำหนักคะแนน @@ -429,14 +429,14 @@
ประเภทบริหาร
-
ระดับต้น-สูง
+
ระดับต้น - สูง
ประเภทอำนวยการ
-
ระดับต้น-สูง
+
ระดับต้น - สูง
@@ -444,7 +444,7 @@ ประเภทวิชาการ
-
ระดับในปฏิบัติการ-ทรงคุณวุฒิ
+
ระดับปฏิบัติการ - ทรงคุณวุฒิ
ที่ดำรงตำแหน่งทางการบริหาร*
@@ -488,12 +488,12 @@
ประเภทวิชาการ
-
ระดับในปฏิบัติการ-ทรงคุณวุฒิ
+
ระดับปฏิบัติการ - ทรงคุณวุฒิ
ประเภททั่วไป
-
ระดับในปฏิบัติงาน-อาวุโส
+
ระดับปฏิบัติงาน - อาวุโส
From f52cfd27a7b56eedd8a90acf4f1a4743064773e2 Mon Sep 17 00:00:00 2001 From: "DESKTOP-1R2VSQH\\Lenovo ThinkPad E490" Date: Tue, 15 Jul 2025 10:50:51 +0700 Subject: [PATCH 4/6] =?UTF-8?q?refactor=20code=20=20=3D=3D=3D>=20=E0=B8=AA?= =?UTF-8?q?=E0=B8=A1=E0=B8=A3=E0=B8=A3=E0=B8=96=E0=B8=99=E0=B8=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../competency/01ListCompetency.vue | 68 ++-- .../competency/02ListLinkPosition.vue | 75 +++-- .../components/competency/03ListLinkGroup.vue | 303 ++++++++++-------- .../components/competency/04ListCriteria.vue | 39 ++- .../components/competency/Forms/Main.vue | 1 + .../01_masterdata/interface/response/Main.ts | 55 +++- 6 files changed, 328 insertions(+), 213 deletions(-) diff --git a/src/modules/01_masterdata/components/competency/01ListCompetency.vue b/src/modules/01_masterdata/components/competency/01ListCompetency.vue index b2bebdb3f..ee6fcfc0e 100644 --- a/src/modules/01_masterdata/components/competency/01ListCompetency.vue +++ b/src/modules/01_masterdata/components/competency/01ListCompetency.vue @@ -9,6 +9,7 @@ import config from "@/app.config"; import { useCounterMixin } from "@/stores/mixin"; import { useKPIDataStore } from "@/modules/01_masterdata/stores/KPIStore"; import { checkPermission } from "@/utils/permissions"; +import { updateCurrentPage } from "@/utils/function"; import type { DataOption, @@ -23,10 +24,32 @@ const $q = useQuasar(); const mixin = useCounterMixin(); const { dialogRemove, messageError, showLoader, hideLoader, success } = mixin; -const total = ref(); const store = useKPIDataStore(); const router = useRouter(); +const columns = ref([ + { + name: "name", + align: "left", + label: "ชื่อสมรรถนะ", + sortable: true, + field: "name", + headerStyle: "font-size: 14px", + style: "font-size: 14px", + sort: (a: string, b: string) => + a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }), + }, +]); +const visibleColumns = ref(["name"]); + +const rows = ref([]); // ข้อมูลสมรรถนะ +const total = ref(0); // จำนวนรายการทั้งหมด +const totalList = ref(1); // จำนวนหน้าทั้งหมด +const formQuery = reactive({ + page: 1, + pageSize: 10, + keyword: "", +}); // form query สำหรับการค้นหา const competencyTypeOp = ref([ { id: "HEAD", @@ -48,31 +71,9 @@ const competencyTypeOp = ref([ id: "INSPECTOR", name: "สมรรถนะเฉพาะสำหรับตำแหน่งผู้ตรวจราชการ กทม. และผู้ตรวจราชการ", }, -]); -const columns = ref([ - { - name: "name", - align: "left", - label: "ชื่อสมรรถนะ", - sortable: true, - field: "name", - headerStyle: "font-size: 14px", - style: "font-size: 14px", - sort: (a: string, b: string) => - a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }), - }, -]); -const visibleColumns = ref(["name"]); +]); // ประเภทสมรรถนะ -const rows = ref([]); -const formQuery = reactive({ - page: 1, - pageSize: 10, - keyword: "", -}); -const totalList = ref(1); //จำนวนข้อมูลรายการ - -/** ดึงข้อมูล */ +/** ฟังก์ชันดึงข้อมูลรายการสมรรถนะ */ async function fetchList() { showLoader(); await http @@ -96,20 +97,37 @@ async function fetchList() { }); } +/** + * ฟังก์ชันไปหน้าแก้ไขสมรรถนะ + * @param id รหัสสมรรถนะที่ต้องการแก้ไข + */ async function onViewDetail(id: string) { router.push(`/masterdata/competency/${id}`); } +/** + * ฟังก์ชันดูรายละเอียดสมรรถนะ + * @param id รหัสสมรรถนะที่ต้องการดูรายละเอียด + */ async function onViewDetailPage(id: string) { router.push(`/masterdata/competency-detail/${id}`); } +/** + * ฟังก์ชันลบข้อมูลสมรรถนะ + * @param id รหัสสมรรถนะที่ต้องการลบ + */ function deleteData(id: string) { dialogRemove($q, async () => { showLoader(); await http .delete(config.API.kpiCapacity + `/${id}`) .then(async () => { + formQuery.page = await updateCurrentPage( + formQuery.page, + totalList.value, + rows.value.length + ); await fetchList(); success($q, "ลบข้อมูลสำเร็จ"); }) diff --git a/src/modules/01_masterdata/components/competency/02ListLinkPosition.vue b/src/modules/01_masterdata/components/competency/02ListLinkPosition.vue index 2552c2667..63b5478cd 100644 --- a/src/modules/01_masterdata/components/competency/02ListLinkPosition.vue +++ b/src/modules/01_masterdata/components/competency/02ListLinkPosition.vue @@ -7,18 +7,24 @@ import http from "@/plugins/http"; import config from "@/app.config"; import { checkPermission } from "@/utils/permissions"; import { useCounterMixin } from "@/stores/mixin"; +import { updateCurrentPage } from "@/utils/function"; +import type { DataKPIGroup } from "@/modules/01_masterdata/interface/response/Main"; import type { NewPagination } from "@/modules/14_KPI/interface/index/Main"; import dialogHeader from "@/components/DialogHeader.vue"; -const total = ref(); -const modal = ref(false); -const rows = ref([]); -const groupName = ref(""); +const $q = useQuasar(); +const mixin = useCounterMixin(); +const { + dialogRemove, + dialogConfirm, + showLoader, + hideLoader, + messageError, + success, +} = mixin; -const editStatus = ref(false); -const editId = ref(""); const columns = ref([ { name: "nameGroupKPI", @@ -32,18 +38,6 @@ const columns = ref([ a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }), }, ]); - -const $q = useQuasar(); -const mixin = useCounterMixin(); -const { - dialogRemove, - dialogConfirm, - showLoader, - hideLoader, - messageError, - success, -} = mixin; - const visibleColumns = ref(["nameGroupKPI"]); const formQuery = reactive({ @@ -51,9 +45,15 @@ const formQuery = reactive({ pageSize: 10, keyword: "", }); -const totalList = ref(1); //จำนวนข้อมูลรายการ +const totalList = ref(1); //จำนวนหน้าทั้งหมด +const total = ref(0); // จำนวนรายการทั้งหมด +const modal = ref(false); // เปิด/ปิด dialog +const rows = ref([]); // ข้อมูลกลุ่มงาน +const groupName = ref(""); // ชื่อกลุ่มงาน +const editStatus = ref(false); // สถานะการแก้ไข +const editId = ref(""); // รหัสกลุ่มงานที่ต้องการแก้ไข -/** ดึงข้อมูล */ +/** ฟังก์ชันดึงข้อมูลกลุ่มงาน */ async function fetchData() { showLoader(); await http @@ -77,7 +77,7 @@ async function fetchData() { }); } -/** เพิ่มข้อมูล */ +/** ฟังก์ชันบันทึกการเพิ่มข้อมูลกลุ่มงาน */ async function addData() { showLoader(); await http @@ -96,7 +96,10 @@ async function addData() { }); } -/** save แก้ไขข้อมูล */ +/** + * ฟังก์ชันบันทึกการแก้ไขข้อมูลกลุ่มงาน + * @param id รหัสกลุ่มงานที่ต้องการแก้ไข + */ async function editData(id: string) { showLoader(); await http @@ -115,12 +118,20 @@ async function editData(id: string) { }); } -/** ลบข้อมูล */ +/** + * ฟังก์ชันลบข้อมูลกลุ่มงาน + * @param id รหัสกลุ่มงานที่ต้องการลบ + */ async function deleteData(id: string) { showLoader(); await http .delete(config.API.kpiGroupById(id)) .then(async () => { + formQuery.page = await updateCurrentPage( + formQuery.page, + totalList.value, + rows.value.length + ); await fetchData(); success($q, "ลบข้อมูลสำเร็จ"); }) @@ -132,19 +143,23 @@ async function deleteData(id: string) { }); } -/** เปลี่ยนเป็นหน้าเพิ่มข้อมูล */ +/** ฟังก์ชันเปิด dialog เพิ่มข้อมูล */ function onAdd() { modal.value = true; } +/** ฟังก์ชันปิด dialog */ function closeDialog() { modal.value = false; editStatus.value = false; groupName.value = ""; } -/** เปิด dialog แก้ไข */ -function onEdit(data: any) { +/** + * ฟังก์ชันเปิด dialog แก้ไข + * @param data ข้อมูลกลุ่มงานที่ต้องการแก้ไข + */ +function onEdit(data: DataKPIGroup) { modal.value = true; editStatus.value = true; groupName.value = data.nameGroupKPI; @@ -165,18 +180,21 @@ async function onSubmit() { } /** - * function updatePagination + * ฟังก์ชันอัปเดตข้อมูล Pagination * @param newPagination ข้อมูล Pagination ใหม่ */ function updatePagination(newPagination: NewPagination) { formQuery.page = 1; formQuery.pageSize = newPagination.rowsPerPage; } + +/** ฟังก์ชันดึงข้อมูลกลุ่มงานใหม่ */ function fetchNewList() { formQuery.page = 1; fetchData(); } +/** ฟังก์ชันติดตามการเปลี่ยนแปลงจำนวนแถวต่อหน้า */ watch( () => formQuery.pageSize, () => { @@ -184,7 +202,8 @@ watch( } ); -onMounted(async () => { +/** lifecycle hook */ +onMounted(() => { fetchData(); }); diff --git a/src/modules/01_masterdata/components/competency/03ListLinkGroup.vue b/src/modules/01_masterdata/components/competency/03ListLinkGroup.vue index ab446b64e..184fb47b2 100644 --- a/src/modules/01_masterdata/components/competency/03ListLinkGroup.vue +++ b/src/modules/01_masterdata/components/competency/03ListLinkGroup.vue @@ -3,13 +3,12 @@ import { ref, onMounted, reactive, watch } from "vue"; import type { QTableProps } from "quasar"; import { useQuasar } from "quasar"; -import { useRoute } from "vue-router"; import http from "@/plugins/http"; import config from "@/app.config"; import { useCounterMixin } from "@/stores/mixin"; - -import Header from "@/components/DialogHeader.vue"; +import { checkPermission } from "@/utils/permissions"; +import { updateCurrentPage } from "@/utils/function"; import type { DataOption, @@ -17,26 +16,47 @@ import type { ListLinkGroup, Position, } from "@/modules/01_masterdata/interface/index/Main"; +import type { + DataKPIGroup, + DataKPIPosition, + DataKPICapacity, +} from "@/modules/01_masterdata/interface/response/Main"; -import { checkPermission } from "@/utils/permissions"; +import Header from "@/components/DialogHeader.vue"; -const total = ref(); -const id = ref(""); -const modal = ref(false); -const rows = ref([]); -const editStatus = ref(false); -const groupName = ref(); -const position = ref(); -const competency = ref(); -const route = useRoute(); +const $q = useQuasar(); +const mixin = useCounterMixin(); +const { + dialogRemove, + messageError, + showLoader, + hideLoader, + success, + dialogConfirm, +} = mixin; -const groupNameOp = ref([]); -const groupNameOpMain = ref([]); -const positionOp = ref([]); -const positionMainOp = ref([]); -const competencyOp = ref([]); -const competencyOpMain = ref([]); +const id = ref(""); // รหัสกลุ่มงานที่ต้องการแก้ไข +const modal = ref(false); // เปิด/ปิด dialog +const editStatus = ref(false); // สถานะการแก้ไข +const groupName = ref(); // กลุ่มงานที่เลือก +const position = ref([]); // ตำแหน่งที่เลือก +const competency = ref([]); // สมรรถนะที่เลือก +const groupNameOp = ref([]); // กลุ่มงาน +const groupNameOpMain = ref([]); // กลุ่มงานหลัก +const positionOp = ref([]); // ตำแหน่ง +const positionMainOp = ref([]); // ตำแหน่งหลัก +const competencyOp = ref([]); // สมรรถนะ +const competencyOpMain = ref([]); // สมรรถนะหลัก + +const formQuery = reactive({ + page: 1, + pageSize: 10, + keyword: "", +}); +const totalList = ref(1); // จำนวนหน้าทั้งหมด +const total = ref(0); // จำนวนรายการทั้งหมด +const rows = ref([]); // ข้อมูลเชื่อมโยงกับกลุ่มงานและตำแหน่ง const columns = ref([ { name: "groupName", @@ -72,28 +92,9 @@ const columns = ref([ a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }), }, ]); - -const $q = useQuasar(); -const mixin = useCounterMixin(); -const { - dialogRemove, - messageError, - showLoader, - hideLoader, - success, - dialogConfirm, -} = mixin; - const visibleColumns = ref(["groupName", "positions", "capacitys"]); -const formQuery = reactive({ - page: 1, - pageSize: 10, - keyword: "", -}); -const totalList = ref(1); //จำนวนข้อมูลรายการ - -/** ดึงข้อมูล */ +/** ฟังก์ชันดึงข้อมูลรายการเชื่อมโยงกับกลุ่มงานและตำแหน่ง */ async function getData() { showLoader(); http @@ -109,19 +110,30 @@ async function getData() { totalList.value = Math.ceil(res.data.result.total / formQuery.pageSize); rows.value = data.data; }) + .catch((err) => { + messageError($q, err); + }) .finally(() => { hideLoader(); }); } +/** + * ฟังก์ชันลบข้อมูลเชื่อมโยงกับกลุ่มงานและตำแหน่ง + * @param id รหัสรายการข้อมูลเชื่อมโยงกับกลุ่มงานและตำแหน่ง + */ async function deleteData(id: string) { showLoader(); await http .delete(config.API.kpiLink + `/${id}`) .then(async () => { + formQuery.page = await updateCurrentPage( + formQuery.page, + totalList.value, + rows.value.length + ); await getData(); success($q, "ลบข้อมูลสำเร็จ"); - close(); }) .catch((err) => { messageError($q, err); @@ -131,23 +143,22 @@ async function deleteData(id: string) { }); } -/** ดึงข้อมูล */ +/** ฟังก์ชันดึงข้อมูลกลุ่มงาน */ async function getListGroup() { - showLoader(); await http .get(config.API.kpiGroup + `?pageSize=50`) .then(async (res) => { const dataOp = res.data.result.data; const uniqueNames = new Set(); const filteredData = dataOp - .filter((item: any) => { + .filter((item: DataKPIGroup) => { if (!uniqueNames.has(item.id)) { uniqueNames.add(item.nameGroupKPI); return true; } return false; }) - .map((item: any) => ({ + .map((item: DataKPIGroup) => ({ id: item.id, name: item.nameGroupKPI, })); @@ -156,29 +167,25 @@ async function getListGroup() { }) .catch((err) => { messageError($q, err); - }) - .finally(() => { - hideLoader(); }); } -/** ดึงข้อมูล */ +/** ฟังก์ชันดึงข้อมูลสมรรถนะ */ async function getCompetency() { - showLoader(); await http .get(config.API.kpiCapacity + `?type=GROUP&pageSize=50`) .then(async (res) => { const dataOp = res.data.result.data; const uniqueNames = new Set(); const filteredData = dataOp - .filter((item: any) => { + .filter((item: DataKPICapacity) => { if (!uniqueNames.has(item.id)) { uniqueNames.add(item.name); return true; } return false; }) - .map((item: any) => ({ + .map((item: DataKPICapacity) => ({ id: item.id, name: item.name, })); @@ -187,33 +194,70 @@ async function getCompetency() { }) .catch((err) => { messageError($q, err); - }) - .finally(() => { - hideLoader(); }); } -/** เปลี่ยนเป็นหน้าเพิ่มข้อมูล */ -function onAdd() { - getOptions(); - getListGroup(); - getCompetency(); - modal.value = true; +/** ฟังก์ชันดึงข้อมูลตำแหน่ง */ +async function getOptions() { + await http + .get(config.API.orgSalaryPosition) + .then((res) => { + const dataOp = res.data.result; + const uniqueNames = new Set(); + const filteredData = dataOp + .filter((item: DataKPIPosition) => { + if (!uniqueNames.has(item.positionName)) { + uniqueNames.add(item.positionName); + return true; + } + return false; + }) + .map((item: DataKPIPosition) => ({ + id: item.positionName, + name: item.positionName, + })); + + positionMainOp.value = filteredData; + }) + .catch((err) => { + messageError($q, err); + }); } -async function onEdit(data: any) { - id.value = data; - await getOptions(); - await getListGroup(); - await getCompetency(); - await getDataEdit(id.value); - modal.value = true; - editStatus.value = true; -} - -async function getDataEdit(id: string) { +/** ฟังก์ชันเปิด dialog เพิ่มข้อมูล */ +async function onAdd() { showLoader(); - http + try { + modal.value = true; + await Promise.all([getOptions(), getListGroup(), getCompetency()]); + } finally { + hideLoader(); + } +} + +/** + * ฟังก์ชันเปิด dialog แก้ไข + * @param rowId รหัสกลุ่มงานที่ต้องการแก้ไข + */ +async function onEdit(rowId: string) { + showLoader(); + try { + id.value = rowId; + modal.value = true; + editStatus.value = true; + await Promise.all([getOptions(), getListGroup(), getCompetency()]); + await getDataEdit(id.value); + } finally { + hideLoader(); + } +} + +/** + * ฟังก์ชันดึงข้อมูลสำหรับแก้ไข + * @param id รหัสกลุ่มงานที่ต้องการแก้ไข + */ +async function getDataEdit(id: string) { + await http .get(config.API.kpiLink + `/edit/${id}`) .then((res) => { const data = res.data.result; @@ -221,17 +265,18 @@ async function getDataEdit(id: string) { id: data.groupId, name: data.groupName, }; - position.value = data.positions.map((i: any) => i.name); - competency.value = data.capacitys.map((i: any) => ({ + position.value = data.positions.map((i: Position) => i.name); + competency.value = data.capacitys.map((i: DataKPICapacity) => ({ id: i.id, name: i.name, })); }) - .finally(() => { - hideLoader(); + .catch((err) => { + messageError($q, err); }); } +/** ฟังก์ชันบันทึกข้อมูล */ function onSubmit() { const url = editStatus.value ? config.API.kpiLink + `/${id.value}` @@ -239,7 +284,7 @@ function onSubmit() { const body = { kpiGroupId: groupName.value?.id, positions: position.value, - kpiCapacityIds: competency.value?.map((i: any) => i.id), + kpiCapacityIds: competency.value?.map((i: Position) => i.id), }; dialogConfirm($q, async () => { showLoader(); @@ -267,82 +312,56 @@ function close() { competency.value = []; } -async function getOptions() { - http.get(config.API.orgSalaryPosition).then((res) => { - const dataOp = res.data.result; - const uniqueNames = new Set(); - const filteredData = dataOp - .filter((item: any) => { - if (!uniqueNames.has(item.positionName)) { - uniqueNames.add(item.positionName); - return true; - } - return false; - }) - .map((item: any) => ({ - id: item.positionName, - name: item.positionName, - })); - - positionMainOp.value = filteredData; - }); -} - /** - * function ต้นหาข้อมูลของ Option + * ฟังก์ชันค้นหาข้อมูลของ Option * @param val ค่าที่ต้องการฟิลเตอร์ * @param update อัพเดทค่า - * @param refData ดาต้าที่ต้องการฟิลเตอร์ + * @param type ประเภทของ Option ที่ต้องการฟิลเตอร์ */ -function filterOptionGroup(val: any, update: Function) { - update(() => { - groupNameOp.value = groupNameOpMain.value.filter( - (v: any) => v.name.indexOf(val) > -1 - ); - }); +function filterOptionSelect(val: string, update: Function, type: string) { + switch (type) { + case "group": + update(() => { + groupNameOp.value = groupNameOpMain.value.filter( + (v: DataOption) => v.name.indexOf(val) > -1 + ); + }); + break; + case "position": + update(() => { + positionOp.value = positionMainOp.value.filter( + (v: DataOption) => v.name.indexOf(val) > -1 + ); + }); + break; + case "competency": + update(() => { + competencyOp.value = competencyOpMain.value.filter( + (v: DataOption) => v.name.indexOf(val) > -1 + ); + }); + + default: + break; + } } /** - * function ต้นหาข้อมูลของ Option - * @param val ค่าที่ต้องการฟิลเตอร์ - * @param update อัพเดทค่า - * @param refData ดาต้าที่ต้องการฟิลเตอร์ - */ -function filterOption(val: any, update: Function) { - update(() => { - positionOp.value = positionMainOp.value.filter( - (v: any) => v.name.indexOf(val) > -1 - ); - }); -} - -/** - * function ต้นหาข้อมูลของ Option - * @param val ค่าที่ต้องการฟิลเตอร์ - * @param update อัพเดทค่า - * @param refData ดาต้าที่ต้องการฟิลเตอร์ - */ -function filterOptionCompetency(val: any, update: Function) { - update(() => { - competencyOp.value = competencyOpMain.value.filter( - (v: any) => v.name.indexOf(val) > -1 - ); - }); -} - -/** - * function updatePagination + * ฟังก์ชันอัปเดต Pagination * @param newPagination ข้อมูล Pagination ใหม่ */ function updatePagination(newPagination: NewPagination) { formQuery.page = 1; formQuery.pageSize = newPagination.rowsPerPage; } + +/** ฟังก์ชันดึงข้อมูลใหม่ */ function fetchNewList() { formQuery.page = 1; getData(); } +/** ฟังก์ชันติดตามการเปลี่ยนแปลงจำนวนแถวต่อหน้า */ watch( () => formQuery.pageSize, () => { @@ -350,7 +369,8 @@ watch( } ); -onMounted(async () => { +/** lifecycle hook */ +onMounted(() => { getData(); }); @@ -376,8 +396,7 @@ onMounted(async () => { label="ค้นหา" @keyup.enter="fetchNewList()" > - { class="custom-header-table" :visible-columns="visibleColumns" :separator="'cell'" - :rows-per-page-options="[10, 25, 50, 100]" + :rows-per-page-options="[1, 10, 25, 50, 100]" @update:pagination="updatePagination" >