diff --git a/src/components/TablePagination.vue b/src/components/TablePagination.vue new file mode 100644 index 000000000..cfbf5a724 --- /dev/null +++ b/src/components/TablePagination.vue @@ -0,0 +1,234 @@ + + + + diff --git a/src/composables/usePagination.ts b/src/composables/usePagination.ts new file mode 100644 index 000000000..842619634 --- /dev/null +++ b/src/composables/usePagination.ts @@ -0,0 +1,47 @@ +import { ref, computed } from "vue"; +import type { PropsTable } from "@/interface/index/PropsTable"; + +export function usePagination( + defaultSort = "", + fetchFunction?: () => Promise +) { + const pagination = ref({ + sortBy: defaultSort, + descending: true, + page: 1, + rowsPerPage: 10, + rowsNumber: 0, + }); + + const params = computed(() => { + const queryParams: Record = { + page: pagination.value.page.toString(), + pageSize: pagination.value.rowsPerPage.toString(), + }; + + if (pagination.value.sortBy) { + queryParams.sortBy = pagination.value.sortBy; + queryParams.descending = ( + pagination.value.descending ?? false + ).toString(); + } + + return queryParams; + }); + + async function onRequest(props: PropsTable.RequestProps) { + const newPagination = props?.pagination || props; + if (!newPagination?.page || !newPagination?.rowsPerPage) return; + + pagination.value = { ...newPagination }; + if (fetchFunction) { + await fetchFunction(); // เรียกฟังก์ชันที่ส่งเข้ามา + } + } + + return { + pagination, + params, + onRequest, + }; +} diff --git a/src/interface/index/PropsTable.ts b/src/interface/index/PropsTable.ts new file mode 100644 index 000000000..b9d4fe063 --- /dev/null +++ b/src/interface/index/PropsTable.ts @@ -0,0 +1,36 @@ +/** Namespace สำหรับ Table-related types */ +export namespace PropsTable { + /** Interface สำหรับ pagination object */ + export interface Pagination { + /** หน้าปัจจุบัน (เริ่มจาก 1) */ + page: number; + /** จำนวนแถวต่อหน้า */ + rowsPerPage: number; + /** จำนวนแถวทั้งหมด */ + rowsNumber?: number; + /** คอลัมน์ที่ใช้ sort */ + sortBy?: string; + /** เรียงจากมากไปน้อย */ + descending?: boolean; + + rowsTotal?: number; + } + + /** Interface สำหรับ request props จาก d-table */ + export interface RequestProps { + /** ข้อมูล pagination */ + pagination: Pagination; + /** ตัวกรองข้อมูล */ + filter?: any; + /** function สำหรับดึงค่าจาก cell */ + getCellValue?: (col: any, row: any) => any; + } + + /** Union type สำหรับ handleRequest function */ + export type HandleRequestProps = RequestProps; +} + +// Export แบบเดิมเพื่อ backward compatibility +export type TablePagination = PropsTable.Pagination; +export type TableRequestProps = PropsTable.RequestProps; +export type HandleRequestProps = PropsTable.HandleRequestProps; diff --git a/src/main.ts b/src/main.ts index e179635f1..570937672 100644 --- a/src/main.ts +++ b/src/main.ts @@ -73,5 +73,10 @@ app.component( defineAsyncComponent(() => import("@/components/Table.vue")) ); +app.component( + "p-table", + defineAsyncComponent(() => import("@/components/TablePagination.vue")) +); + app.config.globalProperties.$http = http; app.mount("#app"); diff --git a/src/modules/04_registryPerson/components/detail/Achievement/05_ResultsPerformance.vue b/src/modules/04_registryPerson/components/detail/Achievement/05_ResultsPerformance.vue index d7accda5a..d1337c253 100644 --- a/src/modules/04_registryPerson/components/detail/Achievement/05_ResultsPerformance.vue +++ b/src/modules/04_registryPerson/components/detail/Achievement/05_ResultsPerformance.vue @@ -6,6 +6,7 @@ import { useRoute } from "vue-router"; import { checkPermission } from "@/utils/permissions"; import { useCounterMixin } from "@/stores/mixin"; import { useResultsPerformDataStore } from "@/modules/04_registryPerson/stores/ResultsPerformance"; +import { usePagination } from "@/composables/usePagination"; import http from "@/plugins/http"; import config from "@/app.config"; @@ -24,6 +25,9 @@ const $q = useQuasar(); const route = useRoute(); const store = useResultsPerformDataStore(); const { textRangePoint, textPoint } = store; +const { pagination, params, onRequest } = usePagination("", () => + getDevelop(true) +); const mixin = useCounterMixin(); const { date2Thai, @@ -61,15 +65,6 @@ const isLeave = defineModel("isLeave", { required: true, }); -const totalIdp = ref(0); -const totalListIdp = ref(1); -const paginationIdp = ref({ - sortBy: "createdAt", - descending: true, - page: 1, - rowsPerPage: 10, -}); - const resPerformForm = reactive({ name: "", point1Total: 0, //ส่วนที่1 (น้ำหนัก) @@ -273,9 +268,6 @@ const columns = ref( const visibleColumns = ref( baseVisibleColumns.value.filter((e: string) => e !== "lastUpdateFullName") ); -const pagination = ref({ - sortBy: "lastUpdatedAt", -}); //Table การพัฒนารายบุคคล (Individual Development Plan) const rowsPlan = ref([]); @@ -295,12 +287,10 @@ const columnsPlan = ref([ name: "name", align: "left", label: "ความรู้/ทักษะ/สมรรถนะที่ต้องได้รับการพัฒนา", - sortable: false, + 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" }), }, { name: "developmentProjects", @@ -310,44 +300,36 @@ const columnsPlan = ref([ field: "developmentProjects", headerStyle: "font-size: 14px", style: "font-size: 14px", - sort: (a: string, b: string) => - a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }), }, { name: "developmentTarget", align: "left", label: "เป้าหมายการพัฒนา", - sortable: false, + sortable: true, field: "developmentTarget", headerStyle: "font-size: 14px", style: "font-size: 14px", - sort: (a: string, b: string) => - a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }), }, { name: "developmentResults", align: "left", label: "วิธีการวัดผลการพัฒนา", - sortable: false, + sortable: true, field: "developmentResults", headerStyle: "font-size: 14px", style: "font-size: 14px", - sort: (a: string, b: string) => - a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }), }, { name: "developmentReport", align: "left", label: "รายงานผลการพัฒนา", - sortable: false, + sortable: true, field: "developmentReport", headerStyle: "font-size: 14px", style: "font-size: 14px", - sort: (a: string, b: string) => - a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }), }, ]); -const visibleColumnsPlan = ref([ +const visibleColumnsPlan = ref([ "no", "name", "developmentProjects", @@ -357,8 +339,6 @@ const visibleColumnsPlan = ref([ ]); //Table ประวัติแก้ไข -const rowsHistory = ref([]); -const rowsHistoryMain = ref([]); const historyId = ref(""); const columnsHistory = ref(baseColumns.value); const visibleColumnsHistory = ref(baseVisibleColumns.value); @@ -378,8 +358,8 @@ async function fetchData() { rowsMain.value = res.data.result; } catch (error) { messageError($q, error); - hideLoader(); } finally { + hideLoader(); } } @@ -387,29 +367,25 @@ async function fetchData() { async function getDevelop(isLoad?: boolean) { if (!profileId.value) return; isLoad && showLoader(); + const queryParams = { + ...params.value, + searchKeyword: filterSearchPlan.value.trim(), + }; await http - .get( - config.API.developMentPlan(empType.value) + - `/${profileId.value}?page=${paginationIdp.value.page}&pageSize=${ - paginationIdp.value.rowsPerPage - }&searchKeyword=${filterSearchPlan.value.trim()} -` - ) + .get(config.API.developMentPlan(empType.value) + `/${profileId.value}`, { + params: queryParams, + }) .then((res) => { - const data = res.data.result.data; - totalListIdp.value = Math.ceil( - res.data.result.total / paginationIdp.value.rowsPerPage - ); - totalIdp.value = res.data.result.total; - rowsPlan.value = data; - - isLoad && hideLoader(); + const data = res.data.result; + pagination.value.rowsNumber = data.total; + rowsPlan.value = data.data; }) .catch((e) => { messageError($q, e); - hideLoader(); }) - .finally(() => {}); + .finally(() => { + isLoad && hideLoader(); + }); } /** @@ -531,11 +507,6 @@ function openDialogDevelop(data: any) { typeIDP.value = data.type; } -function updatePaginationIdp(newPagination: any) { - paginationIdp.value.page = 1; - paginationIdp.value.rowsPerPage = newPagination.rowsPerPage; -} - function serchDataTable() { rows.value = onSearchDataTable( filterSearch.value, @@ -544,13 +515,6 @@ function serchDataTable() { ); } -watch( - () => paginationIdp.value.rowsPerPage, - async () => { - await getDevelop(true); - } -); - onMounted(async () => { await fetchData(); empType.value !== "-temp" && (await getDevelop()); @@ -647,7 +611,6 @@ onMounted(async () => { bordered :rows="rows" :columns="columns" - v-model:pagination="pagination" :grid="modeView === 'card'" :visible-columns="visibleColumns" > @@ -769,9 +732,7 @@ onMounted(async () => { ref="filterPlanRef" outlined placeholder="ค้นหา" - @keydown.enter.prevent=" - (paginationIdp.page = 1), getDevelop(true) - " + @keydown.enter.prevent="(pagination.page = 1), getDevelop(true)" >