fix load Table

This commit is contained in:
DESKTOP-1R2VSQH\Lenovo ThinkPad E490 2025-08-29 13:45:33 +07:00
parent 1ec4a97538
commit d39753fbde
56 changed files with 684 additions and 978 deletions

View file

@ -10,13 +10,16 @@
dense dense
:pagination-label="paginationLabel" :pagination-label="paginationLabel"
v-model:pagination="pagination" v-model:pagination="pagination"
@request="onRequest"
:grid="!$q.screen.gt.xs" :grid="!$q.screen.gt.xs"
:rows-per-page-options="[10, 25, 50, 100]" :rows-per-page-options="[10, 25, 50, 100]"
:loading="loading"
> >
<template v-slot:pagination="scope"> <template v-slot:pagination="scope">
งหมด {{ attrs.rows.length }} รายการ งหมด {{ pagination.rowsNumber || attrs.rows.length }} รายการ
<q-pagination <q-pagination
v-model="pagination.page" v-model="pagination.page"
@update:model-value="handlePageChange"
active-color="primary" active-color="primary"
color="dark" color="dark"
:max="scope.pagesNumber" :max="scope.pagesNumber"
@ -27,9 +30,25 @@
></q-pagination> ></q-pagination>
</template> </template>
<template v-for="(_, slot) in slots" v-slot:[slot]="scope"> <template v-for="(_, slot) in slots" v-slot:[slot]="scope" :key="slot">
<slot :name="slot" v-bind="scope || {}" /> <slot :name="slot" v-bind="scope || {}" />
</template> </template>
<template v-slot:loading>
<q-inner-loading showing class="q-mt-lg">
<q-spinner-dots color="primary" size="40px" />
</q-inner-loading>
</template>
<template v-slot:no-data>
<div
v-if="!loading && attrs.rows.length === 0"
class="full-width row flex-center q-pa-sm rounded-borders text-weight-medium"
>
<span> ไมพบขอม </span>
</div>
</template>
<!-- <template #item="props"> <!-- <template #item="props">
<div class="q-pa-xs col-xs-12 col-sm-6 col-md-4 col-lg-3"> <div class="q-pa-xs col-xs-12 col-sm-6 col-md-4 col-lg-3">
<q-card bordered flat> <q-card bordered flat>
@ -55,22 +74,45 @@
</q-table> </q-table>
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { ref, useAttrs, useSlots } from "vue"; import { ref, useAttrs, useSlots, computed, watch } from "vue";
const attrs = ref<any>(useAttrs()); const attrs = ref<any>(useAttrs());
const slots = ref<any>(useSlots()); const slots = ref<any>(useSlots());
const emit = defineEmits(["update:pagination", "request"]);
const props = defineProps({ const props = defineProps({
paging: { paging: {
type: Boolean, type: Boolean,
defualt: false, default: false,
},
loading: {
type: Boolean,
default: false,
},
pagination: {
type: Object,
default: () => ({
sortBy: "desc",
descending: false,
page: 1,
rowsPerPage: 10,
// rowsNumber: 0,
}),
}, },
}); });
const pagination = ref({ // Internal pagination state
sortBy: "desc", const internalPagination = ref({
descending: false, ...props.pagination,
page: 1, });
rowsPerPage: 10,
// computed sync props internal state
const pagination = computed({
get: () => internalPagination.value,
set: (value) => {
internalPagination.value = { ...value };
emit("update:pagination", value);
},
}); });
const paginationLabel = (start: string, end: string, total: string) => { const paginationLabel = (start: string, end: string, total: string) => {
@ -78,6 +120,57 @@ const paginationLabel = (start: string, end: string, total: string) => {
return " " + start + " ถึง " + end + " จากจำนวน " + total + " รายการ"; return " " + start + " ถึง " + end + " จากจำนวน " + total + " รายการ";
else return start + "-" + end + " ใน " + total; else return start + "-" + end + " ใน " + total;
}; };
function onRequest(requestProp: any) {
if (!requestProp || !requestProp.pagination) {
return;
}
const { pagination: newPagination } = requestProp;
// (page rowsPerPage ) request
const isPageChange =
internalPagination.value.page !== newPagination.page ||
internalPagination.value.rowsPerPage !== newPagination.rowsPerPage;
internalPagination.value = {
...internalPagination.value,
...newPagination,
};
if (isPageChange) {
emit("request", requestProp);
}
}
function handlePageChange(newPage: number) {
if (!newPage || newPage < 1) {
return;
}
internalPagination.value = {
...internalPagination.value,
page: newPage,
};
// request object onRequest
const requestProp = {
pagination: internalPagination.value,
filter: null,
getCellValue: () => {},
};
emit("request", requestProp);
}
// Watch props internal state parent
watch(
() => props.pagination,
(newPagination) => {
internalPagination.value = { ...newPagination };
},
{ deep: true, immediate: true }
);
</script> </script>
<style lang="scss"> <style lang="scss">
@ -113,5 +206,33 @@ const paginationLabel = (start: string, end: string, total: string) => {
margin-bottom: 0 !important; margin-bottom: 0 !important;
min-height: 0px !important; min-height: 0px !important;
} }
// Loading styles
.loading-overlay {
width: 100%;
}
.loading-row {
background: white;
}
.loading-cell {
text-align: center;
padding: 60px 20px;
border: none;
}
.loading-content {
display: flex;
flex-direction: column;
align-items: center;
gap: 16px;
}
.loading-text {
color: #666;
font-size: 14px;
font-weight: 500;
}
} }
</style> </style>

View file

@ -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;

View file

@ -14,8 +14,6 @@ import type {
TransferMain, TransferMain,
} from "@/modules/02_transfer/interface/Main"; } from "@/modules/02_transfer/interface/Main";
import SkeletonTable from "@/components/SkeletonTable.vue";
const $q = useQuasar(); const $q = useQuasar();
const router = useRouter(); const router = useRouter();
const mixin = useCounterMixin(); const mixin = useCounterMixin();
@ -247,33 +245,18 @@ onMounted(async () => {
</div> </div>
<div> <div>
<d-table <d-table
v-if="!isLoading"
flat flat
bordered bordered
dense dense
:paging="true" :paging="true"
row-key="id" row-key="id"
class="custom-table2"
style="max-height: 80vh"
:rows="rows" :rows="rows"
:columns="columns" :columns="columns"
:visible-columns="visibleColumns" :visible-columns="visibleColumns"
:rows-per-page-options="[10, 25, 50, 100]" :rows-per-page-options="[10, 25, 50, 100]"
v-model:pagination="pagination" :pagination="pagination"
:loading="isLoading"
> >
<template v-slot:pagination="scope">
งหมด {{ rows.length }} รายการ
<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>
<template v-slot:header="props"> <template v-slot:header="props">
<q-tr :props="props"> <q-tr :props="props">
<q-th <q-th
@ -341,11 +324,11 @@ onMounted(async () => {
</div> </div>
</template> </template>
</d-table> </d-table>
<SkeletonTable v-else :columns="columns" />
</div> </div>
</q-card> </q-card>
</div> </div>
</div> </div>
</div> </div>
</template> </template>
<style scoped lang="scss"></style> <style scoped lang="scss"></style>

View file

@ -20,7 +20,7 @@ import Dialog from "@/modules/03_retire/views/DialogRetire.vue";
import Header from "@/components/DialogHeader.vue"; import Header from "@/components/DialogHeader.vue";
import Workflow from "@/components/Workflow/Main.vue"; import Workflow from "@/components/Workflow/Main.vue";
import SkeletonTable from "@/components/SkeletonTable.vue";
const $q = useQuasar(); const $q = useQuasar();
const route = useRoute(); const route = useRoute();
@ -608,7 +608,6 @@ onMounted(async () => {
<q-separator /> <q-separator />
<div class="col-12 q-pa-sm"> <div class="col-12 q-pa-sm">
<d-table <d-table
v-if="!isLoad"
ref="table" ref="table"
:columns="columnsCommanders" :columns="columnsCommanders"
:rows="rowsApprover?.commanders ?? []" :rows="rowsApprover?.commanders ?? []"
@ -618,6 +617,8 @@ onMounted(async () => {
:paging="true" :paging="true"
dense dense
:rows-per-page-options="[1, 25, 50, 100]" :rows-per-page-options="[1, 25, 50, 100]"
:pagination="{ page: 1, rowsPerPage: 10 }"
:loading="isLoad"
> >
<template v-slot:header="props"> <template v-slot:header="props">
<q-tr :props="props"> <q-tr :props="props">
@ -657,7 +658,6 @@ onMounted(async () => {
</q-tr> </q-tr>
</template> </template>
</d-table> </d-table>
<SkeletonTable v-else :columns="columnsCommanders" />
</div> </div>
</q-card> </q-card>
</div> </div>
@ -769,7 +769,6 @@ onMounted(async () => {
<q-separator /> <q-separator />
<div class="col-12 q-pa-sm"> <div class="col-12 q-pa-sm">
<d-table <d-table
v-if="!isLoad"
ref="table" ref="table"
:columns="columnsCommanders" :columns="columnsCommanders"
:rows="rowsApprover?.cancelCommanders ?? []" :rows="rowsApprover?.cancelCommanders ?? []"
@ -779,6 +778,8 @@ onMounted(async () => {
:paging="true" :paging="true"
dense dense
:rows-per-page-options="[1, 25, 50, 100]" :rows-per-page-options="[1, 25, 50, 100]"
:pagination="{ page: 1, rowsPerPage: 10 }"
:loading="isLoad"
> >
<template v-slot:header="props"> <template v-slot:header="props">
<q-tr :props="props"> <q-tr :props="props">
@ -818,7 +819,6 @@ onMounted(async () => {
</q-tr> </q-tr>
</template> </template>
</d-table> </d-table>
<SkeletonTable v-else :columns="columnsCommanders" />
</div> </div>
</q-card> </q-card>
</div> </div>

View file

@ -15,15 +15,12 @@ import type {
MainListResponse, MainListResponse,
} from "@/modules/03_retire/interface/Main"; } from "@/modules/03_retire/interface/Main";
import SkeletonTable from "@/components/SkeletonTable.vue";
const $q = useQuasar(); const $q = useQuasar();
const router = useRouter(); const router = useRouter();
const link = ref<string>(""); const link = ref<string>("");
const dataStore = useDataStore(); const dataStore = useDataStore();
const mixin = useCounterMixin(); const mixin = useCounterMixin();
const { date2Thai, messageError, showLoader, hideLoader, onSearchDataTable } = const { date2Thai, messageError, onSearchDataTable } = mixin;
mixin;
const RestData = useRestDataStore(); const RestData = useRestDataStore();
const { statusText } = RestData; //Func status to text const { statusText } = RestData; //Func status to text
@ -200,8 +197,7 @@ onMounted(async () => {
</div> </div>
<div> <div>
<d-table <d-table
v-if="!isLoad" fla
flat
bordered bordered
dense dense
row-key="id" row-key="id"
@ -210,20 +206,8 @@ onMounted(async () => {
:visible-columns="visibleColumns" :visible-columns="visibleColumns"
:rows-per-page-options="[10, 25, 50, 100]" :rows-per-page-options="[10, 25, 50, 100]"
v-model:pagination="pagination" v-model:pagination="pagination"
:loading="isLoad"
> >
<template v-slot:pagination="scope">
งหมด {{ rows.length }} รายการ
<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>
<template v-slot:header="props"> <template v-slot:header="props">
<q-tr :props="props"> <q-tr :props="props">
<q-th <q-th
@ -280,7 +264,6 @@ onMounted(async () => {
</div> </div>
</template> </template>
</d-table> </d-table>
<SkeletonTable v-else :columns="columns" />
</div> </div>
</q-card> </q-card>
</div> </div>

View file

@ -1,5 +1,5 @@
<script setup lang="ts"> <script setup lang="ts">
import { onMounted, ref, watch } from "vue"; import { ref } from "vue";
import { useQuasar, type QTableProps } from "quasar"; import { useQuasar, type QTableProps } from "quasar";
import http from "@/plugins/http"; import http from "@/plugins/http";
@ -8,15 +8,16 @@ import { useCounterMixin } from "@/stores/mixin";
import { useLeaveStore } from "@/modules/05_leave/store"; import { useLeaveStore } from "@/modules/05_leave/store";
import { useDataStore } from "@/stores/data"; import { useDataStore } from "@/stores/data";
import DialogHeader from "@/components/DialogHeader.vue"; import type { PropsTable } from "@/interface/PropsTable";
import SkeletonTable from "@/components/SkeletonTable.vue"; import type { DataCommander } from "@/modules/05_leave/interface/response/main";
const mixin = useCounterMixin(); import DialogHeader from "@/components/DialogHeader.vue";
const $q = useQuasar();
const dataStore = useLeaveStore(); const dataStore = useLeaveStore();
const storeData = useDataStore(); const storeData = useDataStore();
const { date2Thai, showLoader, hideLoader, messageError } = mixin; const { date2Thai, messageError } = useCounterMixin();
const modal = ref<boolean>(false);
/** รับ props มาจากหน้าหลัก */ /** รับ props มาจากหน้าหลัก */
const props = defineProps({ const props = defineProps({
model: { model: {
@ -25,21 +26,13 @@ const props = defineProps({
}, },
}); });
const $q = useQuasar(); const modal = ref<boolean>(false);
const isAct = ref<boolean>(false);
const search = ref<string>("");
const total = ref<number>(0);
const totalList = ref<number>(1);
const pagination = ref({
sortBy: "createdAt",
descending: true,
page: 1,
rowsPerPage: 10,
});
const selected = ref<any[]>([]); const isAct = ref<boolean>(false);
const selected = ref<DataCommander[]>([]);
const search = ref<string>("");
const isLoading = ref<boolean>(false); const isLoading = ref<boolean>(false);
const rows = ref<any[]>([]); const rows = ref<DataCommander[]>([]);
const columns = ref<QTableProps["columns"]>([ const columns = ref<QTableProps["columns"]>([
{ {
name: "posNo", name: "posNo",
@ -72,28 +65,15 @@ const columns = ref<QTableProps["columns"]>([
style: "font-size: 14px", style: "font-size: 14px",
}, },
]); ]);
const pagination = ref<PropsTable.Pagination>({
sortBy: "createdAt",
descending: true,
page: 1,
rowsPerPage: 10,
rowsNumber: 0,
});
function onPerson() { /** ฟังก์ชันสำหรับดึงข้อมูลผู้บังคับบัญชา */
modal.value = true;
getCommander();
}
function onSubmit() {
modal.value = false;
dataStore.dear = selected.value[0].firstName
? `${selected.value[0].prefix}${selected.value[0].firstName} ${selected.value[0].lastName}`
: "";
dataStore.commanderPosition = selected.value[0].posExecutiveName;
}
function closeDialog() {
modal.value = false;
search.value = "";
rows.value = [];
selected.value = [];
}
async function getCommander() { async function getCommander() {
isLoading.value = true; isLoading.value = true;
await http await http
@ -109,11 +89,12 @@ async function getCommander() {
: "employee", : "employee",
}) })
.then((res) => { .then((res) => {
rows.value = res.data.result.data; const result = res.data.result;
total.value = res.data.result.total; rows.value = result.data;
totalList.value = Math.ceil( pagination.value = {
res.data.result.total / pagination.value.rowsPerPage ...pagination.value,
); rowsNumber: result.total,
};
}) })
.catch((e) => { .catch((e) => {
messageError($q, e); messageError($q, e);
@ -123,25 +104,53 @@ async function getCommander() {
}); });
} }
function updatePagination(newPagination: any) { /*** ฟังก์ชันสำหรับเปิด Modal และดึงข้อมูลผู้บังคับบัญชา */
pagination.value.rowsPerPage = newPagination.rowsPerPage; function onPerson() {
modal.value = true;
getCommander();
} }
/*** ฟังก์ชันสำหรับปิด Modal และล้างข้อมูล */
function closeDialog() {
modal.value = false;
search.value = "";
rows.value = [];
selected.value = [];
pagination.value = {
sortBy: "createdAt",
descending: true,
page: 1,
rowsPerPage: 10,
rowsNumber: 0,
};
}
/** ฟังก์ชันสำหรับยืนยันการเลือกผู้บังคับบัญชา */
function onSubmit() {
modal.value = false;
dataStore.dear = selected.value[0].firstName
? `${selected.value[0].prefix}${selected.value[0].firstName} ${selected.value[0].lastName}`
: "";
dataStore.commanderPosition = selected.value[0].posExecutiveName;
}
/**
* งกนร request จากตาราง เมอมการเปลยน pagination
* @param requestProps อมลการรองขอจากตาราง
*/
function onTableRequest(requestProps: PropsTable.RequestProps) {
const newPagination = requestProps?.pagination || requestProps;
if (!newPagination?.page || !newPagination?.rowsPerPage) return;
pagination.value = { ...newPagination };
getCommander();
}
/** ฟังก์ชันสำหรับค้นหาข้อมูล*/
function getSearch() { function getSearch() {
pagination.value.page = 1; pagination.value.page = 1;
getCommander(); getCommander();
} }
watch(
() => pagination.value.rowsPerPage,
async () => {
getSearch();
}
);
/**Hook */
onMounted(() => {
});
</script> </script>
<template> <template>
@ -227,15 +236,6 @@ onMounted(() => {
v-model="dataStore.typeLeave" v-model="dataStore.typeLeave"
label="เรื่อง" label="เรื่อง"
/> />
<!-- <q-input
class="col-12 col-sm-4"
dense
outlined
readonly
bg-color="white"
v-model="dataStore.commanderPosition"
label="เรียน"
/> -->
<q-input <q-input
class="col-12 col-sm-4" class="col-12 col-sm-4"
@ -315,7 +315,7 @@ onMounted(() => {
<div class="row q-col-gutter-sm"> <div class="row q-col-gutter-sm">
<div class="col-12"> <div class="col-12">
<div class="row q-col-gutter-md items-start"> <div class="row q-col-gutter-md items-start">
<div class="col-12 col-sm-4 col-md-4"> <div class="col-12 col-sm-6 col-md-4">
<q-input <q-input
v-model="search" v-model="search"
outlined outlined
@ -325,17 +325,20 @@ onMounted(() => {
@keydown.enter.prevent="getSearch()" @keydown.enter.prevent="getSearch()"
/> />
</div> </div>
<q-checkbox <div class="col-12 col-sm-6 col-md-4">
keep-color <q-checkbox
v-model="isAct" keep-color
label="แสดงเฉพาะรักษาการแทน" v-model="isAct"
color="primary" label="แสดงเฉพาะรักษาการแทน"
> color="primary"
<q-tooltip>แสดงเฉพาะรกษาการแทน </q-tooltip> @update:model-value="getSearch()"
</q-checkbox> >
<q-space /> <q-tooltip>แสดงเฉพาะรกษาการแทน </q-tooltip>
</q-checkbox>
</div>
<q-space v-if="$q.screen.gt.sm" />
<div class="col-12 col-sm-6 col-md-3"> <div class="col-12 col-md-3">
<q-btn <q-btn
color="primary" color="primary"
icon="search" icon="search"
@ -349,9 +352,7 @@ onMounted(() => {
</div> </div>
</div> </div>
<div class="col-12"> <div class="col-12">
<SkeletonTable v-if="isLoading" :columns="columns" />
<d-table <d-table
v-else
ref="table" ref="table"
:columns="columns" :columns="columns"
:rows="rows" :rows="rows"
@ -362,25 +363,11 @@ onMounted(() => {
dense dense
:rows-per-page-options="[10, 25, 50, 100]" :rows-per-page-options="[10, 25, 50, 100]"
selection="single" selection="single"
@update:pagination="updatePagination"
v-model:pagination="pagination" v-model:pagination="pagination"
v-model:selected="selected" v-model:selected="selected"
:loading="isLoading"
@request="onTableRequest"
> >
<template v-slot:pagination="scope">
งหมด {{ total }} รายการ
<q-pagination
v-model="pagination.page"
active-color="primary"
color="dark"
:max="Number(totalList)"
size="sm"
boundary-links
direction-links
:max-pages="5"
@update:model-value="getSearch"
></q-pagination>
</template>
<template v-slot:header-selection="scope"> <template v-slot:header-selection="scope">
<q-checkbox <q-checkbox
keep-color keep-color

View file

@ -2,8 +2,8 @@
import { ref, useAttrs, watch } from "vue"; import { ref, useAttrs, watch } from "vue";
import { useQuasar } from "quasar"; import { useQuasar } from "quasar";
import type { PropsTable } from "@/interface/PropsTable";
import { useLeaveStore } from "@/modules/05_leave/store"; import { useLeaveStore } from "@/modules/05_leave/store";
import SkeletonTable from "@/components/SkeletonTable.vue";
const $q = useQuasar(); const $q = useQuasar();
const attrs = ref<any>(useAttrs()); const attrs = ref<any>(useAttrs());
@ -54,13 +54,26 @@ const table = ref<any>(null);
/** ตั้งค่า pagination*/ /** ตั้งค่า pagination*/
const currentPage = ref<number>(1); const currentPage = ref<number>(1);
const pagination = ref({
const pagination = ref<PropsTable.Pagination>({
sortBy: "dateSendLeave", sortBy: "dateSendLeave",
descending: true, descending: true,
page: 1, page: 1,
rowsPerPage: Number(props.pageSize), rowsPerPage: Number(props.pageSize),
rowsNumber: Number(props.total),
}); });
// Watch props pagination ( props)
watch(
() => [props.pageSize, props.total],
([newPageSize, newTotal]) => {
pagination.value.rowsPerPage = Number(newPageSize);
pagination.value.rowsNumber = Number(newTotal);
},
{ immediate: true }
);
/** filter */ /** filter */
const year = ref<number>(new Date().getFullYear()); const year = ref<number>(new Date().getFullYear());
const filter = ref<string>(""); const filter = ref<string>("");
@ -86,18 +99,17 @@ function updatePagination(p: number, ps: number) {
emit("update:Pagination", p, ps); emit("update:Pagination", p, ps);
} }
/** function updatePageSize*/ /**
function updatePageSize(newPageSize: any) { * งกนร request จากตาราง เมอมการเปลยน pagination
pagination.value.rowsPerPage = newPageSize.rowsPerPage; * @param requestProps อมลการรองขอจากตาราง
*/
function onTableRequest(requestProps: PropsTable.RequestProps) {
const newPagination = requestProps?.pagination || requestProps;
if (!newPagination?.page || !newPagination?.rowsPerPage) return;
currentPage.value = newPagination.page;
pagination.value = { ...newPagination };
updatePagination(newPagination.page, newPagination.rowsPerPage);
} }
watch(
() => pagination.value.rowsPerPage,
() => {
currentPage.value = 1;
updatePagination(currentPage.value, pagination.value.rowsPerPage);
}
);
</script> </script>
<template> <template>
@ -240,9 +252,7 @@ watch(
</q-card> </q-card>
</div> </div>
<div> <div>
<SkeletonTable v-if="isloadingData" :columns="leaveStore.columns" />
<d-table <d-table
v-else
ref="table" ref="table"
flat flat
bordered bordered
@ -251,9 +261,11 @@ watch(
:virtual-scroll-sticky-size-start="48" :virtual-scroll-sticky-size-start="48"
dense dense
:rows-per-page-options="[10, 25, 50, 100]" :rows-per-page-options="[10, 25, 50, 100]"
D
v-model:pagination="pagination" v-model:pagination="pagination"
@update:pagination="updatePageSize" @request="onTableRequest"
:grid="$q.screen.gt.xs ? false : true" :grid="$q.screen.gt.xs ? false : true"
:loading="isloadingData"
> >
<template v-slot:header="props"> <template v-slot:header="props">
<q-tr :props="props"> <q-tr :props="props">
@ -262,21 +274,6 @@ watch(
</q-th> </q-th>
</q-tr> </q-tr>
</template> </template>
<template v-slot:pagination="scope">
งหมด {{ props.total }} รายการ
<q-pagination
v-model="currentPage"
active-color="primary"
color="dark"
:max="Number(props.maxPage)"
size="sm"
boundary-links
direction-links
@update:model-value="
updatePagination(currentPage, pagination.rowsPerPage)
"
></q-pagination>
</template>
<template #body="props"> <template #body="props">
<slot v-bind="props" name="columns"></slot> <slot v-bind="props" name="columns"></slot>
</template> </template>

View file

@ -0,0 +1,34 @@
interface DataCommander {
actFullName: string;
actFullNameId: string;
actFullNameKeycloakId: string;
citizenId: string;
firstName: string;
id: string;
isDeputy: number;
isDirector: number;
isOfficer: boolean;
key: string;
keycloakId: string;
lastName: string;
orgChild1: string;
orgChild1Id: string;
orgChild2: string;
orgChild2Id: string;
orgChild3: string;
orgChild3Id: string;
orgChild4: string;
orgChild4Id: string;
orgRevisionId: string;
orgRoot: string;
orgRootId: string;
posExecutiveName: string;
posExecutiveNameOrg: string;
posLevel: string;
posNo: string;
posType: string;
position: string;
prefix: string;
}
export type { DataCommander };

View file

@ -459,7 +459,6 @@ onMounted(() => {
<q-skeleton <q-skeleton
v-if="isLoadingFile['fileEvaluation1']" v-if="isLoadingFile['fileEvaluation1']"
height="120px" height="120px"
type="QCard"
/> />
<q-card v-else bordered> <q-card v-else bordered>
<div <div
@ -552,7 +551,6 @@ onMounted(() => {
<q-skeleton <q-skeleton
v-if="isLoadingFile['fileEvaluation2']" v-if="isLoadingFile['fileEvaluation2']"
height="120px" height="120px"
type="QCard"
/> />
<q-card v-else bordered> <q-card v-else bordered>
<div <div
@ -645,7 +643,6 @@ onMounted(() => {
<q-skeleton <q-skeleton
v-if="isLoadingFile['fileEvaluation3']" v-if="isLoadingFile['fileEvaluation3']"
height="120px" height="120px"
type="QCard"
/> />
<q-card v-else bordered> <q-card v-else bordered>
<div <div
@ -738,7 +735,6 @@ onMounted(() => {
<q-skeleton <q-skeleton
v-if="isLoadingFile['fileEvaluation5']" v-if="isLoadingFile['fileEvaluation5']"
height="120px" height="120px"
type="QCard"
/> />
<q-card v-else bordered> <q-card v-else bordered>
<div <div
@ -830,7 +826,6 @@ onMounted(() => {
<q-skeleton <q-skeleton
v-if="isLoadingFile['fileEvaluation4']" v-if="isLoadingFile['fileEvaluation4']"
height="120px" height="120px"
type="QCard"
/> />
<q-card v-else bordered> <q-card v-else bordered>
<div <div
@ -921,7 +916,6 @@ onMounted(() => {
<q-skeleton <q-skeleton
v-if="isLoadingFile['fileEvaluation6']" v-if="isLoadingFile['fileEvaluation6']"
height="120px" height="120px"
type="QCard"
/> />
<q-card v-else bordered> <q-card v-else bordered>
<div <div

View file

@ -99,12 +99,7 @@ watch(modal, (v) => {
<q-separator /> <q-separator />
<q-card-section> <q-card-section>
<div class="row q-col-gutter-sm q-pb-sm"> <div class="row q-col-gutter-sm q-pb-sm">
<q-skeleton <q-skeleton v-if="isLoading" width="100%" height="240px" />
v-if="isLoading"
type="Qcard"
width="100%"
height="240px"
/>
<div <div
v-else v-else

View file

@ -1,47 +1,35 @@
<script setup lang="ts"> <script setup lang="ts">
import { ref, onMounted, watch } from "vue"; import { ref, onMounted } from "vue";
import { useRouter } from "vue-router"; import { useRouter } from "vue-router";
import { useQuasar } from "quasar"; import { useQuasar } from "quasar";
import type { PropsTable } from "@/interface/PropsTable";
import type { QTableProps } from "quasar"; import type { QTableProps } from "quasar";
import config from "@/app.config"; import config from "@/app.config";
import http from "@/plugins/http"; import http from "@/plugins/http";
import { useEvaluateStore } from "@/modules/06_evaluate/store"; import { useEvaluateStore } from "@/modules/06_evaluate/store";
import { useCounterMixin } from "@/stores/mixin"; import { useCounterMixin } from "@/stores/mixin";
import SkeletonTable from "@/components/SkeletonTable.vue";
/** use*/ /** use*/
const $q = useQuasar(); const $q = useQuasar();
const store = useEvaluateStore(); const store = useEvaluateStore();
const mixin = useCounterMixin(); const mixin = useCounterMixin();
const router = useRouter(); const router = useRouter();
const total = defineModel<number>("total", { required: true });
const totalList = defineModel<number>("totalList", { required: true });
const pagination = defineModel<any>("pagination", { required: true });
const { dialogRemove, showLoader, hideLoader, success, messageError } = mixin; const { dialogRemove, showLoader, hideLoader, success, messageError } = mixin;
const isLoading = defineModel<boolean>("isLoading", {
default: false,
});
const pagination = defineModel<PropsTable.Pagination>("pagination", {
required: true,
});
const props = defineProps({ const props = defineProps({
page: {
type: Number,
require: true,
},
pageSize: {
type: Number,
require: true,
},
maxPage: {
type: Number,
require: true,
},
fetchData: { fetchData: {
type: Function, type: Function,
require: true, require: true,
}, },
isLoading: {
type: Boolean,
default: false,
},
}); });
const emit = defineEmits(["update:pagination"]); const emit = defineEmits(["update:pagination"]);
@ -87,25 +75,11 @@ const columns = ref<QTableProps["columns"]>([
}, },
]); ]);
/**
* function งขอมลไป Update Paging
* @param newPagination อม Paging ใหม
* @param page หน
*/
function updateProp(newPagination: any, page: number) {
emit("update:pagination", newPagination, page);
}
function updatePagination(newPagination: any) {
pagination.value.page = 1;
pagination.value.rowsPerPage = newPagination.rowsPerPage;
}
/** /**
* function ลบรายการประเม * function ลบรายการประเม
* @param id รายการประเม * @param id รายการประเม
*/ */
async function onCkilckDelete(id: string) { async function onClickDelete(id: string) {
dialogRemove($q, async () => { dialogRemove($q, async () => {
showLoader(); showLoader();
await http await http
@ -132,6 +106,17 @@ function redirectToDetail(data: any) {
router.push(`/evaluate/detail/${data.typeparam.toLowerCase()}/${data.id}`); router.push(`/evaluate/detail/${data.typeparam.toLowerCase()}/${data.id}`);
} }
/**
* งกนร request จากตาราง เมอมการเปลยน pagination
* @param requestProps อมลการรองขอจากตาราง
*/
function onTableRequest(requestProps: PropsTable.RequestProps) {
const newPagination = requestProps?.pagination || requestProps;
if (!newPagination?.page || !newPagination?.rowsPerPage) return;
pagination.value = { ...newPagination };
props.fetchData?.();
}
/** Hook lifecycle*/ /** Hook lifecycle*/
onMounted(() => { onMounted(() => {
store.columns = columns.value; store.columns = columns.value;
@ -140,20 +125,19 @@ onMounted(() => {
</script> </script>
<template> <template>
<SkeletonTable v-if="isLoading" :columns="columns" />
<d-table <d-table
v-else
ref="table" ref="table"
flat flat
bordered bordere
class="custom-header-table"
:columns="columns" :columns="columns"
:rows="store.row" :rows="store.row"
dense dense
:visible-columns="store.visibleColumns" :visible-columns="store.visibleColumns"
:rows-per-page-options="[10, 25, 50, 100]" :rows-per-page-options="[10, 25, 50, 100]"
@update:pagination="updatePagination" @request="onTableRequest"
v-model:pagination="pagination" v-model:pagination="pagination"
:loading="isLoading"
row-key="id"
> >
<template v-slot:header="props"> <template v-slot:header="props">
<q-tr :props="props"> <q-tr :props="props">
@ -190,7 +174,7 @@ onMounted(() => {
round round
color="red" color="red"
icon="delete" icon="delete"
@click.stop="onCkilckDelete(props.row.id)" @click.stop="onClickDelete(props.row.id)"
> >
<q-tooltip>ลบ</q-tooltip> <q-tooltip>ลบ</q-tooltip>
</q-btn> </q-btn>
@ -235,7 +219,7 @@ onMounted(() => {
round round
color="red" color="red"
icon="delete" icon="delete"
@click.stop="onCkilckDelete(props.row.id)" @click.stop="onClickDelete(props.row.id)"
> >
<q-tooltip>ลบ</q-tooltip> <q-tooltip>ลบ</q-tooltip>
</q-btn> </q-btn>
@ -243,48 +227,7 @@ onMounted(() => {
</q-card> </q-card>
</div> </div>
</template> </template>
<template v-slot:pagination="scope">
งหมด {{ total }} รายการ
<q-pagination
v-model="pagination.page"
active-color="primary"
color="dark"
:max="Number(totalList)"
size="sm"
boundary-links
direction-links
:max-pages="5"
@update:model-value="props.fetchData?.()"
></q-pagination>
</template>
</d-table> </d-table>
</template> </template>
<style lang="scss" scoped> <style lang="scss" scoped></style>
.custom-header-table {
height: auto;
.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

@ -90,13 +90,7 @@ onMounted(() => {
</script> </script>
<template> <template>
<q-skeleton <q-skeleton v-if="isLoading" class="q-mb-md" width="100%" height="100%" />
v-if="isLoading"
class="q-mb-md"
type="Qcard"
width="100%"
height="100%"
/>
<div class="q-pa-sm" v-else> <div class="q-pa-sm" v-else>
<q-list dense> <q-list dense>
<q-item v-ripple class="listItem"> <q-item v-ripple class="listItem">

View file

@ -349,7 +349,7 @@ onMounted(async () => {
<div class="col-12 q-pa-sm"> <div class="col-12 q-pa-sm">
<!-- ผลงาน --> <!-- ผลงาน -->
<div class="col-12"> <div class="col-12">
<q-skeleton type="Qcard" height="100px" v-if="isLoading" class="q-mb-sm" /> <q-skeleton height="100px" v-if="isLoading" class="q-mb-sm" />
<q-card v-else bordered class="cardSp1 col-12"> <q-card v-else bordered class="cardSp1 col-12">
<div class="text-weight-medium bg-grey-1 col-12 q-py-sm q-px-md"> <div class="text-weight-medium bg-grey-1 col-12 q-py-sm q-px-md">
ผลงาน ผลงาน
@ -425,7 +425,7 @@ onMounted(async () => {
<!-- เลอกผเซนเอกสาร --> <!-- เลอกผเซนเอกสาร -->
<div class="col-12"> <div class="col-12">
<q-skeleton type="Qcard" height="200px" v-if="isLoading" /> <q-skeleton height="200px" v-if="isLoading" />
<q-card v-else bordered class="cardSp1 col-12"> <q-card v-else bordered class="cardSp1 col-12">
<div class="text-weight-medium bg-grey-1 q-py-sm q-px-md"> <div class="text-weight-medium bg-grey-1 q-py-sm q-px-md">
เลอกผเซนเอกสาร เลอกผเซนเอกสาร
@ -584,7 +584,7 @@ onMounted(async () => {
v-for="(item, index) in formTemplates" v-for="(item, index) in formTemplates"
:key="index" :key="index"
> >
<q-skeleton type="Qcard" height="100px" v-if="item.isLoading" /> <q-skeleton height="100px" v-if="item.isLoading" />
<q-card bordered class="cardSp1" v-else> <q-card bordered class="cardSp1" v-else>
<div <div

View file

@ -235,7 +235,6 @@ onMounted(async () => {
<div class="row q-col-gutter-sm q-pa-sm"> <div class="row q-col-gutter-sm q-pa-sm">
<div class="col-6" v-for="(item, index) in formTemplates" :key="index"> <div class="col-6" v-for="(item, index) in formTemplates" :key="index">
<q-skeleton <q-skeleton
type="Qcard"
:height="store.currentStep !== 4 ? '50px' : '100px'" :height="store.currentStep !== 4 ? '50px' : '100px'"
v-if="item.isLoading" v-if="item.isLoading"
/> />

View file

@ -96,11 +96,7 @@ onMounted(async () => {
<template> <template>
<div class="row col-12 q-pa-sm"> <div class="row col-12 q-pa-sm">
<q-skeleton <q-skeleton v-if="isLoading" style="width: 100%; height: 300px" />
v-if="isLoading"
type="Qcard"
style="width: 100%; height: 300px"
/>
<div v-else class="row col-12 q-col-gutter-sm"> <div v-else class="row col-12 q-col-gutter-sm">
<div class="col-12 text-center"> <div class="col-12 text-center">
<q-banner rounded class="text-weight-bold text-red-14 bg-red-1"> <q-banner rounded class="text-weight-bold text-red-14 bg-red-1">

View file

@ -251,7 +251,7 @@ onMounted(async () => {
<div class="row col-12 q-pa-sm"> <div class="row col-12 q-pa-sm">
<div class="row col-12 q-col-gutter-sm"> <div class="row col-12 q-col-gutter-sm">
<div class="col-12 text-center"> <div class="col-12 text-center">
<q-skeleton v-if="isLoadingDate" type="Qcard" height="50px" /> <q-skeleton v-if="isLoadingDate" height="50px" />
<q-banner v-else rounded class="text-weight-bold text-red-14 bg-red-1"> <q-banner v-else rounded class="text-weight-bold text-red-14 bg-red-1">
<div class="text-weight-bold"> <div class="text-weight-bold">
<q-icon name="info_outline" color="red-14" size="24px" /> <q-icon name="info_outline" color="red-14" size="24px" />
@ -262,7 +262,7 @@ onMounted(async () => {
<!-- ผลงาน --> <!-- ผลงาน -->
<div class="col-12"> <div class="col-12">
<q-skeleton v-if="isLoading" type="Qcard" height="200px" width="100%" /> <q-skeleton v-if="isLoading" height="200px" width="100%" />
<q-card <q-card
v-else v-else
@ -373,7 +373,7 @@ onMounted(async () => {
<!-- เลอกผเซนเอกสาร --> <!-- เลอกผเซนเอกสาร -->
<div class="col-12"> <div class="col-12">
<q-skeleton v-if="isLoading" type="Qcard" height="200px" width="100%" /> <q-skeleton v-if="isLoading" height="200px" width="100%" />
<q-card <q-card
v-else v-else
bordered bordered
@ -548,7 +548,7 @@ onMounted(async () => {
<!-- ปไฟล --> <!-- ปไฟล -->
<div class="col-12" v-if="store.currentStep === 6"> <div class="col-12" v-if="store.currentStep === 6">
<q-skeleton type="Qcard" height="100px" v-if="isLoadingFile" /> <q-skeleton height="100px" v-if="isLoadingFile" />
<q-card <q-card
v-else v-else
bordered bordered

View file

@ -181,7 +181,6 @@ onMounted(async () => {
" "
> >
<q-skeleton <q-skeleton
type="Qcard"
:height="store.currentStep !== 8 ? '50px' : '100px'" :height="store.currentStep !== 8 ? '50px' : '100px'"
v-if="isLoadingFile" v-if="isLoadingFile"
/> />

View file

@ -9,12 +9,11 @@ import config from "@/app.config";
import { useCounterMixin } from "@/stores/mixin"; import { useCounterMixin } from "@/stores/mixin";
import HeaderDialog from "@/components/DialogHeader.vue"; import HeaderDialog from "@/components/DialogHeader.vue";
import SkeletonTable from "@/components/SkeletonTable.vue";
const $q = useQuasar(); const $q = useQuasar();
const route = useRoute(); const route = useRoute();
const mixins = useCounterMixin(); const mixins = useCounterMixin();
const { showLoader, hideLoader, date2Thai, messageError } = mixins; const { date2Thai, messageError } = mixins;
const isLoading = ref<boolean>(false); const isLoading = ref<boolean>(false);
@ -127,9 +126,7 @@ watch(
<q-card-section> <q-card-section>
<div class="col-xs-12 col-sm-12 col-md-12 row q-col-gutter-md"> <div class="col-xs-12 col-sm-12 col-md-12 row q-col-gutter-md">
<div class="col-12"> <div class="col-12">
<SkeletonTable v-if="isLoading" :columns="columns" />
<d-table <d-table
v-else
ref="table" ref="table"
flat flat
bordered bordered
@ -138,6 +135,8 @@ watch(
:rows="row" :rows="row"
dense dense
:rows-per-page-options="[10, 25, 50, 100]" :rows-per-page-options="[10, 25, 50, 100]"
:pagination="{ page: 1, rowsPerPage: 10 }"
:loading="isLoading"
> >
<template v-slot:header="props"> <template v-slot:header="props">
<q-tr :props="props"> <q-tr :props="props">

View file

@ -1,6 +1,4 @@
<script setup lang="ts"> <script setup lang="ts">
import SkeletonTable from "@/components/SkeletonTable.vue";
const props = defineProps({ const props = defineProps({
columns: { columns: {
type: Array as () => any[], type: Array as () => any[],
@ -19,9 +17,7 @@ const props = defineProps({
<template> <template>
<div class="q-pa-sm row col-12"> <div class="q-pa-sm row col-12">
<SkeletonTable class="col-12" v-if="isLoading" :columns="props.columns" />
<d-table <d-table
v-else
ref="table" ref="table"
flat flat
bordered bordered
@ -32,6 +28,9 @@ const props = defineProps({
virtual-scroll virtual-scroll
class="row col-12" class="row col-12"
:style="$q.screen.lt.sm ? 'width: 80vw' : 'width: 50vw;'" :style="$q.screen.lt.sm ? 'width: 80vw' : 'width: 50vw;'"
:pagination="{ page: 1, rowsPerPage: 10 }"
:loading="isLoading"
row-key="id"
> >
<template v-slot:header="props"> <template v-slot:header="props">
<q-tr :props="props" class="bg-grey-2"> <q-tr :props="props" class="bg-grey-2">
@ -54,30 +53,4 @@ const props = defineProps({
</div> </div>
</template> </template>
<style lang="scss" scoped> <style lang="scss" scoped></style>
.custom-header-table {
height: auto;
.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;
}
/* 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

@ -2,7 +2,7 @@ div
<script setup lang="ts"> <script setup lang="ts">
import { reactive, onMounted, ref } from "vue"; import { reactive, onMounted, ref } from "vue";
import { useRoute } from "vue-router"; import { useRoute } from "vue-router";
import { is, useQuasar } from "quasar"; import { useQuasar } from "quasar";
import http from "@/plugins/http"; import http from "@/plugins/http";
import config from "@/app.config"; import config from "@/app.config";
@ -21,7 +21,6 @@ import type {
/** importComponents*/ /** importComponents*/
import TableData from "@/modules/06_evaluate/components/viewstep/tableStep1.vue"; import TableData from "@/modules/06_evaluate/components/viewstep/tableStep1.vue";
import HeaderDialog from "@/components/DialogHeader.vue"; import HeaderDialog from "@/components/DialogHeader.vue";
import SkeletonTable from "@/components/SkeletonTable.vue";
/** use*/ /** use*/
const mixin = useCounterMixin(); const mixin = useCounterMixin();
@ -410,7 +409,7 @@ onMounted(async () => {
> >
<div class="row col-12"> <div class="row col-12">
<div class="col-12" v-if="isLoading.loadDetail"> <div class="col-12" v-if="isLoading.loadDetail">
<q-skeleton type="Qcard" height="200px" class="q-mb-md" /> <q-skeleton height="200px" class="q-mb-md" />
</div> </div>
<q-card v-else class="col-12 cardSp1" bordered> <q-card v-else class="col-12 cardSp1" bordered>
<div class="text-weight-bold row items-center bg-grey-2 col-12"> <div class="text-weight-bold row items-center bg-grey-2 col-12">
@ -516,7 +515,7 @@ onMounted(async () => {
</q-card> </q-card>
<div class="col-12" v-if="isLoading.loadEducation"> <div class="col-12" v-if="isLoading.loadEducation">
<q-skeleton type="Qcard" height="200px" class="q-mb-md" /> <q-skeleton height="200px" class="q-mb-md" />
</div> </div>
<q-card v-else class="col-12 cardSp1" bordered> <q-card v-else class="col-12 cardSp1" bordered>
<div class="text-weight-bold row items-center bg-grey-2 col-12"> <div class="text-weight-bold row items-center bg-grey-2 col-12">
@ -668,14 +667,8 @@ onMounted(async () => {
<span class="q-ml-lg q-my-sm">ประวการรบราชการ</span> <span class="q-ml-lg q-my-sm">ประวการรบราชการ</span>
</div> </div>
<div class="col-12"><q-separator /></div> <div class="col-12"><q-separator /></div>
<div class="col-10 q-pa-sm">
<div class="col-10">
<SkeletonTable
v-if="isLoading.loadSalary"
:columns="columnSalaries"
/>
<d-table <d-table
v-else
ref="table" ref="table"
row-key="id" row-key="id"
flat flat
@ -685,6 +678,8 @@ onMounted(async () => {
:rows="formDetail.salaries" :rows="formDetail.salaries"
:paging="true" :paging="true"
:rows-per-page-options="[20, 50, 100]" :rows-per-page-options="[20, 50, 100]"
:pagination="{ page: 1, rowsPerPage: 20 }"
:loading="isLoading.loadSalary"
> >
<template v-slot:header="props"> <template v-slot:header="props">
<q-tr :props="props"> <q-tr :props="props">
@ -768,13 +763,7 @@ onMounted(async () => {
<div class="col-12"><q-separator /></div> <div class="col-12"><q-separator /></div>
<div class="col-10"> <div class="col-10">
<div class="q-pa-sm row col-12"> <div class="q-pa-sm row col-12">
<SkeletonTable
v-if="isLoading.loadExperience"
:columns="columnAssessments"
class="col-12"
/>
<d-table <d-table
v-else
flat flat
bordered bordered
:columns="columnAssessments" :columns="columnAssessments"
@ -784,6 +773,8 @@ onMounted(async () => {
virtual-scroll virtual-scroll
class="row col-12" class="row col-12"
:style="$q.screen.lt.sm ? 'width: 80vw' : 'width: 50vw;'" :style="$q.screen.lt.sm ? 'width: 80vw' : 'width: 50vw;'"
:pagination="{ page: 1, rowsPerPage: 20 }"
:loading="isLoading.loadExperience"
> >
<template v-slot:header="props"> <template v-slot:header="props">
<q-tr :props="props" class="bg-grey-2"> <q-tr :props="props" class="bg-grey-2">

View file

@ -14,6 +14,7 @@ import TableListEvaluate from "@/modules/06_evaluate/components/TableListEvaluat
import DialogMain from "@/modules/06_evaluate/components/DialogMain.vue"; // popup import DialogMain from "@/modules/06_evaluate/components/DialogMain.vue"; // popup
/** import Type*/ /** import Type*/
import type { PropsTable } from "@/interface/PropsTable";
import type { ListMenu } from "@/modules/06_evaluate/interface/evalute"; import type { ListMenu } from "@/modules/06_evaluate/interface/evalute";
import type { OptionStatus } from "@/modules/06_evaluate/interface/main"; import type { OptionStatus } from "@/modules/06_evaluate/interface/main";
@ -50,13 +51,12 @@ const listMenu = ref<ListMenu[]>([
}, },
]); ]);
const total = ref<number>(0); const pagination = ref<PropsTable.Pagination>({
const totalList = ref<number>(1);
const pagination = ref({
sortBy: "createdAt", sortBy: "createdAt",
descending: true, descending: true,
page: 1, page: 1,
rowsPerPage: 10, rowsPerPage: 10,
rowsNumber: 0,
}); });
/** /**
@ -85,11 +85,9 @@ async function fetchEvaluteList() {
await http await http
.put(config.API.evaluationList(), body) .put(config.API.evaluationList(), body)
.then(async (res) => { .then(async (res) => {
totalList.value = Math.ceil( const result = res.data.result;
res.data.result.total / pagination.value.rowsPerPage pagination.value.rowsNumber = result.total;
); store.fetchEvaluateList(result.data);
total.value = res.data.result.total;
store.fetchEvaluateList(res.data.result.data);
}) })
.catch((err) => { .catch((err) => {
messageError($q, err); messageError($q, err);
@ -193,13 +191,6 @@ function getSearch() {
fetchEvaluteList(); fetchEvaluteList();
} }
watch(
() => pagination.value.rowsPerPage,
async () => {
getSearch();
}
);
/** hook lifecycle*/ /** hook lifecycle*/
onMounted(async () => { onMounted(async () => {
await fetchEvaluteList(); await fetchEvaluteList();
@ -325,10 +316,8 @@ onMounted(async () => {
<div class="col-12"> <div class="col-12">
<TableListEvaluate <TableListEvaluate
:fetchData="fetchEvaluteList" :fetchData="fetchEvaluteList"
v-model:total="total"
v-model:total-list="totalList"
v-model:pagination="pagination" v-model:pagination="pagination"
:isLoading="isLoading" v-model:isLoading="isLoading"
/> />
</div> </div>
</q-card> </q-card>

View file

@ -10,16 +10,15 @@ import config from "@/app.config";
import { useCounterMixin } from "@/stores/mixin"; import { useCounterMixin } from "@/stores/mixin";
import { useAppealComplainStore } from "@/modules/07_appealComplain/store"; import { useAppealComplainStore } from "@/modules/07_appealComplain/store";
import type { PropsTable } from "@/interface/PropsTable";
import type { FormType } from "@/modules/07_appealComplain/interface/response/mainType"; import type { FormType } from "@/modules/07_appealComplain/interface/response/mainType";
import type { DataOption } from "@/modules/07_appealComplain/interface/index/main"; import type { DataOption } from "@/modules/07_appealComplain/interface/index/main";
import SkeletonTable from "@/components/SkeletonTable.vue";
const $q = useQuasar(); const $q = useQuasar();
const router = useRouter(); const router = useRouter();
const mixin = useCounterMixin(); const mixin = useCounterMixin();
const dataStore = useAppealComplainStore(); const dataStore = useAppealComplainStore();
const { messageError, showLoader, hideLoader } = mixin; const { messageError } = mixin;
const filterKeyword = ref<string>(""); const filterKeyword = ref<string>("");
const type = ref<DataOption[]>([ const type = ref<DataOption[]>([
@ -28,25 +27,18 @@ const type = ref<DataOption[]>([
]); ]);
const isload = ref<boolean>(false); const isload = ref<boolean>(false);
const total = ref<number>(0); const pagination = ref<PropsTable.Pagination>({
const totalList = ref<number>(1);
const pagination = ref({
sortBy: "createdAt", sortBy: "createdAt",
descending: true, descending: true,
page: 1, page: 1,
rowsPerPage: 10, rowsPerPage: 10,
rowsNumber: 0,
}); });
/**
* เพมหวขอตาราง
*/
const formData = reactive<FormType>({ const formData = reactive<FormType>({
type: "ALL", type: "ALL",
status: "ALL", status: "ALL",
year: new Date().getFullYear(), year: new Date().getFullYear(),
}); });
const visibleColumns = ref<string[]>([ const visibleColumns = ref<string[]>([
"no", "no",
"title", "title",
@ -59,7 +51,6 @@ const visibleColumns = ref<string[]>([
"lastUpdatedAt", "lastUpdatedAt",
"status", "status",
]); ]);
const columns = ref<QTableProps["columns"]>([ const columns = ref<QTableProps["columns"]>([
{ {
name: "no", name: "no",
@ -170,19 +161,16 @@ async function getData() {
) )
) )
.then(async (res) => { .then(async (res) => {
totalList.value = Math.ceil( const result = res.data.result;
res.data.result.total / pagination.value.rowsPerPage pagination.value.rowsNumber = result.total;
); dataStore.fetchAppealComplain(result.data);
total.value = res.data.result.total;
let data = res.data.result.data;
await dataStore.fetchAppealComplain(data);
isload.value = false;
}) })
.catch((e: any) => { .catch((e: any) => {
messageError($q, e); messageError($q, e);
isload.value = false;
}) })
.finally(() => {}); .finally(() => {
isload.value = false;
});
} }
/** /**
@ -214,22 +202,21 @@ function redirectToPageadd() {
router.push(`/appeal-complain/add`); router.push(`/appeal-complain/add`);
} }
function updatePagination(newPagination: any) {
pagination.value.page = 1;
pagination.value.rowsPerPage = newPagination.rowsPerPage;
}
function getSearch() { function getSearch() {
pagination.value.page = 1; pagination.value.page = 1;
getData(); getData();
} }
watch( /**
() => pagination.value.rowsPerPage, * งกนร request จากตาราง เมอมการเปลยน pagination
async () => { * @param requestProps อมลการรองขอจากตาราง
getSearch(); */
} function onTableRequest(requestProps: PropsTable.RequestProps) {
); const newPagination = requestProps?.pagination || requestProps;
if (!newPagination?.page || !newPagination?.rowsPerPage) return;
pagination.value = { ...newPagination };
getData();
}
/** /**
* เรยกฟงกนทงหมดตอนเรยกใชไฟล * เรยกฟงกนทงหมดตอนเรยกใชไฟล
@ -241,6 +228,7 @@ onMounted(async () => {
await getData(); await getData();
}); });
</script> </script>
<template> <template>
<div class="col-12 row justify-center"> <div class="col-12 row justify-center">
<div class="col-xs-12 col-sm-12 col-md-11"> <div class="col-xs-12 col-sm-12 col-md-11">
@ -377,36 +365,18 @@ onMounted(async () => {
/> />
<div class="col-12"> <div class="col-12">
<SkeletonTable v-if="isload" :columns="dataStore.columns" />
<d-table <d-table
v-else
flat flat
bordered bordered
dense dense
class="custom-table2"
style="max-height: 80vh"
:rows="dataStore.rows" :rows="dataStore.rows"
:columns="dataStore.columns" :columns="dataStore.columns"
:visible-columns="dataStore.visibleColumns" :visible-columns="dataStore.visibleColumns"
:rows-per-page-options="[10, 25, 50, 100]" :rows-per-page-options="[10, 25, 50, 100]"
@update:pagination="updatePagination" @request="onTableRequest"
v-model:pagination="pagination" v-model:pagination="pagination"
:loading="isload"
> >
<template v-slot:pagination="scope">
งหมด {{ total }} รายการ
<q-pagination
v-model="pagination.page"
active-color="primary"
color="dark"
:max="Number(totalList)"
size="sm"
boundary-links
direction-links
:max-pages="5"
@update:model-value="getData()"
></q-pagination>
</template>
<template v-slot:header="props"> <template v-slot:header="props">
<q-tr :props="props"> <q-tr :props="props">
<q-th <q-th
@ -425,7 +395,7 @@ onMounted(async () => {
v-for="col in props.cols" v-for="col in props.cols"
:key="col.name" :key="col.name"
:props="props" :props="props"
@click="editPage(props.row.id)" @click.stop.prevent="editPage(props.row.id)"
> >
<div v-if="col.name == 'no'"> <div v-if="col.name == 'no'">
{{ {{
@ -445,7 +415,7 @@ onMounted(async () => {
<template #item="props"> <template #item="props">
<div class="q-pa-xs col-xs-12 col-sm-6 col-md-4 col-lg-3"> <div class="q-pa-xs col-xs-12 col-sm-6 col-md-4 col-lg-3">
<q-card bordered flat> <q-card bordered flat>
<q-list @click="editPage(props.row.id)"> <q-list @click.stop.prevent="editPage(props.row.id)">
<q-item v-for="col in props.cols" :key="col.name"> <q-item v-for="col in props.cols" :key="col.name">
<q-item-section> <q-item-section>
<q-item-label caption>{{ col.label }}</q-item-label> <q-item-label caption>{{ col.label }}</q-item-label>
@ -469,49 +439,5 @@ onMounted(async () => {
</div> </div>
</div> </div>
</template> </template>
<style lang="scss">
.icon-color {
color: #4154b3;
}
.custom-table2 { <style lang="scss"></style>
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;
}
.q-table td:nth-of-type(2) {
z-index: 3 !important;
}
.q-table th:nth-of-type(2),
.q-table td:nth-of-type(2) {
position: sticky;
left: 0;
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

@ -1,18 +1,17 @@
<script setup lang="ts"> <script setup lang="ts">
import { ref } from "vue"; import { ref, watch } from "vue";
import { useRouter } from "vue-router"; import { useRouter } from "vue-router";
import type { QTableProps } from "quasar"; import type { QTableProps } from "quasar";
import { useKpiDataStore } from "@/modules/08_KPI/store"; import { useKpiDataStore } from "@/modules/08_KPI/store";
import type { PropsTable } from "@/interface/PropsTable";
import type { ResEvaluatorAssessor } from "@/modules/08_KPI/interface/response/index"; import type { ResEvaluatorAssessor } from "@/modules/08_KPI/interface/response/index";
import type { FormQuery } from "@/modules/08_KPI/interface/request/index"; import type { FormQuery } from "@/modules/08_KPI/interface/request/index";
import SkeletonTable from "@/components/SkeletonTable.vue";
const store = useKpiDataStore(); const store = useKpiDataStore();
const router = useRouter(); const router = useRouter();
const isLoad = defineModel<boolean>('isLoad',{required:true}) const isLoad = defineModel<boolean>("isLoad", { required: true });
const visibleColumns = defineModel<string[]>("visibleColumns", { const visibleColumns = defineModel<string[]>("visibleColumns", {
required: true, required: true,
}); });
@ -22,30 +21,53 @@ const columns = defineModel<QTableProps["columns"]>("columns", {
const rows = defineModel<ResEvaluatorAssessor[]>("rows", { required: true }); const rows = defineModel<ResEvaluatorAssessor[]>("rows", { required: true });
const formQuery = defineModel<FormQuery>("formQuery", { required: true }); const formQuery = defineModel<FormQuery>("formQuery", { required: true });
const total = defineModel<number>("total", { required: true }); const total = defineModel<number>("total", { required: true });
const maxPage = defineModel<number>("maxPage", { required: true });
const props = defineProps({ const props = defineProps({
updatePagination: { type: Function },
fetchList: { type: Function }, fetchList: { type: Function },
}); });
const pagination = ref({ const pagination = ref<PropsTable.Pagination>({
sortBy: "desc", sortBy: "desc",
descending: false, descending: false,
page: 1, page: formQuery.value.page,
rowsPerPage: 10, rowsPerPage: formQuery.value.pageSize,
rowsNumber: total.value,
}); });
async function redirectViewDetail(id: string) { async function redirectViewDetail(id: string) {
store.tabMain = await ""; store.tabMain = "";
router.push(`/KPI-evaluator/${id}`); router.push(`/KPI-evaluator/${id}`);
} }
/**
* งกนร request จากตาราง เมอมการเปลยน pagination
* @param requestProps อมลการรองขอจากตาราง
*/
function onTableRequest(requestProps: PropsTable.RequestProps) {
const newPagination = requestProps?.pagination || requestProps;
if (!newPagination?.page || !newPagination?.rowsPerPage) return;
formQuery.value.page = newPagination.page;
formQuery.value.pageSize = newPagination.rowsPerPage;
props?.fetchList?.();
}
watch(
[
() => formQuery.value.page,
() => formQuery.value.pageSize,
() => total.value,
],
([page, pageSize, total]) => {
pagination.value.page = page;
pagination.value.rowsPerPage = pageSize;
pagination.value.rowsNumber = total;
}
);
</script> </script>
<template> <template>
<div class="col-12"> <div class="col-12">
<d-table <d-table
v-if="!isLoad"
ref="table" ref="table"
:columns="columns" :columns="columns"
:rows="rows" :rows="rows"
@ -54,11 +76,11 @@ async function redirectViewDetail(id: string) {
bordered bordered
:paging="true" :paging="true"
dense dense
class="custom-table2" :rows-per-page-options="[1, 10, 25, 50, 100]"
:rows-per-page-options="[10, 25, 50, 100]"
:visible-columns="visibleColumns" :visible-columns="visibleColumns"
v-model:pagination="pagination" v-model:pagination="pagination"
@update:pagination="props.updatePagination" @request="onTableRequest"
:loading="isLoad"
> >
<template v-slot:header="props"> <template v-slot:header="props">
<q-tr :props="props"> <q-tr :props="props">
@ -109,22 +131,7 @@ async function redirectViewDetail(id: string) {
</q-card> </q-card>
</div> </div>
</template> </template>
<template v-slot:pagination="scope">
งหมด {{ total }} รายการ
<q-pagination
v-model="formQuery.page"
active-color="primary"
color="dark"
:max="Number(maxPage)"
size="sm"
boundary-links
direction-links
:max-pages="5"
@update:model-value="props.fetchList?.()"
></q-pagination>
</template>
</d-table> </d-table>
<SkeletonTable v-else :columns="columns"/>
</div> </div>
</template> </template>

View file

@ -1,6 +1,6 @@
<script setup lang="ts"> <script setup lang="ts">
import { ref } from "vue"; import { ref, watch } from "vue";
import { useQuasar } from "quasar"; import { Loading, useQuasar } from "quasar";
import { useRouter } from "vue-router"; import { useRouter } from "vue-router";
import type { QTableProps } from "quasar"; import type { QTableProps } from "quasar";
@ -9,11 +9,10 @@ import http from "@/plugins/http";
import { useCounterMixin } from "@/stores/mixin"; import { useCounterMixin } from "@/stores/mixin";
import { useKpiDataStore } from "@/modules/08_KPI/store"; import { useKpiDataStore } from "@/modules/08_KPI/store";
import type { PropsTable } from "@/interface/PropsTable";
import type { FormQuery } from "@/modules/08_KPI/interface/request/index"; import type { FormQuery } from "@/modules/08_KPI/interface/request/index";
import type { ResEvaluatorAssessor } from "@/modules/08_KPI/interface/response/index"; import type { ResEvaluatorAssessor } from "@/modules/08_KPI/interface/response/index";
import SkeletonTable from "@/components/SkeletonTable.vue";
const $q = useQuasar(); const $q = useQuasar();
const router = useRouter(); const router = useRouter();
const store = useKpiDataStore(); const store = useKpiDataStore();
@ -35,25 +34,24 @@ const columns = defineModel<QTableProps["columns"]>("columns", {
const rows = defineModel<ResEvaluatorAssessor[]>("rows", { required: true }); const rows = defineModel<ResEvaluatorAssessor[]>("rows", { required: true });
const formQuery = defineModel<FormQuery>("formQuery", { required: true }); const formQuery = defineModel<FormQuery>("formQuery", { required: true });
const total = defineModel<number>("total", { required: true }); const total = defineModel<number>("total", { required: true });
const maxPage = defineModel<number>("maxPage", { required: true });
const isLoad = defineModel<boolean>("isLoad", { required: true }); const isLoad = defineModel<boolean>("isLoad", { required: true });
const props = defineProps({ const props = defineProps({
updatePagination: { type: Function },
fetchList: { type: Function }, fetchList: { type: Function },
}); });
const pagination = ref<PropsTable.Pagination>({
sortBy: "desc",
descending: false,
page: formQuery.value.page,
rowsPerPage: formQuery.value.pageSize,
rowsNumber: total.value,
});
function redirectViewDetail(id: string) { function redirectViewDetail(id: string) {
router.push(`/KPI-evaluator/${id}`); router.push(`/KPI-evaluator/${id}`);
} }
const pagination = ref({
sortBy: "desc",
descending: false,
page: 1,
rowsPerPage: 10,
});
async function onClickApprove(type: string = "") { async function onClickApprove(type: string = "") {
if (store.selected.length !== 0) { if (store.selected.length !== 0) {
const userIds = await store.selected.map( const userIds = await store.selected.map(
@ -107,12 +105,36 @@ async function onClickApprove(type: string = "") {
dialogMessageNotify($q, "เลือกอย่างน้อย 1 รายการ"); dialogMessageNotify($q, "เลือกอย่างน้อย 1 รายการ");
} }
} }
/**
* งกนร request จากตาราง เมอมการเปลยน pagination
* @param requestProps อมลการรองขอจากตาราง
*/
function onTableRequest(requestProps: PropsTable.RequestProps) {
const newPagination = requestProps?.pagination || requestProps;
if (!newPagination?.page || !newPagination?.rowsPerPage) return;
formQuery.value.page = newPagination.page;
formQuery.value.pageSize = newPagination.rowsPerPage;
props?.fetchList?.();
}
watch(
[
() => formQuery.value.page,
() => formQuery.value.pageSize,
() => total.value,
],
([page, pageSize, total]) => {
pagination.value.page = page;
pagination.value.rowsPerPage = pageSize;
pagination.value.rowsNumber = total;
}
);
</script> </script>
<template> <template>
<div class="col-12"> <div class="col-12">
<d-table <d-table
v-if="!isLoad"
ref="table" ref="table"
:columns="columns" :columns="columns"
:rows="rows" :rows="rows"
@ -124,13 +146,14 @@ async function onClickApprove(type: string = "") {
:rows-per-page-options="[10, 25, 50, 100]" :rows-per-page-options="[10, 25, 50, 100]"
:visible-columns="visibleColumns" :visible-columns="visibleColumns"
v-model:pagination="pagination" v-model:pagination="pagination"
@update:pagination="props.updatePagination"
:selection=" :selection="
store.tabMainevaluator === '5' || store.tabMainevaluator === '6' store.tabMainevaluator === '5' || store.tabMainevaluator === '6'
? 'none' ? 'none'
: 'multiple' : 'multiple'
" "
v-model:selected="store.selected" v-model:selected="store.selected"
@request="onTableRequest"
:loading="isLoad"
> >
<template v-slot:header-selection="scope"> <template v-slot:header-selection="scope">
<q-checkbox keep-color color="primary" dense v-model="scope.selected" /> <q-checkbox keep-color color="primary" dense v-model="scope.selected" />
@ -211,22 +234,7 @@ async function onClickApprove(type: string = "") {
</q-card> </q-card>
</div> </div>
</template> </template>
<template v-slot:pagination="scope">
งหมด {{ total }} รายการ
<q-pagination
v-model="formQuery.page"
active-color="primary"
color="dark"
:max="Number(maxPage)"
size="sm"
boundary-links
direction-links
:max-pages="5"
@update:model-value="props.fetchList?.()"
></q-pagination>
</template>
</d-table> </d-table>
<SkeletonTable v-else :columns="columns" />
</div> </div>
<div class="row justify-end q-mt-md q-gutter-sm" v-if="rows.length !== 0"> <div class="row justify-end q-mt-md q-gutter-sm" v-if="rows.length !== 0">

View file

@ -13,8 +13,6 @@ import type { ListCapacity } from "@/modules/08_KPI/interface/request/index";
import DialogHeader from "@/components/DialogHeader.vue"; import DialogHeader from "@/components/DialogHeader.vue";
import SkeletonTable from '@/components/SkeletonTable.vue'
const dataListCapacityDetails = ref<ListCapacity[]>([]); const dataListCapacityDetails = ref<ListCapacity[]>([]);
const route = useRoute(); const route = useRoute();
const idParam = ref<string>(route.params.id as string); const idParam = ref<string>(route.params.id as string);
@ -483,7 +481,7 @@ watch(
</div> </div>
<div class="col-xs-12 col-md-7"> <div class="col-xs-12 col-md-7">
<d-table <d-table
v-if="!isLoadById" v-if="!isLoadById"
flat flat
bordered bordered
dense dense
@ -491,10 +489,12 @@ watch(
row-key="level" row-key="level"
virtual-scroll virtual-scroll
:rows="dataListCapacityDetails" :rows="dataListCapacityDetails"
:rows-per-page-options="[100]"
hide-pagination hide-pagination
:columns="columns" :columns="columns"
:visible-columns="visibleColumns" :visible-columns="visibleColumns"
v-model:pagination="pagination" :pagination="pagination"
:loading="isLoadById"
> >
<template v-slot:header="props"> <template v-slot:header="props">
<q-tr :props="props"> <q-tr :props="props">
@ -558,7 +558,6 @@ watch(
</div> </div>
</template> </template>
</d-table> </d-table>
<SkeletonTable v-else :columns="columns"/>
</div> </div>
</div> </div>
</div> </div>

View file

@ -10,20 +10,10 @@ import { useCounterMixin } from "@/stores/mixin";
import DialogHeader from "@/components/DialogHeader.vue"; import DialogHeader from "@/components/DialogHeader.vue";
import SkeletonTable from "@/components/SkeletonTable.vue";
const $q = useQuasar(); const $q = useQuasar();
const store = useKpiDataStore(); const store = useKpiDataStore();
const mixin = useCounterMixin(); const mixin = useCounterMixin();
const { const { messageError, findOrgNameOldHtml, date2Thai } = mixin;
showLoader,
hideLoader,
messageError,
findPosMasterNoOld,
findOrgNameOld,
findOrgNameOldHtml,
date2Thai,
} = mixin;
const modal = defineModel<boolean>("modal", { required: true }); const modal = defineModel<boolean>("modal", { required: true });
const filterKeyword = ref<string>(""); const filterKeyword = ref<string>("");
@ -138,29 +128,6 @@ const columns = ref<QTableProps["columns"]>([
}, },
]); ]);
/** เเปลง status เป็น text */
function statusText(val: string) {
switch (val) {
case "WAITTING":
return "รอดำเนินการ";
case "PENDING":
return "เลือกตำแหน่งแล้ว";
case "APPROVE":
return "อนุมัติ";
case "REJECT":
return "ไม่อนุมัติ";
case "REPORT":
return "ส่งรายชื่อไปออกคำสั่ง";
case "WAITING":
return "รอออกคำสั่ง";
case "DONE":
return "ออกคำสั่งเสร็จแล้ว";
default:
return "-";
}
}
/** ปิด dialog */ /** ปิด dialog */
function close() { function close() {
modal.value = false; modal.value = false;
@ -174,7 +141,6 @@ function getData() {
.then((res) => { .then((res) => {
const data = res.data.result; const data = res.data.result;
rows.value = data; rows.value = data;
isLoad.value = false;
}) })
.catch((e) => { .catch((e) => {
messageError($q, e); messageError($q, e);
@ -187,7 +153,7 @@ function getData() {
watch( watch(
() => modal.value, () => modal.value,
(n) => { (n) => {
if (n == true) { if (n) {
getData(); getData();
} }
} }
@ -202,7 +168,6 @@ watch(
<div class="row"> <div class="row">
<div class="col-12"> <div class="col-12">
<d-table <d-table
v-if="!isLoad"
ref="table" ref="table"
:columns="columns" :columns="columns"
:rows="rows" :rows="rows"
@ -214,6 +179,8 @@ watch(
dense dense
:rows-per-page-options="[10, 25, 50, 100]" :rows-per-page-options="[10, 25, 50, 100]"
:visible-columns="visibleColumns" :visible-columns="visibleColumns"
:loading="isLoad"
:pagination="{ page: 1, rowsPerPage: 10 }"
> >
<template v-slot:header="props"> <template v-slot:header="props">
<q-tr :props="props"> <q-tr :props="props">
@ -245,7 +212,6 @@ watch(
</q-tr> </q-tr>
</template> </template>
</d-table> </d-table>
<SkeletonTable v-else :columns="columns" />
</div> </div>
</div> </div>
</q-card-section> </q-card-section>

View file

@ -1,6 +1,6 @@
<script setup lang="ts"> <script setup lang="ts">
import { computed, ref, watch } from "vue"; import { computed, ref, watch } from "vue";
import { useQuasar } from "quasar"; import { Loading, useQuasar } from "quasar";
import config from "@/app.config"; import config from "@/app.config";
import http from "@/plugins/http"; import http from "@/plugins/http";
@ -15,19 +15,16 @@ import DialogViewInfo from "@/modules/08_KPI/components/Tab/Dialog/DialogViewInf
import DialogProgress from "@/modules/08_KPI/components/Tab/Dialog/DialogCommentProgress.vue"; import DialogProgress from "@/modules/08_KPI/components/Tab/Dialog/DialogCommentProgress.vue";
import DialogProblem from "@/modules/08_KPI/components/Tab/Dialog/DialogCommentProblem.vue"; import DialogProblem from "@/modules/08_KPI/components/Tab/Dialog/DialogCommentProblem.vue";
import SkeletonTable from "@/components/SkeletonTable.vue";
const $q = useQuasar(); const $q = useQuasar();
const store = useKpiDataStore(); const store = useKpiDataStore();
const { dialogRemove, showLoader, hideLoader, messageError, success } = const { dialogRemove, messageError, success } = useCounterMixin();
useCounterMixin();
const checkDetail = ref<boolean>(false); const checkDetail = ref<boolean>(false);
const title = defineModel<string>("title", { required: true }); const title = defineModel<string>("title", { required: true });
const rows = defineModel<any>("data", { required: true }); const rows = defineModel<any>("data", { required: true });
const numpage = defineModel<number>("page", { required: true }); const numpage = defineModel<number>("page", { required: true });
const isLoad = defineModel<boolean>('isLoad',{required:true}) const isLoad = defineModel<boolean>("isLoad", { required: true });
const props = defineProps({ const props = defineProps({
fetchList: { type: Function, required: true }, fetchList: { type: Function, required: true },
}); });
@ -139,7 +136,7 @@ async function onEvaluate() {
function onDelete(id: string) { function onDelete(id: string) {
dialogRemove($q, async () => { dialogRemove($q, async () => {
try { try {
isLoad.value = true isLoad.value = true;
const url = const url =
numpage.value === 1 numpage.value === 1
? config.API.kpiAchievement("planned") + `/${id}` ? config.API.kpiAchievement("planned") + `/${id}`
@ -243,12 +240,10 @@ const isEditStep3 = computed(() => {
</q-card-section> </q-card-section>
<q-separator /> <q-separator />
<q-card-section class="q-pa-sm"> <q-card-section class="q-pa-sm">
<d-table <d-table
v-if="!isLoad"
ref="table" ref="table"
:columns="columns" :columns="columns"
:rows="rows" :rows="rows || []"
:filter="filterKeyword" :filter="filterKeyword"
row-key="id" row-key="id"
flat flat
@ -257,7 +252,7 @@ const isEditStep3 = computed(() => {
hide-pagination hide-pagination
:visible-columns="visibleColumns" :visible-columns="visibleColumns"
:rows-per-page-options="[20]" :rows-per-page-options="[20]"
no-data-label="ไม่มีข้อมูล" :loading="isLoad"
> >
<template v-slot:header="props"> <template v-slot:header="props">
<q-tr :props="props"> <q-tr :props="props">
@ -464,7 +459,6 @@ const isEditStep3 = computed(() => {
</div> </div>
</template> </template>
</d-table> </d-table>
<SkeletonTable v-else :columns="columns"/>
</q-card-section> </q-card-section>
</q-card> </q-card>

View file

@ -22,8 +22,6 @@ import DialogEvaluate from "@/modules/08_KPI/components/Tab/DialogEvaluate/02_Co
import DialogListCriteria from "@/modules/08_KPI/components/Tab/Dialog/DialogListCriteria.vue"; import DialogListCriteria from "@/modules/08_KPI/components/Tab/Dialog/DialogListCriteria.vue";
import DialogCompetncyByRow from "@/modules/08_KPI/components/Tab/Dialog/DialogCompetncyByRow.vue"; import DialogCompetncyByRow from "@/modules/08_KPI/components/Tab/Dialog/DialogCompetncyByRow.vue";
import SkeletonTable from "@/components/SkeletonTable.vue";
const modalLevel = ref<boolean>(false); const modalLevel = ref<boolean>(false);
const modalCompetncyByRow = ref<boolean>(false); const modalCompetncyByRow = ref<boolean>(false);
const dataCompetncyByRow = ref<any[]>([]); const dataCompetncyByRow = ref<any[]>([]);
@ -160,15 +158,14 @@ function onAdd(type: string) {
/** ดึงข้อมูล */ /** ดึงข้อมูล */
function getData(type: string) { function getData(type: string) {
isLoad.value[type] = true;
http http
.get(config.API.kpiUserCapacity + `?id=${id.value}&type=${type}`) .get(config.API.kpiUserCapacity + `?id=${id.value}&type=${type}`)
.then(async (res) => { .then(async (res) => {
const data = res.data.result.data; const data = res.data.result.data;
isLoad.value[type] = data ? true : false;
rows.value[type] = data; rows.value[type] = data;
lists.value = await lists.value.filter((x: any) => x.type != type); lists.value = await lists.value.filter((x: any) => x.type != type);
lists.value.push({ type: type, data }); lists.value.push({ type: type, data });
isLoad.value[type] = false;
}) })
.catch((e) => { .catch((e) => {
messageError($q, e); messageError($q, e);
@ -220,6 +217,7 @@ function getData(type: string) {
: 0; : 0;
} }
} }
isLoad.value[type] = false;
}); });
} }
@ -400,20 +398,21 @@ watch(
</q-btn> </q-btn>
</div> </div>
</q-card-section> </q-card-section>
<q-card-section class="q-pa-sm"> <q-card-section class="q-pa-sm">
<d-table <d-table
v-if="!isLoad[item.id]"
ref="table" ref="table"
:columns="columns" :columns="columns"
:rows="rows[item.id]" :rows="rows[item.id] || []"
row-key="id" row-key="id"
flat flat
bordered bordered
:paging="true" :paging="true"
dense dense
hide-pagination hide-pagination
no-data-label="ไม่มีข้อมูล"
:visible-columns="visibleColumns" :visible-columns="visibleColumns"
:rows-per-page-options="[20]"
:loading="isLoad[item.id]"
> >
<template v-slot:header="props"> <template v-slot:header="props">
<q-tr :props="props"> <q-tr :props="props">
@ -634,7 +633,6 @@ watch(
</div> </div>
</template> </template>
</d-table> </d-table>
<SkeletonTable v-else :columns="columns" />
</q-card-section> </q-card-section>
</q-card> </q-card>
</div> </div>

View file

@ -13,8 +13,6 @@ import DialogEvalutionDevelop from "@/modules/08_KPI/components/Tab/DialogEvalua
import DialogProgress from "@/modules/08_KPI/components/Tab/Dialog/DialogCommentProgress.vue"; import DialogProgress from "@/modules/08_KPI/components/Tab/Dialog/DialogCommentProgress.vue";
import DialogProblem from "@/modules/08_KPI/components/Tab/Dialog/DialogCommentProblem.vue"; import DialogProblem from "@/modules/08_KPI/components/Tab/Dialog/DialogCommentProblem.vue";
import SkeletonTable from "@/components/SkeletonTable.vue";
const store = useKpiDataStore(); const store = useKpiDataStore();
const route = useRoute(); const route = useRoute();
const evaluationId = ref<string>(route.params.id.toString()); const evaluationId = ref<string>(route.params.id.toString());
@ -26,14 +24,7 @@ const idEditDevelop = ref<string>("");
const $q = useQuasar(); const $q = useQuasar();
const mixin = useCounterMixin(); const mixin = useCounterMixin();
const { const { date2Thai, messageError, dialogRemove, success } = mixin;
date2Thai,
messageError,
showLoader,
hideLoader,
dialogRemove,
success,
} = mixin;
const isUpdate = defineModel("isUpdate", { const isUpdate = defineModel("isUpdate", {
type: Boolean, type: Boolean,
@ -248,7 +239,6 @@ onMounted(() => {
</q-card-section> </q-card-section>
<q-card-section class="q-pa-sm"> <q-card-section class="q-pa-sm">
<d-table <d-table
v-if="!isLoad"
ref="table" ref="table"
:columns="columns" :columns="columns"
:rows="rows" :rows="rows"
@ -258,8 +248,9 @@ onMounted(() => {
:paging="true" :paging="true"
dense dense
hide-pagination hide-pagination
no-data-label="ไม่มีข้อมูล" :rows-per-page-options="[20]"
:visible-columns="visibleColumns" :visible-columns="visibleColumns"
:loading="isLoad"
> >
<template v-slot:header="props"> <template v-slot:header="props">
<q-tr :props="props"> <q-tr :props="props">
@ -507,8 +498,6 @@ onMounted(() => {
</div> </div>
</template> </template>
</d-table> </d-table>
<SkeletonTable v-else :columns="columns" />
</q-card-section> </q-card-section>
</q-card> </q-card>

View file

@ -1,19 +1,19 @@
<script setup lang="ts"> <script setup lang="ts">
import { ref, onMounted, reactive, watch } from "vue"; import { ref, onMounted, reactive } from "vue";
import { useRouter } from "vue-router"; import { useRouter } from "vue-router";
import { useQuasar } from "quasar"; import { useQuasar } from "quasar";
import type { QTableProps } from "quasar";
import config from "@/app.config"; import config from "@/app.config";
import http from "@/plugins/http"; import http from "@/plugins/http";
import { useCounterMixin } from "@/stores/mixin"; import { useCounterMixin } from "@/stores/mixin";
import { useKpiDataStore } from "@/modules/08_KPI/store"; import { useKpiDataStore } from "@/modules/08_KPI/store";
import type { QTableProps } from "quasar";
import type { DataProfile } from "@/interface/Main"; import type { DataProfile } from "@/interface/Main";
import type { PropsTable } from "@/interface/PropsTable";
import type { import type {
DataOptions, DataOptions,
MainListKpi, MainListKpi,
PaginationType,
} from "@/modules/08_KPI/interface/index/Main"; } from "@/modules/08_KPI/interface/index/Main";
import type { import type {
RoundKpiResponse, RoundKpiResponse,
@ -21,7 +21,6 @@ import type {
} from "@/modules/08_KPI/interface/response/index"; } from "@/modules/08_KPI/interface/response/index";
import DialogHeader from "@/components/DialogHeader.vue"; import DialogHeader from "@/components/DialogHeader.vue";
import SkeletonTable from "@/components/SkeletonTable.vue";
const $q = useQuasar(); const $q = useQuasar();
const mixin = useCounterMixin(); const mixin = useCounterMixin();
@ -107,7 +106,6 @@ const columns = ref<QTableProps["columns"]>([
/** List*/ /** List*/
const year = ref<number>(new Date().getFullYear()); const year = ref<number>(new Date().getFullYear());
const round = ref<string>(""); const round = ref<string>("");
const filterKeyword = ref<string>("");
const roundMainOp = ref<DataOptions[]>([]); const roundMainOp = ref<DataOptions[]>([]);
const roundDialgOp = ref<DataOptions[]>([]); const roundDialgOp = ref<DataOptions[]>([]);
@ -142,20 +140,18 @@ const formRound = reactive({
/** pagetion*/ /** pagetion*/
const formQuery = reactive({ const formQuery = reactive({
page: 1,
pageSize: 10,
status: "", status: "",
results: "", results: "",
}); });
const total = ref<number>(0);
const totalList = ref<number>(1);
const isRoundClose = ref<boolean>(false); const isRoundClose = ref<boolean>(false);
const pagination = ref({ const pagination = ref<PropsTable.Pagination>({
sortBy: "desc", sortBy: "desc",
descending: false, descending: false,
page: 1, page: 1,
rowsPerPage: 10, rowsPerPage: 10,
rowsNumber: 0,
}); });
/** /**
@ -206,14 +202,12 @@ async function fetchRoundOption(type: string) {
}); });
} }
/** /** ฟังก์ชันดึงข้อมูลรายการขอรับประเมินผลการปฏิบัติราชการระดับบุคคล*/
* fetch รายการขอรบประเมนผลการปฏราชการระดบบคคล
*/
async function fetchList() { async function fetchList() {
isLoad.value = true; isLoad.value = true;
let queryParams = { let queryParams = {
page: formQuery.page, page: pagination.value.page,
pageSize: formQuery.pageSize, pageSize: pagination.value.rowsPerPage,
kpiPeriodId: round.value, kpiPeriodId: round.value,
status: formQuery.status === "" ? undefined : formQuery.status, status: formQuery.status === "" ? undefined : formQuery.status,
results: formQuery.results === "" ? undefined : formQuery.results, results: formQuery.results === "" ? undefined : formQuery.results,
@ -225,21 +219,20 @@ async function fetchList() {
}) })
.then(async (res) => { .then(async (res) => {
const data = await res.data.result; const data = await res.data.result;
total.value = data.total; pagination.value.rowsNumber = data.total;
totalList.value = Math.ceil(data.total / formQuery.pageSize);
rows.value = data.data; rows.value = data.data;
isLoad.value = false;
}) })
.catch((err) => { .catch((err) => {
isLoad.value = false;
messageError($q, err); messageError($q, err);
}) })
.finally(() => {}); .finally(() => {
isLoad.value = false;
});
} }
/** เลือกรอบการประเมิน */ /** เลือกรอบการประเมิน */
function changRound() { function changRound() {
formQuery.page = 1; pagination.value.page = 1;
fetchList(); fetchList();
} }
@ -333,15 +326,6 @@ function checkClosed() {
isRoundClose.value = formRound.kpiPeriodId.isClosed; isRoundClose.value = formRound.kpiPeriodId.isClosed;
} }
/**
* function updatePagination
* @param newPagination อม Pagination ใหม
*/
function updatePagination(newPagination: PaginationType) {
formQuery.page = 1;
formQuery.pageSize = newPagination.rowsPerPage;
}
/** ดึงข้อมูล option */ /** ดึงข้อมูล option */
function getOrgOp() { function getOrgOp() {
http http
@ -421,12 +405,16 @@ function filterOption(val: string, update: Function, refData: string) {
} }
} }
watch( /**
() => formQuery.pageSize, * งกนร request จากตาราง เมอมการเปลยน pagination
() => { * @param requestProps อมลการรองขอจากตาราง
fetchList(); */
} function onTableRequest(requestProps: PropsTable.RequestProps) {
); const newPagination = requestProps?.pagination || requestProps;
if (!newPagination?.page || !newPagination?.rowsPerPage) return;
pagination.value = { ...newPagination };
fetchList();
}
onMounted(async () => { onMounted(async () => {
await Promise.all([fetchRoundOption("main"), getOrgOp()]); await Promise.all([fetchRoundOption("main"), getOrgOp()]);
@ -462,7 +450,7 @@ onMounted(async () => {
year-picker year-picker
:enableTimePicker="false" :enableTimePicker="false"
@update:model-value=" @update:model-value="
(formQuery.page = 1), fetchRoundOption('main') (pagination.page = 1), fetchRoundOption('main')
" "
> >
<template #year="{ year }">{{ year + 543 }}</template> <template #year="{ year }">{{ year + 543 }}</template>
@ -557,7 +545,7 @@ onMounted(async () => {
outlined outlined
use-input use-input
input-debounce="0" input-debounce="0"
@update:model-value="(formQuery.page = 1), fetchList()" @update:model-value="(pagination.page = 1), fetchList()"
:clearable="formQuery.status !== ''" :clearable="formQuery.status !== ''"
@clear=" @clear="
(formQuery.status = ''), (formQuery.status = ''),
@ -589,7 +577,7 @@ onMounted(async () => {
lazy-rules lazy-rules
hide-bottom-space hide-bottom-space
outlined outlined
@update:model-value="(formQuery.page = 1), fetchList()" @update:model-value="(pagination.page = 1), fetchList()"
use-input use-input
@clear=" @clear="
(formQuery.results = ''), (formQuery.results = ''),
@ -615,11 +603,9 @@ onMounted(async () => {
<div class="col-12"> <div class="col-12">
<d-table <d-table
v-if="!isLoad"
ref="table" ref="table"
:columns="columns" :columns="columns"
:rows="rows" :rows="rows"
:filter="filterKeyword"
row-key="id" row-key="id"
flat flat
bordered bordered
@ -627,8 +613,9 @@ onMounted(async () => {
dense dense
:rows-per-page-options="[10, 25, 50, 100]" :rows-per-page-options="[10, 25, 50, 100]"
:visible-columns="visibleColumns" :visible-columns="visibleColumns"
@request="onTableRequest"
v-model:pagination="pagination" v-model:pagination="pagination"
@update:pagination="updatePagination" :loading="isLoad"
> >
<template v-slot:header="props"> <template v-slot:header="props">
<q-tr :props="props"> <q-tr :props="props">
@ -671,22 +658,7 @@ onMounted(async () => {
</q-card> </q-card>
</div> </div>
</template> </template>
<template v-slot:pagination="scope">
งหมด {{ total }} รายการ
<q-pagination
v-model="formQuery.page"
active-color="primary"
color="dark"
:max="Number(totalList)"
size="sm"
boundary-links
direction-links
:max-pages="5"
@update:model-value="fetchList"
></q-pagination>
</template>
</d-table> </d-table>
<SkeletonTable v-else :columns="columns" />
</div> </div>
</div> </div>
</q-card> </q-card>
@ -746,7 +718,7 @@ onMounted(async () => {
<div class="col-12"> <div class="col-12">
<q-select <q-select
v-if="!isLoadDialog" v-if="!isLoadDialog"
:readonly="yearDialog === null" :readonly="yearDialog === null"
v-model="formRound.kpiPeriodId" v-model="formRound.kpiPeriodId"
outlined outlined
@ -760,7 +732,7 @@ onMounted(async () => {
:rules="[(val:DataOptions) => !!val.id || `${'กรุณาเลือกรอบการประเมิน'}`]" :rules="[(val:DataOptions) => !!val.id || `${'กรุณาเลือกรอบการประเมิน'}`]"
@update:model-value="checkClosed" @update:model-value="checkClosed"
/> />
<q-skeleton type="QInput" height="40px" v-else/> <q-skeleton type="QInput" height="40px" v-else />
</div> </div>
<div class="col-12"> <div class="col-12">

View file

@ -1,5 +1,5 @@
<script setup lang="ts"> <script setup lang="ts">
import { ref, onMounted, watch } from "vue"; import { ref, onMounted } from "vue";
import { useRouter } from "vue-router"; import { useRouter } from "vue-router";
import { useQuasar } from "quasar"; import { useQuasar } from "quasar";
import type { QTableProps } from "quasar"; import type { QTableProps } from "quasar";
@ -9,10 +9,7 @@ import http from "@/plugins/http";
import { useCounterMixin } from "@/stores/mixin"; import { useCounterMixin } from "@/stores/mixin";
import { useKpiDataStore } from "@/modules/08_KPI/store"; import { useKpiDataStore } from "@/modules/08_KPI/store";
import type { import type { DataOptions } from "@/modules/08_KPI/interface/index/Main";
DataOptions,
Pagination,
} from "@/modules/08_KPI/interface/index/Main";
import type { import type {
ResRound, ResRound,
ResEvaluatorAssessor, ResEvaluatorAssessor,
@ -24,7 +21,7 @@ import TabOther from "@/modules/08_KPI/components/Evaluator/02_TabOther.vue";
const $q = useQuasar(); const $q = useQuasar();
const router = useRouter(); const router = useRouter();
const store = useKpiDataStore(); const store = useKpiDataStore();
const { showLoader, hideLoader, messageError, date2Thai } = useCounterMixin(); const { messageError, date2Thai } = useCounterMixin();
const dataListMain = ref<ResEvaluatorAssessor[]>([]); const dataListMain = ref<ResEvaluatorAssessor[]>([]);
@ -87,7 +84,6 @@ const columns = ref<QTableProps["columns"]>([
]); ]);
const totalList = ref<number>(0); const totalList = ref<number>(0);
const maxPage = ref<number>(1);
/** /**
* งขอมลรายการขอรบประเมนผลการปฏราชการระดบบคคล * งขอมลรายการขอรบประเมนผลการปฏราชการระดบบคคล
@ -121,19 +117,19 @@ async function fetchRoundOption() {
store.formQuery.round = roundOp.value[0].id; store.formQuery.round = roundOp.value[0].id;
await fetchList(); await fetchList();
} }
isLoadOp.value = false;
}) })
.catch((err) => { .catch((err) => {
messageError($q, err); messageError($q, err);
isLoadOp.value = false;
}) })
.finally(() => {}); .finally(() => {
isLoadOp.value = false;
});
} }
/** ดึงข้อมูล list */ /** ดึงข้อมูล list */
const isLoad = ref<boolean>(false) const isLoad = ref<boolean>(false);
async function fetchList() { async function fetchList() {
isLoad.value = true isLoad.value = true;
const body = { const body = {
page: store.formQuery.page, page: store.formQuery.page,
pageSize: store.formQuery.pageSize, pageSize: store.formQuery.pageSize,
@ -157,16 +153,15 @@ async function fetchList() {
.post(config.API.kpiEvaluation + `/admin`, body) .post(config.API.kpiEvaluation + `/admin`, body)
.then(async (res) => { .then(async (res) => {
const data = await res.data.result; const data = await res.data.result;
maxPage.value = Math.ceil(data.total / store.formQuery.pageSize);
totalList.value = data.total; totalList.value = data.total;
dataListMain.value = data.data; dataListMain.value = data.data;
isLoad.value = false
}) })
.catch((err) => { .catch((err) => {
messageError($q, err); messageError($q, err);
isLoad.value = false
}) })
.finally(() => {}); .finally(() => {
isLoad.value = false;
});
} }
/** เลือกรอบการประเมิน */ /** เลือกรอบการประเมิน */
@ -175,15 +170,6 @@ function changRound() {
fetchList(); fetchList();
} }
/**
* function updatePagination
* @param newPagination อม Pagination ใหม
*/
function updatePagination(newPagination: Pagination) {
store.formQuery.page = 1;
store.formQuery.pageSize = newPagination.rowsPerPage;
}
/** เปลี่ยน tab */ /** เปลี่ยน tab */
async function onChangTab() { async function onChangTab() {
store.formQuery.page = 1; store.formQuery.page = 1;
@ -192,13 +178,6 @@ async function onChangTab() {
await fetchList(); await fetchList();
} }
watch(
() => store.formQuery.pageSize,
() => {
fetchList();
}
);
onMounted(async () => { onMounted(async () => {
await fetchRoundOption(); await fetchRoundOption();
}); });
@ -347,8 +326,6 @@ onMounted(async () => {
:rows="dataListMain" :rows="dataListMain"
:formQuery="store.formQuery" :formQuery="store.formQuery"
:total="totalList" :total="totalList"
:maxPage="maxPage"
:updatePagination="updatePagination"
:fetchList="fetchList" :fetchList="fetchList"
:is-load="isLoad" :is-load="isLoad"
/> />
@ -361,8 +338,6 @@ onMounted(async () => {
:rows="dataListMain" :rows="dataListMain"
:formQuery="store.formQuery" :formQuery="store.formQuery"
:total="totalList" :total="totalList"
:maxPage="maxPage"
:updatePagination="updatePagination"
:fetchList="fetchList" :fetchList="fetchList"
:is-load="isLoad" :is-load="isLoad"
/> />
@ -375,8 +350,6 @@ onMounted(async () => {
:rows="dataListMain" :rows="dataListMain"
:formQuery="store.formQuery" :formQuery="store.formQuery"
:total="totalList" :total="totalList"
:maxPage="maxPage"
:updatePagination="updatePagination"
:fetchList="fetchList" :fetchList="fetchList"
:is-load="isLoad" :is-load="isLoad"
/> />
@ -389,8 +362,6 @@ onMounted(async () => {
:rows="dataListMain" :rows="dataListMain"
:formQuery="store.formQuery" :formQuery="store.formQuery"
:total="totalList" :total="totalList"
:maxPage="maxPage"
:updatePagination="updatePagination"
:fetchList="fetchList" :fetchList="fetchList"
:is-load="isLoad" :is-load="isLoad"
/> />
@ -403,8 +374,6 @@ onMounted(async () => {
:rows="dataListMain" :rows="dataListMain"
:formQuery="store.formQuery" :formQuery="store.formQuery"
:total="totalList" :total="totalList"
:maxPage="maxPage"
:updatePagination="updatePagination"
:fetchList="fetchList" :fetchList="fetchList"
:is-load="isLoad" :is-load="isLoad"
/> />

View file

@ -13,10 +13,8 @@ import type {
Scholarship, Scholarship,
} from "@/modules/09_scholarship/interface/index/Main"; } from "@/modules/09_scholarship/interface/index/Main";
import SkeletonTable from "@/components/SkeletonTable.vue";
const mixin = useCounterMixin(); const mixin = useCounterMixin();
const { showLoader, hideLoader, messageError } = mixin; const { messageError } = mixin;
const router = useRouter(); const router = useRouter();
const $q = useQuasar(); const $q = useQuasar();
@ -88,7 +86,7 @@ const visibleColumns = ref<string[]>(["scholarshipYear", "scholarshipType"]);
/** ดึงข้อมูล */ /** ดึงข้อมูล */
async function getData() { async function getData() {
isLoad.value = true;
await http await http
.get( .get(
config.API.developmentScholarship + config.API.developmentScholarship +
@ -96,13 +94,12 @@ async function getData() {
) )
.then(async (res) => { .then(async (res) => {
rows.value = res.data.result; rows.value = res.data.result;
isLoad.value = false
}) })
.catch((e) => { .catch((e) => {
messageError($q, e); messageError($q, e);
}) })
.finally(() => { .finally(() => {
isLoad.value = false isLoad.value = false;
}); });
} }
@ -110,42 +107,22 @@ function onEdit(id: string) {
router.push(`/scholarship/${id}`); router.push(`/scholarship/${id}`);
} }
// watch(
// () => currentPage.value,
// () => {
// rowsPerPage.value = pagination.value.rowsPerPage;
// getData();
// }
// );
// watch(
// () => pagination.value.rowsPerPage,
// () => {
// rowsPerPage.value = pagination.value.rowsPerPage;
// currentPage.value = 1;
// getData();
// }
// );
async function getProfileId() { async function getProfileId() {
isLoad.value = true isLoad.value = true;
if (dataStore.profileId) { if (dataStore.profileId) {
profilId.value = dataStore.profileId; profilId.value = dataStore.profileId;
} else { } else {
try { try {
const res = await http.get(config.API.profilePosition()); const res = await http.get(config.API.profilePosition());
dataStore.profileId = res.data.result.profileId; dataStore.profileId = res.data.result.profileId;
profilId.value = dataStore.profileId; profilId.value = dataStore.profileId;
await getData();
} catch (e) { } catch (e) {
messageError($q, e); messageError($q, e);
} finally { } finally {
isLoad.value = false;
} }
} }
await getData();
} }
function convertType(val: string) { function convertType(val: string) {
@ -259,9 +236,8 @@ onMounted(async () => {
/> />
</div> </div>
<div> <div class="col-12">
<d-table <d-table
v-if="!isLoad"
flat flat
bordered bordered
dense dense
@ -270,21 +246,9 @@ onMounted(async () => {
:columns="columns" :columns="columns"
:visible-columns="visibleColumns" :visible-columns="visibleColumns"
:rows-per-page-options="[10, 25, 50, 100]" :rows-per-page-options="[10, 25, 50, 100]"
v-model:pagination="pagination" :pagination="pagination"
:loading="isLoad"
> >
<template v-slot:pagination="scope">
งหมด {{ rows.length }} รายการ
<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>
<template v-slot:header="props"> <template v-slot:header="props">
<q-tr :props="props"> <q-tr :props="props">
<q-th <q-th
@ -346,7 +310,6 @@ onMounted(async () => {
</div> </div>
</template> </template>
</d-table> </d-table>
<SkeletonTable v-else :columns="columns" />
</div> </div>
</q-card> </q-card>
</div> </div>

View file

@ -1,6 +1,6 @@
<script setup lang="ts"> <script setup lang="ts">
import { ref, reactive, onMounted, computed } from "vue"; import { ref, reactive, onMounted, computed } from "vue";
import { is, useQuasar, type QTableProps } from "quasar"; import { useQuasar, type QTableProps } from "quasar";
import http from "@/plugins/http"; import http from "@/plugins/http";
import config from "@/app.config"; import config from "@/app.config";

View file

@ -10,9 +10,6 @@ import config from "@/app.config";
import { useQuasar, type QTableProps } from "quasar"; import { useQuasar, type QTableProps } from "quasar";
import type { ChangNameRows } from "@/modules/10_registry/interface/response/01_Information"; import type { ChangNameRows } from "@/modules/10_registry/interface/response/01_Information";
/** import component */
import SkeletonTable from "@/components/SkeletonTable.vue";
const $q = useQuasar(); const $q = useQuasar();
const dataStore = useDataStore(); const dataStore = useDataStore();
const { showLoader, hideLoader, messageError, date2Thai, onSearchDataTable } = const { showLoader, hideLoader, messageError, date2Thai, onSearchDataTable } =
@ -194,23 +191,21 @@ onMounted(async () => {
/> />
</q-toolbar> </q-toolbar>
<div v-if="isLoading"> <div class="col-12">
<SkeletonTable :columns="columns" />
</div>
<div class="col-12" v-else>
<d-table <d-table
flat flat
dense dense
bordered bordered
virtual-scroll virtual-scroll
row-key="id"
:rows="rows.length !== 0 ? rows : []" :rows="rows.length !== 0 ? rows : []"
:columns="columns" :columns="columns"
:grid="!mode" :grid="!mode"
:rows-per-page-options="[10, 25, 50, 100]" :rows-per-page-options="[10, 25, 50, 100]"
:visible-columns="visibleColumns" :visible-columns="visibleColumns"
:virtual-scroll-sticky-size-start="48" :virtual-scroll-sticky-size-start="48"
v-model:pagination="pagination" :pagination="pagination"
:loading="isLoading"
> >
<template v-slot:header="props"> <template v-slot:header="props">
<q-tr :props="props"> <q-tr :props="props">

View file

@ -10,7 +10,6 @@ import { useCounterMixin } from "@/stores/mixin";
import type { EducationProfile } from "@/modules/10_registry/interface/index/Main"; import type { EducationProfile } from "@/modules/10_registry/interface/index/Main";
import DialogHistory from "@/modules/10_registry/Dialog/DialogHistory.vue"; import DialogHistory from "@/modules/10_registry/Dialog/DialogHistory.vue";
import SkeletonTable from "@/components/SkeletonTable.vue";
const link = ref<string>(""); const link = ref<string>("");
const $q = useQuasar(); const $q = useQuasar();
@ -530,7 +529,7 @@ function onHistory(id: string) {
/** get history */ /** get history */
async function getHistory() { async function getHistory() {
isLoadingHistory.value = true isLoadingHistory.value = true;
rowsHistory.value = []; rowsHistory.value = [];
rowsHistoryData.value = []; rowsHistoryData.value = [];
await http await http
@ -601,9 +600,7 @@ onMounted(async () => {
/> />
</q-toolbar> </q-toolbar>
<SkeletonTable v-if="isLoading" :columns="columns" />
<d-table <d-table
v-else
flat flat
dense dense
bordered bordered
@ -611,9 +608,12 @@ onMounted(async () => {
:rows="rows.length !== 0 ? rows : []" :rows="rows.length !== 0 ? rows : []"
:columns="columns" :columns="columns"
:grid="!mode" :grid="!mode"
:rows-per-page-options="[10, 25, 50, 100]" :rows-per-page-options="[1, 10, 25, 50, 100]"
:visible-columns="visibleColumns" :visible-columns="visibleColumns"
:virtual-scroll-sticky-size-start="48" :virtual-scroll-sticky-size-start="48"
:loading="isLoading"
row-key="id"
:pagination="{ page: 1, rowsPerPage: 10 }"
> >
<template v-slot:header="props"> <template v-slot:header="props">
<q-tr :props="props"> <q-tr :props="props">

View file

@ -12,7 +12,6 @@ import type { AbilityRows } from "@/modules/10_registry/interface/index/Main";
/** import components */ /** import components */
import DialogHistory from "@/modules/10_registry/Dialog/DialogHistory.vue"; import DialogHistory from "@/modules/10_registry/Dialog/DialogHistory.vue";
import SkeletonTable from "@/components/SkeletonTable.vue";
const $q = useQuasar(); const $q = useQuasar();
const dataStore = useDataStore(); const dataStore = useDataStore();
@ -317,9 +316,7 @@ onMounted(async () => {
/> />
</q-toolbar> </q-toolbar>
<SkeletonTable v-if="isLoading" :columns="columns" />
<d-table <d-table
v-else
flat flat
dense dense
bordered bordered
@ -330,7 +327,9 @@ onMounted(async () => {
:rows-per-page-options="[10, 25, 50, 100]" :rows-per-page-options="[10, 25, 50, 100]"
:visible-columns="visibleColumns" :visible-columns="visibleColumns"
:virtual-scroll-sticky-size-start="48" :virtual-scroll-sticky-size-start="48"
v-model:pagination="pagination" :pagination="pagination"
:loading="isLoading"
row-key="id"
> >
<template v-slot:header="props"> <template v-slot:header="props">
<q-tr :props="props"> <q-tr :props="props">

View file

@ -11,7 +11,6 @@ import { useRegistryDataStore } from "@/modules/10_registry/store/Main";
import type { DisciplineDetail } from "@/modules/10_registry/interface/index/Main"; import type { DisciplineDetail } from "@/modules/10_registry/interface/index/Main";
import DialogHistory from "@/modules/10_registry/Dialog/DialogHistory.vue"; import DialogHistory from "@/modules/10_registry/Dialog/DialogHistory.vue";
import SkeletonTable from "@/components/SkeletonTable.vue";
const $q = useQuasar(); const $q = useQuasar();
const dataStore = useDataStore(); const dataStore = useDataStore();
@ -254,9 +253,8 @@ onMounted(async () => {
:display-value="$q.lang.table.columns" :display-value="$q.lang.table.columns"
/> />
</q-toolbar> </q-toolbar>
<SkeletonTable v-if="isLoading" :columns="columns" />
<d-table <d-table
v-else
flat flat
dense dense
bordered bordered
@ -267,7 +265,9 @@ onMounted(async () => {
:rows-per-page-options="[10, 25, 50, 100]" :rows-per-page-options="[10, 25, 50, 100]"
:visible-columns="visibleColumns" :visible-columns="visibleColumns"
:virtual-scroll-sticky-size-start="48" :virtual-scroll-sticky-size-start="48"
v-model:pagination="pagination" :pagination="pagination"
:loading="isLoading"
row-key="id"
> >
<template v-slot:header="props"> <template v-slot:header="props">
<q-tr :props="props"> <q-tr :props="props">
@ -321,6 +321,7 @@ onMounted(async () => {
</q-td> </q-td>
</q-tr> </q-tr>
</template> </template>
<template v-else v-slot:item="props"> <template v-else v-slot:item="props">
<div class="q-mb-xs col-xs-12 col-sm-6 col-md-4 col-lg-3"> <div class="q-mb-xs col-xs-12 col-sm-6 col-md-4 col-lg-3">
<q-card bordered flat> <q-card bordered flat>

View file

@ -10,7 +10,6 @@ import { useDataStore } from "@/stores/data";
import type { LeaveFormType } from "@/modules/10_registry/interface/index/Main"; import type { LeaveFormType } from "@/modules/10_registry/interface/index/Main";
import DialogHistory from "@/modules/10_registry/Dialog/DialogHistory.vue"; import DialogHistory from "@/modules/10_registry/Dialog/DialogHistory.vue";
import SkeletonTable from "@/components/SkeletonTable.vue";
const $q = useQuasar(); const $q = useQuasar();
const dataStore = useDataStore(); const dataStore = useDataStore();
@ -396,9 +395,7 @@ onMounted(async () => {
/> />
</q-toolbar> </q-toolbar>
<SkeletonTable v-if="isLoading" :columns="columns" />
<d-table <d-table
v-else
flat flat
dense dense
bordered bordered
@ -409,7 +406,9 @@ onMounted(async () => {
:rows-per-page-options="[10, 25, 50, 100]" :rows-per-page-options="[10, 25, 50, 100]"
:visible-columns="visibleColumns" :visible-columns="visibleColumns"
:virtual-scroll-sticky-size-start="48" :virtual-scroll-sticky-size-start="48"
v-model:pagination="pagination" :pagination="pagination"
:loading="isLoading"
row-key="id"
> >
<template v-slot:header="props"> <template v-slot:header="props">
<q-tr :props="props"> <q-tr :props="props">

View file

@ -11,7 +11,6 @@ import { useRegistryDataStore } from "@/modules/10_registry/store/Main";
import type { DutyFormType } from "@/modules/10_registry/interface/index/Main"; import type { DutyFormType } from "@/modules/10_registry/interface/index/Main";
import DialogHistory from "@/modules/10_registry/Dialog/DialogHistory.vue"; import DialogHistory from "@/modules/10_registry/Dialog/DialogHistory.vue";
import SkeletonTable from "@/components/SkeletonTable.vue";
const $q = useQuasar(); const $q = useQuasar();
const dataStore = useDataStore(); const dataStore = useDataStore();
@ -358,9 +357,8 @@ onMounted(async () => {
:display-value="$q.lang.table.columns" :display-value="$q.lang.table.columns"
/> />
</q-toolbar> </q-toolbar>
<SkeletonTable v-if="isLoading" :columns="columns" />
<d-table <d-table
v-else
flat flat
dense dense
bordered bordered
@ -371,7 +369,9 @@ onMounted(async () => {
:rows-per-page-options="[10, 25, 50, 100]" :rows-per-page-options="[10, 25, 50, 100]"
:visible-columns="visibleColumns" :visible-columns="visibleColumns"
:virtual-scroll-sticky-size-start="48" :virtual-scroll-sticky-size-start="48"
v-model:pagination="pagination" :pagination="pagination"
:loading="isLoading"
row-key="id"
> >
<template v-slot:header="props"> <template v-slot:header="props">
<q-tr :props="props"> <q-tr :props="props">

View file

@ -11,7 +11,6 @@ import type { DutyFormType } from "@/modules/10_registry/interface/index/Main";
/** import components */ /** import components */
import DialogHistory from "@/modules/10_registry/Dialog/DialogHistory.vue"; import DialogHistory from "@/modules/10_registry/Dialog/DialogHistory.vue";
import SkeletonTable from "@/components/SkeletonTable.vue";
const $q = useQuasar(); const $q = useQuasar();
const dataStore = useDataStore(); const dataStore = useDataStore();
@ -287,9 +286,7 @@ onMounted(async () => {
/> />
</q-toolbar> </q-toolbar>
<SkeletonTable v-if="isLoading" :columns="columns" />
<d-table <d-table
v-else
flat flat
dense dense
bordered bordered
@ -300,7 +297,9 @@ onMounted(async () => {
:rows-per-page-options="[10, 25, 50, 100]" :rows-per-page-options="[10, 25, 50, 100]"
:visible-columns="visibleColumns" :visible-columns="visibleColumns"
:virtual-scroll-sticky-size-start="48" :virtual-scroll-sticky-size-start="48"
v-model:pagination="pagination" :pagination="pagination"
:loading="isLoading"
row-key="id"
> >
<template v-slot:header="props"> <template v-slot:header="props">
<q-tr :props="props"> <q-tr :props="props">

View file

@ -11,7 +11,6 @@ import type { DutyFormType } from "@/modules/10_registry/interface/index/Main";
/** import components */ /** import components */
import DialogHistory from "@/modules/10_registry/Dialog/DialogHistory.vue"; import DialogHistory from "@/modules/10_registry/Dialog/DialogHistory.vue";
import SkeletonTable from "@/components/SkeletonTable.vue";
const $q = useQuasar(); const $q = useQuasar();
@ -368,9 +367,7 @@ onMounted(async () => {
/> />
</q-toolbar> </q-toolbar>
<SkeletonTable v-if="isLoading" :columns="columns" />
<d-table <d-table
v-else
flat flat
dense dense
bordered bordered
@ -381,7 +378,9 @@ onMounted(async () => {
:rows-per-page-options="[10, 25, 50, 100]" :rows-per-page-options="[10, 25, 50, 100]"
:visible-columns="visibleColumns" :visible-columns="visibleColumns"
:virtual-scroll-sticky-size-start="48" :virtual-scroll-sticky-size-start="48"
v-model:pagination="pagination" :pagination="pagination"
:loading="isLoading"
row-key="id"
> >
<template v-slot:header="props"> <template v-slot:header="props">
<q-tr :props="props"> <q-tr :props="props">

View file

@ -14,7 +14,6 @@ import type {
/**import components*/ /**import components*/
import DialogHistory from "@/modules/10_registry/Dialog/DialogHistory.vue"; import DialogHistory from "@/modules/10_registry/Dialog/DialogHistory.vue";
import SkeletonTable from "@/components/SkeletonTable.vue";
const $q = useQuasar(); const $q = useQuasar();
const dataPerson = useDataStore(); const dataPerson = useDataStore();
@ -526,9 +525,7 @@ onMounted(async () => {
</div> </div>
<div class="col-12 q-mt-sm"> <div class="col-12 q-mt-sm">
<SkeletonTable v-if="isLoading.position" :columns="columns" />
<d-table <d-table
v-else
flat flat
dense dense
bordered bordered
@ -539,6 +536,9 @@ onMounted(async () => {
:rows-per-page-options="[10, 25, 50, 100]" :rows-per-page-options="[10, 25, 50, 100]"
:visible-columns="visibleColumns" :visible-columns="visibleColumns"
:virtual-scroll-sticky-size-start="48" :virtual-scroll-sticky-size-start="48"
:isLoading="isLoading.position"
row-key="id"
:pagination="{ page: 1, rowsPerPage: 10 }"
> >
<template v-slot:header="props"> <template v-slot:header="props">
<q-tr :props="props"> <q-tr :props="props">

View file

@ -10,7 +10,6 @@ import { useDataStore } from "@/stores/data";
import type { SalaryFormType } from "@/modules/10_registry/interface/index/Main"; import type { SalaryFormType } from "@/modules/10_registry/interface/index/Main";
import DialogHistory from "@/modules/10_registry/Dialog/DialogHistory.vue"; import DialogHistory from "@/modules/10_registry/Dialog/DialogHistory.vue";
import SkeletonTable from "@/components/SkeletonTable.vue";
const $q = useQuasar(); const $q = useQuasar();
const dataPerson = useDataStore(); const dataPerson = useDataStore();
@ -729,19 +728,20 @@ onMounted(async () => {
/> />
</q-toolbar> </q-toolbar>
<SkeletonTable v-if="isLoading" :columns="columns" />
<d-table <d-table
v-else
flat flat
dense dense
bordered bordered
virtual-scroll virtual-scroll
row-key="id"
:rows="rows.length !== 0 ? rows : []" :rows="rows.length !== 0 ? rows : []"
:columns="columns" :columns="columns"
:grid="!mode" :grid="!mode"
:rows-per-page-options="[10, 25, 50, 100]" :rows-per-page-options="[10, 25, 50, 100]"
:visible-columns="visibleColumns" :visible-columns="visibleColumns"
:virtual-scroll-sticky-size-start="48" :virtual-scroll-sticky-size-start="48"
:loading="isLoading"
:pagination="{ page: 1, rowsPerPage: 10 }"
> >
<template v-slot:header="props"> <template v-slot:header="props">
<q-tr :props="props"> <q-tr :props="props">
@ -765,7 +765,11 @@ onMounted(async () => {
<div v-else-if="col.name == 'status'"> <div v-else-if="col.name == 'status'">
{{ props.row.status ? props.row.status : "-" }} {{ props.row.status ? props.row.status : "-" }}
</div> </div>
<div v-else-if="col.name == 'organization'" class="text-html"> <div
v-else-if="col.name == 'organization'"
class="text-html"
style="width: 200px"
>
{{ {{
props.row props.row
? findOrgNameHtml({ ? findOrgNameHtml({

View file

@ -11,7 +11,6 @@ import { useRegistryDataStore } from "@/modules/10_registry/store/Main";
import type { NopaidFormType } from "@/modules/10_registry/interface/index/Main"; import type { NopaidFormType } from "@/modules/10_registry/interface/index/Main";
import DialogHistory from "@/modules/10_registry/Dialog/DialogHistory.vue"; import DialogHistory from "@/modules/10_registry/Dialog/DialogHistory.vue";
import SkeletonTable from "@/components/SkeletonTable.vue";
const $q = useQuasar(); const $q = useQuasar();
const dataPerson = useDataStore(); const dataPerson = useDataStore();
@ -340,9 +339,7 @@ onMounted(async () => {
/> />
</q-toolbar> </q-toolbar>
<SkeletonTable v-if="isLoading" :columns="columns" />
<d-table <d-table
v-else
flat flat
dense dense
bordered bordered
@ -353,7 +350,9 @@ onMounted(async () => {
:rows-per-page-options="[10, 25, 50, 100]" :rows-per-page-options="[10, 25, 50, 100]"
:visible-columns="visibleColumns" :visible-columns="visibleColumns"
:virtual-scroll-sticky-size-start="48" :virtual-scroll-sticky-size-start="48"
v-model:pagination="pagination" :pagination="pagination"
:loading="isLoading"
row-key="id"
> >
<template v-slot:header="props"> <template v-slot:header="props">
<q-tr :props="props"> <q-tr :props="props">

View file

@ -11,7 +11,6 @@ import { useRegistryDataStore } from "@/modules/10_registry/store/Main";
import type { CertificateDetail } from "@/modules/10_registry/interface/index/Main"; import type { CertificateDetail } from "@/modules/10_registry/interface/index/Main";
import DialogHistory from "@/modules/10_registry/Dialog/DialogHistory.vue"; import DialogHistory from "@/modules/10_registry/Dialog/DialogHistory.vue";
import SkeletonTable from "@/components/SkeletonTable.vue";
const $q = useQuasar(); const $q = useQuasar();
const dataPerson = useDataStore(); const dataPerson = useDataStore();
@ -338,10 +337,8 @@ onMounted(async () => {
:display-value="$q.lang.table.columns" :display-value="$q.lang.table.columns"
/> />
</q-toolbar> </q-toolbar>
<SkeletonTable v-if="isLoading" :columns="columns" />
<d-table <d-table
v-else
flat flat
dense dense
bordered bordered
@ -352,7 +349,9 @@ onMounted(async () => {
:rows-per-page-options="[10, 25, 50, 100]" :rows-per-page-options="[10, 25, 50, 100]"
:visible-columns="visibleColumns" :visible-columns="visibleColumns"
:virtual-scroll-sticky-size-start="48" :virtual-scroll-sticky-size-start="48"
v-model:pagination="pagination" :pagination="pagination"
:loading="isLoading"
row-key="id"
> >
<template v-slot:header="props"> <template v-slot:header="props">
<q-tr :props="props"> <q-tr :props="props">

View file

@ -11,7 +11,6 @@ import type { TrainingFormType } from "@/modules/10_registry/interface/index/Mai
//history dialog //history dialog
import DialogHistory from "@/modules/10_registry/Dialog/DialogHistory.vue"; import DialogHistory from "@/modules/10_registry/Dialog/DialogHistory.vue";
import SkeletonTable from "@/components/SkeletonTable.vue";
const $q = useQuasar(); const $q = useQuasar();
const dataPerson = useDataStore(); const dataPerson = useDataStore();
@ -447,9 +446,7 @@ onMounted(async () => {
/> />
</q-toolbar> </q-toolbar>
<SkeletonTable v-if="isLoading" :columns="columns" />
<d-table <d-table
v-else
flat flat
dense dense
bordered bordered
@ -460,7 +457,9 @@ onMounted(async () => {
:rows-per-page-options="[10, 25, 50, 100]" :rows-per-page-options="[10, 25, 50, 100]"
:visible-columns="visibleColumns" :visible-columns="visibleColumns"
:virtual-scroll-sticky-size-start="48" :virtual-scroll-sticky-size-start="48"
v-model:pagination="pagination" :pagination="pagination"
:loading="isLoading"
row-key="id"
> >
<template v-slot:header="props"> <template v-slot:header="props">
<q-tr :props="props"> <q-tr :props="props">

View file

@ -11,7 +11,6 @@ import { useRegistryDataStore } from "@/modules/10_registry/store/Main";
import type { InsigniaFormType } from "@/modules/10_registry/interface/index/Main"; import type { InsigniaFormType } from "@/modules/10_registry/interface/index/Main";
import DialogHistory from "@/modules/10_registry/Dialog/DialogHistory.vue"; import DialogHistory from "@/modules/10_registry/Dialog/DialogHistory.vue";
import SkeletonTable from "@/components/SkeletonTable.vue";
const $q = useQuasar(); const $q = useQuasar();
const dataPerson = useDataStore(); const dataPerson = useDataStore();
@ -555,9 +554,7 @@ onMounted(async () => {
/> />
</q-toolbar> </q-toolbar>
<SkeletonTable v-if="isLoading" :columns="columns" />
<d-table <d-table
v-else
flat flat
dense dense
bordered bordered
@ -568,7 +565,9 @@ onMounted(async () => {
:rows-per-page-options="[10, 25, 50, 100]" :rows-per-page-options="[10, 25, 50, 100]"
:visible-columns="visibleColumns" :visible-columns="visibleColumns"
:virtual-scroll-sticky-size-start="48" :virtual-scroll-sticky-size-start="48"
v-model:pagination="pagination" :pagination="pagination"
:loading="isLoading"
row-key="id"
> >
<template v-slot:header="props"> <template v-slot:header="props">
<q-tr :props="props"> <q-tr :props="props">

View file

@ -12,7 +12,6 @@ import type { HonorFormData } from "@/modules/10_registry/interface/index/Main";
//history dialog //history dialog
import DialogHistory from "@/modules/10_registry/Dialog/DialogHistory.vue"; import DialogHistory from "@/modules/10_registry/Dialog/DialogHistory.vue";
import SkeletonTable from "@/components/SkeletonTable.vue";
const $q = useQuasar(); const $q = useQuasar();
const dataPerson = useDataStore(); const dataPerson = useDataStore();
@ -339,9 +338,7 @@ onMounted(async () => {
/> />
</q-toolbar> </q-toolbar>
<SkeletonTable v-if="isLoading" :columns="columns" />
<d-table <d-table
v-else
flat flat
dense dense
bordered bordered
@ -352,7 +349,9 @@ onMounted(async () => {
:rows-per-page-options="[10, 25, 50, 100]" :rows-per-page-options="[10, 25, 50, 100]"
:visible-columns="visibleColumns" :visible-columns="visibleColumns"
:virtual-scroll-sticky-size-start="48" :virtual-scroll-sticky-size-start="48"
v-model:pagination="pagination" :pagination="pagination"
:loading="isLoading"
row-key="id"
> >
<template v-slot:header="props"> <template v-slot:header="props">
<q-tr :props="props"> <q-tr :props="props">

View file

@ -13,7 +13,6 @@ import type {
} from "@/modules/10_registry/interface/index/Main"; } from "@/modules/10_registry/interface/index/Main";
import DialogHistory from "@/modules/10_registry/Dialog/DialogHistory.vue"; import DialogHistory from "@/modules/10_registry/Dialog/DialogHistory.vue";
import SkeletonTable from "@/components/SkeletonTable.vue";
const $q = useQuasar(); const $q = useQuasar();
const dataPerson = useDataStore(); const dataPerson = useDataStore();
@ -473,9 +472,7 @@ onMounted(async () => {
/> />
</q-toolbar> </q-toolbar>
<SkeletonTable v-if="isLoading" :columns="columns" />
<d-table <d-table
v-else
flat flat
dense dense
bordered bordered
@ -486,7 +483,9 @@ onMounted(async () => {
:rows-per-page-options="[10, 25, 50, 100]" :rows-per-page-options="[10, 25, 50, 100]"
:visible-columns="visibleColumns" :visible-columns="visibleColumns"
:virtual-scroll-sticky-size-start="48" :virtual-scroll-sticky-size-start="48"
v-model:pagination="pagination" :pagination="pagination"
:loading="isLoading"
row-key="id"
> >
<template v-slot:header="props"> <template v-slot:header="props">
<q-tr :props="props"> <q-tr :props="props">

View file

@ -8,7 +8,6 @@ import { useCounterMixin } from "@/stores/mixin";
import { useDataStore } from "@/stores/data"; import { useDataStore } from "@/stores/data";
import DialogDevelop from "@/modules/10_registry/Dialog/DialogDevelopmant.vue"; import DialogDevelop from "@/modules/10_registry/Dialog/DialogDevelopmant.vue";
import SkeletonTable from "@/components/SkeletonTable.vue";
const $q = useQuasar(); const $q = useQuasar();
const dataPerson = useDataStore(); const dataPerson = useDataStore();
@ -209,9 +208,8 @@ onMounted(async () => {
:display-value="$q.lang.table.columns" :display-value="$q.lang.table.columns"
/> />
</q-toolbar> </q-toolbar>
<SkeletonTable v-if="isLoading" :columns="columns" />
<d-table <d-table
v-else
flat flat
dense dense
bordered bordered
@ -222,6 +220,9 @@ onMounted(async () => {
:rows-per-page-options="[10, 25, 50, 100]" :rows-per-page-options="[10, 25, 50, 100]"
:visible-columns="visibleColumns" :visible-columns="visibleColumns"
:virtual-scroll-sticky-size-start="48" :virtual-scroll-sticky-size-start="48"
:pagination="{ page: 1, rowsPerPage: 10 }"
:loading="isLoading"
row-key="id"
> >
<template v-slot:header="props"> <template v-slot:header="props">
<q-tr :props="props"> <q-tr :props="props">

View file

@ -10,7 +10,6 @@ import { useDataStore } from "@/stores/data";
import type { OtherFormType } from "@/modules/10_registry/interface/index/Main"; import type { OtherFormType } from "@/modules/10_registry/interface/index/Main";
import DialogHistory from "@/modules/10_registry/Dialog/DialogHistory.vue"; import DialogHistory from "@/modules/10_registry/Dialog/DialogHistory.vue";
import SkeletonTable from "@/components/SkeletonTable.vue";
const $q = useQuasar(); const $q = useQuasar();
const dataPerson = useDataStore(); const dataPerson = useDataStore();
@ -232,9 +231,7 @@ onMounted(async () => {
/> />
</q-toolbar> </q-toolbar>
<SkeletonTable v-if="isLoading" :columns="columns" />
<d-table <d-table
v-else
flat flat
dense dense
bordered bordered
@ -245,7 +242,9 @@ onMounted(async () => {
:rows-per-page-options="[10, 25, 50, 100]" :rows-per-page-options="[10, 25, 50, 100]"
:visible-columns="visibleColumns" :visible-columns="visibleColumns"
:virtual-scroll-sticky-size-start="48" :virtual-scroll-sticky-size-start="48"
v-model:pagination="pagination" :pagination="pagination"
:loading="isLoading"
row-key="id"
> >
<template v-slot:header="props"> <template v-slot:header="props">
<q-tr :props="props"> <q-tr :props="props">
@ -276,6 +275,7 @@ onMounted(async () => {
</q-td> </q-td>
</q-tr> </q-tr>
</template> </template>
<template v-else v-slot:item="props"> <template v-else v-slot:item="props">
<div class="q-mb-xs col-xs-12 col-sm-6 col-md-4 col-lg-3"> <div class="q-mb-xs col-xs-12 col-sm-6 col-md-4 col-lg-3">
<q-card bordered flat> <q-card bordered flat>
@ -308,13 +308,6 @@ onMounted(async () => {
</q-card> </q-card>
</div> </div>
</template> </template>
<template v-slot:no-data>
<div
class="full-width row flex-center q-pa-sm rounded-borders text-weight-medium"
>
<span> ไมพบขอม </span>
</div>
</template>
</d-table> </d-table>
</div> </div>

View file

@ -8,7 +8,6 @@ import type { QTableProps } from "quasar";
/** import component */ /** import component */
import DialogHeader from "@/components/DialogHeader.vue"; import DialogHeader from "@/components/DialogHeader.vue";
import SkeletonTable from "@/components/SkeletonTable.vue";
const { date2Thai, onSearchDataTable, findOrgNameHtml } = useCounterMixin(); const { date2Thai, onSearchDataTable, findOrgNameHtml } = useCounterMixin();
@ -129,11 +128,8 @@ watch(
/> />
</div> </div>
</div> </div>
<div v-if="isLoading">
<SkeletonTable :columns="columns" />
</div>
<div v-else class="col-12"> <div class="col-12">
<d-table <d-table
flat flat
dense dense
@ -144,7 +140,9 @@ watch(
:rows-per-page-options="[10, 25, 50, 100]" :rows-per-page-options="[10, 25, 50, 100]"
:visible-columns="visibleColumns" :visible-columns="visibleColumns"
:virtual-scroll-sticky-size-start="48" :virtual-scroll-sticky-size-start="48"
v-model:pagination="pagination" :pagination="pagination"
:loading="isLoading"
row-key="id"
> >
<template v-slot:header="props"> <template v-slot:header="props">
<q-tr :props="props"> <q-tr :props="props">
@ -262,13 +260,6 @@ watch(
</q-card> </q-card>
</div> </div>
</template> </template>
<template v-slot:no-data>
<div
class="full-width row flex-center q-pa-sm rounded-borders text-weight-medium"
>
<span> ไมพบขอม </span>
</div>
</template>
</d-table> </d-table>
</div> </div>
</q-card-section> </q-card-section>

View file

@ -1,5 +1,5 @@
<script setup lang="ts"> <script setup lang="ts">
import { ref, onMounted, watch } from "vue"; import { ref, onMounted } from "vue";
import config from "@/app.config"; import config from "@/app.config";
import http from "@/plugins/http"; import http from "@/plugins/http";
@ -11,15 +11,12 @@ import { useCounterMixin } from "@/stores/mixin";
/**importType*/ /**importType*/
import type { QTableProps } from "quasar"; import type { QTableProps } from "quasar";
import type { import type { PropsTable } from "@/interface/PropsTable";
DataOption, import type { DataOption } from "@/modules/10_registry/interface/index/Main";
NewPagination,
} from "@/modules/10_registry/interface/index/Main";
import type { DataRequest } from "@/modules/10_registry/interface/response/Main"; import type { DataRequest } from "@/modules/10_registry/interface/response/Main";
/** importComponents*/ /** importComponents*/
import DialogAddRequestEdit from "@/modules/10_registry/components/DialogAddRequestEdit.vue"; import DialogAddRequestEdit from "@/modules/10_registry/components/DialogAddRequestEdit.vue";
import SkeletonTable from "@/components/SkeletonTable.vue";
/** use */ /** use */
const $q = useQuasar(); const $q = useQuasar();
@ -38,10 +35,6 @@ const isLoading = ref<boolean>(false);
/** Table*/ /** Table*/
const rows = ref<DataRequest[]>([]); const rows = ref<DataRequest[]>([]);
const page = ref<number>(1);
const pageSize = ref<number>(10);
const rowsTotal = ref<number>(0);
const maxPage = ref<number>(0);
const columns = ref<QTableProps["columns"]>([ const columns = ref<QTableProps["columns"]>([
{ {
name: "no", name: "no",
@ -110,10 +103,11 @@ const visibleColumns = ref<string[]>([
"status", "status",
"remark", "remark",
]); ]);
const pagination = ref({ const pagination = ref<PropsTable.Pagination>({
descending: true, descending: true,
page: page.value, page: 1,
rowsPerPage: pageSize.value, rowsPerPage: 10,
rowsNumber: 0,
}); });
/** function กลับไปหน้าทะเบียนประวัติ*/ /** function กลับไปหน้าทะเบียนประวัติ*/
@ -129,8 +123,8 @@ function onClickAdd() {
/** function fetch รายการข้อมูลการยื่นคำร้องขอแก้ไขข้อมูล*/ /** function fetch รายการข้อมูลการยื่นคำร้องขอแก้ไขข้อมูล*/
async function fetchListRequset() { async function fetchListRequset() {
let queryParams = { let queryParams = {
page: page.value, page: pagination.value.page,
pageSize: pageSize.value, pageSize: pagination.value.rowsPerPage,
status: status.value, status: status.value,
keyword: keyword.value, keyword: keyword.value,
}; };
@ -140,10 +134,9 @@ async function fetchListRequset() {
params: queryParams, params: queryParams,
}) })
.then((res) => { .then((res) => {
const data = res.data.result; const result = res.data.result;
maxPage.value = Math.ceil(data.total / pageSize.value); pagination.value.rowsNumber = result.total;
rowsTotal.value = data.total; rows.value = result.data;
rows.value = data.data;
}) })
.catch((err) => { .catch((err) => {
messageError($q, err); messageError($q, err);
@ -155,7 +148,7 @@ async function fetchListRequset() {
/** function เลือกสถานะคำร้อง*/ /** function เลือกสถานะคำร้อง*/
function updateStatusValue() { function updateStatusValue() {
page.value = 1; pagination.value.page = 1;
fetchListRequset(); fetchListRequset();
} }
@ -180,21 +173,16 @@ function filterOption(val: string, update: Function) {
} }
/** /**
* function พเดทขนาดหนาใpagination * งกนร request จากตาราง เมอมการเปลpagination
* @param newPagination อมลใหมของ pagination * @param requestProps อมลการรองขอจากตาราง
*/ */
function updatePageSizePagination(newPagination: NewPagination) { function onTableRequest(requestProps: PropsTable.RequestProps) {
page.value = 1; const newPagination = requestProps?.pagination || requestProps;
pageSize.value = newPagination.rowsPerPage; if (!newPagination?.page || !newPagination?.rowsPerPage) return;
pagination.value = { ...newPagination };
fetchListRequset();
} }
watch(
() => pageSize.value,
() => {
fetchListRequset();
}
);
onMounted(async () => { onMounted(async () => {
link.value = await dataStore.getProFileType(); link.value = await dataStore.getProFileType();
fetchListRequset(); fetchListRequset();
@ -298,17 +286,16 @@ onMounted(async () => {
</div> </div>
</div> </div>
<div class="col-12"> <div class="col-12">
<SkeletonTable v-if="isLoading" :columns="columns" />
<d-table <d-table
v-else
:columns="columns" :columns="columns"
:rows="rows" :rows="rows"
row-key="id" row-key="id"
:rows-per-page-options="[10, 25, 50, 100]" :rows-per-page-options="[10, 25, 50, 100]"
:paging="true" :paging="true"
:visible-columns="visibleColumns" :visible-columns="visibleColumns"
@update:pagination="updatePageSizePagination"
v-model:pagination="pagination" v-model:pagination="pagination"
:loading="isLoading"
@request="onTableRequest"
> >
<template v-slot:header="props"> <template v-slot:header="props">
<q-tr :props="props"> <q-tr :props="props">
@ -338,20 +325,6 @@ onMounted(async () => {
</q-td> </q-td>
</q-tr> </q-tr>
</template> </template>
<template v-slot:pagination="scope">
งหมด {{ rowsTotal }} รายการ
<q-pagination
v-model="page"
active-color="primary"
color="dark"
:max="Number(maxPage)"
:max-pages="5"
size="sm"
boundary-links
direction-links
@update:model-value="fetchListRequset()"
></q-pagination>
</template>
</d-table> </d-table>
</div> </div>
</q-card> </q-card>

View file

@ -14,18 +14,10 @@ import type {
ProbationFormType, ProbationFormType,
} from "@/modules/11_probation/interface/index/main"; } from "@/modules/11_probation/interface/index/main";
import SkeletonTable from "@/components/SkeletonTable.vue";
const $q = useQuasar(); const $q = useQuasar();
const mixin = useCounterMixin(); const mixin = useCounterMixin();
const { const { messageError, findOrgName, hideLoader, date2Thai, onSearchDataTable } =
messageError, mixin;
findOrgName,
showLoader,
hideLoader,
date2Thai,
onSearchDataTable,
} = mixin;
const profileId = ref<string>(""); const profileId = ref<string>("");
const rows = ref<ListMain[]>([]); const rows = ref<ListMain[]>([]);
@ -312,7 +304,10 @@ onMounted(async () => {
</div> </div>
<q-resize-observer @resize="onResize" /> <q-resize-observer @resize="onResize" />
<q-card-section> <q-card-section>
<div class="text-center q-mt-md" style="display: flex;justify-content: center;"> <div
class="text-center q-mt-md"
style="display: flex; justify-content: center"
>
<q-avatar v-if="!isLoad" :size="sizeImg" rounded> <q-avatar v-if="!isLoad" :size="sizeImg" rounded>
<img <img
:src="profileImg" :src="profileImg"
@ -397,7 +392,6 @@ onMounted(async () => {
</div> </div>
<div class="q-mt-sm"> <div class="q-mt-sm">
<d-table <d-table
v-if="!isLoad"
flat flat
dense dense
bordered bordered
@ -409,6 +403,8 @@ onMounted(async () => {
:rows-per-page-options="[10, 25, 50, 100]" :rows-per-page-options="[10, 25, 50, 100]"
:visible-columns="visibleColumns" :visible-columns="visibleColumns"
:virtual-scroll-sticky-size-start="48" :virtual-scroll-sticky-size-start="48"
:pagination="{ page: 1, rowsPerPage: 10 }"
:loading="isLoad"
> >
<template v-slot:header="props"> <template v-slot:header="props">
<q-tr :props="props"> <q-tr :props="props">
@ -471,15 +467,7 @@ onMounted(async () => {
</q-card> </q-card>
</div> </div>
</template> </template>
<template v-slot:no-data>
<div
class="full-width row flex-center q-pa-sm rounded-borders text-weight-medium"
>
<span> ไมพบขอม </span>
</div>
</template>
</d-table> </d-table>
<SkeletonTable v-else :columns="columns" />
</div> </div>
</q-card> </q-card>
</div> </div>

View file

@ -10,8 +10,6 @@ import { useCounterMixin } from "@/stores/mixin";
import type { PortfolioRowsType } from "@/modules/13_portfolio/interface/Main"; import type { PortfolioRowsType } from "@/modules/13_portfolio/interface/Main";
import SkeletonTable from "@/components/SkeletonTable.vue";
const $q = useQuasar(); const $q = useQuasar();
const router = useRouter(); const router = useRouter();
const mixin = useCounterMixin(); const mixin = useCounterMixin();
@ -115,7 +113,6 @@ function onDelete(id: string) {
}); });
} }
/** ฟังก์ชั่นค้นหาข้อมูลในตาราง */ /** ฟังก์ชั่นค้นหาข้อมูลในตาราง */
function onSearch() { function onSearch() {
rows.value = onSearchDataTable( rows.value = onSearchDataTable(
@ -125,6 +122,10 @@ function onSearch() {
); );
} }
function onTableRequest() {
console.log(1111);
}
/** Hook Lifecycle */ /** Hook Lifecycle */
onMounted(async () => { onMounted(async () => {
await fecthList(); await fecthList();
@ -199,35 +200,21 @@ onMounted(async () => {
</div> </div>
</div> </div>
<SkeletonTable v-if="isLoading" :columns="columns" /> <div class="col-12">
<div class="col-12" v-else>
<d-table <d-table
flat flat
bordered bordered
dense dense
:paging="true" :paging="true"
row-key="id" row-key="id"
class="custom-table2"
style="max-height: 80vh"
:rows="rows" :rows="rows"
:columns="columns" :columns="columns"
:visible-columns="visibleColumns" :visible-columns="visibleColumns"
:rows-per-page-options="[10, 25, 50, 100]" :rows-per-page-options="[10, 25, 50, 100]"
v-model:pagination="pagination" :pagination="pagination"
:loading="isLoading"
@request="onTableRequest"
> >
<template v-slot:pagination="scope">
งหมด {{ rows.length }} รายการ
<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>
<template v-slot:header="props"> <template v-slot:header="props">
<q-tr :props="props"> <q-tr :props="props">
<q-th <q-th

View file

@ -8,10 +8,9 @@ import config from "@/app.config";
import { useCounterMixin } from "@/stores/mixin"; import { useCounterMixin } from "@/stores/mixin";
import { useIndividualDevelopmentPlan } from "@/modules/14_IDP/store"; // store IDP import { useIndividualDevelopmentPlan } from "@/modules/14_IDP/store"; // store IDP
import type { PropsTable } from "@/interface/PropsTable";
import type { DataOption, RowsListMain } from "@/modules/14_IDP/interface/Main"; import type { DataOption, RowsListMain } from "@/modules/14_IDP/interface/Main";
import SkeletonTable from "@/components/SkeletonTable.vue";
const $q = useQuasar(); const $q = useQuasar();
const router = useRouter(); const router = useRouter();
const mixin = useCounterMixin(); const mixin = useCounterMixin();
@ -23,13 +22,12 @@ const filterKeyword = ref<string>("");
const status = ref<string>("ALL"); // const status = ref<string>("ALL"); //
const statusOptions = ref<DataOption[]>(store.optionStatus); const statusOptions = ref<DataOption[]>(store.optionStatus);
const rows = ref<RowsListMain[]>([]); const rows = ref<RowsListMain[]>([]);
const total = ref<number>(0); const pagination = ref<PropsTable.Pagination>({
const totalList = ref<number>(1);
const pagination = ref({
sortBy: "createdAt", sortBy: "createdAt",
descending: true, descending: true,
page: 1, page: 1,
rowsPerPage: 10, rowsPerPage: 10,
rowsNumber: 0,
}); });
const visibleColumns = ref<string[]>([ const visibleColumns = ref<string[]>([
"no", "no",
@ -186,11 +184,9 @@ async function getListData() {
` `
) )
.then(async (res) => { .then(async (res) => {
const data = await res.data.result.data; const result = await res.data.result;
const dataTotal = await res.data.result.total; pagination.value.rowsNumber = result.total;
totalList.value = Math.ceil(dataTotal / pagination.value.rowsPerPage); rows.value = result.data;
total.value = dataTotal;
rows.value = data;
}) })
.catch((e) => { .catch((e) => {
messageError($q, e); messageError($q, e);
@ -245,10 +241,15 @@ async function downloadUrl(id: string, fileName: string) {
}); });
} }
/** เมื่อมีการเปลี่ยน แถว ดึงข้อมูลใหม่ */ /**
function updatePagination(newPagination: any) { * งกนร request จากตาราง เมอมการเปลยน pagination
pagination.value.page = 1; * @param requestProps อมลการรองขอจากตาราง
pagination.value.rowsPerPage = newPagination.rowsPerPage; */
function onTableRequest(requestProps: PropsTable.RequestProps) {
const newPagination = requestProps?.pagination || requestProps;
if (!newPagination?.page || !newPagination?.rowsPerPage) return;
pagination.value = { ...newPagination };
getListData();
} }
/** /**
@ -264,13 +265,6 @@ function getSerach() {
getListData(); getListData();
} }
watch(
() => pagination.value.rowsPerPage,
async () => {
await getListData();
}
);
onMounted(async () => { onMounted(async () => {
await getListData(); await getListData();
}); });
@ -366,17 +360,16 @@ onMounted(async () => {
</div> </div>
<div class="col-12"> <div class="col-12">
<SkeletonTable v-if="isLoading" :columns="columns" />
<d-table <d-table
v-else
:columns="columns" :columns="columns"
:rows="rows" :rows="rows"
row-key="id" row-key="id"
:paging="true" :paging="true"
:visible-columns="visibleColumns" :visible-columns="visibleColumns"
:rows-per-page-options="[10, 25, 50, 100]" :rows-per-page-options="[10, 25, 50, 100]"
@update:pagination="updatePagination" @request="onTableRequest"
v-model:pagination="pagination" v-model:pagination="pagination"
:loading="isLoading"
> >
<template v-slot:header="props"> <template v-slot:header="props">
<q-tr :props="props"> <q-tr :props="props">
@ -459,20 +452,6 @@ onMounted(async () => {
</q-td> </q-td>
</q-tr> </q-tr>
</template> </template>
<template v-slot:pagination="scope">
งหมด {{ total }} รายการ
<q-pagination
v-model="pagination.page"
active-color="primary"
color="dark"
:max="Number(totalList)"
size="sm"
boundary-links
direction-links
:max-pages="5"
@update:model-value="getListData()"
></q-pagination>
</template>
</d-table> </d-table>
</div> </div>
</q-card> </q-card>