fix load Table
This commit is contained in:
parent
1ec4a97538
commit
d39753fbde
56 changed files with 684 additions and 978 deletions
|
|
@ -14,8 +14,6 @@ import type {
|
|||
TransferMain,
|
||||
} from "@/modules/02_transfer/interface/Main";
|
||||
|
||||
import SkeletonTable from "@/components/SkeletonTable.vue";
|
||||
|
||||
const $q = useQuasar();
|
||||
const router = useRouter();
|
||||
const mixin = useCounterMixin();
|
||||
|
|
@ -247,33 +245,18 @@ onMounted(async () => {
|
|||
</div>
|
||||
<div>
|
||||
<d-table
|
||||
v-if="!isLoading"
|
||||
flat
|
||||
bordered
|
||||
dense
|
||||
:paging="true"
|
||||
row-key="id"
|
||||
class="custom-table2"
|
||||
style="max-height: 80vh"
|
||||
:rows="rows"
|
||||
:columns="columns"
|
||||
:visible-columns="visibleColumns"
|
||||
: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">
|
||||
<q-tr :props="props">
|
||||
<q-th
|
||||
|
|
@ -341,11 +324,11 @@ onMounted(async () => {
|
|||
</div>
|
||||
</template>
|
||||
</d-table>
|
||||
<SkeletonTable v-else :columns="columns" />
|
||||
</div>
|
||||
</q-card>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped lang="scss"></style>
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ import Dialog from "@/modules/03_retire/views/DialogRetire.vue";
|
|||
import Header from "@/components/DialogHeader.vue";
|
||||
import Workflow from "@/components/Workflow/Main.vue";
|
||||
|
||||
import SkeletonTable from "@/components/SkeletonTable.vue";
|
||||
|
||||
|
||||
const $q = useQuasar();
|
||||
const route = useRoute();
|
||||
|
|
@ -608,7 +608,6 @@ onMounted(async () => {
|
|||
<q-separator />
|
||||
<div class="col-12 q-pa-sm">
|
||||
<d-table
|
||||
v-if="!isLoad"
|
||||
ref="table"
|
||||
:columns="columnsCommanders"
|
||||
:rows="rowsApprover?.commanders ?? []"
|
||||
|
|
@ -618,6 +617,8 @@ onMounted(async () => {
|
|||
:paging="true"
|
||||
dense
|
||||
:rows-per-page-options="[1, 25, 50, 100]"
|
||||
:pagination="{ page: 1, rowsPerPage: 10 }"
|
||||
:loading="isLoad"
|
||||
>
|
||||
<template v-slot:header="props">
|
||||
<q-tr :props="props">
|
||||
|
|
@ -657,7 +658,6 @@ onMounted(async () => {
|
|||
</q-tr>
|
||||
</template>
|
||||
</d-table>
|
||||
<SkeletonTable v-else :columns="columnsCommanders" />
|
||||
</div>
|
||||
</q-card>
|
||||
</div>
|
||||
|
|
@ -769,7 +769,6 @@ onMounted(async () => {
|
|||
<q-separator />
|
||||
<div class="col-12 q-pa-sm">
|
||||
<d-table
|
||||
v-if="!isLoad"
|
||||
ref="table"
|
||||
:columns="columnsCommanders"
|
||||
:rows="rowsApprover?.cancelCommanders ?? []"
|
||||
|
|
@ -779,6 +778,8 @@ onMounted(async () => {
|
|||
:paging="true"
|
||||
dense
|
||||
:rows-per-page-options="[1, 25, 50, 100]"
|
||||
:pagination="{ page: 1, rowsPerPage: 10 }"
|
||||
:loading="isLoad"
|
||||
>
|
||||
<template v-slot:header="props">
|
||||
<q-tr :props="props">
|
||||
|
|
@ -818,7 +819,6 @@ onMounted(async () => {
|
|||
</q-tr>
|
||||
</template>
|
||||
</d-table>
|
||||
<SkeletonTable v-else :columns="columnsCommanders" />
|
||||
</div>
|
||||
</q-card>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -15,15 +15,12 @@ import type {
|
|||
MainListResponse,
|
||||
} from "@/modules/03_retire/interface/Main";
|
||||
|
||||
import SkeletonTable from "@/components/SkeletonTable.vue";
|
||||
|
||||
const $q = useQuasar();
|
||||
const router = useRouter();
|
||||
const link = ref<string>("");
|
||||
const dataStore = useDataStore();
|
||||
const mixin = useCounterMixin();
|
||||
const { date2Thai, messageError, showLoader, hideLoader, onSearchDataTable } =
|
||||
mixin;
|
||||
const { date2Thai, messageError, onSearchDataTable } = mixin;
|
||||
const RestData = useRestDataStore();
|
||||
const { statusText } = RestData; //Func แปลง status to text
|
||||
|
||||
|
|
@ -200,8 +197,7 @@ onMounted(async () => {
|
|||
</div>
|
||||
<div>
|
||||
<d-table
|
||||
v-if="!isLoad"
|
||||
flat
|
||||
fla
|
||||
bordered
|
||||
dense
|
||||
row-key="id"
|
||||
|
|
@ -210,20 +206,8 @@ onMounted(async () => {
|
|||
:visible-columns="visibleColumns"
|
||||
:rows-per-page-options="[10, 25, 50, 100]"
|
||||
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">
|
||||
<q-tr :props="props">
|
||||
<q-th
|
||||
|
|
@ -280,7 +264,6 @@ onMounted(async () => {
|
|||
</div>
|
||||
</template>
|
||||
</d-table>
|
||||
<SkeletonTable v-else :columns="columns" />
|
||||
</div>
|
||||
</q-card>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
<script setup lang="ts">
|
||||
import { onMounted, ref, watch } from "vue";
|
||||
import { ref } from "vue";
|
||||
import { useQuasar, type QTableProps } from "quasar";
|
||||
|
||||
import http from "@/plugins/http";
|
||||
|
|
@ -8,15 +8,16 @@ import { useCounterMixin } from "@/stores/mixin";
|
|||
import { useLeaveStore } from "@/modules/05_leave/store";
|
||||
import { useDataStore } from "@/stores/data";
|
||||
|
||||
import DialogHeader from "@/components/DialogHeader.vue";
|
||||
import SkeletonTable from "@/components/SkeletonTable.vue";
|
||||
import type { PropsTable } from "@/interface/PropsTable";
|
||||
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 storeData = useDataStore();
|
||||
const { date2Thai, showLoader, hideLoader, messageError } = mixin;
|
||||
const { date2Thai, messageError } = useCounterMixin();
|
||||
|
||||
const modal = ref<boolean>(false);
|
||||
/** รับ props มาจากหน้าหลัก */
|
||||
const props = defineProps({
|
||||
model: {
|
||||
|
|
@ -25,21 +26,13 @@ const props = defineProps({
|
|||
},
|
||||
});
|
||||
|
||||
const $q = useQuasar();
|
||||
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 modal = ref<boolean>(false);
|
||||
|
||||
const selected = ref<any[]>([]);
|
||||
const isAct = ref<boolean>(false);
|
||||
const selected = ref<DataCommander[]>([]);
|
||||
const search = ref<string>("");
|
||||
const isLoading = ref<boolean>(false);
|
||||
const rows = ref<any[]>([]);
|
||||
const rows = ref<DataCommander[]>([]);
|
||||
const columns = ref<QTableProps["columns"]>([
|
||||
{
|
||||
name: "posNo",
|
||||
|
|
@ -72,28 +65,15 @@ const columns = ref<QTableProps["columns"]>([
|
|||
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() {
|
||||
isLoading.value = true;
|
||||
await http
|
||||
|
|
@ -109,11 +89,12 @@ async function getCommander() {
|
|||
: "employee",
|
||||
})
|
||||
.then((res) => {
|
||||
rows.value = res.data.result.data;
|
||||
total.value = res.data.result.total;
|
||||
totalList.value = Math.ceil(
|
||||
res.data.result.total / pagination.value.rowsPerPage
|
||||
);
|
||||
const result = res.data.result;
|
||||
rows.value = result.data;
|
||||
pagination.value = {
|
||||
...pagination.value,
|
||||
rowsNumber: result.total,
|
||||
};
|
||||
})
|
||||
.catch((e) => {
|
||||
messageError($q, e);
|
||||
|
|
@ -123,25 +104,53 @@ async function getCommander() {
|
|||
});
|
||||
}
|
||||
|
||||
function updatePagination(newPagination: any) {
|
||||
pagination.value.rowsPerPage = newPagination.rowsPerPage;
|
||||
/*** ฟังก์ชันสำหรับเปิด Modal และดึงข้อมูลผู้บังคับบัญชา */
|
||||
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() {
|
||||
pagination.value.page = 1;
|
||||
getCommander();
|
||||
}
|
||||
|
||||
watch(
|
||||
() => pagination.value.rowsPerPage,
|
||||
async () => {
|
||||
getSearch();
|
||||
}
|
||||
);
|
||||
|
||||
/**Hook */
|
||||
onMounted(() => {
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
|
|
@ -227,15 +236,6 @@ onMounted(() => {
|
|||
v-model="dataStore.typeLeave"
|
||||
label="เรื่อง"
|
||||
/>
|
||||
<!-- <q-input
|
||||
class="col-12 col-sm-4"
|
||||
dense
|
||||
outlined
|
||||
readonly
|
||||
bg-color="white"
|
||||
v-model="dataStore.commanderPosition"
|
||||
label="เรียน"
|
||||
/> -->
|
||||
|
||||
<q-input
|
||||
class="col-12 col-sm-4"
|
||||
|
|
@ -315,7 +315,7 @@ onMounted(() => {
|
|||
<div class="row q-col-gutter-sm">
|
||||
<div class="col-12">
|
||||
<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
|
||||
v-model="search"
|
||||
outlined
|
||||
|
|
@ -325,17 +325,20 @@ onMounted(() => {
|
|||
@keydown.enter.prevent="getSearch()"
|
||||
/>
|
||||
</div>
|
||||
<q-checkbox
|
||||
keep-color
|
||||
v-model="isAct"
|
||||
label="แสดงเฉพาะรักษาการแทน"
|
||||
color="primary"
|
||||
>
|
||||
<q-tooltip>แสดงเฉพาะรักษาการแทน </q-tooltip>
|
||||
</q-checkbox>
|
||||
<q-space />
|
||||
<div class="col-12 col-sm-6 col-md-4">
|
||||
<q-checkbox
|
||||
keep-color
|
||||
v-model="isAct"
|
||||
label="แสดงเฉพาะรักษาการแทน"
|
||||
color="primary"
|
||||
@update:model-value="getSearch()"
|
||||
>
|
||||
<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
|
||||
color="primary"
|
||||
icon="search"
|
||||
|
|
@ -349,9 +352,7 @@ onMounted(() => {
|
|||
</div>
|
||||
</div>
|
||||
<div class="col-12">
|
||||
<SkeletonTable v-if="isLoading" :columns="columns" />
|
||||
<d-table
|
||||
v-else
|
||||
ref="table"
|
||||
:columns="columns"
|
||||
:rows="rows"
|
||||
|
|
@ -362,25 +363,11 @@ onMounted(() => {
|
|||
dense
|
||||
:rows-per-page-options="[10, 25, 50, 100]"
|
||||
selection="single"
|
||||
@update:pagination="updatePagination"
|
||||
v-model:pagination="pagination"
|
||||
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">
|
||||
<q-checkbox
|
||||
keep-color
|
||||
|
|
|
|||
|
|
@ -2,8 +2,8 @@
|
|||
import { ref, useAttrs, watch } from "vue";
|
||||
import { useQuasar } from "quasar";
|
||||
|
||||
import type { PropsTable } from "@/interface/PropsTable";
|
||||
import { useLeaveStore } from "@/modules/05_leave/store";
|
||||
import SkeletonTable from "@/components/SkeletonTable.vue";
|
||||
|
||||
const $q = useQuasar();
|
||||
const attrs = ref<any>(useAttrs());
|
||||
|
|
@ -54,13 +54,26 @@ const table = ref<any>(null);
|
|||
|
||||
/** ตั้งค่า pagination*/
|
||||
const currentPage = ref<number>(1);
|
||||
const pagination = ref({
|
||||
|
||||
const pagination = ref<PropsTable.Pagination>({
|
||||
sortBy: "dateSendLeave",
|
||||
descending: true,
|
||||
page: 1,
|
||||
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 */
|
||||
const year = ref<number>(new Date().getFullYear());
|
||||
const filter = ref<string>("");
|
||||
|
|
@ -86,18 +99,17 @@ function updatePagination(p: number, ps: number) {
|
|||
emit("update:Pagination", p, ps);
|
||||
}
|
||||
|
||||
/** function updatePageSize*/
|
||||
function updatePageSize(newPageSize: any) {
|
||||
pagination.value.rowsPerPage = newPageSize.rowsPerPage;
|
||||
/**
|
||||
* ฟังก์ชันรับ request จากตาราง เมื่อมีการเปลี่ยน pagination
|
||||
* @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>
|
||||
|
||||
<template>
|
||||
|
|
@ -240,9 +252,7 @@ watch(
|
|||
</q-card>
|
||||
</div>
|
||||
<div>
|
||||
<SkeletonTable v-if="isloadingData" :columns="leaveStore.columns" />
|
||||
<d-table
|
||||
v-else
|
||||
ref="table"
|
||||
flat
|
||||
bordered
|
||||
|
|
@ -251,9 +261,11 @@ watch(
|
|||
:virtual-scroll-sticky-size-start="48"
|
||||
dense
|
||||
:rows-per-page-options="[10, 25, 50, 100]"
|
||||
D
|
||||
v-model:pagination="pagination"
|
||||
@update:pagination="updatePageSize"
|
||||
@request="onTableRequest"
|
||||
:grid="$q.screen.gt.xs ? false : true"
|
||||
:loading="isloadingData"
|
||||
>
|
||||
<template v-slot:header="props">
|
||||
<q-tr :props="props">
|
||||
|
|
@ -262,21 +274,6 @@ watch(
|
|||
</q-th>
|
||||
</q-tr>
|
||||
</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">
|
||||
<slot v-bind="props" name="columns"></slot>
|
||||
</template>
|
||||
|
|
|
|||
34
src/modules/05_leave/interface/response/main.ts
Normal file
34
src/modules/05_leave/interface/response/main.ts
Normal 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 };
|
||||
|
|
@ -459,7 +459,6 @@ onMounted(() => {
|
|||
<q-skeleton
|
||||
v-if="isLoadingFile['fileEvaluation1']"
|
||||
height="120px"
|
||||
type="QCard"
|
||||
/>
|
||||
<q-card v-else bordered>
|
||||
<div
|
||||
|
|
@ -552,7 +551,6 @@ onMounted(() => {
|
|||
<q-skeleton
|
||||
v-if="isLoadingFile['fileEvaluation2']"
|
||||
height="120px"
|
||||
type="QCard"
|
||||
/>
|
||||
<q-card v-else bordered>
|
||||
<div
|
||||
|
|
@ -645,7 +643,6 @@ onMounted(() => {
|
|||
<q-skeleton
|
||||
v-if="isLoadingFile['fileEvaluation3']"
|
||||
height="120px"
|
||||
type="QCard"
|
||||
/>
|
||||
<q-card v-else bordered>
|
||||
<div
|
||||
|
|
@ -738,7 +735,6 @@ onMounted(() => {
|
|||
<q-skeleton
|
||||
v-if="isLoadingFile['fileEvaluation5']"
|
||||
height="120px"
|
||||
type="QCard"
|
||||
/>
|
||||
<q-card v-else bordered>
|
||||
<div
|
||||
|
|
@ -830,7 +826,6 @@ onMounted(() => {
|
|||
<q-skeleton
|
||||
v-if="isLoadingFile['fileEvaluation4']"
|
||||
height="120px"
|
||||
type="QCard"
|
||||
/>
|
||||
<q-card v-else bordered>
|
||||
<div
|
||||
|
|
@ -921,7 +916,6 @@ onMounted(() => {
|
|||
<q-skeleton
|
||||
v-if="isLoadingFile['fileEvaluation6']"
|
||||
height="120px"
|
||||
type="QCard"
|
||||
/>
|
||||
<q-card v-else bordered>
|
||||
<div
|
||||
|
|
|
|||
|
|
@ -99,12 +99,7 @@ watch(modal, (v) => {
|
|||
<q-separator />
|
||||
<q-card-section>
|
||||
<div class="row q-col-gutter-sm q-pb-sm">
|
||||
<q-skeleton
|
||||
v-if="isLoading"
|
||||
type="Qcard"
|
||||
width="100%"
|
||||
height="240px"
|
||||
/>
|
||||
<q-skeleton v-if="isLoading" width="100%" height="240px" />
|
||||
|
||||
<div
|
||||
v-else
|
||||
|
|
|
|||
|
|
@ -1,47 +1,35 @@
|
|||
<script setup lang="ts">
|
||||
import { ref, onMounted, watch } from "vue";
|
||||
import { ref, onMounted } from "vue";
|
||||
import { useRouter } from "vue-router";
|
||||
import { useQuasar } from "quasar";
|
||||
|
||||
import type { PropsTable } from "@/interface/PropsTable";
|
||||
import type { QTableProps } from "quasar";
|
||||
|
||||
import config from "@/app.config";
|
||||
import http from "@/plugins/http";
|
||||
import { useEvaluateStore } from "@/modules/06_evaluate/store";
|
||||
import { useCounterMixin } from "@/stores/mixin";
|
||||
import SkeletonTable from "@/components/SkeletonTable.vue";
|
||||
|
||||
/** use*/
|
||||
const $q = useQuasar();
|
||||
const store = useEvaluateStore();
|
||||
const mixin = useCounterMixin();
|
||||
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 isLoading = defineModel<boolean>("isLoading", {
|
||||
default: false,
|
||||
});
|
||||
const pagination = defineModel<PropsTable.Pagination>("pagination", {
|
||||
required: true,
|
||||
});
|
||||
|
||||
const props = defineProps({
|
||||
page: {
|
||||
type: Number,
|
||||
require: true,
|
||||
},
|
||||
pageSize: {
|
||||
type: Number,
|
||||
require: true,
|
||||
},
|
||||
maxPage: {
|
||||
type: Number,
|
||||
require: true,
|
||||
},
|
||||
fetchData: {
|
||||
type: Function,
|
||||
require: true,
|
||||
},
|
||||
isLoading: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
});
|
||||
|
||||
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 ลบรายการประเมิน
|
||||
* @param id รายการประเมิน
|
||||
*/
|
||||
async function onCkilckDelete(id: string) {
|
||||
async function onClickDelete(id: string) {
|
||||
dialogRemove($q, async () => {
|
||||
showLoader();
|
||||
await http
|
||||
|
|
@ -132,6 +106,17 @@ function redirectToDetail(data: any) {
|
|||
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*/
|
||||
onMounted(() => {
|
||||
store.columns = columns.value;
|
||||
|
|
@ -140,20 +125,19 @@ onMounted(() => {
|
|||
</script>
|
||||
|
||||
<template>
|
||||
<SkeletonTable v-if="isLoading" :columns="columns" />
|
||||
<d-table
|
||||
v-else
|
||||
ref="table"
|
||||
flat
|
||||
bordered
|
||||
class="custom-header-table"
|
||||
bordere
|
||||
:columns="columns"
|
||||
:rows="store.row"
|
||||
dense
|
||||
:visible-columns="store.visibleColumns"
|
||||
:rows-per-page-options="[10, 25, 50, 100]"
|
||||
@update:pagination="updatePagination"
|
||||
@request="onTableRequest"
|
||||
v-model:pagination="pagination"
|
||||
:loading="isLoading"
|
||||
row-key="id"
|
||||
>
|
||||
<template v-slot:header="props">
|
||||
<q-tr :props="props">
|
||||
|
|
@ -190,7 +174,7 @@ onMounted(() => {
|
|||
round
|
||||
color="red"
|
||||
icon="delete"
|
||||
@click.stop="onCkilckDelete(props.row.id)"
|
||||
@click.stop="onClickDelete(props.row.id)"
|
||||
>
|
||||
<q-tooltip>ลบ</q-tooltip>
|
||||
</q-btn>
|
||||
|
|
@ -235,7 +219,7 @@ onMounted(() => {
|
|||
round
|
||||
color="red"
|
||||
icon="delete"
|
||||
@click.stop="onCkilckDelete(props.row.id)"
|
||||
@click.stop="onClickDelete(props.row.id)"
|
||||
>
|
||||
<q-tooltip>ลบ</q-tooltip>
|
||||
</q-btn>
|
||||
|
|
@ -243,48 +227,7 @@ onMounted(() => {
|
|||
</q-card>
|
||||
</div>
|
||||
</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>
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.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>
|
||||
<style lang="scss" scoped></style>
|
||||
|
|
|
|||
|
|
@ -90,13 +90,7 @@ onMounted(() => {
|
|||
</script>
|
||||
|
||||
<template>
|
||||
<q-skeleton
|
||||
v-if="isLoading"
|
||||
class="q-mb-md"
|
||||
type="Qcard"
|
||||
width="100%"
|
||||
height="100%"
|
||||
/>
|
||||
<q-skeleton v-if="isLoading" class="q-mb-md" width="100%" height="100%" />
|
||||
<div class="q-pa-sm" v-else>
|
||||
<q-list dense>
|
||||
<q-item v-ripple class="listItem">
|
||||
|
|
|
|||
|
|
@ -349,7 +349,7 @@ onMounted(async () => {
|
|||
<div class="col-12 q-pa-sm">
|
||||
<!-- ผลงาน -->
|
||||
<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">
|
||||
<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">
|
||||
<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">
|
||||
<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"
|
||||
: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>
|
||||
<div
|
||||
|
|
|
|||
|
|
@ -235,7 +235,6 @@ onMounted(async () => {
|
|||
<div class="row q-col-gutter-sm q-pa-sm">
|
||||
<div class="col-6" v-for="(item, index) in formTemplates" :key="index">
|
||||
<q-skeleton
|
||||
type="Qcard"
|
||||
:height="store.currentStep !== 4 ? '50px' : '100px'"
|
||||
v-if="item.isLoading"
|
||||
/>
|
||||
|
|
|
|||
|
|
@ -96,11 +96,7 @@ onMounted(async () => {
|
|||
|
||||
<template>
|
||||
<div class="row col-12 q-pa-sm">
|
||||
<q-skeleton
|
||||
v-if="isLoading"
|
||||
type="Qcard"
|
||||
style="width: 100%; height: 300px"
|
||||
/>
|
||||
<q-skeleton v-if="isLoading" style="width: 100%; height: 300px" />
|
||||
<div v-else class="row col-12 q-col-gutter-sm">
|
||||
<div class="col-12 text-center">
|
||||
<q-banner rounded class="text-weight-bold text-red-14 bg-red-1">
|
||||
|
|
|
|||
|
|
@ -251,7 +251,7 @@ onMounted(async () => {
|
|||
<div class="row col-12 q-pa-sm">
|
||||
<div class="row col-12 q-col-gutter-sm">
|
||||
<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">
|
||||
<div class="text-weight-bold">
|
||||
<q-icon name="info_outline" color="red-14" size="24px" />
|
||||
|
|
@ -262,7 +262,7 @@ onMounted(async () => {
|
|||
|
||||
<!-- ผลงาน -->
|
||||
<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
|
||||
v-else
|
||||
|
|
@ -373,7 +373,7 @@ onMounted(async () => {
|
|||
|
||||
<!-- เลือกผู้เซ็นเอกสาร -->
|
||||
<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
|
||||
v-else
|
||||
bordered
|
||||
|
|
@ -548,7 +548,7 @@ onMounted(async () => {
|
|||
|
||||
<!-- อัปไฟล์ -->
|
||||
<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
|
||||
v-else
|
||||
bordered
|
||||
|
|
|
|||
|
|
@ -181,7 +181,6 @@ onMounted(async () => {
|
|||
"
|
||||
>
|
||||
<q-skeleton
|
||||
type="Qcard"
|
||||
:height="store.currentStep !== 8 ? '50px' : '100px'"
|
||||
v-if="isLoadingFile"
|
||||
/>
|
||||
|
|
|
|||
|
|
@ -9,12 +9,11 @@ import config from "@/app.config";
|
|||
import { useCounterMixin } from "@/stores/mixin";
|
||||
|
||||
import HeaderDialog from "@/components/DialogHeader.vue";
|
||||
import SkeletonTable from "@/components/SkeletonTable.vue";
|
||||
|
||||
const $q = useQuasar();
|
||||
const route = useRoute();
|
||||
const mixins = useCounterMixin();
|
||||
const { showLoader, hideLoader, date2Thai, messageError } = mixins;
|
||||
const { date2Thai, messageError } = mixins;
|
||||
|
||||
const isLoading = ref<boolean>(false);
|
||||
|
||||
|
|
@ -127,9 +126,7 @@ watch(
|
|||
<q-card-section>
|
||||
<div class="col-xs-12 col-sm-12 col-md-12 row q-col-gutter-md">
|
||||
<div class="col-12">
|
||||
<SkeletonTable v-if="isLoading" :columns="columns" />
|
||||
<d-table
|
||||
v-else
|
||||
ref="table"
|
||||
flat
|
||||
bordered
|
||||
|
|
@ -138,6 +135,8 @@ watch(
|
|||
:rows="row"
|
||||
dense
|
||||
:rows-per-page-options="[10, 25, 50, 100]"
|
||||
:pagination="{ page: 1, rowsPerPage: 10 }"
|
||||
:loading="isLoading"
|
||||
>
|
||||
<template v-slot:header="props">
|
||||
<q-tr :props="props">
|
||||
|
|
|
|||
|
|
@ -1,6 +1,4 @@
|
|||
<script setup lang="ts">
|
||||
import SkeletonTable from "@/components/SkeletonTable.vue";
|
||||
|
||||
const props = defineProps({
|
||||
columns: {
|
||||
type: Array as () => any[],
|
||||
|
|
@ -19,9 +17,7 @@ const props = defineProps({
|
|||
|
||||
<template>
|
||||
<div class="q-pa-sm row col-12">
|
||||
<SkeletonTable class="col-12" v-if="isLoading" :columns="props.columns" />
|
||||
<d-table
|
||||
v-else
|
||||
ref="table"
|
||||
flat
|
||||
bordered
|
||||
|
|
@ -32,6 +28,9 @@ const props = defineProps({
|
|||
virtual-scroll
|
||||
class="row col-12"
|
||||
:style="$q.screen.lt.sm ? 'width: 80vw' : 'width: 50vw;'"
|
||||
:pagination="{ page: 1, rowsPerPage: 10 }"
|
||||
:loading="isLoading"
|
||||
row-key="id"
|
||||
>
|
||||
<template v-slot:header="props">
|
||||
<q-tr :props="props" class="bg-grey-2">
|
||||
|
|
@ -54,30 +53,4 @@ const props = defineProps({
|
|||
</div>
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.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>
|
||||
<style lang="scss" scoped></style>
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ div
|
|||
<script setup lang="ts">
|
||||
import { reactive, onMounted, ref } from "vue";
|
||||
import { useRoute } from "vue-router";
|
||||
import { is, useQuasar } from "quasar";
|
||||
import { useQuasar } from "quasar";
|
||||
|
||||
import http from "@/plugins/http";
|
||||
import config from "@/app.config";
|
||||
|
|
@ -21,7 +21,6 @@ import type {
|
|||
/** importComponents*/
|
||||
import TableData from "@/modules/06_evaluate/components/viewstep/tableStep1.vue";
|
||||
import HeaderDialog from "@/components/DialogHeader.vue";
|
||||
import SkeletonTable from "@/components/SkeletonTable.vue";
|
||||
|
||||
/** use*/
|
||||
const mixin = useCounterMixin();
|
||||
|
|
@ -410,7 +409,7 @@ onMounted(async () => {
|
|||
>
|
||||
<div class="row col-12">
|
||||
<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>
|
||||
<q-card v-else class="col-12 cardSp1" bordered>
|
||||
<div class="text-weight-bold row items-center bg-grey-2 col-12">
|
||||
|
|
@ -516,7 +515,7 @@ onMounted(async () => {
|
|||
</q-card>
|
||||
|
||||
<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>
|
||||
<q-card v-else class="col-12 cardSp1" bordered>
|
||||
<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>
|
||||
</div>
|
||||
<div class="col-12"><q-separator /></div>
|
||||
|
||||
<div class="col-10">
|
||||
<SkeletonTable
|
||||
v-if="isLoading.loadSalary"
|
||||
:columns="columnSalaries"
|
||||
/>
|
||||
<div class="col-10 q-pa-sm">
|
||||
<d-table
|
||||
v-else
|
||||
ref="table"
|
||||
row-key="id"
|
||||
flat
|
||||
|
|
@ -685,6 +678,8 @@ onMounted(async () => {
|
|||
:rows="formDetail.salaries"
|
||||
:paging="true"
|
||||
:rows-per-page-options="[20, 50, 100]"
|
||||
:pagination="{ page: 1, rowsPerPage: 20 }"
|
||||
:loading="isLoading.loadSalary"
|
||||
>
|
||||
<template v-slot:header="props">
|
||||
<q-tr :props="props">
|
||||
|
|
@ -768,13 +763,7 @@ onMounted(async () => {
|
|||
<div class="col-12"><q-separator /></div>
|
||||
<div class="col-10">
|
||||
<div class="q-pa-sm row col-12">
|
||||
<SkeletonTable
|
||||
v-if="isLoading.loadExperience"
|
||||
:columns="columnAssessments"
|
||||
class="col-12"
|
||||
/>
|
||||
<d-table
|
||||
v-else
|
||||
flat
|
||||
bordered
|
||||
:columns="columnAssessments"
|
||||
|
|
@ -784,6 +773,8 @@ onMounted(async () => {
|
|||
virtual-scroll
|
||||
class="row col-12"
|
||||
:style="$q.screen.lt.sm ? 'width: 80vw' : 'width: 50vw;'"
|
||||
:pagination="{ page: 1, rowsPerPage: 20 }"
|
||||
:loading="isLoading.loadExperience"
|
||||
>
|
||||
<template v-slot:header="props">
|
||||
<q-tr :props="props" class="bg-grey-2">
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@ import TableListEvaluate from "@/modules/06_evaluate/components/TableListEvaluat
|
|||
import DialogMain from "@/modules/06_evaluate/components/DialogMain.vue"; // popup การเพิ่มประเมิน
|
||||
|
||||
/** import Type*/
|
||||
import type { PropsTable } from "@/interface/PropsTable";
|
||||
import type { ListMenu } from "@/modules/06_evaluate/interface/evalute";
|
||||
import type { OptionStatus } from "@/modules/06_evaluate/interface/main";
|
||||
|
||||
|
|
@ -50,13 +51,12 @@ const listMenu = ref<ListMenu[]>([
|
|||
},
|
||||
]);
|
||||
|
||||
const total = ref<number>(0);
|
||||
const totalList = ref<number>(1);
|
||||
const pagination = ref({
|
||||
const pagination = ref<PropsTable.Pagination>({
|
||||
sortBy: "createdAt",
|
||||
descending: true,
|
||||
page: 1,
|
||||
rowsPerPage: 10,
|
||||
rowsNumber: 0,
|
||||
});
|
||||
|
||||
/**
|
||||
|
|
@ -85,11 +85,9 @@ async function fetchEvaluteList() {
|
|||
await http
|
||||
.put(config.API.evaluationList(), body)
|
||||
.then(async (res) => {
|
||||
totalList.value = Math.ceil(
|
||||
res.data.result.total / pagination.value.rowsPerPage
|
||||
);
|
||||
total.value = res.data.result.total;
|
||||
store.fetchEvaluateList(res.data.result.data);
|
||||
const result = res.data.result;
|
||||
pagination.value.rowsNumber = result.total;
|
||||
store.fetchEvaluateList(result.data);
|
||||
})
|
||||
.catch((err) => {
|
||||
messageError($q, err);
|
||||
|
|
@ -193,13 +191,6 @@ function getSearch() {
|
|||
fetchEvaluteList();
|
||||
}
|
||||
|
||||
watch(
|
||||
() => pagination.value.rowsPerPage,
|
||||
async () => {
|
||||
getSearch();
|
||||
}
|
||||
);
|
||||
|
||||
/** hook lifecycle*/
|
||||
onMounted(async () => {
|
||||
await fetchEvaluteList();
|
||||
|
|
@ -325,10 +316,8 @@ onMounted(async () => {
|
|||
<div class="col-12">
|
||||
<TableListEvaluate
|
||||
:fetchData="fetchEvaluteList"
|
||||
v-model:total="total"
|
||||
v-model:total-list="totalList"
|
||||
v-model:pagination="pagination"
|
||||
:isLoading="isLoading"
|
||||
v-model:isLoading="isLoading"
|
||||
/>
|
||||
</div>
|
||||
</q-card>
|
||||
|
|
|
|||
|
|
@ -10,16 +10,15 @@ import config from "@/app.config";
|
|||
import { useCounterMixin } from "@/stores/mixin";
|
||||
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 { DataOption } from "@/modules/07_appealComplain/interface/index/main";
|
||||
|
||||
import SkeletonTable from "@/components/SkeletonTable.vue";
|
||||
|
||||
const $q = useQuasar();
|
||||
const router = useRouter();
|
||||
const mixin = useCounterMixin();
|
||||
const dataStore = useAppealComplainStore();
|
||||
const { messageError, showLoader, hideLoader } = mixin;
|
||||
const { messageError } = mixin;
|
||||
|
||||
const filterKeyword = ref<string>("");
|
||||
const type = ref<DataOption[]>([
|
||||
|
|
@ -28,25 +27,18 @@ const type = ref<DataOption[]>([
|
|||
]);
|
||||
|
||||
const isload = ref<boolean>(false);
|
||||
const total = ref<number>(0);
|
||||
const totalList = ref<number>(1);
|
||||
const pagination = ref({
|
||||
const pagination = ref<PropsTable.Pagination>({
|
||||
sortBy: "createdAt",
|
||||
descending: true,
|
||||
page: 1,
|
||||
rowsPerPage: 10,
|
||||
rowsNumber: 0,
|
||||
});
|
||||
|
||||
/**
|
||||
* เพิ่มหัวข้อตาราง
|
||||
*/
|
||||
|
||||
const formData = reactive<FormType>({
|
||||
type: "ALL",
|
||||
status: "ALL",
|
||||
year: new Date().getFullYear(),
|
||||
});
|
||||
|
||||
const visibleColumns = ref<string[]>([
|
||||
"no",
|
||||
"title",
|
||||
|
|
@ -59,7 +51,6 @@ const visibleColumns = ref<string[]>([
|
|||
"lastUpdatedAt",
|
||||
"status",
|
||||
]);
|
||||
|
||||
const columns = ref<QTableProps["columns"]>([
|
||||
{
|
||||
name: "no",
|
||||
|
|
@ -170,19 +161,16 @@ async function getData() {
|
|||
)
|
||||
)
|
||||
.then(async (res) => {
|
||||
totalList.value = Math.ceil(
|
||||
res.data.result.total / pagination.value.rowsPerPage
|
||||
);
|
||||
total.value = res.data.result.total;
|
||||
let data = res.data.result.data;
|
||||
await dataStore.fetchAppealComplain(data);
|
||||
isload.value = false;
|
||||
const result = res.data.result;
|
||||
pagination.value.rowsNumber = result.total;
|
||||
dataStore.fetchAppealComplain(result.data);
|
||||
})
|
||||
.catch((e: any) => {
|
||||
messageError($q, e);
|
||||
isload.value = false;
|
||||
})
|
||||
.finally(() => {});
|
||||
.finally(() => {
|
||||
isload.value = false;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -214,22 +202,21 @@ function redirectToPageadd() {
|
|||
router.push(`/appeal-complain/add`);
|
||||
}
|
||||
|
||||
function updatePagination(newPagination: any) {
|
||||
pagination.value.page = 1;
|
||||
pagination.value.rowsPerPage = newPagination.rowsPerPage;
|
||||
}
|
||||
|
||||
function getSearch() {
|
||||
pagination.value.page = 1;
|
||||
getData();
|
||||
}
|
||||
|
||||
watch(
|
||||
() => pagination.value.rowsPerPage,
|
||||
async () => {
|
||||
getSearch();
|
||||
}
|
||||
);
|
||||
/**
|
||||
* ฟังก์ชันรับ request จากตาราง เมื่อมีการเปลี่ยน pagination
|
||||
* @param requestProps ข้อมูลการร้องขอจากตาราง
|
||||
*/
|
||||
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();
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="col-12 row justify-center">
|
||||
<div class="col-xs-12 col-sm-12 col-md-11">
|
||||
|
|
@ -377,36 +365,18 @@ onMounted(async () => {
|
|||
/>
|
||||
|
||||
<div class="col-12">
|
||||
<SkeletonTable v-if="isload" :columns="dataStore.columns" />
|
||||
<d-table
|
||||
v-else
|
||||
flat
|
||||
bordered
|
||||
dense
|
||||
class="custom-table2"
|
||||
style="max-height: 80vh"
|
||||
:rows="dataStore.rows"
|
||||
:columns="dataStore.columns"
|
||||
:visible-columns="dataStore.visibleColumns"
|
||||
:rows-per-page-options="[10, 25, 50, 100]"
|
||||
@update:pagination="updatePagination"
|
||||
@request="onTableRequest"
|
||||
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">
|
||||
<q-tr :props="props">
|
||||
<q-th
|
||||
|
|
@ -425,7 +395,7 @@ onMounted(async () => {
|
|||
v-for="col in props.cols"
|
||||
:key="col.name"
|
||||
:props="props"
|
||||
@click="editPage(props.row.id)"
|
||||
@click.stop.prevent="editPage(props.row.id)"
|
||||
>
|
||||
<div v-if="col.name == 'no'">
|
||||
{{
|
||||
|
|
@ -445,7 +415,7 @@ onMounted(async () => {
|
|||
<template #item="props">
|
||||
<div class="q-pa-xs col-xs-12 col-sm-6 col-md-4 col-lg-3">
|
||||
<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-section>
|
||||
<q-item-label caption>{{ col.label }}</q-item-label>
|
||||
|
|
@ -469,49 +439,5 @@ onMounted(async () => {
|
|||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<style lang="scss">
|
||||
.icon-color {
|
||||
color: #4154b3;
|
||||
}
|
||||
|
||||
.custom-table2 {
|
||||
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>
|
||||
<style lang="scss"></style>
|
||||
|
|
|
|||
|
|
@ -1,18 +1,17 @@
|
|||
<script setup lang="ts">
|
||||
import { ref } from "vue";
|
||||
import { ref, watch } from "vue";
|
||||
import { useRouter } from "vue-router";
|
||||
import type { QTableProps } from "quasar";
|
||||
|
||||
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 { FormQuery } from "@/modules/08_KPI/interface/request/index";
|
||||
|
||||
import SkeletonTable from "@/components/SkeletonTable.vue";
|
||||
|
||||
const store = useKpiDataStore();
|
||||
const router = useRouter();
|
||||
const isLoad = defineModel<boolean>('isLoad',{required:true})
|
||||
const isLoad = defineModel<boolean>("isLoad", { required: true });
|
||||
const visibleColumns = defineModel<string[]>("visibleColumns", {
|
||||
required: true,
|
||||
});
|
||||
|
|
@ -22,30 +21,53 @@ const columns = defineModel<QTableProps["columns"]>("columns", {
|
|||
const rows = defineModel<ResEvaluatorAssessor[]>("rows", { required: true });
|
||||
const formQuery = defineModel<FormQuery>("formQuery", { required: true });
|
||||
const total = defineModel<number>("total", { required: true });
|
||||
const maxPage = defineModel<number>("maxPage", { required: true });
|
||||
|
||||
const props = defineProps({
|
||||
updatePagination: { type: Function },
|
||||
fetchList: { type: Function },
|
||||
});
|
||||
|
||||
const pagination = ref({
|
||||
const pagination = ref<PropsTable.Pagination>({
|
||||
sortBy: "desc",
|
||||
descending: false,
|
||||
page: 1,
|
||||
rowsPerPage: 10,
|
||||
page: formQuery.value.page,
|
||||
rowsPerPage: formQuery.value.pageSize,
|
||||
rowsNumber: total.value,
|
||||
});
|
||||
|
||||
async function redirectViewDetail(id: string) {
|
||||
store.tabMain = await "";
|
||||
store.tabMain = "";
|
||||
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>
|
||||
|
||||
<template>
|
||||
<div class="col-12">
|
||||
<d-table
|
||||
v-if="!isLoad"
|
||||
ref="table"
|
||||
:columns="columns"
|
||||
:rows="rows"
|
||||
|
|
@ -54,11 +76,11 @@ async function redirectViewDetail(id: string) {
|
|||
bordered
|
||||
:paging="true"
|
||||
dense
|
||||
class="custom-table2"
|
||||
:rows-per-page-options="[10, 25, 50, 100]"
|
||||
:rows-per-page-options="[1, 10, 25, 50, 100]"
|
||||
:visible-columns="visibleColumns"
|
||||
v-model:pagination="pagination"
|
||||
@update:pagination="props.updatePagination"
|
||||
@request="onTableRequest"
|
||||
:loading="isLoad"
|
||||
>
|
||||
<template v-slot:header="props">
|
||||
<q-tr :props="props">
|
||||
|
|
@ -109,22 +131,7 @@ async function redirectViewDetail(id: string) {
|
|||
</q-card>
|
||||
</div>
|
||||
</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>
|
||||
<SkeletonTable v-else :columns="columns"/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
<script setup lang="ts">
|
||||
import { ref } from "vue";
|
||||
import { useQuasar } from "quasar";
|
||||
import { ref, watch } from "vue";
|
||||
import { Loading, useQuasar } from "quasar";
|
||||
import { useRouter } from "vue-router";
|
||||
import type { QTableProps } from "quasar";
|
||||
|
||||
|
|
@ -9,11 +9,10 @@ import http from "@/plugins/http";
|
|||
import { useCounterMixin } from "@/stores/mixin";
|
||||
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 { ResEvaluatorAssessor } from "@/modules/08_KPI/interface/response/index";
|
||||
|
||||
import SkeletonTable from "@/components/SkeletonTable.vue";
|
||||
|
||||
const $q = useQuasar();
|
||||
const router = useRouter();
|
||||
const store = useKpiDataStore();
|
||||
|
|
@ -35,25 +34,24 @@ const columns = defineModel<QTableProps["columns"]>("columns", {
|
|||
const rows = defineModel<ResEvaluatorAssessor[]>("rows", { required: true });
|
||||
const formQuery = defineModel<FormQuery>("formQuery", { required: true });
|
||||
const total = defineModel<number>("total", { required: true });
|
||||
const maxPage = defineModel<number>("maxPage", { required: true });
|
||||
const isLoad = defineModel<boolean>("isLoad", { required: true });
|
||||
|
||||
const props = defineProps({
|
||||
updatePagination: { 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) {
|
||||
router.push(`/KPI-evaluator/${id}`);
|
||||
}
|
||||
|
||||
const pagination = ref({
|
||||
sortBy: "desc",
|
||||
descending: false,
|
||||
page: 1,
|
||||
rowsPerPage: 10,
|
||||
});
|
||||
|
||||
async function onClickApprove(type: string = "") {
|
||||
if (store.selected.length !== 0) {
|
||||
const userIds = await store.selected.map(
|
||||
|
|
@ -107,12 +105,36 @@ async function onClickApprove(type: string = "") {
|
|||
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>
|
||||
|
||||
<template>
|
||||
<div class="col-12">
|
||||
<d-table
|
||||
v-if="!isLoad"
|
||||
ref="table"
|
||||
:columns="columns"
|
||||
:rows="rows"
|
||||
|
|
@ -124,13 +146,14 @@ async function onClickApprove(type: string = "") {
|
|||
:rows-per-page-options="[10, 25, 50, 100]"
|
||||
:visible-columns="visibleColumns"
|
||||
v-model:pagination="pagination"
|
||||
@update:pagination="props.updatePagination"
|
||||
:selection="
|
||||
store.tabMainevaluator === '5' || store.tabMainevaluator === '6'
|
||||
? 'none'
|
||||
: 'multiple'
|
||||
"
|
||||
v-model:selected="store.selected"
|
||||
@request="onTableRequest"
|
||||
:loading="isLoad"
|
||||
>
|
||||
<template v-slot:header-selection="scope">
|
||||
<q-checkbox keep-color color="primary" dense v-model="scope.selected" />
|
||||
|
|
@ -211,22 +234,7 @@ async function onClickApprove(type: string = "") {
|
|||
</q-card>
|
||||
</div>
|
||||
</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>
|
||||
<SkeletonTable v-else :columns="columns" />
|
||||
</div>
|
||||
|
||||
<div class="row justify-end q-mt-md q-gutter-sm" v-if="rows.length !== 0">
|
||||
|
|
|
|||
|
|
@ -13,8 +13,6 @@ import type { ListCapacity } from "@/modules/08_KPI/interface/request/index";
|
|||
|
||||
import DialogHeader from "@/components/DialogHeader.vue";
|
||||
|
||||
import SkeletonTable from '@/components/SkeletonTable.vue'
|
||||
|
||||
const dataListCapacityDetails = ref<ListCapacity[]>([]);
|
||||
const route = useRoute();
|
||||
const idParam = ref<string>(route.params.id as string);
|
||||
|
|
@ -483,7 +481,7 @@ watch(
|
|||
</div>
|
||||
<div class="col-xs-12 col-md-7">
|
||||
<d-table
|
||||
v-if="!isLoadById"
|
||||
v-if="!isLoadById"
|
||||
flat
|
||||
bordered
|
||||
dense
|
||||
|
|
@ -491,10 +489,12 @@ watch(
|
|||
row-key="level"
|
||||
virtual-scroll
|
||||
:rows="dataListCapacityDetails"
|
||||
:rows-per-page-options="[100]"
|
||||
hide-pagination
|
||||
:columns="columns"
|
||||
:visible-columns="visibleColumns"
|
||||
v-model:pagination="pagination"
|
||||
:pagination="pagination"
|
||||
:loading="isLoadById"
|
||||
>
|
||||
<template v-slot:header="props">
|
||||
<q-tr :props="props">
|
||||
|
|
@ -558,7 +558,6 @@ watch(
|
|||
</div>
|
||||
</template>
|
||||
</d-table>
|
||||
<SkeletonTable v-else :columns="columns"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -10,20 +10,10 @@ import { useCounterMixin } from "@/stores/mixin";
|
|||
|
||||
import DialogHeader from "@/components/DialogHeader.vue";
|
||||
|
||||
import SkeletonTable from "@/components/SkeletonTable.vue";
|
||||
|
||||
const $q = useQuasar();
|
||||
const store = useKpiDataStore();
|
||||
const mixin = useCounterMixin();
|
||||
const {
|
||||
showLoader,
|
||||
hideLoader,
|
||||
messageError,
|
||||
findPosMasterNoOld,
|
||||
findOrgNameOld,
|
||||
findOrgNameOldHtml,
|
||||
date2Thai,
|
||||
} = mixin;
|
||||
const { messageError, findOrgNameOldHtml, date2Thai } = mixin;
|
||||
|
||||
const modal = defineModel<boolean>("modal", { required: true });
|
||||
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 */
|
||||
function close() {
|
||||
modal.value = false;
|
||||
|
|
@ -174,7 +141,6 @@ function getData() {
|
|||
.then((res) => {
|
||||
const data = res.data.result;
|
||||
rows.value = data;
|
||||
isLoad.value = false;
|
||||
})
|
||||
.catch((e) => {
|
||||
messageError($q, e);
|
||||
|
|
@ -187,7 +153,7 @@ function getData() {
|
|||
watch(
|
||||
() => modal.value,
|
||||
(n) => {
|
||||
if (n == true) {
|
||||
if (n) {
|
||||
getData();
|
||||
}
|
||||
}
|
||||
|
|
@ -202,7 +168,6 @@ watch(
|
|||
<div class="row">
|
||||
<div class="col-12">
|
||||
<d-table
|
||||
v-if="!isLoad"
|
||||
ref="table"
|
||||
:columns="columns"
|
||||
:rows="rows"
|
||||
|
|
@ -214,6 +179,8 @@ watch(
|
|||
dense
|
||||
:rows-per-page-options="[10, 25, 50, 100]"
|
||||
:visible-columns="visibleColumns"
|
||||
:loading="isLoad"
|
||||
:pagination="{ page: 1, rowsPerPage: 10 }"
|
||||
>
|
||||
<template v-slot:header="props">
|
||||
<q-tr :props="props">
|
||||
|
|
@ -245,7 +212,6 @@ watch(
|
|||
</q-tr>
|
||||
</template>
|
||||
</d-table>
|
||||
<SkeletonTable v-else :columns="columns" />
|
||||
</div>
|
||||
</div>
|
||||
</q-card-section>
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
<script setup lang="ts">
|
||||
import { computed, ref, watch } from "vue";
|
||||
import { useQuasar } from "quasar";
|
||||
import { Loading, useQuasar } from "quasar";
|
||||
|
||||
import config from "@/app.config";
|
||||
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 DialogProblem from "@/modules/08_KPI/components/Tab/Dialog/DialogCommentProblem.vue";
|
||||
|
||||
import SkeletonTable from "@/components/SkeletonTable.vue";
|
||||
|
||||
const $q = useQuasar();
|
||||
const store = useKpiDataStore();
|
||||
const { dialogRemove, showLoader, hideLoader, messageError, success } =
|
||||
useCounterMixin();
|
||||
const { dialogRemove, messageError, success } = useCounterMixin();
|
||||
|
||||
const checkDetail = ref<boolean>(false);
|
||||
const title = defineModel<string>("title", { required: true });
|
||||
const rows = defineModel<any>("data", { 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({
|
||||
fetchList: { type: Function, required: true },
|
||||
});
|
||||
|
|
@ -139,7 +136,7 @@ async function onEvaluate() {
|
|||
function onDelete(id: string) {
|
||||
dialogRemove($q, async () => {
|
||||
try {
|
||||
isLoad.value = true
|
||||
isLoad.value = true;
|
||||
const url =
|
||||
numpage.value === 1
|
||||
? config.API.kpiAchievement("planned") + `/${id}`
|
||||
|
|
@ -243,12 +240,10 @@ const isEditStep3 = computed(() => {
|
|||
</q-card-section>
|
||||
<q-separator />
|
||||
<q-card-section class="q-pa-sm">
|
||||
|
||||
<d-table
|
||||
v-if="!isLoad"
|
||||
ref="table"
|
||||
:columns="columns"
|
||||
:rows="rows"
|
||||
:rows="rows || []"
|
||||
:filter="filterKeyword"
|
||||
row-key="id"
|
||||
flat
|
||||
|
|
@ -257,7 +252,7 @@ const isEditStep3 = computed(() => {
|
|||
hide-pagination
|
||||
:visible-columns="visibleColumns"
|
||||
:rows-per-page-options="[20]"
|
||||
no-data-label="ไม่มีข้อมูล"
|
||||
:loading="isLoad"
|
||||
>
|
||||
<template v-slot:header="props">
|
||||
<q-tr :props="props">
|
||||
|
|
@ -464,7 +459,6 @@ const isEditStep3 = computed(() => {
|
|||
</div>
|
||||
</template>
|
||||
</d-table>
|
||||
<SkeletonTable v-else :columns="columns"/>
|
||||
</q-card-section>
|
||||
</q-card>
|
||||
|
||||
|
|
|
|||
|
|
@ -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 DialogCompetncyByRow from "@/modules/08_KPI/components/Tab/Dialog/DialogCompetncyByRow.vue";
|
||||
|
||||
import SkeletonTable from "@/components/SkeletonTable.vue";
|
||||
|
||||
const modalLevel = ref<boolean>(false);
|
||||
const modalCompetncyByRow = ref<boolean>(false);
|
||||
const dataCompetncyByRow = ref<any[]>([]);
|
||||
|
|
@ -160,15 +158,14 @@ function onAdd(type: string) {
|
|||
|
||||
/** ดึงข้อมูล */
|
||||
function getData(type: string) {
|
||||
isLoad.value[type] = true;
|
||||
http
|
||||
.get(config.API.kpiUserCapacity + `?id=${id.value}&type=${type}`)
|
||||
.then(async (res) => {
|
||||
const data = res.data.result.data;
|
||||
isLoad.value[type] = data ? true : false;
|
||||
rows.value[type] = data;
|
||||
lists.value = await lists.value.filter((x: any) => x.type != type);
|
||||
lists.value.push({ type: type, data });
|
||||
isLoad.value[type] = false;
|
||||
})
|
||||
.catch((e) => {
|
||||
messageError($q, e);
|
||||
|
|
@ -220,6 +217,7 @@ function getData(type: string) {
|
|||
: 0;
|
||||
}
|
||||
}
|
||||
isLoad.value[type] = false;
|
||||
});
|
||||
}
|
||||
|
||||
|
|
@ -400,20 +398,21 @@ watch(
|
|||
</q-btn>
|
||||
</div>
|
||||
</q-card-section>
|
||||
|
||||
<q-card-section class="q-pa-sm">
|
||||
<d-table
|
||||
v-if="!isLoad[item.id]"
|
||||
ref="table"
|
||||
:columns="columns"
|
||||
:rows="rows[item.id]"
|
||||
:rows="rows[item.id] || []"
|
||||
row-key="id"
|
||||
flat
|
||||
bordered
|
||||
:paging="true"
|
||||
dense
|
||||
hide-pagination
|
||||
no-data-label="ไม่มีข้อมูล"
|
||||
:visible-columns="visibleColumns"
|
||||
:rows-per-page-options="[20]"
|
||||
:loading="isLoad[item.id]"
|
||||
>
|
||||
<template v-slot:header="props">
|
||||
<q-tr :props="props">
|
||||
|
|
@ -634,7 +633,6 @@ watch(
|
|||
</div>
|
||||
</template>
|
||||
</d-table>
|
||||
<SkeletonTable v-else :columns="columns" />
|
||||
</q-card-section>
|
||||
</q-card>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -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 DialogProblem from "@/modules/08_KPI/components/Tab/Dialog/DialogCommentProblem.vue";
|
||||
|
||||
import SkeletonTable from "@/components/SkeletonTable.vue";
|
||||
|
||||
const store = useKpiDataStore();
|
||||
const route = useRoute();
|
||||
const evaluationId = ref<string>(route.params.id.toString());
|
||||
|
|
@ -26,14 +24,7 @@ const idEditDevelop = ref<string>("");
|
|||
|
||||
const $q = useQuasar();
|
||||
const mixin = useCounterMixin();
|
||||
const {
|
||||
date2Thai,
|
||||
messageError,
|
||||
showLoader,
|
||||
hideLoader,
|
||||
dialogRemove,
|
||||
success,
|
||||
} = mixin;
|
||||
const { date2Thai, messageError, dialogRemove, success } = mixin;
|
||||
|
||||
const isUpdate = defineModel("isUpdate", {
|
||||
type: Boolean,
|
||||
|
|
@ -248,7 +239,6 @@ onMounted(() => {
|
|||
</q-card-section>
|
||||
<q-card-section class="q-pa-sm">
|
||||
<d-table
|
||||
v-if="!isLoad"
|
||||
ref="table"
|
||||
:columns="columns"
|
||||
:rows="rows"
|
||||
|
|
@ -258,8 +248,9 @@ onMounted(() => {
|
|||
:paging="true"
|
||||
dense
|
||||
hide-pagination
|
||||
no-data-label="ไม่มีข้อมูล"
|
||||
:rows-per-page-options="[20]"
|
||||
:visible-columns="visibleColumns"
|
||||
:loading="isLoad"
|
||||
>
|
||||
<template v-slot:header="props">
|
||||
<q-tr :props="props">
|
||||
|
|
@ -507,8 +498,6 @@ onMounted(() => {
|
|||
</div>
|
||||
</template>
|
||||
</d-table>
|
||||
|
||||
<SkeletonTable v-else :columns="columns" />
|
||||
</q-card-section>
|
||||
</q-card>
|
||||
|
||||
|
|
|
|||
|
|
@ -1,19 +1,19 @@
|
|||
<script setup lang="ts">
|
||||
import { ref, onMounted, reactive, watch } from "vue";
|
||||
import { ref, onMounted, reactive } from "vue";
|
||||
import { useRouter } from "vue-router";
|
||||
import { useQuasar } from "quasar";
|
||||
import type { QTableProps } from "quasar";
|
||||
|
||||
import config from "@/app.config";
|
||||
import http from "@/plugins/http";
|
||||
import { useCounterMixin } from "@/stores/mixin";
|
||||
import { useKpiDataStore } from "@/modules/08_KPI/store";
|
||||
|
||||
import type { QTableProps } from "quasar";
|
||||
import type { DataProfile } from "@/interface/Main";
|
||||
import type { PropsTable } from "@/interface/PropsTable";
|
||||
import type {
|
||||
DataOptions,
|
||||
MainListKpi,
|
||||
PaginationType,
|
||||
} from "@/modules/08_KPI/interface/index/Main";
|
||||
import type {
|
||||
RoundKpiResponse,
|
||||
|
|
@ -21,7 +21,6 @@ import type {
|
|||
} from "@/modules/08_KPI/interface/response/index";
|
||||
|
||||
import DialogHeader from "@/components/DialogHeader.vue";
|
||||
import SkeletonTable from "@/components/SkeletonTable.vue";
|
||||
|
||||
const $q = useQuasar();
|
||||
const mixin = useCounterMixin();
|
||||
|
|
@ -107,7 +106,6 @@ const columns = ref<QTableProps["columns"]>([
|
|||
/** List*/
|
||||
const year = ref<number>(new Date().getFullYear());
|
||||
const round = ref<string>("");
|
||||
const filterKeyword = ref<string>("");
|
||||
const roundMainOp = ref<DataOptions[]>([]);
|
||||
const roundDialgOp = ref<DataOptions[]>([]);
|
||||
|
||||
|
|
@ -142,20 +140,18 @@ const formRound = reactive({
|
|||
|
||||
/** pagetion*/
|
||||
const formQuery = reactive({
|
||||
page: 1,
|
||||
pageSize: 10,
|
||||
status: "",
|
||||
results: "",
|
||||
});
|
||||
const total = ref<number>(0);
|
||||
const totalList = ref<number>(1);
|
||||
|
||||
const isRoundClose = ref<boolean>(false);
|
||||
|
||||
const pagination = ref({
|
||||
const pagination = ref<PropsTable.Pagination>({
|
||||
sortBy: "desc",
|
||||
descending: false,
|
||||
page: 1,
|
||||
rowsPerPage: 10,
|
||||
rowsNumber: 0,
|
||||
});
|
||||
|
||||
/**
|
||||
|
|
@ -206,14 +202,12 @@ async function fetchRoundOption(type: string) {
|
|||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* fetch รายการขอรับประเมินผลการปฏิบัติราชการระดับบุคคล
|
||||
*/
|
||||
/** ฟังก์ชันดึงข้อมูลรายการขอรับประเมินผลการปฏิบัติราชการระดับบุคคล*/
|
||||
async function fetchList() {
|
||||
isLoad.value = true;
|
||||
let queryParams = {
|
||||
page: formQuery.page,
|
||||
pageSize: formQuery.pageSize,
|
||||
page: pagination.value.page,
|
||||
pageSize: pagination.value.rowsPerPage,
|
||||
kpiPeriodId: round.value,
|
||||
status: formQuery.status === "" ? undefined : formQuery.status,
|
||||
results: formQuery.results === "" ? undefined : formQuery.results,
|
||||
|
|
@ -225,21 +219,20 @@ async function fetchList() {
|
|||
})
|
||||
.then(async (res) => {
|
||||
const data = await res.data.result;
|
||||
total.value = data.total;
|
||||
totalList.value = Math.ceil(data.total / formQuery.pageSize);
|
||||
pagination.value.rowsNumber = data.total;
|
||||
rows.value = data.data;
|
||||
isLoad.value = false;
|
||||
})
|
||||
.catch((err) => {
|
||||
isLoad.value = false;
|
||||
messageError($q, err);
|
||||
})
|
||||
.finally(() => {});
|
||||
.finally(() => {
|
||||
isLoad.value = false;
|
||||
});
|
||||
}
|
||||
|
||||
/** เลือกรอบการประเมิน */
|
||||
function changRound() {
|
||||
formQuery.page = 1;
|
||||
pagination.value.page = 1;
|
||||
fetchList();
|
||||
}
|
||||
|
||||
|
|
@ -333,15 +326,6 @@ function checkClosed() {
|
|||
isRoundClose.value = formRound.kpiPeriodId.isClosed;
|
||||
}
|
||||
|
||||
/**
|
||||
* function updatePagination
|
||||
* @param newPagination ข้อมูล Pagination ใหม่
|
||||
*/
|
||||
function updatePagination(newPagination: PaginationType) {
|
||||
formQuery.page = 1;
|
||||
formQuery.pageSize = newPagination.rowsPerPage;
|
||||
}
|
||||
|
||||
/** ดึงข้อมูล option */
|
||||
function getOrgOp() {
|
||||
http
|
||||
|
|
@ -421,12 +405,16 @@ function filterOption(val: string, update: Function, refData: string) {
|
|||
}
|
||||
}
|
||||
|
||||
watch(
|
||||
() => formQuery.pageSize,
|
||||
() => {
|
||||
fetchList();
|
||||
}
|
||||
);
|
||||
/**
|
||||
* ฟังก์ชันรับ request จากตาราง เมื่อมีการเปลี่ยน pagination
|
||||
* @param requestProps ข้อมูลการร้องขอจากตาราง
|
||||
*/
|
||||
function onTableRequest(requestProps: PropsTable.RequestProps) {
|
||||
const newPagination = requestProps?.pagination || requestProps;
|
||||
if (!newPagination?.page || !newPagination?.rowsPerPage) return;
|
||||
pagination.value = { ...newPagination };
|
||||
fetchList();
|
||||
}
|
||||
|
||||
onMounted(async () => {
|
||||
await Promise.all([fetchRoundOption("main"), getOrgOp()]);
|
||||
|
|
@ -462,7 +450,7 @@ onMounted(async () => {
|
|||
year-picker
|
||||
:enableTimePicker="false"
|
||||
@update:model-value="
|
||||
(formQuery.page = 1), fetchRoundOption('main')
|
||||
(pagination.page = 1), fetchRoundOption('main')
|
||||
"
|
||||
>
|
||||
<template #year="{ year }">{{ year + 543 }}</template>
|
||||
|
|
@ -557,7 +545,7 @@ onMounted(async () => {
|
|||
outlined
|
||||
use-input
|
||||
input-debounce="0"
|
||||
@update:model-value="(formQuery.page = 1), fetchList()"
|
||||
@update:model-value="(pagination.page = 1), fetchList()"
|
||||
:clearable="formQuery.status !== ''"
|
||||
@clear="
|
||||
(formQuery.status = ''),
|
||||
|
|
@ -589,7 +577,7 @@ onMounted(async () => {
|
|||
lazy-rules
|
||||
hide-bottom-space
|
||||
outlined
|
||||
@update:model-value="(formQuery.page = 1), fetchList()"
|
||||
@update:model-value="(pagination.page = 1), fetchList()"
|
||||
use-input
|
||||
@clear="
|
||||
(formQuery.results = ''),
|
||||
|
|
@ -615,11 +603,9 @@ onMounted(async () => {
|
|||
|
||||
<div class="col-12">
|
||||
<d-table
|
||||
v-if="!isLoad"
|
||||
ref="table"
|
||||
:columns="columns"
|
||||
:rows="rows"
|
||||
:filter="filterKeyword"
|
||||
row-key="id"
|
||||
flat
|
||||
bordered
|
||||
|
|
@ -627,8 +613,9 @@ onMounted(async () => {
|
|||
dense
|
||||
:rows-per-page-options="[10, 25, 50, 100]"
|
||||
:visible-columns="visibleColumns"
|
||||
@request="onTableRequest"
|
||||
v-model:pagination="pagination"
|
||||
@update:pagination="updatePagination"
|
||||
:loading="isLoad"
|
||||
>
|
||||
<template v-slot:header="props">
|
||||
<q-tr :props="props">
|
||||
|
|
@ -671,22 +658,7 @@ onMounted(async () => {
|
|||
</q-card>
|
||||
</div>
|
||||
</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>
|
||||
<SkeletonTable v-else :columns="columns" />
|
||||
</div>
|
||||
</div>
|
||||
</q-card>
|
||||
|
|
@ -746,7 +718,7 @@ onMounted(async () => {
|
|||
|
||||
<div class="col-12">
|
||||
<q-select
|
||||
v-if="!isLoadDialog"
|
||||
v-if="!isLoadDialog"
|
||||
:readonly="yearDialog === null"
|
||||
v-model="formRound.kpiPeriodId"
|
||||
outlined
|
||||
|
|
@ -760,7 +732,7 @@ onMounted(async () => {
|
|||
:rules="[(val:DataOptions) => !!val.id || `${'กรุณาเลือกรอบการประเมิน'}`]"
|
||||
@update:model-value="checkClosed"
|
||||
/>
|
||||
<q-skeleton type="QInput" height="40px" v-else/>
|
||||
<q-skeleton type="QInput" height="40px" v-else />
|
||||
</div>
|
||||
|
||||
<div class="col-12">
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
<script setup lang="ts">
|
||||
import { ref, onMounted, watch } from "vue";
|
||||
import { ref, onMounted } from "vue";
|
||||
import { useRouter } from "vue-router";
|
||||
import { useQuasar } from "quasar";
|
||||
import type { QTableProps } from "quasar";
|
||||
|
|
@ -9,10 +9,7 @@ import http from "@/plugins/http";
|
|||
import { useCounterMixin } from "@/stores/mixin";
|
||||
import { useKpiDataStore } from "@/modules/08_KPI/store";
|
||||
|
||||
import type {
|
||||
DataOptions,
|
||||
Pagination,
|
||||
} from "@/modules/08_KPI/interface/index/Main";
|
||||
import type { DataOptions } from "@/modules/08_KPI/interface/index/Main";
|
||||
import type {
|
||||
ResRound,
|
||||
ResEvaluatorAssessor,
|
||||
|
|
@ -24,7 +21,7 @@ import TabOther from "@/modules/08_KPI/components/Evaluator/02_TabOther.vue";
|
|||
const $q = useQuasar();
|
||||
const router = useRouter();
|
||||
const store = useKpiDataStore();
|
||||
const { showLoader, hideLoader, messageError, date2Thai } = useCounterMixin();
|
||||
const { messageError, date2Thai } = useCounterMixin();
|
||||
|
||||
const dataListMain = ref<ResEvaluatorAssessor[]>([]);
|
||||
|
||||
|
|
@ -87,7 +84,6 @@ const columns = ref<QTableProps["columns"]>([
|
|||
]);
|
||||
|
||||
const totalList = ref<number>(0);
|
||||
const maxPage = ref<number>(1);
|
||||
|
||||
/**
|
||||
* ดึงข้อมูลรายการขอรับประเมินผลการปฏิบัติราชการระดับบุคคล
|
||||
|
|
@ -121,19 +117,19 @@ async function fetchRoundOption() {
|
|||
store.formQuery.round = roundOp.value[0].id;
|
||||
await fetchList();
|
||||
}
|
||||
isLoadOp.value = false;
|
||||
})
|
||||
.catch((err) => {
|
||||
messageError($q, err);
|
||||
isLoadOp.value = false;
|
||||
})
|
||||
.finally(() => {});
|
||||
.finally(() => {
|
||||
isLoadOp.value = false;
|
||||
});
|
||||
}
|
||||
|
||||
/** ดึงข้อมูล list */
|
||||
const isLoad = ref<boolean>(false)
|
||||
const isLoad = ref<boolean>(false);
|
||||
async function fetchList() {
|
||||
isLoad.value = true
|
||||
isLoad.value = true;
|
||||
const body = {
|
||||
page: store.formQuery.page,
|
||||
pageSize: store.formQuery.pageSize,
|
||||
|
|
@ -157,16 +153,15 @@ async function fetchList() {
|
|||
.post(config.API.kpiEvaluation + `/admin`, body)
|
||||
.then(async (res) => {
|
||||
const data = await res.data.result;
|
||||
maxPage.value = Math.ceil(data.total / store.formQuery.pageSize);
|
||||
totalList.value = data.total;
|
||||
dataListMain.value = data.data;
|
||||
isLoad.value = false
|
||||
})
|
||||
.catch((err) => {
|
||||
messageError($q, err);
|
||||
isLoad.value = false
|
||||
})
|
||||
.finally(() => {});
|
||||
.finally(() => {
|
||||
isLoad.value = false;
|
||||
});
|
||||
}
|
||||
|
||||
/** เลือกรอบการประเมิน */
|
||||
|
|
@ -175,15 +170,6 @@ function changRound() {
|
|||
fetchList();
|
||||
}
|
||||
|
||||
/**
|
||||
* function updatePagination
|
||||
* @param newPagination ข้อมูล Pagination ใหม่
|
||||
*/
|
||||
function updatePagination(newPagination: Pagination) {
|
||||
store.formQuery.page = 1;
|
||||
store.formQuery.pageSize = newPagination.rowsPerPage;
|
||||
}
|
||||
|
||||
/** เปลี่ยน tab */
|
||||
async function onChangTab() {
|
||||
store.formQuery.page = 1;
|
||||
|
|
@ -192,13 +178,6 @@ async function onChangTab() {
|
|||
await fetchList();
|
||||
}
|
||||
|
||||
watch(
|
||||
() => store.formQuery.pageSize,
|
||||
() => {
|
||||
fetchList();
|
||||
}
|
||||
);
|
||||
|
||||
onMounted(async () => {
|
||||
await fetchRoundOption();
|
||||
});
|
||||
|
|
@ -347,8 +326,6 @@ onMounted(async () => {
|
|||
:rows="dataListMain"
|
||||
:formQuery="store.formQuery"
|
||||
:total="totalList"
|
||||
:maxPage="maxPage"
|
||||
:updatePagination="updatePagination"
|
||||
:fetchList="fetchList"
|
||||
:is-load="isLoad"
|
||||
/>
|
||||
|
|
@ -361,8 +338,6 @@ onMounted(async () => {
|
|||
:rows="dataListMain"
|
||||
:formQuery="store.formQuery"
|
||||
:total="totalList"
|
||||
:maxPage="maxPage"
|
||||
:updatePagination="updatePagination"
|
||||
:fetchList="fetchList"
|
||||
:is-load="isLoad"
|
||||
/>
|
||||
|
|
@ -375,8 +350,6 @@ onMounted(async () => {
|
|||
:rows="dataListMain"
|
||||
:formQuery="store.formQuery"
|
||||
:total="totalList"
|
||||
:maxPage="maxPage"
|
||||
:updatePagination="updatePagination"
|
||||
:fetchList="fetchList"
|
||||
:is-load="isLoad"
|
||||
/>
|
||||
|
|
@ -389,8 +362,6 @@ onMounted(async () => {
|
|||
:rows="dataListMain"
|
||||
:formQuery="store.formQuery"
|
||||
:total="totalList"
|
||||
:maxPage="maxPage"
|
||||
:updatePagination="updatePagination"
|
||||
:fetchList="fetchList"
|
||||
:is-load="isLoad"
|
||||
/>
|
||||
|
|
@ -403,8 +374,6 @@ onMounted(async () => {
|
|||
:rows="dataListMain"
|
||||
:formQuery="store.formQuery"
|
||||
:total="totalList"
|
||||
:maxPage="maxPage"
|
||||
:updatePagination="updatePagination"
|
||||
:fetchList="fetchList"
|
||||
:is-load="isLoad"
|
||||
/>
|
||||
|
|
|
|||
|
|
@ -13,10 +13,8 @@ import type {
|
|||
Scholarship,
|
||||
} from "@/modules/09_scholarship/interface/index/Main";
|
||||
|
||||
import SkeletonTable from "@/components/SkeletonTable.vue";
|
||||
|
||||
const mixin = useCounterMixin();
|
||||
const { showLoader, hideLoader, messageError } = mixin;
|
||||
const { messageError } = mixin;
|
||||
const router = useRouter();
|
||||
|
||||
const $q = useQuasar();
|
||||
|
|
@ -88,7 +86,7 @@ const visibleColumns = ref<string[]>(["scholarshipYear", "scholarshipType"]);
|
|||
|
||||
/** ดึงข้อมูล */
|
||||
async function getData() {
|
||||
|
||||
isLoad.value = true;
|
||||
await http
|
||||
.get(
|
||||
config.API.developmentScholarship +
|
||||
|
|
@ -96,13 +94,12 @@ async function getData() {
|
|||
)
|
||||
.then(async (res) => {
|
||||
rows.value = res.data.result;
|
||||
isLoad.value = false
|
||||
})
|
||||
.catch((e) => {
|
||||
messageError($q, e);
|
||||
})
|
||||
.finally(() => {
|
||||
isLoad.value = false
|
||||
isLoad.value = false;
|
||||
});
|
||||
}
|
||||
|
||||
|
|
@ -110,42 +107,22 @@ function onEdit(id: string) {
|
|||
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() {
|
||||
isLoad.value = true
|
||||
isLoad.value = true;
|
||||
if (dataStore.profileId) {
|
||||
profilId.value = dataStore.profileId;
|
||||
} else {
|
||||
|
||||
try {
|
||||
const res = await http.get(config.API.profilePosition());
|
||||
dataStore.profileId = res.data.result.profileId;
|
||||
profilId.value = dataStore.profileId;
|
||||
|
||||
await getData();
|
||||
} catch (e) {
|
||||
messageError($q, e);
|
||||
} finally {
|
||||
|
||||
isLoad.value = false;
|
||||
}
|
||||
}
|
||||
|
||||
await getData();
|
||||
}
|
||||
|
||||
function convertType(val: string) {
|
||||
|
|
@ -259,9 +236,8 @@ onMounted(async () => {
|
|||
/>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<div class="col-12">
|
||||
<d-table
|
||||
v-if="!isLoad"
|
||||
flat
|
||||
bordered
|
||||
dense
|
||||
|
|
@ -270,21 +246,9 @@ onMounted(async () => {
|
|||
:columns="columns"
|
||||
:visible-columns="visibleColumns"
|
||||
: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">
|
||||
<q-tr :props="props">
|
||||
<q-th
|
||||
|
|
@ -346,7 +310,6 @@ onMounted(async () => {
|
|||
</div>
|
||||
</template>
|
||||
</d-table>
|
||||
<SkeletonTable v-else :columns="columns" />
|
||||
</div>
|
||||
</q-card>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
<script setup lang="ts">
|
||||
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 config from "@/app.config";
|
||||
|
|
|
|||
|
|
@ -10,9 +10,6 @@ import config from "@/app.config";
|
|||
import { useQuasar, type QTableProps } from "quasar";
|
||||
import type { ChangNameRows } from "@/modules/10_registry/interface/response/01_Information";
|
||||
|
||||
/** import component */
|
||||
import SkeletonTable from "@/components/SkeletonTable.vue";
|
||||
|
||||
const $q = useQuasar();
|
||||
const dataStore = useDataStore();
|
||||
const { showLoader, hideLoader, messageError, date2Thai, onSearchDataTable } =
|
||||
|
|
@ -194,23 +191,21 @@ onMounted(async () => {
|
|||
/>
|
||||
</q-toolbar>
|
||||
|
||||
<div v-if="isLoading">
|
||||
<SkeletonTable :columns="columns" />
|
||||
</div>
|
||||
|
||||
<div class="col-12" v-else>
|
||||
<div class="col-12">
|
||||
<d-table
|
||||
flat
|
||||
dense
|
||||
bordered
|
||||
virtual-scroll
|
||||
row-key="id"
|
||||
:rows="rows.length !== 0 ? rows : []"
|
||||
:columns="columns"
|
||||
:grid="!mode"
|
||||
:rows-per-page-options="[10, 25, 50, 100]"
|
||||
:visible-columns="visibleColumns"
|
||||
:virtual-scroll-sticky-size-start="48"
|
||||
v-model:pagination="pagination"
|
||||
:pagination="pagination"
|
||||
:loading="isLoading"
|
||||
>
|
||||
<template v-slot:header="props">
|
||||
<q-tr :props="props">
|
||||
|
|
|
|||
|
|
@ -10,7 +10,6 @@ import { useCounterMixin } from "@/stores/mixin";
|
|||
import type { EducationProfile } from "@/modules/10_registry/interface/index/Main";
|
||||
|
||||
import DialogHistory from "@/modules/10_registry/Dialog/DialogHistory.vue";
|
||||
import SkeletonTable from "@/components/SkeletonTable.vue";
|
||||
|
||||
const link = ref<string>("");
|
||||
const $q = useQuasar();
|
||||
|
|
@ -530,7 +529,7 @@ function onHistory(id: string) {
|
|||
|
||||
/** get history */
|
||||
async function getHistory() {
|
||||
isLoadingHistory.value = true
|
||||
isLoadingHistory.value = true;
|
||||
rowsHistory.value = [];
|
||||
rowsHistoryData.value = [];
|
||||
await http
|
||||
|
|
@ -601,9 +600,7 @@ onMounted(async () => {
|
|||
/>
|
||||
</q-toolbar>
|
||||
|
||||
<SkeletonTable v-if="isLoading" :columns="columns" />
|
||||
<d-table
|
||||
v-else
|
||||
flat
|
||||
dense
|
||||
bordered
|
||||
|
|
@ -611,9 +608,12 @@ onMounted(async () => {
|
|||
:rows="rows.length !== 0 ? rows : []"
|
||||
:columns="columns"
|
||||
:grid="!mode"
|
||||
:rows-per-page-options="[10, 25, 50, 100]"
|
||||
:rows-per-page-options="[1, 10, 25, 50, 100]"
|
||||
:visible-columns="visibleColumns"
|
||||
:virtual-scroll-sticky-size-start="48"
|
||||
:loading="isLoading"
|
||||
row-key="id"
|
||||
:pagination="{ page: 1, rowsPerPage: 10 }"
|
||||
>
|
||||
<template v-slot:header="props">
|
||||
<q-tr :props="props">
|
||||
|
|
|
|||
|
|
@ -12,7 +12,6 @@ import type { AbilityRows } from "@/modules/10_registry/interface/index/Main";
|
|||
|
||||
/** import components */
|
||||
import DialogHistory from "@/modules/10_registry/Dialog/DialogHistory.vue";
|
||||
import SkeletonTable from "@/components/SkeletonTable.vue";
|
||||
|
||||
const $q = useQuasar();
|
||||
const dataStore = useDataStore();
|
||||
|
|
@ -317,9 +316,7 @@ onMounted(async () => {
|
|||
/>
|
||||
</q-toolbar>
|
||||
|
||||
<SkeletonTable v-if="isLoading" :columns="columns" />
|
||||
<d-table
|
||||
v-else
|
||||
flat
|
||||
dense
|
||||
bordered
|
||||
|
|
@ -330,7 +327,9 @@ onMounted(async () => {
|
|||
:rows-per-page-options="[10, 25, 50, 100]"
|
||||
:visible-columns="visibleColumns"
|
||||
:virtual-scroll-sticky-size-start="48"
|
||||
v-model:pagination="pagination"
|
||||
:pagination="pagination"
|
||||
:loading="isLoading"
|
||||
row-key="id"
|
||||
>
|
||||
<template v-slot:header="props">
|
||||
<q-tr :props="props">
|
||||
|
|
|
|||
|
|
@ -11,7 +11,6 @@ import { useRegistryDataStore } from "@/modules/10_registry/store/Main";
|
|||
import type { DisciplineDetail } from "@/modules/10_registry/interface/index/Main";
|
||||
|
||||
import DialogHistory from "@/modules/10_registry/Dialog/DialogHistory.vue";
|
||||
import SkeletonTable from "@/components/SkeletonTable.vue";
|
||||
|
||||
const $q = useQuasar();
|
||||
const dataStore = useDataStore();
|
||||
|
|
@ -254,9 +253,8 @@ onMounted(async () => {
|
|||
:display-value="$q.lang.table.columns"
|
||||
/>
|
||||
</q-toolbar>
|
||||
<SkeletonTable v-if="isLoading" :columns="columns" />
|
||||
|
||||
<d-table
|
||||
v-else
|
||||
flat
|
||||
dense
|
||||
bordered
|
||||
|
|
@ -267,7 +265,9 @@ onMounted(async () => {
|
|||
:rows-per-page-options="[10, 25, 50, 100]"
|
||||
:visible-columns="visibleColumns"
|
||||
:virtual-scroll-sticky-size-start="48"
|
||||
v-model:pagination="pagination"
|
||||
:pagination="pagination"
|
||||
:loading="isLoading"
|
||||
row-key="id"
|
||||
>
|
||||
<template v-slot:header="props">
|
||||
<q-tr :props="props">
|
||||
|
|
@ -321,6 +321,7 @@ onMounted(async () => {
|
|||
</q-td>
|
||||
</q-tr>
|
||||
</template>
|
||||
|
||||
<template v-else v-slot:item="props">
|
||||
<div class="q-mb-xs col-xs-12 col-sm-6 col-md-4 col-lg-3">
|
||||
<q-card bordered flat>
|
||||
|
|
|
|||
|
|
@ -10,7 +10,6 @@ import { useDataStore } from "@/stores/data";
|
|||
import type { LeaveFormType } from "@/modules/10_registry/interface/index/Main";
|
||||
|
||||
import DialogHistory from "@/modules/10_registry/Dialog/DialogHistory.vue";
|
||||
import SkeletonTable from "@/components/SkeletonTable.vue";
|
||||
|
||||
const $q = useQuasar();
|
||||
const dataStore = useDataStore();
|
||||
|
|
@ -396,9 +395,7 @@ onMounted(async () => {
|
|||
/>
|
||||
</q-toolbar>
|
||||
|
||||
<SkeletonTable v-if="isLoading" :columns="columns" />
|
||||
<d-table
|
||||
v-else
|
||||
flat
|
||||
dense
|
||||
bordered
|
||||
|
|
@ -409,7 +406,9 @@ onMounted(async () => {
|
|||
:rows-per-page-options="[10, 25, 50, 100]"
|
||||
:visible-columns="visibleColumns"
|
||||
:virtual-scroll-sticky-size-start="48"
|
||||
v-model:pagination="pagination"
|
||||
:pagination="pagination"
|
||||
:loading="isLoading"
|
||||
row-key="id"
|
||||
>
|
||||
<template v-slot:header="props">
|
||||
<q-tr :props="props">
|
||||
|
|
|
|||
|
|
@ -11,7 +11,6 @@ import { useRegistryDataStore } from "@/modules/10_registry/store/Main";
|
|||
import type { DutyFormType } from "@/modules/10_registry/interface/index/Main";
|
||||
|
||||
import DialogHistory from "@/modules/10_registry/Dialog/DialogHistory.vue";
|
||||
import SkeletonTable from "@/components/SkeletonTable.vue";
|
||||
|
||||
const $q = useQuasar();
|
||||
const dataStore = useDataStore();
|
||||
|
|
@ -358,9 +357,8 @@ onMounted(async () => {
|
|||
:display-value="$q.lang.table.columns"
|
||||
/>
|
||||
</q-toolbar>
|
||||
<SkeletonTable v-if="isLoading" :columns="columns" />
|
||||
|
||||
<d-table
|
||||
v-else
|
||||
flat
|
||||
dense
|
||||
bordered
|
||||
|
|
@ -371,7 +369,9 @@ onMounted(async () => {
|
|||
:rows-per-page-options="[10, 25, 50, 100]"
|
||||
:visible-columns="visibleColumns"
|
||||
:virtual-scroll-sticky-size-start="48"
|
||||
v-model:pagination="pagination"
|
||||
:pagination="pagination"
|
||||
:loading="isLoading"
|
||||
row-key="id"
|
||||
>
|
||||
<template v-slot:header="props">
|
||||
<q-tr :props="props">
|
||||
|
|
|
|||
|
|
@ -11,7 +11,6 @@ import type { DutyFormType } from "@/modules/10_registry/interface/index/Main";
|
|||
|
||||
/** import components */
|
||||
import DialogHistory from "@/modules/10_registry/Dialog/DialogHistory.vue";
|
||||
import SkeletonTable from "@/components/SkeletonTable.vue";
|
||||
|
||||
const $q = useQuasar();
|
||||
const dataStore = useDataStore();
|
||||
|
|
@ -287,9 +286,7 @@ onMounted(async () => {
|
|||
/>
|
||||
</q-toolbar>
|
||||
|
||||
<SkeletonTable v-if="isLoading" :columns="columns" />
|
||||
<d-table
|
||||
v-else
|
||||
flat
|
||||
dense
|
||||
bordered
|
||||
|
|
@ -300,7 +297,9 @@ onMounted(async () => {
|
|||
:rows-per-page-options="[10, 25, 50, 100]"
|
||||
:visible-columns="visibleColumns"
|
||||
:virtual-scroll-sticky-size-start="48"
|
||||
v-model:pagination="pagination"
|
||||
:pagination="pagination"
|
||||
:loading="isLoading"
|
||||
row-key="id"
|
||||
>
|
||||
<template v-slot:header="props">
|
||||
<q-tr :props="props">
|
||||
|
|
|
|||
|
|
@ -11,7 +11,6 @@ import type { DutyFormType } from "@/modules/10_registry/interface/index/Main";
|
|||
|
||||
/** import components */
|
||||
import DialogHistory from "@/modules/10_registry/Dialog/DialogHistory.vue";
|
||||
import SkeletonTable from "@/components/SkeletonTable.vue";
|
||||
|
||||
const $q = useQuasar();
|
||||
|
||||
|
|
@ -368,9 +367,7 @@ onMounted(async () => {
|
|||
/>
|
||||
</q-toolbar>
|
||||
|
||||
<SkeletonTable v-if="isLoading" :columns="columns" />
|
||||
<d-table
|
||||
v-else
|
||||
flat
|
||||
dense
|
||||
bordered
|
||||
|
|
@ -381,7 +378,9 @@ onMounted(async () => {
|
|||
:rows-per-page-options="[10, 25, 50, 100]"
|
||||
:visible-columns="visibleColumns"
|
||||
:virtual-scroll-sticky-size-start="48"
|
||||
v-model:pagination="pagination"
|
||||
:pagination="pagination"
|
||||
:loading="isLoading"
|
||||
row-key="id"
|
||||
>
|
||||
<template v-slot:header="props">
|
||||
<q-tr :props="props">
|
||||
|
|
|
|||
|
|
@ -14,7 +14,6 @@ import type {
|
|||
|
||||
/**import components*/
|
||||
import DialogHistory from "@/modules/10_registry/Dialog/DialogHistory.vue";
|
||||
import SkeletonTable from "@/components/SkeletonTable.vue";
|
||||
|
||||
const $q = useQuasar();
|
||||
const dataPerson = useDataStore();
|
||||
|
|
@ -526,9 +525,7 @@ onMounted(async () => {
|
|||
</div>
|
||||
|
||||
<div class="col-12 q-mt-sm">
|
||||
<SkeletonTable v-if="isLoading.position" :columns="columns" />
|
||||
<d-table
|
||||
v-else
|
||||
flat
|
||||
dense
|
||||
bordered
|
||||
|
|
@ -539,6 +536,9 @@ onMounted(async () => {
|
|||
:rows-per-page-options="[10, 25, 50, 100]"
|
||||
:visible-columns="visibleColumns"
|
||||
:virtual-scroll-sticky-size-start="48"
|
||||
:isLoading="isLoading.position"
|
||||
row-key="id"
|
||||
:pagination="{ page: 1, rowsPerPage: 10 }"
|
||||
>
|
||||
<template v-slot:header="props">
|
||||
<q-tr :props="props">
|
||||
|
|
|
|||
|
|
@ -10,7 +10,6 @@ import { useDataStore } from "@/stores/data";
|
|||
import type { SalaryFormType } from "@/modules/10_registry/interface/index/Main";
|
||||
|
||||
import DialogHistory from "@/modules/10_registry/Dialog/DialogHistory.vue";
|
||||
import SkeletonTable from "@/components/SkeletonTable.vue";
|
||||
|
||||
const $q = useQuasar();
|
||||
const dataPerson = useDataStore();
|
||||
|
|
@ -729,19 +728,20 @@ onMounted(async () => {
|
|||
/>
|
||||
</q-toolbar>
|
||||
|
||||
<SkeletonTable v-if="isLoading" :columns="columns" />
|
||||
<d-table
|
||||
v-else
|
||||
flat
|
||||
dense
|
||||
bordered
|
||||
virtual-scroll
|
||||
row-key="id"
|
||||
:rows="rows.length !== 0 ? rows : []"
|
||||
:columns="columns"
|
||||
:grid="!mode"
|
||||
:rows-per-page-options="[10, 25, 50, 100]"
|
||||
:visible-columns="visibleColumns"
|
||||
:virtual-scroll-sticky-size-start="48"
|
||||
:loading="isLoading"
|
||||
:pagination="{ page: 1, rowsPerPage: 10 }"
|
||||
>
|
||||
<template v-slot:header="props">
|
||||
<q-tr :props="props">
|
||||
|
|
@ -765,7 +765,11 @@ onMounted(async () => {
|
|||
<div v-else-if="col.name == 'status'">
|
||||
{{ props.row.status ? props.row.status : "-" }}
|
||||
</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
|
||||
? findOrgNameHtml({
|
||||
|
|
|
|||
|
|
@ -11,7 +11,6 @@ import { useRegistryDataStore } from "@/modules/10_registry/store/Main";
|
|||
import type { NopaidFormType } from "@/modules/10_registry/interface/index/Main";
|
||||
|
||||
import DialogHistory from "@/modules/10_registry/Dialog/DialogHistory.vue";
|
||||
import SkeletonTable from "@/components/SkeletonTable.vue";
|
||||
|
||||
const $q = useQuasar();
|
||||
const dataPerson = useDataStore();
|
||||
|
|
@ -340,9 +339,7 @@ onMounted(async () => {
|
|||
/>
|
||||
</q-toolbar>
|
||||
|
||||
<SkeletonTable v-if="isLoading" :columns="columns" />
|
||||
<d-table
|
||||
v-else
|
||||
flat
|
||||
dense
|
||||
bordered
|
||||
|
|
@ -353,7 +350,9 @@ onMounted(async () => {
|
|||
:rows-per-page-options="[10, 25, 50, 100]"
|
||||
:visible-columns="visibleColumns"
|
||||
:virtual-scroll-sticky-size-start="48"
|
||||
v-model:pagination="pagination"
|
||||
:pagination="pagination"
|
||||
:loading="isLoading"
|
||||
row-key="id"
|
||||
>
|
||||
<template v-slot:header="props">
|
||||
<q-tr :props="props">
|
||||
|
|
|
|||
|
|
@ -11,7 +11,6 @@ import { useRegistryDataStore } from "@/modules/10_registry/store/Main";
|
|||
import type { CertificateDetail } from "@/modules/10_registry/interface/index/Main";
|
||||
|
||||
import DialogHistory from "@/modules/10_registry/Dialog/DialogHistory.vue";
|
||||
import SkeletonTable from "@/components/SkeletonTable.vue";
|
||||
|
||||
const $q = useQuasar();
|
||||
const dataPerson = useDataStore();
|
||||
|
|
@ -338,10 +337,8 @@ onMounted(async () => {
|
|||
:display-value="$q.lang.table.columns"
|
||||
/>
|
||||
</q-toolbar>
|
||||
<SkeletonTable v-if="isLoading" :columns="columns" />
|
||||
|
||||
<d-table
|
||||
v-else
|
||||
flat
|
||||
dense
|
||||
bordered
|
||||
|
|
@ -352,7 +349,9 @@ onMounted(async () => {
|
|||
:rows-per-page-options="[10, 25, 50, 100]"
|
||||
:visible-columns="visibleColumns"
|
||||
:virtual-scroll-sticky-size-start="48"
|
||||
v-model:pagination="pagination"
|
||||
:pagination="pagination"
|
||||
:loading="isLoading"
|
||||
row-key="id"
|
||||
>
|
||||
<template v-slot:header="props">
|
||||
<q-tr :props="props">
|
||||
|
|
|
|||
|
|
@ -11,7 +11,6 @@ import type { TrainingFormType } from "@/modules/10_registry/interface/index/Mai
|
|||
|
||||
//history dialog
|
||||
import DialogHistory from "@/modules/10_registry/Dialog/DialogHistory.vue";
|
||||
import SkeletonTable from "@/components/SkeletonTable.vue";
|
||||
|
||||
const $q = useQuasar();
|
||||
const dataPerson = useDataStore();
|
||||
|
|
@ -447,9 +446,7 @@ onMounted(async () => {
|
|||
/>
|
||||
</q-toolbar>
|
||||
|
||||
<SkeletonTable v-if="isLoading" :columns="columns" />
|
||||
<d-table
|
||||
v-else
|
||||
flat
|
||||
dense
|
||||
bordered
|
||||
|
|
@ -460,7 +457,9 @@ onMounted(async () => {
|
|||
:rows-per-page-options="[10, 25, 50, 100]"
|
||||
:visible-columns="visibleColumns"
|
||||
:virtual-scroll-sticky-size-start="48"
|
||||
v-model:pagination="pagination"
|
||||
:pagination="pagination"
|
||||
:loading="isLoading"
|
||||
row-key="id"
|
||||
>
|
||||
<template v-slot:header="props">
|
||||
<q-tr :props="props">
|
||||
|
|
|
|||
|
|
@ -11,7 +11,6 @@ import { useRegistryDataStore } from "@/modules/10_registry/store/Main";
|
|||
import type { InsigniaFormType } from "@/modules/10_registry/interface/index/Main";
|
||||
|
||||
import DialogHistory from "@/modules/10_registry/Dialog/DialogHistory.vue";
|
||||
import SkeletonTable from "@/components/SkeletonTable.vue";
|
||||
|
||||
const $q = useQuasar();
|
||||
const dataPerson = useDataStore();
|
||||
|
|
@ -555,9 +554,7 @@ onMounted(async () => {
|
|||
/>
|
||||
</q-toolbar>
|
||||
|
||||
<SkeletonTable v-if="isLoading" :columns="columns" />
|
||||
<d-table
|
||||
v-else
|
||||
flat
|
||||
dense
|
||||
bordered
|
||||
|
|
@ -568,7 +565,9 @@ onMounted(async () => {
|
|||
:rows-per-page-options="[10, 25, 50, 100]"
|
||||
:visible-columns="visibleColumns"
|
||||
:virtual-scroll-sticky-size-start="48"
|
||||
v-model:pagination="pagination"
|
||||
:pagination="pagination"
|
||||
:loading="isLoading"
|
||||
row-key="id"
|
||||
>
|
||||
<template v-slot:header="props">
|
||||
<q-tr :props="props">
|
||||
|
|
|
|||
|
|
@ -12,7 +12,6 @@ import type { HonorFormData } from "@/modules/10_registry/interface/index/Main";
|
|||
|
||||
//history dialog
|
||||
import DialogHistory from "@/modules/10_registry/Dialog/DialogHistory.vue";
|
||||
import SkeletonTable from "@/components/SkeletonTable.vue";
|
||||
|
||||
const $q = useQuasar();
|
||||
const dataPerson = useDataStore();
|
||||
|
|
@ -339,9 +338,7 @@ onMounted(async () => {
|
|||
/>
|
||||
</q-toolbar>
|
||||
|
||||
<SkeletonTable v-if="isLoading" :columns="columns" />
|
||||
<d-table
|
||||
v-else
|
||||
flat
|
||||
dense
|
||||
bordered
|
||||
|
|
@ -352,7 +349,9 @@ onMounted(async () => {
|
|||
:rows-per-page-options="[10, 25, 50, 100]"
|
||||
:visible-columns="visibleColumns"
|
||||
:virtual-scroll-sticky-size-start="48"
|
||||
v-model:pagination="pagination"
|
||||
:pagination="pagination"
|
||||
:loading="isLoading"
|
||||
row-key="id"
|
||||
>
|
||||
<template v-slot:header="props">
|
||||
<q-tr :props="props">
|
||||
|
|
|
|||
|
|
@ -13,7 +13,6 @@ import type {
|
|||
} from "@/modules/10_registry/interface/index/Main";
|
||||
|
||||
import DialogHistory from "@/modules/10_registry/Dialog/DialogHistory.vue";
|
||||
import SkeletonTable from "@/components/SkeletonTable.vue";
|
||||
|
||||
const $q = useQuasar();
|
||||
const dataPerson = useDataStore();
|
||||
|
|
@ -473,9 +472,7 @@ onMounted(async () => {
|
|||
/>
|
||||
</q-toolbar>
|
||||
|
||||
<SkeletonTable v-if="isLoading" :columns="columns" />
|
||||
<d-table
|
||||
v-else
|
||||
flat
|
||||
dense
|
||||
bordered
|
||||
|
|
@ -486,7 +483,9 @@ onMounted(async () => {
|
|||
:rows-per-page-options="[10, 25, 50, 100]"
|
||||
:visible-columns="visibleColumns"
|
||||
:virtual-scroll-sticky-size-start="48"
|
||||
v-model:pagination="pagination"
|
||||
:pagination="pagination"
|
||||
:loading="isLoading"
|
||||
row-key="id"
|
||||
>
|
||||
<template v-slot:header="props">
|
||||
<q-tr :props="props">
|
||||
|
|
|
|||
|
|
@ -8,7 +8,6 @@ import { useCounterMixin } from "@/stores/mixin";
|
|||
import { useDataStore } from "@/stores/data";
|
||||
|
||||
import DialogDevelop from "@/modules/10_registry/Dialog/DialogDevelopmant.vue";
|
||||
import SkeletonTable from "@/components/SkeletonTable.vue";
|
||||
|
||||
const $q = useQuasar();
|
||||
const dataPerson = useDataStore();
|
||||
|
|
@ -209,9 +208,8 @@ onMounted(async () => {
|
|||
:display-value="$q.lang.table.columns"
|
||||
/>
|
||||
</q-toolbar>
|
||||
<SkeletonTable v-if="isLoading" :columns="columns" />
|
||||
|
||||
<d-table
|
||||
v-else
|
||||
flat
|
||||
dense
|
||||
bordered
|
||||
|
|
@ -222,6 +220,9 @@ onMounted(async () => {
|
|||
:rows-per-page-options="[10, 25, 50, 100]"
|
||||
:visible-columns="visibleColumns"
|
||||
:virtual-scroll-sticky-size-start="48"
|
||||
:pagination="{ page: 1, rowsPerPage: 10 }"
|
||||
:loading="isLoading"
|
||||
row-key="id"
|
||||
>
|
||||
<template v-slot:header="props">
|
||||
<q-tr :props="props">
|
||||
|
|
|
|||
|
|
@ -10,7 +10,6 @@ import { useDataStore } from "@/stores/data";
|
|||
import type { OtherFormType } from "@/modules/10_registry/interface/index/Main";
|
||||
|
||||
import DialogHistory from "@/modules/10_registry/Dialog/DialogHistory.vue";
|
||||
import SkeletonTable from "@/components/SkeletonTable.vue";
|
||||
|
||||
const $q = useQuasar();
|
||||
const dataPerson = useDataStore();
|
||||
|
|
@ -232,9 +231,7 @@ onMounted(async () => {
|
|||
/>
|
||||
</q-toolbar>
|
||||
|
||||
<SkeletonTable v-if="isLoading" :columns="columns" />
|
||||
<d-table
|
||||
v-else
|
||||
flat
|
||||
dense
|
||||
bordered
|
||||
|
|
@ -245,7 +242,9 @@ onMounted(async () => {
|
|||
:rows-per-page-options="[10, 25, 50, 100]"
|
||||
:visible-columns="visibleColumns"
|
||||
:virtual-scroll-sticky-size-start="48"
|
||||
v-model:pagination="pagination"
|
||||
:pagination="pagination"
|
||||
:loading="isLoading"
|
||||
row-key="id"
|
||||
>
|
||||
<template v-slot:header="props">
|
||||
<q-tr :props="props">
|
||||
|
|
@ -276,6 +275,7 @@ onMounted(async () => {
|
|||
</q-td>
|
||||
</q-tr>
|
||||
</template>
|
||||
|
||||
<template v-else v-slot:item="props">
|
||||
<div class="q-mb-xs col-xs-12 col-sm-6 col-md-4 col-lg-3">
|
||||
<q-card bordered flat>
|
||||
|
|
@ -308,13 +308,6 @@ onMounted(async () => {
|
|||
</q-card>
|
||||
</div>
|
||||
</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>
|
||||
</div>
|
||||
|
||||
|
|
|
|||
|
|
@ -8,7 +8,6 @@ import type { QTableProps } from "quasar";
|
|||
|
||||
/** import component */
|
||||
import DialogHeader from "@/components/DialogHeader.vue";
|
||||
import SkeletonTable from "@/components/SkeletonTable.vue";
|
||||
|
||||
const { date2Thai, onSearchDataTable, findOrgNameHtml } = useCounterMixin();
|
||||
|
||||
|
|
@ -129,11 +128,8 @@ watch(
|
|||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="isLoading">
|
||||
<SkeletonTable :columns="columns" />
|
||||
</div>
|
||||
|
||||
<div v-else class="col-12">
|
||||
<div class="col-12">
|
||||
<d-table
|
||||
flat
|
||||
dense
|
||||
|
|
@ -144,7 +140,9 @@ watch(
|
|||
:rows-per-page-options="[10, 25, 50, 100]"
|
||||
:visible-columns="visibleColumns"
|
||||
:virtual-scroll-sticky-size-start="48"
|
||||
v-model:pagination="pagination"
|
||||
:pagination="pagination"
|
||||
:loading="isLoading"
|
||||
row-key="id"
|
||||
>
|
||||
<template v-slot:header="props">
|
||||
<q-tr :props="props">
|
||||
|
|
@ -262,13 +260,6 @@ watch(
|
|||
</q-card>
|
||||
</div>
|
||||
</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>
|
||||
</div>
|
||||
</q-card-section>
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
<script setup lang="ts">
|
||||
import { ref, onMounted, watch } from "vue";
|
||||
import { ref, onMounted } from "vue";
|
||||
|
||||
import config from "@/app.config";
|
||||
import http from "@/plugins/http";
|
||||
|
|
@ -11,15 +11,12 @@ import { useCounterMixin } from "@/stores/mixin";
|
|||
|
||||
/**importType*/
|
||||
import type { QTableProps } from "quasar";
|
||||
import type {
|
||||
DataOption,
|
||||
NewPagination,
|
||||
} from "@/modules/10_registry/interface/index/Main";
|
||||
import type { PropsTable } from "@/interface/PropsTable";
|
||||
import type { DataOption } from "@/modules/10_registry/interface/index/Main";
|
||||
import type { DataRequest } from "@/modules/10_registry/interface/response/Main";
|
||||
|
||||
/** importComponents*/
|
||||
import DialogAddRequestEdit from "@/modules/10_registry/components/DialogAddRequestEdit.vue";
|
||||
import SkeletonTable from "@/components/SkeletonTable.vue";
|
||||
|
||||
/** use */
|
||||
const $q = useQuasar();
|
||||
|
|
@ -38,10 +35,6 @@ const isLoading = ref<boolean>(false);
|
|||
|
||||
/** Table*/
|
||||
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"]>([
|
||||
{
|
||||
name: "no",
|
||||
|
|
@ -110,10 +103,11 @@ const visibleColumns = ref<string[]>([
|
|||
"status",
|
||||
"remark",
|
||||
]);
|
||||
const pagination = ref({
|
||||
const pagination = ref<PropsTable.Pagination>({
|
||||
descending: true,
|
||||
page: page.value,
|
||||
rowsPerPage: pageSize.value,
|
||||
page: 1,
|
||||
rowsPerPage: 10,
|
||||
rowsNumber: 0,
|
||||
});
|
||||
|
||||
/** function กลับไปหน้าทะเบียนประวัติ*/
|
||||
|
|
@ -129,8 +123,8 @@ function onClickAdd() {
|
|||
/** function fetch รายการข้อมูลการยื่นคำร้องขอแก้ไขข้อมูล*/
|
||||
async function fetchListRequset() {
|
||||
let queryParams = {
|
||||
page: page.value,
|
||||
pageSize: pageSize.value,
|
||||
page: pagination.value.page,
|
||||
pageSize: pagination.value.rowsPerPage,
|
||||
status: status.value,
|
||||
keyword: keyword.value,
|
||||
};
|
||||
|
|
@ -140,10 +134,9 @@ async function fetchListRequset() {
|
|||
params: queryParams,
|
||||
})
|
||||
.then((res) => {
|
||||
const data = res.data.result;
|
||||
maxPage.value = Math.ceil(data.total / pageSize.value);
|
||||
rowsTotal.value = data.total;
|
||||
rows.value = data.data;
|
||||
const result = res.data.result;
|
||||
pagination.value.rowsNumber = result.total;
|
||||
rows.value = result.data;
|
||||
})
|
||||
.catch((err) => {
|
||||
messageError($q, err);
|
||||
|
|
@ -155,7 +148,7 @@ async function fetchListRequset() {
|
|||
|
||||
/** function เลือกสถานะคำร้อง*/
|
||||
function updateStatusValue() {
|
||||
page.value = 1;
|
||||
pagination.value.page = 1;
|
||||
fetchListRequset();
|
||||
}
|
||||
|
||||
|
|
@ -180,21 +173,16 @@ function filterOption(val: string, update: Function) {
|
|||
}
|
||||
|
||||
/**
|
||||
* function อัพเดทขนาดหน้าใน pagination
|
||||
* @param newPagination ข้อมูลใหม่ของ pagination
|
||||
* ฟังก์ชันรับ request จากตาราง เมื่อมีการเปลี่ยน pagination
|
||||
* @param requestProps ข้อมูลการร้องขอจากตาราง
|
||||
*/
|
||||
function updatePageSizePagination(newPagination: NewPagination) {
|
||||
page.value = 1;
|
||||
pageSize.value = newPagination.rowsPerPage;
|
||||
function onTableRequest(requestProps: PropsTable.RequestProps) {
|
||||
const newPagination = requestProps?.pagination || requestProps;
|
||||
if (!newPagination?.page || !newPagination?.rowsPerPage) return;
|
||||
pagination.value = { ...newPagination };
|
||||
fetchListRequset();
|
||||
}
|
||||
|
||||
watch(
|
||||
() => pageSize.value,
|
||||
() => {
|
||||
fetchListRequset();
|
||||
}
|
||||
);
|
||||
|
||||
onMounted(async () => {
|
||||
link.value = await dataStore.getProFileType();
|
||||
fetchListRequset();
|
||||
|
|
@ -298,17 +286,16 @@ onMounted(async () => {
|
|||
</div>
|
||||
</div>
|
||||
<div class="col-12">
|
||||
<SkeletonTable v-if="isLoading" :columns="columns" />
|
||||
<d-table
|
||||
v-else
|
||||
:columns="columns"
|
||||
:rows="rows"
|
||||
row-key="id"
|
||||
:rows-per-page-options="[10, 25, 50, 100]"
|
||||
:paging="true"
|
||||
:visible-columns="visibleColumns"
|
||||
@update:pagination="updatePageSizePagination"
|
||||
v-model:pagination="pagination"
|
||||
:loading="isLoading"
|
||||
@request="onTableRequest"
|
||||
>
|
||||
<template v-slot:header="props">
|
||||
<q-tr :props="props">
|
||||
|
|
@ -338,20 +325,6 @@ onMounted(async () => {
|
|||
</q-td>
|
||||
</q-tr>
|
||||
</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>
|
||||
</div>
|
||||
</q-card>
|
||||
|
|
|
|||
|
|
@ -14,18 +14,10 @@ import type {
|
|||
ProbationFormType,
|
||||
} from "@/modules/11_probation/interface/index/main";
|
||||
|
||||
import SkeletonTable from "@/components/SkeletonTable.vue";
|
||||
|
||||
const $q = useQuasar();
|
||||
const mixin = useCounterMixin();
|
||||
const {
|
||||
messageError,
|
||||
findOrgName,
|
||||
showLoader,
|
||||
hideLoader,
|
||||
date2Thai,
|
||||
onSearchDataTable,
|
||||
} = mixin;
|
||||
const { messageError, findOrgName, hideLoader, date2Thai, onSearchDataTable } =
|
||||
mixin;
|
||||
|
||||
const profileId = ref<string>("");
|
||||
const rows = ref<ListMain[]>([]);
|
||||
|
|
@ -312,7 +304,10 @@ onMounted(async () => {
|
|||
</div>
|
||||
<q-resize-observer @resize="onResize" />
|
||||
<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>
|
||||
<img
|
||||
:src="profileImg"
|
||||
|
|
@ -397,7 +392,6 @@ onMounted(async () => {
|
|||
</div>
|
||||
<div class="q-mt-sm">
|
||||
<d-table
|
||||
v-if="!isLoad"
|
||||
flat
|
||||
dense
|
||||
bordered
|
||||
|
|
@ -409,6 +403,8 @@ onMounted(async () => {
|
|||
:rows-per-page-options="[10, 25, 50, 100]"
|
||||
:visible-columns="visibleColumns"
|
||||
:virtual-scroll-sticky-size-start="48"
|
||||
:pagination="{ page: 1, rowsPerPage: 10 }"
|
||||
:loading="isLoad"
|
||||
>
|
||||
<template v-slot:header="props">
|
||||
<q-tr :props="props">
|
||||
|
|
@ -471,15 +467,7 @@ onMounted(async () => {
|
|||
</q-card>
|
||||
</div>
|
||||
</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>
|
||||
<SkeletonTable v-else :columns="columns" />
|
||||
</div>
|
||||
</q-card>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -10,8 +10,6 @@ import { useCounterMixin } from "@/stores/mixin";
|
|||
|
||||
import type { PortfolioRowsType } from "@/modules/13_portfolio/interface/Main";
|
||||
|
||||
import SkeletonTable from "@/components/SkeletonTable.vue";
|
||||
|
||||
const $q = useQuasar();
|
||||
const router = useRouter();
|
||||
const mixin = useCounterMixin();
|
||||
|
|
@ -115,7 +113,6 @@ function onDelete(id: string) {
|
|||
});
|
||||
}
|
||||
|
||||
|
||||
/** ฟังก์ชั่นค้นหาข้อมูลในตาราง */
|
||||
function onSearch() {
|
||||
rows.value = onSearchDataTable(
|
||||
|
|
@ -125,6 +122,10 @@ function onSearch() {
|
|||
);
|
||||
}
|
||||
|
||||
function onTableRequest() {
|
||||
console.log(1111);
|
||||
}
|
||||
|
||||
/** Hook Lifecycle */
|
||||
onMounted(async () => {
|
||||
await fecthList();
|
||||
|
|
@ -199,35 +200,21 @@ onMounted(async () => {
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<SkeletonTable v-if="isLoading" :columns="columns" />
|
||||
<div class="col-12" v-else>
|
||||
<div class="col-12">
|
||||
<d-table
|
||||
flat
|
||||
bordered
|
||||
dense
|
||||
:paging="true"
|
||||
row-key="id"
|
||||
class="custom-table2"
|
||||
style="max-height: 80vh"
|
||||
:rows="rows"
|
||||
:columns="columns"
|
||||
:visible-columns="visibleColumns"
|
||||
: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">
|
||||
<q-tr :props="props">
|
||||
<q-th
|
||||
|
|
|
|||
|
|
@ -8,10 +8,9 @@ import config from "@/app.config";
|
|||
import { useCounterMixin } from "@/stores/mixin";
|
||||
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 SkeletonTable from "@/components/SkeletonTable.vue";
|
||||
|
||||
const $q = useQuasar();
|
||||
const router = useRouter();
|
||||
const mixin = useCounterMixin();
|
||||
|
|
@ -23,13 +22,12 @@ const filterKeyword = ref<string>("");
|
|||
const status = ref<string>("ALL"); // สถานะคำร้อง
|
||||
const statusOptions = ref<DataOption[]>(store.optionStatus);
|
||||
const rows = ref<RowsListMain[]>([]);
|
||||
const total = ref<number>(0);
|
||||
const totalList = ref<number>(1);
|
||||
const pagination = ref({
|
||||
const pagination = ref<PropsTable.Pagination>({
|
||||
sortBy: "createdAt",
|
||||
descending: true,
|
||||
page: 1,
|
||||
rowsPerPage: 10,
|
||||
rowsNumber: 0,
|
||||
});
|
||||
const visibleColumns = ref<string[]>([
|
||||
"no",
|
||||
|
|
@ -186,11 +184,9 @@ async function getListData() {
|
|||
`
|
||||
)
|
||||
.then(async (res) => {
|
||||
const data = await res.data.result.data;
|
||||
const dataTotal = await res.data.result.total;
|
||||
totalList.value = Math.ceil(dataTotal / pagination.value.rowsPerPage);
|
||||
total.value = dataTotal;
|
||||
rows.value = data;
|
||||
const result = await res.data.result;
|
||||
pagination.value.rowsNumber = result.total;
|
||||
rows.value = result.data;
|
||||
})
|
||||
.catch((e) => {
|
||||
messageError($q, e);
|
||||
|
|
@ -245,10 +241,15 @@ async function downloadUrl(id: string, fileName: string) {
|
|||
});
|
||||
}
|
||||
|
||||
/** เมื่อมีการเปลี่ยน แถว ดึงข้อมูลใหม่ */
|
||||
function updatePagination(newPagination: any) {
|
||||
pagination.value.page = 1;
|
||||
pagination.value.rowsPerPage = newPagination.rowsPerPage;
|
||||
/**
|
||||
* ฟังก์ชันรับ request จากตาราง เมื่อมีการเปลี่ยน pagination
|
||||
* @param requestProps ข้อมูลการร้องขอจากตาราง
|
||||
*/
|
||||
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();
|
||||
}
|
||||
|
||||
watch(
|
||||
() => pagination.value.rowsPerPage,
|
||||
async () => {
|
||||
await getListData();
|
||||
}
|
||||
);
|
||||
|
||||
onMounted(async () => {
|
||||
await getListData();
|
||||
});
|
||||
|
|
@ -366,17 +360,16 @@ onMounted(async () => {
|
|||
</div>
|
||||
|
||||
<div class="col-12">
|
||||
<SkeletonTable v-if="isLoading" :columns="columns" />
|
||||
<d-table
|
||||
v-else
|
||||
:columns="columns"
|
||||
:rows="rows"
|
||||
row-key="id"
|
||||
:paging="true"
|
||||
:visible-columns="visibleColumns"
|
||||
:rows-per-page-options="[10, 25, 50, 100]"
|
||||
@update:pagination="updatePagination"
|
||||
@request="onTableRequest"
|
||||
v-model:pagination="pagination"
|
||||
:loading="isLoading"
|
||||
>
|
||||
<template v-slot:header="props">
|
||||
<q-tr :props="props">
|
||||
|
|
@ -459,20 +452,6 @@ onMounted(async () => {
|
|||
</q-td>
|
||||
</q-tr>
|
||||
</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>
|
||||
</div>
|
||||
</q-card>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue